File indexing completed on 2024-05-05 10:10:09
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