breezehelper.cpp 56.1 KB
Newer Older
1
2
3
4
5
/*
 * SPDX-FileCopyrightText: 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */
6
7
8

#include "breezehelper.h"

9
#include "breeze.h"
10
#include "breezestyleconfigdata.h"
11

David Redondo's avatar
David Redondo committed
12
#include <KColorScheme>
13
#include <KColorUtils>
14
#include <KIconLoader>
15
16
#include <KWindowSystem>

17
#include <QApplication>
Janet Blackquill's avatar
Janet Blackquill committed
18
#include <QDBusConnection>
Alexander Lohnau's avatar
Alexander Lohnau committed
19
#include <QDockWidget>
Janet Blackquill's avatar
Janet Blackquill committed
20
21
22
#include <QFileInfo>
#include <QMainWindow>
#include <QMdiArea>
Alexander Lohnau's avatar
Alexander Lohnau committed
23
24
#include <QMenuBar>
#include <QPainter>
Janet Blackquill's avatar
Janet Blackquill committed
25
#include <QWindow>
26

27
#if BREEZE_HAVE_QTX11EXTRAS
28
29
30
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
#include <private/qtx11extras_p.h>
#else
31
32
#include <QX11Info>
#endif
33
#endif
34

Janet Blackquill's avatar
Janet Blackquill committed
35
#include <QDialog>
Alexander Lohnau's avatar
Alexander Lohnau committed
36
#include <algorithm>
37

38
39
namespace Breeze
{
Alexander Lohnau's avatar
Alexander Lohnau committed
40
41
//* contrast for arrow and treeline rendering
static const qreal arrowShade = 0.15;
42

Alexander Lohnau's avatar
Alexander Lohnau committed
43
static const qreal highlightBackgroundAlpha = 0.33;
44

Alexander Lohnau's avatar
Alexander Lohnau committed
45
static const auto radioCheckSunkenDarkeningFactor = 110;
Janet Blackquill's avatar
Janet Blackquill committed
46

Alexander Lohnau's avatar
Alexander Lohnau committed
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//____________________________________________________________________
Helper::Helper(KSharedConfig::Ptr config, QObject *parent)
    : QObject(parent)
    , _config(std::move(config))
    , _kwinConfig(KSharedConfig::openConfig("kwinrc"))
    , _decorationConfig(new InternalSettings())
{
    if (qApp) {
        connect(qApp, &QApplication::paletteChanged, this, [=]() {
            if (qApp->property("KDE_COLOR_SCHEME_PATH").isValid()) {
                const auto path = qApp->property("KDE_COLOR_SCHEME_PATH").toString();
                KConfig config(path, KConfig::SimpleConfig);
                KConfigGroup group(config.group("WM"));
                const QPalette palette(QApplication::palette());
                _activeTitleBarColor = group.readEntry("activeBackground", palette.color(QPalette::Active, QPalette::Highlight));
                _activeTitleBarTextColor = group.readEntry("activeForeground", palette.color(QPalette::Active, QPalette::HighlightedText));
                _inactiveTitleBarColor = group.readEntry("inactiveBackground", palette.color(QPalette::Disabled, QPalette::Highlight));
                _inactiveTitleBarTextColor = group.readEntry("inactiveForeground", palette.color(QPalette::Disabled, QPalette::HighlightedText));
            }
        });
67
    }
Alexander Lohnau's avatar
Alexander Lohnau committed
68
}
69

Alexander Lohnau's avatar
Alexander Lohnau committed
70
71
72
73
74
//____________________________________________________________________
KSharedConfig::Ptr Helper::config() const
{
    return _config;
}
75

Alexander Lohnau's avatar
Alexander Lohnau committed
76
77
78
79
80
//____________________________________________________________________
QSharedPointer<InternalSettings> Helper::decorationConfig() const
{
    return _decorationConfig;
}
81

Alexander Lohnau's avatar
Alexander Lohnau committed
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//____________________________________________________________________
void Helper::loadConfig()
{
    _viewFocusBrush = KStatefulBrush(KColorScheme::View, KColorScheme::FocusColor);
    _viewHoverBrush = KStatefulBrush(KColorScheme::View, KColorScheme::HoverColor);
    _buttonFocusBrush = KStatefulBrush(KColorScheme::Button, KColorScheme::FocusColor);
    _buttonHoverBrush = KStatefulBrush(KColorScheme::Button, KColorScheme::HoverColor);
    _viewNegativeTextBrush = KStatefulBrush(KColorScheme::View, KColorScheme::NegativeText);
    _viewNeutralTextBrush = KStatefulBrush(KColorScheme::View, KColorScheme::NeutralText);

    const QPalette palette(QApplication::palette());
    _config->reparseConfiguration();
    _kwinConfig->reparseConfiguration();
    _cachedAutoValid = false;
    _decorationConfig->load();

    KConfig config(qApp->property("KDE_COLOR_SCHEME_PATH").toString(), KConfig::SimpleConfig);
    KConfigGroup appGroup(config.group("WM"));
    KConfigGroup globalGroup(_config->group("WM"));
    _activeTitleBarColor =
        appGroup.readEntry("activeBackground", globalGroup.readEntry("activeBackground", palette.color(QPalette::Active, QPalette::Highlight)));
    _activeTitleBarTextColor =
        appGroup.readEntry("activeForeground", globalGroup.readEntry("activeForeground", palette.color(QPalette::Active, QPalette::HighlightedText)));
    _inactiveTitleBarColor =
        appGroup.readEntry("inactiveBackground", globalGroup.readEntry("inactiveBackground", palette.color(QPalette::Disabled, QPalette::Highlight)));
    _inactiveTitleBarTextColor =
        appGroup.readEntry("inactiveForeground", globalGroup.readEntry("inactiveForeground", palette.color(QPalette::Disabled, QPalette::HighlightedText)));
}
110

Alexander Lohnau's avatar
Alexander Lohnau committed
111
112
113
114
115
116
QColor transparentize(const QColor &color, qreal amount)
{
    auto clone = color;
    clone.setAlphaF(amount);
    return clone;
}
117

Alexander Lohnau's avatar
Alexander Lohnau committed
118
119
120
121
//____________________________________________________________________
QColor Helper::frameOutlineColor(const QPalette &palette, bool mouseOver, bool hasFocus, qreal opacity, AnimationMode mode) const
{
    QColor outline(KColorUtils::mix(palette.color(QPalette::Window), palette.color(QPalette::WindowText), 0.25));
122

Alexander Lohnau's avatar
Alexander Lohnau committed
123
124
125
126
    // focus takes precedence over hover
    if (mode == AnimationFocus) {
        const QColor focus(focusColor(palette));
        const QColor hover(hoverColor(palette));
127

Alexander Lohnau's avatar
Alexander Lohnau committed
128
129
130
131
        if (mouseOver)
            outline = KColorUtils::mix(hover, focus, opacity);
        else
            outline = KColorUtils::mix(outline, focus, opacity);
132

Alexander Lohnau's avatar
Alexander Lohnau committed
133
134
    } else if (hasFocus) {
        outline = focusColor(palette);
135

Alexander Lohnau's avatar
Alexander Lohnau committed
136
137
138
    } else if (mode == AnimationHover) {
        const QColor hover(hoverColor(palette));
        outline = KColorUtils::mix(outline, hover, opacity);
139

Alexander Lohnau's avatar
Alexander Lohnau committed
140
141
    } else if (mouseOver) {
        outline = hoverColor(palette);
142
143
    }

Alexander Lohnau's avatar
Alexander Lohnau committed
144
145
    return outline;
}
146

Alexander Lohnau's avatar
Alexander Lohnau committed
147
148
149
150
151
//____________________________________________________________________
QColor Helper::focusOutlineColor(const QPalette &palette) const
{
    return KColorUtils::mix(focusColor(palette), palette.color(QPalette::WindowText), 0.15);
}
152

Alexander Lohnau's avatar
Alexander Lohnau committed
153
154
155
156
157
//____________________________________________________________________
QColor Helper::hoverOutlineColor(const QPalette &palette) const
{
    return KColorUtils::mix(hoverColor(palette), palette.color(QPalette::WindowText), 0.15);
}
158

Alexander Lohnau's avatar
Alexander Lohnau committed
159
160
161
162
163
//____________________________________________________________________
QColor Helper::buttonFocusOutlineColor(const QPalette &palette) const
{
    return KColorUtils::mix(buttonFocusColor(palette), palette.color(QPalette::ButtonText), 0.15);
}
164

Alexander Lohnau's avatar
Alexander Lohnau committed
165
166
167
168
169
//____________________________________________________________________
QColor Helper::buttonHoverOutlineColor(const QPalette &palette) const
{
    return KColorUtils::mix(buttonHoverColor(palette), palette.color(QPalette::ButtonText), 0.15);
}
170

Alexander Lohnau's avatar
Alexander Lohnau committed
171
172
173
174
175
//____________________________________________________________________
QColor Helper::sidePanelOutlineColor(const QPalette &palette, bool hasFocus, qreal opacity, AnimationMode mode) const
{
    QColor outline(palette.color(QPalette::Inactive, QPalette::Highlight));
    const QColor &focus = palette.color(QPalette::Active, QPalette::Highlight);
176

Alexander Lohnau's avatar
Alexander Lohnau committed
177
178
    if (mode == AnimationFocus) {
        outline = KColorUtils::mix(outline, focus, opacity);
179

Alexander Lohnau's avatar
Alexander Lohnau committed
180
181
    } else if (hasFocus) {
        outline = focus;
182
183
    }

Alexander Lohnau's avatar
Alexander Lohnau committed
184
185
    return outline;
}
186

Alexander Lohnau's avatar
Alexander Lohnau committed
187
188
189
190
191
//____________________________________________________________________
QColor Helper::frameBackgroundColor(const QPalette &palette, QPalette::ColorGroup group) const
{
    return KColorUtils::mix(palette.color(group, QPalette::Window), palette.color(group, QPalette::Base), 0.3);
}
192

Alexander Lohnau's avatar
Alexander Lohnau committed
193
194
195
196
197
198
199
200
201
202
203
204
//____________________________________________________________________
QColor Helper::arrowColor(const QPalette &palette, QPalette::ColorGroup group, QPalette::ColorRole role) const
{
    switch (role) {
    case QPalette::Text:
        return KColorUtils::mix(palette.color(group, QPalette::Text), palette.color(group, QPalette::Base), arrowShade);
    case QPalette::WindowText:
        return KColorUtils::mix(palette.color(group, QPalette::WindowText), palette.color(group, QPalette::Window), arrowShade);
    case QPalette::ButtonText:
        return KColorUtils::mix(palette.color(group, QPalette::ButtonText), palette.color(group, QPalette::Button), arrowShade);
    default:
        return palette.color(group, role);
205
    }
Alexander Lohnau's avatar
Alexander Lohnau committed
206
}
207

Alexander Lohnau's avatar
Alexander Lohnau committed
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
//____________________________________________________________________
QColor Helper::arrowColor(const QPalette &palette, bool mouseOver, bool hasFocus, qreal opacity, AnimationMode mode) const
{
    QColor outline(arrowColor(palette, QPalette::WindowText));
    if (mode == AnimationHover) {
        const QColor focus(focusColor(palette));
        const QColor hover(hoverColor(palette));
        if (hasFocus)
            outline = KColorUtils::mix(focus, hover, opacity);
        else
            outline = KColorUtils::mix(outline, hover, opacity);

    } else if (mouseOver) {
        outline = hoverColor(palette);

    } else if (mode == AnimationFocus) {
        const QColor focus(focusColor(palette));
        outline = KColorUtils::mix(outline, focus, opacity);

    } else if (hasFocus) {
        outline = focusColor(palette);
229
230
    }

Alexander Lohnau's avatar
Alexander Lohnau committed
231
232
    return outline;
}
233

Alexander Lohnau's avatar
Alexander Lohnau committed
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
//____________________________________________________________________
QColor Helper::sliderOutlineColor(const QPalette &palette, bool mouseOver, bool hasFocus, qreal opacity, AnimationMode mode) const
{
    QColor outline(KColorUtils::mix(palette.color(QPalette::Window), palette.color(QPalette::WindowText), 0.4));

    // hover takes precedence over focus
    if (mode == AnimationHover) {
        const QColor hover(hoverColor(palette));
        const QColor focus(focusColor(palette));
        if (hasFocus)
            outline = KColorUtils::mix(focus, hover, opacity);
        else
            outline = KColorUtils::mix(outline, hover, opacity);

    } else if (mouseOver) {
        outline = hoverColor(palette);

    } else if (mode == AnimationFocus) {
        const QColor focus(focusColor(palette));
        outline = KColorUtils::mix(outline, focus, opacity);

    } else if (hasFocus) {
        outline = focusColor(palette);
    }
258

Alexander Lohnau's avatar
Alexander Lohnau committed
259
260
    return outline;
}
261

Alexander Lohnau's avatar
Alexander Lohnau committed
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
//____________________________________________________________________
QColor Helper::scrollBarHandleColor(const QPalette &palette, bool mouseOver, bool hasFocus, qreal opacity, AnimationMode mode) const
{
    QColor color(alphaColor(palette.color(QPalette::WindowText), 0.5));

    // hover takes precedence over focus
    if (mode == AnimationHover) {
        const QColor hover(hoverColor(palette));
        const QColor focus(focusColor(palette));
        if (hasFocus)
            color = KColorUtils::mix(focus, hover, opacity);
        else
            color = KColorUtils::mix(color, hover, opacity);

    } else if (mouseOver) {
        color = hoverColor(palette);

    } else if (mode == AnimationFocus) {
        const QColor focus(focusColor(palette));
        color = KColorUtils::mix(color, focus, opacity);

    } else if (hasFocus) {
        color = focusColor(palette);
    }
286

Alexander Lohnau's avatar
Alexander Lohnau committed
287
288
    return color;
}
289

Alexander Lohnau's avatar
Alexander Lohnau committed
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
//______________________________________________________________________________
QColor Helper::checkBoxIndicatorColor(const QPalette &palette, bool mouseOver, bool active, qreal opacity, AnimationMode mode) const
{
    QColor color(KColorUtils::mix(palette.color(QPalette::Window), palette.color(QPalette::WindowText), 0.6));
    if (mode == AnimationHover) {
        const QColor focus(focusColor(palette));
        const QColor hover(hoverColor(palette));
        if (active)
            color = KColorUtils::mix(focus, hover, opacity);
        else
            color = KColorUtils::mix(color, hover, opacity);

    } else if (mouseOver) {
        color = hoverColor(palette);

    } else if (active) {
        color = focusColor(palette);
    }
308

Alexander Lohnau's avatar
Alexander Lohnau committed
309
310
    return color;
}
311

Alexander Lohnau's avatar
Alexander Lohnau committed
312
313
314
315
316
//______________________________________________________________________________
QColor Helper::separatorColor(const QPalette &palette) const
{
    return KColorUtils::mix(palette.color(QPalette::Window), palette.color(QPalette::WindowText), 0.25);
}
317

Alexander Lohnau's avatar
Alexander Lohnau committed
318
319
320
321
//______________________________________________________________________________
QPalette Helper::disabledPalette(const QPalette &source, qreal ratio) const
{
    QPalette copy(source);
322

Alexander Lohnau's avatar
Alexander Lohnau committed
323
324
325
326
327
    const QList<QPalette::ColorRole> roles =
        {QPalette::Window, QPalette::Highlight, QPalette::WindowText, QPalette::ButtonText, QPalette::Text, QPalette::Button};
    foreach (const QPalette::ColorRole &role, roles) {
        copy.setColor(role, KColorUtils::mix(source.color(QPalette::Active, role), source.color(QPalette::Disabled, role), 1.0 - ratio));
    }
328

Alexander Lohnau's avatar
Alexander Lohnau committed
329
330
    return copy;
}
331

Alexander Lohnau's avatar
Alexander Lohnau committed
332
333
334
335
336
//____________________________________________________________________
QColor Helper::alphaColor(QColor color, qreal alpha) const
{
    if (alpha >= 0 && alpha < 1.0) {
        color.setAlphaF(alpha * color.alphaF());
337
    }
Alexander Lohnau's avatar
Alexander Lohnau committed
338
339
    return color;
}
340

Alexander Lohnau's avatar
Alexander Lohnau committed
341
342
343
344
345
346
347
348
349
350
//______________________________________________________________________________
void Helper::renderDebugFrame(QPainter *painter, const QRect &rect) const
{
    painter->save();
    painter->setRenderHints(QPainter::Antialiasing);
    painter->setBrush(Qt::NoBrush);
    painter->setPen(Qt::red);
    painter->drawRect(strokedRect(rect));
    painter->restore();
}
351

Alexander Lohnau's avatar
Alexander Lohnau committed
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
//______________________________________________________________________________
void Helper::renderFocusRect(QPainter *painter, const QRect &rect, const QColor &color, const QColor &outline, Sides sides) const
{
    if (!color.isValid())
        return;

    painter->save();
    painter->setRenderHints(QPainter::Antialiasing);
    painter->setBrush(color);

    if (!(outline.isValid() && sides)) {
        painter->setPen(Qt::NoPen);
        painter->drawRect(rect);

    } else {
        painter->setClipRect(rect);

        QRectF copy(strokedRect(rect));

        const qreal radius(frameRadius(PenWidth::Frame));
        if (!(sides & SideTop))
            copy.adjust(0, -radius, 0, 0);
        if (!(sides & SideBottom))
            copy.adjust(0, 0, 0, radius);
        if (!(sides & SideLeft))
            copy.adjust(-radius, 0, 0, 0);
        if (!(sides & SideRight))
            copy.adjust(0, 0, radius, 0);

        painter->setPen(outline);
        // painter->setBrush( Qt::NoBrush );
        painter->drawRoundedRect(copy, radius, radius);
    }
385

Alexander Lohnau's avatar
Alexander Lohnau committed
386
387
    painter->restore();
}
388

Alexander Lohnau's avatar
Alexander Lohnau committed
389
390
391
392
393
//______________________________________________________________________________
void Helper::renderFocusLine(QPainter *painter, const QRect &rect, const QColor &color) const
{
    if (!color.isValid())
        return;
394

Alexander Lohnau's avatar
Alexander Lohnau committed
395
396
397
398
    painter->save();
    painter->setRenderHint(QPainter::Antialiasing, false);
    painter->setBrush(Qt::NoBrush);
    painter->setPen(color);
399

Alexander Lohnau's avatar
Alexander Lohnau committed
400
401
402
403
    painter->translate(0, 2);
    painter->drawLine(rect.bottomLeft(), rect.bottomRight());
    painter->restore();
}
404

Alexander Lohnau's avatar
Alexander Lohnau committed
405
406
407
408
//______________________________________________________________________________
void Helper::renderFrameWithSides(QPainter *painter, const QRect &rect, const QColor &color, Qt::Edges edges, const QColor &outline) const
{
    painter->save();
409

Alexander Lohnau's avatar
Alexander Lohnau committed
410
    painter->setRenderHint(QPainter::Antialiasing);
411

Alexander Lohnau's avatar
Alexander Lohnau committed
412
    QRectF frameRect(rect);
413

Alexander Lohnau's avatar
Alexander Lohnau committed
414
415
416
    // set brush
    painter->setBrush(color);
    painter->setPen(Qt::NoPen);
417

Alexander Lohnau's avatar
Alexander Lohnau committed
418
419
    // render
    painter->drawRect(frameRect);
420

Alexander Lohnau's avatar
Alexander Lohnau committed
421
422
423
    // set brush again
    painter->setBrush(Qt::NoBrush);
    painter->setPen(outline);
424

Alexander Lohnau's avatar
Alexander Lohnau committed
425
426
427
    // manually apply the effects of StrokedRect here but only to the edges with a frame
    if (edges & Qt::LeftEdge) {
        frameRect.adjust(0.5, 0.0, 0.0, 0.0);
428
    }
Alexander Lohnau's avatar
Alexander Lohnau committed
429
430
    if (edges & Qt::RightEdge) {
        frameRect.adjust(0.0, 0, -0.5, 0.0);
431
    }
Alexander Lohnau's avatar
Alexander Lohnau committed
432
433
    if (edges & Qt::TopEdge) {
        frameRect.adjust(0.0, 0.5, 0.0, 0.0);
434
    }
Alexander Lohnau's avatar
Alexander Lohnau committed
435
436
    if (edges & Qt::BottomEdge) {
        frameRect.adjust(0.0, 0.0, 0.0, -0.5);
437
438
    }

Alexander Lohnau's avatar
Alexander Lohnau committed
439
440
441
    // draw lines
    if (edges & Qt::LeftEdge) {
        painter->drawLine(QLineF(frameRect.topLeft(), frameRect.bottomLeft()));
442
    }
Alexander Lohnau's avatar
Alexander Lohnau committed
443
444
    if (edges & Qt::RightEdge) {
        painter->drawLine(QLineF(frameRect.topRight(), frameRect.bottomRight()));
445
    }
Alexander Lohnau's avatar
Alexander Lohnau committed
446
447
448
449
450
    if (edges & Qt::TopEdge) {
        painter->drawLine(QLineF(frameRect.topLeft(), frameRect.topRight()));
    }
    if (edges & Qt::BottomEdge) {
        painter->drawLine(QLineF(frameRect.bottomLeft(), frameRect.bottomRight()));
451
452
    }

Alexander Lohnau's avatar
Alexander Lohnau committed
453
454
    painter->restore();
}
Hugo Pereira Da Costa's avatar
cleanup    
Hugo Pereira Da Costa committed
455

Alexander Lohnau's avatar
Alexander Lohnau committed
456
457
458
459
//______________________________________________________________________________
void Helper::renderFrame(QPainter *painter, const QRect &rect, const QColor &color, const QColor &outline) const
{
    painter->setRenderHint(QPainter::Antialiasing);
460

Alexander Lohnau's avatar
Alexander Lohnau committed
461
462
    QRectF frameRect(rect.adjusted(1, 1, -1, -1));
    qreal radius(frameRadius(PenWidth::NoPen));
463

Alexander Lohnau's avatar
Alexander Lohnau committed
464
465
466
467
468
    // set pen
    if (outline.isValid()) {
        painter->setPen(outline);
        frameRect = strokedRect(frameRect);
        radius = frameRadiusForNewPenWidth(radius, PenWidth::Frame);
469

Alexander Lohnau's avatar
Alexander Lohnau committed
470
471
472
    } else {
        painter->setPen(Qt::NoPen);
    }
473

Alexander Lohnau's avatar
Alexander Lohnau committed
474
475
476
477
478
    // set brush
    if (color.isValid())
        painter->setBrush(color);
    else
        painter->setBrush(Qt::NoBrush);
479

Alexander Lohnau's avatar
Alexander Lohnau committed
480
481
482
    // render
    painter->drawRoundedRect(frameRect, radius, radius);
}
483

Alexander Lohnau's avatar
Alexander Lohnau committed
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
//______________________________________________________________________________
void Helper::renderSidePanelFrame(QPainter *painter, const QRect &rect, const QColor &outline, Side side) const
{
    // check color
    if (!outline.isValid())
        return;

    // adjust rect
    QRectF frameRect(strokedRect(rect));

    // setup painter
    painter->setRenderHint(QPainter::Antialiasing);
    painter->setPen(outline);

    // render
    switch (side) {
    default:
    case SideLeft:
        painter->drawLine(frameRect.topRight(), frameRect.bottomRight());
        break;

    case SideTop:
        painter->drawLine(frameRect.topLeft(), frameRect.topRight());
        break;

    case SideRight:
        painter->drawLine(frameRect.topLeft(), frameRect.bottomLeft());
        break;

    case SideBottom:
        painter->drawLine(frameRect.bottomLeft(), frameRect.bottomRight());
        break;

    case AllSides: {
        const qreal radius(frameRadius(PenWidth::Frame));
        painter->drawRoundedRect(frameRect, radius, radius);
        break;
    }
    }
}
524

Alexander Lohnau's avatar
Alexander Lohnau committed
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
//______________________________________________________________________________
void Helper::renderMenuFrame(QPainter *painter, const QRect &rect, const QColor &color, const QColor &outline, bool roundCorners, bool isTopMenu) const
{
    painter->save();

    // set brush
    if (color.isValid())
        painter->setBrush(color);
    else
        painter->setBrush(Qt::NoBrush);

    // We simulate being able to independently adjust corner radii by
    // setting a clip region and then extending the rectangle beyond it.
    if (isTopMenu) {
        painter->setClipRect(rect);
540
541
    }

Alexander Lohnau's avatar
Alexander Lohnau committed
542
543
544
545
    if (roundCorners) {
        painter->setRenderHint(QPainter::Antialiasing);
        QRectF frameRect(rect);
        qreal radius(frameRadius(PenWidth::NoPen));
546

Alexander Lohnau's avatar
Alexander Lohnau committed
547
548
        if (isTopMenu)
            frameRect.adjust(0, -radius, 0, 0);
549

Alexander Lohnau's avatar
Alexander Lohnau committed
550
551
552
553
554
        // set pen
        if (outline.isValid()) {
            painter->setPen(outline);
            frameRect = strokedRect(frameRect);
            radius = frameRadiusForNewPenWidth(radius, PenWidth::Frame);
555

Alexander Lohnau's avatar
Alexander Lohnau committed
556
557
        } else
            painter->setPen(Qt::NoPen);
558

559
        // render
Alexander Lohnau's avatar
Alexander Lohnau committed
560
        painter->drawRoundedRect(frameRect, radius, radius);
561

Alexander Lohnau's avatar
Alexander Lohnau committed
562
563
564
565
566
    } else {
        painter->setRenderHint(QPainter::Antialiasing, false);
        QRect frameRect(rect);
        if (isTopMenu)
            frameRect.adjust(0, 1, 0, 0);
567

Alexander Lohnau's avatar
Alexander Lohnau committed
568
569
570
        if (outline.isValid()) {
            painter->setPen(outline);
            frameRect.adjust(0, 0, -1, -1);
571

Alexander Lohnau's avatar
Alexander Lohnau committed
572
573
        } else
            painter->setPen(Qt::NoPen);
574

Alexander Lohnau's avatar
Alexander Lohnau committed
575
        painter->drawRect(frameRect);
576
577
    }

Alexander Lohnau's avatar
Alexander Lohnau committed
578
579
    painter->restore();
}
580

Alexander Lohnau's avatar
Alexander Lohnau committed
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
//______________________________________________________________________________
void Helper::renderButtonFrame(QPainter *painter,
                               const QRect &rect,
                               const QPalette &palette,
                               const QHash<QByteArray, bool> &stateProperties,
                               qreal bgAnimation,
                               qreal penAnimation) const
{
    bool enabled = stateProperties.value("enabled", true);
    bool visualFocus = stateProperties.value("visualFocus");
    bool hovered = stateProperties.value("hovered");
    bool down = stateProperties.value("down");
    bool checked = stateProperties.value("checked");
    bool flat = stateProperties.value("flat");
    bool defaultButton = stateProperties.value("defaultButton");
    bool hasNeutralHighlight = stateProperties.value("hasNeutralHighlight");
    bool isActiveWindow = stateProperties.value("isActiveWindow");

    // don't render background if flat and not hovered, down, checked, or given visual focus
    if (flat && !(hovered || down || checked || visualFocus) && bgAnimation == AnimationData::OpacityInvalid && penAnimation == AnimationData::OpacityInvalid) {
        return;
602
603
    }

Alexander Lohnau's avatar
Alexander Lohnau committed
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
    QRectF shadowedRect = this->shadowedRect(rect);
    QRectF frameRect = strokedRect(shadowedRect);
    qreal radius = frameRadius(PenWidth::Frame);
    // setting color group to work around KColorScheme feature
    const QColor &highlightColor = palette.color(!enabled ? QPalette::Disabled : QPalette::Active, QPalette::Highlight);
    QBrush bgBrush;
    QBrush penBrush;

    // Colors
    if (flat) {
        if (down && enabled) {
            bgBrush = alphaColor(highlightColor, highlightBackgroundAlpha);
        } else if (checked) {
            bgBrush = hasNeutralHighlight ? alphaColor(neutralText(palette), highlightBackgroundAlpha) : alphaColor(palette.buttonText().color(), 0.125);
            penBrush = hasNeutralHighlight ? neutralText(palette) : KColorUtils::mix(palette.button().color(), palette.buttonText().color(), 0.3);
        } else if (isActiveWindow && defaultButton) {
            bgBrush = alphaColor(highlightColor, 0.125);
            penBrush = KColorUtils::mix(highlightColor, KColorUtils::mix(palette.button().color(), palette.buttonText().color(), 0.333), 0.5);
622
        } else {
Alexander Lohnau's avatar
Alexander Lohnau committed
623
624
            bgBrush = alphaColor(highlightColor, 0);
            penBrush = hasNeutralHighlight ? neutralText(palette) : bgBrush;
625
        }
Alexander Lohnau's avatar
Alexander Lohnau committed
626
627
628
629
630
631
632
633
634
635
636
637
638
    } else {
        if (down && enabled) {
            bgBrush = KColorUtils::mix(palette.button().color(), highlightColor, 0.333);
        } else if (checked) {
            bgBrush = hasNeutralHighlight ? KColorUtils::mix(palette.button().color(), neutralText(palette), 0.333)
                                          : KColorUtils::mix(palette.button().color(), palette.buttonText().color(), 0.125);
            penBrush = hasNeutralHighlight ? neutralText(palette) : KColorUtils::mix(palette.button().color(), palette.buttonText().color(), 0.3);
        } else if (isActiveWindow && defaultButton) {
            bgBrush = KColorUtils::mix(palette.button().color(), highlightColor, 0.2);
            penBrush = KColorUtils::mix(highlightColor, KColorUtils::mix(palette.button().color(), palette.buttonText().color(), 0.333), 0.5);
        } else {
            bgBrush = palette.button().color();
            penBrush = hasNeutralHighlight ? neutralText(palette) : KColorUtils::mix(palette.button().color(), palette.buttonText().color(), 0.3);
639
640
641
        }
    }

Alexander Lohnau's avatar
Alexander Lohnau committed
642
643
    if ((hovered || visualFocus || down) && enabled) {
        penBrush = highlightColor;
644
645
    }

Alexander Lohnau's avatar
Alexander Lohnau committed
646
647
648
649
650
    // Animations
    if (bgAnimation != AnimationData::OpacityInvalid && enabled) {
        QColor color1 = bgBrush.color();
        QColor color2 = flat ? alphaColor(highlightColor, highlightBackgroundAlpha) : KColorUtils::mix(palette.button().color(), highlightColor, 0.333);
        bgBrush = KColorUtils::mix(color1, color2, bgAnimation);
651
    }
Alexander Lohnau's avatar
Alexander Lohnau committed
652
653
654
655
    if (penAnimation != AnimationData::OpacityInvalid && enabled) {
        QColor color1 = penBrush.color();
        QColor color2 = highlightColor;
        penBrush = KColorUtils::mix(color1, color2, penAnimation);
Hugo Pereira Da Costa's avatar
Hugo Pereira Da Costa committed
656
657
    }

Alexander Lohnau's avatar
Alexander Lohnau committed
658
659
660
661
    // Shadow
    if (isActiveWindow && !(flat || down || checked) && enabled) {
        renderRoundedRectShadow(painter, shadowedRect, shadowColor(palette));
    }
662

Alexander Lohnau's avatar
Alexander Lohnau committed
663
664
665
666
667
668
    // Render button
    painter->setRenderHint(QPainter::Antialiasing, true);
    painter->setBrush(bgBrush);
    painter->setPen(QPen(penBrush, PenWidth::Frame));
    painter->drawRoundedRect(frameRect, radius, radius);
}
669

Alexander Lohnau's avatar
Alexander Lohnau committed
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
//______________________________________________________________________________
void Helper::renderToolBoxFrame(QPainter *painter, const QRect &rect, int tabWidth, const QColor &outline) const
{
    if (!outline.isValid())
        return;

    // round radius
    const qreal radius(frameRadius(PenWidth::Frame));
    const QSizeF cornerSize(2 * radius, 2 * radius);

    // if rect - tabwidth is even, need to increase tabWidth by 1 unit
    // for anti aliasing
    if (!((rect.width() - tabWidth) % 2))
        ++tabWidth;

    // adjust rect for antialiasing
    QRectF baseRect(strokedRect(rect));

    // create path
    QPainterPath path;
    path.moveTo(0, baseRect.height() - 1);
    path.lineTo((baseRect.width() - tabWidth) / 2 - radius, baseRect.height() - 1);
    path.arcTo(QRectF(QPointF((baseRect.width() - tabWidth) / 2 - 2 * radius, baseRect.height() - 1 - 2 * radius), cornerSize), 270, 90);
    path.lineTo((baseRect.width() - tabWidth) / 2, radius);
    path.arcTo(QRectF(QPointF((baseRect.width() - tabWidth) / 2, 0), cornerSize), 180, -90);
    path.lineTo((baseRect.width() + tabWidth) / 2 - 1 - radius, 0);
    path.arcTo(QRectF(QPointF((baseRect.width() + tabWidth) / 2 - 1 - 2 * radius, 0), cornerSize), 90, -90);
    path.lineTo((baseRect.width() + tabWidth) / 2 - 1, baseRect.height() - 1 - radius);
    path.arcTo(QRectF(QPointF((baseRect.width() + tabWidth) / 2 - 1, baseRect.height() - 1 - 2 * radius), cornerSize), 180, 90);
    path.lineTo(baseRect.width() - 1, baseRect.height() - 1);

    // render
    painter->setRenderHints(QPainter::Antialiasing);
    painter->setBrush(Qt::NoBrush);
    painter->setPen(outline);
    painter->translate(baseRect.topLeft());
    painter->drawPath(path);
}
708

Alexander Lohnau's avatar
Alexander Lohnau committed
709
710
711
712
//______________________________________________________________________________
void Helper::renderTabWidgetFrame(QPainter *painter, const QRect &rect, const QColor &color, const QColor &outline, Corners corners) const
{
    painter->setRenderHint(QPainter::Antialiasing);
713

Alexander Lohnau's avatar
Alexander Lohnau committed
714
715
    QRectF frameRect(rect.adjusted(1, 1, -1, -1));
    qreal radius(frameRadius(PenWidth::NoPen));
716

Alexander Lohnau's avatar
Alexander Lohnau committed
717
718
719
    // set pen
    if (outline.isValid()) {
        painter->setPen(outline);
720
        frameRect = strokedRect(frameRect);
Alexander Lohnau's avatar
Alexander Lohnau committed
721
        radius = frameRadiusForNewPenWidth(radius, PenWidth::Frame);
722

Alexander Lohnau's avatar
Alexander Lohnau committed
723
724
    } else
        painter->setPen(Qt::NoPen);
725

Alexander Lohnau's avatar
Alexander Lohnau committed
726
727
728
729
730
    // set brush
    if (color.isValid())
        painter->setBrush(color);
    else
        painter->setBrush(Qt::NoBrush);
731

Alexander Lohnau's avatar
Alexander Lohnau committed
732
733
734
735
    // render
    QPainterPath path(roundedPath(frameRect, corners, radius));
    painter->drawPath(path);
}
736

Alexander Lohnau's avatar
Alexander Lohnau committed
737
738
739
740
741
742
743
744
//______________________________________________________________________________
void Helper::renderSelection(QPainter *painter, const QRect &rect, const QColor &color) const
{
    painter->setRenderHint(QPainter::Antialiasing);
    painter->setPen(Qt::NoPen);
    painter->setBrush(color);
    painter->drawRect(rect);
}
745

Alexander Lohnau's avatar
Alexander Lohnau committed
746
747
748
749
750
751
//______________________________________________________________________________
void Helper::renderSeparator(QPainter *painter, const QRect &rect, const QColor &color, bool vertical) const
{
    painter->setRenderHint(QPainter::Antialiasing, false);
    painter->setBrush(Qt::NoBrush);
    painter->setPen(color);
752

Alexander Lohnau's avatar
Alexander Lohnau committed
753
754
755
    if (vertical) {
        painter->translate(rect.width() / 2, 0);
        painter->drawLine(rect.topLeft(), rect.bottomLeft());
756

Alexander Lohnau's avatar
Alexander Lohnau committed
757
758
759
    } else {
        painter->translate(0, rect.height() / 2);
        painter->drawLine(rect.topLeft(), rect.topRight());
760
    }
Alexander Lohnau's avatar
Alexander Lohnau committed
761
}
762

Alexander Lohnau's avatar
Alexander Lohnau committed
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
//______________________________________________________________________________
void Helper::renderCheckBoxBackground(QPainter *painter,
                                      const QRect &rect,
                                      const QPalette &palette,
                                      CheckBoxState state,
                                      bool neutalHighlight,
                                      bool sunken,
                                      qreal animation) const
{
    // setup painter
    painter->setRenderHint(QPainter::Antialiasing, true);

    // copy rect
    QRectF frameRect(rect);
    frameRect.adjust(2, 2, -2, -2);
    frameRect = strokedRect(frameRect);

    auto transparent = neutalHighlight ? neutralText(palette) : palette.highlight().color();
    transparent.setAlphaF(highlightBackgroundAlpha);

    QBrush penBrush;
    if (neutalHighlight) {
        penBrush = neutralText(palette);
    } else if (state == CheckOn || state == CheckPartial) {
        penBrush = palette.highlight().color();
    } else {
        penBrush = transparentize(palette.text().color(), highlightBackgroundAlpha);
    }
    painter->setPen(QPen(penBrush, PenWidth::Frame));
792

Alexander Lohnau's avatar
Alexander Lohnau committed
793
    const auto radius = Metrics::CheckBox_Radius;
794

Alexander Lohnau's avatar
Alexander Lohnau committed
795
796
797
798
799
    switch (state) {
    case CheckOff:
        painter->setBrush(palette.base().color().darker(sunken ? radioCheckSunkenDarkeningFactor : 100));
        painter->drawRoundedRect(frameRect, radius, radius);
        break;
800

Alexander Lohnau's avatar
Alexander Lohnau committed
801
802
803
804
805
    case CheckPartial:
    case CheckOn:
        painter->setBrush(transparent);
        painter->drawRoundedRect(frameRect, radius, radius);
        break;
806

Alexander Lohnau's avatar
Alexander Lohnau committed
807
808
809
810
811
812
813
814
815
    case CheckAnimated:
        painter->setBrush(palette.base().color().darker(sunken ? radioCheckSunkenDarkeningFactor : 100));
        painter->drawRoundedRect(frameRect, radius, radius);
        painter->setBrush(transparent);
        painter->setOpacity(animation);
        painter->drawRoundedRect(frameRect, radius, radius);
        break;
    }
}
816

Alexander Lohnau's avatar
Alexander Lohnau committed
817
818
819
820
821
822
823
824
825
826
827
828
829
//______________________________________________________________________________
void Helper::renderCheckBox(QPainter *painter,
                            const QRect &rect,
                            const QPalette &palette,
                            bool mouseOver,
                            CheckBoxState state,
                            CheckBoxState target,
                            bool neutalHighlight,
                            bool sunken,
                            qreal animation,
                            qreal hoverAnimation) const
{
    Q_UNUSED(sunken)
830

Alexander Lohnau's avatar
Alexander Lohnau committed
831
832
    // setup painter
    painter->setRenderHint(QPainter::Antialiasing, true);
833

Alexander Lohnau's avatar
Alexander Lohnau committed
834
835
836
    // copy rect and radius
    QRectF frameRect(rect);
    frameRect.adjust(2, 2, -2, -2);
837

Alexander Lohnau's avatar
Alexander Lohnau committed
838
839
    if (mouseOver) {
        painter->save();
840

Alexander Lohnau's avatar
Alexander Lohnau committed
841
842
843
        if (hoverAnimation != AnimationData::OpacityInvalid) {
            painter->setOpacity(hoverAnimation);
        }
844

Alexander Lohnau's avatar
Alexander Lohnau committed
845
846
        painter->setPen(QPen(neutalHighlight ? neutralText(palette).lighter() : focusColor(palette), PenWidth::Frame));
        painter->setBrush(Qt::NoBrush);
847

Alexander Lohnau's avatar
Alexander Lohnau committed
848
        painter->drawRoundedRect(frameRect.adjusted(0.5, 0.5, -0.5, -0.5), Metrics::CheckBox_Radius, Metrics::CheckBox_Radius);
849

Alexander Lohnau's avatar
Alexander Lohnau committed
850
851
        painter->restore();
    }
852

Alexander Lohnau's avatar
Alexander Lohnau committed
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
    // check
    auto leftPoint = frameRect.center();
    leftPoint.setX(frameRect.left() + 4);

    auto bottomPoint = frameRect.center();
    bottomPoint.setX(bottomPoint.x() - 1);
    bottomPoint.setY(frameRect.bottom() - 5);

    auto rightPoint = frameRect.center();
    rightPoint.setX(rightPoint.x() + 4.5);
    rightPoint.setY(frameRect.top() + 5.5);

    QPainterPath path;
    path.moveTo(leftPoint);
    path.lineTo(bottomPoint);
    path.lineTo(rightPoint);

    // dots
    auto centerDot = QRectF(frameRect.center(), QSize(2, 2));
    centerDot.adjust(-1, -1, -1, -1);
    auto leftDot = centerDot.adjusted(-4, 0, -4, 0);
    auto rightDot = centerDot.adjusted(4, 0, 4, 0);

    painter->setPen(Qt::transparent);
    painter->setBrush(Qt::transparent);

    auto checkPen = QPen(palette.text(), PenWidth::Frame * 2);
    checkPen.setJoinStyle(Qt::MiterJoin);

    switch (state) {
    case CheckOff:
        break;
    case CheckOn:
        painter->setPen(checkPen);
        painter->drawPath(path);
        break;
    case CheckPartial:
        painter->setBrush(palette.text());
        painter->drawRect(leftDot);
        painter->drawRect(centerDot);
        painter->drawRect(rightDot);
        break;
    case CheckAnimated:
        checkPen.setDashPattern({path.length() * animation, path.length()});

        switch (target) {
899
900
901
        case CheckOff:
            break;
        case CheckOn:
Alexander Lohnau's avatar
Alexander Lohnau committed
902
903
            painter->setPen(checkPen);
            painter->drawPath(path);
904
905
            break;
        case CheckPartial:
Alexander Lohnau's avatar
Alexander Lohnau committed
906
907
908
909
910
911
            if (animation >= 3 / 3)
                painter->drawRect(rightDot);
            if (animation >= 2 / 3)
                painter->drawRect(centerDot);
            if (animation >= 1 / 3)
                painter->drawRect(leftDot);
912
913
914
            break;
        case CheckAnimated:
            break;
915
        }
Alexander Lohnau's avatar
Alexander Lohnau committed
916
        break;
917
    }
Alexander Lohnau's avatar
Alexander Lohnau committed
918
}
919

Alexander Lohnau's avatar
Alexander Lohnau committed
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
//______________________________________________________________________________
void Helper::renderRadioButtonBackground(QPainter *painter,
                                         const QRect &rect,
                                         const QPalette &palette,
                                         RadioButtonState state,
                                         bool neutalHighlight,
                                         bool sunken,
                                         qreal animation) const
{
    // setup painter
    painter->setRenderHint(QPainter::Antialiasing, true);

    // copy rect
    QRectF frameRect(rect);
    frameRect.adjust(2, 2, -2, -2);
    frameRect.adjust(0.5, 0.5, -0.5, -0.5);

    auto transparent = neutalHighlight ? neutralText(palette) : palette.highlight().color();
    transparent.setAlphaF(highlightBackgroundAlpha);

    QBrush penBrush;
    if (neutalHighlight) {
        penBrush = neutralText(palette);
    } else if (state == RadioOn) {
        penBrush = palette.highlight().color();
    } else {
        penBrush = transparentize(palette.text().color(), highlightBackgroundAlpha);
947
    }
Alexander Lohnau's avatar
Alexander Lohnau committed
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
    painter->setPen(QPen(penBrush, PenWidth::Frame));

    switch (state) {
    case RadioOff:
        painter->setBrush(palette.base().color().darker(sunken ? radioCheckSunkenDarkeningFactor : 100));
        painter->drawEllipse(frameRect);
        break;
    case RadioOn:
        painter->setBrush(transparent);
        painter->drawEllipse(frameRect);
        break;
    case RadioAnimated:
        painter->setBrush(palette.base().color().darker(sunken ? radioCheckSunkenDarkeningFactor : 100));
        painter->drawEllipse(frameRect);
        painter->setBrush(transparent);
        painter->setOpacity(animation);
        painter->drawEllipse(frameRect);
        break;
966
    }
Alexander Lohnau's avatar
Alexander Lohnau committed
967
}
968

Alexander Lohnau's avatar
Alexander Lohnau committed
969
970
971
972
973
974
975
976
977
978
979
980
//______________________________________________________________________________
void Helper::renderRadioButton(QPainter *painter,
                               const QRect &rect,
                               const QPalette &palette,
                               bool mouseOver,
                               RadioButtonState state,
                               bool neutralHighlight,
                               bool sunken,
                               qreal animation,
                               qreal animationHover) const
{
    Q_UNUSED(sunken)
981

Alexander Lohnau's avatar
Alexander Lohnau committed
982
983
    // setup painter
    painter->setRenderHint(QPainter::Antialiasing, true);
984

Alexander Lohnau's avatar
Alexander Lohnau committed
985
986
987
    // copy rect
    QRectF frameRect(rect);
    frameRect.adjust(1, 1, -1, -1);
988

Alexander Lohnau's avatar
Alexander Lohnau committed
989
990
    if (mouseOver) {
        painter->save();
991

Alexander Lohnau's avatar
Alexander Lohnau committed
992
993
        if (animationHover != AnimationData::OpacityInvalid) {
            painter->setOpacity(animationHover);
994
        }
995

Alexander Lohnau's avatar
Alexander Lohnau committed
996
997
        painter->setPen(QPen(neutralHighlight ? neutralText(palette).lighter() : focusColor(palette), PenWidth::Frame));
        painter->setBrush(Qt::NoBrush);
998

Alexander Lohnau's avatar
Alexander Lohnau committed
999
1000
        const QRectF contentRect(frameRect.adjusted(1, 1, -1, -1).adjusted(0.5, 0.5, -0.5, -0.5));
        painter->drawEllipse(contentRect);
1001

Alexander Lohnau's avatar
Alexander Lohnau committed
1002
1003
        painter->restore();
    }
1004

Alexander Lohnau's avatar
Alexander Lohnau committed
1005
1006
    painter->setBrush(palette.text());
    painter->setPen(Qt::NoPen);
1007

Alexander Lohnau's avatar
Alexander Lohnau committed
1008
1009
    QRectF markerRect;
    markerRect = frameRect.adjusted(6, 6, -6, -6);
1010

Alexander Lohnau's avatar
Alexander Lohnau committed
1011
    qreal adjustFactor;
1012

Alexander Lohnau's avatar
Alexander Lohnau committed
1013
1014
1015
1016
    // mark
    switch (state) {
    case RadioOn:
        painter->drawEllipse(markerRect);
1017

Alexander Lohnau's avatar
Alexander Lohnau committed
1018
1019
1020
1021
1022
        break;
    case RadioAnimated:
        adjustFactor = markerRect.height() * (1 - animation);
        markerRect.adjust(adjustFactor, adjustFactor, -adjustFactor, -adjustFactor);
        painter->drawEllipse(markerRect);
1023

Alexander Lohnau's avatar
Alexander Lohnau committed
1024
1025
1026
        break;
    default:
        break;
1027
    }
Alexander Lohnau's avatar
Alexander Lohnau committed
1028
}
1029

Alexander Lohnau's avatar
Alexander Lohnau committed
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
//______________________________________________________________________________
void Helper::renderSliderGroove(QPainter *painter, const QRect &rect, const QColor &color) const
{
    // setup painter
    painter->setRenderHint(QPainter::Antialiasing, true);

    QRectF baseRect(rect);
    baseRect.adjust(0.5, 0.5, -0.5, -0.5);
    const qreal radius(0.5 * Metrics::Slider_GrooveThickness);

    // content
    if (color.isValid()) {
        painter->setPen(QPen(color, PenWidth::Frame));
        auto bg = color;
        bg.setAlphaF(bg.alphaF() / 2);
        painter->setBrush(bg);
        painter->drawRoundedRect(baseRect, radius, radius);
    }
}
1049

Alexander Lohnau's avatar
Alexander Lohnau committed
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
//______________________________________________________________________________
void Helper::renderDialGroove(QPainter *painter, const QRect &rect, const QColor &fg, const QColor &bg, qreal first, qreal last) const
{
    // setup painter
    painter->setRenderHint(QPainter::Antialiasing, true);

    const QRectF baseRect(rect);

    // content
    if (fg.isValid()) {
        const qreal penWidth(Metrics::Slider_GrooveThickness);
        const QRectF grooveRect(rect.adjusted(penWidth / 2, penWidth / 2, -penWidth / 2, -penWidth / 2));

        // setup angles
        const int angleStart(first * 180 * 16 / M_PI);
        const int angleSpan((last - first) * 180 * 16 / M_PI);

        const QPen bgPen(fg, penWidth, Qt::SolidLine, Qt::RoundCap);
        const QPen fgPen(KColorUtils::overlayColors(bg, alphaColor(fg, 0.5)), penWidth - 2, Qt::SolidLine, Qt::RoundCap);

        // setup pen
        if (angleSpan != 0) {
            painter->setPen(bgPen);
            painter->setBrush(Qt::NoBrush);
            painter->drawArc(grooveRect, angleStart, angleSpan);
            painter->setPen(fgPen);
            painter->drawArc(grooveRect, angleStart, angleSpan);
1077
1078
        }
    }
Alexander Lohnau's avatar
Alexander Lohnau committed
1079
}
1080

Alexander Lohnau's avatar
Alexander Lohnau committed
1081
1082
1083
1084
1085
//______________________________________________________________________________
void Helper::renderSliderHandle(QPainter *painter, const QRect &rect, const QColor &color, const QColor &outline, const QColor &shadow, bool sunken) const
{
    // setup painter
    painter->setRenderHint(QPainter::Antialiasing, true);
1086

Alexander Lohnau's avatar
Alexander Lohnau committed
1087
1088
1089
    // copy rect
    QRectF frameRect(rect);
    frameRect.adjust(1, 1, -1, -1);
1090

Alexander Lohnau's avatar
Alexander Lohnau committed
1091
1092
1093
1094
    // shadow
    if (!sunken) {
        renderEllipseShadow(painter, frameRect, shadow);
    }
1095

Alexander Lohnau's avatar
Alexander Lohnau committed
1096
1097
1098
1099
    // set pen
    if (outline.isValid()) {
        painter->setPen(QPen(outline, PenWidth::Frame));
        frameRect = strokedRect(frameRect);
1100

Alexander Lohnau's avatar
Alexander Lohnau committed
1101
1102
    } else
        painter->setPen(Qt::NoPen);
1103

Alexander Lohnau's avatar
Alexander Lohnau committed
1104
1105
1106
1107
1108
    // set brush
    if (color.isValid())
        painter->setBrush(color);
    else
        painter->setBrush(Qt::NoBrush);
1109

Alexander Lohnau's avatar
Alexander Lohnau committed
1110
1111
1112
    // render
    painter->drawEllipse(frameRect);
}
1113

Alexander Lohnau's avatar
Alexander Lohnau committed
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
//______________________________________________________________________________
void Helper::renderProgressBarGroove(QPainter *painter, const QRect &rect, const QColor &fg, const QColor &bg) const
{
    // setup painter
    painter->setRenderHint(QPainter::Antialiasing, true);

    QRectF baseRect(rect);
    baseRect.adjust(0.5, 0.5, -0.5, -0.5);
    const qreal radius(0.5 * Metrics::ProgressBar_Thickness);

    // content
    if (fg.isValid()) {
        painter->setPen(QPen(fg, PenWidth::Frame));
        painter->setBrush(KColorUtils::overlayColors(bg, alphaColor(fg, 0.5)));
        painter->drawRoundedRect(baseRect, radius, radius);
    }
}
1131

Alexander Lohnau's avatar
Alexander Lohnau committed
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
//______________________________________________________________________________
void Helper::renderProgressBarBusyContents(QPainter *painter,
                                           const QRect &rect,
                                           const QColor &first,
                                           const QColor &second,
                                           bool horizontal,
                                           bool reverse,
                                           int progress) const
{
    // setup painter
    painter->setRenderHint(QPainter::Antialiasing, true);

    const QRectF baseRect(rect);
    const qreal radius(0.5 * Metrics::ProgressBar_Thickness);

    // setup brush
    QPixmap pixmap(horizontal ? 2 * Metrics::ProgressBar_BusyIndicatorSize : 1, horizontal ? 1 : 2 * Metrics::ProgressBar_BusyIndicatorSize);
    pixmap.fill(second);
    if (horizontal) {
        QPainter painter(&pixmap);
        painter.setBrush(first);
        painter.setPen(Qt::NoPen);

        progress %= 2 * Metrics::ProgressBar_BusyIndicatorSize;
        if (reverse)
            progress = 2 * Metrics::ProgressBar_BusyIndicatorSize - progress - 1;
        painter.drawRect(QRect(0, 0, Metrics::ProgressBar_BusyIndicatorSize, 1).translated(progress, 0));

        if (progress > Metrics::ProgressBar_BusyIndicatorSize) {
            painter.drawRect(QRect(0, 0, Metrics::ProgressBar_BusyIndicatorSize, 1).translated(progress - 2 * Metrics::ProgressBar_BusyIndicatorSize, 0));
        }
1163

Alexander Lohnau's avatar
Alexander Lohnau committed
1164
1165
1166
1167
    } else {
        QPainter painter(&pixmap);
        painter.setBrush(first);
        painter.setPen(Qt::NoPen);
1168

Alexander Lohnau's avatar
Alexander Lohnau committed
1169
1170
1171
        progress %= 2 * Metrics::ProgressBar_BusyIndicatorSize;
        progress = 2 * Metrics::ProgressBar_BusyIndicatorSize - progress - 1;
        painter.drawRect(QRect(0, 0, 1, Metrics::ProgressBar_BusyIndicatorSize).translated(0, progress));
1172

Alexander Lohnau's avatar
Alexander Lohnau committed
1173
1174
        if (progress > Metrics::ProgressBar_BusyIndicatorSize) {
            painter.drawRect(QRect(0, 0, 1, Metrics::ProgressBar_BusyIndicatorSize).translated(0, progress - 2 * Metrics::ProgressBar_BusyIndicatorSize));
1175
1176
1177
        }
    }

Alexander Lohnau's avatar
Alexander Lohnau committed
1178
1179
1180
1181
    painter->setPen(Qt::NoPen);
    painter->setBrush(pixmap);
    painter->drawRoundedRect(baseRect, radius, radius);
}
1182

Alexander Lohnau's avatar
Alexander Lohnau committed
1183
1184
1185
1186
1187
//______________________________________________________________________________
void Helper::renderScrollBarHandle(QPainter *painter, const QRect &rect, const QColor &fg, const QColor &bg) const
{
    // setup painter
    painter->setRenderHint(QPainter::Antialiasing, true);
1188

Alexander Lohnau's avatar
Alexander Lohnau committed
1189
1190
    const QRectF baseRect(rect);
    const qreal radius(0.5 * std::min({baseRect.width(), baseRect.height(), (qreal)Metrics::ScrollBar_SliderWidth}));
1191

Alexander Lohnau's avatar
Alexander Lohnau committed
1192
1193
1194
1195
1196
    painter->setPen(Qt::NoPen);
    painter->setPen(QPen(fg, 1.001));
    painter->setBrush(KColorUtils::overlayColors(bg, alphaColor(fg, 0.5)));
    painter->drawRoundedRect(strokedRect(baseRect), radius, radius);
}
1197

Alexander Lohnau's avatar
Alexander Lohnau committed
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
void Helper::renderScrollBarGroove(QPainter *painter, const QRect &rect, const QColor &color) const
{
    // setup painter
    painter->setRenderHint(QPainter::Antialiasing, true);

    const QRectF baseRect(rect);
    const qreal radius(0.5 * std::min({baseRect.width(), baseRect.height(), (qreal)Metrics::ScrollBar_SliderWidth}));

    // content
    if (color.isValid()) {
        painter->setPen(Qt::NoPen);
        auto bg = color;
        bg.setAlphaF(bg.alphaF() / 2.0);
        painter->setBrush(bg);
        painter->setPen(QPen(color, 1.001));
        painter->drawRoundedRect(strokedRect(baseRect), radius, radius);
1214
    }
Alexander Lohnau's avatar
Alexander Lohnau committed
1215
}
1216

Alexander Lohnau's avatar
Alexander Lohnau committed
1217
1218
1219
1220
1221
1222
1223
1224
//______________________________________________________________________________
void Helper::renderScrollBarBorder(QPainter *painter, const QRect &rect, const QColor &color) const
{
    // content
    if (color.isValid()) {
        painter->setPen(Qt::NoPen);
        painter->setBrush(color);
        painter->drawRect(rect);
1225
    }
Alexander Lohnau's avatar
Alexander Lohnau committed
1226
}
1227

Alexander Lohnau's avatar
Alexander Lohnau committed
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
//______________________________________________________________________________
void Helper::renderTabBarTab(QPainter *painter,
                             const QRect &rect,
                             const QPalette &palette,
                             const QHash<QByteArray, bool> &stateProperties,
                             Corners corners,
                             qreal animation) const
{
    bool enabled = stateProperties.value("enabled", true);
    bool <