310
|
1 /****************************************************************************
|
|
2 **
|
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
|
4 ** Contact: Qt Software Information (qt-info@nokia.com)
|
|
5 **
|
|
6 ** This file is part of the demonstration applications of the Qt Toolkit.
|
|
7 **
|
|
8 ** $QT_BEGIN_LICENSE:LGPL$
|
|
9 ** Commercial Usage
|
|
10 ** Licensees holding valid Qt Commercial licenses may use this file in
|
|
11 ** accordance with the Qt Commercial License Agreement provided with the
|
|
12 ** Software or, alternatively, in accordance with the terms contained in
|
|
13 ** a written agreement between you and Nokia.
|
|
14 **
|
|
15 ** GNU Lesser General Public License Usage
|
|
16 ** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
17 ** General Public License version 2.1 as published by the Free Software
|
|
18 ** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
19 ** packaging of this file. Please review the following information to
|
|
20 ** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
21 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
22 **
|
|
23 ** In addition, as a special exception, Nokia gives you certain
|
|
24 ** additional rights. These rights are described in the Nokia Qt LGPL
|
|
25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
|
|
26 ** package.
|
|
27 **
|
|
28 ** GNU General Public License Usage
|
|
29 ** Alternatively, this file may be used under the terms of the GNU
|
|
30 ** General Public License version 3.0 as published by the Free Software
|
|
31 ** Foundation and appearing in the file LICENSE.GPL included in the
|
|
32 ** packaging of this file. Please review the following information to
|
|
33 ** ensure the GNU General Public License version 3.0 requirements will be
|
|
34 ** met: http://www.gnu.org/copyleft/gpl.html.
|
|
35 **
|
|
36 ** If you are unsure which license is appropriate for your use, please
|
|
37 ** contact the sales department at qt-sales@nokia.com.
|
|
38 ** $QT_END_LICENSE$
|
|
39 **
|
|
40 ****************************************************************************/
|
|
41 module arthurstyle;
|
|
42
|
|
43
|
|
44 import
|
|
45 qt.gui.QLayout,
|
|
46 qt.gui.QWindowsStyle,
|
|
47 qt.gui.QPainter,
|
|
48 qt.gui.QPainterPath,
|
|
49 qt.gui.QPixmapCache,
|
|
50 qt.gui.QRadioButton,
|
|
51 qt.gui.QPushButton,
|
|
52 qt.gui.QGroupBox,
|
|
53 qt.gui.QLinearGradient,
|
|
54 qt.gui.QStyleOption,
|
|
55 qt.gui.QStyleOptionFrameV2;
|
|
56
|
|
57
|
|
58 class ArthurStyle : QWindowsStyle
|
|
59 {
|
|
60 QPixmap cached(string img)
|
|
61 {
|
|
62 QPixmap pm = new QPixmap;
|
|
63 if (QPixmapCache.find(img, pm))
|
|
64 return pm;
|
|
65
|
|
66 pm = QPixmap.fromImage(new QImage(img), Qt.OrderedDither | Qt.OrderedAlphaDither);
|
|
67 if (pm.isNull)
|
|
68 return new QPixmap;
|
|
69
|
|
70 QPixmapCache.insert(img, pm);
|
|
71 return pm;
|
|
72 }
|
|
73
|
|
74 this()
|
|
75 {
|
|
76 //Q_INIT_RESOURCE(shared);
|
|
77 }
|
|
78
|
|
79 void drawHoverRect(QPainter painter, QRect r)
|
|
80 {
|
|
81 qreal h = r.height();
|
|
82 qreal h2 = r.height() / 2.0;
|
|
83 QPainterPath path = new QPainterPath;
|
|
84 path.addRect(r.x() + h2, r.y() + 0, r.width() - h2 * 2, r.height());
|
|
85 path.addEllipse(r.x(), r.y(), h, h);
|
|
86 path.addEllipse(r.x() + r.width() - h, r.y(), h, h);
|
|
87 path.setFillRule(Qt.WindingFill);
|
|
88 painter.setPen(Qt.NoPen);
|
|
89 painter.setBrush(new QColor(191, 215, 191));
|
|
90 painter.setRenderHint(QPainter.Antialiasing);
|
|
91 painter.drawPath(path);
|
|
92 }
|
|
93
|
|
94 override void drawPrimitive(PrimitiveElement element, QStyleOption option, QPainter painter, QWidget widget)
|
|
95 {
|
|
96 assert(option);
|
|
97 switch (element)
|
|
98 {
|
|
99 case PE_FrameFocusRect:
|
|
100 break;
|
|
101
|
|
102 case PE_IndicatorRadioButton:
|
|
103 if (QStyleOptionButton button = cast(QStyleOptionButton)(option)) {
|
|
104 bool hover = (button.state & State_Enabled) && (button.state & State_MouseOver);
|
|
105 painter.save;
|
|
106 QPixmap radio;
|
|
107 if (hover)
|
|
108 drawHoverRect(painter, widget.rect);
|
|
109
|
|
110 if (button.state & State_Sunken)
|
|
111 radio = cached(":res/images/radiobutton-on.png");
|
|
112 else if (button.state & State_On)
|
|
113 radio = cached(":res/images/radiobutton_on.png");
|
|
114 else
|
|
115 radio = cached(":res/images/radiobutton_off.png");
|
|
116 painter.drawPixmap(button.rect.topLeft, radio);
|
|
117
|
|
118 painter.restore();
|
|
119 }
|
|
120 break;
|
|
121
|
|
122 case PE_PanelButtonCommand:
|
|
123 if (QStyleOptionButton button = cast(QStyleOptionButton)(option)) {
|
|
124 bool hover = (button.state & State_Enabled) && (button.state & State_MouseOver);
|
|
125
|
|
126 painter.save();
|
|
127 QPushButton pushButton = cast(QPushButton)(widget);
|
|
128 assert(pushButton);
|
|
129 auto parent = pushButton.parentWidget;
|
|
130 if (parent && cast(QGroupBox)(parent)) {
|
|
131 auto lg = new QLinearGradient(0, 0, 0, parent.height);
|
|
132 lg.setColorAt(0, new QColor(224,224,224));
|
|
133 lg.setColorAt(1, new QColor(255,255,255));
|
|
134 painter.setPen(Qt.NoPen);
|
|
135 painter.setBrush(lg);
|
|
136 painter.setBrushOrigin(QPoint() - widget.mapToParent(QPoint(0,0)));
|
|
137 painter.drawRect(button.rect);
|
|
138 painter.setBrushOrigin(0, 0);
|
|
139 }
|
|
140
|
|
141 bool down = (button.state & State_Sunken) || (button.state & State_On);
|
|
142
|
|
143 QPixmap left, right, mid;
|
|
144 if (down) {
|
|
145 left = cached(":res/images/button_pressed_cap_left.png");
|
|
146 right = cached(":res/images/button_pressed_cap_right.png");
|
|
147 mid = cached(":res/images/button_pressed_stretch.png");
|
|
148 } else {
|
|
149 left = cached(":res/images/button_normal_cap_left.png");
|
|
150 right = cached(":res/images/button_normal_cap_right.png");
|
|
151 mid = cached(":res/images/button_normal_stretch.png");
|
|
152 }
|
|
153 painter.drawPixmap(button.rect.topLeft, left);
|
|
154 painter.drawTiledPixmap(QRect(button.rect.x + left.width,
|
|
155 button.rect.y,
|
|
156 button.rect.width - left.width - right.width,
|
|
157 left.height),
|
|
158 mid);
|
|
159 painter.drawPixmap(button.rect.x + button.rect.width - right.width,
|
|
160 button.rect.y,
|
|
161 right);
|
|
162 if (hover)
|
|
163 painter.fillRect(widget.rect.adjusted(3,5,-3,-5), new QColor(31,127,31,63));
|
|
164 painter.restore;
|
|
165 }
|
|
166 break;
|
|
167
|
|
168 case PE_FrameGroupBox:
|
|
169 if (QStyleOptionFrameV2 group = cast(QStyleOptionFrameV2)(option)) {
|
|
170 auto r = group.rect;
|
|
171
|
|
172 painter.save();
|
|
173 int radius = 14;
|
|
174 int radius2 = radius*2;
|
|
175 QPainterPath clipPath;
|
|
176 clipPath.moveTo(radius, 0);
|
|
177 clipPath.arcTo(r.right() - radius2, 0, radius2, radius2, 90, -90);
|
|
178 clipPath.arcTo(r.right() - radius2, r.bottom() - radius2, radius2, radius2, 0, -90);
|
|
179 clipPath.arcTo(r.left(), r.bottom() - radius2, radius2, radius2, 270, -90);
|
|
180 clipPath.arcTo(r.left(), r.top(), radius2, radius2, 180, -90);
|
|
181 painter.setClipPath(clipPath);
|
|
182 QPixmap titleStretch = cached(":res/images/title_stretch.png");
|
|
183 QPixmap topLeft = cached(":res/images/groupframe_topleft.png");
|
|
184 QPixmap topRight = cached(":res/images/groupframe_topright.png");
|
|
185 QPixmap bottomLeft = cached(":res/images/groupframe_bottom_left.png");
|
|
186 QPixmap bottomRight = cached(":res/images/groupframe_bottom_right.png");
|
|
187 QPixmap leftStretch = cached(":res/images/groupframe_left_stretch.png");
|
|
188 QPixmap topStretch = cached(":res/images/groupframe_top_stretch.png");
|
|
189 QPixmap rightStretch = cached(":res/images/groupframe_right_stretch.png");
|
|
190 QPixmap bottomStretch = cached(":res/images/groupframe_bottom_stretch.png");
|
|
191 auto lg = new QLinearGradient(0, 0, 0, r.height());
|
|
192 lg.setColorAt(0, new QColor(224,224,224));
|
|
193 lg.setColorAt(1, new QColor(255,255,255));
|
|
194 painter.setPen(Qt.NoPen);
|
|
195 painter.setBrush(lg);
|
|
196 painter.drawRect(r.adjusted(0, titleStretch.height()/2, 0, 0));
|
|
197 painter.setClipping(false);
|
|
198
|
|
199 int topFrameOffset = titleStretch.height()/2 - 2;
|
|
200 painter.drawPixmap(r.topLeft() + QPoint(0, topFrameOffset), topLeft);
|
|
201 painter.drawPixmap(r.topRight() - QPoint(topRight.width()-1, 0) + QPoint(0, topFrameOffset), topRight);
|
|
202 painter.drawPixmap(r.bottomLeft() - QPoint(0, bottomLeft.height()-1), bottomLeft);
|
|
203 painter.drawPixmap(r.bottomRight() - QPoint(bottomRight.width()-1, bottomRight.height()-1), bottomRight);
|
|
204
|
|
205 QRect left = r;
|
|
206 left.setY(r.y() + topLeft.height() + topFrameOffset);
|
|
207 left.setWidth(leftStretch.width());
|
|
208 left.setHeight(r.height() - topLeft.height() - bottomLeft.height() - topFrameOffset);
|
|
209 painter.drawTiledPixmap(left, leftStretch);
|
|
210
|
|
211 QRect top = r;
|
|
212 top.setX(r.x() + topLeft.width());
|
|
213 top.setY(r.y() + topFrameOffset);
|
|
214 top.setWidth(r.width() - topLeft.width() - topRight.width());
|
|
215 top.setHeight(topLeft.height());
|
|
216 painter.drawTiledPixmap(top, topStretch);
|
|
217
|
|
218 QRect right = r;
|
|
219 right.setX(r.right() - rightStretch.width()+1);
|
|
220 right.setY(r.y() + topRight.height() + topFrameOffset);
|
|
221 right.setWidth(rightStretch.width());
|
|
222 right.setHeight(r.height() - topRight.height() - bottomRight.height() - topFrameOffset);
|
|
223 painter.drawTiledPixmap(right, rightStretch);
|
|
224
|
|
225 QRect bottom = r;
|
|
226 bottom.setX(r.x() + bottomLeft.width());
|
|
227 bottom.setY(r.bottom() - bottomStretch.height()+1);
|
|
228 bottom.setWidth(r.width() - bottomLeft.width() - bottomRight.width());
|
|
229 bottom.setHeight(bottomLeft.height());
|
|
230 painter.drawTiledPixmap(bottom, bottomStretch);
|
|
231 painter.restore();
|
|
232 }
|
|
233 break;
|
|
234
|
|
235 default:
|
|
236 QWindowsStyle.drawPrimitive(element, option, painter, widget);
|
|
237 break;
|
|
238 }
|
|
239 return;
|
|
240 }
|
|
241
|
|
242 override void drawComplexControl(ComplexControl control, QStyleOptionComplex option,
|
|
243 QPainter painter, QWidget widget)
|
|
244 {
|
|
245 switch (control) {
|
|
246 case CC_Slider:
|
|
247 if (QStyleOptionSlider slider = cast(QStyleOptionSlider)(option)) {
|
|
248 QRect groove = subControlRect(CC_Slider, option, SC_SliderGroove, widget);
|
|
249 QRect handle = subControlRect(CC_Slider, option, SC_SliderHandle, widget);
|
|
250
|
|
251 painter.save;
|
|
252
|
|
253 bool hover = (slider.state & State_Enabled) && (slider.state & State_MouseOver);
|
|
254 if (hover) {
|
|
255 QRect moderated = widget.rect().adjusted(0, 4, 0, -4);
|
|
256 drawHoverRect(painter, moderated);
|
|
257 }
|
|
258
|
|
259 if ((option.subControls & SC_SliderGroove) && groove.isValid()) {
|
|
260 QPixmap grv = cached(":res/images/slider_bar.png");
|
|
261 painter.drawPixmap(QRect(groove.x() + 5, groove.y(),
|
|
262 groove.width() - 10, grv.height()),
|
|
263 grv);
|
|
264 }
|
|
265 if ((option.subControls & SC_SliderHandle) && handle.isValid()) {
|
|
266 QPixmap hndl = cached(":res/images/slider_thumb_on.png");
|
|
267 painter.drawPixmap(handle.topLeft(), hndl);
|
|
268 }
|
|
269
|
|
270 painter.restore();
|
|
271 }
|
|
272 break;
|
|
273 case CC_GroupBox:
|
|
274 if (QStyleOptionGroupBox groupBox
|
|
275 = cast(QStyleOptionGroupBox)(option)) {
|
|
276 auto groupBoxCopy = new QStyleOptionGroupBox(groupBox);
|
|
277 groupBoxCopy.setSubControls = groupBoxCopy.subControls & ~SC_GroupBoxLabel;
|
|
278 QWindowsStyle.drawComplexControl(control, groupBoxCopy, painter, widget);
|
|
279
|
|
280 if (groupBox.subControls & SC_GroupBoxLabel) {
|
|
281 QRect r = groupBox.rect;
|
|
282 QPixmap titleLeft = cached(":res/images/title_cap_left.png");
|
|
283 QPixmap titleRight = cached(":res/images/title_cap_right.png");
|
|
284 QPixmap titleStretch = cached(":res/images/title_stretch.png");
|
|
285 int txt_width = groupBox.fontMetrics.width(groupBox.text) + 20;
|
|
286 painter.drawPixmap(r.center().x() - txt_width/2, 0, titleLeft);
|
|
287 QRect tileRect = subControlRect(control, groupBox, SC_GroupBoxLabel, widget);
|
|
288 painter.drawTiledPixmap(tileRect, titleStretch);
|
|
289 painter.drawPixmap(tileRect.x() + tileRect.width(), 0, titleRight);
|
|
290 int opacity = 31;
|
|
291 painter.setPen(new QColor(0, 0, 0, opacity));
|
|
292 painter.drawText(tileRect.translated(0, 1),
|
|
293 cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null);
|
|
294 painter.drawText(tileRect.translated(2, 1),
|
|
295 cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null);
|
|
296 painter.setPen(new QColor(0, 0, 0, opacity * 2));
|
|
297 painter.drawText(tileRect.translated(1, 1),
|
|
298 cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null);
|
|
299 painter.setPen(new QColor(Qt.white));
|
|
300 painter.drawText(tileRect, cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null);
|
|
301 }
|
|
302 }
|
|
303 break;
|
|
304 default:
|
|
305 QWindowsStyle.drawComplexControl(control, option, painter, widget);
|
|
306 break;
|
|
307 }
|
|
308 return;
|
|
309 }
|
|
310
|
|
311 override QRect subControlRect(QStyle_ComplexControl control, QStyleOptionComplex option,
|
|
312 int sc, QWidget widget = null)
|
|
313 {
|
|
314 QRect rect;
|
|
315
|
|
316 auto subControl = cast(SubControl)sc;
|
|
317
|
|
318 switch (control) {
|
|
319 default:
|
|
320 rect = QWindowsStyle.subControlRect(control, option, subControl, widget);
|
|
321 break;
|
|
322 case CC_GroupBox:
|
|
323 if (QStyleOptionGroupBox group
|
|
324 = cast(QStyleOptionGroupBox)(option)) {
|
|
325 switch (subControl) {
|
|
326 default:
|
|
327 rect = QWindowsStyle.subControlRect(control, option, subControl, widget);
|
|
328 break;
|
|
329 case SC_GroupBoxContents:
|
|
330 rect = QWindowsStyle.subControlRect(control, option, subControl, widget);
|
|
331 rect.adjust(0, -8, 0, 0);
|
|
332 break;
|
|
333 case SC_GroupBoxFrame:
|
|
334 rect = group.rect;
|
|
335 break;
|
|
336 case SC_GroupBoxLabel:
|
|
337 QPixmap titleLeft = cached(":res/images/title_cap_left.png");
|
|
338 QPixmap titleRight = cached(":res/images/title_cap_right.png");
|
|
339 QPixmap titleStretch = cached(":res/images/title_stretch.png");
|
|
340 int txt_width = group.fontMetrics.width(group.text) + 20;
|
|
341 rect = QRect(group.rect.center().x() - txt_width/2 + titleLeft.width(), 0,
|
|
342 txt_width - titleLeft.width() - titleRight.width(),
|
|
343 titleStretch.height());
|
|
344 break;
|
|
345 }
|
|
346 }
|
|
347 break;
|
|
348 }
|
|
349
|
|
350 if (control == CC_Slider && subControl == SC_SliderHandle) {
|
|
351 rect.setWidth(13);
|
|
352 rect.setHeight(27);
|
|
353 } else if (control == CC_Slider && subControl == SC_SliderGroove) {
|
|
354 rect.setHeight(9);
|
|
355 rect.moveTop(27/2 - 9/2);
|
|
356 }
|
|
357 return rect;
|
|
358 }
|
|
359
|
|
360 override QSize sizeFromContents(ContentsType type, QStyleOption option,
|
|
361 QSize size, QWidget widget)
|
|
362 {
|
|
363 QSize newSize = QWindowsStyle.sizeFromContents(type, option, size, widget);
|
|
364
|
|
365 switch (type) {
|
|
366 case CT_RadioButton:
|
|
367 newSize += QSize(20, 0);
|
|
368 break;
|
|
369
|
|
370 case CT_PushButton:
|
|
371 newSize.setHeight(26);
|
|
372 break;
|
|
373
|
|
374 case CT_Slider:
|
|
375 newSize.setHeight(27);
|
|
376 break;
|
|
377
|
|
378 default:
|
|
379 break;
|
|
380 }
|
|
381
|
|
382 return newSize;
|
|
383 }
|
|
384
|
|
385 override int pixelMetric(PixelMetric pm, QStyleOption opt, QWidget widget)
|
|
386 {
|
|
387 if (pm == PM_SliderLength)
|
|
388 return 13;
|
|
389 return QWindowsStyle.pixelMetric(pm, opt, widget);
|
|
390 }
|
|
391
|
|
392 override void polish(QWidget widget)
|
|
393 {
|
|
394 if (widget.layout() && cast(QGroupBox)(widget)) {
|
|
395 if (widget.findChildren!(QGroupBox).length == 0) {
|
|
396 widget.layout().setWidgetSpacing(0); // Why setSpacing was renamed to setWidgetSpacing?
|
|
397 widget.layout().setMargin(12);
|
|
398 } else {
|
|
399 widget.layout().setMargin(13);
|
|
400 }
|
|
401 }
|
|
402
|
|
403 if (cast(QPushButton)(widget)
|
|
404 || cast(QRadioButton)(widget)
|
|
405 || cast(QSlider)(widget)) {
|
|
406 widget.setAttribute(Qt.WA_Hover);
|
|
407 }
|
|
408
|
|
409 QPalette pal = widget.palette();
|
|
410 if (widget.isWindow()) {
|
|
411 pal.setColor(QPalette.Window, new QColor(241, 241, 241));
|
|
412 widget.setPalette(pal);
|
|
413 }
|
|
414 }
|
|
415
|
|
416 override void unpolish(QWidget widget)
|
|
417 {
|
|
418 if (cast(QPushButton)(widget)
|
|
419 || cast(QRadioButton)(widget)
|
|
420 || cast(QSlider)(widget)) {
|
|
421 widget.setAttribute(Qt.WA_Hover, false);
|
|
422 }
|
|
423 }
|
|
424
|
|
425 override void polish(QPalette palette)
|
|
426 {
|
|
427 palette.setColor(QPalette.Window, new QColor(241, 241, 241));
|
|
428 }
|
|
429
|
|
430 override QRect subElementRect(SubElement element, QStyleOption option, QWidget widget)
|
|
431 {
|
|
432 QRect r;
|
|
433 switch(element) {
|
|
434 case SE_RadioButtonClickRect:
|
|
435 r = widget.rect();
|
|
436 break;
|
|
437 case SE_RadioButtonContents:
|
|
438 r = widget.rect().adjusted(20, 0, 0, 0);
|
|
439 break;
|
|
440 default:
|
|
441 r = QWindowsStyle.subElementRect(element, option, widget);
|
|
442 break;
|
|
443 }
|
|
444
|
|
445 if (cast(QRadioButton)(widget))
|
|
446 r = r.adjusted(5, 0, -5, 0);
|
|
447
|
|
448 return r;
|
|
449 }
|
|
450 }
|