41
|
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
|
|
42
|
|
43 //import arthurwidgets;
|
|
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.QstyleOptionFrameV2,
|
|
55 qt.gui.QStyleOption;
|
|
56
|
|
57 class ArthurStyle : QWindowsStyle
|
|
58 {
|
|
59 QPixmap cached(string img)
|
|
60 {
|
|
61 QPixmap pm = new QPixmap;
|
|
62 if (QPixmapCache.find(img, pm))
|
|
63 return pm;
|
|
64
|
|
65 pm = QPixmap.fromImage(new QImage(img), Qt.OrderedDither | Qt.OrderedAlphaDither);
|
|
66 if (pm.isNull)
|
|
67 return new QPixmap;
|
|
68
|
|
69 QPixmapCache.insert(img, pm);
|
|
70 return pm;
|
|
71 }
|
|
72
|
|
73 this()
|
|
74 {
|
|
75 //Q_INIT_RESOURCE(shared);
|
|
76 }
|
|
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;
|
|
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
|
|
95 override void drawPrimitive(PrimitiveElement element, QStyleOption option,
|
|
96 QPainter painter, QWidget widget)
|
|
97 {
|
|
98 assert(option);
|
|
99 switch (element)
|
|
100 {
|
|
101 case PE_FrameFocusRect:
|
|
102 break;
|
|
103
|
|
104 case PE_IndicatorRadioButton:
|
|
105 if (QStyleOptionButton button = cast(QStyleOptionButton)(option)) {
|
|
106 bool hover = (button.state & State_Enabled) && (button.state & State_MouseOver);
|
|
107 painter.save;
|
|
108 QPixmap radio;
|
|
109 if (hover)
|
|
110 drawHoverRect(painter, widget.rect);
|
|
111
|
|
112 if (button.state & State_Sunken)
|
|
113 radio = cached(":res/images/radiobutton-on.png");
|
|
114 else if (button.state & State_On)
|
|
115 radio = cached(":res/images/radiobutton_on.png");
|
|
116 else
|
|
117 radio = cached(":res/images/radiobutton_off.png");
|
|
118 painter.drawPixmap(button.rect.topLeft, radio);
|
|
119
|
|
120 painter.restore();
|
|
121 }
|
|
122 break;
|
|
123
|
|
124 case PE_PanelButtonCommand:
|
|
125 if (QStyleOptionButton button = cast(QStyleOptionButton)(option)) {
|
|
126 bool hover = (button.state & State_Enabled) && (button.state & State_MouseOver);
|
|
127
|
|
128 painter.save();
|
|
129 QPushButton pushButton = cast(QPushButton)(widget);
|
|
130 assert(pushButton);
|
|
131 auto parent = pushButton.parentWidget;
|
|
132 if (parent && cast(QGroupBox)(parent)) {
|
|
133 auto lg = new QLinearGradient(0, 0, 0, parent.height);
|
|
134 lg.setColorAt(0, new QColor(224,224,224));
|
|
135 lg.setColorAt(1, new QColor(255,255,255));
|
|
136 painter.setPen(Qt.NoPen);
|
|
137 painter.setBrush(lg);
|
|
138 painter.setBrushOrigin(QPoint() - widget.mapToParent(QPoint(0,0)));
|
|
139 painter.drawRect(button.rect);
|
|
140 painter.setBrushOrigin(0, 0);
|
|
141 }
|
|
142
|
|
143 bool down = (button.state & State_Sunken) || (button.state & State_On);
|
|
144
|
|
145 QPixmap left, right, mid;
|
|
146 if (down) {
|
|
147 left = cached(":res/images/button_pressed_cap_left.png");
|
|
148 right = cached(":res/images/button_pressed_cap_right.png");
|
|
149 mid = cached(":res/images/button_pressed_stretch.png");
|
|
150 } else {
|
|
151 left = cached(":res/images/button_normal_cap_left.png");
|
|
152 right = cached(":res/images/button_normal_cap_right.png");
|
|
153 mid = cached(":res/images/button_normal_stretch.png");
|
|
154 }
|
|
155 painter.drawPixmap(button.rect.topLeft, left);
|
|
156 painter.drawTiledPixmap(new QRect(button.rect.x + left.width,
|
|
157 button.rect.y,
|
|
158 button.rect.width - left.width - right.width,
|
|
159 left.height),
|
|
160 mid);
|
|
161 painter.drawPixmap(button.rect.x + button.rect.width - right.width,
|
|
162 button.rect.y,
|
|
163 right);
|
|
164 if (hover)
|
|
165 painter.fillRect(widget.rect.adjusted(3,5,-3,-5), new QColor(31,127,31,63));
|
|
166 painter.restore;
|
|
167 }
|
|
168 break;
|
|
169
|
|
170 case PE_FrameGroupBox:
|
|
171 if (QStyleOptionFrameV2 group
|
|
172 = cast(QStyleOptionFrameV2)(option)) {
|
|
173 auto r = group.rect;
|
|
174
|
|
175 painter.save();
|
|
176 int radius = 14;
|
|
177 int radius2 = radius*2;
|
|
178 QPainterPath clipPath;
|
|
179 clipPath.moveTo(radius, 0);
|
|
180 clipPath.arcTo(r.right() - radius2, 0, radius2, radius2, 90, -90);
|
|
181 clipPath.arcTo(r.right() - radius2, r.bottom() - radius2, radius2, radius2, 0, -90);
|
|
182 clipPath.arcTo(r.left(), r.bottom() - radius2, radius2, radius2, 270, -90);
|
|
183 clipPath.arcTo(r.left(), r.top(), radius2, radius2, 180, -90);
|
|
184 painter.setClipPath(clipPath);
|
|
185 QPixmap titleStretch = cached(":res/images/title_stretch.png");
|
|
186 QPixmap topLeft = cached(":res/images/groupframe_topleft.png");
|
|
187 QPixmap topRight = cached(":res/images/groupframe_topright.png");
|
|
188 QPixmap bottomLeft = cached(":res/images/groupframe_bottom_left.png");
|
|
189 QPixmap bottomRight = cached(":res/images/groupframe_bottom_right.png");
|
|
190 QPixmap leftStretch = cached(":res/images/groupframe_left_stretch.png");
|
|
191 QPixmap topStretch = cached(":res/images/groupframe_top_stretch.png");
|
|
192 QPixmap rightStretch = cached(":res/images/groupframe_right_stretch.png");
|
|
193 QPixmap bottomStretch = cached(":res/images/groupframe_bottom_stretch.png");
|
|
194 auto lg = new QLinearGradient(0, 0, 0, r.height());
|
|
195 lg.setColorAt(0, new QColor(224,224,224));
|
|
196 lg.setColorAt(1, new QColor(255,255,255));
|
|
197 painter.setPen(Qt.NoPen);
|
|
198 painter.setBrush(lg);
|
|
199 painter.drawRect(r.adjusted(0, titleStretch.height()/2, 0, 0));
|
|
200 painter.setClipping(false);
|
|
201
|
|
202 int topFrameOffset = titleStretch.height()/2 - 2;
|
|
203 painter.drawPixmap(r.topLeft() + QPoint(0, topFrameOffset), topLeft);
|
|
204 painter.drawPixmap(r.topRight() - QPoint(topRight.width()-1, 0)
|
|
205 + QPoint(0, topFrameOffset), topRight);
|
|
206 painter.drawPixmap(r.bottomLeft() - QPoint(0, bottomLeft.height()-1), bottomLeft);
|
|
207 painter.drawPixmap(r.bottomRight() - QPoint(bottomRight.width()-1,
|
|
208 bottomRight.height()-1), bottomRight);
|
|
209
|
|
210 QRect left = r;
|
|
211 left.setY(r.y() + topLeft.height() + topFrameOffset);
|
|
212 left.setWidth(leftStretch.width());
|
|
213 left.setHeight(r.height() - topLeft.height() - bottomLeft.height() - topFrameOffset);
|
|
214 painter.drawTiledPixmap(left, leftStretch);
|
|
215
|
|
216 QRect top = r;
|
|
217 top.setX(r.x() + topLeft.width());
|
|
218 top.setY(r.y() + topFrameOffset);
|
|
219 top.setWidth(r.width() - topLeft.width() - topRight.width());
|
|
220 top.setHeight(topLeft.height());
|
|
221 painter.drawTiledPixmap(top, topStretch);
|
|
222
|
|
223 QRect right = r;
|
|
224 right.setX(r.right() - rightStretch.width()+1);
|
|
225 right.setY(r.y() + topRight.height() + topFrameOffset);
|
|
226 right.setWidth(rightStretch.width());
|
|
227 right.setHeight(r.height() - topRight.height()
|
|
228 - bottomRight.height() - topFrameOffset);
|
|
229 painter.drawTiledPixmap(right, rightStretch);
|
|
230
|
|
231 QRect bottom = r;
|
|
232 bottom.setX(r.x() + bottomLeft.width());
|
|
233 bottom.setY(r.bottom() - bottomStretch.height()+1);
|
|
234 bottom.setWidth(r.width() - bottomLeft.width() - bottomRight.width());
|
|
235 bottom.setHeight(bottomLeft.height());
|
|
236 painter.drawTiledPixmap(bottom, bottomStretch);
|
|
237 painter.restore();
|
|
238 }
|
|
239 break;
|
|
240
|
|
241 default:
|
|
242 QWindowsStyle.drawPrimitive(element, option, painter, widget);
|
|
243 break;
|
|
244 }
|
|
245 return;
|
|
246 }
|
|
247
|
|
248 override void drawComplexControl(ComplexControl control, QStyleOptionComplex option,
|
|
249 QPainter painter, QWidget widget)
|
|
250 {
|
|
251 switch (control) {
|
|
252 case CC_Slider:
|
|
253 if (QStyleOptionSlider slider = cast(QStyleOptionSlider)(option)) {
|
|
254 QRect groove = subControlRect(CC_Slider, option, SC_SliderGroove, widget);
|
|
255 QRect handle = subControlRect(CC_Slider, option, SC_SliderHandle, widget);
|
|
256
|
|
257 painter.save;
|
|
258
|
|
259 bool hover = (slider.state & State_Enabled) && (slider.state & State_MouseOver);
|
|
260 if (hover) {
|
|
261 QRect moderated = widget.rect().adjusted(0, 4, 0, -4);
|
|
262 drawHoverRect(painter, moderated);
|
|
263 }
|
|
264
|
|
265 if ((option.subControls & SC_SliderGroove) && groove.isValid()) {
|
|
266 QPixmap grv = cached(":res/images/slider_bar.png");
|
|
267 painter.drawPixmap(new QRect(groove.x() + 5, groove.y(),
|
|
268 groove.width() - 10, grv.height()),
|
|
269 grv);
|
|
270 }
|
|
271 if ((option.subControls & SC_SliderHandle) && handle.isValid()) {
|
|
272 QPixmap hndl = cached(":res/images/slider_thumb_on.png");
|
|
273 painter.drawPixmap(handle.topLeft(), hndl);
|
|
274 }
|
|
275
|
|
276 painter.restore();
|
|
277 }
|
|
278 break;
|
|
279 case CC_GroupBox:
|
|
280 if (QStyleOptionGroupBox groupBox
|
|
281 = cast(QStyleOptionGroupBox)(option)) {
|
|
282 auto groupBoxCopy = new QStyleOptionGroupBox(groupBox);
|
|
283 groupBoxCopy.setSubControls = groupBoxCopy.subControls & ~SC_GroupBoxLabel;
|
|
284 QWindowsStyle.drawComplexControl(control, groupBoxCopy, painter, widget);
|
|
285
|
|
286 if (groupBox.subControls & SC_GroupBoxLabel) {
|
|
287 QRect r = groupBox.rect;
|
|
288 QPixmap titleLeft = cached(":res/images/title_cap_left.png");
|
|
289 QPixmap titleRight = cached(":res/images/title_cap_right.png");
|
|
290 QPixmap titleStretch = cached(":res/images/title_stretch.png");
|
|
291 int txt_width = groupBox.fontMetrics.width(groupBox.text) + 20;
|
|
292 painter.drawPixmap(r.center().x() - txt_width/2, 0, titleLeft);
|
|
293 QRect tileRect = subControlRect(control, groupBox, SC_GroupBoxLabel, widget);
|
|
294 painter.drawTiledPixmap(tileRect, titleStretch);
|
|
295 painter.drawPixmap(tileRect.x() + tileRect.width(), 0, titleRight);
|
|
296 int opacity = 31;
|
|
297 painter.setPen(new QColor(0, 0, 0, opacity));
|
|
298 painter.drawText(tileRect.translated(0, 1),
|
|
299 cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null);
|
|
300 painter.drawText(tileRect.translated(2, 1),
|
|
301 cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null);
|
|
302 painter.setPen(new QColor(0, 0, 0, opacity * 2));
|
|
303 painter.drawText(tileRect.translated(1, 1),
|
|
304 cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null);
|
|
305 painter.setPen(new QColor(Qt.white));
|
|
306 painter.drawText(tileRect, cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null);
|
|
307 }
|
|
308 }
|
|
309 break;
|
|
310 default:
|
|
311 QWindowsStyle.drawComplexControl(control, option, painter, widget);
|
|
312 break;
|
|
313 }
|
|
314 return;
|
|
315 }
|
|
316
|
|
317 override QRect subControlRect(QStyle_ComplexControl control, QStyleOptionComplex option,
|
|
318 int sc, QWidget widget = null)
|
|
319 {
|
|
320 QRect rect;
|
|
321
|
|
322 auto subControl = cast(SubControl)sc;
|
|
323
|
|
324 switch (control) {
|
|
325 default:
|
|
326 rect = QWindowsStyle.subControlRect(control, option, subControl, widget);
|
|
327 break;
|
|
328 case CC_GroupBox:
|
|
329 if (QStyleOptionGroupBox group
|
|
330 = cast(QStyleOptionGroupBox)(option)) {
|
|
331 switch (subControl) {
|
|
332 default:
|
|
333 rect = QWindowsStyle.subControlRect(control, option, subControl, widget);
|
|
334 break;
|
|
335 case SC_GroupBoxContents:
|
|
336 rect = QWindowsStyle.subControlRect(control, option, subControl, widget);
|
|
337 rect.adjust(0, -8, 0, 0);
|
|
338 break;
|
|
339 case SC_GroupBoxFrame:
|
|
340 rect = group.rect;
|
|
341 break;
|
|
342 case SC_GroupBoxLabel:
|
|
343 QPixmap titleLeft = cached(":res/images/title_cap_left.png");
|
|
344 QPixmap titleRight = cached(":res/images/title_cap_right.png");
|
|
345 QPixmap titleStretch = cached(":res/images/title_stretch.png");
|
|
346 int txt_width = group.fontMetrics.width(group.text) + 20;
|
|
347 rect = new QRect(group.rect.center().x() - txt_width/2 + titleLeft.width(), 0,
|
|
348 txt_width - titleLeft.width() - titleRight.width(),
|
|
349 titleStretch.height());
|
|
350 break;
|
|
351 }
|
|
352 }
|
|
353 break;
|
|
354 }
|
|
355
|
|
356 if (control == CC_Slider && subControl == SC_SliderHandle) {
|
|
357 rect.setWidth(13);
|
|
358 rect.setHeight(27);
|
|
359 } else if (control == CC_Slider && subControl == SC_SliderGroove) {
|
|
360 rect.setHeight(9);
|
|
361 rect.moveTop(27/2 - 9/2);
|
|
362 }
|
|
363 return rect;
|
|
364 }
|
|
365
|
|
366 override QSize sizeFromContents(ContentsType type, QStyleOption option,
|
|
367 QSize size, QWidget widget)
|
|
368 {
|
|
369 QSize newSize = QWindowsStyle.sizeFromContents(type, option, size, widget);
|
|
370
|
|
371 switch (type) {
|
|
372 case CT_RadioButton:
|
|
373 newSize += QSize(20, 0);
|
|
374 break;
|
|
375
|
|
376 case CT_PushButton:
|
|
377 newSize.setHeight(26);
|
|
378 break;
|
|
379
|
|
380 case CT_Slider:
|
|
381 newSize.setHeight(27);
|
|
382 break;
|
|
383
|
|
384 default:
|
|
385 break;
|
|
386 }
|
|
387
|
|
388 return newSize;
|
|
389 }
|
|
390
|
|
391 override int pixelMetric(PixelMetric pm, QStyleOption opt, QWidget widget)
|
|
392 {
|
|
393 if (pm == PM_SliderLength)
|
|
394 return 13;
|
|
395 return QWindowsStyle.pixelMetric(pm, opt, widget);
|
|
396 }
|
|
397
|
|
398 override void polish(QWidget widget)
|
|
399 {
|
|
400 if (widget.layout() && cast(QGroupBox)(widget)) {
|
|
401 if (widget.findChildren!(QGroupBox).length == 0) {
|
|
402 widget.layout().setWidgetSpacing(0); // Why setSpacing was renamed to setWidgetSpacing?
|
|
403 widget.layout().setMargin(12);
|
|
404 } else {
|
|
405 widget.layout().setMargin(13);
|
|
406 }
|
|
407 }
|
|
408
|
|
409 if (cast(QPushButton)(widget)
|
|
410 || cast(QRadioButton)(widget)
|
|
411 || cast(QSlider)(widget)) {
|
|
412 widget.setAttribute(Qt.WA_Hover);
|
|
413 }
|
|
414
|
|
415 QPalette pal = widget.palette();
|
|
416 if (widget.isWindow()) {
|
|
417 pal.setColor(QPalette.Window, new QColor(241, 241, 241));
|
|
418 widget.setPalette(pal);
|
|
419 }
|
|
420
|
|
421 }
|
|
422
|
|
423 override void unpolish(QWidget widget)
|
|
424 {
|
|
425 if (cast(QPushButton)(widget)
|
|
426 || cast(QRadioButton)(widget)
|
|
427 || cast(QSlider)(widget)) {
|
|
428 widget.setAttribute(Qt.WA_Hover, false);
|
|
429 }
|
|
430 }
|
|
431
|
|
432 override void polish(QPalette palette)
|
|
433 {
|
|
434 palette.setColor(QPalette.Window, new QColor(241, 241, 241));
|
|
435 }
|
|
436
|
|
437 override QRect subElementRect(SubElement element, QStyleOption option, QWidget widget)
|
|
438 {
|
|
439 QRect r;
|
|
440 switch(element) {
|
|
441 case SE_RadioButtonClickRect:
|
|
442 r = widget.rect();
|
|
443 break;
|
|
444 case SE_RadioButtonContents:
|
|
445 r = widget.rect().adjusted(20, 0, 0, 0);
|
|
446 break;
|
|
447 default:
|
|
448 r = QWindowsStyle.subElementRect(element, option, widget);
|
|
449 break;
|
|
450 }
|
|
451
|
|
452 if (cast(QRadioButton)(widget))
|
|
453 r = r.adjusted(5, 0, -5, 0);
|
|
454
|
|
455 return r;
|
|
456 }
|
|
457 }
|