| 1 | /* |
| 2 | * Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com) |
| 3 | * |
| 4 | * This program is free software: you can redistribute it and/or modify |
| 5 | * it under the terms of the GNU General Public License as published by |
| 6 | * the Free Software Foundation, either version 3 of the License, or |
| 7 | * (at your option) any later version. |
| 8 | * |
| 9 | * This program is distributed in the hope that it will be useful, |
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | * GNU General Public License for more details. |
| 13 | * |
| 14 | * You should have received a copy of the GNU General Public License |
| 15 | * along with this program. If not, see <https://www.gnu.org/licenses/>. |
| 16 | */ |
| 17 | #include "darkfusionstyle.h" |
| 18 | |
| 19 | #include <QPainter> |
| 20 | #include <QStyleOption> |
| 21 | #include <QGroupBox> |
| 22 | #include <qdrawutil.h> |
| 23 | #include <QPainterPath> |
| 24 | #include <QCoreApplication> |
| 25 | #include <QPixmapCache> |
| 26 | #include <QApplication> |
| 27 | #include <QSvgRenderer> |
| 28 | #include "../settings.h" |
| 29 | |
| 30 | #if defined(Q_OS_MACX) |
| 31 | #include <QtGui/private/qguiapplication_p.h> |
| 32 | #include <QtGui/qpa/qplatformtheme.h> |
| 33 | #endif |
| 34 | |
| 35 | #define BEGIN_STYLE_PIXMAPCACHE(a) \ |
| 36 | QRect rect = option->rect; \ |
| 37 | QPixmap internalPixmapCache; \ |
| 38 | QImage imageCache; \ |
| 39 | QPainter *p = painter; \ |
| 40 | QString unique = QStyleHelper::uniqueName((a), option, option->rect.size()); \ |
| 41 | int txType = painter->deviceTransform().type() | painter->worldTransform().type(); \ |
| 42 | bool doPixmapCache = (!option->rect.isEmpty()) \ |
| 43 | && ((txType <= QTransform::TxTranslate) || (painter->deviceTransform().type() == QTransform::TxScale)); \ |
| 44 | if (doPixmapCache && QPixmapCache::find(unique, &internalPixmapCache)) { \ |
| 45 | painter->drawPixmap(option->rect.topLeft(), internalPixmapCache); \ |
| 46 | } else { \ |
| 47 | if (doPixmapCache) { \ |
| 48 | rect.setRect(0, 0, option->rect.width(), option->rect.height()); \ |
| 49 | imageCache = styleCacheImage(option->rect.size()); \ |
| 50 | imageCache.fill(0); \ |
| 51 | p = new QPainter(&imageCache); \ |
| 52 | } |
| 53 | |
| 54 | |
| 55 | |
| 56 | #define END_STYLE_PIXMAPCACHE \ |
| 57 | if (doPixmapCache) { \ |
| 58 | p->end(); \ |
| 59 | delete p; \ |
| 60 | internalPixmapCache = QPixmap::fromImage(imageCache); \ |
| 61 | painter->drawPixmap(option->rect.topLeft(), internalPixmapCache); \ |
| 62 | QPixmapCache::insert(unique, internalPixmapCache); \ |
| 63 | } \ |
| 64 | } |
| 65 | |
| 66 | |
| 67 | namespace QStyleHelper { |
| 68 | |
| 69 | |
| 70 | static QString uniqueName(const QString &key, const QStyleOption *option, const QSize &size) |
| 71 | { |
| 72 | const QStyleOptionComplex *complexOption = qstyleoption_cast<const QStyleOptionComplex *>(option); |
| 73 | QString tmp = QString("%1%2%3%4%5%6%7" ) |
| 74 | .arg(key) |
| 75 | .arg(option->state) |
| 76 | .arg(option->direction) |
| 77 | .arg(complexOption ? uint(complexOption->activeSubControls) : 0u) |
| 78 | .arg(option->palette.cacheKey()) |
| 79 | .arg(size.width()) |
| 80 | .arg(size.height()); |
| 81 | |
| 82 | #if QT_CONFIG(spinbox) |
| 83 | if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) { |
| 84 | tmp = tmp + QString("%1%2%3" ) |
| 85 | .arg(spinBox->buttonSymbols) |
| 86 | .arg(spinBox->stepEnabled) |
| 87 | .arg(QLatin1Char(spinBox->frame ? '1' : '0')); |
| 88 | } |
| 89 | #endif // QT_CONFIG(spinbox) |
| 90 | |
| 91 | return tmp; |
| 92 | } |
| 93 | |
| 94 | static qreal calcDpi() { |
| 95 | return screenDPI(); |
| 96 | } |
| 97 | |
| 98 | static qreal calcDpiScaled(qreal value, qreal dpi) { |
| 99 | return value*96/dpi; |
| 100 | } |
| 101 | |
| 102 | } |
| 103 | |
| 104 | |
| 105 | enum Direction { |
| 106 | TopDown, |
| 107 | FromLeft, |
| 108 | BottomUp, |
| 109 | FromRight |
| 110 | }; |
| 111 | |
| 112 | // from windows style |
| 113 | //static const int windowsItemFrame = 2; // menu item frame width |
| 114 | //static const int windowsItemHMargin = 3; // menu item hor text margin |
| 115 | //static const int windowsItemVMargin = 8; // menu item ver text margin |
| 116 | //static const int windowsRightBorder = 15; // right border on windows |
| 117 | |
| 118 | //static const int groupBoxBottomMargin = 0; // space below the groupbox |
| 119 | //static const int groupBoxTopMargin = 3; |
| 120 | |
| 121 | DarkFusionStyle::DarkFusionStyle():QProxyStyle("fusion" ) |
| 122 | { |
| 123 | |
| 124 | } |
| 125 | // On mac we want a standard blue color used when the system palette is used |
| 126 | static bool isMacSystemPalette(const QPalette &pal){ |
| 127 | Q_UNUSED(pal); |
| 128 | #if defined(Q_OS_MACX) |
| 129 | const QPalette *themePalette = QGuiApplicationPrivate::platformTheme()->palette(); |
| 130 | if (themePalette && themePalette->color(QPalette::Normal, QPalette::Highlight) == |
| 131 | pal.color(QPalette::Normal, QPalette::Highlight) && |
| 132 | themePalette->color(QPalette::Normal, QPalette::HighlightedText) == |
| 133 | pal.color(QPalette::Normal, QPalette::HighlightedText)) |
| 134 | return true; |
| 135 | #endif |
| 136 | return false; |
| 137 | } |
| 138 | |
| 139 | // Used for grip handles |
| 140 | static QColor calcDarkShade() { |
| 141 | return QColor(255, 255, 255, 150); |
| 142 | } |
| 143 | static QColor calcLightShade() { |
| 144 | return QColor(0, 0, 0, 60); |
| 145 | } |
| 146 | |
| 147 | // The default button and handle gradient |
| 148 | static QLinearGradient qt_fusion_gradient(const QRect &rect, const QBrush &baseColor, Direction direction = TopDown) |
| 149 | { |
| 150 | int x = rect.center().x(); |
| 151 | int y = rect.center().y(); |
| 152 | QLinearGradient gradient; |
| 153 | switch (direction) { |
| 154 | case FromLeft: |
| 155 | gradient = QLinearGradient(rect.left(), y, rect.right(), y); |
| 156 | break; |
| 157 | case FromRight: |
| 158 | gradient = QLinearGradient(rect.right(), y, rect.left(), y); |
| 159 | break; |
| 160 | case BottomUp: |
| 161 | gradient = QLinearGradient(x, rect.bottom(), x, rect.top()); |
| 162 | break; |
| 163 | case TopDown: |
| 164 | default: |
| 165 | gradient = QLinearGradient(x, rect.top(), x, rect.bottom()); |
| 166 | break; |
| 167 | } |
| 168 | if (baseColor.gradient()) |
| 169 | gradient.setStops(baseColor.gradient()->stops()); |
| 170 | else { |
| 171 | QColor gradientStartColor = baseColor.color().lighter(124); |
| 172 | QColor gradientStopColor = baseColor.color().lighter(102); |
| 173 | gradient.setColorAt(0, gradientStartColor); |
| 174 | gradient.setColorAt(1, gradientStopColor); |
| 175 | // Uncomment for adding shiny shading |
| 176 | // QColor midColor1 = mergedColors(gradientStartColor, gradientStopColor, 55); |
| 177 | // QColor midColor2 = mergedColors(gradientStartColor, gradientStopColor, 45); |
| 178 | // gradient.setColorAt(0.5, midColor1); |
| 179 | // gradient.setColorAt(0.501, midColor2); |
| 180 | } |
| 181 | return gradient; |
| 182 | } |
| 183 | |
| 184 | |
| 185 | static QColor calcHighlight(const QPalette &pal) { |
| 186 | if (isMacSystemPalette(pal)) |
| 187 | return QColor(60, 140, 230); |
| 188 | return pal.color(QPalette::Highlight); |
| 189 | } |
| 190 | |
| 191 | static QColor calcOutline(const QPalette &pal) { |
| 192 | if (pal.window().style() == Qt::TexturePattern) |
| 193 | return QColor(255, 255, 255, 160); |
| 194 | return pal.window().color().lighter(180); |
| 195 | } |
| 196 | |
| 197 | static QColor calcHighlightedOutline(const QPalette &pal) { |
| 198 | QColor highlightedOutline = calcHighlight(pal).lighter(125); |
| 199 | if (highlightedOutline.value() > 160) |
| 200 | highlightedOutline.setHsl(highlightedOutline.hue(), highlightedOutline.saturation(), 160); |
| 201 | return highlightedOutline; |
| 202 | } |
| 203 | |
| 204 | static QColor calcButtonColor(const QPalette &pal) { |
| 205 | QColor buttonColor = pal.button().color(); |
| 206 | int val = qGray(buttonColor.rgb()); |
| 207 | buttonColor = buttonColor.darker(100 + qMax(1, (180 - val)/6)); |
| 208 | buttonColor.setHsv(buttonColor.hue(), buttonColor.saturation() * 0.75, buttonColor.value()); |
| 209 | return buttonColor; |
| 210 | } |
| 211 | |
| 212 | static QColor calcTabFrameColor(const QPalette &pal) { |
| 213 | if (pal.window().style() == Qt::TexturePattern) |
| 214 | return QColor(255, 255, 255, 8); |
| 215 | return calcButtonColor(pal).lighter(104); |
| 216 | } |
| 217 | |
| 218 | static QColor calcTopShadow() { |
| 219 | return QColor(255, 255, 255, 18); |
| 220 | } |
| 221 | |
| 222 | static QColor calcInnerContrastLine() { |
| 223 | return QColor(0, 0, 0, 30); |
| 224 | } |
| 225 | |
| 226 | static QColor mergedColors(const QColor &colorA, const QColor &colorB, int factor = 50) |
| 227 | { |
| 228 | const int maxFactor = 100; |
| 229 | QColor tmp = colorA; |
| 230 | tmp.setRed((tmp.red() * factor) / maxFactor + (colorB.red() * (maxFactor - factor)) / maxFactor); |
| 231 | tmp.setGreen((tmp.green() * factor) / maxFactor + (colorB.green() * (maxFactor - factor)) / maxFactor); |
| 232 | tmp.setBlue((tmp.blue() * factor) / maxFactor + (colorB.blue() * (maxFactor - factor)) / maxFactor); |
| 233 | return tmp; |
| 234 | } |
| 235 | |
| 236 | static QImage styleCacheImage(const QSize &size) |
| 237 | { |
| 238 | const qreal pixelRatio = qApp->devicePixelRatio(); |
| 239 | QImage cacheImage = QImage(size * pixelRatio, QImage::Format_ARGB32_Premultiplied); |
| 240 | cacheImage.setDevicePixelRatio(pixelRatio); |
| 241 | return cacheImage; |
| 242 | } |
| 243 | |
| 244 | |
| 245 | |
| 246 | void DarkFusionStyle::drawPrimitive(PrimitiveElement elem, const QStyleOption *option, QPainter *painter, const QWidget *widget) const |
| 247 | { |
| 248 | Q_ASSERT(option); |
| 249 | |
| 250 | QRect rect = option->rect; |
| 251 | int state = option->state; |
| 252 | |
| 253 | QColor outline = calcOutline(option->palette); |
| 254 | QColor highlightedOutline = calcHighlightedOutline(option->palette); |
| 255 | |
| 256 | QColor tabFrameColor = calcTabFrameColor(option->palette); |
| 257 | |
| 258 | switch (elem) { |
| 259 | |
| 260 | //#if QT_CONFIG(groupbox) |
| 261 | // // No frame drawn |
| 262 | // case PE_FrameGroupBox: |
| 263 | // { |
| 264 | // QPixmap pixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_groupbox.png")); |
| 265 | // int topMargin = 0; |
| 266 | // auto control = qobject_cast<const QGroupBox *>(widget); |
| 267 | // if (control && !control->isCheckable() && control->title().isEmpty()) { |
| 268 | // // Shrinking the topMargin if Not checkable AND title is empty |
| 269 | // topMargin = groupBoxTopMargin; |
| 270 | // } else { |
| 271 | // topMargin = qMax(pixelMetric(PM_ExclusiveIndicatorHeight), option->fontMetrics.height()) + groupBoxTopMargin; |
| 272 | // } |
| 273 | // QRect frame = option->rect.adjusted(0, topMargin, 0, 0); |
| 274 | // qDrawBorderPixmap(painter, frame, QMargins(6, 6, 6, 6), pixmap); |
| 275 | // break; |
| 276 | // } |
| 277 | //#endif // QT_CONFIG(groupbox) |
| 278 | // case PE_IndicatorBranch: { |
| 279 | // if (!(option->state & State_Children)) |
| 280 | // break; |
| 281 | // if (option->state & State_Open) |
| 282 | // drawPrimitive(PE_IndicatorArrowDown, option, painter, widget); |
| 283 | // else { |
| 284 | // const bool reverse = (option->direction == Qt::RightToLeft); |
| 285 | // drawPrimitive(reverse ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight, option, painter, widget); |
| 286 | // } |
| 287 | // break; |
| 288 | // } |
| 289 | #if QT_CONFIG(tabbar) |
| 290 | case PE_FrameTabBarBase: |
| 291 | if (const QStyleOptionTabBarBase *tbb |
| 292 | = qstyleoption_cast<const QStyleOptionTabBarBase *>(option)) { |
| 293 | painter->save(); |
| 294 | painter->setPen(QPen(outline.darker(110))); |
| 295 | switch (tbb->shape) { |
| 296 | case QTabBar::RoundedNorth: { |
| 297 | QRegion region(tbb->rect); |
| 298 | region -= tbb->selectedTabRect; |
| 299 | painter->drawLine(tbb->rect.topLeft(), tbb->rect.topRight()); |
| 300 | painter->setClipRegion(region); |
| 301 | painter->setPen(option->palette.light().color()); |
| 302 | painter->drawLine(tbb->rect.topLeft() + QPoint(0, 1), tbb->rect.topRight() + QPoint(0, 1)); |
| 303 | } |
| 304 | break; |
| 305 | case QTabBar::RoundedWest: |
| 306 | painter->drawLine(tbb->rect.left(), tbb->rect.top(), tbb->rect.left(), tbb->rect.bottom()); |
| 307 | break; |
| 308 | case QTabBar::RoundedSouth: |
| 309 | painter->drawLine(tbb->rect.left(), tbb->rect.bottom(), |
| 310 | tbb->rect.right(), tbb->rect.bottom()); |
| 311 | break; |
| 312 | case QTabBar::RoundedEast: |
| 313 | painter->drawLine(tbb->rect.topRight(), tbb->rect.bottomRight()); |
| 314 | break; |
| 315 | case QTabBar::TriangularNorth: |
| 316 | case QTabBar::TriangularEast: |
| 317 | case QTabBar::TriangularWest: |
| 318 | case QTabBar::TriangularSouth: |
| 319 | painter->restore(); |
| 320 | QCommonStyle::drawPrimitive(elem, option, painter, widget); |
| 321 | return; |
| 322 | } |
| 323 | painter->restore(); |
| 324 | } |
| 325 | return; |
| 326 | #endif // QT_CONFIG(tabbar) |
| 327 | case PE_PanelScrollAreaCorner: { |
| 328 | painter->save(); |
| 329 | QColor alphaOutline = outline; |
| 330 | alphaOutline.setAlpha(180); |
| 331 | painter->setPen(alphaOutline); |
| 332 | painter->setBrush(option->palette.brush(QPalette::Window)); |
| 333 | painter->drawRect(option->rect); |
| 334 | painter->restore(); |
| 335 | } break; |
| 336 | // case PE_IndicatorArrowUp: |
| 337 | // case PE_IndicatorArrowDown: |
| 338 | // case PE_IndicatorArrowRight: |
| 339 | // case PE_IndicatorArrowLeft: |
| 340 | // { |
| 341 | // if (option->rect.width() <= 1 || option->rect.height() <= 1) |
| 342 | // break; |
| 343 | // QColor arrowColor = option->palette.windowText().color(); |
| 344 | // arrowColor.setAlpha(160); |
| 345 | // Qt::ArrowType arrow = Qt::UpArrow; |
| 346 | // switch (elem) { |
| 347 | // case PE_IndicatorArrowDown: |
| 348 | // arrow = Qt::DownArrow; |
| 349 | // break; |
| 350 | // case PE_IndicatorArrowRight: |
| 351 | // arrow = Qt::RightArrow; |
| 352 | // break; |
| 353 | // case PE_IndicatorArrowLeft: |
| 354 | // arrow = Qt::LeftArrow; |
| 355 | // break; |
| 356 | // default: |
| 357 | // break; |
| 358 | // } |
| 359 | // qt_fusion_draw_arrow(arrow, painter, option, option->rect, arrowColor); |
| 360 | // } |
| 361 | // break; |
| 362 | // case PE_IndicatorItemViewItemCheck: |
| 363 | // { |
| 364 | // QStyleOptionButton button; |
| 365 | // button.QStyleOption::operator=(*option); |
| 366 | // button.state &= ~State_MouseOver; |
| 367 | // proxy()->drawPrimitive(PE_IndicatorCheckBox, &button, painter, widget); |
| 368 | // } |
| 369 | // return; |
| 370 | // case PE_IndicatorHeaderArrow: |
| 371 | // if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) { |
| 372 | // QRect r = header->rect; |
| 373 | // QColor arrowColor = header->palette.windowText().color(); |
| 374 | // arrowColor.setAlpha(180); |
| 375 | // QPoint offset = QPoint(0, -2); |
| 376 | |
| 377 | //#if defined(Q_OS_LINUX) |
| 378 | // if (header->sortIndicator & QStyleOptionHeader::SortUp) { |
| 379 | // qt_fusion_draw_arrow(Qt::UpArrow, painter, option, r.translated(offset), arrowColor); |
| 380 | // } else if (header->sortIndicator & QStyleOptionHeader::SortDown) { |
| 381 | // qt_fusion_draw_arrow(Qt::DownArrow, painter, option, r.translated(offset), arrowColor); |
| 382 | // } |
| 383 | //#else |
| 384 | // if (header->sortIndicator & QStyleOptionHeader::SortUp) { |
| 385 | // qt_fusion_draw_arrow(Qt::DownArrow, painter, option, r.translated(offset), arrowColor); |
| 386 | // } else if (header->sortIndicator & QStyleOptionHeader::SortDown) { |
| 387 | // qt_fusion_draw_arrow(Qt::UpArrow, painter, option, r.translated(offset), arrowColor); |
| 388 | // } |
| 389 | //#endif |
| 390 | // } |
| 391 | // break; |
| 392 | // case PE_IndicatorButtonDropDown: |
| 393 | // proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget); |
| 394 | // break; |
| 395 | |
| 396 | case PE_IndicatorToolBarSeparator: |
| 397 | { |
| 398 | QRect rect = option->rect; |
| 399 | const int margin = 6; |
| 400 | if (option->state & State_Horizontal) { |
| 401 | const int offset = rect.width()/2; |
| 402 | painter->setPen(QPen(option->palette.window().color().lighter(110))); |
| 403 | painter->drawLine(rect.bottomLeft().x() + offset, |
| 404 | rect.bottomLeft().y() - margin, |
| 405 | rect.topLeft().x() + offset, |
| 406 | rect.topLeft().y() + margin); |
| 407 | painter->setPen(QPen(option->palette.window().color().darker(110))); |
| 408 | painter->drawLine(rect.bottomLeft().x() + offset + 1, |
| 409 | rect.bottomLeft().y() - margin, |
| 410 | rect.topLeft().x() + offset + 1, |
| 411 | rect.topLeft().y() + margin); |
| 412 | } else { //Draw vertical separator |
| 413 | const int offset = rect.height()/2; |
| 414 | painter->setPen(QPen(option->palette.window().color().lighter(110))); |
| 415 | painter->drawLine(rect.topLeft().x() + margin , |
| 416 | rect.topLeft().y() + offset, |
| 417 | rect.topRight().x() - margin, |
| 418 | rect.topRight().y() + offset); |
| 419 | painter->setPen(QPen(option->palette.window().color().darker(110))); |
| 420 | painter->drawLine(rect.topLeft().x() + margin , |
| 421 | rect.topLeft().y() + offset + 1, |
| 422 | rect.topRight().x() - margin, |
| 423 | rect.topRight().y() + offset + 1); |
| 424 | } |
| 425 | } |
| 426 | break; |
| 427 | case PE_Frame: { |
| 428 | if (widget && widget->inherits("QComboBoxPrivateContainer" )){ |
| 429 | QStyleOption copy = *option; |
| 430 | copy.state |= State_Raised; |
| 431 | proxy()->drawPrimitive(PE_PanelMenu, ©, painter, widget); |
| 432 | break; |
| 433 | } |
| 434 | painter->save(); |
| 435 | QPen thePen(outline.darker(108)); |
| 436 | thePen.setCosmetic(false); |
| 437 | painter->setPen(thePen); |
| 438 | painter->drawRect(option->rect.adjusted(0, 0, -1, -1)); |
| 439 | painter->restore(); } |
| 440 | break; |
| 441 | case PE_FrameMenu: |
| 442 | painter->save(); |
| 443 | { |
| 444 | painter->setPen(QPen(outline)); |
| 445 | painter->drawRect(option->rect.adjusted(0, 0, -1, -1)); |
| 446 | QColor frameLight = option->palette.window().color().darker(160); |
| 447 | QColor frameShadow = option->palette.window().color().lighter(110); |
| 448 | |
| 449 | //paint beveleffect |
| 450 | QRect frame = option->rect.adjusted(1, 1, -1, -1); |
| 451 | painter->setPen(frameLight); |
| 452 | painter->drawLine(frame.topLeft(), frame.bottomLeft()); |
| 453 | painter->drawLine(frame.topLeft(), frame.topRight()); |
| 454 | |
| 455 | painter->setPen(frameShadow); |
| 456 | painter->drawLine(frame.topRight(), frame.bottomRight()); |
| 457 | painter->drawLine(frame.bottomLeft(), frame.bottomRight()); |
| 458 | } |
| 459 | painter->restore(); |
| 460 | break; |
| 461 | case PE_FrameDockWidget: |
| 462 | |
| 463 | painter->save(); |
| 464 | { |
| 465 | QColor softshadow = option->palette.window().color().lighter(120); |
| 466 | |
| 467 | QRect rect= option->rect; |
| 468 | painter->setPen(softshadow); |
| 469 | painter->drawRect(option->rect.adjusted(0, 0, -1, -1)); |
| 470 | painter->setPen(QPen(option->palette.light(), 1)); |
| 471 | painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1), QPoint(rect.left() + 1, rect.bottom() - 1)); |
| 472 | painter->setPen(QPen(option->palette.window().color().lighter(120))); |
| 473 | painter->drawLine(QPoint(rect.left() + 1, rect.bottom() - 1), QPoint(rect.right() - 2, rect.bottom() - 1)); |
| 474 | painter->drawLine(QPoint(rect.right() - 1, rect.top() + 1), QPoint(rect.right() - 1, rect.bottom() - 1)); |
| 475 | |
| 476 | } |
| 477 | painter->restore(); |
| 478 | break; |
| 479 | // case PE_PanelButtonTool: |
| 480 | // painter->save(); |
| 481 | // if ((option->state & State_Enabled || option->state & State_On) || !(option->state & State_AutoRaise)) { |
| 482 | // if (widget && widget->inherits("QDockWidgetTitleButton")) { |
| 483 | // if (option->state & State_MouseOver) |
| 484 | // proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget); |
| 485 | // } else { |
| 486 | // proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget); |
| 487 | // } |
| 488 | // } |
| 489 | // painter->restore(); |
| 490 | // break; |
| 491 | // case PE_IndicatorDockWidgetResizeHandle: |
| 492 | // { |
| 493 | // QStyleOption dockWidgetHandle = *option; |
| 494 | // bool horizontal = option->state & State_Horizontal; |
| 495 | // dockWidgetHandle.state.setFlag(State_Horizontal, !horizontal); |
| 496 | // proxy()->drawControl(CE_Splitter, &dockWidgetHandle, painter, widget); |
| 497 | // } |
| 498 | // break; |
| 499 | case PE_FrameWindow: |
| 500 | painter->save(); |
| 501 | { |
| 502 | QRect rect= option->rect; |
| 503 | painter->setPen(QPen(outline.lighter(150))); |
| 504 | painter->drawRect(option->rect.adjusted(0, 0, -1, -1)); |
| 505 | painter->setPen(QPen(option->palette.light(), 1)); |
| 506 | painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1), |
| 507 | QPoint(rect.left() + 1, rect.bottom() - 1)); |
| 508 | painter->setPen(QPen(option->palette.window().color().darker(120))); |
| 509 | painter->drawLine(QPoint(rect.left() + 1, rect.bottom() - 1), |
| 510 | QPoint(rect.right() - 2, rect.bottom() - 1)); |
| 511 | painter->drawLine(QPoint(rect.right() - 1, rect.top() + 1), |
| 512 | QPoint(rect.right() - 1, rect.bottom() - 1)); |
| 513 | } |
| 514 | painter->restore(); |
| 515 | break; |
| 516 | case PE_FrameLineEdit: |
| 517 | { |
| 518 | QRect r = rect; |
| 519 | bool hasFocus = option->state & State_HasFocus; |
| 520 | |
| 521 | painter->save(); |
| 522 | |
| 523 | painter->setRenderHint(QPainter::Antialiasing, true); |
| 524 | // ### highdpi painter bug. |
| 525 | painter->translate(0.5, 0.5); |
| 526 | |
| 527 | // Draw Outline |
| 528 | painter->setPen( QPen(hasFocus ? highlightedOutline : outline)); |
| 529 | painter->drawRoundedRect(r.adjusted(0, 0, -1, -1), 2, 2); |
| 530 | |
| 531 | if (hasFocus) { |
| 532 | QColor softHighlight = highlightedOutline; |
| 533 | softHighlight.setAlpha(40); |
| 534 | painter->setPen(softHighlight); |
| 535 | painter->drawRoundedRect(r.adjusted(1, 1, -2, -2), 1.7, 1.7); |
| 536 | } |
| 537 | // Draw inner shadow |
| 538 | painter->setPen(calcTopShadow()); |
| 539 | painter->drawLine(QPoint(r.left() + 2, r.top() + 1), QPoint(r.right() - 2, r.top() + 1)); |
| 540 | |
| 541 | painter->restore(); |
| 542 | |
| 543 | } |
| 544 | break; |
| 545 | case PE_IndicatorCheckBox: |
| 546 | painter->save(); |
| 547 | if (const QStyleOptionButton *checkbox = qstyleoption_cast<const QStyleOptionButton*>(option)) { |
| 548 | painter->setRenderHint(QPainter::Antialiasing, true); |
| 549 | painter->translate(0.5, 0.5); |
| 550 | rect = rect.adjusted(0, 0, -1, -1); |
| 551 | |
| 552 | QColor pressedColor = mergedColors(option->palette.base().color(), option->palette.windowText().color(), 85); |
| 553 | painter->setBrush(Qt::NoBrush); |
| 554 | |
| 555 | // Gradient fill |
| 556 | QLinearGradient gradient(rect.topLeft(), rect.bottomLeft()); |
| 557 | gradient.setColorAt(0, (state & State_Sunken) ? pressedColor : option->palette.base().color().lighter(115)); |
| 558 | gradient.setColorAt(0.15, (state & State_Sunken) ? pressedColor : option->palette.base().color()); |
| 559 | gradient.setColorAt(1, (state & State_Sunken) ? pressedColor : option->palette.base().color()); |
| 560 | |
| 561 | painter->setBrush((state & State_Sunken) ? QBrush(pressedColor) : gradient); |
| 562 | painter->setPen(QPen(outline.lighter(110))); |
| 563 | |
| 564 | if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange) |
| 565 | painter->setPen(QPen(highlightedOutline)); |
| 566 | painter->drawRect(rect); |
| 567 | |
| 568 | QColor checkMarkColor = option->palette.text().color().lighter(120); |
| 569 | const qreal checkMarkPadding = 1 + rect.width() * 0.13; // at least one pixel padding |
| 570 | |
| 571 | if (checkbox->state & State_NoChange) { |
| 572 | gradient = QLinearGradient(rect.topLeft(), rect.bottomLeft()); |
| 573 | checkMarkColor.setAlpha(80); |
| 574 | gradient.setColorAt(0, checkMarkColor); |
| 575 | checkMarkColor.setAlpha(140); |
| 576 | gradient.setColorAt(1, checkMarkColor); |
| 577 | checkMarkColor.setAlpha(180); |
| 578 | painter->setPen(QPen(checkMarkColor, 1)); |
| 579 | painter->setBrush(gradient); |
| 580 | painter->drawRect(rect.adjusted(checkMarkPadding, checkMarkPadding, -checkMarkPadding, -checkMarkPadding)); |
| 581 | |
| 582 | } else if (checkbox->state & State_On) { |
| 583 | |
| 584 | const qreal dpi = QStyleHelper::calcDpi(); |
| 585 | |
| 586 | qreal penWidth = QStyleHelper::calcDpiScaled(1.5, dpi); |
| 587 | penWidth = qMax<qreal>(penWidth, 0.13 * rect.height()); |
| 588 | penWidth = qMin<qreal>(penWidth, 0.20 * rect.height()); |
| 589 | QPen checkPen = QPen(checkMarkColor, penWidth); |
| 590 | checkMarkColor.setAlpha(210); |
| 591 | painter->translate(QStyleHelper::calcDpiScaled(-0.8, dpi), QStyleHelper::calcDpiScaled(0.5, dpi)); |
| 592 | painter->setPen(checkPen); |
| 593 | painter->setBrush(Qt::NoBrush); |
| 594 | |
| 595 | // Draw checkmark |
| 596 | QPainterPath path; |
| 597 | const qreal rectHeight = rect.height(); // assuming height equals width |
| 598 | path.moveTo(checkMarkPadding + rectHeight * 0.11, rectHeight * 0.47); |
| 599 | path.lineTo(rectHeight * 0.5, rectHeight - checkMarkPadding); |
| 600 | path.lineTo(rectHeight - checkMarkPadding, checkMarkPadding); |
| 601 | painter->drawPath(path.translated(rect.topLeft())); |
| 602 | } |
| 603 | } |
| 604 | painter->restore(); |
| 605 | break; |
| 606 | case PE_IndicatorRadioButton: |
| 607 | painter->save(); |
| 608 | { |
| 609 | QColor pressedColor = mergedColors(option->palette.base().color(), option->palette.windowText().color(), 85); |
| 610 | painter->setBrush((state & State_Sunken) ? pressedColor : option->palette.base().color()); |
| 611 | painter->setRenderHint(QPainter::Antialiasing, true); |
| 612 | QPainterPath circle; |
| 613 | const QPointF circleCenter = rect.center() + QPoint(1, 1); |
| 614 | const qreal outlineRadius = (rect.width() + (rect.width() + 1) % 2) / 2.0 - 1; |
| 615 | circle.addEllipse(circleCenter, outlineRadius, outlineRadius); |
| 616 | painter->setPen(QPen(option->palette.window().color().lighter(150))); |
| 617 | if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange) |
| 618 | painter->setPen(QPen(highlightedOutline)); |
| 619 | painter->drawPath(circle); |
| 620 | |
| 621 | if (state & (State_On )) { |
| 622 | circle = QPainterPath(); |
| 623 | const qreal checkmarkRadius = outlineRadius / 2.32; |
| 624 | circle.addEllipse(circleCenter, checkmarkRadius, checkmarkRadius); |
| 625 | QColor checkMarkColor = option->palette.text().color().lighter(120); |
| 626 | checkMarkColor.setAlpha(200); |
| 627 | painter->setPen(checkMarkColor); |
| 628 | checkMarkColor.setAlpha(180); |
| 629 | painter->setBrush(checkMarkColor); |
| 630 | painter->drawPath(circle); |
| 631 | } |
| 632 | } |
| 633 | painter->restore(); |
| 634 | break; |
| 635 | case PE_IndicatorToolBarHandle: |
| 636 | { |
| 637 | //draw grips |
| 638 | if (option->state & State_Horizontal) { |
| 639 | for (int i = -3 ; i < 2 ; i += 3) { |
| 640 | for (int j = -8 ; j < 10 ; j += 3) { |
| 641 | painter->fillRect(rect.center().x() + i, rect.center().y() + j, 2, 2, calcLightShade()); |
| 642 | painter->fillRect(rect.center().x() + i, rect.center().y() + j, 1, 1, calcDarkShade()); |
| 643 | } |
| 644 | } |
| 645 | } else { //vertical toolbar |
| 646 | for (int i = -6 ; i < 12 ; i += 3) { |
| 647 | for (int j = -3 ; j < 2 ; j += 3) { |
| 648 | painter->fillRect(rect.center().x() + i, rect.center().y() + j, 2, 2, calcLightShade()); |
| 649 | painter->fillRect(rect.center().x() + i, rect.center().y() + j, 1, 1, calcDarkShade()); |
| 650 | } |
| 651 | } |
| 652 | } |
| 653 | break; |
| 654 | } |
| 655 | case PE_FrameDefaultButton: |
| 656 | break; |
| 657 | case PE_FrameFocusRect: |
| 658 | if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(option)) { |
| 659 | //### check for d->alt_down |
| 660 | if (!(fropt->state & State_KeyboardFocusChange)) |
| 661 | return; |
| 662 | QRect rect = option->rect; |
| 663 | |
| 664 | painter->save(); |
| 665 | painter->setRenderHint(QPainter::Antialiasing, true); |
| 666 | painter->translate(0.5, 0.5); |
| 667 | QColor fillcolor = highlightedOutline; |
| 668 | fillcolor.setAlpha(80); |
| 669 | painter->setPen(fillcolor.lighter(120)); |
| 670 | fillcolor.setAlpha(30); |
| 671 | QLinearGradient gradient(rect.topLeft(), rect.bottomLeft()); |
| 672 | gradient.setColorAt(0, fillcolor.darker(160)); |
| 673 | gradient.setColorAt(1, fillcolor); |
| 674 | painter->setBrush(gradient); |
| 675 | painter->drawRoundedRect(option->rect.adjusted(0, 0, -1, -1), 1, 1); |
| 676 | painter->restore(); |
| 677 | } |
| 678 | break; |
| 679 | case PE_PanelButtonCommand: |
| 680 | { |
| 681 | bool isDefault = false; |
| 682 | bool isFlat = false; |
| 683 | bool isDown = (option->state & State_Sunken) || (option->state & State_On); |
| 684 | QRect r; |
| 685 | |
| 686 | if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton*>(option)) { |
| 687 | isDefault = (button->features & QStyleOptionButton::DefaultButton) && (button->state & State_Enabled); |
| 688 | isFlat = (button->features & QStyleOptionButton::Flat); |
| 689 | } |
| 690 | |
| 691 | if (isFlat && !isDown) { |
| 692 | if (isDefault) { |
| 693 | r = option->rect.adjusted(0, 1, 0, -1); |
| 694 | painter->setPen(QPen(Qt::lightGray)); |
| 695 | const QLine lines[4] = { |
| 696 | QLine(QPoint(r.left() + 2, r.top()), |
| 697 | QPoint(r.right() - 2, r.top())), |
| 698 | QLine(QPoint(r.left(), r.top() + 2), |
| 699 | QPoint(r.left(), r.bottom() - 2)), |
| 700 | QLine(QPoint(r.right(), r.top() + 2), |
| 701 | QPoint(r.right(), r.bottom() - 2)), |
| 702 | QLine(QPoint(r.left() + 2, r.bottom()), |
| 703 | QPoint(r.right() - 2, r.bottom())) |
| 704 | }; |
| 705 | painter->drawLines(lines, 4); |
| 706 | const QPoint points[4] = { |
| 707 | QPoint(r.right() - 1, r.bottom() - 1), |
| 708 | QPoint(r.right() - 1, r.top() + 1), |
| 709 | QPoint(r.left() + 1, r.bottom() - 1), |
| 710 | QPoint(r.left() + 1, r.top() + 1) |
| 711 | }; |
| 712 | painter->drawPoints(points, 4); |
| 713 | } |
| 714 | return; |
| 715 | } |
| 716 | |
| 717 | |
| 718 | bool isEnabled = option->state & State_Enabled; |
| 719 | bool hasFocus = (option->state & State_HasFocus && option->state & State_KeyboardFocusChange); |
| 720 | QColor buttonColor = calcButtonColor(option->palette); |
| 721 | |
| 722 | QColor darkOutline = outline; |
| 723 | if (hasFocus | isDefault) { |
| 724 | darkOutline = highlightedOutline; |
| 725 | } |
| 726 | |
| 727 | if (isDefault) |
| 728 | buttonColor = mergedColors(buttonColor, highlightedOutline.lighter(130), 90); |
| 729 | |
| 730 | BEGIN_STYLE_PIXMAPCACHE(QStringLiteral("pushbutton-" ) + buttonColor.name(QColor::HexArgb)) |
| 731 | r = rect.adjusted(0, 1, -1, 0); |
| 732 | |
| 733 | p->setRenderHint(QPainter::Antialiasing, true); |
| 734 | p->translate(0.5, -0.5); |
| 735 | |
| 736 | QLinearGradient gradient = qt_fusion_gradient(rect, (isEnabled && option->state & State_MouseOver ) ? buttonColor : buttonColor.darker(104)); |
| 737 | p->setPen(Qt::transparent); |
| 738 | p->setBrush(isDown ? QBrush(buttonColor.lighter(250)) : gradient); |
| 739 | p->drawRoundedRect(r, 2.0, 2.0); |
| 740 | p->setBrush(Qt::NoBrush); |
| 741 | |
| 742 | // Outline |
| 743 | p->setPen(!isEnabled ? QPen(darkOutline.lighter(115)) : QPen(darkOutline)); |
| 744 | p->drawRoundedRect(r, 2.0, 2.0); |
| 745 | |
| 746 | p->setPen(calcInnerContrastLine()); |
| 747 | p->drawRoundedRect(r.adjusted(1, 1, -1, -1), 2.0, 2.0); |
| 748 | |
| 749 | END_STYLE_PIXMAPCACHE |
| 750 | } |
| 751 | break; |
| 752 | case PE_FrameTabWidget: |
| 753 | painter->save(); |
| 754 | painter->fillRect(option->rect.adjusted(0, 0, -1, -1), tabFrameColor); |
| 755 | #if QT_CONFIG(tabwidget) |
| 756 | if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) { |
| 757 | QColor borderColor = outline.lighter(110); |
| 758 | QRect rect = option->rect.adjusted(0, 0, -1, -1); |
| 759 | |
| 760 | // Shadow outline |
| 761 | if (twf->shape != QTabBar::RoundedSouth) { |
| 762 | rect.adjust(0, 0, 0, -1); |
| 763 | QColor alphaShadow(Qt::black); |
| 764 | alphaShadow.setAlpha(15); |
| 765 | painter->setPen(alphaShadow); |
| 766 | painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight()); painter->setPen(borderColor); |
| 767 | } |
| 768 | |
| 769 | // outline |
| 770 | painter->setPen(outline); |
| 771 | painter->drawRect(rect); |
| 772 | |
| 773 | // Inner frame highlight |
| 774 | painter->setPen(calcInnerContrastLine()); |
| 775 | painter->drawRect(rect.adjusted(1, 1, -1, -1)); |
| 776 | |
| 777 | } |
| 778 | #endif // QT_CONFIG(tabwidget) |
| 779 | painter->restore(); |
| 780 | break ; |
| 781 | |
| 782 | case PE_FrameStatusBarItem: |
| 783 | break; |
| 784 | case PE_IndicatorTabClose: |
| 785 | { |
| 786 | QIcon closeIcon = proxy()->standardIcon(SP_DialogCloseButton, option, widget); |
| 787 | if ((option->state & State_Enabled) && (option->state & State_MouseOver)) |
| 788 | proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget); |
| 789 | int size = pointToPixel(pSettings->environment().interfaceFontSize()); |
| 790 | QPixmap pixmap = closeIcon.pixmap(QSize(size, size), QIcon::Normal, QIcon::On); |
| 791 | proxy()->drawItemPixmap(painter, option->rect, Qt::AlignCenter, pixmap); |
| 792 | } |
| 793 | break; |
| 794 | case PE_PanelMenu: { |
| 795 | painter->save(); |
| 796 | const QBrush = option->palette.base().color().darker(108); |
| 797 | QColor borderColor = option->palette.window().color().lighter(160); |
| 798 | qDrawPlainRect(painter, option->rect, borderColor, 1, &menuBackground); |
| 799 | painter->restore(); |
| 800 | } |
| 801 | break; |
| 802 | default: |
| 803 | QProxyStyle::drawPrimitive(elem, option, painter, widget); |
| 804 | break; |
| 805 | } |
| 806 | } |
| 807 | |
| 808 | QIcon DarkFusionStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const |
| 809 | { |
| 810 | switch (standardIcon) { |
| 811 | case SP_TitleBarCloseButton: |
| 812 | case SP_DockWidgetCloseButton: |
| 813 | case SP_DialogCloseButton: { |
| 814 | int size = pointToPixel(pSettings->environment().interfaceFontSize()); |
| 815 | QSvgRenderer renderer(QString(":/icons/images/dark-close.svg" )); |
| 816 | QPixmap pixmap(size,size); |
| 817 | pixmap.fill(Qt::transparent); |
| 818 | QPainter painter(&pixmap); |
| 819 | renderer.render(&painter,pixmap.rect()); |
| 820 | return QIcon(pixmap); |
| 821 | } |
| 822 | default: |
| 823 | break; |
| 824 | } |
| 825 | |
| 826 | return QProxyStyle::standardIcon(standardIcon, option, widget); |
| 827 | } |
| 828 | |
| 829 | void DarkFusionStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const |
| 830 | { |
| 831 | QProxyStyle::drawComplexControl(control,option,painter,widget); |
| 832 | } |
| 833 | |
| 834 | int DarkFusionStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const |
| 835 | { |
| 836 | switch ( metric ) { |
| 837 | case QStyle::PM_SmallIconSize: |
| 838 | return pointToPixel(pSettings->environment().interfaceFontSize()); |
| 839 | case QStyle::PM_TabCloseIndicatorHeight: |
| 840 | case QStyle::PM_TabCloseIndicatorWidth: |
| 841 | return 1.2*pointToPixel(pSettings->environment().interfaceFontSize()); |
| 842 | default: |
| 843 | return QProxyStyle::pixelMetric( metric, option, widget ); |
| 844 | } |
| 845 | } |
| 846 | |
| 847 | void DarkFusionStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, |
| 848 | const QWidget *widget) const |
| 849 | { |
| 850 | QRect rect = option->rect; |
| 851 | QColor outline = calcOutline(option->palette); |
| 852 | //QColor highlightedOutline = calcHighlightedOutline(option->palette); |
| 853 | QColor shadow = calcDarkShade(); |
| 854 | |
| 855 | |
| 856 | switch (element) { |
| 857 | case CE_MenuItem: |
| 858 | // Draws one item in a popup menu. |
| 859 | if (const QStyleOptionMenuItem * = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) { |
| 860 | //QColor highlightOutline = highlightedOutline; |
| 861 | //QColor highlight = option->palette.highlight().color(); |
| 862 | if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) { |
| 863 | painter->save(); |
| 864 | int w = 0; |
| 865 | qreal dpi = QStyleHelper::calcDpi(); |
| 866 | const int margin = int(QStyleHelper::calcDpiScaled(5, dpi)); |
| 867 | if (!menuItem->text.isEmpty()) { |
| 868 | painter->setFont(menuItem->font); |
| 869 | proxy()->drawItemText(painter, menuItem->rect.adjusted(margin, 0, -margin, 0), Qt::AlignLeft | Qt::AlignVCenter, |
| 870 | menuItem->palette, menuItem->state & State_Enabled, menuItem->text, |
| 871 | QPalette::Text); |
| 872 | w = menuItem->fontMetrics.horizontalAdvance(menuItem->text) + margin; |
| 873 | } |
| 874 | painter->setPen(shadow.darker(150)); |
| 875 | bool reverse = menuItem->direction == Qt::RightToLeft; |
| 876 | painter->drawLine(menuItem->rect.left() + margin + (reverse ? 0 : w), menuItem->rect.center().y(), |
| 877 | menuItem->rect.right() - margin - (reverse ? w : 0), menuItem->rect.center().y()); |
| 878 | painter->restore(); |
| 879 | break; |
| 880 | } |
| 881 | } |
| 882 | QProxyStyle::drawControl(element, option, painter, widget); |
| 883 | break; |
| 884 | case CE_TabBarTabShape: |
| 885 | painter->save(); |
| 886 | if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) { |
| 887 | |
| 888 | bool rtlHorTabs = (tab->direction == Qt::RightToLeft |
| 889 | && (tab->shape == QTabBar::RoundedNorth |
| 890 | || tab->shape == QTabBar::RoundedSouth)); |
| 891 | bool selected = tab->state & State_Selected; |
| 892 | bool lastTab = ((!rtlHorTabs && tab->position == QStyleOptionTab::End) |
| 893 | || (rtlHorTabs |
| 894 | && tab->position == QStyleOptionTab::Beginning)); |
| 895 | bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab; |
| 896 | int tabOverlap = pixelMetric(PM_TabBarTabOverlap, option, widget); |
| 897 | rect = option->rect.adjusted(0, 0, (onlyOne || lastTab) ? 0 : tabOverlap, 0); |
| 898 | |
| 899 | QRect r2(rect); |
| 900 | int x1 = r2.left(); |
| 901 | int x2 = r2.right(); |
| 902 | int y1 = r2.top(); |
| 903 | int y2 = r2.bottom(); |
| 904 | |
| 905 | painter->setPen(calcInnerContrastLine()); |
| 906 | |
| 907 | QTransform rotMatrix; |
| 908 | bool flip = false; |
| 909 | painter->setPen(shadow); |
| 910 | |
| 911 | switch (tab->shape) { |
| 912 | case QTabBar::RoundedNorth: |
| 913 | break; |
| 914 | case QTabBar::RoundedSouth: |
| 915 | rotMatrix.rotate(180); |
| 916 | rotMatrix.translate(0, -rect.height() + 1); |
| 917 | rotMatrix.scale(-1, 1); |
| 918 | painter->setTransform(rotMatrix, true); |
| 919 | break; |
| 920 | case QTabBar::RoundedWest: |
| 921 | rotMatrix.rotate(180 + 90); |
| 922 | rotMatrix.scale(-1, 1); |
| 923 | flip = true; |
| 924 | painter->setTransform(rotMatrix, true); |
| 925 | break; |
| 926 | case QTabBar::RoundedEast: |
| 927 | rotMatrix.rotate(90); |
| 928 | rotMatrix.translate(0, - rect.width() + 1); |
| 929 | flip = true; |
| 930 | painter->setTransform(rotMatrix, true); |
| 931 | break; |
| 932 | default: |
| 933 | painter->restore(); |
| 934 | QCommonStyle::drawControl(element, tab, painter, widget); |
| 935 | return; |
| 936 | } |
| 937 | |
| 938 | if (flip) { |
| 939 | QRect tmp = rect; |
| 940 | rect = QRect(tmp.y(), tmp.x(), tmp.height(), tmp.width()); |
| 941 | int temp = x1; |
| 942 | x1 = y1; |
| 943 | y1 = temp; |
| 944 | temp = x2; |
| 945 | x2 = y2; |
| 946 | y2 = temp; |
| 947 | } |
| 948 | |
| 949 | painter->setRenderHint(QPainter::Antialiasing, true); |
| 950 | painter->translate(0.5, 0.5); |
| 951 | |
| 952 | QColor tabFrameColor = tab->features & QStyleOptionTab::HasFrame ? |
| 953 | calcTabFrameColor(option->palette) : |
| 954 | option->palette.window().color(); |
| 955 | |
| 956 | QLinearGradient fillGradient(rect.topLeft(), rect.bottomLeft()); |
| 957 | QLinearGradient outlineGradient(rect.topLeft(), rect.bottomLeft()); |
| 958 | QPen outlinePen = outline.lighter(110); |
| 959 | if (selected) { |
| 960 | fillGradient.setColorAt(0, tabFrameColor.lighter(250)); |
| 961 | // QColor highlight = option->palette.highlight().color(); |
| 962 | // if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange) { |
| 963 | // fillGradient.setColorAt(0, highlight.lighter(130)); |
| 964 | // outlineGradient.setColorAt(0, highlight.darker(130)); |
| 965 | // fillGradient.setColorAt(0.14, highlight); |
| 966 | // outlineGradient.setColorAt(0.14, highlight.darker(130)); |
| 967 | // fillGradient.setColorAt(0.1401, tabFrameColor); |
| 968 | // outlineGradient.setColorAt(0.1401, highlight.darker(130)); |
| 969 | // } |
| 970 | fillGradient.setColorAt(0.85, tabFrameColor.lighter(150)); |
| 971 | fillGradient.setColorAt(1, tabFrameColor); |
| 972 | outlineGradient.setColorAt(1, outline); |
| 973 | outlinePen = QPen(outlineGradient, 1); |
| 974 | } else { |
| 975 | fillGradient.setColorAt(0, tabFrameColor.darker(108)); |
| 976 | fillGradient.setColorAt(0.85, tabFrameColor.darker(108)); |
| 977 | fillGradient.setColorAt(1, tabFrameColor.darker(116)); |
| 978 | } |
| 979 | |
| 980 | QRect drawRect = rect.adjusted(0, selected ? 0 : 2, 0, 3); |
| 981 | painter->setPen(outlinePen); |
| 982 | painter->save(); |
| 983 | painter->setClipRect(rect.adjusted(-1, -1, 1, selected ? -2 : -3)); |
| 984 | painter->setBrush(fillGradient); |
| 985 | painter->drawRoundedRect(drawRect.adjusted(0, 0, -1, -1), 2.0, 2.0); |
| 986 | painter->setBrush(Qt::NoBrush); |
| 987 | painter->setPen(calcInnerContrastLine()); |
| 988 | painter->drawRoundedRect(drawRect.adjusted(1, 1, -2, -1), 2.0, 2.0); |
| 989 | painter->restore(); |
| 990 | |
| 991 | if (selected) { |
| 992 | painter->fillRect(rect.left() + 1, rect.bottom() - 1, rect.width() - 2, rect.bottom() - 1, tabFrameColor); |
| 993 | painter->fillRect(QRect(rect.bottomRight() + QPoint(-2, -1), QSize(1, 1)), calcInnerContrastLine()); |
| 994 | painter->fillRect(QRect(rect.bottomLeft() + QPoint(0, -1), QSize(1, 1)), calcInnerContrastLine()); |
| 995 | painter->fillRect(QRect(rect.bottomRight() + QPoint(-1, -1), QSize(1, 1)), calcInnerContrastLine()); |
| 996 | } |
| 997 | } |
| 998 | painter->restore(); |
| 999 | break; |
| 1000 | default: |
| 1001 | QProxyStyle::drawControl(element, option, painter, widget); |
| 1002 | break; |
| 1003 | } |
| 1004 | } |
| 1005 | |