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());
833void QAndroidStyle::Android9PatchDrawable::draw(QPainter *painter,
const QStyleOption *opt)
const
835 if (m_hashKey.isEmpty())
836 m_hashKey = QFileInfo(m_filePath).fileName();
839 if (!QPixmapCache::find(m_hashKey, &pixmap)) {
840 pixmap.load(m_filePath);
841 QPixmapCache::insert(m_hashKey, pixmap);
844 const QRect &bounds = opt->rect;
847 const int pixmapWidth = pixmap.width();
848 const int pixmapHeight = pixmap.height();
850 if (bounds.isNull() || !pixmapWidth || !pixmapHeight)
853 QPainter::RenderHints savedHints = painter->renderHints();
856 painter->setRenderHints(QPainter::SmoothPixmapTransform,
false);
861 const qint32 x0 = m_chunkData.xDivs[0];
862 const qint32 y0 = m_chunkData.yDivs[0];
863 const quint8 numXDivs = m_chunkData.xDivs.size();
864 const quint8 numYDivs = m_chunkData.yDivs.size();
870 const bool initialXIsStretchable = (x0 == 0);
871 bool yIsStretchable = (y0 == 0);
872 const int bitmapWidth = pixmap.width();
873 const int bitmapHeight = pixmap.height();
875 int *dstRights =
static_cast<
int *>(alloca((numXDivs + 1) *
sizeof(
int)));
876 bool dstRightsHaveBeenCached =
false;
878 int numStretchyXPixelsRemaining = 0;
879 for (i = 0; i < numXDivs; i += 2)
880 numStretchyXPixelsRemaining += m_chunkData.xDivs[i + 1] - m_chunkData.xDivs[i];
882 int numFixedXPixelsRemaining = bitmapWidth - numStretchyXPixelsRemaining;
883 int numStretchyYPixelsRemaining = 0;
884 for (i = 0; i < numYDivs; i += 2)
885 numStretchyYPixelsRemaining += m_chunkData.yDivs[i + 1] - m_chunkData.yDivs[i];
887 int numFixedYPixelsRemaining = bitmapHeight - numStretchyYPixelsRemaining;
889 dst.setTop(bounds.top());
906 for (j = yIsStretchable ? 1 : 0;
907 j <= numYDivs && src.top() < bitmapHeight;
908 j++, yIsStretchable = !yIsStretchable) {
910 dst.setLeft(bounds.left());
912 src.setBottom(bitmapHeight);
913 dst.setBottom(bounds.bottom());
915 src.setBottom(m_chunkData.yDivs[j]);
916 const int srcYSize = src.bottom() - src.top();
917 if (yIsStretchable) {
918 dst.setBottom(dst.top() + calculateStretch(bounds.bottom(), dst.top(),
920 numStretchyYPixelsRemaining,
921 numFixedYPixelsRemaining));
922 numStretchyYPixelsRemaining -= srcYSize;
924 dst.setBottom(dst.top() + srcYSize);
925 numFixedYPixelsRemaining -= srcYSize;
929 xIsStretchable = initialXIsStretchable;
932 for (i = xIsStretchable ? 1 : 0;
933 i <= numXDivs && src.left() < bitmapWidth;
934 i++, xIsStretchable = !xIsStretchable) {
935 color = m_chunkData.colors[colorIndex++];
936 if (color != TRANSPARENT_COLOR)
939 src.setRight(bitmapWidth);
940 dst.setRight(bounds.right());
942 src.setRight(m_chunkData.xDivs[i]);
943 if (dstRightsHaveBeenCached) {
944 dst.setRight(dstRights[i]);
946 const int srcXSize = src.right() - src.left();
947 if (xIsStretchable) {
948 dst.setRight(dst.left() + calculateStretch(bounds.right(), dst.left(),
950 numStretchyXPixelsRemaining,
951 numFixedXPixelsRemaining));
952 numStretchyXPixelsRemaining -= srcXSize;
954 dst.setRight(dst.left() + srcXSize);
955 numFixedXPixelsRemaining -= srcXSize;
957 dstRights[i] = dst.right();
963 if (src.left() >= src.right()) {
964 src.setLeft(src.right());
968 if (dst.right() <= dst.left() || dst.bottom() <= dst.top()) {
972 if (color == TRANSPARENT_COLOR)
974 if (color != NO_COLOR)
975 painter->fillRect(dst, QRgb(color));
977 painter->drawPixmap(dst, pixmap, src);
979 src.setLeft(src.right());
980 dst.setLeft(dst.right());
982 src.setTop(src.bottom());
983 dst.setTop(dst.bottom());
984 dstRightsHaveBeenCached =
true;
986 painter->setRenderHints(savedHints);
989QAndroidStyle::AndroidGradientDrawable::AndroidGradientDrawable(
const QVariantMap &drawable,
990 QAndroidStyle::ItemType itemType)
991 : AndroidDrawable(drawable, itemType), m_orientation(TOP_BOTTOM)
993 m_radius = drawable.value(QLatin1String(
"radius")).toInt();
997 QVariantList colors = drawable.value(QLatin1String(
"colors")).toList();
998 QVariantList positions = drawable.value(QLatin1String(
"positions")).toList();
999 int min = colors.size() < positions.size() ? colors.size() : positions.size();
1000 for (
int i = 0; i < min; i++)
1001 m_gradient.setColorAt(positions.at(i).toDouble(), QRgb(colors.at(i).toInt()));
1003 QByteArray orientation = drawable.value(QLatin1String(
"orientation")).toByteArray();
1004 if (orientation ==
"TOP_BOTTOM")
1005 m_orientation = TOP_BOTTOM;
1006 else if (orientation ==
"TR_BL")
1007 m_orientation = TR_BL;
1008 else if (orientation ==
"RIGHT_LEFT")
1009 m_orientation = RIGHT_LEFT;
1010 else if (orientation ==
"BR_TL")
1011 m_orientation = BR_TL;
1012 else if (orientation ==
"BOTTOM_TOP")
1013 m_orientation = BOTTOM_TOP;
1014 else if (orientation ==
"BL_TR")
1015 m_orientation = BL_TR;
1016 else if (orientation ==
"LEFT_RIGHT")
1017 m_orientation = LEFT_RIGHT;
1018 else if (orientation ==
"TL_BR")
1019 m_orientation = TL_BR;
1021 qWarning(
"AndroidGradientDrawable: unknown orientation");
1029void QAndroidStyle::AndroidGradientDrawable::draw(QPainter *painter,
const QStyleOption *opt)
const
1031 const int width = opt->rect.width();
1032 const int height = opt->rect.height();
1033 switch (m_orientation) {
1036 m_gradient.setStart(width / 2, 0);
1037 m_gradient.setFinalStop(width / 2, height);
1041 m_gradient.setStart(width, 0);
1042 m_gradient.setFinalStop(0, height);
1046 m_gradient.setStart(width, height / 2);
1047 m_gradient.setFinalStop(0, height / 2);
1051 m_gradient.setStart(width, height);
1052 m_gradient.setFinalStop(0, 0);
1056 m_gradient.setStart(width / 2, height);
1057 m_gradient.setFinalStop(width / 2, 0);
1061 m_gradient.setStart(0, height);
1062 m_gradient.setFinalStop(width, 0);
1066 m_gradient.setStart(0, height / 2);
1067 m_gradient.setFinalStop(width, height / 2);
1071 m_gradient.setStart(0, 0);
1072 m_gradient.setFinalStop(width, height);
1076 const QBrush &oldBrush = painter->brush();
1077 const QPen oldPen = painter->pen();
1078 painter->setPen(Qt::NoPen);
1079 painter->setBrush(m_gradient);
1080 painter->drawRoundedRect(opt->rect, m_radius, m_radius);
1081 painter->setBrush(oldBrush);
1082 painter->setPen(oldPen);
1172const QAndroidStyle::AndroidDrawable * QAndroidStyle::AndroidStateDrawable::bestAndroidStateMatch(
const QStyleOption *opt)
const
1174 const AndroidDrawable *bestMatch =
nullptr;
1176 if (m_states.size())
1177 return m_states[0].second;
1181 uint bestCost = 0xffff;
1182 for (
const StateType & state : m_states) {
1183 if (
int(opt->state) == state.first)
1184 return state.second;
1187 int difference =
int(opt->state^state.first);
1189 if (difference & QStyle::State_Active)
1192 if (difference & QStyle::State_Enabled)
1195 if (difference & QStyle::State_Raised)
1198 if (difference & QStyle::State_Sunken)
1201 if (difference & QStyle::State_Off)
1204 if (difference & QStyle::State_On)
1207 if (difference & QStyle::State_HasFocus)
1210 if (difference & QStyle::State_Selected)
1213 if (cost < bestCost) {
1215 bestMatch = state.second;
1221int QAndroidStyle::AndroidStateDrawable::extractState(
const QVariantMap &value)
1223 QStyle::State state = QStyle::State_Enabled | QStyle::State_Active;
1224 for (
auto it = value.cbegin(), end = value.cend(); it != end; ++it) {
1225 const QString &key = it.key();
1226 bool val = it.value().toString() == QLatin1String(
"true");
1227 if (key == QLatin1String(
"enabled")) {
1228 state.setFlag(QStyle::State_Enabled, val);
1232 if (key == QLatin1String(
"window_focused")) {
1233 state.setFlag(QStyle::State_Active, val);
1237 if (key == QLatin1String(
"focused")) {
1238 state.setFlag(QStyle::State_HasFocus, val);
1242 if (key == QLatin1String(
"checked")) {
1243 state |= val ? QStyle::State_On : QStyle::State_Off;
1247 if (key == QLatin1String(
"pressed")) {
1248 state |= val ? QStyle::State_Sunken : QStyle::State_Raised;
1252 if (key == QLatin1String(
"selected")) {
1253 state.setFlag(QStyle::State_Selected, val);
1257 if (key == QLatin1String(
"active")) {
1258 state.setFlag(QStyle::State_Active, val);
1262 if (key == QLatin1String(
"multiline"))
1265 if (key == QLatin1String(
"background") && val)
1268 return static_cast<
int>(state);
1379void QAndroidStyle::AndroidControl::drawControl(
const QStyleOption *opt, QPainter *p,
const QWidget * )
1382 m_background->draw(p, opt);
1384 if (
const QStyleOptionFrame *frame = qstyleoption_cast<
const QStyleOptionFrame *>(opt)) {
1385 if ((frame->state & State_Sunken) || (frame->state & State_Raised)) {
1386 qDrawShadePanel(p, frame->rect, frame->palette, frame->state & State_Sunken,
1389 qDrawPlainRect(p, frame->rect, frame->palette.windowText().color(), frame->lineWidth);
1392 if (
const QStyleOptionFocusRect *fropt = qstyleoption_cast<
const QStyleOptionFocusRect *>(opt)) {
1393 QColor bg = fropt->backgroundColor;
1394 QPen oldPen = p->pen();
1397 bg.getHsv(&h, &s, &v);
1399 p->setPen(Qt::black);
1401 p->setPen(Qt::white);
1403 p->setPen(opt->palette.windowText().color());
1405 QRect focusRect = opt->rect.adjusted(1, 1, -1, -1);
1406 p->drawRect(focusRect.adjusted(0, 0, -1, -1));
1409 p->fillRect(opt->rect, opt->palette.window());
1415QRect QAndroidStyle::AndroidControl::subElementRect(QStyle::SubElement ,
1416 const QStyleOption *option,
1417 const QWidget * )
const
1419 if (
const AndroidDrawable *drawable = backgroundDrawable()) {
1420 if (drawable->type() == State)
1421 drawable =
static_cast<
const AndroidStateDrawable *>(backgroundDrawable())->bestAndroidStateMatch(option);
1423 const QMargins &padding = drawable->padding();
1425 QRect r = option->rect.adjusted(padding.left(), padding.top(),
1426 -padding.right(), -padding.bottom());
1428 if (r.width() < m_minSize.width())
1429 r.setWidth(m_minSize.width());
1431 if (r.height() < m_minSize.height())
1432 r.setHeight(m_minSize.height());
1434 return visualRect(option->direction, option->rect, r);
1436 return option->rect;
1446QSize QAndroidStyle::AndroidControl::sizeFromContents(
const QStyleOption *opt,
1447 const QSize &contentsSize,
1448 const QWidget * )
const
1451 if (
const AndroidDrawable *drawable = backgroundDrawable()) {
1453 if (drawable->type() == State)
1454 drawable =
static_cast<
const AndroidStateDrawable*>(backgroundDrawable())->bestAndroidStateMatch(opt);
1455 const QMargins &padding = drawable->padding();
1456 sz.setWidth(padding.left() + padding.right());
1457 sz.setHeight(padding.top() + padding.bottom());
1459 sz = drawable->size();
1462 if (contentsSize.height() < opt->fontMetrics.height())
1463 sz.setHeight(sz.height() + (opt->fontMetrics.height() - contentsSize.height()));
1464 if (sz.height() < m_minSize.height())
1465 sz.setHeight(m_minSize.height());
1466 if (sz.width() < m_minSize.width())
1467 sz.setWidth(m_minSize.width());
1545QAndroidStyle::AndroidProgressBarControl::AndroidProgressBarControl(
const QVariantMap &control,
1547 : AndroidControl(control, itemType)
1549 QVariantMap::const_iterator it = control.find(QLatin1String(
"ProgressBar_indeterminateDrawable"));
1550 if (it != control.end())
1551 m_indeterminateDrawable = AndroidDrawable::fromMap(it.value().toMap(), itemType);
1553 m_indeterminateDrawable = 0;
1555 it = control.find(QLatin1String(
"ProgressBar_progressDrawable"));
1556 if (it != control.end())
1557 m_progressDrawable = AndroidDrawable::fromMap(it.value().toMap(), itemType);
1559 m_progressDrawable = 0;
1561 it = control.find(QLatin1String(
"ProgressBar_progress_id"));
1562 if (it != control.end())
1563 m_progressId = it.value().toInt();
1565 it = control.find(QLatin1String(
"ProgressBar_secondaryProgress_id"));
1566 if (it != control.end())
1567 m_secondaryProgress_id = it.value().toInt();
1569 it = control.find(QLatin1String(
"ProgressBar_minWidth"));
1570 if (it != control.end())
1571 m_minSize.setWidth(it.value().toInt());
1573 it = control.find(QLatin1String(
"ProgressBar_minHeight"));
1574 if (it != control.end())
1575 m_minSize.setHeight(it.value().toInt());
1577 it = control.find(QLatin1String(
"ProgressBar_maxWidth"));
1578 if (it != control.end())
1579 m_maxSize.setWidth(it.value().toInt());
1581 it = control.find(QLatin1String(
"ProgressBar_maxHeight"));
1582 if (it != control.end())
1583 m_maxSize.setHeight(it.value().toInt());
1592void QAndroidStyle::AndroidProgressBarControl::drawControl(
const QStyleOption *option, QPainter *p,
const QWidget * )
1594 if (!m_progressDrawable)
1597 if (
const QStyleOptionProgressBar *pb = qstyleoption_cast<
const QStyleOptionProgressBar *>(option)) {
1598 if (m_progressDrawable->type() == QAndroidStyle::Layer) {
1599 const double fraction =
double(qint64(pb->progress) - pb->minimum) / (qint64(pb->maximum) - pb->minimum);
1600 QAndroidStyle::AndroidDrawable *clipDrawable =
static_cast<QAndroidStyle::AndroidLayerDrawable *>(m_progressDrawable)->layer(m_progressId);
1601 const Qt::Orientation orientation = pb->state & QStyle::State_Horizontal ? Qt::Horizontal : Qt::Vertical;
1602 if (clipDrawable->type() == QAndroidStyle::Clip)
1603 static_cast<AndroidClipDrawable *>(clipDrawable)->setFactor(fraction, orientation);
1605 static_cast<AndroidLayerDrawable *>(m_progressDrawable)->setFactor(m_progressId, fraction, orientation);
1607 m_progressDrawable->draw(p, option);
1611QRect QAndroidStyle::AndroidProgressBarControl::subElementRect(QStyle::SubElement subElement,
1612 const QStyleOption *option,
1613 const QWidget *widget)
const
1615 if (
const QStyleOptionProgressBar *progressBarOption =
1616 qstyleoption_cast<
const QStyleOptionProgressBar *>(option)) {
1617 const bool horizontal = progressBarOption->state & QStyle::State_Horizontal;
1619 return option->rect;
1621 QMargins padding = m_background->padding();
1622 QRect p(padding.left(), padding.top(), padding.right() - padding.left(), padding.bottom() - padding.top());
1623 padding = m_indeterminateDrawable->padding();
1624 p |= QRect(padding.left(), padding.top(), padding.right() - padding.left(), padding.bottom() - padding.top());
1625 padding = m_progressDrawable->padding();
1626 p |= QRect(padding.left(), padding.top(), padding.right() - padding.left(), padding.bottom() - padding.top());
1627 QRect r = option->rect.adjusted(p.left(), p.top(), -p.right(), -p.bottom());
1630 if (r.height()<m_minSize.height())
1631 r.setHeight(m_minSize.height());
1633 if (r.height()>m_maxSize.height())
1634 r.setHeight(m_maxSize.height());
1636 if (r.width()<m_minSize.width())
1637 r.setWidth(m_minSize.width());
1639 if (r.width()>m_maxSize.width())
1640 r.setWidth(m_maxSize.width());
1642 return visualRect(option->direction, option->rect, r);
1644 return AndroidControl::subElementRect(subElement, option, widget);
1686void QAndroidStyle::AndroidSeekBarControl::drawControl(
const QStyleOption *option,
1690 if (!m_seekBarThumb || !m_progressDrawable)
1693 if (
const QStyleOptionSlider *styleOption =
1694 qstyleoption_cast<
const QStyleOptionSlider *>(option)) {
1695 double factor =
double(styleOption->sliderPosition - styleOption->minimum)
1696 /
double(styleOption->maximum - styleOption->minimum);
1700 if (styleOption->orientation == Qt::Vertical)
1701 factor = 1 - factor;
1703 if (m_progressDrawable->type() == QAndroidStyle::Layer) {
1704 QAndroidStyle::AndroidDrawable *clipDrawable =
static_cast<QAndroidStyle::AndroidLayerDrawable *>(m_progressDrawable)->layer(m_progressId);
1705 if (clipDrawable->type() == QAndroidStyle::Clip)
1706 static_cast<QAndroidStyle::AndroidClipDrawable *>(clipDrawable)->setFactor(factor, Qt::Horizontal);
1708 static_cast<QAndroidStyle::AndroidLayerDrawable *>(m_progressDrawable)->setFactor(m_progressId, factor, Qt::Horizontal);
1710 const AndroidDrawable *drawable = m_seekBarThumb;
1711 if (drawable->type() == State)
1712 drawable =
static_cast<
const QAndroidStyle::AndroidStateDrawable *>(m_seekBarThumb)->bestAndroidStateMatch(option);
1713 QStyleOption copy(*option);
1717 if (styleOption->orientation == Qt::Vertical) {
1720 copy.rect = QRect(copy.rect.y(), copy.rect.x() - copy.rect.width(), copy.rect.height(), copy.rect.width());
1723 copy.rect.setHeight(m_progressDrawable->size().height());
1724 copy.rect.setWidth(copy.rect.width() - drawable->size().width());
1725 const int yTranslate = abs(drawable->size().height() - copy.rect.height()) / 2;
1726 copy.rect.translate(drawable->size().width() / 2, yTranslate);
1727 m_progressDrawable->draw(p, ©);
1728 int pos = copy.rect.width() * factor - drawable->size().width() / 2;
1729 copy.rect.translate(pos, -yTranslate);
1730 copy.rect.setSize(drawable->size());
1731 m_seekBarThumb->draw(p, ©);
1750QRect QAndroidStyle::AndroidSeekBarControl::subControlRect(
const QStyleOptionComplex *option,
1752 const QWidget * )
const
1754 const QStyleOptionSlider *styleOption =
1755 qstyleoption_cast<
const QStyleOptionSlider *>(option);
1757 if (m_seekBarThumb && sc == SC_SliderHandle && styleOption) {
1758 const AndroidDrawable *drawable = m_seekBarThumb;
1759 if (drawable->type() == State)
1760 drawable =
static_cast<
const QAndroidStyle::AndroidStateDrawable *>(m_seekBarThumb)->bestAndroidStateMatch(option);
1762 QRect r(option->rect);
1763 double factor =
double(styleOption->sliderPosition - styleOption->minimum)
1764 / (styleOption->maximum - styleOption->minimum);
1765 if (styleOption->orientation == Qt::Vertical) {
1766 int pos = option->rect.height() * (1 - factor) -
double(drawable->size().height() / 2);
1767 r.setY(r.y() + pos);
1769 int pos = option->rect.width() * factor -
double(drawable->size().width() / 2);
1770 r.setX(r.x() + pos);
1772 r.setSize(drawable->size());
1775 return option->rect;