Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qandroidstyle.cpp
Go to the documentation of this file.
1// Copyright (C) 2013 BogDan Vatra <bogdan@kde.org>
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qandroidstyle_p.h"
5
6#include <QFile>
7#include <QFont>
8#include <QApplication>
9#include <qdrawutil.h>
10#include <QPixmapCache>
11#include <QFileInfo>
12#include <QStyleOption>
13#include <QPainter>
14#include <QJsonDocument>
15#include <QJsonObject>
16#include <QDebug>
17
18#include <QGuiApplication>
19#include <qpa/qplatformnativeinterface.h>
20#include <qpa/qplatformtheme.h>
21
23
24namespace {
25 const quint32 NO_COLOR = 1;
27}
28
30 : QFusionStyle()
31{
33 checkBoxControl = NULL;
35 QPalette *standardPalette = reinterpret_cast<QPalette *>(nativeInterface->nativeResourceForIntegration("AndroidStandardPalette"));
37 m_standardPalette = *standardPalette;
38
39 QHash<QByteArray, QFont> *qwidgetsFonts = reinterpret_cast<QHash<QByteArray, QFont> *>(nativeInterface->nativeResourceForIntegration("AndroidQWidgetFonts"));
40 if (qwidgetsFonts) {
41 for (auto it = qwidgetsFonts->constBegin(); it != qwidgetsFonts->constEnd(); ++it)
42 QApplication::setFont(it.value(), it.key());
43 qwidgetsFonts->clear(); // free the memory
44 }
45
46 QJsonObject *object = reinterpret_cast<QJsonObject *>(nativeInterface->nativeResourceForIntegration("AndroidStyleData"));
47 if (!object)
48 return;
49
50 for (QJsonObject::const_iterator objectIterator = object->constBegin();
51 objectIterator != object->constEnd();
52 ++objectIterator) {
53 QString key = objectIterator.key();
54 QJsonValue value = objectIterator.value();
55 if (Q_UNLIKELY(!value.isObject())) {
56 qWarning("Style.json structure is unrecognized.");
57 continue;
58 }
59
60 QJsonObject item = value.toObject();
61 QAndroidStyle::ItemType itemType = qtControl(key);
62 if (QC_UnknownType == itemType)
63 continue;
64
65 switch (itemType) {
66 case QC_Checkbox:
67 checkBoxControl = new AndroidCompoundButtonControl(item.toVariantMap(), itemType);
68 m_androidControlsHash[int(itemType)] = checkBoxControl;
69 break;
70 case QC_RadioButton:
71 m_androidControlsHash[int(itemType)] = new AndroidCompoundButtonControl(item.toVariantMap(),
72 itemType);
73 break;
74
75 case QC_ProgressBar:
76 m_androidControlsHash[int(itemType)] = new AndroidProgressBarControl(item.toVariantMap(),
77 itemType);
78 break;
79
80 case QC_Slider:
81 m_androidControlsHash[int(itemType)] = new AndroidSeekBarControl(item.toVariantMap(),
82 itemType);
83 break;
84
85 case QC_Combobox:
86 m_androidControlsHash[int(itemType)] = new AndroidSpinnerControl(item.toVariantMap(),
87 itemType);
88 break;
89
90 default:
91 m_androidControlsHash[int(itemType)] = new AndroidControl(item.toVariantMap(),
92 itemType);
93 break;
94 }
95 }
96 *object = QJsonObject(); // free memory
97}
98
100{
101 qDeleteAll(m_androidControlsHash);
102}
103
104QAndroidStyle::ItemType QAndroidStyle::qtControl(const QString &android)
105{
106 if (android == QLatin1String("buttonStyle"))
107 return QC_Button;
108 if (android == QLatin1String("editTextStyle"))
109 return QC_EditText;
110 if (android == QLatin1String("radioButtonStyle"))
111 return QC_RadioButton;
112 if (android == QLatin1String("checkboxStyle"))
113 return QC_Checkbox;
114 if (android == QLatin1String("textViewStyle"))
115 return QC_View;
116 if (android == QLatin1String("buttonStyleToggle"))
117 return QC_Switch;
118 if (android == QLatin1String("spinnerStyle"))
119 return QC_Combobox;
120 if (android == QLatin1String("progressBarStyleHorizontal"))
121 return QC_ProgressBar;
122 if (android == QLatin1String("seekBarStyle"))
123 return QC_Slider;
124
125 return QC_UnknownType;
126}
127
128QAndroidStyle::ItemType QAndroidStyle::qtControl(QStyle::ComplexControl control)
129{
130 switch (control) {
131 case CC_ComboBox:
132 return QC_Combobox;
133 case CC_Slider:
134 return QC_Slider;
135 default:
136 return QC_UnknownType;
137 }
138}
139
140QAndroidStyle::ItemType QAndroidStyle::qtControl(QStyle::ContentsType contentsType)
141{
142 switch (contentsType) {
143 case CT_PushButton:
144 return QC_Button;
145 case CT_CheckBox:
146 return QC_Checkbox;
147 case CT_RadioButton:
148 return QC_RadioButton;
149 case CT_ComboBox:
150 return QC_Combobox;
151 case CT_ProgressBar:
152 return QC_ProgressBar;
153 case CT_Slider:
154 return QC_Slider;
155 case CT_ScrollBar:
156 return QC_Slider;
157 case CT_TabWidget:
158 return QC_Tab;
159 case CT_TabBarTab:
160 return QC_TabButton;
161 case CT_LineEdit:
162 return QC_EditText;
163 case CT_GroupBox:
164 return QC_GroupBox;
165 default:
166 return QC_UnknownType;
167 }
168}
169
170QAndroidStyle::ItemType QAndroidStyle::qtControl(QStyle::ControlElement controlElement)
171{
172 switch (controlElement) {
173 case CE_PushButton:
174 case CE_PushButtonBevel:
175 case CE_PushButtonLabel:
176 return QC_Button;
177
178 case CE_CheckBox:
179 case CE_CheckBoxLabel:
180 return QC_Checkbox;
181
182 case CE_RadioButton:
183 case CE_RadioButtonLabel:
184 return QC_RadioButton;
185
186 case CE_TabBarTab:
187 case CE_TabBarTabShape:
188 case CE_TabBarTabLabel:
189 return QC_Tab;
190
191 case CE_ProgressBar:
192 case CE_ProgressBarGroove:
193 case CE_ProgressBarContents:
194 case CE_ProgressBarLabel:
195 return QC_ProgressBar;
196
197 case CE_ComboBoxLabel:
198 return QC_Combobox;
199
200 case CE_ShapedFrame:
201 return QC_View;
202
203 default:
204 return QC_UnknownType;
205 }
206}
207
208QAndroidStyle::ItemType QAndroidStyle::qtControl(QStyle::PrimitiveElement primitiveElement)
209{
210 switch (primitiveElement) {
213 return QC_EditText;
214
217 return QC_Checkbox;
218
221 case QStyle::PE_Frame:
223 return QC_View;
224 default:
225 return QC_UnknownType;
226 }
227}
228
229QAndroidStyle::ItemType QAndroidStyle::qtControl(QStyle::SubElement subElement)
230{
231 switch (subElement) {
233 return QC_EditText;
234
237 return QC_Button;
238
239 case SE_RadioButtonContents:
240 return QC_RadioButton;
241
242 case SE_CheckBoxContents:
243 return QC_Checkbox;
244
245 default:
246 return QC_UnknownType;
247 }
248}
249
250void QAndroidStyle::drawPrimitive(PrimitiveElement pe,
251 const QStyleOption *opt,
252 QPainter *p,
253 const QWidget *w) const
254{
255 const ItemType itemType = qtControl(pe);
257 ? m_androidControlsHash.find(itemType)
258 : m_androidControlsHash.end();
259 if (it != m_androidControlsHash.end()) {
260 if (itemType != QC_EditText) {
261 it.value()->drawControl(opt, p, w);
262 } else {
264 copy.state &= ~QStyle::State_Sunken;
265 it.value()->drawControl(&copy, p, w);
266 }
267 } else if (pe == PE_FrameGroupBox) {
268 if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
269 if (frame->features & QStyleOptionFrame::Flat) {
270 QRect fr = frame->rect;
271 QPoint p1(fr.x(), fr.y() + 1);
272 QPoint p2(fr.x() + fr.width(), p1.y());
273 qDrawShadeLine(p, p1, p2, frame->palette, true,
275 } else {
277 frame->rect.height(), frame->palette, true,
279 }
280 }
281 } else {
282 QFusionStyle::drawPrimitive(pe, opt, p, w);
283 }
284}
285
286
288 const QStyleOption *opt,
289 QPainter *p,
290 const QWidget *w) const
291{
292 const ItemType itemType = qtControl(element);
294 ? m_androidControlsHash.find(itemType)
295 : m_androidControlsHash.end();
296 if (it != m_androidControlsHash.end()) {
297 AndroidControl *androidControl = it.value();
298
299 if (element != QStyle::CE_CheckBoxLabel
300 && element != QStyle::CE_PushButtonLabel
301 && element != QStyle::CE_RadioButtonLabel
302 && element != QStyle::CE_TabBarTabLabel
303 && element != QStyle::CE_ProgressBarLabel) {
304 androidControl->drawControl(opt, p, w);
305 }
306
307 if (element != QStyle::CE_PushButtonBevel
308 && element != QStyle::CE_TabBarTabShape
309 && element != QStyle::CE_ProgressBarGroove) {
310 switch (itemType) {
311 case QC_Button:
312 if (const QStyleOptionButton *buttonOption =
313 qstyleoption_cast<const QStyleOptionButton *>(opt)) {
314 QMargins padding = androidControl->padding();
315 QStyleOptionButton copy(*buttonOption);
316 copy.rect.adjust(padding.left(), padding.top(), -padding.right(), -padding.bottom());
317 QFusionStyle::drawControl(CE_PushButtonLabel, &copy, p, w);
318 }
319 break;
320 case QC_Checkbox:
321 case QC_RadioButton:
322 if (const QStyleOptionButton *btn =
323 qstyleoption_cast<const QStyleOptionButton *>(opt)) {
324 const bool isRadio = (element == CE_RadioButton);
326 subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents
327 : SE_CheckBoxContents, btn, w);
328 QFusionStyle::drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, p, w);
329 }
330 break;
331 case QC_Combobox:
332 if (const QStyleOptionComboBox *comboboxOption =
333 qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
334 QMargins padding = androidControl->padding();
335 QStyleOptionComboBox copy (*comboboxOption);
336 copy.rect.adjust(padding.left(), padding.top(), -padding.right(), -padding.bottom());
337 QFusionStyle::drawControl(CE_ComboBoxLabel, comboboxOption, p, w);
338 }
339 break;
340 default:
341 QFusionStyle::drawControl(element, opt, p, w);
342 break;
343 }
344 }
345 } else {
346 QFusionStyle::drawControl(element, opt, p, w);
347 }
348}
349
351 const QStyleOption *option,
352 const QWidget *widget) const
353{
354 const ItemType itemType = qtControl(subElement);
356 ? m_androidControlsHash.find(itemType)
357 : m_androidControlsHash.end();
358 if (it != m_androidControlsHash.end())
359 return it.value()->subElementRect(subElement, option, widget);
360 return QFusionStyle::subElementRect(subElement, option, widget);
361}
362
365 QPainter *p,
366 const QWidget *widget) const
367{
368 const ItemType itemType = qtControl(cc);
370 ? m_androidControlsHash.find(itemType)
371 : m_androidControlsHash.end();
372 if (it != m_androidControlsHash.end()) {
373 it.value()->drawControl(opt, p, widget);
374 return;
375 }
376 if (cc == CC_GroupBox) {
377 if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
378 // Draw frame
379 QRect textRect = subControlRect(CC_GroupBox, opt, SC_GroupBoxLabel, widget);
380 QRect checkBoxRect;
381 if (groupBox->subControls & SC_GroupBoxCheckBox)
382 checkBoxRect = subControlRect(CC_GroupBox, opt, SC_GroupBoxCheckBox, widget);
383 if (groupBox->subControls & QStyle::SC_GroupBoxFrame) {
385 frame.QStyleOption::operator=(*groupBox);
386 frame.features = groupBox->features;
387 frame.lineWidth = groupBox->lineWidth;
388 frame.midLineWidth = groupBox->midLineWidth;
389 frame.rect = subControlRect(CC_GroupBox, opt, SC_GroupBoxFrame, widget);
390 p->save();
391 QRegion region(groupBox->rect);
392 if (!groupBox->text.isEmpty()) {
393 bool ltr = groupBox->direction == Qt::LeftToRight;
394 QRect finalRect;
395 if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox) {
396 finalRect = checkBoxRect.united(textRect);
397 finalRect.adjust(ltr ? -4 : 0, 0, ltr ? 0 : 4, 0);
398 } else {
399 finalRect = textRect;
400 }
401 region -= finalRect;
402 }
403 p->setClipRegion(region);
404 drawPrimitive(PE_FrameGroupBox, &frame, p, widget);
405 p->restore();
406 }
407
408 // Draw title
409 if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
410 QColor textColor = groupBox->textColor;
411 if (textColor.isValid())
412 p->setPen(textColor);
413 int alignment = int(groupBox->textAlignment);
416
418 groupBox->palette, groupBox->state & State_Enabled, groupBox->text,
420
421 if (groupBox->state & State_HasFocus) {
423 fropt.QStyleOption::operator=(*groupBox);
424 fropt.rect = textRect;
425 drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
426 }
427 }
428
429 // Draw checkbox
430 if (groupBox->subControls & SC_GroupBoxCheckBox) {
432 box.QStyleOption::operator=(*groupBox);
433 box.rect = checkBoxRect;
434 checkBoxControl->drawControl(&box, p, widget);
435 }
436 }
437 return;
438 }
439 QFusionStyle::drawComplexControl(cc, opt, p, widget);
440}
441
444 const QPoint &pt,
445 const QWidget *widget) const
446{
447 const ItemType itemType = qtControl(cc);
449 ? m_androidControlsHash.find(itemType)
450 : m_androidControlsHash.end();
451 if (it != m_androidControlsHash.end()) {
452 switch (cc) {
453 case CC_Slider:
454 if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
455 QRect r = it.value()->subControlRect(slider, SC_SliderHandle, widget);
456 if (r.isValid() && r.contains(pt)) {
457 return SC_SliderHandle;
458 } else {
459 r = it.value()->subControlRect(slider, SC_SliderGroove, widget);
460 if (r.isValid() && r.contains(pt))
461 return SC_SliderGroove;
462 }
463 }
464 break;
465 default:
466 break;
467 }
468 }
469 return QFusionStyle::hitTestComplexControl(cc, opt, pt, widget);
470}
471
474 SubControl sc,
475 const QWidget *widget) const
476{
477 const ItemType itemType = qtControl(cc);
479 ? m_androidControlsHash.find(itemType)
480 : m_androidControlsHash.end();
481 if (it != m_androidControlsHash.end())
482 return it.value()->subControlRect(opt, sc, widget);
483 QRect rect = opt->rect;
484 switch (cc) {
485 case CC_GroupBox: {
486 if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
487 QSize textSize = opt->fontMetrics.boundingRect(groupBox->text).size() + QSize(2, 2);
488 QSize checkBoxSize = checkBoxControl->size(opt);
489 int indicatorWidth = checkBoxSize.width();
490 int indicatorHeight = checkBoxSize.height();
491 QRect checkBoxRect;
492 if (opt->subControls & QStyle::SC_GroupBoxCheckBox) {
493 checkBoxRect.setWidth(indicatorWidth);
494 checkBoxRect.setHeight(indicatorHeight);
495 }
496 checkBoxRect.moveLeft(1);
497 QRect textRect = checkBoxRect;
498 textRect.setSize(textSize);
499 if (opt->subControls & QStyle::SC_GroupBoxCheckBox)
500 textRect.translate(indicatorWidth + 5, (indicatorHeight - textSize.height()) / 2);
501 if (sc == SC_GroupBoxFrame) {
502 rect = opt->rect.adjusted(0, 0, 0, 0);
503 rect.translate(0, textRect.height() / 2);
504 rect.setHeight(rect.height() - textRect.height() / 2);
505 } else if (sc == SC_GroupBoxContents) {
506 QRect frameRect = opt->rect.adjusted(0, 0, 0, -groupBox->lineWidth);
507 int margin = 3;
508 int leftMarginExtension = 0;
509 int topMargin = qMax(pixelMetric(PM_ExclusiveIndicatorHeight), opt->fontMetrics.height()) + groupBox->lineWidth;
510 frameRect.adjust(leftMarginExtension + margin, margin + topMargin, -margin, -margin - groupBox->lineWidth);
511 frameRect.translate(0, textRect.height() / 2);
512 rect = frameRect;
513 rect.setHeight(rect.height() - textRect.height() / 2);
514 } else if (sc == SC_GroupBoxCheckBox) {
515 rect = checkBoxRect;
516 } else if (sc == SC_GroupBoxLabel) {
517 rect = textRect;
518 }
519 return visualRect(opt->direction, opt->rect, rect);
520 }
521
522 return rect;
523 }
524
525 default:
526 break;
527 }
528
529
530 return QFusionStyle::subControlRect(cc, opt, sc, widget);
531}
532
533int QAndroidStyle::pixelMetric(PixelMetric metric, const QStyleOption *option,
534 const QWidget *widget) const
535{
536 switch (metric) {
537 case PM_ButtonMargin:
538 case PM_FocusFrameVMargin:
539 case PM_FocusFrameHMargin:
540 case PM_ComboBoxFrameWidth:
541 case PM_SpinBoxFrameWidth:
542 case PM_ScrollBarExtent:
543 return 0;
544 case PM_IndicatorWidth:
545 return checkBoxControl->size(option).width();
546 case PM_IndicatorHeight:
547 return checkBoxControl->size(option).height();
548 default:
549 return QFusionStyle::pixelMetric(metric, option, widget);
550 }
551
552}
553
555 const QStyleOption *opt,
556 const QSize &contentsSize,
557 const QWidget *w) const
558{
559 QSize sz = QFusionStyle::sizeFromContents(ct, opt, contentsSize, w);
560 if (ct == CT_HeaderSection) {
561 if (const QStyleOptionHeader *hdr = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
562 bool nullIcon = hdr->icon.isNull();
563 int margin = pixelMetric(QStyle::PM_HeaderMargin, hdr, w);
564 int iconSize = nullIcon ? 0 : checkBoxControl->size(opt).width();
565 QSize txt;
566/*
567 * These next 4 lines are a bad hack to fix a bug in case a QStyleSheet is applied at QApplication level.
568 * In that case, even if the stylesheet does not refer to headers, the header font is changed to application
569 * font, which is wrong. Even worst, hdr->fontMetrics(...) does not report the proper size.
570 */
571 if (qApp->styleSheet().isEmpty())
572 txt = hdr->fontMetrics.size(0, hdr->text);
573 else
574 txt = QFontMetrics(QApplication::font()).size(0, hdr->text);
575
576 sz.setHeight(margin + qMax(iconSize, txt.height()) + margin);
577 sz.setWidth((nullIcon ? 0 : margin) + iconSize
578 + (hdr->text.isNull() ? 0 : margin) + txt.width() + margin);
579 if (hdr->sortIndicator != QStyleOptionHeader::None) {
580 int margin = pixelMetric(QStyle::PM_HeaderMargin, hdr, w);
581 if (hdr->orientation == Qt::Horizontal)
582 sz.rwidth() += sz.height() + margin;
583 else
584 sz.rheight() += sz.width() + margin;
585 }
586 return sz;
587 }
588 }
589 const ItemType itemType = qtControl(ct);
591 ? m_androidControlsHash.find(itemType)
592 : m_androidControlsHash.end();
593 if (it != m_androidControlsHash.end())
594 return it.value()->sizeFromContents(opt, sz, w);
595 if (ct == CT_GroupBox) {
596 if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
597 QSize textSize = opt->fontMetrics.boundingRect(groupBox->text).size() + QSize(2, 2);
598 QSize checkBoxSize = checkBoxControl->size(opt);
599 int indicatorWidth = checkBoxSize.width();
600 int indicatorHeight = checkBoxSize.height();
601 QRect checkBoxRect;
602 if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox) {
603 checkBoxRect.setWidth(indicatorWidth);
604 checkBoxRect.setHeight(indicatorHeight);
605 }
606 checkBoxRect.moveLeft(1);
607 QRect textRect = checkBoxRect;
608 textRect.setSize(textSize);
609 if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox)
610 textRect.translate(indicatorWidth + 5, (indicatorHeight - textSize.height()) / 2);
611 QRect u = textRect.united(checkBoxRect);
612 sz = QSize(sz.width(), sz.height() + u.height());
613 }
614 }
615 return sz;
616}
617
618QPixmap QAndroidStyle::standardPixmap(StandardPixmap standardPixmap,
619 const QStyleOption *opt,
620 const QWidget *widget) const
621{
622 return QFusionStyle::standardPixmap(standardPixmap, opt, widget);
623}
624
626 const QPixmap &pixmap,
627 const QStyleOption *opt) const
628{
629 return QFusionStyle::generatedIconPixmap(iconMode, pixmap, opt);
630}
631
633{
634 switch (hint) {
635 case SH_Slider_AbsoluteSetButtons:
636 return Qt::LeftButton;
637
638 case SH_Slider_PageSetButtons:
639 return 0;
640
641 case SH_RequestSoftwareInputPanel:
642 return RSIP_OnMouseClick;
643
644 case SH_SpinBox_SelectOnStep:
645 return 0;
646
647 default:
648 return QFusionStyle::styleHint(hint, option, widget, returnData);
649 }
650}
651
653{
654 return m_standardPalette;
655}
656
661
666
669{
670 initPadding(drawable);
671 m_itemType = itemType;
672}
673
677
679{
680 QVariantMap::const_iterator it = drawable.find(QLatin1String("padding"));
681 if (it != drawable.end())
682 m_padding = extractMargins(it.value().toMap());
683}
684
686{
687 return m_padding;
688}
689
691{
692 if (type() == Image || type() == NinePatch)
693 return static_cast<const QAndroidStyle::AndroidImageDrawable *>(this)->size();
694
695 return QSize();
696}
697
699 ItemType itemType)
700{
701 const QString type = drawable.value(QLatin1String("type")).toString();
702 if (type == QLatin1String("image"))
703 return new QAndroidStyle::AndroidImageDrawable(drawable, itemType);
704 if (type == QLatin1String("9patch"))
705 return new QAndroidStyle::Android9PatchDrawable(drawable, itemType);
706 if (type == QLatin1String("stateslist"))
707 return new QAndroidStyle::AndroidStateDrawable(drawable, itemType);
708 if (type == QLatin1String("layer"))
709 return new QAndroidStyle::AndroidLayerDrawable(drawable, itemType);
710 if (type == QLatin1String("gradient"))
711 return new QAndroidStyle::AndroidGradientDrawable(drawable, itemType);
712 if (type == QLatin1String("clipDrawable"))
713 return new QAndroidStyle::AndroidClipDrawable(drawable, itemType);
714 if (type == QLatin1String("color"))
715 return new QAndroidStyle::AndroidColorDrawable(drawable, itemType);
716 return 0;
717}
718
720{
721 QMargins m;
722 m.setLeft(value.value(QLatin1String("left")).toInt());
723 m.setRight(value.value(QLatin1String("right")).toInt());
724 m.setTop(value.value(QLatin1String("top")).toInt());
725 m.setBottom(value.value(QLatin1String("bottom")).toInt());
726 return m;
727}
728
730{
731 QSize sz = size();
732 if (m_padding.isNull() && !sz.isNull())
733 m_padding.setLeft(sz.width());
734}
735
736
739 : AndroidDrawable(drawable, itemType)
740{
741 m_filePath = drawable.value(QLatin1String("path")).toString();
742 m_size.setHeight(drawable.value(QLatin1String("height")).toInt());
743 m_size.setWidth(drawable.value(QLatin1String("width")).toInt());
744}
745
750
752{
753 if (m_hashKey.isEmpty())
754 m_hashKey = QFileInfo(m_filePath).fileName();
755
756 QPixmap pm;
757 if (!QPixmapCache::find(m_hashKey, &pm)) {
758 pm.load(m_filePath);
759 QPixmapCache::insert(m_hashKey, pm);
760 }
761
762 painter->drawPixmap(opt->rect.x(), opt->rect.y() + (opt->rect.height() - pm.height()) / 2, pm);
763}
764
766{
767 return m_size;
768}
769
771 ItemType itemType)
772 : AndroidDrawable(drawable, itemType)
773{
774 m_color.setRgba(QRgb(drawable.value(QLatin1String("color")).toInt()));
775}
776
781
786
789 : AndroidImageDrawable(drawable.value(QLatin1String("drawable")).toMap(), itemType)
790{
791 initPadding(drawable);
792 QVariantMap chunk = drawable.value(QLatin1String("chunkInfo")).toMap();
793 extractIntArray(chunk.value(QLatin1String("xdivs")).toList(), m_chunkData.xDivs);
794 extractIntArray(chunk.value(QLatin1String("ydivs")).toList(), m_chunkData.yDivs);
795 extractIntArray(chunk.value(QLatin1String("colors")).toList(), m_chunkData.colors);
796}
797
802
803int QAndroidStyle::Android9PatchDrawable::calculateStretch(int boundsLimit,
804 int startingPoint,
805 int srcSpace,
806 int numStrechyPixelsRemaining,
807 int numFixedPixelsRemaining)
808{
809 int spaceRemaining = boundsLimit - startingPoint;
810 int stretchySpaceRemaining = spaceRemaining - numFixedPixelsRemaining;
811 return (float(srcSpace) * stretchySpaceRemaining / numStrechyPixelsRemaining + .5);
812}
813
814void QAndroidStyle::Android9PatchDrawable::extractIntArray(const QVariantList &values,
815 QList<int> & array)
816{
817 for (const QVariant &value : values)
818 array << value.toInt();
819}
820
821
823{
824 if (m_hashKey.isEmpty())
825 m_hashKey = QFileInfo(m_filePath).fileName();
826
828 if (!QPixmapCache::find(m_hashKey, &pixmap)) {
829 pixmap.load(m_filePath);
830 QPixmapCache::insert(m_hashKey, pixmap);
831 }
832
833 const QRect &bounds = opt->rect;
834
835 // shamelessly stolen from Android's sources (NinepatchImpl.cpp) and adapted for Qt
836 const int pixmapWidth = pixmap.width();
837 const int pixmapHeight = pixmap.height();
838
839 if (bounds.isNull() || !pixmapWidth || !pixmapHeight)
840 return;
841
842 QPainter::RenderHints savedHints = painter->renderHints();
843
844 // The patchs doesn't need smooth transform !
846
847 QRectF dst;
848 QRectF src;
849
850 const qint32 x0 = m_chunkData.xDivs[0];
851 const qint32 y0 = m_chunkData.yDivs[0];
852 const quint8 numXDivs = m_chunkData.xDivs.size();
853 const quint8 numYDivs = m_chunkData.yDivs.size();
854 int i;
855 int j;
856 int colorIndex = 0;
858 bool xIsStretchable;
859 const bool initialXIsStretchable = (x0 == 0);
860 bool yIsStretchable = (y0 == 0);
861 const int bitmapWidth = pixmap.width();
862 const int bitmapHeight = pixmap.height();
863
864 int *dstRights = static_cast<int *>(alloca((numXDivs + 1) * sizeof(int)));
865 bool dstRightsHaveBeenCached = false;
866
867 int numStretchyXPixelsRemaining = 0;
868 for (i = 0; i < numXDivs; i += 2)
869 numStretchyXPixelsRemaining += m_chunkData.xDivs[i + 1] - m_chunkData.xDivs[i];
870
871 int numFixedXPixelsRemaining = bitmapWidth - numStretchyXPixelsRemaining;
872 int numStretchyYPixelsRemaining = 0;
873 for (i = 0; i < numYDivs; i += 2)
874 numStretchyYPixelsRemaining += m_chunkData.yDivs[i + 1] - m_chunkData.yDivs[i];
875
876 int numFixedYPixelsRemaining = bitmapHeight - numStretchyYPixelsRemaining;
877 src.setTop(0);
878 dst.setTop(bounds.top());
879 // The first row always starts with the top being at y=0 and the bottom
880 // being either yDivs[1] (if yDivs[0]=0) of yDivs[0]. In the former case
881 // the first row is stretchable along the Y axis, otherwise it is fixed.
882 // The last row always ends with the bottom being bitmap.height and the top
883 // being either yDivs[numYDivs-2] (if yDivs[numYDivs-1]=bitmap.height) or
884 // yDivs[numYDivs-1]. In the former case the last row is stretchable along
885 // the Y axis, otherwise it is fixed.
886 //
887 // The first and last columns are similarly treated with respect to the X
888 // axis.
889 //
890 // The above is to help explain some of the special casing that goes on the
891 // code below.
892
893 // The initial yDiv and whether the first row is considered stretchable or
894 // not depends on whether yDiv[0] was zero or not.
895 for (j = yIsStretchable ? 1 : 0;
896 j <= numYDivs && src.top() < bitmapHeight;
897 j++, yIsStretchable = !yIsStretchable) {
898 src.setLeft(0);
899 dst.setLeft(bounds.left());
900 if (j == numYDivs) {
901 src.setBottom(bitmapHeight);
902 dst.setBottom(bounds.bottom());
903 } else {
904 src.setBottom(m_chunkData.yDivs[j]);
905 const int srcYSize = src.bottom() - src.top();
906 if (yIsStretchable) {
907 dst.setBottom(dst.top() + calculateStretch(bounds.bottom(), dst.top(),
908 srcYSize,
909 numStretchyYPixelsRemaining,
910 numFixedYPixelsRemaining));
911 numStretchyYPixelsRemaining -= srcYSize;
912 } else {
913 dst.setBottom(dst.top() + srcYSize);
914 numFixedYPixelsRemaining -= srcYSize;
915 }
916 }
917
918 xIsStretchable = initialXIsStretchable;
919 // The initial xDiv and whether the first column is considered
920 // stretchable or not depends on whether xDiv[0] was zero or not.
921 for (i = xIsStretchable ? 1 : 0;
922 i <= numXDivs && src.left() < bitmapWidth;
923 i++, xIsStretchable = !xIsStretchable) {
924 color = m_chunkData.colors[colorIndex++];
925 if (color != TRANSPARENT_COLOR)
926 color = NO_COLOR;
927 if (i == numXDivs) {
928 src.setRight(bitmapWidth);
929 dst.setRight(bounds.right());
930 } else {
931 src.setRight(m_chunkData.xDivs[i]);
932 if (dstRightsHaveBeenCached) {
933 dst.setRight(dstRights[i]);
934 } else {
935 const int srcXSize = src.right() - src.left();
936 if (xIsStretchable) {
937 dst.setRight(dst.left() + calculateStretch(bounds.right(), dst.left(),
938 srcXSize,
939 numStretchyXPixelsRemaining,
940 numFixedXPixelsRemaining));
941 numStretchyXPixelsRemaining -= srcXSize;
942 } else {
943 dst.setRight(dst.left() + srcXSize);
944 numFixedXPixelsRemaining -= srcXSize;
945 }
946 dstRights[i] = dst.right();
947 }
948 }
949 // If this horizontal patch is too small to be displayed, leave
950 // the destination left edge where it is and go on to the next patch
951 // in the source.
952 if (src.left() >= src.right()) {
953 src.setLeft(src.right());
954 continue;
955 }
956 // Make sure that we actually have room to draw any bits
957 if (dst.right() <= dst.left() || dst.bottom() <= dst.top()) {
958 goto nextDiv;
959 }
960 // If this patch is transparent, skip and don't draw.
961 if (color == TRANSPARENT_COLOR)
962 goto nextDiv;
963 if (color != NO_COLOR)
965 else
967nextDiv:
968 src.setLeft(src.right());
969 dst.setLeft(dst.right());
970 }
971 src.setTop(src.bottom());
972 dst.setTop(dst.bottom());
973 dstRightsHaveBeenCached = true;
974 }
975 painter->setRenderHints(savedHints);
976}
977
980 : AndroidDrawable(drawable, itemType), m_orientation(TOP_BOTTOM)
981{
982 m_radius = drawable.value(QLatin1String("radius")).toInt();
983 if (m_radius < 0)
984 m_radius = 0;
985
986 QVariantList colors = drawable.value(QLatin1String("colors")).toList();
987 QVariantList positions = drawable.value(QLatin1String("positions")).toList();
988 int min = colors.size() < positions.size() ? colors.size() : positions.size();
989 for (int i = 0; i < min; i++)
990 m_gradient.setColorAt(positions.at(i).toDouble(), QRgb(colors.at(i).toInt()));
991
992 QByteArray orientation = drawable.value(QLatin1String("orientation")).toByteArray();
993 if (orientation == "TOP_BOTTOM") // draw the gradient from the top to the bottom
994 m_orientation = TOP_BOTTOM;
995 else if (orientation == "TR_BL") // draw the gradient from the top-right to the bottom-left
996 m_orientation = TR_BL;
997 else if (orientation == "RIGHT_LEFT") // draw the gradient from the right to the left
998 m_orientation = RIGHT_LEFT;
999 else if (orientation == "BR_TL") // draw the gradient from the bottom-right to the top-left
1000 m_orientation = BR_TL;
1001 else if (orientation == "BOTTOM_TOP") // draw the gradient from the bottom to the top
1002 m_orientation = BOTTOM_TOP;
1003 else if (orientation == "BL_TR") // draw the gradient from the bottom-left to the top-right
1004 m_orientation = BL_TR;
1005 else if (orientation == "LEFT_RIGHT") // draw the gradient from the left to the right
1006 m_orientation = LEFT_RIGHT;
1007 else if (orientation == "TL_BR") // draw the gradient from the top-left to the bottom-right
1008 m_orientation = TL_BR;
1009 else
1010 qWarning("AndroidGradientDrawable: unknown orientation");
1011}
1012
1017
1019{
1020 const int width = opt->rect.width();
1021 const int height = opt->rect.height();
1022 switch (m_orientation) {
1023 case TOP_BOTTOM:
1024 // draw the gradient from the top to the bottom
1025 m_gradient.setStart(width / 2, 0);
1026 m_gradient.setFinalStop(width / 2, height);
1027 break;
1028 case TR_BL:
1029 // draw the gradient from the top-right to the bottom-left
1030 m_gradient.setStart(width, 0);
1031 m_gradient.setFinalStop(0, height);
1032 break;
1033 case RIGHT_LEFT:
1034 // draw the gradient from the right to the left
1035 m_gradient.setStart(width, height / 2);
1036 m_gradient.setFinalStop(0, height / 2);
1037 break;
1038 case BR_TL:
1039 // draw the gradient from the bottom-right to the top-left
1040 m_gradient.setStart(width, height);
1041 m_gradient.setFinalStop(0, 0);
1042 break;
1043 case BOTTOM_TOP:
1044 // draw the gradient from the bottom to the top
1045 m_gradient.setStart(width / 2, height);
1046 m_gradient.setFinalStop(width / 2, 0);
1047 break;
1048 case BL_TR:
1049 // draw the gradient from the bottom-left to the top-right
1050 m_gradient.setStart(0, height);
1051 m_gradient.setFinalStop(width, 0);
1052 break;
1053 case LEFT_RIGHT:
1054 // draw the gradient from the left to the right
1055 m_gradient.setStart(0, height / 2);
1056 m_gradient.setFinalStop(width, height / 2);
1057 break;
1058 case TL_BR:
1059 // draw the gradient from the top-left to the bottom-right
1060 m_gradient.setStart(0, 0);
1061 m_gradient.setFinalStop(width, height);
1062 break;
1063 }
1064
1065 const QBrush &oldBrush = painter->brush();
1066 const QPen oldPen = painter->pen();
1068 painter->setBrush(m_gradient);
1069 painter->drawRoundedRect(opt->rect, m_radius, m_radius);
1070 painter->setBrush(oldBrush);
1071 painter->setPen(oldPen);
1072}
1073
1075{
1076 return QSize(m_radius * 2, m_radius * 2);
1077}
1078
1080 QAndroidStyle::ItemType itemType)
1081 : AndroidDrawable(drawable, itemType)
1082{
1083 m_drawable = fromMap(drawable.value(QLatin1String("drawable")).toMap(), itemType);
1084 m_factor = 0;
1085 m_orientation = Qt::Horizontal;
1086}
1087
1092
1097
1099{
1100 m_factor = factor;
1101 m_orientation = orientation;
1102}
1103
1105{
1107 if (m_orientation == Qt::Horizontal)
1108 copy.rect.setWidth(copy.rect.width() * m_factor);
1109 else
1110 copy.rect.setHeight(copy.rect.height() * m_factor);
1111
1112 m_drawable->draw(painter, &copy);
1113}
1114
1116 QAndroidStyle::ItemType itemType)
1117 : AndroidDrawable(drawable, itemType)
1118{
1119 const QVariantList states = drawable.value(QLatin1String("stateslist")).toList();
1120 for (const QVariant &stateVariant : states) {
1121 QVariantMap state = stateVariant.toMap();
1122 const int s = extractState(state.value(QLatin1String("states")).toMap());
1123 if (-1 == s)
1124 continue;
1125 const AndroidDrawable *ad = fromMap(state.value(QLatin1String("drawable")).toMap(), itemType);
1126 if (!ad)
1127 continue;
1128 StateType item;
1129 item.first = s;
1130 item.second = ad;
1131 m_states<<item;
1132 }
1133}
1134
1136{
1137 for (const StateType &type : std::as_const(m_states))
1138 delete type.second;
1139}
1140
1145
1147{
1148 const AndroidDrawable *drawable = bestAndroidStateMatch(opt);
1149 if (drawable)
1150 drawable->draw(painter, opt);
1151}
1153{
1154 QSize s;
1155 const AndroidDrawable *drawable = bestAndroidStateMatch(opt);
1156 if (drawable)
1157 s = drawable->size();
1158 return s;
1159}
1160
1162{
1163 const AndroidDrawable *bestMatch = nullptr;
1164 if (!opt) {
1165 if (m_states.size())
1166 return m_states[0].second;
1167 return bestMatch;
1168 }
1169
1170 uint bestCost = 0xffff;
1171 for (const StateType & state : m_states) {
1172 if (int(opt->state) == state.first)
1173 return state.second;
1174 uint cost = 1;
1175
1176 int difference = int(opt->state^state.first);
1177
1178 if (difference & QStyle::State_Active)
1179 cost <<= 1;
1180
1181 if (difference & QStyle::State_Enabled)
1182 cost <<= 1;
1183
1184 if (difference & QStyle::State_Raised)
1185 cost <<= 1;
1186
1187 if (difference & QStyle::State_Sunken)
1188 cost <<= 1;
1189
1190 if (difference & QStyle::State_Off)
1191 cost <<= 1;
1192
1193 if (difference & QStyle::State_On)
1194 cost <<= 1;
1195
1196 if (difference & QStyle::State_HasFocus)
1197 cost <<= 1;
1198
1199 if (difference & QStyle::State_Selected)
1200 cost <<= 1;
1201
1202 if (cost < bestCost) {
1203 bestCost = cost;
1204 bestMatch = state.second;
1205 }
1206 }
1207 return bestMatch;
1208}
1209
1211{
1213 for (auto it = value.cbegin(), end = value.cend(); it != end; ++it) {
1214 const QString &key = it.key();
1215 bool val = it.value().toString() == QLatin1String("true");
1216 if (key == QLatin1String("enabled")) {
1218 continue;
1219 }
1220
1221 if (key == QLatin1String("window_focused")) {
1222 state.setFlag(QStyle::State_Active, val);
1223 continue;
1224 }
1225
1226 if (key == QLatin1String("focused")) {
1228 continue;
1229 }
1230
1231 if (key == QLatin1String("checked")) {
1233 continue;
1234 }
1235
1236 if (key == QLatin1String("pressed")) {
1238 continue;
1239 }
1240
1241 if (key == QLatin1String("selected")) {
1243 continue;
1244 }
1245
1246 if (key == QLatin1String("active")) {
1247 state.setFlag(QStyle::State_Active, val);
1248 continue;
1249 }
1250
1251 if (key == QLatin1String("multiline"))
1252 return 0;
1253
1254 if (key == QLatin1String("background") && val)
1255 return -1;
1256 }
1257 return static_cast<int>(state);
1258}
1259
1261{
1262 for (const StateType &type : std::as_const(m_states))
1263 const_cast<AndroidDrawable *>(type.second)->setPaddingLeftToSizeWidth();
1264}
1265
1267 QAndroidStyle::ItemType itemType)
1268 : AndroidDrawable(drawable, itemType)
1269{
1270 m_id = 0;
1271 m_factor = 1;
1272 m_orientation = Qt::Horizontal;
1273 const QVariantList layers = drawable.value(QLatin1String("layers")).toList();
1274 for (const QVariant &layer : layers) {
1275 QVariantMap layerMap = layer.toMap();
1276 AndroidDrawable *ad = fromMap(layerMap, itemType);
1277 if (ad) {
1278 LayerType l;
1279 l.second = ad;
1280 l.first = layerMap.value(QLatin1String("id")).toInt();
1281 m_layers << l;
1282 }
1283 }
1284}
1285
1287{
1288 for (const LayerType &layer : std::as_const(m_layers))
1289 delete layer.second;
1290}
1291
1296
1298{
1299 m_id = id;
1300 m_factor = factor;
1301 m_orientation = orientation;
1302}
1303
1305{
1306 for (const LayerType &layer : m_layers) {
1307 if (layer.first == m_id) {
1309 if (m_orientation == Qt::Horizontal)
1310 copy.rect.setWidth(copy.rect.width() * m_factor);
1311 else
1312 copy.rect.setHeight(copy.rect.height() * m_factor);
1313 layer.second->draw(painter, &copy);
1314 } else {
1315 layer.second->draw(painter, opt);
1316 }
1317 }
1318}
1319
1321{
1322 for (const LayerType &layer : m_layers) {
1323 if (layer.first == id)
1324 return layer.second;
1325 }
1326 return 0;
1327}
1328
1330{
1331 QSize sz;
1332 for (const LayerType &layer : m_layers)
1333 sz = sz.expandedTo(layer.second->size());
1334 return sz;
1335}
1336
1338 QAndroidStyle::ItemType itemType)
1339{
1340 QVariantMap::const_iterator it = control.find(QLatin1String("View_background"));
1341 if (it != control.end())
1342 m_background = AndroidDrawable::fromMap(it.value().toMap(), itemType);
1343 else
1344 m_background = 0;
1345
1346 it = control.find(QLatin1String("View_minWidth"));
1347 if (it != control.end())
1348 m_minSize.setWidth(it.value().toInt());
1349
1350 it = control.find(QLatin1String("View_minHeight"));
1351 if (it != control.end())
1352 m_minSize.setHeight(it.value().toInt());
1353
1354 it = control.find(QLatin1String("View_maxWidth"));
1355 if (it != control.end())
1356 m_maxSize.setWidth(it.value().toInt());
1357
1358 it = control.find(QLatin1String("View_maxHeight"));
1359 if (it != control.end())
1360 m_maxSize.setHeight(it.value().toInt());
1361}
1362
1364{
1365 delete m_background;
1366}
1367
1369{
1370 if (m_background) {
1371 m_background->draw(p, opt);
1372 } else {
1373 if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
1374 if ((frame->state & State_Sunken) || (frame->state & State_Raised)) {
1375 qDrawShadePanel(p, frame->rect, frame->palette, frame->state & State_Sunken,
1376 frame->lineWidth);
1377 } else {
1379 }
1380 } else {
1381 if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(opt)) {
1382 QColor bg = fropt->backgroundColor;
1383 QPen oldPen = p->pen();
1384 if (bg.isValid()) {
1385 int h, s, v;
1386 bg.getHsv(&h, &s, &v);
1387 if (v >= 128)
1388 p->setPen(Qt::black);
1389 else
1390 p->setPen(Qt::white);
1391 } else {
1392 p->setPen(opt->palette.windowText().color());
1393 }
1394 QRect focusRect = opt->rect.adjusted(1, 1, -1, -1);
1395 p->drawRect(focusRect.adjusted(0, 0, -1, -1)); //draw pen inclusive
1396 p->setPen(oldPen);
1397 } else {
1398 p->fillRect(opt->rect, opt->palette.window());
1399 }
1400 }
1401 }
1402}
1403
1405 const QStyleOption *option,
1406 const QWidget * /* widget */) const
1407{
1408 if (const AndroidDrawable *drawable = backgroundDrawable()) {
1409 if (drawable->type() == State)
1410 drawable = static_cast<const AndroidStateDrawable *>(backgroundDrawable())->bestAndroidStateMatch(option);
1411
1412 const QMargins &padding = drawable->padding();
1413
1414 QRect r = option->rect.adjusted(padding.left(), padding.top(),
1415 -padding.right(), -padding.bottom());
1416
1417 if (r.width() < m_minSize.width())
1418 r.setWidth(m_minSize.width());
1419
1420 if (r.height() < m_minSize.height())
1421 r.setHeight(m_minSize.height());
1422
1423 return visualRect(option->direction, option->rect, r);
1424 }
1425 return option->rect;
1426}
1427
1434
1436 const QSize &contentsSize,
1437 const QWidget * /* w */) const
1438{
1439 QSize sz;
1440 if (const AndroidDrawable *drawable = backgroundDrawable()) {
1441
1442 if (drawable->type() == State)
1443 drawable = static_cast<const AndroidStateDrawable*>(backgroundDrawable())->bestAndroidStateMatch(opt);
1444 const QMargins &padding = drawable->padding();
1445 sz.setWidth(padding.left() + padding.right());
1446 sz.setHeight(padding.top() + padding.bottom());
1447 if (sz.isEmpty())
1448 sz = drawable->size();
1449 }
1450 sz += contentsSize;
1451 if (contentsSize.height() < opt->fontMetrics.height())
1452 sz.setHeight(sz.height() + (opt->fontMetrics.height() - contentsSize.height()));
1453 if (sz.height() < m_minSize.height())
1454 sz.setHeight(m_minSize.height());
1455 if (sz.width() < m_minSize.width())
1456 sz.setWidth(m_minSize.width());
1457 return sz;
1458}
1459
1461{
1462 if (const AndroidDrawable *drawable = m_background) {
1463 if (drawable->type() == State)
1464 drawable = static_cast<const AndroidStateDrawable *>(m_background)->bestAndroidStateMatch(0);
1465 return drawable->padding();
1466 }
1467 return QMargins();
1468}
1469
1471{
1472 if (const AndroidDrawable *drawable = backgroundDrawable()) {
1473 if (drawable->type() == State)
1474 drawable = static_cast<const AndroidStateDrawable *>(backgroundDrawable())->bestAndroidStateMatch(option);
1475 return drawable->size();
1476 }
1477 return QSize();
1478}
1479
1484
1486 ItemType itemType)
1487 : AndroidControl(control, itemType)
1488{
1489 QVariantMap::const_iterator it = control.find(QLatin1String("CompoundButton_button"));
1490 if (it != control.end()) {
1491 m_button = AndroidDrawable::fromMap(it.value().toMap(), itemType);
1492 const_cast<AndroidDrawable *>(m_button)->setPaddingLeftToSizeWidth();
1493 } else {
1494 m_button = 0;
1495 }
1496}
1497
1502
1504 QPainter *p,
1505 const QWidget *w)
1506{
1508 if (m_button)
1509 m_button->draw(p, opt);
1510}
1511
1513{
1514 if (m_button)
1515 return m_button->padding();
1516 return AndroidControl::padding();
1517}
1518
1520{
1521 if (m_button) {
1522 if (m_button->type() == State)
1523 return static_cast<const AndroidStateDrawable *>(m_button)->bestAndroidStateMatch(option)->size();
1524 return m_button->size();
1525 }
1527}
1528
1530{
1531 return m_background ? m_background : m_button;
1532}
1533
1535 ItemType itemType)
1536 : AndroidControl(control, itemType)
1537{
1538 QVariantMap::const_iterator it = control.find(QLatin1String("ProgressBar_indeterminateDrawable"));
1539 if (it != control.end())
1540 m_indeterminateDrawable = AndroidDrawable::fromMap(it.value().toMap(), itemType);
1541 else
1543
1544 it = control.find(QLatin1String("ProgressBar_progressDrawable"));
1545 if (it != control.end())
1546 m_progressDrawable = AndroidDrawable::fromMap(it.value().toMap(), itemType);
1547 else
1549
1550 it = control.find(QLatin1String("ProgressBar_progress_id"));
1551 if (it != control.end())
1552 m_progressId = it.value().toInt();
1553
1554 it = control.find(QLatin1String("ProgressBar_secondaryProgress_id"));
1555 if (it != control.end())
1556 m_secondaryProgress_id = it.value().toInt();
1557
1558 it = control.find(QLatin1String("ProgressBar_minWidth"));
1559 if (it != control.end())
1560 m_minSize.setWidth(it.value().toInt());
1561
1562 it = control.find(QLatin1String("ProgressBar_minHeight"));
1563 if (it != control.end())
1564 m_minSize.setHeight(it.value().toInt());
1565
1566 it = control.find(QLatin1String("ProgressBar_maxWidth"));
1567 if (it != control.end())
1568 m_maxSize.setWidth(it.value().toInt());
1569
1570 it = control.find(QLatin1String("ProgressBar_maxHeight"));
1571 if (it != control.end())
1572 m_maxSize.setHeight(it.value().toInt());
1573}
1574
1576{
1577 delete m_progressDrawable;
1578 delete m_indeterminateDrawable;
1579}
1580
1582{
1583 if (!m_progressDrawable)
1584 return;
1585
1586 if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
1587 if (m_progressDrawable->type() == QAndroidStyle::Layer) {
1588 const double fraction = double(qint64(pb->progress) - pb->minimum) / (qint64(pb->maximum) - pb->minimum);
1589 QAndroidStyle::AndroidDrawable *clipDrawable = static_cast<QAndroidStyle::AndroidLayerDrawable *>(m_progressDrawable)->layer(m_progressId);
1590 const Qt::Orientation orientation = pb->state & QStyle::State_Horizontal ? Qt::Horizontal : Qt::Vertical;
1591 if (clipDrawable->type() == QAndroidStyle::Clip)
1592 static_cast<AndroidClipDrawable *>(clipDrawable)->setFactor(fraction, orientation);
1593 else
1594 static_cast<AndroidLayerDrawable *>(m_progressDrawable)->setFactor(m_progressId, fraction, orientation);
1595 }
1596 m_progressDrawable->draw(p, option);
1597 }
1598}
1599
1601 const QStyleOption *option,
1602 const QWidget *widget) const
1603{
1604 if (const QStyleOptionProgressBar *progressBarOption =
1605 qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
1606 const bool horizontal = progressBarOption->state & QStyle::State_Horizontal;
1607 if (!m_background)
1608 return option->rect;
1609
1610 QMargins padding = m_background->padding();
1611 QRect p(padding.left(), padding.top(), padding.right() - padding.left(), padding.bottom() - padding.top());
1612 padding = m_indeterminateDrawable->padding();
1613 p |= QRect(padding.left(), padding.top(), padding.right() - padding.left(), padding.bottom() - padding.top());
1614 padding = m_progressDrawable->padding();
1615 p |= QRect(padding.left(), padding.top(), padding.right() - padding.left(), padding.bottom() - padding.top());
1616 QRect r = option->rect.adjusted(p.left(), p.top(), -p.right(), -p.bottom());
1617
1618 if (horizontal) {
1619 if (r.height()<m_minSize.height())
1620 r.setHeight(m_minSize.height());
1621
1622 if (r.height()>m_maxSize.height())
1623 r.setHeight(m_maxSize.height());
1624 } else {
1625 if (r.width()<m_minSize.width())
1626 r.setWidth(m_minSize.width());
1627
1628 if (r.width()>m_maxSize.width())
1629 r.setWidth(m_maxSize.width());
1630 }
1631 return visualRect(option->direction, option->rect, r);
1632 }
1633 return AndroidControl::subElementRect(subElement, option, widget);
1634}
1635
1637 const QSize &contentsSize,
1638 const QWidget * /* w */) const
1639{
1640 QSize sz(contentsSize);
1641 if (sz.height() < m_minSize.height())
1642 sz.setHeight(m_minSize.height());
1643 if (sz.width() < m_minSize.width())
1644 sz.setWidth(m_minSize.width());
1645
1646 if (const QStyleOptionProgressBar *progressBarOption =
1647 qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
1648 if (progressBarOption->state & QStyle::State_Horizontal) {
1649 if (sz.width() > m_maxSize.width())
1650 sz.setWidth(m_maxSize.width());
1651 } else {
1652 if (sz.height() > m_maxSize.height())
1653 sz.setHeight(m_maxSize.height());
1654 }
1655 }
1656 return contentsSize;
1657}
1658
1660 ItemType itemType)
1661 : AndroidProgressBarControl(control, itemType)
1662{
1663 QVariantMap::const_iterator it = control.find(QLatin1String("SeekBar_thumb"));
1664 if (it != control.end())
1665 m_seekBarThumb = AndroidDrawable::fromMap(it.value().toMap(), itemType);
1666 else
1667 m_seekBarThumb = 0;
1668}
1669
1674
1676 QPainter *p,
1677 const QWidget * /* w */)
1678{
1679 if (!m_seekBarThumb || !m_progressDrawable)
1680 return;
1681
1682 if (const QStyleOptionSlider *styleOption =
1683 qstyleoption_cast<const QStyleOptionSlider *>(option)) {
1684 double factor = double(styleOption->sliderPosition - styleOption->minimum)
1685 / double(styleOption->maximum - styleOption->minimum);
1686
1687 // Android does not have a vertical slider. To support the vertical orientation, we rotate
1688 // the painter and pretend that we are horizontal.
1689 if (styleOption->orientation == Qt::Vertical)
1690 factor = 1 - factor;
1691
1692 if (m_progressDrawable->type() == QAndroidStyle::Layer) {
1693 QAndroidStyle::AndroidDrawable *clipDrawable = static_cast<QAndroidStyle::AndroidLayerDrawable *>(m_progressDrawable)->layer(m_progressId);
1694 if (clipDrawable->type() == QAndroidStyle::Clip)
1695 static_cast<QAndroidStyle::AndroidClipDrawable *>(clipDrawable)->setFactor(factor, Qt::Horizontal);
1696 else
1697 static_cast<QAndroidStyle::AndroidLayerDrawable *>(m_progressDrawable)->setFactor(m_progressId, factor, Qt::Horizontal);
1698 }
1699 const AndroidDrawable *drawable = m_seekBarThumb;
1700 if (drawable->type() == State)
1701 drawable = static_cast<const QAndroidStyle::AndroidStateDrawable *>(m_seekBarThumb)->bestAndroidStateMatch(option);
1703
1704 p->save();
1705
1706 if (styleOption->orientation == Qt::Vertical) {
1707 // rotate the painter, and transform the rectangle to match
1708 p->rotate(90);
1709 copy.rect = QRect(copy.rect.y(), copy.rect.x() - copy.rect.width(), copy.rect.height(), copy.rect.width());
1710 }
1711
1712 copy.rect.setHeight(m_progressDrawable->size().height());
1713 copy.rect.setWidth(copy.rect.width() - drawable->size().width());
1714 const int yTranslate = abs(drawable->size().height() - copy.rect.height()) / 2;
1715 copy.rect.translate(drawable->size().width() / 2, yTranslate);
1716 m_progressDrawable->draw(p, &copy);
1717 int pos = copy.rect.width() * factor - drawable->size().width() / 2;
1718 copy.rect.translate(pos, -yTranslate);
1719 copy.rect.setSize(drawable->size());
1720 m_seekBarThumb->draw(p, &copy);
1721
1722 p->restore();
1723 }
1724}
1725
1727 const QSize &contentsSize,
1728 const QWidget *w) const
1729{
1731 if (!m_seekBarThumb)
1732 return sz;
1733 const AndroidDrawable *drawable = m_seekBarThumb;
1734 if (drawable->type() == State)
1735 drawable = static_cast<const QAndroidStyle::AndroidStateDrawable *>(m_seekBarThumb)->bestAndroidStateMatch(opt);
1736 return sz.expandedTo(drawable->size());
1737}
1738
1740 SubControl sc,
1741 const QWidget * /* widget */) const
1742{
1743 const QStyleOptionSlider *styleOption =
1744 qstyleoption_cast<const QStyleOptionSlider *>(option);
1745
1746 if (m_seekBarThumb && sc == SC_SliderHandle && styleOption) {
1747 const AndroidDrawable *drawable = m_seekBarThumb;
1748 if (drawable->type() == State)
1749 drawable = static_cast<const QAndroidStyle::AndroidStateDrawable *>(m_seekBarThumb)->bestAndroidStateMatch(option);
1750
1751 QRect r(option->rect);
1752 double factor = double(styleOption->sliderPosition - styleOption->minimum)
1753 / (styleOption->maximum - styleOption->minimum);
1754 if (styleOption->orientation == Qt::Vertical) {
1755 int pos = option->rect.height() * (1 - factor) - double(drawable->size().height() / 2);
1756 r.setY(r.y() + pos);
1757 } else {
1758 int pos = option->rect.width() * factor - double(drawable->size().width() / 2);
1759 r.setX(r.x() + pos);
1760 }
1761 r.setSize(drawable->size());
1762 return r;
1763 }
1764 return option->rect;
1765}
1766
1771
1773 SubControl sc,
1774 const QWidget *widget) const
1775{
1777 return option->rect;
1778 if (sc == QStyle::SC_ComboBoxArrow) {
1780 return QRect(editField.topRight(), QSize(option->rect.width() - editField.width(), option->rect.height()));
1781 }
1783}
1784
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
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 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()
Returns the default application font.
static void setFont(const QFont &, const char *className=nullptr)
Changes the default application font to font.
\inmodule QtGui
Definition qbrush.h:30
const QColor & color() const
Returns the brush color.
Definition qbrush.h:121
\inmodule QtCore
Definition qbytearray.h:57
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
void setRgba(QRgb rgba) noexcept
Sets the RGB value to rgba, including its alpha.
Definition qcolor.cpp:1388
void getHsv(int *h, int *s, int *v, int *a=nullptr) const
Sets the contents pointed to by h, s, v, and a, to the hue, saturation, value, and alpha-channel (tra...
Definition qcolor.cpp:1045
bool isValid() const noexcept
Returns true if the color is valid; otherwise returns false.
Definition qcolor.h:285
QString fileName() const
\reentrant \inmodule QtGui
int height() const
Returns the height of the font.
QRect boundingRect(QChar) const
Returns the rectangle that is covered by ink if character ch were to be drawn at the origin of the co...
QSize size(int flags, const QString &str, int tabstops=0, int *tabarray=nullptr) const
Returns the size in pixels of text.
int midLineWidth
the width of the mid-line
Definition qframe.h:23
int lineWidth
the line width
Definition qframe.h:22
void setColorAt(qreal pos, const QColor &color)
Creates a stop point at the given position with the given color.
Definition qbrush.cpp:1563
static QPlatformNativeInterface * platformNativeInterface()
iterator find(const Key &key)
Returns an iterator pointing to the item with the key in the hash.
Definition qhash.h:1291
iterator end() noexcept
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the last ...
Definition qhash.h:1216
Mode
This enum type describes the mode for which a pixmap is intended to be used.
Definition qicon.h:22
\inmodule QtCore\reentrant
Definition qjsonobject.h:20
\inmodule QtCore\reentrant
Definition qjsonvalue.h:25
T value(const Key &key, const T &defaultValue=T()) const
Definition qmap.h:357
iterator find(const Key &key)
Definition qmap.h:641
iterator end()
Definition qmap.h:602
\inmodule QtCore
Definition qmargins.h:24
constexpr int bottom() const noexcept
Returns the bottom margin.
Definition qmargins.h:115
constexpr void setLeft(int left) noexcept
Sets the left margin to left.
Definition qmargins.h:119
constexpr int left() const noexcept
Returns the left margin.
Definition qmargins.h:106
constexpr int right() const noexcept
Returns the right margin.
Definition qmargins.h:112
constexpr int top() const noexcept
Returns the top margin.
Definition qmargins.h:109
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
const QPen & pen() const
Returns the painter's current pen.
RenderHints renderHints() const
Returns a flag that specifies the rendering hints that are set for this painter.
void setPen(const QColor &color)
This is an overloaded member function, provided for convenience. It differs from the above function o...
const QBrush & brush() const
Returns the painter's current brush.
void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect)
Draws the rectangular portion source of the given pixmap into the given target in the paint device.
void setBrush(const QBrush &brush)
Sets the painter's brush to the given brush.
@ SmoothPixmapTransform
Definition qpainter.h:54
void setRenderHints(RenderHints hints, bool on=true)
void fillRect(const QRectF &, const QBrush &)
Fills the given rectangle with the brush specified.
void drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode=Qt::AbsoluteSize)
The QPalette class contains color groups for each widget state.
Definition qpalette.h:19
const QBrush & windowText() const
Returns the window text (general foreground) brush of the current color group.
Definition qpalette.h:83
const QBrush & window() const
Returns the window (general background) brush of the current color group.
Definition qpalette.h:93
@ WindowText
Definition qpalette.h:51
\inmodule QtGui
Definition qpen.h:28
static bool find(const QString &key, QPixmap *pixmap)
Looks for a cached pixmap associated with the given key in the cache.
static bool insert(const QString &key, const QPixmap &pixmap)
Inserts a copy of the pixmap pixmap associated with the key into the cache.
static void clear()
Removes all pixmaps from the cache.
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
Definition qpixmap.h:27
int height() const
Returns the height of the pixmap.
Definition qpixmap.cpp:480
bool load(const QString &fileName, const char *format=nullptr, Qt::ImageConversionFlags flags=Qt::AutoColor)
Loads a pixmap from the file with the given fileName.
Definition qpixmap.cpp:704
The QPlatformNativeInterface class provides an abstraction for retrieving native resource handles.
virtual void * nativeResourceForIntegration(const QByteArray &resource)
\inmodule QtCore\reentrant
Definition qpoint.h:25
\inmodule QtCore\reentrant
Definition qrect.h:484
constexpr QSizeF size() const noexcept
Returns the size of the rectangle.
Definition qrect.h:735
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr void adjust(int x1, int y1, int x2, int y2) noexcept
Adds dx1, dy1, dx2 and dy2 respectively to the existing coordinates of the rectangle.
Definition qrect.h:373
constexpr int height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:239
constexpr bool isNull() const noexcept
Returns true if the rectangle is a null rectangle, otherwise returns false.
Definition qrect.h:164
constexpr int bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
Definition qrect.h:182
constexpr void setSize(const QSize &s) noexcept
Sets the size of the rectangle to the given size.
Definition qrect.h:387
constexpr QRect adjusted(int x1, int y1, int x2, int y2) const noexcept
Returns a new rectangle with dx1, dy1, dx2 and dy2 added respectively to the existing coordinates of ...
Definition qrect.h:370
constexpr int top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:176
constexpr int left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:173
constexpr int x() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:185
constexpr void setWidth(int w) noexcept
Sets the width of the rectangle to the given width.
Definition qrect.h:381
constexpr QSize size() const noexcept
Returns the size of the rectangle.
Definition qrect.h:242
constexpr void translate(int dx, int dy) noexcept
Moves the rectangle dx along the x axis and dy along the y axis, relative to the current position.
Definition qrect.h:245
constexpr int width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:236
QRect united(const QRect &other) const noexcept
Definition qrect.h:420
constexpr int y() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:188
constexpr void setHeight(int h) noexcept
Sets the height of the rectangle to the given height.
Definition qrect.h:384
constexpr int right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
Definition qrect.h:179
The QRegion class specifies a clip region for a painter.
Definition qregion.h:27
const_iterator constBegin() const noexcept
Definition qset.h:139
const_iterator constEnd() const noexcept
Definition qset.h:143
const_iterator cbegin() const noexcept
Definition qset.h:138
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:133
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:130
constexpr int & rheight() noexcept
Returns a reference to the height.
Definition qsize.h:157
constexpr QSize expandedTo(const QSize &) const noexcept
Returns a size holding the maximum width and height of this size and the given otherSize.
Definition qsize.h:192
constexpr void setWidth(int w) noexcept
Sets the width to the given width.
Definition qsize.h:136
constexpr int & rwidth() noexcept
Returns a reference to the width.
Definition qsize.h:154
constexpr bool isNull() const noexcept
Returns true if both the width and height is 0; otherwise returns false.
Definition qsize.h:121
constexpr bool isEmpty() const noexcept
Returns true if either of the width and height is less than or equal to 0; otherwise returns false.
Definition qsize.h:124
constexpr void setHeight(int h) noexcept
Sets the height to the given height.
Definition qsize.h:139
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
\variable QStyleOptionGraphicsItem::exposedRect
\variable QStyleOptionHeaderV2::textElideMode
\variable QStyleOptionToolButton::features
\variable QStyleOptionMenuItem::menuItemType
\variable QStyleOption::palette
\variable QStyleOptionFocusRect::backgroundColor
\variable QStyleOptionFrame::features
The QStyleOptionHeader class is used to describe the parameters for drawing a header.
\variable QStyleOptionButton::features
The QStyleOption class stores the parameters used by QStyle functions.
QFontMetrics fontMetrics
QStyle::State state
QPalette palette
Qt::LayoutDirection direction
The QStyle class is an abstract base class that encapsulates the look and feel of a GUI.
Definition qstyle.h:29
@ State_Sunken
Definition qstyle.h:69
@ State_HasFocus
Definition qstyle.h:75
@ State_Active
Definition qstyle.h:83
@ State_Off
Definition qstyle.h:70
@ State_Enabled
Definition qstyle.h:67
@ State_Horizontal
Definition qstyle.h:74
@ State_On
Definition qstyle.h:72
@ State_Raised
Definition qstyle.h:68
@ State_Selected
Definition qstyle.h:82
ContentsType
This enum describes the available contents types.
Definition qstyle.h:546
StyleHint
This enum describes the available style hints.
Definition qstyle.h:584
@ SH_UnderlineShortcut
Definition qstyle.h:626
ControlElement
This enum represents a control element.
Definition qstyle.h:170
@ CE_ProgressBarLabel
Definition qstyle.h:188
@ CE_TabBarTabLabel
Definition qstyle.h:183
@ CE_TabBarTabShape
Definition qstyle.h:182
@ CE_RadioButtonLabel
Definition qstyle.h:179
@ CE_CheckBoxLabel
Definition qstyle.h:176
@ CE_PushButtonBevel
Definition qstyle.h:172
@ CE_ProgressBarGroove
Definition qstyle.h:186
@ CE_PushButtonLabel
Definition qstyle.h:173
@ PM_HeaderMargin
Definition qstyle.h:476
ComplexControl
This enum describes the available complex controls.
Definition qstyle.h:331
PrimitiveElement
This enum describes the various primitive elements.
Definition qstyle.h:102
@ PE_FrameLineEdit
Definition qstyle.h:108
@ PE_PanelLineEdit
Definition qstyle.h:122
@ PE_FrameWindow
Definition qstyle.h:112
@ PE_Widget
Definition qstyle.h:148
@ PE_IndicatorCheckBox
Definition qstyle.h:131
@ PE_Frame
Definition qstyle.h:103
@ PE_FrameFocusRect
Definition qstyle.h:106
@ PE_IndicatorItemViewItemCheck
Definition qstyle.h:130
SubElement
This enum represents a sub-area of a widget.
Definition qstyle.h:242
@ SE_LineEditContents
Definition qstyle.h:281
@ SE_PushButtonFocusRect
Definition qstyle.h:244
@ SE_PushButtonContents
Definition qstyle.h:243
@ SE_CustomBase
Definition qstyle.h:323
SubControl
This enum describes the available sub controls.
Definition qstyle.h:347
@ SC_ComboBoxListBoxPopup
Definition qstyle.h:367
@ SC_GroupBoxCheckBox
Definition qstyle.h:390
@ SC_GroupBoxLabel
Definition qstyle.h:391
@ SC_ComboBoxEditField
Definition qstyle.h:365
@ SC_ComboBoxArrow
Definition qstyle.h:366
@ SC_GroupBoxFrame
Definition qstyle.h:393
\inmodule QtCore
Definition qvariant.h:65
QList< QVariant > toList() const
Returns the variant as a QVariantList if the variant has userType() \l QMetaType::QVariantList.
QMap< QString, QVariant > toMap() const
Returns the variant as a QVariantMap if the variant has type() \l QMetaType::QVariantMap.
int toInt(bool *ok=nullptr) const
Returns the variant as an int if the variant has userType() \l QMetaType::Int, \l QMetaType::Bool,...
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
QByteArray toByteArray() const
Returns the variant as a QByteArray if the variant has userType() \l QMetaType::QByteArray or \l QMet...
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
void setAttribute(Qt::WidgetAttribute, bool on=true)
Sets the attribute attribute on this widget if on is true; otherwise clears the attribute.
QPalette palette
the widget's palette
Definition qwidget.h:132
QRect rect
the internal geometry of the widget excluding any window frame
Definition qwidget.h:116
QOpenGLWidget * widget
[1]
QPixmap p2
QPixmap p1
[0]
qDeleteAll(list.begin(), list.end())
QSet< QString >::iterator it
opt iconSize
rect
[4]
QStyleOptionButton subopt
[2]
uint alignment
QStyleOptionButton opt
else opt state
[0]
QRect textRect
const QStyleOptionButton * btn
[3]
Combined button and popup list for selecting options.
const quint32 TRANSPARENT_COLOR
const quint32 NO_COLOR
@ AlignHCenter
Definition qnamespace.h:148
@ LeftButton
Definition qnamespace.h:58
@ WA_StyledBackground
Definition qnamespace.h:366
@ LeftToRight
Orientation
Definition qnamespace.h:98
@ Horizontal
Definition qnamespace.h:99
@ Vertical
Definition qnamespace.h:100
@ TextHideMnemonic
Definition qnamespace.h:178
@ TextShowMnemonic
Definition qnamespace.h:173
@ white
Definition qnamespace.h:31
@ black
Definition qnamespace.h:30
@ NoPen
static jboolean copy(JNIEnv *, jobject)
#define Q_UNLIKELY(x)
#define qApp
static const QCssKnownValue positions[NumKnownPositionModes - 1]
void qDrawShadePanel(QPainter *p, int x, int y, int w, int h, const QPalette &pal, bool sunken, int lineWidth, const QBrush *fill)
void qDrawShadeLine(QPainter *p, int x1, int y1, int x2, int y2, const QPalette &pal, bool sunken, int lineWidth, int midLineWidth)
Definition qdrawutil.cpp:86
void qDrawShadeRect(QPainter *p, int x, int y, int w, int h, const QPalette &pal, bool sunken, int lineWidth, int midLineWidth, const QBrush *fill)
void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &c, int lineWidth, const QBrush *fill)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
const EGLAttrib EGLOutputLayerEXT * layers
EGLOutputLayerEXT layer
static void visualRect(QRectF *geom, Qt::LayoutDirection dir, const QRectF &contentsRect)
#define qWarning
Definition qlogging.h:166
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLenum GLsizei GLsizei GLint * values
[15]
GLsizei const GLfloat * v
[13]
const GLfloat * m
GLuint64 key
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLboolean r
[2]
GLuint GLuint end
GLenum GLuint id
[7]
GLuint object
[3]
GLenum src
GLint GLsizei width
GLuint color
[2]
GLenum type
GLenum GLenum dst
GLuint GLfloat x0
GLuint GLfloat GLfloat y0
GLsizei const GLint * box
GLfloat GLfloat GLfloat GLfloat h
GLdouble s
[6]
Definition qopenglext.h:235
GLuint GLfloat * val
GLenum array
GLfloat GLfloat p
[1]
GLuint GLenum option
GLuint * states
static qsizetype cost(const QPixmap &pixmap)
static QT_BEGIN_NAMESPACE const QRgb colors[][14]
QT_BEGIN_NAMESPACE typedef unsigned int QRgb
Definition qrgb.h:13
static QList< QVariant > toList(char **buf, int count)
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
static QT_BEGIN_NAMESPACE QVariant hint(QPlatformIntegration::StyleHint h)
unsigned int quint32
Definition qtypes.h:50
int qint32
Definition qtypes.h:49
unsigned int uint
Definition qtypes.h:34
long long qint64
Definition qtypes.h:60
unsigned char quint8
Definition qtypes.h:46
static int toInt(const QChar &qc, int R)
value toMap().value(key)
[3]
Text files * txt
QGraphicsItem * item
widget render & pixmap
QPainter painter(this)
[7]
QFrame frame
[0]