QtBase  v6.3.1
qandroidstyle.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 BogDan Vatra <bogdan@kde.org>
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtWidgets module 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 The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "qandroidstyle_p.h"
41 
42 #include <QFile>
43 #include <QFont>
44 #include <QApplication>
45 #include <qdrawutil.h>
46 #include <QPixmapCache>
47 #include <QFileInfo>
48 #include <QStyleOption>
49 #include <QPainter>
50 #include <QJsonDocument>
51 #include <QJsonObject>
52 #include <QDebug>
53 
54 #include <QGuiApplication>
55 #include <qpa/qplatformnativeinterface.h>
56 #include <qpa/qplatformtheme.h>
57 
59 
60 namespace {
61  const quint32 NO_COLOR = 1;
63 }
64 
66  : QFusionStyle()
67 {
69  checkBoxControl = NULL;
71  QPalette *standardPalette = reinterpret_cast<QPalette *>(nativeInterface->nativeResourceForIntegration("AndroidStandardPalette"));
72  if (standardPalette)
73  m_standardPalette = *standardPalette;
74 
75  QHash<QByteArray, QFont> *qwidgetsFonts = reinterpret_cast<QHash<QByteArray, QFont> *>(nativeInterface->nativeResourceForIntegration("AndroidQWidgetFonts"));
76  if (qwidgetsFonts) {
77  for (auto it = qwidgetsFonts->constBegin(); it != qwidgetsFonts->constEnd(); ++it)
78  QApplication::setFont(it.value(), it.key());
79  qwidgetsFonts->clear(); // free the memory
80  }
81 
82  QJsonObject *object = reinterpret_cast<QJsonObject *>(nativeInterface->nativeResourceForIntegration("AndroidStyleData"));
83  if (!object)
84  return;
85 
86  for (QJsonObject::const_iterator objectIterator = object->constBegin();
87  objectIterator != object->constEnd();
88  ++objectIterator) {
89  QString key = objectIterator.key();
90  QJsonValue value = objectIterator.value();
91  if (Q_UNLIKELY(!value.isObject())) {
92  qWarning("Style.json structure is unrecognized.");
93  continue;
94  }
95 
96  QJsonObject item = value.toObject();
97  QAndroidStyle::ItemType itemType = qtControl(key);
98  if (QC_UnknownType == itemType)
99  continue;
100 
101  switch (itemType) {
102  case QC_Checkbox:
103  checkBoxControl = new AndroidCompoundButtonControl(item.toVariantMap(), itemType);
104  m_androidControlsHash[int(itemType)] = checkBoxControl;
105  break;
106  case QC_RadioButton:
107  m_androidControlsHash[int(itemType)] = new AndroidCompoundButtonControl(item.toVariantMap(),
108  itemType);
109  break;
110 
111  case QC_ProgressBar:
112  m_androidControlsHash[int(itemType)] = new AndroidProgressBarControl(item.toVariantMap(),
113  itemType);
114  break;
115 
116  case QC_Slider:
117  m_androidControlsHash[int(itemType)] = new AndroidSeekBarControl(item.toVariantMap(),
118  itemType);
119  break;
120 
121  case QC_Combobox:
122  m_androidControlsHash[int(itemType)] = new AndroidSpinnerControl(item.toVariantMap(),
123  itemType);
124  break;
125 
126  default:
127  m_androidControlsHash[int(itemType)] = new AndroidControl(item.toVariantMap(),
128  itemType);
129  break;
130  }
131  }
132  *object = QJsonObject(); // free memory
133 }
134 
136 {
137  qDeleteAll(m_androidControlsHash);
138 }
139 
140 QAndroidStyle::ItemType QAndroidStyle::qtControl(const QString &android)
141 {
142  if (android == QLatin1String("buttonStyle"))
143  return QC_Button;
144  if (android == QLatin1String("editTextStyle"))
145  return QC_EditText;
146  if (android == QLatin1String("radioButtonStyle"))
147  return QC_RadioButton;
148  if (android == QLatin1String("checkboxStyle"))
149  return QC_Checkbox;
150  if (android == QLatin1String("textViewStyle"))
151  return QC_View;
152  if (android == QLatin1String("buttonStyleToggle"))
153  return QC_Switch;
154  if (android == QLatin1String("spinnerStyle"))
155  return QC_Combobox;
156  if (android == QLatin1String("progressBarStyleHorizontal"))
157  return QC_ProgressBar;
158  if (android == QLatin1String("seekBarStyle"))
159  return QC_Slider;
160 
161  return QC_UnknownType;
162 }
163 
164 QAndroidStyle::ItemType QAndroidStyle::qtControl(QStyle::ComplexControl control)
165 {
166  switch (control) {
167  case CC_ComboBox:
168  return QC_Combobox;
169  case CC_Slider:
170  return QC_Slider;
171  default:
172  return QC_UnknownType;
173  }
174 }
175 
176 QAndroidStyle::ItemType QAndroidStyle::qtControl(QStyle::ContentsType contentsType)
177 {
178  switch (contentsType) {
179  case CT_PushButton:
180  return QC_Button;
181  case CT_CheckBox:
182  return QC_Checkbox;
183  case CT_RadioButton:
184  return QC_RadioButton;
185  case CT_ComboBox:
186  return QC_Combobox;
187  case CT_ProgressBar:
188  return QC_ProgressBar;
189  case CT_Slider:
190  return QC_Slider;
191  case CT_ScrollBar:
192  return QC_Slider;
193  case CT_TabWidget:
194  return QC_Tab;
195  case CT_TabBarTab:
196  return QC_TabButton;
197  case CT_LineEdit:
198  return QC_EditText;
199  case CT_GroupBox:
200  return QC_GroupBox;
201  default:
202  return QC_UnknownType;
203  }
204 }
205 
206 QAndroidStyle::ItemType QAndroidStyle::qtControl(QStyle::ControlElement controlElement)
207 {
208  switch (controlElement) {
209  case CE_PushButton:
210  case CE_PushButtonBevel:
211  case CE_PushButtonLabel:
212  return QC_Button;
213 
214  case CE_CheckBox:
215  case CE_CheckBoxLabel:
216  return QC_Checkbox;
217 
218  case CE_RadioButton:
219  case CE_RadioButtonLabel:
220  return QC_RadioButton;
221 
222  case CE_TabBarTab:
223  case CE_TabBarTabShape:
224  case CE_TabBarTabLabel:
225  return QC_Tab;
226 
227  case CE_ProgressBar:
228  case CE_ProgressBarGroove:
229  case CE_ProgressBarContents:
230  case CE_ProgressBarLabel:
231  return QC_ProgressBar;
232 
233  case CE_ComboBoxLabel:
234  return QC_Combobox;
235 
236  case CE_ShapedFrame:
237  return QC_View;
238 
239  default:
240  return QC_UnknownType;
241  }
242 }
243 
244 QAndroidStyle::ItemType QAndroidStyle::qtControl(QStyle::PrimitiveElement primitiveElement)
245 {
246  switch (primitiveElement) {
249  return QC_EditText;
250 
253  return QC_Checkbox;
254 
256  case QStyle::PE_Widget:
257  case QStyle::PE_Frame:
259  return QC_View;
260  default:
261  return QC_UnknownType;
262  }
263 }
264 
265 QAndroidStyle::ItemType QAndroidStyle::qtControl(QStyle::SubElement subElement)
266 {
267  switch (subElement) {
269  return QC_EditText;
270 
273  return QC_Button;
274 
275  case SE_RadioButtonContents:
276  return QC_RadioButton;
277 
278  case SE_CheckBoxContents:
279  return QC_Checkbox;
280 
281  default:
282  return QC_UnknownType;
283  }
284 }
285 
286 void QAndroidStyle::drawPrimitive(PrimitiveElement pe,
287  const QStyleOption *opt,
288  QPainter *p,
289  const QWidget *w) const
290 {
291  const ItemType itemType = qtControl(pe);
293  ? m_androidControlsHash.find(itemType)
294  : m_androidControlsHash.end();
295  if (it != m_androidControlsHash.end()) {
296  if (itemType != QC_EditText) {
297  it.value()->drawControl(opt, p, w);
298  } else {
299  QStyleOption copy(*opt);
300  copy.state &= ~QStyle::State_Sunken;
301  it.value()->drawControl(&copy, p, w);
302  }
303  } else if (pe == PE_FrameGroupBox) {
304  if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
305  if (frame->features & QStyleOptionFrame::Flat) {
306  QRect fr = frame->rect;
307  QPoint p1(fr.x(), fr.y() + 1);
308  QPoint p2(fr.x() + fr.width(), p1.y());
309  qDrawShadeLine(p, p1, p2, frame->palette, true,
311  } else {
313  frame->rect.height(), frame->palette, true,
315  }
316  }
317  } else {
319  }
320 }
321 
322 
324  const QStyleOption *opt,
325  QPainter *p,
326  const QWidget *w) const
327 {
328  const ItemType itemType = qtControl(element);
330  ? m_androidControlsHash.find(itemType)
331  : m_androidControlsHash.end();
332  if (it != m_androidControlsHash.end()) {
333  AndroidControl *androidControl = it.value();
334 
335  if (element != QStyle::CE_CheckBoxLabel
336  && element != QStyle::CE_PushButtonLabel
337  && element != QStyle::CE_RadioButtonLabel
338  && element != QStyle::CE_TabBarTabLabel
339  && element != QStyle::CE_ProgressBarLabel) {
340  androidControl->drawControl(opt, p, w);
341  }
342 
343  if (element != QStyle::CE_PushButtonBevel
344  && element != QStyle::CE_TabBarTabShape
345  && element != QStyle::CE_ProgressBarGroove) {
346  switch (itemType) {
347  case QC_Button:
348  if (const QStyleOptionButton *buttonOption =
349  qstyleoption_cast<const QStyleOptionButton *>(opt)) {
350  QMargins padding = androidControl->padding();
351  QStyleOptionButton copy(*buttonOption);
352  copy.rect.adjust(padding.left(), padding.top(), -padding.right(), -padding.bottom());
353  QFusionStyle::drawControl(CE_PushButtonLabel, &copy, p, w);
354  }
355  break;
356  case QC_Checkbox:
357  case QC_RadioButton:
358  if (const QStyleOptionButton *btn =
359  qstyleoption_cast<const QStyleOptionButton *>(opt)) {
360  const bool isRadio = (element == CE_RadioButton);
362  subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents
363  : SE_CheckBoxContents, btn, w);
364  QFusionStyle::drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, p, w);
365  }
366  break;
367  case QC_Combobox:
368  if (const QStyleOptionComboBox *comboboxOption =
369  qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
370  QMargins padding = androidControl->padding();
371  QStyleOptionComboBox copy (*comboboxOption);
372  copy.rect.adjust(padding.left(), padding.top(), -padding.right(), -padding.bottom());
373  QFusionStyle::drawControl(CE_ComboBoxLabel, comboboxOption, p, w);
374  }
375  break;
376  default:
377  QFusionStyle::drawControl(element, opt, p, w);
378  break;
379  }
380  }
381  } else {
382  QFusionStyle::drawControl(element, opt, p, w);
383  }
384 }
385 
386 QRect QAndroidStyle::subElementRect(SubElement subElement,
387  const QStyleOption *option,
388  const QWidget *widget) const
389 {
390  const ItemType itemType = qtControl(subElement);
392  ? m_androidControlsHash.find(itemType)
393  : m_androidControlsHash.end();
394  if (it != m_androidControlsHash.end())
395  return it.value()->subElementRect(subElement, option, widget);
396  return QFusionStyle::subElementRect(subElement, option, widget);
397 }
398 
399 void QAndroidStyle::drawComplexControl(ComplexControl cc,
400  const QStyleOptionComplex *opt,
401  QPainter *p,
402  const QWidget *widget) const
403 {
404  const ItemType itemType = qtControl(cc);
406  ? m_androidControlsHash.find(itemType)
407  : m_androidControlsHash.end();
408  if (it != m_androidControlsHash.end()) {
409  it.value()->drawControl(opt, p, widget);
410  return;
411  }
412  if (cc == CC_GroupBox) {
413  if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
414  // Draw frame
415  QRect textRect = subControlRect(CC_GroupBox, opt, SC_GroupBoxLabel, widget);
416  QRect checkBoxRect;
417  if (groupBox->subControls & SC_GroupBoxCheckBox)
418  checkBoxRect = subControlRect(CC_GroupBox, opt, SC_GroupBoxCheckBox, widget);
419  if (groupBox->subControls & QStyle::SC_GroupBoxFrame) {
421  frame.QStyleOption::operator=(*groupBox);
422  frame.features = groupBox->features;
423  frame.lineWidth = groupBox->lineWidth;
424  frame.midLineWidth = groupBox->midLineWidth;
425  frame.rect = subControlRect(CC_GroupBox, opt, SC_GroupBoxFrame, widget);
426  p->save();
427  QRegion region(groupBox->rect);
428  if (!groupBox->text.isEmpty()) {
429  bool ltr = groupBox->direction == Qt::LeftToRight;
430  QRect finalRect;
431  if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox) {
432  finalRect = checkBoxRect.united(textRect);
433  finalRect.adjust(ltr ? -4 : 0, 0, ltr ? 0 : 4, 0);
434  } else {
435  finalRect = textRect;
436  }
437  region -= finalRect;
438  }
439  p->setClipRegion(region);
440  drawPrimitive(PE_FrameGroupBox, &frame, p, widget);
441  p->restore();
442  }
443 
444  // Draw title
445  if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
446  QColor textColor = groupBox->textColor;
447  if (textColor.isValid())
448  p->setPen(textColor);
449  int alignment = int(groupBox->textAlignment);
452 
454  groupBox->palette, groupBox->state & State_Enabled, groupBox->text,
456 
457  if (groupBox->state & State_HasFocus) {
458  QStyleOptionFocusRect fropt;
459  fropt.QStyleOption::operator=(*groupBox);
460  fropt.rect = textRect;
461  drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
462  }
463  }
464 
465  // Draw checkbox
466  if (groupBox->subControls & SC_GroupBoxCheckBox) {
468  box.QStyleOption::operator=(*groupBox);
469  box.rect = checkBoxRect;
470  checkBoxControl->drawControl(&box, p, widget);
471  }
472  }
473  return;
474  }
475  QFusionStyle::drawComplexControl(cc, opt, p, widget);
476 }
477 
479  const QStyleOptionComplex *opt,
480  const QPoint &pt,
481  const QWidget *widget) const
482 {
483  const ItemType itemType = qtControl(cc);
485  ? m_androidControlsHash.find(itemType)
486  : m_androidControlsHash.end();
487  if (it != m_androidControlsHash.end()) {
488  switch (cc) {
489  case CC_Slider:
490  if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
491  QRect r = it.value()->subControlRect(slider, SC_SliderHandle, widget);
492  if (r.isValid() && r.contains(pt)) {
493  return SC_SliderHandle;
494  } else {
495  r = it.value()->subControlRect(slider, SC_SliderGroove, widget);
496  if (r.isValid() && r.contains(pt))
497  return SC_SliderGroove;
498  }
499  }
500  break;
501  default:
502  break;
503  }
504  }
505  return QFusionStyle::hitTestComplexControl(cc, opt, pt, widget);
506 }
507 
509  const QStyleOptionComplex *opt,
510  SubControl sc,
511  const QWidget *widget) const
512 {
513  const ItemType itemType = qtControl(cc);
515  ? m_androidControlsHash.find(itemType)
516  : m_androidControlsHash.end();
517  if (it != m_androidControlsHash.end())
518  return it.value()->subControlRect(opt, sc, widget);
519  QRect rect = opt->rect;
520  switch (cc) {
521  case CC_GroupBox: {
522  if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
523  QSize textSize = opt->fontMetrics.boundingRect(groupBox->text).size() + QSize(2, 2);
524  QSize checkBoxSize = checkBoxControl->size(opt);
525  int indicatorWidth = checkBoxSize.width();
526  int indicatorHeight = checkBoxSize.height();
527  QRect checkBoxRect;
528  if (opt->subControls & QStyle::SC_GroupBoxCheckBox) {
529  checkBoxRect.setWidth(indicatorWidth);
530  checkBoxRect.setHeight(indicatorHeight);
531  }
532  checkBoxRect.moveLeft(1);
533  QRect textRect = checkBoxRect;
534  textRect.setSize(textSize);
535  if (opt->subControls & QStyle::SC_GroupBoxCheckBox)
536  textRect.translate(indicatorWidth + 5, (indicatorHeight - textSize.height()) / 2);
537  if (sc == SC_GroupBoxFrame) {
538  rect = opt->rect.adjusted(0, 0, 0, 0);
539  rect.translate(0, textRect.height() / 2);
540  rect.setHeight(rect.height() - textRect.height() / 2);
541  } else if (sc == SC_GroupBoxContents) {
542  QRect frameRect = opt->rect.adjusted(0, 0, 0, -groupBox->lineWidth);
543  int margin = 3;
544  int leftMarginExtension = 0;
545  int topMargin = qMax(pixelMetric(PM_ExclusiveIndicatorHeight), opt->fontMetrics.height()) + groupBox->lineWidth;
546  frameRect.adjust(leftMarginExtension + margin, margin + topMargin, -margin, -margin - groupBox->lineWidth);
547  frameRect.translate(0, textRect.height() / 2);
548  rect = frameRect;
549  rect.setHeight(rect.height() - textRect.height() / 2);
550  } else if (sc == SC_GroupBoxCheckBox) {
551  rect = checkBoxRect;
552  } else if (sc == SC_GroupBoxLabel) {
553  rect = textRect;
554  }
555  return visualRect(opt->direction, opt->rect, rect);
556  }
557 
558  return rect;
559  }
560 
561  default:
562  break;
563  }
564 
565 
566  return QFusionStyle::subControlRect(cc, opt, sc, widget);
567 }
568 
569 int QAndroidStyle::pixelMetric(PixelMetric metric, const QStyleOption *option,
570  const QWidget *widget) const
571 {
572  switch (metric) {
573  case PM_ButtonMargin:
574  case PM_FocusFrameVMargin:
575  case PM_FocusFrameHMargin:
576  case PM_ComboBoxFrameWidth:
577  case PM_SpinBoxFrameWidth:
578  case PM_ScrollBarExtent:
579  return 0;
580  case PM_IndicatorWidth:
581  return checkBoxControl->size(option).width();
582  case PM_IndicatorHeight:
583  return checkBoxControl->size(option).height();
584  default:
585  return QFusionStyle::pixelMetric(metric, option, widget);
586  }
587 
588 }
589 
591  const QStyleOption *opt,
592  const QSize &contentsSize,
593  const QWidget *w) const
594 {
595  QSize sz = QFusionStyle::sizeFromContents(ct, opt, contentsSize, w);
596  if (ct == CT_HeaderSection) {
597  if (const QStyleOptionHeader *hdr = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
598  bool nullIcon = hdr->icon.isNull();
599  int margin = pixelMetric(QStyle::PM_HeaderMargin, hdr, w);
600  int iconSize = nullIcon ? 0 : checkBoxControl->size(opt).width();
601  QSize txt;
602 /*
603  * These next 4 lines are a bad hack to fix a bug in case a QStyleSheet is applied at QApplication level.
604  * In that case, even if the stylesheet does not refer to headers, the header font is changed to application
605  * font, which is wrong. Even worst, hdr->fontMetrics(...) does not report the proper size.
606  */
607  if (qApp->styleSheet().isEmpty())
608  txt = hdr->fontMetrics.size(0, hdr->text);
609  else
610  txt = QFontMetrics(QApplication::font()).size(0, hdr->text);
611 
612  sz.setHeight(margin + qMax(iconSize, txt.height()) + margin);
613  sz.setWidth((nullIcon ? 0 : margin) + iconSize
614  + (hdr->text.isNull() ? 0 : margin) + txt.width() + margin);
615  if (hdr->sortIndicator != QStyleOptionHeader::None) {
616  int margin = pixelMetric(QStyle::PM_HeaderMargin, hdr, w);
617  if (hdr->orientation == Qt::Horizontal)
618  sz.rwidth() += sz.height() + margin;
619  else
620  sz.rheight() += sz.width() + margin;
621  }
622  return sz;
623  }
624  }
625  const ItemType itemType = qtControl(ct);
627  ? m_androidControlsHash.find(itemType)
628  : m_androidControlsHash.end();
629  if (it != m_androidControlsHash.end())
630  return it.value()->sizeFromContents(opt, sz, w);
631  if (ct == CT_GroupBox) {
632  if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
633  QSize textSize = opt->fontMetrics.boundingRect(groupBox->text).size() + QSize(2, 2);
634  QSize checkBoxSize = checkBoxControl->size(opt);
635  int indicatorWidth = checkBoxSize.width();
636  int indicatorHeight = checkBoxSize.height();
637  QRect checkBoxRect;
638  if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox) {
639  checkBoxRect.setWidth(indicatorWidth);
640  checkBoxRect.setHeight(indicatorHeight);
641  }
642  checkBoxRect.moveLeft(1);
643  QRect textRect = checkBoxRect;
644  textRect.setSize(textSize);
645  if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox)
646  textRect.translate(indicatorWidth + 5, (indicatorHeight - textSize.height()) / 2);
647  QRect u = textRect.united(checkBoxRect);
648  sz = QSize(sz.width(), sz.height() + u.height());
649  }
650  }
651  return sz;
652 }
653 
654 QPixmap QAndroidStyle::standardPixmap(StandardPixmap standardPixmap,
655  const QStyleOption *opt,
656  const QWidget *widget) const
657 {
658  return QFusionStyle::standardPixmap(standardPixmap, opt, widget);
659 }
660 
662  const QPixmap &pixmap,
663  const QStyleOption *opt) const
664 {
665  return QFusionStyle::generatedIconPixmap(iconMode, pixmap, opt);
666 }
667 
669 {
670  switch (hint) {
671  case SH_Slider_AbsoluteSetButtons:
672  return Qt::LeftButton;
673 
674  case SH_Slider_PageSetButtons:
675  return 0;
676 
677  case SH_RequestSoftwareInputPanel:
678  return RSIP_OnMouseClick;
679 
680  case SH_SpinBox_SelectOnStep:
681  return 0;
682 
683  default:
684  return QFusionStyle::styleHint(hint, option, widget, returnData);
685  }
686 }
687 
689 {
690  return m_standardPalette;
691 }
692 
694 {
696 }
697 
699 {
701 }
702 
704  QAndroidStyle::ItemType itemType)
705 {
706  initPadding(drawable);
707  m_itemType = itemType;
708 }
709 
711 {
712 }
713 
715 {
716  QVariantMap::const_iterator it = drawable.find(QLatin1String("padding"));
717  if (it != drawable.end())
718  m_padding = extractMargins(it.value().toMap());
719 }
720 
722 {
723  return m_padding;
724 }
725 
727 {
728  if (type() == Image || type() == NinePatch)
729  return static_cast<const QAndroidStyle::AndroidImageDrawable *>(this)->size();
730 
731  return QSize();
732 }
733 
735  ItemType itemType)
736 {
737  const QString type = drawable.value(QLatin1String("type")).toString();
738  if (type == QLatin1String("image"))
739  return new QAndroidStyle::AndroidImageDrawable(drawable, itemType);
740  if (type == QLatin1String("9patch"))
741  return new QAndroidStyle::Android9PatchDrawable(drawable, itemType);
742  if (type == QLatin1String("stateslist"))
743  return new QAndroidStyle::AndroidStateDrawable(drawable, itemType);
744  if (type == QLatin1String("layer"))
745  return new QAndroidStyle::AndroidLayerDrawable(drawable, itemType);
746  if (type == QLatin1String("gradient"))
747  return new QAndroidStyle::AndroidGradientDrawable(drawable, itemType);
748  if (type == QLatin1String("clipDrawable"))
749  return new QAndroidStyle::AndroidClipDrawable(drawable, itemType);
750  if (type == QLatin1String("color"))
751  return new QAndroidStyle::AndroidColorDrawable(drawable, itemType);
752  return 0;
753 }
754 
756 {
757  QMargins m;
758  m.setLeft(value.value(QLatin1String("left")).toInt());
759  m.setRight(value.value(QLatin1String("right")).toInt());
760  m.setTop(value.value(QLatin1String("top")).toInt());
761  m.setBottom(value.value(QLatin1String("bottom")).toInt());
762  return m;
763 }
764 
766 {
767  QSize sz = size();
768  if (m_padding.isNull() && !sz.isNull())
769  m_padding.setLeft(sz.width());
770 }
771 
772 
774  QAndroidStyle::ItemType itemType)
775  : AndroidDrawable(drawable, itemType)
776 {
777  m_filePath = drawable.value(QLatin1String("path")).toString();
778  m_size.setHeight(drawable.value(QLatin1String("height")).toInt());
779  m_size.setWidth(drawable.value(QLatin1String("width")).toInt());
780 }
781 
783 {
784  return QAndroidStyle::Image;
785 }
786 
788 {
789  if (m_hashKey.isEmpty())
790  m_hashKey = QFileInfo(m_filePath).fileName();
791 
792  QPixmap pm;
793  if (!QPixmapCache::find(m_hashKey, &pm)) {
794  pm.load(m_filePath);
795  QPixmapCache::insert(m_hashKey, pm);
796  }
797 
798  painter->drawPixmap(opt->rect.x(), opt->rect.y() + (opt->rect.height() - pm.height()) / 2, pm);
799 }
800 
802 {
803  return m_size;
804 }
805 
807  ItemType itemType)
808  : AndroidDrawable(drawable, itemType)
809 {
810  m_color.setRgba(QRgb(drawable.value(QLatin1String("color")).toInt()));
811 }
812 
814 {
815  return QAndroidStyle::Color;
816 }
817 
819 {
820  painter->fillRect(opt->rect, m_color);
821 }
822 
824  QAndroidStyle::ItemType itemType)
825  : AndroidImageDrawable(drawable.value(QLatin1String("drawable")).toMap(), itemType)
826 {
827  initPadding(drawable);
828  QVariantMap chunk = drawable.value(QLatin1String("chunkInfo")).toMap();
829  extractIntArray(chunk.value(QLatin1String("xdivs")).toList(), m_chunkData.xDivs);
830  extractIntArray(chunk.value(QLatin1String("ydivs")).toList(), m_chunkData.yDivs);
831  extractIntArray(chunk.value(QLatin1String("colors")).toList(), m_chunkData.colors);
832 }
833 
835 {
837 }
838 
839 int QAndroidStyle::Android9PatchDrawable::calculateStretch(int boundsLimit,
840  int startingPoint,
841  int srcSpace,
842  int numStrechyPixelsRemaining,
843  int numFixedPixelsRemaining)
844 {
845  int spaceRemaining = boundsLimit - startingPoint;
846  int stretchySpaceRemaining = spaceRemaining - numFixedPixelsRemaining;
847  return (float(srcSpace) * stretchySpaceRemaining / numStrechyPixelsRemaining + .5);
848 }
849 
850 void QAndroidStyle::Android9PatchDrawable::extractIntArray(const QVariantList &values,
851  QList<int> & array)
852 {
853  for (const QVariant &value : values)
854  array << value.toInt();
855 }
856 
857 
859 {
860  if (m_hashKey.isEmpty())
861  m_hashKey = QFileInfo(m_filePath).fileName();
862 
863  QPixmap pixmap;
864  if (!QPixmapCache::find(m_hashKey, &pixmap)) {
865  pixmap.load(m_filePath);
866  QPixmapCache::insert(m_hashKey, pixmap);
867  }
868 
869  const QRect &bounds = opt->rect;
870 
871  // shamelessly stolen from Android's sources (NinepatchImpl.cpp) and adapted for Qt
872  const int pixmapWidth = pixmap.width();
873  const int pixmapHeight = pixmap.height();
874 
875  if (bounds.isNull() || !pixmapWidth || !pixmapHeight)
876  return;
877 
878  QPainter::RenderHints savedHints = painter->renderHints();
879 
880  // The patchs doesn't need smooth transform !
882 
883  QRectF dst;
884  QRectF src;
885 
886  const qint32 x0 = m_chunkData.xDivs[0];
887  const qint32 y0 = m_chunkData.yDivs[0];
888  const quint8 numXDivs = m_chunkData.xDivs.size();
889  const quint8 numYDivs = m_chunkData.yDivs.size();
890  int i;
891  int j;
892  int colorIndex = 0;
893  quint32 color;
894  bool xIsStretchable;
895  const bool initialXIsStretchable = (x0 == 0);
896  bool yIsStretchable = (y0 == 0);
897  const int bitmapWidth = pixmap.width();
898  const int bitmapHeight = pixmap.height();
899 
900  int *dstRights = static_cast<int *>(alloca((numXDivs + 1) * sizeof(int)));
901  bool dstRightsHaveBeenCached = false;
902 
903  int numStretchyXPixelsRemaining = 0;
904  for (i = 0; i < numXDivs; i += 2)
905  numStretchyXPixelsRemaining += m_chunkData.xDivs[i + 1] - m_chunkData.xDivs[i];
906 
907  int numFixedXPixelsRemaining = bitmapWidth - numStretchyXPixelsRemaining;
908  int numStretchyYPixelsRemaining = 0;
909  for (i = 0; i < numYDivs; i += 2)
910  numStretchyYPixelsRemaining += m_chunkData.yDivs[i + 1] - m_chunkData.yDivs[i];
911 
912  int numFixedYPixelsRemaining = bitmapHeight - numStretchyYPixelsRemaining;
913  src.setTop(0);
914  dst.setTop(bounds.top());
915  // The first row always starts with the top being at y=0 and the bottom
916  // being either yDivs[1] (if yDivs[0]=0) of yDivs[0]. In the former case
917  // the first row is stretchable along the Y axis, otherwise it is fixed.
918  // The last row always ends with the bottom being bitmap.height and the top
919  // being either yDivs[numYDivs-2] (if yDivs[numYDivs-1]=bitmap.height) or
920  // yDivs[numYDivs-1]. In the former case the last row is stretchable along
921  // the Y axis, otherwise it is fixed.
922  //
923  // The first and last columns are similarly treated with respect to the X
924  // axis.
925  //
926  // The above is to help explain some of the special casing that goes on the
927  // code below.
928 
929  // The initial yDiv and whether the first row is considered stretchable or
930  // not depends on whether yDiv[0] was zero or not.
931  for (j = yIsStretchable ? 1 : 0;
932  j <= numYDivs && src.top() < bitmapHeight;
933  j++, yIsStretchable = !yIsStretchable) {
934  src.setLeft(0);
935  dst.setLeft(bounds.left());
936  if (j == numYDivs) {
937  src.setBottom(bitmapHeight);
938  dst.setBottom(bounds.bottom());
939  } else {
940  src.setBottom(m_chunkData.yDivs[j]);
941  const int srcYSize = src.bottom() - src.top();
942  if (yIsStretchable) {
943  dst.setBottom(dst.top() + calculateStretch(bounds.bottom(), dst.top(),
944  srcYSize,
945  numStretchyYPixelsRemaining,
946  numFixedYPixelsRemaining));
947  numStretchyYPixelsRemaining -= srcYSize;
948  } else {
949  dst.setBottom(dst.top() + srcYSize);
950  numFixedYPixelsRemaining -= srcYSize;
951  }
952  }
953 
954  xIsStretchable = initialXIsStretchable;
955  // The initial xDiv and whether the first column is considered
956  // stretchable or not depends on whether xDiv[0] was zero or not.
957  for (i = xIsStretchable ? 1 : 0;
958  i <= numXDivs && src.left() < bitmapWidth;
959  i++, xIsStretchable = !xIsStretchable) {
960  color = m_chunkData.colors[colorIndex++];
961  if (color != TRANSPARENT_COLOR)
962  color = NO_COLOR;
963  if (i == numXDivs) {
964  src.setRight(bitmapWidth);
965  dst.setRight(bounds.right());
966  } else {
967  src.setRight(m_chunkData.xDivs[i]);
968  if (dstRightsHaveBeenCached) {
969  dst.setRight(dstRights[i]);
970  } else {
971  const int srcXSize = src.right() - src.left();
972  if (xIsStretchable) {
973  dst.setRight(dst.left() + calculateStretch(bounds.right(), dst.left(),
974  srcXSize,
975  numStretchyXPixelsRemaining,
976  numFixedXPixelsRemaining));
977  numStretchyXPixelsRemaining -= srcXSize;
978  } else {
979  dst.setRight(dst.left() + srcXSize);
980  numFixedXPixelsRemaining -= srcXSize;
981  }
982  dstRights[i] = dst.right();
983  }
984  }
985  // If this horizontal patch is too small to be displayed, leave
986  // the destination left edge where it is and go on to the next patch
987  // in the source.
988  if (src.left() >= src.right()) {
989  src.setLeft(src.right());
990  continue;
991  }
992  // Make sure that we actually have room to draw any bits
993  if (dst.right() <= dst.left() || dst.bottom() <= dst.top()) {
994  goto nextDiv;
995  }
996  // If this patch is transparent, skip and don't draw.
997  if (color == TRANSPARENT_COLOR)
998  goto nextDiv;
999  if (color != NO_COLOR)
1001  else
1003 nextDiv:
1004  src.setLeft(src.right());
1005  dst.setLeft(dst.right());
1006  }
1007  src.setTop(src.bottom());
1008  dst.setTop(dst.bottom());
1009  dstRightsHaveBeenCached = true;
1010  }
1011  painter->setRenderHints(savedHints);
1012 }
1013 
1015  QAndroidStyle::ItemType itemType)
1016  : AndroidDrawable(drawable, itemType), m_orientation(TOP_BOTTOM)
1017 {
1018  m_radius = drawable.value(QLatin1String("radius")).toInt();
1019  if (m_radius < 0)
1020  m_radius = 0;
1021 
1022  QVariantList colors = drawable.value(QLatin1String("colors")).toList();
1023  QVariantList positions = drawable.value(QLatin1String("positions")).toList();
1024  int min = colors.size() < positions.size() ? colors.size() : positions.size();
1025  for (int i = 0; i < min; i++)
1026  m_gradient.setColorAt(positions.at(i).toDouble(), QRgb(colors.at(i).toInt()));
1027 
1028  QByteArray orientation = drawable.value(QLatin1String("orientation")).toByteArray();
1029  if (orientation == "TOP_BOTTOM") // draw the gradient from the top to the bottom
1030  m_orientation = TOP_BOTTOM;
1031  else if (orientation == "TR_BL") // draw the gradient from the top-right to the bottom-left
1032  m_orientation = TR_BL;
1033  else if (orientation == "RIGHT_LEFT") // draw the gradient from the right to the left
1034  m_orientation = RIGHT_LEFT;
1035  else if (orientation == "BR_TL") // draw the gradient from the bottom-right to the top-left
1036  m_orientation = BR_TL;
1037  else if (orientation == "BOTTOM_TOP") // draw the gradient from the bottom to the top
1038  m_orientation = BOTTOM_TOP;
1039  else if (orientation == "BL_TR") // draw the gradient from the bottom-left to the top-right
1040  m_orientation = BL_TR;
1041  else if (orientation == "LEFT_RIGHT") // draw the gradient from the left to the right
1042  m_orientation = LEFT_RIGHT;
1043  else if (orientation == "TL_BR") // draw the gradient from the top-left to the bottom-right
1044  m_orientation = TL_BR;
1045  else
1046  qWarning("AndroidGradientDrawable: unknown orientation");
1047 }
1048 
1050 {
1051  return QAndroidStyle::Gradient;
1052 }
1053 
1055 {
1056  const int width = opt->rect.width();
1057  const int height = opt->rect.height();
1058  switch (m_orientation) {
1059  case TOP_BOTTOM:
1060  // draw the gradient from the top to the bottom
1061  m_gradient.setStart(width / 2, 0);
1062  m_gradient.setFinalStop(width / 2, height);
1063  break;
1064  case TR_BL:
1065  // draw the gradient from the top-right to the bottom-left
1066  m_gradient.setStart(width, 0);
1067  m_gradient.setFinalStop(0, height);
1068  break;
1069  case RIGHT_LEFT:
1070  // draw the gradient from the right to the left
1071  m_gradient.setStart(width, height / 2);
1072  m_gradient.setFinalStop(0, height / 2);
1073  break;
1074  case BR_TL:
1075  // draw the gradient from the bottom-right to the top-left
1076  m_gradient.setStart(width, height);
1077  m_gradient.setFinalStop(0, 0);
1078  break;
1079  case BOTTOM_TOP:
1080  // draw the gradient from the bottom to the top
1081  m_gradient.setStart(width / 2, height);
1082  m_gradient.setFinalStop(width / 2, 0);
1083  break;
1084  case BL_TR:
1085  // draw the gradient from the bottom-left to the top-right
1086  m_gradient.setStart(0, height);
1087  m_gradient.setFinalStop(width, 0);
1088  break;
1089  case LEFT_RIGHT:
1090  // draw the gradient from the left to the right
1091  m_gradient.setStart(0, height / 2);
1092  m_gradient.setFinalStop(width, height / 2);
1093  break;
1094  case TL_BR:
1095  // draw the gradient from the top-left to the bottom-right
1096  m_gradient.setStart(0, 0);
1097  m_gradient.setFinalStop(width, height);
1098  break;
1099  }
1100 
1101  const QBrush &oldBrush = painter->brush();
1102  const QPen oldPen = painter->pen();
1104  painter->setBrush(m_gradient);
1105  painter->drawRoundedRect(opt->rect, m_radius, m_radius);
1106  painter->setBrush(oldBrush);
1107  painter->setPen(oldPen);
1108 }
1109 
1111 {
1112  return QSize(m_radius * 2, m_radius * 2);
1113 }
1114 
1116  QAndroidStyle::ItemType itemType)
1117  : AndroidDrawable(drawable, itemType)
1118 {
1119  m_drawable = fromMap(drawable.value(QLatin1String("drawable")).toMap(), itemType);
1120  m_factor = 0;
1121  m_orientation = Qt::Horizontal;
1122 }
1123 
1125 {
1126  delete m_drawable;
1127 }
1128 
1130 {
1131  return QAndroidStyle::Clip;
1132 }
1133 
1135 {
1136  m_factor = factor;
1137  m_orientation = orientation;
1138 }
1139 
1141 {
1142  QStyleOption copy(*opt);
1143  if (m_orientation == Qt::Horizontal)
1144  copy.rect.setWidth(copy.rect.width() * m_factor);
1145  else
1146  copy.rect.setHeight(copy.rect.height() * m_factor);
1147 
1148  m_drawable->draw(painter, &copy);
1149 }
1150 
1152  QAndroidStyle::ItemType itemType)
1153  : AndroidDrawable(drawable, itemType)
1154 {
1155  const QVariantList states = drawable.value(QLatin1String("stateslist")).toList();
1156  for (const QVariant &stateVariant : states) {
1157  QVariantMap state = stateVariant.toMap();
1158  const int s = extractState(state.value(QLatin1String("states")).toMap());
1159  if (-1 == s)
1160  continue;
1161  const AndroidDrawable *ad = fromMap(state.value(QLatin1String("drawable")).toMap(), itemType);
1162  if (!ad)
1163  continue;
1164  StateType item;
1165  item.first = s;
1166  item.second = ad;
1167  m_states<<item;
1168  }
1169 }
1170 
1172 {
1173  for (const StateType &type : qAsConst(m_states))
1174  delete type.second;
1175 }
1176 
1178 {
1179  return QAndroidStyle::State;
1180 }
1181 
1183 {
1184  const AndroidDrawable *drawable = bestAndroidStateMatch(opt);
1185  if (drawable)
1186  drawable->draw(painter, opt);
1187 }
1189 {
1190  QSize s;
1191  const AndroidDrawable *drawable = bestAndroidStateMatch(opt);
1192  if (drawable)
1193  s = drawable->size();
1194  return s;
1195 }
1196 
1198 {
1199  const AndroidDrawable *bestMatch = nullptr;
1200  if (!opt) {
1201  if (m_states.size())
1202  return m_states[0].second;
1203  return bestMatch;
1204  }
1205 
1206  uint bestCost = 0xffff;
1207  for (const StateType & state : m_states) {
1208  if (int(opt->state) == state.first)
1209  return state.second;
1210  uint cost = 1;
1211 
1212  int difference = int(opt->state^state.first);
1213 
1214  if (difference & QStyle::State_Active)
1215  cost <<= 1;
1216 
1217  if (difference & QStyle::State_Enabled)
1218  cost <<= 1;
1219 
1220  if (difference & QStyle::State_Raised)
1221  cost <<= 1;
1222 
1223  if (difference & QStyle::State_Sunken)
1224  cost <<= 1;
1225 
1226  if (difference & QStyle::State_Off)
1227  cost <<= 1;
1228 
1229  if (difference & QStyle::State_On)
1230  cost <<= 1;
1231 
1232  if (difference & QStyle::State_HasFocus)
1233  cost <<= 1;
1234 
1235  if (difference & QStyle::State_Selected)
1236  cost <<= 1;
1237 
1238  if (cost < bestCost) {
1239  bestCost = cost;
1240  bestMatch = state.second;
1241  }
1242  }
1243  return bestMatch;
1244 }
1245 
1247 {
1249  for (auto it = value.cbegin(), end = value.cend(); it != end; ++it) {
1250  const QString &key = it.key();
1251  bool val = it.value().toString() == QLatin1String("true");
1252  if (key == QLatin1String("enabled")) {
1253  state.setFlag(QStyle::State_Enabled, val);
1254  continue;
1255  }
1256 
1257  if (key == QLatin1String("window_focused")) {
1258  state.setFlag(QStyle::State_Active, val);
1259  continue;
1260  }
1261 
1262  if (key == QLatin1String("focused")) {
1263  state.setFlag(QStyle::State_HasFocus, val);
1264  continue;
1265  }
1266 
1267  if (key == QLatin1String("checked")) {
1269  continue;
1270  }
1271 
1272  if (key == QLatin1String("pressed")) {
1274  continue;
1275  }
1276 
1277  if (key == QLatin1String("selected")) {
1278  state.setFlag(QStyle::State_Selected, val);
1279  continue;
1280  }
1281 
1282  if (key == QLatin1String("active")) {
1283  state.setFlag(QStyle::State_Active, val);
1284  continue;
1285  }
1286 
1287  if (key == QLatin1String("multiline"))
1288  return 0;
1289 
1290  if (key == QLatin1String("background") && val)
1291  return -1;
1292  }
1293  return static_cast<int>(state);
1294 }
1295 
1297 {
1298  for (const StateType &type : qAsConst(m_states))
1299  const_cast<AndroidDrawable *>(type.second)->setPaddingLeftToSizeWidth();
1300 }
1301 
1303  QAndroidStyle::ItemType itemType)
1304  : AndroidDrawable(drawable, itemType)
1305 {
1306  m_id = 0;
1307  m_factor = 1;
1308  m_orientation = Qt::Horizontal;
1309  const QVariantList layers = drawable.value(QLatin1String("layers")).toList();
1310  for (const QVariant &layer : layers) {
1311  QVariantMap layerMap = layer.toMap();
1312  AndroidDrawable *ad = fromMap(layerMap, itemType);
1313  if (ad) {
1314  LayerType l;
1315  l.second = ad;
1316  l.first = layerMap.value(QLatin1String("id")).toInt();
1317  m_layers << l;
1318  }
1319  }
1320 }
1321 
1323 {
1324  for (const LayerType &layer : qAsConst(m_layers))
1325  delete layer.second;
1326 }
1327 
1329 {
1330  return QAndroidStyle::Layer;
1331 }
1332 
1334 {
1335  m_id = id;
1336  m_factor = factor;
1337  m_orientation = orientation;
1338 }
1339 
1341 {
1342  for (const LayerType &layer : m_layers) {
1343  if (layer.first == m_id) {
1344  QStyleOption copy(*opt);
1345  if (m_orientation == Qt::Horizontal)
1346  copy.rect.setWidth(copy.rect.width() * m_factor);
1347  else
1348  copy.rect.setHeight(copy.rect.height() * m_factor);
1349  layer.second->draw(painter, &copy);
1350  } else {
1351  layer.second->draw(painter, opt);
1352  }
1353  }
1354 }
1355 
1357 {
1358  for (const LayerType &layer : m_layers) {
1359  if (layer.first == id)
1360  return layer.second;
1361  }
1362  return 0;
1363 }
1364 
1366 {
1367  QSize sz;
1368  for (const LayerType &layer : m_layers)
1369  sz = sz.expandedTo(layer.second->size());
1370  return sz;
1371 }
1372 
1374  QAndroidStyle::ItemType itemType)
1375 {
1376  QVariantMap::const_iterator it = control.find(QLatin1String("View_background"));
1377  if (it != control.end())
1378  m_background = AndroidDrawable::fromMap(it.value().toMap(), itemType);
1379  else
1380  m_background = 0;
1381 
1382  it = control.find(QLatin1String("View_minWidth"));
1383  if (it != control.end())
1384  m_minSize.setWidth(it.value().toInt());
1385 
1386  it = control.find(QLatin1String("View_minHeight"));
1387  if (it != control.end())
1388  m_minSize.setHeight(it.value().toInt());
1389 
1390  it = control.find(QLatin1String("View_maxWidth"));
1391  if (it != control.end())
1392  m_maxSize.setWidth(it.value().toInt());
1393 
1394  it = control.find(QLatin1String("View_maxHeight"));
1395  if (it != control.end())
1396  m_maxSize.setHeight(it.value().toInt());
1397 }
1398 
1400 {
1401  delete m_background;
1402 }
1403 
1405 {
1406  if (m_background) {
1407  m_background->draw(p, opt);
1408  } else {
1409  if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
1410  if ((frame->state & State_Sunken) || (frame->state & State_Raised)) {
1411  qDrawShadePanel(p, frame->rect, frame->palette, frame->state & State_Sunken,
1412  frame->lineWidth);
1413  } else {
1415  }
1416  } else {
1417  if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(opt)) {
1418  QColor bg = fropt->backgroundColor;
1419  QPen oldPen = p->pen();
1420  if (bg.isValid()) {
1421  int h, s, v;
1422  bg.getHsv(&h, &s, &v);
1423  if (v >= 128)
1424  p->setPen(Qt::black);
1425  else
1426  p->setPen(Qt::white);
1427  } else {
1428  p->setPen(opt->palette.windowText().color());
1429  }
1430  QRect focusRect = opt->rect.adjusted(1, 1, -1, -1);
1431  p->drawRect(focusRect.adjusted(0, 0, -1, -1)); //draw pen inclusive
1432  p->setPen(oldPen);
1433  } else {
1434  p->fillRect(opt->rect, opt->palette.window());
1435  }
1436  }
1437  }
1438 }
1439 
1441  const QStyleOption *option,
1442  const QWidget * /* widget */) const
1443 {
1444  if (const AndroidDrawable *drawable = backgroundDrawable()) {
1445  if (drawable->type() == State)
1446  drawable = static_cast<const AndroidStateDrawable *>(backgroundDrawable())->bestAndroidStateMatch(option);
1447 
1448  const QMargins &padding = drawable->padding();
1449 
1450  QRect r = option->rect.adjusted(padding.left(), padding.top(),
1451  -padding.right(), -padding.bottom());
1452 
1453  if (r.width() < m_minSize.width())
1454  r.setWidth(m_minSize.width());
1455 
1456  if (r.height() < m_minSize.height())
1457  r.setHeight(m_minSize.height());
1458 
1459  return visualRect(option->direction, option->rect, r);
1460  }
1461  return option->rect;
1462 }
1463 
1465  QStyle::SubControl /*sc*/,
1466  const QWidget *widget) const
1467 {
1469 }
1470 
1472  const QSize &contentsSize,
1473  const QWidget * /* w */) const
1474 {
1475  QSize sz;
1476  if (const AndroidDrawable *drawable = backgroundDrawable()) {
1477 
1478  if (drawable->type() == State)
1479  drawable = static_cast<const AndroidStateDrawable*>(backgroundDrawable())->bestAndroidStateMatch(opt);
1480  const QMargins &padding = drawable->padding();
1481  sz.setWidth(padding.left() + padding.right());
1482  sz.setHeight(padding.top() + padding.bottom());
1483  if (sz.isEmpty())
1484  sz = drawable->size();
1485  }
1486  sz += contentsSize;
1487  if (contentsSize.height() < opt->fontMetrics.height())
1488  sz.setHeight(sz.height() + (opt->fontMetrics.height() - contentsSize.height()));
1489  if (sz.height() < m_minSize.height())
1490  sz.setHeight(m_minSize.height());
1491  if (sz.width() < m_minSize.width())
1492  sz.setWidth(m_minSize.width());
1493  return sz;
1494 }
1495 
1497 {
1498  if (const AndroidDrawable *drawable = m_background) {
1499  if (drawable->type() == State)
1500  drawable = static_cast<const AndroidStateDrawable *>(m_background)->bestAndroidStateMatch(0);
1501  return drawable->padding();
1502  }
1503  return QMargins();
1504 }
1505 
1507 {
1508  if (const AndroidDrawable *drawable = backgroundDrawable()) {
1509  if (drawable->type() == State)
1510  drawable = static_cast<const AndroidStateDrawable *>(backgroundDrawable())->bestAndroidStateMatch(option);
1511  return drawable->size();
1512  }
1513  return QSize();
1514 }
1515 
1517 {
1518  return m_background;
1519 }
1520 
1522  ItemType itemType)
1523  : AndroidControl(control, itemType)
1524 {
1525  QVariantMap::const_iterator it = control.find(QLatin1String("CompoundButton_button"));
1526  if (it != control.end()) {
1527  m_button = AndroidDrawable::fromMap(it.value().toMap(), itemType);
1528  const_cast<AndroidDrawable *>(m_button)->setPaddingLeftToSizeWidth();
1529  } else {
1530  m_button = 0;
1531  }
1532 }
1533 
1535 {
1536  delete m_button;
1537 }
1538 
1540  QPainter *p,
1541  const QWidget *w)
1542 {
1544  if (m_button)
1545  m_button->draw(p, opt);
1546 }
1547 
1549 {
1550  if (m_button)
1551  return m_button->padding();
1552  return AndroidControl::padding();
1553 }
1554 
1556 {
1557  if (m_button) {
1558  if (m_button->type() == State)
1559  return static_cast<const AndroidStateDrawable *>(m_button)->bestAndroidStateMatch(option)->size();
1560  return m_button->size();
1561  }
1562  return AndroidControl::size(option);
1563 }
1564 
1566 {
1567  return m_background ? m_background : m_button;
1568 }
1569 
1571  ItemType itemType)
1572  : AndroidControl(control, itemType)
1573 {
1574  QVariantMap::const_iterator it = control.find(QLatin1String("ProgressBar_indeterminateDrawable"));
1575  if (it != control.end())
1576  m_indeterminateDrawable = AndroidDrawable::fromMap(it.value().toMap(), itemType);
1577  else
1579 
1580  it = control.find(QLatin1String("ProgressBar_progressDrawable"));
1581  if (it != control.end())
1582  m_progressDrawable = AndroidDrawable::fromMap(it.value().toMap(), itemType);
1583  else
1584  m_progressDrawable = 0;
1585 
1586  it = control.find(QLatin1String("ProgressBar_progress_id"));
1587  if (it != control.end())
1588  m_progressId = it.value().toInt();
1589 
1590  it = control.find(QLatin1String("ProgressBar_secondaryProgress_id"));
1591  if (it != control.end())
1592  m_secondaryProgress_id = it.value().toInt();
1593 
1594  it = control.find(QLatin1String("ProgressBar_minWidth"));
1595  if (it != control.end())
1596  m_minSize.setWidth(it.value().toInt());
1597 
1598  it = control.find(QLatin1String("ProgressBar_minHeight"));
1599  if (it != control.end())
1600  m_minSize.setHeight(it.value().toInt());
1601 
1602  it = control.find(QLatin1String("ProgressBar_maxWidth"));
1603  if (it != control.end())
1604  m_maxSize.setWidth(it.value().toInt());
1605 
1606  it = control.find(QLatin1String("ProgressBar_maxHeight"));
1607  if (it != control.end())
1608  m_maxSize.setHeight(it.value().toInt());
1609 }
1610 
1612 {
1613  delete m_progressDrawable;
1614  delete m_indeterminateDrawable;
1615 }
1616 
1618 {
1619  if (!m_progressDrawable)
1620  return;
1621 
1622  if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
1623  if (m_progressDrawable->type() == QAndroidStyle::Layer) {
1624  const double fraction = double(qint64(pb->progress) - pb->minimum) / (qint64(pb->maximum) - pb->minimum);
1625  QAndroidStyle::AndroidDrawable *clipDrawable = static_cast<QAndroidStyle::AndroidLayerDrawable *>(m_progressDrawable)->layer(m_progressId);
1626  const Qt::Orientation orientation = pb->state & QStyle::State_Horizontal ? Qt::Horizontal : Qt::Vertical;
1627  if (clipDrawable->type() == QAndroidStyle::Clip)
1628  static_cast<AndroidClipDrawable *>(clipDrawable)->setFactor(fraction, orientation);
1629  else
1630  static_cast<AndroidLayerDrawable *>(m_progressDrawable)->setFactor(m_progressId, fraction, orientation);
1631  }
1632  m_progressDrawable->draw(p, option);
1633  }
1634 }
1635 
1637  const QStyleOption *option,
1638  const QWidget *widget) const
1639 {
1640  if (const QStyleOptionProgressBar *progressBarOption =
1641  qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
1642  const bool horizontal = progressBarOption->state & QStyle::State_Horizontal;
1643  if (!m_background)
1644  return option->rect;
1645 
1646  QMargins padding = m_background->padding();
1647  QRect p(padding.left(), padding.top(), padding.right() - padding.left(), padding.bottom() - padding.top());
1648  padding = m_indeterminateDrawable->padding();
1649  p |= QRect(padding.left(), padding.top(), padding.right() - padding.left(), padding.bottom() - padding.top());
1650  padding = m_progressDrawable->padding();
1651  p |= QRect(padding.left(), padding.top(), padding.right() - padding.left(), padding.bottom() - padding.top());
1652  QRect r = option->rect.adjusted(p.left(), p.top(), -p.right(), -p.bottom());
1653 
1654  if (horizontal) {
1655  if (r.height()<m_minSize.height())
1656  r.setHeight(m_minSize.height());
1657 
1658  if (r.height()>m_maxSize.height())
1659  r.setHeight(m_maxSize.height());
1660  } else {
1661  if (r.width()<m_minSize.width())
1662  r.setWidth(m_minSize.width());
1663 
1664  if (r.width()>m_maxSize.width())
1665  r.setWidth(m_maxSize.width());
1666  }
1667  return visualRect(option->direction, option->rect, r);
1668  }
1669  return AndroidControl::subElementRect(subElement, option, widget);
1670 }
1671 
1673  const QSize &contentsSize,
1674  const QWidget * /* w */) const
1675 {
1676  QSize sz(contentsSize);
1677  if (sz.height() < m_minSize.height())
1678  sz.setHeight(m_minSize.height());
1679  if (sz.width() < m_minSize.width())
1680  sz.setWidth(m_minSize.width());
1681 
1682  if (const QStyleOptionProgressBar *progressBarOption =
1683  qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
1684  if (progressBarOption->state & QStyle::State_Horizontal) {
1685  if (sz.width() > m_maxSize.width())
1686  sz.setWidth(m_maxSize.width());
1687  } else {
1688  if (sz.height() > m_maxSize.height())
1689  sz.setHeight(m_maxSize.height());
1690  }
1691  }
1692  return contentsSize;
1693 }
1694 
1696  ItemType itemType)
1697  : AndroidProgressBarControl(control, itemType)
1698 {
1699  QVariantMap::const_iterator it = control.find(QLatin1String("SeekBar_thumb"));
1700  if (it != control.end())
1701  m_seekBarThumb = AndroidDrawable::fromMap(it.value().toMap(), itemType);
1702  else
1703  m_seekBarThumb = 0;
1704 }
1705 
1707 {
1708  delete m_seekBarThumb;
1709 }
1710 
1712  QPainter *p,
1713  const QWidget * /* w */)
1714 {
1715  if (!m_seekBarThumb || !m_progressDrawable)
1716  return;
1717 
1718  if (const QStyleOptionSlider *styleOption =
1719  qstyleoption_cast<const QStyleOptionSlider *>(option)) {
1720  double factor = double(styleOption->sliderPosition - styleOption->minimum)
1721  / double(styleOption->maximum - styleOption->minimum);
1722 
1723  // Android does not have a vertical slider. To support the vertical orientation, we rotate
1724  // the painter and pretend that we are horizontal.
1725  if (styleOption->orientation == Qt::Vertical)
1726  factor = 1 - factor;
1727 
1728  if (m_progressDrawable->type() == QAndroidStyle::Layer) {
1729  QAndroidStyle::AndroidDrawable *clipDrawable = static_cast<QAndroidStyle::AndroidLayerDrawable *>(m_progressDrawable)->layer(m_progressId);
1730  if (clipDrawable->type() == QAndroidStyle::Clip)
1731  static_cast<QAndroidStyle::AndroidClipDrawable *>(clipDrawable)->setFactor(factor, Qt::Horizontal);
1732  else
1733  static_cast<QAndroidStyle::AndroidLayerDrawable *>(m_progressDrawable)->setFactor(m_progressId, factor, Qt::Horizontal);
1734  }
1735  const AndroidDrawable *drawable = m_seekBarThumb;
1736  if (drawable->type() == State)
1737  drawable = static_cast<const QAndroidStyle::AndroidStateDrawable *>(m_seekBarThumb)->bestAndroidStateMatch(option);
1738  QStyleOption copy(*option);
1739 
1740  p->save();
1741 
1742  if (styleOption->orientation == Qt::Vertical) {
1743  // rotate the painter, and transform the rectangle to match
1744  p->rotate(90);
1745  copy.rect = QRect(copy.rect.y(), copy.rect.x() - copy.rect.width(), copy.rect.height(), copy.rect.width());
1746  }
1747 
1748  copy.rect.setHeight(m_progressDrawable->size().height());
1749  copy.rect.setWidth(copy.rect.width() - drawable->size().width());
1750  const int yTranslate = abs(drawable->size().height() - copy.rect.height()) / 2;
1751  copy.rect.translate(drawable->size().width() / 2, yTranslate);
1752  m_progressDrawable->draw(p, &copy);
1753  int pos = copy.rect.width() * factor - drawable->size().width() / 2;
1754  copy.rect.translate(pos, -yTranslate);
1755  copy.rect.setSize(drawable->size());
1756  m_seekBarThumb->draw(p, &copy);
1757 
1758  p->restore();
1759  }
1760 }
1761 
1763  const QSize &contentsSize,
1764  const QWidget *w) const
1765 {
1767  if (!m_seekBarThumb)
1768  return sz;
1769  const AndroidDrawable *drawable = m_seekBarThumb;
1770  if (drawable->type() == State)
1771  drawable = static_cast<const QAndroidStyle::AndroidStateDrawable *>(m_seekBarThumb)->bestAndroidStateMatch(opt);
1772  return sz.expandedTo(drawable->size());
1773 }
1774 
1776  SubControl sc,
1777  const QWidget * /* widget */) const
1778 {
1779  const QStyleOptionSlider *styleOption =
1780  qstyleoption_cast<const QStyleOptionSlider *>(option);
1781 
1782  if (m_seekBarThumb && sc == SC_SliderHandle && styleOption) {
1783  const AndroidDrawable *drawable = m_seekBarThumb;
1784  if (drawable->type() == State)
1785  drawable = static_cast<const QAndroidStyle::AndroidStateDrawable *>(m_seekBarThumb)->bestAndroidStateMatch(option);
1786 
1787  QRect r(option->rect);
1788  double factor = double(styleOption->sliderPosition - styleOption->minimum)
1789  / (styleOption->maximum - styleOption->minimum);
1790  if (styleOption->orientation == Qt::Vertical) {
1791  int pos = option->rect.height() * (1 - factor) - double(drawable->size().height() / 2);
1792  r.setY(r.y() + pos);
1793  } else {
1794  int pos = option->rect.width() * factor - double(drawable->size().width() / 2);
1795  r.setX(r.x() + pos);
1796  }
1797  r.setSize(drawable->size());
1798  return r;
1799  }
1800  return option->rect;
1801 }
1802 
1804  QAndroidStyle::ItemType itemType)
1805  : AndroidControl(control, itemType)
1806 {}
1807 
1809  SubControl sc,
1810  const QWidget *widget) const
1811 {
1813  return option->rect;
1814  if (sc == QStyle::SC_ComboBoxArrow) {
1816  return QRect(editField.topRight(), QSize(option->rect.width() - editField.width(), option->rect.height()));
1817  }
1819 }
1820 
small capitals from c petite p scientific f u
Definition: afcover.h:88
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
enum State_ State
virtual AndroidDrawableType type() const
Android9PatchDrawable(const QVariantMap &drawable, ItemType itemType)
virtual void draw(QPainter *painter, const QStyleOption *opt) const
virtual void setFactor(double factor, Qt::Orientation orientation)
virtual AndroidDrawableType type() const
virtual void draw(QPainter *painter, const QStyleOption *opt) const
AndroidClipDrawable(const QVariantMap &drawable, ItemType itemType)
virtual void draw(QPainter *painter, const QStyleOption *opt) const
virtual AndroidDrawableType type() const
AndroidColorDrawable(const QVariantMap &drawable, ItemType itemType)
AndroidCompoundButtonControl(const QVariantMap &control, ItemType itemType)
virtual QSize size(const QStyleOption *option)
virtual void drawControl(const QStyleOption *opt, QPainter *p, const QWidget *w)
virtual const AndroidDrawable * backgroundDrawable() const
virtual QSize size(const QStyleOption *option)
virtual QRect subElementRect(SubElement subElement, const QStyleOption *option, const QWidget *widget=nullptr) const
virtual void drawControl(const QStyleOption *opt, QPainter *p, const QWidget *w)
AndroidControl(const QVariantMap &control, ItemType itemType)
virtual const AndroidDrawable * backgroundDrawable() const
virtual QRect subControlRect(const QStyleOptionComplex *option, SubControl sc, const QWidget *widget=nullptr) const
virtual QSize sizeFromContents(const QStyleOption *opt, const QSize &contentsSize, const QWidget *w) const
const QMargins & padding() const
virtual QSize size() const
static AndroidDrawable * fromMap(const QVariantMap &drawable, ItemType itemType)
static QMargins extractMargins(const QVariantMap &value)
virtual AndroidDrawableType type() const =0
AndroidDrawable(const QVariantMap &drawable, ItemType itemType)
virtual void setPaddingLeftToSizeWidth()
virtual void initPadding(const QVariantMap &drawable)
virtual void draw(QPainter *painter, const QStyleOption *opt) const =0
virtual void draw(QPainter *painter, const QStyleOption *opt) const
virtual AndroidDrawableType type() const
AndroidGradientDrawable(const QVariantMap &drawable, ItemType itemType)
AndroidImageDrawable(const QVariantMap &drawable, ItemType itemType)
virtual AndroidDrawableType type() const
virtual void draw(QPainter *painter, const QStyleOption *opt) const
virtual AndroidDrawableType type() const
AndroidLayerDrawable(const QVariantMap &drawable, QAndroidStyle::ItemType itemType)
virtual void setFactor(int id, double factor, Qt::Orientation orientation)
virtual void draw(QPainter *painter, const QStyleOption *opt) const
AndroidDrawable * layer(int id) const
QSize sizeFromContents(const QStyleOption *opt, const QSize &contentsSize, const QWidget *w) const
virtual void drawControl(const QStyleOption *option, QPainter *p, const QWidget *w)
virtual QRect subElementRect(SubElement subElement, const QStyleOption *option, const QWidget *widget=nullptr) const
AndroidProgressBarControl(const QVariantMap &control, ItemType itemType)
virtual void drawControl(const QStyleOption *option, QPainter *p, const QWidget *w)
QRect subControlRect(const QStyleOptionComplex *option, SubControl sc, const QWidget *widget=nullptr) const
QSize sizeFromContents(const QStyleOption *opt, const QSize &contentsSize, const QWidget *w) const
AndroidSeekBarControl(const QVariantMap &control, ItemType itemType)
virtual QRect subControlRect(const QStyleOptionComplex *option, SubControl sc, const QWidget *widget=nullptr) const
AndroidSpinnerControl(const QVariantMap &control, ItemType itemType)
const AndroidDrawable * bestAndroidStateMatch(const QStyleOption *opt) const
static int extractState(const QVariantMap &value)
AndroidStateDrawable(const QVariantMap &drawable, ItemType itemType)
virtual void draw(QPainter *painter, const QStyleOption *opt) const
virtual AndroidDrawableType type() const
QSize sizeImage(const QStyleOption *opt) const
virtual QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *w=nullptr) const
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option=nullptr, const QWidget *widget=nullptr) const
virtual QRect subElementRect(SubElement subElement, const QStyleOption *option, const QWidget *widget=nullptr) const
virtual SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, const QPoint &pt, const QWidget *widget=nullptr) const
virtual void drawControl(QStyle::ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w=nullptr) const
void polish(QWidget *widget)
virtual QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt=nullptr, const QWidget *widget=nullptr) const
virtual QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const
virtual QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget=nullptr) const
int styleHint(StyleHint hint, const QStyleOption *option=nullptr, const QWidget *widget=nullptr, QStyleHintReturn *returnData=nullptr) const
virtual void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w=nullptr) const
virtual QPalette standardPalette() const
virtual void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, const QWidget *widget=nullptr) const
void unpolish(QWidget *widget)
static QFont font()
static void setFont(const QFont &, const char *className=nullptr)
The QBrush class defines the fill pattern of shapes drawn by QPainter.
Definition: qbrush.h:66
const QColor & color() const
Definition: qbrush.h:157
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:85
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
void setRgba(QRgb rgba) noexcept
Definition: qcolor.cpp:1385
void getHsv(int *h, int *s, int *v, int *a=nullptr) const
Definition: qcolor.cpp:1039
bool isValid() const noexcept
Definition: qcolor.h:307
The QFileInfo class provides system-independent file information.
Definition: qfileinfo.h:57
QString fileName() const
Definition: qfileinfo.cpp:772
The QFontMetrics class provides font metrics information.
Definition: qfontmetrics.h:56
int height() const
QRect boundingRect(QChar) const
QSize size(int flags, const QString &str, int tabstops=0, int *tabarray=nullptr) const
int midLineWidth
the width of the mid-line
Definition: qframe.h:59
int lineWidth
the line width
Definition: qframe.h:58
void setColorAt(qreal pos, const QColor &color)
Definition: qbrush.cpp:1596
static QPlatformNativeInterface * platformNativeInterface()
const_iterator constEnd() const noexcept
Definition: qhash.h:1162
iterator find(const Key &key)
Definition: qhash.h:1204
const_iterator constBegin() const noexcept
Definition: qhash.h:1158
iterator end() noexcept
Definition: qhash.h:1159
friend class const_iterator
Definition: qhash.h:1125
void clear() noexcept(std::is_nothrow_destructible< Node >::value)
Definition: qhash.h:904
Mode
Definition: qicon.h:58
The QJsonObject::const_iterator class provides an STL-style const iterator for QJsonObject.
Definition: qjsonobject.h:185
The QJsonObject class encapsulates a JSON object.
Definition: qjsonobject.h:56
The QJsonValue class encapsulates a value in JSON.
Definition: qjsonvalue.h:60
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal.
Definition: qstring.h:84
qsizetype size() const noexcept
Definition: qlist.h:414
const_reference at(qsizetype i) const noexcept
Definition: qlist.h:457
T value(const Key &key, const T &defaultValue=T()) const
Definition: qmap.h:392
iterator find(const Key &key)
Definition: qmap.h:672
iterator end()
Definition: qmap.h:637
The QMargins class defines the four margins of a rectangle.
Definition: qmargins.h:52
constexpr int bottom() const noexcept
Definition: qmargins.h:146
constexpr int left() const noexcept
Definition: qmargins.h:137
constexpr int right() const noexcept
Definition: qmargins.h:143
constexpr int top() const noexcept
Definition: qmargins.h:140
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:82
const QPen & pen() const
Definition: qpainter.cpp:3736
RenderHints renderHints() const
Definition: qpainter.cpp:6897
void setPen(const QColor &color)
Definition: qpainter.cpp:3640
const QBrush & brush() const
Definition: qpainter.cpp:3813
void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect)
Definition: qpainter.cpp:4883
void setBrush(const QBrush &brush)
Definition: qpainter.cpp:3755
@ SmoothPixmapTransform
Definition: qpainter.h:90
void setRenderHints(RenderHints hints, bool on=true)
Definition: qpainter.cpp:6871
void fillRect(const QRectF &, const QBrush &)
Definition: qpainter.cpp:6644
void drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode=Qt::AbsoluteSize)
Definition: qpainter.cpp:3924
The QPalette class contains color groups for each widget state.
Definition: qpalette.h:55
const QBrush & windowText() const
Definition: qpalette.h:117
const QBrush & window() const
Definition: qpalette.h:127
@ WindowText
Definition: qpalette.h:86
@ NoRole
Definition: qpalette.h:91
The QPen class defines how a QPainter should draw lines and outlines of shapes.
Definition: qpen.h:61
static bool find(const QString &key, QPixmap *pixmap)
static bool insert(const QString &key, const QPixmap &pixmap)
static void clear()
The QPixmap class is an off-screen image representation that can be used as a paint device.
Definition: qpixmap.h:63
int height() const
Definition: qpixmap.cpp:515
bool load(const QString &fileName, const char *format=nullptr, Qt::ImageConversionFlags flags=Qt::AutoColor)
Definition: qpixmap.cpp:737
virtual void * nativeResourceForIntegration(const QByteArray &resource)
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:52
The QRectF class defines a finite rectangle in the plane using floating point precision.
Definition: qrect.h:511
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:59
constexpr void adjust(int x1, int y1, int x2, int y2) noexcept
Definition: qrect.h:400
constexpr int height() const noexcept
Definition: qrect.h:266
constexpr bool isNull() const noexcept
Definition: qrect.h:191
constexpr int bottom() const noexcept
Definition: qrect.h:209
constexpr void setSize(const QSize &s) noexcept
Definition: qrect.h:414
constexpr QRect adjusted(int x1, int y1, int x2, int y2) const noexcept
Definition: qrect.h:397
constexpr int top() const noexcept
Definition: qrect.h:203
constexpr QPoint topRight() const noexcept
Definition: qrect.h:254
constexpr void moveLeft(int pos) noexcept
Definition: qrect.h:313
constexpr int left() const noexcept
Definition: qrect.h:200
constexpr int x() const noexcept
Definition: qrect.h:212
constexpr void setWidth(int w) noexcept
Definition: qrect.h:408
constexpr QSize size() const noexcept
Definition: qrect.h:269
constexpr void translate(int dx, int dy) noexcept
Definition: qrect.h:272
constexpr int width() const noexcept
Definition: qrect.h:263
QRect united(const QRect &other) const noexcept
Definition: qrect.h:447
constexpr int y() const noexcept
Definition: qrect.h:215
constexpr void setHeight(int h) noexcept
Definition: qrect.h:411
constexpr int right() const noexcept
Definition: qrect.h:206
The QRegion class specifies a clip region for a painter.
Definition: qregion.h:63
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:55
constexpr int height() const noexcept
Definition: qsize.h:160
constexpr int width() const noexcept
Definition: qsize.h:157
constexpr int & rheight() noexcept
Definition: qsize.h:184
constexpr QSize expandedTo(const QSize &) const noexcept
Definition: qsize.h:219
constexpr void setWidth(int w) noexcept
Definition: qsize.h:163
constexpr int & rwidth() noexcept
Definition: qsize.h:181
constexpr bool isNull() const noexcept
Definition: qsize.h:148
constexpr bool isEmpty() const noexcept
Definition: qsize.h:151
constexpr void setHeight(int h) noexcept
Definition: qsize.h:166
The QString class provides a Unicode character string.
Definition: qstring.h:388
the exposed rectangle, in item coordinates
Definition: qstyleoption.h:724
The QStyle class is an abstract base class that encapsulates the look and feel of a GUI.
Definition: qstyle.h:65
@ State_Sunken
Definition: qstyle.h:105
@ State_HasFocus
Definition: qstyle.h:111
@ State_Active
Definition: qstyle.h:119
@ State_Off
Definition: qstyle.h:106
@ State_Enabled
Definition: qstyle.h:103
@ State_Horizontal
Definition: qstyle.h:110
@ State_On
Definition: qstyle.h:108
@ State_Raised
Definition: qstyle.h:104
@ State_Selected
Definition: qstyle.h:118
ContentsType
Definition: qstyle.h:580
StyleHint
Definition: qstyle.h:618
@ SH_UnderlineShortcut
Definition: qstyle.h:660
ControlElement
Definition: qstyle.h:206
@ CE_ProgressBarLabel
Definition: qstyle.h:224
@ CE_TabBarTabLabel
Definition: qstyle.h:219
@ CE_TabBarTabShape
Definition: qstyle.h:218
@ CE_RadioButtonLabel
Definition: qstyle.h:215
@ CE_CheckBoxLabel
Definition: qstyle.h:212
@ CE_PushButtonBevel
Definition: qstyle.h:208
@ CE_ProgressBarGroove
Definition: qstyle.h:222
@ CE_PushButtonLabel
Definition: qstyle.h:209
@ PM_HeaderMargin
Definition: qstyle.h:510
ComplexControl
Definition: qstyle.h:367
PrimitiveElement
Definition: qstyle.h:138
@ PE_FrameLineEdit
Definition: qstyle.h:144
@ PE_PanelLineEdit
Definition: qstyle.h:158
@ PE_FrameWindow
Definition: qstyle.h:148
@ PE_Widget
Definition: qstyle.h:184
@ PE_IndicatorCheckBox
Definition: qstyle.h:167
@ PE_Frame
Definition: qstyle.h:139
@ PE_FrameFocusRect
Definition: qstyle.h:142
@ PE_IndicatorItemViewItemCheck
Definition: qstyle.h:166
SubElement
Definition: qstyle.h:278
@ SE_LineEditContents
Definition: qstyle.h:317
@ SE_PushButtonFocusRect
Definition: qstyle.h:280
@ SE_PushButtonContents
Definition: qstyle.h:279
@ SE_CustomBase
Definition: qstyle.h:359
SubControl
Definition: qstyle.h:383
@ SC_ComboBoxListBoxPopup
Definition: qstyle.h:403
@ SC_GroupBoxCheckBox
Definition: qstyle.h:426
@ SC_GroupBoxLabel
Definition: qstyle.h:427
@ SC_ComboBoxEditField
Definition: qstyle.h:401
@ SC_ComboBoxArrow
Definition: qstyle.h:402
@ SC_GroupBoxFrame
Definition: qstyle.h:429
where ellipsis should be added for text that is too long to fit into an item
Definition: qstyleoption.h:251
an OR combination of the tool button's features
Definition: qstyleoption.h:608
the type of menu item
Definition: qstyleoption.h:515
the palette that should be used when painting the control
Definition: qstyleoption.h:111
the background color on which the focus rectangle is being drawn
Definition: qstyleoption.h:127
a bitwise OR of the features that describe this frame.
Definition: qstyleoption.h:649
The QStyleOptionHeader class is used to describe the parameters for drawing a header.
Definition: qstyleoption.h:204
The QStyleOption class stores the parameters used by QStyle functions.
Definition: qstyleoption.h:75
QFontMetrics fontMetrics
Definition: qstyleoption.h:98
QStyle::State state
Definition: qstyleoption.h:95
QPalette palette
Definition: qstyleoption.h:99
Qt::LayoutDirection direction
Definition: qstyleoption.h:96
a bitwise OR of the features that describe this button
Definition: qstyleoption.h:346
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:95
double toDouble(bool *ok=nullptr) const
Definition: qvariant.cpp:1929
QList< QVariant > toList() const
Definition: qvariant.cpp:1979
QMap< QString, QVariant > toMap() const
Definition: qvariant.cpp:1427
int toInt(bool *ok=nullptr) const
Definition: qvariant.cpp:1833
QString toString() const
Definition: qvariant.cpp:1416
QByteArray toByteArray() const
Definition: qvariant.cpp:1519
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:133
void setAttribute(Qt::WidgetAttribute, bool on=true)
Definition: qwidget.cpp:11088
QPalette palette
the widget's palette
Definition: qwidget.h:166
QRect rect
the internal geometry of the widget excluding any window frame
Definition: qwidget.h:150
float factor
QOpenGLWidget * widget
[1]
QPixmap p2
QPixmap p1
[0]
qDeleteAll(list.begin(), list.end())
void drawControl(ControlElement element, QPainter *painter, const QWidget *widget, const QRect &rect, const QColorGroup &colorGroup, SFlags how=Style_Default, const QStyleOption &option=QStyleOption::Default) const
[1]
opt iconSize
drawPrimitive(PE_IndicatorCheckBox, &subopt, p, widget)
rect
[4]
QStyleOptionButton subopt
[2]
uint alignment
QStyleOptionButton opt
else opt state
[0]
QRect textRect
const QStyleOptionButton * btn
[3]
@ NO_COLOR
Definition: extract.h:22
@ TRANSPARENT_COLOR
Definition: extract.h:25
int8_t numYDivs
Definition: extract.h:6
int8_t numXDivs
Definition: extract.h:5
for(n=0;n< outline->n_points;n++)
Definition: ftbbox.c:494
#define NULL
Definition: ftobjs.h:61
GeneratorWrapper< std::vector< T > > chunk(size_t size, GeneratorWrapper< T > &&generator)
Definition: catch_p_p.h:4333
typename C::const_iterator const_iterator
@ AlignHCenter
Definition: qnamespace.h:173
@ LeftButton
Definition: qnamespace.h:83
@ WA_StyledBackground
Definition: qnamespace.h:391
@ LeftToRight
Definition: qnamespace.h:1463
Orientation
Definition: qnamespace.h:123
@ Horizontal
Definition: qnamespace.h:124
@ Vertical
Definition: qnamespace.h:125
@ TextHideMnemonic
Definition: qnamespace.h:203
@ TextShowMnemonic
Definition: qnamespace.h:198
@ white
Definition: qnamespace.h:62
@ black
Definition: qnamespace.h:61
@ NoPen
Definition: qnamespace.h:1112
#define Q_UNLIKELY(x)
#define qApp
void qDrawShadePanel(QPainter *p, int x, int y, int w, int h, const QPalette &pal, bool sunken, int lineWidth, const QBrush *fill)
Definition: qdrawutil.cpp:366
void qDrawShadeLine(QPainter *p, int x1, int y1, int x2, int y2, const QPalette &pal, bool sunken, int lineWidth, int midLineWidth)
Definition: qdrawutil.cpp:122
void qDrawShadeRect(QPainter *p, int x, int y, int w, int h, const QPalette &pal, bool sunken, int lineWidth, int midLineWidth, const QBrush *fill)
Definition: qdrawutil.cpp:249
void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &c, int lineWidth, const QBrush *fill)
Definition: qdrawutil.cpp:612
EGLOutputLayerEXT EGLint EGLAttrib value
const EGLAttrib EGLOutputLayerEXT * layers
EGLOutputLayerEXT layer
unsigned int quint32
Definition: qglobal.h:288
int qint32
Definition: qglobal.h:287
unsigned int uint
Definition: qglobal.h:334
long long qint64
Definition: qglobal.h:298
unsigned char quint8
Definition: qglobal.h:284
#define qWarning
Definition: qlogging.h:179
GLenum GLuint id
[6]
Definition: qopengl.h:270
GLenum type
Definition: qopengl.h:270
GLenum GLsizei GLsizei GLint * values
[16]
GLsizei const GLfloat * v
[13]
const GLfloat * m
GLuint64 key
GLboolean r
[2]
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint GLuint end
GLuint object
[3]
GLenum src
GLint GLsizei width
GLuint color
[2]
GLenum GLenum dst
GLuint GLfloat x0
GLuint GLfloat GLfloat y0
GLsizei const GLint * box
GLfloat GLfloat GLfloat GLfloat h
GLuint GLfloat * val
Definition: qopenglext.h:1513
GLenum array
Definition: qopenglext.h:7028
GLdouble s
[6]
Definition: qopenglext.h:235
GLfloat GLfloat p
[1]
Definition: qopenglext.h:12698
GLuint GLenum option
Definition: qopenglext.h:5929
GLuint * states
Definition: qopenglext.h:9584
QT_BEGIN_NAMESPACE typedef unsigned int QRgb
Definition: qrgb.h:49
value toMap().value(key)
[3]
Text files * txt
QGraphicsItem * item
widget render & pixmap
QPainter painter(this)
[7]
QFrame frame
[0]
QStringList::Iterator it
Definition: jquant2.c:237
QCommandLinkButton * pb