Cleanup
[carla.git] / source / theme / CarlaStyle.cpp
blob72555a87ab3b16609bec43a033eea2cee179718a
1 /*
2 * Carla Style, based on Qt5 fusion style
3 * Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies)
4 * Copyright (C) 2013-2019 Filipe Coelho <falktx@falktx.com>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
15 * For a full copy of the license see the doc/LGPL.txt file
18 #include "CarlaStylePrivate.hpp"
20 #include <QtCore/qmath.h>
21 #include <QtCore/QStringBuilder>
23 #if defined(__GNUC__) && __GNUC__ >= 8
24 # pragma GCC diagnostic ignored "-Wdeprecated-copy"
25 #endif
27 #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
28 # include <QtGui/QPainter>
29 # include <QtGui/QPainterPath>
30 # include <QtGui/QPixmapCache>
31 # include <QtWidgets/qdrawutil.h>
32 # include <QtWidgets/QApplication>
33 # include <QtWidgets/QComboBox>
34 # include <QtWidgets/QGroupBox>
35 # include <QtWidgets/QMainWindow>
36 # include <QtWidgets/QProgressBar>
37 # include <QtWidgets/QPushButton>
38 # include <QtWidgets/QScrollBar>
39 # include <QtWidgets/QSlider>
40 # include <QtWidgets/QSpinBox>
41 # include <QtWidgets/QSplitter>
42 # include <QtWidgets/QWizard>
43 # define QStyleOptionFrameV3 QStyleOptionFrame
44 # define QStyleOptionProgressBarV2 QStyleOptionProgressBar
45 #else
46 # ifdef __clang__
47 # pragma clang diagnostic push
48 # pragma clang diagnostic ignored "-Wdeprecated-register"
49 # endif
50 # include <QtGui/QPainter>
51 # include <QtGui/QPainterPath>
52 # include <QtGui/QPixmapCache>
53 # include <QtGui/QApplication>
54 # include <QtGui/QComboBox>
55 # include <QtGui/QGroupBox>
56 # include <QtGui/QMainWindow>
57 # include <QtGui/QProgressBar>
58 # include <QtGui/QPushButton>
59 # include <QtGui/QScrollBar>
60 # include <QtGui/QSlider>
61 # include <QtGui/QSpinBox>
62 # include <QtGui/QSplitter>
63 # include <QtGui/QWizard>
64 # ifdef __clang__
65 # pragma clang diagnostic pop
66 # endif
67 #endif
69 #if defined(__GNUC__) && __GNUC__ >= 8
70 # pragma GCC diagnostic pop
71 #endif
73 #include <cstdio>
75 #if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
76 #define PIXMAPCACHE_VAR_PREFIX &
77 #else
78 #define PIXMAPCACHE_VAR_PREFIX
79 #endif
81 #define BEGIN_STYLE_PIXMAPCACHE(a) \
82 QRect rect = option->rect; \
83 QPixmap internalPixmapCache; \
84 QImage imageCache; \
85 QPainter *p = painter; \
86 QString unique = uniqueName((a), option, option->rect.size()); \
87 int txType = painter->deviceTransform().type() | painter->worldTransform().type(); \
88 bool doPixmapCache = txType <= QTransform::TxTranslate; \
89 if (doPixmapCache && QPixmapCache::find(unique, PIXMAPCACHE_VAR_PREFIX internalPixmapCache)) { \
90 painter->drawPixmap(option->rect.topLeft(), internalPixmapCache); \
91 } else { \
92 if (doPixmapCache) { \
93 rect.setRect(0, 0, option->rect.width(), option->rect.height()); \
94 imageCache = QImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); \
95 imageCache.fill(0); \
96 p = new QPainter(&imageCache); \
99 #define END_STYLE_PIXMAPCACHE \
100 if (doPixmapCache) { \
101 p->end(); \
102 delete p; \
103 internalPixmapCache = QPixmap::fromImage(imageCache); \
104 painter->drawPixmap(option->rect.topLeft(), internalPixmapCache); \
105 QPixmapCache::insert(unique, internalPixmapCache); \
109 enum Direction {
110 TopDown,
111 FromLeft,
112 BottomUp,
113 FromRight
116 // from windows style
117 static const int windowsItemFrame = 2; // menu item frame width
118 static const int windowsItemHMargin = 3; // menu item hor text margin
119 static const int windowsItemVMargin = 8; // menu item ver text margin
120 static const int windowsRightBorder = 15; // right border on windows
122 static const int groupBoxBottomMargin = 0; // space below the groupbox
123 static const int groupBoxTopMargin = 3;
125 /* XPM */
126 static const char * const qt_titlebar_context_help[] = {
127 "10 10 3 1",
128 " c None",
129 "# c #000000",
130 "+ c #444444",
131 " +####+ ",
132 " ### ### ",
133 " ## ## ",
134 " +##+ ",
135 " +## ",
136 " ## ",
137 " ## ",
138 " ",
139 " ## ",
140 " ## "};
142 static const qreal Q_PI = qreal(3.14159265358979323846);
144 // internal helper. Converts an integer value to an unique string token
145 template <typename T>
146 struct HexString
148 HexString(const T t)
149 : val(t) {}
151 void write(QChar* &dest) const
153 const ushort hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
154 const char* c = reinterpret_cast<const char*>(&val);
156 for (uint i = 0; i < sizeof(T); ++i)
158 *dest++ = hexChars[*c & 0xf];
159 *dest++ = hexChars[(*c & 0xf0) >> 4];
160 ++c;
164 const T val;
167 // specialization to enable fast concatenating of our string tokens to a string
168 template <typename T>
169 struct QConcatenable<HexString<T> >
171 typedef HexString<T> type;
172 enum { ExactSize = true };
173 static int size(const HexString<T> &) { return sizeof(T) * 2; }
174 static inline void appendTo(const HexString<T> &str, QChar *&out) { str.write(out); }
175 typedef QString ConvertTo;
178 inline int qt_div_255(int x)
180 return (x + (x>>8) + 0x80) >> 8;
183 inline QPixmap styleCachePixmap(const QSize &size)
185 return QPixmap(size);
188 inline int fontMetricsHorizontalAdvance(const QFontMetrics& fm, const QString& s)
190 #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
191 return fm.horizontalAdvance(s);
192 #else
193 return fm.width(s);
194 #endif
197 int calcBigLineSize(int radius)
199 int bigLineSize = radius / 6;
200 if (bigLineSize < 4)
201 bigLineSize = 4;
202 if (bigLineSize > radius / 2)
203 bigLineSize = radius / 2;
204 return bigLineSize;
207 static QPolygonF calcLines(const QStyleOptionSlider* dial)
209 QPolygonF poly;
210 int width = dial->rect.width();
211 int height = dial->rect.height();
212 qreal r = qMin(width, height) / 2;
213 int bigLineSize = calcBigLineSize(int(r));
215 qreal xc = width / 2 + 0.5;
216 qreal yc = height / 2 + 0.5;
217 const int ns = dial->tickInterval;
218 if (!ns) // Invalid values may be set by Qt Designer.
219 return poly;
220 int notches = (dial->maximum + ns - 1 - dial->minimum) / ns;
221 if (notches <= 0)
222 return poly;
223 if (dial->maximum < dial->minimum || dial->maximum - dial->minimum > 1000) {
224 int maximum = dial->minimum + 1000;
225 notches = (maximum + ns - 1 - dial->minimum) / ns;
228 poly.resize(2 + 2 * notches);
229 int smallLineSize = bigLineSize / 2;
230 for (int i = 0; i <= notches; ++i) {
231 qreal angle = dial->dialWrapping ? Q_PI * 3 / 2 - i * 2 * Q_PI / notches
232 : (Q_PI * 8 - i * 10 * Q_PI / notches) / 6;
233 qreal s = qSin(angle);
234 qreal c = qCos(angle);
235 if (i == 0 || (((ns * i) % (dial->pageStep ? dial->pageStep : 1)) == 0)) {
236 poly[2 * i] = QPointF(xc + (r - bigLineSize) * c,
237 yc - (r - bigLineSize) * s);
238 poly[2 * i + 1] = QPointF(xc + r * c, yc - r * s);
239 } else {
240 poly[2 * i] = QPointF(xc + (r - 1 - smallLineSize) * c,
241 yc - (r - 1 - smallLineSize) * s);
242 poly[2 * i + 1] = QPointF(xc + (r - 1) * c, yc -(r - 1) * s);
245 return poly;
248 static QPointF calcRadialPos(const QStyleOptionSlider *dial, qreal offset)
250 const int width = dial->rect.width();
251 const int height = dial->rect.height();
252 const int r = qMin(width, height) / 2;
253 const int currentSliderPosition = dial->upsideDown ? dial->sliderPosition : (dial->maximum - dial->sliderPosition);
254 qreal a = 0;
255 if (dial->maximum == dial->minimum)
256 a = Q_PI / 2;
257 else if (dial->dialWrapping)
258 a = Q_PI * 3 / 2 - (currentSliderPosition - dial->minimum) * 2 * Q_PI
259 / (dial->maximum - dial->minimum);
260 else
261 a = (Q_PI * 8 - (currentSliderPosition - dial->minimum) * 10 * Q_PI
262 / (dial->maximum - dial->minimum)) / 6;
263 qreal xc = width / 2.0;
264 qreal yc = height / 2.0;
265 qreal len = r - calcBigLineSize(r) - 3;
266 qreal back = offset * len;
267 QPointF pos(QPointF(xc + back * qCos(a), yc - back * qSin(a)));
268 return pos;
271 static QString uniqueName(const QString &key, const QStyleOption *option, const QSize &size)
273 const QStyleOptionComplex* complexOption = qstyleoption_cast<const QStyleOptionComplex *>(option);
274 QString tmp = key % HexString<uint>(option->state)
275 % HexString<uint>(option->direction)
276 % HexString<uint>(complexOption ? uint(complexOption->activeSubControls) : 0u)
277 % HexString<quint64>(option->palette.cacheKey())
278 % HexString<uint>(size.width())
279 % HexString<uint>(size.height());
281 #ifndef QT_NO_SPINBOX
282 if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
283 tmp = tmp % HexString<uint>(spinBox->buttonSymbols)
284 % HexString<uint>(spinBox->stepEnabled)
285 % QLatin1Char(spinBox->frame ? '1' : '0'); ;
287 #endif // QT_NO_SPINBOX
288 return tmp;
291 // This will draw a nice and shiny QDial for us. We don't want
292 // all the shinyness in QWindowsStyle, hence we place it here
294 static void drawDial(const QStyleOptionSlider* option, QPainter* painter)
296 QPalette pal = option->palette;
297 QColor buttonColor = pal.button().color();
298 const int width = option->rect.width();
299 const int height = option->rect.height();
300 const bool enabled = option->state & QStyle::State_Enabled;
301 qreal r = qMin(width, height) / 2;
302 r -= r/50;
303 const qreal penSize = r/20.0;
305 painter->save();
306 painter->setRenderHint(QPainter::Antialiasing);
308 // Draw notches
309 if (option->subControls & QStyle::SC_DialTickmarks) {
310 painter->setPen(option->palette.dark().color().darker(120));
311 painter->drawLines(calcLines(option));
314 // Cache dial background
315 BEGIN_STYLE_PIXMAPCACHE(QString::fromLatin1("qdial"));
316 p->setRenderHint(QPainter::Antialiasing);
318 const qreal d_ = r / 6;
319 const qreal dx = option->rect.x() + d_ + (width - 2 * r) / 2 + 1;
320 const qreal dy = option->rect.y() + d_ + (height - 2 * r) / 2 + 1;
322 QRectF br = QRectF(dx + 0.5, dy + 0.5,
323 int(r * 2 - 2 * d_ - 2),
324 int(r * 2 - 2 * d_ - 2));
325 buttonColor.setHsv(buttonColor .hue(),
326 qMin(140, buttonColor .saturation()),
327 qMax(180, buttonColor.value()));
328 QColor shadowColor(0, 0, 0, 20);
330 if (enabled) {
331 // Drop shadow
332 qreal shadowSize = qMax(1.0, penSize/2.0);
333 QRectF shadowRect= br.adjusted(-2*shadowSize, -2*shadowSize,
334 2*shadowSize, 2*shadowSize);
335 QRadialGradient shadowGradient(shadowRect.center().x(),
336 shadowRect.center().y(), shadowRect.width()/2.0,
337 shadowRect.center().x(), shadowRect.center().y());
338 shadowGradient.setColorAt(qreal(0.91), QColor(0, 0, 0, 40));
339 shadowGradient.setColorAt(qreal(1.0), Qt::transparent);
340 p->setBrush(shadowGradient);
341 p->setPen(Qt::NoPen);
342 p->translate(shadowSize, shadowSize);
343 p->drawEllipse(shadowRect);
344 p->translate(-shadowSize, -shadowSize);
346 // Main gradient
347 QRadialGradient gradient(br.center().x() - br.width()/3, dy,
348 br.width()*1.3, br.center().x(),
349 br.center().y() - br.height()/2);
350 gradient.setColorAt(0, buttonColor.lighter(110));
351 gradient.setColorAt(qreal(0.5), buttonColor);
352 gradient.setColorAt(qreal(0.501), buttonColor.darker(102));
353 gradient.setColorAt(1, buttonColor.darker(115));
354 p->setBrush(gradient);
355 } else {
356 p->setBrush(Qt::NoBrush);
359 p->setPen(QPen(buttonColor.darker(280)));
360 p->drawEllipse(br);
361 p->setBrush(Qt::NoBrush);
362 p->setPen(buttonColor.lighter(110));
363 p->drawEllipse(br.adjusted(1, 1, -1, -1));
365 if (option->state & QStyle::State_HasFocus) {
366 QColor highlight = pal.highlight().color();
367 highlight.setHsv(highlight.hue(),
368 qMin(160, highlight.saturation()),
369 qMax(230, highlight.value()));
370 highlight.setAlpha(127);
371 p->setPen(QPen(highlight, 2.0));
372 p->setBrush(Qt::NoBrush);
373 p->drawEllipse(br.adjusted(-1, -1, 1, 1));
376 END_STYLE_PIXMAPCACHE
378 QPointF dp = calcRadialPos(option, qreal(0.70));
379 buttonColor = buttonColor.lighter(104);
380 buttonColor.setAlphaF(qreal(0.8));
381 const qreal ds = r/qreal(7.0);
382 QRectF dialRect(dp.x() - ds, dp.y() - ds, 2*ds, 2*ds);
383 QRadialGradient dialGradient(dialRect.center().x() + dialRect.width()/2,
384 dialRect.center().y() + dialRect.width(),
385 dialRect.width()*2,
386 dialRect.center().x(), dialRect.center().y());
387 dialGradient.setColorAt(1, buttonColor.darker(140));
388 dialGradient.setColorAt(qreal(0.4), buttonColor.darker(120));
389 dialGradient.setColorAt(0, buttonColor.darker(110));
390 if (penSize > 3.0) {
391 painter->setPen(QPen(QColor(0, 0, 0, 25), penSize));
392 painter->drawLine(calcRadialPos(option, qreal(0.90)), calcRadialPos(option, qreal(0.96)));
395 painter->setBrush(dialGradient);
396 painter->setPen(QColor(255, 255, 255, 150));
397 painter->drawEllipse(dialRect.adjusted(-1, -1, 1, 1));
398 painter->setPen(QColor(0, 0, 0, 80));
399 painter->drawEllipse(dialRect);
400 painter->restore();
403 static QColor mergedColors(const QColor &colorA, const QColor &colorB, int factor = 50)
405 const int maxFactor = 100;
406 QColor tmp = colorA;
407 tmp.setRed((tmp.red() * factor) / maxFactor + (colorB.red() * (maxFactor - factor)) / maxFactor);
408 tmp.setGreen((tmp.green() * factor) / maxFactor + (colorB.green() * (maxFactor - factor)) / maxFactor);
409 tmp.setBlue((tmp.blue() * factor) / maxFactor + (colorB.blue() * (maxFactor - factor)) / maxFactor);
410 return tmp;
413 static QPixmap colorizedImage(const QString &fileName, const QColor &color, int rotation = 0)
415 QString pixmapName = QLatin1String("$qt_ia-") % fileName % HexString<uint>(color.rgba()) % QString::number(rotation);
416 QPixmap pixmap;
417 if (!QPixmapCache::find(pixmapName, PIXMAPCACHE_VAR_PREFIX pixmap)) {
418 QImage image(fileName);
420 if (image.format() != QImage::Format_ARGB32_Premultiplied)
421 image = image.convertToFormat( QImage::Format_ARGB32_Premultiplied);
423 int width = image.width();
424 int height = image.height();
425 int source = color.rgba();
427 unsigned char sourceRed = qRed(source);
428 unsigned char sourceGreen = qGreen(source);
429 unsigned char sourceBlue = qBlue(source);
431 for (int y = 0; y < height; ++y)
433 QRgb *data = (QRgb*) image.scanLine(y);
434 for (int x = 0 ; x < width ; ++x) {
435 QRgb col = data[x];
436 unsigned int colorDiff = (qBlue(col) - qRed(col));
437 unsigned char gray = qGreen(col);
438 unsigned char red = gray + qt_div_255(sourceRed * colorDiff);
439 unsigned char green = gray + qt_div_255(sourceGreen * colorDiff);
440 unsigned char blue = gray + qt_div_255(sourceBlue * colorDiff);
441 unsigned char alpha = qt_div_255(qAlpha(col) * qAlpha(source));
442 data[x] = qRgba(red, green, blue, alpha);
445 if (rotation != 0) {
446 QTransform transform;
447 transform.translate(-image.width()/2, -image.height()/2);
448 transform.rotate(rotation);
449 transform.translate(image.width()/2, image.height()/2);
450 image = image.transformed(transform);
453 pixmap = QPixmap::fromImage(image);
454 QPixmapCache::insert(pixmapName, pixmap);
456 return pixmap;
459 // The default button and handle gradient
460 static QLinearGradient qt_fusion_gradient(const QRect &rect, const QBrush &baseColor, Direction direction = TopDown)
462 int x = rect.center().x();
463 int y = rect.center().y();
464 QLinearGradient gradient;
465 switch (direction) {
466 case FromLeft:
467 gradient = QLinearGradient(rect.left(), y, rect.right(), y);
468 break;
469 case FromRight:
470 gradient = QLinearGradient(rect.right(), y, rect.left(), y);
471 break;
472 case BottomUp:
473 gradient = QLinearGradient(x, rect.bottom(), x, rect.top());
474 break;
475 case TopDown:
476 default:
477 gradient = QLinearGradient(x, rect.top(), x, rect.bottom());
478 break;
480 if (baseColor.gradient())
481 gradient.setStops(baseColor.gradient()->stops());
482 else {
483 QColor gradientStartColor = baseColor.color().lighter(124);
484 QColor gradientStopColor = baseColor.color().lighter(102);
485 gradient.setColorAt(0, gradientStartColor);
486 gradient.setColorAt(1, gradientStopColor);
487 // Uncomment for adding shiny shading
488 // QColor midColor1 = mergedColors(gradientStartColor, gradientStopColor, 55);
489 // QColor midColor2 = mergedColors(gradientStartColor, gradientStopColor, 45);
490 // gradient.setColorAt(0.5, midColor1);
491 // gradient.setColorAt(0.501, midColor2);
493 return gradient;
496 static void qt_fusion_draw_mdibutton(QPainter *painter, const QStyleOptionTitleBar *option, const QRect &tmp, bool hover, bool sunken)
498 QColor dark;
499 dark.setHsv(option->palette.button().color().hue(),
500 qMin(255, (int)(option->palette.button().color().saturation())),
501 qMin(255, (int)(option->palette.button().color().value()*0.7)));
503 QColor highlight = option->palette.highlight().color();
505 bool active = (option->titleBarState & QStyle::State_Active);
506 QColor titleBarHighlight(255, 255, 255, 60);
508 if (sunken)
509 painter->fillRect(tmp.adjusted(1, 1, -1, -1), option->palette.highlight().color().darker(120));
510 else if (hover)
511 painter->fillRect(tmp.adjusted(1, 1, -1, -1), QColor(255, 255, 255, 20));
513 QColor mdiButtonGradientStartColor;
514 QColor mdiButtonGradientStopColor;
516 mdiButtonGradientStartColor = QColor(0, 0, 0, 40);
517 mdiButtonGradientStopColor = QColor(255, 255, 255, 60);
519 if (sunken)
520 titleBarHighlight = highlight.darker(130);
522 QLinearGradient gradient(tmp.center().x(), tmp.top(), tmp.center().x(), tmp.bottom());
523 gradient.setColorAt(0, mdiButtonGradientStartColor);
524 gradient.setColorAt(1, mdiButtonGradientStopColor);
525 QColor mdiButtonBorderColor(active ? option->palette.highlight().color().darker(180): dark.darker(110));
527 painter->setPen(QPen(mdiButtonBorderColor, 1));
528 const QLine lines[4] = {
529 QLine(tmp.left() + 2, tmp.top(), tmp.right() - 2, tmp.top()),
530 QLine(tmp.left() + 2, tmp.bottom(), tmp.right() - 2, tmp.bottom()),
531 QLine(tmp.left(), tmp.top() + 2, tmp.left(), tmp.bottom() - 2),
532 QLine(tmp.right(), tmp.top() + 2, tmp.right(), tmp.bottom() - 2)
534 painter->drawLines(lines, 4);
535 const QPoint points[4] = {
536 QPoint(tmp.left() + 1, tmp.top() + 1),
537 QPoint(tmp.right() - 1, tmp.top() + 1),
538 QPoint(tmp.left() + 1, tmp.bottom() - 1),
539 QPoint(tmp.right() - 1, tmp.bottom() - 1)
541 painter->drawPoints(points, 4);
543 painter->setPen(titleBarHighlight);
544 painter->drawLine(tmp.left() + 2, tmp.top() + 1, tmp.right() - 2, tmp.top() + 1);
545 painter->drawLine(tmp.left() + 1, tmp.top() + 2, tmp.left() + 1, tmp.bottom() - 2);
547 painter->setPen(QPen(gradient, 1));
548 painter->drawLine(tmp.right() + 1, tmp.top() + 2, tmp.right() + 1, tmp.bottom() - 2);
549 painter->drawPoint(tmp.right() , tmp.top() + 1);
551 painter->drawLine(tmp.left() + 2, tmp.bottom() + 1, tmp.right() - 2, tmp.bottom() + 1);
552 painter->drawPoint(tmp.left() + 1, tmp.bottom());
553 painter->drawPoint(tmp.right() - 1, tmp.bottom());
554 painter->drawPoint(tmp.right() , tmp.bottom() - 1);
557 CarlaStyle::CarlaStyle()
558 : QCommonStyle(),
559 d(new CarlaStylePrivate(this))
561 setObjectName(QLatin1String("CarlaStyle"));
563 #if 0
564 fPalSystem = app->palette();
566 fPalBlack.setColor(QPalette::Disabled, QPalette::Window, QColor(14, 14, 14));
567 fPalBlack.setColor(QPalette::Active, QPalette::Window, QColor(17, 17, 17));
568 fPalBlack.setColor(QPalette::Inactive, QPalette::Window, QColor(17, 17, 17));
569 fPalBlack.setColor(QPalette::Disabled, QPalette::WindowText, QColor(83, 83, 83));
570 fPalBlack.setColor(QPalette::Active, QPalette::WindowText, QColor(240, 240, 240));
571 fPalBlack.setColor(QPalette::Inactive, QPalette::WindowText, QColor(240, 240, 240));
572 fPalBlack.setColor(QPalette::Disabled, QPalette::Base, QColor(6, 6, 6));
573 fPalBlack.setColor(QPalette::Active, QPalette::Base, QColor(7, 7, 7));
574 fPalBlack.setColor(QPalette::Inactive, QPalette::Base, QColor(7, 7, 7));
575 fPalBlack.setColor(QPalette::Disabled, QPalette::AlternateBase, QColor(12, 12, 12));
576 fPalBlack.setColor(QPalette::Active, QPalette::AlternateBase, QColor(14, 14, 14));
577 fPalBlack.setColor(QPalette::Inactive, QPalette::AlternateBase, QColor(14, 14, 14));
578 fPalBlack.setColor(QPalette::Disabled, QPalette::ToolTipBase, QColor(4, 4, 4));
579 fPalBlack.setColor(QPalette::Active, QPalette::ToolTipBase, QColor(4, 4, 4));
580 fPalBlack.setColor(QPalette::Inactive, QPalette::ToolTipBase, QColor(4, 4, 4));
581 fPalBlack.setColor(QPalette::Disabled, QPalette::ToolTipText, QColor(230, 230, 230));
582 fPalBlack.setColor(QPalette::Active, QPalette::ToolTipText, QColor(230, 230, 230));
583 fPalBlack.setColor(QPalette::Inactive, QPalette::ToolTipText, QColor(230, 230, 230));
584 fPalBlack.setColor(QPalette::Disabled, QPalette::Text, QColor(74, 74, 74));
585 fPalBlack.setColor(QPalette::Active, QPalette::Text, QColor(230, 230, 230));
586 fPalBlack.setColor(QPalette::Inactive, QPalette::Text, QColor(230, 230, 230));
587 fPalBlack.setColor(QPalette::Disabled, QPalette::Button, QColor(24, 24, 24));
588 fPalBlack.setColor(QPalette::Active, QPalette::Button, QColor(28, 28, 28));
589 fPalBlack.setColor(QPalette::Inactive, QPalette::Button, QColor(28, 28, 28));
590 fPalBlack.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(90, 90, 90));
591 fPalBlack.setColor(QPalette::Active, QPalette::ButtonText, QColor(240, 240, 240));
592 fPalBlack.setColor(QPalette::Inactive, QPalette::ButtonText, QColor(240, 240, 240));
593 fPalBlack.setColor(QPalette::Disabled, QPalette::BrightText, QColor(255, 255, 255));
594 fPalBlack.setColor(QPalette::Active, QPalette::BrightText, QColor(255, 255, 255));
595 fPalBlack.setColor(QPalette::Inactive, QPalette::BrightText, QColor(255, 255, 255));
596 fPalBlack.setColor(QPalette::Disabled, QPalette::Light, QColor(191, 191, 191));
597 fPalBlack.setColor(QPalette::Active, QPalette::Light, QColor(191, 191, 191));
598 fPalBlack.setColor(QPalette::Inactive, QPalette::Light, QColor(191, 191, 191));
599 fPalBlack.setColor(QPalette::Disabled, QPalette::Midlight, QColor(155, 155, 155));
600 fPalBlack.setColor(QPalette::Active, QPalette::Midlight, QColor(155, 155, 155));
601 fPalBlack.setColor(QPalette::Inactive, QPalette::Midlight, QColor(155, 155, 155));
602 fPalBlack.setColor(QPalette::Disabled, QPalette::Dark, QColor(129, 129, 129));
603 fPalBlack.setColor(QPalette::Active, QPalette::Dark, QColor(129, 129, 129));
604 fPalBlack.setColor(QPalette::Inactive, QPalette::Dark, QColor(129, 129, 129));
605 fPalBlack.setColor(QPalette::Disabled, QPalette::Mid, QColor(94, 94, 94));
606 fPalBlack.setColor(QPalette::Active, QPalette::Mid, QColor(94, 94, 94));
607 fPalBlack.setColor(QPalette::Inactive, QPalette::Mid, QColor(94, 94, 94));
608 fPalBlack.setColor(QPalette::Disabled, QPalette::Shadow, QColor(155, 155, 155));
609 fPalBlack.setColor(QPalette::Active, QPalette::Shadow, QColor(155, 155, 155));
610 fPalBlack.setColor(QPalette::Inactive, QPalette::Shadow, QColor(155, 155, 155));
611 fPalBlack.setColor(QPalette::Disabled, QPalette::Highlight, QColor(14, 14, 14));
612 fPalBlack.setColor(QPalette::Active, QPalette::Highlight, QColor(60, 60, 60));
613 fPalBlack.setColor(QPalette::Inactive, QPalette::Highlight, QColor(34, 34, 34));
614 fPalBlack.setColor(QPalette::Disabled, QPalette::HighlightedText, QColor(83, 83, 83));
615 fPalBlack.setColor(QPalette::Active, QPalette::HighlightedText, QColor(255, 255, 255));
616 fPalBlack.setColor(QPalette::Inactive, QPalette::HighlightedText, QColor(240, 240, 240));
617 fPalBlack.setColor(QPalette::Disabled, QPalette::Link, QColor(34, 34, 74));
618 fPalBlack.setColor(QPalette::Active, QPalette::Link, QColor(100, 100, 230));
619 fPalBlack.setColor(QPalette::Inactive, QPalette::Link, QColor(100, 100, 230));
620 fPalBlack.setColor(QPalette::Disabled, QPalette::LinkVisited, QColor(74, 34, 74));
621 fPalBlack.setColor(QPalette::Active, QPalette::LinkVisited, QColor(230, 100, 230));
622 fPalBlack.setColor(QPalette::Inactive, QPalette::LinkVisited, QColor(230, 100, 230));
624 fPalBlue.setColor(QPalette::Disabled, QPalette::Window, QColor(32, 35, 39));
625 fPalBlue.setColor(QPalette::Active, QPalette::Window, QColor(37, 40, 45));
626 fPalBlue.setColor(QPalette::Inactive, QPalette::Window, QColor(37, 40, 45));
627 fPalBlue.setColor(QPalette::Disabled, QPalette::WindowText, QColor(89, 95, 104));
628 fPalBlue.setColor(QPalette::Active, QPalette::WindowText, QColor(223, 237, 255));
629 fPalBlue.setColor(QPalette::Inactive, QPalette::WindowText, QColor(223, 237, 255));
630 fPalBlue.setColor(QPalette::Disabled, QPalette::Base, QColor(48, 53, 60));
631 fPalBlue.setColor(QPalette::Active, QPalette::Base, QColor(55, 61, 69));
632 fPalBlue.setColor(QPalette::Inactive, QPalette::Base, QColor(55, 61, 69));
633 fPalBlue.setColor(QPalette::Disabled, QPalette::AlternateBase, QColor(60, 64, 67));
634 fPalBlue.setColor(QPalette::Active, QPalette::AlternateBase, QColor(69, 73, 77));
635 fPalBlue.setColor(QPalette::Inactive, QPalette::AlternateBase, QColor(69, 73, 77));
636 fPalBlue.setColor(QPalette::Disabled, QPalette::ToolTipBase, QColor(182, 193, 208));
637 fPalBlue.setColor(QPalette::Active, QPalette::ToolTipBase, QColor(182, 193, 208));
638 fPalBlue.setColor(QPalette::Inactive, QPalette::ToolTipBase, QColor(182, 193, 208));
639 fPalBlue.setColor(QPalette::Disabled, QPalette::ToolTipText, QColor(42, 44, 48));
640 fPalBlue.setColor(QPalette::Active, QPalette::ToolTipText, QColor(42, 44, 48));
641 fPalBlue.setColor(QPalette::Inactive, QPalette::ToolTipText, QColor(42, 44, 48));
642 fPalBlue.setColor(QPalette::Disabled, QPalette::Text, QColor(96, 103, 113));
643 fPalBlue.setColor(QPalette::Active, QPalette::Text, QColor(210, 222, 240));
644 fPalBlue.setColor(QPalette::Inactive, QPalette::Text, QColor(210, 222, 240));
645 fPalBlue.setColor(QPalette::Disabled, QPalette::Button, QColor(51, 55, 62));
646 fPalBlue.setColor(QPalette::Active, QPalette::Button, QColor(59, 63, 71));
647 fPalBlue.setColor(QPalette::Inactive, QPalette::Button, QColor(59, 63, 71));
648 fPalBlue.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(98, 104, 114));
649 fPalBlue.setColor(QPalette::Active, QPalette::ButtonText, QColor(210, 222, 240));
650 fPalBlue.setColor(QPalette::Inactive, QPalette::ButtonText, QColor(210, 222, 240));
651 fPalBlue.setColor(QPalette::Disabled, QPalette::BrightText, QColor(255, 255, 255));
652 fPalBlue.setColor(QPalette::Active, QPalette::BrightText, QColor(255, 255, 255));
653 fPalBlue.setColor(QPalette::Inactive, QPalette::BrightText, QColor(255, 255, 255));
654 fPalBlue.setColor(QPalette::Disabled, QPalette::Light, QColor(59, 64, 72));
655 fPalBlue.setColor(QPalette::Active, QPalette::Light, QColor(63, 68, 76));
656 fPalBlue.setColor(QPalette::Inactive, QPalette::Light, QColor(63, 68, 76));
657 fPalBlue.setColor(QPalette::Disabled, QPalette::Midlight, QColor(48, 52, 59));
658 fPalBlue.setColor(QPalette::Active, QPalette::Midlight, QColor(51, 56, 63));
659 fPalBlue.setColor(QPalette::Inactive, QPalette::Midlight, QColor(51, 56, 63));
660 fPalBlue.setColor(QPalette::Disabled, QPalette::Dark, QColor(18, 19, 22));
661 fPalBlue.setColor(QPalette::Active, QPalette::Dark, QColor(20, 22, 25));
662 fPalBlue.setColor(QPalette::Inactive, QPalette::Dark, QColor(20, 22, 25));
663 fPalBlue.setColor(QPalette::Disabled, QPalette::Mid, QColor(28, 30, 34));
664 fPalBlue.setColor(QPalette::Active, QPalette::Mid, QColor(32, 35, 39));
665 fPalBlue.setColor(QPalette::Inactive, QPalette::Mid, QColor(32, 35, 39));
666 fPalBlue.setColor(QPalette::Disabled, QPalette::Shadow, QColor(13, 14, 16));
667 fPalBlue.setColor(QPalette::Active, QPalette::Shadow, QColor(15, 16, 18));
668 fPalBlue.setColor(QPalette::Inactive, QPalette::Shadow, QColor(15, 16, 18));
669 fPalBlue.setColor(QPalette::Disabled, QPalette::Highlight, QColor(32, 35, 39));
670 fPalBlue.setColor(QPalette::Active, QPalette::Highlight, QColor(14, 14, 17));
671 fPalBlue.setColor(QPalette::Inactive, QPalette::Highlight, QColor(27, 28, 33));
672 fPalBlue.setColor(QPalette::Disabled, QPalette::HighlightedText, QColor(89, 95, 104));
673 fPalBlue.setColor(QPalette::Active, QPalette::HighlightedText, QColor(217, 234, 253));
674 fPalBlue.setColor(QPalette::Inactive, QPalette::HighlightedText, QColor(223, 237, 255));
675 fPalBlue.setColor(QPalette::Disabled, QPalette::Link, QColor(79, 100, 118));
676 fPalBlue.setColor(QPalette::Active, QPalette::Link, QColor(156, 212, 255));
677 fPalBlue.setColor(QPalette::Inactive, QPalette::Link, QColor(156, 212, 255));
678 fPalBlue.setColor(QPalette::Disabled, QPalette::LinkVisited, QColor(51, 74, 118));
679 fPalBlue.setColor(QPalette::Active, QPalette::LinkVisited, QColor(64, 128, 255));
680 fPalBlue.setColor(QPalette::Inactive, QPalette::LinkVisited, QColor(64, 128, 255));
681 #endif
684 CarlaStyle::~CarlaStyle()
686 delete d;
689 void printPalette(const QPalette& pal)
691 #define PAL "fPalBlue"
693 #define PAL_PRINT(ROLE) \
695 QColor color1(pal.color(QPalette::Disabled, ROLE)); \
696 QColor color2(pal.color(QPalette::Active, ROLE)); \
697 QColor color3(pal.color(QPalette::Inactive, ROLE)); \
698 printf(PAL ".setColor(QPalette::Disabled, " #ROLE ", QColor(%i, %i, %i));\n", color1.red(), color1.green(), color1.blue()); \
699 printf(PAL ".setColor(QPalette::Active, " #ROLE ", QColor(%i, %i, %i));\n", color2.red(), color2.green(), color2.blue()); \
700 printf(PAL ".setColor(QPalette::Inactive, " #ROLE ", QColor(%i, %i, %i));\n", color3.red(), color3.green(), color3.blue()); \
703 PAL_PRINT(QPalette::Window)
704 PAL_PRINT(QPalette::WindowText)
705 PAL_PRINT(QPalette::Base)
706 PAL_PRINT(QPalette::AlternateBase)
707 PAL_PRINT(QPalette::ToolTipBase)
708 PAL_PRINT(QPalette::ToolTipText)
709 PAL_PRINT(QPalette::Text)
710 PAL_PRINT(QPalette::Button)
711 PAL_PRINT(QPalette::ButtonText)
712 PAL_PRINT(QPalette::BrightText)
713 PAL_PRINT(QPalette::Light)
714 PAL_PRINT(QPalette::Midlight)
715 PAL_PRINT(QPalette::Dark)
716 PAL_PRINT(QPalette::Mid)
717 PAL_PRINT(QPalette::Shadow)
718 PAL_PRINT(QPalette::Highlight)
719 PAL_PRINT(QPalette::HighlightedText)
720 PAL_PRINT(QPalette::Link)
721 PAL_PRINT(QPalette::LinkVisited)
723 #undef PAL
727 \fn void CarlaStyle::drawItemText(QPainter *painter, const QRect &rectangle, int alignment, const QPalette &palette,
728 bool enabled, const QString& text, QPalette::ColorRole textRole) const
730 Draws the given \a text in the specified \a rectangle using the
731 provided \a painter and \a palette.
733 Text is drawn using the painter's pen. If an explicit \a textRole
734 is specified, then the text is drawn using the \a palette's color
735 for the specified role. The \a enabled value indicates whether or
736 not the item is enabled; when reimplementing, this value should
737 influence how the item is drawn.
739 The text is aligned and wrapped according to the specified \a
740 alignment.
742 \sa Qt::Alignment
744 void CarlaStyle::drawItemText(QPainter *painter, const QRect &rect, int alignment, const QPalette &pal,
745 bool enabled, const QString& text, QPalette::ColorRole textRole) const
747 if (text.isEmpty())
748 return;
750 QPen savedPen = painter->pen();
751 if (textRole != QPalette::NoRole) {
752 painter->setPen(QPen(pal.brush(textRole), savedPen.widthF()));
754 if (!enabled) {
755 QPen pen = painter->pen();
756 painter->setPen(pen);
758 painter->drawText(rect, alignment, text);
759 painter->setPen(savedPen);
763 \reimp
765 void CarlaStyle::drawPrimitive(PrimitiveElement elem,
766 const QStyleOption *option,
767 QPainter *painter, const QWidget *widget) const
769 Q_ASSERT(option);
771 QRect rect = option->rect;
772 int state = option->state;
774 QColor outline = d->outline(option->palette);
775 QColor highlightedOutline = d->highlightedOutline(option->palette);
777 QColor tabFrameColor = d->tabFrameColor(option->palette);
779 switch (elem) {
781 // No frame drawn
782 case PE_FrameGroupBox:
784 QPixmap pixmap(QLatin1String(":/bitmaps/style/groupbox.png"));
785 int topMargin = qMax(pixelMetric(PM_ExclusiveIndicatorHeight), option->fontMetrics.height()) + groupBoxTopMargin;
786 QRect frame = option->rect.adjusted(0, topMargin, 0, 0);
787 qDrawBorderPixmap(painter, frame, QMargins(6, 6, 6, 6), pixmap);
788 break;
790 case PE_IndicatorBranch: {
791 if (!(option->state & State_Children))
792 break;
793 if (option->state & State_Open)
794 drawPrimitive(PE_IndicatorArrowDown, option, painter, widget);
795 else
796 drawPrimitive(PE_IndicatorArrowRight, option, painter, widget);
797 break;
799 case PE_FrameTabBarBase:
800 if (const QStyleOptionTabBarBase *tbb
801 = qstyleoption_cast<const QStyleOptionTabBarBase *>(option)) {
802 painter->save();
803 painter->setPen(QPen(outline.lighter(110), 0));
804 switch (tbb->shape) {
805 case QTabBar::RoundedNorth: {
806 QRegion region(tbb->rect);
807 region -= tbb->selectedTabRect;
808 painter->drawLine(tbb->rect.topLeft(), tbb->rect.topRight());
809 painter->setClipRegion(region);
810 painter->setPen(option->palette.light().color());
811 painter->drawLine(tbb->rect.topLeft() + QPoint(0, 1), tbb->rect.topRight() + QPoint(0, 1));
813 break;
814 case QTabBar::RoundedWest:
815 painter->drawLine(tbb->rect.left(), tbb->rect.top(), tbb->rect.left(), tbb->rect.bottom());
816 break;
817 case QTabBar::RoundedSouth:
818 painter->drawLine(tbb->rect.left(), tbb->rect.bottom(),
819 tbb->rect.right(), tbb->rect.bottom());
820 break;
821 case QTabBar::RoundedEast:
822 painter->drawLine(tbb->rect.topRight(), tbb->rect.bottomRight());
823 break;
824 case QTabBar::TriangularNorth:
825 case QTabBar::TriangularEast:
826 case QTabBar::TriangularWest:
827 case QTabBar::TriangularSouth:
828 painter->restore();
829 QCommonStyle::drawPrimitive(elem, option, painter, widget);
830 return;
832 painter->restore();
834 return;
835 case PE_PanelScrollAreaCorner: {
836 painter->save();
837 QColor alphaOutline = outline;
838 alphaOutline.setAlpha(180);
839 painter->setPen(alphaOutline);
840 painter->setBrush(option->palette.brush(QPalette::Window));
841 painter->drawRect(option->rect);
842 painter->restore();
843 } break;
844 case PE_IndicatorArrowUp:
845 case PE_IndicatorArrowDown:
846 case PE_IndicatorArrowRight:
847 case PE_IndicatorArrowLeft:
849 if (option->rect.width() <= 1 || option->rect.height() <= 1)
850 break;
851 QColor arrowColor = qt_palette_fg_color(option->palette);
852 QPixmap arrow;
853 int rotation = 0;
854 switch (elem) {
855 case PE_IndicatorArrowDown:
856 rotation = 180;
857 break;
858 case PE_IndicatorArrowRight:
859 rotation = 90;
860 break;
861 case PE_IndicatorArrowLeft:
862 rotation = -90;
863 break;
864 default:
865 break;
867 arrow = colorizedImage(QLatin1String(":/bitmaps/style/arrow.png"), arrowColor, rotation);
868 QRect rect = option->rect;
869 QRect arrowRect;
870 int imageMax = qMin(arrow.height(), arrow.width());
871 int rectMax = qMin(rect.height(), rect.width());
872 int size = qMin(imageMax, rectMax);
874 arrowRect.setWidth(size);
875 arrowRect.setHeight(size);
876 if (arrow.width() > arrow.height())
877 arrowRect.setHeight(arrow.height() * size / arrow.width());
878 else
879 arrowRect.setWidth(arrow.width() * size / arrow.height());
881 arrowRect.moveTopLeft(rect.center() - arrowRect.center());
882 painter->save();
883 painter->setRenderHint(QPainter::SmoothPixmapTransform);
884 painter->drawPixmap(arrowRect, arrow);
885 painter->restore();
887 break;
888 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
889 case PE_IndicatorItemViewItemCheck:
890 #else
891 case PE_IndicatorViewItemCheck:
892 #endif
894 QStyleOptionButton button;
895 button.QStyleOption::operator=(*option);
896 button.state &= ~State_MouseOver;
897 proxy()->drawPrimitive(PE_IndicatorCheckBox, &button, painter, widget);
899 return;
900 case PE_IndicatorHeaderArrow:
901 if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
902 QRect r = header->rect;
903 QPixmap arrow;
904 QColor arrowColor = qt_palette_fg_color(header->palette);
905 QPoint offset = QPoint(0, -1);
907 if (header->sortIndicator & QStyleOptionHeader::SortUp) {
908 arrow = colorizedImage(QLatin1String(":/bitmaps/style/arrow.png"), arrowColor);
909 } else if (header->sortIndicator & QStyleOptionHeader::SortDown) {
910 arrow = colorizedImage(QLatin1String(":/bitmaps/style/arrow.png"), arrowColor, 180);
911 } if (!arrow.isNull()) {
912 r.setSize(QSize(arrow.width()/2, arrow.height()/2));
913 r.moveCenter(header->rect.center());
914 painter->drawPixmap(r.translated(offset), arrow);
917 break;
918 case PE_IndicatorButtonDropDown:
919 proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget);
920 break;
922 case PE_IndicatorToolBarSeparator:
924 QRect rect = option->rect;
925 const int margin = 6;
926 QColor separator_color = option->palette.text().color();
927 separator_color.setAlpha(50);
928 painter->setPen(QPen(separator_color));
929 if (option->state & State_Horizontal) {
930 const int offset = rect.width()/2;
932 painter->drawLine(rect.bottomLeft().x() + offset,
933 rect.bottomLeft().y() - margin,
934 rect.topLeft().x() + offset,
935 rect.topLeft().y() + margin);
936 painter->setPen(QPen(qt_palette_bg_color(option->palette).lighter(110)));
937 painter->drawLine(rect.bottomLeft().x() + offset + 1,
938 rect.bottomLeft().y() - margin,
939 rect.topLeft().x() + offset + 1,
940 rect.topLeft().y() + margin);
941 } else { //Draw vertical separator
942 const int offset = rect.height()/2;
943 painter->drawLine(rect.topLeft().x() + margin ,
944 rect.topLeft().y() + offset,
945 rect.topRight().x() - margin,
946 rect.topRight().y() + offset);
947 painter->setPen(QPen(qt_palette_bg_color(option->palette).lighter(110)));
948 painter->drawLine(rect.topLeft().x() + margin ,
949 rect.topLeft().y() + offset + 1,
950 rect.topRight().x() - margin,
951 rect.topRight().y() + offset + 1);
954 break;
955 case PE_Frame:
956 if (widget && widget->inherits("QComboBoxPrivateContainer")){
957 QStyleOption copy = *option;
958 copy.state |= State_Raised;
959 proxy()->drawPrimitive(PE_PanelMenu, &copy, painter, widget);
960 break;
962 painter->save();
963 painter->setPen(outline.lighter(108));
964 painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
965 painter->restore();
966 break;
967 case PE_FrameMenu:
968 painter->save();
970 painter->setPen(QPen(outline, 1));
971 painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
972 QColor frameLight = qt_palette_bg_color(option->palette).lighter(160);
973 QColor frameShadow = qt_palette_bg_color(option->palette).darker(110);
975 //paint beveleffect
976 QRect frame = option->rect.adjusted(1, 1, -1, -1);
977 painter->setPen(frameLight);
978 painter->drawLine(frame.topLeft(), frame.bottomLeft());
979 painter->drawLine(frame.topLeft(), frame.topRight());
981 painter->setPen(frameShadow);
982 painter->drawLine(frame.topRight(), frame.bottomRight());
983 painter->drawLine(frame.bottomLeft(), frame.bottomRight());
985 painter->restore();
986 break;
987 case PE_FrameDockWidget:
989 painter->save();
991 QColor softshadow = qt_palette_bg_color(option->palette).darker(120);
993 QRect rect= option->rect;
994 painter->setPen(softshadow);
995 painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
996 painter->setPen(QPen(option->palette.light(), 0));
997 painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1), QPoint(rect.left() + 1, rect.bottom() - 1));
998 painter->setPen(QPen(qt_palette_bg_color(option->palette).darker(120), 0));
999 painter->drawLine(QPoint(rect.left() + 1, rect.bottom() - 1), QPoint(rect.right() - 2, rect.bottom() - 1));
1000 painter->drawLine(QPoint(rect.right() - 1, rect.top() + 1), QPoint(rect.right() - 1, rect.bottom() - 1));
1003 painter->restore();
1004 break;
1005 case PE_PanelButtonTool:
1006 painter->save();
1007 if ((option->state & State_Enabled || option->state & State_On) || !(option->state & State_AutoRaise)) {
1008 if (widget && widget->inherits("QDockWidgetTitleButton")) {
1009 if (option->state & State_MouseOver)
1010 proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget);
1011 } else {
1012 proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget);
1015 painter->restore();
1016 break;
1017 case PE_IndicatorDockWidgetResizeHandle:
1019 QStyleOption dockWidgetHandle = *option;
1020 bool horizontal = option->state & State_Horizontal;
1021 if (horizontal)
1022 dockWidgetHandle.state &= ~State_Horizontal;
1023 else
1024 dockWidgetHandle.state |= State_Horizontal;
1025 proxy()->drawControl(CE_Splitter, &dockWidgetHandle, painter, widget);
1027 break;
1028 case PE_FrameWindow:
1029 painter->save();
1031 QRect rect= option->rect;
1032 painter->setPen(QPen(outline.darker(150), 0));
1033 painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
1034 painter->setPen(QPen(option->palette.light(), 0));
1035 painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1),
1036 QPoint(rect.left() + 1, rect.bottom() - 1));
1037 painter->setPen(QPen(qt_palette_bg_color(option->palette).darker(120), 0));
1038 painter->drawLine(QPoint(rect.left() + 1, rect.bottom() - 1),
1039 QPoint(rect.right() - 2, rect.bottom() - 1));
1040 painter->drawLine(QPoint(rect.right() - 1, rect.top() + 1),
1041 QPoint(rect.right() - 1, rect.bottom() - 1));
1043 painter->restore();
1044 break;
1045 case PE_FrameLineEdit:
1047 QRect r = rect;
1048 bool hasFocus = option->state & State_HasFocus;
1050 painter->save();
1052 painter->setRenderHint(QPainter::Antialiasing, true);
1053 // ### highdpi painter bug.
1054 painter->translate(0.5, 0.5);
1056 // Draw Outline
1057 painter->setPen( QPen(hasFocus ? highlightedOutline : highlightedOutline.darker(160), 0));
1058 painter->setBrush(option->palette.base());
1059 painter->drawRoundedRect(r.adjusted(0, 0, -1, -1), 2, 2);
1061 if (hasFocus) {
1062 QColor softHighlight = highlightedOutline;
1063 softHighlight.setAlpha(40);
1064 painter->setPen(softHighlight);
1065 painter->drawRoundedRect(r.adjusted(1, 1, -2, -2), 1.7, 1.7);
1067 // Draw inner shadow
1068 painter->setPen(d->topShadow());
1069 painter->drawLine(QPoint(r.left() + 2, r.top() + 1), QPoint(r.right() - 2, r.top() + 1));
1071 painter->restore();
1074 break;
1075 case PE_IndicatorCheckBox:
1076 painter->save();
1077 if (const QStyleOptionButton *checkbox = qstyleoption_cast<const QStyleOptionButton*>(option)) {
1078 painter->setRenderHint(QPainter::Antialiasing, true);
1079 painter->translate(0.5, 0.5);
1080 rect = rect.adjusted(0, 0, -1, -1);
1082 const QColor& baseColor = option->palette.base().color();
1084 QColor pressedColor = mergedColors(baseColor, qt_palette_fg_color(option->palette), 85);
1085 painter->setBrush(Qt::NoBrush);
1087 // Gradient fill
1088 QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
1090 if (state & State_Sunken)
1092 gradient.setColorAt(0, pressedColor);
1093 gradient.setColorAt(0.15, pressedColor);
1094 gradient.setColorAt(1, pressedColor);
1096 else
1098 gradient.setColorAt(0, baseColor.blackF() > 0.4 ? baseColor.lighter(115) : baseColor.darker(115));
1099 gradient.setColorAt(0.15, baseColor);
1100 gradient.setColorAt(1, baseColor);
1103 painter->setBrush((state & State_Sunken) ? QBrush(pressedColor) : gradient);
1105 if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange)
1106 painter->setPen(QPen(highlightedOutline, 1));
1107 else
1108 painter->setPen(QPen(outline.lighter(110), 1));
1110 painter->drawRect(rect);
1112 QColor checkMarkColor = option->palette.text().color().darker(120);
1114 if (checkbox->state & State_NoChange) {
1115 gradient = QLinearGradient(rect.topLeft(), rect.bottomLeft());
1116 checkMarkColor.setAlpha(80);
1117 gradient.setColorAt(0, checkMarkColor);
1118 checkMarkColor.setAlpha(140);
1119 gradient.setColorAt(1, checkMarkColor);
1120 checkMarkColor.setAlpha(180);
1121 painter->setPen(QPen(checkMarkColor, 1));
1122 painter->setBrush(gradient);
1123 painter->drawRect(rect.adjusted(3, 3, -3, -3));
1125 } else if (checkbox->state & (State_On)) {
1126 QPen checkPen = QPen(checkMarkColor, 1.8);
1127 checkMarkColor.setAlpha(210);
1128 painter->translate(-1, 0.5);
1129 painter->setPen(checkPen);
1130 painter->setBrush(Qt::NoBrush);
1131 painter->translate(0.2, 0.0);
1133 // Draw checkmark
1134 QPainterPath path;
1135 path.moveTo(5, rect.height() / 2.0);
1136 path.lineTo(rect.width() / 2.0 - 0, rect.height() - 3);
1137 path.lineTo(rect.width() - 2.5, 3);
1138 painter->drawPath(path.translated(rect.topLeft()));
1141 painter->restore();
1142 break;
1143 case PE_IndicatorRadioButton:
1144 painter->save();
1146 QColor pressedColor = mergedColors(option->palette.base().color(), qt_palette_fg_color(option->palette), 85);
1147 painter->setBrush((state & State_Sunken) ? pressedColor : option->palette.base().color());
1148 painter->setRenderHint(QPainter::Antialiasing, true);
1149 QPainterPath circle;
1150 circle.addEllipse(rect.center() + QPoint(1.0, 1.0), 6.5, 6.5);
1151 painter->setPen(QPen(qt_palette_bg_color(option->palette).darker(150), 1));
1152 if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange)
1153 painter->setPen(QPen(highlightedOutline, 1));
1154 painter->drawPath(circle);
1156 if (state & (State_On )) {
1157 circle = QPainterPath();
1158 circle.addEllipse(rect.center() + QPoint(1, 1), 2.8, 2.8);
1159 QColor checkMarkColor = option->palette.text().color().darker(120);
1160 checkMarkColor.setAlpha(200);
1161 painter->setPen(checkMarkColor);
1162 checkMarkColor.setAlpha(180);
1163 painter->setBrush(checkMarkColor);
1164 painter->drawPath(circle);
1167 painter->restore();
1168 break;
1169 case PE_IndicatorToolBarHandle:
1171 //draw grips
1172 if (option->state & State_Horizontal) {
1173 for (int i = -3 ; i < 2 ; i += 3) {
1174 for (int j = -8 ; j < 10 ; j += 3) {
1175 painter->fillRect(rect.center().x() + i, rect.center().y() + j, 2, 2, d->lightShade());
1176 painter->fillRect(rect.center().x() + i, rect.center().y() + j, 1, 1, d->darkShade());
1179 } else { //vertical toolbar
1180 for (int i = -6 ; i < 12 ; i += 3) {
1181 for (int j = -3 ; j < 2 ; j += 3) {
1182 painter->fillRect(rect.center().x() + i, rect.center().y() + j, 2, 2, d->lightShade());
1183 painter->fillRect(rect.center().x() + i, rect.center().y() + j, 1, 1, d->darkShade());
1187 break;
1189 case PE_FrameDefaultButton:
1190 break;
1191 case PE_FrameFocusRect:
1192 if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(option)) {
1193 //### check for d->alt_down
1194 if (!(fropt->state & State_KeyboardFocusChange))
1195 return;
1196 QRect rect = option->rect;
1198 painter->save();
1199 painter->setRenderHint(QPainter::Antialiasing, true);
1200 painter->translate(0.5, 0.5);
1201 QColor fillcolor = highlightedOutline;
1202 fillcolor.setAlpha(80);
1203 painter->setPen(fillcolor.darker(120));
1204 fillcolor.setAlpha(30);
1205 QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
1206 gradient.setColorAt(0, fillcolor.lighter(160));
1207 gradient.setColorAt(1, fillcolor);
1208 painter->setBrush(gradient);
1209 painter->drawRoundedRect(option->rect.adjusted(0, 0, -1, -1), 1, 1);
1210 painter->restore();
1212 break;
1213 case PE_PanelButtonCommand:
1215 bool isDefault = false;
1216 bool isFlat = false;
1217 bool isDown = (option->state & State_Sunken) || (option->state & State_On);
1218 QRect r;
1220 if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton*>(option)) {
1221 isDefault = (button->features & QStyleOptionButton::DefaultButton) && (button->state & State_Enabled);
1222 isFlat = (button->features & QStyleOptionButton::Flat);
1225 if (isFlat && !isDown) {
1226 if (isDefault) {
1227 r = option->rect.adjusted(0, 1, 0, -1);
1228 painter->setPen(QPen(Qt::black, 0));
1229 const QLine lines[4] = {
1230 QLine(QPoint(r.left() + 2, r.top()),
1231 QPoint(r.right() - 2, r.top())),
1232 QLine(QPoint(r.left(), r.top() + 2),
1233 QPoint(r.left(), r.bottom() - 2)),
1234 QLine(QPoint(r.right(), r.top() + 2),
1235 QPoint(r.right(), r.bottom() - 2)),
1236 QLine(QPoint(r.left() + 2, r.bottom()),
1237 QPoint(r.right() - 2, r.bottom()))
1239 painter->drawLines(lines, 4);
1240 const QPoint points[4] = {
1241 QPoint(r.right() - 1, r.bottom() - 1),
1242 QPoint(r.right() - 1, r.top() + 1),
1243 QPoint(r.left() + 1, r.bottom() - 1),
1244 QPoint(r.left() + 1, r.top() + 1)
1246 painter->drawPoints(points, 4);
1248 return;
1251 BEGIN_STYLE_PIXMAPCACHE(QString::fromLatin1("pushbutton-%1").arg(isDefault))
1252 r = rect.adjusted(0, 1, -1, 0);
1254 bool isEnabled = option->state & State_Enabled;
1255 bool hasFocus = (option->state & State_HasFocus && option->state & State_KeyboardFocusChange);
1256 QColor buttonColor = d->buttonColor(option->palette);
1258 QColor darkOutline = outline;
1259 if (hasFocus || isDefault) {
1260 darkOutline = highlightedOutline;
1263 if (isDefault)
1264 buttonColor = mergedColors(buttonColor, highlightedOutline.lighter(130), 90);
1266 p->setRenderHint(QPainter::Antialiasing, true);
1267 p->translate(0.5, -0.5);
1269 QLinearGradient gradient = qt_fusion_gradient(rect, (isEnabled && option->state & State_MouseOver ) ? buttonColor : buttonColor.darker(104));
1270 p->setBrush(isDown ? QBrush(buttonColor.darker(110)) : gradient);
1271 p->setPen(QPen(p->brush(), 1));
1272 p->drawRoundedRect(r.adjusted(1,1,-1,-1), 1.8, 1.8);
1273 p->setBrush(Qt::NoBrush);
1275 // Outline
1276 p->setPen(!isEnabled ? QPen(darkOutline.lighter(115)) : QPen(darkOutline, 1));
1277 p->drawRoundedRect(r, 2.5, 2.5);
1279 p->setPen(d->innerContrastLine());
1280 p->drawRoundedRect(r.adjusted(1, 1, -1, -1), 1.8, 1.8);
1282 END_STYLE_PIXMAPCACHE
1284 break;
1285 case PE_FrameTabWidget:
1286 painter->save();
1287 painter->fillRect(option->rect.adjusted(0, 0, -1, -1), tabFrameColor);
1288 if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) {
1289 QColor borderColor = outline.lighter(110);
1290 QRect rect = option->rect.adjusted(0, 0, -1, -1);
1292 // Shadow outline
1293 if (twf->shape != QTabBar::RoundedSouth) {
1294 rect.adjust(0, 0, 0, -1);
1295 QColor alphaShadow(Qt::black);
1296 alphaShadow.setAlpha(15);
1297 painter->setPen(alphaShadow);
1298 painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight()); painter->setPen(borderColor);
1301 // outline
1302 painter->setPen(outline);
1303 painter->drawRect(rect);
1305 // Inner frame highlight
1306 painter->setPen(d->innerContrastLine());
1307 painter->drawRect(rect.adjusted(1, 1, -1, -1));
1310 painter->restore();
1311 break ;
1313 case PE_FrameStatusBarItem:
1314 break;
1315 case PE_IndicatorTabClose:
1317 if (d->tabBarcloseButtonIcon.isNull())
1318 d->tabBarcloseButtonIcon = standardIcon(SP_DialogCloseButton, option, widget);
1319 if ((option->state & State_Enabled) && (option->state & State_MouseOver))
1320 proxy()->drawPrimitive(PE_PanelButtonCommand, option, painter, widget);
1321 QPixmap pixmap = d->tabBarcloseButtonIcon.pixmap(QSize(16, 16), QIcon::Normal, QIcon::On);
1322 proxy()->drawItemPixmap(painter, option->rect, Qt::AlignCenter, pixmap);
1324 break;
1325 case PE_PanelMenu: {
1326 painter->save();
1327 const QBrush menuBackground = option->palette.base().color().lighter(108);
1328 QColor borderColor(32, 32, 32);
1329 qDrawPlainRect(painter, option->rect, borderColor, 1, &menuBackground);
1330 painter->restore();
1332 break;
1334 default:
1335 QCommonStyle::drawPrimitive(elem, option, painter, widget);
1336 break;
1341 \reimp
1343 void CarlaStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter,
1344 const QWidget *widget) const
1346 QRect rect = option->rect;
1347 QColor outline = d->outline(option->palette);
1348 QColor highlightedOutline = d->highlightedOutline(option->palette);
1349 QColor shadow = d->darkShade();
1351 switch (element) {
1352 case CE_ComboBoxLabel:
1353 if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
1354 QRect editRect = proxy()->subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, widget);
1355 painter->save();
1356 painter->setClipRect(editRect);
1357 if (!cb->currentIcon.isNull()) {
1358 QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal
1359 : QIcon::Disabled;
1360 QPixmap pixmap = cb->currentIcon.pixmap(cb->iconSize, mode);
1361 QRect iconRect(editRect);
1362 iconRect.setWidth(cb->iconSize.width() + 4);
1363 iconRect = alignedRect(cb->direction,
1364 Qt::AlignLeft | Qt::AlignVCenter,
1365 iconRect.size(), editRect);
1366 if (cb->editable)
1367 painter->fillRect(iconRect, cb->palette.brush(QPalette::Base));
1368 proxy()->drawItemPixmap(painter, iconRect, Qt::AlignCenter, pixmap);
1370 if (cb->direction == Qt::RightToLeft)
1371 editRect.translate(-4 - cb->iconSize.width(), 0);
1372 else
1373 editRect.translate(cb->iconSize.width() + 4, 0);
1375 if (!cb->currentText.isEmpty() && !cb->editable) {
1376 proxy()->drawItemText(painter, editRect.adjusted(1, 0, -1, 0),
1377 visualAlignment(cb->direction, Qt::AlignLeft | Qt::AlignVCenter),
1378 cb->palette, cb->state & State_Enabled, cb->currentText,
1379 cb->editable ? QPalette::Text : QPalette::ButtonText);
1381 painter->restore();
1383 break;
1384 case CE_Splitter:
1386 // Don't draw handle for single pixel splitters
1387 if (option->rect.width() > 1 && option->rect.height() > 1) {
1388 //draw grips
1389 if (option->state & State_Horizontal) {
1390 for (int j = -6 ; j< 12 ; j += 3) {
1391 painter->fillRect(rect.center().x() + 1, rect.center().y() + j, 2, 2, d->lightShade());
1392 painter->fillRect(rect.center().x() + 1, rect.center().y() + j, 1, 1, d->darkShade());
1394 } else {
1395 for (int i = -6; i< 12 ; i += 3) {
1396 painter->fillRect(rect.center().x() + i, rect.center().y(), 2, 2, d->lightShade());
1397 painter->fillRect(rect.center().x() + i, rect.center().y(), 1, 1, d->darkShade());
1401 break;
1403 case CE_RubberBand:
1404 if (qstyleoption_cast<const QStyleOptionRubberBand *>(option)) {
1405 QColor highlight = option->palette.color(QPalette::Active, QPalette::Highlight);
1406 painter->save();
1407 QColor penColor = highlight.darker(120);
1408 penColor.setAlpha(180);
1409 painter->setPen(penColor);
1410 QColor dimHighlight(qMin(highlight.red()/2 + 110, 255),
1411 qMin(highlight.green()/2 + 110, 255),
1412 qMin(highlight.blue()/2 + 110, 255));
1413 dimHighlight.setAlpha(widget &&
1414 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
1415 widget->isWindow()
1416 #else
1417 widget->isTopLevel()
1418 #endif
1419 ? 255 : 80);
1420 QLinearGradient gradient(rect.topLeft(), QPoint(rect.bottomLeft().x(), rect.bottomLeft().y()));
1421 gradient.setColorAt(0, dimHighlight.lighter(120));
1422 gradient.setColorAt(1, dimHighlight);
1423 painter->setRenderHint(QPainter::Antialiasing, true);
1424 painter->translate(0.5, 0.5);
1425 painter->setBrush(dimHighlight);
1426 painter->drawRoundedRect(option->rect.adjusted(0, 0, -1, -1), 1.3, 1.3);
1427 QColor innerLine = Qt::white;
1428 innerLine.setAlpha(40);
1429 painter->setPen(innerLine);
1430 painter->drawRoundedRect(option->rect.adjusted(1, 1, -2, -2), 0.7, 0.7);
1431 painter->restore();
1432 return;
1434 break;
1435 case CE_SizeGrip:
1436 painter->save();
1438 //draw grips
1439 for (int i = -6; i< 12 ; i += 3) {
1440 for (int j = -6 ; j< 12 ; j += 3) {
1441 if ((option->direction == Qt::LeftToRight && i > -j) || (option->direction == Qt::RightToLeft && j > i) ) {
1442 painter->fillRect(rect.center().x() + i, rect.center().y() + j, 2, 2, d->lightShade());
1443 painter->fillRect(rect.center().x() + i, rect.center().y() + j, 1, 1, d->darkShade());
1448 painter->restore();
1449 break;
1450 case CE_ToolBar:
1451 if (const QStyleOptionToolBar *toolBar = qstyleoption_cast<const QStyleOptionToolBar *>(option)) {
1452 // Reserve the beveled appearance only for mainwindow toolbars
1453 if (widget && !(qobject_cast<const QMainWindow*> (widget->parentWidget())))
1454 break;
1456 // Draws the light line above and the dark line below menu bars and
1457 // tool bars.
1458 QLinearGradient gradient(option->rect.topLeft(), option->rect.bottomLeft());
1459 if (!(option->state & State_Horizontal))
1460 gradient = QLinearGradient(rect.left(), rect.center().y(),
1461 rect.right(), rect.center().y());
1462 gradient.setColorAt(0, option->palette.window().color().lighter(104));
1463 gradient.setColorAt(1, option->palette.window().color());
1464 painter->fillRect(option->rect, gradient);
1466 QColor light = d->lightShade();
1467 QColor shadow = d->darkShade();
1469 QPen oldPen = painter->pen();
1470 if (toolBar->toolBarArea == Qt::TopToolBarArea) {
1471 if (toolBar->positionOfLine == QStyleOptionToolBar::End
1472 || toolBar->positionOfLine == QStyleOptionToolBar::OnlyOne) {
1473 // The end and onlyone top toolbar lines draw a double
1474 // line at the bottom to blend with the central
1475 // widget.
1476 painter->setPen(light);
1477 painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
1478 painter->setPen(shadow);
1479 painter->drawLine(option->rect.left(), option->rect.bottom() - 1,
1480 option->rect.right(), option->rect.bottom() - 1);
1481 } else {
1482 // All others draw a single dark line at the bottom.
1483 painter->setPen(shadow);
1484 painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
1486 // All top toolbar lines draw a light line at the top.
1487 painter->setPen(light);
1488 painter->drawLine(option->rect.topLeft(), option->rect.topRight());
1489 } else if (toolBar->toolBarArea == Qt::BottomToolBarArea) {
1490 if (toolBar->positionOfLine == QStyleOptionToolBar::End
1491 || toolBar->positionOfLine == QStyleOptionToolBar::Middle) {
1492 // The end and middle bottom tool bar lines draw a dark
1493 // line at the bottom.
1494 painter->setPen(shadow);
1495 painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
1497 if (toolBar->positionOfLine == QStyleOptionToolBar::Beginning
1498 || toolBar->positionOfLine == QStyleOptionToolBar::OnlyOne) {
1499 // The beginning and only one tool bar lines draw a
1500 // double line at the bottom to blend with the
1501 // status bar.
1502 // ### The styleoption could contain whether the
1503 // main window has a menu bar and a status bar, and
1504 // possibly dock widgets.
1505 painter->setPen(shadow);
1506 painter->drawLine(option->rect.left(), option->rect.bottom() - 1,
1507 option->rect.right(), option->rect.bottom() - 1);
1508 painter->setPen(light);
1509 painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
1511 if (toolBar->positionOfLine == QStyleOptionToolBar::End) {
1512 painter->setPen(shadow);
1513 painter->drawLine(option->rect.topLeft(), option->rect.topRight());
1514 painter->setPen(light);
1515 painter->drawLine(option->rect.left(), option->rect.top() + 1,
1516 option->rect.right(), option->rect.top() + 1);
1518 } else {
1519 // All other bottom toolbars draw a light line at the top.
1520 painter->setPen(light);
1521 painter->drawLine(option->rect.topLeft(), option->rect.topRight());
1524 if (toolBar->toolBarArea == Qt::LeftToolBarArea) {
1525 if (toolBar->positionOfLine == QStyleOptionToolBar::Middle
1526 || toolBar->positionOfLine == QStyleOptionToolBar::End) {
1527 // The middle and left end toolbar lines draw a light
1528 // line to the left.
1529 painter->setPen(light);
1530 painter->drawLine(option->rect.topLeft(), option->rect.bottomLeft());
1532 if (toolBar->positionOfLine == QStyleOptionToolBar::End) {
1533 // All other left toolbar lines draw a dark line to the right
1534 painter->setPen(shadow);
1535 painter->drawLine(option->rect.right() - 1, option->rect.top(),
1536 option->rect.right() - 1, option->rect.bottom());
1537 painter->setPen(light);
1538 painter->drawLine(option->rect.topRight(), option->rect.bottomRight());
1539 } else {
1540 // All other left toolbar lines draw a dark line to the right
1541 painter->setPen(shadow);
1542 painter->drawLine(option->rect.topRight(), option->rect.bottomRight());
1544 } else if (toolBar->toolBarArea == Qt::RightToolBarArea) {
1545 if (toolBar->positionOfLine == QStyleOptionToolBar::Middle
1546 || toolBar->positionOfLine == QStyleOptionToolBar::End) {
1547 // Right middle and end toolbar lines draw the dark right line
1548 painter->setPen(shadow);
1549 painter->drawLine(option->rect.topRight(), option->rect.bottomRight());
1551 if (toolBar->positionOfLine == QStyleOptionToolBar::End
1552 || toolBar->positionOfLine == QStyleOptionToolBar::OnlyOne) {
1553 // The right end and single toolbar draws the dark
1554 // line on its left edge
1555 painter->setPen(shadow);
1556 painter->drawLine(option->rect.topLeft(), option->rect.bottomLeft());
1557 // And a light line next to it
1558 painter->setPen(light);
1559 painter->drawLine(option->rect.left() + 1, option->rect.top(),
1560 option->rect.left() + 1, option->rect.bottom());
1561 } else {
1562 // Other right toolbars draw a light line on its left edge
1563 painter->setPen(light);
1564 painter->drawLine(option->rect.topLeft(), option->rect.bottomLeft());
1567 painter->setPen(oldPen);
1569 break;
1570 case CE_DockWidgetTitle:
1571 painter->save();
1572 if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
1573 bool verticalTitleBar = false;
1575 QRect titleRect = subElementRect(SE_DockWidgetTitleBarText, option, widget);
1576 if (verticalTitleBar) {
1577 QRect rect = dwOpt->rect;
1578 QRect r = rect;
1579 QSize s = r.size();
1580 s.transpose();
1581 r.setSize(s);
1582 titleRect = QRect(r.left() + rect.bottom()
1583 - titleRect.bottom(),
1584 r.top() + titleRect.left() - rect.left(),
1585 titleRect.height(), titleRect.width());
1587 painter->translate(r.left(), r.top() + r.width());
1588 painter->rotate(-90);
1589 painter->translate(-r.left(), -r.top());
1592 if (!dwOpt->title.isEmpty()) {
1593 QString titleText
1594 = painter->fontMetrics().elidedText(dwOpt->title,
1595 Qt::ElideRight, titleRect.width());
1596 proxy()->drawItemText(painter,
1597 titleRect,
1598 Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, dwOpt->palette,
1599 dwOpt->state & State_Enabled, titleText,
1600 QPalette::WindowText);
1603 painter->restore();
1604 break;
1605 case CE_HeaderSection:
1606 painter->save();
1607 // Draws the header in tables.
1608 if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
1609 QString pixmapName = uniqueName(QLatin1String("headersection"), option, option->rect.size());
1610 pixmapName += QString::number(- int(header->position));
1611 pixmapName += QString::number(- int(header->orientation));
1613 QPixmap cache;
1614 if (!QPixmapCache::find(pixmapName, PIXMAPCACHE_VAR_PREFIX cache)) {
1615 cache = styleCachePixmap(rect.size());
1616 cache.fill(Qt::transparent);
1617 QRect pixmapRect(0, 0, rect.width(), rect.height());
1618 QPainter cachePainter(&cache);
1619 QColor buttonColor = d->buttonColor(option->palette);
1620 QColor gradientStopColor;
1621 QColor gradientStartColor = buttonColor.lighter(104);
1622 gradientStopColor = buttonColor.darker(102);
1623 QLinearGradient gradient(pixmapRect.topLeft(), pixmapRect.bottomLeft());
1625 #if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
1626 const QGradient* gradientBrush = option->palette.window().gradient();
1627 #else
1628 const QGradient* gradientBrush = option->palette.background().gradient();
1629 #endif
1630 if (gradientBrush) {
1631 gradient.setStops(gradientBrush->stops());
1632 } else {
1633 QColor midColor1 = mergedColors(gradientStartColor, gradientStopColor, 60);
1634 QColor midColor2 = mergedColors(gradientStartColor, gradientStopColor, 40);
1635 gradient.setColorAt(0, gradientStartColor);
1636 gradient.setColorAt(0.5, midColor1);
1637 gradient.setColorAt(0.501, midColor2);
1638 gradient.setColorAt(0.92, gradientStopColor);
1639 gradient.setColorAt(1, gradientStopColor.darker(104));
1641 cachePainter.fillRect(pixmapRect, gradient);
1642 cachePainter.setPen(d->innerContrastLine());
1643 cachePainter.setBrush(Qt::NoBrush);
1644 cachePainter.drawLine(pixmapRect.topLeft(), pixmapRect.topRight());
1645 cachePainter.setPen(d->outline(option->palette));
1646 cachePainter.drawLine(pixmapRect.bottomLeft(), pixmapRect.bottomRight());
1648 if (header->orientation == Qt::Horizontal &&
1649 header->position != QStyleOptionHeader::End &&
1650 header->position != QStyleOptionHeader::OnlyOneSection) {
1651 cachePainter.setPen(QColor(0, 0, 0, 40));
1652 cachePainter.drawLine(pixmapRect.topRight(), pixmapRect.bottomRight() + QPoint(0, -1));
1653 cachePainter.setPen(d->innerContrastLine());
1654 cachePainter.drawLine(pixmapRect.topRight() + QPoint(-1, 0), pixmapRect.bottomRight() + QPoint(-1, -1));
1655 } else if (header->orientation == Qt::Vertical) {
1656 cachePainter.setPen(d->outline(option->palette));
1657 cachePainter.drawLine(pixmapRect.topRight(), pixmapRect.bottomRight());
1659 cachePainter.end();
1660 QPixmapCache::insert(pixmapName, cache);
1662 painter->drawPixmap(rect.topLeft(), cache);
1664 painter->restore();
1665 break;
1666 case CE_ProgressBarGroove:
1667 painter->save();
1669 painter->setRenderHint(QPainter::Antialiasing, true);
1670 painter->translate(0.5, 0.5);
1672 QColor shadowAlpha = Qt::black;
1673 shadowAlpha.setAlpha(16);
1674 painter->setPen(shadowAlpha);
1675 painter->drawLine(rect.topLeft() - QPoint(0, 1), rect.topRight() - QPoint(0, 1));
1677 painter->setBrush(Qt::NoBrush);
1678 painter->setPen(QPen(outline, 1));
1679 painter->drawRoundedRect(rect.adjusted(0, 0, -1, -1), 2.5, 2.5);
1680 painter->setBrush(option->palette.base());
1681 painter->setPen(QPen(option->palette.base(), 1));
1682 painter->drawRoundedRect(rect.adjusted(1, 1, -2, -2), 1.8, 1.8);
1684 // Inner shadow
1685 painter->setPen(d->topShadow());
1686 painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1),
1687 QPoint(rect.right() - 1, rect.top() + 1));
1689 painter->restore();
1690 break;
1691 case CE_ProgressBarContents:
1692 painter->save();
1693 painter->setRenderHint(QPainter::Antialiasing, true);
1694 painter->translate(0.5, 0.5);
1695 if (const QStyleOptionProgressBarV2 *bar = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
1696 bool vertical = false;
1697 bool inverted = false;
1698 bool indeterminate = (bar->minimum == 0 && bar->maximum == 0);
1699 bool complete = bar->progress == bar->maximum;
1701 // Get extra style options if version 2
1702 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
1703 vertical = (bar->state & QStyle::State_Horizontal) == 0;
1704 #else
1705 vertical = (bar->orientation == Qt::Vertical);
1706 #endif
1707 inverted = bar->invertedAppearance;
1709 // If the orientation is vertical, we use a transform to rotate
1710 // the progress bar 90 degrees clockwise. This way we can use the
1711 // same rendering code for both orientations.
1712 if (vertical) {
1713 rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height
1714 QTransform m = QTransform::fromTranslate(rect.height()-1, -1.0);
1715 m.rotate(90.0);
1716 painter->setTransform(m, true);
1719 int maxWidth = rect.width();
1720 int minWidth = 0;
1721 qreal progress = qMax(bar->progress, bar->minimum); // workaround for bug in QProgressBar
1722 int progressBarWidth = (progress - bar->minimum) * qreal(maxWidth) / qMax(qreal(1.0), qreal(bar->maximum) - bar->minimum);
1723 int width = indeterminate ? maxWidth : qMax(minWidth, progressBarWidth);
1725 bool reverse = (!vertical && (bar->direction == Qt::RightToLeft)) || vertical;
1726 if (inverted)
1727 reverse = !reverse;
1729 int step = 0;
1730 QRect progressBar;
1731 QColor highlight = d->highlight(option->palette);
1732 QColor highlightedoutline = highlight.darker(140);
1733 if (qGray(outline.rgb()) > qGray(highlightedoutline.rgb()))
1734 outline = highlightedoutline;
1736 if (!indeterminate) {
1737 QColor innerShadow(Qt::black);
1738 innerShadow.setAlpha(35);
1739 painter->setPen(innerShadow);
1740 if (!reverse) {
1741 progressBar.setRect(rect.left(), rect.top(), width - 1, rect.height() - 1);
1742 if (!complete) {
1743 painter->drawLine(progressBar.topRight() + QPoint(2, 1), progressBar.bottomRight() + QPoint(2, 0));
1744 painter->setPen(QPen(highlight.darker(140), 0));
1745 painter->drawLine(progressBar.topRight() + QPoint(1, 1), progressBar.bottomRight() + QPoint(1, 0));
1747 } else {
1748 progressBar.setRect(rect.right() - width - 1, rect.top(), width + 2, rect.height() - 1);
1749 if (!complete) {
1750 painter->drawLine(progressBar.topLeft() + QPoint(-2, 1), progressBar.bottomLeft() + QPoint(-2, 0));
1751 painter->setPen(QPen(highlight.darker(140), 0));
1752 painter->drawLine(progressBar.topLeft() + QPoint(-1, 1), progressBar.bottomLeft() + QPoint(-1, 0));
1755 } else {
1756 progressBar.setRect(rect.left(), rect.top(), rect.width() - 1, rect.height() - 1);
1759 if (indeterminate || bar->progress > bar->minimum) {
1761 QColor highlightedGradientStartColor = highlight.lighter(120);
1762 QColor highlightedGradientStopColor = highlight;
1763 QLinearGradient gradient(rect.topLeft(), QPoint(rect.bottomLeft().x(), rect.bottomLeft().y()));
1764 gradient.setColorAt(0, highlightedGradientStartColor);
1765 gradient.setColorAt(1, highlightedGradientStopColor);
1767 painter->setBrush(gradient);
1768 painter->setPen(QPen(painter->brush(), 1));
1770 painter->save();
1771 if (!complete && !indeterminate)
1772 painter->setClipRect(progressBar.adjusted(0, 0, -1, 0));
1773 QRect fillRect = progressBar.adjusted( indeterminate || complete || !reverse ? 1 : -1, 1,
1774 indeterminate || complete || reverse ? -1 : 1, -1);
1775 painter->drawRoundedRect(fillRect, 1.8, 1.8);
1776 painter->restore();
1778 painter->setBrush(Qt::NoBrush);
1779 painter->setPen(QColor(255, 255, 255, 50));
1780 painter->drawRoundedRect(progressBar.adjusted(1, 1, -1, -1), 1.8, 1.8);
1782 if (!indeterminate) {
1783 d->stopAnimation(widget);
1784 } else {
1785 highlightedGradientStartColor.setAlpha(120);
1786 painter->setPen(QPen(highlightedGradientStartColor, 9.0));
1787 painter->setClipRect(progressBar.adjusted(1, 1, -1, -1));
1788 #ifndef QT_NO_ANIMATION
1789 if (CarlaProgressStyleAnimation *animation = qobject_cast<CarlaProgressStyleAnimation*>(d->animation(widget)))
1790 step = animation->animationStep() % 22;
1791 else
1792 d->startAnimation(new CarlaProgressStyleAnimation(d->animationFps(), const_cast<QWidget*>(widget)));
1793 #endif
1794 for (int x = progressBar.left() - rect.height(); x < rect.right() ; x += 22)
1795 painter->drawLine(x + step, progressBar.bottom() + 1,
1796 x + rect.height() + step, progressBar.top() - 2);
1800 painter->restore();
1801 break;
1802 case CE_ProgressBarLabel:
1803 if (const QStyleOptionProgressBarV2 *bar = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
1804 QRect leftRect;
1805 QRect rect = bar->rect;
1806 QColor textColor = option->palette.text().color();
1807 QColor alternateTextColor = d->highlightedText(option->palette);
1809 painter->save();
1810 bool vertical = false, inverted = false;
1811 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
1812 vertical = (bar->state & QStyle::State_Horizontal) == 0;
1813 #else
1814 vertical = (bar->orientation == Qt::Vertical);
1815 #endif
1816 inverted = bar->invertedAppearance;
1817 if (vertical)
1818 rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height
1819 const int progressIndicatorPos = (bar->progress - qreal(bar->minimum)) * rect.width() /
1820 qMax(qreal(1.0), qreal(bar->maximum) - bar->minimum);
1821 if (progressIndicatorPos >= 0 && progressIndicatorPos <= rect.width())
1822 leftRect = QRect(rect.left(), rect.top(), progressIndicatorPos, rect.height());
1823 if (vertical)
1824 leftRect.translate(rect.width() - progressIndicatorPos, 0);
1826 bool flip = (!vertical && (((bar->direction == Qt::RightToLeft) && !inverted) ||
1827 ((bar->direction == Qt::LeftToRight) && inverted)));
1829 QRegion rightRect = rect;
1830 rightRect = rightRect.subtracted(leftRect);
1831 painter->setClipRegion(rightRect);
1832 painter->setPen(flip ? alternateTextColor : textColor);
1833 painter->drawText(rect, bar->text, QTextOption(Qt::AlignAbsolute | Qt::AlignHCenter | Qt::AlignVCenter));
1834 if (!leftRect.isNull()) {
1835 painter->setPen(flip ? textColor : alternateTextColor);
1836 painter->setClipRect(leftRect);
1837 painter->drawText(rect, bar->text, QTextOption(Qt::AlignAbsolute | Qt::AlignHCenter | Qt::AlignVCenter));
1839 painter->restore();
1841 break;
1842 case CE_MenuBarItem:
1843 painter->save();
1844 if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
1846 QStyleOptionMenuItem item = *mbi;
1847 item.rect = mbi->rect.adjusted(0, 1, 0, -3);
1848 QColor highlightOutline = option->palette.highlight().color().darker(125);
1849 painter->fillRect(rect, option->palette.window());
1851 QCommonStyle::drawControl(element, &item, painter, widget);
1853 bool act = mbi->state & State_Selected && mbi->state & State_Sunken;
1854 bool dis = !(mbi->state & State_Enabled);
1856 QRect r = option->rect;
1857 if (act)
1859 painter->setBrush(option->palette.highlight().color());
1860 painter->setPen(QPen(highlightOutline, 0));
1861 painter->drawRect(r.adjusted(0, 5, -1, -1));
1862 painter->drawRoundedRect(r.adjusted(0, 0, -1, -1), 2, 2);
1864 //draw text
1865 QPalette::ColorRole textRole = dis ? QPalette::Text : QPalette::HighlightedText;
1866 uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
1867 if (!styleHint(SH_UnderlineShortcut, mbi, widget))
1868 alignment |= Qt::TextHideMnemonic;
1869 proxy()->drawItemText(painter, item.rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole);
1871 else
1873 QColor shadow = mergedColors(qt_palette_bg_color(option->palette).darker(120),
1874 outline.lighter(140), 60);
1875 painter->setPen(QPen(shadow));
1876 painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
1879 painter->restore();
1880 break;
1881 case CE_MenuItem:
1882 painter->save();
1883 // Draws one item in a popup menu.
1884 if (const QStyleOptionMenuItem* menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
1885 QColor highlightOutline = highlightedOutline;
1886 QColor highlight = option->palette.highlight().color();
1887 if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
1888 int w = 0;
1889 if (!menuItem->text.isEmpty()) {
1890 painter->setFont(menuItem->font);
1891 proxy()->drawItemText(painter, menuItem->rect.adjusted(5, 0, -5, 0), Qt::AlignLeft | Qt::AlignVCenter,
1892 menuItem->palette, menuItem->state & State_Enabled, menuItem->text,
1893 QPalette::Text);
1894 w = fontMetricsHorizontalAdvance(menuItem->fontMetrics, menuItem->text) + 5;
1896 painter->setPen(highlight);
1897 bool reverse = menuItem->direction == Qt::RightToLeft;
1898 painter->drawLine(menuItem->rect.left() + 5 + (reverse ? 0 : w), menuItem->rect.center().y(),
1899 menuItem->rect.right() - 5 - (reverse ? w : 0), menuItem->rect.center().y());
1900 painter->restore();
1901 break;
1903 bool selected = menuItem->state & State_Selected && menuItem->state & State_Enabled;
1904 if (selected) {
1905 QRect r = option->rect;
1906 painter->fillRect(r, highlight);
1907 painter->setPen(QPen(highlightOutline, 0));
1908 painter->drawRect(QRectF(r).adjusted(0.5, 0.5, -0.5, -0.5));
1910 bool checkable = menuItem->checkType != QStyleOptionMenuItem::NotCheckable;
1911 bool checked = menuItem->checked;
1912 bool sunken = menuItem->state & State_Sunken;
1913 bool enabled = menuItem->state & State_Enabled;
1915 bool ignoreCheckMark = false;
1916 int checkcol = qMax(menuItem->maxIconWidth, 20);
1918 if (qobject_cast<const QComboBox*>(widget))
1919 ignoreCheckMark = true; //ignore the checkmarks provided by the QComboMenuDelegate
1921 if (!ignoreCheckMark) {
1922 // Check
1923 QRect checkRect(option->rect.left() + 7, option->rect.center().y() - 6, 14, 14);
1924 checkRect = visualRect(menuItem->direction, menuItem->rect, checkRect);
1925 if (checkable) {
1926 if (menuItem->checkType & QStyleOptionMenuItem::Exclusive) {
1927 // Radio button
1928 if (checked || sunken) {
1929 painter->setRenderHint(QPainter::Antialiasing);
1930 painter->setPen(Qt::NoPen);
1932 QPalette::ColorRole textRole = !enabled ? QPalette::Text:
1933 selected ? QPalette::HighlightedText : QPalette::ButtonText;
1934 painter->setBrush(option->palette.brush( option->palette.currentColorGroup(), textRole));
1935 painter->drawEllipse(checkRect.adjusted(4, 4, -4, -4));
1937 } else {
1938 // Check box
1939 if (menuItem->icon.isNull()) {
1940 QStyleOptionButton box;
1941 box.QStyleOption::operator=(*option);
1942 box.rect = checkRect;
1943 if (checked)
1944 box.state |= State_On;
1945 proxy()->drawPrimitive(PE_IndicatorCheckBox, &box, painter, widget);
1946 painter->setPen(QPen(highlight, 0));
1947 painter->drawRect(checkRect);
1951 } else { //ignore checkmark
1952 if (menuItem->icon.isNull())
1953 checkcol = 0;
1954 else
1955 checkcol = menuItem->maxIconWidth;
1958 // Text and icon, ripped from windows style
1959 bool dis = !(menuItem->state & State_Enabled);
1960 bool act = menuItem->state & State_Selected;
1961 const QStyleOption *opt = option;
1962 const QStyleOptionMenuItem *menuitem = menuItem;
1964 QPainter *p = painter;
1965 QRect vCheckRect = visualRect(opt->direction, menuitem->rect,
1966 QRect(menuitem->rect.x() + 4, menuitem->rect.y(),
1967 checkcol, menuitem->rect.height()));
1968 if (!menuItem->icon.isNull()) {
1969 QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
1970 if (act && !dis)
1971 mode = QIcon::Active;
1972 QPixmap pixmap;
1974 int smallIconSize = proxy()->pixelMetric(PM_SmallIconSize, option, widget);
1975 QSize iconSize(smallIconSize, smallIconSize);
1976 if (const QComboBox *combo = qobject_cast<const QComboBox*>(widget))
1977 iconSize = combo->iconSize();
1978 if (checked)
1979 pixmap = menuItem->icon.pixmap(iconSize, mode, QIcon::On);
1980 else
1981 pixmap = menuItem->icon.pixmap(iconSize, mode);
1983 #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
1984 const int pixw = pixmap.width() / pixmap.devicePixelRatioF();
1985 const int pixh = pixmap.height() / pixmap.devicePixelRatioF();
1986 #else
1987 const int pixw = pixmap.width();
1988 const int pixh = pixmap.height();
1989 #endif
1991 QRect pmr(0, 0, pixw, pixh);
1992 pmr.moveCenter(vCheckRect.center());
1993 painter->setPen(menuItem->palette.text().color());
1994 if (checkable && checked) {
1995 QStyleOption opt = *option;
1996 if (act) {
1997 QColor activeColor = mergedColors(qt_palette_bg_color(option->palette),
1998 option->palette.highlight().color());
1999 opt.palette.setBrush(QPalette::Button, activeColor);
2001 opt.state |= State_Sunken;
2002 opt.rect = vCheckRect;
2003 proxy()->drawPrimitive(PE_PanelButtonCommand, &opt, painter, widget);
2005 painter->drawPixmap(pmr.topLeft(), pixmap);
2007 if (selected) {
2008 painter->setPen(menuItem->palette.highlightedText().color());
2009 } else {
2010 painter->setPen(menuItem->palette.text().color());
2012 int x, y, w, h;
2013 menuitem->rect.getRect(&x, &y, &w, &h);
2014 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
2015 int tab = menuitem->reservedShortcutWidth;
2016 #else
2017 int tab = menuitem->tabWidth;
2018 #endif
2019 QColor discol;
2020 if (dis) {
2021 discol = menuitem->palette.text().color();
2022 p->setPen(discol);
2024 int xm = windowsItemFrame + checkcol + windowsItemHMargin + 2;
2025 int xpos = menuitem->rect.x() + xm;
2027 QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
2028 QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect);
2029 QString s = menuitem->text;
2030 if (!s.isEmpty()) { // draw text
2031 p->save();
2032 int t = s.indexOf(QLatin1Char('\t'));
2033 int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
2034 if (!styleHint(SH_UnderlineShortcut, menuitem, widget))
2035 text_flags |= Qt::TextHideMnemonic;
2036 text_flags |= Qt::AlignLeft;
2037 if (t >= 0) {
2038 QRect vShortcutRect = visualRect(opt->direction, menuitem->rect,
2039 QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
2040 if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) {
2041 p->setPen(menuitem->palette.light().color());
2042 p->drawText(vShortcutRect.adjusted(1, 1, 1, 1), text_flags, s.mid(t + 1));
2043 p->setPen(discol);
2045 p->drawText(vShortcutRect, text_flags, s.mid(t + 1));
2046 s = s.left(t);
2048 QFont font = menuitem->font;
2049 // font may not have any "hard" flags set. We override
2050 // the point size so that when it is resolved against the device, this font will win.
2051 // This is mainly to handle cases where someone sets the font on the window
2052 // and then the combo inherits it and passes it onward. At that point the resolve mask
2053 // is very, very weak. This makes it stonger.
2054 font.setPointSizeF(QFontInfo(menuItem->font).pointSizeF());
2056 if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
2057 font.setBold(true);
2059 p->setFont(font);
2060 if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) {
2061 p->setPen(menuitem->palette.light().color());
2062 p->drawText(vTextRect.adjusted(1, 1, 1, 1), text_flags, s.left(t));
2063 p->setPen(discol);
2065 p->drawText(vTextRect, text_flags, s.left(t));
2066 p->restore();
2069 // Arrow
2070 if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
2071 int dim = (menuItem->rect.height() - 4) / 2;
2072 PrimitiveElement arrow;
2073 arrow = option->direction == Qt::RightToLeft ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
2074 int xpos = menuItem->rect.left() + menuItem->rect.width() - 3 - dim;
2075 QRect vSubMenuRect = visualRect(option->direction, menuItem->rect,
2076 QRect(xpos, menuItem->rect.top() + menuItem->rect.height() / 2 - dim / 2, dim, dim));
2077 QStyleOptionMenuItem newMI = *menuItem;
2078 newMI.rect = vSubMenuRect;
2079 newMI.state = !enabled ? State_None : State_Enabled;
2080 if (selected)
2081 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
2082 newMI.palette.setColor(QPalette::WindowText,
2083 #else
2084 newMI.palette.setColor(QPalette::Foreground,
2085 #endif
2086 newMI.palette.highlightedText().color());
2087 proxy()->drawPrimitive(arrow, &newMI, painter, widget);
2090 painter->restore();
2091 break;
2092 case CE_MenuHMargin:
2093 case CE_MenuVMargin:
2094 break;
2095 case CE_MenuEmptyArea:
2096 break;
2097 case CE_PushButton:
2098 if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
2099 proxy()->drawControl(CE_PushButtonBevel, btn, painter, widget);
2100 QStyleOptionButton subopt = *btn;
2101 subopt.rect = subElementRect(SE_PushButtonContents, btn, widget);
2102 proxy()->drawControl(CE_PushButtonLabel, &subopt, painter, widget);
2104 break;
2105 case CE_PushButtonLabel:
2106 if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
2107 QRect ir = button->rect;
2108 uint tf = Qt::AlignVCenter;
2109 if (styleHint(SH_UnderlineShortcut, button, widget))
2110 tf |= Qt::TextShowMnemonic;
2111 else
2112 tf |= Qt::TextHideMnemonic;
2114 if (!button->icon.isNull()) {
2115 //Center both icon and text
2116 QPoint point;
2118 QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal
2119 : QIcon::Disabled;
2120 if (mode == QIcon::Normal && button->state & State_HasFocus)
2121 mode = QIcon::Active;
2122 QIcon::State state = QIcon::Off;
2123 if (button->state & State_On)
2124 state = QIcon::On;
2126 QPixmap pixmap = button->icon.pixmap(button->iconSize, mode, state);
2127 #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
2128 int w = pixmap.width() / pixmap.devicePixelRatio();
2129 int h = pixmap.height() / pixmap.devicePixelRatio();
2130 #else
2131 int w = pixmap.width();
2132 int h = pixmap.height();
2133 #endif
2135 if (!button->text.isEmpty())
2136 w += button->fontMetrics.boundingRect(option->rect, tf, button->text).width() + 2;
2138 point = QPoint(ir.x() + ir.width() / 2 - w / 2,
2139 ir.y() + ir.height() / 2 - h / 2);
2141 #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
2142 w = pixmap.width() / pixmap.devicePixelRatio();
2143 #else
2144 w = pixmap.width();
2145 #endif
2147 if (button->direction == Qt::RightToLeft)
2148 point.rx() += w;
2150 painter->drawPixmap(visualPos(button->direction, button->rect, point), pixmap);
2152 if (button->direction == Qt::RightToLeft)
2153 ir.translate(-point.x() - 2, 0);
2154 else
2155 ir.translate(point.x() + w, 0);
2157 // left-align text if there is
2158 if (!button->text.isEmpty())
2159 tf |= Qt::AlignLeft;
2161 } else {
2162 tf |= Qt::AlignHCenter;
2165 if (button->features & QStyleOptionButton::HasMenu)
2166 ir = ir.adjusted(0, 0, -proxy()->pixelMetric(PM_MenuButtonIndicator, button, widget), 0);
2167 proxy()->drawItemText(painter, ir, tf, button->palette, (button->state & State_Enabled),
2168 button->text, QPalette::ButtonText);
2170 break;
2171 case CE_MenuBarEmptyArea:
2172 painter->save();
2174 painter->fillRect(rect, option->palette.window());
2175 if (widget && qobject_cast<const QMainWindow *>(widget->parentWidget())) {
2176 QColor shadow = mergedColors(qt_palette_bg_color(option->palette).darker(120),
2177 outline.lighter(140), 60);
2178 painter->setPen(QPen(shadow));
2179 painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
2182 painter->restore();
2183 break;
2184 case CE_TabBarTabShape:
2185 painter->save();
2186 if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
2188 bool rtlHorTabs = (tab->direction == Qt::RightToLeft
2189 && (tab->shape == QTabBar::RoundedNorth
2190 || tab->shape == QTabBar::RoundedSouth));
2191 bool selected = tab->state & State_Selected;
2192 bool lastTab = ((!rtlHorTabs && tab->position == QStyleOptionTab::End)
2193 || (rtlHorTabs
2194 && tab->position == QStyleOptionTab::Beginning));
2195 bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
2196 int tabOverlap = pixelMetric(PM_TabBarTabOverlap, option, widget);
2197 rect = option->rect.adjusted(0, 0, (onlyOne || lastTab) ? 0 : tabOverlap, 0);
2199 #if 0
2200 QRect r2(rect);
2201 int x1 = r2.left();
2202 int x2 = r2.right();
2203 int y1 = r2.top();
2204 int y2 = r2.bottom();
2205 #endif
2207 painter->setPen(d->innerContrastLine());
2209 QTransform rotMatrix;
2210 bool flip = false;
2211 painter->setPen(shadow);
2213 switch (tab->shape) {
2214 case QTabBar::RoundedNorth:
2215 break;
2216 case QTabBar::RoundedSouth:
2217 rotMatrix.rotate(180);
2218 rotMatrix.translate(0, -rect.height() + 1);
2219 rotMatrix.scale(-1, 1);
2220 painter->setTransform(rotMatrix, true);
2221 break;
2222 case QTabBar::RoundedWest:
2223 rotMatrix.rotate(180 + 90);
2224 rotMatrix.scale(-1, 1);
2225 flip = true;
2226 painter->setTransform(rotMatrix, true);
2227 break;
2228 case QTabBar::RoundedEast:
2229 rotMatrix.rotate(90);
2230 rotMatrix.translate(0, - rect.width() + 1);
2231 flip = true;
2232 painter->setTransform(rotMatrix, true);
2233 break;
2234 default:
2235 painter->restore();
2236 QCommonStyle::drawControl(element, tab, painter, widget);
2237 return;
2240 if (flip) {
2241 QRect tmp = rect;
2242 rect = QRect(tmp.y(), tmp.x(), tmp.height(), tmp.width());
2243 #if 0
2244 int temp = x1;
2245 x1 = y1;
2246 y1 = temp;
2247 temp = x2;
2248 x2 = y2;
2249 y2 = temp;
2250 #endif
2253 painter->setRenderHint(QPainter::Antialiasing, true);
2254 painter->translate(0.5, 0.5);
2256 QColor tabFrameColor = d->tabFrameColor(option->palette);
2258 QLinearGradient fillGradient(rect.topLeft(), rect.bottomLeft());
2259 QLinearGradient outlineGradient(rect.topLeft(), rect.bottomLeft());
2260 QPen outlinePen = outline.lighter(110);
2261 if (selected) {
2262 fillGradient.setColorAt(0, tabFrameColor.lighter(104));
2263 // QColor highlight = option->palette.highlight().color();
2264 // if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange) {
2265 // fillGradient.setColorAt(0, highlight.lighter(130));
2266 // outlineGradient.setColorAt(0, highlight.darker(130));
2267 // fillGradient.setColorAt(0.14, highlight);
2268 // outlineGradient.setColorAt(0.14, highlight.darker(130));
2269 // fillGradient.setColorAt(0.1401, tabFrameColor);
2270 // outlineGradient.setColorAt(0.1401, highlight.darker(130));
2271 // }
2272 fillGradient.setColorAt(1, tabFrameColor);
2273 outlineGradient.setColorAt(1, outline);
2274 outlinePen = QPen(outlineGradient, 1);
2275 } else {
2276 fillGradient.setColorAt(0, tabFrameColor.darker(108));
2277 fillGradient.setColorAt(0.85, tabFrameColor.darker(108));
2278 fillGradient.setColorAt(1, tabFrameColor.darker(116));
2281 QRect drawRect = rect.adjusted(0, selected ? 0 : 2, 0, 3);
2282 painter->setPen(outlinePen);
2283 painter->save();
2284 painter->setClipRect(rect.adjusted(-1, -1, 1, selected ? -2 : -3));
2285 painter->setBrush(Qt::NoBrush);
2286 painter->drawRoundedRect(drawRect.adjusted(0, 0, -1, -1), 2.5, 2.5);
2288 painter->setBrush(fillGradient);
2289 painter->setPen(QPen(QBrush(fillGradient), 1));
2290 drawRect.adjust(1, 1, -2, -1);
2291 painter->drawRoundedRect(drawRect, 1.8, 1.8);
2293 painter->setBrush(Qt::NoBrush);
2294 painter->setPen(d->innerContrastLine());
2295 painter->drawRoundedRect(drawRect, 1.8, 1.8);
2297 painter->restore();
2299 if (selected) {
2300 painter->fillRect(rect.left() + 1, rect.bottom() - 1, rect.width() - 2, rect.bottom() - 1, tabFrameColor);
2301 painter->fillRect(QRect(rect.bottomRight() + QPoint(-2, -1), QSize(1, 1)), d->innerContrastLine());
2302 painter->fillRect(QRect(rect.bottomLeft() + QPoint(0, -1), QSize(1, 1)), d->innerContrastLine());
2303 painter->fillRect(QRect(rect.bottomRight() + QPoint(-1, -1), QSize(1, 1)), d->innerContrastLine());
2306 painter->restore();
2307 break;
2308 default:
2309 QCommonStyle::drawControl(element,option,painter,widget);
2310 break;
2315 \reimp
2317 QPalette CarlaStyle::standardPalette () const
2319 QPalette palette = QCommonStyle::standardPalette();
2320 palette.setBrush(QPalette::Active, QPalette::Highlight, QColor(48, 140, 198));
2321 palette.setBrush(QPalette::Inactive, QPalette::Highlight, QColor(145, 141, 126));
2322 palette.setBrush(QPalette::Disabled, QPalette::Highlight, QColor(145, 141, 126));
2324 QColor backGround(239, 235, 231);
2326 QColor light = backGround.lighter(150);
2327 QColor base = Qt::white;
2328 QColor dark = QColor(170, 156, 143).darker(110);
2329 dark = backGround.darker(150);
2330 QColor darkDisabled = QColor(209, 200, 191).darker(110);
2332 //### Find the correct disabled text color
2333 palette.setBrush(QPalette::Disabled, QPalette::Text, QColor(190, 190, 190));
2335 palette.setBrush(QPalette::Window, backGround);
2336 palette.setBrush(QPalette::Mid, backGround.darker(130));
2337 palette.setBrush(QPalette::Light, light);
2339 palette.setBrush(QPalette::Active, QPalette::Base, base);
2340 palette.setBrush(QPalette::Inactive, QPalette::Base, base);
2341 palette.setBrush(QPalette::Disabled, QPalette::Base, backGround);
2343 palette.setBrush(QPalette::Midlight, palette.mid().color().lighter(110));
2345 palette.setBrush(QPalette::All, QPalette::Dark, dark);
2346 palette.setBrush(QPalette::Disabled, QPalette::Dark, darkDisabled);
2348 QColor button = backGround;
2350 palette.setBrush(QPalette::Button, button);
2352 QColor shadow = dark.darker(135);
2353 palette.setBrush(QPalette::Shadow, shadow);
2354 palette.setBrush(QPalette::Disabled, QPalette::Shadow, shadow.lighter(150));
2355 palette.setBrush(QPalette::HighlightedText, QColor(QRgb(0xffffffff)));
2357 return palette;
2361 \reimp
2363 void CarlaStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
2364 QPainter *painter, const QWidget *widget) const
2366 QColor buttonColor = d->buttonColor(option->palette);
2367 QColor gradientStartColor = buttonColor.lighter(118);
2368 QColor gradientStopColor = buttonColor;
2369 QColor outline = d->outline(option->palette);
2371 QColor alphaCornerColor;
2372 if (widget) {
2373 // ### backgroundrole/foregroundrole should be part of the style option
2374 alphaCornerColor = mergedColors(option->palette.color(widget->backgroundRole()), outline);
2375 } else {
2376 alphaCornerColor = mergedColors(qt_palette_bg_color(option->palette), outline);
2379 switch (control) {
2380 case CC_GroupBox:
2381 painter->save();
2382 if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
2383 // Draw frame
2384 QRect textRect = proxy()->subControlRect(CC_GroupBox, option, SC_GroupBoxLabel, widget);
2385 QRect checkBoxRect = proxy()->subControlRect(CC_GroupBox, option, SC_GroupBoxCheckBox, widget);
2387 if (groupBox->subControls & QStyle::SC_GroupBoxFrame) {
2388 QStyleOptionFrameV3 frame;
2389 frame.QStyleOption::operator=(*groupBox);
2390 frame.features = groupBox->features;
2391 frame.lineWidth = groupBox->lineWidth;
2392 frame.midLineWidth = groupBox->midLineWidth;
2393 frame.rect = proxy()->subControlRect(CC_GroupBox, option, SC_GroupBoxFrame, widget);
2394 proxy()->drawPrimitive(PE_FrameGroupBox, &frame, painter, widget);
2397 // Draw title
2398 if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
2399 // groupBox->textColor gets the incorrect palette here
2400 painter->setPen(QPen(option->palette.windowText(), 1));
2401 int alignment = int(groupBox->textAlignment);
2402 if (!proxy()->styleHint(QStyle::SH_UnderlineShortcut, option, widget))
2403 alignment |= Qt::TextHideMnemonic;
2405 proxy()->drawItemText(painter, textRect, Qt::TextShowMnemonic | Qt::AlignLeft | alignment,
2406 groupBox->palette, groupBox->state & State_Enabled, groupBox->text, QPalette::NoRole);
2408 if (groupBox->state & State_HasFocus) {
2409 QStyleOptionFocusRect fropt;
2410 fropt.QStyleOption::operator=(*groupBox);
2411 fropt.rect = textRect.adjusted(-2, -1, 2, 1);
2412 proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
2416 // Draw checkbox
2417 if (groupBox->subControls & SC_GroupBoxCheckBox) {
2418 QStyleOptionButton box;
2419 box.QStyleOption::operator=(*groupBox);
2420 box.rect = checkBoxRect;
2421 proxy()->drawPrimitive(PE_IndicatorCheckBox, &box, painter, widget);
2424 painter->restore();
2425 break;
2426 case CC_SpinBox:
2427 if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
2428 QPixmap cache;
2429 QString pixmapName = uniqueName(QLatin1String("spinbox"), spinBox, spinBox->rect.size());
2430 if (!QPixmapCache::find(pixmapName, PIXMAPCACHE_VAR_PREFIX cache)) {
2432 cache = styleCachePixmap(spinBox->rect.size());
2433 cache.fill(Qt::transparent);
2435 QRect pixmapRect(0, 0, spinBox->rect.width(), spinBox->rect.height());
2436 QRect rect = pixmapRect;
2437 QRect r = rect;
2438 QPainter cachePainter(&cache);
2439 QColor arrowColor = qt_palette_fg_color(spinBox->palette);
2440 arrowColor.setAlpha(220);
2442 const bool isEnabled = (spinBox->state & State_Enabled);
2443 const bool hover = isEnabled && (spinBox->state & State_MouseOver);
2444 const bool sunken = (spinBox->state & State_Sunken);
2445 const bool upIsActive = (spinBox->activeSubControls == SC_SpinBoxUp);
2446 const bool downIsActive = (spinBox->activeSubControls == SC_SpinBoxDown);
2447 const bool hasFocus = (option->state & State_HasFocus);
2449 QStyleOptionSpinBox spinBoxCopy = *spinBox;
2450 spinBoxCopy.rect = pixmapRect;
2451 QRect upRect = proxy()->subControlRect(CC_SpinBox, &spinBoxCopy, SC_SpinBoxUp, widget);
2452 QRect downRect = proxy()->subControlRect(CC_SpinBox, &spinBoxCopy, SC_SpinBoxDown, widget);
2454 const bool oddHeight = (1+upRect.bottom() != downRect.top());
2456 if (spinBox->frame) {
2457 // Button group outer bounds
2458 const int bty = upRect.top();
2459 const int bby = 1+downRect.bottom() - 1;
2460 const int brx = 1+upRect.right() - 1;
2462 cachePainter.save();
2463 cachePainter.setRenderHint(QPainter::Antialiasing, true);
2464 cachePainter.translate(0.5, 0.5);
2466 // Fill background
2467 const QBrush & brush = option->palette.base();
2468 cachePainter.setPen(brush.color());
2469 cachePainter.setBrush(brush);
2470 cachePainter.drawRoundedRect(r.adjusted(1, 1, -2, -2), 1.8, 1.8);
2472 // Draw inner shadow
2473 cachePainter.setPen(d->topShadow());
2474 cachePainter.drawLine(QPoint(r.left() + 2, r.top() + 1), QPoint(1+r.right() - 2, r.top() + 1));
2476 // Draw button gradient
2477 QColor buttonColor = d->buttonColor(option->palette);
2478 QRectF updownRect(upRect.topLeft(), downRect.bottomRight() + QPoint(1,1));
2479 updownRect.adjust(-0.5, -0.5, 0.5-1, 0.5-1);
2480 QLinearGradient gradient = qt_fusion_gradient(updownRect.toAlignedRect(), (isEnabled && option->state & State_MouseOver ) ? buttonColor : buttonColor.darker(104));
2482 // Draw button gradient
2483 cachePainter.setPen(QPen(gradient, 1));
2484 cachePainter.setBrush(gradient);
2486 cachePainter.save();
2487 cachePainter.setClipRect(updownRect);
2488 cachePainter.drawRoundedRect(QRect(0, bty, brx, bby-bty), 1.8, 1.8);
2489 cachePainter.setPen(QPen(d->innerContrastLine()));
2490 cachePainter.setBrush(Qt::NoBrush);
2491 cachePainter.drawRoundedRect(QRect(0, bty, brx, bby-bty), 1.8, 1.8);
2492 cachePainter.drawLine(upRect.left(), bty + 1, upRect.left(), bby - 1);
2493 if (hover) {
2494 const int y = oddHeight ? (downRect.top() - 1) : (upIsActive ? (1+upRect.bottom() - 1) : downRect.top());
2495 cachePainter.setOpacity(0.4);
2496 cachePainter.drawLine(downRect.left() + 1, y, brx - 1, y);
2497 cachePainter.setOpacity(1.0);
2499 cachePainter.restore();
2500 cachePainter.setPen(Qt::NoPen);
2502 // Buttons mouse over background
2503 if ((spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled) && upIsActive) {
2504 QPointF clipTLeft(0, upRect.top());
2505 QPointF clipBRight(1+downRect.right() - 1, 1+downRect.bottom() - 1);
2506 QRectF clipRect(clipTLeft, clipBRight);
2508 cachePainter.save();
2510 clipRect.adjust(-0.5,-0.5, 0.5, 0.5);
2511 QPainterPath clipPath;
2512 clipPath.addRoundedRect(clipRect, 2.0, 2.0);
2513 cachePainter.setClipPath(clipPath);
2515 const int cy_fix = oddHeight ? 0 : -1;
2516 if (sunken)
2517 cachePainter.fillRect(QRectF(upRect).adjusted(-0.5, -0.5, 0.5-1, 0.5+cy_fix), gradientStopColor.darker(110));
2518 else if (hover)
2519 cachePainter.fillRect(QRectF(upRect).adjusted(-0.5, -0.5, 0.5-1, 0.5+cy_fix), d->innerContrastLine());
2521 cachePainter.restore();
2524 if ((spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled) && downIsActive) {
2525 QPointF clipTLeft(0, upRect.top());
2526 QPointF clipBRight(1+downRect.right() - 1, 1+downRect.bottom() - 1);
2527 QRectF clipRect(clipTLeft, clipBRight);
2529 cachePainter.save();
2531 clipRect.adjust(-0.5,-0.5, 0.5, 0.5);
2532 QPainterPath clipPath;
2533 clipPath.addRoundedRect(clipRect, 2.0, 2.0);
2534 cachePainter.setClipPath(clipPath);
2536 const int cy_fix = oddHeight ? 0 : 1;
2537 if (sunken)
2538 cachePainter.fillRect(QRectF(downRect).adjusted(-0.5, -0.5-1+cy_fix, 0.5-1, 0.5-1-cy_fix), gradientStopColor.darker(110));
2539 else if (hover)
2540 cachePainter.fillRect(QRectF(downRect).adjusted(-0.5, -0.5-1+cy_fix, 0.5-1, 0.5-1-cy_fix), d->innerContrastLine());
2542 cachePainter.restore();
2545 // Common highlight border
2546 QColor highlightOutline = d->highlightedOutline(option->palette);
2547 cachePainter.setPen(hasFocus ? highlightOutline : highlightOutline.darker(160));
2548 cachePainter.setBrush(Qt::NoBrush);
2549 cachePainter.drawRoundedRect(r.adjusted(0, 0, -1, -1), 2.5, 2.5);
2550 if (hasFocus) {
2551 QColor softHighlight = option->palette.highlight().color();
2552 softHighlight.setAlpha(40);
2553 cachePainter.setPen(softHighlight);
2554 cachePainter.drawRoundedRect(r.adjusted(1, 1, -2, -2), 1.8, 1.8);
2556 cachePainter.restore();
2559 // outline the up/down buttons
2560 cachePainter.setPen(outline);
2561 if (spinBox->direction == Qt::RightToLeft) {
2562 cachePainter.drawLine(1+upRect.right() + 1, upRect.top(), 1+upRect.right() + 1, 1+downRect.bottom() - 1);
2563 } else {
2564 cachePainter.drawLine(upRect.left() - 1, upRect.top(), upRect.left() - 1, 1+downRect.bottom() - 1);
2567 if (upIsActive && sunken) {
2568 cachePainter.setPen(gradientStopColor.darker(130));
2569 const int left = upRect.left();
2570 const int right = 1+upRect.right() - 1;
2571 const int top = upRect.top();
2572 const int bottom = oddHeight ? (1+upRect.bottom()) : (1+upRect.bottom() - 1);
2573 const QPoint points[] = {QPoint(right,bottom), QPoint(left,bottom), QPoint(left,top), QPoint(right-1,top)};
2574 cachePainter.drawPolyline(points, 4);
2577 if (downIsActive && sunken) {
2578 cachePainter.setPen(gradientStopColor.darker(130));
2579 const int left = downRect.left();
2580 const int right = 1+downRect.right() - 1;
2581 const int top = oddHeight ? (downRect.top() - 1) : downRect.top();
2582 const int bottom = 1+downRect.bottom() - 1;
2583 const QPoint points[] = {QPoint(left,bottom), QPoint(left,top), QPoint(right,top)};
2584 cachePainter.drawPolyline(points, 3);
2587 QColor disabledColor = mergedColors(arrowColor, option->palette.button().color());
2588 if (spinBox->buttonSymbols == QAbstractSpinBox::PlusMinus) {
2589 // plus/minus
2590 int centerX, centerY;
2592 centerX = upRect.center().x();
2593 centerY = upRect.center().y();
2594 cachePainter.setPen((spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled) ? arrowColor : disabledColor);
2595 cachePainter.drawLine(centerX - 1, centerY, centerX + 3, centerY);
2596 cachePainter.drawLine(centerX + 1, centerY - 2, centerX + 1, centerY + 2);
2598 centerX = downRect.center().x();
2599 centerY = downRect.center().y();
2600 cachePainter.setPen((spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled) ? arrowColor : disabledColor);
2601 cachePainter.drawLine(centerX - 1, centerY, centerX + 3, centerY);
2603 } else if (spinBox->buttonSymbols == QAbstractSpinBox::UpDownArrows){
2604 // arrows
2605 painter->setRenderHint(QPainter::SmoothPixmapTransform);
2607 QPixmap upArrow = colorizedImage(QLatin1String(":/bitmaps/style/arrow.png"),
2608 (spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled) ? arrowColor : disabledColor);
2610 QPixmap downArrow = colorizedImage(QLatin1String(":/bitmaps/style/arrow.png"),
2611 (spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled) ? arrowColor : disabledColor, 180);
2613 int y1, y2;
2614 const int imgW = (upArrow.width() + downArrow.width()) / 2;
2615 const int imgH = (upArrow.height() + downArrow.height()) / 2;
2616 const float f = 1.0 / ceil(imgW / upRect.width() * 2);
2617 const int w = imgW * f;
2618 const int h = imgH * f;
2620 const int x = upRect.center().x() - w / 2;
2621 y1 = upRect.center().y();
2622 y2 = downRect.center().y();
2623 const int dy1 = 1+upRect.bottom() - y1;
2624 const int dy2 = y2 - downRect.top();
2625 const int dy = dy1 < dy2 ? dy1 : dy2;
2626 y1 = (1+upRect.bottom() - dy - 1) - ceil(h / 4.0);
2627 y2 = (downRect.top() + dy + 1) - floor(h / 4.0 * 3);
2629 cachePainter.drawPixmap(QRectF(x, y1, w, h), upArrow, upArrow.rect());
2630 cachePainter.drawPixmap(QRectF(x, y2, w, h), downArrow, downArrow.rect());
2633 cachePainter.end();
2634 QPixmapCache::insert(pixmapName, cache);
2636 painter->drawPixmap(spinBox->rect.topLeft(), cache);
2638 break;
2639 case CC_TitleBar:
2640 painter->save();
2641 if (const QStyleOptionTitleBar *titleBar = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
2642 const int buttonMargin = 5;
2643 bool active = (titleBar->titleBarState & State_Active);
2644 QRect fullRect = titleBar->rect;
2645 QPalette palette = option->palette;
2646 QColor highlight = option->palette.highlight().color();
2648 QColor titleBarFrameBorder(active ? highlight.darker(180): outline.darker(110));
2649 QColor titleBarHighlight(active ? highlight.lighter(120): qt_palette_bg_color(palette).lighter(120));
2650 QColor textColor(active ? 0xffffff : 0xff000000);
2651 QColor textAlphaColor(active ? 0xffffff : 0xff000000 );
2654 // Fill title bar gradient
2655 QColor titlebarColor = QColor(active ? highlight: qt_palette_bg_color(palette));
2656 QLinearGradient gradient(option->rect.center().x(), option->rect.top(),
2657 option->rect.center().x(), option->rect.bottom());
2659 gradient.setColorAt(0, titlebarColor.lighter(114));
2660 gradient.setColorAt(0.5, titlebarColor.lighter(102));
2661 gradient.setColorAt(0.51, titlebarColor.darker(104));
2662 gradient.setColorAt(1, titlebarColor);
2663 painter->fillRect(option->rect.adjusted(1, 1, -1, 0), gradient);
2665 // Frame and rounded corners
2666 painter->setPen(titleBarFrameBorder);
2668 // top outline
2669 painter->drawLine(fullRect.left() + 5, fullRect.top(), fullRect.right() - 5, fullRect.top());
2670 painter->drawLine(fullRect.left(), fullRect.top() + 4, fullRect.left(), fullRect.bottom());
2671 const QPoint points[5] = {
2672 QPoint(fullRect.left() + 4, fullRect.top() + 1),
2673 QPoint(fullRect.left() + 3, fullRect.top() + 1),
2674 QPoint(fullRect.left() + 2, fullRect.top() + 2),
2675 QPoint(fullRect.left() + 1, fullRect.top() + 3),
2676 QPoint(fullRect.left() + 1, fullRect.top() + 4)
2678 painter->drawPoints(points, 5);
2680 painter->drawLine(fullRect.right(), fullRect.top() + 4, fullRect.right(), fullRect.bottom());
2681 const QPoint points2[5] = {
2682 QPoint(fullRect.right() - 3, fullRect.top() + 1),
2683 QPoint(fullRect.right() - 4, fullRect.top() + 1),
2684 QPoint(fullRect.right() - 2, fullRect.top() + 2),
2685 QPoint(fullRect.right() - 1, fullRect.top() + 3),
2686 QPoint(fullRect.right() - 1, fullRect.top() + 4)
2688 painter->drawPoints(points2, 5);
2690 // draw bottomline
2691 painter->drawLine(fullRect.right(), fullRect.bottom(), fullRect.left(), fullRect.bottom());
2693 // top highlight
2694 painter->setPen(titleBarHighlight);
2695 painter->drawLine(fullRect.left() + 6, fullRect.top() + 1, fullRect.right() - 6, fullRect.top() + 1);
2697 // draw title
2698 QRect textRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarLabel, widget);
2699 painter->setPen(active? (titleBar->palette.text().color().lighter(120)) :
2700 titleBar->palette.text().color() );
2701 // Note workspace also does elliding but it does not use the correct font
2702 QString title = painter->fontMetrics().elidedText(titleBar->text, Qt::ElideRight, textRect.width() - 14);
2703 painter->drawText(textRect.adjusted(1, 1, 1, 1), title, QTextOption(Qt::AlignHCenter | Qt::AlignVCenter));
2704 painter->setPen(Qt::white);
2705 if (active)
2706 painter->drawText(textRect, title, QTextOption(Qt::AlignHCenter | Qt::AlignVCenter));
2707 // min button
2708 if ((titleBar->subControls & SC_TitleBarMinButton) && (titleBar->titleBarFlags & Qt::WindowMinimizeButtonHint) &&
2709 !(titleBar->titleBarState& Qt::WindowMinimized)) {
2710 QRect minButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarMinButton, widget);
2711 if (minButtonRect.isValid()) {
2712 bool hover = (titleBar->activeSubControls & SC_TitleBarMinButton) && (titleBar->state & State_MouseOver);
2713 bool sunken = (titleBar->activeSubControls & SC_TitleBarMinButton) && (titleBar->state & State_Sunken);
2714 qt_fusion_draw_mdibutton(painter, titleBar, minButtonRect, hover, sunken);
2715 QRect minButtonIconRect = minButtonRect.adjusted(buttonMargin ,buttonMargin , -buttonMargin, -buttonMargin);
2716 painter->setPen(textColor);
2717 painter->drawLine(minButtonIconRect.center().x() - 2, minButtonIconRect.center().y() + 3,
2718 minButtonIconRect.center().x() + 3, minButtonIconRect.center().y() + 3);
2719 painter->drawLine(minButtonIconRect.center().x() - 2, minButtonIconRect.center().y() + 4,
2720 minButtonIconRect.center().x() + 3, minButtonIconRect.center().y() + 4);
2721 painter->setPen(textAlphaColor);
2722 painter->drawLine(minButtonIconRect.center().x() - 3, minButtonIconRect.center().y() + 3,
2723 minButtonIconRect.center().x() - 3, minButtonIconRect.center().y() + 4);
2724 painter->drawLine(minButtonIconRect.center().x() + 4, minButtonIconRect.center().y() + 3,
2725 minButtonIconRect.center().x() + 4, minButtonIconRect.center().y() + 4);
2728 // max button
2729 if ((titleBar->subControls & SC_TitleBarMaxButton) && (titleBar->titleBarFlags & Qt::WindowMaximizeButtonHint) &&
2730 !(titleBar->titleBarState & Qt::WindowMaximized)) {
2731 QRect maxButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarMaxButton, widget);
2732 if (maxButtonRect.isValid()) {
2733 bool hover = (titleBar->activeSubControls & SC_TitleBarMaxButton) && (titleBar->state & State_MouseOver);
2734 bool sunken = (titleBar->activeSubControls & SC_TitleBarMaxButton) && (titleBar->state & State_Sunken);
2735 qt_fusion_draw_mdibutton(painter, titleBar, maxButtonRect, hover, sunken);
2737 QRect maxButtonIconRect = maxButtonRect.adjusted(buttonMargin, buttonMargin, -buttonMargin, -buttonMargin);
2739 painter->setPen(textColor);
2740 painter->drawRect(maxButtonIconRect.adjusted(0, 0, -1, -1));
2741 painter->drawLine(maxButtonIconRect.left() + 1, maxButtonIconRect.top() + 1,
2742 maxButtonIconRect.right() - 1, maxButtonIconRect.top() + 1);
2743 painter->setPen(textAlphaColor);
2744 const QPoint points[4] = {
2745 maxButtonIconRect.topLeft(),
2746 maxButtonIconRect.topRight(),
2747 maxButtonIconRect.bottomLeft(),
2748 maxButtonIconRect.bottomRight()
2750 painter->drawPoints(points, 4);
2754 // close button
2755 if ((titleBar->subControls & SC_TitleBarCloseButton) && (titleBar->titleBarFlags & Qt::WindowSystemMenuHint)) {
2756 QRect closeButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarCloseButton, widget);
2757 if (closeButtonRect.isValid()) {
2758 bool hover = (titleBar->activeSubControls & SC_TitleBarCloseButton) && (titleBar->state & State_MouseOver);
2759 bool sunken = (titleBar->activeSubControls & SC_TitleBarCloseButton) && (titleBar->state & State_Sunken);
2760 qt_fusion_draw_mdibutton(painter, titleBar, closeButtonRect, hover, sunken);
2761 QRect closeIconRect = closeButtonRect.adjusted(buttonMargin, buttonMargin, -buttonMargin, -buttonMargin);
2762 painter->setPen(textAlphaColor);
2763 const QLine lines[4] = {
2764 QLine(closeIconRect.left() + 1, closeIconRect.top(),
2765 closeIconRect.right(), closeIconRect.bottom() - 1),
2766 QLine(closeIconRect.left(), closeIconRect.top() + 1,
2767 closeIconRect.right() - 1, closeIconRect.bottom()),
2768 QLine(closeIconRect.right() - 1, closeIconRect.top(),
2769 closeIconRect.left(), closeIconRect.bottom() - 1),
2770 QLine(closeIconRect.right(), closeIconRect.top() + 1,
2771 closeIconRect.left() + 1, closeIconRect.bottom())
2773 painter->drawLines(lines, 4);
2774 const QPoint points[4] = {
2775 closeIconRect.topLeft(),
2776 closeIconRect.topRight(),
2777 closeIconRect.bottomLeft(),
2778 closeIconRect.bottomRight()
2780 painter->drawPoints(points, 4);
2782 painter->setPen(textColor);
2783 painter->drawLine(closeIconRect.left() + 1, closeIconRect.top() + 1,
2784 closeIconRect.right() - 1, closeIconRect.bottom() - 1);
2785 painter->drawLine(closeIconRect.left() + 1, closeIconRect.bottom() - 1,
2786 closeIconRect.right() - 1, closeIconRect.top() + 1);
2790 // normalize button
2791 if ((titleBar->subControls & SC_TitleBarNormalButton) &&
2792 (((titleBar->titleBarFlags & Qt::WindowMinimizeButtonHint) &&
2793 (titleBar->titleBarState & Qt::WindowMinimized)) ||
2794 ((titleBar->titleBarFlags & Qt::WindowMaximizeButtonHint) &&
2795 (titleBar->titleBarState & Qt::WindowMaximized)))) {
2796 QRect normalButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarNormalButton, widget);
2797 if (normalButtonRect.isValid()) {
2799 bool hover = (titleBar->activeSubControls & SC_TitleBarNormalButton) && (titleBar->state & State_MouseOver);
2800 bool sunken = (titleBar->activeSubControls & SC_TitleBarNormalButton) && (titleBar->state & State_Sunken);
2801 QRect normalButtonIconRect = normalButtonRect.adjusted(buttonMargin, buttonMargin, -buttonMargin, -buttonMargin);
2802 qt_fusion_draw_mdibutton(painter, titleBar, normalButtonRect, hover, sunken);
2804 QRect frontWindowRect = normalButtonIconRect.adjusted(0, 3, -3, 0);
2805 painter->setPen(textColor);
2806 painter->drawRect(frontWindowRect.adjusted(0, 0, -1, -1));
2807 painter->drawLine(frontWindowRect.left() + 1, frontWindowRect.top() + 1,
2808 frontWindowRect.right() - 1, frontWindowRect.top() + 1);
2809 painter->setPen(textAlphaColor);
2810 const QPoint points[4] = {
2811 frontWindowRect.topLeft(),
2812 frontWindowRect.topRight(),
2813 frontWindowRect.bottomLeft(),
2814 frontWindowRect.bottomRight()
2816 painter->drawPoints(points, 4);
2818 QRect backWindowRect = normalButtonIconRect.adjusted(3, 0, 0, -3);
2819 QRegion clipRegion = backWindowRect;
2820 clipRegion -= frontWindowRect;
2821 painter->save();
2822 painter->setClipRegion(clipRegion);
2823 painter->setPen(textColor);
2824 painter->drawRect(backWindowRect.adjusted(0, 0, -1, -1));
2825 painter->drawLine(backWindowRect.left() + 1, backWindowRect.top() + 1,
2826 backWindowRect.right() - 1, backWindowRect.top() + 1);
2827 painter->setPen(textAlphaColor);
2828 const QPoint points2[4] = {
2829 backWindowRect.topLeft(),
2830 backWindowRect.topRight(),
2831 backWindowRect.bottomLeft(),
2832 backWindowRect.bottomRight()
2834 painter->drawPoints(points2, 4);
2835 painter->restore();
2839 // context help button
2840 if (titleBar->subControls & SC_TitleBarContextHelpButton
2841 && (titleBar->titleBarFlags & Qt::WindowContextHelpButtonHint)) {
2842 QRect contextHelpButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarContextHelpButton, widget);
2843 if (contextHelpButtonRect.isValid()) {
2844 bool hover = (titleBar->activeSubControls & SC_TitleBarContextHelpButton) && (titleBar->state & State_MouseOver);
2845 bool sunken = (titleBar->activeSubControls & SC_TitleBarContextHelpButton) && (titleBar->state & State_Sunken);
2846 qt_fusion_draw_mdibutton(painter, titleBar, contextHelpButtonRect, hover, sunken);
2847 QImage image(qt_titlebar_context_help);
2848 QColor alpha = textColor;
2849 alpha.setAlpha(128);
2850 image.setColor(1, textColor.rgba());
2851 image.setColor(2, alpha.rgba());
2852 painter->setRenderHint(QPainter::SmoothPixmapTransform);
2853 painter->drawImage(contextHelpButtonRect.adjusted(4, 4, -4, -4), image);
2857 // shade button
2858 if (titleBar->subControls & SC_TitleBarShadeButton && (titleBar->titleBarFlags & Qt::WindowShadeButtonHint)) {
2859 QRect shadeButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarShadeButton, widget);
2860 if (shadeButtonRect.isValid()) {
2861 bool hover = (titleBar->activeSubControls & SC_TitleBarShadeButton) && (titleBar->state & State_MouseOver);
2862 bool sunken = (titleBar->activeSubControls & SC_TitleBarShadeButton) && (titleBar->state & State_Sunken);
2863 qt_fusion_draw_mdibutton(painter, titleBar, shadeButtonRect, hover, sunken);
2864 QPixmap arrow = colorizedImage(QLatin1String(":/bitmaps/style/arrow.png"), textColor);
2865 painter->drawPixmap(shadeButtonRect.adjusted(5, 7, -5, -7), arrow);
2869 // unshade button
2870 if (titleBar->subControls & SC_TitleBarUnshadeButton && (titleBar->titleBarFlags & Qt::WindowShadeButtonHint)) {
2871 QRect unshadeButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarUnshadeButton, widget);
2872 if (unshadeButtonRect.isValid()) {
2873 bool hover = (titleBar->activeSubControls & SC_TitleBarUnshadeButton) && (titleBar->state & State_MouseOver);
2874 bool sunken = (titleBar->activeSubControls & SC_TitleBarUnshadeButton) && (titleBar->state & State_Sunken);
2875 qt_fusion_draw_mdibutton(painter, titleBar, unshadeButtonRect, hover, sunken);
2876 QPixmap arrow = colorizedImage(QLatin1String(":/bitmaps/style/arrow.png"), textColor, 180);
2877 painter->drawPixmap(unshadeButtonRect.adjusted(5, 7, -5, -7), arrow);
2881 if ((titleBar->subControls & SC_TitleBarSysMenu) && (titleBar->titleBarFlags & Qt::WindowSystemMenuHint)) {
2882 QRect iconRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarSysMenu, widget);
2883 if (iconRect.isValid()) {
2884 if (!titleBar->icon.isNull()) {
2885 titleBar->icon.paint(painter, iconRect);
2886 } else {
2887 QStyleOption tool(0);
2888 tool.palette = titleBar->palette;
2889 QPixmap pm = standardIcon(SP_TitleBarMenuButton, &tool, widget).pixmap(16, 16);
2890 tool.rect = iconRect;
2891 painter->save();
2892 proxy()->drawItemPixmap(painter, iconRect, Qt::AlignCenter, pm);
2893 painter->restore();
2898 painter->restore();
2899 break;
2900 case CC_ScrollBar:
2901 painter->save();
2902 if (const QStyleOptionSlider *scrollBar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
2903 bool horizontal = scrollBar->orientation == Qt::Horizontal;
2904 bool sunken = scrollBar->state & State_Sunken;
2906 QRect scrollBarSubLine = proxy()->subControlRect(control, scrollBar, SC_ScrollBarSubLine, widget);
2907 QRect scrollBarAddLine = proxy()->subControlRect(control, scrollBar, SC_ScrollBarAddLine, widget);
2908 QRect scrollBarSlider = proxy()->subControlRect(control, scrollBar, SC_ScrollBarSlider, widget);
2909 QRect scrollBarGroove = proxy()->subControlRect(control, scrollBar, SC_ScrollBarGroove, widget);
2911 QRect rect = option->rect;
2912 QColor alphaOutline = outline;
2913 alphaOutline.setAlpha(180);
2915 QColor arrowColor = qt_palette_fg_color(option->palette);
2916 arrowColor.setAlpha(220);
2918 // Paint groove
2919 if (scrollBar->subControls & SC_ScrollBarGroove) {
2920 QLinearGradient gradient(rect.center().x(), rect.top(),
2921 rect.center().x(), rect.bottom());
2922 if (!horizontal)
2923 gradient = QLinearGradient(rect.left(), rect.center().y(),
2924 rect.right(), rect.center().y());
2925 gradient.setColorAt(0, buttonColor.darker(107));
2926 gradient.setColorAt(0.1, buttonColor.darker(105));
2927 gradient.setColorAt(0.9, buttonColor.darker(105));
2928 gradient.setColorAt(1, buttonColor.darker(107));
2930 painter->fillRect(option->rect, gradient);
2931 painter->setPen(Qt::NoPen);
2932 painter->setPen(alphaOutline);
2933 if (horizontal)
2934 painter->drawLine(rect.topLeft(), rect.topRight());
2935 else
2936 painter->drawLine(rect.topLeft(), rect.bottomLeft());
2938 QColor subtleEdge = alphaOutline;
2939 subtleEdge.setAlpha(40);
2940 painter->setPen(subtleEdge);
2941 painter->setBrush(Qt::NoBrush);
2942 painter->save();
2943 painter->setClipRect(scrollBarGroove.adjusted(1, 0, -1, -3));
2944 painter->drawRect(scrollBarGroove.adjusted(1, 0, -1, -1));
2945 painter->restore();
2948 QRect pixmapRect = scrollBarSlider;
2949 QLinearGradient gradient(pixmapRect.center().x(), pixmapRect.top(),
2950 pixmapRect.center().x(), pixmapRect.bottom());
2951 if (!horizontal)
2952 gradient = QLinearGradient(pixmapRect.left(), pixmapRect.center().y(),
2953 pixmapRect.right(), pixmapRect.center().y());
2955 QLinearGradient highlightedGradient = gradient;
2957 QColor midColor2 = mergedColors(gradientStartColor, gradientStopColor, 40);
2958 gradient.setColorAt(0, d->buttonColor(option->palette).lighter(108));
2959 gradient.setColorAt(1, d->buttonColor(option->palette));
2961 highlightedGradient.setColorAt(0, gradientStartColor.darker(102));
2962 highlightedGradient.setColorAt(1, gradientStopColor.lighter(102));
2964 // Paint slider
2965 if (scrollBar->subControls & SC_ScrollBarSlider) {
2966 QRect pixmapRect = scrollBarSlider;
2967 painter->setPen(QPen(alphaOutline, 0));
2968 if (option->state & State_Sunken && scrollBar->activeSubControls & SC_ScrollBarSlider)
2969 painter->setBrush(midColor2);
2970 else if (option->state & State_MouseOver && scrollBar->activeSubControls & SC_ScrollBarSlider)
2971 painter->setBrush(highlightedGradient);
2972 else
2973 painter->setBrush(gradient);
2975 painter->drawRect(pixmapRect.adjusted(horizontal ? -1 : 0, horizontal ? 0 : -1, horizontal ? 0 : 1, horizontal ? 1 : 0));
2977 painter->setPen(d->innerContrastLine());
2978 painter->drawRect(scrollBarSlider.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0, -1, -1));
2980 // Outer shadow
2981 // painter->setPen(subtleEdge);
2982 // if (horizontal) {
2983 //// painter->drawLine(scrollBarSlider.topLeft() + QPoint(-2, 0), scrollBarSlider.bottomLeft() + QPoint(2, 0));
2984 //// painter->drawLine(scrollBarSlider.topRight() + QPoint(-2, 0), scrollBarSlider.bottomRight() + QPoint(2, 0));
2985 // } else {
2986 //// painter->drawLine(pixmapRect.topLeft() + QPoint(0, -2), pixmapRect.bottomLeft() + QPoint(0, -2));
2987 //// painter->drawLine(pixmapRect.topRight() + QPoint(0, 2), pixmapRect.bottomRight() + QPoint(0, 2));
2988 // }
2991 // The SubLine (up/left) buttons
2992 if (scrollBar->subControls & SC_ScrollBarSubLine) {
2993 if ((scrollBar->activeSubControls & SC_ScrollBarSubLine) && sunken)
2994 painter->setBrush(gradientStopColor);
2995 else if ((scrollBar->activeSubControls & SC_ScrollBarSubLine))
2996 painter->setBrush(highlightedGradient);
2997 else
2998 painter->setBrush(gradient);
3000 painter->setPen(Qt::NoPen);
3001 painter->drawRect(scrollBarSubLine.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0, 0, 0));
3002 painter->setPen(QPen(alphaOutline, 1));
3003 if (option->state & State_Horizontal) {
3004 if (option->direction == Qt::RightToLeft) {
3005 pixmapRect.setLeft(scrollBarSubLine.left());
3006 painter->drawLine(pixmapRect.topLeft(), pixmapRect.bottomLeft());
3007 } else {
3008 pixmapRect.setRight(scrollBarSubLine.right());
3009 painter->drawLine(pixmapRect.topRight(), pixmapRect.bottomRight());
3011 } else {
3012 pixmapRect.setBottom(scrollBarSubLine.bottom());
3013 painter->drawLine(pixmapRect.bottomLeft(), pixmapRect.bottomRight());
3016 painter->setBrush(Qt::NoBrush);
3017 painter->setPen(d->innerContrastLine());
3018 painter->drawRect(scrollBarSubLine.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0 , horizontal ? -2 : -1, horizontal ? -1 : -2));
3020 // Arrows
3021 int rotation = 0;
3022 if (option->state & State_Horizontal)
3023 rotation = option->direction == Qt::LeftToRight ? -90 : 90;
3024 QRect upRect = scrollBarSubLine.translated(horizontal ? -2 : -1, 0);
3025 QPixmap arrowPixmap = colorizedImage(QLatin1String(":/bitmaps/style/arrow.png"), arrowColor, rotation);
3026 painter->drawPixmap(QRect(upRect.center().x() - arrowPixmap.width() / 4 + 2,
3027 upRect.center().y() - arrowPixmap.height() / 4 + 1,
3028 arrowPixmap.width()/2, arrowPixmap.height()/2), arrowPixmap);
3031 // The AddLine (down/right) button
3032 if (scrollBar->subControls & SC_ScrollBarAddLine) {
3033 if ((scrollBar->activeSubControls & SC_ScrollBarAddLine) && sunken)
3034 painter->setBrush(gradientStopColor);
3035 else if ((scrollBar->activeSubControls & SC_ScrollBarAddLine))
3036 painter->setBrush(midColor2);
3037 else
3038 painter->setBrush(gradient);
3040 painter->setPen(Qt::NoPen);
3041 painter->drawRect(scrollBarAddLine.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0, 0, 0));
3042 painter->setPen(QPen(alphaOutline, 1));
3043 if (option->state & State_Horizontal) {
3044 if (option->direction == Qt::LeftToRight) {
3045 pixmapRect.setLeft(scrollBarAddLine.left());
3046 painter->drawLine(pixmapRect.topLeft(), pixmapRect.bottomLeft());
3047 } else {
3048 pixmapRect.setRight(scrollBarAddLine.right());
3049 painter->drawLine(pixmapRect.topRight(), pixmapRect.bottomRight());
3051 } else {
3052 pixmapRect.setTop(scrollBarAddLine.top());
3053 painter->drawLine(pixmapRect.topLeft(), pixmapRect.topRight());
3056 painter->setPen(d->innerContrastLine());
3057 painter->setBrush(Qt::NoBrush);
3058 painter->drawRect(scrollBarAddLine.adjusted(1, 1, -1, -1));
3060 int rotation = 180;
3061 if (option->state & State_Horizontal)
3062 rotation = option->direction == Qt::LeftToRight ? 90 : -90;
3063 QRect downRect = scrollBarAddLine.translated(-1, 1);
3064 QPixmap arrowPixmap = colorizedImage(QLatin1String(":/bitmaps/style/arrow.png"), arrowColor, rotation);
3065 painter->drawPixmap(QRect(downRect.center().x() - arrowPixmap.width() / 4 + 2,
3066 downRect.center().y() - arrowPixmap.height() / 4,
3067 arrowPixmap.width()/2, arrowPixmap.height()/2), arrowPixmap);
3071 painter->restore();
3072 break;;
3073 case CC_ComboBox:
3074 painter->save();
3075 if (const QStyleOptionComboBox *comboBox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
3076 bool hasFocus = option->state & State_HasFocus && option->state & State_KeyboardFocusChange;
3077 bool sunken = comboBox->state & State_On; // play dead, if combobox has no items
3078 bool isEnabled = (comboBox->state & State_Enabled);
3079 QPixmap cache;
3080 QString pixmapName = uniqueName(QLatin1String("combobox"), option, comboBox->rect.size());
3081 if (sunken)
3082 pixmapName += QLatin1String("-sunken");
3083 if (comboBox->editable)
3084 pixmapName += QLatin1String("-editable");
3085 if (isEnabled)
3086 pixmapName += QLatin1String("-enabled");
3088 if (!QPixmapCache::find(pixmapName, PIXMAPCACHE_VAR_PREFIX cache)) {
3089 cache = styleCachePixmap(comboBox->rect.size());
3090 cache.fill(Qt::transparent);
3091 QPainter cachePainter(&cache);
3092 QRect pixmapRect(0, 0, comboBox->rect.width(), comboBox->rect.height());
3093 QStyleOptionComboBox comboBoxCopy = *comboBox;
3094 comboBoxCopy.rect = pixmapRect;
3096 QRect rect = pixmapRect;
3097 QRect downArrowRect = proxy()->subControlRect(CC_ComboBox, &comboBoxCopy,
3098 SC_ComboBoxArrow, widget);
3099 // Draw a line edit
3100 if (comboBox->editable) {
3101 QStyleOptionFrame buttonOption;
3102 buttonOption.QStyleOption::operator=(*comboBox);
3103 buttonOption.rect = rect;
3104 buttonOption.state = (comboBox->state & (State_Enabled | State_MouseOver | State_HasFocus))
3105 | State_KeyboardFocusChange; // Always show hig
3107 if (sunken) {
3108 buttonOption.state |= State_Sunken;
3109 buttonOption.state &= ~State_MouseOver;
3112 proxy()->drawPrimitive(PE_FrameLineEdit, &buttonOption, &cachePainter, widget);
3114 // Draw button clipped
3115 cachePainter.save();
3116 cachePainter.setClipRect(downArrowRect.adjusted(0, 0, 1, 0));
3117 buttonOption.rect.setLeft(comboBox->direction == Qt::LeftToRight ?
3118 downArrowRect.left() - 6: downArrowRect.right() + 6);
3119 proxy()->drawPrimitive(PE_PanelButtonCommand, &buttonOption, &cachePainter, widget);
3120 cachePainter.restore();
3121 cachePainter.setPen( QPen(hasFocus ? option->palette.highlight() : outline.lighter(110), 0));
3123 if (!sunken) {
3124 int borderSize = 1;
3125 if (comboBox->direction == Qt::RightToLeft) {
3126 cachePainter.drawLine(QPoint(downArrowRect.right() - 1, downArrowRect.top() + borderSize ),
3127 QPoint(downArrowRect.right() - 1, downArrowRect.bottom() - borderSize));
3128 } else {
3129 cachePainter.drawLine(QPoint(downArrowRect.left() , downArrowRect.top() + borderSize),
3130 QPoint(downArrowRect.left() , downArrowRect.bottom() - borderSize));
3132 } else {
3133 if (comboBox->direction == Qt::RightToLeft) {
3134 cachePainter.drawLine(QPoint(downArrowRect.right(), downArrowRect.top() + 2),
3135 QPoint(downArrowRect.right(), downArrowRect.bottom() - 2));
3137 } else {
3138 cachePainter.drawLine(QPoint(downArrowRect.left(), downArrowRect.top() + 2),
3139 QPoint(downArrowRect.left(), downArrowRect.bottom() - 2));
3142 } else {
3143 QStyleOptionButton buttonOption;
3144 buttonOption.QStyleOption::operator=(*comboBox);
3145 buttonOption.rect = rect;
3146 buttonOption.state = comboBox->state & (State_Enabled | State_MouseOver | State_HasFocus | State_KeyboardFocusChange);
3147 if (sunken) {
3148 buttonOption.state |= State_Sunken;
3149 buttonOption.state &= ~State_MouseOver;
3151 proxy()->drawPrimitive(PE_PanelButtonCommand, &buttonOption, &cachePainter, widget);
3153 if (comboBox->subControls & SC_ComboBoxArrow) {
3154 // Draw the up/down arrow
3155 QColor arrowColor = option->palette.buttonText().color();
3156 arrowColor.setAlpha(220);
3157 QPixmap downArrow = colorizedImage(QLatin1String(":/bitmaps/style/arrow.png"), arrowColor, 180);
3158 cachePainter.drawPixmap(QRect(downArrowRect.center().x() - downArrow.width() / 4 + 1,
3159 downArrowRect.center().y() - downArrow.height() / 4 + 1,
3160 downArrow.width()/2, downArrow.height()/2), downArrow);
3162 cachePainter.end();
3163 QPixmapCache::insert(pixmapName, cache);
3165 painter->drawPixmap(comboBox->rect.topLeft(), cache);
3167 painter->restore();
3168 break;
3169 case CC_Slider:
3170 if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
3171 QRect groove = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget);
3172 QRect handle = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget);
3174 bool horizontal = slider->orientation == Qt::Horizontal;
3175 bool ticksAbove = slider->tickPosition & QSlider::TicksAbove;
3176 bool ticksBelow = slider->tickPosition & QSlider::TicksBelow;
3177 QColor activeHighlight = d->highlight(option->palette);
3178 QPixmap cache;
3179 QBrush oldBrush = painter->brush();
3180 QPen oldPen = painter->pen();
3181 QColor shadowAlpha(Qt::black);
3182 shadowAlpha.setAlpha(10);
3183 if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange)
3184 outline = d->highlightedOutline(option->palette);
3187 if ((option->subControls & SC_SliderGroove) && groove.isValid()) {
3188 QColor grooveColor;
3189 grooveColor.setHsv(buttonColor.hue(),
3190 qMin(255, (int)(buttonColor.saturation())),
3191 qMin(255, (int)(buttonColor.value()*0.9)));
3192 QString groovePixmapName = uniqueName(QLatin1String("slider_groove"), option, groove.size());
3193 QRect pixmapRect(0, 0, groove.width(), groove.height());
3195 // draw background groove
3196 if (!QPixmapCache::find(groovePixmapName, PIXMAPCACHE_VAR_PREFIX cache)) {
3197 cache = styleCachePixmap(pixmapRect.size());
3198 cache.fill(Qt::transparent);
3199 QPainter groovePainter(&cache);
3200 groovePainter.setRenderHint(QPainter::Antialiasing, true);
3201 groovePainter.translate(0.5, 0.5);
3202 QLinearGradient gradient;
3203 if (horizontal) {
3204 gradient.setStart(pixmapRect.center().x(), pixmapRect.top());
3205 gradient.setFinalStop(pixmapRect.center().x(), pixmapRect.bottom());
3207 else {
3208 gradient.setStart(pixmapRect.left(), pixmapRect.center().y());
3209 gradient.setFinalStop(pixmapRect.right(), pixmapRect.center().y());
3211 groovePainter.setPen(QPen(outline, 0));
3212 gradient.setColorAt(0, grooveColor.darker(110));
3213 gradient.setColorAt(1, grooveColor.lighter(110));//palette.button().color().darker(115));
3214 groovePainter.setBrush(gradient);
3215 groovePainter.drawRoundedRect(pixmapRect.adjusted(1, 1, -2, -2), 1, 1);
3216 groovePainter.end();
3217 QPixmapCache::insert(groovePixmapName, cache);
3219 painter->drawPixmap(groove.topLeft(), cache);
3221 // draw blue groove highlight
3222 QRect clipRect;
3223 groovePixmapName += QLatin1String("_blue");
3224 if (!QPixmapCache::find(groovePixmapName, PIXMAPCACHE_VAR_PREFIX cache)) {
3225 cache = styleCachePixmap(pixmapRect.size());
3226 cache.fill(Qt::transparent);
3227 QPainter groovePainter(&cache);
3228 QLinearGradient gradient;
3229 if (horizontal) {
3230 gradient.setStart(pixmapRect.center().x(), pixmapRect.top());
3231 gradient.setFinalStop(pixmapRect.center().x(), pixmapRect.bottom());
3233 else {
3234 gradient.setStart(pixmapRect.left(), pixmapRect.center().y());
3235 gradient.setFinalStop(pixmapRect.right(), pixmapRect.center().y());
3237 QColor highlight = d->highlight(option->palette);
3238 QColor highlightedoutline = highlight.darker(140);
3239 if (qGray(outline.rgb()) > qGray(highlightedoutline.rgb()))
3240 outline = highlightedoutline;
3243 groovePainter.setRenderHint(QPainter::Antialiasing, true);
3244 groovePainter.translate(0.5, 0.5);
3245 groovePainter.setPen(QPen(outline, 0));
3246 gradient.setColorAt(0, activeHighlight);
3247 gradient.setColorAt(1, activeHighlight.lighter(130));
3248 groovePainter.setBrush(gradient);
3249 groovePainter.drawRoundedRect(pixmapRect.adjusted(1, 1, -2, -2), 1, 1);
3250 groovePainter.setPen(d->innerContrastLine());
3251 groovePainter.setBrush(Qt::NoBrush);
3252 groovePainter.drawRoundedRect(pixmapRect.adjusted(2, 2, -3, -3), 1, 1);
3253 groovePainter.end();
3254 QPixmapCache::insert(groovePixmapName, cache);
3256 if (horizontal) {
3257 if (slider->upsideDown)
3258 clipRect = QRect(handle.right(), groove.top(), groove.right() - handle.right(), groove.height());
3259 else
3260 clipRect = QRect(groove.left(), groove.top(), handle.left(), groove.height());
3261 } else {
3262 if (slider->upsideDown)
3263 clipRect = QRect(groove.left(), handle.bottom(), groove.width(), groove.height() - handle.bottom());
3264 else
3265 clipRect = QRect(groove.left(), groove.top(), groove.width(), handle.top() - groove.top());
3267 painter->save();
3268 painter->setClipRect(clipRect.adjusted(0, 0, 1, 1));
3269 painter->drawPixmap(groove.topLeft(), cache);
3270 painter->restore();
3273 if (option->subControls & SC_SliderTickmarks) {
3274 painter->setPen(outline);
3275 int tickSize = proxy()->pixelMetric(PM_SliderTickmarkOffset, option, widget);
3276 int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider, widget);
3277 int interval = slider->tickInterval;
3278 if (interval <= 0) {
3279 interval = slider->singleStep;
3280 if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval,
3281 available)
3282 - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
3283 0, available) < 3)
3284 interval = slider->pageStep;
3286 if (interval <= 0)
3287 interval = 1;
3289 int v = slider->minimum;
3290 int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
3291 while (v <= slider->maximum + 1) {
3292 if (v == slider->maximum + 1 && interval == 1)
3293 break;
3294 const int v_ = qMin(v, slider->maximum);
3295 int pos = sliderPositionFromValue(slider->minimum, slider->maximum,
3296 v_, (horizontal
3297 ? slider->rect.width()
3298 : slider->rect.height()) - len,
3299 slider->upsideDown) + len / 2;
3300 int extra = 2 - ((v_ == slider->minimum || v_ == slider->maximum) ? 1 : 0);
3302 if (horizontal) {
3303 if (ticksAbove) {
3304 painter->drawLine(pos, slider->rect.top() + extra,
3305 pos, slider->rect.top() + tickSize);
3307 if (ticksBelow) {
3308 painter->drawLine(pos, slider->rect.bottom() - extra,
3309 pos, slider->rect.bottom() - tickSize);
3311 } else {
3312 if (ticksAbove) {
3313 painter->drawLine(slider->rect.left() + extra, pos,
3314 slider->rect.left() + tickSize, pos);
3316 if (ticksBelow) {
3317 painter->drawLine(slider->rect.right() - extra, pos,
3318 slider->rect.right() - tickSize, pos);
3321 // in the case where maximum is max int
3322 int nextInterval = v + interval;
3323 if (nextInterval < v)
3324 break;
3325 v = nextInterval;
3329 // draw handle
3330 if ((option->subControls & SC_SliderHandle) ) {
3331 QString handlePixmapName = uniqueName(QLatin1String("slider_handle"), option, handle.size());
3332 if (!QPixmapCache::find(handlePixmapName, PIXMAPCACHE_VAR_PREFIX cache)) {
3333 cache = styleCachePixmap(handle.size());
3334 cache.fill(Qt::transparent);
3335 QRect pixmapRect(0, 0, handle.width(), handle.height());
3336 QPainter handlePainter(&cache);
3337 QRect gradRect = pixmapRect.adjusted(2, 2, -2, -2);
3339 // gradient fill
3340 QRect r = pixmapRect.adjusted(1, 1, -2, -2);
3341 QLinearGradient gradient = qt_fusion_gradient(gradRect, d->buttonColor(option->palette),horizontal ? TopDown : FromLeft);
3343 handlePainter.setRenderHint(QPainter::Antialiasing, true);
3344 handlePainter.translate(0.5, 0.5);
3346 handlePainter.setPen(Qt::NoPen);
3347 handlePainter.setBrush(QColor(0, 0, 0, 40));
3348 handlePainter.drawRect(r.adjusted(-1, 2, 1, -2));
3350 handlePainter.setPen(QPen(d->outline(option->palette), 1));
3351 if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange)
3352 handlePainter.setPen(QPen(d->highlightedOutline(option->palette), 1));
3354 handlePainter.setBrush(gradient);
3355 handlePainter.drawRoundedRect(r, 2, 2);
3356 handlePainter.setBrush(Qt::NoBrush);
3357 handlePainter.setPen(d->innerContrastLine());
3358 handlePainter.drawRoundedRect(r.adjusted(1, 1, -1, -1), 2, 2);
3360 QColor cornerAlpha = outline.darker(120);
3361 cornerAlpha.setAlpha(80);
3363 //handle shadow
3364 handlePainter.setPen(shadowAlpha);
3365 handlePainter.drawLine(QPoint(r.left() + 2, r.bottom() + 1), QPoint(r.right() - 2, r.bottom() + 1));
3366 handlePainter.drawLine(QPoint(r.right() + 1, r.bottom() - 3), QPoint(r.right() + 1, r.top() + 4));
3367 handlePainter.drawLine(QPoint(r.right() - 1, r.bottom()), QPoint(r.right() + 1, r.bottom() - 2));
3369 handlePainter.end();
3370 QPixmapCache::insert(handlePixmapName, cache);
3373 painter->drawPixmap(handle.topLeft(), cache);
3376 painter->setBrush(oldBrush);
3377 painter->setPen(oldPen);
3379 break;
3380 case CC_Dial:
3381 if (const QStyleOptionSlider* dial = qstyleoption_cast<const QStyleOptionSlider *>(option))
3382 drawDial(dial, painter);
3383 break;
3384 default:
3385 QCommonStyle::drawComplexControl(control, option, painter, widget);
3386 break;
3391 \reimp
3393 int CarlaStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
3395 switch (metric)
3397 case PM_SliderTickmarkOffset:
3398 return 4;
3399 case PM_HeaderMargin:
3400 return 2;
3401 case PM_ToolTipLabelFrameWidth:
3402 return 2;
3403 case PM_ButtonDefaultIndicator:
3404 return 0;
3405 case PM_ButtonShiftHorizontal:
3406 case PM_ButtonShiftVertical:
3407 return 0;
3408 case PM_MessageBoxIconSize:
3409 return 48;
3410 case PM_ListViewIconSize:
3411 return 24;
3412 case PM_DialogButtonsSeparator:
3413 case PM_ScrollBarSliderMin:
3414 return 26;
3415 case PM_TitleBarHeight:
3416 return 24;
3417 case PM_ScrollBarExtent:
3418 return 14;
3419 case PM_SliderThickness:
3420 return 15;
3421 case PM_SliderLength:
3422 return 15;
3423 case PM_DockWidgetTitleMargin:
3424 return 1;
3425 case PM_DefaultFrameWidth:
3426 return 1;
3427 case PM_SpinBoxFrameWidth:
3428 return 2;
3429 case PM_MenuVMargin:
3430 case PM_MenuHMargin:
3431 return 0;
3432 case PM_MenuPanelWidth:
3433 return 0;
3434 case PM_MenuBarItemSpacing:
3435 return 6;
3436 case PM_MenuBarVMargin:
3437 return 0;
3438 case PM_MenuBarHMargin:
3439 return 0;
3440 case PM_MenuBarPanelWidth:
3441 return 0;
3442 case PM_ToolBarHandleExtent:
3443 return 9;
3444 case PM_ToolBarItemSpacing:
3445 return 1;
3446 case PM_ToolBarFrameWidth:
3447 return 2;
3448 case PM_ToolBarItemMargin:
3449 return 2;
3450 case PM_SmallIconSize:
3451 return 16;
3452 case PM_ButtonIconSize:
3453 return 16;
3454 case PM_DockWidgetTitleBarButtonMargin:
3455 return 2;
3456 case PM_MaximumDragDistance:
3457 return -1;
3458 case PM_TabCloseIndicatorWidth:
3459 case PM_TabCloseIndicatorHeight:
3460 return 20;
3461 case PM_TabBarTabVSpace:
3462 return 12;
3463 case PM_TabBarTabOverlap:
3464 return 1;
3465 case PM_TabBarBaseOverlap:
3466 return 2;
3467 case PM_SubMenuOverlap:
3468 return -1;
3469 case PM_DockWidgetHandleExtent:
3470 case PM_SplitterWidth:
3471 return 4;
3472 case PM_IndicatorHeight:
3473 case PM_IndicatorWidth:
3474 case PM_ExclusiveIndicatorHeight:
3475 case PM_ExclusiveIndicatorWidth:
3476 return 14;
3477 case PM_ScrollView_ScrollBarSpacing:
3478 return 0;
3479 default:
3480 break;
3482 return QCommonStyle::pixelMetric(metric, option, widget);
3486 \reimp
3488 QSize CarlaStyle::sizeFromContents(ContentsType type, const QStyleOption* option,
3489 const QSize& size, const QWidget* widget) const
3491 QSize newSize = QCommonStyle::sizeFromContents(type, option, size, widget);
3493 switch (type)
3495 case CT_PushButton:
3496 if (const QStyleOptionButton* btn = qstyleoption_cast<const QStyleOptionButton *>(option))
3498 if (!btn->text.isEmpty() && newSize.width() < 80)
3499 newSize.setWidth(80);
3500 if (!btn->icon.isNull() && btn->iconSize.height() > 16)
3501 newSize -= QSize(0, 2);
3503 break;
3505 case CT_GroupBox:
3506 if (option)
3508 int topMargin = qMax(pixelMetric(PM_ExclusiveIndicatorHeight), option->fontMetrics.height()) + groupBoxTopMargin;
3509 newSize += QSize(10, topMargin); // Add some space below the groupbox
3511 break;
3513 case CT_RadioButton:
3514 case CT_CheckBox:
3515 newSize += QSize(0, 1);
3516 break;
3518 case CT_ToolButton:
3519 newSize += QSize(3, 3);
3520 break;
3522 case CT_SpinBox:
3523 newSize += QSize(0, -3);
3524 break;
3526 case CT_ComboBox:
3527 newSize += QSize(2, 4);
3528 break;
3530 case CT_LineEdit:
3531 newSize += QSize(0, 4);
3532 break;
3534 case CT_MenuBarItem:
3535 newSize += QSize(8, 5);
3536 break;
3538 case CT_MenuItem:
3539 if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
3541 int w = newSize.width();
3542 int maxpmw = menuItem->maxIconWidth;
3543 int tabSpacing = 20;
3544 if (menuItem->text.contains(QLatin1Char('\t')))
3545 w += tabSpacing;
3546 else if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu)
3547 w += 2 * CarlaStylePrivate::menuArrowHMargin;
3548 else if (menuItem->menuItemType == QStyleOptionMenuItem::DefaultItem) {
3549 QFontMetrics fm(menuItem->font);
3550 QFont fontBold = menuItem->font;
3551 fontBold.setBold(true);
3552 QFontMetrics fmBold(fontBold);
3553 w += fontMetricsHorizontalAdvance(fmBold, menuItem->text) - fontMetricsHorizontalAdvance(fm, menuItem->text);
3555 int checkcol = qMax<int>(maxpmw, CarlaStylePrivate::menuCheckMarkWidth); // Windows always shows a check column
3556 w += checkcol;
3557 w += int(CarlaStylePrivate::menuRightBorder) + 10;
3558 newSize.setWidth(w);
3559 if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
3560 if (!menuItem->text.isEmpty()) {
3561 newSize.setHeight(menuItem->fontMetrics.height());
3564 else if (!menuItem->icon.isNull())
3566 if (const QComboBox *combo = qobject_cast<const QComboBox*>(widget)) {
3567 newSize.setHeight(qMax(combo->iconSize().height() + 2, newSize.height()));
3570 newSize.setWidth(newSize.width() + 12);
3571 newSize.setWidth(qMax(newSize.width(), 120));
3573 break;
3575 case CT_SizeGrip:
3576 newSize += QSize(4, 4);
3577 break;
3579 case CT_MdiControls:
3580 if (const QStyleOptionComplex *styleOpt = qstyleoption_cast<const QStyleOptionComplex *>(option))
3582 int width = 0;
3583 if (styleOpt->subControls & SC_MdiMinButton)
3584 width += 19 + 1;
3585 if (styleOpt->subControls & SC_MdiNormalButton)
3586 width += 19 + 1;
3587 if (styleOpt->subControls & SC_MdiCloseButton)
3588 width += 19 + 1;
3589 newSize = QSize(width, 19);
3591 else
3593 newSize = QSize(60, 19);
3595 break;
3597 default:
3598 break;
3600 return newSize;
3603 void CarlaStyle::polish(QApplication* app)
3605 QCommonStyle::polish(app);
3608 void CarlaStyle::polish(QPalette& pal)
3610 QCommonStyle::polish(pal);
3614 \reimp
3616 void CarlaStyle::polish(QWidget *widget)
3618 QCommonStyle::polish(widget);
3619 if (qobject_cast<QAbstractButton*>(widget)
3620 || qobject_cast<QComboBox *>(widget)
3621 || qobject_cast<QProgressBar *>(widget)
3622 || qobject_cast<QScrollBar *>(widget)
3623 || qobject_cast<QSplitterHandle *>(widget)
3624 || qobject_cast<QAbstractSlider *>(widget)
3625 || qobject_cast<QAbstractSpinBox *>(widget)
3626 || (widget->inherits("QDockSeparator"))
3627 || (widget->inherits("QDockWidgetSeparator"))
3629 widget->setAttribute(Qt::WA_Hover, true);
3634 void CarlaStyle::unpolish(QApplication* app)
3636 QCommonStyle::unpolish(app);
3640 \reimp
3642 void CarlaStyle::unpolish(QWidget *widget)
3644 QCommonStyle::unpolish(widget);
3645 if (qobject_cast<QAbstractButton*>(widget)
3646 || qobject_cast<QComboBox *>(widget)
3647 || qobject_cast<QProgressBar *>(widget)
3648 || qobject_cast<QScrollBar *>(widget)
3649 || qobject_cast<QSplitterHandle *>(widget)
3650 || qobject_cast<QAbstractSlider *>(widget)
3651 || qobject_cast<QAbstractSpinBox *>(widget)
3652 || (widget->inherits("QDockSeparator"))
3653 || (widget->inherits("QDockWidgetSeparator"))
3655 widget->setAttribute(Qt::WA_Hover, false);
3660 \reimp
3662 QRect CarlaStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
3663 SubControl subControl, const QWidget *widget) const
3665 QRect rect = QCommonStyle::subControlRect(control, option, subControl, widget);
3667 switch (control) {
3668 case CC_Slider:
3669 if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
3670 int tickSize = proxy()->pixelMetric(PM_SliderTickmarkOffset, option, widget);
3671 switch (subControl) {
3672 case SC_SliderHandle: {
3673 if (slider->orientation == Qt::Horizontal) {
3674 rect.setHeight(proxy()->pixelMetric(PM_SliderThickness));
3675 rect.setWidth(proxy()->pixelMetric(PM_SliderLength));
3676 int centerY = slider->rect.center().y() - rect.height() / 2;
3677 if (slider->tickPosition & QSlider::TicksAbove)
3678 centerY += tickSize;
3679 if (slider->tickPosition & QSlider::TicksBelow)
3680 centerY -= tickSize;
3681 rect.moveTop(centerY);
3682 } else {
3683 rect.setWidth(proxy()->pixelMetric(PM_SliderThickness));
3684 rect.setHeight(proxy()->pixelMetric(PM_SliderLength));
3685 int centerX = slider->rect.center().x() - rect.width() / 2;
3686 if (slider->tickPosition & QSlider::TicksAbove)
3687 centerX += tickSize;
3688 if (slider->tickPosition & QSlider::TicksBelow)
3689 centerX -= tickSize;
3690 rect.moveLeft(centerX);
3693 break;
3694 case SC_SliderGroove: {
3695 QPoint grooveCenter = slider->rect.center();
3696 if (slider->orientation == Qt::Horizontal) {
3697 rect.setHeight(7);
3698 if (slider->tickPosition & QSlider::TicksAbove)
3699 grooveCenter.ry() += tickSize;
3700 if (slider->tickPosition & QSlider::TicksBelow)
3701 grooveCenter.ry() -= tickSize;
3702 } else {
3703 rect.setWidth(7);
3704 if (slider->tickPosition & QSlider::TicksAbove)
3705 grooveCenter.rx() += tickSize;
3706 if (slider->tickPosition & QSlider::TicksBelow)
3707 grooveCenter.rx() -= tickSize;
3709 rect.moveCenter(grooveCenter);
3710 break;
3712 default:
3713 break;
3716 break;
3717 case CC_SpinBox:
3718 if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
3719 QSize bs;
3720 const float center = spinbox->rect.height() / 2.0;
3721 const int fw = spinbox->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0;
3722 const int y = 1;
3723 bs.setHeight(qMax(8, int(floor(center) - y)));
3724 bs.setWidth(14);
3725 int x, lx, rx;
3726 x = spinbox->rect.width() - y - bs.width();
3727 lx = fw;
3728 rx = x - fw;
3729 switch (subControl) {
3730 case SC_SpinBoxUp:
3731 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
3732 return QRect();
3733 rect = QRect(x, y, bs.width(), bs.height());
3734 break;
3735 case SC_SpinBoxDown:
3736 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
3737 return QRect();
3739 rect = QRect(x, ceil(center), bs.width(), bs.height());
3740 break;
3741 case SC_SpinBoxEditField:
3742 if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) {
3743 rect = QRect(lx, fw, spinbox->rect.width() - 2*fw, spinbox->rect.height() - 2*fw);
3744 } else {
3745 rect = QRect(lx, fw, rx - qMax(fw - 1, 0), spinbox->rect.height() - 2*fw);
3747 break;
3748 case SC_SpinBoxFrame:
3749 rect = spinbox->rect;
3750 default:
3751 break;
3753 rect = visualRect(spinbox->direction, spinbox->rect, rect);
3755 break;
3757 case CC_GroupBox:
3758 if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
3759 rect = option->rect;
3760 if (subControl == SC_GroupBoxFrame)
3761 return rect.adjusted(0, 0, 0, 0);
3762 else if (subControl == SC_GroupBoxContents) {
3763 QRect frameRect = option->rect.adjusted(0, 0, 0, -groupBoxBottomMargin);
3764 int margin = 3;
3765 int leftMarginExtension = 0;
3766 int topMargin = qMax(pixelMetric(PM_ExclusiveIndicatorHeight), option->fontMetrics.height()) + groupBoxTopMargin;
3767 return frameRect.adjusted(leftMarginExtension + margin, margin + topMargin, -margin, -margin - groupBoxBottomMargin);
3770 QSize textSize = option->fontMetrics.boundingRect(groupBox->text).size() + QSize(2, 2);
3771 int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, option, widget);
3772 int indicatorHeight = proxy()->pixelMetric(PM_IndicatorHeight, option, widget);
3773 rect = QRect();
3774 if (subControl == SC_GroupBoxCheckBox) {
3775 rect.setWidth(indicatorWidth);
3776 rect.setHeight(indicatorHeight);
3777 rect.moveTop(textSize.height() > indicatorHeight ? (textSize.height() - indicatorHeight) / 2 : 0);
3778 rect.moveLeft(1);
3779 } else if (subControl == SC_GroupBoxLabel) {
3780 rect.setSize(textSize);
3781 rect.moveTop(1);
3782 if (option->subControls & QStyle::SC_GroupBoxCheckBox)
3783 rect.translate(indicatorWidth + 5, 0);
3785 return visualRect(option->direction, option->rect, rect);
3788 return rect;
3790 case CC_ComboBox:
3791 switch (subControl) {
3792 case SC_ComboBoxArrow:
3793 rect = visualRect(option->direction, option->rect, rect);
3794 rect.setRect(rect.right() - 18, rect.top() - 2,
3795 19, rect.height() + 4);
3796 rect = visualRect(option->direction, option->rect, rect);
3797 break;
3798 case SC_ComboBoxEditField: {
3799 int frameWidth = 2;
3800 rect = visualRect(option->direction, option->rect, rect);
3801 rect.setRect(option->rect.left() + frameWidth, option->rect.top() + frameWidth,
3802 option->rect.width() - 19 - 2 * frameWidth,
3803 option->rect.height() - 2 * frameWidth);
3804 if (const QStyleOptionComboBox *box = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
3805 if (!box->editable) {
3806 rect.adjust(2, 0, 0, 0);
3807 if (box->state & (State_Sunken | State_On))
3808 rect.translate(1, 1);
3811 rect = visualRect(option->direction, option->rect, rect);
3812 break;
3814 default:
3815 break;
3817 break;
3818 case CC_TitleBar:
3819 if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
3820 SubControl sc = subControl;
3821 QRect &ret = rect;
3822 const int indent = 3;
3823 const int controlTopMargin = 3;
3824 const int controlBottomMargin = 3;
3825 const int controlWidthMargin = 2;
3826 const int controlHeight = tb->rect.height() - controlTopMargin - controlBottomMargin ;
3827 const int delta = controlHeight + controlWidthMargin;
3828 int offset = 0;
3830 bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
3831 bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
3833 switch (sc) {
3834 case SC_TitleBarLabel:
3835 if (tb->titleBarFlags & (Qt::WindowTitleHint | Qt::WindowSystemMenuHint)) {
3836 ret = tb->rect;
3837 if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
3838 ret.adjust(delta, 0, -delta, 0);
3839 if (tb->titleBarFlags & Qt::WindowMinimizeButtonHint)
3840 ret.adjust(0, 0, -delta, 0);
3841 if (tb->titleBarFlags & Qt::WindowMaximizeButtonHint)
3842 ret.adjust(0, 0, -delta, 0);
3843 if (tb->titleBarFlags & Qt::WindowShadeButtonHint)
3844 ret.adjust(0, 0, -delta, 0);
3845 if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
3846 ret.adjust(0, 0, -delta, 0);
3848 break;
3849 case SC_TitleBarContextHelpButton:
3850 if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
3851 offset += delta;
3852 // fall through
3853 case SC_TitleBarMinButton:
3854 if (!isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
3855 offset += delta;
3856 else if (sc == SC_TitleBarMinButton)
3857 break;
3858 // fall through
3859 case SC_TitleBarNormalButton:
3860 if (isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
3861 offset += delta;
3862 else if (isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
3863 offset += delta;
3864 else if (sc == SC_TitleBarNormalButton)
3865 break;
3866 // fall through
3867 case SC_TitleBarMaxButton:
3868 if (!isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
3869 offset += delta;
3870 else if (sc == SC_TitleBarMaxButton)
3871 break;
3872 // fall through
3873 case SC_TitleBarShadeButton:
3874 if (!isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
3875 offset += delta;
3876 else if (sc == SC_TitleBarShadeButton)
3877 break;
3878 // fall through
3879 case SC_TitleBarUnshadeButton:
3880 if (isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
3881 offset += delta;
3882 else if (sc == SC_TitleBarUnshadeButton)
3883 break;
3884 // fall through
3885 case SC_TitleBarCloseButton:
3886 if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
3887 offset += delta;
3888 else if (sc == SC_TitleBarCloseButton)
3889 break;
3890 ret.setRect(tb->rect.right() - indent - offset, tb->rect.top() + controlTopMargin,
3891 controlHeight, controlHeight);
3892 break;
3893 case SC_TitleBarSysMenu:
3894 if (tb->titleBarFlags & Qt::WindowSystemMenuHint) {
3895 ret.setRect(tb->rect.left() + controlWidthMargin + indent, tb->rect.top() + controlTopMargin,
3896 controlHeight, controlHeight);
3898 break;
3899 default:
3900 break;
3902 ret = visualRect(tb->direction, tb->rect, ret);
3904 break;
3905 default:
3906 break;
3909 return rect;
3913 \reimp
3915 QPixmap CarlaStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption* opt, const QWidget* widget) const
3917 #if 0 // ndef QT_NO_IMAGEFORMAT_XPM
3918 switch (standardPixmap) {
3919 case SP_TitleBarNormalButton:
3920 return QPixmap((const char **)dock_widget_restore_xpm);
3921 case SP_TitleBarMinButton:
3922 return QPixmap((const char **)workspace_minimize);
3923 case SP_TitleBarCloseButton:
3924 case SP_DockWidgetCloseButton:
3925 return QPixmap((const char **)dock_widget_close_xpm);
3926 default:
3927 break;
3929 #endif //QT_NO_IMAGEFORMAT_XPM
3931 QPixmap pixmap = QCommonStyle::standardPixmap(standardPixmap, opt, widget);
3933 if(!pixmap.isNull())
3934 return pixmap;
3936 #if 0 // ndef QT_NO_IMAGEFORMAT_XPM
3937 switch (standardPixmap) {
3938 case SP_TitleBarMenuButton:
3939 return QPixmap(qt_menu_xpm);
3940 case SP_TitleBarShadeButton:
3941 return QPixmap(qt_shade_xpm);
3942 case SP_TitleBarUnshadeButton:
3943 return QPixmap(qt_unshade_xpm);
3944 case SP_TitleBarMaxButton:
3945 return QPixmap(qt_maximize_xpm);
3946 case SP_TitleBarCloseButton:
3947 return QPixmap(qt_close_xpm);
3948 case SP_TitleBarContextHelpButton:
3949 return QPixmap(qt_help_xpm);
3950 case SP_MessageBoxInformation:
3951 return QPixmap(information_xpm);
3952 case SP_MessageBoxWarning:
3953 return QPixmap(warning_xpm);
3954 case SP_MessageBoxCritical:
3955 return QPixmap(critical_xpm);
3956 case SP_MessageBoxQuestion:
3957 return QPixmap(question_xpm);
3958 default:
3959 break;
3961 #endif //QT_NO_IMAGEFORMAT_XPM
3963 return QPixmap();
3967 \reimp
3969 int CarlaStyle::styleHint(StyleHint hint, const QStyleOption* option, const QWidget* widget,
3970 QStyleHintReturn* returnData) const
3972 switch (hint)
3974 case SH_Slider_SnapToValue:
3975 case SH_PrintDialog_RightAlignButtons:
3976 case SH_FontDialog_SelectAssociatedText:
3977 case SH_MenuBar_AltKeyNavigation:
3978 case SH_ComboBox_ListMouseTracking:
3979 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
3980 case SH_Slider_StopMouseOverSlider:
3981 #else
3982 case SH_ScrollBar_StopMouseOverSlider:
3983 #endif
3984 case SH_ScrollBar_MiddleClickAbsolutePosition:
3985 case SH_TitleBar_AutoRaise:
3986 case SH_TitleBar_NoBorder:
3987 case SH_ItemView_ShowDecorationSelected:
3988 case SH_ItemView_ArrowKeysNavigateIntoChildren:
3989 case SH_ItemView_ChangeHighlightOnFocus:
3990 case SH_MenuBar_MouseTracking:
3991 case SH_Menu_MouseTracking:
3992 return 1;
3994 case SH_ComboBox_Popup:
3995 case SH_EtchDisabledText:
3996 case SH_ToolBox_SelectedPageTitleBold:
3997 case SH_ScrollView_FrameOnlyAroundContents:
3998 case SH_Menu_AllowActiveAndDisabled:
3999 case SH_MainWindow_SpaceBelowMenuBar:
4000 //case SH_DialogButtonBox_ButtonsHaveIcons:
4001 case SH_MessageBox_CenterButtons:
4002 case SH_RubberBand_Mask:
4003 case SH_UnderlineShortcut:
4004 return 0;
4006 case SH_Table_GridLineColor:
4007 return option ? qt_palette_bg_color(option->palette).darker(120).rgb() : 0;
4009 case SH_MessageBox_TextInteractionFlags:
4010 return Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse;
4012 case SH_WizardStyle:
4013 return QWizard::ClassicStyle;
4015 case SH_Menu_SubMenuPopupDelay:
4016 return 225; // default from GtkMenu
4018 case SH_WindowFrame_Mask:
4019 if (QStyleHintReturnMask* mask = qstyleoption_cast<QStyleHintReturnMask*>(returnData)) {
4020 //left rounded corner
4021 mask->region = option->rect;
4022 mask->region -= QRect(option->rect.left(), option->rect.top(), 5, 1);
4023 mask->region -= QRect(option->rect.left(), option->rect.top() + 1, 3, 1);
4024 mask->region -= QRect(option->rect.left(), option->rect.top() + 2, 2, 1);
4025 mask->region -= QRect(option->rect.left(), option->rect.top() + 3, 1, 2);
4027 //right rounded corner
4028 mask->region -= QRect(option->rect.right() - 4, option->rect.top(), 5, 1);
4029 mask->region -= QRect(option->rect.right() - 2, option->rect.top() + 1, 3, 1);
4030 mask->region -= QRect(option->rect.right() - 1, option->rect.top() + 2, 2, 1);
4031 mask->region -= QRect(option->rect.right() , option->rect.top() + 3, 1, 2);
4032 return 1;
4034 default:
4035 break;
4037 return QCommonStyle::styleHint(hint, option, widget, returnData);
4040 /*! \reimp */
4041 QRect CarlaStyle::subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *w) const
4043 QRect r = QCommonStyle::subElementRect(sr, opt, w);
4044 switch (sr) {
4045 case SE_ProgressBarLabel:
4046 case SE_ProgressBarContents:
4047 case SE_ProgressBarGroove:
4048 return opt->rect;
4049 case SE_PushButtonFocusRect:
4050 r.adjust(0, 1, 0, -1);
4051 break;
4052 case SE_DockWidgetTitleBarText: {
4053 if (const QStyleOptionDockWidget *titlebar = qstyleoption_cast<const QStyleOptionDockWidget*>(opt)) {
4054 Q_UNUSED(titlebar);
4055 bool verticalTitleBar = false;
4056 if (verticalTitleBar) {
4057 r.adjust(0, 0, 0, -4);
4058 } else {
4059 if (opt->direction == Qt::LeftToRight)
4060 r.adjust(4, 0, 0, 0);
4061 else
4062 r.adjust(0, 0, -4, 0);
4066 break;
4068 default:
4069 break;
4071 return r;