Changeset View
Changeset View
Standalone View
Standalone View
kdecoration/breezedecoration.cpp
Show All 22 Lines | |||||
23 | #include "breezedecoration.h" | 23 | #include "breezedecoration.h" | ||
24 | 24 | | |||
25 | #include "breeze.h" | 25 | #include "breeze.h" | ||
26 | #include "breezesettingsprovider.h" | 26 | #include "breezesettingsprovider.h" | ||
27 | #include "config-breeze.h" | 27 | #include "config-breeze.h" | ||
28 | #include "config/breezeconfigwidget.h" | 28 | #include "config/breezeconfigwidget.h" | ||
29 | 29 | | |||
30 | #include "breezebutton.h" | 30 | #include "breezebutton.h" | ||
31 | #include "breezedecorationshadow.h" | ||||
31 | #include "breezesizegrip.h" | 32 | #include "breezesizegrip.h" | ||
32 | 33 | | |||
33 | #include "breezeboxshadowrenderer.h" | 34 | #include "breezeboxshadowrenderer.h" | ||
34 | 35 | | |||
35 | #include <KDecoration2/DecoratedClient> | 36 | #include <KDecoration2/DecoratedClient> | ||
36 | #include <KDecoration2/DecorationButtonGroup> | 37 | #include <KDecoration2/DecorationButtonGroup> | ||
37 | #include <KDecoration2/DecorationSettings> | 38 | #include <KDecoration2/DecorationSettings> | ||
38 | #include <KDecoration2/DecorationShadow> | 39 | #include <KDecoration2/DecorationShadow> | ||
Show All 17 Lines | |||||
56 | K_PLUGIN_FACTORY_WITH_JSON( | 57 | K_PLUGIN_FACTORY_WITH_JSON( | ||
57 | BreezeDecoFactory, | 58 | BreezeDecoFactory, | ||
58 | "breeze.json", | 59 | "breeze.json", | ||
59 | registerPlugin<Breeze::Decoration>(); | 60 | registerPlugin<Breeze::Decoration>(); | ||
60 | registerPlugin<Breeze::Button>(QStringLiteral("button")); | 61 | registerPlugin<Breeze::Button>(QStringLiteral("button")); | ||
61 | registerPlugin<Breeze::ConfigWidget>(QStringLiteral("kcmodule")); | 62 | registerPlugin<Breeze::ConfigWidget>(QStringLiteral("kcmodule")); | ||
62 | ) | 63 | ) | ||
63 | 64 | | |||
64 | namespace | | |||
65 | { | | |||
66 | struct ShadowParams { | | |||
67 | ShadowParams() | | |||
68 | : offset(QPoint(0, 0)) | | |||
69 | , radius(0) | | |||
70 | , opacity(0) {} | | |||
71 | | ||||
72 | ShadowParams(const QPoint &offset, int radius, qreal opacity) | | |||
73 | : offset(offset) | | |||
74 | , radius(radius) | | |||
75 | , opacity(opacity) {} | | |||
76 | | ||||
77 | QPoint offset; | | |||
78 | int radius; | | |||
79 | qreal opacity; | | |||
80 | }; | | |||
81 | | ||||
82 | struct CompositeShadowParams { | | |||
83 | CompositeShadowParams() = default; | | |||
84 | | ||||
85 | CompositeShadowParams( | | |||
86 | const QPoint &offset, | | |||
87 | const ShadowParams &shadow1, | | |||
88 | const ShadowParams &shadow2) | | |||
89 | : offset(offset) | | |||
90 | , shadow1(shadow1) | | |||
91 | , shadow2(shadow2) {} | | |||
92 | | ||||
93 | bool isNone() const { | | |||
94 | return qMax(shadow1.radius, shadow2.radius) == 0; | | |||
95 | } | | |||
96 | | ||||
97 | QPoint offset; | | |||
98 | ShadowParams shadow1; | | |||
99 | ShadowParams shadow2; | | |||
100 | }; | | |||
101 | | ||||
102 | const CompositeShadowParams s_shadowParams[] = { | | |||
103 | // None | | |||
104 | CompositeShadowParams(), | | |||
105 | // Small | | |||
106 | CompositeShadowParams( | | |||
107 | QPoint(0, 4), | | |||
108 | ShadowParams(QPoint(0, 0), 16, 1), | | |||
109 | ShadowParams(QPoint(0, -2), 8, 0.4)), | | |||
110 | // Medium | | |||
111 | CompositeShadowParams( | | |||
112 | QPoint(0, 8), | | |||
113 | ShadowParams(QPoint(0, 0), 32, 0.9), | | |||
114 | ShadowParams(QPoint(0, -4), 16, 0.3)), | | |||
115 | // Large | | |||
116 | CompositeShadowParams( | | |||
117 | QPoint(0, 12), | | |||
118 | ShadowParams(QPoint(0, 0), 48, 0.8), | | |||
119 | ShadowParams(QPoint(0, -6), 24, 0.2)), | | |||
120 | // Very large | | |||
121 | CompositeShadowParams( | | |||
122 | QPoint(0, 16), | | |||
123 | ShadowParams(QPoint(0, 0), 64, 0.7), | | |||
124 | ShadowParams(QPoint(0, -8), 32, 0.1)), | | |||
125 | }; | | |||
126 | | ||||
127 | inline CompositeShadowParams lookupShadowParams(int size) | | |||
128 | { | | |||
129 | switch (size) { | | |||
130 | case Breeze::InternalSettings::ShadowNone: | | |||
131 | return s_shadowParams[0]; | | |||
132 | case Breeze::InternalSettings::ShadowSmall: | | |||
133 | return s_shadowParams[1]; | | |||
134 | case Breeze::InternalSettings::ShadowMedium: | | |||
135 | return s_shadowParams[2]; | | |||
136 | case Breeze::InternalSettings::ShadowLarge: | | |||
137 | return s_shadowParams[3]; | | |||
138 | case Breeze::InternalSettings::ShadowVeryLarge: | | |||
139 | return s_shadowParams[4]; | | |||
140 | default: | | |||
141 | // Fallback to the Large size. | | |||
142 | return s_shadowParams[3]; | | |||
143 | } | | |||
144 | } | | |||
145 | } | | |||
146 | | ||||
147 | namespace Breeze | 65 | namespace Breeze | ||
148 | { | 66 | { | ||
149 | 67 | | |||
150 | using KDecoration2::ColorRole; | 68 | using KDecoration2::ColorRole; | ||
151 | using KDecoration2::ColorGroup; | 69 | using KDecoration2::ColorGroup; | ||
152 | 70 | | |||
153 | //________________________________________________________________ | 71 | //________________________________________________________________ | ||
154 | static int g_sDecoCount = 0; | | |||
155 | static int g_shadowSizeEnum = InternalSettings::ShadowLarge; | | |||
156 | static int g_shadowStrength = 255; | | |||
157 | static QColor g_shadowColor = Qt::black; | | |||
158 | static QSharedPointer<KDecoration2::DecorationShadow> g_sShadow; | | |||
159 | | ||||
160 | //________________________________________________________________ | | |||
161 | Decoration::Decoration(QObject *parent, const QVariantList &args) | 72 | Decoration::Decoration(QObject *parent, const QVariantList &args) | ||
162 | : KDecoration2::Decoration(parent, args) | 73 | : KDecoration2::Decoration(parent, args) | ||
163 | , m_animation( new QVariantAnimation( this ) ) | 74 | , m_animation( new QVariantAnimation( this ) ) | ||
164 | { | 75 | { | ||
165 | g_sDecoCount++; | | |||
166 | } | 76 | } | ||
167 | 77 | | |||
168 | //________________________________________________________________ | 78 | //________________________________________________________________ | ||
169 | Decoration::~Decoration() | 79 | Decoration::~Decoration() | ||
170 | { | 80 | { | ||
171 | g_sDecoCount--; | | |||
172 | if (g_sDecoCount == 0) { | | |||
173 | // last deco destroyed, clean up shadow | | |||
174 | g_sShadow.clear(); | | |||
175 | } | | |||
176 | | ||||
177 | deleteSizeGrip(); | 81 | deleteSizeGrip(); | ||
178 | | ||||
179 | } | 82 | } | ||
180 | 83 | | |||
181 | //________________________________________________________________ | 84 | //________________________________________________________________ | ||
182 | void Decoration::setOpacity( qreal value ) | 85 | void Decoration::setOpacity( qreal value ) | ||
183 | { | 86 | { | ||
184 | if( m_opacity == value ) return; | 87 | if( m_opacity == value ) return; | ||
185 | m_opacity = value; | 88 | m_opacity = value; | ||
186 | update(); | 89 | update(); | ||
▲ Show 20 Lines • Show All 242 Lines • ▼ Show 20 Line(s) | 331 | { | |||
429 | if( !isMaximizedHorizontally() ) extSides = extSize; | 332 | if( !isMaximizedHorizontally() ) extSides = extSize; | ||
430 | if( !isMaximizedVertically() ) extBottom = extSize; | 333 | if( !isMaximizedVertically() ) extBottom = extSize; | ||
431 | 334 | | |||
432 | } else if( hasNoSideBorders() && !isMaximizedHorizontally() ) { | 335 | } else if( hasNoSideBorders() && !isMaximizedHorizontally() ) { | ||
433 | 336 | | |||
434 | extSides = extSize; | 337 | extSides = extSize; | ||
435 | 338 | | |||
436 | } | 339 | } | ||
437 | 340 | if(auto breezeShadow = qobject_cast<Shadow*>(shadow())){ | |||
341 | breezeShadow->setEdges(isRightEdge(), isLeftEdge(), isBottomEdge(), isTopEdge()); | ||||
342 | } | ||||
438 | setResizeOnlyBorders(QMargins(extSides, 0, extSides, extBottom)); | 343 | setResizeOnlyBorders(QMargins(extSides, 0, extSides, extBottom)); | ||
439 | } | 344 | } | ||
440 | 345 | | |||
441 | //________________________________________________________________ | 346 | //________________________________________________________________ | ||
442 | void Decoration::createButtons() | 347 | void Decoration::createButtons() | ||
443 | { | 348 | { | ||
444 | m_leftButtons = new KDecoration2::DecorationButtonGroup(KDecoration2::DecorationButtonGroup::Position::Left, this, &Button::create); | 349 | m_leftButtons = new KDecoration2::DecorationButtonGroup(KDecoration2::DecorationButtonGroup::Position::Left, this, &Button::create); | ||
445 | m_rightButtons = new KDecoration2::DecorationButtonGroup(KDecoration2::DecorationButtonGroup::Position::Right, this, &Button::create); | 350 | m_rightButtons = new KDecoration2::DecorationButtonGroup(KDecoration2::DecorationButtonGroup::Position::Right, this, &Button::create); | ||
▲ Show 20 Lines • Show All 260 Lines • ▼ Show 20 Line(s) | 564 | { | |||
706 | 611 | | |||
707 | } | 612 | } | ||
708 | 613 | | |||
709 | } | 614 | } | ||
710 | 615 | | |||
711 | //________________________________________________________________ | 616 | //________________________________________________________________ | ||
712 | void Decoration::createShadow() | 617 | void Decoration::createShadow() | ||
713 | { | 618 | { | ||
714 | if (!g_sShadow | 619 | setShadow(QSharedPointer<Shadow>(new Shadow(static_cast<InternalSettings::EnumShadowSize>(internalSettings()->shadowSize()), | ||
715 | ||g_shadowSizeEnum != m_internalSettings->shadowSize() | 620 | internalSettings()->shadowStrength(), internalSettings()->shadowColor()))); | ||
716 | || g_shadowStrength != m_internalSettings->shadowStrength() | 621 | qobject_cast<Shadow*>(shadow())->setEdges(isRightEdge(), isLeftEdge(), isBottomEdge(), isTopEdge()); | ||
717 | || g_shadowColor != m_internalSettings->shadowColor()) | | |||
718 | { | | |||
719 | g_shadowSizeEnum = m_internalSettings->shadowSize(); | | |||
720 | g_shadowStrength = m_internalSettings->shadowStrength(); | | |||
721 | g_shadowColor = m_internalSettings->shadowColor(); | | |||
722 | | ||||
723 | const CompositeShadowParams params = lookupShadowParams(g_shadowSizeEnum); | | |||
724 | if (params.isNone()) { | | |||
725 | g_sShadow.clear(); | | |||
726 | setShadow(g_sShadow); | | |||
727 | return; | | |||
728 | } | | |||
729 | | ||||
730 | auto withOpacity = [](const QColor &color, qreal opacity) -> QColor { | | |||
731 | QColor c(color); | | |||
732 | c.setAlphaF(opacity); | | |||
733 | return c; | | |||
734 | }; | | |||
735 | | ||||
736 | const QSize boxSize = BoxShadowRenderer::calculateMinimumBoxSize(params.shadow1.radius) | | |||
737 | .expandedTo(BoxShadowRenderer::calculateMinimumBoxSize(params.shadow2.radius)); | | |||
738 | | ||||
739 | BoxShadowRenderer shadowRenderer; | | |||
740 | shadowRenderer.setBorderRadius(Metrics::Frame_FrameRadius + 0.5); | | |||
741 | shadowRenderer.setBoxSize(boxSize); | | |||
742 | shadowRenderer.setDevicePixelRatio(1.0); // TODO: Create HiDPI shadows? | | |||
743 | | ||||
744 | const qreal strength = static_cast<qreal>(g_shadowStrength) / 255.0; | | |||
745 | shadowRenderer.addShadow(params.shadow1.offset, params.shadow1.radius, | | |||
746 | withOpacity(g_shadowColor, params.shadow1.opacity * strength)); | | |||
747 | shadowRenderer.addShadow(params.shadow2.offset, params.shadow2.radius, | | |||
748 | withOpacity(g_shadowColor, params.shadow2.opacity * strength)); | | |||
749 | | ||||
750 | QImage shadowTexture = shadowRenderer.render(); | | |||
751 | | ||||
752 | QPainter painter(&shadowTexture); | | |||
753 | painter.setRenderHint(QPainter::Antialiasing); | | |||
754 | | ||||
755 | const QRect outerRect = shadowTexture.rect(); | | |||
756 | | ||||
757 | QRect boxRect(QPoint(0, 0), boxSize); | | |||
758 | boxRect.moveCenter(outerRect.center()); | | |||
759 | | ||||
760 | // Mask out inner rect. | | |||
761 | const QMargins padding = QMargins( | | |||
762 | boxRect.left() - outerRect.left() - Metrics::Shadow_Overlap - params.offset.x(), | | |||
763 | boxRect.top() - outerRect.top() - Metrics::Shadow_Overlap - params.offset.y(), | | |||
764 | outerRect.right() - boxRect.right() - Metrics::Shadow_Overlap + params.offset.x(), | | |||
765 | outerRect.bottom() - boxRect.bottom() - Metrics::Shadow_Overlap + params.offset.y()); | | |||
766 | const QRect innerRect = outerRect - padding; | | |||
767 | | ||||
768 | painter.setPen(Qt::NoPen); | | |||
769 | painter.setBrush(Qt::black); | | |||
770 | painter.setCompositionMode(QPainter::CompositionMode_DestinationOut); | | |||
771 | painter.drawRoundedRect( | | |||
772 | innerRect, | | |||
773 | Metrics::Frame_FrameRadius + 0.5, | | |||
774 | Metrics::Frame_FrameRadius + 0.5); | | |||
775 | | ||||
776 | // Draw outline. | | |||
777 | painter.setPen(withOpacity(g_shadowColor, 0.2 * strength)); | | |||
778 | painter.setBrush(Qt::NoBrush); | | |||
779 | painter.setCompositionMode(QPainter::CompositionMode_SourceOver); | | |||
780 | painter.drawRoundedRect( | | |||
781 | innerRect, | | |||
782 | Metrics::Frame_FrameRadius - 0.5, | | |||
783 | Metrics::Frame_FrameRadius - 0.5); | | |||
784 | | ||||
785 | painter.end(); | | |||
786 | | ||||
787 | g_sShadow = QSharedPointer<KDecoration2::DecorationShadow>::create(); | | |||
788 | g_sShadow->setPadding(padding); | | |||
789 | g_sShadow->setInnerShadowRect(QRect(outerRect.center(), QSize(1, 1))); | | |||
790 | g_sShadow->setShadow(shadowTexture); | | |||
791 | } | | |||
792 | | ||||
793 | setShadow(g_sShadow); | | |||
794 | } | 622 | } | ||
795 | 623 | | |||
796 | //_________________________________________________________________ | 624 | //_________________________________________________________________ | ||
797 | void Decoration::createSizeGrip() | 625 | void Decoration::createSizeGrip() | ||
798 | { | 626 | { | ||
799 | 627 | | |||
800 | // do nothing if size grip already exist | 628 | // do nothing if size grip already exist | ||
801 | if( m_sizeGrip ) return; | 629 | if( m_sizeGrip ) return; | ||
Show All 33 Lines |