diff options
Diffstat (limited to 'src/widgets/styles/qandroidstyle.cpp')
-rw-r--r-- | src/widgets/styles/qandroidstyle.cpp | 1820 |
1 files changed, 0 insertions, 1820 deletions
diff --git a/src/widgets/styles/qandroidstyle.cpp b/src/widgets/styles/qandroidstyle.cpp deleted file mode 100644 index 55f125c6b5..0000000000 --- a/src/widgets/styles/qandroidstyle.cpp +++ /dev/null @@ -1,1820 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 BogDan Vatra <bogdan@kde.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWidgets module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qandroidstyle_p.h" - -#if QT_CONFIG(style_android) || defined(QT_PLUGIN) - -#include <QFile> -#include <QFont> -#include <QApplication> -#include <qdrawutil.h> -#include <QPixmapCache> -#include <QFileInfo> -#include <QStyleOption> -#include <QPainter> -#include <QJsonDocument> -#include <QJsonObject> -#include <QDebug> - -#include <QGuiApplication> -#include <qpa/qplatformnativeinterface.h> -#include <qpa/qplatformtheme.h> - -QT_BEGIN_NAMESPACE - -namespace { - const quint32 NO_COLOR = 1; - const quint32 TRANSPARENT_COLOR = 0; -} - -QAndroidStyle::QAndroidStyle() - : QFusionStyle() -{ - QPixmapCache::clear(); - checkBoxControl = NULL; - QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); - QPalette *standardPalette = reinterpret_cast<QPalette *>(nativeInterface->nativeResourceForIntegration("AndroidStandardPalette")); - if (standardPalette) - m_standardPalette = *standardPalette; - - QHash<QByteArray, QFont> *qwidgetsFonts = reinterpret_cast<QHash<QByteArray, QFont> *>(nativeInterface->nativeResourceForIntegration("AndroidQWidgetFonts")); - if (qwidgetsFonts) { - for (auto it = qwidgetsFonts->constBegin(); it != qwidgetsFonts->constEnd(); ++it) - QApplication::setFont(it.value(), it.key()); - qwidgetsFonts->clear(); // free the memory - } - - QJsonObject *object = reinterpret_cast<QJsonObject *>(nativeInterface->nativeResourceForIntegration("AndroidStyleData")); - if (!object) - return; - - for (QJsonObject::const_iterator objectIterator = object->constBegin(); - objectIterator != object->constEnd(); - ++objectIterator) { - QString key = objectIterator.key(); - QJsonValue value = objectIterator.value(); - if (Q_UNLIKELY(!value.isObject())) { - qWarning("Style.json structure is unrecognized."); - continue; - } - - QJsonObject item = value.toObject(); - QAndroidStyle::ItemType itemType = qtControl(key); - if (QC_UnknownType == itemType) - continue; - - switch (itemType) { - case QC_Checkbox: - checkBoxControl = new AndroidCompoundButtonControl(item.toVariantMap(), itemType); - m_androidControlsHash[int(itemType)] = checkBoxControl; - break; - case QC_RadioButton: - m_androidControlsHash[int(itemType)] = new AndroidCompoundButtonControl(item.toVariantMap(), - itemType); - break; - - case QC_ProgressBar: - m_androidControlsHash[int(itemType)] = new AndroidProgressBarControl(item.toVariantMap(), - itemType); - break; - - case QC_Slider: - m_androidControlsHash[int(itemType)] = new AndroidSeekBarControl(item.toVariantMap(), - itemType); - break; - - case QC_Combobox: - m_androidControlsHash[int(itemType)] = new AndroidSpinnerControl(item.toVariantMap(), - itemType); - break; - - default: - m_androidControlsHash[int(itemType)] = new AndroidControl(item.toVariantMap(), - itemType); - break; - } - } - *object = QJsonObject(); // free memory -} - -QAndroidStyle::~QAndroidStyle() -{ - qDeleteAll(m_androidControlsHash); -} - -QAndroidStyle::ItemType QAndroidStyle::qtControl(const QString &android) -{ - if (android == QLatin1String("buttonStyle")) - return QC_Button; - if (android == QLatin1String("editTextStyle")) - return QC_EditText; - if (android == QLatin1String("radioButtonStyle")) - return QC_RadioButton; - if (android == QLatin1String("checkboxStyle")) - return QC_Checkbox; - if (android == QLatin1String("textViewStyle")) - return QC_View; - if (android == QLatin1String("buttonStyleToggle")) - return QC_Switch; - if (android == QLatin1String("spinnerStyle")) - return QC_Combobox; - if (android == QLatin1String("progressBarStyleHorizontal")) - return QC_ProgressBar; - if (android == QLatin1String("seekBarStyle")) - return QC_Slider; - - return QC_UnknownType; -} - -QAndroidStyle::ItemType QAndroidStyle::qtControl(QStyle::ComplexControl control) -{ - switch (control) { - case CC_ComboBox: - return QC_Combobox; - case CC_Slider: - return QC_Slider; - default: - return QC_UnknownType; - } -} - -QAndroidStyle::ItemType QAndroidStyle::qtControl(QStyle::ContentsType contentsType) -{ - switch (contentsType) { - case CT_PushButton: - return QC_Button; - case CT_CheckBox: - return QC_Checkbox; - case CT_RadioButton: - return QC_RadioButton; - case CT_ComboBox: - return QC_Combobox; - case CT_ProgressBar: - return QC_ProgressBar; - case CT_Slider: - return QC_Slider; - case CT_ScrollBar: - return QC_Slider; - case CT_TabWidget: - return QC_Tab; - case CT_TabBarTab: - return QC_TabButton; - case CT_LineEdit: - return QC_EditText; - case CT_GroupBox: - return QC_GroupBox; - default: - return QC_UnknownType; - } -} - -QAndroidStyle::ItemType QAndroidStyle::qtControl(QStyle::ControlElement controlElement) -{ - switch (controlElement) { - case CE_PushButton: - case CE_PushButtonBevel: - case CE_PushButtonLabel: - return QC_Button; - - case CE_CheckBox: - case CE_CheckBoxLabel: - return QC_Checkbox; - - case CE_RadioButton: - case CE_RadioButtonLabel: - return QC_RadioButton; - - case CE_TabBarTab: - case CE_TabBarTabShape: - case CE_TabBarTabLabel: - return QC_Tab; - - case CE_ProgressBar: - case CE_ProgressBarGroove: - case CE_ProgressBarContents: - case CE_ProgressBarLabel: - return QC_ProgressBar; - - case CE_ComboBoxLabel: - return QC_Combobox; - - case CE_ShapedFrame: - return QC_View; - - default: - return QC_UnknownType; - } -} - -QAndroidStyle::ItemType QAndroidStyle::qtControl(QStyle::PrimitiveElement primitiveElement) -{ - switch (primitiveElement) { - case QStyle::PE_PanelLineEdit: - case QStyle::PE_FrameLineEdit: - return QC_EditText; - - case QStyle::PE_IndicatorViewItemCheck: - case QStyle::PE_IndicatorCheckBox: - return QC_Checkbox; - - case QStyle::PE_FrameWindow: - case QStyle::PE_Widget: - case QStyle::PE_Frame: - case QStyle::PE_FrameFocusRect: - return QC_View; - default: - return QC_UnknownType; - } -} - -QAndroidStyle::ItemType QAndroidStyle::qtControl(QStyle::SubElement subElement) -{ - switch (subElement) { - case QStyle::SE_LineEditContents: - return QC_EditText; - - case QStyle::SE_PushButtonContents: - case QStyle::SE_PushButtonFocusRect: - return QC_Button; - - case SE_RadioButtonContents: - return QC_RadioButton; - - case SE_CheckBoxContents: - return QC_Checkbox; - - default: - return QC_UnknownType; - } -} - -void QAndroidStyle::drawPrimitive(PrimitiveElement pe, - const QStyleOption *opt, - QPainter *p, - const QWidget *w) const -{ - const ItemType itemType = qtControl(pe); - AndroidControlsHash::const_iterator it = itemType != QC_UnknownType - ? m_androidControlsHash.find(itemType) - : m_androidControlsHash.end(); - if (it != m_androidControlsHash.end()) { - if (itemType != QC_EditText) { - it.value()->drawControl(opt, p, w); - } else { - QStyleOption copy(*opt); - copy.state &= ~QStyle::State_Sunken; - it.value()->drawControl(©, p, w); - } - } else if (pe == PE_FrameGroupBox) { - if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) { - if (frame->features & QStyleOptionFrame::Flat) { - QRect fr = frame->rect; - QPoint p1(fr.x(), fr.y() + 1); - QPoint p2(fr.x() + fr.width(), p1.y()); - qDrawShadeLine(p, p1, p2, frame->palette, true, - frame->lineWidth, frame->midLineWidth); - } else { - qDrawShadeRect(p, frame->rect.x(), frame->rect.y(), frame->rect.width(), - frame->rect.height(), frame->palette, true, - frame->lineWidth, frame->midLineWidth); - } - } - } else { - QFusionStyle::drawPrimitive(pe, opt, p, w); - } -} - - -void QAndroidStyle::drawControl(QStyle::ControlElement element, - const QStyleOption *opt, - QPainter *p, - const QWidget *w) const -{ - const ItemType itemType = qtControl(element); - AndroidControlsHash::const_iterator it = itemType != QC_UnknownType - ? m_androidControlsHash.find(itemType) - : m_androidControlsHash.end(); - if (it != m_androidControlsHash.end()) { - AndroidControl *androidControl = it.value(); - - if (element != QStyle::CE_CheckBoxLabel - && element != QStyle::CE_PushButtonLabel - && element != QStyle::CE_RadioButtonLabel - && element != QStyle::CE_TabBarTabLabel - && element != QStyle::CE_ProgressBarLabel) { - androidControl->drawControl(opt, p, w); - } - - if (element != QStyle::CE_PushButtonBevel - && element != QStyle::CE_TabBarTabShape - && element != QStyle::CE_ProgressBarGroove) { - switch (itemType) { - case QC_Button: - if (const QStyleOptionButton *buttonOption = - qstyleoption_cast<const QStyleOptionButton *>(opt)) { - QMargins padding = androidControl->padding(); - QStyleOptionButton copy(*buttonOption); - copy.rect.adjust(padding.left(), padding.top(), -padding.right(), -padding.bottom()); - QFusionStyle::drawControl(CE_PushButtonLabel, ©, p, w); - } - break; - case QC_Checkbox: - case QC_RadioButton: - if (const QStyleOptionButton *btn = - qstyleoption_cast<const QStyleOptionButton *>(opt)) { - const bool isRadio = (element == CE_RadioButton); - QStyleOptionButton subopt(*btn); - subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents - : SE_CheckBoxContents, btn, w); - QFusionStyle::drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, p, w); - } - break; - case QC_Combobox: - if (const QStyleOptionComboBox *comboboxOption = - qstyleoption_cast<const QStyleOptionComboBox *>(opt)) { - QMargins padding = androidControl->padding(); - QStyleOptionComboBox copy (*comboboxOption); - copy.rect.adjust(padding.left(), padding.top(), -padding.right(), -padding.bottom()); - QFusionStyle::drawControl(CE_ComboBoxLabel, comboboxOption, p, w); - } - break; - default: - QFusionStyle::drawControl(element, opt, p, w); - break; - } - } - } else { - QFusionStyle::drawControl(element, opt, p, w); - } -} - -QRect QAndroidStyle::subElementRect(SubElement subElement, - const QStyleOption *option, - const QWidget *widget) const -{ - const ItemType itemType = qtControl(subElement); - AndroidControlsHash::const_iterator it = itemType != QC_UnknownType - ? m_androidControlsHash.find(itemType) - : m_androidControlsHash.end(); - if (it != m_androidControlsHash.end()) - return it.value()->subElementRect(subElement, option, widget); - return QFusionStyle::subElementRect(subElement, option, widget); -} - -void QAndroidStyle::drawComplexControl(ComplexControl cc, - const QStyleOptionComplex *opt, - QPainter *p, - const QWidget *widget) const -{ - const ItemType itemType = qtControl(cc); - AndroidControlsHash::const_iterator it = itemType != QC_UnknownType - ? m_androidControlsHash.find(itemType) - : m_androidControlsHash.end(); - if (it != m_androidControlsHash.end()) { - it.value()->drawControl(opt, p, widget); - return; - } - if (cc == CC_GroupBox) { - if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) { - // Draw frame - QRect textRect = subControlRect(CC_GroupBox, opt, SC_GroupBoxLabel, widget); - QRect checkBoxRect; - if (groupBox->subControls & SC_GroupBoxCheckBox) - checkBoxRect = subControlRect(CC_GroupBox, opt, SC_GroupBoxCheckBox, widget); - if (groupBox->subControls & QStyle::SC_GroupBoxFrame) { - QStyleOptionFrame frame; - frame.QStyleOption::operator=(*groupBox); - frame.features = groupBox->features; - frame.lineWidth = groupBox->lineWidth; - frame.midLineWidth = groupBox->midLineWidth; - frame.rect = subControlRect(CC_GroupBox, opt, SC_GroupBoxFrame, widget); - p->save(); - QRegion region(groupBox->rect); - if (!groupBox->text.isEmpty()) { - bool ltr = groupBox->direction == Qt::LeftToRight; - QRect finalRect; - if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox) { - finalRect = checkBoxRect.united(textRect); - finalRect.adjust(ltr ? -4 : 0, 0, ltr ? 0 : 4, 0); - } else { - finalRect = textRect; - } - region -= finalRect; - } - p->setClipRegion(region); - drawPrimitive(PE_FrameGroupBox, &frame, p, widget); - p->restore(); - } - - // Draw title - if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) { - QColor textColor = groupBox->textColor; - if (textColor.isValid()) - p->setPen(textColor); - int alignment = int(groupBox->textAlignment); - if (!styleHint(QStyle::SH_UnderlineShortcut, opt, widget)) - alignment |= Qt::TextHideMnemonic; - - drawItemText(p, textRect, Qt::TextShowMnemonic | Qt::AlignHCenter | alignment, - groupBox->palette, groupBox->state & State_Enabled, groupBox->text, - textColor.isValid() ? QPalette::NoRole : QPalette::WindowText); - - if (groupBox->state & State_HasFocus) { - QStyleOptionFocusRect fropt; - fropt.QStyleOption::operator=(*groupBox); - fropt.rect = textRect; - drawPrimitive(PE_FrameFocusRect, &fropt, p, widget); - } - } - - // Draw checkbox - if (groupBox->subControls & SC_GroupBoxCheckBox) { - QStyleOptionButton box; - box.QStyleOption::operator=(*groupBox); - box.rect = checkBoxRect; - checkBoxControl->drawControl(&box, p, widget); - } - } - return; - } - QFusionStyle::drawComplexControl(cc, opt, p, widget); -} - -QStyle::SubControl QAndroidStyle::hitTestComplexControl(ComplexControl cc, - const QStyleOptionComplex *opt, - const QPoint &pt, - const QWidget *widget) const -{ - const ItemType itemType = qtControl(cc); - AndroidControlsHash::const_iterator it = itemType != QC_UnknownType - ? m_androidControlsHash.find(itemType) - : m_androidControlsHash.end(); - if (it != m_androidControlsHash.end()) { - switch (cc) { - case CC_Slider: - if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { - QRect r = it.value()->subControlRect(slider, SC_SliderHandle, widget); - if (r.isValid() && r.contains(pt)) { - return SC_SliderHandle; - } else { - r = it.value()->subControlRect(slider, SC_SliderGroove, widget); - if (r.isValid() && r.contains(pt)) - return SC_SliderGroove; - } - } - break; - default: - break; - } - } - return QFusionStyle::hitTestComplexControl(cc, opt, pt, widget); -} - -QRect QAndroidStyle::subControlRect(ComplexControl cc, - const QStyleOptionComplex *opt, - SubControl sc, - const QWidget *widget) const -{ - const ItemType itemType = qtControl(cc); - AndroidControlsHash::const_iterator it = itemType != QC_UnknownType - ? m_androidControlsHash.find(itemType) - : m_androidControlsHash.end(); - if (it != m_androidControlsHash.end()) - return it.value()->subControlRect(opt, sc, widget); - QRect rect = opt->rect; - switch (cc) { - case CC_GroupBox: { - if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) { - QSize textSize = opt->fontMetrics.boundingRect(groupBox->text).size() + QSize(2, 2); - QSize checkBoxSize = checkBoxControl->size(opt); - int indicatorWidth = checkBoxSize.width(); - int indicatorHeight = checkBoxSize.height(); - QRect checkBoxRect; - if (opt->subControls & QStyle::SC_GroupBoxCheckBox) { - checkBoxRect.setWidth(indicatorWidth); - checkBoxRect.setHeight(indicatorHeight); - } - checkBoxRect.moveLeft(1); - QRect textRect = checkBoxRect; - textRect.setSize(textSize); - if (opt->subControls & QStyle::SC_GroupBoxCheckBox) - textRect.translate(indicatorWidth + 5, (indicatorHeight - textSize.height()) / 2); - if (sc == SC_GroupBoxFrame) { - rect = opt->rect.adjusted(0, 0, 0, 0); - rect.translate(0, textRect.height() / 2); - rect.setHeight(rect.height() - textRect.height() / 2); - } else if (sc == SC_GroupBoxContents) { - QRect frameRect = opt->rect.adjusted(0, 0, 0, -groupBox->lineWidth); - int margin = 3; - int leftMarginExtension = 0; - int topMargin = qMax(pixelMetric(PM_ExclusiveIndicatorHeight), opt->fontMetrics.height()) + groupBox->lineWidth; - frameRect.adjust(leftMarginExtension + margin, margin + topMargin, -margin, -margin - groupBox->lineWidth); - frameRect.translate(0, textRect.height() / 2); - rect = frameRect; - rect.setHeight(rect.height() - textRect.height() / 2); - } else if (sc == SC_GroupBoxCheckBox) { - rect = checkBoxRect; - } else if (sc == SC_GroupBoxLabel) { - rect = textRect; - } - return visualRect(opt->direction, opt->rect, rect); - } - - return rect; - } - - default: - break; - } - - - return QFusionStyle::subControlRect(cc, opt, sc, widget); -} - -int QAndroidStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, - const QWidget *widget) const -{ - switch (metric) { - case PM_ButtonMargin: - case PM_FocusFrameVMargin: - case PM_FocusFrameHMargin: - case PM_ComboBoxFrameWidth: - case PM_SpinBoxFrameWidth: - case PM_ScrollBarExtent: - return 0; - case PM_IndicatorWidth: - return checkBoxControl->size(option).width(); - case PM_IndicatorHeight: - return checkBoxControl->size(option).height(); - default: - return QFusionStyle::pixelMetric(metric, option, widget); - } - -} - -QSize QAndroidStyle::sizeFromContents(ContentsType ct, - const QStyleOption *opt, - const QSize &contentsSize, - const QWidget *w) const -{ - QSize sz = QFusionStyle::sizeFromContents(ct, opt, contentsSize, w); - if (ct == CT_HeaderSection) { - if (const QStyleOptionHeader *hdr = qstyleoption_cast<const QStyleOptionHeader *>(opt)) { - bool nullIcon = hdr->icon.isNull(); - int margin = pixelMetric(QStyle::PM_HeaderMargin, hdr, w); - int iconSize = nullIcon ? 0 : checkBoxControl->size(opt).width(); - QSize txt; -/* - * These next 4 lines are a bad hack to fix a bug in case a QStyleSheet is applied at QApplication level. - * In that case, even if the stylesheet does not refer to headers, the header font is changed to application - * font, which is wrong. Even worst, hdr->fontMetrics(...) does not report the proper size. - */ - if (qApp->styleSheet().isEmpty()) - txt = hdr->fontMetrics.size(0, hdr->text); - else - txt = qApp->fontMetrics().size(0, hdr->text); - - sz.setHeight(margin + qMax(iconSize, txt.height()) + margin); - sz.setWidth((nullIcon ? 0 : margin) + iconSize - + (hdr->text.isNull() ? 0 : margin) + txt.width() + margin); - if (hdr->sortIndicator != QStyleOptionHeader::None) { - int margin = pixelMetric(QStyle::PM_HeaderMargin, hdr, w); - if (hdr->orientation == Qt::Horizontal) - sz.rwidth() += sz.height() + margin; - else - sz.rheight() += sz.width() + margin; - } - return sz; - } - } - const ItemType itemType = qtControl(ct); - AndroidControlsHash::const_iterator it = itemType != QC_UnknownType - ? m_androidControlsHash.find(itemType) - : m_androidControlsHash.end(); - if (it != m_androidControlsHash.end()) - return it.value()->sizeFromContents(opt, sz, w); - if (ct == CT_GroupBox) { - if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) { - QSize textSize = opt->fontMetrics.boundingRect(groupBox->text).size() + QSize(2, 2); - QSize checkBoxSize = checkBoxControl->size(opt); - int indicatorWidth = checkBoxSize.width(); - int indicatorHeight = checkBoxSize.height(); - QRect checkBoxRect; - if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox) { - checkBoxRect.setWidth(indicatorWidth); - checkBoxRect.setHeight(indicatorHeight); - } - checkBoxRect.moveLeft(1); - QRect textRect = checkBoxRect; - textRect.setSize(textSize); - if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox) - textRect.translate(indicatorWidth + 5, (indicatorHeight - textSize.height()) / 2); - QRect u = textRect.united(checkBoxRect); - sz = QSize(sz.width(), sz.height() + u.height()); - } - } - return sz; -} - -QPixmap QAndroidStyle::standardPixmap(StandardPixmap standardPixmap, - const QStyleOption *opt, - const QWidget *widget) const -{ - return QFusionStyle::standardPixmap(standardPixmap, opt, widget); -} - -QPixmap QAndroidStyle::generatedIconPixmap(QIcon::Mode iconMode, - const QPixmap &pixmap, - const QStyleOption *opt) const -{ - return QFusionStyle::generatedIconPixmap(iconMode, pixmap, opt); -} - -int QAndroidStyle::styleHint(QStyle::StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const -{ - switch (hint) { - case SH_Slider_AbsoluteSetButtons: - return Qt::LeftButton; - - case SH_Slider_PageSetButtons: - return 0; - - case SH_RequestSoftwareInputPanel: - return RSIP_OnMouseClick; - - default: - return QFusionStyle::styleHint(hint, option, widget, returnData); - } -} - -QPalette QAndroidStyle::standardPalette() const -{ - return m_standardPalette; -} - -void QAndroidStyle::polish(QWidget *widget) -{ - widget->setAttribute(Qt::WA_StyledBackground, true); -} - -void QAndroidStyle::unpolish(QWidget *widget) -{ - widget->setAttribute(Qt::WA_StyledBackground, false); -} - -QAndroidStyle::AndroidDrawable::AndroidDrawable(const QVariantMap &drawable, - QAndroidStyle::ItemType itemType) -{ - initPadding(drawable); - m_itemType = itemType; -} - -QAndroidStyle::AndroidDrawable::~AndroidDrawable() -{ -} - -void QAndroidStyle::AndroidDrawable::initPadding(const QVariantMap &drawable) -{ - QVariantMap::const_iterator it = drawable.find(QLatin1String("padding")); - if (it != drawable.end()) - m_padding = extractMargins(it.value().toMap()); -} - -const QMargins &QAndroidStyle::AndroidDrawable::padding() const -{ - return m_padding; -} - -QSize QAndroidStyle::AndroidDrawable::size() const -{ - if (type() == Image || type() == NinePatch) - return static_cast<const QAndroidStyle::AndroidImageDrawable *>(this)->size(); - - return QSize(); -} - -QAndroidStyle::AndroidDrawable * QAndroidStyle::AndroidDrawable::fromMap(const QVariantMap &drawable, - ItemType itemType) -{ - const QString type = drawable.value(QLatin1String("type")).toString(); - if (type == QLatin1String("image")) - return new QAndroidStyle::AndroidImageDrawable(drawable, itemType); - if (type == QLatin1String("9patch")) - return new QAndroidStyle::Android9PatchDrawable(drawable, itemType); - if (type == QLatin1String("stateslist")) - return new QAndroidStyle::AndroidStateDrawable(drawable, itemType); - if (type == QLatin1String("layer")) - return new QAndroidStyle::AndroidLayerDrawable(drawable, itemType); - if (type == QLatin1String("gradient")) - return new QAndroidStyle::AndroidGradientDrawable(drawable, itemType); - if (type == QLatin1String("clipDrawable")) - return new QAndroidStyle::AndroidClipDrawable(drawable, itemType); - if (type == QLatin1String("color")) - return new QAndroidStyle::AndroidColorDrawable(drawable, itemType); - return 0; -} - -QMargins QAndroidStyle::AndroidDrawable::extractMargins(const QVariantMap &value) -{ - QMargins m; - m.setLeft(value.value(QLatin1String("left")).toInt()); - m.setRight(value.value(QLatin1String("right")).toInt()); - m.setTop(value.value(QLatin1String("top")).toInt()); - m.setBottom(value.value(QLatin1String("bottom")).toInt()); - return m; -} - -void QAndroidStyle::AndroidDrawable::setPaddingLeftToSizeWidth() -{ - QSize sz = size(); - if (m_padding.isNull() && !sz.isNull()) - m_padding.setLeft(sz.width()); -} - - -QAndroidStyle::AndroidImageDrawable::AndroidImageDrawable(const QVariantMap &drawable, - QAndroidStyle::ItemType itemType) - : AndroidDrawable(drawable, itemType) -{ - m_filePath = drawable.value(QLatin1String("path")).toString(); - m_size.setHeight(drawable.value(QLatin1String("height")).toInt()); - m_size.setWidth(drawable.value(QLatin1String("width")).toInt()); -} - -QAndroidStyle::AndroidDrawableType QAndroidStyle::AndroidImageDrawable::type() const -{ - return QAndroidStyle::Image; -} - -void QAndroidStyle::AndroidImageDrawable::draw(QPainter *painter, const QStyleOption *opt) const -{ - if (m_hashKey.isEmpty()) - m_hashKey = QFileInfo(m_filePath).fileName(); - - QPixmap pm; - if (!QPixmapCache::find(m_hashKey, &pm)) { - pm.load(m_filePath); - QPixmapCache::insert(m_hashKey, pm); - } - - painter->drawPixmap(opt->rect.x(), opt->rect.y() + (opt->rect.height() - pm.height()) / 2, pm); -} - -QSize QAndroidStyle::AndroidImageDrawable::size() const -{ - return m_size; -} - -QAndroidStyle::AndroidColorDrawable::AndroidColorDrawable(const QVariantMap &drawable, - ItemType itemType) - : AndroidDrawable(drawable, itemType) -{ - m_color.setRgba(QRgb(drawable.value(QLatin1String("color")).toInt())); -} - -QAndroidStyle::AndroidDrawableType QAndroidStyle::AndroidColorDrawable::type() const -{ - return QAndroidStyle::Color; -} - -void QAndroidStyle::AndroidColorDrawable::draw(QPainter *painter, const QStyleOption *opt) const -{ - painter->fillRect(opt->rect, m_color); -} - -QAndroidStyle::Android9PatchDrawable::Android9PatchDrawable(const QVariantMap &drawable, - QAndroidStyle::ItemType itemType) - : AndroidImageDrawable(drawable.value(QLatin1String("drawable")).toMap(), itemType) -{ - initPadding(drawable); - QVariantMap chunk = drawable.value(QLatin1String("chunkInfo")).toMap(); - extractIntArray(chunk.value(QLatin1String("xdivs")).toList(), m_chunkData.xDivs); - extractIntArray(chunk.value(QLatin1String("ydivs")).toList(), m_chunkData.yDivs); - extractIntArray(chunk.value(QLatin1String("colors")).toList(), m_chunkData.colors); -} - -QAndroidStyle::AndroidDrawableType QAndroidStyle::Android9PatchDrawable::type() const -{ - return QAndroidStyle::NinePatch; -} - -int QAndroidStyle::Android9PatchDrawable::calculateStretch(int boundsLimit, - int startingPoint, - int srcSpace, - int numStrechyPixelsRemaining, - int numFixedPixelsRemaining) -{ - int spaceRemaining = boundsLimit - startingPoint; - int stretchySpaceRemaining = spaceRemaining - numFixedPixelsRemaining; - return (float(srcSpace) * stretchySpaceRemaining / numStrechyPixelsRemaining + .5); -} - -void QAndroidStyle::Android9PatchDrawable::extractIntArray(const QVariantList &values, - QVector<int> & array) -{ - for (const QVariant &value : values) - array << value.toInt(); -} - - -void QAndroidStyle::Android9PatchDrawable::draw(QPainter *painter, const QStyleOption *opt) const -{ - if (m_hashKey.isEmpty()) - m_hashKey = QFileInfo(m_filePath).fileName(); - - QPixmap pixmap; - if (!QPixmapCache::find(m_hashKey, &pixmap)) { - pixmap.load(m_filePath); - QPixmapCache::insert(m_hashKey, pixmap); - } - - const QRect &bounds = opt->rect; - - // shamelessly stolen from Android's sources (NinepatchImpl.cpp) and adapted for Qt - const int pixmapWidth = pixmap.width(); - const int pixmapHeight = pixmap.height(); - - if (bounds.isNull() || !pixmapWidth || !pixmapHeight) - return; - - QPainter::RenderHints savedHints = painter->renderHints(); - - // The patchs doesn't need smooth transform ! - painter->setRenderHints(QPainter::SmoothPixmapTransform, false); - - QRectF dst; - QRectF src; - - const qint32 x0 = m_chunkData.xDivs[0]; - const qint32 y0 = m_chunkData.yDivs[0]; - const quint8 numXDivs = m_chunkData.xDivs.size(); - const quint8 numYDivs = m_chunkData.yDivs.size(); - int i; - int j; - int colorIndex = 0; - quint32 color; - bool xIsStretchable; - const bool initialXIsStretchable = (x0 == 0); - bool yIsStretchable = (y0 == 0); - const int bitmapWidth = pixmap.width(); - const int bitmapHeight = pixmap.height(); - - int *dstRights = static_cast<int *>(alloca((numXDivs + 1) * sizeof(int))); - bool dstRightsHaveBeenCached = false; - - int numStretchyXPixelsRemaining = 0; - for (i = 0; i < numXDivs; i += 2) - numStretchyXPixelsRemaining += m_chunkData.xDivs[i + 1] - m_chunkData.xDivs[i]; - - int numFixedXPixelsRemaining = bitmapWidth - numStretchyXPixelsRemaining; - int numStretchyYPixelsRemaining = 0; - for (i = 0; i < numYDivs; i += 2) - numStretchyYPixelsRemaining += m_chunkData.yDivs[i + 1] - m_chunkData.yDivs[i]; - - int numFixedYPixelsRemaining = bitmapHeight - numStretchyYPixelsRemaining; - src.setTop(0); - dst.setTop(bounds.top()); - // The first row always starts with the top being at y=0 and the bottom - // being either yDivs[1] (if yDivs[0]=0) of yDivs[0]. In the former case - // the first row is stretchable along the Y axis, otherwise it is fixed. - // The last row always ends with the bottom being bitmap.height and the top - // being either yDivs[numYDivs-2] (if yDivs[numYDivs-1]=bitmap.height) or - // yDivs[numYDivs-1]. In the former case the last row is stretchable along - // the Y axis, otherwise it is fixed. - // - // The first and last columns are similarly treated with respect to the X - // axis. - // - // The above is to help explain some of the special casing that goes on the - // code below. - - // The initial yDiv and whether the first row is considered stretchable or - // not depends on whether yDiv[0] was zero or not. - for (j = yIsStretchable ? 1 : 0; - j <= numYDivs && src.top() < bitmapHeight; - j++, yIsStretchable = !yIsStretchable) { - src.setLeft(0); - dst.setLeft(bounds.left()); - if (j == numYDivs) { - src.setBottom(bitmapHeight); - dst.setBottom(bounds.bottom()); - } else { - src.setBottom(m_chunkData.yDivs[j]); - const int srcYSize = src.bottom() - src.top(); - if (yIsStretchable) { - dst.setBottom(dst.top() + calculateStretch(bounds.bottom(), dst.top(), - srcYSize, - numStretchyYPixelsRemaining, - numFixedYPixelsRemaining)); - numStretchyYPixelsRemaining -= srcYSize; - } else { - dst.setBottom(dst.top() + srcYSize); - numFixedYPixelsRemaining -= srcYSize; - } - } - - xIsStretchable = initialXIsStretchable; - // The initial xDiv and whether the first column is considered - // stretchable or not depends on whether xDiv[0] was zero or not. - for (i = xIsStretchable ? 1 : 0; - i <= numXDivs && src.left() < bitmapWidth; - i++, xIsStretchable = !xIsStretchable) { - color = m_chunkData.colors[colorIndex++]; - if (color != TRANSPARENT_COLOR) - color = NO_COLOR; - if (i == numXDivs) { - src.setRight(bitmapWidth); - dst.setRight(bounds.right()); - } else { - src.setRight(m_chunkData.xDivs[i]); - if (dstRightsHaveBeenCached) { - dst.setRight(dstRights[i]); - } else { - const int srcXSize = src.right() - src.left(); - if (xIsStretchable) { - dst.setRight(dst.left() + calculateStretch(bounds.right(), dst.left(), - srcXSize, - numStretchyXPixelsRemaining, - numFixedXPixelsRemaining)); - numStretchyXPixelsRemaining -= srcXSize; - } else { - dst.setRight(dst.left() + srcXSize); - numFixedXPixelsRemaining -= srcXSize; - } - dstRights[i] = dst.right(); - } - } - // If this horizontal patch is too small to be displayed, leave - // the destination left edge where it is and go on to the next patch - // in the source. - if (src.left() >= src.right()) { - src.setLeft(src.right()); - continue; - } - // Make sure that we actually have room to draw any bits - if (dst.right() <= dst.left() || dst.bottom() <= dst.top()) { - goto nextDiv; - } - // If this patch is transparent, skip and don't draw. - if (color == TRANSPARENT_COLOR) - goto nextDiv; - if (color != NO_COLOR) - painter->fillRect(dst, QRgb(color)); - else - painter->drawPixmap(dst, pixmap, src); -nextDiv: - src.setLeft(src.right()); - dst.setLeft(dst.right()); - } - src.setTop(src.bottom()); - dst.setTop(dst.bottom()); - dstRightsHaveBeenCached = true; - } - painter->setRenderHints(savedHints); -} - -QAndroidStyle::AndroidGradientDrawable::AndroidGradientDrawable(const QVariantMap &drawable, - QAndroidStyle::ItemType itemType) - : AndroidDrawable(drawable, itemType), m_orientation(TOP_BOTTOM) -{ - m_radius = drawable.value(QLatin1String("radius")).toInt(); - if (m_radius < 0) - m_radius = 0; - - QVariantList colors = drawable.value(QLatin1String("colors")).toList(); - QVariantList positions = drawable.value(QLatin1String("positions")).toList(); - int min = colors.size() < positions.size() ? colors.size() : positions.size(); - for (int i = 0; i < min; i++) - m_gradient.setColorAt(positions.at(i).toDouble(), QRgb(colors.at(i).toInt())); - - QByteArray orientation = drawable.value(QLatin1String("orientation")).toByteArray(); - if (orientation == "TOP_BOTTOM") // draw the gradient from the top to the bottom - m_orientation = TOP_BOTTOM; - else if (orientation == "TR_BL") // draw the gradient from the top-right to the bottom-left - m_orientation = TR_BL; - else if (orientation == "RIGHT_LEFT") // draw the gradient from the right to the left - m_orientation = RIGHT_LEFT; - else if (orientation == "BR_TL") // draw the gradient from the bottom-right to the top-left - m_orientation = BR_TL; - else if (orientation == "BOTTOM_TOP") // draw the gradient from the bottom to the top - m_orientation = BOTTOM_TOP; - else if (orientation == "BL_TR") // draw the gradient from the bottom-left to the top-right - m_orientation = BL_TR; - else if (orientation == "LEFT_RIGHT") // draw the gradient from the left to the right - m_orientation = LEFT_RIGHT; - else if (orientation == "TL_BR") // draw the gradient from the top-left to the bottom-right - m_orientation = TL_BR; - else - qWarning("AndroidGradientDrawable: unknown orientation"); -} - -QAndroidStyle::AndroidDrawableType QAndroidStyle::AndroidGradientDrawable::type() const -{ - return QAndroidStyle::Gradient; -} - -void QAndroidStyle::AndroidGradientDrawable::draw(QPainter *painter, const QStyleOption *opt) const -{ - const int width = opt->rect.width(); - const int height = opt->rect.height(); - switch (m_orientation) { - case TOP_BOTTOM: - // draw the gradient from the top to the bottom - m_gradient.setStart(width / 2, 0); - m_gradient.setFinalStop(width / 2, height); - break; - case TR_BL: - // draw the gradient from the top-right to the bottom-left - m_gradient.setStart(width, 0); - m_gradient.setFinalStop(0, height); - break; - case RIGHT_LEFT: - // draw the gradient from the right to the left - m_gradient.setStart(width, height / 2); - m_gradient.setFinalStop(0, height / 2); - break; - case BR_TL: - // draw the gradient from the bottom-right to the top-left - m_gradient.setStart(width, height); - m_gradient.setFinalStop(0, 0); - break; - case BOTTOM_TOP: - // draw the gradient from the bottom to the top - m_gradient.setStart(width / 2, height); - m_gradient.setFinalStop(width / 2, 0); - break; - case BL_TR: - // draw the gradient from the bottom-left to the top-right - m_gradient.setStart(0, height); - m_gradient.setFinalStop(width, 0); - break; - case LEFT_RIGHT: - // draw the gradient from the left to the right - m_gradient.setStart(0, height / 2); - m_gradient.setFinalStop(width, height / 2); - break; - case TL_BR: - // draw the gradient from the top-left to the bottom-right - m_gradient.setStart(0, 0); - m_gradient.setFinalStop(width, height); - break; - } - - const QBrush &oldBrush = painter->brush(); - const QPen oldPen = painter->pen(); - painter->setPen(Qt::NoPen); - painter->setBrush(m_gradient); - painter->drawRoundedRect(opt->rect, m_radius, m_radius); - painter->setBrush(oldBrush); - painter->setPen(oldPen); -} - -QSize QAndroidStyle::AndroidGradientDrawable::size() const -{ - return QSize(m_radius * 2, m_radius * 2); -} - -QAndroidStyle::AndroidClipDrawable::AndroidClipDrawable(const QVariantMap &drawable, - QAndroidStyle::ItemType itemType) - : AndroidDrawable(drawable, itemType) -{ - m_drawable = fromMap(drawable.value(QLatin1String("drawable")).toMap(), itemType); - m_factor = 0; - m_orientation = Qt::Horizontal; -} - -QAndroidStyle::AndroidClipDrawable::~AndroidClipDrawable() -{ - delete m_drawable; -} - -QAndroidStyle::AndroidDrawableType QAndroidStyle::AndroidClipDrawable::type() const -{ - return QAndroidStyle::Clip; -} - -void QAndroidStyle::AndroidClipDrawable::setFactor(double factor, Qt::Orientation orientation) -{ - m_factor = factor; - m_orientation = orientation; -} - -void QAndroidStyle::AndroidClipDrawable::draw(QPainter *painter, const QStyleOption *opt) const -{ - QStyleOption copy(*opt); - if (m_orientation == Qt::Horizontal) - copy.rect.setWidth(copy.rect.width() * m_factor); - else - copy.rect.setHeight(copy.rect.height() * m_factor); - - m_drawable->draw(painter, ©); -} - -QAndroidStyle::AndroidStateDrawable::AndroidStateDrawable(const QVariantMap &drawable, - QAndroidStyle::ItemType itemType) - : AndroidDrawable(drawable, itemType) -{ - const QVariantList states = drawable.value(QLatin1String("stateslist")).toList(); - for (const QVariant &stateVariant : states) { - QVariantMap state = stateVariant.toMap(); - const int s = extractState(state.value(QLatin1String("states")).toMap()); - if (-1 == s) - continue; - const AndroidDrawable *ad = fromMap(state.value(QLatin1String("drawable")).toMap(), itemType); - if (!ad) - continue; - StateType item; - item.first = s; - item.second = ad; - m_states<<item; - } -} - -QAndroidStyle::AndroidStateDrawable::~AndroidStateDrawable() -{ - for (const StateType &type : qAsConst(m_states)) - delete type.second; -} - -QAndroidStyle::AndroidDrawableType QAndroidStyle::AndroidStateDrawable::type() const -{ - return QAndroidStyle::State; -} - -void QAndroidStyle::AndroidStateDrawable::draw(QPainter *painter, const QStyleOption *opt) const -{ - const AndroidDrawable *drawable = bestAndroidStateMatch(opt); - if (drawable) - drawable->draw(painter, opt); -} -QSize QAndroidStyle::AndroidStateDrawable::sizeImage(const QStyleOption *opt) const -{ - QSize s; - const AndroidDrawable *drawable = bestAndroidStateMatch(opt); - if (drawable) - s = drawable->size(); - return s; -} - -const QAndroidStyle::AndroidDrawable * QAndroidStyle::AndroidStateDrawable::bestAndroidStateMatch(const QStyleOption *opt) const -{ - const AndroidDrawable *bestMatch = 0; - if (!opt) { - if (m_states.size()) - return m_states[0].second; - return bestMatch; - } - - uint bestCost = 0xffff; - for (const StateType & state : m_states) { - if (int(opt->state) == state.first) - return state.second; - uint cost = 1; - - int difference = int(opt->state^state.first); - - if (difference & QStyle::State_Active) - cost <<= 1; - - if (difference & QStyle::State_Enabled) - cost <<= 1; - - if (difference & QStyle::State_Raised) - cost <<= 1; - - if (difference & QStyle::State_Sunken) - cost <<= 1; - - if (difference & QStyle::State_Off) - cost <<= 1; - - if (difference & QStyle::State_On) - cost <<= 1; - - if (difference & QStyle::State_HasFocus) - cost <<= 1; - - if (difference & QStyle::State_Selected) - cost <<= 1; - - if (cost < bestCost) { - bestCost = cost; - bestMatch = state.second; - } - } - return bestMatch; -} - -int QAndroidStyle::AndroidStateDrawable::extractState(const QVariantMap &value) -{ - QStyle::State state = QStyle::State_Enabled | QStyle::State_Active;; - for (auto it = value.cbegin(), end = value.cend(); it != end; ++it) { - const QString &key = it.key(); - bool val = it.value().toString() == QLatin1String("true"); - if (key == QLatin1String("enabled")) { - state.setFlag(QStyle::State_Enabled, val); - continue; - } - - if (key == QLatin1String("window_focused")) { - state.setFlag(QStyle::State_Active, val); - continue; - } - - if (key == QLatin1String("focused")) { - state.setFlag(QStyle::State_HasFocus, val); - continue; - } - - if (key == QLatin1String("checked")) { - state |= val ? QStyle::State_On : QStyle::State_Off; - continue; - } - - if (key == QLatin1String("pressed")) { - state |= val ? QStyle::State_Sunken : QStyle::State_Raised; - continue; - } - - if (key == QLatin1String("selected")) { - state.setFlag(QStyle::State_Selected, val); - continue; - } - - if (key == QLatin1String("active")) { - state.setFlag(QStyle::State_Active, val); - continue; - } - - if (key == QLatin1String("multiline")) - return 0; - - if (key == QLatin1String("background") && val) - return -1; - } - return static_cast<int>(state); -} - -void QAndroidStyle::AndroidStateDrawable::setPaddingLeftToSizeWidth() -{ - for (const StateType &type : qAsConst(m_states)) - const_cast<AndroidDrawable *>(type.second)->setPaddingLeftToSizeWidth(); -} - -QAndroidStyle::AndroidLayerDrawable::AndroidLayerDrawable(const QVariantMap &drawable, - QAndroidStyle::ItemType itemType) - : AndroidDrawable(drawable, itemType) -{ - m_id = 0; - m_factor = 1; - m_orientation = Qt::Horizontal; - const QVariantList layers = drawable.value(QLatin1String("layers")).toList(); - for (const QVariant &layer : layers) { - QVariantMap layerMap = layer.toMap(); - AndroidDrawable *ad = fromMap(layerMap, itemType); - if (ad) { - LayerType l; - l.second = ad; - l.first = layerMap.value(QLatin1String("id")).toInt(); - m_layers << l; - } - } -} - -QAndroidStyle::AndroidLayerDrawable::~AndroidLayerDrawable() -{ - for (const LayerType &layer : qAsConst(m_layers)) - delete layer.second; -} - -QAndroidStyle::AndroidDrawableType QAndroidStyle::AndroidLayerDrawable::type() const -{ - return QAndroidStyle::Layer; -} - -void QAndroidStyle::AndroidLayerDrawable::setFactor(int id, double factor, Qt::Orientation orientation) -{ - m_id = id; - m_factor = factor; - m_orientation = orientation; -} - -void QAndroidStyle::AndroidLayerDrawable::draw(QPainter *painter, const QStyleOption *opt) const -{ - for (const LayerType &layer : m_layers) { - if (layer.first == m_id) { - QStyleOption copy(*opt); - if (m_orientation == Qt::Horizontal) - copy.rect.setWidth(copy.rect.width() * m_factor); - else - copy.rect.setHeight(copy.rect.height() * m_factor); - layer.second->draw(painter, ©); - } else { - layer.second->draw(painter, opt); - } - } -} - -QAndroidStyle::AndroidDrawable *QAndroidStyle::AndroidLayerDrawable::layer(int id) const -{ - for (const LayerType &layer : m_layers) - if (layer.first == id) - return layer.second; - return 0; -} - -QSize QAndroidStyle::AndroidLayerDrawable::size() const -{ - QSize sz; - for (const LayerType &layer : m_layers) - sz = sz.expandedTo(layer.second->size()); - return sz; -} - -QAndroidStyle::AndroidControl::AndroidControl(const QVariantMap &control, - QAndroidStyle::ItemType itemType) -{ - QVariantMap::const_iterator it = control.find(QLatin1String("View_background")); - if (it != control.end()) - m_background = AndroidDrawable::fromMap(it.value().toMap(), itemType); - else - m_background = 0; - - it = control.find(QLatin1String("View_minWidth")); - if (it != control.end()) - m_minSize.setWidth(it.value().toInt()); - - it = control.find(QLatin1String("View_minHeight")); - if (it != control.end()) - m_minSize.setHeight(it.value().toInt()); - - it = control.find(QLatin1String("View_maxWidth")); - if (it != control.end()) - m_maxSize.setWidth(it.value().toInt()); - - it = control.find(QLatin1String("View_maxHeight")); - if (it != control.end()) - m_maxSize.setHeight(it.value().toInt()); -} - -QAndroidStyle::AndroidControl::~AndroidControl() -{ - delete m_background; -} - -void QAndroidStyle::AndroidControl::drawControl(const QStyleOption *opt, QPainter *p, const QWidget * /* w */) -{ - if (m_background) { - m_background->draw(p, opt); - } else { - if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) { - if ((frame->state & State_Sunken) || (frame->state & State_Raised)) { - qDrawShadePanel(p, frame->rect, frame->palette, frame->state & State_Sunken, - frame->lineWidth); - } else { - qDrawPlainRect(p, frame->rect, frame->palette.foreground().color(), frame->lineWidth); - } - } else { - if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(opt)) { - QColor bg = fropt->backgroundColor; - QPen oldPen = p->pen(); - if (bg.isValid()) { - int h, s, v; - bg.getHsv(&h, &s, &v); - if (v >= 128) - p->setPen(Qt::black); - else - p->setPen(Qt::white); - } else { - p->setPen(opt->palette.foreground().color()); - } - QRect focusRect = opt->rect.adjusted(1, 1, -1, -1); - p->drawRect(focusRect.adjusted(0, 0, -1, -1)); //draw pen inclusive - p->setPen(oldPen); - } else { - p->fillRect(opt->rect, opt->palette.brush(QPalette::Background)); - } - } - } -} - -QRect QAndroidStyle::AndroidControl::subElementRect(QStyle::SubElement /* subElement */, - const QStyleOption *option, - const QWidget * /* widget */) const -{ - if (const AndroidDrawable *drawable = backgroundDrawable()) { - if (drawable->type() == State) - drawable = static_cast<const AndroidStateDrawable *>(backgroundDrawable())->bestAndroidStateMatch(option); - - const QMargins &padding = drawable->padding(); - - QRect r = option->rect.adjusted(padding.left(), padding.top(), - -padding.right(), -padding.bottom()); - - if (r.width() < m_minSize.width()) - r.setWidth(m_minSize.width()); - - if (r.height() < m_minSize.height()) - r.setHeight(m_minSize.height()); - - return visualRect(option->direction, option->rect, r); - } - return option->rect; -} - -QRect QAndroidStyle::AndroidControl::subControlRect(const QStyleOptionComplex *option, - QStyle::SubControl /*sc*/, - const QWidget *widget) const -{ - return subElementRect(QStyle::SE_CustomBase, option, widget); -} - -QSize QAndroidStyle::AndroidControl::sizeFromContents(const QStyleOption *opt, - const QSize &contentsSize, - const QWidget * /* w */) const -{ - QSize sz; - if (const AndroidDrawable *drawable = backgroundDrawable()) { - - if (drawable->type() == State) - drawable = static_cast<const AndroidStateDrawable*>(backgroundDrawable())->bestAndroidStateMatch(opt); - const QMargins &padding = drawable->padding(); - sz.setWidth(padding.left() + padding.right()); - sz.setHeight(padding.top() + padding.bottom()); - if (sz.isEmpty()) - sz = drawable->size(); - } - sz += contentsSize; - if (contentsSize.height() < opt->fontMetrics.height()) - sz.setHeight(sz.height() + (opt->fontMetrics.height() - contentsSize.height())); - if (sz.height() < m_minSize.height()) - sz.setHeight(m_minSize.height()); - if (sz.width() < m_minSize.width()) - sz.setWidth(m_minSize.width()); - return sz; -} - -QMargins QAndroidStyle::AndroidControl::padding() -{ - if (const AndroidDrawable *drawable = m_background) { - if (drawable->type() == State) - drawable = static_cast<const AndroidStateDrawable *>(m_background)->bestAndroidStateMatch(0); - return drawable->padding(); - } - return QMargins(); -} - -QSize QAndroidStyle::AndroidControl::size(const QStyleOption *option) -{ - if (const AndroidDrawable *drawable = backgroundDrawable()) { - if (drawable->type() == State) - drawable = static_cast<const AndroidStateDrawable *>(backgroundDrawable())->bestAndroidStateMatch(option); - return drawable->size(); - } - return QSize(); -} - -const QAndroidStyle::AndroidDrawable *QAndroidStyle::AndroidControl::backgroundDrawable() const -{ - return m_background; -} - -QAndroidStyle::AndroidCompoundButtonControl::AndroidCompoundButtonControl(const QVariantMap &control, - ItemType itemType) - : AndroidControl(control, itemType) -{ - QVariantMap::const_iterator it = control.find(QLatin1String("CompoundButton_button")); - if (it != control.end()) { - m_button = AndroidDrawable::fromMap(it.value().toMap(), itemType); - const_cast<AndroidDrawable *>(m_button)->setPaddingLeftToSizeWidth(); - } else { - m_button = 0; - } -} - -QAndroidStyle::AndroidCompoundButtonControl::~AndroidCompoundButtonControl() -{ - delete m_button; -} - -void QAndroidStyle::AndroidCompoundButtonControl::drawControl(const QStyleOption *opt, - QPainter *p, - const QWidget *w) -{ - AndroidControl::drawControl(opt, p, w); - if (m_button) - m_button->draw(p, opt); -} - -QMargins QAndroidStyle::AndroidCompoundButtonControl::padding() -{ - if (m_button) - return m_button->padding(); - return AndroidControl::padding(); -} - -QSize QAndroidStyle::AndroidCompoundButtonControl::size(const QStyleOption *option) -{ - if (m_button) { - if (m_button->type() == State) - return static_cast<const AndroidStateDrawable *>(m_button)->bestAndroidStateMatch(option)->size(); - return m_button->size(); - } - return AndroidControl::size(option); -} - -const QAndroidStyle::AndroidDrawable * QAndroidStyle::AndroidCompoundButtonControl::backgroundDrawable() const -{ - return m_background ? m_background : m_button; -} - -QAndroidStyle::AndroidProgressBarControl::AndroidProgressBarControl(const QVariantMap &control, - ItemType itemType) - : AndroidControl(control, itemType) -{ - QVariantMap::const_iterator it = control.find(QLatin1String("ProgressBar_indeterminateDrawable")); - if (it != control.end()) - m_indeterminateDrawable = AndroidDrawable::fromMap(it.value().toMap(), itemType); - else - m_indeterminateDrawable = 0; - - it = control.find(QLatin1String("ProgressBar_progressDrawable")); - if (it != control.end()) - m_progressDrawable = AndroidDrawable::fromMap(it.value().toMap(), itemType); - else - m_progressDrawable = 0; - - it = control.find(QLatin1String("ProgressBar_progress_id")); - if (it != control.end()) - m_progressId = it.value().toInt(); - - it = control.find(QLatin1String("ProgressBar_secondaryProgress_id")); - if (it != control.end()) - m_secondaryProgress_id = it.value().toInt(); - - it = control.find(QLatin1String("ProgressBar_minWidth")); - if (it != control.end()) - m_minSize.setWidth(it.value().toInt()); - - it = control.find(QLatin1String("ProgressBar_minHeight")); - if (it != control.end()) - m_minSize.setHeight(it.value().toInt()); - - it = control.find(QLatin1String("ProgressBar_maxWidth")); - if (it != control.end()) - m_maxSize.setWidth(it.value().toInt()); - - it = control.find(QLatin1String("ProgressBar_maxHeight")); - if (it != control.end()) - m_maxSize.setHeight(it.value().toInt()); -} - -QAndroidStyle::AndroidProgressBarControl::~AndroidProgressBarControl() -{ - delete m_progressDrawable; - delete m_indeterminateDrawable; -} - -void QAndroidStyle::AndroidProgressBarControl::drawControl(const QStyleOption *option, QPainter *p, const QWidget * /* w */) -{ - if (!m_progressDrawable) - return; - - if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) { - if (m_progressDrawable->type() == QAndroidStyle::Layer) { - const double fraction = double(qint64(pb->progress) - pb->minimum) / (qint64(pb->maximum) - pb->minimum); - QAndroidStyle::AndroidDrawable *clipDrawable = static_cast<QAndroidStyle::AndroidLayerDrawable *>(m_progressDrawable)->layer(m_progressId); - if (clipDrawable->type() == QAndroidStyle::Clip) - static_cast<AndroidClipDrawable *>(clipDrawable)->setFactor(fraction, pb->orientation); - else - static_cast<AndroidLayerDrawable *>(m_progressDrawable)->setFactor(m_progressId, fraction, pb->orientation); - } - m_progressDrawable->draw(p, option); - } -} - -QRect QAndroidStyle::AndroidProgressBarControl::subElementRect(QStyle::SubElement subElement, - const QStyleOption *option, - const QWidget *widget) const -{ - if (const QStyleOptionProgressBar *progressBarOption = - qstyleoption_cast<const QStyleOptionProgressBar *>(option)) { - const bool horizontal = progressBarOption->orientation == Qt::Vertical; - if (!m_background) - return option->rect; - - QMargins padding = m_background->padding(); - QRect p(padding.left(), padding.top(), padding.right() - padding.left(), padding.bottom() - padding.top()); - padding = m_indeterminateDrawable->padding(); - p |= QRect(padding.left(), padding.top(), padding.right() - padding.left(), padding.bottom() - padding.top()); - padding = m_progressDrawable->padding(); - p |= QRect(padding.left(), padding.top(), padding.right() - padding.left(), padding.bottom() - padding.top()); - QRect r = option->rect.adjusted(p.left(), p.top(), -p.right(), -p.bottom()); - - if (horizontal) { - if (r.height()<m_minSize.height()) - r.setHeight(m_minSize.height()); - - if (r.height()>m_maxSize.height()) - r.setHeight(m_maxSize.height()); - } else { - if (r.width()<m_minSize.width()) - r.setWidth(m_minSize.width()); - - if (r.width()>m_maxSize.width()) - r.setWidth(m_maxSize.width()); - } - return visualRect(option->direction, option->rect, r); - } - return AndroidControl::subElementRect(subElement, option, widget); -} - -QSize QAndroidStyle::AndroidProgressBarControl::sizeFromContents(const QStyleOption *opt, - const QSize &contentsSize, - const QWidget * /* w */) const -{ - QSize sz(contentsSize); - if (sz.height() < m_minSize.height()) - sz.setHeight(m_minSize.height()); - if (sz.width() < m_minSize.width()) - sz.setWidth(m_minSize.width()); - - if (const QStyleOptionProgressBar *progressBarOption = - qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) { - if (progressBarOption->orientation == Qt::Vertical) { - if (sz.height() > m_maxSize.height()) - sz.setHeight(m_maxSize.height()); - } else { - if (sz.width() > m_maxSize.width()) - sz.setWidth(m_maxSize.width()); - } - } - return contentsSize; -} - -QAndroidStyle::AndroidSeekBarControl::AndroidSeekBarControl(const QVariantMap &control, - ItemType itemType) - : AndroidProgressBarControl(control, itemType) -{ - QVariantMap::const_iterator it = control.find(QLatin1String("SeekBar_thumb")); - if (it != control.end()) - m_seekBarThumb = AndroidDrawable::fromMap(it.value().toMap(), itemType); - else - m_seekBarThumb = 0; -} - -QAndroidStyle::AndroidSeekBarControl::~AndroidSeekBarControl() -{ - delete m_seekBarThumb; -} - -void QAndroidStyle::AndroidSeekBarControl::drawControl(const QStyleOption *option, - QPainter *p, - const QWidget * /* w */) -{ - if (!m_seekBarThumb || !m_progressDrawable) - return; - - if (const QStyleOptionSlider *styleOption = - qstyleoption_cast<const QStyleOptionSlider *>(option)) { - double factor = double(styleOption->sliderPosition - styleOption->minimum) - / double(styleOption->maximum - styleOption->minimum); - - // Android does not have a vertical slider. To support the vertical orientation, we rotate - // the painter and pretend that we are horizontal. - if (styleOption->orientation == Qt::Vertical) - factor = 1 - factor; - - if (m_progressDrawable->type() == QAndroidStyle::Layer) { - QAndroidStyle::AndroidDrawable *clipDrawable = static_cast<QAndroidStyle::AndroidLayerDrawable *>(m_progressDrawable)->layer(m_progressId); - if (clipDrawable->type() == QAndroidStyle::Clip) - static_cast<QAndroidStyle::AndroidClipDrawable *>(clipDrawable)->setFactor(factor, Qt::Horizontal); - else - static_cast<QAndroidStyle::AndroidLayerDrawable *>(m_progressDrawable)->setFactor(m_progressId, factor, Qt::Horizontal); - } - const AndroidDrawable *drawable = m_seekBarThumb; - if (drawable->type() == State) - drawable = static_cast<const QAndroidStyle::AndroidStateDrawable *>(m_seekBarThumb)->bestAndroidStateMatch(option); - QStyleOption copy(*option); - - p->save(); - - if (styleOption->orientation == Qt::Vertical) { - // rotate the painter, and transform the rectangle to match - p->rotate(90); - copy.rect = QRect(copy.rect.y(), copy.rect.x() - copy.rect.width(), copy.rect.height(), copy.rect.width()); - } - - copy.rect.setHeight(m_progressDrawable->size().height()); - copy.rect.setWidth(copy.rect.width() - drawable->size().width()); - const int yTranslate = abs(drawable->size().height() - copy.rect.height()) / 2; - copy.rect.translate(drawable->size().width() / 2, yTranslate); - m_progressDrawable->draw(p, ©); - int pos = copy.rect.width() * factor - drawable->size().width() / 2; - copy.rect.translate(pos, -yTranslate); - copy.rect.setSize(drawable->size()); - m_seekBarThumb->draw(p, ©); - - p->restore(); - } -} - -QSize QAndroidStyle::AndroidSeekBarControl::sizeFromContents(const QStyleOption *opt, - const QSize &contentsSize, - const QWidget *w) const -{ - QSize sz = AndroidProgressBarControl::sizeFromContents(opt, contentsSize, w); - if (!m_seekBarThumb) - return sz; - const AndroidDrawable *drawable = m_seekBarThumb; - if (drawable->type() == State) - drawable = static_cast<const QAndroidStyle::AndroidStateDrawable *>(m_seekBarThumb)->bestAndroidStateMatch(opt); - return sz.expandedTo(drawable->size()); -} - -QRect QAndroidStyle::AndroidSeekBarControl::subControlRect(const QStyleOptionComplex *option, - SubControl sc, - const QWidget * /* widget */) const -{ - const QStyleOptionSlider *styleOption = - qstyleoption_cast<const QStyleOptionSlider *>(option); - - if (m_seekBarThumb && sc == SC_SliderHandle && styleOption) { - const AndroidDrawable *drawable = m_seekBarThumb; - if (drawable->type() == State) - drawable = static_cast<const QAndroidStyle::AndroidStateDrawable *>(m_seekBarThumb)->bestAndroidStateMatch(option); - - QRect r(option->rect); - double factor = double(styleOption->sliderPosition - styleOption->minimum) - / (styleOption->maximum - styleOption->minimum); - if (styleOption->orientation == Qt::Vertical) { - int pos = option->rect.height() * (1 - factor) - double(drawable->size().height() / 2); - r.setY(r.y() + pos); - } else { - int pos = option->rect.width() * factor - double(drawable->size().width() / 2); - r.setX(r.x() + pos); - } - r.setSize(drawable->size()); - return r; - } - return option->rect; -} - -QAndroidStyle::AndroidSpinnerControl::AndroidSpinnerControl(const QVariantMap &control, - QAndroidStyle::ItemType itemType) - : AndroidControl(control, itemType) -{} - -QRect QAndroidStyle::AndroidSpinnerControl::subControlRect(const QStyleOptionComplex *option, - SubControl sc, - const QWidget *widget) const -{ - if (sc == QStyle::SC_ComboBoxListBoxPopup) - return option->rect; - if (sc == QStyle::SC_ComboBoxArrow) { - const QRect editField = subControlRect(option, QStyle::SC_ComboBoxEditField, widget); - return QRect(editField.topRight(), QSize(option->rect.width() - editField.width(), option->rect.height())); - } - return AndroidControl::subControlRect(option, sc, widget); -} - -QT_END_NAMESPACE - -#endif // QT_CONFIG(style_android) || defined(QT_PLUGIN) |