File indexing completed on 2024-04-28 05:47:19
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 #include "qtcurve_p.h" 0024 #include "qtcurve_plugin.h" 0025 #include "qtcurve_fonthelper.h" 0026 #include <qtcurve-utils/qtprops.h> 0027 0028 #include <qglobal.h> 0029 #include <QDBusConnection> 0030 #include <QDBusInterface> 0031 #include "windowmanager.h" 0032 #include "blurhelper.h" 0033 #include "shortcuthandler.h" 0034 #include <common/config_file.h> 0035 #include "check_on-png.h" 0036 #include "check_x_on-png.h" 0037 0038 #ifndef QTC_QT5_ENABLE_KDE 0039 # include "dialog_error-png.h" 0040 # include "dialog_warning-png.h" 0041 # include "dialog_information-png.h" 0042 #endif 0043 0044 #include <QFormLayout> 0045 #include <QAbstractItemView> 0046 #include <QDialog> 0047 #include <QSplitter> 0048 #include <QMdiSubWindow> 0049 #include <QMainWindow> 0050 #include <QComboBox> 0051 #include <QTreeView> 0052 #include <QGroupBox> 0053 #include <QListView> 0054 #include <QCheckBox> 0055 #include <QRadioButton> 0056 #include <QTextEdit> 0057 #include <QDial> 0058 #include <QLabel> 0059 #include <QStackedLayout> 0060 #include <QMenuBar> 0061 #include <QMouseEvent> 0062 #include <QScrollBar> 0063 #include <QWizard> 0064 #include <QDialogButtonBox> 0065 #include <QHeaderView> 0066 #include <QLineEdit> 0067 #include <QSpinBox> 0068 #include <QDir> 0069 #include <QSettings> 0070 #include <QPixmapCache> 0071 #include <QTextStream> 0072 #include <QtDebug> 0073 0074 #include "shadowhelper.h" 0075 #include <qtcurve-utils/x11qtc.h> 0076 #include <sys/time.h> 0077 0078 #ifdef QTC_QT5_ENABLE_KDE 0079 #include <KConfigCore/KSharedConfig> 0080 #include <KWindowSystem/KWindowSystem> 0081 #include <KConfigWidgets/KColorScheme> 0082 #include <KConfigWidgets/KStandardAction> 0083 #include <KXmlGui/KActionCollection> 0084 #include <KXmlGui/KXmlGuiWindow> 0085 #endif 0086 0087 #include <qtcurve-utils/color.h> 0088 0089 namespace QtCurve { 0090 0091 class Style::DBusHelper { 0092 public: 0093 DBusHelper() 0094 : m_dBus(0) 0095 , m_dbusConnected(false) 0096 {} 0097 ~DBusHelper() 0098 { 0099 if (m_dBus) { 0100 m_dBus->disconnect(); 0101 m_dBus->deleteLater(); 0102 m_dBus = 0; 0103 } 0104 } 0105 0106 std::once_flag m_aboutToQuitInit; 0107 QDBusInterface *m_dBus; 0108 bool m_dbusConnected; 0109 }; 0110 0111 static inline void setPainterPen(QPainter *p, const QColor &col, const qreal width=1.0) 0112 { 0113 p->setPen(QPen(col, width)); 0114 } 0115 0116 static Style::Icon 0117 pix2Icon(QStyle::StandardPixmap pix) 0118 { 0119 switch (pix) { 0120 case QStyle::SP_TitleBarNormalButton: 0121 return Style::ICN_RESTORE; 0122 case QStyle::SP_TitleBarShadeButton: 0123 return Style::ICN_SHADE; 0124 case QStyle::SP_ToolBarHorizontalExtensionButton: 0125 return Style::ICN_RIGHT; 0126 case QStyle::SP_ToolBarVerticalExtensionButton: 0127 return Style::ICN_DOWN; 0128 case QStyle::SP_TitleBarUnshadeButton: 0129 return Style::ICN_UNSHADE; 0130 default: 0131 case QStyle::SP_DockWidgetCloseButton: 0132 case QStyle::SP_TitleBarCloseButton: 0133 return Style::ICN_CLOSE; 0134 } 0135 } 0136 0137 static Style::Icon 0138 subControlToIcon(QStyle::SubControl sc) 0139 { 0140 switch (sc) { 0141 case QStyle::SC_TitleBarMinButton: 0142 return Style::ICN_MIN; 0143 case QStyle::SC_TitleBarMaxButton: 0144 return Style::ICN_MAX; 0145 case QStyle::SC_TitleBarCloseButton: 0146 default: 0147 return Style::ICN_CLOSE; 0148 case QStyle::SC_TitleBarNormalButton: 0149 return Style::ICN_RESTORE; 0150 case QStyle::SC_TitleBarShadeButton: 0151 return Style::ICN_SHADE; 0152 case QStyle::SC_TitleBarUnshadeButton: 0153 return Style::ICN_UNSHADE; 0154 case QStyle::SC_TitleBarSysMenu: 0155 return Style::ICN_MENU; 0156 } 0157 } 0158 0159 QtcThemedApp theThemedApp = APP_OTHER; 0160 0161 // do not initialise the variable here by calling qApp->arguments(). Normally it will 0162 // be safe when we're loaded as a style plugin in a Qt application (which happens during 0163 // the Q*Application initialisation phase so the qApp instance exists). However, when 0164 // we're loaded in a different context this can happen: 0165 // `QCoreApplication::arguments: Please instantiate the QApplication object first` 0166 // `Segmentation fault` 0167 QString appName; 0168 0169 static QColor 0170 checkColour(const QStyleOption *option, QPalette::ColorRole role) 0171 { 0172 QColor col(option->palette.brush(role).color()); 0173 0174 if (col.alpha() == 255 && isBlack(col)) 0175 return QApplication::palette().brush(role).color(); 0176 return col; 0177 } 0178 0179 static void 0180 addStripes(QPainter *p, const QPainterPath &path, 0181 const QRect &rect, bool horizontal) 0182 { 0183 QColor col(Qt::white); 0184 QLinearGradient patternGradient(rect.topLeft(), 0185 rect.topLeft() + 0186 (horizontal ? QPoint(STRIPE_WIDTH, 0) : 0187 QPoint(0, STRIPE_WIDTH))); 0188 0189 col.setAlphaF(0.0); 0190 patternGradient.setColorAt(0.0, col); 0191 col.setAlphaF(0.15); 0192 patternGradient.setColorAt(1.0, col); 0193 patternGradient.setSpread(QGradient::ReflectSpread); 0194 if (path.isEmpty()) { 0195 p->fillRect(rect, patternGradient); 0196 } else { 0197 p->save(); 0198 p->setRenderHint(QPainter::Antialiasing, true); 0199 p->fillPath(path, patternGradient); 0200 p->restore(); 0201 } 0202 } 0203 0204 #ifndef QTC_QT5_ENABLE_KDE 0205 static void 0206 setRgb(QColor *col, const QStringList &rgb) 0207 { 0208 if (rgb.size() == 3) { 0209 *col = QColor(rgb[0].toInt(), rgb[1].toInt(), rgb[2].toInt()); 0210 } 0211 } 0212 0213 static QString 0214 kdeHome() 0215 { 0216 static QString kdeHomePath; 0217 if (kdeHomePath.isEmpty()) { 0218 kdeHomePath = QString::fromLocal8Bit(qgetenv("KDEHOME")); 0219 if (kdeHomePath.isEmpty()) { 0220 QDir homeDir(QDir::homePath()); 0221 QString kdeConfDir(QLatin1String("/.kde")); 0222 if (homeDir.exists(QLatin1String(".kde4"))) 0223 kdeConfDir = QLatin1String("/.kde4"); 0224 kdeHomePath = QDir::homePath() + kdeConfDir; 0225 } 0226 } 0227 return kdeHomePath; 0228 } 0229 #endif 0230 0231 static bool 0232 isHoriz(const QStyleOption *option, EWidget w, bool joinedTBar) 0233 { 0234 return (option->state & QStyle::State_Horizontal || 0235 (WIDGET_BUTTON(w) && 0236 (!joinedTBar || noneOf(w, WIDGET_TOOLBAR_BUTTON, 0237 WIDGET_NO_ETCH_BTN, 0238 WIDGET_MENU_BUTTON)))); 0239 } 0240 0241 static bool 0242 isOnToolbar(const QWidget *widget) 0243 { 0244 const QWidget *wid = widget ? widget->parentWidget() : 0L; 0245 while (wid) { 0246 if (qobject_cast<const QToolBar*>(wid)) { 0247 return true; 0248 } 0249 wid = wid->parentWidget(); 0250 } 0251 return false; 0252 } 0253 0254 /* 0255 Cache key: 0256 widgettype 2 0257 app 5 0258 size 15 0259 horiz 1 0260 alpha 8 0261 blue 8 0262 green 8 0263 red 8 0264 type 1 (0 for widget, 1 for pixmap) 0265 ------------ 0266 56 0267 */ 0268 enum ECacheType { 0269 CACHE_STD, 0270 CACHE_PBAR, 0271 CACHE_TAB_TOP, 0272 CACHE_TAB_BOT 0273 }; 0274 0275 static QtcKey 0276 createKey(qulonglong size, const QColor &color, bool horiz, int app, EWidget w) 0277 { 0278 ECacheType type=WIDGET_TAB_TOP==w 0279 ? CACHE_TAB_TOP 0280 : WIDGET_TAB_BOT==w 0281 ? CACHE_TAB_BOT 0282 : WIDGET_PROGRESSBAR==w 0283 ? CACHE_PBAR 0284 : CACHE_STD; 0285 0286 return (color.rgba()<<1)+ 0287 (((qulonglong)(horiz ? 1 : 0))<<33)+ 0288 (((qulonglong)(size&0xFFFF))<<34)+ 0289 (((qulonglong)(app&0x1F))<<50)+ 0290 (((qulonglong)(type&0x03))<<55); 0291 } 0292 0293 static QtcKey createKey(const QColor &color, EPixmap p) 0294 { 0295 return 1 + 0296 ((color.rgb()&RGB_MASK)<<1)+ 0297 (((qulonglong)(p&0x1F))<<33)+ 0298 (((qulonglong)1)<<38); 0299 } 0300 0301 #ifdef QTC_QT5_ENABLE_KDE 0302 static void parseWindowLine(const QString &line, QList<int> &data) 0303 { 0304 int len(line.length()); 0305 0306 for(int i = 0;i < len;++i) { 0307 switch(line[i].toLatin1()) { 0308 case 'M': 0309 data.append(QStyle::SC_TitleBarSysMenu); 0310 break; 0311 case '_': 0312 data.append(WINDOWTITLE_SPACER); 0313 break; 0314 case 'H': 0315 data.append(QStyle::SC_TitleBarContextHelpButton); 0316 break; 0317 case 'L': 0318 data.append(QStyle::SC_TitleBarShadeButton); 0319 break; 0320 case 'I': 0321 data.append(QStyle::SC_TitleBarMinButton); 0322 break; 0323 case 'A': 0324 data.append(QStyle::SC_TitleBarMaxButton); 0325 break; 0326 case 'X': 0327 data.append(QStyle::SC_TitleBarCloseButton); 0328 default: 0329 break; 0330 } 0331 } 0332 } 0333 #endif 0334 0335 Style::Style() : 0336 m_dBusHelper(new DBusHelper()), 0337 m_fntHelper(new FontHelper()), 0338 m_popupMenuCols(0L), 0339 m_sliderCols(0L), 0340 m_defBtnCols(0L), 0341 m_comboBtnCols(0L), 0342 m_checkRadioSelCols(0L), 0343 m_sortedLvColors(0L), 0344 m_ooMenuCols(0L), 0345 m_progressCols(0L), 0346 m_saveMenuBarStatus(false), 0347 m_usePixmapCache(true), 0348 m_inactiveChangeSelectionColor(false), 0349 m_isPreview(PREVIEW_FALSE), 0350 m_sidebarButtonsCols(0L), 0351 m_activeMdiColors(0L), 0352 m_mdiColors(0L), 0353 m_pixmapCache(150000), 0354 m_active(true), 0355 m_sbWidget(0L), 0356 m_clickedLabel(0L), 0357 m_progressBarAnimateTimer(0), 0358 m_animateStep(0), 0359 m_titlebarHeight(0), 0360 m_shadowHelper(new ShadowHelper(this)), 0361 m_sViewSBar(0L), 0362 m_windowManager(new WindowManager(this)), 0363 m_blurHelper(new BlurHelper(this)), 0364 m_shortcutHandler(new ShortcutHandler(this)) 0365 { 0366 const char *env = getenv(QTCURVE_PREVIEW_CONFIG); 0367 #ifdef QTC_QT5_ENABLE_KDE 0368 m_configFile = KSharedConfig::openConfig(); 0369 m_kdeGlobals = KSharedConfig::openConfig(QStringLiteral("kdeglobals"), KConfig::NoGlobals); 0370 #endif 0371 if (env && strcmp(env, QTCURVE_PREVIEW_CONFIG) == 0) { 0372 // To enable preview of QtCurve settings, the style config module will set QTCURVE_PREVIEW_CONFIG 0373 // and use CE_QtC_SetOptions to set options. If this is set, we do not use the QPixmapCache as it 0374 // will interfere with that of the kcm's widgets! 0375 m_isPreview=PREVIEW_MDI; 0376 m_usePixmapCache=false; 0377 } else if(env && strcmp(env, QTCURVE_PREVIEW_CONFIG_FULL) == 0) { 0378 // As above, but preview is in window - so can use opacity settings! 0379 m_isPreview=PREVIEW_WINDOW; 0380 m_usePixmapCache=false; 0381 } else { 0382 init(true); 0383 } 0384 } 0385 0386 void Style::init(bool initial) 0387 { 0388 if(!initial) 0389 freeColors(); 0390 0391 if (m_isPreview) { 0392 if (m_isPreview != PREVIEW_WINDOW) { 0393 opts.bgndOpacity = opts.dlgOpacity = opts.menuBgndOpacity = 100; 0394 } 0395 } else { 0396 qtcReadConfig(QString(), &opts); 0397 0398 if (initial) { 0399 if (QCoreApplication::instance()) { 0400 // we can obtain the application name safely. 0401 appName = QFileInfo(QCoreApplication::instance()->arguments()[0]).fileName(); 0402 } 0403 #ifdef Q_OS_MACOS 0404 if (opts.nonnativeMenubarApps.contains("kde") || opts.nonnativeMenubarApps.contains(appName)) { 0405 QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuBar); 0406 opts.currentNonnativeMenubarApps << appName; 0407 } 0408 #endif 0409 connectDBus(); 0410 #ifdef QTC_QT5_ENABLE_KDE 0411 connect(KWindowSystem::self(), &KWindowSystem::compositingChanged, this, &Style::compositingToggled); 0412 #endif 0413 // prepare the cleanup handler 0414 if (QCoreApplication::instance()) { 0415 std::call_once(m_dBusHelper->m_aboutToQuitInit, [this] { 0416 connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, [this] () { 0417 // disconnect from the session DBus. We're no longer interested in the 0418 // information it might send when the app we're serving is shutting down. 0419 disconnectDBus(); 0420 // Stop listening to select signals. We shouldn't stop emitting signals 0421 // (like QObject::destroyed) but we can reduce the likelihood that pending 0422 // signals will be sent to us post-mortem. 0423 #ifdef QTC_QT5_ENABLE_KDE 0424 disconnect(KWindowSystem::self(), &KWindowSystem::compositingChanged, 0425 this, &Style::compositingToggled); 0426 #endif 0427 } ); 0428 } ); 0429 } 0430 } 0431 } 0432 0433 opts.contrast=QSettings(QLatin1String("Trolltech")).value("/Qt/KDE/contrast", DEFAULT_CONTRAST).toInt(); 0434 if(opts.contrast<0 || opts.contrast>10) 0435 opts.contrast=DEFAULT_CONTRAST; 0436 0437 shadeColors(QApplication::palette().color(QPalette::Active, QPalette::Highlight), m_highlightCols); 0438 shadeColors(QApplication::palette().color(QPalette::Active, QPalette::Background), m_backgroundCols); 0439 shadeColors(QApplication::palette().color(QPalette::Active, QPalette::Button), m_buttonCols); 0440 0441 // Set defaults for Hover and Focus, these will be changed when KDE4 palette is applied... 0442 shadeColors(QApplication::palette().color(QPalette::Active, 0443 QPalette::Highlight), m_focusCols); 0444 shadeColors(QApplication::palette().color(QPalette::Active, QPalette::Highlight), m_mouseOverCols); 0445 // Dont setup KDE4 fonts/colours here - seems to mess things up when using proxy styles. 0446 // See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=638629 0447 //#ifdef QTC_QT5_ENABLE_KDE 0448 // setupKde4(); 0449 //#endif 0450 0451 m_windowManager->initialize(opts.windowDrag, opts.windowDragWhiteList.values(), opts.windowDragBlackList.values()); 0452 0453 switch(opts.shadeSliders) 0454 { 0455 default: 0456 case SHADE_DARKEN: 0457 case SHADE_NONE: 0458 break; 0459 case SHADE_SELECTED: 0460 m_sliderCols=m_highlightCols; 0461 break; 0462 case SHADE_BLEND_SELECTED: 0463 case SHADE_CUSTOM: 0464 if (!m_sliderCols) { 0465 m_sliderCols = new QColor[TOTAL_SHADES + 1]; 0466 } 0467 shadeColors(opts.shadeSliders == SHADE_BLEND_SELECTED ? 0468 midColor(m_highlightCols[ORIGINAL_SHADE], 0469 m_buttonCols[ORIGINAL_SHADE]) : 0470 opts.customSlidersColor, m_sliderCols); 0471 } 0472 0473 switch(opts.defBtnIndicator) 0474 { 0475 case IND_GLOW: 0476 case IND_SELECTED: 0477 m_defBtnCols=m_highlightCols; 0478 break; 0479 case IND_TINT: 0480 m_defBtnCols=new QColor [TOTAL_SHADES+1]; 0481 shadeColors(tint(m_buttonCols[ORIGINAL_SHADE], 0482 m_highlightCols[ORIGINAL_SHADE], DEF_BNT_TINT), 0483 m_defBtnCols); 0484 break; 0485 default: 0486 break; 0487 case IND_COLORED: 0488 if (opts.shadeSliders == SHADE_BLEND_SELECTED) { 0489 m_defBtnCols = m_sliderCols; 0490 } else { 0491 m_defBtnCols = new QColor[TOTAL_SHADES + 1]; 0492 shadeColors(midColor(m_highlightCols[ORIGINAL_SHADE], 0493 m_buttonCols[ORIGINAL_SHADE]), m_defBtnCols); 0494 } 0495 } 0496 0497 switch(opts.comboBtn) { 0498 default: 0499 case SHADE_DARKEN: 0500 case SHADE_NONE: 0501 break; 0502 case SHADE_SELECTED: 0503 m_comboBtnCols=m_highlightCols; 0504 break; 0505 case SHADE_BLEND_SELECTED: 0506 if (opts.shadeSliders == SHADE_BLEND_SELECTED) { 0507 m_comboBtnCols = m_sliderCols; 0508 break; 0509 } 0510 QTC_FALLTHROUGH(); 0511 case SHADE_CUSTOM: 0512 if (opts.shadeSliders == SHADE_CUSTOM && 0513 opts.customSlidersColor == opts.customComboBtnColor) { 0514 m_comboBtnCols = m_sliderCols; 0515 break; 0516 } 0517 if (!m_comboBtnCols) { 0518 m_comboBtnCols = new QColor[TOTAL_SHADES + 1]; 0519 } 0520 shadeColors(opts.comboBtn == SHADE_BLEND_SELECTED ? 0521 midColor(m_highlightCols[ORIGINAL_SHADE], 0522 m_buttonCols[ORIGINAL_SHADE]) : 0523 opts.customComboBtnColor, m_comboBtnCols); 0524 } 0525 0526 switch (opts.sortedLv) { 0527 case SHADE_DARKEN: 0528 if (!m_sortedLvColors) { 0529 m_sortedLvColors = new QColor[TOTAL_SHADES + 1]; 0530 } 0531 shadeColors(shade(opts.lvButton ? m_buttonCols[ORIGINAL_SHADE] : m_backgroundCols[ORIGINAL_SHADE], LV_HEADER_DARK_FACTOR), m_sortedLvColors); 0532 break; 0533 default: 0534 case SHADE_NONE: 0535 break; 0536 case SHADE_SELECTED: 0537 m_sortedLvColors=m_highlightCols; 0538 break; 0539 case SHADE_BLEND_SELECTED: 0540 if (opts.shadeSliders == SHADE_BLEND_SELECTED) { 0541 m_sortedLvColors = m_sliderCols; 0542 break; 0543 } else if (opts.comboBtn == SHADE_BLEND_SELECTED) { 0544 m_sortedLvColors = m_comboBtnCols; 0545 break; 0546 } 0547 QTC_FALLTHROUGH(); 0548 case SHADE_CUSTOM: 0549 if (opts.shadeSliders == SHADE_CUSTOM && 0550 opts.customSlidersColor == opts.customSortedLvColor) { 0551 m_sortedLvColors = m_sliderCols; 0552 break; 0553 } 0554 if (opts.comboBtn == SHADE_CUSTOM && 0555 opts.customComboBtnColor == opts.customSortedLvColor) { 0556 m_sortedLvColors = m_comboBtnCols; 0557 break; 0558 } 0559 if (!m_sortedLvColors) { 0560 m_sortedLvColors = new QColor[TOTAL_SHADES + 1]; 0561 } 0562 shadeColors(opts.sortedLv == SHADE_BLEND_SELECTED ? 0563 midColor(m_highlightCols[ORIGINAL_SHADE], 0564 (opts.lvButton ? m_buttonCols[ORIGINAL_SHADE] : 0565 m_backgroundCols[ORIGINAL_SHADE])) : 0566 opts.customSortedLvColor, m_sortedLvColors); 0567 } 0568 0569 switch (opts.crColor) { 0570 default: 0571 case SHADE_NONE: 0572 m_checkRadioSelCols = m_buttonCols; 0573 break; 0574 case SHADE_DARKEN: 0575 if (!m_checkRadioSelCols) { 0576 m_checkRadioSelCols = new QColor[TOTAL_SHADES + 1]; 0577 } 0578 shadeColors(shade(m_buttonCols[ORIGINAL_SHADE], LV_HEADER_DARK_FACTOR), 0579 m_checkRadioSelCols); 0580 break; 0581 case SHADE_SELECTED: 0582 m_checkRadioSelCols = m_highlightCols; 0583 break; 0584 case SHADE_CUSTOM: 0585 if(SHADE_CUSTOM==opts.shadeSliders && opts.customSlidersColor==opts.customCrBgndColor) 0586 m_checkRadioSelCols=m_sliderCols; 0587 else if(SHADE_CUSTOM==opts.comboBtn && opts.customComboBtnColor==opts.customCrBgndColor) 0588 m_checkRadioSelCols=m_comboBtnCols; 0589 else if(SHADE_CUSTOM==opts.sortedLv && opts.customSortedLvColor==opts.customCrBgndColor) 0590 m_checkRadioSelCols=m_sortedLvColors; 0591 else 0592 { 0593 if(!m_checkRadioSelCols) 0594 m_checkRadioSelCols=new QColor [TOTAL_SHADES+1]; 0595 shadeColors(opts.customCrBgndColor, m_checkRadioSelCols); 0596 } 0597 break; 0598 case SHADE_BLEND_SELECTED: 0599 if(SHADE_BLEND_SELECTED==opts.shadeSliders) 0600 m_checkRadioSelCols=m_sliderCols; 0601 else if(SHADE_BLEND_SELECTED==opts.comboBtn) 0602 m_checkRadioSelCols=m_comboBtnCols; 0603 else if(SHADE_BLEND_SELECTED==opts.sortedLv) 0604 m_checkRadioSelCols=m_sortedLvColors; 0605 else 0606 { 0607 if(!m_checkRadioSelCols) 0608 m_checkRadioSelCols=new QColor [TOTAL_SHADES+1]; 0609 shadeColors(midColor(m_highlightCols[ORIGINAL_SHADE], m_buttonCols[ORIGINAL_SHADE]), m_checkRadioSelCols); 0610 } 0611 } 0612 0613 switch(opts.progressColor) 0614 { 0615 case SHADE_NONE: 0616 m_progressCols=m_backgroundCols; 0617 break; 0618 default: 0619 // Not set! 0620 break; 0621 case SHADE_CUSTOM: 0622 if(SHADE_CUSTOM==opts.shadeSliders && opts.customSlidersColor==opts.customProgressColor) 0623 m_progressCols=m_sliderCols; 0624 else if(SHADE_CUSTOM==opts.comboBtn && opts.customComboBtnColor==opts.customProgressColor) 0625 m_progressCols=m_comboBtnCols; 0626 else if(SHADE_CUSTOM==opts.sortedLv && opts.customSortedLvColor==opts.customProgressColor) 0627 m_progressCols=m_sortedLvColors; 0628 else if(SHADE_CUSTOM==opts.crColor && opts.customCrBgndColor==opts.customProgressColor) 0629 m_progressCols=m_checkRadioSelCols; 0630 else 0631 { 0632 if(!m_progressCols) 0633 m_progressCols=new QColor [TOTAL_SHADES+1]; 0634 shadeColors(opts.customProgressColor, m_progressCols); 0635 } 0636 break; 0637 case SHADE_BLEND_SELECTED: 0638 if(SHADE_BLEND_SELECTED==opts.shadeSliders) 0639 m_progressCols=m_sliderCols; 0640 else if(SHADE_BLEND_SELECTED==opts.comboBtn) 0641 m_progressCols=m_comboBtnCols; 0642 else if(SHADE_BLEND_SELECTED==opts.sortedLv) 0643 m_progressCols=m_sortedLvColors; 0644 else 0645 { 0646 if(!m_progressCols) 0647 m_progressCols=new QColor [TOTAL_SHADES+1]; 0648 shadeColors(midColor(m_highlightCols[ORIGINAL_SHADE], m_backgroundCols[ORIGINAL_SHADE]), m_progressCols); 0649 } 0650 } 0651 0652 setMenuColors(QApplication::palette().color(QPalette::Active, QPalette::Background)); 0653 0654 switch(opts.shadeCheckRadio) 0655 { 0656 default: 0657 m_checkRadioCol=QApplication::palette().color(QPalette::Active, opts.crButton ? QPalette::ButtonText : QPalette::Text); 0658 break; 0659 case SHADE_BLEND_SELECTED: 0660 case SHADE_SELECTED: 0661 m_checkRadioCol=QApplication::palette().color(QPalette::Active, QPalette::Highlight); 0662 break; 0663 case SHADE_CUSTOM: 0664 m_checkRadioCol=opts.customCheckRadioColor; 0665 } 0666 0667 if(opts.titlebarButtons&TITLEBAR_BUTTON_COLOR && opts.titlebarButtonColors.size()>=NUM_TITLEBAR_BUTTONS) 0668 for(int i=0; i<NUM_TITLEBAR_BUTTONS; ++i) 0669 { 0670 QColor *cols=new QColor [TOTAL_SHADES+1]; 0671 shadeColors(opts.titlebarButtonColors[(ETitleBarButtons)i], cols); 0672 m_titleBarButtonsCols[i]=cols; 0673 } 0674 else 0675 opts.titlebarButtons&=~TITLEBAR_BUTTON_COLOR; 0676 0677 if (oneOf(opts.bgndImage.type, IMG_PLAIN_RINGS, IMG_BORDERED_RINGS, 0678 IMG_SQUARE_RINGS) || 0679 oneOf(opts.menuBgndImage.type, IMG_PLAIN_RINGS, IMG_BORDERED_RINGS, 0680 IMG_SQUARE_RINGS)) { 0681 qtcCalcRingAlphas(&m_backgroundCols[ORIGINAL_SHADE]); 0682 } 0683 0684 m_blurHelper->setEnabled(opts.bgndOpacity != 100 || 0685 opts.dlgOpacity != 100 || 0686 opts.menuBgndOpacity != 100); 0687 0688 opts.fontTickWidth=-1; 0689 opts.menuTick=QString(QChar(0x2713)); 0690 0691 #ifdef QTC_QT5_ENABLE_KDE 0692 // We need to set the decoration colours for the preview now... 0693 if (m_isPreview) { 0694 setDecorationColors(); 0695 } 0696 #endif 0697 } 0698 0699 void Style::connectDBus() 0700 { 0701 if (m_dBusHelper->m_dbusConnected) 0702 return; 0703 auto bus = QDBusConnection::sessionBus(); 0704 if (bus.isConnected()) { 0705 m_dBusHelper->m_dbusConnected = true; 0706 bus.connect(QString(), "/KGlobalSettings", "org.kde.KGlobalSettings", 0707 "notifyChange", this, SLOT(kdeGlobalSettingsChange(int, int))); 0708 #ifndef QTC_QT5_ENABLE_KDE 0709 bus.connect("org.kde.kwin", "/KWin", "org.kde.KWin", "compositingToggled", 0710 this, SLOT(compositingToggled())); 0711 #endif 0712 0713 if (!qApp || (appName != "kwin" && appName != "kwin_x11" && appName != "kwin_wayland")) { 0714 // don't connect to signals if we know we're sending them out ourselves 0715 bus.connect("org.kde.kwin", "/QtCurve", "org.kde.QtCurve", 0716 "borderSizesChanged", this, SLOT(borderSizesChanged())); 0717 if (opts.menubarHiding & HIDE_KWIN) 0718 bus.connect("org.kde.kwin", "/QtCurve", "org.kde.QtCurve", 0719 "toggleMenuBar", 0720 this, SLOT(toggleMenuBar(unsigned int))); 0721 0722 if (opts.statusbarHiding & HIDE_KWIN) { 0723 bus.connect("org.kde.kwin", "/QtCurve", "org.kde.QtCurve", 0724 "toggleStatusBar", 0725 this, SLOT(toggleStatusBar(unsigned int))); 0726 } 0727 } 0728 } 0729 } 0730 0731 void Style::disconnectDBus() 0732 { 0733 if (!m_dBusHelper->m_dbusConnected) 0734 return; 0735 auto bus = QDBusConnection::sessionBus(); 0736 if (!bus.isConnected()) 0737 return; 0738 m_dBusHelper->m_dbusConnected = false; 0739 if (getenv("QTCURVE_DEBUG")) { 0740 qWarning() << Q_FUNC_INFO << this << "Disconnecting from" << bus.name() << "/" << bus.baseService(); 0741 dumpObjectInfo(); 0742 } 0743 bus.disconnect(QString(), "/KGlobalSettings", "org.kde.KGlobalSettings", 0744 "notifyChange", 0745 this, SLOT(kdeGlobalSettingsChange(int, int))); 0746 #ifndef QTC_QT5_ENABLE_KDE 0747 bus.disconnect("org.kde.kwin", "/KWin", "org.kde.KWin", "compositingToggled", 0748 this, SLOT(compositingToggled())); 0749 #endif 0750 0751 if (!qApp || (appName != "kwin" && appName != "kwin_x11" && appName != "kwin_wayland")) { 0752 bus.disconnect("org.kde.kwin", "/QtCurve", "org.kde.QtCurve", 0753 "borderSizesChanged", this, SLOT(borderSizesChanged())); 0754 if (opts.menubarHiding & HIDE_KWIN) 0755 bus.disconnect("org.kde.kwin", "/QtCurve", "org.kde.QtCurve", 0756 "toggleMenuBar", 0757 this, SLOT(toggleMenuBar(unsigned int))); 0758 0759 if (opts.statusbarHiding & HIDE_KWIN) { 0760 bus.disconnect("org.kde.kwin", "/QtCurve", "org.kde.QtCurve", 0761 "toggleStatusBar", 0762 this, SLOT(toggleStatusBar(unsigned int))); 0763 } 0764 } 0765 } 0766 0767 Style::~Style() 0768 { 0769 qtcInfo("Deleting style instance %p\n", this); 0770 disconnectDBus(); 0771 if (m_plugin && m_plugin->m_styleInstances.contains(this)) { 0772 m_plugin->m_styleInstances.removeAll(this); 0773 } 0774 freeColors(); 0775 delete m_fntHelper; 0776 delete m_dBusHelper; 0777 } 0778 0779 void Style::freeColor(QSet<QColor *> &freedColors, QColor **cols) 0780 { 0781 if(!freedColors.contains(*cols) && 0782 *cols!=m_highlightCols && 0783 *cols!=m_backgroundCols && 0784 *cols!=m_menubarCols && 0785 *cols!=m_focusCols && 0786 *cols!=m_mouseOverCols && 0787 *cols!=m_buttonCols && 0788 *cols!=m_coloredButtonCols && 0789 *cols!=m_coloredBackgroundCols && 0790 *cols!=m_coloredHighlightCols) { 0791 freedColors.insert(*cols); 0792 delete [] *cols; 0793 } 0794 *cols=0L; 0795 } 0796 0797 void Style::freeColors() 0798 { 0799 if(0!=m_progressBarAnimateTimer) { 0800 killTimer(m_progressBarAnimateTimer); 0801 m_progressBarAnimateTimer = 0; 0802 } 0803 0804 QSet<QColor*> freedColors; 0805 0806 freeColor(freedColors, &m_sidebarButtonsCols); 0807 freeColor(freedColors, &m_popupMenuCols); 0808 freeColor(freedColors, &m_activeMdiColors); 0809 freeColor(freedColors, &m_mdiColors); 0810 freeColor(freedColors, &m_progressCols); 0811 freeColor(freedColors, &m_checkRadioSelCols); 0812 freeColor(freedColors, &m_sortedLvColors); 0813 freeColor(freedColors, &m_comboBtnCols); 0814 freeColor(freedColors, &m_defBtnCols); 0815 freeColor(freedColors, &m_sliderCols); 0816 0817 if (opts.titlebarButtons & TITLEBAR_BUTTON_COLOR) { 0818 for (int i = 0;i < NUM_TITLEBAR_BUTTONS;i++) { 0819 delete []m_titleBarButtonsCols[i]; 0820 m_titleBarButtonsCols[i] = 0L; 0821 } 0822 } 0823 if (m_ooMenuCols) { 0824 delete []m_ooMenuCols; 0825 m_ooMenuCols = 0L; 0826 } 0827 } 0828 0829 #if 1 0830 static QFontMetrics styledFontMetrics(const QStyleOption *option, const QWidget *widget) 0831 { 0832 return option 0833 ? option->fontMetrics 0834 : widget 0835 ? widget->fontMetrics() 0836 : qApp->fontMetrics(); 0837 } 0838 0839 static int fontHeight(const QStyleOption *option, const QWidget *widget) 0840 { 0841 return styledFontMetrics(option, widget).height(); 0842 } 0843 0844 // Taken from skulpture 0.2.3 0845 void Style::polishFormLayout(QFormLayout *layout) 0846 { 0847 int widgetSize=-1; 0848 0849 if (layout->labelAlignment() & Qt::AlignVCenter) 0850 return; 0851 0852 int addedHeight = -1; 0853 for (int row = 0; row < layout->rowCount(); ++row) 0854 { 0855 QLayoutItem *labelItem = layout->itemAt(row, QFormLayout::LabelRole); 0856 if (!labelItem) 0857 continue; 0858 0859 QLayoutItem *fieldItem = layout->itemAt(row, QFormLayout::FieldRole); 0860 if (!fieldItem) 0861 continue; 0862 0863 QWidget *label = labelItem->widget(); 0864 if (!label) 0865 continue; 0866 0867 int labelHeight; 0868 if (addedHeight < 0) 0869 addedHeight = 4 + 2 * widgetSize; 0870 if (qobject_cast<QLabel *>(label)) 0871 labelHeight = label->sizeHint().height() + addedHeight; 0872 else if (qobject_cast<QCheckBox *>(label)) 0873 labelHeight = label->sizeHint().height(); 0874 else 0875 continue; 0876 0877 int fieldHeight = fieldItem->sizeHint().height(); 0878 /* for large fields, we don't center */ 0879 if (fieldHeight <= 2 * fontHeight(0, label) + addedHeight) 0880 { 0881 if (fieldHeight > labelHeight) 0882 labelHeight = fieldHeight; 0883 } 0884 // else if (verticalTextShift(label->fontMetrics()) & 1) 0885 // labelHeight += 1; 0886 if (qobject_cast<QCheckBox *>(label)) { 0887 label->setMinimumHeight(labelHeight); 0888 } else { 0889 label->setMinimumHeight((labelHeight * 4 + 6) / 7); 0890 } 0891 } 0892 } 0893 0894 void Style::polishLayout(QLayout *layout) 0895 { 0896 if (QFormLayout *formLayout = qobject_cast<QFormLayout *>(layout)) 0897 polishFormLayout(formLayout); 0898 // recurse into layouts 0899 for (int i = 0; i < layout->count(); ++i) 0900 if (QLayout *l = layout->itemAt(i)->layout()) 0901 polishLayout(l); 0902 } 0903 #endif 0904 0905 // Taken from oxygen! 0906 void Style::polishScrollArea(QAbstractScrollArea *scrollArea, bool isKFilePlacesView) const 0907 { 0908 if(!scrollArea) 0909 return; 0910 0911 // HACK: add exception for KPIM transactionItemView, which is an overlay widget and must have filled background. This is a temporary workaround 0912 // until a more robust solution is found. 0913 if(scrollArea->inherits("KPIM::TransactionItemView")) 0914 { 0915 // also need to make the scrollarea background plain (using autofill background) so that optional vertical scrollbar background is not 0916 // transparent either. 0917 // TODO: possibly add an event filter to use the "normal" window background instead of something flat. 0918 scrollArea->setAutoFillBackground(true); 0919 return; 0920 } 0921 0922 // check frame style and background role 0923 if(QFrame::NoFrame!=scrollArea->frameShape() || QPalette::Window!=scrollArea->backgroundRole()) 0924 return; 0925 0926 // get viewport and check background role 0927 QWidget *viewport(scrollArea->viewport()); 0928 if(!(viewport && viewport->backgroundRole() == QPalette::Window) && 0929 !isKFilePlacesView) { 0930 return; 0931 } 0932 0933 // change viewport autoFill background. 0934 // do the same for children if the background role is QPalette::Window 0935 viewport->setAutoFillBackground(false); 0936 for (QWidget *child: viewport->findChildren<QWidget*>()) { 0937 if (child->parent() == viewport && 0938 child->backgroundRole() == QPalette::Window) { 0939 child->setAutoFillBackground(false); 0940 } 0941 } 0942 } 0943 0944 QIcon Style::standardIcon(StandardPixmap pix, const QStyleOption *option, 0945 const QWidget *widget) const 0946 { 0947 switch (pix) { 0948 // case SP_TitleBarMenuButton: 0949 // case SP_TitleBarMinButton: 0950 // case SP_TitleBarMaxButton: 0951 // case SP_TitleBarContextHelpButton: 0952 case SP_TitleBarNormalButton: 0953 case SP_TitleBarShadeButton: 0954 case SP_TitleBarUnshadeButton: 0955 case SP_DockWidgetCloseButton: 0956 case SP_TitleBarCloseButton: { 0957 QPixmap pm(13, 13); 0958 0959 pm.fill(Qt::transparent); 0960 0961 QPainter painter(&pm); 0962 0963 drawIcon(&painter, Qt::color1, QRect(0, 0, pm.width(), pm.height()), 0964 false, pix2Icon(pix), oneOf(pix, SP_TitleBarShadeButton, 0965 SP_TitleBarUnshadeButton)); 0966 return QIcon(pm); 0967 } 0968 case SP_ToolBarHorizontalExtensionButton: 0969 case SP_ToolBarVerticalExtensionButton: 0970 { 0971 QPixmap pm(9, 9); 0972 0973 pm.fill(Qt::transparent); 0974 0975 QPainter painter(&pm); 0976 0977 drawIcon(&painter, Qt::color1, QRect(0, 0, pm.width(), pm.height()), false, pix2Icon(pix), true); 0978 return QIcon(pm); 0979 } 0980 #ifndef QTC_QT5_ENABLE_KDE 0981 case SP_MessageBoxQuestion: 0982 case SP_MessageBoxInformation: { 0983 static QIcon icn(QPixmap::fromImage(qtc_dialog_information)); 0984 return icn; 0985 } 0986 case SP_MessageBoxWarning: { 0987 static QIcon icn(QPixmap::fromImage(qtc_dialog_warning)); 0988 return icn; 0989 } 0990 case SP_MessageBoxCritical: { 0991 static QIcon icn(QPixmap::fromImage(qtc_dialog_error)); 0992 return icn; 0993 } 0994 /* 0995 case SP_DialogYesButton: 0996 case SP_DialogOkButton: 0997 { 0998 static QIcon icn(load(dialog_ok_png_len, dialog_ok_png_data)); 0999 return icn; 1000 } 1001 case SP_DialogNoButton: 1002 case SP_DialogCancelButton: 1003 { 1004 static QIcon icn(load(dialog_cancel_png_len, dialog_cancel_png_data)); 1005 return icn; 1006 } 1007 case SP_DialogHelpButton: 1008 { 1009 static QIcon icn(load(help_contents_png_len, help_contents_png_data)); 1010 return icn; 1011 } 1012 case SP_DialogCloseButton: 1013 { 1014 static QIcon icn(load(dialog_close_png_len, dialog_close_png_data)); 1015 return icn; 1016 } 1017 case SP_DialogApplyButton: 1018 { 1019 static QIcon icn(load(dialog_ok_apply_png_len, dialog_ok_apply_png_data)); 1020 return icn; 1021 } 1022 case SP_DialogResetButton: 1023 { 1024 static QIcon icn(load(document_revert_png_len, document_revert_png_data)); 1025 return icn; 1026 } 1027 */ 1028 #else 1029 case SP_MessageBoxInformation: 1030 return QIcon::fromTheme(QStringLiteral("dialog-information")); 1031 case SP_MessageBoxWarning: 1032 return QIcon::fromTheme(QStringLiteral("dialog-warning")); 1033 case SP_MessageBoxCritical: 1034 return QIcon::fromTheme(QStringLiteral("dialog-error")); 1035 case SP_MessageBoxQuestion: 1036 return QIcon::fromTheme(QStringLiteral("dialog-information")); 1037 case SP_DesktopIcon: 1038 return QIcon::fromTheme(QStringLiteral("user-desktop")); 1039 case SP_TrashIcon: 1040 return QIcon::fromTheme(QStringLiteral("user-trash")); 1041 case SP_ComputerIcon: 1042 return QIcon::fromTheme(QStringLiteral("computer")); 1043 case SP_DriveFDIcon: 1044 return QIcon::fromTheme(QStringLiteral("media-floppy")); 1045 case SP_DriveHDIcon: 1046 return QIcon::fromTheme(QStringLiteral("drive-harddisk")); 1047 case SP_DriveCDIcon: 1048 case SP_DriveDVDIcon: 1049 return QIcon::fromTheme(QStringLiteral("media-optical")); 1050 case SP_DriveNetIcon: 1051 return QIcon::fromTheme(QStringLiteral("network-server")); 1052 case SP_DirOpenIcon: 1053 return QIcon::fromTheme(QStringLiteral("document-open")); 1054 case SP_DirIcon: 1055 case SP_DirClosedIcon: 1056 return QIcon::fromTheme(QStringLiteral("folder")); 1057 // case SP_DirLinkIcon: 1058 case SP_FileIcon: 1059 return QIcon::fromTheme(QStringLiteral("application-x-zerosize")); 1060 // case SP_FileLinkIcon: 1061 case SP_FileDialogStart: 1062 return QIcon::fromTheme(QApplication::layoutDirection() == Qt::RightToLeft ? 1063 QStringLiteral("go-edn") : QStringLiteral("go-first")); 1064 case SP_FileDialogEnd: 1065 return QIcon::fromTheme(QApplication::layoutDirection() == Qt::RightToLeft ? 1066 QStringLiteral("go-first") : QStringLiteral("go-end")); 1067 case SP_FileDialogToParent: 1068 return QIcon::fromTheme(QStringLiteral("go-up")); 1069 case SP_FileDialogNewFolder: 1070 return QIcon::fromTheme(QStringLiteral("folder-new")); 1071 case SP_FileDialogDetailedView: 1072 return QIcon::fromTheme(QStringLiteral("view-list-details")); 1073 // case SP_FileDialogInfoView: 1074 // return QIcon::fromTheme(QStringLiteral("dialog-ok")); 1075 // case SP_FileDialogContentsView: 1076 // return QIcon::fromTheme(QStringLiteral("dialog-ok")); 1077 case SP_FileDialogListView: 1078 return QIcon::fromTheme(QStringLiteral("view-list-icons")); 1079 case SP_FileDialogBack: 1080 return QIcon::fromTheme(QApplication::layoutDirection() == Qt::RightToLeft ? 1081 QStringLiteral("go-next") : QStringLiteral("go-previous")); 1082 case SP_DialogOkButton: 1083 return QIcon::fromTheme(QStringLiteral("dialog-ok")); 1084 case SP_DialogCancelButton: 1085 return QIcon::fromTheme(QStringLiteral("dialog-cancel")); 1086 case SP_DialogHelpButton: 1087 return QIcon::fromTheme(QStringLiteral("help-contents")); 1088 case SP_DialogOpenButton: 1089 return QIcon::fromTheme(QStringLiteral("document-open")); 1090 case SP_DialogSaveButton: 1091 return QIcon::fromTheme(QStringLiteral("document-save")); 1092 case SP_DialogCloseButton: 1093 return QIcon::fromTheme(QStringLiteral("dialog-close")); 1094 case SP_DialogApplyButton: 1095 return QIcon::fromTheme(QStringLiteral("dialog-ok-apply")); 1096 case SP_DialogResetButton: 1097 return QIcon::fromTheme(QStringLiteral("document-revert")); 1098 // case SP_DialogDiscardButton: 1099 // return QIcon::fromTheme(QStringLiteral("dialog-cancel")); 1100 case SP_DialogYesButton: 1101 return QIcon::fromTheme(QStringLiteral("dialog-ok")); 1102 case SP_DialogNoButton: 1103 return QIcon::fromTheme(QStringLiteral("dialog-cancel")); 1104 case SP_ArrowUp: 1105 return QIcon::fromTheme(QStringLiteral("arrow-up")); 1106 case SP_ArrowDown: 1107 return QIcon::fromTheme(QStringLiteral("arrow-down")); 1108 case SP_ArrowLeft: 1109 return QIcon::fromTheme(QStringLiteral("arrow-left")); 1110 case SP_ArrowRight: 1111 return QIcon::fromTheme(QStringLiteral("arrow-right")); 1112 case SP_ArrowBack: 1113 return QIcon::fromTheme(QApplication::layoutDirection() == Qt::RightToLeft ? 1114 QStringLiteral("go-next") : QStringLiteral("go-previous")); 1115 case SP_ArrowForward: 1116 return QIcon::fromTheme(QApplication::layoutDirection() == Qt::RightToLeft ? 1117 QStringLiteral("go-previous") : QStringLiteral("go-next")); 1118 case SP_DirHomeIcon: 1119 return QIcon::fromTheme(QStringLiteral("user-home")); 1120 // case SP_CommandLink: 1121 // case SP_VistaShield: 1122 case SP_BrowserReload: 1123 return QIcon::fromTheme(QStringLiteral("view-refresh")); 1124 case SP_BrowserStop: 1125 return QIcon::fromTheme(QStringLiteral("process-stop")); 1126 case SP_MediaPlay: 1127 return QIcon::fromTheme(QStringLiteral("media-playback-start")); 1128 case SP_MediaStop: 1129 return QIcon::fromTheme(QStringLiteral("media-playback-stop")); 1130 case SP_MediaPause: 1131 return QIcon::fromTheme(QStringLiteral("media-playback-pause")); 1132 case SP_MediaSkipForward: 1133 return QIcon::fromTheme(QStringLiteral("media-skip-forward")); 1134 case SP_MediaSkipBackward: 1135 return QIcon::fromTheme(QStringLiteral("media-skip-backward")); 1136 case SP_MediaSeekForward: 1137 return QIcon::fromTheme(QStringLiteral("media-seek-forward")); 1138 case SP_MediaSeekBackward: 1139 return QIcon::fromTheme(QStringLiteral("media-seek-backward")); 1140 case SP_MediaVolume: 1141 return QIcon::fromTheme(QStringLiteral("player-volume")); 1142 case SP_MediaVolumeMuted: 1143 return QIcon::fromTheme(QStringLiteral("player-volume-muted")); 1144 #endif 1145 default: 1146 break; 1147 } 1148 // TODO ? 1149 return ParentStyleClass::standardIcon(pix, option, widget); 1150 } 1151 1152 int Style::layoutSpacing(QSizePolicy::ControlType control1, 1153 QSizePolicy::ControlType control2, 1154 Qt::Orientation orientation, 1155 const QStyleOption *option, const QWidget *widget) const 1156 { 1157 Q_UNUSED(control1); 1158 Q_UNUSED(control2); 1159 Q_UNUSED(orientation); 1160 return pixelMetric(PM_DefaultLayoutSpacing, option, widget); 1161 } 1162 1163 // Use 'drawItemTextWithRole' when already know which role to use. 1164 void 1165 Style::drawItemTextWithRole(QPainter *painter, const QRect &rect, int flags, 1166 const QPalette &pal, bool enabled, 1167 const QString &text, 1168 QPalette::ColorRole textRole) const 1169 { 1170 ParentStyleClass::drawItemText(painter, rect, flags, pal, 1171 enabled, text, textRole); 1172 } 1173 1174 void Style::drawSideBarButton(QPainter *painter, const QRect &r, const QStyleOption *option, const QWidget *widget) const 1175 { 1176 const QPalette &palette(option->palette); 1177 QRect r2(r); 1178 QStyleOption opt(*option); 1179 1180 if(r2.height()>r2.width() || (r2.height()<r2.width() && r2.width()<=32)) 1181 opt.state&=~State_Horizontal; 1182 else 1183 opt.state|=State_Horizontal; 1184 1185 const QColor *use(opt.state&State_On ? getSidebarButtons() : buttonColors(option)); 1186 bool horiz(opt.state&State_Horizontal); 1187 1188 painter->save(); 1189 if(opt.state&State_On || opt.state&State_MouseOver) 1190 { 1191 r2.adjust(-1, -1, 1, 1); 1192 drawLightBevel(painter, r2, &opt, widget, ROUNDED_NONE, 1193 getFill(&opt, use), use, false, WIDGET_MENU_ITEM); 1194 } 1195 else 1196 painter->fillRect(r2, palette.window().color()); 1197 1198 if (opt.state & State_MouseOver && opts.coloredMouseOver) { 1199 r2 = r; 1200 if (opts.coloredMouseOver == MO_PLASTIK) { 1201 if (horiz) { 1202 r2.adjust(0, 1, 0, -1); 1203 } else { 1204 r2.adjust(1, 0, -1, 0); 1205 } 1206 } else { 1207 r2.adjust(1, 1, -1, -1); 1208 } 1209 if (opts.coloredMouseOver == MO_GLOW) { 1210 QColor col(m_mouseOverCols[opt.state&State_On ? 0 : 1]); 1211 1212 col.setAlphaF(GLOW_ALPHA(false)); 1213 painter->setPen(col); 1214 drawRect(painter, r); 1215 col = m_mouseOverCols[opt.state&State_On ? 4 : 3]; 1216 col.setAlphaF(0.8); 1217 painter->setPen(col); 1218 drawRect(painter, r2); 1219 } else { 1220 painter->setPen(m_mouseOverCols[opt.state&State_On ? 0 : 1]); 1221 1222 if (horiz || MO_PLASTIK!=opts.coloredMouseOver) 1223 { 1224 painter->drawLine(r.x(), r.y(), r.x()+r.width()-1, r.y()); 1225 painter->drawLine(r2.x(), r2.y(), r2.x()+r2.width()-1, r2.y()); 1226 } 1227 1228 if(!horiz || MO_PLASTIK!=opts.coloredMouseOver) 1229 { 1230 painter->drawLine(r.x(), r.y(), r.x(), r.y()+r.height()-1); 1231 painter->drawLine(r2.x(), r2.y(), r2.x(), r2.y()+r2.height()-1); 1232 if(MO_PLASTIK!=opts.coloredMouseOver) 1233 painter->setPen(m_mouseOverCols[opt.state&State_On ? 1 : 2]); 1234 } 1235 1236 if(horiz || MO_PLASTIK!=opts.coloredMouseOver) 1237 { 1238 painter->drawLine(r.x(), r.y()+r.height()-1, r.x()+r.width()-1, r.y()+r.height()-1); 1239 painter->drawLine(r2.x(), r2.y()+r2.height()-1, r2.x()+r2.width()-1, r2.y()+r2.height()-1); 1240 } 1241 1242 if(!horiz || MO_PLASTIK!=opts.coloredMouseOver) 1243 { 1244 painter->drawLine(r.x()+r.width()-1, r.y(), r.x()+r.width()-1, r.y()+r.height()-1); 1245 painter->drawLine(r2.x()+r2.width()-1, r2.y(), r2.x()+r2.width()-1, r2.y()+r2.height()-1); 1246 } 1247 } 1248 } 1249 1250 painter->restore(); 1251 } 1252 1253 void Style::drawHighlight(QPainter *p, const QRect &r, bool horiz, bool inc) const 1254 { 1255 QColor col1(m_mouseOverCols[ORIGINAL_SHADE]); 1256 1257 col1.setAlphaF(0.5); 1258 drawFadedLine(p, r, inc ? col1 : m_mouseOverCols[ORIGINAL_SHADE], true, true, horiz); 1259 drawFadedLine(p, r.adjusted(horiz ? 0 : 1, horiz ? 1 : 0, 0, 0), inc ? m_mouseOverCols[ORIGINAL_SHADE] : col1, true, true, horiz); 1260 } 1261 1262 void 1263 Style::drawFadedLine(QPainter *p, const QRect &r, const QColor &col, 1264 bool fadeStart, bool fadeEnd, bool horiz, 1265 double fadeSizeStart, double fadeSizeEnd) const 1266 { 1267 bool aa(p->testRenderHint(QPainter::Antialiasing)); 1268 QPointF start(r.x()+(aa ? 0.5 : 0.0), r.y()+(aa ? 0.5 : 0.0)), 1269 end(r.x()+(horiz ? r.width()-1 : 0)+(aa ? 0.5 : 0.0), 1270 r.y()+(horiz ? 0 : r.height()-1)+(aa ? 0.5 : 0.0)); 1271 1272 if(opts.fadeLines && (fadeStart || fadeEnd)) 1273 { 1274 QLinearGradient grad(start, end); 1275 QColor fade(col); 1276 1277 fade.setAlphaF(0.0); 1278 grad.setColorAt(0, fadeStart && opts.fadeLines ? fade : col); 1279 if(fadeSizeStart>=0 && fadeSizeStart<=1.0) 1280 grad.setColorAt(fadeSizeStart, col); 1281 if(fadeSizeEnd>=0 && fadeSizeEnd<=1.0) 1282 grad.setColorAt(1.0-fadeSizeEnd, col); 1283 grad.setColorAt(1, fadeEnd && opts.fadeLines ? fade : col); 1284 p->setPen(QPen(QBrush(grad), QPENWIDTH1)); 1285 } 1286 else 1287 p->setPen(col); 1288 p->drawLine(start, end); 1289 } 1290 1291 void Style::drawLines(QPainter *p, const QRect &r, bool horiz, int nLines, int offset, const QColor *cols, int startOffset, 1292 int dark, ELine type) const 1293 { 1294 int space((nLines*2)+(LINE_DASHES!=type ? (nLines-1) : 0)), 1295 step(LINE_DASHES!=type ? 3 : 2), 1296 etchedDisp(type == LINE_SUNKEN ? 1 : 0), 1297 x(horiz ? r.x() : r.x()+((r.width()-space)>>1)), 1298 y(horiz ? r.y()+((r.height()-space)>>1) : r.y()), 1299 x2(r.x()+r.width()-1), 1300 y2(r.y()+r.height()-1), 1301 i; 1302 QPen dp(cols[dark], QPENWIDTH1), 1303 lp(cols[0], QPENWIDTH1); 1304 1305 if(opts.fadeLines && (horiz ? r.width() : r.height())>16) 1306 { 1307 QLinearGradient grad(r.topLeft(), horiz ? r.topRight() : r.bottomLeft()); 1308 QColor fade(cols[dark]); 1309 1310 fade.setAlphaF(0.0); 1311 grad.setColorAt(0, fade); 1312 grad.setColorAt(0.4, cols[dark]); 1313 grad.setColorAt(0.6, cols[dark]); 1314 grad.setColorAt(1, fade); 1315 1316 dp=QPen(QBrush(grad), QPENWIDTH1); 1317 1318 if(LINE_FLAT!=type) 1319 { 1320 fade=QColor(cols[0]); 1321 1322 fade.setAlphaF(0.0); 1323 grad.setColorAt(0, fade); 1324 grad.setColorAt(0.4, cols[0]); 1325 grad.setColorAt(0.6, cols[0]); 1326 grad.setColorAt(1, fade); 1327 lp=QPen(QBrush(grad), QPENWIDTH1); 1328 } 1329 } 1330 1331 p->setRenderHint(QPainter::Antialiasing, true); 1332 if(horiz) 1333 { 1334 if(startOffset && y+startOffset>0) 1335 y+=startOffset; 1336 1337 p->setPen(dp); 1338 for(i=0; i<space; i+=step) 1339 drawAaLine(p, x+offset, y+i, x2-offset, y+i); 1340 1341 if(LINE_FLAT!=type) 1342 { 1343 p->setPen(lp); 1344 x+=etchedDisp; 1345 x2+=etchedDisp; 1346 for(i=1; i<space; i+=step) 1347 drawAaLine(p, x+offset, y+i, x2-offset, y+i); 1348 } 1349 } 1350 else 1351 { 1352 if(startOffset && x+startOffset>0) 1353 x+=startOffset; 1354 1355 p->setPen(dp); 1356 for(i=0; i<space; i+=step) 1357 drawAaLine(p, x+i, y+offset, x+i, y2-offset); 1358 1359 if(LINE_FLAT!=type) 1360 { 1361 p->setPen(lp); 1362 y+=etchedDisp; 1363 y2+=etchedDisp; 1364 for(i=1; i<space; i+=step) 1365 drawAaLine(p, x+i, y+offset, x+i, y2-offset); 1366 } 1367 } 1368 QPAINTER_RENDERHINT_AA_MAYBE_OFF(p); 1369 } 1370 1371 void Style::drawProgressBevelGradient(QPainter *p, const QRect &origRect, const QStyleOption *option, bool horiz, EAppearance bevApp, 1372 const QColor *cols) const 1373 { 1374 bool vertical(!horiz), 1375 inCache(true); 1376 QRect r(0, 0, horiz ? PROGRESS_CHUNK_WIDTH*2 : origRect.width(), 1377 horiz ? origRect.height() : PROGRESS_CHUNK_WIDTH*2); 1378 QtcKey key(createKey(horiz ? r.height() : r.width(), cols[ORIGINAL_SHADE], horiz, bevApp, WIDGET_PROGRESSBAR)); 1379 QPixmap *pix(m_pixmapCache.object(key)); 1380 1381 if(!pix) 1382 { 1383 pix=new QPixmap(r.width(), r.height()); 1384 1385 QPainter pixPainter(pix); 1386 1387 if(qtcIsFlat(bevApp)) 1388 pixPainter.fillRect(r, cols[ORIGINAL_SHADE]); 1389 else 1390 drawBevelGradientReal(cols[ORIGINAL_SHADE], &pixPainter, r, horiz, false, bevApp, WIDGET_PROGRESSBAR); 1391 1392 switch(opts.stripedProgress) 1393 { 1394 default: 1395 case STRIPE_NONE: 1396 break; 1397 case STRIPE_PLAIN: 1398 { 1399 QRect r2(horiz 1400 ? QRect(r.x(), r.y(), PROGRESS_CHUNK_WIDTH, r.height()) 1401 : QRect(r.x(), r.y(), r.width(), PROGRESS_CHUNK_WIDTH)); 1402 1403 if(qtcIsFlat(bevApp)) 1404 pixPainter.fillRect(r2, cols[1]); 1405 else 1406 drawBevelGradientReal(cols[1], &pixPainter, r2, horiz, false, bevApp, WIDGET_PROGRESSBAR); 1407 break; 1408 } 1409 case STRIPE_DIAGONAL: 1410 { 1411 QRegion reg; 1412 int size(vertical ? origRect.width() : origRect.height()); 1413 1414 for(int offset=0; offset<(size*2); offset+=(PROGRESS_CHUNK_WIDTH*2)) 1415 { 1416 QPolygon a; 1417 1418 if(vertical) 1419 a.setPoints(4, r.x(), r.y()+offset, 1420 r.x()+r.width(), (r.y()+offset)-size, 1421 r.x()+r.width(), (r.y()+offset+PROGRESS_CHUNK_WIDTH)-size, 1422 r.x(), r.y()+offset+PROGRESS_CHUNK_WIDTH); 1423 else 1424 a.setPoints(4, r.x()+offset, r.y(), 1425 r.x()+offset+PROGRESS_CHUNK_WIDTH, r.y(), 1426 (r.x()+offset+PROGRESS_CHUNK_WIDTH)-size, r.y()+r.height(), 1427 (r.x()+offset)-size, r.y()+r.height()); 1428 1429 reg+=QRegion(a); 1430 } 1431 1432 pixPainter.setClipRegion(reg); 1433 if(qtcIsFlat(bevApp)) 1434 pixPainter.fillRect(r, cols[1]); 1435 else 1436 drawBevelGradientReal(cols[1], &pixPainter, r, horiz, false, bevApp, WIDGET_PROGRESSBAR); 1437 } 1438 } 1439 1440 pixPainter.end(); 1441 int cost(pix->width()*pix->height()*(pix->depth()/8)); 1442 1443 if(cost<m_pixmapCache.maxCost()) 1444 m_pixmapCache.insert(key, pix, cost); 1445 else 1446 inCache=false; 1447 } 1448 QRect fillRect(origRect); 1449 1450 if(opts.animatedProgress) 1451 { 1452 int animShift=vertical || option->state&STATE_REVERSE ? PROGRESS_CHUNK_WIDTH : -PROGRESS_CHUNK_WIDTH; 1453 1454 if(vertical || option->state&STATE_REVERSE) 1455 animShift -= (m_animateStep/2) % (PROGRESS_CHUNK_WIDTH*2); 1456 else 1457 animShift += (m_animateStep/2) % (PROGRESS_CHUNK_WIDTH*2); 1458 1459 if(horiz) 1460 fillRect.adjust(animShift-PROGRESS_CHUNK_WIDTH, 0, PROGRESS_CHUNK_WIDTH, 0); 1461 else 1462 fillRect.adjust(0, animShift-PROGRESS_CHUNK_WIDTH, 0, PROGRESS_CHUNK_WIDTH); 1463 } 1464 1465 p->save(); 1466 p->setClipRect(origRect, Qt::IntersectClip); 1467 p->drawTiledPixmap(fillRect, *pix); 1468 if (opts.stripedProgress == STRIPE_FADE && fillRect.width() > 4 && 1469 fillRect.height() > 4) { 1470 addStripes(p, QPainterPath(), fillRect, !vertical); 1471 } 1472 p->restore(); 1473 1474 if (!inCache) { 1475 delete pix; 1476 } 1477 } 1478 1479 void 1480 Style::drawBevelGradient(const QColor &base, QPainter *p, const QRect &origRect, 1481 const QPainterPath &path, bool horiz, bool sel, 1482 EAppearance bevApp, EWidget w, bool useCache) const 1483 { 1484 if (origRect.width() < 1 || origRect.height() < 1) { 1485 return; 1486 } 1487 if (qtcIsFlat(bevApp)) { 1488 if (noneOf(w, WIDGET_TAB_TOP, WIDGET_TAB_BOT) || 1489 !qtcIsCustomBgnd(opts) || opts.tabBgnd || !sel) { 1490 if (path.isEmpty()) { 1491 p->fillRect(origRect, base); 1492 } else { 1493 p->fillPath(path, base); 1494 } 1495 } 1496 } else { 1497 bool tab = oneOf(w, WIDGET_TAB_TOP, WIDGET_TAB_BOT); 1498 bool selected = tab ? false : sel; 1499 EAppearance app = 1500 (selected ? opts.sunkenAppearance : 1501 w == WIDGET_LISTVIEW_HEADER && bevApp == APPEARANCE_BEVELLED ? 1502 APPEARANCE_LV_BEVELLED : bevApp != APPEARANCE_BEVELLED || 1503 WIDGET_BUTTON(w) || 1504 oneOf(w, WIDGET_LISTVIEW_HEADER, WIDGET_TROUGH, 1505 WIDGET_NO_ETCH_BTN, WIDGET_MENU_BUTTON) ? bevApp : 1506 APPEARANCE_GRADIENT); 1507 1508 if (w == WIDGET_PROGRESSBAR || !useCache) { 1509 drawBevelGradientReal(base, p, origRect, path, horiz, sel, app, w); 1510 } else { 1511 QRect r(0, 0, horiz ? PIXMAP_DIMENSION : origRect.width(), 1512 horiz ? origRect.height() : PIXMAP_DIMENSION); 1513 QtcKey key(createKey(horiz ? r.height() : r.width(), 1514 base, horiz, app, w)); 1515 QPixmap *pix(m_pixmapCache.object(key)); 1516 bool inCache(true); 1517 1518 if (!pix) { 1519 pix = new QPixmap(r.width(), r.height()); 1520 pix->fill(Qt::transparent); 1521 1522 QPainter pixPainter(pix); 1523 1524 drawBevelGradientReal(base, &pixPainter, r, horiz, sel, app, w); 1525 pixPainter.end(); 1526 1527 int cost(pix->width()*pix->height()*(pix->depth()/8)); 1528 1529 if (cost < m_pixmapCache.maxCost()) { 1530 m_pixmapCache.insert(key, pix, cost); 1531 } else { 1532 inCache = false; 1533 } 1534 } 1535 1536 if(!path.isEmpty()) 1537 { 1538 p->save(); 1539 p->setClipPath(path, Qt::IntersectClip); 1540 } 1541 1542 p->drawTiledPixmap(origRect, *pix); 1543 if(!path.isEmpty()) 1544 p->restore(); 1545 if(!inCache) 1546 delete pix; 1547 } 1548 } 1549 } 1550 1551 void 1552 Style::drawBevelGradientReal(const QColor &base, QPainter *p, const QRect &r, 1553 const QPainterPath &path, bool horiz, bool sel, 1554 EAppearance app, EWidget w) const 1555 { 1556 bool topTab = (w == WIDGET_TAB_TOP); 1557 bool botTab = (w == WIDGET_TAB_BOT); 1558 bool dwt = qtcIsCustomBgnd(opts) && (w == WIDGET_DOCK_WIDGET_TITLE); 1559 bool titleBar = (opts.windowBorder & WINDOW_BORDER_BLEND_TITLEBAR && 1560 (oneOf(w, WIDGET_MDI_WINDOW, WIDGET_MDI_WINDOW_TITLE) || 1561 (opts.dwtSettings & DWT_COLOR_AS_PER_TITLEBAR && 1562 w == WIDGET_DOCK_WIDGET_TITLE && !dwt))); 1563 bool reverse = QApplication::layoutDirection() == Qt::RightToLeft; 1564 const Gradient *grad = qtcGetGradient(app, &opts); 1565 QLinearGradient g(r.topLeft(), horiz ? r.bottomLeft() : r.topRight()); 1566 GradientStopCont::const_iterator it(grad->stops.begin()); 1567 GradientStopCont::const_iterator end(grad->stops.end()); 1568 int numStops(grad->stops.size()); 1569 1570 for (int i = 0;it != end;++it, ++i) { 1571 QColor col; 1572 1573 if ((topTab || botTab || dwt || titleBar) && i == numStops-1) { 1574 if (titleBar) { 1575 col = m_backgroundCols[ORIGINAL_SHADE]; 1576 col.setAlphaF(0.0); 1577 } else { 1578 col = base; 1579 if ((sel && opts.tabBgnd == 0 && !reverse) || dwt) { 1580 col.setAlphaF(0.0); 1581 } 1582 } 1583 } else { 1584 shade(base, &col, botTab && opts.invertBotTab ? 1585 qMax(INVERT_SHADE((*it).val), 0.9) : (*it).val); 1586 } 1587 if (w != WIDGET_TOOLTIP && (*it).alpha < 1.0) { 1588 col.setAlphaF(col.alphaF() * (*it).alpha); 1589 } 1590 g.setColorAt(botTab ? 1.0 - (*it).pos : (*it).pos, col); 1591 } 1592 1593 if (app == APPEARANCE_AGUA && !(topTab || botTab || dwt) && 1594 (horiz ? r.height() : r.width()) > AGUA_MAX) { 1595 QColor col; 1596 double pos = AGUA_MAX/((horiz ? r.height() : r.width())*2.0); 1597 shade(base, &col, AGUA_MID_SHADE); 1598 g.setColorAt(pos, col); 1599 g.setColorAt(1.0-pos, col); 1600 } 1601 1602 //p->fillRect(r, base); 1603 if (path.isEmpty()) { 1604 p->fillRect(r, QBrush(g)); 1605 } else { 1606 p->fillPath(path, QBrush(g)); 1607 } 1608 } 1609 1610 void Style::drawSunkenBevel(QPainter *p, const QRect &r, const QColor &col) const 1611 { 1612 double radius=opts.titlebarButtons&TITLEBAR_BUTTON_ROUND 1613 ? r.height()/2.0 1614 : opts.round>ROUND_FULL 1615 ? 5.0 1616 : opts.round>ROUND_SLIGHT 1617 ? 3.0 1618 : 2.0; 1619 QPainterPath path(buildPath(QRectF(r), WIDGET_OTHER, ROUNDED_ALL, radius)); 1620 QLinearGradient g(r.topLeft(), r.bottomLeft()); 1621 QColor black(Qt::black), 1622 white(Qt::white); 1623 1624 black.setAlphaF(SUNKEN_BEVEL_DARK_ALPHA(col)); 1625 white.setAlphaF(SUNKEN_BEVEL_LIGHT_ALPHA(col)); 1626 g.setColorAt(0, black); 1627 g.setColorAt(1, white); 1628 p->save(); 1629 p->setRenderHint(QPainter::Antialiasing, true); 1630 p->fillPath(path, QBrush(g)); 1631 p->restore(); 1632 } 1633 1634 void 1635 Style::drawLightBevel(QPainter *p, const QRect &r, const QStyleOption *option, 1636 const QWidget *widget, int round, const QColor &fill, 1637 const QColor *custom, bool doBorder, EWidget w) const 1638 { 1639 bool onToolbar = (opts.tbarBtnAppearance != APPEARANCE_NONE && 1640 (w == WIDGET_TOOLBAR_BUTTON || 1641 (WIDGET_BUTTON(w) && isOnToolbar(widget)))); 1642 1643 if (oneOf(w, WIDGET_PROGRESSBAR, WIDGET_SB_BUTTON) || 1644 (w == WIDGET_SPIN && !opts.unifySpin)/* || !m_usePixmapCache*/) { 1645 drawLightBevelReal(p, r, option, widget, round, fill, custom, 1646 doBorder, w, true, opts.round, onToolbar); 1647 } else { 1648 static const int constMaxCachePixmap = 128; 1649 1650 int endSize = 0; 1651 int middleSize = 8; 1652 bool horiz = (CIRCULAR_SLIDER(w) || 1653 isHoriz(option, w, opts.tbarBtns == TBTN_JOINED)); 1654 bool circular = ((w == WIDGET_MDI_WINDOW_BUTTON && 1655 (opts.titlebarButtons & TITLEBAR_BUTTON_ROUND)) || 1656 oneOf(w, WIDGET_RADIO_BUTTON, WIDGET_DIAL) || 1657 CIRCULAR_SLIDER(w)); 1658 double radius = 0; 1659 ERound realRound = qtcGetWidgetRound(&opts, r.width(), r.height(), w); 1660 1661 if (!circular) { 1662 switch (realRound) { 1663 case ROUND_SLIGHT: 1664 case ROUND_NONE: 1665 case ROUND_FULL: 1666 endSize = (SLIDER(w) && opts.coloredMouseOver == MO_PLASTIK && 1667 option->state&State_MouseOver ? 9 : 5); 1668 break; 1669 case ROUND_EXTRA: 1670 endSize = 7; 1671 break; 1672 case ROUND_MAX: 1673 radius = qtcGetRadius(&opts, r.width(), r.height(), 1674 w, RADIUS_ETCH); 1675 endSize = (SLIDER(w) ? qMax((opts.sliderWidth / 2) + 1, 1676 int(radius + 1.5)) : 1677 int(radius + 2.5)); 1678 middleSize = MIN_ROUND_MAX_WIDTH - (endSize * 2) + 4; 1679 if (middleSize < 4) 1680 middleSize = 4; 1681 break; 1682 } 1683 } 1684 1685 int size = 2 * endSize + middleSize; 1686 1687 if (size > constMaxCachePixmap) { 1688 drawLightBevelReal(p, r, option, widget, round, fill, custom, 1689 doBorder, w, true, realRound, onToolbar); 1690 } else { 1691 bool small(circular || (horiz ? r.width() : r.height())<(2*endSize)); 1692 QPixmap pix; 1693 const QSize pixSize(small ? QSize(r.width(), r.height()) : 1694 QSize(horiz ? size : r.width(), 1695 horiz ? r.height() : size)); 1696 uint state(option->state&(State_Raised|State_Sunken|State_On|State_Horizontal|State_HasFocus|State_MouseOver| 1697 (WIDGET_MDI_WINDOW_BUTTON==w ? State_Active : State_None))); 1698 1699 QString key = QStringLiteral("qtc-%1-%2-%3-%4-%5-%6-%7-%8-%9") 1700 .arg(w, 0, 16).arg(onToolbar ? 1 : 0, 0, 16).arg(round, 0, 16) 1701 .arg((int)realRound, 0, 16).arg(pixSize.width(), 0, 16) 1702 .arg(pixSize.height(), 0, 16) 1703 .arg(state, 0, 16).arg(fill.rgba(), 0, 16).arg((int)(radius * 100), 0, 16); 1704 if (!m_usePixmapCache || !QPixmapCache::find(key, &pix)) { 1705 pix = QPixmap(pixSize); 1706 pix.fill(Qt::transparent); 1707 1708 QPainter pixPainter(&pix); 1709 ERound oldRound = opts.round; 1710 opts.round = realRound; 1711 pixPainter.setRenderHint(QPainter::Antialiasing, true); 1712 drawLightBevelReal(&pixPainter, QRect(0, 0, pixSize.width(), 1713 pixSize.height()), option, 1714 widget, round, fill, custom, doBorder, w, 1715 false, realRound, onToolbar); 1716 opts.round = oldRound; 1717 pixPainter.end(); 1718 1719 if (m_usePixmapCache) { 1720 QPixmapCache::insert(key, pix); 1721 } 1722 } 1723 1724 if (small) { 1725 p->drawPixmap(r.topLeft(), pix); 1726 } else if (horiz) { 1727 int middle(qMin(r.width()-(2*endSize), middleSize)); 1728 if(middle>0) 1729 p->drawTiledPixmap(r.x()+endSize, r.y(), r.width()-(2*endSize), pix.height(), pix.copy(endSize, 0, middle, pix.height())); 1730 p->drawPixmap(r.x(), r.y(), pix.copy(0, 0, endSize, pix.height())); 1731 p->drawPixmap(r.x()+r.width()-endSize, r.y(), pix.copy(pix.width()-endSize, 0, endSize, pix.height())); 1732 } else { 1733 int middle(qMin(r.height()-(2*endSize), middleSize)); 1734 if (middle > 0) { 1735 p->drawTiledPixmap(r.x(), r.y() + endSize, pix.width(), 1736 r.height() - 2 * endSize, 1737 pix.copy(0, endSize, 1738 pix.width(), middle)); 1739 } 1740 p->drawPixmap(r.x(), r.y(), 1741 pix.copy(0, 0, pix.width(), endSize)); 1742 p->drawPixmap(r.x(), r.y() + r.height() - endSize, 1743 pix.copy(0, pix.height() - endSize, pix.width(), 1744 endSize)); 1745 } 1746 1747 if (w == WIDGET_SB_SLIDER && opts.stripedSbar) { 1748 QRect rx(r.adjusted(1, 1, -1, -1)); 1749 addStripes(p, buildPath(rx, WIDGET_SB_SLIDER, realRound, 1750 qtcGetRadius(&opts, rx.width() - 1, 1751 rx.height() - 1, 1752 WIDGET_SB_SLIDER, 1753 RADIUS_INTERNAL)), 1754 rx, horiz); 1755 } 1756 } 1757 } 1758 } 1759 1760 void 1761 Style::drawLightBevelReal(QPainter *p, const QRect &rOrig, 1762 const QStyleOption *option, const QWidget *widget, 1763 int round, const QColor &fill, const QColor *custom, 1764 bool doBorder, EWidget w, bool useCache, 1765 ERound realRound, bool onToolbar) const 1766 { 1767 EAppearance app(qtcWidgetApp(onToolbar ? WIDGET_TOOLBAR_BUTTON : w, 1768 &opts, option->state&State_Active)); 1769 QRect r(rOrig); 1770 bool bevelledButton((WIDGET_BUTTON(w) || WIDGET_NO_ETCH_BTN == w || 1771 WIDGET_MENU_BUTTON == w) && APPEARANCE_BEVELLED == app); 1772 bool sunken(option->state &(/*State_Down | */State_On | State_Sunken)); 1773 bool flatWidget((WIDGET_MDI_WINDOW_BUTTON==w && 1774 (opts.round==ROUND_MAX || 1775 opts.titlebarButtons&TITLEBAR_BUTTON_ROUND)) || 1776 (WIDGET_PROGRESSBAR==w && !opts.borderProgress)); 1777 bool lightBorder(!flatWidget && DRAW_LIGHT_BORDER(sunken, w, app)); 1778 bool draw3dfull(!flatWidget && !lightBorder && 1779 DRAW_3D_FULL_BORDER(sunken, app)); 1780 bool draw3d(!flatWidget && (draw3dfull || 1781 (!lightBorder && DRAW_3D_BORDER(sunken, app)))); 1782 bool drawShine(DRAW_SHINE(sunken, app)); 1783 bool doColouredMouseOver(doBorder && option->state&State_Enabled && 1784 WIDGET_MDI_WINDOW_BUTTON!=w && WIDGET_SPIN!=w && 1785 WIDGET_COMBO_BUTTON!=w && WIDGET_SB_BUTTON!=w && 1786 (!SLIDER(w) || !opts.colorSliderMouseOver) && 1787 !(option->state&STATE_KWIN_BUTTON) && 1788 (opts.coloredTbarMo || 1789 !(option->state&STATE_TBAR_BUTTON)) && 1790 opts.coloredMouseOver && 1791 option->state&State_MouseOver && 1792 WIDGET_PROGRESSBAR!=w && 1793 (option->state&STATE_TOGGLE_BUTTON || !sunken)); 1794 bool plastikMouseOver(doColouredMouseOver && 1795 MO_PLASTIK==opts.coloredMouseOver); 1796 bool colouredMouseOver(doColouredMouseOver && WIDGET_MENU_BUTTON!=w && 1797 (MO_COLORED==opts.coloredMouseOver || 1798 MO_COLORED_THICK==opts.coloredMouseOver || 1799 (MO_GLOW==opts.coloredMouseOver && 1800 !(opts.buttonEffect != EFFECT_NONE)))), 1801 doEtch(doBorder && ETCH_WIDGET(w) && opts.buttonEffect != EFFECT_NONE), 1802 glowFocus(doEtch && USE_GLOW_FOCUS(option->state&State_MouseOver) && option->state&State_HasFocus && 1803 option->state&State_Enabled), 1804 horiz(CIRCULAR_SLIDER(w) || isHoriz(option, w, TBTN_JOINED==opts.tbarBtns)), 1805 sunkenToggleMo(sunken && !(option->state&State_Sunken) && option->state&(State_MouseOver|STATE_TOGGLE_BUTTON)); 1806 const QColor *cols(custom ? custom : m_backgroundCols), 1807 *border(colouredMouseOver ? borderColors(option, cols) : cols); 1808 1809 p->save(); 1810 1811 if (doEtch) 1812 r.adjust(1, 1, -1, -1); 1813 1814 if (WIDGET_TROUGH == w && !opts.borderSbarGroove) 1815 doBorder = false; 1816 1817 p->setRenderHint(QPainter::Antialiasing, true); 1818 1819 if (r.width() > 0 && r.height() > 0) { 1820 if (w == WIDGET_PROGRESSBAR && opts.stripedProgress != STRIPE_NONE) { 1821 drawProgressBevelGradient(p, opts.borderProgress ? 1822 r.adjusted(1, 1, -1, -1) : r, 1823 option, horiz, app, custom); 1824 } else { 1825 drawBevelGradient(fill, p, WIDGET_PROGRESSBAR==w && opts.borderProgress ? r.adjusted(1, 1, -1, -1) : r, 1826 doBorder 1827 ? buildPath(r, w, round, qtcGetRadius(&opts, r.width()-2, r.height()-2, w, RADIUS_INTERNAL)) 1828 : buildPath(QRectF(r), w, round, qtcGetRadius(&opts, r.width(), r.height(), w, RADIUS_EXTERNAL)), 1829 horiz, sunken, app, w, useCache); 1830 1831 if(!sunken || sunkenToggleMo) 1832 if(plastikMouseOver) // && !sunken) 1833 { 1834 p->save(); 1835 p->setClipPath(buildPath(r.adjusted(0, 0, 0, -1), w, round, 1836 qtcGetRadius(&opts, r.width()-2, r.height()-2, w, RADIUS_INTERNAL))); 1837 if (SLIDER(w)) { 1838 int len = sbSliderMOLen(opts, horiz ? r.width() : 1839 r.height()) + 1; 1840 int so = lightBorder ? SLIDER_MO_PLASTIK_BORDER : 1; 1841 int eo = len + so; 1842 int col = SLIDER_MO_SHADE; 1843 1844 if (horiz) { 1845 drawBevelGradient(m_mouseOverCols[col], p, QRect(r.x()+so-1, r.y(), len, r.height()-1), horiz, sunken, app, w, useCache); 1846 drawBevelGradient(m_mouseOverCols[col], p, QRect(r.x()+r.width()-eo+1, r.y(), len, r.height()-1), horiz, sunken, app, w, useCache); 1847 } 1848 else 1849 { 1850 drawBevelGradient(m_mouseOverCols[col], p, QRect(r.x(), r.y()+so-1, r.width()-1, len), horiz, sunken, app, w, useCache); 1851 drawBevelGradient(m_mouseOverCols[col], p, QRect(r.x(), r.y()+r.height()-eo+1, r.width()-1, len), horiz, sunken, app, w, useCache); 1852 } 1853 } 1854 else 1855 { 1856 bool horizontal((horiz && WIDGET_SB_BUTTON!=w)|| (!horiz && WIDGET_SB_BUTTON==w)), 1857 thin(WIDGET_SB_BUTTON==w || WIDGET_SPIN==w || ((horiz ? r.height() : r.width())<16)); 1858 1859 setPainterPen(p, m_mouseOverCols[MO_PLASTIK_DARK(w)], QPENWIDTH1); 1860 if(horizontal) 1861 { 1862 drawAaLine(p, r.x()+1, r.y()+1, r.x()+r.width()-2, r.y()+1); 1863 drawAaLine(p, r.x()+1, r.y()+r.height()-2, r.x()+r.width()-2, r.y()+r.height()-2); 1864 } 1865 else 1866 { 1867 drawAaLine(p, r.x()+1, r.y()+1, r.x()+1, r.y()+r.height()-2); 1868 drawAaLine(p, r.x()+r.width()-2, r.y()+1, r.x()+r.width()-2, r.y()+r.height()-2); 1869 } 1870 if(!thin) 1871 { 1872 setPainterPen(p, m_mouseOverCols[MO_PLASTIK_LIGHT(w)], QPENWIDTH1); 1873 if(horizontal) 1874 { 1875 drawAaLine(p, r.x()+1, r.y()+2, r.x()+r.width()-2, r.y()+2); 1876 drawAaLine(p, r.x()+1, r.y()+r.height()-3, r.x()+r.width()-2, r.y()+r.height()-3); 1877 } 1878 else 1879 { 1880 drawAaLine(p, r.x()+2, r.y()+1, r.x()+2, r.y()+r.height()-2); 1881 drawAaLine(p, r.x()+r.width()-3, r.y()+1, r.x()+r.width()-3, r.y()+r.height()-2); 1882 } 1883 } 1884 } 1885 p->restore(); 1886 } 1887 } 1888 1889 if(drawShine) 1890 { 1891 bool mo(option->state&State_Enabled && option->state&State_MouseOver && opts.highlightFactor); 1892 QColor white(Qt::white); 1893 1894 if(WIDGET_MDI_WINDOW_BUTTON==w || WIDGET_RADIO_BUTTON==w || CIRCULAR_SLIDER(w)) 1895 { 1896 QRectF ra(r.x()+0.5, r.y()+0.5, r.width(), r.height()); 1897 double topSize=(ra.height()*0.4), 1898 topWidthAdjust=WIDGET_RADIO_BUTTON==w || WIDGET_SLIDER==w ? 4 : 4.75; 1899 QRectF topGradRect(ra.x()+topWidthAdjust, ra.y(), 1900 ra.width()-(topWidthAdjust*2)-1, topSize-1); 1901 QLinearGradient topGrad(topGradRect.topLeft(), topGradRect.bottomLeft()); 1902 1903 white.setAlphaF(mo ? (opts.highlightFactor>0 ? 0.8 : 0.7) : 0.75); 1904 topGrad.setColorAt(0.0, white); 1905 white.setAlphaF(/*mo ? (opts.highlightFactor>0 ? 0.3 : 0.1) : */0.2); 1906 topGrad.setColorAt(1.0, white); 1907 p->fillPath(buildPath(topGradRect, w, round, topSize), QBrush(topGrad)); 1908 } 1909 else 1910 { 1911 QRectF ra(r.x()+0.5, r.y()+0.5, r.width(), r.height()); 1912 double size = qtcMin((horiz ? ra.height() : ra.width()) / 2.0, 1913 16), 1914 rad=size/2.0; 1915 int mod=4; 1916 1917 if(horiz) 1918 { 1919 if(!(ROUNDED_LEFT&round)) 1920 ra.adjust(-8, 0, 0, 0); 1921 if(!(ROUNDED_RIGHT&round)) 1922 ra.adjust(0, 0, 8, 0); 1923 } 1924 else 1925 { 1926 if(!(ROUNDED_TOP&round)) 1927 ra.adjust(0, -8, 0, 0); 1928 if(!(ROUNDED_BOTTOM&round)) 1929 ra.adjust(0, 0, 0, 8); 1930 } 1931 1932 if (realRound < ROUND_MAX || 1933 (!isMaxRoundWidget(w) && !IS_SLIDER(w))) { 1934 rad /= 2.0; 1935 mod = mod >> 1; 1936 } 1937 1938 QRectF gr(horiz ? QRectF(ra.x()+mod, ra.y(), ra.width()-(mod*2)-1, size-1) 1939 : QRectF(ra.x(), ra.y()+mod, size-1, ra.height()-(mod*2)-1)); 1940 QLinearGradient g(gr.topLeft(), horiz ? gr.bottomLeft() : gr.topRight()); 1941 1942 white.setAlphaF(mo ? (opts.highlightFactor>0 ? 0.95 : 0.85) : 0.9); 1943 g.setColorAt(0.0, white); 1944 white.setAlphaF(mo ? (opts.highlightFactor>0 ? 0.3 : 0.1) : 0.2); 1945 g.setColorAt(1.0, white); 1946 if(WIDGET_SB_BUTTON==w) 1947 { 1948 p->save(); 1949 p->setClipRect(r); 1950 } 1951 p->fillPath(buildPath(gr, w, round, rad), QBrush(g)); 1952 if(WIDGET_SB_BUTTON==w) 1953 p->restore(); 1954 } 1955 } 1956 } 1957 1958 r.adjust(1, 1, -1, -1); 1959 1960 if (plastikMouseOver && (!sunken || sunkenToggleMo)) { 1961 bool thin = (oneOf(w, WIDGET_SB_BUTTON, WIDGET_SPIN) || 1962 (horiz ? r.height() : r.width()) < 16); 1963 bool horizontal = (SLIDER(w) ? !horiz : 1964 (horiz && w != WIDGET_SB_BUTTON) || 1965 (!horiz && w == WIDGET_SB_BUTTON)); 1966 int len = SLIDER(w) ? sbSliderMOLen(opts, horiz ? r.width() : 1967 r.height()) : (thin ? 1 : 2); 1968 1969 p->save(); 1970 if (horizontal) { 1971 p->setClipRect(r.x(), r.y() + len, r.width(), r.height() - len * 2); 1972 } else { 1973 p->setClipRect(r.x() + len, r.y(), r.width() - len * 2, r.height()); 1974 } 1975 } 1976 1977 if (!colouredMouseOver && lightBorder) { 1978 setPainterPen(p, cols[LIGHT_BORDER(app)], QPENWIDTH1); 1979 p->drawPath(buildPath(r, w, round, 1980 qtcGetRadius(&opts, r.width(), 1981 r.height(), w, RADIUS_INTERNAL))); 1982 } else if (colouredMouseOver || (draw3d && option->state & State_Raised)) { 1983 QPainterPath innerTlPath; 1984 QPainterPath innerBrPath; 1985 int dark(/*bevelledButton ? */2/* : 4*/); 1986 1987 buildSplitPath(r, round, qtcGetRadius(&opts, r.width(), r.height(), w, RADIUS_INTERNAL), 1988 innerTlPath, innerBrPath); 1989 1990 setPainterPen(p, border[colouredMouseOver ? MO_STD_LIGHT(w, sunken) : (sunken ? dark : 0)], QPENWIDTH1); 1991 p->drawPath(innerTlPath); 1992 if(colouredMouseOver || bevelledButton || draw3dfull) 1993 { 1994 setPainterPen(p, border[colouredMouseOver ? MO_STD_DARK(w) : (sunken ? 0 : dark)], QPENWIDTH1); 1995 p->drawPath(innerBrPath); 1996 } 1997 } 1998 if(plastikMouseOver && (!sunken || sunkenToggleMo)) 1999 p->restore(); 2000 QPAINTER_RENDERHINT_AA_MAYBE_OFF(p); 2001 2002 if(doEtch || glowFocus) 2003 { 2004 if( !(opts.thin&THIN_FRAMES) && (!sunken || sunkenToggleMo || 2005 (sunken && glowFocus && widget && qobject_cast<const QAbstractButton *>(widget) && 2006 static_cast<const QAbstractButton *>(widget)->isCheckable())) && 2007 ((WIDGET_OTHER!=w && WIDGET_SLIDER_TROUGH!=w && MO_GLOW==opts.coloredMouseOver && option->state&State_MouseOver) || 2008 (WIDGET_DEF_BUTTON==w && IND_GLOW==opts.defBtnIndicator) || 2009 glowFocus) ) 2010 drawGlow(p, rOrig, WIDGET_DEF_BUTTON==w && option->state&State_MouseOver ? WIDGET_STD_BUTTON : w, 2011 glowFocus ? m_focusCols : 0L); 2012 else 2013 drawEtch(p, rOrig, widget, w, EFFECT_SHADOW==opts.buttonEffect && WIDGET_BUTTON(w) && !sunken); 2014 } 2015 2016 if(doBorder) 2017 { 2018 const QColor *borderCols=glowFocus || ( (WIDGET_COMBO==w || WIDGET_MENU_BUTTON==w || (WIDGET_NO_ETCH_BTN==w && ROUNDED_ALL!=round)) && 2019 USE_GLOW_FOCUS(option->state&State_MouseOver) && 2020 option->state&State_HasFocus && option->state&State_Enabled) 2021 ? m_focusCols 2022 : (WIDGET_COMBO==w || WIDGET_COMBO_BUTTON==w) && border==m_comboBtnCols 2023 ? option->state&State_MouseOver && MO_GLOW==opts.coloredMouseOver && !sunken 2024 ? m_mouseOverCols 2025 : m_buttonCols 2026 : cols; 2027 2028 r.adjust(-1, -1, 1, 1); 2029 if(!sunken && option->state&State_Enabled && !glowFocus && 2030 ( ( ( (doEtch && WIDGET_OTHER!=w && WIDGET_SLIDER_TROUGH!=w) || SLIDER(w) || WIDGET_COMBO==w || WIDGET_MENU_BUTTON==w ) && 2031 (MO_GLOW==opts.coloredMouseOver/* || MO_COLORED==opts.colorMenubarMouseOver*/) && option->state&State_MouseOver) || 2032 glowFocus || (doEtch && WIDGET_DEF_BUTTON==w && IND_GLOW==opts.defBtnIndicator))) 2033 drawBorder(p, r, option, round, 2034 WIDGET_DEF_BUTTON==w && IND_GLOW==opts.defBtnIndicator && !(option->state&State_MouseOver) 2035 ? m_defBtnCols : m_mouseOverCols, w); 2036 else 2037 drawBorder(p, r, option, round, 2038 colouredMouseOver && MO_COLORED_THICK==opts.coloredMouseOver ? m_mouseOverCols : borderCols, w); 2039 } 2040 2041 p->restore(); 2042 } 2043 2044 void Style::drawGlow(QPainter *p, const QRect &r, EWidget w, const QColor *cols) const 2045 { 2046 bool def(WIDGET_DEF_BUTTON==w && IND_GLOW==opts.defBtnIndicator), 2047 defShade=def && (!m_defBtnCols || 2048 (m_defBtnCols[ORIGINAL_SHADE]==m_mouseOverCols[ORIGINAL_SHADE])); 2049 QColor col(cols ? cols[GLOW_MO] 2050 : def && m_defBtnCols 2051 ? m_defBtnCols[GLOW_DEFBTN] : m_mouseOverCols[GLOW_MO]); 2052 2053 col.setAlphaF(GLOW_ALPHA(defShade)); 2054 p->setBrush(Qt::NoBrush); 2055 p->setRenderHint(QPainter::Antialiasing, true); 2056 setPainterPen(p, col, QPENWIDTH1); 2057 p->drawPath(buildPath(r, w, ROUNDED_ALL, qtcGetRadius(&opts, r.width(), r.height(), w, RADIUS_ETCH))); 2058 QPAINTER_RENDERHINT_AA_MAYBE_OFF(p); 2059 } 2060 2061 void Style::drawEtch(QPainter *p, const QRect &r, const QWidget *widget, EWidget w, bool raised, int round) const 2062 { 2063 QPainterPath tl, 2064 br; 2065 QColor col(Qt::black); 2066 2067 if(WIDGET_TOOLBAR_BUTTON==w && EFFECT_ETCH==opts.tbarBtnEffect) 2068 raised=false; 2069 2070 buildSplitPath(r, round, qtcGetRadius(&opts, r.width(), r.height(), w, RADIUS_ETCH), tl, br); 2071 2072 col.setAlphaF(USE_CUSTOM_ALPHAS(opts) ? opts.customAlphas[ALPHA_ETCH_DARK] : ETCH_TOP_ALPHA); 2073 p->setBrush(Qt::NoBrush); 2074 p->setRenderHint(QPainter::Antialiasing, true); 2075 setPainterPen(p, col, QPENWIDTH1); 2076 2077 if(!raised && WIDGET_SLIDER!=w) 2078 { 2079 p->drawPath(tl); 2080 if(WIDGET_SLIDER_TROUGH==w && opts.thinSbarGroove && widget && qobject_cast<const QScrollBar *>(widget)) 2081 { 2082 QColor col(Qt::white); 2083 col.setAlphaF(USE_CUSTOM_ALPHAS(opts) ? opts.customAlphas[ALPHA_ETCH_LIGHT] : ETCH_BOTTOM_ALPHA); // 0.25); 2084 setPainterPen(p, col, QPENWIDTH1); 2085 } 2086 else 2087 setPainterPen(p, getLowerEtchCol(widget), QPENWIDTH1); 2088 } 2089 2090 p->drawPath(br); 2091 QPAINTER_RENDERHINT_AA_MAYBE_OFF(p); 2092 } 2093 2094 void Style::drawBgndRing(QPainter &painter, int x, int y, int size, int size2, bool isWindow) const 2095 { 2096 double width=(size-size2)/2.0, 2097 width2=width/2.0; 2098 QColor col(Qt::white); 2099 2100 col.setAlphaF(RINGS_INNER_ALPHA(isWindow ? opts.bgndImage.type : opts.menuBgndImage.type)); 2101 if (width == 1) { 2102 width = QPENWIDTH1; 2103 } 2104 painter.setPen(QPen(col, width)); 2105 painter.drawEllipse(QRectF(x+width2, y+width2, size-width, size-width)); 2106 2107 if(IMG_BORDERED_RINGS==(isWindow ? opts.bgndImage.type : opts.menuBgndImage.type)) 2108 { 2109 col.setAlphaF(RINGS_OUTER_ALPHA); 2110 painter.setPen(QPen(col, QPENWIDTH1)); 2111 painter.drawEllipse(QRectF(x, y, size, size)); 2112 if(size2) 2113 painter.drawEllipse(QRectF(x+width, y+width, size2, size2)); 2114 } 2115 } 2116 2117 QPixmap Style::drawStripes(const QColor &color, int opacity) const 2118 { 2119 QPixmap pix; 2120 QColor col(color); 2121 2122 if(100!=opacity) 2123 col.setAlphaF(opacity/100.0); 2124 2125 QString key = QStringLiteral("qtc-stripes-%1").arg(col.rgba(), 0, 16); 2126 if(!m_usePixmapCache || !QPixmapCache::find(key, &pix)) 2127 { 2128 pix=QPixmap(QSize(64, 64)); 2129 2130 if(100!=opacity) 2131 pix.fill(Qt::transparent); 2132 2133 QPainter pixPainter(&pix); 2134 QColor col2(shade(col, BGND_STRIPE_SHADE)); 2135 2136 if(100!=opacity) 2137 { 2138 col2.setAlphaF(opacity/100.0); 2139 pixPainter.setPen(QPen(col, QPENWIDTH1)); 2140 for(int i=0; i<pix.height(); i+=4) 2141 pixPainter.drawLine(0, i, pix.width()-1, i); 2142 } 2143 else 2144 pixPainter.fillRect(pix.rect(), col); 2145 pixPainter.setPen(QPen(QColor((3*col.red()+col2.red())/4, 2146 (3*col.green()+col2.green())/4, 2147 (3*col.blue()+col2.blue())/4, 2148 100!=opacity ? col2.alpha() : 255), QPENWIDTH1)); 2149 2150 for(int i=1; i<pix.height(); i+=4) 2151 { 2152 pixPainter.drawLine(0, i, pix.width()-1, i); 2153 pixPainter.drawLine(0, i+2, pix.width()-1, i+2); 2154 } 2155 pixPainter.setPen(QPen(col2, QPENWIDTH1)); 2156 for(int i=2; i<pix.height()-1; i+=4) 2157 pixPainter.drawLine(0, i, pix.width()-1, i); 2158 2159 if(m_usePixmapCache) 2160 QPixmapCache::insert(key, pix); 2161 } 2162 2163 return pix; 2164 } 2165 2166 void 2167 Style::drawBackground(QPainter *p, const QColor &bgnd, const QRect &r, 2168 int opacity, BackgroundType type, EAppearance app, 2169 const QPainterPath &path) const 2170 { 2171 bool isWindow = type != BGND_MENU; 2172 2173 if (!qtcIsFlatBgnd(app)) { 2174 static const int constPixmapWidth = 16; 2175 static const int constPixmapHeight = 512; 2176 2177 QColor col(bgnd); 2178 QPixmap pix; 2179 QSize scaledSize; 2180 EGradType grad = isWindow ? opts.bgndGrad : opts.menuBgndGrad; 2181 2182 if (app == APPEARANCE_STRIPED) { 2183 pix = drawStripes(col, opacity); 2184 } else if (app == APPEARANCE_FILE) { 2185 pix = isWindow ? opts.bgndPixmap.img : opts.menuBgndPixmap.img; 2186 } else { 2187 scaledSize = QSize(grad == GT_HORIZ ? constPixmapWidth : r.width(), 2188 grad == GT_HORIZ ? r.height() : 2189 constPixmapWidth); 2190 2191 if (opacity != 100) 2192 col.setAlphaF(opacity / 100.0); 2193 2194 QString key = QStringLiteral("qtc-bgnd-%1-%2-%3") 2195 .arg(col.rgba(), 0, 16).arg(grad).arg(app); 2196 if (!m_usePixmapCache || !QPixmapCache::find(key, &pix)) { 2197 pix = QPixmap(QSize(grad == GT_HORIZ ? constPixmapWidth : 2198 constPixmapHeight, grad == GT_HORIZ ? 2199 constPixmapHeight : constPixmapWidth)); 2200 pix.fill(Qt::transparent); 2201 2202 QPainter pixPainter(&pix); 2203 drawBevelGradientReal(col, &pixPainter, 2204 QRect(0, 0, pix.width(), pix.height()), 2205 grad == GT_HORIZ, false, app, 2206 WIDGET_OTHER); 2207 pixPainter.end(); 2208 if (m_usePixmapCache) { 2209 QPixmapCache::insert(key, pix); 2210 } 2211 } 2212 } 2213 2214 if (path.isEmpty()) { 2215 p->drawTiledPixmap(r, oneOf(app, APPEARANCE_STRIPED, 2216 APPEARANCE_FILE) || 2217 scaledSize == pix.size() ? pix : 2218 pix.scaled(scaledSize, Qt::IgnoreAspectRatio)); 2219 } else { 2220 p->save(); 2221 p->setBrushOrigin(r.x(), r.y()); 2222 p->fillPath(path, 2223 QBrush(oneOf(app, APPEARANCE_STRIPED, 2224 APPEARANCE_FILE) || 2225 scaledSize == pix.size() ? pix : 2226 pix.scaled(scaledSize, Qt::IgnoreAspectRatio))); 2227 p->restore(); 2228 } 2229 2230 if (isWindow && noneOf(app, APPEARANCE_STRIPED, APPEARANCE_FILE) && 2231 grad == GT_HORIZ && 2232 qtcGetGradient(app, &opts)->border == GB_SHINE) { 2233 int size = qMin(BGND_SHINE_SIZE, qMin(r.height() * 2, r.width())); 2234 QString key = QStringLiteral("qtc-radial-%1").arg(size / BGND_SHINE_STEPS, 0, 16); 2235 if (!m_usePixmapCache || !QPixmapCache::find(key, &pix)) { 2236 size /= BGND_SHINE_STEPS; 2237 size *= BGND_SHINE_STEPS; 2238 pix = QPixmap(size, size / 2); 2239 pix.fill(Qt::transparent); 2240 QRadialGradient gradient(QPointF(pix.width() / 2.0, 0), 2241 pix.width() / 2.0, 2242 QPointF(pix.width() / 2.0, 0)); 2243 QColor c(Qt::white); 2244 double alpha = qtcShineAlpha(&col); 2245 2246 c.setAlphaF(alpha); 2247 gradient.setColorAt(0, c); 2248 c.setAlphaF(alpha * 0.625); 2249 gradient.setColorAt(0.5, c); 2250 c.setAlphaF(alpha * 0.175); 2251 gradient.setColorAt(0.75, c); 2252 c.setAlphaF(0); 2253 gradient.setColorAt(1, c); 2254 QPainter pixPainter(&pix); 2255 pixPainter.fillRect(QRect(0, 0, pix.width(), pix.height()), 2256 gradient); 2257 pixPainter.end(); 2258 if (m_usePixmapCache) { 2259 QPixmapCache::insert(key, pix); 2260 } 2261 } 2262 p->drawPixmap(r.x() + ((r.width() - pix.width()) / 2), r.y(), pix); 2263 } 2264 } else { 2265 QColor col(bgnd); 2266 if (opacity != 100) { 2267 col.setAlphaF(opacity / 100.0); 2268 } 2269 if (path.isEmpty()) { 2270 p->fillRect(r, col); 2271 } else { 2272 p->save(); 2273 p->setBrushOrigin(r.x(), r.y()); 2274 p->fillPath(path, col); 2275 p->restore(); 2276 } 2277 } 2278 } 2279 2280 void 2281 Style::drawBackgroundImage(QPainter *p, bool isWindow, const QRect &r) const 2282 { 2283 QtCImage &img = isWindow ? opts.bgndImage : opts.menuBgndImage; 2284 int imgWidth = img.type == IMG_FILE ? img.width : RINGS_WIDTH(img.type); 2285 int imgHeight = img.type == IMG_FILE ? img.height : RINGS_HEIGHT(img.type); 2286 2287 switch (img.type) { 2288 case IMG_NONE: 2289 break; 2290 case IMG_FILE: 2291 qtcLoadBgndImage(&img); 2292 if (!img.pixmap.img.isNull()) { 2293 switch (img.pos) { 2294 case PP_TL: 2295 p->drawPixmap(r.x(), r.y(), img.pixmap.img); 2296 break; 2297 case PP_TM: 2298 p->drawPixmap(r.x() + (r.width() - img.pixmap.img.width()) / 2, 2299 r.y(), img.pixmap.img); 2300 break; 2301 default: 2302 case PP_TR: 2303 p->drawPixmap(r.right() - img.pixmap.img.width(), r.y(), 2304 img.pixmap.img); 2305 break; 2306 case PP_BL: 2307 p->drawPixmap(r.x(), r.bottom() - img.pixmap.img.height(), 2308 img.pixmap.img); 2309 break; 2310 case PP_BM: 2311 p->drawPixmap(r.x() + (r.width() - img.pixmap.img.width()) / 2, 2312 r.bottom() - img.pixmap.img.height(), 2313 img.pixmap.img); 2314 break; 2315 case PP_BR: 2316 p->drawPixmap(r.right() - img.pixmap.img.width(), 2317 r.bottom() - img.pixmap.img.height(), 2318 img.pixmap.img); 2319 break; 2320 case PP_LM: 2321 p->drawPixmap(r.left(), r.y() + (r.height() - 2322 img.pixmap.img.height()) / 2, 2323 img.pixmap.img); 2324 break; 2325 case PP_RM: 2326 p->drawPixmap(r.right() - img.pixmap.img.width(), 2327 r.y() + (r.height() - 2328 img.pixmap.img.height()) / 2, 2329 img.pixmap.img); 2330 break; 2331 case PP_CENTRED: 2332 p->drawPixmap(r.x() + (r.width() - img.pixmap.img.width()) / 2, 2333 r.y() + (r.height() - 2334 img.pixmap.img.height()) / 2, 2335 img.pixmap.img); 2336 } 2337 } 2338 break; 2339 case IMG_PLAIN_RINGS: 2340 case IMG_BORDERED_RINGS: 2341 if (img.pixmap.img.isNull()) { 2342 img.pixmap.img = QPixmap(imgWidth, imgHeight); 2343 img.pixmap.img.fill(Qt::transparent); 2344 QPainter pixPainter(&img.pixmap.img); 2345 2346 pixPainter.setRenderHint(QPainter::Antialiasing); 2347 drawBgndRing(pixPainter, 0, 0, 200, 140, isWindow); 2348 2349 drawBgndRing(pixPainter, 210, 10, 230, 214, isWindow); 2350 drawBgndRing(pixPainter, 226, 26, 198, 182, isWindow); 2351 drawBgndRing(pixPainter, 300, 100, 50, 0, isWindow); 2352 2353 drawBgndRing(pixPainter, 100, 96, 160, 144, isWindow); 2354 drawBgndRing(pixPainter, 116, 112, 128, 112, isWindow); 2355 2356 drawBgndRing(pixPainter, 250, 160, 200, 140, isWindow); 2357 drawBgndRing(pixPainter, 310, 220, 80, 0, isWindow); 2358 pixPainter.end(); 2359 } 2360 p->drawPixmap(r.right() - img.pixmap.img.width(), 2361 r.y() + 1, img.pixmap.img); 2362 break; 2363 case IMG_SQUARE_RINGS: 2364 if (img.pixmap.img.isNull()) { 2365 img.pixmap.img = QPixmap(imgWidth, imgHeight); 2366 img.pixmap.img.fill(Qt::transparent); 2367 QPainter pixPainter(&img.pixmap.img); 2368 QColor col(Qt::white); 2369 double halfWidth = RINGS_SQUARE_LINE_WIDTH / 2.0; 2370 2371 col.setAlphaF(RINGS_SQUARE_SMALL_ALPHA); 2372 pixPainter.setRenderHint(QPainter::Antialiasing); 2373 pixPainter.setPen(QPen(col, RINGS_SQUARE_LINE_WIDTH, Qt::SolidLine, 2374 Qt::SquareCap, Qt::RoundJoin)); 2375 pixPainter.drawPath(buildPath(QRectF(halfWidth + 0.5, 2376 halfWidth + 0.5, 2377 RINGS_SQUARE_SMALL_SIZE, 2378 RINGS_SQUARE_SMALL_SIZE), 2379 WIDGET_OTHER, ROUNDED_ALL, 2380 RINGS_SQUARE_RADIUS)); 2381 pixPainter.drawPath(buildPath(QRectF(halfWidth + 0.5 + 2382 (imgWidth - 2383 (RINGS_SQUARE_SMALL_SIZE + 2384 RINGS_SQUARE_LINE_WIDTH)), 2385 halfWidth + 0.5 + 2386 (imgHeight - 2387 (RINGS_SQUARE_SMALL_SIZE + 2388 RINGS_SQUARE_LINE_WIDTH)), 2389 RINGS_SQUARE_SMALL_SIZE, 2390 RINGS_SQUARE_SMALL_SIZE), 2391 WIDGET_OTHER, ROUNDED_ALL, 2392 RINGS_SQUARE_RADIUS)); 2393 col.setAlphaF(RINGS_SQUARE_LARGE_ALPHA); 2394 pixPainter.setPen(QPen(col, RINGS_SQUARE_LINE_WIDTH, Qt::SolidLine, 2395 Qt::SquareCap, Qt::RoundJoin)); 2396 pixPainter.drawPath(buildPath(QRectF(halfWidth + 0.5 + 2397 (imgWidth - 2398 RINGS_SQUARE_LARGE_SIZE - 2399 RINGS_SQUARE_LINE_WIDTH) / 2.0, 2400 halfWidth + 0.5 + 2401 (imgHeight - 2402 RINGS_SQUARE_LARGE_SIZE - 2403 RINGS_SQUARE_LINE_WIDTH) / 2.0, 2404 RINGS_SQUARE_LARGE_SIZE, 2405 RINGS_SQUARE_LARGE_SIZE), 2406 WIDGET_OTHER, ROUNDED_ALL, 2407 RINGS_SQUARE_RADIUS)); 2408 pixPainter.end(); 2409 } 2410 p->drawPixmap(r.right() - img.pixmap.img.width(), 2411 r.y() + 1, img.pixmap.img); 2412 break; 2413 } 2414 } 2415 2416 void 2417 Style::drawBackground(QPainter *p, const QWidget *widget, 2418 BackgroundType type) const 2419 { 2420 bool isWindow = type != BGND_MENU; 2421 bool previewMdi = (isWindow && m_isPreview && 2422 qobject_cast<const QMdiSubWindow*>(widget)); 2423 const QWidget *window = m_isPreview ? widget : widget->window(); 2424 int opacity = (type == BGND_MENU ? opts.menuBgndOpacity : 2425 type == BGND_DIALOG ? opts.dlgOpacity : opts.bgndOpacity); 2426 QRect bgndRect = widget->rect(); 2427 QRect imgRect = bgndRect; 2428 QtcQWidgetProps props(widget); 2429 2430 if (opacity != 100 && !(qobject_cast<const QMdiSubWindow*>(widget) || 2431 Utils::hasAlphaChannel(window))) { 2432 opacity = 100; 2433 } 2434 if (widget) { 2435 props->opacity = opacity; 2436 } 2437 2438 p->setClipRegion(widget->rect(), Qt::IntersectClip); 2439 2440 if (isWindow) { 2441 if (!previewMdi) { 2442 WindowBorders borders = qtcGetWindowBorderSize(false); 2443 bgndRect.adjust(-borders.sides, -borders.titleHeight, 2444 borders.sides, borders.bottom); 2445 } else { 2446 bgndRect.adjust(0, -pixelMetric(PM_TitleBarHeight, 2447 0L, widget), 0, 0); 2448 } 2449 if (opts.bgndImage.type == IMG_FILE && opts.bgndImage.onBorder) { 2450 imgRect = bgndRect; 2451 } 2452 } 2453 2454 drawBackground(p, (isWindow ? window->palette().window().color() : 2455 popupMenuCols()[ORIGINAL_SHADE]), bgndRect, opacity, 2456 type, (type != BGND_MENU ? opts.bgndAppearance : 2457 opts.menuBgndAppearance)); 2458 // FIXME, workaround only, the non transparent part of the image will have 2459 // a different overall opacity. 2460 p->save(); 2461 p->setCompositionMode(QPainter::CompositionMode_SourceOver); 2462 drawBackgroundImage(p, isWindow, imgRect); 2463 p->restore(); 2464 } 2465 2466 QPainterPath 2467 Style::buildPath(const QRectF &r, EWidget w, int round, double radius) const 2468 { 2469 QPainterPath path; 2470 2471 if (oneOf(w, WIDGET_RADIO_BUTTON, WIDGET_DIAL) || 2472 (w == WIDGET_MDI_WINDOW_BUTTON && 2473 opts.titlebarButtons & TITLEBAR_BUTTON_ROUND) || CIRCULAR_SLIDER(w)) { 2474 path.addEllipse(r); 2475 return path; 2476 } 2477 2478 if (opts.round == ROUND_NONE || radius < 0.01) { 2479 round = ROUNDED_NONE; 2480 } 2481 2482 double diameter = radius * 2; 2483 2484 if (w != WIDGET_MDI_WINDOW_TITLE && round & CORNER_BR) { 2485 path.moveTo(r.x() + r.width(), r.y() + r.height() - radius); 2486 } else { 2487 path.moveTo(r.x() + r.width(), r.y() + r.height()); 2488 } 2489 if (round & CORNER_TR) { 2490 path.arcTo(r.x() + r.width() - diameter, r.y(), 2491 diameter, diameter, 0, 90); 2492 } else { 2493 path.lineTo(r.x() + r.width(), r.y()); 2494 } 2495 if (round & CORNER_TL) { 2496 path.arcTo(r.x(), r.y(), diameter, diameter, 90, 90); 2497 } else { 2498 path.lineTo(r.x(), r.y()); 2499 } 2500 if (w != WIDGET_MDI_WINDOW_TITLE && round & CORNER_BL) { 2501 path.arcTo(r.x(), r.y() + r.height() - diameter, 2502 diameter, diameter, 180, 90); 2503 } else { 2504 path.lineTo(r.x(), r.y() + r.height()); 2505 } 2506 2507 if (w != WIDGET_MDI_WINDOW_TITLE) { 2508 if (round & CORNER_BR) { 2509 path.arcTo(r.x() + r.width() - diameter, 2510 r.y() + r.height() - diameter, 2511 diameter, diameter, 270, 90); 2512 } else { 2513 path.lineTo(r.x() + r.width(), r.y() + r.height()); 2514 } 2515 } 2516 return path; 2517 } 2518 2519 QPainterPath 2520 Style::buildPath(const QRect &r, EWidget w, int round, double radius) const 2521 { 2522 return buildPath(QRectF(r.x() + 0.5, r.y() + 0.5, 2523 r.width() - 1, r.height() - 1), w, round, radius); 2524 } 2525 2526 void 2527 Style::buildSplitPath(const QRect &r, int round, double radius, 2528 QPainterPath &tl, QPainterPath &br) const 2529 { 2530 double xd = r.x() + 0.5; 2531 double yd = r.y() + 0.5; 2532 double diameter = radius * 2; 2533 bool rounded = diameter > 0.0; 2534 int width = r.width() - 1; 2535 int height = r.height() - 1; 2536 2537 if (rounded && round & CORNER_TR) { 2538 tl.arcMoveTo(xd + width - diameter, yd, diameter, diameter, 45); 2539 tl.arcTo(xd + width - diameter, yd, diameter, diameter, 45, 45); 2540 if (width > diameter) { 2541 tl.lineTo(xd + width - diameter, yd); 2542 } 2543 } else { 2544 tl.moveTo(xd + width, yd); 2545 } 2546 2547 if (rounded && round & CORNER_TL) { 2548 tl.arcTo(xd, yd, diameter, diameter, 90, 90); 2549 } else { 2550 tl.lineTo(xd, yd); 2551 } 2552 2553 if (rounded && round & CORNER_BL) { 2554 tl.arcTo(xd, yd + height - diameter, diameter, diameter, 180, 45); 2555 br.arcMoveTo(xd, yd + height - diameter, diameter, diameter, 180 + 45); 2556 br.arcTo(xd, yd + height - diameter, diameter, diameter, 180 + 45, 45); 2557 } else { 2558 tl.lineTo(xd, yd + height); 2559 br.moveTo(xd, yd + height); 2560 } 2561 2562 if (rounded && round & CORNER_BR) { 2563 br.arcTo(xd + width - diameter, yd + height - diameter, diameter, 2564 diameter, 270, 90); 2565 } else { 2566 br.lineTo(xd + width, yd + height); 2567 } 2568 2569 if (rounded && round & CORNER_TR) { 2570 br.arcTo(xd + width - diameter, yd, diameter, diameter, 0, 45); 2571 } else { 2572 br.lineTo(xd + width, yd); 2573 } 2574 } 2575 2576 void 2577 Style::drawBorder(QPainter *p, const QRect &r, const QStyleOption *option, 2578 int round, const QColor *custom, EWidget w, 2579 EBorder borderProfile, bool doBlend, int borderVal) const 2580 { 2581 if(ROUND_NONE==opts.round) 2582 round=ROUNDED_NONE; 2583 2584 State state(option->state); 2585 bool enabled(state&State_Enabled), 2586 entry(WIDGET_ENTRY==w || (WIDGET_SCROLLVIEW==w && opts.highlightScrollViews)), 2587 hasFocus(enabled && entry && state&State_HasFocus), 2588 hasMouseOver(enabled && entry && state & State_MouseOver && 2589 opts.unifyCombo && opts.unifySpin); 2590 const QColor *cols(enabled && hasMouseOver && opts.coloredMouseOver && entry 2591 ? m_mouseOverCols 2592 : enabled && hasFocus && entry 2593 ? m_focusCols 2594 : custom 2595 ? custom 2596 : APP_KRUNNER==theThemedApp ? m_backgroundCols : backgroundColors(option)); 2597 QColor border(WIDGET_DEF_BUTTON==w && IND_FONT_COLOR==opts.defBtnIndicator && enabled 2598 ? option->palette.buttonText().color() 2599 : cols[WIDGET_PROGRESSBAR==w 2600 ? PBAR_BORDER 2601 : !enabled && (WIDGET_BUTTON(w) || WIDGET_SLIDER_TROUGH==w) 2602 ? QTC_STD_BORDER 2603 : m_mouseOverCols==cols && IS_SLIDER(w) 2604 ? SLIDER_MO_BORDER_VAL 2605 : borderVal]); 2606 2607 p->setRenderHint(QPainter::Antialiasing, true); 2608 p->setBrush(Qt::NoBrush); 2609 2610 if(WIDGET_TAB_BOT==w || WIDGET_TAB_TOP==w) 2611 cols=m_backgroundCols; 2612 2613 if(!(opts.thin&THIN_FRAMES) && (WIDGET_SCROLLVIEW!=w || !(opts.square&SQUARE_SCROLLVIEW) || opts.highlightScrollViews)) 2614 switch(borderProfile) 2615 { 2616 case BORDER_FLAT: 2617 break; 2618 case BORDER_RAISED: 2619 case BORDER_SUNKEN: 2620 case BORDER_LIGHT: 2621 { 2622 int dark=FRAME_DARK_SHADOW; 2623 QColor tl(cols[BORDER_RAISED==borderProfile || BORDER_LIGHT==borderProfile ? 0 : dark]), 2624 br(cols[BORDER_RAISED==borderProfile ? dark : 0]); 2625 QPainterPath topPath, 2626 botPath; 2627 2628 if( ((hasMouseOver || hasFocus) && WIDGET_ENTRY==w) || 2629 (hasFocus && WIDGET_SCROLLVIEW==w)) 2630 { 2631 tl.setAlphaF(ENTRY_INNER_ALPHA); 2632 br.setAlphaF(ENTRY_INNER_ALPHA); 2633 } 2634 else if(doBlend) 2635 { 2636 tl.setAlphaF(BORDER_BLEND_ALPHA(w)); 2637 br.setAlphaF(BORDER_SUNKEN==borderProfile ? 0.0 : BORDER_BLEND_ALPHA(w)); 2638 } 2639 2640 QRect inner(r.adjusted(1, 1, -1, -1)); 2641 2642 buildSplitPath(inner, round, qtcGetRadius(&opts, inner.width(), inner.height(), w, RADIUS_INTERNAL), topPath, botPath); 2643 2644 setPainterPen(p, (enabled || BORDER_SUNKEN==borderProfile) /*&& 2645 (BORDER_RAISED==borderProfile || BORDER_LIGHT==borderProfile || hasFocus || APPEARANCE_FLAT!=app)*/ 2646 ? tl 2647 : option->palette.window().color(), QPENWIDTH1); 2648 p->drawPath(topPath); 2649 if(WIDGET_SCROLLVIEW==w || // Because of list view headers, need to draw dark line on right! 2650 (! ( (WIDGET_ENTRY==w && !hasFocus && !hasMouseOver) || 2651 (WIDGET_ENTRY!=w && doBlend && BORDER_SUNKEN==borderProfile) ) ) ) 2652 { 2653 if(!hasFocus && !hasMouseOver && BORDER_LIGHT!=borderProfile && WIDGET_SCROLLVIEW!=w) 2654 setPainterPen(p, /*WIDGET_SCROLLVIEW==w && !hasFocus 2655 ? checkColour(option, QPalette::Window) 2656 : WIDGET_ENTRY==w && !hasFocus 2657 ? checkColour(option, QPalette::Base) 2658 : */enabled && (BORDER_SUNKEN==borderProfile || hasFocus || /*APPEARANCE_FLAT!=app ||*/ 2659 WIDGET_TAB_TOP==w || WIDGET_TAB_BOT==w) 2660 ? br 2661 : checkColour(option, QPalette::Window), QPENWIDTH1); 2662 p->drawPath(botPath); 2663 } 2664 } 2665 } 2666 2667 if(BORDER_SUNKEN==borderProfile && 2668 (WIDGET_FRAME==w || ((WIDGET_ENTRY==w || WIDGET_SCROLLVIEW==w) && !opts.etchEntry && !hasFocus && !hasMouseOver))) 2669 { 2670 QPainterPath topPath, 2671 botPath; 2672 QColor col(border); 2673 2674 col.setAlphaF(LOWER_BORDER_ALPHA); 2675 buildSplitPath(r, round, qtcGetRadius(&opts, r.width(), r.height(), w, RADIUS_EXTERNAL), topPath, botPath); 2676 p->setPen(QPen(/*enabled ? */border/* : col*/, QPENWIDTH1)); 2677 p->drawPath(topPath); 2678 // if(enabled) 2679 p->setPen(col); 2680 p->drawPath(botPath); 2681 } 2682 else 2683 { 2684 p->setPen(QPen(border, QPENWIDTH1)); 2685 p->drawPath(buildPath(r, w, round, qtcGetRadius(&opts, r.width(), r.height(), w, RADIUS_EXTERNAL))); 2686 } 2687 2688 QPAINTER_RENDERHINT_AA_MAYBE_OFF(p); 2689 } 2690 2691 void Style::drawMdiControl(QPainter *p, const QStyleOptionTitleBar *titleBar, SubControl sc, const QWidget *widget, 2692 ETitleBarButtons btn, const QColor &iconColor, const QColor *btnCols, const QColor *bgndCols, 2693 int adjust, bool activeWindow) const 2694 { 2695 bool hover((titleBar->activeSubControls&sc) && (titleBar->state&State_MouseOver)); 2696 2697 if(!activeWindow && !hover && opts.titlebarButtons&TITLEBAR_BUTTOM_HIDE_ON_INACTIVE_WINDOW) 2698 return; 2699 2700 QRect rect(subControlRect(CC_TitleBar, titleBar, sc, widget)); 2701 2702 if (rect.isValid()) 2703 { 2704 rect.adjust(adjust, adjust, -adjust, -adjust); 2705 2706 bool sunken((titleBar->activeSubControls&sc) && (titleBar->state&State_Sunken)), 2707 colored(coloredMdiButtons(titleBar->state&State_Active, hover)), 2708 useBtnCols(opts.titlebarButtons&TITLEBAR_BUTTON_STD_COLOR && 2709 (hover || 2710 !(opts.titlebarButtons&TITLEBAR_BUTTON_COLOR_MOUSE_OVER) || 2711 opts.titlebarButtons&TITLEBAR_BUTTON_COLOR)); 2712 const QColor *buttonColors=colored && !(opts.titlebarButtons&TITLEBAR_BUTTON_COLOR_SYMBOL) 2713 ? m_titleBarButtonsCols[btn] : (useBtnCols ? btnCols : bgndCols); 2714 const QColor &icnColor=opts.titlebarButtons&TITLEBAR_BUTTON_ICON_COLOR 2715 ? opts.titlebarButtonColors[btn+(NUM_TITLEBAR_BUTTONS*(titleBar->state&State_Active ? 1 : 2))] 2716 : colored && opts.titlebarButtons&TITLEBAR_BUTTON_COLOR_SYMBOL 2717 ? m_titleBarButtonsCols[btn][ORIGINAL_SHADE] 2718 : SC_TitleBarCloseButton==sc && hover && !sunken && !(opts.titlebarButtons&TITLEBAR_BUTTON_COLOR) 2719 ? CLOSE_COLOR 2720 : SC_TitleBarCloseButton!=sc && hover && !sunken && 2721 !(opts.titlebarButtons&TITLEBAR_BUTTON_COLOR) && 2722 opts.titlebarButtons&TITLEBAR_BUTTON_USE_HOVER_COLOR 2723 ? m_mouseOverCols[ORIGINAL_SHADE] 2724 : iconColor; 2725 2726 bool drewFrame=drawMdiButton(p, rect, hover, sunken, buttonColors); 2727 drawMdiIcon(p, icnColor, (drewFrame ? buttonColors : bgndCols)[ORIGINAL_SHADE], 2728 rect, hover, sunken, subControlToIcon(sc), true, drewFrame); 2729 } 2730 } 2731 2732 void Style::drawDwtControl(QPainter *p, const State &state, const QRect &rect, ETitleBarButtons btn, Icon icon, 2733 const QColor &iconColor, const QColor *btnCols, const QColor *bgndCols) const 2734 { 2735 bool sunken(state&State_Sunken), 2736 hover(state&State_MouseOver), 2737 colored(coloredMdiButtons(state&State_Active, hover)), 2738 useBtnCols(opts.titlebarButtons&TITLEBAR_BUTTON_STD_COLOR && 2739 (hover || 2740 !(opts.titlebarButtons&TITLEBAR_BUTTON_COLOR_MOUSE_OVER) || 2741 opts.titlebarButtons&TITLEBAR_BUTTON_COLOR)); 2742 const QColor *buttonColors=colored && !(opts.titlebarButtons&TITLEBAR_BUTTON_COLOR_SYMBOL) 2743 ? m_titleBarButtonsCols[btn] : (useBtnCols ? btnCols : bgndCols); 2744 const QColor &icnColor=opts.dwtSettings&DWT_ICON_COLOR_AS_PER_TITLEBAR && opts.titlebarButtons&TITLEBAR_BUTTON_ICON_COLOR 2745 ? opts.titlebarButtonColors[btn+(NUM_TITLEBAR_BUTTONS/**(titleBar->state&State_Active ? 1 : 2)*/)] 2746 : colored && opts.titlebarButtons&TITLEBAR_BUTTON_COLOR_SYMBOL 2747 ? m_titleBarButtonsCols[btn][ORIGINAL_SHADE] 2748 : (TITLEBAR_CLOSE==btn && !(opts.titlebarButtons&TITLEBAR_BUTTON_COLOR) && (hover || sunken) 2749 ? CLOSE_COLOR 2750 : iconColor); 2751 2752 bool drewFrame=drawMdiButton(p, rect, hover, sunken, buttonColors); 2753 drawMdiIcon(p, icnColor, (drewFrame ? buttonColors : bgndCols)[ORIGINAL_SHADE], rect, hover, sunken, icon, false, drewFrame); 2754 } 2755 2756 bool Style::drawMdiButton(QPainter *painter, const QRect &r, bool hover, bool sunken, const QColor *cols) const 2757 { 2758 if(!(opts.titlebarButtons&TITLEBAR_BUTTON_NO_FRAME) && 2759 (hover || sunken || !(opts.titlebarButtons&TITLEBAR_BUTTON_HOVER_FRAME))) 2760 { 2761 QStyleOption opt; 2762 2763 opt.rect=r; // .adjusted(1, 1, -1, -1); 2764 if(opts.titlebarButtons&TITLEBAR_BUTTON_ROUND) 2765 opt.rect.adjust(1, 1, -1, -1); 2766 opt.state=State_Enabled|State_Horizontal|State_Raised; 2767 if(hover) 2768 opt.state|=State_MouseOver; 2769 if(sunken) 2770 opt.state|=State_Sunken; 2771 2772 drawLightBevel(painter, opt.rect, &opt, 0L, ROUNDED_ALL, getFill(&opt, cols), cols, true, WIDGET_MDI_WINDOW_BUTTON); 2773 return true; 2774 } 2775 2776 return false; 2777 } 2778 2779 void Style::drawMdiIcon(QPainter *painter, const QColor &color, const QColor &bgnd, const QRect &r, bool hover, bool sunken, Icon icon, 2780 bool stdSize, bool drewFrame) const 2781 { 2782 if(!(opts.titlebarButtons&TITLEBAR_BUTTON_HOVER_SYMBOL_FULL) || hover || sunken) 2783 { 2784 bool faded=!sunken && !hover && opts.titlebarButtons&TITLEBAR_BUTTON_HOVER_SYMBOL; 2785 2786 if(!sunken && !faded && EFFECT_NONE!=opts.titlebarEffect) 2787 // // && hover && !(opts.titlebarButtons&TITLEBAR_BUTTON_HOVER_SYMBOL) && !customCol) 2788 { 2789 EEffect effect=opts.titlebarEffect; 2790 2791 if(EFFECT_ETCH==opts.titlebarEffect && drewFrame) 2792 effect=EFFECT_SHADOW; 2793 2794 drawIcon(painter, blendColors(WINDOW_SHADOW_COLOR(effect), bgnd, WINDOW_TEXT_SHADOW_ALPHA(effect)), 2795 EFFECT_SHADOW==effect 2796 ? r.adjusted(1, 1, 1, 1) 2797 : r.adjusted(0, 1, 0, 1), 2798 sunken, icon, stdSize); 2799 } 2800 2801 QColor col(color); 2802 2803 if(faded) 2804 col=blendColors(col, bgnd, HOVER_BUTTON_ALPHA(col)); 2805 2806 drawIcon(painter, col, r, sunken, icon, stdSize); 2807 } 2808 } 2809 2810 void Style::drawIcon(QPainter *painter, const QColor &color, const QRect &r, bool sunken, Icon icon, bool stdSize) const 2811 { 2812 static const int constIconSize=9; 2813 static const int constSmallIconSize=7; 2814 2815 painter->setPen(color); 2816 2817 QSize iconSize(stdSize 2818 ? constIconSize 2819 : constSmallIconSize, 2820 stdSize 2821 ? constIconSize 2822 : (ICN_RESTORE==icon && !(opts.titlebarButtons&TITLEBAR_BUTTOM_ARROW_MIN_MAX) 2823 ? constSmallIconSize+1 2824 : constSmallIconSize)); 2825 QRect br(r.x()+((r.width()-iconSize.width())>>1), 2826 r.y()+((r.height()-iconSize.height())>>1), 2827 iconSize.width(), iconSize.height()); 2828 if(sunken) 2829 br.adjust(1, 1, 1, 1); 2830 2831 switch(icon) 2832 { 2833 case ICN_MIN: 2834 if(opts.titlebarButtons&TITLEBAR_BUTTOM_ARROW_MIN_MAX) 2835 drawArrow(painter, opts.vArrows ? br.adjusted(0, 1, 0, 1) : br, PE_IndicatorArrowDown, color, false); 2836 else 2837 drawRect(painter, QRect(br.left(), br.bottom()-1, br.width(), 2)); 2838 break; 2839 case ICN_MAX: 2840 if(opts.titlebarButtons&TITLEBAR_BUTTOM_ARROW_MIN_MAX) 2841 drawArrow(painter, opts.vArrows ? br.adjusted(0, -1, 0, -1) : br, PE_IndicatorArrowUp, color, false); 2842 else 2843 { 2844 drawRect(painter, br); 2845 painter->drawLine(br.left() + 1, br.top() + 1, br.right() - 1, br.top() + 1); 2846 } 2847 break; 2848 case ICN_CLOSE: 2849 if(stdSize && opts.titlebarButtons&TITLEBAR_BUTTON_SUNKEN_BACKGROUND) 2850 br.adjust(1, 1, -1, -1); 2851 painter->save(); 2852 painter->setClipRect(br); 2853 painter->setPen(QPen(color, 2)); 2854 painter->drawLine(br.left(), br.top(), br.right(), br.bottom()); 2855 painter->drawLine(br.right(), br.top(), br.left(), br.bottom()); 2856 painter->restore(); 2857 break; 2858 case ICN_RESTORE: 2859 if(opts.titlebarButtons&TITLEBAR_BUTTOM_ARROW_MIN_MAX) 2860 { 2861 painter->drawLine(br.x()+1, br.y(), br.x()+br.width()-2, br.y()); 2862 painter->drawLine(br.x()+1, br.y()+br.height()-1, br.x()+br.width()-2, br.y()+br.height()-1); 2863 painter->drawLine(br.x(), br.y()+1, br.x(), br.y()+br.height()-2); 2864 painter->drawLine(br.x()+br.width()-1, br.y()+1, br.x()+br.width()-1, br.y()+br.height()-2); 2865 drawRect(painter, br.adjusted(1, 1, -1, -1)); 2866 } 2867 else 2868 { 2869 drawRect(painter, QRect(br.x(), br.y()+3, br.width()-2, br.height()-3)); 2870 painter->drawLine(br.x()+1, br.y()+4, br.x()+br.width()-4, br.y()+4); 2871 painter->drawLine(br.x()+2, br.y(), br.x()+br.width()-1, br.y()); 2872 painter->drawLine(br.x()+2, br.y()+1, br.x()+br.width()-1, br.y()+1); 2873 painter->drawLine(br.x()+br.width()-1, br.y()+2, br.x()+br.width()-1, br.y()+(stdSize ? 5 : 4)); 2874 painter->drawPoint(br.x()+br.width()-2, br.y()+(stdSize ? 5 : 4)); 2875 painter->drawPoint(br.x()+2, br.y()+2); 2876 } 2877 break; 2878 case ICN_UP: 2879 drawArrow(painter, br, PE_IndicatorArrowUp, color, false); 2880 break; 2881 case ICN_DOWN: 2882 drawArrow(painter, opts.vArrows ? br.adjusted(0, 1, 0, 1) : br, PE_IndicatorArrowDown, color, false); 2883 break; 2884 case ICN_RIGHT: 2885 drawArrow(painter, br, PE_IndicatorArrowRight, color, false); 2886 break; 2887 case ICN_MENU: 2888 for(int i=1; i<=constIconSize; i+=3) 2889 painter->drawLine(br.left() + 1, br.top() + i, br.right() - 1, br.top() + i); 2890 break; 2891 case ICN_SHADE: 2892 case ICN_UNSHADE: 2893 { 2894 bool isDwt=opts.dwtSettings&DWT_BUTTONS_AS_PER_TITLEBAR; 2895 br.adjust(0, -2, 0, 0); 2896 drawRect(painter, isDwt ? QRect(br.left(), br.bottom(), br.width(), 2) : QRect(br.left()+1, br.bottom()-1, br.width()-2, 2)); 2897 br.adjust(0, ICN_SHADE==icon ? -3 : -5, 0, 0); 2898 drawArrow(painter, opts.vArrows ? br.adjusted(0, 1, 0, 1) : br, 2899 ICN_SHADE==icon ? PE_IndicatorArrowDown : PE_IndicatorArrowUp, color, false); 2900 break; 2901 } 2902 default: 2903 break; 2904 } 2905 } 2906 2907 void Style::drawEntryField(QPainter *p, const QRect &rx, const QWidget *widget, const QStyleOption *option, 2908 int round, bool fill, bool doEtch, EWidget w) const 2909 { 2910 QRect r(rx); 2911 2912 if(doEtch && opts.etchEntry) 2913 r.adjust(1, 1, -1, -1); 2914 2915 p->setRenderHint(QPainter::Antialiasing, true); 2916 if(fill) 2917 p->fillPath(buildPath(QRectF(r).adjusted(1, 1, -1, -1), WIDGET_SCROLLVIEW==w ? w : WIDGET_ENTRY, round, 2918 qtcGetRadius(&opts, r.width()-2, r.height()-2, WIDGET_SCROLLVIEW==w ? w : WIDGET_ENTRY, RADIUS_INTERNAL)), 2919 option->palette.brush(QPalette::Base)); 2920 else 2921 { 2922 p->setPen(WIDGET_SCROLLVIEW!=w || !(opts.square&SQUARE_SCROLLVIEW) || opts.highlightScrollViews ? checkColour(option, QPalette::Base) 2923 : backgroundColors(option)[ORIGINAL_SHADE]); 2924 p->drawPath(buildPath(r.adjusted(1, 1, -1, -1), WIDGET_SCROLLVIEW==w ? w : WIDGET_ENTRY, round, 2925 qtcGetRadius(&opts, r.width()-2, r.height()-2, WIDGET_SCROLLVIEW==w ? w : WIDGET_ENTRY, RADIUS_INTERNAL))); 2926 } 2927 QPAINTER_RENDERHINT_AA_MAYBE_OFF(p); 2928 2929 if(doEtch && opts.etchEntry) 2930 drawEtch(p, rx, widget, WIDGET_SCROLLVIEW==w ? w : WIDGET_ENTRY, false); 2931 2932 drawBorder(p, r, option, round, 0L, w, BORDER_SUNKEN); 2933 } 2934 2935 void Style::drawMenuItem(QPainter *p, const QRect &r, const QStyleOption *option, MenuItemType type, int round, const QColor *cols) const 2936 { 2937 QColor altCols[TOTAL_SHADES+1]; 2938 if (theThemedApp == APP_KWIN) { 2939 QWidget *w = qobject_cast<QWidget*>(option->styleObject); 2940 QPalette::ColorRole role = (opts.useHighlightForMenu || (option->state & (State_On|State_Sunken))) ? 2941 QPalette::HighlightedText : QPalette::WindowText; 2942 if (w && w->palette().color(QPalette::Active, role) 2943 != QApplication::palette().color(QPalette::Active, role)) { 2944 // qWarning() << "drawMenuItem: widget" << w << "bgCol" << w->palette().color(QPalette::Active, role) 2945 // << "differs from app bgCol" << QApplication::palette().color(QPalette::Active, role); 2946 shadeColors(w->palette().color(QPalette::Active, role), altCols); 2947 cols = altCols; 2948 } 2949 } 2950 2951 int fill=opts.useHighlightForMenu && ((MENU_BAR!=type) || m_highlightCols==cols || APP_OPENOFFICE==theThemedApp) ? ORIGINAL_SHADE : 4, 2952 border=opts.borderMenuitems ? 0 : fill; 2953 2954 if(m_highlightCols!=cols && MENU_BAR==type && !(option->state&(State_On|State_Sunken)) && 2955 !opts.colorMenubarMouseOver && (opts.borderMenuitems || !qtcIsFlat(opts.menuitemAppearance))) 2956 fill=ORIGINAL_SHADE; 2957 2958 if(MENU_BAR!=type && APPEARANCE_FADE==opts.menuitemAppearance) 2959 { 2960 bool reverse = Qt::RightToLeft==option->direction; 2961 QColor trans(Qt::white); 2962 QRect r2(opts.round != ROUND_NONE ? r.adjusted(1, 1, -1, -1) : r); 2963 QRectF rf(r2); 2964 double fadePercent = ((double)MENUITEM_FADE_SIZE)/rf.width(); 2965 QLinearGradient grad(r2.topLeft(), r2.topRight()); 2966 2967 trans.setAlphaF(0.0); 2968 grad.setColorAt(0, reverse ? trans : cols[fill]); 2969 grad.setColorAt(reverse ? fadePercent : 1.0-fadePercent, cols[fill]); 2970 grad.setColorAt(1, reverse ? cols[fill] : trans); 2971 if (opts.round != ROUND_NONE) { 2972 p->save(); 2973 p->setRenderHint(QPainter::Antialiasing, true); 2974 p->fillPath(buildPath(rf, WIDGET_OTHER, 2975 reverse ? ROUNDED_RIGHT : ROUNDED_LEFT, 4), 2976 QBrush(grad)); 2977 p->restore(); 2978 } else { 2979 p->fillRect(r2, QBrush(grad)); 2980 } 2981 } else if (MENU_BAR==type || opts.borderMenuitems) { 2982 bool stdColor(MENU_BAR!=type || (SHADE_BLEND_SELECTED!=opts.shadeMenubars && SHADE_SELECTED!=opts.shadeMenubars)); 2983 2984 QStyleOption opt(*option); 2985 2986 opt.state|=State_Horizontal|State_Raised; 2987 opt.state&=~(State_Sunken|State_On); 2988 2989 if(stdColor && opts.borderMenuitems) 2990 drawLightBevel(p, r, &opt, 0L, round, cols[fill], cols, stdColor, WIDGET_MENU_ITEM); 2991 else 2992 { 2993 QRect fr(r); 2994 2995 fr.adjust(1, 1, -1, -1); 2996 2997 if(fr.width()>0 && fr.height()>0) 2998 drawBevelGradient(cols[fill], p, fr, true, false, opts.menuitemAppearance, WIDGET_MENU_ITEM); 2999 drawBorder(p, r, &opt, round, cols, WIDGET_MENU_ITEM, BORDER_FLAT, false, border); 3000 } 3001 } 3002 else 3003 { 3004 // For now dont round combos - getting weird effects with shadow/clipping in Gtk2 style :-( 3005 if (/*MENU_COMBO==type || */opts.square & SQUARE_POPUP_MENUS) { 3006 drawBevelGradient(cols[fill], p, r, true, false, 3007 opts.menuitemAppearance, WIDGET_MENU_ITEM); 3008 } else { 3009 p->save(); 3010 p->setRenderHint(QPainter::Antialiasing, true); 3011 drawBevelGradient( 3012 cols[fill], p, r, 3013 buildPath(QRectF(r), WIDGET_OTHER, ROUNDED_ALL, 3014 (opts.round >= ROUND_FULL ? 5.0 : 2.5) - 3015 (opts.round > ROUND_SLIGHT ? 1.0 : 0.5)), true, false, 3016 opts.menuitemAppearance, WIDGET_MENU_ITEM, false); 3017 p->restore(); 3018 } 3019 } 3020 } 3021 3022 void Style::drawProgress(QPainter *p, const QRect &r, const QStyleOption *option, bool vertical, bool reverse) const 3023 { 3024 QStyleOption opt(*option); 3025 QRect rx(r); 3026 3027 opt.state|=State_Raised; 3028 3029 if(vertical) 3030 opt.state&=~State_Horizontal; 3031 else 3032 opt.state|=State_Horizontal; 3033 3034 if(reverse) 3035 opt.state|=STATE_REVERSE; 3036 else 3037 opt.state&=~STATE_REVERSE; 3038 3039 if((vertical ? r.height() : r.width())<1) 3040 return; 3041 3042 if(vertical && r.height()<3) 3043 rx.setHeight(3); 3044 3045 if(!vertical && rx.width()<3) 3046 rx.setWidth(3); 3047 3048 // KTorrent's progressbars seem to have state==State_None 3049 const QColor *use=option->state&State_Enabled || State_None==option->state || ECOLOR_BACKGROUND==opts.progressGrooveColor 3050 ? m_progressCols 3051 ? m_progressCols 3052 : highlightColors(option, true) 3053 : m_backgroundCols; 3054 3055 drawLightBevel(p, rx, &opt, 0L, ROUNDED_ALL, use[ORIGINAL_SHADE], use, opts.borderProgress, WIDGET_PROGRESSBAR); 3056 3057 if(opts.glowProgress && (vertical ? rx.height() : rx.width())>3) 3058 { 3059 QRect ri(opts.borderProgress ? rx.adjusted(1, 1, -1, -1) : rx); 3060 QLinearGradient grad(0, 0, vertical ? 0 : 1, vertical ? 1 : 0); 3061 QColor glow(Qt::white), 3062 blank(Qt::white); 3063 3064 blank.setAlphaF(0); 3065 glow.setAlphaF(GLOW_PROG_ALPHA); 3066 grad.setCoordinateMode(QGradient::ObjectBoundingMode); 3067 grad.setColorAt(0, (reverse ? GLOW_END : GLOW_START)==opts.glowProgress ? glow : blank); 3068 if(GLOW_MIDDLE==opts.glowProgress) 3069 grad.setColorAt(0.5, glow); 3070 grad.setColorAt(1, (reverse ? GLOW_START : GLOW_END)==opts.glowProgress ? glow : blank); 3071 p->fillRect(ri, grad); 3072 } 3073 3074 if(!opts.borderProgress) 3075 { 3076 p->setPen(use[PBAR_BORDER]); 3077 if(!vertical) 3078 { 3079 p->drawLine(rx.topLeft(), rx.topRight()); 3080 p->drawLine(rx.bottomLeft(), rx.bottomRight()); 3081 } 3082 else 3083 { 3084 p->drawLine(rx.topLeft(), rx.bottomLeft()); 3085 p->drawLine(rx.topRight(), rx.bottomRight()); 3086 } 3087 } 3088 } 3089 3090 static QPolygon rotate(const QPolygon &p, double angle) 3091 { 3092 QTransform transform; 3093 transform.rotate(angle); 3094 return transform.map(p); 3095 } 3096 3097 void 3098 Style::drawArrow(QPainter *p, const QRect &rx, PrimitiveElement pe, 3099 QColor col, bool small, bool kwin) const 3100 { 3101 QPolygon a; 3102 QRect r(rx); 3103 int m = !small && kwin ? ((r.height() - 7) / 2) : 0; 3104 3105 if(small) 3106 a.setPoints(opts.vArrows ? 6 : 3, 2,0, 0,-2, -2,0, -2,1, 0,-1, 2,1); 3107 else 3108 a.setPoints(opts.vArrows ? 8 : 3, 3+m,1+m, 0,-2, -(3+m),1+m, -(3+m),2+m, -(2+m),2+m, 0,0, 2+m,2+m, 3+m,2+m); 3109 3110 switch (pe) { 3111 case PE_IndicatorArrowUp: 3112 if(m) 3113 r.adjust(0, -m, 0, -m); 3114 break; 3115 case PE_IndicatorArrowDown: 3116 if(m) 3117 r.adjust(0, m, 0, m); 3118 a=rotate(a, 180); 3119 break; 3120 case PE_IndicatorArrowRight: 3121 a=rotate(a, 90); 3122 break; 3123 case PE_IndicatorArrowLeft: 3124 a=rotate(a, 270); 3125 break; 3126 default: 3127 return; 3128 } 3129 a.translate((r.x()+(r.width()>>1)), (r.y()+(r.height()>>1))); 3130 p->save(); 3131 col.setAlpha(255); 3132 p->setPen(col); 3133 p->setBrush(col); 3134 // Qt5 changes how coordinates is calculate for non-AA drawing. 3135 // use QPainter::Qt4CompatiblePainting for now. 3136 // A better solution should be shifting the coordinates by 0.5 3137 // or maybe use QPainterPath 3138 p->setRenderHint(QPainter::Qt4CompatiblePainting, true); 3139 // Qt >= 4.8.5 has problem drawing polygons correctly. Enabling 3140 // antialiasing can work around the problem although it will also make 3141 // the arrow blurry. 3142 // QtCurve issue: 3143 // https://github.com/QtCurve/qtcurve-qt4/issues/3. 3144 // Upstream bug report: 3145 // https://bugreports.qt-project.org/browse/QTBUG-33512 3146 p->setRenderHint(QPainter::Antialiasing, opts.vArrows); 3147 p->drawPolygon(a); 3148 p->restore(); 3149 } 3150 3151 void Style::drawSbSliderHandle(QPainter *p, const QRect &rOrig, const QStyleOption *option, bool slider) const 3152 { 3153 QStyleOption opt(*option); 3154 QRect r(rOrig); 3155 3156 if(opt.state&(State_Sunken|State_On)) 3157 opt.state|=State_MouseOver; 3158 3159 if(r.width()>r.height()) 3160 opt.state|=State_Horizontal; 3161 3162 opt.state &= ~(State_Sunken | State_On); 3163 opt.state |= State_Raised; 3164 3165 if (auto slider = styleOptCast<QStyleOptionSlider>(option)) { 3166 if (slider->minimum == slider->maximum) { 3167 opt.state &= ~(State_MouseOver | State_Enabled); 3168 } 3169 } 3170 3171 int min(MIN_SLIDER_SIZE(opts.sliderThumbs)); 3172 const QColor *use(sliderColors(&opt)); 3173 3174 drawLightBevel(p, r, &opt, 0L, (slider && (!(opts.square&SQUARE_SLIDER) || 3175 (SLIDER_ROUND==opts.sliderStyle || SLIDER_ROUND_ROTATED==opts.sliderStyle))) 3176 #ifndef SIMPLE_SCROLLBARS 3177 || (!slider && !(opts.square&SQUARE_SB_SLIDER) && (SCROLLBAR_NONE==opts.scrollbarType || opts.flatSbarButtons)) 3178 #endif 3179 ? ROUNDED_ALL : ROUNDED_NONE, 3180 getFill(&opt, use, false, SHADE_DARKEN==opts.shadeSliders), use, true, 3181 slider ? WIDGET_SLIDER : WIDGET_SB_SLIDER); 3182 3183 if(LINE_NONE!=opts.sliderThumbs && (slider || ((opt.state&State_Horizontal && r.width()>=min)|| r.height()>=min)) && 3184 (!slider || SLIDER_CIRCULAR!=opts.sliderStyle)) 3185 { 3186 const QColor *markers(use); 3187 bool horiz(opt.state&State_Horizontal); 3188 3189 if(LINE_SUNKEN==opts.sliderThumbs) 3190 if(horiz) 3191 r.adjust(0, -1, 0, 0); 3192 else 3193 r.adjust(-1, 0, 0, 0); 3194 else 3195 r.adjust(horiz ? 1 : 0, horiz ? 0 : 1, 0, 0); 3196 3197 switch(opts.sliderThumbs) 3198 { 3199 case LINE_1DOT: 3200 p->drawPixmap(r.x()+((r.width()-5)/2), r.y()+((r.height()-5)/2), *getPixmap(markers[QTC_STD_BORDER], PIX_DOT, 1.0)); 3201 break; 3202 case LINE_FLAT: 3203 drawLines(p, r, !horiz, 3, 5, markers, 0, 5, opts.sliderThumbs); 3204 break; 3205 case LINE_SUNKEN: 3206 drawLines(p, r, !horiz, 4, 3, markers, 0, 3, opts.sliderThumbs); 3207 break; 3208 case LINE_DOTS: 3209 default: 3210 drawDots(p, r, !horiz, slider ? 3 : 5, slider ? 4 : 2, markers, 0, 5); 3211 } 3212 } 3213 } 3214 3215 void Style::drawSliderHandle(QPainter *p, const QRect &r, const QStyleOptionSlider *option) const 3216 { 3217 bool horiz(SLIDER_TRIANGULAR==opts.sliderStyle ? r.height()>r.width() : r.width()>r.height()); 3218 QStyleOption opt(*option); 3219 3220 if(!(option->activeSubControls&SC_SliderHandle) || !(opt.state&State_Enabled)) 3221 opt.state&=~State_MouseOver; 3222 3223 if (opts.sliderStyle == SLIDER_TRIANGULAR) { 3224 if (r.width() > r.height()) { 3225 opt.state |= State_Horizontal; 3226 } 3227 opt.state &= ~(State_Sunken | State_On); 3228 opt.state |= State_Raised; 3229 const QColor *use = sliderColors(&opt); 3230 const QColor *border = (opt.state & State_MouseOver && 3231 oneOf(opts.coloredMouseOver, MO_GLOW, 3232 MO_COLORED) ? m_mouseOverCols : use); 3233 const QColor &fill(getFill(&opt, use, false, 3234 opts.shadeSliders == SHADE_DARKEN)); 3235 int x = r.x(); 3236 int y = r.y(); 3237 PrimitiveElement direction(horiz ? PE_IndicatorArrowDown : 3238 PE_IndicatorArrowRight); 3239 QPolygon clipRegion; 3240 bool drawLight(MO_PLASTIK!=opts.coloredMouseOver || !(opt.state&State_MouseOver)); 3241 int size(SLIDER_TRIANGULAR==opts.sliderStyle ? 15 : 13), 3242 borderVal(m_mouseOverCols==border ? SLIDER_MO_BORDER_VAL : BORDER_VAL(opt.state&State_Enabled)); 3243 3244 if(option->tickPosition & QSlider::TicksBelow) 3245 direction=horiz ? PE_IndicatorArrowDown : PE_IndicatorArrowRight; 3246 else if(option->tickPosition & QSlider::TicksAbove) 3247 direction=horiz ? PE_IndicatorArrowUp : PE_IndicatorArrowLeft; 3248 3249 if (MO_GLOW==opts.coloredMouseOver && opts.buttonEffect != EFFECT_NONE) 3250 x++, y++; 3251 3252 switch(direction) 3253 { 3254 default: 3255 case PE_IndicatorArrowDown: 3256 clipRegion.setPoints(7, x, y+2, x+2, y, x+8, y, x+10, y+2, x+10, y+9, x+5, y+14, x, y+9); 3257 break; 3258 case PE_IndicatorArrowUp: 3259 clipRegion.setPoints(7, x, y+12, x+2, y+14, x+8, y+14, x+10, y+12, x+10, y+5, x+5, y, x, y+5); 3260 break; 3261 case PE_IndicatorArrowLeft: 3262 clipRegion.setPoints(7, x+12, y, x+14, y+2, x+14, y+8, x+12, y+10, x+5, y+10, x, y+5, x+5, y ); 3263 break; 3264 case PE_IndicatorArrowRight: 3265 clipRegion.setPoints(7, x+2, y, x, y+2, x, y+8, x+2, y+10, x+9, y+10, x+14, y+5, x+9, y); 3266 } 3267 3268 p->save(); 3269 p->setClipRegion(QRegion(clipRegion)); // , QPainter::CoordPainter); 3270 if(qtcIsFlat(opts.sliderAppearance)) 3271 { 3272 p->fillRect(r, fill); 3273 3274 if(MO_PLASTIK==opts.coloredMouseOver && opt.state&State_MouseOver && !opts.colorSliderMouseOver) 3275 { 3276 int col(SLIDER_MO_SHADE), 3277 len(SLIDER_MO_LEN); 3278 3279 if(horiz) 3280 { 3281 p->fillRect(QRect(x+1, y+1, len, size-2), m_mouseOverCols[col]); 3282 p->fillRect(QRect(x+r.width()-(1+len), y+1, len, r.height()-2), m_mouseOverCols[col]); 3283 } 3284 else 3285 { 3286 p->fillRect(QRect(x+1, y+1, size-2, len), m_mouseOverCols[col]); 3287 p->fillRect(QRect(x+1, y+r.height()-(1+len), r.width()-2, len), m_mouseOverCols[col]); 3288 } 3289 } 3290 } 3291 else 3292 { 3293 drawBevelGradient(fill, p, QRect(x, y, horiz ? r.width()-1 : size, horiz ? size : r.height()-1), 3294 horiz, false, MODIFY_AGUA(opts.sliderAppearance)); 3295 3296 if(MO_PLASTIK==opts.coloredMouseOver && opt.state&State_MouseOver && !opts.colorSliderMouseOver) 3297 { 3298 int col(SLIDER_MO_SHADE), 3299 len(SLIDER_MO_LEN); 3300 3301 if(horiz) 3302 { 3303 drawBevelGradient(m_mouseOverCols[col], p, QRect(x+1, y+1, len, size-2), 3304 horiz, false, MODIFY_AGUA(opts.sliderAppearance)); 3305 drawBevelGradient(m_mouseOverCols[col], p, QRect(x+r.width()-(1+len), y+1, len, size-2), 3306 horiz, false, MODIFY_AGUA(opts.sliderAppearance)); 3307 } 3308 else 3309 { 3310 drawBevelGradient(m_mouseOverCols[col], p, QRect(x+1, y+1, size-2, len), 3311 horiz, false, MODIFY_AGUA(opts.sliderAppearance)); 3312 drawBevelGradient(m_mouseOverCols[col], p,QRect(x+1, y+r.height()-(1+len), size-2, len), 3313 horiz, false, MODIFY_AGUA(opts.sliderAppearance)); 3314 } 3315 } 3316 } 3317 3318 p->restore(); 3319 p->save(); 3320 3321 QPainterPath path; 3322 double xd(x+0.5), 3323 yd(y+0.5), 3324 radius(2.5), 3325 diameter(radius*2), 3326 xdg(x-0.5), 3327 ydg(y-0.5), 3328 radiusg(radius+1), 3329 diameterg(radiusg*2); 3330 bool glowMo(MO_GLOW==opts.coloredMouseOver && opt.state&State_MouseOver); 3331 QColor glowCol(border[GLOW_MO]); 3332 3333 glowCol.setAlphaF(GLOW_ALPHA(false)); 3334 3335 p->setPen(glowMo ? glowCol : border[borderVal]); 3336 3337 switch(direction) 3338 { 3339 default: 3340 case PE_IndicatorArrowDown: 3341 p->setRenderHint(QPainter::Antialiasing, true); 3342 if(glowMo) 3343 { 3344 path.moveTo(xdg+12-radiusg, ydg); 3345 path.arcTo(xdg, ydg, diameterg, diameterg, 90, 90); 3346 path.lineTo(xdg, ydg+10.5); 3347 path.lineTo(xdg+6, ydg+16.5); 3348 path.lineTo(xdg+12, ydg+10.5); 3349 path.arcTo(xdg+12-diameterg, ydg, diameterg, diameterg, 0, 90); 3350 p->drawPath(path); 3351 path=QPainterPath(); 3352 p->setPen(border[borderVal]); 3353 } 3354 path.moveTo(xd+10-radius, yd); 3355 path.arcTo(xd, yd, diameter, diameter, 90, 90); 3356 path.lineTo(xd, yd+9); 3357 path.lineTo(xd+5, yd+14); 3358 path.lineTo(xd+10, yd+9); 3359 path.arcTo(xd+10-diameter, yd, diameter, diameter, 0, 90); 3360 p->drawPath(path); 3361 QPAINTER_RENDERHINT_AA_MAYBE_OFF(p); 3362 if(drawLight) 3363 { 3364 p->setPen(use[APPEARANCE_DULL_GLASS==opts.sliderAppearance ? 1 : 0]); 3365 p->drawLine(x+1, y+2, x+1, y+8); 3366 p->drawLine(x+2, y+1, x+7, y+1); 3367 } 3368 break; 3369 case PE_IndicatorArrowUp: 3370 p->setRenderHint(QPainter::Antialiasing, true); 3371 if(glowMo) 3372 { 3373 path.moveTo(xdg, ydg+6); 3374 path.arcTo(xdg, ydg+16-diameterg, diameterg, diameterg, 180, 90); 3375 path.arcTo(xdg+12-diameterg, ydg+16-diameterg, diameterg, diameterg, 270, 90); 3376 path.lineTo(xdg+12, ydg+5.5); 3377 path.lineTo(xdg+6, ydg-0.5); 3378 path.lineTo(xdg, ydg+5.5); 3379 p->drawPath(path); 3380 path=QPainterPath(); 3381 p->setPen(border[borderVal]); 3382 } 3383 path.moveTo(xd, yd+5); 3384 path.arcTo(xd, yd+14-diameter, diameter, diameter, 180, 90); 3385 path.arcTo(xd+10-diameter, yd+14-diameter, diameter, diameter, 270, 90); 3386 path.lineTo(xd+10, yd+5); 3387 path.lineTo(xd+5, yd); 3388 path.lineTo(xd, yd+5); 3389 p->drawPath(path); 3390 QPAINTER_RENDERHINT_AA_MAYBE_OFF(p); 3391 if(drawLight) 3392 { 3393 p->setPen(use[APPEARANCE_DULL_GLASS==opts.sliderAppearance ? 1 : 0]); 3394 p->drawLine(x+5, y+1, x+1, y+5); 3395 p->drawLine(x+1, y+5, x+1, y+11); 3396 } 3397 break; 3398 case PE_IndicatorArrowLeft: 3399 p->setRenderHint(QPainter::Antialiasing, true); 3400 if(glowMo) 3401 { 3402 path.moveTo(xdg+6, ydg+12); 3403 path.arcTo(xdg+16-diameterg, ydg+12-diameterg, diameterg, diameterg, 270, 90); 3404 path.arcTo(xdg+16-diameterg, ydg, diameterg, diameterg, 0, 90); 3405 path.lineTo(xdg+5.5, ydg); 3406 path.lineTo(xdg-0.5, ydg+6); 3407 path.lineTo(xdg+5.5, ydg+12); 3408 p->drawPath(path); 3409 path=QPainterPath(); 3410 p->setPen(border[borderVal]); 3411 } 3412 path.moveTo(xd+5, yd+10); 3413 path.arcTo(xd+14-diameter, yd+10-diameter, diameter, diameter, 270, 90); 3414 path.arcTo(xd+14-diameter, yd, diameter, diameter, 0, 90); 3415 path.lineTo(xd+5, yd); 3416 path.lineTo(xd, yd+5); 3417 path.lineTo(xd+5, yd+10); 3418 p->drawPath(path); 3419 QPAINTER_RENDERHINT_AA_MAYBE_OFF(p); 3420 if(drawLight) 3421 { 3422 p->setPen(use[APPEARANCE_DULL_GLASS==opts.sliderAppearance ? 1 : 0]); 3423 p->drawLine(x+1, y+5, x+5, y+1); 3424 p->drawLine(x+5, y+1, x+11, y+1); 3425 } 3426 break; 3427 case PE_IndicatorArrowRight: 3428 p->setRenderHint(QPainter::Antialiasing, true); 3429 if(glowMo) 3430 { 3431 path.moveTo(xdg+11, ydg); 3432 path.arcTo(xdg, ydg, diameterg, diameterg, 90, 90); 3433 path.arcTo(xdg, ydg+12-diameterg, diameterg, diameterg, 180, 90); 3434 path.lineTo(xdg+10.5, ydg+12); 3435 path.lineTo(xdg+16.5, ydg+6); 3436 path.lineTo(xdg+10.5, ydg); 3437 p->drawPath(path); 3438 path=QPainterPath(); 3439 p->setPen(border[borderVal]); 3440 } 3441 path.moveTo(xd+9, yd); 3442 path.arcTo(xd, yd, diameter, diameter, 90, 90); 3443 path.arcTo(xd, yd+10-diameter, diameter, diameter, 180, 90); 3444 path.lineTo(xd+9, yd+10); 3445 path.lineTo(xd+14, yd+5); 3446 path.lineTo(xd+9, yd); 3447 p->drawPath(path); 3448 QPAINTER_RENDERHINT_AA_MAYBE_OFF(p); 3449 if(drawLight) 3450 { 3451 p->setPen(use[APPEARANCE_DULL_GLASS==opts.sliderAppearance ? 1 : 0]); 3452 p->drawLine(x+2, y+1, x+7, y+1); 3453 p->drawLine(x+1, y+2, x+1, y+8); 3454 } 3455 break; 3456 } 3457 p->restore(); 3458 } else { 3459 if (oneOf(opts.sliderStyle, SLIDER_PLAIN_ROTATED, 3460 SLIDER_ROUND_ROTATED)) { 3461 opt.state ^= State_Horizontal; 3462 } 3463 drawSbSliderHandle(p, r, &opt, true); 3464 } 3465 } 3466 3467 void Style::drawSliderGroove(QPainter *p, const QRect &groove, const QRect &handle, const QStyleOptionSlider *slider, 3468 const QWidget *widget) const 3469 { 3470 bool horiz(Qt::Horizontal==slider->orientation); 3471 QRect grv(groove); 3472 QStyleOptionSlider opt(*slider); 3473 3474 opt.state&=~(State_HasFocus|State_On|State_Sunken|State_MouseOver); 3475 3476 if(horiz) 3477 { 3478 int dh=(grv.height()-5)>>1; 3479 grv.adjust(0, dh, 0, -dh); 3480 opt.state|=State_Horizontal; 3481 3482 if (opts.buttonEffect != EFFECT_NONE) 3483 grv.adjust(0, -1, 0, 1); 3484 } 3485 else 3486 { 3487 int dw=(grv.width()-5)>>1; 3488 grv.adjust(dw, 0, -dw, 0); 3489 opt.state&=~State_Horizontal; 3490 3491 if (opts.buttonEffect != EFFECT_NONE) 3492 grv.adjust(-1, 0, 1, 0); 3493 } 3494 3495 if(grv.height()>0 && grv.width()>0) 3496 { 3497 drawLightBevel(p, grv, &opt, widget, 3498 opts.square&SQUARE_SLIDER ? ROUNDED_NONE : ROUNDED_ALL, 3499 m_backgroundCols[slider->state&State_Enabled ? 2 : ORIGINAL_SHADE], 3500 m_backgroundCols, true, WIDGET_SLIDER_TROUGH); 3501 3502 if(opts.fillSlider && slider->maximum!=slider->minimum && slider->state&State_Enabled) 3503 { 3504 const QColor *usedCols=m_sliderCols ? m_sliderCols : m_highlightCols; 3505 3506 if (horiz) 3507 if (slider->upsideDown) 3508 grv=QRect(handle.right()-4, grv.top(), (grv.right()-handle.right())+4, grv.height()); 3509 else 3510 grv=QRect(grv.left(), grv.top(), handle.left()+4, grv.height()); 3511 else 3512 if (slider->upsideDown) 3513 grv=QRect(grv.left(), handle.bottom()-4, grv.width(), (grv.height() - handle.bottom())+4); 3514 else 3515 grv=QRect(grv.left(), grv.top(), grv.width(), (handle.top() - grv.top())+4); 3516 3517 if(grv.height()>0 && grv.width()>0) 3518 drawLightBevel(p, grv, &opt, widget, opts.square&SQUARE_SLIDER ? ROUNDED_NONE : ROUNDED_ALL, 3519 usedCols[ORIGINAL_SHADE], usedCols, true, WIDGET_FILLED_SLIDER_TROUGH); 3520 } 3521 } 3522 } 3523 3524 void 3525 Style::drawMenuOrToolBarBackground(const QWidget *widget, QPainter *p, 3526 const QRect &r, const QStyleOption *option, 3527 bool menu, bool horiz) const 3528 { 3529 // LibreOffice - when drawMenuOrToolBarBackground is called with menuRect, 3530 // this is empty! 3531 if (r.width() < 1 || r.height() < 1) 3532 return; 3533 3534 EAppearance app = menu ? opts.menubarAppearance : opts.toolbarAppearance; 3535 if (!qtcIsCustomBgnd(opts) || !qtcIsFlat(app) || 3536 (menu && opts.shadeMenubars != SHADE_NONE)) { 3537 p->save(); 3538 #if 0 3539 // Revert for now 3540 // This is necessary for correct opacity on the menubar but may 3541 // break transparent gradient. 3542 p->setCompositionMode(QPainter::CompositionMode_Source); 3543 #endif 3544 QRect rx(r); 3545 #ifdef Q_OS_MACOS 3546 QColor col(menu ? 3547 menuColors(option, m_active)[ORIGINAL_SHADE] : 3548 option->palette.window().color()); 3549 #else 3550 QColor col(menu && (option->state & State_Enabled || 3551 opts.shadeMenubars != SHADE_NONE) ? 3552 menuColors(option, m_active)[ORIGINAL_SHADE] : 3553 option->palette.window().color()); 3554 #endif 3555 // TODO: QtQuick 3556 int opacity = qtcGetOpacity(widget ? widget : getWidget(p)); 3557 3558 if (menu && BLEND_TITLEBAR) { 3559 rx.adjust(0, -qtcGetWindowBorderSize(false).titleHeight, 0, 0); 3560 } 3561 if (opacity < 100) { 3562 col.setAlphaF(opacity / 100.0); 3563 } 3564 drawBevelGradient(col, p, rx, horiz, false, MODIFY_AGUA(app)); 3565 p->restore(); 3566 } 3567 } 3568 3569 void Style::drawHandleMarkers(QPainter *p, const QRect &rx, const QStyleOption *option, bool tb, ELine handles) const 3570 { 3571 if(rx.width()<2 || rx.height()<2) 3572 return; 3573 3574 QRect r(rx); 3575 3576 if(APP_OPENOFFICE==theThemedApp) 3577 { 3578 r.setX(r.x()+2); 3579 r.setWidth(10); 3580 } 3581 3582 // CPD: Mouse over of toolbar handles not working - the whole toolbar seems to be active :-( 3583 QStyleOption opt(*option); 3584 3585 opt.state&=~State_MouseOver; 3586 3587 const QColor *border(borderColors(&opt, m_backgroundCols)); 3588 3589 switch(handles) 3590 { 3591 case LINE_NONE: 3592 break; 3593 case LINE_1DOT: 3594 p->drawPixmap(r.x()+((r.width()-5)/2), r.y()+((r.height()-5)/2), *getPixmap(border[QTC_STD_BORDER], PIX_DOT, 1.0)); 3595 break; 3596 case LINE_DOTS: 3597 drawDots(p, r, !(option->state&State_Horizontal), 2, tb ? 5 : 3, border, tb ? -2 : 0, 5); 3598 break; 3599 case LINE_DASHES: 3600 if(option->state&State_Horizontal) 3601 drawLines(p, QRect(r.x()+(tb ? 2 : (r.width()-6)/2), r.y(), 3, r.height()), true, (r.height()-8)/2, 3602 tb ? 0 : (r.width()-5)/2, border, 0, 5, handles); 3603 else 3604 drawLines(p, QRect(r.x(), r.y()+(tb ? 2 : (r.height()-6)/2), r.width(), 3), false, (r.width()-8)/2, 3605 tb ? 0 : (r.height()-5)/2, border, 0, 5, handles); 3606 break; 3607 case LINE_FLAT: 3608 drawLines(p, r, !(option->state&State_Horizontal), 2, tb ? 4 : 2, border, tb ? -2 : 0, 4, handles); 3609 break; 3610 default: 3611 drawLines(p, r, !(option->state&State_Horizontal), 2, tb ? 4 : 2, border, tb ? -2 : 0, 3, handles); 3612 } 3613 } 3614 3615 void Style::fillTab(QPainter *p, const QRect &r, const QStyleOption *option, const QColor &fill, bool horiz, EWidget tab, 3616 bool tabOnly) const 3617 { 3618 bool invertedSel=option->state&State_Selected && APPEARANCE_INVERTED==opts.appearance; 3619 QColor col(invertedSel ? option->palette.window().color() : fill); 3620 3621 if(opts.tabBgnd && !tabOnly) 3622 col=shade(col, TO_FACTOR(opts.tabBgnd)); 3623 3624 if(invertedSel) 3625 p->fillRect(r, col); 3626 else 3627 { 3628 bool selected(option->state&State_Selected); 3629 EAppearance app(selected ? SEL_TAB_APP : NORM_TAB_APP); 3630 3631 drawBevelGradient(col, p, r, horiz, selected, app, tab); 3632 } 3633 } 3634 3635 void Style::colorTab(QPainter *p, const QRect &r, bool horiz, EWidget tab, int round) const 3636 { 3637 p->save(); 3638 p->setRenderHint(QPainter::Antialiasing, true); 3639 QLinearGradient grad(r.topLeft(), horiz ? r.bottomLeft() : r.topRight()); 3640 QColor start(m_highlightCols[ORIGINAL_SHADE]), 3641 end(m_highlightCols[ORIGINAL_SHADE]); 3642 3643 start.setAlphaF(TO_ALPHA(opts.colorSelTab)); 3644 end.setAlphaF(0.0); 3645 grad.setColorAt(0, WIDGET_TAB_TOP==tab ? start : end); 3646 grad.setColorAt(1, WIDGET_TAB_TOP==tab ? end : start); 3647 p->fillPath(buildPath(r, tab, round, qtcGetRadius(&opts, r.width(), r.height(), tab, RADIUS_EXTERNAL)), grad); 3648 p->restore(); 3649 } 3650 3651 void Style::shadeColors(const QColor &base, QColor *vals) const 3652 { 3653 bool useCustom(USE_CUSTOM_SHADES(opts)); 3654 double hl=TO_FACTOR(opts.highlightFactor); 3655 3656 for(int i=0; i<QTC_NUM_STD_SHADES; ++i) 3657 shade(base, &vals[i], useCustom ? opts.customShades[i] : 3658 qtcShadeGetIntern(opts.contrast, i, 3659 opts.darkerBorders, opts.shading)); 3660 shade(base, &vals[SHADE_ORIG_HIGHLIGHT], hl); 3661 shade(vals[4], &vals[SHADE_4_HIGHLIGHT], hl); 3662 shade(vals[2], &vals[SHADE_2_HIGHLIGHT], hl); 3663 vals[ORIGINAL_SHADE]=base; 3664 } 3665 3666 const QColor * Style::buttonColors(const QStyleOption *option) const 3667 { 3668 if(option && option->version>=TBAR_VERSION_HACK && 3669 option->version<TBAR_VERSION_HACK+NUM_TITLEBAR_BUTTONS && 3670 coloredMdiButtons(option->state&State_Active, option->state&(State_MouseOver|State_Sunken))) 3671 return m_titleBarButtonsCols[option->version-TBAR_VERSION_HACK]; 3672 3673 if(option && option->palette.button()!=m_buttonCols[ORIGINAL_SHADE]) 3674 { 3675 shadeColors(option->palette.button().color(), m_coloredButtonCols); 3676 return m_coloredButtonCols; 3677 } 3678 3679 return m_buttonCols; 3680 } 3681 3682 QColor Style::titlebarIconColor(const QStyleOption *option) const 3683 { 3684 if(option && option->version>=TBAR_VERSION_HACK) 3685 { 3686 if(opts.titlebarButtons&TITLEBAR_BUTTON_ICON_COLOR && option->version<TBAR_VERSION_HACK+(NUM_TITLEBAR_BUTTONS*3)) 3687 return opts.titlebarButtonColors[option->version-TBAR_VERSION_HACK]; 3688 if(option->version<TBAR_VERSION_HACK+NUM_TITLEBAR_BUTTONS && 3689 coloredMdiButtons(option->state&State_Active, option->state&(State_MouseOver|State_Sunken))) 3690 return m_titleBarButtonsCols[option->version-TBAR_VERSION_HACK][ORIGINAL_SHADE]; 3691 } 3692 3693 return buttonColors(option)[ORIGINAL_SHADE]; 3694 } 3695 3696 const QColor * Style::popupMenuCols(const QStyleOption *option) const 3697 { 3698 return (opts.lighterPopupMenuBgnd || opts.shadePopupMenu || !option ? 3699 m_popupMenuCols : backgroundColors(option)); 3700 } 3701 3702 const QColor* 3703 Style::checkRadioColors(const QStyleOption *option) const 3704 { 3705 return (opts.crColor && option && option->state & State_Enabled && 3706 (option->state & State_On || option->state & State_NoChange) 3707 ? m_checkRadioSelCols : buttonColors(option)); 3708 } 3709 3710 const QColor * Style::sliderColors(const QStyleOption *option) const 3711 { 3712 return (option && option->state&State_Enabled) 3713 ? SHADE_NONE!=opts.shadeSliders && m_sliderCols && 3714 (!opts.colorSliderMouseOver || option->state&State_MouseOver) 3715 ? m_sliderCols 3716 : m_buttonCols //buttonColors(option) 3717 : m_backgroundCols; 3718 } 3719 3720 const QColor * Style::backgroundColors(const QColor &col) const 3721 { 3722 if(col.alpha()!=0 && col!=m_backgroundCols[ORIGINAL_SHADE]) 3723 { 3724 shadeColors(col, m_coloredBackgroundCols); 3725 return m_coloredBackgroundCols; 3726 } 3727 3728 return m_backgroundCols; 3729 } 3730 3731 const QColor * Style::highlightColors(const QColor &col) const 3732 { 3733 if(col.alpha()!=0 && col!=m_highlightCols[ORIGINAL_SHADE]) 3734 { 3735 shadeColors(col, m_coloredHighlightCols); 3736 return m_coloredHighlightCols; 3737 } 3738 3739 return m_highlightCols; 3740 } 3741 3742 const QColor * Style::borderColors(const QStyleOption *option, const QColor *use) const 3743 { 3744 return opts.coloredMouseOver && option && option->state&State_MouseOver && option->state&State_Enabled ? m_mouseOverCols : use; 3745 } 3746 3747 const QColor * Style::getSidebarButtons() const 3748 { 3749 if(!m_sidebarButtonsCols) 3750 { 3751 if(SHADE_BLEND_SELECTED==opts.shadeSliders) 3752 m_sidebarButtonsCols=m_sliderCols; 3753 else if(IND_COLORED==opts.defBtnIndicator) 3754 m_sidebarButtonsCols=m_defBtnCols; 3755 else 3756 { 3757 m_sidebarButtonsCols=new QColor [TOTAL_SHADES+1]; 3758 shadeColors(midColor(m_highlightCols[ORIGINAL_SHADE], m_buttonCols[ORIGINAL_SHADE]), 3759 m_sidebarButtonsCols); 3760 } 3761 } 3762 3763 return m_sidebarButtonsCols; 3764 } 3765 3766 void Style::setMenuColors(const QColor &bgnd) 3767 { 3768 switch (opts.shadeMenubars) { 3769 case SHADE_NONE: 3770 std::copy(m_backgroundCols, m_backgroundCols + TOTAL_SHADES + 1, m_menubarCols); 3771 break; 3772 case SHADE_BLEND_SELECTED: 3773 shadeColors(midColor(m_highlightCols[ORIGINAL_SHADE], m_backgroundCols[ORIGINAL_SHADE]), m_menubarCols); 3774 break; 3775 case SHADE_SELECTED: 3776 shadeColors(IS_GLASS(opts.appearance) 3777 ? shade(m_highlightCols[ORIGINAL_SHADE], MENUBAR_GLASS_SELECTED_DARK_FACTOR) 3778 : m_highlightCols[ORIGINAL_SHADE], 3779 m_menubarCols); 3780 break; 3781 case SHADE_CUSTOM: 3782 shadeColors(opts.customMenubarsColor, m_menubarCols); 3783 break; 3784 case SHADE_DARKEN: 3785 shadeColors(shade(bgnd, MENUBAR_DARK_FACTOR), m_menubarCols); 3786 break; 3787 case SHADE_WINDOW_BORDER: 3788 break; 3789 } 3790 3791 QColor *base=opts.shadePopupMenu 3792 ? SHADE_WINDOW_BORDER==opts.shadeMenubars 3793 ? (QColor *)getMdiColors(0L, true) // TODO: option!!! 3794 : m_menubarCols 3795 : m_backgroundCols; 3796 3797 if (opts.lighterPopupMenuBgnd) { 3798 if (!m_popupMenuCols) { 3799 m_popupMenuCols = new QColor[TOTAL_SHADES + 1]; 3800 } 3801 shadeColors(shade(base[ORIGINAL_SHADE], 3802 TO_FACTOR(opts.lighterPopupMenuBgnd)), 3803 m_popupMenuCols); 3804 } else { 3805 m_popupMenuCols = base; 3806 } 3807 } 3808 3809 void Style::setMenuTextColors(QWidget *widget, bool isMenuBar) const 3810 { 3811 if(SHADE_WINDOW_BORDER==opts.shadeMenubars) 3812 { 3813 QPalette pal(widget->palette()); 3814 QStyleOption opt; 3815 3816 opt.init(widget); 3817 getMdiColors(&opt, false); 3818 3819 pal.setBrush(QPalette::Active, QPalette::Foreground, m_activeMdiTextColor); 3820 pal.setBrush(QPalette::Active, QPalette::Text, pal.brush(QPalette::Active, QPalette::Foreground)); 3821 if(isMenuBar) 3822 { 3823 pal.setBrush(QPalette::Inactive, QPalette::Foreground, 3824 opts.shadeMenubarOnlyWhenActive ? m_mdiTextColor : m_activeMdiTextColor); 3825 pal.setBrush(QPalette::Inactive, QPalette::Text, pal.brush(QPalette::Inactive, QPalette::Foreground)); 3826 } 3827 else if(opts.shadePopupMenu) 3828 { 3829 pal.setBrush(QPalette::Disabled, QPalette::Foreground, midColor(m_activeMdiTextColor, popupMenuCols()[ORIGINAL_SHADE])); 3830 pal.setBrush(QPalette::Disabled, QPalette::Text, pal.brush(QPalette::Disabled, QPalette::Foreground)); 3831 } 3832 3833 widget->setPalette(pal); 3834 } else if (opts.customMenuTextColor || 3835 oneOf(opts.shadeMenubars, SHADE_BLEND_SELECTED, 3836 SHADE_SELECTED) || 3837 (opts.shadeMenubars == SHADE_CUSTOM && 3838 TOO_DARK(m_menubarCols[ORIGINAL_SHADE]))) { 3839 QPalette pal(widget->palette()); 3840 3841 pal.setBrush(QPalette::Active, QPalette::Foreground, 3842 opts.customMenuTextColor ? opts.customMenuNormTextColor : 3843 pal.highlightedText().color()); 3844 pal.setBrush(QPalette::Active, QPalette::Text, pal.brush(QPalette::Active, QPalette::Foreground)); 3845 3846 if(isMenuBar && !opts.shadeMenubarOnlyWhenActive) 3847 { 3848 pal.setBrush(QPalette::Inactive, QPalette::Foreground, opts.customMenuTextColor 3849 ? opts.customMenuNormTextColor 3850 : pal.highlightedText().color()); 3851 pal.setBrush(QPalette::Inactive, QPalette::Text, pal.brush(QPalette::Inactive, QPalette::Foreground)); 3852 } 3853 else if(!isMenuBar && opts.shadePopupMenu) 3854 { 3855 pal.setBrush(QPalette::Disabled, QPalette::Foreground, 3856 midColor(pal.brush(QPalette::Active, QPalette::Foreground).color(), popupMenuCols()[ORIGINAL_SHADE])); 3857 pal.setBrush(QPalette::Disabled, QPalette::Text, pal.brush(QPalette::Disabled, QPalette::Foreground)); 3858 } 3859 widget->setPalette(pal); 3860 } 3861 } 3862 3863 const QColor * Style::menuColors(const QStyleOption *option, bool active) const 3864 { 3865 if(SHADE_WINDOW_BORDER == opts.shadeMenubars) 3866 { 3867 return getMdiColors(option, active); 3868 } 3869 #ifdef Q_OS_MACOS 3870 else if(opts.shadeMenubarOnlyWhenActive && !active) 3871 #else 3872 else if(opts.shadeMenubars == SHADE_NONE || (opts.shadeMenubarOnlyWhenActive && !active)) 3873 #endif 3874 { 3875 return backgroundColors(option); 3876 } 3877 return m_menubarCols; 3878 } 3879 3880 bool 3881 Style::coloredMdiButtons(bool active, bool mouseOver) const 3882 { 3883 return (opts.titlebarButtons & TITLEBAR_BUTTON_COLOR && 3884 (active ? 3885 (mouseOver || !(opts.titlebarButtons & 3886 TITLEBAR_BUTTON_COLOR_MOUSE_OVER)) : 3887 ((opts.titlebarButtons & TITLEBAR_BUTTON_COLOR_MOUSE_OVER && 3888 mouseOver) || 3889 (!(opts.titlebarButtons & TITLEBAR_BUTTON_COLOR_MOUSE_OVER) && 3890 opts.titlebarButtons & TITLEBAR_BUTTON_COLOR_INACTIVE)))); 3891 } 3892 3893 const QColor* 3894 Style::getMdiColors(const QStyleOption *option, bool active) const 3895 { 3896 if (!m_activeMdiColors) { 3897 #ifndef QTC_QT5_ENABLE_KDE 3898 m_activeMdiTextColor = (option ? option->palette.text().color() : 3899 QApplication::palette().text().color()); 3900 m_mdiTextColor = (option ? option->palette.text().color() : 3901 QApplication::palette().text().color()); 3902 3903 QFile f(kdeHome() + "/share/config/kdeglobals"); 3904 3905 if (f.open(QIODevice::ReadOnly)) { 3906 QTextStream in(&f); 3907 bool inPal = false; 3908 3909 while (!in.atEnd()) { 3910 QString line(in.readLine()); 3911 if (inPal) { 3912 if (!m_activeMdiColors && 3913 line.indexOf("activeBackground=") == 0) { 3914 QColor col; 3915 setRgb(&col, line.mid(17).split(",")); 3916 if (col != m_highlightCols[ORIGINAL_SHADE]) { 3917 m_activeMdiColors = new QColor[TOTAL_SHADES + 1]; 3918 shadeColors(col, m_activeMdiColors); 3919 } 3920 } else if (!m_mdiColors && 3921 line.indexOf("inactiveBackground=") == 0) { 3922 QColor col; 3923 setRgb(&col, line.mid(19).split(",")); 3924 if (col != m_buttonCols[ORIGINAL_SHADE]) { 3925 m_mdiColors = new QColor[TOTAL_SHADES+1]; 3926 shadeColors(col, m_mdiColors); 3927 } 3928 } else if(line.indexOf("activeForeground=") == 0) { 3929 setRgb(&m_activeMdiTextColor, line.mid(17).split(",")); 3930 } else if(line.indexOf("inactiveForeground=") == 0) { 3931 setRgb(&m_mdiTextColor, line.mid(19).split(",")); 3932 } else if (line.indexOf('[') != -1) { 3933 break; 3934 } 3935 } else if(line.indexOf("[WM]") == 0) { 3936 inPal = true; 3937 } 3938 } 3939 f.close(); 3940 } 3941 #else 3942 Q_UNUSED(option); 3943 KConfigGroup cg(m_kdeGlobals, "WM"); 3944 3945 QColor col = cg.readEntry("activeBackground", QColor(48, 174, 232)); 3946 3947 if (col != m_backgroundCols[ORIGINAL_SHADE]) { 3948 m_activeMdiColors = new QColor[TOTAL_SHADES + 1]; 3949 shadeColors(col, m_activeMdiColors); 3950 } 3951 3952 col = cg.readEntry("inactiveBackground", QColor(224, 223, 222));; 3953 if (col != m_backgroundCols[ORIGINAL_SHADE]) { 3954 m_mdiColors = new QColor[TOTAL_SHADES+1]; 3955 shadeColors(col, m_mdiColors); 3956 } 3957 3958 m_activeMdiTextColor = cg.readEntry("activeForeground", QColor(255, 255, 255)); 3959 m_mdiTextColor = cg.readEntry("inactiveForeground", QColor(75, 71, 67)); 3960 #endif 3961 3962 if(!m_activeMdiColors) 3963 m_activeMdiColors=(QColor *)m_backgroundCols; 3964 if(!m_mdiColors) 3965 m_mdiColors=(QColor *)m_backgroundCols; 3966 3967 if(opts.shadeMenubarOnlyWhenActive && SHADE_WINDOW_BORDER==opts.shadeMenubars && 3968 m_activeMdiColors[ORIGINAL_SHADE]==m_mdiColors[ORIGINAL_SHADE]) 3969 opts.shadeMenubarOnlyWhenActive=false; 3970 } 3971 3972 return active ? m_activeMdiColors : m_mdiColors; 3973 } 3974 3975 void Style::readMdiPositions() const 3976 { 3977 if (0==m_mdiButtons[0].size() && 0==m_mdiButtons[1].size()) { 3978 #ifdef Q_OS_MACOS 3979 // no control over where the system menu appears, so we have little choice 3980 // but to keep it at its default position. The user can still override this. 3981 m_mdiButtons[0].append(SC_TitleBarSysMenu); 3982 m_mdiButtons[0].append(SC_TitleBarCloseButton); 3983 m_mdiButtons[0].append(SC_TitleBarMinButton); 3984 m_mdiButtons[0].append(SC_TitleBarMaxButton); 3985 3986 m_mdiButtons[1].append(SC_TitleBarShadeButton); 3987 m_mdiButtons[1].append(SC_TitleBarContextHelpButton); 3988 #else 3989 // Set defaults... 3990 m_mdiButtons[0].append(SC_TitleBarSysMenu); 3991 m_mdiButtons[0].append(SC_TitleBarShadeButton); 3992 3993 m_mdiButtons[1].append(SC_TitleBarContextHelpButton); 3994 m_mdiButtons[1].append(SC_TitleBarMinButton); 3995 m_mdiButtons[1].append(SC_TitleBarMaxButton); 3996 m_mdiButtons[1].append(WINDOWTITLE_SPACER); 3997 m_mdiButtons[1].append(SC_TitleBarCloseButton); 3998 #endif 3999 4000 #ifdef QTC_QT5_ENABLE_KDE 4001 KSharedConfigPtr cfg = KSharedConfig::openConfig("kwinrc"); 4002 KConfigGroup grp = cfg->group("org.kde.kdecoration2"); 4003 4004 QString left=grp.readEntry("ButtonsOnLeft", QString()), 4005 right=grp.readEntry("ButtonsOnRight", QString()); 4006 4007 if(!left.isEmpty() || !right.isEmpty()) 4008 m_mdiButtons[0].clear(), m_mdiButtons[1].clear(); 4009 4010 if(!left.isEmpty()) 4011 parseWindowLine(left, m_mdiButtons[0]); 4012 4013 if(!right.isEmpty()) 4014 parseWindowLine(right, m_mdiButtons[1]); 4015 4016 // Designer uses shade buttons, not min/max - so if we don't have shade in our kwin config. 4017 // then add this button near the max button... 4018 if (-1==m_mdiButtons[0].indexOf(SC_TitleBarShadeButton) && -1==m_mdiButtons[1].indexOf(SC_TitleBarShadeButton)) { 4019 int maxPos=m_mdiButtons[0].indexOf(SC_TitleBarMaxButton); 4020 4021 if(-1==maxPos) // Left doesnt have max button, assume right does and add shade there 4022 { 4023 int minPos=m_mdiButtons[1].indexOf(SC_TitleBarMinButton); 4024 maxPos=m_mdiButtons[1].indexOf(SC_TitleBarMaxButton); 4025 4026 m_mdiButtons[1].insert(minPos<maxPos ? (minPos==-1 ? 0 : minPos) 4027 : (maxPos==-1 ? 0 : maxPos), SC_TitleBarShadeButton); 4028 } 4029 else // Add to left button 4030 { 4031 int minPos=m_mdiButtons[0].indexOf(SC_TitleBarMinButton); 4032 4033 m_mdiButtons[1].insert(minPos>maxPos ? (minPos==-1 ? 0 : minPos) 4034 : (maxPos==-1 ? 0 : maxPos), SC_TitleBarShadeButton); 4035 } 4036 } 4037 #endif 4038 } 4039 } 4040 4041 const QColor & Style::getFill(const QStyleOption *option, const QColor *use, bool cr, bool darker) const 4042 { 4043 return !option || !(option->state&State_Enabled) 4044 ? use[darker ? 2 : ORIGINAL_SHADE] 4045 : option->state&State_Sunken // State_Down ???? 4046 ? use[darker ? 5 : 4] 4047 : option->state&State_MouseOver 4048 ? !cr && option->state&State_On 4049 ? use[darker ? 3 : SHADE_4_HIGHLIGHT] 4050 : use[darker ? SHADE_2_HIGHLIGHT : SHADE_ORIG_HIGHLIGHT] 4051 : !cr && option->state&State_On 4052 ? use[darker ? 5 : 4] 4053 : use[darker ? 2 : ORIGINAL_SHADE]; 4054 } 4055 4056 QPixmap * Style::getPixmap(const QColor col, EPixmap p, double shade) const 4057 { 4058 QtcKey key(createKey(col, p)); 4059 QPixmap *pix=m_pixmapCache.object(key); 4060 4061 if (!pix) { 4062 if (p == PIX_DOT) { 4063 pix=new QPixmap(5, 5); 4064 pix->fill(Qt::transparent); 4065 4066 QColor c(col); 4067 QPainter p(pix); 4068 QLinearGradient g1(0, 0, 5, 5), 4069 g2(0, 0, 3, 3); 4070 4071 g1.setColorAt(0.0, c); 4072 c.setAlphaF(0.4); 4073 g1.setColorAt(1.0, c); 4074 c=Qt::white; 4075 c.setAlphaF(0.9); 4076 g2.setColorAt(0.0, c); 4077 c.setAlphaF(0.7); 4078 g2.setColorAt(1.0, c); 4079 p.setRenderHint(QPainter::Antialiasing, true); 4080 p.setPen(Qt::NoPen); 4081 p.setBrush(g1); 4082 p.drawEllipse(0, 0, 5, 5); 4083 p.setBrush(g2); 4084 p.drawEllipse(1, 1, 4, 4); 4085 p.end(); 4086 } 4087 else 4088 { 4089 pix=new QPixmap(); 4090 4091 QImage img; 4092 4093 switch(p) 4094 { 4095 case PIX_CHECK: 4096 if(opts.xCheck) { 4097 img = qtc_check_x_on; 4098 } else { 4099 img = qtc_check_on; 4100 } 4101 break; 4102 default: 4103 break; 4104 } 4105 4106 if (img.depth()<32) 4107 img=img.convertToFormat(QImage::Format_ARGB32); 4108 4109 qtcAdjustPix(img.bits(), 4, img.width(), img.height(), 4110 img.bytesPerLine(), col.red(), col.green(), 4111 col.blue(), shade, QTC_PIXEL_QT); 4112 *pix=QPixmap::fromImage(img); 4113 } 4114 m_pixmapCache.insert(key, pix, pix->depth()/8); 4115 } 4116 4117 return pix; 4118 } 4119 4120 const QColor & Style::getTabFill(bool current, bool highlight, const QColor *use) const 4121 { 4122 return (current ? use[ORIGINAL_SHADE] : highlight ? 4123 use[SHADE_2_HIGHLIGHT] : use[2]); 4124 } 4125 4126 QColor Style::menuStripeCol() const 4127 { 4128 switch(opts.menuStripe) 4129 { 4130 default: 4131 case SHADE_NONE: 4132 return m_backgroundCols[ORIGINAL_SHADE]; 4133 case SHADE_CUSTOM: 4134 return opts.customMenuStripeColor; 4135 case SHADE_BLEND_SELECTED: 4136 // Hack! Use opts.customMenuStripeColor to store this setting! 4137 if (isBlack(opts.customMenuStripeColor)) { 4138 opts.customMenuStripeColor = 4139 midColor(m_highlightCols[ORIGINAL_SHADE], 4140 popupMenuCols()[ORIGINAL_SHADE]); 4141 } 4142 return opts.customMenuStripeColor; 4143 case SHADE_SELECTED: 4144 return m_highlightCols[MENU_STRIPE_SHADE]; 4145 case SHADE_DARKEN: 4146 return popupMenuCols()[MENU_STRIPE_SHADE]; 4147 } 4148 } 4149 4150 const QColor & Style::checkRadioCol(const QStyleOption *opt) const 4151 { 4152 return opt->state&State_Enabled 4153 ? m_checkRadioCol 4154 : opts.crButton 4155 ? opt->palette.buttonText().color() 4156 : opt->palette.text().color(); 4157 } 4158 4159 QColor Style::shade(const QColor &a, double k) const 4160 { 4161 QColor mod; 4162 qtcShade(&a, &mod, k, opts.shading); 4163 return mod; 4164 } 4165 4166 void Style::shade(const QColor &ca, QColor *cb, double k) const 4167 { 4168 qtcShade(&ca, cb, k, opts.shading); 4169 } 4170 4171 QColor Style::getLowerEtchCol(const QWidget *widget) const 4172 { 4173 if(USE_CUSTOM_ALPHAS(opts)) 4174 { 4175 QColor col(Qt::white); 4176 col.setAlphaF(opts.customAlphas[ALPHA_ETCH_LIGHT]); 4177 return col; 4178 } 4179 4180 if (qtcIsFlatBgnd(opts.bgndAppearance)) { 4181 QtcQWidgetProps props(widget); 4182 bool doEtch = widget && widget->parentWidget() && !props->noEtch; 4183 // CPD: Don't really want to check here for every widget, when 4184 // (so far) on problem seems to be in KPackageKit, and thats with 4185 // its KTextBrowser - so just check when we draw scrollviews... 4186 // if (doEtch && isInQAbstractItemView(widget->parentWidget())) { 4187 // doEtch = false; 4188 // props->noEtch = true; 4189 // } 4190 4191 if(doEtch) 4192 { 4193 QColor bgnd(widget->parentWidget()->palette().color(widget->parentWidget()->backgroundRole())); 4194 4195 if(bgnd.alpha()>0) 4196 return shade(bgnd, 1.06); 4197 } 4198 } 4199 4200 QColor col(Qt::white); 4201 col.setAlphaF(0.1); // qtcIsFlatBgnd(opts.bgndAppearance) ? 0.25 : 0.4); 4202 4203 return col; 4204 } 4205 4206 int 4207 Style::getFrameRound(const QWidget *widget) const 4208 { 4209 if (opts.square & SQUARE_FRAME) { 4210 return ROUNDED_NONE; 4211 } 4212 const QWidget *window = widget ? widget->window() : nullptr; 4213 4214 if (window) { 4215 if (widget->rect() == window->rect()) { 4216 return ROUNDED_NONE; 4217 } 4218 } 4219 4220 if ((opts.square & SQUARE_ENTRY) && widget && 4221 qobject_cast<const QLabel*>(widget)) { 4222 return ROUNDED_NONE; 4223 } 4224 return ROUNDED_ALL; 4225 } 4226 4227 void 4228 Style::widgetDestroyed(QObject *o) 4229 { 4230 QWidget *w = static_cast<QWidget*>(o); 4231 if (theThemedApp == APP_KONTACT) { 4232 m_sViewContainers.remove(w); 4233 QMap<QWidget*, QSet<QWidget*> >::Iterator it(m_sViewContainers.begin()); 4234 QMap<QWidget*, QSet<QWidget*> >::Iterator end(m_sViewContainers.end()); 4235 QSet<QWidget*> rem; 4236 4237 for (;it != end;++it) { 4238 (*it).remove(w); 4239 if ((*it).isEmpty()) { 4240 rem.insert(it.key()); 4241 } 4242 } 4243 for (QWidget *widget: const_(rem)) { 4244 m_sViewContainers.remove(widget); 4245 } 4246 } 4247 } 4248 4249 #ifdef QTC_QT5_ENABLE_KDE 4250 // void Style::setupKde4() 4251 // { 4252 // if(kapp) { 4253 // setDecorationColors(); 4254 // } else { 4255 // applyKdeSettings(true); 4256 // applyKdeSettings(false); 4257 // } 4258 // } 4259 4260 void 4261 Style::setDecorationColors() 4262 { 4263 KColorScheme kcs(QPalette::Active); 4264 if (opts.coloredMouseOver) { 4265 shadeColors(kcs.decoration(KColorScheme::HoverColor).color(), 4266 m_mouseOverCols); 4267 } 4268 shadeColors(kcs.decoration(KColorScheme::FocusColor).color(), m_focusCols); 4269 } 4270 4271 // void Style::applyKdeSettings(bool pal) 4272 // { 4273 // if(pal) 4274 // { 4275 // if(!kapp) 4276 // QApplication::setPalette(standardPalette()); 4277 // setDecorationColors(); 4278 // } 4279 // else 4280 // { 4281 // KConfigGroup g(m_configFile, "General"); 4282 // QFont mnu=g.readEntry("menuFont", QApplication::font()); 4283 4284 // QApplication::setFont(g.readEntry("font", QApplication::font())); 4285 // QApplication::setFont(mnu, "QMenuBar"); 4286 // QApplication::setFont(mnu, "QMenu"); 4287 // QApplication::setFont(mnu, "KPopupTitle"); 4288 // QApplication::setFont(g.readEntry("toolBarFont", QApplication::font()), "QToolBar"); 4289 // } 4290 // } 4291 #endif 4292 4293 void Style::kdeGlobalSettingsChange(int type, int) 4294 { 4295 // TODO 4296 // KDE5 is not emitting this anymore. 4297 // We need our own signal from the configure UI 4298 Q_UNUSED(type); 4299 // switch(type) { 4300 // case KGlobalSettings::StyleChanged: { 4301 // m_configFile->reparseConfiguration(); 4302 // if (m_usePixmapCache) 4303 // QPixmapCache::clear(); 4304 // init(false); 4305 4306 // for (QWidget *widget: QApplication::topLevelWidgets()) { 4307 // widget->update(); 4308 // } 4309 // break; 4310 // } 4311 // case KGlobalSettings::PaletteChanged: 4312 // m_configFile->reparseConfiguration(); 4313 // applyKdeSettings(true); 4314 // if (m_usePixmapCache) 4315 // QPixmapCache::clear(); 4316 // break; 4317 // case KGlobalSettings::FontChanged: 4318 // m_configFile->reparseConfiguration(); 4319 // applyKdeSettings(false); 4320 // break; 4321 // } 4322 4323 m_blurHelper->setEnabled(Utils::compositingActive()); 4324 m_windowManager->initialize(opts.windowDrag); 4325 } 4326 4327 void Style::borderSizesChanged() 4328 { 4329 #ifdef QTC_QT5_ENABLE_KDE 4330 int old = qtcGetWindowBorderSize(false).titleHeight; 4331 4332 if (old != qtcGetWindowBorderSize(true).titleHeight) { 4333 for (QWidget *widget: QApplication::topLevelWidgets()) { 4334 if (qobject_cast<QMainWindow*>(widget) && 4335 static_cast<QMainWindow*>(widget)->menuBar()) { 4336 static_cast<QMainWindow*>(widget)->menuBar()->update(); 4337 } 4338 } 4339 } 4340 #endif 4341 } 4342 4343 static QMainWindow* 4344 getWindow(unsigned int xid) 4345 { 4346 QTC_RET_IF_FAIL(xid, nullptr); 4347 for (QWidget *widget: QApplication::topLevelWidgets()) { 4348 if (qobject_cast<QMainWindow*>(widget) && qtcGetWid(widget) == xid) { 4349 return static_cast<QMainWindow*>(widget); 4350 } 4351 } 4352 return nullptr; 4353 } 4354 4355 static bool 4356 diffTime(struct timeval *lastTime) 4357 { 4358 struct timeval now, diff; 4359 4360 gettimeofday(&now, nullptr); 4361 timersub(&now, lastTime, &diff); 4362 *lastTime = now; 4363 return diff.tv_sec > 0 || diff.tv_usec > 500000; 4364 } 4365 4366 void 4367 Style::toggleMenuBar(unsigned int xid) 4368 { 4369 static unsigned int lastXid = 0; 4370 static struct timeval lastTime = {0, 0}; 4371 4372 if (diffTime(&lastTime) || lastXid != xid) { 4373 QMainWindow *win = getWindow(xid); 4374 if (win) { 4375 toggleMenuBar(win); 4376 } 4377 } 4378 lastXid = xid; 4379 } 4380 4381 void 4382 Style::toggleStatusBar(unsigned int xid) 4383 { 4384 static unsigned int lastXid = 0; 4385 static struct timeval lastTime = {0, 0}; 4386 4387 if (diffTime(&lastTime) || lastXid != xid) { 4388 QMainWindow *win = getWindow(xid); 4389 if (win) { 4390 toggleStatusBar(win); 4391 } 4392 } 4393 lastXid = xid; 4394 } 4395 4396 void Style::compositingToggled() 4397 { 4398 for (QWidget *widget: QApplication::topLevelWidgets()) { 4399 widget->update(); 4400 } 4401 } 4402 4403 void Style::toggleMenuBar(QMainWindow *window) 4404 { 4405 bool triggeredAction(false); 4406 4407 #ifdef QTC_QT5_ENABLE_KDE 4408 if (qobject_cast<KXmlGuiWindow*>(window)) { 4409 KActionCollection *collection=static_cast<KXmlGuiWindow *>(window)->actionCollection(); 4410 QAction *act=collection ? collection->action(KStandardAction::name(KStandardAction::ShowMenubar)) : 0L; 4411 if(act) 4412 { 4413 act->trigger(); 4414 triggeredAction=true; 4415 } 4416 } 4417 #endif 4418 if(!triggeredAction) 4419 { 4420 QWidget *menubar=window->menuWidget(); 4421 if(m_saveMenuBarStatus) 4422 qtcSetMenuBarHidden(appName, menubar->isVisible()); 4423 4424 window->menuWidget()->setHidden(menubar->isVisible()); 4425 } 4426 } 4427 4428 void Style::toggleStatusBar(QMainWindow *window) 4429 { 4430 bool triggeredAction(false); 4431 4432 #ifdef QTC_QT5_ENABLE_KDE 4433 if (qobject_cast<KXmlGuiWindow*>(window)) { 4434 KActionCollection *collection=static_cast<KXmlGuiWindow *>(window)->actionCollection(); 4435 QAction *act=collection ? collection->action(KStandardAction::name(KStandardAction::ShowStatusbar)) : 0L; 4436 if(act) 4437 { 4438 act->trigger(); 4439 triggeredAction=true; 4440 //emitStatusBarState(true); // TODO: ??? 4441 } 4442 } 4443 #endif 4444 if (!triggeredAction) { 4445 QList<QStatusBar*> sb = getStatusBars(window); 4446 4447 if (sb.count()) { 4448 if (m_saveStatusBarStatus) { 4449 qtcSetStatusBarHidden(appName, sb.first()->isVisible()); 4450 } 4451 for (QStatusBar *statusBar: const_(sb)) { 4452 statusBar->setHidden(statusBar->isVisible()); 4453 } 4454 emitStatusBarState(sb.first()); 4455 } 4456 } 4457 } 4458 4459 void Style::emitMenuSize(QWidget *w, unsigned short size, bool force) 4460 { 4461 // DO NOT condition compile on QTC_ENABLE_X11. 4462 // There's no direct linkage on X11 and the following code will just do 4463 // nothing if X11 is not enabled (either at compile time or at run time). 4464 QTC_RET_IF_FAIL(qtcX11Enabled()); 4465 4466 if (WId wid = qtcGetWid(w->window())) { 4467 static const char *constMenuSizeProperty = "qtcMenuSize"; 4468 unsigned short oldSize = 2000; 4469 4470 if (!force) { 4471 QVariant prop(w->property(constMenuSizeProperty)); 4472 if (prop.isValid()) { 4473 bool ok; 4474 oldSize = prop.toUInt(&ok); 4475 if (!ok) { 4476 oldSize = 2000; 4477 } 4478 } 4479 } 4480 4481 if (oldSize != size) { 4482 w->setProperty(constMenuSizeProperty, size); 4483 qtcX11SetMenubarSize(wid, size); 4484 if(!m_dBusHelper->m_dBus) 4485 m_dBusHelper->m_dBus = new QDBusInterface("org.kde.kwin", "/QtCurve", 4486 "org.kde.QtCurve"); 4487 m_dBusHelper->m_dBus->call(QDBus::NoBlock, "menuBarSize", 4488 (unsigned int)wid, (int)size); 4489 } 4490 } 4491 } 4492 4493 void Style::emitStatusBarState(QStatusBar *sb) 4494 { 4495 if (opts.statusbarHiding & HIDE_KWIN) { 4496 if (!m_dBusHelper->m_dBus) 4497 m_dBusHelper->m_dBus = new QDBusInterface("org.kde.kwin", "/QtCurve", 4498 "org.kde.QtCurve"); 4499 m_dBusHelper->m_dBus->call(QDBus::NoBlock, "statusBarState", 4500 (unsigned int)qtcGetWid(sb->window()), 4501 sb->isVisible()); 4502 } 4503 } 4504 }