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