30QAndroidStyle::QAndroidStyle()
33 QPixmapCache::clear();
34 QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
35 QPalette *standardPalette =
reinterpret_cast<QPalette *>(nativeInterface->nativeResourceForIntegration(
"AndroidStandardPalette"));
37 m_standardPalette = *standardPalette;
39 QHash<QByteArray, QFont> *qwidgetsFonts =
reinterpret_cast<QHash<QByteArray, QFont> *>(nativeInterface->nativeResourceForIntegration(
"AndroidQWidgetFonts"));
41 for (
auto it = qwidgetsFonts->constBegin(); it != qwidgetsFonts->constEnd(); ++it)
42 QApplication::setFont(it.value(), it.key());
43 qwidgetsFonts->clear();
46 QJsonObject *object =
reinterpret_cast<QJsonObject *>(nativeInterface->nativeResourceForIntegration(
"AndroidStyleData"));
50 for (QJsonObject::const_iterator objectIterator = object->constBegin();
51 objectIterator != object->constEnd();
53 QString key = objectIterator.key();
54 QJsonValue value = objectIterator.value();
55 if (Q_UNLIKELY(!value.isObject())) {
56 qWarning(
"Style.json structure is unrecognized.");
60 QJsonObject item = value.toObject();
61 QAndroidStyle::ItemType itemType = qtControl(key);
62 if (QC_UnknownType == itemType)
67 m_checkBoxControl =
new AndroidCompoundButtonControl(item.toVariantMap(), itemType);
68 m_androidControlsHash[
int(itemType)] = m_checkBoxControl;
71 m_androidControlsHash[
int(itemType)] =
new AndroidCompoundButtonControl(item.toVariantMap(),
76 m_androidControlsHash[
int(itemType)] =
new AndroidProgressBarControl(item.toVariantMap(),
81 m_androidControlsHash[
int(itemType)] =
new AndroidSeekBarControl(item.toVariantMap(),
86 m_androidControlsHash[
int(itemType)] =
new AndroidSpinnerControl(item.toVariantMap(),
91 m_androidControlsHash[
int(itemType)] =
new AndroidControl(item.toVariantMap(),
96 *object = QJsonObject();
250void QAndroidStyle::drawPrimitive(PrimitiveElement pe,
251 const QStyleOption *opt,
253 const QWidget *w)
const
255 const ItemType itemType = qtControl(pe);
256 AndroidControlsHash::const_iterator it = itemType != QC_UnknownType
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);
263 QStyleOption copy(*opt);
264 copy.state &= ~QStyle::State_Sunken;
265 it.value()->drawControl(©, p, w);
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,
274 frame->lineWidth, frame->midLineWidth);
276 qDrawShadeRect(p, frame->rect.x(), frame->rect.y(), frame->rect.width(),
277 frame->rect.height(), frame->palette,
true,
278 frame->lineWidth, frame->midLineWidth);
282 QFusionStyle::drawPrimitive(pe, opt, p, w);
287void QAndroidStyle::drawControl(QStyle::ControlElement element,
288 const QStyleOption *opt,
290 const QWidget *w)
const
292 const ItemType itemType = qtControl(element);
293 AndroidControlsHash::const_iterator it = itemType != QC_UnknownType
294 ? m_androidControlsHash.find(itemType)
295 : m_androidControlsHash.end();
296 if (it != m_androidControlsHash.end()) {
297 AndroidControl *androidControl = it.value();
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);
307 if (element != QStyle::CE_PushButtonBevel
308 && element != QStyle::CE_TabBarTabShape
309 && element != QStyle::CE_ProgressBarGroove) {
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, ©, p, w);
322 if (
const QStyleOptionButton *btn =
323 qstyleoption_cast<
const QStyleOptionButton *>(opt)) {
324 const bool isRadio = (element == CE_RadioButton);
325 QStyleOptionButton subopt(*btn);
326 subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents
327 : SE_CheckBoxContents, btn, w);
328 QFusionStyle::drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, p, w);
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);
341 QFusionStyle::drawControl(element, opt, p, w);
346 QFusionStyle::drawControl(element, opt, p, w);
363void QAndroidStyle::drawComplexControl(ComplexControl cc,
364 const QStyleOptionComplex *opt,
366 const QWidget *widget)
const
368 const ItemType itemType = qtControl(cc);
369 AndroidControlsHash::const_iterator it = itemType != QC_UnknownType
370 ? m_androidControlsHash.find(itemType)
371 : m_androidControlsHash.end();
372 if (it != m_androidControlsHash.end()) {
373 it.value()->drawControl(opt, p, widget);
376 if (cc == CC_GroupBox) {
377 if (!m_checkBoxControl) {
378 QFusionStyle::drawComplexControl(cc, opt, p, widget);
381 if (
const QStyleOptionGroupBox *groupBox = qstyleoption_cast<
const QStyleOptionGroupBox *>(opt)) {
383 QRect textRect = subControlRect(CC_GroupBox, opt, SC_GroupBoxLabel, widget);
385 if (groupBox->subControls & SC_GroupBoxCheckBox)
386 checkBoxRect = subControlRect(CC_GroupBox, opt, SC_GroupBoxCheckBox, widget);
387 if (groupBox->subControls & QStyle::SC_GroupBoxFrame) {
388 QStyleOptionFrame frame;
389 frame.QStyleOption::operator=(*groupBox);
390 frame.features = groupBox->features;
391 frame.lineWidth = groupBox->lineWidth;
392 frame.midLineWidth = groupBox->midLineWidth;
393 frame.rect = subControlRect(CC_GroupBox, opt, SC_GroupBoxFrame, widget);
395 QRegion region(groupBox->rect);
396 if (!groupBox->text.isEmpty()) {
397 bool ltr = groupBox->direction == Qt::LeftToRight;
399 if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox) {
400 finalRect = checkBoxRect.united(textRect);
401 finalRect.adjust(ltr ? -4 : 0, 0, ltr ? 0 : 4, 0);
403 finalRect = textRect;
407 p->setClipRegion(region);
408 drawPrimitive(PE_FrameGroupBox, &frame, p, widget);
413 if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
414 QColor textColor = groupBox->textColor;
415 if (textColor.isValid())
416 p->setPen(textColor);
417 int alignment =
int(groupBox->textAlignment);
418 if (!styleHint(QStyle::SH_UnderlineShortcut, opt, widget))
419 alignment |= Qt::TextHideMnemonic;
421 drawItemText(p, textRect, Qt::TextShowMnemonic | Qt::AlignHCenter | alignment,
422 groupBox->palette, groupBox->state & State_Enabled, groupBox->text,
423 textColor.isValid() ? QPalette::NoRole : QPalette::WindowText);
425 if (groupBox->state & State_HasFocus) {
426 QStyleOptionFocusRect fropt;
427 fropt.QStyleOption::operator=(*groupBox);
428 fropt.rect = textRect;
429 drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
434 if (groupBox->subControls & SC_GroupBoxCheckBox) {
435 QStyleOptionButton box;
436 box.QStyleOption::operator=(*groupBox);
437 box.rect = checkBoxRect;
438 m_checkBoxControl->drawControl(&box, p, widget);
443 QFusionStyle::drawComplexControl(cc, opt, p, widget);
446QStyle::SubControl QAndroidStyle::hitTestComplexControl(ComplexControl cc,
447 const QStyleOptionComplex *opt,
449 const QWidget *widget)
const
451 const ItemType itemType = qtControl(cc);
452 AndroidControlsHash::const_iterator it = itemType != QC_UnknownType
453 ? m_androidControlsHash.find(itemType)
454 : m_androidControlsHash.end();
455 if (it != m_androidControlsHash.end()) {
458 if (
const QStyleOptionSlider *slider = qstyleoption_cast<
const QStyleOptionSlider *>(opt)) {
459 QRect r = it.value()->subControlRect(slider, SC_SliderHandle, widget);
460 if (r.isValid() && r.contains(pt)) {
461 return SC_SliderHandle;
463 r = it.value()->subControlRect(slider, SC_SliderGroove, widget);
464 if (r.isValid() && r.contains(pt))
465 return SC_SliderGroove;
473 return QFusionStyle::hitTestComplexControl(cc, opt, pt, widget);
476QRect QAndroidStyle::subControlRect(ComplexControl cc,
477 const QStyleOptionComplex *opt,
479 const QWidget *widget)
const
481 if (cc == CC_GroupBox && !m_checkBoxControl)
482 return QFusionStyle::subControlRect(cc, opt, sc, widget);
484 const ItemType itemType = qtControl(cc);
485 AndroidControlsHash::const_iterator it = itemType != QC_UnknownType
486 ? m_androidControlsHash.find(itemType)
487 : m_androidControlsHash.end();
488 if (it != m_androidControlsHash.end())
489 return it.value()->subControlRect(opt, sc, widget);
490 QRect rect = opt->rect;
493 if (
const QStyleOptionGroupBox *groupBox = qstyleoption_cast<
const QStyleOptionGroupBox *>(opt)) {
494 QSize textSize = opt->fontMetrics.boundingRect(groupBox->text).size() + QSize(2, 2);
495 QSize checkBoxSize = m_checkBoxControl->size(opt);
496 int indicatorWidth = checkBoxSize.width();
497 int indicatorHeight = checkBoxSize.height();
499 if (opt->subControls & QStyle::SC_GroupBoxCheckBox) {
500 checkBoxRect.setWidth(indicatorWidth);
501 checkBoxRect.setHeight(indicatorHeight);
503 checkBoxRect.moveLeft(1);
504 QRect textRect = checkBoxRect;
505 textRect.setSize(textSize);
506 if (opt->subControls & QStyle::SC_GroupBoxCheckBox)
507 textRect.translate(indicatorWidth + 5, (indicatorHeight - textSize.height()) / 2);
508 if (sc == SC_GroupBoxFrame) {
509 rect = opt->rect.adjusted(0, 0, 0, 0);
510 rect.translate(0, textRect.height() / 2);
511 rect.setHeight(rect.height() - textRect.height() / 2);
512 }
else if (sc == SC_GroupBoxContents) {
513 QRect frameRect = opt->rect.adjusted(0, 0, 0, -groupBox->lineWidth);
515 int leftMarginExtension = 0;
516 int topMargin = qMax(pixelMetric(PM_ExclusiveIndicatorHeight), opt->fontMetrics.height()) + groupBox->lineWidth;
517 frameRect.adjust(leftMarginExtension + margin, margin + topMargin, -margin, -margin - groupBox->lineWidth);
518 frameRect.translate(0, textRect.height() / 2);
520 rect.setHeight(rect.height() - textRect.height() / 2);
521 }
else if (sc == SC_GroupBoxCheckBox) {
523 }
else if (sc == SC_GroupBoxLabel) {
526 return visualRect(opt->direction, opt->rect, rect);
537 return QFusionStyle::subControlRect(cc, opt, sc, widget);
565QSize QAndroidStyle::sizeFromContents(ContentsType ct,
566 const QStyleOption *opt,
567 const QSize &contentsSize,
568 const QWidget *w)
const
570 QSize sz = QFusionStyle::sizeFromContents(ct, opt, contentsSize, w);
571 if (ct == CT_HeaderSection) {
572 if (
const QStyleOptionHeader *hdr = qstyleoption_cast<
const QStyleOptionHeader *>(opt)) {
573 bool nullIcon = hdr->icon.isNull();
574 int margin = pixelMetric(QStyle::PM_HeaderMargin, hdr, w);
575 int iconSize = nullIcon ? 0 : pixelMetric(QStyle::PM_IndicatorWidth, opt, w);
578
579
580
581
582 if (qApp->styleSheet().isEmpty())
583 txt = hdr->fontMetrics.size(0, hdr->text);
585 txt = QFontMetrics(QApplication::font()).size(0, hdr->text);
587 sz.setHeight(margin + qMax(iconSize, txt.height()) + margin);
588 sz.setWidth((nullIcon ? 0 : margin) + iconSize
589 + (hdr->text.isNull() ? 0 : margin) + txt.width() + margin);
590 if (hdr->sortIndicator != QStyleOptionHeader::None) {
591 int margin = pixelMetric(QStyle::PM_HeaderMargin, hdr, w);
592 if (hdr->orientation == Qt::Horizontal)
593 sz.rwidth() += sz.height() + margin;
595 sz.rheight() += sz.width() + margin;
600 const ItemType itemType = qtControl(ct);
601 AndroidControlsHash::const_iterator it = itemType != QC_UnknownType
602 ? m_androidControlsHash.find(itemType)
603 : m_androidControlsHash.end();
604 if (it != m_androidControlsHash.end())
605 return it.value()->sizeFromContents(opt, sz, w);
606 if (ct == CT_GroupBox && m_checkBoxControl) {
607 if (
const QStyleOptionGroupBox *groupBox = qstyleoption_cast<
const QStyleOptionGroupBox *>(opt)) {
608 QSize textSize = opt->fontMetrics.boundingRect(groupBox->text).size() + QSize(2, 2);
609 QSize checkBoxSize = m_checkBoxControl->size(opt);
610 int indicatorWidth = checkBoxSize.width();
611 int indicatorHeight = checkBoxSize.height();
613 if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox) {
614 checkBoxRect.setWidth(indicatorWidth);
615 checkBoxRect.setHeight(indicatorHeight);
617 checkBoxRect.moveLeft(1);
618 QRect textRect = checkBoxRect;
619 textRect.setSize(textSize);
620 if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox)
621 textRect.translate(indicatorWidth + 5, (indicatorHeight - textSize.height()) / 2);
622 QRect u = textRect.united(checkBoxRect);
623 sz = QSize(sz.width(), sz.height() + u.height());
835void QAndroidStyle::Android9PatchDrawable::draw(QPainter *painter,
const QStyleOption *opt)
const
837 if (m_hashKey.isEmpty())
838 m_hashKey = QFileInfo(m_filePath).fileName();
841 if (!QPixmapCache::find(m_hashKey, &pixmap)) {
842 pixmap.load(m_filePath);
843 QPixmapCache::insert(m_hashKey, pixmap);
846 const QRect &bounds = opt->rect;
849 const int pixmapWidth = pixmap.width();
850 const int pixmapHeight = pixmap.height();
852 if (bounds.isNull() || !pixmapWidth || !pixmapHeight)
855 QPainter::RenderHints savedHints = painter->renderHints();
858 painter->setRenderHints(QPainter::SmoothPixmapTransform,
false);
865 if (m_chunkData.xDivs.isEmpty() || m_chunkData.yDivs.isEmpty()) {
866 painter->drawPixmap(bounds, pixmap);
867 painter->setRenderHints(savedHints);
871 const qint32 x0 = m_chunkData.xDivs[0];
872 const qint32 y0 = m_chunkData.yDivs[0];
873 const quint8 numXDivs = m_chunkData.xDivs.size();
874 const quint8 numYDivs = m_chunkData.yDivs.size();
880 const bool initialXIsStretchable = (x0 == 0);
881 bool yIsStretchable = (y0 == 0);
882 const int bitmapWidth = pixmap.width();
883 const int bitmapHeight = pixmap.height();
885 int *dstRights =
static_cast<
int *>(alloca((numXDivs + 1) *
sizeof(
int)));
886 bool dstRightsHaveBeenCached =
false;
888 int numStretchyXPixelsRemaining = 0;
889 for (i = 0; i + 1 < numXDivs; i += 2)
890 numStretchyXPixelsRemaining += m_chunkData.xDivs[i + 1] - m_chunkData.xDivs[i];
892 int numFixedXPixelsRemaining = bitmapWidth - numStretchyXPixelsRemaining;
893 int numStretchyYPixelsRemaining = 0;
894 for (i = 0; i + 1 < numYDivs; i += 2)
895 numStretchyYPixelsRemaining += m_chunkData.yDivs[i + 1] - m_chunkData.yDivs[i];
897 int numFixedYPixelsRemaining = bitmapHeight - numStretchyYPixelsRemaining;
899 dst.setTop(bounds.top());
916 for (j = yIsStretchable ? 1 : 0;
917 j <= numYDivs && src.top() < bitmapHeight;
918 j++, yIsStretchable = !yIsStretchable) {
920 dst.setLeft(bounds.left());
922 src.setBottom(bitmapHeight);
923 dst.setBottom(bounds.bottom());
925 src.setBottom(m_chunkData.yDivs[j]);
926 const int srcYSize = src.bottom() - src.top();
927 if (yIsStretchable) {
928 dst.setBottom(dst.top() + calculateStretch(bounds.bottom(), dst.top(),
930 numStretchyYPixelsRemaining,
931 numFixedYPixelsRemaining));
932 numStretchyYPixelsRemaining -= srcYSize;
934 dst.setBottom(dst.top() + srcYSize);
935 numFixedYPixelsRemaining -= srcYSize;
939 xIsStretchable = initialXIsStretchable;
942 for (i = xIsStretchable ? 1 : 0;
943 i <= numXDivs && src.left() < bitmapWidth;
944 i++, xIsStretchable = !xIsStretchable) {
945 color = colorIndex < m_chunkData.colors.size() ? m_chunkData.colors[colorIndex]
948 if (color != TRANSPARENT_COLOR)
951 src.setRight(bitmapWidth);
952 dst.setRight(bounds.right());
954 src.setRight(m_chunkData.xDivs[i]);
955 if (dstRightsHaveBeenCached) {
956 dst.setRight(dstRights[i]);
958 const int srcXSize = src.right() - src.left();
959 if (xIsStretchable) {
960 dst.setRight(dst.left() + calculateStretch(bounds.right(), dst.left(),
962 numStretchyXPixelsRemaining,
963 numFixedXPixelsRemaining));
964 numStretchyXPixelsRemaining -= srcXSize;
966 dst.setRight(dst.left() + srcXSize);
967 numFixedXPixelsRemaining -= srcXSize;
969 dstRights[i] = dst.right();
975 if (src.left() >= src.right()) {
976 src.setLeft(src.right());
980 if (dst.right() <= dst.left() || dst.bottom() <= dst.top()) {
984 if (color == TRANSPARENT_COLOR)
986 if (color != NO_COLOR)
987 painter->fillRect(dst, QRgb(color));
989 painter->drawPixmap(dst, pixmap, src);
991 src.setLeft(src.right());
992 dst.setLeft(dst.right());
994 src.setTop(src.bottom());
995 dst.setTop(dst.bottom());
996 dstRightsHaveBeenCached =
true;
998 painter->setRenderHints(savedHints);
1001QAndroidStyle::AndroidGradientDrawable::AndroidGradientDrawable(
const QVariantMap &drawable,
1002 QAndroidStyle::ItemType itemType)
1003 : AndroidDrawable(drawable, itemType), m_orientation(TOP_BOTTOM)
1005 m_radius = drawable.value(QLatin1String(
"radius")).toInt();
1009 QVariantList colors = drawable.value(QLatin1String(
"colors")).toList();
1010 QVariantList positions = drawable.value(QLatin1String(
"positions")).toList();
1011 int min = colors.size() < positions.size() ? colors.size() : positions.size();
1012 for (
int i = 0; i < min; i++)
1013 m_gradient.setColorAt(positions.at(i).toDouble(), QRgb(colors.at(i).toInt()));
1015 QByteArray orientation = drawable.value(QLatin1String(
"orientation")).toByteArray();
1016 if (orientation ==
"TOP_BOTTOM")
1017 m_orientation = TOP_BOTTOM;
1018 else if (orientation ==
"TR_BL")
1019 m_orientation = TR_BL;
1020 else if (orientation ==
"RIGHT_LEFT")
1021 m_orientation = RIGHT_LEFT;
1022 else if (orientation ==
"BR_TL")
1023 m_orientation = BR_TL;
1024 else if (orientation ==
"BOTTOM_TOP")
1025 m_orientation = BOTTOM_TOP;
1026 else if (orientation ==
"BL_TR")
1027 m_orientation = BL_TR;
1028 else if (orientation ==
"LEFT_RIGHT")
1029 m_orientation = LEFT_RIGHT;
1030 else if (orientation ==
"TL_BR")
1031 m_orientation = TL_BR;
1033 qWarning(
"AndroidGradientDrawable: unknown orientation");
1041void QAndroidStyle::AndroidGradientDrawable::draw(QPainter *painter,
const QStyleOption *opt)
const
1043 const int width = opt->rect.width();
1044 const int height = opt->rect.height();
1045 switch (m_orientation) {
1048 m_gradient.setStart(width / 2, 0);
1049 m_gradient.setFinalStop(width / 2, height);
1053 m_gradient.setStart(width, 0);
1054 m_gradient.setFinalStop(0, height);
1058 m_gradient.setStart(width, height / 2);
1059 m_gradient.setFinalStop(0, height / 2);
1063 m_gradient.setStart(width, height);
1064 m_gradient.setFinalStop(0, 0);
1068 m_gradient.setStart(width / 2, height);
1069 m_gradient.setFinalStop(width / 2, 0);
1073 m_gradient.setStart(0, height);
1074 m_gradient.setFinalStop(width, 0);
1078 m_gradient.setStart(0, height / 2);
1079 m_gradient.setFinalStop(width, height / 2);
1083 m_gradient.setStart(0, 0);
1084 m_gradient.setFinalStop(width, height);
1088 const QBrush &oldBrush = painter->brush();
1089 const QPen oldPen = painter->pen();
1090 painter->setPen(Qt::NoPen);
1091 painter->setBrush(m_gradient);
1092 painter->drawRoundedRect(opt->rect, m_radius, m_radius);
1093 painter->setBrush(oldBrush);
1094 painter->setPen(oldPen);
1184const QAndroidStyle::AndroidDrawable * QAndroidStyle::AndroidStateDrawable::bestAndroidStateMatch(
const QStyleOption *opt)
const
1186 const AndroidDrawable *bestMatch =
nullptr;
1188 if (m_states.size())
1189 return m_states[0].second;
1193 uint bestCost = 0xffff;
1194 for (
const StateType & state : m_states) {
1195 if (
int(opt->state) == state.first)
1196 return state.second;
1199 int difference =
int(opt->state^state.first);
1201 if (difference & QStyle::State_Active)
1204 if (difference & QStyle::State_Enabled)
1207 if (difference & QStyle::State_Raised)
1210 if (difference & QStyle::State_Sunken)
1213 if (difference & QStyle::State_Off)
1216 if (difference & QStyle::State_On)
1219 if (difference & QStyle::State_HasFocus)
1222 if (difference & QStyle::State_Selected)
1225 if (cost < bestCost) {
1227 bestMatch = state.second;
1233int QAndroidStyle::AndroidStateDrawable::extractState(
const QVariantMap &value)
1235 QStyle::State state = QStyle::State_Enabled | QStyle::State_Active;
1236 for (
auto it = value.cbegin(), end = value.cend(); it != end; ++it) {
1237 const QString &key = it.key();
1238 bool val = it.value().toString() == QLatin1String(
"true");
1239 if (key == QLatin1String(
"enabled")) {
1240 state.setFlag(QStyle::State_Enabled, val);
1244 if (key == QLatin1String(
"window_focused")) {
1245 state.setFlag(QStyle::State_Active, val);
1249 if (key == QLatin1String(
"focused")) {
1250 state.setFlag(QStyle::State_HasFocus, val);
1254 if (key == QLatin1String(
"checked")) {
1255 state |= val ? QStyle::State_On : QStyle::State_Off;
1259 if (key == QLatin1String(
"pressed")) {
1260 state |= val ? QStyle::State_Sunken : QStyle::State_Raised;
1264 if (key == QLatin1String(
"selected")) {
1265 state.setFlag(QStyle::State_Selected, val);
1269 if (key == QLatin1String(
"active")) {
1270 state.setFlag(QStyle::State_Active, val);
1274 if (key == QLatin1String(
"multiline"))
1277 if (key == QLatin1String(
"background") && val)
1280 return static_cast<
int>(state);
1391void QAndroidStyle::AndroidControl::drawControl(
const QStyleOption *opt, QPainter *p,
const QWidget * )
1394 m_background->draw(p, opt);
1396 if (
const QStyleOptionFrame *frame = qstyleoption_cast<
const QStyleOptionFrame *>(opt)) {
1397 if ((frame->state & State_Sunken) || (frame->state & State_Raised)) {
1398 qDrawShadePanel(p, frame->rect, frame->palette, frame->state & State_Sunken,
1401 qDrawPlainRect(p, frame->rect, frame->palette.windowText().color(), frame->lineWidth);
1404 if (
const QStyleOptionFocusRect *fropt = qstyleoption_cast<
const QStyleOptionFocusRect *>(opt)) {
1405 QColor bg = fropt->backgroundColor;
1406 QPen oldPen = p->pen();
1409 bg.getHsv(&h, &s, &v);
1411 p->setPen(Qt::black);
1413 p->setPen(Qt::white);
1415 p->setPen(opt->palette.windowText().color());
1417 QRect focusRect = opt->rect.adjusted(1, 1, -1, -1);
1418 p->drawRect(focusRect.adjusted(0, 0, -1, -1));
1421 p->fillRect(opt->rect, opt->palette.window());
1427QRect QAndroidStyle::AndroidControl::subElementRect(QStyle::SubElement ,
1428 const QStyleOption *option,
1429 const QWidget * )
const
1431 if (
const AndroidDrawable *drawable = backgroundDrawable()) {
1432 if (drawable->type() == State)
1433 drawable =
static_cast<
const AndroidStateDrawable *>(backgroundDrawable())->bestAndroidStateMatch(option);
1435 const QMargins &padding = drawable->padding();
1437 QRect r = option->rect.adjusted(padding.left(), padding.top(),
1438 -padding.right(), -padding.bottom());
1440 if (r.width() < m_minSize.width())
1441 r.setWidth(m_minSize.width());
1443 if (r.height() < m_minSize.height())
1444 r.setHeight(m_minSize.height());
1446 return visualRect(option->direction, option->rect, r);
1448 return option->rect;
1557QAndroidStyle::AndroidProgressBarControl::AndroidProgressBarControl(
const QVariantMap &control,
1559 : AndroidControl(control, itemType)
1561 QVariantMap::const_iterator it = control.find(QLatin1String(
"ProgressBar_indeterminateDrawable"));
1562 if (it != control.end())
1563 m_indeterminateDrawable = AndroidDrawable::fromMap(it.value().toMap(), itemType);
1565 m_indeterminateDrawable = 0;
1567 it = control.find(QLatin1String(
"ProgressBar_progressDrawable"));
1568 if (it != control.end())
1569 m_progressDrawable = AndroidDrawable::fromMap(it.value().toMap(), itemType);
1571 m_progressDrawable = 0;
1573 it = control.find(QLatin1String(
"ProgressBar_progress_id"));
1574 if (it != control.end())
1575 m_progressId = it.value().toInt();
1577 it = control.find(QLatin1String(
"ProgressBar_secondaryProgress_id"));
1578 if (it != control.end())
1579 m_secondaryProgress_id = it.value().toInt();
1581 it = control.find(QLatin1String(
"ProgressBar_minWidth"));
1582 if (it != control.end())
1583 m_minSize.setWidth(it.value().toInt());
1585 it = control.find(QLatin1String(
"ProgressBar_minHeight"));
1586 if (it != control.end())
1587 m_minSize.setHeight(it.value().toInt());
1589 it = control.find(QLatin1String(
"ProgressBar_maxWidth"));
1590 if (it != control.end())
1591 m_maxSize.setWidth(it.value().toInt());
1593 it = control.find(QLatin1String(
"ProgressBar_maxHeight"));
1594 if (it != control.end())
1595 m_maxSize.setHeight(it.value().toInt());
1604void QAndroidStyle::AndroidProgressBarControl::drawControl(
const QStyleOption *option, QPainter *p,
const QWidget * )
1606 if (!m_progressDrawable)
1609 if (
const QStyleOptionProgressBar *pb = qstyleoption_cast<
const QStyleOptionProgressBar *>(option)) {
1610 if (m_progressDrawable->type() == QAndroidStyle::Layer) {
1611 const double fraction =
double(qint64(pb->progress) - pb->minimum) / (qint64(pb->maximum) - pb->minimum);
1612 QAndroidStyle::AndroidDrawable *clipDrawable =
static_cast<QAndroidStyle::AndroidLayerDrawable *>(m_progressDrawable)->layer(m_progressId);
1613 const Qt::Orientation orientation = pb->state & QStyle::State_Horizontal ? Qt::Horizontal : Qt::Vertical;
1614 if (clipDrawable->type() == QAndroidStyle::Clip)
1615 static_cast<AndroidClipDrawable *>(clipDrawable)->setFactor(fraction, orientation);
1617 static_cast<AndroidLayerDrawable *>(m_progressDrawable)->setFactor(m_progressId, fraction, orientation);
1619 m_progressDrawable->draw(p, option);
1623QRect QAndroidStyle::AndroidProgressBarControl::subElementRect(QStyle::SubElement subElement,
1624 const QStyleOption *option,
1625 const QWidget *widget)
const
1627 if (
const QStyleOptionProgressBar *progressBarOption =
1628 qstyleoption_cast<
const QStyleOptionProgressBar *>(option)) {
1629 const bool horizontal = progressBarOption->state & QStyle::State_Horizontal;
1631 return option->rect;
1633 QMargins padding = m_background->padding();
1634 QRect p(padding.left(), padding.top(), padding.right() - padding.left(), padding.bottom() - padding.top());
1635 padding = m_indeterminateDrawable->padding();
1636 p |= QRect(padding.left(), padding.top(), padding.right() - padding.left(), padding.bottom() - padding.top());
1637 padding = m_progressDrawable->padding();
1638 p |= QRect(padding.left(), padding.top(), padding.right() - padding.left(), padding.bottom() - padding.top());
1639 QRect r = option->rect.adjusted(p.left(), p.top(), -p.right(), -p.bottom());
1642 if (r.height()<m_minSize.height())
1643 r.setHeight(m_minSize.height());
1645 if (r.height()>m_maxSize.height())
1646 r.setHeight(m_maxSize.height());
1648 if (r.width()<m_minSize.width())
1649 r.setWidth(m_minSize.width());
1651 if (r.width()>m_maxSize.width())
1652 r.setWidth(m_maxSize.width());
1654 return visualRect(option->direction, option->rect, r);
1656 return AndroidControl::subElementRect(subElement, option, widget);
1698void QAndroidStyle::AndroidSeekBarControl::drawControl(
const QStyleOption *option,
1702 if (!m_seekBarThumb || !m_progressDrawable)
1705 if (
const QStyleOptionSlider *styleOption =
1706 qstyleoption_cast<
const QStyleOptionSlider *>(option)) {
1707 double factor =
double(styleOption->sliderPosition - styleOption->minimum)
1708 /
double(styleOption->maximum - styleOption->minimum);
1712 if (styleOption->orientation == Qt::Vertical)
1713 factor = 1 - factor;
1715 if (m_progressDrawable->type() == QAndroidStyle::Layer) {
1716 QAndroidStyle::AndroidDrawable *clipDrawable =
static_cast<QAndroidStyle::AndroidLayerDrawable *>(m_progressDrawable)->layer(m_progressId);
1717 if (clipDrawable->type() == QAndroidStyle::Clip)
1718 static_cast<QAndroidStyle::AndroidClipDrawable *>(clipDrawable)->setFactor(factor, Qt::Horizontal);
1720 static_cast<QAndroidStyle::AndroidLayerDrawable *>(m_progressDrawable)->setFactor(m_progressId, factor, Qt::Horizontal);
1722 const AndroidDrawable *drawable = m_seekBarThumb;
1723 if (drawable->type() == State)
1724 drawable =
static_cast<
const QAndroidStyle::AndroidStateDrawable *>(m_seekBarThumb)->bestAndroidStateMatch(option);
1725 QStyleOption copy(*option);
1729 if (styleOption->orientation == Qt::Vertical) {
1732 copy.rect = QRect(copy.rect.y(), copy.rect.x() - copy.rect.width(), copy.rect.height(), copy.rect.width());
1735 copy.rect.setHeight(m_progressDrawable->size().height());
1736 copy.rect.setWidth(copy.rect.width() - drawable->size().width());
1737 const int yTranslate = abs(drawable->size().height() - copy.rect.height()) / 2;
1738 copy.rect.translate(drawable->size().width() / 2, yTranslate);
1739 m_progressDrawable->draw(p, ©);
1740 int pos = copy.rect.width() * factor - drawable->size().width() / 2;
1741 copy.rect.translate(pos, -yTranslate);
1742 copy.rect.setSize(drawable->size());
1743 m_seekBarThumb->draw(p, ©);
1762QRect QAndroidStyle::AndroidSeekBarControl::subControlRect(
const QStyleOptionComplex *option,
1764 const QWidget * )
const
1766 const QStyleOptionSlider *styleOption =
1767 qstyleoption_cast<
const QStyleOptionSlider *>(option);
1769 if (m_seekBarThumb && sc == SC_SliderHandle && styleOption) {
1770 const AndroidDrawable *drawable = m_seekBarThumb;
1771 if (drawable->type() == State)
1772 drawable =
static_cast<
const QAndroidStyle::AndroidStateDrawable *>(m_seekBarThumb)->bestAndroidStateMatch(option);
1774 QRect r(option->rect);
1775 double factor =
double(styleOption->sliderPosition - styleOption->minimum)
1776 / (styleOption->maximum - styleOption->minimum);
1777 if (styleOption->orientation == Qt::Vertical) {
1778 int pos = option->rect.height() * (1 - factor) -
double(drawable->size().height() / 2);
1779 r.setY(r.y() + pos);
1781 int pos = option->rect.width() * factor -
double(drawable->size().width() / 2);
1782 r.setX(r.x() + pos);
1784 r.setSize(drawable->size());
1787 return option->rect;