File indexing completed on 2024-04-21 16:31:16

0001 /*****************************************************************************
0002  *   Copyright 2007 - 2010 Craig Drummond <craig.p.drummond@gmail.com>       *
0003  *   Copyright 2013 - 2015 Yichao Yu <yyc1992@gmail.com>                     *
0004  *                                                                           *
0005  *   This program is free software; you can redistribute it and/or modify    *
0006  *   it under the terms of the GNU Lesser General Public License as          *
0007  *   published by the Free Software Foundation; either version 2.1 of the    *
0008  *   License, or (at your option) version 3, or any later version accepted   *
0009  *   by the membership of KDE e.V. (or its successor approved by the         *
0010  *   membership of KDE e.V.), which shall act as a proxy defined in          *
0011  *   Section 6 of version 3 of the license.                                  *
0012  *                                                                           *
0013  *   This program is distributed in the hope that it will be useful,         *
0014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
0015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       *
0016  *   Lesser General Public License for more details.                         *
0017  *                                                                           *
0018  *   You should have received a copy of the GNU Lesser General Public        *
0019  *   License along with this library. If not,                                *
0020  *   see <http://www.gnu.org/licenses/>.                                     *
0021  *****************************************************************************/
0022 
0023 #ifndef __QTCURVE_H__
0024 #define __QTCURVE_H__
0025 
0026 #include <QTime>
0027 #include <QPalette>
0028 #include <QMap>
0029 #include <QList>
0030 #include <QSet>
0031 #include <QCache>
0032 #include <QColor>
0033 #include <QStyleOption>
0034 #include <QtGlobal>
0035 #include <QCommonStyle>
0036 typedef qulonglong QtcKey;
0037 #include <common/common.h>
0038 
0039 // TODO maybe we should have QTC_QT4_DBUS_FOUND?
0040 #include <QDBusInterface>
0041 
0042 #ifdef QTC_QT4_ENABLE_KDE
0043 #  include <KDE/KStyle>
0044 #  include <KDE/KComponentData>
0045 #endif
0046 
0047 class QStyleOptionSlider;
0048 class QLabel;
0049 class QMenuBar;
0050 class QScrollBar;
0051 class QMainWindow;
0052 class QStatusBar;
0053 class QAbstractScrollArea;
0054 class QProgressBar;
0055 class QFormLayout;
0056 
0057 namespace QtCurve {
0058 class WindowManager;
0059 class BlurHelper;
0060 class ShortcutHandler;
0061 class ShadowHelper;
0062 
0063 typedef QCommonStyle BaseStyle;
0064 
0065 class Style: public BaseStyle {
0066     Q_OBJECT
0067     Q_CLASSINFO("X-KDE-CustomElements", "true")
0068 public:
0069     enum BackgroundType {
0070         BGND_WINDOW,
0071         BGND_DIALOG,
0072         BGND_MENU
0073     };
0074 
0075     enum MenuItemType {
0076         MENU_POPUP,
0077         MENU_BAR,
0078         MENU_COMBO
0079     };
0080 
0081     enum CustomElements {
0082         CE_QtC_KCapacityBar = CE_CustomBase + 0x00FFFF00,
0083         CE_QtC_Preview,
0084         CE_QtC_SetOptions
0085     };
0086 
0087     enum PreviewType {
0088         PREVIEW_FALSE,
0089         PREVIEW_MDI,
0090         PREVIEW_WINDOW
0091     };
0092 
0093     class PreviewOption: public QStyleOption {
0094     public:
0095         Options opts;
0096     };
0097 
0098     class BgndOption: public QStyleOption {
0099     public:
0100         EAppearance app;
0101         QPainterPath path;
0102         QRect widgetRect;
0103     };
0104 
0105     enum Icon {
0106         ICN_MIN,
0107         ICN_MAX,
0108         ICN_MENU,
0109         ICN_RESTORE,
0110         ICN_CLOSE,
0111         ICN_UP,
0112         ICN_DOWN,
0113         ICN_RIGHT,
0114         ICN_SHADE,
0115         ICN_UNSHADE
0116     };
0117 
0118 #ifdef QTC_QT4_STYLE_SUPPORT
0119     Style(const QString &name=QString());
0120 #else
0121     Style();
0122 #endif
0123     ~Style();
0124 
0125     void polish(QApplication *app) override;
0126     void polish(QPalette &palette) override;
0127     void polish(QWidget *widget) override;
0128     void unpolish(QApplication *app) override;
0129     void unpolish(QWidget *widget) override;
0130 
0131     bool eventFilter(QObject *object, QEvent *event) override;
0132     void timerEvent(QTimerEvent *event) override;
0133 
0134     int pixelMetric(PixelMetric metric, const QStyleOption *option=0,
0135                     const QWidget *widget=0) const override;
0136     int styleHint(StyleHint hint, const QStyleOption *option,
0137                   const QWidget *widget,
0138                   QStyleHintReturn *returnData=0) const override;
0139     QSize sizeFromContents(ContentsType type, const QStyleOption *option,
0140                            const QSize &size,
0141                            const QWidget *widget) const override;
0142     QPalette standardPalette() const override;
0143 
0144     void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
0145                        QPainter *painter, const QWidget *widget) const override;
0146     void drawControl(ControlElement control, const QStyleOption *option,
0147                      QPainter *painter, const QWidget *widget) const override;
0148     void drawComplexControl(ComplexControl control,
0149                             const QStyleOptionComplex *option,
0150                             QPainter *painter,
0151                             const QWidget *widget) const override;
0152     void drawItemText(QPainter *painter, const QRect &rect, int flags,
0153                       const QPalette &pal, bool enabled,
0154                       const QString &text,
0155                       QPalette::ColorRole=QPalette::NoRole) const override;
0156 
0157     QRect subElementRect(SubElement element, const QStyleOption *option,
0158                          const QWidget *widget) const override;
0159     QRect subControlRect(ComplexControl control,
0160                          const QStyleOptionComplex *option,
0161                          SubControl subControl,
0162                          const QWidget *widget) const override;
0163     SubControl hitTestComplexControl(ComplexControl control,
0164                                      const QStyleOptionComplex *option,
0165                                      const QPoint &pos,
0166                                      const QWidget *widget) const override;
0167     void prePolish(QWidget *w) const;
0168     void
0169     prePolish(const QWidget *w) const
0170     {
0171         prePolish(const_cast<QWidget*>(w));
0172     }
0173 
0174 private:
0175     void init(bool initial);
0176     void freeColor(QSet<QColor*> &freedColors, QColor **cols);
0177     void freeColors();
0178     void polishFormLayout(QFormLayout *layout);
0179     void polishLayout(QLayout *layout);
0180     void polishScrollArea(QAbstractScrollArea *scrollArea,
0181                           bool isKFilePlacesView=false) const;
0182 
0183     void drawItemTextWithRole(QPainter *painter, const QRect &rect, int flags,
0184                               const QPalette &pal, bool enabled,
0185                               const QString &text,
0186                               QPalette::ColorRole textRole) const;
0187     void drawSideBarButton(QPainter *painter, const QRect &r,
0188                            const QStyleOption *option,
0189                            const QWidget *widget) const;
0190     void drawHighlight(QPainter *p, const QRect &r, bool horiz, bool inc) const;
0191     void drawFadedLine(QPainter *p, const QRect &r, const QColor &col,
0192                        bool fadeStart, bool fadeEnd, bool horiz,
0193                        double fadeSizeStart=FADE_SIZE,
0194                        double fadeSizeEnd=FADE_SIZE) const;
0195     void drawLines(QPainter *p, const QRect &r, bool horiz, int nLines,
0196                    int offset, const QColor *cols, int startOffset,
0197                    int dark, ELine type) const;
0198     void drawProgressBevelGradient(QPainter *p, const QRect &origRect,
0199                                    const QStyleOption *option, bool horiz,
0200                                    EAppearance bevApp,
0201                                    const QColor *cols) const;
0202     void drawBevelGradient(const QColor &base, QPainter *p, QRect const &r,
0203                            const QPainterPath &path, bool horiz, bool sel,
0204                            EAppearance bevApp, EWidget w=WIDGET_OTHER,
0205                            bool useCache=true) const;
0206     void drawBevelGradientReal(const QColor &base, QPainter *p, const QRect &r,
0207                                const QPainterPath &path, bool horiz, bool sel,
0208                                EAppearance bevApp, EWidget w) const;
0209 
0210     void
0211     drawBevelGradient(const QColor &base, QPainter *p, QRect const &r,
0212                       bool horiz, bool sel, EAppearance bevApp,
0213                       EWidget w=WIDGET_OTHER, bool useCache=true) const
0214     {
0215         drawBevelGradient(base, p, r, QPainterPath(), horiz, sel, bevApp, w,
0216                           useCache);
0217     }
0218     void
0219     drawBevelGradientReal(const QColor &base, QPainter *p, const QRect &r,
0220                           bool horiz, bool sel,
0221                           EAppearance bevApp, EWidget w) const
0222     {
0223         drawBevelGradientReal(base, p, r, QPainterPath(), horiz,
0224                               sel, bevApp, w);
0225     }
0226 
0227     void drawSunkenBevel(QPainter *p, const QRect &r, const QColor &col) const;
0228     void drawLightBevel(QPainter *p, const QRect &r, const QStyleOption *option,
0229                         const QWidget *widget, int round, const QColor &fill,
0230                         const QColor *custom=0, bool doBorder=true,
0231                         EWidget w=WIDGET_OTHER) const;
0232     void drawLightBevelReal(QPainter *p, const QRect &r,
0233                             const QStyleOption *option, const QWidget *widget,
0234                             int round, const QColor &fill,
0235                             const QColor *custom, bool doBorder, EWidget w,
0236                             bool useCache, ERound realRound,
0237                             bool onToolbar) const;
0238     void drawGlow(QPainter *p, const QRect &r, EWidget w,
0239                   const QColor *cols=0L) const;
0240     void drawEtch(QPainter *p, const QRect &r, const QWidget *widget,
0241                   EWidget w, bool raised=false, int round=ROUNDED_ALL) const;
0242     void drawBgndRing(QPainter &painter, int x, int y, int size,
0243                       int size2, bool isWindow) const;
0244     QPixmap drawStripes(const QColor &color, int opacity) const;
0245     void drawBackground(QPainter *p, const QColor &bgnd, const QRect &r,
0246                         int opacity, BackgroundType type, EAppearance app,
0247                         const QPainterPath &path=QPainterPath()) const;
0248     void drawBackgroundImage(QPainter *p, bool isWindow, const QRect &r) const;
0249     void drawBackground(QPainter *p, const QWidget *widget,
0250                         BackgroundType type) const;
0251     QPainterPath buildPath(const QRectF &r, EWidget w,
0252                            int round, double radius) const;
0253     QPainterPath buildPath(const QRect &r, EWidget w,
0254                            int round, double radius) const;
0255     void buildSplitPath(const QRect &r, int round, double radius,
0256                         QPainterPath &tl, QPainterPath &br) const;
0257     void drawBorder(QPainter *p, const QRect &r, const QStyleOption *option,
0258                     int round, const QColor *custom=0, EWidget w=WIDGET_OTHER,
0259                     EBorder borderProfile=BORDER_FLAT, bool doBlend=true,
0260                     int borderVal=QTC_STD_BORDER) const;
0261     void drawMdiControl(QPainter *p, const QStyleOptionTitleBar *titleBar,
0262                         SubControl sc, const QWidget *widget,
0263                         ETitleBarButtons btn, const QColor &iconColor,
0264                         const QColor *btnCols, const QColor *bgndCols,
0265                         int adjust, bool activeWindow) const;
0266     void drawDwtControl(QPainter *p, const QFlags<State> &state,
0267                         const QRect &rect, ETitleBarButtons btn, Icon icon,
0268                         const QColor &iconColor, const QColor *btnCols,
0269                         const QColor *bgndCols) const;
0270     bool drawMdiButton(QPainter *painter, const QRect &r, bool hover,
0271                        bool sunken, const QColor *cols) const;
0272     void drawMdiIcon(QPainter *painter, const QColor &color, const QColor &bgnd,
0273                      const QRect &r, bool hover, bool sunken, Icon iclearcon,
0274                      bool stdSize, bool drewFrame) const;
0275     void drawIcon(QPainter *painter, const QColor &color, const QRect &r,
0276                   bool sunken, Icon icon, bool stdSize=true) const;
0277     void drawEntryField(QPainter *p, const QRect &rx, const QWidget *widget,
0278                         const QStyleOption *option, int round,
0279                         bool fill, bool doEtch, EWidget w=WIDGET_ENTRY) const;
0280     void drawMenuItem(QPainter *p, const QRect &r, const QStyleOption *option,
0281                       MenuItemType type, int round, const QColor *cols) const;
0282     void drawProgress(QPainter *p, const QRect &r, const QStyleOption *option,
0283                       bool vertical=false, bool reverse=false) const;
0284     void drawArrow(QPainter *p, const QRect &rx, PrimitiveElement pe,
0285                    QColor col, bool small=false, bool kwin=false) const;
0286     void drawSbSliderHandle(QPainter *p, const QRect &r,
0287                             const QStyleOption *option,
0288                             bool slider=false) const;
0289     void drawSliderHandle(QPainter *p, const QRect &r,
0290                           const QStyleOptionSlider *option) const;
0291     void drawSliderGroove(QPainter *p, const QRect &groove, const QRect &handle,
0292                           const QStyleOptionSlider *slider,
0293                           const QWidget *widget) const;
0294     void drawMenuOrToolBarBackground(const QWidget *widget, QPainter *p,
0295                                      const QRect &r, const QStyleOption *option,
0296                                      bool menu=true, bool horiz=true) const;
0297     void drawHandleMarkers(QPainter *p, const QRect &r,
0298                            const QStyleOption *option, bool tb,
0299                            ELine handles) const;
0300     void fillTab(QPainter *p, const QRect &r, const QStyleOption *option,
0301                  const QColor &fill, bool horiz, EWidget tab,
0302                  bool tabOnly) const;
0303     void colorTab(QPainter *p, const QRect &r, bool horiz,
0304                   EWidget tab, int round) const;
0305     void shadeColors(const QColor &base, QColor *vals) const;
0306     const QColor *buttonColors(const QStyleOption *option) const;
0307     QColor titlebarIconColor(const QStyleOption *option) const;
0308     const QColor *popupMenuCols(const QStyleOption *option=0L) const;
0309     const QColor *checkRadioColors(const QStyleOption *option) const;
0310     const QColor *sliderColors(const QStyleOption *option) const;
0311     const QColor *backgroundColors(const QColor &col) const;
0312     const QColor*
0313     backgroundColors(const QStyleOption *option) const
0314     {
0315         return (option ?
0316                 backgroundColors(option->palette.background().color()) :
0317                 m_backgroundCols);
0318     }
0319     const QColor *highlightColors(const QColor &col) const;
0320     const QColor*
0321     highlightColors(const QStyleOption *option, bool useActive) const
0322     {
0323         return highlightColors(
0324             option->palette.brush(useActive ? QPalette::Active :
0325                                   QPalette::Current,
0326                                   QPalette::Highlight).color());
0327     }
0328     const QColor *borderColors(const QStyleOption *option,
0329                                const QColor *use) const;
0330     const QColor *getSidebarButtons() const;
0331     void setMenuColors(const QColor &bgnd);
0332     void setMenuTextColors(QWidget *widget, bool isMenuBar) const;
0333     const QColor *menuColors(const QStyleOption *option, bool active) const;
0334     bool coloredMdiButtons(bool active, bool mouseOver) const;
0335     const QColor *getMdiColors(const QStyleOption *option, bool active) const;
0336     void readMdiPositions() const;
0337     const QColor &getFill(const QStyleOption *option, const QColor *use,
0338                           bool cr=false, bool darker=false) const;
0339     const QColor &getTabFill(bool current, bool highlight,
0340                              const QColor *use) const;
0341     QColor menuStripeCol() const;
0342     QPixmap *getPixmap(const QColor col, EPixmap p, double shade=1.0) const;
0343     const QColor &checkRadioCol(const QStyleOption *opt) const;
0344     QColor shade(const QColor &a, double k) const;
0345     void shade(const QColor &ca, QColor *cb, double k) const;
0346     QColor getLowerEtchCol(const QWidget *widget) const;
0347     int getFrameRound(const QWidget *widget) const;
0348 
0349 private Q_SLOTS:
0350     void widgetDestroyed(QObject *o);
0351     int layoutSpacingImplementation(
0352         QSizePolicy::ControlType control1, QSizePolicy::ControlType control2,
0353         Qt::Orientation orientation, const QStyleOption *option=0,
0354         const QWidget *widget=0) const;
0355     QIcon standardIconImplementation(
0356         StandardPixmap pix, const QStyleOption *option=0,
0357         const QWidget *widget=0) const;
0358     void kdeGlobalSettingsChange(int type, int);
0359     void borderSizesChanged();
0360     void toggleMenuBar(unsigned int xid);
0361     void toggleStatusBar(unsigned int xid);
0362     void compositingToggled();
0363 
0364 private:
0365     void toggleMenuBar(QMainWindow *window);
0366     void toggleStatusBar(QMainWindow *window);
0367 
0368 #ifdef QTC_QT4_ENABLE_KDE
0369     void setupKde4();
0370     void setDecorationColors();
0371     void applyKdeSettings(bool pal);
0372 #endif
0373     bool isWindowDragWidget(QObject *o);
0374     void emitMenuSize(QWidget *w, unsigned short size, bool force=false);
0375     void emitStatusBarState(QStatusBar *sb);
0376     const QColor&
0377     MOArrow(QFlags<State> state, const QPalette &palette, bool mo,
0378             QPalette::ColorRole rol) const
0379     {
0380         if (!(state & State_Enabled)) {
0381             return palette.color(QPalette::Disabled, rol);
0382         } else if (opts.coloredMouseOver != MO_NONE && mo) {
0383             return m_mouseOverCols[ARROW_MO_SHADE];
0384         } else {
0385             return palette.color(rol);
0386         }
0387     }
0388     const QColor&
0389     MOArrow(QFlags<State> state, const QPalette &palette,
0390             QPalette::ColorRole rol) const
0391     {
0392         return MOArrow(state, palette, state & State_MouseOver, rol);
0393     }
0394     QDBusInterface*
0395     getKWinDBus()
0396     {
0397         if (qtcUnlikely(!m_dBus)) {
0398             m_dBus = new QDBusInterface("org.kde.kwin", "/QtCurve",
0399                                         "org.kde.QtCurve");
0400         }
0401         return m_dBus;
0402     }
0403 
0404 private:
0405     mutable Options opts;
0406     QColor m_highlightCols[TOTAL_SHADES + 1],
0407         m_backgroundCols[TOTAL_SHADES + 1],
0408         m_menubarCols[TOTAL_SHADES + 1],
0409         m_focusCols[TOTAL_SHADES + 1],
0410         m_mouseOverCols[TOTAL_SHADES + 1],
0411         *m_popupMenuCols,
0412         *m_sliderCols,
0413         *m_defBtnCols,
0414         *m_comboBtnCols,
0415         *m_checkRadioSelCols,
0416         *m_sortedLvColors,
0417         *m_ooMenuCols,
0418         *m_progressCols,
0419         m_buttonCols[TOTAL_SHADES + 1],
0420         m_checkRadioCol;
0421     bool m_saveMenuBarStatus,
0422         m_saveStatusBarStatus,
0423         m_usePixmapCache,
0424         m_inactiveChangeSelectionColor;
0425     PreviewType m_isPreview;
0426     mutable QColor *m_sidebarButtonsCols;
0427     mutable QColor *m_activeMdiColors;
0428     mutable QColor *m_mdiColors;
0429     mutable QColor m_activeMdiTextColor;
0430     mutable QColor m_mdiTextColor;
0431     mutable QColor m_coloredButtonCols[TOTAL_SHADES + 1];
0432     mutable QColor m_coloredBackgroundCols[TOTAL_SHADES + 1];
0433     mutable QColor m_coloredHighlightCols[TOTAL_SHADES + 1];
0434     mutable QCache<QtcKey, QPixmap> m_pixmapCache;
0435     mutable bool m_active;
0436     mutable const QWidget *m_sbWidget;
0437     mutable QLabel *m_clickedLabel;
0438     QSet<QProgressBar*> m_progressBars;
0439     mutable int m_progressBarAnimateTimer,
0440         m_progressBarAnimateFps,
0441         m_animateStep;
0442     mutable QTime m_timer;
0443     mutable QMap<int, QColor*> m_titleBarButtonsCols;
0444     mutable QList<int> m_mdiButtons[2]; // 0=left, 1=right
0445     mutable int m_titlebarHeight;
0446 
0447     // Required for Q3Header hover...
0448     QPoint m_pos;
0449     QWidget *m_hoverWidget;
0450     QDBusInterface *m_dBus;
0451     ShadowHelper *m_shadowHelper;
0452     mutable QScrollBar *m_sViewSBar;
0453     mutable QMap<QWidget*, QSet<QWidget*> > m_sViewContainers;
0454 #ifdef QTC_QT4_ENABLE_KDE
0455     KComponentData m_componentData;
0456 #endif
0457     WindowManager *m_windowManager;
0458     BlurHelper *m_blurHelper;
0459     ShortcutHandler *m_shortcutHandler;
0460 #ifdef QTC_QT4_STYLE_SUPPORT
0461     QString m_name;
0462 #endif
0463 };
0464 }
0465 
0466 #endif