Changeset View
Changeset View
Standalone View
Standalone View
kstyle/widgets/mdi.cpp
- This file was added.
1 | #include "breezestyle.h" | ||||
---|---|---|---|---|---|
2 | | ||||
3 | namespace Breeze | ||||
4 | { | ||||
5 | //______________________________________________________________________________ | ||||
6 | void Helper::renderDecorationButton(QPainter *painter, const QRect &rect, const QColor &color, ButtonType buttonType, bool inverted) const | ||||
7 | { | ||||
8 | painter->save(); | ||||
9 | painter->setViewport(rect); | ||||
10 | painter->setWindow(0, 0, 18, 18); | ||||
11 | painter->setRenderHints(QPainter::Antialiasing); | ||||
12 | | ||||
13 | // initialize pen | ||||
14 | QPen pen; | ||||
15 | pen.setCapStyle(Qt::RoundCap); | ||||
16 | pen.setJoinStyle(Qt::MiterJoin); | ||||
17 | | ||||
18 | if (inverted) { | ||||
19 | // render circle | ||||
20 | painter->setPen(Qt::NoPen); | ||||
21 | painter->setBrush(color); | ||||
22 | painter->drawEllipse(QRectF(0, 0, 18, 18)); | ||||
23 | | ||||
24 | // take out the inner part | ||||
25 | painter->setCompositionMode(QPainter::CompositionMode_DestinationOut); | ||||
26 | painter->setBrush(Qt::NoBrush); | ||||
27 | pen.setColor(Qt::black); | ||||
28 | | ||||
29 | } else { | ||||
30 | painter->setBrush(Qt::NoBrush); | ||||
31 | pen.setColor(color); | ||||
32 | } | ||||
33 | | ||||
34 | pen.setCapStyle(Qt::RoundCap); | ||||
35 | pen.setJoinStyle(Qt::MiterJoin); | ||||
36 | pen.setWidthF(1.1 * qMax(1.0, 18.0 / rect.width())); | ||||
37 | painter->setPen(pen); | ||||
38 | | ||||
39 | switch (buttonType) { | ||||
40 | case ButtonClose: { | ||||
41 | painter->drawLine(QPointF(5, 5), QPointF(13, 13)); | ||||
42 | painter->drawLine(13, 5, 5, 13); | ||||
43 | break; | ||||
44 | } | ||||
45 | | ||||
46 | case ButtonMaximize: { | ||||
47 | painter->drawPolyline(QVector<QPointF> {QPointF(4, 11), QPointF(9, 6), QPointF(14, 11)}); | ||||
48 | break; | ||||
49 | } | ||||
50 | | ||||
51 | case ButtonMinimize: { | ||||
52 | painter->drawPolyline(QVector<QPointF> {QPointF(4, 7), QPointF(9, 12), QPointF(14, 7)}); | ||||
53 | break; | ||||
54 | } | ||||
55 | | ||||
56 | case ButtonRestore: { | ||||
57 | pen.setJoinStyle(Qt::RoundJoin); | ||||
58 | painter->setPen(pen); | ||||
59 | painter->drawPolygon(QVector<QPointF> {QPointF(4.5, 9), QPointF(9, 4.5), QPointF(13.5, 9), QPointF(9, 13.5)}); | ||||
60 | break; | ||||
61 | } | ||||
62 | | ||||
63 | default: | ||||
64 | break; | ||||
65 | } | ||||
66 | | ||||
67 | painter->restore(); | ||||
68 | } | ||||
69 | | ||||
70 | //____________________________________________________________________________ | ||||
71 | bool Style::eventFilterMdiSubWindow(QMdiSubWindow *subWindow, QEvent *event) | ||||
72 | { | ||||
73 | if (event->type() == QEvent::Paint) { | ||||
74 | QPainter painter(subWindow); | ||||
75 | QPaintEvent *paintEvent(static_cast<QPaintEvent *>(event)); | ||||
76 | painter.setClipRegion(paintEvent->region()); | ||||
77 | | ||||
78 | const auto rect(subWindow->rect()); | ||||
79 | const auto background(subWindow->palette().color(QPalette::Window)); | ||||
80 | | ||||
81 | if (subWindow->isMaximized()) { | ||||
82 | // full painting | ||||
83 | painter.setPen(Qt::NoPen); | ||||
84 | painter.setBrush(background); | ||||
85 | painter.drawRect(rect); | ||||
86 | | ||||
87 | } else { | ||||
88 | // framed painting | ||||
89 | _helper->renderMenuFrame(&painter, rect, background, QColor()); | ||||
90 | } | ||||
91 | } | ||||
92 | | ||||
93 | // continue with normal painting | ||||
94 | return false; | ||||
95 | } | ||||
96 | | ||||
97 | //______________________________________________________________ | ||||
98 | bool Style::drawTitleBarComplexControl(const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const | ||||
99 | { | ||||
100 | // cast option and check | ||||
101 | const auto titleBarOption(qstyleoption_cast<const QStyleOptionTitleBar *>(option)); | ||||
102 | if (!titleBarOption) | ||||
103 | return true; | ||||
104 | | ||||
105 | // store palette and rect | ||||
106 | auto palette(option->palette); | ||||
107 | const auto &rect(option->rect); | ||||
108 | | ||||
109 | const State &flags(option->state); | ||||
110 | const bool enabled(flags & State_Enabled); | ||||
111 | const bool active(enabled && (titleBarOption->titleBarState & Qt::WindowActive)); | ||||
112 | | ||||
113 | if (titleBarOption->subControls & SC_TitleBarLabel) { | ||||
114 | // render background | ||||
115 | painter->setClipRect(rect); | ||||
116 | const auto outline(active ? QColor() : _helper->frameOutlineColor(palette, false, false)); | ||||
117 | const auto background(_helper->titleBarColor(active)); | ||||
118 | _helper->renderTabWidgetFrame(painter, rect.adjusted(-1, -1, 1, 3), background, outline, CornersTop); | ||||
119 | | ||||
120 | const bool useSeparator(active && _helper->titleBarColor(active) != palette.color(QPalette::Window) && !(titleBarOption->titleBarState & Qt::WindowMinimized)); | ||||
121 | | ||||
122 | if (useSeparator) { | ||||
123 | painter->setRenderHint(QPainter::Antialiasing, false); | ||||
124 | painter->setBrush(Qt::NoBrush); | ||||
125 | painter->setPen(palette.color(QPalette::Highlight)); | ||||
126 | painter->drawLine(rect.bottomLeft(), rect.bottomRight()); | ||||
127 | } | ||||
128 | | ||||
129 | // render text | ||||
130 | palette.setColor(QPalette::WindowText, _helper->titleBarTextColor(active)); | ||||
131 | const auto textRect(subControlRect(CC_TitleBar, option, SC_TitleBarLabel, widget)); | ||||
132 | ParentStyleClass::drawItemText(painter, textRect, Qt::AlignCenter, palette, active, titleBarOption->text, QPalette::WindowText); | ||||
133 | } | ||||
134 | | ||||
135 | // buttons | ||||
136 | static const QList<SubControl> subControls = {SC_TitleBarMinButton, SC_TitleBarMaxButton, SC_TitleBarCloseButton, SC_TitleBarNormalButton, SC_TitleBarSysMenu}; | ||||
137 | | ||||
138 | // loop over supported buttons | ||||
139 | foreach (const SubControl &subControl, subControls) { | ||||
140 | // skip if not requested | ||||
141 | if (!(titleBarOption->subControls & subControl)) | ||||
142 | continue; | ||||
143 | | ||||
144 | // find matching icon | ||||
145 | QIcon icon; | ||||
146 | switch (subControl) { | ||||
147 | case SC_TitleBarMinButton: | ||||
148 | icon = standardIcon(SP_TitleBarMinButton, option, widget); | ||||
149 | break; | ||||
150 | case SC_TitleBarMaxButton: | ||||
151 | icon = standardIcon(SP_TitleBarMaxButton, option, widget); | ||||
152 | break; | ||||
153 | case SC_TitleBarCloseButton: | ||||
154 | icon = standardIcon(SP_TitleBarCloseButton, option, widget); | ||||
155 | break; | ||||
156 | case SC_TitleBarNormalButton: | ||||
157 | icon = standardIcon(SP_TitleBarNormalButton, option, widget); | ||||
158 | break; | ||||
159 | case SC_TitleBarSysMenu: | ||||
160 | icon = titleBarOption->icon; | ||||
161 | break; | ||||
162 | default: | ||||
163 | break; | ||||
164 | } | ||||
165 | | ||||
166 | // check icon | ||||
167 | if (icon.isNull()) | ||||
168 | continue; | ||||
169 | | ||||
170 | // define icon rect | ||||
171 | auto iconRect(subControlRect(CC_TitleBar, option, subControl, widget)); | ||||
172 | if (iconRect.isEmpty()) | ||||
173 | continue; | ||||
174 | | ||||
175 | // active state | ||||
176 | const bool subControlActive(titleBarOption->activeSubControls & subControl); | ||||
177 | | ||||
178 | // mouse over state | ||||
179 | const bool mouseOver(!subControlActive && widget && iconRect.translated(widget->mapToGlobal(QPoint(0, 0))).contains(QCursor::pos())); | ||||
180 | | ||||
181 | // adjust iconRect | ||||
182 | const int iconWidth(pixelMetric(PM_SmallIconSize, option, widget)); | ||||
183 | const QSize iconSize(iconWidth, iconWidth); | ||||
184 | iconRect = centerRect(iconRect, iconSize); | ||||
185 | | ||||
186 | // set icon mode and state | ||||
187 | QIcon::Mode iconMode; | ||||
188 | QIcon::State iconState; | ||||
189 | | ||||
190 | if (!enabled) { | ||||
191 | iconMode = QIcon::Disabled; | ||||
192 | iconState = QIcon::Off; | ||||
193 | | ||||
194 | } else { | ||||
195 | if (mouseOver) | ||||
196 | iconMode = QIcon::Active; | ||||
197 | else if (active) | ||||
198 | iconMode = QIcon::Selected; | ||||
199 | else | ||||
200 | iconMode = QIcon::Normal; | ||||
201 | | ||||
202 | iconState = subControlActive ? QIcon::On : QIcon::Off; | ||||
203 | } | ||||
204 | | ||||
205 | // get pixmap and render | ||||
206 | const QPixmap pixmap = icon.pixmap(iconSize, iconMode, iconState); | ||||
207 | painter->drawPixmap(iconRect, pixmap); | ||||
208 | } | ||||
209 | | ||||
210 | return true; | ||||
211 | } | ||||
212 | | ||||
213 | //____________________________________________________________________________________ | ||||
214 | QIcon Style::titleBarButtonIcon(StandardPixmap standardPixmap, const QStyleOption *option, const QWidget *widget) const | ||||
215 | { | ||||
216 | // map standardPixmap to button type | ||||
217 | ButtonType buttonType; | ||||
218 | switch (standardPixmap) { | ||||
219 | case SP_TitleBarNormalButton: | ||||
220 | buttonType = ButtonRestore; | ||||
221 | break; | ||||
222 | case SP_TitleBarMinButton: | ||||
223 | buttonType = ButtonMinimize; | ||||
224 | break; | ||||
225 | case SP_TitleBarMaxButton: | ||||
226 | buttonType = ButtonMaximize; | ||||
227 | break; | ||||
228 | case SP_TitleBarCloseButton: | ||||
229 | case SP_DockWidgetCloseButton: | ||||
230 | buttonType = ButtonClose; | ||||
231 | break; | ||||
232 | | ||||
233 | default: | ||||
234 | return QIcon(); | ||||
235 | } | ||||
236 | | ||||
237 | // store palette | ||||
238 | // due to Qt, it is not always safe to assume that either option, nor widget are defined | ||||
239 | QPalette palette; | ||||
240 | if (option) | ||||
241 | palette = option->palette; | ||||
242 | else if (widget) | ||||
243 | palette = widget->palette(); | ||||
244 | else | ||||
245 | palette = QApplication::palette(); | ||||
246 | | ||||
247 | const bool isCloseButton(buttonType == ButtonClose && StyleConfigData::outlineCloseButton()); | ||||
248 | | ||||
249 | palette.setCurrentColorGroup(QPalette::Active); | ||||
250 | const auto base(palette.color(QPalette::WindowText)); | ||||
251 | const auto selected(palette.color(QPalette::HighlightedText)); | ||||
252 | const auto negative(buttonType == ButtonClose ? _helper->negativeText(palette) : base); | ||||
253 | const auto negativeSelected(buttonType == ButtonClose ? _helper->negativeText(palette) : selected); | ||||
254 | | ||||
255 | const bool invertNormalState(isCloseButton); | ||||
256 | | ||||
257 | // convenience class to map color to icon mode | ||||
258 | struct IconData { | ||||
259 | QColor _color; | ||||
260 | bool _inverted; | ||||
261 | QIcon::Mode _mode; | ||||
262 | QIcon::State _state; | ||||
263 | }; | ||||
264 | | ||||
265 | // map colors to icon states | ||||
266 | const QList<IconData> iconTypes = { | ||||
267 | | ||||
268 | // state off icons | ||||
269 | {KColorUtils::mix(palette.color(QPalette::Window), base, 0.5), invertNormalState, QIcon::Normal, QIcon::Off}, | ||||
270 | {KColorUtils::mix(palette.color(QPalette::Window), selected, 0.5), invertNormalState, QIcon::Selected, QIcon::Off}, | ||||
271 | {KColorUtils::mix(palette.color(QPalette::Window), negative, 0.5), true, QIcon::Active, QIcon::Off}, | ||||
272 | {KColorUtils::mix(palette.color(QPalette::Window), base, 0.2), invertNormalState, QIcon::Disabled, QIcon::Off}, | ||||
273 | | ||||
274 | // state on icons | ||||
275 | {KColorUtils::mix(palette.color(QPalette::Window), negative, 0.7), true, QIcon::Normal, QIcon::On}, | ||||
276 | {KColorUtils::mix(palette.color(QPalette::Window), negativeSelected, 0.7), true, QIcon::Selected, QIcon::On}, | ||||
277 | {KColorUtils::mix(palette.color(QPalette::Window), negative, 0.7), true, QIcon::Active, QIcon::On}, | ||||
278 | {KColorUtils::mix(palette.color(QPalette::Window), base, 0.2), invertNormalState, QIcon::Disabled, QIcon::On} | ||||
279 | | ||||
280 | }; | ||||
281 | | ||||
282 | // default icon sizes | ||||
283 | static const QList<int> iconSizes = {8, 16, 22, 32, 48}; | ||||
284 | | ||||
285 | // output icon | ||||
286 | QIcon icon; | ||||
287 | | ||||
288 | foreach (const IconData &iconData, iconTypes) { | ||||
289 | foreach (const int &iconSize, iconSizes) { | ||||
290 | // create pixmap | ||||
291 | QPixmap pixmap(iconSize, iconSize); | ||||
292 | pixmap.fill(Qt::transparent); | ||||
293 | | ||||
294 | // create painter and render | ||||
295 | QPainter painter(&pixmap); | ||||
296 | _helper->renderDecorationButton(&painter, pixmap.rect(), iconData._color, buttonType, iconData._inverted); | ||||
297 | | ||||
298 | painter.end(); | ||||
299 | | ||||
300 | // store | ||||
301 | icon.addPixmap(pixmap, iconData._mode, iconData._state); | ||||
302 | } | ||||
303 | } | ||||
304 | | ||||
305 | return icon; | ||||
306 | } | ||||
307 | | ||||
308 | } |