30QAndroidStyle::QAndroidStyle()
33 QPixmapCache::clear();
34 checkBoxControl = NULL;
35 QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
36 QPalette *standardPalette =
reinterpret_cast<QPalette *>(nativeInterface->nativeResourceForIntegration(
"AndroidStandardPalette"));
38 m_standardPalette = *standardPalette;
40 QHash<QByteArray, QFont> *qwidgetsFonts =
reinterpret_cast<QHash<QByteArray, QFont> *>(nativeInterface->nativeResourceForIntegration(
"AndroidQWidgetFonts"));
42 for (
auto it = qwidgetsFonts->constBegin(); it != qwidgetsFonts->constEnd(); ++it)
43 QApplication::setFont(it.value(), it.key());
44 qwidgetsFonts->clear();
47 QJsonObject *object =
reinterpret_cast<QJsonObject *>(nativeInterface->nativeResourceForIntegration(
"AndroidStyleData"));
51 for (QJsonObject::const_iterator objectIterator = object->constBegin();
52 objectIterator != object->constEnd();
54 QString key = objectIterator.key();
55 QJsonValue value = objectIterator.value();
56 if (Q_UNLIKELY(!value.isObject())) {
57 qWarning(
"Style.json structure is unrecognized.");
61 QJsonObject item = value.toObject();
62 QAndroidStyle::ItemType itemType = qtControl(key);
63 if (QC_UnknownType == itemType)
68 checkBoxControl =
new AndroidCompoundButtonControl(item.toVariantMap(), itemType);
69 m_androidControlsHash[
int(itemType)] = checkBoxControl;
72 m_androidControlsHash[
int(itemType)] =
new AndroidCompoundButtonControl(item.toVariantMap(),
77 m_androidControlsHash[
int(itemType)] =
new AndroidProgressBarControl(item.toVariantMap(),
82 m_androidControlsHash[
int(itemType)] =
new AndroidSeekBarControl(item.toVariantMap(),
87 m_androidControlsHash[
int(itemType)] =
new AndroidSpinnerControl(item.toVariantMap(),
92 m_androidControlsHash[
int(itemType)] =
new AndroidControl(item.toVariantMap(),
97 *object = QJsonObject();
251void QAndroidStyle::drawPrimitive(PrimitiveElement pe,
252 const QStyleOption *opt,
254 const QWidget *w)
const
256 const ItemType itemType = qtControl(pe);
257 AndroidControlsHash::const_iterator it = itemType != QC_UnknownType
258 ? m_androidControlsHash.find(itemType)
259 : m_androidControlsHash.end();
260 if (it != m_androidControlsHash.end()) {
261 if (itemType != QC_EditText) {
262 it.value()->drawControl(opt, p, w);
264 QStyleOption copy(*opt);
265 copy.state &= ~QStyle::State_Sunken;
266 it.value()->drawControl(©, p, w);
268 }
else if (pe == PE_FrameGroupBox) {
269 if (
const QStyleOptionFrame *frame = qstyleoption_cast<
const QStyleOptionFrame *>(opt)) {
270 if (frame->features & QStyleOptionFrame::Flat) {
271 QRect fr = frame->rect;
272 QPoint p1(fr.x(), fr.y() + 1);
273 QPoint p2(fr.x() + fr.width(), p1.y());
274 qDrawShadeLine(p, p1, p2, frame->palette,
true,
275 frame->lineWidth, frame->midLineWidth);
277 qDrawShadeRect(p, frame->rect.x(), frame->rect.y(), frame->rect.width(),
278 frame->rect.height(), frame->palette,
true,
279 frame->lineWidth, frame->midLineWidth);
283 QFusionStyle::drawPrimitive(pe, opt, p, w);
288void QAndroidStyle::drawControl(QStyle::ControlElement element,
289 const QStyleOption *opt,
291 const QWidget *w)
const
293 const ItemType itemType = qtControl(element);
294 AndroidControlsHash::const_iterator it = itemType != QC_UnknownType
295 ? m_androidControlsHash.find(itemType)
296 : m_androidControlsHash.end();
297 if (it != m_androidControlsHash.end()) {
298 AndroidControl *androidControl = it.value();
300 if (element != QStyle::CE_CheckBoxLabel
301 && element != QStyle::CE_PushButtonLabel
302 && element != QStyle::CE_RadioButtonLabel
303 && element != QStyle::CE_TabBarTabLabel
304 && element != QStyle::CE_ProgressBarLabel) {
305 androidControl->drawControl(opt, p, w);
308 if (element != QStyle::CE_PushButtonBevel
309 && element != QStyle::CE_TabBarTabShape
310 && element != QStyle::CE_ProgressBarGroove) {
313 if (
const QStyleOptionButton *buttonOption =
314 qstyleoption_cast<
const QStyleOptionButton *>(opt)) {
315 QMargins padding = androidControl->padding();
316 QStyleOptionButton copy(*buttonOption);
317 copy.rect.adjust(padding.left(), padding.top(), -padding.right(), -padding.bottom());
318 QFusionStyle::drawControl(CE_PushButtonLabel, ©, p, w);
323 if (
const QStyleOptionButton *btn =
324 qstyleoption_cast<
const QStyleOptionButton *>(opt)) {
325 const bool isRadio = (element == CE_RadioButton);
326 QStyleOptionButton subopt(*btn);
327 subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents
328 : SE_CheckBoxContents, btn, w);
329 QFusionStyle::drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, p, w);
333 if (
const QStyleOptionComboBox *comboboxOption =
334 qstyleoption_cast<
const QStyleOptionComboBox *>(opt)) {
335 QMargins padding = androidControl->padding();
336 QStyleOptionComboBox copy (*comboboxOption);
337 copy.rect.adjust(padding.left(), padding.top(), -padding.right(), -padding.bottom());
338 QFusionStyle::drawControl(CE_ComboBoxLabel, comboboxOption, p, w);
342 QFusionStyle::drawControl(element, opt, p, w);
347 QFusionStyle::drawControl(element, opt, p, w);
364void QAndroidStyle::drawComplexControl(ComplexControl cc,
365 const QStyleOptionComplex *opt,
367 const QWidget *widget)
const
369 const ItemType itemType = qtControl(cc);
370 AndroidControlsHash::const_iterator it = itemType != QC_UnknownType
371 ? m_androidControlsHash.find(itemType)
372 : m_androidControlsHash.end();
373 if (it != m_androidControlsHash.end()) {
374 it.value()->drawControl(opt, p, widget);
377 if (cc == CC_GroupBox) {
378 if (
const QStyleOptionGroupBox *groupBox = qstyleoption_cast<
const QStyleOptionGroupBox *>(opt)) {
380 QRect textRect = subControlRect(CC_GroupBox, opt, SC_GroupBoxLabel, widget);
382 if (groupBox->subControls & SC_GroupBoxCheckBox)
383 checkBoxRect = subControlRect(CC_GroupBox, opt, SC_GroupBoxCheckBox, widget);
384 if (groupBox->subControls & QStyle::SC_GroupBoxFrame) {
385 QStyleOptionFrame frame;
386 frame.QStyleOption::operator=(*groupBox);
387 frame.features = groupBox->features;
388 frame.lineWidth = groupBox->lineWidth;
389 frame.midLineWidth = groupBox->midLineWidth;
390 frame.rect = subControlRect(CC_GroupBox, opt, SC_GroupBoxFrame, widget);
392 QRegion region(groupBox->rect);
393 if (!groupBox->text.isEmpty()) {
394 bool ltr = groupBox->direction == Qt::LeftToRight;
396 if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox) {
397 finalRect = checkBoxRect.united(textRect);
398 finalRect.adjust(ltr ? -4 : 0, 0, ltr ? 0 : 4, 0);
400 finalRect = textRect;
404 p->setClipRegion(region);
405 drawPrimitive(PE_FrameGroupBox, &frame, p, widget);
410 if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
411 QColor textColor = groupBox->textColor;
412 if (textColor.isValid())
413 p->setPen(textColor);
414 int alignment =
int(groupBox->textAlignment);
415 if (!styleHint(QStyle::SH_UnderlineShortcut, opt, widget))
416 alignment |= Qt::TextHideMnemonic;
418 drawItemText(p, textRect, Qt::TextShowMnemonic | Qt::AlignHCenter | alignment,
419 groupBox->palette, groupBox->state & State_Enabled, groupBox->text,
420 textColor.isValid() ? QPalette::NoRole : QPalette::WindowText);
422 if (groupBox->state & State_HasFocus) {
423 QStyleOptionFocusRect fropt;
424 fropt.QStyleOption::operator=(*groupBox);
425 fropt.rect = textRect;
426 drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
431 if (groupBox->subControls & SC_GroupBoxCheckBox) {
432 QStyleOptionButton box;
433 box.QStyleOption::operator=(*groupBox);
434 box.rect = checkBoxRect;
435 checkBoxControl->drawControl(&box, p, widget);
440 QFusionStyle::drawComplexControl(cc, opt, p, widget);
443QStyle::SubControl QAndroidStyle::hitTestComplexControl(ComplexControl cc,
444 const QStyleOptionComplex *opt,
446 const QWidget *widget)
const
448 const ItemType itemType = qtControl(cc);
449 AndroidControlsHash::const_iterator it = itemType != QC_UnknownType
450 ? m_androidControlsHash.find(itemType)
451 : m_androidControlsHash.end();
452 if (it != m_androidControlsHash.end()) {
455 if (
const QStyleOptionSlider *slider = qstyleoption_cast<
const QStyleOptionSlider *>(opt)) {
456 QRect r = it.value()->subControlRect(slider, SC_SliderHandle, widget);
457 if (r.isValid() && r.contains(pt)) {
458 return SC_SliderHandle;
460 r = it.value()->subControlRect(slider, SC_SliderGroove, widget);
461 if (r.isValid() && r.contains(pt))
462 return SC_SliderGroove;
470 return QFusionStyle::hitTestComplexControl(cc, opt, pt, widget);
473QRect QAndroidStyle::subControlRect(ComplexControl cc,
474 const QStyleOptionComplex *opt,
476 const QWidget *widget)
const
478 const ItemType itemType = qtControl(cc);
479 AndroidControlsHash::const_iterator it = itemType != QC_UnknownType
480 ? m_androidControlsHash.find(itemType)
481 : m_androidControlsHash.end();
482 if (it != m_androidControlsHash.end())
483 return it.value()->subControlRect(opt, sc, widget);
484 QRect rect = opt->rect;
487 if (
const QStyleOptionGroupBox *groupBox = qstyleoption_cast<
const QStyleOptionGroupBox *>(opt)) {
488 QSize textSize = opt->fontMetrics.boundingRect(groupBox->text).size() + QSize(2, 2);
489 QSize checkBoxSize = checkBoxControl->size(opt);
490 int indicatorWidth = checkBoxSize.width();
491 int indicatorHeight = checkBoxSize.height();
493 if (opt->subControls & QStyle::SC_GroupBoxCheckBox) {
494 checkBoxRect.setWidth(indicatorWidth);
495 checkBoxRect.setHeight(indicatorHeight);
497 checkBoxRect.moveLeft(1);
498 QRect textRect = checkBoxRect;
499 textRect.setSize(textSize);
500 if (opt->subControls & QStyle::SC_GroupBoxCheckBox)
501 textRect.translate(indicatorWidth + 5, (indicatorHeight - textSize.height()) / 2);
502 if (sc == SC_GroupBoxFrame) {
503 rect = opt->rect.adjusted(0, 0, 0, 0);
504 rect.translate(0, textRect.height() / 2);
505 rect.setHeight(rect.height() - textRect.height() / 2);
506 }
else if (sc == SC_GroupBoxContents) {
507 QRect frameRect = opt->rect.adjusted(0, 0, 0, -groupBox->lineWidth);
509 int leftMarginExtension = 0;
510 int topMargin = qMax(pixelMetric(PM_ExclusiveIndicatorHeight), opt->fontMetrics.height()) + groupBox->lineWidth;
511 frameRect.adjust(leftMarginExtension + margin, margin + topMargin, -margin, -margin - groupBox->lineWidth);
512 frameRect.translate(0, textRect.height() / 2);
514 rect.setHeight(rect.height() - textRect.height() / 2);
515 }
else if (sc == SC_GroupBoxCheckBox) {
517 }
else if (sc == SC_GroupBoxLabel) {
520 return visualRect(opt->direction, opt->rect, rect);
531 return QFusionStyle::subControlRect(cc, opt, sc, widget);
555QSize QAndroidStyle::sizeFromContents(ContentsType ct,
556 const QStyleOption *opt,
557 const QSize &contentsSize,
558 const QWidget *w)
const
560 QSize sz = QFusionStyle::sizeFromContents(ct, opt, contentsSize, w);
561 if (ct == CT_HeaderSection) {
562 if (
const QStyleOptionHeader *hdr = qstyleoption_cast<
const QStyleOptionHeader *>(opt)) {
563 bool nullIcon = hdr->icon.isNull();
564 int margin = pixelMetric(QStyle::PM_HeaderMargin, hdr, w);
565 int iconSize = nullIcon ? 0 : checkBoxControl->size(opt).width();
568
569
570
571
572 if (qApp->styleSheet().isEmpty())
573 txt = hdr->fontMetrics.size(0, hdr->text);
575 txt = QFontMetrics(QApplication::font()).size(0, hdr->text);
577 sz.setHeight(margin + qMax(iconSize, txt.height()) + margin);
578 sz.setWidth((nullIcon ? 0 : margin) + iconSize
579 + (hdr->text.isNull() ? 0 : margin) + txt.width() + margin);
580 if (hdr->sortIndicator != QStyleOptionHeader::None) {
581 int margin = pixelMetric(QStyle::PM_HeaderMargin, hdr, w);
582 if (hdr->orientation == Qt::Horizontal)
583 sz.rwidth() += sz.height() + margin;
585 sz.rheight() += sz.width() + margin;
590 const ItemType itemType = qtControl(ct);
591 AndroidControlsHash::const_iterator it = itemType != QC_UnknownType
592 ? m_androidControlsHash.find(itemType)
593 : m_androidControlsHash.end();
594 if (it != m_androidControlsHash.end())
595 return it.value()->sizeFromContents(opt, sz, w);
596 if (ct == CT_GroupBox) {
597 if (
const QStyleOptionGroupBox *groupBox = qstyleoption_cast<
const QStyleOptionGroupBox *>(opt)) {
598 QSize textSize = opt->fontMetrics.boundingRect(groupBox->text).size() + QSize(2, 2);
599 QSize checkBoxSize = checkBoxControl->size(opt);
600 int indicatorWidth = checkBoxSize.width();
601 int indicatorHeight = checkBoxSize.height();
603 if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox) {
604 checkBoxRect.setWidth(indicatorWidth);
605 checkBoxRect.setHeight(indicatorHeight);
607 checkBoxRect.moveLeft(1);
608 QRect textRect = checkBoxRect;
609 textRect.setSize(textSize);
610 if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox)
611 textRect.translate(indicatorWidth + 5, (indicatorHeight - textSize.height()) / 2);
612 QRect u = textRect.united(checkBoxRect);
613 sz = QSize(sz.width(), sz.height() + u.height());
823void QAndroidStyle::Android9PatchDrawable::draw(QPainter *painter,
const QStyleOption *opt)
const
825 if (m_hashKey.isEmpty())
826 m_hashKey = QFileInfo(m_filePath).fileName();
829 if (!QPixmapCache::find(m_hashKey, &pixmap)) {
830 pixmap.load(m_filePath);
831 QPixmapCache::insert(m_hashKey, pixmap);
834 const QRect &bounds = opt->rect;
837 const int pixmapWidth = pixmap.width();
838 const int pixmapHeight = pixmap.height();
840 if (bounds.isNull() || !pixmapWidth || !pixmapHeight)
843 QPainter::RenderHints savedHints = painter->renderHints();
846 painter->setRenderHints(QPainter::SmoothPixmapTransform,
false);
851 const qint32 x0 = m_chunkData.xDivs[0];
852 const qint32 y0 = m_chunkData.yDivs[0];
853 const quint8 numXDivs = m_chunkData.xDivs.size();
854 const quint8 numYDivs = m_chunkData.yDivs.size();
860 const bool initialXIsStretchable = (x0 == 0);
861 bool yIsStretchable = (y0 == 0);
862 const int bitmapWidth = pixmap.width();
863 const int bitmapHeight = pixmap.height();
865 int *dstRights =
static_cast<
int *>(alloca((numXDivs + 1) *
sizeof(
int)));
866 bool dstRightsHaveBeenCached =
false;
868 int numStretchyXPixelsRemaining = 0;
869 for (i = 0; i < numXDivs; i += 2)
870 numStretchyXPixelsRemaining += m_chunkData.xDivs[i + 1] - m_chunkData.xDivs[i];
872 int numFixedXPixelsRemaining = bitmapWidth - numStretchyXPixelsRemaining;
873 int numStretchyYPixelsRemaining = 0;
874 for (i = 0; i < numYDivs; i += 2)
875 numStretchyYPixelsRemaining += m_chunkData.yDivs[i + 1] - m_chunkData.yDivs[i];
877 int numFixedYPixelsRemaining = bitmapHeight - numStretchyYPixelsRemaining;
879 dst.setTop(bounds.top());
896 for (j = yIsStretchable ? 1 : 0;
897 j <= numYDivs && src.top() < bitmapHeight;
898 j++, yIsStretchable = !yIsStretchable) {
900 dst.setLeft(bounds.left());
902 src.setBottom(bitmapHeight);
903 dst.setBottom(bounds.bottom());
905 src.setBottom(m_chunkData.yDivs[j]);
906 const int srcYSize = src.bottom() - src.top();
907 if (yIsStretchable) {
908 dst.setBottom(dst.top() + calculateStretch(bounds.bottom(), dst.top(),
910 numStretchyYPixelsRemaining,
911 numFixedYPixelsRemaining));
912 numStretchyYPixelsRemaining -= srcYSize;
914 dst.setBottom(dst.top() + srcYSize);
915 numFixedYPixelsRemaining -= srcYSize;
919 xIsStretchable = initialXIsStretchable;
922 for (i = xIsStretchable ? 1 : 0;
923 i <= numXDivs && src.left() < bitmapWidth;
924 i++, xIsStretchable = !xIsStretchable) {
925 color = m_chunkData.colors[colorIndex++];
926 if (color != TRANSPARENT_COLOR)
929 src.setRight(bitmapWidth);
930 dst.setRight(bounds.right());
932 src.setRight(m_chunkData.xDivs[i]);
933 if (dstRightsHaveBeenCached) {
934 dst.setRight(dstRights[i]);
936 const int srcXSize = src.right() - src.left();
937 if (xIsStretchable) {
938 dst.setRight(dst.left() + calculateStretch(bounds.right(), dst.left(),
940 numStretchyXPixelsRemaining,
941 numFixedXPixelsRemaining));
942 numStretchyXPixelsRemaining -= srcXSize;
944 dst.setRight(dst.left() + srcXSize);
945 numFixedXPixelsRemaining -= srcXSize;
947 dstRights[i] = dst.right();
953 if (src.left() >= src.right()) {
954 src.setLeft(src.right());
958 if (dst.right() <= dst.left() || dst.bottom() <= dst.top()) {
962 if (color == TRANSPARENT_COLOR)
964 if (color != NO_COLOR)
965 painter->fillRect(dst, QRgb(color));
967 painter->drawPixmap(dst, pixmap, src);
969 src.setLeft(src.right());
970 dst.setLeft(dst.right());
972 src.setTop(src.bottom());
973 dst.setTop(dst.bottom());
974 dstRightsHaveBeenCached =
true;
976 painter->setRenderHints(savedHints);
979QAndroidStyle::AndroidGradientDrawable::AndroidGradientDrawable(
const QVariantMap &drawable,
980 QAndroidStyle::ItemType itemType)
981 : AndroidDrawable(drawable, itemType), m_orientation(TOP_BOTTOM)
983 m_radius = drawable.value(QLatin1String(
"radius")).toInt();
987 QVariantList colors = drawable.value(QLatin1String(
"colors")).toList();
988 QVariantList positions = drawable.value(QLatin1String(
"positions")).toList();
989 int min = colors.size() < positions.size() ? colors.size() : positions.size();
990 for (
int i = 0; i < min; i++)
991 m_gradient.setColorAt(positions.at(i).toDouble(), QRgb(colors.at(i).toInt()));
993 QByteArray orientation = drawable.value(QLatin1String(
"orientation")).toByteArray();
994 if (orientation ==
"TOP_BOTTOM")
995 m_orientation = TOP_BOTTOM;
996 else if (orientation ==
"TR_BL")
997 m_orientation = TR_BL;
998 else if (orientation ==
"RIGHT_LEFT")
999 m_orientation = RIGHT_LEFT;
1000 else if (orientation ==
"BR_TL")
1001 m_orientation = BR_TL;
1002 else if (orientation ==
"BOTTOM_TOP")
1003 m_orientation = BOTTOM_TOP;
1004 else if (orientation ==
"BL_TR")
1005 m_orientation = BL_TR;
1006 else if (orientation ==
"LEFT_RIGHT")
1007 m_orientation = LEFT_RIGHT;
1008 else if (orientation ==
"TL_BR")
1009 m_orientation = TL_BR;
1011 qWarning(
"AndroidGradientDrawable: unknown orientation");
1019void QAndroidStyle::AndroidGradientDrawable::draw(QPainter *painter,
const QStyleOption *opt)
const
1021 const int width = opt->rect.width();
1022 const int height = opt->rect.height();
1023 switch (m_orientation) {
1026 m_gradient.setStart(width / 2, 0);
1027 m_gradient.setFinalStop(width / 2, height);
1031 m_gradient.setStart(width, 0);
1032 m_gradient.setFinalStop(0, height);
1036 m_gradient.setStart(width, height / 2);
1037 m_gradient.setFinalStop(0, height / 2);
1041 m_gradient.setStart(width, height);
1042 m_gradient.setFinalStop(0, 0);
1046 m_gradient.setStart(width / 2, height);
1047 m_gradient.setFinalStop(width / 2, 0);
1051 m_gradient.setStart(0, height);
1052 m_gradient.setFinalStop(width, 0);
1056 m_gradient.setStart(0, height / 2);
1057 m_gradient.setFinalStop(width, height / 2);
1061 m_gradient.setStart(0, 0);
1062 m_gradient.setFinalStop(width, height);
1066 const QBrush &oldBrush = painter->brush();
1067 const QPen oldPen = painter->pen();
1068 painter->setPen(Qt::NoPen);
1069 painter->setBrush(m_gradient);
1070 painter->drawRoundedRect(opt->rect, m_radius, m_radius);
1071 painter->setBrush(oldBrush);
1072 painter->setPen(oldPen);
1162const QAndroidStyle::AndroidDrawable * QAndroidStyle::AndroidStateDrawable::bestAndroidStateMatch(
const QStyleOption *opt)
const
1164 const AndroidDrawable *bestMatch =
nullptr;
1166 if (m_states.size())
1167 return m_states[0].second;
1171 uint bestCost = 0xffff;
1172 for (
const StateType & state : m_states) {
1173 if (
int(opt->state) == state.first)
1174 return state.second;
1177 int difference =
int(opt->state^state.first);
1179 if (difference & QStyle::State_Active)
1182 if (difference & QStyle::State_Enabled)
1185 if (difference & QStyle::State_Raised)
1188 if (difference & QStyle::State_Sunken)
1191 if (difference & QStyle::State_Off)
1194 if (difference & QStyle::State_On)
1197 if (difference & QStyle::State_HasFocus)
1200 if (difference & QStyle::State_Selected)
1203 if (cost < bestCost) {
1205 bestMatch = state.second;
1211int QAndroidStyle::AndroidStateDrawable::extractState(
const QVariantMap &value)
1213 QStyle::State state = QStyle::State_Enabled | QStyle::State_Active;
1214 for (
auto it = value.cbegin(), end = value.cend(); it != end; ++it) {
1215 const QString &key = it.key();
1216 bool val = it.value().toString() == QLatin1String(
"true");
1217 if (key == QLatin1String(
"enabled")) {
1218 state.setFlag(QStyle::State_Enabled, val);
1222 if (key == QLatin1String(
"window_focused")) {
1223 state.setFlag(QStyle::State_Active, val);
1227 if (key == QLatin1String(
"focused")) {
1228 state.setFlag(QStyle::State_HasFocus, val);
1232 if (key == QLatin1String(
"checked")) {
1233 state |= val ? QStyle::State_On : QStyle::State_Off;
1237 if (key == QLatin1String(
"pressed")) {
1238 state |= val ? QStyle::State_Sunken : QStyle::State_Raised;
1242 if (key == QLatin1String(
"selected")) {
1243 state.setFlag(QStyle::State_Selected, val);
1247 if (key == QLatin1String(
"active")) {
1248 state.setFlag(QStyle::State_Active, val);
1252 if (key == QLatin1String(
"multiline"))
1255 if (key == QLatin1String(
"background") && val)
1258 return static_cast<
int>(state);
1369void QAndroidStyle::AndroidControl::drawControl(
const QStyleOption *opt, QPainter *p,
const QWidget * )
1372 m_background->draw(p, opt);
1374 if (
const QStyleOptionFrame *frame = qstyleoption_cast<
const QStyleOptionFrame *>(opt)) {
1375 if ((frame->state & State_Sunken) || (frame->state & State_Raised)) {
1376 qDrawShadePanel(p, frame->rect, frame->palette, frame->state & State_Sunken,
1379 qDrawPlainRect(p, frame->rect, frame->palette.windowText().color(), frame->lineWidth);
1382 if (
const QStyleOptionFocusRect *fropt = qstyleoption_cast<
const QStyleOptionFocusRect *>(opt)) {
1383 QColor bg = fropt->backgroundColor;
1384 QPen oldPen = p->pen();
1387 bg.getHsv(&h, &s, &v);
1389 p->setPen(Qt::black);
1391 p->setPen(Qt::white);
1393 p->setPen(opt->palette.windowText().color());
1395 QRect focusRect = opt->rect.adjusted(1, 1, -1, -1);
1396 p->drawRect(focusRect.adjusted(0, 0, -1, -1));
1399 p->fillRect(opt->rect, opt->palette.window());
1405QRect QAndroidStyle::AndroidControl::subElementRect(QStyle::SubElement ,
1406 const QStyleOption *option,
1407 const QWidget * )
const
1409 if (
const AndroidDrawable *drawable = backgroundDrawable()) {
1410 if (drawable->type() == State)
1411 drawable =
static_cast<
const AndroidStateDrawable *>(backgroundDrawable())->bestAndroidStateMatch(option);
1413 const QMargins &padding = drawable->padding();
1415 QRect r = option->rect.adjusted(padding.left(), padding.top(),
1416 -padding.right(), -padding.bottom());
1418 if (r.width() < m_minSize.width())
1419 r.setWidth(m_minSize.width());
1421 if (r.height() < m_minSize.height())
1422 r.setHeight(m_minSize.height());
1424 return visualRect(option->direction, option->rect, r);
1426 return option->rect;
1436QSize QAndroidStyle::AndroidControl::sizeFromContents(
const QStyleOption *opt,
1437 const QSize &contentsSize,
1438 const QWidget * )
const
1441 if (
const AndroidDrawable *drawable = backgroundDrawable()) {
1443 if (drawable->type() == State)
1444 drawable =
static_cast<
const AndroidStateDrawable*>(backgroundDrawable())->bestAndroidStateMatch(opt);
1445 const QMargins &padding = drawable->padding();
1446 sz.setWidth(padding.left() + padding.right());
1447 sz.setHeight(padding.top() + padding.bottom());
1449 sz = drawable->size();
1452 if (contentsSize.height() < opt->fontMetrics.height())
1453 sz.setHeight(sz.height() + (opt->fontMetrics.height() - contentsSize.height()));
1454 if (sz.height() < m_minSize.height())
1455 sz.setHeight(m_minSize.height());
1456 if (sz.width() < m_minSize.width())
1457 sz.setWidth(m_minSize.width());
1535QAndroidStyle::AndroidProgressBarControl::AndroidProgressBarControl(
const QVariantMap &control,
1537 : AndroidControl(control, itemType)
1539 QVariantMap::const_iterator it = control.find(QLatin1String(
"ProgressBar_indeterminateDrawable"));
1540 if (it != control.end())
1541 m_indeterminateDrawable = AndroidDrawable::fromMap(it.value().toMap(), itemType);
1543 m_indeterminateDrawable = 0;
1545 it = control.find(QLatin1String(
"ProgressBar_progressDrawable"));
1546 if (it != control.end())
1547 m_progressDrawable = AndroidDrawable::fromMap(it.value().toMap(), itemType);
1549 m_progressDrawable = 0;
1551 it = control.find(QLatin1String(
"ProgressBar_progress_id"));
1552 if (it != control.end())
1553 m_progressId = it.value().toInt();
1555 it = control.find(QLatin1String(
"ProgressBar_secondaryProgress_id"));
1556 if (it != control.end())
1557 m_secondaryProgress_id = it.value().toInt();
1559 it = control.find(QLatin1String(
"ProgressBar_minWidth"));
1560 if (it != control.end())
1561 m_minSize.setWidth(it.value().toInt());
1563 it = control.find(QLatin1String(
"ProgressBar_minHeight"));
1564 if (it != control.end())
1565 m_minSize.setHeight(it.value().toInt());
1567 it = control.find(QLatin1String(
"ProgressBar_maxWidth"));
1568 if (it != control.end())
1569 m_maxSize.setWidth(it.value().toInt());
1571 it = control.find(QLatin1String(
"ProgressBar_maxHeight"));
1572 if (it != control.end())
1573 m_maxSize.setHeight(it.value().toInt());
1582void QAndroidStyle::AndroidProgressBarControl::drawControl(
const QStyleOption *option, QPainter *p,
const QWidget * )
1584 if (!m_progressDrawable)
1587 if (
const QStyleOptionProgressBar *pb = qstyleoption_cast<
const QStyleOptionProgressBar *>(option)) {
1588 if (m_progressDrawable->type() == QAndroidStyle::Layer) {
1589 const double fraction =
double(qint64(pb->progress) - pb->minimum) / (qint64(pb->maximum) - pb->minimum);
1590 QAndroidStyle::AndroidDrawable *clipDrawable =
static_cast<QAndroidStyle::AndroidLayerDrawable *>(m_progressDrawable)->layer(m_progressId);
1591 const Qt::Orientation orientation = pb->state & QStyle::State_Horizontal ? Qt::Horizontal : Qt::Vertical;
1592 if (clipDrawable->type() == QAndroidStyle::Clip)
1593 static_cast<AndroidClipDrawable *>(clipDrawable)->setFactor(fraction, orientation);
1595 static_cast<AndroidLayerDrawable *>(m_progressDrawable)->setFactor(m_progressId, fraction, orientation);
1597 m_progressDrawable->draw(p, option);
1601QRect QAndroidStyle::AndroidProgressBarControl::subElementRect(QStyle::SubElement subElement,
1602 const QStyleOption *option,
1603 const QWidget *widget)
const
1605 if (
const QStyleOptionProgressBar *progressBarOption =
1606 qstyleoption_cast<
const QStyleOptionProgressBar *>(option)) {
1607 const bool horizontal = progressBarOption->state & QStyle::State_Horizontal;
1609 return option->rect;
1611 QMargins padding = m_background->padding();
1612 QRect p(padding.left(), padding.top(), padding.right() - padding.left(), padding.bottom() - padding.top());
1613 padding = m_indeterminateDrawable->padding();
1614 p |= QRect(padding.left(), padding.top(), padding.right() - padding.left(), padding.bottom() - padding.top());
1615 padding = m_progressDrawable->padding();
1616 p |= QRect(padding.left(), padding.top(), padding.right() - padding.left(), padding.bottom() - padding.top());
1617 QRect r = option->rect.adjusted(p.left(), p.top(), -p.right(), -p.bottom());
1620 if (r.height()<m_minSize.height())
1621 r.setHeight(m_minSize.height());
1623 if (r.height()>m_maxSize.height())
1624 r.setHeight(m_maxSize.height());
1626 if (r.width()<m_minSize.width())
1627 r.setWidth(m_minSize.width());
1629 if (r.width()>m_maxSize.width())
1630 r.setWidth(m_maxSize.width());
1632 return visualRect(option->direction, option->rect, r);
1634 return AndroidControl::subElementRect(subElement, option, widget);
1676void QAndroidStyle::AndroidSeekBarControl::drawControl(
const QStyleOption *option,
1680 if (!m_seekBarThumb || !m_progressDrawable)
1683 if (
const QStyleOptionSlider *styleOption =
1684 qstyleoption_cast<
const QStyleOptionSlider *>(option)) {
1685 double factor =
double(styleOption->sliderPosition - styleOption->minimum)
1686 /
double(styleOption->maximum - styleOption->minimum);
1690 if (styleOption->orientation == Qt::Vertical)
1691 factor = 1 - factor;
1693 if (m_progressDrawable->type() == QAndroidStyle::Layer) {
1694 QAndroidStyle::AndroidDrawable *clipDrawable =
static_cast<QAndroidStyle::AndroidLayerDrawable *>(m_progressDrawable)->layer(m_progressId);
1695 if (clipDrawable->type() == QAndroidStyle::Clip)
1696 static_cast<QAndroidStyle::AndroidClipDrawable *>(clipDrawable)->setFactor(factor, Qt::Horizontal);
1698 static_cast<QAndroidStyle::AndroidLayerDrawable *>(m_progressDrawable)->setFactor(m_progressId, factor, Qt::Horizontal);
1700 const AndroidDrawable *drawable = m_seekBarThumb;
1701 if (drawable->type() == State)
1702 drawable =
static_cast<
const QAndroidStyle::AndroidStateDrawable *>(m_seekBarThumb)->bestAndroidStateMatch(option);
1703 QStyleOption copy(*option);
1707 if (styleOption->orientation == Qt::Vertical) {
1710 copy.rect = QRect(copy.rect.y(), copy.rect.x() - copy.rect.width(), copy.rect.height(), copy.rect.width());
1713 copy.rect.setHeight(m_progressDrawable->size().height());
1714 copy.rect.setWidth(copy.rect.width() - drawable->size().width());
1715 const int yTranslate = abs(drawable->size().height() - copy.rect.height()) / 2;
1716 copy.rect.translate(drawable->size().width() / 2, yTranslate);
1717 m_progressDrawable->draw(p, ©);
1718 int pos = copy.rect.width() * factor - drawable->size().width() / 2;
1719 copy.rect.translate(pos, -yTranslate);
1720 copy.rect.setSize(drawable->size());
1721 m_seekBarThumb->draw(p, ©);
1740QRect QAndroidStyle::AndroidSeekBarControl::subControlRect(
const QStyleOptionComplex *option,
1742 const QWidget * )
const
1744 const QStyleOptionSlider *styleOption =
1745 qstyleoption_cast<
const QStyleOptionSlider *>(option);
1747 if (m_seekBarThumb && sc == SC_SliderHandle && styleOption) {
1748 const AndroidDrawable *drawable = m_seekBarThumb;
1749 if (drawable->type() == State)
1750 drawable =
static_cast<
const QAndroidStyle::AndroidStateDrawable *>(m_seekBarThumb)->bestAndroidStateMatch(option);
1752 QRect r(option->rect);
1753 double factor =
double(styleOption->sliderPosition - styleOption->minimum)
1754 / (styleOption->maximum - styleOption->minimum);
1755 if (styleOption->orientation == Qt::Vertical) {
1756 int pos = option->rect.height() * (1 - factor) -
double(drawable->size().height() / 2);
1757 r.setY(r.y() + pos);
1759 int pos = option->rect.width() * factor -
double(drawable->size().width() / 2);
1760 r.setX(r.x() + pos);
1762 r.setSize(drawable->size());
1765 return option->rect;