File indexing completed on 2024-04-28 05:47:24

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_P_H__
0024 #define __QTCURVE_P_H__
0025 
0026 #include <qtcurve-utils/log.h>
0027 #include <qtcurve-utils/qtutils.h>
0028 #include "qtcurve.h"
0029 #include <QPainter>
0030 #include <QPushButton>
0031 #include <QToolButton>
0032 #include <QWidget>
0033 #include <QSplitter>
0034 #include <QStatusBar>
0035 #ifdef QTC_QT5_ENABLE_KDE
0036 #include <kiconeffect.h>
0037 #endif
0038 
0039 class QToolBar;
0040 
0041 namespace QtCurve {
0042 
0043 extern QString appName;
0044 static const int constMenuPixmapWidth = 22;
0045 static const int constWindowMargin = 2;
0046 static const int constProgressBarFps = 20;
0047 static const int constTabPad = 6;
0048 
0049 static const QLatin1String constDwtClose("qt_dockwidget_closebutton");
0050 static const QLatin1String constDwtFloat("qt_dockwidget_floatbutton");
0051 
0052 // WebKit seems to just use the values from ::pixelMetric to get button sizes.
0053 // So, in pixelMetric we add some extra padding to PM_ButtonMargin
0054 // if we're max rounding - this gives a nicer border. However, dont want
0055 // this on real buttons - so in sizeFromContents we remove this padding
0056 // in CT_PushButton and CT_ComboBox
0057 #define MAX_ROUND_BTN_PAD (ROUND_MAX==opts.round ? 3 : 0)
0058 
0059 #define SB_SUB2 ((QStyle::SubControl)(QStyle::SC_ScrollBarGroove << 1))
0060 
0061 #define WINDOWTITLE_SPACER 0x10000000
0062 #define STATE_REVERSE QStyle::StateFlag(0x10000000)
0063 #define STATE_MENU QStyle::StateFlag(0x20000000)
0064 #define STATE_VIEW QStyle::StateFlag(0x40000000)
0065 #define STATE_KWIN_BUTTON QStyle::StateFlag(0x40000000)
0066 #define STATE_TBAR_BUTTON QStyle::StateFlag(0x80000000)
0067 #define STATE_DWT_BUTTON QStyle::StateFlag(0x20000000)
0068 #define STATE_TOGGLE_BUTTON QStyle::StateFlag(0x10000000)
0069 
0070 #define PIXMAP_DIMENSION 10
0071 
0072 // TODO! REMOVE THIS WHEN KDE'S ICON SETTINGS ACTUALLY WORK!!!
0073 #define FIX_DISABLED_ICONS
0074 
0075 typedef enum {
0076     APP_PLASMA,
0077     APP_KRUNNER,
0078     APP_KWIN,
0079     APP_SYSTEMSETTINGS,
0080     APP_KONTACT,
0081     APP_ARORA,
0082     APP_REKONQ,
0083     APP_QTCREATOR,
0084     APP_KDEVELOP,
0085     APP_K3B,
0086     APP_OPENOFFICE,
0087     APP_OTHER
0088 } QtcThemedApp;
0089 
0090 typedef enum {
0091     windowsItemFrame      =  2, // menu item frame width
0092     windowsSepHeight      =  9, // separator item height
0093     windowsItemHMargin    =  3, // menu item hor text margin
0094     windowsItemVMargin    =  2, // menu item ver text margin
0095     windowsRightBorder    = 15, // right border on windows
0096     windowsCheckMarkWidth = 12, // checkmarks width on windows
0097     windowsArrowHMargin   =  6  // arrow horizontal margin
0098 } WindowsStyleConsts;
0099 
0100 extern QtcThemedApp theThemedApp;
0101 
0102 static inline bool
0103 isOOWidget(const QWidget *widget)
0104 {
0105     return APP_OPENOFFICE == theThemedApp && !widget;
0106 }
0107 
0108 bool blendOOMenuHighlight(const QPalette &pal, const QColor &highlight);
0109 bool isNoEtchWidget(const QWidget *widget);
0110 
0111 void setOpacityProp(QWidget *w, unsigned short opacity);
0112 void setBgndProp(QWidget *w, EAppearance app, bool haveBgndImage);
0113 void setSbProp(QWidget *w);
0114 
0115 static inline QList<QStatusBar*>
0116 getStatusBars(QWidget *w)
0117 {
0118     return w ? w->findChildren<QStatusBar*>() : QList<QStatusBar*>();
0119 }
0120 #if defined FIX_DISABLED_ICONS && defined QTC_QT5_ENABLE_KDE
0121 static inline QPixmap
0122 getIconPixmap(const QIcon &icon, const QSize &size,
0123               QIcon::Mode mode, QIcon::State)
0124 {
0125     QPixmap pix=icon.pixmap(size, QIcon::Normal);
0126 
0127     if (QIcon::Disabled == mode) {
0128         QImage img = pix.toImage();
0129         KIconEffect::toGray(img, 1.0);
0130         KIconEffect::semiTransparent(img);
0131         pix = QPixmap::fromImage(img);
0132     }
0133     return pix;
0134 }
0135 #else
0136 static inline QPixmap
0137 getIconPixmap(const QIcon &icon, const QSize &size, QIcon::Mode mode,
0138               QIcon::State state=QIcon::Off)
0139 {
0140     return icon.pixmap(size, mode, state);
0141 }
0142 #endif
0143 
0144 static inline QPixmap
0145 getIconPixmap(const QIcon &icon, int size, QIcon::Mode mode,
0146               QIcon::State state=QIcon::Off)
0147 {
0148     return getIconPixmap(icon, QSize(size, size), mode, state);
0149 }
0150 
0151 static inline QPixmap
0152 getIconPixmap(const QIcon &icon, int size, int flags,
0153               QIcon::State state=QIcon::Off)
0154 {
0155     return getIconPixmap(icon, QSize(size, size),
0156                          flags & QStyle::State_Enabled ? QIcon::Normal :
0157                          QIcon::Disabled, state);
0158 }
0159 
0160 static inline QPixmap
0161 getIconPixmap(const QIcon &icon, const QSize &size, int flags,
0162               QIcon::State state=QIcon::Off)
0163 {
0164     return getIconPixmap(icon, size, flags & QStyle::State_Enabled ?
0165                          QIcon::Normal : QIcon::Disabled, state);
0166 }
0167 
0168 static inline void
0169 drawRect(QPainter *p, const QRect &r)
0170 {
0171     p->drawRect(r.x(), r.y(), r.width()-1, r.height()-1);
0172 }
0173 
0174 static inline void
0175 drawAaLine(QPainter *p, int x1, int y1, int x2, int y2)
0176 {
0177     p->drawLine(QLineF(x1 + 0.5, y1 + 0.5, x2 + 0.5, y2 + 0.5));
0178 }
0179 
0180 static inline void
0181 drawAaPoint(QPainter *p, int x, int y)
0182 {
0183     p->drawPoint(QPointF(x + 0.5, y + 0.5));
0184 }
0185 
0186 static inline void
0187 drawAaRect(QPainter *p, const QRect &r)
0188 {
0189     p->drawRect(QRectF(r.x()+0.5, r.y()+0.5, r.width()-1, r.height()-1));
0190 }
0191 
0192 static inline bool
0193 isMultiTabBarTab(const QAbstractButton *button)
0194 {
0195     // Check for isFlat fails in KDE SC4.5
0196     return button && ((qobject_cast<const QPushButton*>(button) &&
0197                        // ((QPushButton *)button)->isFlat() &&
0198                        button->inherits("KMultiTabBarTab")) ||
0199                       (APP_KDEVELOP == theThemedApp &&
0200                        qobject_cast<const QToolButton*>(button) &&
0201                        button->inherits("Sublime::IdealToolButton")));
0202 }
0203 
0204 static inline int
0205 toHint(int sc)
0206 {
0207     switch (sc) {
0208     case QStyle::SC_TitleBarSysMenu:
0209         return Qt::WindowSystemMenuHint;
0210     case QStyle::SC_TitleBarMinButton:
0211         return Qt::WindowMinimizeButtonHint;
0212     case QStyle::SC_TitleBarMaxButton:
0213         return Qt::WindowMaximizeButtonHint;
0214     case QStyle::SC_TitleBarCloseButton:
0215         return 0;
0216     case QStyle::SC_TitleBarNormalButton:
0217         return 0;
0218     case QStyle::SC_TitleBarShadeButton:
0219     case QStyle::SC_TitleBarUnshadeButton:
0220         return Qt::WindowShadeButtonHint;
0221     case QStyle::SC_TitleBarContextHelpButton:
0222         return Qt::WindowContextHelpButtonHint;
0223     default:
0224         return 0;
0225     }
0226 }
0227 
0228 QWidget *scrollViewFrame(QWidget *widget);
0229 
0230 class QtCurveDockWidgetTitleBar: public QWidget {
0231     Q_OBJECT
0232 public:
0233     QtCurveDockWidgetTitleBar(QWidget* parent) : QWidget(parent) {}
0234     QSize sizeHint() const override
0235     {
0236         return QSize(0, 0);
0237     }
0238 };
0239 
0240 QToolBar *getToolBarChild(QWidget *w);
0241 void setStyleRecursive(QWidget *w, QStyle *s, int minSize);
0242 bool updateMenuBarEvent(QMouseEvent *event, QMenuBar *menu);
0243 QRegion windowMask(const QRect &r, bool full);
0244 const QWidget *getWidget(const QPainter *p);
0245 const QImage *getImage(const QPainter *p);
0246 const QAbstractButton *getButton(const QWidget *w, const QPainter *p);
0247 
0248 static inline bool
0249 isKateView(const QWidget *widget)
0250 {
0251     return (qtcCheckType<QFrame>(widget) &&
0252             qtcCheckType(getParent(widget), "KateView"));
0253 }
0254 
0255 static inline bool
0256 isKontactPreviewPane(const QWidget *widget)
0257 {
0258     return (theThemedApp == APP_KONTACT &&
0259             qtcCheckType(widget, "KHBox") &&
0260             qtcCheckType<QSplitter>(getParent(widget)) &&
0261             qtcCheckType(getParent<2>(widget), "KMReaderWin"));
0262 }
0263 
0264 static inline QColor
0265 blendColors(const QColor &foreground, const QColor &background, double alpha)
0266 {
0267 #ifndef QTC_QT5_ENABLE_KDE
0268     return qtcColorMix(&background, &foreground, alpha);
0269 #else
0270     return KColorUtils::mix(background, foreground, alpha);
0271 #endif
0272 }
0273 
0274 void drawDots(QPainter *p, const QRect &r, bool horiz, int nLines, int offset,
0275               const QColor *cols, int startOffset, int dark);
0276 bool isInQAbstractItemView(const QObject *w);
0277 const QToolBar *getToolBar(const QWidget *w);
0278 void drawTbArrow(const QStyle *style, const QStyleOptionToolButton *toolbutton,
0279                  const QRect &rect, QPainter *painter, const QWidget *widget=0);
0280 void adjustToolbarButtons(const QWidget *widget, const QToolBar *toolbar,
0281                           int &leftAdjust, int &topAdjust, int &rightAdjust,
0282                           int &bottomAdjust, int &round);
0283 bool isA(const QObject *w, const char *type);
0284 
0285 }
0286 
0287 // **** experiments (deactivated) to hunt down the cause of the issues drawing round(ed) objects in Qt5 **** //
0288 
0289 // It has been suggested to me that Qt5 might not observe AA settings when drawing lines with width 1 (exact);
0290 // the effect of using widths slightly different from 1 can be tested by setting QPENWIDTH1 to a sligtly
0291 // different value (e.g. #define QPENWIDTH1 1.01)
0292 #define QPENWIDTH1  1
0293 
0294 // Macros that allow leaving antialiasing on everywhere instead of turning it off in certain locations when
0295 // #define QPAINTER_ANTIALIAS_MAYBE_ON true
0296 #define QPAINTER_ANTIALIAS_MAYBE_ON false
0297 #define QPAINTER_RENDERHINT_AA_MAYBE_OFF(p) \
0298     if(!QPAINTER_ANTIALIAS_MAYBE_ON) { (p)->setRenderHint(QPainter::Antialiasing, QPAINTER_ANTIALIAS_MAYBE_ON); }
0299 
0300 #endif