diff options
Diffstat (limited to 'src/widgets/styles')
54 files changed, 550 insertions, 10962 deletions
diff --git a/src/widgets/styles/images/closedock-10.png b/src/widgets/styles/images/closedock-10.png Binary files differnew file mode 100644 index 0000000000..ee2af34550 --- /dev/null +++ b/src/widgets/styles/images/closedock-10.png diff --git a/src/widgets/styles/images/closedock-16.png b/src/widgets/styles/images/closedock-16.png Binary files differindex ab9d669eee..570012fc9a 100644 --- a/src/widgets/styles/images/closedock-16.png +++ b/src/widgets/styles/images/closedock-16.png diff --git a/src/widgets/styles/images/closedock-20.png b/src/widgets/styles/images/closedock-20.png Binary files differnew file mode 100644 index 0000000000..b5ea92d1de --- /dev/null +++ b/src/widgets/styles/images/closedock-20.png diff --git a/src/widgets/styles/images/closedock-32.png b/src/widgets/styles/images/closedock-32.png Binary files differnew file mode 100644 index 0000000000..95a1ad014d --- /dev/null +++ b/src/widgets/styles/images/closedock-32.png diff --git a/src/widgets/styles/images/closedock-48.png b/src/widgets/styles/images/closedock-48.png Binary files differnew file mode 100644 index 0000000000..3ca36d1394 --- /dev/null +++ b/src/widgets/styles/images/closedock-48.png diff --git a/src/widgets/styles/images/closedock-64.png b/src/widgets/styles/images/closedock-64.png Binary files differnew file mode 100644 index 0000000000..cbec2052ad --- /dev/null +++ b/src/widgets/styles/images/closedock-64.png diff --git a/src/widgets/styles/images/closedock-down-16.png b/src/widgets/styles/images/closedock-down-macstyle-16.png Binary files differindex c1791dd2cc..c1791dd2cc 100644 --- a/src/widgets/styles/images/closedock-down-16.png +++ b/src/widgets/styles/images/closedock-down-macstyle-16.png diff --git a/src/widgets/styles/images/closedock-macstyle-16.png b/src/widgets/styles/images/closedock-macstyle-16.png Binary files differnew file mode 100644 index 0000000000..ab9d669eee --- /dev/null +++ b/src/widgets/styles/images/closedock-macstyle-16.png diff --git a/src/widgets/styles/images/dockdock-down-16.png b/src/widgets/styles/images/dockdock-down-macstyle-16.png Binary files differindex 2e85a679be..2e85a679be 100644 --- a/src/widgets/styles/images/dockdock-down-16.png +++ b/src/widgets/styles/images/dockdock-down-macstyle-16.png diff --git a/src/widgets/styles/images/dockdock-16.png b/src/widgets/styles/images/dockdock-macstyle-16.png Binary files differindex 4ac9483176..4ac9483176 100644 --- a/src/widgets/styles/images/dockdock-16.png +++ b/src/widgets/styles/images/dockdock-macstyle-16.png diff --git a/src/widgets/styles/images/fusion_arrow.png b/src/widgets/styles/images/fusion_arrow.png Binary files differdeleted file mode 100644 index d7945e7f76..0000000000 --- a/src/widgets/styles/images/fusion_arrow.png +++ /dev/null diff --git a/src/widgets/styles/images/normalizedockup-10.png b/src/widgets/styles/images/normalizedockup-10.png Binary files differnew file mode 100644 index 0000000000..f380c65035 --- /dev/null +++ b/src/widgets/styles/images/normalizedockup-10.png diff --git a/src/widgets/styles/images/normalizedockup-16.png b/src/widgets/styles/images/normalizedockup-16.png Binary files differnew file mode 100644 index 0000000000..1b795a9e84 --- /dev/null +++ b/src/widgets/styles/images/normalizedockup-16.png diff --git a/src/widgets/styles/images/normalizedockup-20.png b/src/widgets/styles/images/normalizedockup-20.png Binary files differnew file mode 100644 index 0000000000..857338427f --- /dev/null +++ b/src/widgets/styles/images/normalizedockup-20.png diff --git a/src/widgets/styles/images/normalizedockup-32.png b/src/widgets/styles/images/normalizedockup-32.png Binary files differnew file mode 100644 index 0000000000..d8993a1067 --- /dev/null +++ b/src/widgets/styles/images/normalizedockup-32.png diff --git a/src/widgets/styles/images/normalizedockup-48.png b/src/widgets/styles/images/normalizedockup-48.png Binary files differnew file mode 100644 index 0000000000..be48c9524c --- /dev/null +++ b/src/widgets/styles/images/normalizedockup-48.png diff --git a/src/widgets/styles/images/normalizedockup-64.png b/src/widgets/styles/images/normalizedockup-64.png Binary files differnew file mode 100644 index 0000000000..7b540f04f8 --- /dev/null +++ b/src/widgets/styles/images/normalizedockup-64.png 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) diff --git a/src/widgets/styles/qandroidstyle_p.h b/src/widgets/styles/qandroidstyle_p.h deleted file mode 100644 index caff0afada..0000000000 --- a/src/widgets/styles/qandroidstyle_p.h +++ /dev/null @@ -1,395 +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$ -** -****************************************************************************/ - -#ifndef QANDROIDSTYLE_P_H -#define QANDROIDSTYLE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of qstylefactory.cpp. This header may change from version to version -// without notice, or even be removed. -// -// We mean it. -// - -#include <QtWidgets/private/qtwidgetsglobal_p.h> -#include <QtCore/QList> -#include <QtCore/QMargins> -#include <QtCore/QHash> -#include <QtCore/QVariantMap> -#include "qfusionstyle_p.h" - -QT_BEGIN_NAMESPACE - -#if QT_CONFIG(style_android) - -class Q_WIDGETS_EXPORT QAndroidStyle : public QFusionStyle -{ - Q_OBJECT - -public: - enum ItemType - { - QC_UnknownType = -1, - QC_View, - QC_GroupBox, - QC_Button, - QC_Checkbox, - QC_RadioButton, - QC_Slider, - QC_Switch, - QC_EditText, - QC_Combobox, - QC_BusyIndicator, - QC_ProgressBar, - QC_Tab, - QC_TabButton, - QC_RatingIndicator, - QC_SearchBox, - QC_CustomControl=0xf00, - QC_ControlMask=0xfff - }; - - struct Android9PatchChunk - { - QVector<int> xDivs; - QVector<int> yDivs; - QVector<int> colors; - }; - - struct AndroidItemStateInfo - { - AndroidItemStateInfo():state(0){} - int state; - QByteArray filePath; - QByteArray hashKey; - Android9PatchChunk chunkData; - QSize size; - QMargins padding; - }; - - enum AndroidDrawableType - { - Color, - Image, - Clip, - NinePatch, - Gradient, - State, - Layer - }; - - class AndroidDrawable - { - public: - AndroidDrawable(const QVariantMap &drawable, ItemType itemType); - virtual ~AndroidDrawable(); - virtual void initPadding(const QVariantMap &drawable); - virtual AndroidDrawableType type() const = 0; - virtual void draw(QPainter *painter,const QStyleOption *opt) const = 0; - const QMargins &padding() const; - virtual QSize size() const; - static AndroidDrawable *fromMap(const QVariantMap &drawable, ItemType itemType); - static QMargins extractMargins(const QVariantMap &value); - virtual void setPaddingLeftToSizeWidth(); - protected: - ItemType m_itemType; - QMargins m_padding; - }; - - class AndroidColorDrawable: public AndroidDrawable - { - public: - AndroidColorDrawable(const QVariantMap &drawable, ItemType itemType); - virtual AndroidDrawableType type() const; - virtual void draw(QPainter *painter,const QStyleOption *opt) const; - - protected: - QColor m_color; - }; - - class AndroidImageDrawable: public AndroidDrawable - { - public: - AndroidImageDrawable(const QVariantMap &drawable, ItemType itemType); - virtual AndroidDrawableType type() const; - virtual void draw(QPainter *painter,const QStyleOption *opt) const; - virtual QSize size() const; - - protected: - QString m_filePath; - mutable QString m_hashKey; - QSize m_size; - }; - - class Android9PatchDrawable: public AndroidImageDrawable - { - public: - Android9PatchDrawable(const QVariantMap &drawable, ItemType itemType); - virtual AndroidDrawableType type() const; - virtual void draw(QPainter *painter, const QStyleOption *opt) const; - private: - static int calculateStretch(int boundsLimit, int startingPoint, - int srcSpace, int numStrechyPixelsRemaining, - int numFixedPixelsRemaining); - void extractIntArray(const QVariantList &values, QVector<int> &array); - private: - Android9PatchChunk m_chunkData; - }; - - class AndroidGradientDrawable: public AndroidDrawable - { - public: - enum GradientOrientation - { - TOP_BOTTOM, - TR_BL, - RIGHT_LEFT, - BR_TL, - BOTTOM_TOP, - BL_TR, - LEFT_RIGHT, - TL_BR - }; - - public: - AndroidGradientDrawable(const QVariantMap &drawable, ItemType itemType); - virtual AndroidDrawableType type() const; - virtual void draw(QPainter *painter, const QStyleOption *opt) const; - QSize size() const; - private: - mutable QLinearGradient m_gradient; - GradientOrientation m_orientation; - int m_radius; - }; - - class AndroidClipDrawable: public AndroidDrawable - { - public: - AndroidClipDrawable(const QVariantMap &drawable, ItemType itemType); - ~AndroidClipDrawable(); - virtual AndroidDrawableType type() const; - virtual void setFactor(double factor, Qt::Orientation orientation); - virtual void draw(QPainter *painter, const QStyleOption *opt) const; - - private: - double m_factor; - Qt::Orientation m_orientation; - const AndroidDrawable *m_drawable; - }; - - class AndroidStateDrawable: public AndroidDrawable - { - public: - AndroidStateDrawable(const QVariantMap &drawable, ItemType itemType); - ~AndroidStateDrawable(); - virtual AndroidDrawableType type() const; - virtual void draw(QPainter *painter, const QStyleOption *opt) const; - inline const AndroidDrawable *bestAndroidStateMatch(const QStyleOption *opt) const; - static int extractState(const QVariantMap &value); - virtual void setPaddingLeftToSizeWidth(); - QSize sizeImage(const QStyleOption *opt) const; - private: - typedef QPair<int, const AndroidDrawable *> StateType; - QList<StateType> m_states; - }; - - class AndroidLayerDrawable: public AndroidDrawable - { - public: - AndroidLayerDrawable(const QVariantMap &drawable, QAndroidStyle::ItemType itemType); - ~AndroidLayerDrawable(); - virtual AndroidDrawableType type() const; - virtual void setFactor(int id, double factor, Qt::Orientation orientation); - virtual void draw(QPainter *painter, const QStyleOption *opt) const; - AndroidDrawable *layer(int id) const; - QSize size() const; - private: - typedef QPair<int, AndroidDrawable *> LayerType; - QList<LayerType> m_layers; - int m_id; - double m_factor; - Qt::Orientation m_orientation; - }; - - class AndroidControl - { - public: - AndroidControl(const QVariantMap &control, ItemType itemType); - virtual ~AndroidControl(); - virtual void drawControl(const QStyleOption *opt, QPainter *p, const QWidget *w); - virtual QRect subElementRect(SubElement subElement, - const QStyleOption *option, - const QWidget *widget = 0) const; - virtual QRect subControlRect(const QStyleOptionComplex *option, - SubControl sc, - const QWidget *widget = 0) const; - virtual QSize sizeFromContents(const QStyleOption *opt, - const QSize &contentsSize, - const QWidget *w) const; - virtual QMargins padding(); - virtual QSize size(const QStyleOption *option); - protected: - virtual const AndroidDrawable * backgroundDrawable() const; - const AndroidDrawable *m_background; - QSize m_minSize; - QSize m_maxSize; - }; - - class AndroidCompoundButtonControl : public AndroidControl - { - public: - AndroidCompoundButtonControl(const QVariantMap &control, ItemType itemType); - virtual ~AndroidCompoundButtonControl(); - virtual void drawControl(const QStyleOption *opt, QPainter *p, const QWidget *w); - virtual QMargins padding(); - virtual QSize size(const QStyleOption *option); - protected: - virtual const AndroidDrawable * backgroundDrawable() const; - const AndroidDrawable *m_button; - }; - - class AndroidProgressBarControl : public AndroidControl - { - public: - AndroidProgressBarControl(const QVariantMap &control, ItemType itemType); - virtual ~AndroidProgressBarControl(); - virtual void drawControl(const QStyleOption *option, QPainter *p, const QWidget *w); - virtual QRect subElementRect(SubElement subElement, - const QStyleOption *option, - const QWidget *widget = 0) const; - - QSize sizeFromContents(const QStyleOption *opt, - const QSize &contentsSize, - const QWidget *w) const; - protected: - AndroidDrawable *m_progressDrawable; - AndroidDrawable *m_indeterminateDrawable; - int m_secondaryProgress_id; - int m_progressId; - }; - - class AndroidSeekBarControl : public AndroidProgressBarControl - { - public: - AndroidSeekBarControl(const QVariantMap &control, ItemType itemType); - virtual ~AndroidSeekBarControl(); - virtual void drawControl(const QStyleOption *option, QPainter *p, const QWidget *w); - QSize sizeFromContents(const QStyleOption *opt, - const QSize &contentsSize, const QWidget *w) const; - QRect subControlRect(const QStyleOptionComplex *option, SubControl sc, - const QWidget *widget = 0) const; - private: - AndroidDrawable *m_seekBarThumb; - }; - - class AndroidSpinnerControl : public AndroidControl - { - public: - AndroidSpinnerControl(const QVariantMap &control, ItemType itemType); - virtual ~AndroidSpinnerControl(){} - virtual QRect subControlRect(const QStyleOptionComplex *option, - SubControl sc, - const QWidget *widget = 0) const; - }; - - typedef QList<AndroidItemStateInfo *> AndroidItemStateInfoList; - -public: - QAndroidStyle(); - ~QAndroidStyle(); - - virtual void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, - const QWidget *w = 0) const; - - virtual void drawControl(QStyle::ControlElement element, const QStyleOption *opt, QPainter *p, - const QWidget *w = 0) const; - - virtual QRect subElementRect(SubElement subElement, const QStyleOption *option, - const QWidget *widget = 0) const; - virtual void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, - const QWidget *widget = 0) const; - virtual SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, - const QPoint &pt, const QWidget *widget = 0) const; - virtual QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, - SubControl sc, const QWidget *widget = 0) const; - - virtual int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, - const QWidget *widget = 0) const; - - virtual QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, - const QSize &contentsSize, const QWidget *w = 0) const; - - virtual QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt = 0, - const QWidget *widget = 0) const; - - virtual QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, - const QStyleOption *opt) const; - - int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0, - QStyleHintReturn *returnData = 0) const; - - virtual QPalette standardPalette() const; - void polish(QWidget *widget); - void unpolish(QWidget *widget); - -private: - Q_DISABLE_COPY(QAndroidStyle) - static ItemType qtControl(QStyle::ComplexControl control); - static ItemType qtControl(QStyle::ContentsType contentsType); - static ItemType qtControl(QStyle::ControlElement controlElement); - static ItemType qtControl(QStyle::PrimitiveElement primitiveElement); - static ItemType qtControl(QStyle::SubElement subElement); - static ItemType qtControl(const QString &android); - -private: - typedef QHash<int, AndroidControl *> AndroidControlsHash; - AndroidControlsHash m_androidControlsHash; - QPalette m_standardPalette; - AndroidCompoundButtonControl *checkBoxControl; -}; - -#endif // style_android - -QT_END_NAMESPACE - -#endif // QANDROIDSTYLE_P_H diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 4a6a7bce4b..557277b9e0 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -743,8 +743,9 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q % QLatin1String(metaObject()->className()), opt, QSize(size, size)) % HexString<uint>(pe); if (!QPixmapCache::find(pixmapName, pixmap)) { - int border = size/5; - int sqsize = 2*(size/2); + qreal pixelRatio = p->device()->devicePixelRatioF(); + int border = qRound(pixelRatio*(size/5)); + int sqsize = qRound(pixelRatio*(2*(size/2))); QImage image(sqsize, sqsize, QImage::Format_ARGB32_Premultiplied); image.fill(0); QPainter imagePainter(&image); @@ -796,6 +797,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q imagePainter.drawPolygon(a); imagePainter.end(); pixmap = QPixmap::fromImage(image); + pixmap.setDevicePixelRatio(pixelRatio); QPixmapCache::insert(pixmapName, pixmap); } int xOffset = r.x() + (r.width() - size)/2; @@ -889,6 +891,13 @@ QSize QCommonStylePrivate::viewItemSize(const QStyleOptionViewItem *option, int break; } + if (wrapText) { + if (option->features & QStyleOptionViewItem::HasCheckIndicator) + bounds.setWidth(bounds.width() - proxyStyle->pixelMetric(QStyle::PM_IndicatorWidth) - 2 * textMargin); + if (option->features & QStyleOptionViewItem::HasDecoration) + bounds.setWidth(bounds.width() - option->decorationSize.width() - 2 * textMargin); + } + const int lineWidth = bounds.width(); const QSizeF size = viewItemTextLayout(textLayout, lineWidth); return QSize(qCeil(size.width()) + 2 * textMargin, qCeil(size.height())); @@ -994,11 +1003,14 @@ void QCommonStylePrivate::viewItemLayout(const QStyleOptionViewItem *opt, QRect const bool hasCheck = checkRect->isValid(); const bool hasPixmap = pixmapRect->isValid(); const bool hasText = textRect->isValid(); - const int textMargin = hasText ? proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0; - const int pixmapMargin = hasPixmap ? proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0; - const int checkMargin = hasCheck ? proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0; - int x = opt->rect.left(); - int y = opt->rect.top(); + const bool hasMargin = (hasText | hasPixmap | hasCheck); + const int frameHMargin = hasMargin ? + proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0; + const int textMargin = hasText ? frameHMargin : 0; + const int pixmapMargin = hasPixmap ? frameHMargin : 0; + const int checkMargin = hasCheck ? frameHMargin : 0; + const int x = opt->rect.left(); + const int y = opt->rect.top(); int w, h; if (textRect->height() == 0 && (!hasPixmap || !sizehint)) { @@ -1571,10 +1583,11 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, aligned.width() * pixmap.devicePixelRatio(), pixmap.height() * pixmap.devicePixelRatio()); + const int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, opt, widget); if (header->direction == Qt::LeftToRight) - rect.setLeft(rect.left() + pixw + 2); + rect.setLeft(rect.left() + pixw + margin); else - rect.setRight(rect.right() - pixw - 2); + rect.setRight(rect.right() - pixw - margin); } if (header->state & QStyle::State_On) { QFont fnt = p->font(); @@ -2499,7 +2512,7 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt, const bool vertical = pb->orientation == Qt::Vertical; if (!vertical) { if (pb->textVisible) - textw = qMax(pb->fontMetrics.width(pb->text), pb->fontMetrics.width(QLatin1String("100%"))) + 6; + textw = qMax(pb->fontMetrics.horizontalAdvance(pb->text), pb->fontMetrics.horizontalAdvance(QLatin1String("100%"))) + 6; } if ((pb->textAlignment & Qt::AlignCenter) == 0) { @@ -3411,6 +3424,7 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl QRect ir = toolbutton->rect; QStyleOptionToolButton newBtn = *toolbutton; newBtn.rect = QRect(ir.right() + 5 - mbi, ir.y() + ir.height() - mbi + 4, mbi - 6, mbi - 6); + newBtn.rect = visualRect(toolbutton->direction, button, newBtn.rect); proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget); } } @@ -4154,14 +4168,10 @@ QRect QCommonStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex #if QT_CONFIG(combobox) case CC_ComboBox: if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) { - int x = cb->rect.x(), - y = cb->rect.y(), - wi = cb->rect.width(), - he = cb->rect.height(); - int xpos = x; - int margin = cb->frame ? 3 : 0; - int bmarg = cb->frame ? 2 : 0; - xpos += wi - bmarg - 16; + const int x = cb->rect.x(), y = cb->rect.y(), wi = cb->rect.width(), he = cb->rect.height(); + const int margin = cb->frame ? qRound(QStyleHelper::dpiScaled(3)) : 0; + const int bmarg = cb->frame ? qRound(QStyleHelper::dpiScaled(2)) : 0; + const int xpos = x + wi - bmarg - qRound(QStyleHelper::dpiScaled(16)); switch (sc) { @@ -4169,10 +4179,10 @@ QRect QCommonStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex ret = cb->rect; break; case SC_ComboBoxArrow: - ret.setRect(xpos, y + bmarg, 16, he - 2*bmarg); + ret.setRect(xpos, y + bmarg, qRound(QStyleHelper::dpiScaled(16)), he - 2*bmarg); break; case SC_ComboBoxEditField: - ret.setRect(x + margin, y + margin, wi - 2 * margin - 16, he - 2 * margin); + ret.setRect(x + margin, y + margin, wi - 2 * margin - qRound(QStyleHelper::dpiScaled(16)), he - 2 * margin); break; case SC_ComboBoxListBoxPopup: ret = cb->rect; @@ -5264,6 +5274,8 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget break; #endif case SH_Widget_Animate: + // TODO Qt6: move this code in the SH_Widget_Animation_Duration case + // and replace false with 0 and true with 200. #if QT_CONFIG(treeview) if (qobject_cast<const QTreeView*>(widget)) { ret = false; @@ -5281,6 +5293,18 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget ret = QAbstractItemView::ScrollPerItem; break; #endif + case SH_TitleBar_ShowToolTipsOnButtons: + ret = true; + break; + case SH_Widget_Animation_Duration: + ret = styleHint(SH_Widget_Animate, opt, widget, hret) ? 200 : 0; + break; + case SH_ComboBox_AllowWheelScrolling: + ret = true; + break; + case SH_SpinBox_ButtonsInsideFrame: + ret = true; + break; default: ret = 0; break; @@ -5687,6 +5711,22 @@ QPixmap QCommonStyle::standardPixmap(StandardPixmap sp, const QStyleOption *opti return QPixmap(); } +#if QT_CONFIG(imageformat_png) +static inline QString iconResourcePrefix() { return QStringLiteral(":/qt-project.org/styles/commonstyle/images/"); } +static inline QString iconPngSuffix() { return QStringLiteral(".png"); } + +static void addIconFiles(const QString &prefix, const int sizes[], size_t count, QIcon &icon) +{ + for (size_t i = 0; i < count; ++i) { + const int size = sizes[i]; + icon.addFile(prefix + QString::number(size) + iconPngSuffix(), QSize(size, size)); + } +} + +static const int dockTitleIconSizes[] = {10, 16, 20, 32, 48, 64}; + +#endif // imageformat_png + /*! \internal */ @@ -6193,12 +6233,20 @@ QIcon QCommonStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption case SP_MediaVolumeMuted: icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-volume-muted-16.png"), QSize(16, 16)); break; + case SP_TitleBarCloseButton: + addIconFiles(iconResourcePrefix() + QStringLiteral("closedock-"), + dockTitleIconSizes, sizeof(dockTitleIconSizes)/sizeof(dockTitleIconSizes[0]), icon); + break; case SP_TitleBarMenuButton: # ifndef QT_NO_IMAGEFORMAT_XPM icon.addPixmap(titleBarMenuCachedPixmapFromXPM()); # endif icon.addFile(QLatin1String(":/qt-project.org/qmessagebox/images/qtlogo-64.png")); break; + case SP_TitleBarNormalButton: + addIconFiles(iconResourcePrefix() + QStringLiteral("normalizedockup-"), + dockTitleIconSizes, sizeof(dockTitleIconSizes)/sizeof(dockTitleIconSizes[0]), icon); + break; #endif // QT_NO_IMAGEFORMAT_PNG default: icon.addPixmap(proxy()->standardPixmap(standardIcon, option, widget)); @@ -6243,7 +6291,7 @@ QPixmap QCommonStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &p // High intensity colors needs dark shifting in the color table, while // low intensity colors needs light shifting. This is to increase the - // percieved contrast. + // perceived contrast. if ((red - factor > green && red - factor > blue) || (green - factor > red && green - factor > blue) || (blue - factor > red && blue - factor > green)) diff --git a/src/widgets/styles/qcommonstyle.h b/src/widgets/styles/qcommonstyle.h index ed880a150f..f39915295e 100644 --- a/src/widgets/styles/qcommonstyle.h +++ b/src/widgets/styles/qcommonstyle.h @@ -56,40 +56,40 @@ public: ~QCommonStyle(); void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, - const QWidget *w = Q_NULLPTR) const Q_DECL_OVERRIDE; + const QWidget *w = nullptr) const override; void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, - const QWidget *w = Q_NULLPTR) const Q_DECL_OVERRIDE; - QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; + const QWidget *w = nullptr) const override; + QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = nullptr) const override; void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, - const QWidget *w = Q_NULLPTR) const Q_DECL_OVERRIDE; + const QWidget *w = nullptr) const override; SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, - const QPoint &pt, const QWidget *w = Q_NULLPTR) const Q_DECL_OVERRIDE; + const QPoint &pt, const QWidget *w = nullptr) const override; QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, - const QWidget *w = Q_NULLPTR) const Q_DECL_OVERRIDE; + const QWidget *w = nullptr) const override; QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, - const QSize &contentsSize, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; + const QSize &contentsSize, const QWidget *widget = nullptr) const override; - int pixelMetric(PixelMetric m, const QStyleOption *opt = Q_NULLPTR, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; + int pixelMetric(PixelMetric m, const QStyleOption *opt = nullptr, const QWidget *widget = nullptr) const override; - int styleHint(StyleHint sh, const QStyleOption *opt = Q_NULLPTR, const QWidget *w = Q_NULLPTR, - QStyleHintReturn *shret = Q_NULLPTR) const Q_DECL_OVERRIDE; + int styleHint(StyleHint sh, const QStyleOption *opt = nullptr, const QWidget *w = nullptr, + QStyleHintReturn *shret = nullptr) const override; - QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *opt = Q_NULLPTR, - const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; - QPixmap standardPixmap(StandardPixmap sp, const QStyleOption *opt = Q_NULLPTR, - const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; + QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *opt = nullptr, + const QWidget *widget = nullptr) const override; + QPixmap standardPixmap(StandardPixmap sp, const QStyleOption *opt = nullptr, + const QWidget *widget = nullptr) const override; QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, - const QStyleOption *opt) const Q_DECL_OVERRIDE; + const QStyleOption *opt) const override; int layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, - Qt::Orientation orientation, const QStyleOption *option = Q_NULLPTR, - const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; - - void polish(QPalette &) Q_DECL_OVERRIDE; - void polish(QApplication *app) Q_DECL_OVERRIDE; - void polish(QWidget *widget) Q_DECL_OVERRIDE; - void unpolish(QWidget *widget) Q_DECL_OVERRIDE; - void unpolish(QApplication *application) Q_DECL_OVERRIDE; + Qt::Orientation orientation, const QStyleOption *option = nullptr, + const QWidget *widget = nullptr) const override; + + void polish(QPalette &) override; + void polish(QApplication *app) override; + void polish(QWidget *widget) override; + void unpolish(QWidget *widget) override; + void unpolish(QApplication *application) override; protected: QCommonStyle(QCommonStylePrivate &dd); diff --git a/src/widgets/styles/qcommonstyle_p.h b/src/widgets/styles/qcommonstyle_p.h index 9fb731239a..93db75ac2d 100644 --- a/src/widgets/styles/qcommonstyle_p.h +++ b/src/widgets/styles/qcommonstyle_p.h @@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE class QStringList; // Private class -class QCommonStylePrivate : public QStylePrivate +class Q_WIDGETS_EXPORT QCommonStylePrivate : public QStylePrivate { Q_DECLARE_PUBLIC(QCommonStyle) public: diff --git a/src/widgets/styles/qdrawutil.h b/src/widgets/styles/qdrawutil.h index d5582f2c90..346029e1b4 100644 --- a/src/widgets/styles/qdrawutil.h +++ b/src/widgets/styles/qdrawutil.h @@ -70,42 +70,42 @@ Q_WIDGETS_EXPORT void qDrawShadeLine(QPainter *p, const QPoint &p1, const QPoint Q_WIDGETS_EXPORT void qDrawShadeRect(QPainter *p, int x, int y, int w, int h, const QPalette &pal, bool sunken = false, int lineWidth = 1, int midLineWidth = 0, - const QBrush *fill = Q_NULLPTR); + const QBrush *fill = nullptr); Q_WIDGETS_EXPORT void qDrawShadeRect(QPainter *p, const QRect &r, const QPalette &pal, bool sunken = false, int lineWidth = 1, int midLineWidth = 0, - const QBrush *fill = Q_NULLPTR); + const QBrush *fill = nullptr); Q_WIDGETS_EXPORT void qDrawShadePanel(QPainter *p, int x, int y, int w, int h, const QPalette &pal, bool sunken = false, - int lineWidth = 1, const QBrush *fill = Q_NULLPTR); + int lineWidth = 1, const QBrush *fill = nullptr); Q_WIDGETS_EXPORT void qDrawShadePanel(QPainter *p, const QRect &r, const QPalette &pal, bool sunken = false, - int lineWidth = 1, const QBrush *fill = Q_NULLPTR); + int lineWidth = 1, const QBrush *fill = nullptr); Q_WIDGETS_EXPORT void qDrawWinButton(QPainter *p, int x, int y, int w, int h, const QPalette &pal, bool sunken = false, - const QBrush *fill = Q_NULLPTR); + const QBrush *fill = nullptr); Q_WIDGETS_EXPORT void qDrawWinButton(QPainter *p, const QRect &r, const QPalette &pal, bool sunken = false, - const QBrush *fill = Q_NULLPTR); + const QBrush *fill = nullptr); Q_WIDGETS_EXPORT void qDrawWinPanel(QPainter *p, int x, int y, int w, int h, const QPalette &pal, bool sunken = false, - const QBrush *fill = Q_NULLPTR); + const QBrush *fill = nullptr); Q_WIDGETS_EXPORT void qDrawWinPanel(QPainter *p, const QRect &r, const QPalette &pal, bool sunken = false, - const QBrush *fill = Q_NULLPTR); + const QBrush *fill = nullptr); Q_WIDGETS_EXPORT void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &, - int lineWidth = 1, const QBrush *fill = Q_NULLPTR); + int lineWidth = 1, const QBrush *fill = nullptr); Q_WIDGETS_EXPORT void qDrawPlainRect(QPainter *p, const QRect &r, const QColor &, - int lineWidth = 1, const QBrush *fill = Q_NULLPTR); + int lineWidth = 1, const QBrush *fill = nullptr); diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index e6ad0fc898..554c45d570 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -208,55 +208,6 @@ static QColor mergedColors(const QColor &colorA, const QColor &colorB, int facto return tmp; } -static QPixmap colorizedImage(const QString &fileName, const QColor &color, int rotation = 0) { - - QString pixmapName = QLatin1String("$qt_ia-") % fileName % HexString<uint>(color.rgba()) % QString::number(rotation); - QPixmap pixmap; - if (!QPixmapCache::find(pixmapName, pixmap)) { - QImage image(fileName); - - if (image.format() != QImage::Format_ARGB32_Premultiplied) - image = image.convertToFormat( QImage::Format_ARGB32_Premultiplied); - - int width = image.width(); - int height = image.height(); - int source = color.rgba(); - - unsigned char sourceRed = qRed(source); - unsigned char sourceGreen = qGreen(source); - unsigned char sourceBlue = qBlue(source); - - for (int y = 0; y < height; ++y) - { - QRgb *data = (QRgb*) image.scanLine(y); - for (int x = 0 ; x < width ; x++) { - QRgb col = data[x]; - unsigned int colorDiff = (qBlue(col) - qRed(col)); - unsigned char gray = qGreen(col); - unsigned char red = gray + qt_div_255(sourceRed * colorDiff); - unsigned char green = gray + qt_div_255(sourceGreen * colorDiff); - unsigned char blue = gray + qt_div_255(sourceBlue * colorDiff); - unsigned char alpha = qt_div_255(qAlpha(col) * qAlpha(source)); - data[x] = qRgba(std::min(alpha, red), - std::min(alpha, green), - std::min(alpha, blue), - alpha); - } - } - if (rotation != 0) { - QTransform transform; - transform.translate(-image.width()/2, -image.height()/2); - transform.rotate(rotation); - transform.translate(image.width()/2, image.height()/2); - image = image.transformed(transform); - } - - pixmap = QPixmap::fromImage(image); - QPixmapCache::insert(pixmapName, pixmap); - } - return pixmap; -} - // The default button and handle gradient static QLinearGradient qt_fusion_gradient(const QRect &rect, const QBrush &baseColor, Direction direction = TopDown) { @@ -294,6 +245,59 @@ static QLinearGradient qt_fusion_gradient(const QRect &rect, const QBrush &baseC return gradient; } +static void qt_fusion_draw_arrow(Qt::ArrowType type, QPainter *painter, const QStyleOption *option, const QRect &rect, const QColor &color) +{ + const int arrowWidth = QStyleHelper::dpiScaled(14); + const int arrowHeight = QStyleHelper::dpiScaled(8); + + const int arrowMax = qMin(arrowHeight, arrowWidth); + const int rectMax = qMin(rect.height(), rect.width()); + const int size = qMin(arrowMax, rectMax); + + QPixmap cachePixmap; + QString cacheKey = QStyleHelper::uniqueName(QLatin1String("fusion-arrow"), option, rect.size()) + % HexString<uint>(type) + % HexString<uint>(color.rgba()); + if (!QPixmapCache::find(cacheKey, cachePixmap)) { + cachePixmap = styleCachePixmap(rect.size()); + cachePixmap.fill(Qt::transparent); + QPainter cachePainter(&cachePixmap); + + QRectF arrowRect; + arrowRect.setWidth(size); + arrowRect.setHeight(arrowHeight * size / arrowWidth); + if (type == Qt::LeftArrow || type == Qt::RightArrow) + arrowRect = arrowRect.transposed(); + arrowRect.moveTo((rect.width() - arrowRect.width()) / 2.0, + (rect.height() - arrowRect.height()) / 2.0); + + QPolygonF triangle; + triangle.reserve(3); + switch (type) { + case Qt::DownArrow: + triangle << arrowRect.topLeft() << arrowRect.topRight() << QPointF(arrowRect.center().x(), arrowRect.bottom()); + break; + case Qt::RightArrow: + triangle << arrowRect.topLeft() << arrowRect.bottomLeft() << QPointF(arrowRect.right(), arrowRect.center().y()); + break; + case Qt::LeftArrow: + triangle << arrowRect.topRight() << arrowRect.bottomRight() << QPointF(arrowRect.left(), arrowRect.center().y()); + break; + default: + triangle << arrowRect.bottomLeft() << arrowRect.bottomRight() << QPointF(arrowRect.center().x(), arrowRect.top()); + break; + } + + cachePainter.setPen(Qt::NoPen); + cachePainter.setBrush(color); + cachePainter.setRenderHint(QPainter::Antialiasing); + cachePainter.drawPolygon(triangle); + + QPixmapCache::insert(cacheKey, cachePixmap); + } + + painter->drawPixmap(rect, cachePixmap); +} static void qt_fusion_draw_mdibutton(QPainter *painter, const QStyleOptionTitleBar *option, const QRect &tmp, bool hover, bool sunken) { @@ -533,43 +537,22 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, if (option->rect.width() <= 1 || option->rect.height() <= 1) break; QColor arrowColor = option->palette.foreground().color(); - QPixmap arrow; - int rotation = 0; + arrowColor.setAlpha(160); + Qt::ArrowType arrow = Qt::UpArrow; switch (elem) { case PE_IndicatorArrowDown: - rotation = 180; + arrow = Qt::DownArrow; break; case PE_IndicatorArrowRight: - rotation = 90; + arrow = Qt::RightArrow; break; case PE_IndicatorArrowLeft: - rotation = -90; + arrow = Qt::LeftArrow; break; default: break; } - arrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor, rotation); - if (arrow.isNull()) - break; - - QRect rect = option->rect; - QRect arrowRect; - int imageMax = qMin(arrow.height(), arrow.width()); - int rectMax = qMin(rect.height(), rect.width()); - int size = qMin(imageMax, rectMax); - - arrowRect.setWidth(size); - arrowRect.setHeight(size); - if (arrow.width() > arrow.height()) - arrowRect.setHeight(arrow.height() * size / arrow.width()); - else - arrowRect.setWidth(arrow.width() * size / arrow.height()); - - arrowRect.moveTopLeft(rect.center() - arrowRect.center()); - painter->save(); - painter->setRenderHint(QPainter::SmoothPixmapTransform); - painter->drawPixmap(arrowRect, arrow); - painter->restore(); + qt_fusion_draw_arrow(arrow, painter, option, option->rect, arrowColor); } break; case PE_IndicatorViewItemCheck: @@ -583,29 +566,23 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, case PE_IndicatorHeaderArrow: if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) { QRect r = header->rect; - QPixmap arrow; QColor arrowColor = header->palette.foreground().color(); - QPoint offset = QPoint(0, -1); + arrowColor.setAlpha(180); + QPoint offset = QPoint(0, -2); #if defined(Q_OS_LINUX) if (header->sortIndicator & QStyleOptionHeader::SortUp) { - arrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor); + qt_fusion_draw_arrow(Qt::UpArrow, painter, option, r.translated(offset), arrowColor); } else if (header->sortIndicator & QStyleOptionHeader::SortDown) { - arrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor, 180); + qt_fusion_draw_arrow(Qt::DownArrow, painter, option, r.translated(offset), arrowColor); } #else if (header->sortIndicator & QStyleOptionHeader::SortUp) { - arrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor, 180); + qt_fusion_draw_arrow(Qt::DownArrow, painter, option, r.translated(offset), arrowColor); } else if (header->sortIndicator & QStyleOptionHeader::SortDown) { - arrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor); + qt_fusion_draw_arrow(Qt::UpArrow, painter, option, r.translated(offset), arrowColor); } #endif - - if (!arrow.isNull()) { - r.setSize(QSize(arrow.width()/2, arrow.height()/2)); - r.moveCenter(header->rect.center()); - painter->drawPixmap(r.translated(offset), arrow); - } } break; case PE_IndicatorButtonDropDown: @@ -1553,17 +1530,18 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio QColor highlight = option->palette.highlight().color(); if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) { int w = 0; + const int margin = QStyleHelper::dpiScaled(5); if (!menuItem->text.isEmpty()) { painter->setFont(menuItem->font); - proxy()->drawItemText(painter, menuItem->rect.adjusted(5, 0, -5, 0), Qt::AlignLeft | Qt::AlignVCenter, + proxy()->drawItemText(painter, menuItem->rect.adjusted(margin, 0, -margin, 0), Qt::AlignLeft | Qt::AlignVCenter, menuItem->palette, menuItem->state & State_Enabled, menuItem->text, QPalette::Text); - w = menuItem->fontMetrics.width(menuItem->text) + 5; + w = menuItem->fontMetrics.horizontalAdvance(menuItem->text) + margin; } painter->setPen(shadow.lighter(106)); bool reverse = menuItem->direction == Qt::RightToLeft; - painter->drawLine(menuItem->rect.left() + 5 + (reverse ? 0 : w), menuItem->rect.center().y(), - menuItem->rect.right() - 5 - (reverse ? w : 0), menuItem->rect.center().y()); + painter->drawLine(menuItem->rect.left() + margin + (reverse ? 0 : w), menuItem->rect.center().y(), + menuItem->rect.right() - margin - (reverse ? w : 0), menuItem->rect.center().y()); painter->restore(); break; } @@ -2055,7 +2033,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption QRect r = rect.adjusted(0, 1, 0, -1); QPainter cachePainter(&cache); QColor arrowColor = spinBox->palette.foreground().color(); - arrowColor.setAlpha(220); + arrowColor.setAlpha(160); bool isEnabled = (spinBox->state & State_Enabled); bool hover = isEnabled && (spinBox->state & State_MouseOver); @@ -2166,23 +2144,10 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption } else if (spinBox->buttonSymbols == QAbstractSpinBox::UpDownArrows){ // arrows - painter->setRenderHint(QPainter::SmoothPixmapTransform); - - QPixmap upArrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), - (spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled) ? arrowColor : disabledColor); - - QRectF upArrowRect = QRectF(upRect.center().x() - upArrow.width() / 4.0 + 1.0, - upRect.center().y() - upArrow.height() / 4.0 + 1.0, - upArrow.width() / 2.0, upArrow.height() / 2.0); - - cachePainter.drawPixmap(upArrowRect, upArrow, QRectF(QPointF(0.0, 0.0), upArrow.size())); - - QPixmap downArrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), - (spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled) ? arrowColor : disabledColor, 180); - QRectF downArrowRect = QRectF(downRect.center().x() - downArrow.width() / 4.0 + 1.0, - downRect.center().y() - downArrow.height() / 4.0 + 1.0, - downArrow.width() / 2.0, downArrow.height() / 2.0); - cachePainter.drawPixmap(downArrowRect, downArrow, QRectF(QPointF(0.0, 0.0), downArrow.size())); + qt_fusion_draw_arrow(Qt::UpArrow, &cachePainter, option, upRect.adjusted(0, 0, 0, 1), + (spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled) ? arrowColor : disabledColor); + qt_fusion_draw_arrow(Qt::DownArrow, &cachePainter, option, downRect, + (spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled) ? arrowColor : disabledColor); } cachePainter.end(); @@ -2419,8 +2384,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption bool hover = (titleBar->activeSubControls & SC_TitleBarShadeButton) && (titleBar->state & State_MouseOver); bool sunken = (titleBar->activeSubControls & SC_TitleBarShadeButton) && (titleBar->state & State_Sunken); qt_fusion_draw_mdibutton(painter, titleBar, shadeButtonRect, hover, sunken); - QPixmap arrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), textColor); - painter->drawPixmap(shadeButtonRect.adjusted(5, 7, -5, -7), arrow); + qt_fusion_draw_arrow(Qt::UpArrow, painter, option, shadeButtonRect.adjusted(5, 7, -5, -7), textColor); } } @@ -2431,8 +2395,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption bool hover = (titleBar->activeSubControls & SC_TitleBarUnshadeButton) && (titleBar->state & State_MouseOver); bool sunken = (titleBar->activeSubControls & SC_TitleBarUnshadeButton) && (titleBar->state & State_Sunken); qt_fusion_draw_mdibutton(painter, titleBar, unshadeButtonRect, hover, sunken); - QPixmap arrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), textColor, 180); - painter->drawPixmap(unshadeButtonRect.adjusted(5, 7, -5, -7), arrow); + qt_fusion_draw_arrow(Qt::DownArrow, painter, option, unshadeButtonRect.adjusted(5, 7, -5, -7), textColor); } } @@ -2562,7 +2525,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption alphaOutline.setAlpha(180); QColor arrowColor = option->palette.foreground().color(); - arrowColor.setAlpha(220); + arrowColor.setAlpha(160); const QColor bgColor = QStyleHelper::backgroundColor(option->palette, widget); const bool isDarkBg = bgColor.red() < 128 && bgColor.green() < 128 && bgColor.blue() < 128; @@ -2706,20 +2669,16 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption painter->drawLine(pixmapRect.bottomLeft(), pixmapRect.bottomRight()); } + QRect upRect = scrollBarSubLine.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0, horizontal ? -2 : -1, horizontal ? -1 : -2); painter->setBrush(Qt::NoBrush); painter->setPen(d->innerContrastLine()); - painter->drawRect(scrollBarSubLine.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0 , horizontal ? -2 : -1, horizontal ? -1 : -2)); + painter->drawRect(upRect); // Arrows - int rotation = 0; + Qt::ArrowType arrowType = Qt::UpArrow; if (option->state & State_Horizontal) - rotation = option->direction == Qt::LeftToRight ? -90 : 90; - QRect upRect = scrollBarSubLine.translated(horizontal ? -2 : -1, 0); - QPixmap arrowPixmap = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor, rotation); - painter->drawPixmap(QRectF(upRect.center().x() - arrowPixmap.width() / 4.0 + 2.0, - upRect.center().y() - arrowPixmap.height() / 4.0 + 1.0, - arrowPixmap.width() / 2.0, arrowPixmap.height() / 2.0), - arrowPixmap, QRectF(QPoint(0.0, 0.0), arrowPixmap.size())); + arrowType = option->direction == Qt::LeftToRight ? Qt::LeftArrow : Qt::RightArrow; + qt_fusion_draw_arrow(arrowType, painter, option, upRect, arrowColor); } // The AddLine (down/right) button @@ -2747,19 +2706,15 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption painter->drawLine(pixmapRect.topLeft(), pixmapRect.topRight()); } + QRect downRect = scrollBarAddLine.adjusted(1, 1, -1, -1); painter->setPen(d->innerContrastLine()); painter->setBrush(Qt::NoBrush); - painter->drawRect(scrollBarAddLine.adjusted(1, 1, -1, -1)); + painter->drawRect(downRect); - int rotation = 180; + Qt::ArrowType arrowType = Qt::DownArrow; if (option->state & State_Horizontal) - rotation = option->direction == Qt::LeftToRight ? 90 : -90; - QRect downRect = scrollBarAddLine.translated(-1, 1); - QPixmap arrowPixmap = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor, rotation); - painter->drawPixmap(QRectF(downRect.center().x() - arrowPixmap.width() / 4.0 + 2.0, - downRect.center().y() - arrowPixmap.height() / 4.0, - arrowPixmap.width() / 2.0, arrowPixmap.height() / 2.0), - arrowPixmap, QRectF(QPoint(0.0, 0.0), arrowPixmap.size())); + arrowType = option->direction == Qt::LeftToRight ? Qt::RightArrow : Qt::LeftArrow; + qt_fusion_draw_arrow(arrowType, painter, option, downRect, arrowColor); } } @@ -2780,6 +2735,8 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption pixmapName += QLatin1String("-editable"); if (isEnabled) pixmapName += QLatin1String("-enabled"); + if (!comboBox->frame) + pixmapName += QLatin1String("-frameless"); if (!QPixmapCache::find(pixmapName, cache)) { cache = styleCachePixmap(comboBox->rect.size()); @@ -2805,7 +2762,8 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption buttonOption.state &= ~State_MouseOver; } - proxy()->drawPrimitive(PE_FrameLineEdit, &buttonOption, &cachePainter, widget); + if (comboBox->frame) + proxy()->drawPrimitive(PE_FrameLineEdit, &buttonOption, &cachePainter, widget); // Draw button clipped cachePainter.save(); @@ -2849,12 +2807,8 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption if (comboBox->subControls & SC_ComboBoxArrow) { // Draw the up/down arrow QColor arrowColor = option->palette.buttonText().color(); - arrowColor.setAlpha(220); - QPixmap downArrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor, 180); - cachePainter.drawPixmap(QRectF(downArrowRect.center().x() - downArrow.width() / 4.0 + 1.0, - downArrowRect.center().y() - downArrow.height() / 4.0 + 1.0, - downArrow.width() / 2.0, downArrow.height() / 2.0), - downArrow, QRectF(QPointF(0.0, 0.0), downArrow.size())); + arrowColor.setAlpha(160); + qt_fusion_draw_arrow(Qt::DownArrow, &cachePainter, option, downArrowRect, arrowColor); } cachePainter.end(); QPixmapCache::insert(pixmapName, cache); @@ -3258,17 +3212,17 @@ QSize QFusionStyle::sizeFromContents(ContentsType type, const QStyleOption *opti if (menuItem->text.contains(QLatin1Char('\t'))) w += tabSpacing; else if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu) - w += 2 * QFusionStylePrivate::menuArrowHMargin; + w += 2 * QStyleHelper::dpiScaled(QFusionStylePrivate::menuArrowHMargin); else if (menuItem->menuItemType == QStyleOptionMenuItem::DefaultItem) { QFontMetrics fm(menuItem->font); QFont fontBold = menuItem->font; fontBold.setBold(true); QFontMetrics fmBold(fontBold); - w += fmBold.width(menuItem->text) - fm.width(menuItem->text); + w += fmBold.width(menuItem->text) - fm.horizontalAdvance(menuItem->text); } - int checkcol = qMax<int>(maxpmw, QFusionStylePrivate::menuCheckMarkWidth); // Windows always shows a check column + const int checkcol = qMax<int>(maxpmw, QStyleHelper::dpiScaled(QFusionStylePrivate::menuCheckMarkWidth)); // Windows always shows a check column w += checkcol; - w += int(QFusionStylePrivate::menuRightBorder) + 10; + w += QStyleHelper::dpiScaled(int(QFusionStylePrivate::menuRightBorder) + 10); newSize.setWidth(w); if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) { if (!menuItem->text.isEmpty()) { @@ -3282,8 +3236,8 @@ QSize QFusionStyle::sizeFromContents(ContentsType type, const QStyleOption *opti } #endif } - newSize.setWidth(newSize.width() + 12); - newSize.setWidth(qMax(newSize.width(), 120)); + newSize.setWidth(newSize.width() + QStyleHelper::dpiScaled(12)); + newSize.setWidth(qMax<int>(newSize.width(), QStyleHelper::dpiScaled(120))); } break; case CT_SizeGrip: @@ -3546,8 +3500,8 @@ QRect QFusionStyle::subControlRect(ComplexControl control, const QStyleOptionCom switch (subControl) { case SC_ComboBoxArrow: rect = visualRect(option->direction, option->rect, rect); - rect.setRect(rect.right() - 18, rect.top() - 2, - 19, rect.height() + 4); + rect.setRect(rect.right() - QStyleHelper::dpiScaled(18), rect.top() - 2, + QStyleHelper::dpiScaled(19), rect.height() + 4); rect = visualRect(option->direction, option->rect, rect); break; case SC_ComboBoxEditField: { @@ -3816,6 +3770,19 @@ QRect QFusionStyle::subElementRect(SubElement sr, const QStyleOption *opt, const QIcon QFusionStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const { +#if QT_CONFIG(imageformat_xpm) + switch (standardIcon) { + case SP_TitleBarNormalButton: + return QIcon(QPixmap(dock_widget_restore_xpm)); + case SP_TitleBarMinButton: + return QIcon(QPixmap(workspace_minimize)); + case SP_TitleBarCloseButton: + case SP_DockWidgetCloseButton: + return QIcon(QPixmap(dock_widget_close_xpm)); + default: + break; + } +#endif // imageformat_xpm return QCommonStyle::standardIcon(standardIcon, option, widget); } diff --git a/src/widgets/styles/qfusionstyle_p.h b/src/widgets/styles/qfusionstyle_p.h index aac27e51ab..e67e792727 100644 --- a/src/widgets/styles/qfusionstyle_p.h +++ b/src/widgets/styles/qfusionstyle_p.h @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE #if QT_CONFIG(style_fusion) class QFusionStylePrivate; -class QFusionStyle : public QCommonStyle +class Q_WIDGETS_EXPORT QFusionStyle : public QCommonStyle { Q_OBJECT Q_DECLARE_PRIVATE(QFusionStyle) @@ -69,41 +69,41 @@ public: QFusionStyle(); ~QFusionStyle(); - QPalette standardPalette () const Q_DECL_OVERRIDE; + QPalette standardPalette () const override; void drawPrimitive(PrimitiveElement elem, const QStyleOption *option, - QPainter *painter, const QWidget *widget = 0) const Q_DECL_OVERRIDE; + QPainter *painter, const QWidget *widget = 0) const override; void drawControl(ControlElement ce, const QStyleOption *option, QPainter *painter, - const QWidget *widget) const Q_DECL_OVERRIDE; - int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const Q_DECL_OVERRIDE; + const QWidget *widget) const override; + int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const override; void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, - QPainter *painter, const QWidget *widget) const Q_DECL_OVERRIDE; - QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const Q_DECL_OVERRIDE; + QPainter *painter, const QWidget *widget) const override; + QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const override; QSize sizeFromContents(ContentsType type, const QStyleOption *option, - const QSize &size, const QWidget *widget) const Q_DECL_OVERRIDE; + const QSize &size, const QWidget *widget) const override; SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, - const QPoint &pt, const QWidget *w = 0) const Q_DECL_OVERRIDE; + const QPoint &pt, const QWidget *w = 0) const override; QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, - SubControl sc, const QWidget *widget) const Q_DECL_OVERRIDE; + SubControl sc, const QWidget *widget) const override; QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, - const QStyleOption *opt) const Q_DECL_OVERRIDE; + const QStyleOption *opt) const override; int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0, - QStyleHintReturn *returnData = 0) const Q_DECL_OVERRIDE; - QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const Q_DECL_OVERRIDE; + QStyleHintReturn *returnData = 0) const override; + QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const override; QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = 0, - const QWidget *widget = 0) const Q_DECL_OVERRIDE; + const QWidget *widget = 0) const override; QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, - const QWidget *widget = 0) const Q_DECL_OVERRIDE; + const QWidget *widget = 0) const override; void drawItemPixmap(QPainter *painter, const QRect &rect, - int alignment, const QPixmap &pixmap) const Q_DECL_OVERRIDE; + int alignment, const QPixmap &pixmap) const override; void drawItemText(QPainter *painter, const QRect &rect, int flags, const QPalette &pal, bool enabled, - const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const Q_DECL_OVERRIDE; - void polish(QWidget *widget) Q_DECL_OVERRIDE; - void polish(QApplication *app) Q_DECL_OVERRIDE; - void polish(QPalette &pal) Q_DECL_OVERRIDE; - void unpolish(QWidget *widget) Q_DECL_OVERRIDE; - void unpolish(QApplication *app) Q_DECL_OVERRIDE; + const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const override; + void polish(QWidget *widget) override; + void polish(QApplication *app) override; + void polish(QPalette &pal) override; + void unpolish(QWidget *widget) override; + void unpolish(QApplication *app) override; protected: QFusionStyle(QFusionStylePrivate &dd); diff --git a/src/widgets/styles/qmacstyle.qdoc b/src/widgets/styles/qmacstyle.qdoc deleted file mode 100644 index a77843a4dd..0000000000 --- a/src/widgets/styles/qmacstyle.qdoc +++ /dev/null @@ -1,207 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** 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 Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -/*! - \class QMacStyle - \brief The QMacStyle class provides a \macos style using the Apple Appearance Manager. - - \ingroup appearance - \inmodule QtWidgets - \internal - - This class is implemented as a wrapper to the HITheme - APIs, allowing applications to be styled according to the current - theme in use on \macos. This is done by having primitives - in QStyle implemented in terms of what \macos would normally theme. - - \warning This style is only available on \macos because it relies on the - HITheme APIs. - - There are additional issues that should be taken - into consideration to make an application compatible with the - \l{Apple Human Interface Guidelines}{Apple Human Interface Guidelines}. Some of these issues are outlined - below. - - \list - - \li Layout - The restrictions on window layout are such that some - aspects of layout that are style-dependent cannot be achieved - using QLayout. Changes are being considered (and feedback would be - appreciated) to make layouts QStyle-able. Some of the restrictions - involve horizontal and vertical widget alignment and widget size - (covered below). - - \li Widget size - \macos allows widgets to have specific fixed sizes. Qt - does not fully implement this behavior so as to maintain cross-platform - compatibility. As a result some widgets sizes may be inappropriate (and - subsequently not rendered correctly by the HITheme APIs).The - QWidget::sizeHint() will return the appropriate size for many - managed widgets (widgets enumerated in \l QStyle::ContentsType). - - \li Effects - QMacStyle uses HITheme for performing most of the drawing, but - also uses emulation in a few cases where HITheme does not provide the - required functionality (for example, tab bars on Panther, the toolbar - separator, etc). We tried to make the emulation as close to the original as - possible. Please report any issues you see in effects or non-standard - widgets. - - \endlist - - There are other issues that need to be considered in the feel of - your application (including the general color scheme to match the - Aqua colors). The Guidelines mentioned above will remain current - with new advances and design suggestions for \macos. - - Note that the functions provided by QMacStyle are - reimplementations of QStyle functions; see QStyle for their - documentation. - - \image qmacstyle.png - \sa QWindowsXPStyle, QWindowsStyle, QFusionStyle -*/ - - -/*! - \enum QMacStyle::WidgetSizePolicy - - \value SizeSmall - \value SizeLarge - \value SizeMini - \value SizeDefault -*/ - -/*! \fn QMacStyle::QMacStyle() - Constructs a QMacStyle object. -*/ - -/*! \fn QMacStyle::~QMacStyle() - Destructs a QMacStyle object. -*/ - -/*! \fn void QMacStyle::polish(QPalette &pal) - \reimp -*/ - -/*! \fn void QMacStyle::polish(QApplication *) - \reimp -*/ - -/*! \fn void QMacStyle::unpolish(QApplication *) - \reimp -*/ - -/*! \fn void QMacStyle::polish(QWidget* w) - \reimp -*/ - -/*! \fn void QMacStyle::unpolish(QWidget* w) - \reimp -*/ - -/*! \fn int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QWidget *widget) const - \reimp -*/ - -/*! \fn QPalette QMacStyle::standardPalette() const - \reimp -*/ - -/*! \fn int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w, QStyleHintReturn *hret) const - \reimp -*/ - -/*! \fn QPixmap QMacStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const - \reimp -*/ - -/*! \fn QPixmap QMacStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget) const - \reimp -*/ - -/*! \fn void QMacStyle::setWidgetSizePolicy(const QWidget *widget, WidgetSizePolicy policy) - - \obsolete - - Call QWidget::setAttribute() with Qt::WA_MacMiniSize, Qt::WA_MacSmallSize, - or Qt::WA_MacNormalSize instead. -*/ - -/*! \fn QMacStyle::WidgetSizePolicy QMacStyle::widgetSizePolicy(const QWidget *widget, const QStyleOption *opt = 0) - \obsolete - - Call QWidget::testAttribute() with Qt::WA_MacMiniSize, Qt::WA_MacSmallSize, - or Qt::WA_MacNormalSize instead. -*/ - -/*! \fn void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w) const - - \reimp -*/ - -/*! \fn void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter *p, const QWidget *w) const - - \reimp -*/ - -/*! \fn QRect QMacStyle::subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *widget) const - - \reimp -*/ - -/*! \fn void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, const QWidget *widget) const - \reimp -*/ - -/*! \fn QStyle::SubControl QMacStyle::hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, const QPoint &pt, const QWidget *widget) const - \reimp -*/ - -/*! \fn QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const - \reimp -*/ - -/*! \fn QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &csz, const QWidget *widget) const - \reimp -*/ - -/*! \fn void QMacStyle::drawItemText(QPainter *p, const QRect &r, int flags, const QPalette &pal, bool enabled, const QString &text, QPalette::ColorRole textRole) const - \reimp -*/ - -/*! \fn bool QMacStyle::event(QEvent *e) - \reimp -*/ - -/*! \fn QIcon QMacStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption *opt, const QWidget *widget) const - \reimp -*/ - -/*! \fn int QMacStyle::layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, Qt::Orientation orientation, const QStyleOption *option, const QWidget *widget) const - \reimp -*/ - diff --git a/src/widgets/styles/qmacstyle_mac_p.h b/src/widgets/styles/qmacstyle_mac_p.h deleted file mode 100644 index 7296539356..0000000000 --- a/src/widgets/styles/qmacstyle_mac_p.h +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef QMACSTYLE_MAC_P_H -#define QMACSTYLE_MAC_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtWidgets/private/qtwidgetsglobal_p.h> -#include <QtWidgets/qcommonstyle.h> - -QT_BEGIN_NAMESPACE - - -#if QT_CONFIG(style_mac) - -class QPalette; - -class QPushButton; -class QStyleOptionButton; -class QMacStylePrivate; -class QMacStyle : public QCommonStyle -{ - Q_OBJECT -public: - QMacStyle(); - virtual ~QMacStyle(); - - void polish(QWidget *w); - void unpolish(QWidget *w); - - void polish(QApplication*); - void unpolish(QApplication*); - - void polish(QPalette &pal); - - void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, - const QWidget *w = 0) const; - void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, - const QWidget *w = 0) const; - QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const; - void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, - const QWidget *w = 0) const; - SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, - const QPoint &pt, const QWidget *w = 0) const; - QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, - const QWidget *w = 0) const; - QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, - const QSize &contentsSize, const QWidget *w = 0) const; - - int pixelMetric(PixelMetric pm, const QStyleOption *opt = 0, const QWidget *widget = 0) const; - - QPalette standardPalette() const; - - virtual int styleHint(StyleHint sh, const QStyleOption *opt = 0, const QWidget *w = 0, - QStyleHintReturn *shret = 0) const; - - enum WidgetSizePolicy { SizeSmall, SizeLarge, SizeMini, SizeDefault - }; - - static void setWidgetSizePolicy(const QWidget *w, WidgetSizePolicy policy); - static WidgetSizePolicy widgetSizePolicy(const QWidget *w, const QStyleOption *opt = 0); - - QPixmap standardPixmap(StandardPixmap sp, const QStyleOption *opt, - const QWidget *widget = 0) const; - - QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, - const QStyleOption *opt) const; - - virtual void drawItemText(QPainter *p, const QRect &r, int flags, const QPalette &pal, - bool enabled, const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const; - - bool event(QEvent *e); - - QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *opt = 0, - const QWidget *widget = 0) const; - int layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, - Qt::Orientation orientation, const QStyleOption *option = 0, - const QWidget *widget = 0) const; - -private: - Q_DISABLE_COPY(QMacStyle) - Q_DECLARE_PRIVATE(QMacStyle) - -#if QT_CONFIG(pushbutton) - friend bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOptionButton *option); -#endif -}; - -#endif - -QT_END_NAMESPACE - -#endif // QMACSTYLE_MAC_P_H diff --git a/src/widgets/styles/qmacstyle_mac_p_p.h b/src/widgets/styles/qmacstyle_mac_p_p.h deleted file mode 100644 index 228abf950a..0000000000 --- a/src/widgets/styles/qmacstyle_mac_p_p.h +++ /dev/null @@ -1,292 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - - -#ifndef QMACSTYLE_MAC_P_P_H -#define QMACSTYLE_MAC_P_P_H - -#include <Carbon/Carbon.h> -#undef check - -#include <QtWidgets/private/qtwidgetsglobal_p.h> -#include "qmacstyle_mac_p.h" -#include "qcommonstyle_p.h" -#include <private/qapplication_p.h> -#if QT_CONFIG(combobox) -#include <private/qcombobox_p.h> -#endif -#include <private/qpainter_p.h> -#include <private/qstylehelper_p.h> -#include <qapplication.h> -#include <qbitmap.h> -#if QT_CONFIG(checkbox) -#include <qcheckbox.h> -#endif -#include <qcombobox.h> -#if QT_CONFIG(dialogbuttonbox) -#include <qdialogbuttonbox.h> -#endif -#if QT_CONFIG(dockwidget) -#include <qdockwidget.h> -#endif -#include <qevent.h> -#include <qfocusframe.h> -#include <qformlayout.h> -#if QT_CONFIG(groupbox) -#include <qgroupbox.h> -#endif -#include <qhash.h> -#include <qheaderview.h> -#include <qlayout.h> -#if QT_CONFIG(lineedit) -#include <qlineedit.h> -#endif -#if QT_CONFIG(listview) -#include <qlistview.h> -#endif -#if QT_CONFIG(mainwindow) -#include <qmainwindow.h> -#endif -#include <qmap.h> -#if QT_CONFIG(menubar) -#include <qmenubar.h> -#endif -#include <qpaintdevice.h> -#include <qpainter.h> -#include <qpixmapcache.h> -#include <qpointer.h> -#if QT_CONFIG(progressbar) -#include <qprogressbar.h> -#endif -#if QT_CONFIG(pushbutton) -#include <qpushbutton.h> -#endif -#include <qradiobutton.h> -#if QT_CONFIG(rubberband) -#include <qrubberband.h> -#endif -#if QT_CONFIG(sizegrip) -#include <qsizegrip.h> -#endif -#if QT_CONFIG(spinbox) -#include <qspinbox.h> -#endif -#if QT_CONFIG(splitter) -#include <qsplitter.h> -#endif -#include <qstyleoption.h> -#include <qtextedit.h> -#include <qtextstream.h> -#include <qtoolbar.h> -#if QT_CONFIG(toolbutton) -#include <qtoolbutton.h> -#endif -#if QT_CONFIG(treeview) -#include <qtreeview.h> -#endif -#if QT_CONFIG(tableview) -#include <qtableview.h> -#endif -#include <qdebug.h> -#if QT_CONFIG(datetimeedit) -#include <qdatetimeedit.h> -#endif -#include <qmath.h> -#include <qpair.h> -#include <qvector.h> -#include <QtWidgets/qgraphicsproxywidget.h> -#include <QtWidgets/qgraphicsview.h> - - - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -Q_FORWARD_DECLARE_OBJC_CLASS(NSView); -Q_FORWARD_DECLARE_OBJC_CLASS(NSScroller); - -QT_BEGIN_NAMESPACE - -/* - AHIG: - Apple Human Interface Guidelines - http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/ - - Builder: - Apple Interface Builder v. 3.1.1 -*/ - -// this works as long as we have at most 16 different control types -#define CT1(c) CT2(c, c) -#define CT2(c1, c2) ((uint(c1) << 16) | uint(c2)) - -enum QAquaWidgetSize { QAquaSizeLarge = 0, QAquaSizeSmall = 1, QAquaSizeMini = 2, - QAquaSizeUnknown = -1 }; - -enum QCocoaWidgetKind { - QCocoaArrowButton, // Disclosure triangle, like in QTreeView - QCocoaCheckBox, - QCocoaComboBox, // Editable QComboBox - QCocoaPopupButton, // Non-editable QComboBox - QCocoaPullDownButton, // QPushButton with menu - QCocoaPushButton, - QCocoaRadioButton, - QCocoaHorizontalSlider, - QCocoaVerticalSlider -}; - -typedef QPair<QCocoaWidgetKind, QAquaWidgetSize> QCocoaWidget; - -typedef void (^QCocoaDrawRectBlock)(NSRect, CGContextRef); - -#define SIZE(large, small, mini) \ - (controlSize == QAquaSizeLarge ? (large) : controlSize == QAquaSizeSmall ? (small) : (mini)) - -// same as return SIZE(...) but optimized -#define return_SIZE(large, small, mini) \ - do { \ - static const int sizes[] = { (large), (small), (mini) }; \ - return sizes[controlSize]; \ - } while (false) - -#if QT_CONFIG(pushbutton) -bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOptionButton *option); -#endif - -class QMacStylePrivate : public QCommonStylePrivate -{ - Q_DECLARE_PUBLIC(QMacStyle) -public: - QMacStylePrivate(); - ~QMacStylePrivate(); - - // Ideally these wouldn't exist, but since they already exist we need some accessors. - static const int PushButtonLeftOffset; - static const int PushButtonTopOffset; - static const int PushButtonRightOffset; - static const int PushButtonBottomOffset; - static const int MiniButtonH; - static const int SmallButtonH; - static const int BevelButtonW; - static const int BevelButtonH; - static const int PushButtonContentPadding; - - enum Animates { AquaPushButton, AquaProgressBar, AquaListViewItemOpen, AquaScrollBar }; - static ThemeDrawState getDrawState(QStyle::State flags); - QAquaWidgetSize aquaSizeConstrain(const QStyleOption *option, const QWidget *widg, - QStyle::ContentsType ct = QStyle::CT_CustomBase, - QSize szHint=QSize(-1, -1), QSize *insz = 0) const; - QAquaWidgetSize effectiveAquaSizeConstrain(const QStyleOption *option, const QWidget *widg, - QStyle::ContentsType ct = QStyle::CT_CustomBase, - QSize szHint=QSize(-1, -1), QSize *insz = 0) const; - void getSliderInfo(QStyle::ComplexControl cc, const QStyleOptionSlider *slider, - HIThemeTrackDrawInfo *tdi, const QWidget *needToRemoveMe) const; - inline int animateSpeed(Animates) const { return 33; } - - // Utility functions - void drawColorlessButton(const HIRect &macRect, HIThemeButtonDrawInfo *bdi, - QPainter *p, const QStyleOption *opt) const; - - QSize pushButtonSizeFromContents(const QStyleOptionButton *btn) const; - - HIRect pushButtonContentBounds(const QStyleOptionButton *btn, - const HIThemeButtonDrawInfo *bdi) const; - - void initComboboxBdi(const QStyleOptionComboBox *combo, HIThemeButtonDrawInfo *bdi, - const QWidget *widget, const ThemeDrawState &tds) const; - - static HIRect comboboxInnerBounds(const HIRect &outerBounds, int buttonKind); - - static QRect comboboxEditBounds(const QRect &outerBounds, const HIThemeButtonDrawInfo &bdi); - - static void drawCombobox(const HIRect &outerBounds, const HIThemeButtonDrawInfo &bdi, QPainter *p); - static void drawTableHeader(const HIRect &outerBounds, bool drawTopBorder, bool drawLeftBorder, - const HIThemeButtonDrawInfo &bdi, QPainter *p); - bool contentFitsInPushButton(const QStyleOptionButton *btn, HIThemeButtonDrawInfo *bdi, - ThemeButtonKind buttonKindToCheck) const; - void initHIThemePushButton(const QStyleOptionButton *btn, const QWidget *widget, - const ThemeDrawState tds, - HIThemeButtonDrawInfo *bdi) const; - QPixmap generateBackgroundPattern() const; - - void setAutoDefaultButton(QObject *button) const; - - NSView *cocoaControl(QCocoaWidget widget) const; - - void drawNSViewInRect(QCocoaWidget widget, NSView *view, const QRect &rect, QPainter *p, bool isQWidget = true, QCocoaDrawRectBlock drawRectBlock = nil) const; - void resolveCurrentNSView(QWindow *window); - - void drawFocusRing(QPainter *p, const QRect &targetRect, int hMargin, int vMargin, qreal radius = 0) const; - -#if QT_CONFIG(tabbar) - void tabLayout(const QStyleOptionTab *opt, const QWidget *widget, QRect *textRect, QRect *iconRect) const; -#endif - -public: - mutable QPointer<QObject> pressedButton; - mutable QPointer<QObject> defaultButton; - mutable QPointer<QObject> autoDefaultButton; - static QVector<QPointer<QObject> > scrollBars; - - struct ButtonState { - int frame; - enum { ButtonDark, ButtonLight } dir; - } buttonState; - mutable QPointer<QFocusFrame> focusWidget; - CFAbsoluteTime defaultButtonStart; - bool mouseDown; - void* receiver; - NSScroller *horizontalScroller; - NSScroller *verticalScroller; - void *indicatorBranchButtonCell; - NSView *backingStoreNSView; - QHash<QCocoaWidget, NSView *> cocoaControls; -}; - -QT_END_NAMESPACE - -#endif // QMACSTYLE_MAC_P_P_H diff --git a/src/widgets/styles/qpixmapstyle_p.h b/src/widgets/styles/qpixmapstyle_p.h index 618d6d2f50..590434d95e 100644 --- a/src/widgets/styles/qpixmapstyle_p.h +++ b/src/widgets/styles/qpixmapstyle_p.h @@ -136,34 +136,34 @@ public: QPixmapStyle(); ~QPixmapStyle(); - void polish(QApplication *application) Q_DECL_OVERRIDE; - void polish(QPalette &palette) Q_DECL_OVERRIDE; - void polish(QWidget *widget) Q_DECL_OVERRIDE; - void unpolish(QApplication *application) Q_DECL_OVERRIDE; - void unpolish(QWidget *widget) Q_DECL_OVERRIDE; + void polish(QApplication *application) override; + void polish(QPalette &palette) override; + void polish(QWidget *widget) override; + void unpolish(QApplication *application) override; + void unpolish(QWidget *widget) override; void drawPrimitive(PrimitiveElement element, const QStyleOption *option, - QPainter *painter, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; + QPainter *painter, const QWidget *widget = nullptr) const override; void drawControl(ControlElement element, const QStyleOption *option, - QPainter *painter, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; + QPainter *painter, const QWidget *widget = nullptr) const override; void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option, - QPainter *painter, const QWidget *widget=0) const Q_DECL_OVERRIDE; + QPainter *painter, const QWidget *widget=0) const override; QSize sizeFromContents(ContentsType type, const QStyleOption *option, - const QSize &contentsSize, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; + const QSize &contentsSize, const QWidget *widget = nullptr) const override; QRect subElementRect(SubElement element, const QStyleOption *option, - const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; + const QWidget *widget = nullptr) const override; QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *option, - SubControl sc, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; + SubControl sc, const QWidget *widget = nullptr) const override; - int pixelMetric(PixelMetric metric, const QStyleOption *option = Q_NULLPTR, - const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; + int pixelMetric(PixelMetric metric, const QStyleOption *option = nullptr, + const QWidget *widget = nullptr) const override; int styleHint(StyleHint hint, const QStyleOption *option, - const QWidget *widget, QStyleHintReturn *returnData) const Q_DECL_OVERRIDE; + const QWidget *widget, QStyleHintReturn *returnData) const override; SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, - const QPoint &pos, const QWidget *widget) const Q_DECL_OVERRIDE; + const QPoint &pos, const QWidget *widget) const override; - bool eventFilter(QObject *watched, QEvent *event) Q_DECL_OVERRIDE; + bool eventFilter(QObject *watched, QEvent *event) override; void addDescriptor(ControlDescriptor control, const QString &fileName, QMargins margins = QMargins(), diff --git a/src/widgets/styles/qproxystyle.h b/src/widgets/styles/qproxystyle.h index 20a0f12868..c26d9abf59 100644 --- a/src/widgets/styles/qproxystyle.h +++ b/src/widgets/styles/qproxystyle.h @@ -54,47 +54,47 @@ class Q_WIDGETS_EXPORT QProxyStyle : public QCommonStyle Q_OBJECT public: - QProxyStyle(QStyle *style = Q_NULLPTR); + QProxyStyle(QStyle *style = nullptr); QProxyStyle(const QString &key); ~QProxyStyle(); QStyle *baseStyle() const; void setBaseStyle(QStyle *style); - void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; - void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; - void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; + void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const override; + void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const override; + void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = nullptr) const override; void drawItemText(QPainter *painter, const QRect &rect, int flags, const QPalette &pal, bool enabled, - const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const Q_DECL_OVERRIDE; - virtual void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const Q_DECL_OVERRIDE; + const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const override; + virtual void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const override; - QSize sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const Q_DECL_OVERRIDE; + QSize sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const override; - QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const Q_DECL_OVERRIDE; - QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const Q_DECL_OVERRIDE; - QRect itemTextRect(const QFontMetrics &fm, const QRect &r, int flags, bool enabled, const QString &text) const Q_DECL_OVERRIDE; - QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const Q_DECL_OVERRIDE; + QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const override; + QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const override; + QRect itemTextRect(const QFontMetrics &fm, const QRect &r, int flags, bool enabled, const QString &text) const override; + QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const override; - SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, const QPoint &pos, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; - int styleHint(StyleHint hint, const QStyleOption *option = Q_NULLPTR, const QWidget *widget = Q_NULLPTR, QStyleHintReturn *returnData = Q_NULLPTR) const Q_DECL_OVERRIDE; - int pixelMetric(PixelMetric metric, const QStyleOption *option = Q_NULLPTR, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; + SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, const QPoint &pos, const QWidget *widget = nullptr) const override; + int styleHint(StyleHint hint, const QStyleOption *option = nullptr, const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const override; + int pixelMetric(PixelMetric metric, const QStyleOption *option = nullptr, const QWidget *widget = nullptr) const override; int layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, - Qt::Orientation orientation, const QStyleOption *option = Q_NULLPTR, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; + Qt::Orientation orientation, const QStyleOption *option = nullptr, const QWidget *widget = nullptr) const override; - QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = Q_NULLPTR, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; - QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE; - QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const Q_DECL_OVERRIDE; - QPalette standardPalette() const Q_DECL_OVERRIDE; + QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = nullptr, const QWidget *widget = nullptr) const override; + QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget = nullptr) const override; + QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const override; + QPalette standardPalette() const override; - void polish(QWidget *widget) Q_DECL_OVERRIDE; - void polish(QPalette &pal) Q_DECL_OVERRIDE; - void polish(QApplication *app) Q_DECL_OVERRIDE; + void polish(QWidget *widget) override; + void polish(QPalette &pal) override; + void polish(QApplication *app) override; - void unpolish(QWidget *widget) Q_DECL_OVERRIDE; - void unpolish(QApplication *app) Q_DECL_OVERRIDE; + void unpolish(QWidget *widget) override; + void unpolish(QApplication *app) override; protected: - bool event(QEvent *e) Q_DECL_OVERRIDE; + bool event(QEvent *e) override; private: Q_DISABLE_COPY(QProxyStyle) diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp index 01d972af65..73a6554f1a 100644 --- a/src/widgets/styles/qstyle.cpp +++ b/src/widgets/styles/qstyle.cpp @@ -765,8 +765,7 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, */ /*! - \fn void QStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, \ - QPainter *painter, const QWidget *widget) const + \fn void QStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const Draws the given primitive \a element with the provided \a painter using the style options specified by \a option. @@ -1592,8 +1591,7 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, */ /*! - \fn QSize QStyle::sizeFromContents(ContentsType type, const QStyleOption *option, \ - const QSize &contentsSize, const QWidget *widget) const + \fn QSize QStyle::sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &contentsSize, const QWidget *widget) const Returns the size of the element described by the specified \a option and \a type, based on the provided \a contentsSize. @@ -1840,9 +1838,8 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, \value SH_UnderlineShortcut Whether shortcuts are underlined. - \value SH_SpellCheckUnderlineStyle A - QTextCharFormat::UnderlineStyle value that specifies the way - misspelled words should be underlined. + \value SH_SpellCheckUnderlineStyle Obsolete. Use SpellCheckUnderlineStyle + hint in QPlatformTheme instead. \value SH_SpinBox_AnimateButton Animate a click when up or down is pressed in a spin box. @@ -1972,9 +1969,7 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, a tooltip is shown (notice: shown, not hidden). When a new wake isn't needed, a user-requested tooltip will be shown nearly instantly. - \value SH_Widget_Animate Determines if the widget should show animations or not, for example - a transition between checked and unchecked statuses in a checkbox. - This enum value has been introduced in Qt 5.2. + \value SH_Widget_Animate Deprecated. Use \l{SH_Widget_Animation_Duration} instead. \value SH_Splitter_OpaqueResize Determines if resizing is opaque This enum value has been introduced in Qt 5.2 @@ -1987,12 +1982,30 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, by the style. Can be overridden with QAbstractItemView::setVerticalScrollMode() and QAbstractItemView::setHorizontalScrollMode(). This enum value has been introduced in Qt 5.7. + \value SH_TitleBar_ShowToolTipsOnButtons + Determines if tool tips are shown on window title bar buttons. + The Mac style, for example, sets this to false. + This enum value has been introduced in Qt 5.10. + + \value SH_Widget_Animation_Duration + Determines how much an animation should last (in ms). + A value equal to zero means that the animations will be disabled. + This enum value has been introduced in Qt 5.10. + + \value SH_ComboBox_AllowWheelScrolling + Determines if the mouse wheel can be used to scroll inside a QComboBox. + This is on by default in all styles except the Mac style. + This enum value has been introduced in Qt 5.10. + + \value SH_SpinBox_ButtonsInsideFrame + Determnines if the spin box buttons are inside the line edit frame. + This enum value has been introduced in Qt 5.11. + \sa styleHint() */ /*! - \fn int QStyle::styleHint(StyleHint hint, const QStyleOption *option, \ - const QWidget *widget, QStyleHintReturn *returnData) const + \fn int QStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const Returns an integer representing the specified style \a hint for the given \a widget described by the provided style \a option. @@ -2104,8 +2117,7 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, */ /*! - \fn QPixmap QStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option, \ - const QWidget *widget) const + \fn QPixmap QStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option, const QWidget *widget) const \obsolete Returns a pixmap for the given \a standardPixmap. @@ -2286,8 +2298,8 @@ int QStyle::sliderValueFromPosition(int min, int max, int pos, int span, bool up Returns the style's standard palette. Note that on systems that support system colors, the style's - standard palette is not used. In particular, the Windows XP, - Vista, and Mac styles do not use the standard palette, but make + standard palette is not used. In particular, the Windows + Vista and Mac styles do not use the standard palette, but make use of native theme engines. With these styles, you should not set the palette with QApplication::setPalette(). diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h index ce33dbed62..cef569d514 100644 --- a/src/widgets/styles/qstyle.h +++ b/src/widgets/styles/qstyle.h @@ -202,7 +202,7 @@ public: Q_ENUM(PrimitiveElement) virtual void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, - const QWidget *w = Q_NULLPTR) const = 0; + const QWidget *w = nullptr) const = 0; enum ControlElement { CE_PushButton, CE_PushButtonBevel, @@ -273,7 +273,7 @@ public: Q_ENUM(ControlElement) virtual void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, - const QWidget *w = Q_NULLPTR) const = 0; + const QWidget *w = nullptr) const = 0; enum SubElement { SE_PushButtonContents, @@ -362,7 +362,7 @@ public: Q_ENUM(SubElement) virtual QRect subElementRect(SubElement subElement, const QStyleOption *option, - const QWidget *widget = Q_NULLPTR) const = 0; + const QWidget *widget = nullptr) const = 0; enum ComplexControl { @@ -441,11 +441,11 @@ public: virtual void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, - const QWidget *widget = Q_NULLPTR) const = 0; + const QWidget *widget = nullptr) const = 0; virtual SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, - const QPoint &pt, const QWidget *widget = Q_NULLPTR) const = 0; + const QPoint &pt, const QWidget *widget = nullptr) const = 0; virtual QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, - SubControl sc, const QWidget *widget = Q_NULLPTR) const = 0; + SubControl sc, const QWidget *widget = nullptr) const = 0; enum PixelMetric { PM_ButtonMargin, @@ -579,8 +579,8 @@ public: }; Q_ENUM(PixelMetric) - virtual int pixelMetric(PixelMetric metric, const QStyleOption *option = Q_NULLPTR, - const QWidget *widget = Q_NULLPTR) const = 0; + virtual int pixelMetric(PixelMetric metric, const QStyleOption *option = nullptr, + const QWidget *widget = nullptr) const = 0; enum ContentsType { CT_PushButton, @@ -612,7 +612,7 @@ public: Q_ENUM(ContentsType) virtual QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, - const QSize &contentsSize, const QWidget *w = Q_NULLPTR) const = 0; + const QSize &contentsSize, const QWidget *w = nullptr) const = 0; enum RequestSoftwareInputPanel { RSIP_OnMouseClickAndAlreadyFocused, @@ -737,14 +737,18 @@ public: SH_Menu_SubMenuResetWhenReenteringParent, SH_Menu_SubMenuDontStartSloppyOnLeave, SH_ItemView_ScrollMode, + SH_TitleBar_ShowToolTipsOnButtons, + SH_Widget_Animation_Duration, + SH_ComboBox_AllowWheelScrolling, + SH_SpinBox_ButtonsInsideFrame, // Add new style hint values here SH_CustomBase = 0xf0000000 }; Q_ENUM(StyleHint) - virtual int styleHint(StyleHint stylehint, const QStyleOption *opt = Q_NULLPTR, - const QWidget *widget = Q_NULLPTR, QStyleHintReturn* returnData = Q_NULLPTR) const = 0; + virtual int styleHint(StyleHint stylehint, const QStyleOption *opt = nullptr, + const QWidget *widget = nullptr, QStyleHintReturn* returnData = nullptr) const = 0; enum StandardPixmap { SP_TitleBarMenuButton, @@ -823,11 +827,11 @@ public: }; Q_ENUM(StandardPixmap) - virtual QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt = Q_NULLPTR, - const QWidget *widget = Q_NULLPTR) const = 0; + virtual QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt = nullptr, + const QWidget *widget = nullptr) const = 0; - virtual QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = Q_NULLPTR, - const QWidget *widget = Q_NULLPTR) const = 0; + virtual QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = nullptr, + const QWidget *widget = nullptr) const = 0; virtual QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const = 0; @@ -846,10 +850,10 @@ public: virtual int layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, Qt::Orientation orientation, - const QStyleOption *option = Q_NULLPTR, const QWidget *widget = Q_NULLPTR) const = 0; + const QStyleOption *option = nullptr, const QWidget *widget = nullptr) const = 0; int combinedLayoutSpacing(QSizePolicy::ControlTypes controls1, QSizePolicy::ControlTypes controls2, Qt::Orientation orientation, - QStyleOption *option = Q_NULLPTR, QWidget *widget = Q_NULLPTR) const; + QStyleOption *option = nullptr, QWidget *widget = nullptr) const; const QStyle * proxy() const; diff --git a/src/widgets/styles/qstyle.qrc b/src/widgets/styles/qstyle.qrc index d8c73dd6fa..2dc3207e6d 100644 --- a/src/widgets/styles/qstyle.qrc +++ b/src/widgets/styles/qstyle.qrc @@ -128,13 +128,24 @@ <file>images/media-volume-16.png</file> <file>images/media-volume-muted-16.png</file> <file>images/fusion_groupbox.png</file> - <file>images/fusion_arrow.png</file> + <file>images/closedock-10.png</file> + <file>images/closedock-16.png</file> + <file>images/closedock-20.png</file> + <file>images/closedock-32.png</file> + <file>images/closedock-48.png</file> + <file>images/closedock-64.png</file> + <file>images/normalizedockup-10.png</file> + <file>images/normalizedockup-16.png</file> + <file>images/normalizedockup-20.png</file> + <file>images/normalizedockup-32.png</file> + <file>images/normalizedockup-48.png</file> + <file>images/normalizedockup-64.png</file> </qresource> <qresource prefix="/qt-project.org/styles/macstyle"> - <file>images/closedock-16.png</file> - <file>images/closedock-down-16.png</file> - <file>images/dockdock-16.png</file> - <file>images/dockdock-down-16.png</file> + <file alias="images/closedock-16.png">images/closedock-macstyle-16.png</file> + <file alias="images/closedock-down-16.png">images/closedock-down-macstyle-16.png</file> + <file alias="images/dockdock-16.png">images/dockdock-macstyle-16.png</file> + <file alias="images/dockdock-down-16.png">images/dockdock-down-macstyle-16.png</file> <file>images/toolbar-ext.png</file> <file>images/toolbar-ext@2x.png</file> </qresource> diff --git a/src/widgets/styles/qstyleanimation_p.h b/src/widgets/styles/qstyleanimation_p.h index 3b10eeea27..a2ad4a91da 100644 --- a/src/widgets/styles/qstyleanimation_p.h +++ b/src/widgets/styles/qstyleanimation_p.h @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE // We mean it. // -class QStyleAnimation : public QAbstractAnimation +class Q_WIDGETS_EXPORT QStyleAnimation : public QAbstractAnimation { Q_OBJECT @@ -70,7 +70,7 @@ public: QObject *target() const; - int duration() const Q_DECL_OVERRIDE; + int duration() const override; void setDuration(int duration); int delay() const; @@ -83,7 +83,8 @@ public: DefaultFps, SixtyFps, ThirtyFps, - TwentyFps + TwentyFps, + FifteenFps }; FrameRate frameRate() const; @@ -96,7 +97,7 @@ public Q_SLOTS: protected: virtual bool isUpdateNeeded() const; - virtual void updateCurrentTime(int time) Q_DECL_OVERRIDE; + virtual void updateCurrentTime(int time) override; private: int _delay; @@ -106,7 +107,7 @@ private: int _skip; }; -class QProgressStyleAnimation : public QStyleAnimation +class Q_WIDGETS_EXPORT QProgressStyleAnimation : public QStyleAnimation { Q_OBJECT @@ -120,14 +121,14 @@ public: void setSpeed(int speed); protected: - bool isUpdateNeeded() const Q_DECL_OVERRIDE; + bool isUpdateNeeded() const override; private: int _speed; mutable int _step; }; -class QNumberStyleAnimation : public QStyleAnimation +class Q_WIDGETS_EXPORT QNumberStyleAnimation : public QStyleAnimation { Q_OBJECT @@ -143,7 +144,7 @@ public: qreal currentValue() const; protected: - bool isUpdateNeeded() const Q_DECL_OVERRIDE; + bool isUpdateNeeded() const override; private: qreal _start; @@ -151,7 +152,7 @@ private: mutable qreal _prev; }; -class QBlendStyleAnimation : public QStyleAnimation +class Q_WIDGETS_EXPORT QBlendStyleAnimation : public QStyleAnimation { Q_OBJECT @@ -169,7 +170,7 @@ public: QImage currentImage() const; protected: - virtual void updateCurrentTime(int time) Q_DECL_OVERRIDE; + virtual void updateCurrentTime(int time) override; private: Type _type; @@ -178,7 +179,7 @@ private: QImage _current; }; -class QScrollbarStyleAnimation : public QNumberStyleAnimation +class Q_WIDGETS_EXPORT QScrollbarStyleAnimation : public QNumberStyleAnimation { Q_OBJECT @@ -193,7 +194,7 @@ public: void setActive(bool active); private slots: - void updateCurrentTime(int time) Q_DECL_OVERRIDE; + void updateCurrentTime(int time) override; private: Mode _mode; diff --git a/src/widgets/styles/qstylefactory.cpp b/src/widgets/styles/qstylefactory.cpp index 8dc603f8e6..c959994d2c 100644 --- a/src/widgets/styles/qstylefactory.cpp +++ b/src/widgets/styles/qstylefactory.cpp @@ -46,19 +46,6 @@ #include "qwindowsstyle_p.h" #if QT_CONFIG(style_fusion) #include "qfusionstyle_p.h" -#if QT_CONFIG(style_android) -#include "qandroidstyle_p.h" -#endif -#endif -#if QT_CONFIG(style_windowsxp) -#include "qwindowsxpstyle_p.h" -#endif -#if QT_CONFIG(style_windowsvista) -#include "qwindowsvistastyle_p.h" -#endif - -#if QT_CONFIG(style_mac) -# include "qmacstyle_mac_p.h" #endif QT_BEGIN_NAMESPACE @@ -81,7 +68,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, The valid keys can be retrieved using the keys() function. Typically they include "windows" and "fusion". - Depending on the platform, "windowsxp", "windowsvista" + Depending on the platform, "windowsvista" and "macintosh" may be available. Note that keys are case insensitive. @@ -108,35 +95,11 @@ QStyle *QStyleFactory::create(const QString& key) ret = new QWindowsStyle; else #endif -#if QT_CONFIG(style_windowsxp) - if (style == QLatin1String("windowsxp")) - ret = new QWindowsXPStyle; - else -#endif -#if QT_CONFIG(style_windowsvista) - if (style == QLatin1String("windowsvista")) - ret = new QWindowsVistaStyle; - else -#endif #if QT_CONFIG(style_fusion) if (style == QLatin1String("fusion")) ret = new QFusionStyle; else #endif -#if QT_CONFIG(style_android) - if (style == QLatin1String("android")) - ret = new QAndroidStyle; - else -#endif -#if QT_CONFIG(style_mac) - if (style.startsWith(QLatin1String("macintosh"))) { - ret = new QMacStyle; -# if 0 // Used to be included in Qt4 for Q_WS_MAC - if (style == QLatin1String("macintosh")) - style += QLatin1String(" (aqua)"); -# endif - } else -#endif { } // Keep these here - they make the #ifdefery above work if (!ret) ret = qLoadPlugin<QStyle, QStylePlugin>(loader(), style); @@ -164,32 +127,10 @@ QStringList QStyleFactory::keys() if (!list.contains(QLatin1String("Windows"))) list << QLatin1String("Windows"); #endif -#if QT_CONFIG(style_windowsxp) - if (!list.contains(QLatin1String("WindowsXP")) && - (QSysInfo::WindowsVersion >= QSysInfo::WV_XP && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based))) - list << QLatin1String("WindowsXP"); -#endif -#if QT_CONFIG(style_windowsvista) - if (!list.contains(QLatin1String("WindowsVista")) && - (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based))) - list << QLatin1String("WindowsVista"); -#endif -#if QT_CONFIG(style_android) - if (!list.contains(QLatin1String("Android"))) - list << QLatin1String("Android"); -#endif #if QT_CONFIG(style_fusion) if (!list.contains(QLatin1String("Fusion"))) list << QLatin1String("Fusion"); #endif -#if QT_CONFIG(style_mac) - QString mstyle = QLatin1String("Macintosh"); -# if 0 // Used to be included in Qt4 for Q_WS_MAC - mstyle += QLatin1String(" (aqua)"); -# endif - if (!list.contains(mstyle)) - list << mstyle; -#endif return list; } diff --git a/src/widgets/styles/qstylehelper.cpp b/src/widgets/styles/qstylehelper.cpp index 141b731b65..373699a7aa 100644 --- a/src/widgets/styles/qstylehelper.cpp +++ b/src/widgets/styles/qstylehelper.cpp @@ -51,8 +51,6 @@ #include "qstylehelper_p.h" #include <qstringbuilder.h> -#include <qdatastream.h> -#include <qcryptographichash.h> QT_BEGIN_NAMESPACE @@ -66,6 +64,7 @@ QString uniqueName(const QString &key, const QStyleOption *option, const QSize & QString tmp = key % HexString<uint>(option->state) % HexString<uint>(option->direction) % HexString<uint>(complexOption ? uint(complexOption->activeSubControls) : 0u) + % HexString<quint64>(option->palette.cacheKey()) % HexString<uint>(size.width()) % HexString<uint>(size.height()); @@ -77,24 +76,6 @@ QString uniqueName(const QString &key, const QStyleOption *option, const QSize & } #endif // QT_CONFIG(spinbox) - // QTBUG-56743, try to create a palette cache key reflecting the value, - // as leaks may occur in conjunction with QStyleSheetStyle/QRenderRule modifying - // palettes when using QPalette::cacheKey() - if (option->palette != QGuiApplication::palette()) { - tmp.append(QLatin1Char('P')); -#ifndef QT_NO_DATASTREAM - QByteArray key; - key.reserve(5120); // Observed 5040B for a serialized palette on 64bit - { - QDataStream str(&key, QIODevice::WriteOnly); - str << option->palette; - } - const QByteArray sha1 = QCryptographicHash::hash(key, QCryptographicHash::Sha1).toHex(); - tmp.append(QString::fromLatin1(sha1)); -#else // QT_NO_DATASTREAM - tmp.append(QString::number(option->palette.cacheKey(), 16)); -#endif // !QT_NO_DATASTREAM - } return tmp; } @@ -430,5 +411,34 @@ QWindow *styleObjectWindow(QObject *so) return 0; } +void setWidgetSizePolicy(const QWidget *widget, WidgetSizePolicy policy) +{ + QWidget *wadget = const_cast<QWidget *>(widget); + wadget->setAttribute(Qt::WA_MacNormalSize, policy == SizeLarge); + wadget->setAttribute(Qt::WA_MacSmallSize, policy == SizeSmall); + wadget->setAttribute(Qt::WA_MacMiniSize, policy == SizeMini); +} + +WidgetSizePolicy widgetSizePolicy(const QWidget *widget, const QStyleOption *opt) +{ + while (widget) { + if (widget->testAttribute(Qt::WA_MacMiniSize)) { + return SizeMini; + } else if (widget->testAttribute(Qt::WA_MacSmallSize)) { + return SizeSmall; + } else if (widget->testAttribute(Qt::WA_MacNormalSize)) { + return SizeLarge; + } + widget = widget->parentWidget(); + } + + if (opt && opt->state & QStyle::State_Mini) + return SizeMini; + else if (opt && opt->state & QStyle::State_Small) + return SizeSmall; + + return SizeDefault; +} + } QT_END_NAMESPACE diff --git a/src/widgets/styles/qstylehelper_p.h b/src/widgets/styles/qstylehelper_p.h index 17b6d9ab4f..bd263cea7b 100644 --- a/src/widgets/styles/qstylehelper_p.h +++ b/src/widgets/styles/qstylehelper_p.h @@ -62,31 +62,40 @@ QT_BEGIN_NAMESPACE +class QColor; +class QObject; class QPainter; +class QPalette; class QPixmap; class QStyleOptionSlider; class QStyleOption; +class QWidget; class QWindow; namespace QStyleHelper { QString uniqueName(const QString &key, const QStyleOption *option, const QSize &size); - qreal dpiScaled(qreal value); + Q_WIDGETS_EXPORT qreal dpiScaled(qreal value); #if QT_CONFIG(dial) qreal angle(const QPointF &p1, const QPointF &p2); QPolygonF calcLines(const QStyleOptionSlider *dial); int calcBigLineSize(int radius); - void drawDial(const QStyleOptionSlider *dial, QPainter *painter); + Q_WIDGETS_EXPORT void drawDial(const QStyleOptionSlider *dial, QPainter *painter); #endif //QT_CONFIG(dial) - void drawBorderPixmap(const QPixmap &pixmap, QPainter *painter, const QRect &rect, + Q_WIDGETS_EXPORT void drawBorderPixmap(const QPixmap &pixmap, QPainter *painter, const QRect &rect, int left = 0, int top = 0, int right = 0, int bottom = 0); #ifndef QT_NO_ACCESSIBILITY - bool isInstanceOf(QObject *obj, QAccessible::Role role); - bool hasAncestor(QObject *obj, QAccessible::Role role); + Q_WIDGETS_EXPORT bool isInstanceOf(QObject *obj, QAccessible::Role role); + Q_WIDGETS_EXPORT bool hasAncestor(QObject *obj, QAccessible::Role role); #endif - QColor backgroundColor(const QPalette &pal, const QWidget* widget = 0); - QWindow *styleObjectWindow(QObject *so); + Q_WIDGETS_EXPORT QColor backgroundColor(const QPalette &pal, const QWidget* widget = 0); + Q_WIDGETS_EXPORT QWindow *styleObjectWindow(QObject *so); + + enum WidgetSizePolicy { SizeLarge = 0, SizeSmall = 1, SizeMini = 2, SizeDefault = -1 }; + + void setWidgetSizePolicy(const QWidget *w, WidgetSizePolicy policy); + Q_WIDGETS_EXPORT WidgetSizePolicy widgetSizePolicy(const QWidget *w, const QStyleOption *opt = 0); } diff --git a/src/widgets/styles/qstyleoption.cpp b/src/widgets/styles/qstyleoption.cpp index 3e73abc62c..3666bce205 100644 --- a/src/widgets/styles/qstyleoption.cpp +++ b/src/widgets/styles/qstyleoption.cpp @@ -38,11 +38,9 @@ ****************************************************************************/ #include <QtWidgets/private/qtwidgetsglobal_p.h> +#include "private/qstylehelper_p.h" #include "qstyleoption.h" #include "qapplication.h" -#if QT_CONFIG(style_mac) -# include "qmacstyle_mac_p.h" -#endif #include <qdebug.h> #include <QtCore/qmath.h> @@ -205,18 +203,16 @@ void QStyleOption::init(const QWidget *widget) if (!(state & QStyle::State_Active) && !qt_mac_can_clickThrough(widget)) state &= ~QStyle::State_Enabled; #endif -#if QT_CONFIG(style_mac) - switch (QMacStyle::widgetSizePolicy(widget)) { - case QMacStyle::SizeSmall: + switch (QStyleHelper::widgetSizePolicy(widget)) { + case QStyleHelper::SizeSmall: state |= QStyle::State_Small; break; - case QMacStyle::SizeMini: + case QStyleHelper::SizeMini: state |= QStyle::State_Mini; break; default: ; } -#endif #ifdef QT_KEYPAD_NAVIGATION if (widget->hasEditFocus()) state |= QStyle::State_HasEditFocus; @@ -3269,7 +3265,7 @@ QStyleOptionViewItem::QStyleOptionViewItem(int version) #endif // QT_CONFIG(itemviews) /*! - \fn T qstyleoption_cast<T>(const QStyleOption *option) + \fn template <typename T> T qstyleoption_cast<T>(const QStyleOption *option) \relates QStyleOption Returns a T or 0 depending on the \l{QStyleOption::type}{type} and @@ -3283,7 +3279,7 @@ QStyleOptionViewItem::QStyleOptionViewItem(int version) */ /*! - \fn T qstyleoption_cast<T>(QStyleOption *option) + \fn template <typename T> T qstyleoption_cast<T>(QStyleOption *option) \overload \relates QStyleOption @@ -4005,7 +4001,7 @@ QStyleHintReturnVariant::~QStyleHintReturnVariant() */ /*! - \fn T qstyleoption_cast<T>(const QStyleHintReturn *hint) + \fn template <typename T> T qstyleoption_cast<T>(const QStyleHintReturn *hint) \relates QStyleHintReturn Returns a T or 0 depending on the \l{QStyleHintReturn::type}{type} @@ -4019,7 +4015,7 @@ QStyleHintReturnVariant::~QStyleHintReturnVariant() */ /*! - \fn T qstyleoption_cast<T>(QStyleHintReturn *hint) + \fn template <typename T> T qstyleoption_cast<T>(QStyleHintReturn *hint) \overload \relates QStyleHintReturn diff --git a/src/widgets/styles/qstyleoption.h b/src/widgets/styles/qstyleoption.h index f703c56917..2880917510 100644 --- a/src/widgets/styles/qstyleoption.h +++ b/src/widgets/styles/qstyleoption.h @@ -682,7 +682,7 @@ T qstyleoption_cast(const QStyleOption *opt) || (int(Opt::Type) == QStyleOption::SO_Complex && opt->type > QStyleOption::SO_Complex))) return static_cast<T>(opt); - return Q_NULLPTR; + return nullptr; } template <typename T> @@ -694,7 +694,7 @@ T qstyleoption_cast(QStyleOption *opt) || (int(Opt::Type) == QStyleOption::SO_Complex && opt->type > QStyleOption::SO_Complex))) return static_cast<T>(opt); - return Q_NULLPTR; + return nullptr; } // -------------------------- QStyleHintReturn ------------------------------- @@ -743,7 +743,7 @@ T qstyleoption_cast(const QStyleHintReturn *hint) if (hint && hint->version <= Opt::Version && (hint->type == Opt::Type || int(Opt::Type) == QStyleHintReturn::SH_Default)) return static_cast<T>(hint); - return Q_NULLPTR; + return nullptr; } template <typename T> @@ -753,7 +753,7 @@ T qstyleoption_cast(QStyleHintReturn *hint) if (hint && hint->version <= Opt::Version && (hint->type == Opt::Type || int(Opt::Type) == QStyleHintReturn::SH_Default)) return static_cast<T>(hint); - return Q_NULLPTR; + return nullptr; } #if !defined(QT_NO_DEBUG_STREAM) diff --git a/src/widgets/styles/qstylepainter.h b/src/widgets/styles/qstylepainter.h index 191360727e..b5e7956cb1 100644 --- a/src/widgets/styles/qstylepainter.h +++ b/src/widgets/styles/qstylepainter.h @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE class QStylePainter : public QPainter { public: - inline QStylePainter() : QPainter(), widget(Q_NULLPTR), wstyle(Q_NULLPTR) {} + inline QStylePainter() : QPainter(), widget(nullptr), wstyle(nullptr) {} inline explicit QStylePainter(QWidget *w) { begin(w, w); } inline QStylePainter(QPaintDevice *pd, QWidget *w) { begin(pd, w); } inline bool begin(QWidget *w) { return begin(w, w); } diff --git a/src/widgets/styles/qstyleplugin.h b/src/widgets/styles/qstyleplugin.h index d44f57d208..e9a26f9127 100644 --- a/src/widgets/styles/qstyleplugin.h +++ b/src/widgets/styles/qstyleplugin.h @@ -55,7 +55,7 @@ class Q_WIDGETS_EXPORT QStylePlugin : public QObject { Q_OBJECT public: - explicit QStylePlugin(QObject *parent = Q_NULLPTR); + explicit QStylePlugin(QObject *parent = nullptr); ~QStylePlugin(); virtual QStyle *create(const QString &key) = 0; diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index f70313d49e..e12aeb900b 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -710,10 +710,12 @@ static const char knownStyleHints[][45] = { "titlebar-minimize-icon", "titlebar-normal-icon", "titlebar-shade-icon", + "titlebar-show-tooltips-on-buttons", "titlebar-unshade-icon", "toolbutton-popup-delay", "trash-icon", - "uparrow-icon" + "uparrow-icon", + "widget-animation-duration" }; static const int numKnownStyleHints = sizeof(knownStyleHints)/sizeof(knownStyleHints[0]); @@ -831,7 +833,7 @@ QHash<QStyle::SubControl, QRect> QStyleSheetStyle::titleBarLayout(const QWidget continue; } if (info.element == PseudoElement_TitleBar) { - info.width = tb->fontMetrics.width(tb->text) + 6; + info.width = tb->fontMetrics.horizontalAdvance(tb->text) + 6; subRule.geo = new QStyleSheetGeometryData(info.width, tb->fontMetrics.height(), -1, -1, -1, -1); } else { subRule = renderRule(w, tb, info.element); @@ -1461,7 +1463,7 @@ class QStyleSheetStyleSelector : public StyleSelector public: QStyleSheetStyleSelector() { } - QStringList nodeNames(NodePtr node) const Q_DECL_OVERRIDE + QStringList nodeNames(NodePtr node) const override { if (isNullNode(node)) return QStringList(); @@ -1477,7 +1479,7 @@ public: } while (metaObject != 0); return result; } - QString attribute(NodePtr node, const QString& name) const Q_DECL_OVERRIDE + QString attribute(NodePtr node, const QString& name) const override { if (isNullNode(node)) return QString(); @@ -1514,7 +1516,7 @@ public: cache[name] = valueStr; return valueStr; } - bool nodeNameEquals(NodePtr node, const QString& nodeName) const Q_DECL_OVERRIDE + bool nodeNameEquals(NodePtr node, const QString& nodeName) const override { if (isNullNode(node)) return false; @@ -1537,19 +1539,19 @@ public: } while (metaObject != 0); return false; } - bool hasAttributes(NodePtr) const Q_DECL_OVERRIDE + bool hasAttributes(NodePtr) const override { return true; } - QStringList nodeIds(NodePtr node) const Q_DECL_OVERRIDE + QStringList nodeIds(NodePtr node) const override { return isNullNode(node) ? QStringList() : QStringList(OBJECT_PTR(node)->objectName()); } - bool isNullNode(NodePtr node) const Q_DECL_OVERRIDE + bool isNullNode(NodePtr node) const override { return node.ptr == 0; } - NodePtr parentNode(NodePtr node) const Q_DECL_OVERRIDE + NodePtr parentNode(NodePtr node) const override { NodePtr n; n.ptr = isNullNode(node) ? 0 : parentObject(OBJECT_PTR(node)); return n; } - NodePtr previousSiblingNode(NodePtr) const Q_DECL_OVERRIDE + NodePtr previousSiblingNode(NodePtr) const override { NodePtr n; n.ptr = 0; return n; } - NodePtr duplicateNode(NodePtr node) const Q_DECL_OVERRIDE + NodePtr duplicateNode(NodePtr node) const override { return node; } - void freeNode(NodePtr) const Q_DECL_OVERRIDE + void freeNode(NodePtr) const override { } private: @@ -2690,24 +2692,19 @@ void QStyleSheetStyle::unsetStyleSheetFont(QWidget *w) const static void updateObjects(const QList<const QObject *>& objects) { if (!styleSheetCaches->styleRulesCache.isEmpty() || !styleSheetCaches->hasStyleRuleCache.isEmpty() || !styleSheetCaches->renderRulesCache.isEmpty()) { - for (int i = 0; i < objects.size(); ++i) { - const QObject *object = objects.at(i); + for (const QObject *object : objects) { styleSheetCaches->styleRulesCache.remove(object); styleSheetCaches->hasStyleRuleCache.remove(object); styleSheetCaches->renderRulesCache.remove(object); } } - QWidgetList widgets; - foreach (const QObject *object, objects) { - if (QWidget *w = qobject_cast<QWidget*>(const_cast<QObject*>(object))) - widgets << w; - } - QEvent event(QEvent::StyleChange); - foreach (QWidget *widget, widgets) { - widget->style()->polish(widget); - QApplication::sendEvent(widget, &event); + for (const QObject *object : objects) { + if (auto widget = qobject_cast<QWidget*>(const_cast<QObject*>(object))) { + widget->style()->polish(widget); + QApplication::sendEvent(widget, &event); + } } } @@ -4262,7 +4259,7 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op switch (pe) { case PE_FrameStatusBar: { - QRenderRule subRule = renderRule(w ? w->parentWidget() : Q_NULLPTR, opt, PseudoElement_Item); + QRenderRule subRule = renderRule(w ? w->parentWidget() : nullptr, opt, PseudoElement_Item); if (subRule.hasDrawable()) { subRule.drawRule(p, opt->rect); return; @@ -4620,7 +4617,7 @@ QStyle::SubControl QStyleSheetStyle::hitTestComplexControl(ComplexControl cc, co if (!rule.hasDrawable() && !rule.hasBox()) break; } - // intentionally falls through + Q_FALLTHROUGH(); case CC_SpinBox: case CC_GroupBox: case CC_ComboBox: @@ -5348,6 +5345,8 @@ int QStyleSheetStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWi } case SH_ItemView_ArrowKeysNavigateIntoChildren: s = QLatin1String("arrow-keys-navigate-into-children"); break; case SH_ItemView_PaintAlternatingRowColorsForEmptyArea: s = QLatin1String("paint-alternating-row-colors-for-empty-area"); break; + case SH_TitleBar_ShowToolTipsOnButtons: s = QLatin1String("titlebar-show-tooltips-on-buttons"); break; + case SH_Widget_Animation_Duration: s = QLatin1String("widget-animation-duration"); break; default: break; } if (!s.isEmpty() && rule.hasStyleHint(s)) { @@ -5483,7 +5482,7 @@ QRect QStyleSheetStyle::subControlRect(ComplexControl cc, const QStyleOptionComp groupBox.rect = rule.borderRect(opt->rect); return baseStyle()->subControlRect(cc, &groupBox, sc, w); } - int tw = opt->fontMetrics.width(gb->text); + int tw = opt->fontMetrics.horizontalAdvance(gb->text); int th = opt->fontMetrics.height(); int spacing = pixelMetric(QStyle::PM_CheckBoxLabelSpacing, opt, w); int iw = pixelMetric(QStyle::PM_IndicatorWidth, opt, w); @@ -5784,7 +5783,7 @@ QRect QStyleSheetStyle::subElementRect(SubElement se, const QStyleOption *opt, c if (!qstyleoption_cast<const QStyleOptionViewItem *>(opt)) { return subElementRect(SE_CheckBoxIndicator, opt, w); } - // intentionally falls through + Q_FALLTHROUGH(); case SE_ItemViewItemText: case SE_ItemViewItemDecoration: case SE_ItemViewItemFocusRect: @@ -5844,15 +5843,15 @@ QRect QStyleSheetStyle::subElementRect(SubElement se, const QStyleOption *opt, c #if QT_CONFIG(tabbar) case SE_TabWidgetLeftCorner: pe = PseudoElement_TabWidgetLeftCorner; - // intentionally falls through + Q_FALLTHROUGH(); case SE_TabWidgetRightCorner: if (pe == PseudoElement_None) pe = PseudoElement_TabWidgetRightCorner; - // intentionally falls through + Q_FALLTHROUGH(); case SE_TabWidgetTabBar: if (pe == PseudoElement_None) pe = PseudoElement_TabWidgetTabBar; - // intentionally falls through + Q_FALLTHROUGH(); case SE_TabWidgetTabPane: case SE_TabWidgetTabContents: if (pe == PseudoElement_None) diff --git a/src/widgets/styles/qstylesheetstyle_default.cpp b/src/widgets/styles/qstylesheetstyle_default.cpp index 168251b0f3..1cb1adb2db 100644 --- a/src/widgets/styles/qstylesheetstyle_default.cpp +++ b/src/widgets/styles/qstylesheetstyle_default.cpp @@ -78,7 +78,7 @@ using namespace QCss; bSelector.pseudos << pseudo // This is attributes. The third parameter is AttributeSelector::* -// Ex. QComboBox[style="QWindowsXPStyle"] +// Ex. QComboBox[style="QWindowsVistaStyle"] // ^ ^ #define ADD_ATTRIBUTE_SELECTOR(x, y, z) \ @@ -155,7 +155,7 @@ StyleSheet QStyleSheetStyle::getDefaultStyleSheet() const // pixmap based style doesn't support any features bool styleIsPixmapBased = baseStyle()->inherits("QMacStyle") - || baseStyle()->inherits("QWindowsXPStyle"); + || baseStyle()->inherits("QWindowsVistaStyle"); /*QLineEdit { diff --git a/src/widgets/styles/qstylesheetstyle_p.h b/src/widgets/styles/qstylesheetstyle_p.h index 2d302305bd..042abf5c22 100644 --- a/src/widgets/styles/qstylesheetstyle_p.h +++ b/src/widgets/styles/qstylesheetstyle_p.h @@ -82,48 +82,48 @@ public: ~QStyleSheetStyle(); void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, - const QWidget *w = 0) const Q_DECL_OVERRIDE; + const QWidget *w = 0) const override; void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, - const QWidget *w = 0) const Q_DECL_OVERRIDE; - void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const Q_DECL_OVERRIDE; + const QWidget *w = 0) const override; + void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const override; void drawItemText(QPainter *painter, const QRect& rect, int alignment, const QPalette &pal, - bool enabled, const QString& text, QPalette::ColorRole textRole = QPalette::NoRole) const Q_DECL_OVERRIDE; + bool enabled, const QString& text, QPalette::ColorRole textRole = QPalette::NoRole) const override; void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, - const QWidget *w = 0) const Q_DECL_OVERRIDE; + const QWidget *w = 0) const override; QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, - const QStyleOption *option) const Q_DECL_OVERRIDE; + const QStyleOption *option) const override; SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, - const QPoint &pt, const QWidget *w = 0) const Q_DECL_OVERRIDE; - QRect itemPixmapRect(const QRect &rect, int alignment, const QPixmap &pixmap) const Q_DECL_OVERRIDE; + const QPoint &pt, const QWidget *w = 0) const override; + QRect itemPixmapRect(const QRect &rect, int alignment, const QPixmap &pixmap) const override; QRect itemTextRect(const QFontMetrics &metrics, const QRect &rect, int alignment, bool enabled, - const QString &text) const Q_DECL_OVERRIDE; - int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const Q_DECL_OVERRIDE; - void polish(QWidget *widget) Q_DECL_OVERRIDE; - void polish(QApplication *app) Q_DECL_OVERRIDE; - void polish(QPalette &pal) Q_DECL_OVERRIDE; + const QString &text) const override; + int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const override; + void polish(QWidget *widget) override; + void polish(QApplication *app) override; + void polish(QPalette &pal) override; QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, - const QSize &contentsSize, const QWidget *widget = 0) const Q_DECL_OVERRIDE; - QPalette standardPalette() const Q_DECL_OVERRIDE; + const QSize &contentsSize, const QWidget *widget = 0) const override; + QPalette standardPalette() const override; QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *opt = 0, - const QWidget *widget = 0) const Q_DECL_OVERRIDE; + const QWidget *widget = 0) const override; QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option = 0, - const QWidget *w = 0 ) const Q_DECL_OVERRIDE; + const QWidget *w = 0 ) const override; int layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, Qt::Orientation orientation, const QStyleOption *option = 0, - const QWidget *widget = 0) const Q_DECL_OVERRIDE; + const QWidget *widget = 0) const override; int styleHint(StyleHint sh, const QStyleOption *opt = 0, const QWidget *w = 0, - QStyleHintReturn *shret = 0) const Q_DECL_OVERRIDE; - QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const Q_DECL_OVERRIDE; + QStyleHintReturn *shret = 0) const override; + QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const override; QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, - const QWidget *w = 0) const Q_DECL_OVERRIDE; + const QWidget *w = 0) const override; // These functions are called from QApplication/QWidget. Be careful. QStyle *baseStyle() const; void repolish(QWidget *widget); void repolish(QApplication *app); - void unpolish(QWidget *widget) Q_DECL_OVERRIDE; - void unpolish(QApplication *app) Q_DECL_OVERRIDE; + void unpolish(QWidget *widget) override; + void unpolish(QApplication *app) override; QStyle *base; void ref() { ++refcount; } @@ -136,7 +136,7 @@ public: bool styleSheetPalette(const QWidget* w, const QStyleOption* opt, QPalette* pal); protected: - bool event(QEvent *e) Q_DECL_OVERRIDE; + bool event(QEvent *e) override; private: int refcount; diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp index 657166fc8d..89011350ec 100644 --- a/src/widgets/styles/qwindowsstyle.cpp +++ b/src/widgets/styles/qwindowsstyle.cpp @@ -380,7 +380,7 @@ int QWindowsStylePrivate::fixedPixelMetric(QStyle::PixelMetric pm) static QWindow *windowOf(const QWidget *w) { - QWindow *result = Q_NULLPTR; + QWindow *result = nullptr; if (w) { result = w->windowHandle(); if (!result) { @@ -798,9 +798,10 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, break; case PE_FrameDefaultButton: { QPen oldPen = p->pen(); - p->setPen(opt->palette.shadow().color()); - QRect rect = opt->rect; - rect.adjust(0, 0, -1, -1); + p->setPen(QPen(opt->palette.shadow().color(), 0)); + QRectF rect = opt->rect; + rect.adjust(QStyleHelper::dpiScaled(0.5), QStyleHelper::dpiScaled(0.5), + QStyleHelper::dpiScaled(-1.5), QStyleHelper::dpiScaled(-1.5)); p->drawRect(rect); p->setPen(oldPen); break; @@ -843,22 +844,16 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, } #endif // QT_CONFIG(itemviews) if (!(opt->state & State_Off)) { - QLineF lines[7]; - int i, xx, yy; - xx = opt->rect.x() + 3; - yy = opt->rect.y() + 5; - for (i = 0; i < 3; ++i) { - lines[i] = QLineF(xx, yy, xx, yy + 2); - ++xx; - ++yy; - } - yy -= 2; - for (i = 3; i < 7; ++i) { - lines[i] = QLineF(xx, yy, xx, yy + 2); - ++xx; - --yy; - } - p->drawLines(lines, 7); + QPointF points[6]; + points[0] = { opt->rect.x() + QStyleHelper::dpiScaled(3.5), opt->rect.y() + QStyleHelper::dpiScaled(5.5) }; + points[1] = { points[0].x(), points[0].y() + QStyleHelper::dpiScaled(2) }; + points[2] = { points[1].x() + QStyleHelper::dpiScaled(2), points[1].y() + QStyleHelper::dpiScaled(2) }; + points[3] = { points[2].x() + QStyleHelper::dpiScaled(4), points[2].y() - QStyleHelper::dpiScaled(4) }; + points[4] = { points[3].x(), points[3].y() - QStyleHelper::dpiScaled(2) }; + points[5] = { points[4].x() - QStyleHelper::dpiScaled(4), points[4].y() + QStyleHelper::dpiScaled(4) }; + p->setPen(QPen(opt->palette.text().color(), 0)); + p->setBrush(opt->palette.text().color()); + p->drawPolygon(points, 6); } if (doRestore) p->restore(); @@ -890,86 +885,57 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, break; case PE_IndicatorRadioButton: { -#define PTSARRLEN(x) sizeof(x)/(sizeof(QPoint)) - static const QPoint pts1[] = { // dark lines - QPoint(1, 9), QPoint(1, 8), QPoint(0, 7), QPoint(0, 4), QPoint(1, 3), QPoint(1, 2), - QPoint(2, 1), QPoint(3, 1), QPoint(4, 0), QPoint(7, 0), QPoint(8, 1), QPoint(9, 1) - }; - static const QPoint pts2[] = { // black lines - QPoint(2, 8), QPoint(1, 7), QPoint(1, 4), QPoint(2, 3), QPoint(2, 2), QPoint(3, 2), - QPoint(4, 1), QPoint(7, 1), QPoint(8, 2), QPoint(9, 2) - }; - static const QPoint pts3[] = { // background lines - QPoint(2, 9), QPoint(3, 9), QPoint(4, 10), QPoint(7, 10), QPoint(8, 9), QPoint(9, 9), - QPoint(9, 8), QPoint(10, 7), QPoint(10, 4), QPoint(9, 3) - }; - static const QPoint pts4[] = { // white lines - QPoint(2, 10), QPoint(3, 10), QPoint(4, 11), QPoint(7, 11), QPoint(8, 10), - QPoint(9, 10), QPoint(10, 9), QPoint(10, 8), QPoint(11, 7), QPoint(11, 4), - QPoint(10, 3), QPoint(10, 2) - }; - static const QPoint pts5[] = { // inner fill - QPoint(4, 2), QPoint(7, 2), QPoint(9, 4), QPoint(9, 7), QPoint(7, 9), QPoint(4, 9), - QPoint(2, 7), QPoint(2, 4) - }; - - // make sure the indicator is square - QRect ir = opt->rect; - - if (opt->rect.width() < opt->rect.height()) { - ir.setTop(opt->rect.top() + (opt->rect.height() - opt->rect.width()) / 2); - ir.setHeight(opt->rect.width()); - } else if (opt->rect.height() < opt->rect.width()) { - ir.setLeft(opt->rect.left() + (opt->rect.width() - opt->rect.height()) / 2); - ir.setWidth(opt->rect.height()); - } - + QRect r = opt->rect; p->save(); - p->setRenderHint(QPainter::Qt4CompatiblePainting); - bool down = opt->state & State_Sunken; - bool enabled = opt->state & State_Enabled; - bool on = opt->state & State_On; - QPolygon a; - - //center when rect is larger than indicator size - int xOffset = 0; - int yOffset = 0; - int indicatorWidth = proxy()->pixelMetric(PM_ExclusiveIndicatorWidth); - int indicatorHeight = proxy()->pixelMetric(PM_ExclusiveIndicatorHeight); - if (ir.width() > indicatorWidth) - xOffset += (ir.width() - indicatorWidth)/2; - if (ir.height() > indicatorHeight) - yOffset += (ir.height() - indicatorHeight)/2; - p->translate(xOffset, yOffset); - - p->translate(ir.x(), ir.y()); - + p->setRenderHint(QPainter::Antialiasing, true); + + QPointF circleCenter = r.center() + QPoint(1, 1); + qreal radius = (r.width() + (r.width() + 1) % 2) / 2.0 - 1; + + QPainterPath path1; + path1.addEllipse(circleCenter, radius, radius); + radius *= 0.85; + QPainterPath path2; + path2.addEllipse(circleCenter, radius, radius); + radius *= 0.85; + QPainterPath path3; + path3.addEllipse(circleCenter, radius, radius); + radius *= 0.5; + QPainterPath path4; + path4.addEllipse(circleCenter, radius, radius); + + QPolygon topLeftPol, bottomRightPol; + topLeftPol.setPoints(3, r.x(), r.y(), r.x(), r.y() + r.height(), r.x() + r.width(), r.y()); + bottomRightPol.setPoints(3, r.x(), r.y() + r.height(), r.x() + r.width(), r.y() + r.height(), r.x() + r.width(), r.y()); + + p->setClipRegion(QRegion(topLeftPol)); p->setPen(opt->palette.dark().color()); - p->drawPolyline(pts1, PTSARRLEN(pts1)); - + p->setBrush(opt->palette.dark().color()); + p->drawPath(path1); p->setPen(opt->palette.shadow().color()); - p->drawPolyline(pts2, PTSARRLEN(pts2)); + p->setBrush(opt->palette.shadow().color()); + p->drawPath(path2); + p->setClipRegion(QRegion(bottomRightPol)); + p->setPen(opt->palette.light().color()); + p->setBrush(opt->palette.light().color()); + p->drawPath(path1); p->setPen(opt->palette.midlight().color()); - p->drawPolyline(pts3, PTSARRLEN(pts3)); + p->setBrush(opt->palette.midlight().color()); + p->drawPath(path2); - p->setPen(opt->palette.light().color()); - p->drawPolyline(pts4, PTSARRLEN(pts4)); + QColor fillColor = ((opt->state & State_Sunken) || !(opt->state & State_Enabled)) ? + opt->palette.button().color() : opt->palette.base().color(); - QColor fillColor = (down || !enabled) - ? opt->palette.button().color() - : opt->palette.base().color(); + p->setClipping(false); p->setPen(fillColor); - p->setBrush(fillColor) ; - p->drawPolygon(pts5, PTSARRLEN(pts5)); + p->setBrush(fillColor); + p->drawPath(path3); - p->translate(-ir.x(), -ir.y()); // restore translate - - if (on) { - p->setPen(Qt::NoPen); + if (opt->state & State_On) { + p->setPen(opt->palette.text().color()); p->setBrush(opt->palette.text()); - p->drawRect(ir.x() + 5, ir.y() + 4, 2, 4); - p->drawRect(ir.x() + 4, ir.y() + 5, 4, 2); + p->drawPath(path4); } p->restore(); break; @@ -2388,7 +2354,7 @@ QSize QWindowsStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, QFont fontBold = mi->font; fontBold.setBold(true); QFontMetrics fmBold(fontBold); - w += fmBold.width(mi->text) - fm.width(mi->text); + w += fmBold.horizontalAdvance(mi->text) - fm.horizontalAdvance(mi->text); } int checkcol = qMax<int>(maxpmw, QWindowsStylePrivate::windowsCheckMarkWidth); // Windows always shows a check column diff --git a/src/widgets/styles/qwindowsstyle_p.h b/src/widgets/styles/qwindowsstyle_p.h index a1d65610ff..7993b9f1c6 100644 --- a/src/widgets/styles/qwindowsstyle_p.h +++ b/src/widgets/styles/qwindowsstyle_p.h @@ -61,44 +61,44 @@ QT_BEGIN_NAMESPACE class QWindowsStylePrivate; -class QWindowsStyle : public QCommonStyle +class Q_WIDGETS_EXPORT QWindowsStyle : public QCommonStyle { Q_OBJECT public: QWindowsStyle(); ~QWindowsStyle(); - void polish(QApplication*) Q_DECL_OVERRIDE; - void unpolish(QApplication*) Q_DECL_OVERRIDE; + void polish(QApplication*) override; + void unpolish(QApplication*) override; - void polish(QWidget*) Q_DECL_OVERRIDE; - void unpolish(QWidget*) Q_DECL_OVERRIDE; + void polish(QWidget*) override; + void unpolish(QWidget*) override; - void polish(QPalette &) Q_DECL_OVERRIDE; + void polish(QPalette &) override; void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, - const QWidget *w = 0) const Q_DECL_OVERRIDE; + const QWidget *w = 0) const override; void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, - const QWidget *w = 0) const Q_DECL_OVERRIDE; - QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const Q_DECL_OVERRIDE; + const QWidget *w = 0) const override; + QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const override; void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, - const QWidget *w = 0) const Q_DECL_OVERRIDE; + const QWidget *w = 0) const override; QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, - const QSize &contentsSize, const QWidget *widget = 0) const Q_DECL_OVERRIDE; + const QSize &contentsSize, const QWidget *widget = 0) const override; - int pixelMetric(PixelMetric pm, const QStyleOption *option = 0, const QWidget *widget = 0) const Q_DECL_OVERRIDE; + int pixelMetric(PixelMetric pm, const QStyleOption *option = 0, const QWidget *widget = 0) const override; int styleHint(StyleHint hint, const QStyleOption *opt = 0, const QWidget *widget = 0, - QStyleHintReturn *returnData = 0) const Q_DECL_OVERRIDE; + QStyleHintReturn *returnData = 0) const override; QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, - const QWidget *widget = 0) const Q_DECL_OVERRIDE; + const QWidget *widget = 0) const override; QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = 0, - const QWidget *widget = 0) const Q_DECL_OVERRIDE; + const QWidget *widget = 0) const override; protected: - bool eventFilter(QObject *o, QEvent *e) Q_DECL_OVERRIDE; + bool eventFilter(QObject *o, QEvent *e) override; QWindowsStyle(QWindowsStylePrivate &dd); private: diff --git a/src/widgets/styles/qwindowsstyle_p_p.h b/src/widgets/styles/qwindowsstyle_p_p.h index 5023fd1042..67fa6a2f86 100644 --- a/src/widgets/styles/qwindowsstyle_p_p.h +++ b/src/widgets/styles/qwindowsstyle_p_p.h @@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE class QTime; -class QWindowsStylePrivate : public QCommonStylePrivate +class Q_WIDGETS_EXPORT QWindowsStylePrivate : public QCommonStylePrivate { Q_DECLARE_PUBLIC(QWindowsStyle) public: @@ -73,7 +73,7 @@ public: static int fixedPixelMetric(QStyle::PixelMetric pm); static qreal devicePixelRatio(const QWidget *widget = 0) { return widget ? widget->devicePixelRatioF() : QWindowsStylePrivate::appDevicePixelRatio(); } - static qreal nativeMetricScaleFactor(const QWidget *widget = Q_NULLPTR); + static qreal nativeMetricScaleFactor(const QWidget *widget = nullptr); bool hasSeenAlt(const QWidget *widget) const; bool altDown() const { return alt_down; } diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp deleted file mode 100644 index 906c3ed7c3..0000000000 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ /dev/null @@ -1,2492 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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 "qwindowsvistastyle_p.h" -#include "qwindowsvistastyle_p_p.h" -#include <qoperatingsystemversion.h> -#include <qscreen.h> -#include <qwindow.h> -#include <private/qstyleanimation_p.h> -#include <private/qstylehelper_p.h> -#include <private/qapplication_p.h> -#include <qpa/qplatformnativeinterface.h> - -#if QT_CONFIG(style_windowsvista) || defined(QT_PLUGIN) - -QT_BEGIN_NAMESPACE - -static const int windowsItemFrame = 2; // menu item frame width -static const int windowsItemHMargin = 3; // menu item hor text margin -static const int windowsItemVMargin = 4; // menu item ver text margin -static const int windowsArrowHMargin = 6; // arrow horizontal margin -static const int windowsRightBorder = 15; // right border on windows - -#ifndef TMT_CONTENTMARGINS -# define TMT_CONTENTMARGINS 3602 -#endif -#ifndef TMT_SIZINGMARGINS -# define TMT_SIZINGMARGINS 3601 -#endif -#ifndef LISS_NORMAL -# define LISS_NORMAL 1 -# define LISS_HOT 2 -# define LISS_SELECTED 3 -# define LISS_DISABLED 4 -# define LISS_SELECTEDNOTFOCUS 5 -# define LISS_HOTSELECTED 6 -#endif -#ifndef BP_COMMANDLINK -# define BP_COMMANDLINK 6 -# define BP_COMMANDLINKGLYPH 7 -# define CMDLGS_NORMAL 1 -# define CMDLGS_HOT 2 -# define CMDLGS_PRESSED 3 -# define CMDLGS_DISABLED 4 -#endif - -/* \internal - Checks if we should use Vista style , or if we should - fall back to Windows style. -*/ -bool QWindowsVistaStylePrivate::useVista() -{ - return (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA - && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)) - && QWindowsVistaStylePrivate::useXP(); -} - -/* \internal - Checks and returns the style object -*/ -inline QObject *styleObject(const QStyleOption *option) { - return option ? option->styleObject : 0; -} - -/* \internal - Checks if we can animate on a style option -*/ -bool canAnimate(const QStyleOption *option) { - return option - && option->styleObject - && !option->styleObject->property("_q_no_animation").toBool(); -} - -static inline QImage createAnimationBuffer(const QStyleOption *option, const QWidget *widget) -{ - const int devicePixelRatio = widget ? widget->devicePixelRatio() : 1; - QImage result(option->rect.size() * devicePixelRatio, QImage::Format_ARGB32_Premultiplied); - result.setDevicePixelRatio(devicePixelRatio); - result.fill(0); - return result; -} - -/* \internal - Used by animations to clone a styleoption and shift its offset -*/ -QStyleOption *clonedAnimationStyleOption(const QStyleOption*option) { - QStyleOption *styleOption = 0; - if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider*>(option)) - styleOption = new QStyleOptionSlider(*slider); - else if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox*>(option)) - styleOption = new QStyleOptionSpinBox(*spinbox); - else if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox*>(option)) - styleOption = new QStyleOptionGroupBox(*groupBox); - else if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox*>(option)) - styleOption = new QStyleOptionComboBox(*combo); - else if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton*>(option)) - styleOption = new QStyleOptionButton(*button); - else - styleOption = new QStyleOption(*option); - styleOption->rect = QRect(QPoint(0,0), option->rect.size()); - return styleOption; -} - -/* \internal - Used by animations to delete cloned styleoption -*/ -void deleteClonedAnimationStyleOption(const QStyleOption *option) -{ - if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider*>(option)) - delete slider; - else if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox*>(option)) - delete spinbox; - else if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox*>(option)) - delete groupBox; - else if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox*>(option)) - delete combo; - else if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton*>(option)) - delete button; - else - delete option; -} - -/*! - \class QWindowsVistaStyle - \brief The QWindowsVistaStyle class provides a look and feel suitable for applications on Microsoft Windows Vista. - \since 4.3 - \ingroup appearance - \inmodule QtWidgets - \internal - - \warning This style is only available on the Windows Vista platform - because it makes use of Windows Vista's style engine. - - \sa QMacStyle, QWindowsXPStyle, QFusionStyle -*/ - -/*! - Constructs a QWindowsVistaStyle object. -*/ -QWindowsVistaStyle::QWindowsVistaStyle() - : QWindowsXPStyle(*new QWindowsVistaStylePrivate) -{ -} - -/*! - Destructor. -*/ -QWindowsVistaStyle::~QWindowsVistaStyle() -{ -} - -//convert Qt state flags to uxtheme button states -static int buttonStateId(int flags, int partId) -{ - int stateId = 0; - if (partId == BP_RADIOBUTTON || partId == BP_CHECKBOX) { - if (!(flags & QStyle::State_Enabled)) - stateId = RBS_UNCHECKEDDISABLED; - else if (flags & QStyle::State_Sunken) - stateId = RBS_UNCHECKEDPRESSED; - else if (flags & QStyle::State_MouseOver) - stateId = RBS_UNCHECKEDHOT; - else - stateId = RBS_UNCHECKEDNORMAL; - - if (flags & QStyle::State_On) - stateId += RBS_CHECKEDNORMAL-1; - - } else if (partId == BP_PUSHBUTTON) { - if (!(flags & QStyle::State_Enabled)) - stateId = PBS_DISABLED; - else if (flags & (QStyle::State_Sunken | QStyle::State_On)) - stateId = PBS_PRESSED; - else if (flags & QStyle::State_MouseOver) - stateId = PBS_HOT; - else - stateId = PBS_NORMAL; - } else { - Q_ASSERT(1); - } - return stateId; -} - -bool QWindowsVistaAnimation::isUpdateNeeded() const -{ - return QWindowsVistaStylePrivate::useVista(); -} - -void QWindowsVistaAnimation::paint(QPainter *painter, const QStyleOption *option) -{ - painter->drawImage(option->rect, currentImage()); -} - -static inline bool supportsStateTransition(QStyle::PrimitiveElement element, - const QStyleOption *option, - const QWidget *widget) -{ - bool result = false; - switch (element) { - case QStyle::PE_IndicatorRadioButton: - case QStyle::PE_IndicatorCheckBox: - result = true; - break; - // QTBUG-40634, do not animate when color is set in palette for PE_PanelLineEdit. - case QStyle::PE_FrameLineEdit: - result = !QWindowsXPStylePrivate::isLineEditBaseColorSet(option, widget); - break; - default: - break; - } - return result; -} - -/*! - \internal - - Animations are used for some state transitions on specific widgets. - - Only one running animation can exist for a widget at any specific - time. Animations can be added through - QWindowsVistaStylePrivate::startAnimation(Animation *) and any - existing animation on a widget can be retrieved with - QWindowsVistaStylePrivate::widgetAnimation(Widget *). - - Once an animation has been started, - QWindowsVistaStylePrivate::timerEvent(QTimerEvent *) will - continuously call update() on the widget until it is stopped, - meaning that drawPrimitive will be called many times until the - transition has completed. During this time, the result will be - retrieved by the Animation::paint(...) function and not by the style - itself. - - To determine if a transition should occur, the style needs to know - the previous state of the widget as well as the current one. This is - solved by updating dynamic properties on the widget every time the - function is called. - - Transitions interrupting existing transitions should always be - smooth, so whenever a hover-transition is started on a pulsating - button, it uses the current frame of the pulse-animation as the - starting image for the hover transition. - - */ - -void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, - QPainter *painter, const QWidget *widget) const -{ - QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func()); - - int state = option->state; - if (!QWindowsVistaStylePrivate::useVista()) { - QWindowsStyle::drawPrimitive(element, option, painter, widget); - return; - } - - if ((option->state & State_Enabled) && d->transitionsEnabled() && canAnimate(option)) { - { - QRect oldRect; - QRect newRect; - - if (supportsStateTransition(element, option, widget)) { - // Retrieve and update the dynamic properties tracking - // the previous state of the widget: - QObject *styleObject = option->styleObject; - styleObject->setProperty("_q_no_animation", true); - - int oldState = styleObject->property("_q_stylestate").toInt(); - oldRect = styleObject->property("_q_stylerect").toRect(); - newRect = option->rect; - styleObject->setProperty("_q_stylestate", (int)option->state); - styleObject->setProperty("_q_stylerect", option->rect); - - bool doTransition = oldState && - ((state & State_Sunken) != (oldState & State_Sunken) || - (state & State_On) != (oldState & State_On) || - (state & State_MouseOver) != (oldState & State_MouseOver)); - - if (oldRect != newRect || - (state & State_Enabled) != (oldState & State_Enabled) || - (state & State_Active) != (oldState & State_Active)) - d->stopAnimation(styleObject); - - if (option->state & State_ReadOnly && element == PE_FrameLineEdit) // Do not animate read only line edits - doTransition = false; - - if (doTransition) { - QStyleOption *styleOption = clonedAnimationStyleOption(option); - styleOption->state = (QStyle::State)oldState; - - QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject)); - QWindowsVistaTransition *t = new QWindowsVistaTransition(styleObject); - - // We create separate images for the initial and final transition states and store them in the - // Transition object. - QImage startImage = createAnimationBuffer(option, widget); - QPainter startPainter(&startImage); - - QImage endImage = createAnimationBuffer(option, widget); - QPainter endPainter(&endImage); - - // If we have a running animation on the widget already, we will use that to paint the initial - // state of the new transition, this ensures a smooth transition from a current animation such as a - // pulsating default button into the intended target state. - if (!anim) - proxy()->drawPrimitive(element, styleOption, &startPainter, widget); - else - anim->paint(&startPainter, styleOption); - - t->setStartImage(startImage); - - // The end state of the transition is simply the result we would have painted - // if the style was not animated. - styleOption->styleObject = 0; - styleOption->state = option->state; - proxy()->drawPrimitive(element, styleOption, &endPainter, widget); - - - t->setEndImage(endImage); - - HTHEME theme; - int partId; - DWORD duration; - int fromState = 0; - int toState = 0; - - //translate state flags to UXTHEME states : - if (element == PE_FrameLineEdit) { - theme = OpenThemeData(0, L"Edit"); - partId = EP_EDITBORDER_NOSCROLL; - - if (oldState & State_MouseOver) - fromState = ETS_HOT; - else if (oldState & State_HasFocus) - fromState = ETS_FOCUSED; - else - fromState = ETS_NORMAL; - - if (state & State_MouseOver) - toState = ETS_HOT; - else if (state & State_HasFocus) - toState = ETS_FOCUSED; - else - toState = ETS_NORMAL; - - } else { - theme = OpenThemeData(0, L"Button"); - if (element == PE_IndicatorRadioButton) - partId = BP_RADIOBUTTON; - else if (element == PE_IndicatorCheckBox) - partId = BP_CHECKBOX; - else - partId = BP_PUSHBUTTON; - - fromState = buttonStateId(oldState, partId); - toState = buttonStateId(option->state, partId); - } - - // Retrieve the transition time between the states from the system. - if (theme - && SUCCEEDED(GetThemeTransitionDuration(theme, partId, fromState, toState, - TMT_TRANSITIONDURATIONS, &duration))) { - t->setDuration(duration); - } - t->setStartTime(QTime::currentTime()); - - deleteClonedAnimationStyleOption(styleOption); - d->startAnimation(t); - } - styleObject->setProperty("_q_no_animation", false); - } - - } // End of animation part - } - - QRect rect = option->rect; - - switch (element) { - case PE_IndicatorHeaderArrow: - if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) { - int stateId = HSAS_SORTEDDOWN; - if (header->sortIndicator & QStyleOptionHeader::SortDown) - stateId = HSAS_SORTEDUP; //note that the uxtheme sort down indicator is the inverse of ours - XPThemeData theme(widget, painter, - QWindowsXPStylePrivate::HeaderTheme, - HP_HEADERSORTARROW, stateId, option->rect); - d->drawBackground(theme); - } - break; - - case PE_IndicatorBranch: - { - XPThemeData theme(widget, painter, QWindowsXPStylePrivate::VistaTreeViewTheme); - static int decoration_size = 0; - if (!decoration_size && theme.isValid()) { - XPThemeData themeSize = theme; - themeSize.partId = TVP_HOTGLYPH; - themeSize.stateId = GLPS_OPENED; - const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); - decoration_size = qRound(qMax(size.width(), size.height())); - } - int mid_h = option->rect.x() + option->rect.width() / 2; - int mid_v = option->rect.y() + option->rect.height() / 2; - int bef_h = mid_h; - int bef_v = mid_v; - int aft_h = mid_h; - int aft_v = mid_v; - if (option->state & State_Children) { - int delta = decoration_size / 2; - theme.rect = QRect(bef_h - delta, bef_v - delta, decoration_size, decoration_size); - theme.partId = option->state & State_MouseOver ? TVP_HOTGLYPH : TVP_GLYPH; - theme.stateId = option->state & QStyle::State_Open ? GLPS_OPENED : GLPS_CLOSED; - if (option->direction == Qt::RightToLeft) - theme.mirrorHorizontally = true; - d->drawBackground(theme); - bef_h -= delta + 2; - bef_v -= delta + 2; - aft_h += delta - 2; - aft_v += delta - 2; - } -#if 0 - QBrush brush(option->palette.dark().color(), Qt::Dense4Pattern); - if (option->state & State_Item) { - if (option->direction == Qt::RightToLeft) - painter->fillRect(option->rect.left(), mid_v, bef_h - option->rect.left(), 1, brush); - else - painter->fillRect(aft_h, mid_v, option->rect.right() - aft_h + 1, 1, brush); - } - if (option->state & State_Sibling && option->rect.bottom() > aft_v) - painter->fillRect(mid_h, aft_v, 1, option->rect.bottom() - aft_v + 1, brush); - if (option->state & (State_Open | State_Children | State_Item | State_Sibling) && (bef_v > option->rect.y())) - painter->fillRect(mid_h, option->rect.y(), 1, bef_v - option->rect.y(), brush); -#endif - } - break; - - case PE_PanelButtonBevel: - case PE_IndicatorCheckBox: - case PE_IndicatorRadioButton: - { - if (QWindowsVistaAnimation *a = - qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject(option)))){ - a->paint(painter, option); - } else { - QWindowsXPStyle::drawPrimitive(element, option, painter, widget); - } - } - break; - - case PE_FrameMenu: - { - int stateId = option->state & State_Active ? MB_ACTIVE : MB_INACTIVE; - XPThemeData theme(widget, painter, - QWindowsXPStylePrivate::MenuTheme, - MENU_POPUPBORDERS, stateId, option->rect); - d->drawBackground(theme); - } - break; - case PE_Frame: { -#ifndef QT_NO_ACCESSIBILITY - if (QStyleHelper::isInstanceOf(option->styleObject, QAccessible::EditableText) - || QStyleHelper::isInstanceOf(option->styleObject, QAccessible::StaticText) || -#else - if ( -#endif - (widget && widget->inherits("QTextEdit"))) { - painter->save(); - int stateId = ETS_NORMAL; - if (!(state & State_Enabled)) - stateId = ETS_DISABLED; - else if (state & State_ReadOnly) - stateId = ETS_READONLY; - else if (state & State_HasFocus) - stateId = ETS_SELECTED; - XPThemeData theme(widget, painter, - QWindowsXPStylePrivate::EditTheme, - EP_EDITBORDER_HVSCROLL, stateId, option->rect); - // Since EP_EDITBORDER_HVSCROLL does not us borderfill, theme.noContent cannot be used for clipping - int borderSize = 1; - GetThemeInt(theme.handle(), theme.partId, theme.stateId, TMT_BORDERSIZE, &borderSize); - QRegion clipRegion = option->rect; - QRegion content = option->rect.adjusted(borderSize, borderSize, -borderSize, -borderSize); - clipRegion ^= content; - painter->setClipRegion(clipRegion); - d->drawBackground(theme); - painter->restore(); - } else { - QWindowsXPStyle::drawPrimitive(element, option, painter, widget); - } - } - break; - - case PE_PanelLineEdit: - if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) { - bool isEnabled = option->state & State_Enabled; - if (QWindowsXPStylePrivate::isLineEditBaseColorSet(option, widget)) { - painter->fillRect(panel->rect, panel->palette.brush(QPalette::Base)); - } else { - int partId = EP_BACKGROUND; - int stateId = EBS_NORMAL; - if (!isEnabled) - stateId = EBS_DISABLED; - else if (state & State_ReadOnly) - stateId = EBS_READONLY; - else if (state & State_MouseOver) - stateId = EBS_HOT; - - XPThemeData theme(0, painter, QWindowsXPStylePrivate::EditTheme, - partId, stateId, rect); - if (!theme.isValid()) { - QWindowsStyle::drawPrimitive(element, option, painter, widget); - return; - } - int bgType; - GetThemeEnumValue(theme.handle(), partId, stateId, TMT_BGTYPE, &bgType); - if( bgType == BT_IMAGEFILE ) { - d->drawBackground(theme); - } else { - QBrush fillColor = option->palette.brush(QPalette::Base); - if (!isEnabled) { - PROPERTYORIGIN origin = PO_NOTFOUND; - GetThemePropertyOrigin(theme.handle(), theme.partId, theme.stateId, TMT_FILLCOLOR, &origin); - // Use only if the fill property comes from our part - if ((origin == PO_PART || origin == PO_STATE)) { - COLORREF bgRef; - GetThemeColor(theme.handle(), partId, stateId, TMT_FILLCOLOR, &bgRef); - fillColor = QBrush(qRgb(GetRValue(bgRef), GetGValue(bgRef), GetBValue(bgRef))); - } - } - painter->fillRect(option->rect, fillColor); - } - } - if (panel->lineWidth > 0) - proxy()->drawPrimitive(PE_FrameLineEdit, panel, painter, widget); - return; - } - break; - - case PE_FrameLineEdit: - if (QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject(option)))) { - anim->paint(painter, option); - } else { - QPainter *p = painter; - if (QWindowsXPStylePrivate::isItemViewDelegateLineEdit(widget)) { - // we try to check if this lineedit is a delegate on a QAbstractItemView-derived class. - QPen oldPen = p->pen(); - // Inner white border - p->setPen(QPen(option->palette.base().color(), 1)); - p->drawRect(option->rect.adjusted(1, 1, -2, -2)); - // Outer dark border - p->setPen(QPen(option->palette.shadow().color(), 1)); - p->drawRect(option->rect.adjusted(0, 0, -1, -1)); - p->setPen(oldPen); - return; - } else { - int stateId = ETS_NORMAL; - if (!(state & State_Enabled)) - stateId = ETS_DISABLED; - else if (state & State_ReadOnly) - stateId = ETS_READONLY; - else if (state & State_MouseOver) - stateId = ETS_HOT; - else if (state & State_HasFocus) - stateId = ETS_SELECTED; - XPThemeData theme(widget, painter, - QWindowsXPStylePrivate::EditTheme, - EP_EDITBORDER_NOSCROLL, stateId, option->rect); - theme.noContent = true; - painter->save(); - QRegion clipRegion = option->rect; - clipRegion -= option->rect.adjusted(2, 2, -2, -2); - painter->setClipRegion(clipRegion); - d->drawBackground(theme); - painter->restore(); - } - } - break; - - case PE_IndicatorToolBarHandle: - { - XPThemeData theme; - QRect rect; - if (option->state & State_Horizontal) { - theme = XPThemeData(widget, painter, - QWindowsXPStylePrivate::RebarTheme, - RP_GRIPPER, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2)); - rect = option->rect.adjusted(0, 1, 0, -2); - rect.setWidth(4); - } else { - theme = XPThemeData(widget, painter, QWindowsXPStylePrivate::RebarTheme, - RP_GRIPPERVERT, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2)); - rect = option->rect.adjusted(1, 0, -1, 0); - rect.setHeight(4); - } - theme.rect = rect; - d->drawBackground(theme); - } - break; - - case PE_IndicatorToolBarSeparator: - { - QPen pen = painter->pen(); - int margin = 3; - painter->setPen(option->palette.background().color().darker(114)); - if (option->state & State_Horizontal) { - int x1 = option->rect.center().x(); - painter->drawLine(QPoint(x1, option->rect.top() + margin), QPoint(x1, option->rect.bottom() - margin)); - } else { - int y1 = option->rect.center().y(); - painter->drawLine(QPoint(option->rect.left() + margin, y1), QPoint(option->rect.right() - margin, y1)); - } - painter->setPen(pen); - } - break; - - case PE_PanelTipLabel: { - XPThemeData theme(widget, painter, - QWindowsXPStylePrivate::ToolTipTheme, - TTP_STANDARD, TTSS_NORMAL, option->rect); - d->drawBackground(theme); - break; - } - - case PE_PanelItemViewItem: - { - const QStyleOptionViewItem *vopt; - bool newStyle = true; - QAbstractItemView::SelectionBehavior selectionBehavior = QAbstractItemView::SelectRows; - QAbstractItemView::SelectionMode selectionMode = QAbstractItemView::NoSelection; - if (const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget)) { - newStyle = !qobject_cast<const QTableView*>(view); - selectionBehavior = view->selectionBehavior(); - selectionMode = view->selectionMode(); -#ifndef QT_NO_ACCESSIBILITY - } else if (!widget) { - newStyle = !QStyleHelper::hasAncestor(option->styleObject, QAccessible::MenuItem) ; -#endif - } - - if (newStyle && (vopt = qstyleoption_cast<const QStyleOptionViewItem *>(option))) { - bool selected = vopt->state & QStyle::State_Selected; - const bool hover = selectionMode != QAbstractItemView::NoSelection && (vopt->state & QStyle::State_MouseOver); - bool active = vopt->state & QStyle::State_Active; - - if (vopt->features & QStyleOptionViewItem::Alternate) - painter->fillRect(vopt->rect, vopt->palette.alternateBase()); - - QPalette::ColorGroup cg = vopt->state & QStyle::State_Enabled - ? QPalette::Normal : QPalette::Disabled; - if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active)) - cg = QPalette::Inactive; - - QRect itemRect = subElementRect(QStyle::SE_ItemViewItemFocusRect, option, widget).adjusted(-1, 0, 1, 0); - itemRect.setTop(vopt->rect.top()); - itemRect.setBottom(vopt->rect.bottom()); - - QSize sectionSize = itemRect.size(); - if (vopt->showDecorationSelected) - sectionSize = vopt->rect.size(); - - if (selectionBehavior == QAbstractItemView::SelectRows) - sectionSize.setWidth(vopt->rect.width()); - QPixmap pixmap; - - if (vopt->backgroundBrush.style() != Qt::NoBrush) { - const QPointF oldBrushOrigin = painter->brushOrigin(); - painter->setBrushOrigin(vopt->rect.topLeft()); - painter->fillRect(vopt->rect, vopt->backgroundBrush); - painter->setBrushOrigin(oldBrushOrigin); - } - - if (hover || selected) { - if (sectionSize.width() > 0 && sectionSize.height() > 0) { - QString key = QString::fromLatin1("qvdelegate-%1-%2-%3-%4-%5").arg(sectionSize.width()) - .arg(sectionSize.height()).arg(selected).arg(active).arg(hover); - if (!QPixmapCache::find(key, pixmap)) { - pixmap = QPixmap(sectionSize); - pixmap.fill(Qt::transparent); - - int state; - if (selected && hover) - state = LISS_HOTSELECTED; - else if (selected && !active) - state = LISS_SELECTEDNOTFOCUS; - else if (selected) - state = LISS_SELECTED; - else - state = LISS_HOT; - - QPainter pixmapPainter(&pixmap); - XPThemeData theme(widget, &pixmapPainter, - QWindowsXPStylePrivate::VistaTreeViewTheme, - LVP_LISTITEM, state, QRect(0, 0, sectionSize.width(), sectionSize.height())); - if (theme.isValid()) { - d->drawBackground(theme); - } else { - QWindowsXPStyle::drawPrimitive(PE_PanelItemViewItem, option, painter, widget); - break;; - } - QPixmapCache::insert(key, pixmap); - } - } - - if (vopt->showDecorationSelected) { - const int frame = 2; //Assumes a 2 pixel pixmap border - QRect srcRect = QRect(0, 0, sectionSize.width(), sectionSize.height()); - QRect pixmapRect = vopt->rect; - bool reverse = vopt->direction == Qt::RightToLeft; - bool leftSection = vopt->viewItemPosition == QStyleOptionViewItem::Beginning; - bool rightSection = vopt->viewItemPosition == QStyleOptionViewItem::End; - if (vopt->viewItemPosition == QStyleOptionViewItem::OnlyOne - || vopt->viewItemPosition == QStyleOptionViewItem::Invalid) - painter->drawPixmap(pixmapRect.topLeft(), pixmap); - else if (reverse ? rightSection : leftSection){ - painter->drawPixmap(QRect(pixmapRect.topLeft(), - QSize(frame, pixmapRect.height())), pixmap, - QRect(QPoint(0, 0), QSize(frame, pixmapRect.height()))); - painter->drawPixmap(pixmapRect.adjusted(frame, 0, 0, 0), - pixmap, srcRect.adjusted(frame, 0, -frame, 0)); - } else if (reverse ? leftSection : rightSection) { - painter->drawPixmap(QRect(pixmapRect.topRight() - QPoint(frame - 1, 0), - QSize(frame, pixmapRect.height())), pixmap, - QRect(QPoint(pixmapRect.width() - frame, 0), - QSize(frame, pixmapRect.height()))); - painter->drawPixmap(pixmapRect.adjusted(0, 0, -frame, 0), - pixmap, srcRect.adjusted(frame, 0, -frame, 0)); - } else if (vopt->viewItemPosition == QStyleOptionViewItem::Middle) - painter->drawPixmap(pixmapRect, pixmap, - srcRect.adjusted(frame, 0, -frame, 0)); - } else { - if (vopt->text.isEmpty() && vopt->icon.isNull()) - break; - painter->drawPixmap(itemRect.topLeft(), pixmap); - } - } - } else { - QWindowsXPStyle::drawPrimitive(element, option, painter, widget); - } - break; - } - case PE_Widget: - { -#if QT_CONFIG(dialogbuttonbox) - const QDialogButtonBox *buttonBox = 0; - - if (qobject_cast<const QMessageBox *> (widget)) - buttonBox = widget->findChild<const QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox")); -#if QT_CONFIG(inputdialog) - else if (qobject_cast<const QInputDialog *> (widget)) - buttonBox = widget->findChild<const QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox")); -#endif // QT_CONFIG(inputdialog) - - if (buttonBox) { - //draw white panel part - XPThemeData theme(widget, painter, - QWindowsXPStylePrivate::TaskDialogTheme, - TDLG_PRIMARYPANEL, 0, option->rect); - QRect toprect = option->rect; - toprect.setBottom(buttonBox->geometry().top()); - theme.rect = toprect; - d->drawBackground(theme); - - //draw bottom panel part - QRect buttonRect = option->rect; - buttonRect.setTop(buttonBox->geometry().top()); - theme.rect = buttonRect; - theme.partId = TDLG_SECONDARYPANEL; - d->drawBackground(theme); - } -#endif - } - break; - default: - QWindowsXPStyle::drawPrimitive(element, option, painter, widget); - break; - } -} - - -/*! - \internal - - see drawPrimitive for comments on the animation support - */ -void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption *option, - QPainter *painter, const QWidget *widget) const -{ - QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func()); - - if (!QWindowsVistaStylePrivate::useVista()) { - QWindowsStyle::drawControl(element, option, painter, widget); - return; - } - - bool selected = option->state & State_Selected; - bool pressed = option->state & State_Sunken; - bool disabled = !(option->state & State_Enabled); - - int state = option->state; - int themeNumber = -1; - - QRect rect(option->rect); - State flags = option->state; - int partId = 0; - int stateId = 0; - - if (d->transitionsEnabled() && canAnimate(option)) - { - if (element == CE_PushButtonBevel) { - QRect oldRect; - QRect newRect; - - QObject *styleObject = option->styleObject; - - int oldState = styleObject->property("_q_stylestate").toInt(); - oldRect = styleObject->property("_q_stylerect").toRect(); - newRect = option->rect; - styleObject->setProperty("_q_stylestate", (int)option->state); - styleObject->setProperty("_q_stylerect", option->rect); - - bool wasDefault = false; - bool isDefault = false; - if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) { - wasDefault = styleObject->property("_q_isdefault").toBool(); - isDefault = button->features & QStyleOptionButton::DefaultButton; - styleObject->setProperty("_q_isdefault", isDefault); - } - - bool doTransition = ((state & State_Sunken) != (oldState & State_Sunken) || - (state & State_On) != (oldState & State_On) || - (state & State_MouseOver) != (oldState & State_MouseOver)); - - if (oldRect != newRect || (wasDefault && !isDefault)) { - doTransition = false; - d->stopAnimation(styleObject); - } - - if (doTransition) { - styleObject->setProperty("_q_no_animation", true); - - QWindowsVistaTransition *t = new QWindowsVistaTransition(styleObject); - QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject)); - QStyleOption *styleOption = clonedAnimationStyleOption(option); - styleOption->state = (QStyle::State)oldState; - - QImage startImage = createAnimationBuffer(option, widget); - QPainter startPainter(&startImage); - - // Use current state of existing animation if already one is running - if (!anim) { - proxy()->drawControl(element, styleOption, &startPainter, widget); - } else { - anim->paint(&startPainter, styleOption); - d->stopAnimation(styleObject); - } - - t->setStartImage(startImage); - QImage endImage = createAnimationBuffer(option, widget); - QPainter endPainter(&endImage); - styleOption->state = option->state; - proxy()->drawControl(element, styleOption, &endPainter, widget); - t->setEndImage(endImage); - - - DWORD duration = 0; - const HTHEME theme = OpenThemeData(0, L"Button"); - - int fromState = buttonStateId(oldState, BP_PUSHBUTTON); - int toState = buttonStateId(option->state, BP_PUSHBUTTON); - if (GetThemeTransitionDuration(theme, BP_PUSHBUTTON, fromState, toState, TMT_TRANSITIONDURATIONS, &duration) == S_OK) - t->setDuration(duration); - else - t->setDuration(0); - t->setStartTime(QTime::currentTime()); - styleObject->setProperty("_q_no_animation", false); - - deleteClonedAnimationStyleOption(styleOption); - d->startAnimation(t); - } - - QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject)); - if (anim) { - anim->paint(painter, option); - return; - } - - } - } - switch (element) { - case CE_PushButtonBevel: - if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) - { - themeNumber = QWindowsXPStylePrivate::ButtonTheme; - partId = BP_PUSHBUTTON; - if (btn->features & QStyleOptionButton::CommandLinkButton) - partId = BP_COMMANDLINK; - bool justFlat = (btn->features & QStyleOptionButton::Flat) && !(flags & (State_On|State_Sunken)); - if (!(flags & State_Enabled) && !(btn->features & QStyleOptionButton::Flat)) - stateId = PBS_DISABLED; - else if (justFlat) - ; - else if (flags & (State_Sunken | State_On)) - stateId = PBS_PRESSED; - else if (flags & State_MouseOver) - stateId = PBS_HOT; - else if (btn->features & QStyleOptionButton::DefaultButton && (state & State_Active)) - stateId = PBS_DEFAULTED; - else - stateId = PBS_NORMAL; - - if (!justFlat) { - - if (d->transitionsEnabled() && (btn->features & QStyleOptionButton::DefaultButton) && - !(state & (State_Sunken | State_On)) && !(state & State_MouseOver) && - (state & State_Enabled) && (state & State_Active)) - { - QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject(option))); - - if (!anim) { - QImage startImage = createAnimationBuffer(option, widget); - QImage alternateImage = createAnimationBuffer(option, widget); - - QWindowsVistaPulse *pulse = new QWindowsVistaPulse(styleObject(option)); - - QPainter startPainter(&startImage); - stateId = PBS_DEFAULTED; - XPThemeData theme(widget, &startPainter, themeNumber, partId, stateId, rect); - d->drawBackground(theme); - - QPainter alternatePainter(&alternateImage); - theme.stateId = PBS_DEFAULTED_ANIMATING; - theme.painter = &alternatePainter; - d->drawBackground(theme); - pulse->setStartImage(startImage); - pulse->setEndImage(alternateImage); - pulse->setStartTime(QTime::currentTime()); - pulse->setDuration(2000); - d->startAnimation(pulse); - anim = pulse; - } - - if (anim) - anim->paint(painter, option); - else { - XPThemeData theme(widget, painter, themeNumber, partId, stateId, rect); - d->drawBackground(theme); - } - } - else { - XPThemeData theme(widget, painter, themeNumber, partId, stateId, rect); - d->drawBackground(theme); - } - } - - if (btn->features & QStyleOptionButton::HasMenu) { - int mbiw = 0, mbih = 0; - XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ToolBarTheme, - TP_DROPDOWNBUTTON); - if (theme.isValid()) { - const QSizeF size = theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); - if (!size.isEmpty()) { - mbiw = qRound(size.width()); - mbih = qRound(size.height()); - } - } - QRect ir = subElementRect(SE_PushButtonContents, option, 0); - QStyleOptionButton newBtn = *btn; - newBtn.rect = QStyle::visualRect(option->direction, option->rect, - QRect(ir.right() - mbiw - 2, - option->rect.top() + (option->rect.height()/2) - (mbih/2), - mbiw + 1, mbih + 1)); - proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, painter, widget); - } - return; - } - break; - - case CE_ProgressBarContents: - if (const QStyleOptionProgressBar *bar - = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) { - bool isIndeterminate = (bar->minimum == 0 && bar->maximum == 0); - const bool vertical = bar->orientation == Qt::Vertical; - const bool inverted = bar->invertedAppearance; - - if (isIndeterminate || (bar->progress > 0 && (bar->progress < bar->maximum) && d->transitionsEnabled())) { - if (!d->animation(styleObject(option))) - d->startAnimation(new QProgressStyleAnimation(d->animationFps, styleObject(option))); - } else { - d->stopAnimation(styleObject(option)); - } - - XPThemeData theme(widget, painter, - QWindowsXPStylePrivate::ProgressTheme, - vertical ? PP_FILLVERT : PP_FILL); - theme.rect = option->rect; - bool reverse = (bar->direction == Qt::LeftToRight && inverted) || (bar->direction == Qt::RightToLeft && !inverted); - QTime current = QTime::currentTime(); - - if (isIndeterminate) { - if (QProgressStyleAnimation *a = qobject_cast<QProgressStyleAnimation *>(d->animation(styleObject(option)))) { - int glowSize = 120; - int animationWidth = glowSize * 2 + (vertical ? theme.rect.height() : theme.rect.width()); - int animOffset = a->startTime().msecsTo(current) / 4; - if (animOffset > animationWidth) - a->setStartTime(QTime::currentTime()); - painter->save(); - painter->setClipRect(theme.rect); - QRect animRect; - QSize pixmapSize(14, 14); - if (vertical) { - animRect = QRect(theme.rect.left(), - inverted ? rect.top() - glowSize + animOffset : - rect.bottom() + glowSize - animOffset, - rect.width(), glowSize); - pixmapSize.setHeight(animRect.height()); - } else { - animRect = QRect(rect.left() - glowSize + animOffset, - rect.top(), glowSize, rect.height()); - animRect = QStyle::visualRect(reverse ? Qt::RightToLeft : Qt::LeftToRight, - option->rect, animRect); - pixmapSize.setWidth(animRect.width()); - } - QString name = QString::fromLatin1("qiprogress-%1-%2").arg(pixmapSize.width()).arg(pixmapSize.height()); - QPixmap pixmap; - if (!QPixmapCache::find(name, pixmap)) { - QImage image(pixmapSize, QImage::Format_ARGB32); - image.fill(Qt::transparent); - QPainter imagePainter(&image); - theme.painter = &imagePainter; - theme.partId = vertical ? PP_FILLVERT : PP_FILL; - theme.rect = QRect(QPoint(0,0), animRect.size()); - QLinearGradient alphaGradient(0, 0, vertical ? 0 : image.width(), - vertical ? image.height() : 0); - alphaGradient.setColorAt(0, QColor(0, 0, 0, 0)); - alphaGradient.setColorAt(0.5, QColor(0, 0, 0, 220)); - alphaGradient.setColorAt(1, QColor(0, 0, 0, 0)); - imagePainter.fillRect(image.rect(), alphaGradient); - imagePainter.setCompositionMode(QPainter::CompositionMode_SourceIn); - d->drawBackground(theme); - imagePainter.end(); - pixmap = QPixmap::fromImage(image); - QPixmapCache::insert(name, pixmap); - } - painter->drawPixmap(animRect, pixmap); - painter->restore(); - } - } - else { - qint64 progress = qMax<qint64>(bar->progress, bar->minimum); // workaround for bug in QProgressBar - - if (vertical) { - int maxHeight = option->rect.height(); - int minHeight = 0; - double vc6_workaround = ((progress - qint64(bar->minimum)) / qMax(double(1.0), double(qint64(bar->maximum) - qint64(bar->minimum))) * maxHeight); - int height = isIndeterminate ? maxHeight: qMax(int(vc6_workaround), minHeight); - theme.rect.setHeight(height); - if (!inverted) - theme.rect.moveTop(rect.height() - theme.rect.height()); - } else { - int maxWidth = option->rect.width(); - int minWidth = 0; - double vc6_workaround = ((progress - qint64(bar->minimum)) / qMax(double(1.0), double(qint64(bar->maximum) - qint64(bar->minimum))) * maxWidth); - int width = isIndeterminate ? maxWidth : qMax(int(vc6_workaround), minWidth); - theme.rect.setWidth(width); - theme.rect = QStyle::visualRect(reverse ? Qt::RightToLeft : Qt::LeftToRight, - option->rect, theme.rect); - } - d->drawBackground(theme); - - if (QProgressStyleAnimation *a = qobject_cast<QProgressStyleAnimation *>(d->animation(styleObject(option)))) { - int glowSize = 140; - int animationWidth = glowSize * 2 + (vertical ? theme.rect.height() : theme.rect.width()); - int animOffset = a->startTime().msecsTo(current) / 4; - theme.partId = vertical ? PP_MOVEOVERLAYVERT : PP_MOVEOVERLAY; - if (animOffset > animationWidth) { - if (bar->progress < bar->maximum) - a->setStartTime(QTime::currentTime()); - else - d->stopAnimation(styleObject(option)); //we stop the glow motion only after it has - //moved out of view - } - painter->save(); - painter->setClipRect(theme.rect); - if (vertical) { - theme.rect = QRect(theme.rect.left(), - inverted ? rect.top() - glowSize + animOffset : - rect.bottom() + glowSize - animOffset, - rect.width(), glowSize); - } else { - theme.rect = QRect(rect.left() - glowSize + animOffset,rect.top(), glowSize, rect.height()); - theme.rect = QStyle::visualRect(reverse ? Qt::RightToLeft : Qt::LeftToRight, option->rect, theme.rect); - } - d->drawBackground(theme); - painter->restore(); - } - } - } - break; - - case CE_MenuBarItem: - { - - if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) - { - if (mbi->menuItemType == QStyleOptionMenuItem::DefaultItem) - break; - - QPalette::ColorRole textRole = disabled ? QPalette::Text : QPalette::ButtonText; - QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), QIcon::Normal); - - uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine; - if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget)) - alignment |= Qt::TextHideMnemonic; - - if (widget && mbi->palette.color(QPalette::Window) != Qt::transparent) { // Not needed for QtQuick Controls - //The rect adjustment is a workaround for the menu not really filling its background. - XPThemeData theme(widget, painter, - QWindowsXPStylePrivate::MenuTheme, - MENU_BARBACKGROUND, 0, option->rect.adjusted(-1, 0, 2, 1)); - d->drawBackground(theme); - } - - int stateId = MBI_NORMAL; - if (disabled) - stateId = MBI_DISABLED; - else if (pressed) - stateId = MBI_PUSHED; - else if (selected) - stateId = MBI_HOT; - - XPThemeData theme2(widget, painter, - QWindowsXPStylePrivate::MenuTheme, - MENU_BARITEM, stateId, option->rect); - d->drawBackground(theme2); - - if (!pix.isNull()) - drawItemPixmap(painter, mbi->rect, alignment, pix); - else - drawItemText(painter, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole); - } - } - break; -#if QT_CONFIG(menu) - case CE_MenuItem: - if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) { - // windows always has a check column, regardless whether we have an icon or not - const qreal factor = QWindowsXPStylePrivate::nativeMetricScaleFactor(widget); - int checkcol = qRound(qreal(25) * factor); - const int gutterWidth = qRound(qreal(3) * factor); - { - XPThemeData theme(widget, 0, QWindowsXPStylePrivate::MenuTheme, - MENU_POPUPCHECKBACKGROUND, MBI_HOT); - XPThemeData themeSize = theme; - themeSize.partId = MENU_POPUPCHECK; - themeSize.stateId = 0; - const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); - const QMarginsF margins = themeSize.margins() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); - checkcol = qMax(menuitem->maxIconWidth, qRound(gutterWidth + size.width() + margins.left() + margins.right())); - } - QRect rect = option->rect; - - //draw vertical menu line - if (option->direction == Qt::LeftToRight) - checkcol += rect.x(); - QPoint p1 = QStyle::visualPos(option->direction, menuitem->rect, QPoint(checkcol, rect.top())); - QPoint p2 = QStyle::visualPos(option->direction, menuitem->rect, QPoint(checkcol, rect.bottom())); - QRect gutterRect(p1.x(), p1.y(), gutterWidth, p2.y() - p1.y() + 1); - XPThemeData theme2(widget, painter, QWindowsXPStylePrivate::MenuTheme, - MENU_POPUPGUTTER, stateId, gutterRect); - d->drawBackground(theme2); - - int x, y, w, h; - menuitem->rect.getRect(&x, &y, &w, &h); - int tab = menuitem->tabWidth; - bool dis = !(menuitem->state & State_Enabled); - bool checked = menuitem->checkType != QStyleOptionMenuItem::NotCheckable - ? menuitem->checked : false; - bool act = menuitem->state & State_Selected; - - if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) { - int yoff = y-2 + h / 2; - const int separatorSize = qRound(qreal(6) * QWindowsStylePrivate::nativeMetricScaleFactor(widget)); - QPoint p1 = QPoint(x + checkcol, yoff); - QPoint p2 = QPoint(x + w + separatorSize, yoff); - stateId = MBI_HOT; - QRect subRect(p1.x() + (gutterWidth - menuitem->rect.x()), p1.y(), - p2.x() - p1.x(), separatorSize); - subRect = QStyle::visualRect(option->direction, option->rect, subRect ); - XPThemeData theme2(widget, painter, - QWindowsXPStylePrivate::MenuTheme, - MENU_POPUPSEPARATOR, stateId, subRect); - d->drawBackground(theme2); - return; - } - - QRect vCheckRect = visualRect(option->direction, menuitem->rect, QRect(menuitem->rect.x(), - menuitem->rect.y(), checkcol - (gutterWidth + menuitem->rect.x()), menuitem->rect.height())); - - if (act) { - stateId = dis ? MBI_DISABLED : MBI_HOT; - XPThemeData theme2(widget, painter, - QWindowsXPStylePrivate::MenuTheme, - MENU_POPUPITEM, stateId, option->rect); - d->drawBackground(theme2); - } - - if (checked) { - XPThemeData theme(widget, painter, - QWindowsXPStylePrivate::MenuTheme, - MENU_POPUPCHECKBACKGROUND, - menuitem->icon.isNull() ? MBI_HOT : MBI_PUSHED, vCheckRect); - XPThemeData themeSize = theme; - themeSize.partId = MENU_POPUPCHECK; - themeSize.stateId = 0; - const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); - const QMarginsF margins = themeSize.margins() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); - QRect checkRect(0, 0, qRound(size.width() + margins.left() + margins.right()), - qRound(size.height() + margins.bottom() + margins.top())); - checkRect.moveCenter(vCheckRect.center()); - theme.rect = checkRect; - - d->drawBackground(theme); - - if (menuitem->icon.isNull()) { - checkRect = QRect(QPoint(0, 0), size.toSize()); - checkRect.moveCenter(theme.rect.center()); - theme.rect = checkRect; - - theme.partId = MENU_POPUPCHECK; - bool bullet = menuitem->checkType & QStyleOptionMenuItem::Exclusive; - if (dis) - theme.stateId = bullet ? MC_BULLETDISABLED: MC_CHECKMARKDISABLED; - else - theme.stateId = bullet ? MC_BULLETNORMAL: MC_CHECKMARKNORMAL; - d->drawBackground(theme); - } - } - - if (!menuitem->icon.isNull()) { - QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal; - if (act && !dis) - mode = QIcon::Active; - QPixmap pixmap; - if (checked) - pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode, QIcon::On); - else - pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode); - const int pixw = pixmap.width() / pixmap.devicePixelRatio(); - const int pixh = pixmap.height() / pixmap.devicePixelRatio(); - QRect pmr(0, 0, pixw, pixh); - pmr.moveCenter(vCheckRect.center()); - painter->setPen(menuitem->palette.text().color()); - painter->drawPixmap(pmr.topLeft(), pixmap); - } - - painter->setPen(menuitem->palette.buttonText().color()); - - const QColor textColor = menuitem->palette.text().color(); - if (dis) - painter->setPen(textColor); - - int xm = windowsItemFrame + checkcol + windowsItemHMargin + (gutterWidth - menuitem->rect.x()) - 1; - int xpos = menuitem->rect.x() + xm; - QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin); - QRect vTextRect = visualRect(option->direction, menuitem->rect, textRect); - QString s = menuitem->text; - if (!s.isEmpty()) { // draw text - painter->save(); - int t = s.indexOf(QLatin1Char('\t')); - int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine; - if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget)) - text_flags |= Qt::TextHideMnemonic; - text_flags |= Qt::AlignLeft; - if (t >= 0) { - QRect vShortcutRect = visualRect(option->direction, menuitem->rect, - QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom()))); - painter->drawText(vShortcutRect, text_flags, s.mid(t + 1)); - s = s.left(t); - } - QFont font = menuitem->font; - if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem) - font.setBold(true); - painter->setFont(font); - painter->setPen(textColor); - painter->drawText(vTextRect, text_flags, s.left(t)); - painter->restore(); - } - if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow - int dim = (h - 2 * windowsItemFrame) / 2; - PrimitiveElement arrow; - arrow = (option->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight; - xpos = x + w - windowsArrowHMargin - windowsItemFrame - dim; - QRect vSubMenuRect = visualRect(option->direction, menuitem->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim)); - QStyleOptionMenuItem newMI = *menuitem; - newMI.rect = vSubMenuRect; - newMI.state = dis ? State_None : State_Enabled; - proxy()->drawPrimitive(arrow, &newMI, painter, widget); - } - } - break; -#endif // QT_CONFIG(menu) - case CE_HeaderSection: - if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) { - partId = HP_HEADERITEM; - if (flags & State_Sunken) - stateId = HIS_PRESSED; - else if (flags & State_MouseOver) - stateId = HIS_HOT; - else - stateId = HIS_NORMAL; - - if (header->sortIndicator != QStyleOptionHeader::None) - stateId += 3; - - XPThemeData theme(widget, painter, - QWindowsXPStylePrivate::HeaderTheme, - partId, stateId, option->rect); - d->drawBackground(theme); - } - break; - case CE_MenuBarEmptyArea: - { - stateId = MBI_NORMAL; - if (!(state & State_Enabled)) - stateId = MBI_DISABLED; - XPThemeData theme(widget, painter, - QWindowsXPStylePrivate::MenuTheme, - MENU_BARBACKGROUND, stateId, option->rect); - d->drawBackground(theme); - } - break; - case CE_ToolBar: - if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar *>(option)) { - QPalette pal = option->palette; - pal.setColor(QPalette::Dark, option->palette.background().color().darker(130)); - QStyleOptionToolBar copyOpt = *toolbar; - copyOpt.palette = pal; - QWindowsStyle::drawControl(element, ©Opt, painter, widget); - } - break; - case CE_DockWidgetTitle: - if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) { - const QDockWidget *dockWidget = qobject_cast<const QDockWidget *>(widget); - QRect rect = option->rect; - if (dockWidget && dockWidget->isFloating()) { - QWindowsXPStyle::drawControl(element, option, painter, widget); - break; //otherwise fall through - } - - const bool verticalTitleBar = dwOpt->verticalTitleBar; - - if (verticalTitleBar) { - rect = rect.transposed(); - - painter->translate(rect.left() - 1, rect.top() + rect.width()); - painter->rotate(-90); - painter->translate(-rect.left() + 1, -rect.top()); - } - - painter->setBrush(option->palette.background().color().darker(110)); - painter->setPen(option->palette.background().color().darker(130)); - painter->drawRect(rect.adjusted(0, 1, -1, -3)); - - int buttonMargin = 4; - int mw = proxy()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, dwOpt, widget); - int fw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, dwOpt, widget); - const QDockWidget *dw = qobject_cast<const QDockWidget *>(widget); - bool isFloating = dw != 0 && dw->isFloating(); - - QRect r = option->rect.adjusted(0, 2, -1, -3); - QRect titleRect = r; - - if (dwOpt->closable) { - QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarCloseButton, dwOpt, widget).actualSize(QSize(10, 10)); - titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0); - } - - if (dwOpt->floatable) { - QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarMaxButton, dwOpt, widget).actualSize(QSize(10, 10)); - titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0); - } - - if (isFloating) { - titleRect.adjust(0, -fw, 0, 0); - if (widget != 0 && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey()) - titleRect.adjust(titleRect.height() + mw, 0, 0, 0); - } else { - titleRect.adjust(mw, 0, 0, 0); - if (!dwOpt->floatable && !dwOpt->closable) - titleRect.adjust(0, 0, -mw, 0); - } - if (!verticalTitleBar) - titleRect = visualRect(dwOpt->direction, r, titleRect); - - if (!dwOpt->title.isEmpty()) { - QString titleText = painter->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, - verticalTitleBar ? titleRect.height() : titleRect.width()); - const int indent = 4; - drawItemText(painter, rect.adjusted(indent + 1, 1, -indent - 1, -1), - Qt::AlignLeft | Qt::AlignVCenter, dwOpt->palette, - dwOpt->state & State_Enabled, titleText, - QPalette::WindowText); - } - } - break; -#if QT_CONFIG(itemviews) - case CE_ItemViewItem: - { - const QStyleOptionViewItem *vopt; - - const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget); - bool newStyle = true; - - if (qobject_cast<const QTableView*>(widget)) - newStyle = false; - - if (newStyle && view && (vopt = qstyleoption_cast<const QStyleOptionViewItem *>(option))) { - /* - // We cannot currently get the correct selection color for "explorer style" views - COLORREF cref = 0; - XPThemeData theme(d->treeViewHelper(), 0, QLatin1String("LISTVIEW"), 0, 0); - unsigned int res = GetThemeColor(theme.handle(), LVP_LISTITEM, LISS_SELECTED, TMT_TEXTCOLOR, &cref); - QColor textColor(GetRValue(cref), GetGValue(cref), GetBValue(cref)); - */ - QPalette palette = vopt->palette; - palette.setColor(QPalette::All, QPalette::HighlightedText, palette.color(QPalette::Active, QPalette::Text)); - // Note that setting a saturated color here results in ugly XOR colors in the focus rect - palette.setColor(QPalette::All, QPalette::Highlight, palette.base().color().darker(108)); - QStyleOptionViewItem adjustedOption = *vopt; - adjustedOption.palette = palette; - // We hide the focusrect in singleselection as it is not required - if ((view->selectionMode() == QAbstractItemView::SingleSelection) - && !(vopt->state & State_KeyboardFocusChange)) - adjustedOption.state &= ~State_HasFocus; - QWindowsXPStyle::drawControl(element, &adjustedOption, painter, widget); - } else { - QWindowsXPStyle::drawControl(element, option, painter, widget); - } - break; - } -#endif // QT_CONFIG(itemviews) -#if QT_CONFIG(combobox) - case CE_ComboBoxLabel: - QCommonStyle::drawControl(element, option, painter, widget); - break; -#endif // QT_CONFIG(combobox) - default: - QWindowsXPStyle::drawControl(element, option, painter, widget); - break; - } -} - -/*! - \internal - - see drawPrimitive for comments on the animation support - - */ -void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, - QPainter *painter, const QWidget *widget) const -{ - QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func()); - if (!QWindowsVistaStylePrivate::useVista()) { - QWindowsStyle::drawComplexControl(control, option, painter, widget); - return; - } - - State state = option->state; - SubControls sub = option->subControls; - QRect r = option->rect; - - int partId = 0; - int stateId = 0; - - State flags = option->state; - if (widget && widget->testAttribute(Qt::WA_UnderMouse) && widget->isActiveWindow()) - flags |= State_MouseOver; - - if (d->transitionsEnabled() && canAnimate(option)) - { - - if (control == CC_ScrollBar || control == CC_SpinBox ) { - - QObject *styleObject = option->styleObject; // Can be widget or qquickitem - - int oldState = styleObject->property("_q_stylestate").toInt(); - int oldActiveControls = styleObject->property("_q_stylecontrols").toInt(); - - QRect oldRect = styleObject->property("_q_stylerect").toRect(); - styleObject->setProperty("_q_stylestate", (int)option->state); - styleObject->setProperty("_q_stylecontrols", (int)option->activeSubControls); - styleObject->setProperty("_q_stylerect", option->rect); - - bool doTransition = ((state & State_Sunken) != (oldState & State_Sunken) || - (state & State_On) != (oldState & State_On) || - (state & State_MouseOver) != (oldState & State_MouseOver) || - oldActiveControls != int(option->activeSubControls)); - - if (qstyleoption_cast<const QStyleOptionSlider *>(option)) { - QRect oldSliderPos = styleObject->property("_q_stylesliderpos").toRect(); - QRect currentPos = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget); - styleObject->setProperty("_q_stylesliderpos", currentPos); - if (oldSliderPos != currentPos) { - doTransition = false; - d->stopAnimation(styleObject); - } - } else if (control == CC_SpinBox) { - //spinboxes have a transition when focus changes - if (!doTransition) - doTransition = (state & State_HasFocus) != (oldState & State_HasFocus); - } - - if (oldRect != option->rect) { - doTransition = false; - d->stopAnimation(styleObject); - } - - if (doTransition) { - QImage startImage = createAnimationBuffer(option, widget); - QPainter startPainter(&startImage); - - QImage endImage = createAnimationBuffer(option, widget); - QPainter endPainter(&endImage); - - QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject)); - QWindowsVistaTransition *t = new QWindowsVistaTransition(styleObject); - - // Draw the image that ends the animation by using the current styleoption - QStyleOptionComplex *styleOption = qstyleoption_cast<QStyleOptionComplex*>(clonedAnimationStyleOption(option)); - - styleObject->setProperty("_q_no_animation", true); - - // Draw transition source - if (!anim) { - styleOption->state = (QStyle::State)oldState; - styleOption->activeSubControls = (QStyle::SubControl)oldActiveControls; - proxy()->drawComplexControl(control, styleOption, &startPainter, widget); - } else { - anim->paint(&startPainter, option); - } - t->setStartImage(startImage); - - // Draw transition target - styleOption->state = option->state; - styleOption->activeSubControls = option->activeSubControls; - proxy()->drawComplexControl(control, styleOption, &endPainter, widget); - - styleObject->setProperty("_q_no_animation", false); - - t->setEndImage(endImage); - t->setStartTime(QTime::currentTime()); - - if (option->state & State_MouseOver || option->state & State_Sunken) - t->setDuration(150); - else - t->setDuration(500); - - deleteClonedAnimationStyleOption(styleOption); - d->startAnimation(t); - } - if (QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject))) { - anim->paint(painter, option); - return; - } - } - } - - switch (control) { - case CC_ComboBox: - if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) - { - if (cmb->editable) { - if (sub & SC_ComboBoxEditField) { - partId = EP_EDITBORDER_NOSCROLL; - if (!(flags & State_Enabled)) - stateId = ETS_DISABLED; - else if (flags & State_MouseOver) - stateId = ETS_HOT; - else if (flags & State_HasFocus) - stateId = ETS_FOCUSED; - else - stateId = ETS_NORMAL; - - XPThemeData theme(widget, painter, - QWindowsXPStylePrivate::EditTheme, - partId, stateId, r); - - d->drawBackground(theme); - } - if (sub & SC_ComboBoxArrow) { - QRect subRect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget); - XPThemeData theme(widget, painter, QWindowsXPStylePrivate::ComboboxTheme); - theme.rect = subRect; - partId = option->direction == Qt::RightToLeft ? CP_DROPDOWNBUTTONLEFT : CP_DROPDOWNBUTTONRIGHT; - - if (!(cmb->state & State_Enabled)) - stateId = CBXS_DISABLED; - else if (cmb->state & State_Sunken || cmb->state & State_On) - stateId = CBXS_PRESSED; - else if (cmb->state & State_MouseOver && option->activeSubControls & SC_ComboBoxArrow) - stateId = CBXS_HOT; - else - stateId = CBXS_NORMAL; - - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } - - } else { - if (sub & SC_ComboBoxFrame) { - QStyleOptionButton btn; - btn.QStyleOption::operator=(*option); - btn.rect = option->rect.adjusted(-1, -1, 1, 1); - if (sub & SC_ComboBoxArrow) - btn.features = QStyleOptionButton::HasMenu; - proxy()->drawControl(QStyle::CE_PushButton, &btn, painter, widget); - } - } - } - break; - case CC_ScrollBar: - if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option)) - { - XPThemeData theme(widget, painter, QWindowsXPStylePrivate::ScrollBarTheme); - bool maxedOut = (scrollbar->maximum == scrollbar->minimum); - if (maxedOut) - flags &= ~State_Enabled; - - bool isHorz = flags & State_Horizontal; - bool isRTL = option->direction == Qt::RightToLeft; - if (sub & SC_ScrollBarAddLine) { - theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddLine, widget); - partId = SBP_ARROWBTN; - if (!(flags & State_Enabled)) - stateId = (isHorz ? (isRTL ? ABS_LEFTDISABLED : ABS_RIGHTDISABLED) : ABS_DOWNDISABLED); - else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_Sunken)) - stateId = (isHorz ? (isRTL ? ABS_LEFTPRESSED : ABS_RIGHTPRESSED) : ABS_DOWNPRESSED); - else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_MouseOver)) - stateId = (isHorz ? (isRTL ? ABS_LEFTHOT : ABS_RIGHTHOT) : ABS_DOWNHOT); - else if (scrollbar->state & State_MouseOver) - stateId = (isHorz ? (isRTL ? ABS_LEFTHOVER : ABS_RIGHTHOVER) : ABS_DOWNHOVER); - else - stateId = (isHorz ? (isRTL ? ABS_LEFTNORMAL : ABS_RIGHTNORMAL) : ABS_DOWNNORMAL); - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } - if (sub & SC_ScrollBarSubLine) { - theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubLine, widget); - partId = SBP_ARROWBTN; - if (!(flags & State_Enabled)) - stateId = (isHorz ? (isRTL ? ABS_RIGHTDISABLED : ABS_LEFTDISABLED) : ABS_UPDISABLED); - else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_Sunken)) - stateId = (isHorz ? (isRTL ? ABS_RIGHTPRESSED : ABS_LEFTPRESSED) : ABS_UPPRESSED); - else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_MouseOver)) - stateId = (isHorz ? (isRTL ? ABS_RIGHTHOT : ABS_LEFTHOT) : ABS_UPHOT); - else if (scrollbar->state & State_MouseOver) - stateId = (isHorz ? (isRTL ? ABS_RIGHTHOVER : ABS_LEFTHOVER) : ABS_UPHOVER); - else - stateId = (isHorz ? (isRTL ? ABS_RIGHTNORMAL : ABS_LEFTNORMAL) : ABS_UPNORMAL); - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } - if (maxedOut) { - theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget); - theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget)); - theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget)); - partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT; - stateId = SCRBS_DISABLED; - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } else { - if (sub & SC_ScrollBarSubPage) { - theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget); - partId = flags & State_Horizontal ? SBP_UPPERTRACKHORZ : SBP_UPPERTRACKVERT; - if (!(flags & State_Enabled)) - stateId = SCRBS_DISABLED; - else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_Sunken)) - stateId = SCRBS_PRESSED; - else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_MouseOver)) - stateId = SCRBS_HOT; - else - stateId = SCRBS_NORMAL; - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } - if (sub & SC_ScrollBarAddPage) { - theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget); - partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT; - if (!(flags & State_Enabled)) - stateId = SCRBS_DISABLED; - else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_Sunken)) - stateId = SCRBS_PRESSED; - else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_MouseOver)) - stateId = SCRBS_HOT; - else - stateId = SCRBS_NORMAL; - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } - if (sub & SC_ScrollBarSlider) { - theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget); - if (!(flags & State_Enabled)) - stateId = SCRBS_DISABLED; - else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_Sunken)) - stateId = SCRBS_PRESSED; - else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_MouseOver)) - stateId = SCRBS_HOT; - else if (option->state & State_MouseOver) - stateId = SCRBS_HOVER; - else - stateId = SCRBS_NORMAL; - - // Draw handle - theme.partId = flags & State_Horizontal ? SBP_THUMBBTNHORZ : SBP_THUMBBTNVERT; - theme.stateId = stateId; - d->drawBackground(theme); - - if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8) { - const QRect gripperBounds = QWindowsXPStylePrivate::scrollBarGripperBounds(flags, widget, &theme); - // Draw gripper if there is enough space - if (!gripperBounds.isEmpty() && flags & State_Enabled) { - painter->save(); - XPThemeData grippBackground = theme; - grippBackground.partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT; - theme.rect = gripperBounds; - painter->setClipRegion(d->region(theme));// Only change inside the region of the gripper - d->drawBackground(grippBackground);// The gutter is the grippers background - d->drawBackground(theme); // Transparent gripper ontop of background - painter->restore(); - } - } - } - } - } - break; -#if QT_CONFIG(spinbox) - case CC_SpinBox: - if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) - { - XPThemeData theme(widget, painter, QWindowsXPStylePrivate::SpinTheme); - if (sb->frame && (sub & SC_SpinBoxFrame)) { - partId = EP_EDITBORDER_NOSCROLL; - if (!(flags & State_Enabled)) - stateId = ETS_DISABLED; - else if (flags & State_MouseOver) - stateId = ETS_HOT; - else if (flags & State_HasFocus) - stateId = ETS_SELECTED; - else - stateId = ETS_NORMAL; - - XPThemeData ftheme(widget, painter, - QWindowsXPStylePrivate::EditTheme, - partId, stateId, r); - // The spinbox in Windows QStyle is drawn with frameless QLineEdit inside it - // That however breaks with QtQuickControls where this results in transparent - // spinbox background, so if there's no "widget" passed (QtQuickControls case), - // let ftheme.noContent be false, which fixes the spinbox rendering in QQC - ftheme.noContent = (widget != NULL); - d->drawBackground(ftheme); - } - if (sub & SC_SpinBoxUp) { - theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget).adjusted(0, 0, 0, 1); - partId = SPNP_UP; - if (!(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled) || !(flags & State_Enabled)) - stateId = UPS_DISABLED; - else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken)) - stateId = UPS_PRESSED; - else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_MouseOver)) - stateId = UPS_HOT; - else - stateId = UPS_NORMAL; - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } - if (sub & SC_SpinBoxDown) { - theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget); - partId = SPNP_DOWN; - if (!(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled) || !(flags & State_Enabled)) - stateId = DNS_DISABLED; - else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken)) - stateId = DNS_PRESSED; - else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_MouseOver)) - stateId = DNS_HOT; - else - stateId = DNS_NORMAL; - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } - } - break; -#endif // QT_CONFIG(spinbox) - default: - QWindowsXPStyle::drawComplexControl(control, option, painter, widget); - break; - } -} - -/*! - \internal - */ -QSize QWindowsVistaStyle::sizeFromContents(ContentsType type, const QStyleOption *option, - const QSize &size, const QWidget *widget) const -{ - if (!QWindowsVistaStylePrivate::useVista()) - return QWindowsStyle::sizeFromContents(type, option, size, widget); - - QSize sz(size); - switch (type) { - case CT_MenuItem: - sz = QWindowsXPStyle::sizeFromContents(type, option, size, widget); - int minimumHeight; - { - XPThemeData theme(widget, 0, - QWindowsXPStylePrivate::MenuTheme, - MENU_POPUPCHECKBACKGROUND, MBI_HOT); - XPThemeData themeSize = theme; - themeSize.partId = MENU_POPUPCHECK; - themeSize.stateId = 0; - const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); - const QMarginsF margins = themeSize.margins() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); - minimumHeight = qMax(qRound(size.height() + margins.bottom() + margins.top()), sz.height()); - sz.rwidth() += qRound(size.width() + margins.left() + margins.right()); - } - - if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) { - if (menuitem->menuItemType != QStyleOptionMenuItem::Separator) - sz.setHeight(minimumHeight); - } - return sz; -#if QT_CONFIG(menubar) - case CT_MenuBarItem: - if (!sz.isEmpty()) - sz += QSize(windowsItemHMargin * 5 + 1, 5); - return sz; -#endif - case CT_ItemViewItem: - sz = QWindowsXPStyle::sizeFromContents(type, option, size, widget); - sz.rheight() += 2; - return sz; - case CT_SpinBox: - { - //Spinbox adds frame twice - sz = QWindowsStyle::sizeFromContents(type, option, size, widget); - int border = proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget); - sz -= QSize(2*border, 2*border); - } - return sz; - case CT_HeaderSection: - { - // When there is a sort indicator it adds to the width but it is shown - // above the text natively and not on the side - if (QStyleOptionHeader *hdr = qstyleoption_cast<QStyleOptionHeader *>(const_cast<QStyleOption *>(option))) { - QStyleOptionHeader::SortIndicator sortInd = hdr->sortIndicator; - hdr->sortIndicator = QStyleOptionHeader::None; - sz = QWindowsXPStyle::sizeFromContents(type, hdr, size, widget); - hdr->sortIndicator = sortInd; - return sz; - } - break; - } - default: - break; - } - return QWindowsXPStyle::sizeFromContents(type, option, size, widget); -} - -/*! - \internal - */ -QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const -{ - if (!QWindowsVistaStylePrivate::useVista()) - return QWindowsStyle::subElementRect(element, option, widget); - - QRect rect = QWindowsXPStyle::subElementRect(element, option, widget); - switch (element) { - - case SE_PushButtonContents: - if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) { - MARGINS borderSize; - const HTHEME theme = OpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : 0, L"Button"); - if (theme) { - int stateId = PBS_NORMAL; - if (!(option->state & State_Enabled)) - stateId = PBS_DISABLED; - else if (option->state & State_Sunken) - stateId = PBS_PRESSED; - else if (option->state & State_MouseOver) - stateId = PBS_HOT; - else if (btn->features & QStyleOptionButton::DefaultButton) - stateId = PBS_DEFAULTED; - - int border = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget); - rect = option->rect.adjusted(border, border, -border, -border); - - if (SUCCEEDED(GetThemeMargins(theme, NULL, BP_PUSHBUTTON, stateId, TMT_CONTENTMARGINS, NULL, &borderSize))) { - rect.adjust(borderSize.cxLeftWidth, borderSize.cyTopHeight, - -borderSize.cxRightWidth, -borderSize.cyBottomHeight); - rect = visualRect(option->direction, option->rect, rect); - } - } - } - break; - - case SE_HeaderArrow: - { - QRect r = rect; - int h = option->rect.height(); - int w = option->rect.width(); - int x = option->rect.x(); - int y = option->rect.y(); - int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, option, widget); - - XPThemeData theme(widget, 0, - QWindowsXPStylePrivate::HeaderTheme, - HP_HEADERSORTARROW, HSAS_SORTEDDOWN, option->rect); - - int arrowWidth = 13; - int arrowHeight = 5; - if (theme.isValid()) { - const QSizeF size = theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); - if (!size.isEmpty()) { - arrowWidth = qRound(size.width()); - arrowHeight = qRound(size.height()); - } - } - if (option->state & State_Horizontal) { - r.setRect(x + w/2 - arrowWidth/2, y , arrowWidth, arrowHeight); - } else { - int vert_size = w / 2; - r.setRect(x + 5, y + h - margin * 2 - vert_size, - w - margin * 2 - 5, vert_size); - } - rect = visualRect(option->direction, option->rect, r); - } - break; - - case SE_HeaderLabel: - { - int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, option, widget); - QRect r = option->rect; - r.setRect(option->rect.x() + margin, option->rect.y() + margin, - option->rect.width() - margin * 2, option->rect.height() - margin * 2); - if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) { - // Subtract width needed for arrow, if there is one - if (header->sortIndicator != QStyleOptionHeader::None) { - if (!(option->state & State_Horizontal)) //horizontal arrows are positioned on top - r.setHeight(r.height() - (option->rect.width() / 2) - (margin * 2)); - } - } - rect = visualRect(option->direction, option->rect, r); - } - break; - case SE_ProgressBarContents: - rect = QCommonStyle::subElementRect(SE_ProgressBarGroove, option, widget); - break; - case SE_ItemViewItemDecoration: - if (qstyleoption_cast<const QStyleOptionViewItem *>(option)) - rect.adjust(-2, 0, 2, 0); - break; - case SE_ItemViewItemFocusRect: - if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(option)) { - QRect textRect = subElementRect(QStyle::SE_ItemViewItemText, option, widget); - QRect displayRect = subElementRect(QStyle::SE_ItemViewItemDecoration, option, widget); - if (!vopt->icon.isNull()) - rect = textRect.united(displayRect); - else - rect = textRect; - rect = rect.adjusted(1, 0, -1, 0); - } - break; - default: - break; - } - return rect; -} - - -/* - This function is used by subControlRect to check if a button - should be drawn for the given subControl given a set of window flags. -*/ -static bool buttonVisible(const QStyle::SubControl sc, const QStyleOptionTitleBar *tb){ - - bool isMinimized = tb->titleBarState & Qt::WindowMinimized; - bool isMaximized = tb->titleBarState & Qt::WindowMaximized; - const uint flags = tb->titleBarFlags; - bool retVal = false; - switch (sc) { - case QStyle::SC_TitleBarContextHelpButton: - if (flags & Qt::WindowContextHelpButtonHint) - retVal = true; - break; - case QStyle::SC_TitleBarMinButton: - if (!isMinimized && (flags & Qt::WindowMinimizeButtonHint)) - retVal = true; - break; - case QStyle::SC_TitleBarNormalButton: - if (isMinimized && (flags & Qt::WindowMinimizeButtonHint)) - retVal = true; - else if (isMaximized && (flags & Qt::WindowMaximizeButtonHint)) - retVal = true; - break; - case QStyle::SC_TitleBarMaxButton: - if (!isMaximized && (flags & Qt::WindowMaximizeButtonHint)) - retVal = true; - break; - case QStyle::SC_TitleBarShadeButton: - if (!isMinimized && flags & Qt::WindowShadeButtonHint) - retVal = true; - break; - case QStyle::SC_TitleBarUnshadeButton: - if (isMinimized && flags & Qt::WindowShadeButtonHint) - retVal = true; - break; - case QStyle::SC_TitleBarCloseButton: - if (flags & Qt::WindowSystemMenuHint) - retVal = true; - break; - case QStyle::SC_TitleBarSysMenu: - if (flags & Qt::WindowSystemMenuHint) - retVal = true; - break; - default : - retVal = true; - } - return retVal; -} - - -/*! \internal */ -int QWindowsVistaStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, - QStyleHintReturn *returnData) const -{ - QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func()); - int ret = 0; - switch (hint) { - case SH_MessageBox_CenterButtons: - ret = false; - break; - case SH_ToolTip_Mask: - if (option) { - if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(returnData)) { - ret = true; - XPThemeData themeData(widget, 0, - QWindowsXPStylePrivate::ToolTipTheme, - TTP_STANDARD, TTSS_NORMAL, option->rect); - mask->region = d->region(themeData); - } - } - break; - case SH_Table_GridLineColor: - if (option) - ret = option->palette.color(QPalette::Base).darker(118).rgb(); - else - ret = -1; - break; - case SH_Header_ArrowAlignment: - ret = Qt::AlignTop | Qt::AlignHCenter; - break; - default: - ret = QWindowsXPStyle::styleHint(hint, option, widget, returnData); - break; - } - return ret; -} - - -/*! - \internal - */ -QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option, - SubControl subControl, const QWidget *widget) const -{ - if (!QWindowsVistaStylePrivate::useVista()) - return QWindowsStyle::subControlRect(control, option, subControl, widget); - - QRect rect = QWindowsXPStyle::subControlRect(control, option, subControl, widget); - switch (control) { -#if QT_CONFIG(combobox) - case CC_ComboBox: - if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) { - int x = cb->rect.x(), - y = cb->rect.y(), - wi = cb->rect.width(), - he = cb->rect.height(); - int xpos = x; - int margin = cb->frame ? 3 : 0; - int bmarg = cb->frame ? 2 : 0; - int arrowButtonWidth = bmarg + 16; - xpos += wi - arrowButtonWidth; - - switch (subControl) { - case SC_ComboBoxFrame: - rect = cb->rect; - break; - case SC_ComboBoxArrow: - rect.setRect(xpos, y , arrowButtonWidth, he); - break; - case SC_ComboBoxEditField: - rect.setRect(x + margin, y + margin, wi - 2 * margin - 16, he - 2 * margin); - break; - case SC_ComboBoxListBoxPopup: - rect = cb->rect; - break; - default: - break; - } - rect = visualRect(cb->direction, cb->rect, rect); - return rect; - } - break; -#endif // QT_CONFIG(combobox) - case CC_TitleBar: - if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) { - if (!buttonVisible(subControl, tb)) - return rect; - const bool isToolTitle = false; - const int height = tb->rect.height(); - const int width = tb->rect.width(); - const int buttonWidth = - qRound(qreal(GetSystemMetrics(SM_CXSIZE)) * QWindowsStylePrivate::nativeMetricScaleFactor(widget) - - QStyleHelper::dpiScaled(4)); - - const int frameWidth = proxy()->pixelMetric(PM_MdiSubWindowFrameWidth, option, widget); - const bool sysmenuHint = (tb->titleBarFlags & Qt::WindowSystemMenuHint) != 0; - const bool minimizeHint = (tb->titleBarFlags & Qt::WindowMinimizeButtonHint) != 0; - const bool maximizeHint = (tb->titleBarFlags & Qt::WindowMaximizeButtonHint) != 0; - const bool contextHint = (tb->titleBarFlags & Qt::WindowContextHelpButtonHint) != 0; - const bool shadeHint = (tb->titleBarFlags & Qt::WindowShadeButtonHint) != 0; - - switch (subControl) { - case SC_TitleBarLabel: - rect = QRect(frameWidth, 0, width - (buttonWidth + frameWidth + 10), height); - if (isToolTitle) { - if (sysmenuHint) { - rect.adjust(0, 0, -buttonWidth - 3, 0); - } - if (minimizeHint || maximizeHint) - rect.adjust(0, 0, -buttonWidth - 2, 0); - } else { - if (sysmenuHint) { - const int leftOffset = height - 8; - rect.adjust(leftOffset, 0, 0, 4); - } - if (minimizeHint) - rect.adjust(0, 0, -buttonWidth - 2, 0); - if (maximizeHint) - rect.adjust(0, 0, -buttonWidth - 2, 0); - if (contextHint) - rect.adjust(0, 0, -buttonWidth - 2, 0); - if (shadeHint) - rect.adjust(0, 0, -buttonWidth - 2, 0); - } - rect.translate(0, 2); - rect = visualRect(option->direction, option->rect, rect); - break; - case SC_TitleBarSysMenu: - { - const int controlTop = 6; - const int controlHeight = height - controlTop - 3; - int iconExtent = proxy()->pixelMetric(PM_SmallIconSize); - QSize iconSize = tb->icon.actualSize(QSize(iconExtent, iconExtent)); - if (tb->icon.isNull()) - iconSize = QSize(controlHeight, controlHeight); - int hPad = (controlHeight - iconSize.height())/2; - int vPad = (controlHeight - iconSize.width())/2; - rect = QRect(frameWidth + hPad, controlTop + vPad, iconSize.width(), iconSize.height()); - rect.translate(0, 3); - rect = visualRect(option->direction, option->rect, rect); - } - break; - default: - break; - } - } - break; - default: - break; - } - return rect; -} - -/*! - \internal - */ -QStyle::SubControl QWindowsVistaStyle::hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, - const QPoint &pos, const QWidget *widget) const -{ - if (!QWindowsVistaStylePrivate::useVista()) { - return QWindowsStyle::hitTestComplexControl(control, option, pos, widget); - } - return QWindowsXPStyle::hitTestComplexControl(control, option, pos, widget); -} - -int QWindowsVistaStylePrivate::fixedPixelMetric(QStyle::PixelMetric pm) -{ - switch (pm) { - case QStyle::PM_DockWidgetTitleBarButtonMargin: - return 5; - case QStyle::PM_ScrollBarSliderMin: - return 18; - case QStyle::PM_MenuHMargin: - case QStyle::PM_MenuVMargin: - return 0; - case QStyle::PM_MenuPanelWidth: - return 3; - default: - break; - } - return QWindowsVistaStylePrivate::InvalidMetric; -} - -/*! - \internal - */ -int QWindowsVistaStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const -{ - if (!QWindowsVistaStylePrivate::useVista()) - return QWindowsStyle::pixelMetric(metric, option, widget); - - int ret = QWindowsVistaStylePrivate::fixedPixelMetric(metric); - if (ret != QWindowsStylePrivate::InvalidMetric) - return int(QStyleHelper::dpiScaled(ret)); - - return QWindowsXPStyle::pixelMetric(metric, option, widget); -} - -/*! - \internal - */ -QPalette QWindowsVistaStyle::standardPalette() const -{ - return QWindowsXPStyle::standardPalette(); -} - -/*! - \internal - */ -void QWindowsVistaStyle::polish(QApplication *app) -{ - QWindowsXPStyle::polish(app); -} - -/*! - \internal - */ -void QWindowsVistaStyle::polish(QWidget *widget) -{ - QWindowsXPStyle::polish(widget); -#if QT_CONFIG(lineedit) - if (qobject_cast<QLineEdit*>(widget)) - widget->setAttribute(Qt::WA_Hover); - else -#endif // QT_CONFIG(lineedit) - if (qobject_cast<QGroupBox*>(widget)) - widget->setAttribute(Qt::WA_Hover); - else if (qobject_cast<QCommandLinkButton*>(widget)) { - QFont buttonFont = widget->font(); - buttonFont.setFamily(QLatin1String("Segoe UI")); - widget->setFont(buttonFont); - } - else if (widget->inherits("QTipLabel")){ - //note that since tooltips are not reused - //we do not have to care about unpolishing - widget->setContentsMargins(3, 0, 4, 0); - COLORREF bgRef; - HTHEME theme = OpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : 0, L"TOOLTIP"); - if (theme && SUCCEEDED(GetThemeColor(theme, TTP_STANDARD, TTSS_NORMAL, TMT_TEXTCOLOR, &bgRef))) { - QColor textColor = QColor::fromRgb(bgRef); - QPalette pal; - pal.setColor(QPalette::All, QPalette::ToolTipText, textColor); - widget->setPalette(pal); - } - } else if (qobject_cast<QMessageBox *> (widget)) { - widget->setAttribute(Qt::WA_StyledBackground); -#if QT_CONFIG(dialogbuttonbox) - QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox")); - if (buttonBox) - buttonBox->setContentsMargins(0, 9, 0, 0); -#endif - } -#if QT_CONFIG(inputdialog) - else if (qobject_cast<QInputDialog *> (widget)) { - widget->setAttribute(Qt::WA_StyledBackground); -#if QT_CONFIG(dialogbuttonbox) - QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox")); - if (buttonBox) - buttonBox->setContentsMargins(0, 9, 0, 0); -#endif - } -#endif // QT_CONFIG(inputdialog) - else if (QTreeView *tree = qobject_cast<QTreeView *> (widget)) { - tree->viewport()->setAttribute(Qt::WA_Hover); - } - else if (QListView *list = qobject_cast<QListView *> (widget)) { - list->viewport()->setAttribute(Qt::WA_Hover); - } -} - -/*! - \internal - */ -void QWindowsVistaStyle::unpolish(QWidget *widget) -{ - QWindowsXPStyle::unpolish(widget); - - QWindowsVistaStylePrivate *d = d_func(); - - d->stopAnimation(widget); - -#if QT_CONFIG(lineedit) - if (qobject_cast<QLineEdit*>(widget)) - widget->setAttribute(Qt::WA_Hover, false); - else -#endif // QT_CONFIG(lineedit) - if (qobject_cast<QGroupBox*>(widget)) - widget->setAttribute(Qt::WA_Hover, false); - else if (qobject_cast<QMessageBox *> (widget)) { - widget->setAttribute(Qt::WA_StyledBackground, false); -#if QT_CONFIG(dialogbuttonbox) - QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox")); - if (buttonBox) - buttonBox->setContentsMargins(0, 0, 0, 0); -#endif - } -#if QT_CONFIG(inputdialog) - else if (qobject_cast<QInputDialog *> (widget)) { - widget->setAttribute(Qt::WA_StyledBackground, false); -#if QT_CONFIG(dialogbuttonbox) - QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox")); - if (buttonBox) - buttonBox->setContentsMargins(0, 0, 0, 0); -#endif - } -#endif // QT_CONFIG(inputdialog) - else if (QTreeView *tree = qobject_cast<QTreeView *> (widget)) { - tree->viewport()->setAttribute(Qt::WA_Hover, false); - } else if (qobject_cast<QCommandLinkButton*>(widget)) { - QFont font = QApplication::font("QCommandLinkButton"); - QFont widgetFont = widget->font(); - widgetFont.setFamily(font.family()); //Only family set by polish - widget->setFont(widgetFont); - } -} - - -/*! - \internal - */ -void QWindowsVistaStyle::unpolish(QApplication *app) -{ - QWindowsXPStyle::unpolish(app); -} - -/*! - \internal - */ -void QWindowsVistaStyle::polish(QPalette &pal) -{ - QWindowsStyle::polish(pal); - pal.setBrush(QPalette::AlternateBase, pal.base().color().darker(104)); -} - -/*! - \internal - */ -QPixmap QWindowsVistaStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option, - const QWidget *widget) const -{ - if (!QWindowsVistaStylePrivate::useVista()) { - return QWindowsStyle::standardPixmap(standardPixmap, option, widget); - } - return QWindowsXPStyle::standardPixmap(standardPixmap, option, widget); -} - -QWindowsVistaStylePrivate::QWindowsVistaStylePrivate() : - QWindowsXPStylePrivate() -{ -} - -bool QWindowsVistaStylePrivate::transitionsEnabled() const -{ - BOOL animEnabled = false; - if (SystemParametersInfo(SPI_GETCLIENTAREAANIMATION, 0, &animEnabled, 0)) - { - if (animEnabled) - return true; - } - return false; -} - -/*! -\reimp -*/ -QIcon QWindowsVistaStyle::standardIcon(StandardPixmap standardIcon, - const QStyleOption *option, - const QWidget *widget) const -{ - if (!QWindowsVistaStylePrivate::useVista()) { - return QWindowsStyle::standardIcon(standardIcon, option, widget); - } - - QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate *>(d_func()); - switch(standardIcon) { - case SP_CommandLink: - { - XPThemeData theme(0, 0, - QWindowsXPStylePrivate::ButtonTheme, - BP_COMMANDLINKGLYPH, CMDLGS_NORMAL); - if (theme.isValid()) { - const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); - QIcon linkGlyph; - QPixmap pm(size); - pm.fill(Qt::transparent); - QPainter p(&pm); - theme.painter = &p; - theme.rect = QRect(QPoint(0, 0), size); - d->drawBackground(theme); - linkGlyph.addPixmap(pm, QIcon::Normal, QIcon::Off); // Normal - pm.fill(Qt::transparent); - - theme.stateId = CMDLGS_PRESSED; - d->drawBackground(theme); - linkGlyph.addPixmap(pm, QIcon::Normal, QIcon::On); // Pressed - pm.fill(Qt::transparent); - - theme.stateId = CMDLGS_HOT; - d->drawBackground(theme); - linkGlyph.addPixmap(pm, QIcon::Active, QIcon::Off); // Hover - pm.fill(Qt::transparent); - - theme.stateId = CMDLGS_DISABLED; - d->drawBackground(theme); - linkGlyph.addPixmap(pm, QIcon::Disabled, QIcon::Off); // Disabled - return linkGlyph; - } - } - break; - default: - break; - } - return QWindowsXPStyle::standardIcon(standardIcon, option, widget); -} - -QT_END_NAMESPACE - -#endif //QT_NO_WINDOWSVISTA diff --git a/src/widgets/styles/qwindowsvistastyle_p.h b/src/widgets/styles/qwindowsvistastyle_p.h deleted file mode 100644 index 8fbd1dc380..0000000000 --- a/src/widgets/styles/qwindowsvistastyle_p.h +++ /dev/null @@ -1,110 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef QWINDOWSVISTASTYLE_P_H -#define QWINDOWSVISTASTYLE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtWidgets/private/qtwidgetsglobal_p.h> -#include <private/qwindowsxpstyle_p.h> - -QT_BEGIN_NAMESPACE - - -#if QT_CONFIG(style_windowsvista) - -class QWindowsVistaStylePrivate; -class QWindowsVistaStyle : public QWindowsXPStyle -{ - Q_OBJECT -public: - QWindowsVistaStyle(); - ~QWindowsVistaStyle(); - - void drawPrimitive(PrimitiveElement element, const QStyleOption *option, - QPainter *painter, const QWidget *widget = 0) const; - void drawControl(ControlElement element, const QStyleOption *option, - QPainter *painter, const QWidget *widget) const; - void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, - QPainter *painter, const QWidget *widget) const; - QSize sizeFromContents(ContentsType type, const QStyleOption *option, - const QSize &size, const QWidget *widget) const; - - QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const; - QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, - SubControl sc, const QWidget *widget) const; - - SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, - const QPoint &pos, const QWidget *widget = 0) const; - - QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = 0, - const QWidget *widget = 0) const; - QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, - const QWidget *widget = 0) const; - int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const; - int styleHint(StyleHint hint, const QStyleOption *opt = 0, const QWidget *widget = 0, - QStyleHintReturn *returnData = 0) const; - - void polish(QWidget *widget); - void unpolish(QWidget *widget); - void polish(QPalette &pal); - void polish(QApplication *app); - void unpolish(QApplication *app); - QPalette standardPalette() const; - -private: - Q_DISABLE_COPY(QWindowsVistaStyle) - Q_DECLARE_PRIVATE(QWindowsVistaStyle) - friend class QStyleFactory; -}; -#endif // style_windowsvista - -QT_END_NAMESPACE - -#endif // QWINDOWSVISTASTYLE_P_H diff --git a/src/widgets/styles/qwindowsvistastyle_p_p.h b/src/widgets/styles/qwindowsvistastyle_p_p.h deleted file mode 100644 index 6e22f97cf4..0000000000 --- a/src/widgets/styles/qwindowsvistastyle_p_p.h +++ /dev/null @@ -1,204 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef QWINDOWSVISTASTYLE_P_P_H -#define QWINDOWSVISTASTYLE_P_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header -// file may change from version to version without notice, or even be removed. -// -// We mean it. -// - -#include <QtWidgets/private/qtwidgetsglobal_p.h> -#include "qwindowsvistastyle_p.h" - -#if QT_CONFIG(style_windowsvista) -#include <private/qwindowsxpstyle_p_p.h> -#include <private/qstyleanimation_p.h> -#include <private/qpaintengine_raster_p.h> -#include <qpaintengine.h> -#include <qwidget.h> -#include <qapplication.h> -#include <qpixmapcache.h> -#include <qstyleoption.h> -#if QT_CONFIG(pushbutton) -#include <qpushbutton.h> -#endif -#include <qradiobutton.h> -#if QT_CONFIG(lineedit) -#include <qlineedit.h> -#endif -#include <qgroupbox.h> -#if QT_CONFIG(toolbutton) -#include <qtoolbutton.h> -#endif -#if QT_CONFIG(spinbox) -#include <qspinbox.h> -#endif -#include <qtoolbar.h> -#if QT_CONFIG(combobox) -#include <qcombobox.h> -#endif -#if QT_CONFIG(scrollbar) -#include <qscrollbar.h> -#endif -#if QT_CONFIG(progressbar) -#include <qprogressbar.h> -#endif -#if QT_CONFIG(dockwidget) -#include <qdockwidget.h> -#endif -#if QT_CONFIG(listview) -#include <qlistview.h> -#endif -#if QT_CONFIG(treeview) -#include <qtreeview.h> -#endif -#include <qtextedit.h> -#include <qmessagebox.h> -#if QT_CONFIG(dialogbuttonbox) -#include <qdialogbuttonbox.h> -#endif -#include <qinputdialog.h> -#if QT_CONFIG(tableview) -#include <qtableview.h> -#endif -#include <qdatetime.h> -#include <qcommandlinkbutton.h> - -QT_BEGIN_NAMESPACE - -#if !defined(SCHEMA_VERIFY_VSSYM32) -#define TMT_ANIMATIONDURATION 5006 -#define TMT_TRANSITIONDURATIONS 6000 -#define EP_EDITBORDER_NOSCROLL 6 -#define EP_EDITBORDER_HVSCROLL 9 -#define EP_BACKGROUND 3 -#define EBS_NORMAL 1 -#define EBS_HOT 2 -#define EBS_DISABLED 3 -#define EBS_READONLY 5 -#define PBS_DEFAULTED_ANIMATING 6 -#define MBI_NORMAL 1 -#define MBI_HOT 2 -#define MBI_PUSHED 3 -#define MBI_DISABLED 4 -#define MB_ACTIVE 1 -#define MB_INACTIVE 2 -#define PP_FILL 5 -#define PP_FILLVERT 6 -#define PP_MOVEOVERLAY 8 -#define PP_MOVEOVERLAYVERT 10 -#define MENU_BARBACKGROUND 7 -#define MENU_BARITEM 8 -#define MENU_POPUPCHECK 11 -#define MENU_POPUPCHECKBACKGROUND 12 -#define MENU_POPUPGUTTER 13 -#define MENU_POPUPITEM 14 -#define MENU_POPUPBORDERS 10 -#define MENU_POPUPSEPARATOR 15 -#define MC_CHECKMARKNORMAL 1 -#define MC_CHECKMARKDISABLED 2 -#define MC_BULLETNORMAL 3 -#define MC_BULLETDISABLED 4 -#define ABS_UPHOVER 17 -#define ABS_DOWNHOVER 18 -#define ABS_LEFTHOVER 19 -#define ABS_RIGHTHOVER 20 -#define CP_DROPDOWNBUTTONRIGHT 6 -#define CP_DROPDOWNBUTTONLEFT 7 -#define SCRBS_HOVER 5 -#define TVP_HOTGLYPH 4 -#define SPI_GETCLIENTAREAANIMATION 0x1042 -#define TDLG_PRIMARYPANEL 1 -#define TDLG_SECONDARYPANEL 8 -#endif - -class QWindowsVistaAnimation : public QBlendStyleAnimation -{ - Q_OBJECT -public: - QWindowsVistaAnimation(Type type, QObject *target) : QBlendStyleAnimation(type, target) { } - - virtual bool isUpdateNeeded() const; - void paint(QPainter *painter, const QStyleOption *option); -}; - - -// Handles state transition animations -class QWindowsVistaTransition : public QWindowsVistaAnimation -{ - Q_OBJECT -public: - QWindowsVistaTransition(QObject *target) : QWindowsVistaAnimation(Transition, target) {} -}; - - -// Handles pulse animations (default buttons) -class QWindowsVistaPulse: public QWindowsVistaAnimation -{ - Q_OBJECT -public: - QWindowsVistaPulse(QObject *target) : QWindowsVistaAnimation(Pulse, target) {} -}; - - -class QWindowsVistaStylePrivate : public QWindowsXPStylePrivate -{ - Q_DECLARE_PUBLIC(QWindowsVistaStyle) - -public: - QWindowsVistaStylePrivate(); - - static int fixedPixelMetric(QStyle::PixelMetric pm); - static inline bool useVista(); - bool transitionsEnabled() const; -}; - -QT_END_NAMESPACE - -#endif // style_windowsvista - -#endif // QWINDOWSVISTASTYLE_P_P_H diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp deleted file mode 100644 index 8656ca6c09..0000000000 --- a/src/widgets/styles/qwindowsxpstyle.cpp +++ /dev/null @@ -1,4240 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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 "qwindowsxpstyle_p.h" -#include "qwindowsxpstyle_p_p.h" - -#if QT_CONFIG(style_windowsxp) || defined(QT_PLUGIN) - -#include <private/qobject_p.h> -#include <private/qpaintengine_raster_p.h> -#include <private/qapplication_p.h> -#include <qpa/qplatformnativeinterface.h> -#include <private/qstylehelper_p.h> -#include <private/qwidget_p.h> -#include <qpainter.h> -#include <qpaintengine.h> -#include <qwidget.h> -#include <qbackingstore.h> -#include <qapplication.h> -#include <qpixmapcache.h> -#include <private/qapplication_p.h> -#include <qpa/qplatformnativeinterface.h> - -#include <qdesktopwidget.h> -#if QT_CONFIG(toolbutton) -#include <qtoolbutton.h> -#endif -#if QT_CONFIG(tabbar) -#include <qtabbar.h> -#endif -#if QT_CONFIG(combobox) -#include <qcombobox.h> -#endif -#if QT_CONFIG(scrollbar) -#include <qscrollbar.h> -#endif -#include <qheaderview.h> -#if QT_CONFIG(spinbox) -#include <qspinbox.h> -#endif -#if QT_CONFIG(listview) -#include <qlistview.h> -#endif -#if QT_CONFIG(stackedwidget) -#include <qstackedwidget.h> -#endif -#if QT_CONFIG(pushbutton) -#include <qpushbutton.h> -#endif -#include <qtoolbar.h> -#include <qlabel.h> -#include <qvarlengtharray.h> -#include <qdebug.h> - -#include <algorithm> - -QT_BEGIN_NAMESPACE - -// General const values -static const int windowsItemFrame = 2; // menu item frame width -static const int windowsItemHMargin = 3; // menu item hor text margin -static const int windowsItemVMargin = 0; // menu item ver text margin -static const int windowsArrowHMargin = 6; // arrow horizontal margin -static const int windowsRightBorder = 12; // right border on windows - -// External function calls -extern Q_WIDGETS_EXPORT HDC qt_win_display_dc(); -extern QRegion qt_region_from_HRGN(HRGN rgn); - -// Theme names matching the QWindowsXPStylePrivate::Theme enumeration. -static const wchar_t *themeNames[QWindowsXPStylePrivate::NThemes] = -{ - L"BUTTON", L"COMBOBOX", L"EDIT", L"HEADER", L"LISTVIEW", - L"MENU", L"PROGRESS", L"REBAR", L"SCROLLBAR", L"SPIN", - L"TAB", L"TASKDIALOG", L"TOOLBAR", L"TOOLTIP", L"TRACKBAR", - L"TREEVIEW", L"WINDOW", L"STATUS", L"TREEVIEW" -}; - -static inline QBackingStore *backingStoreForWidget(const QWidget *widget) -{ - if (QBackingStore *backingStore = widget->backingStore()) - return backingStore; - if (const QWidget *topLevel = widget->nativeParentWidget()) - if (QBackingStore *topLevelBackingStore = topLevel->backingStore()) - return topLevelBackingStore; - return 0; -} - -static inline HDC hdcForWidgetBackingStore(const QWidget *widget) -{ - if (QBackingStore *backingStore = backingStoreForWidget(widget)) { - QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); - return static_cast<HDC>(nativeInterface->nativeResourceForBackingStore(QByteArrayLiteral("getDC"), backingStore)); - } - return 0; -} - -// Theme data helper ------------------------------------------------------------------------------ -/* \internal - Returns \c true if the themedata is valid for use. -*/ -bool XPThemeData::isValid() -{ - return QWindowsXPStylePrivate::useXP() && theme >= 0 && handle(); -} - - -/* \internal - Returns the theme engine handle to the specific class. - If the handle hasn't been opened before, it opens the data, and - adds it to a static map, for caching. -*/ -HTHEME XPThemeData::handle() -{ - if (!QWindowsXPStylePrivate::useXP()) - return 0; - - if (!htheme) - htheme = QWindowsXPStylePrivate::createTheme(theme, QWindowsXPStylePrivate::winId(widget)); - return htheme; -} - -/* \internal - Converts a QRect to the native RECT structure. -*/ -RECT XPThemeData::toRECT(const QRect &qr) -{ - RECT r; - r.left = qr.x(); - r.right = qr.x() + qr.width(); - r.top = qr.y(); - r.bottom = qr.y() + qr.height(); - return r; -} - -/* \internal - Returns the native region of a part, if the part is considered - transparent. The region is scaled to the parts size (rect). -*/ -HRGN XPThemeData::mask(QWidget *widget) -{ - if (!IsThemeBackgroundPartiallyTransparent(handle(), partId, stateId)) - return 0; - - HRGN hrgn; - HDC dc = 0; - if (widget) - dc = hdcForWidgetBackingStore(widget); - RECT nativeRect = toRECT(rect); - GetThemeBackgroundRegion(handle(), dc, partId, stateId, &nativeRect, &hrgn); - return hrgn; -} - -// QWindowsXPStylePrivate ------------------------------------------------------------------------- -// Static initializations -QPixmap *QWindowsXPStylePrivate::tabbody = 0; -HWND QWindowsXPStylePrivate::m_vistaTreeViewHelper = 0; -HTHEME QWindowsXPStylePrivate::m_themes[NThemes]; -bool QWindowsXPStylePrivate::use_xp = false; -QBasicAtomicInt QWindowsXPStylePrivate::ref = Q_BASIC_ATOMIC_INITIALIZER(-1); // -1 based refcounting - -static void qt_add_rect(HRGN &winRegion, QRect r) -{ - HRGN rgn = CreateRectRgn(r.left(), r.top(), r.x() + r.width(), r.y() + r.height()); - if (rgn) { - HRGN dest = CreateRectRgn(0,0,0,0); - int result = CombineRgn(dest, winRegion, rgn, RGN_OR); - if (result) { - DeleteObject(winRegion); - winRegion = dest; - } - DeleteObject(rgn); - } -} - -static HRGN qt_hrgn_from_qregion(const QRegion ®ion) -{ - HRGN hRegion = CreateRectRgn(0,0,0,0); - if (region.rectCount() == 1) { - qt_add_rect(hRegion, region.boundingRect()); - return hRegion; - } - for (const QRect &rect : region) - qt_add_rect(hRegion, rect); - return hRegion; -} - -/* \internal - Checks if the theme engine can/should be used, or if we should - fall back to Windows style. -*/ -bool QWindowsXPStylePrivate::useXP(bool update) -{ - if (!update) - return use_xp; - return use_xp = IsThemeActive() && (IsAppThemed() || !QApplication::instance()); -} - -/* \internal - Handles refcounting, and queries the theme engine for usage. -*/ -void QWindowsXPStylePrivate::init(bool force) -{ - if (ref.ref() && !force) - return; - if (!force) // -1 based atomic refcounting - ref.ref(); - - useXP(true); - std::fill(m_themes, m_themes + NThemes, HTHEME(0)); -} - -/* \internal - Cleans up all static data. -*/ -void QWindowsXPStylePrivate::cleanup(bool force) -{ - if(bufferBitmap) { - if (bufferDC && nullBitmap) - SelectObject(bufferDC, nullBitmap); - DeleteObject(bufferBitmap); - bufferBitmap = 0; - } - - if(bufferDC) - DeleteDC(bufferDC); - bufferDC = 0; - - if (ref.deref() && !force) - return; - if (!force) // -1 based atomic refcounting - ref.deref(); - - use_xp = false; - cleanupHandleMap(); - delete tabbody; - tabbody = 0; -} - -/* In order to obtain the correct VistaTreeViewTheme (arrows for PE_IndicatorBranch), - * we need to set the windows "explorer" theme explicitly on a native - * window and open the "TREEVIEW" theme handle passing its window handle - * in order to get Vista-style item view themes (particulary drawBackground() - * for selected items needs this). - * We invoke a service of the native Windows interface to create - * a non-visible window handle, open the theme on it and insert it into - * the cache so that it is found by XPThemeData::handle() first. - */ - -static inline HWND createTreeViewHelperWindow() -{ - if (QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface()) { - void *hwnd = 0; - void *wndProc = reinterpret_cast<void *>(DefWindowProc); - if (QMetaObject::invokeMethod(ni, "createMessageWindow", Qt::DirectConnection, - Q_RETURN_ARG(void *, hwnd), - Q_ARG(QString, QStringLiteral("QTreeViewThemeHelperWindowClass")), - Q_ARG(QString, QStringLiteral("QTreeViewThemeHelperWindow")), - Q_ARG(void *, wndProc)) && hwnd) { - return reinterpret_cast<HWND>(hwnd); - } - } - return 0; -} - -bool QWindowsXPStylePrivate::initVistaTreeViewTheming() -{ - if (m_vistaTreeViewHelper) - return true; - - m_vistaTreeViewHelper = createTreeViewHelperWindow(); - if (!m_vistaTreeViewHelper) { - qWarning("Unable to create the treeview helper window."); - return false; - } - if (FAILED(SetWindowTheme(m_vistaTreeViewHelper, L"explorer", NULL))) { - qErrnoWarning("SetWindowTheme() failed."); - cleanupVistaTreeViewTheming(); - return false; - } - return true; -} - -void QWindowsXPStylePrivate::cleanupVistaTreeViewTheming() -{ - if (m_vistaTreeViewHelper) { - DestroyWindow(m_vistaTreeViewHelper); - m_vistaTreeViewHelper = 0; - } -} - -/* \internal - Closes all open theme data handles to ensure that we don't leak - resources, and that we don't refere to old handles when for - example the user changes the theme style. -*/ -void QWindowsXPStylePrivate::cleanupHandleMap() -{ - for (int i = 0; i < NThemes; ++i) - if (m_themes[i]) { - CloseThemeData(m_themes[i]); - m_themes[i] = 0; - } - QWindowsXPStylePrivate::cleanupVistaTreeViewTheming(); -} - -HTHEME QWindowsXPStylePrivate::createTheme(int theme, HWND hwnd) -{ - if (Q_UNLIKELY(theme < 0 || theme >= NThemes || !hwnd)) { - qWarning("Invalid parameters #%d, %p", theme, hwnd); - return 0; - } - if (!m_themes[theme]) { - const wchar_t *name = themeNames[theme]; - if (theme == VistaTreeViewTheme && QWindowsXPStylePrivate::initVistaTreeViewTheming()) - hwnd = QWindowsXPStylePrivate::m_vistaTreeViewHelper; - m_themes[theme] = OpenThemeData(hwnd, name); - if (Q_UNLIKELY(!m_themes[theme])) - qErrnoWarning("OpenThemeData() failed for theme %d (%s).", - theme, qPrintable(themeName(theme))); - } - return m_themes[theme]; -} - -QString QWindowsXPStylePrivate::themeName(int theme) -{ - return theme >= 0 && theme < NThemes ? - QString::fromWCharArray(themeNames[theme]) : - QString(); -} - -bool QWindowsXPStylePrivate::isItemViewDelegateLineEdit(const QWidget *widget) -{ - if (!widget) - return false; - const QWidget *parent1 = widget->parentWidget(); - // Exlude dialogs or other toplevels parented on item views. - if (!parent1 || parent1->isWindow()) - return false; - const QWidget *parent2 = parent1->parentWidget(); - return parent2 && widget->inherits("QLineEdit") - && parent2->inherits("QAbstractItemView"); -} - -// Returns whether base color is set for this widget -bool QWindowsXPStylePrivate::isLineEditBaseColorSet(const QStyleOption *option, const QWidget *widget) -{ - uint resolveMask = option->palette.resolve(); - if (widget) { - // Since spin box includes a line edit we need to resolve the palette mask also from - // the parent, as while the color is always correct on the palette supplied by panel, - // the mask can still be empty. If either mask specifies custom base color, use that. -#if QT_CONFIG(spinbox) - if (const QAbstractSpinBox *spinbox = qobject_cast<QAbstractSpinBox*>(widget->parentWidget())) - resolveMask |= spinbox->palette().resolve(); -#endif // QT_CONFIG(spinbox) - } - return (resolveMask & (1 << QPalette::Base)) != 0; -} - -/*! \internal - This function will always return a valid window handle, and might - create a limbo widget to do so. - We often need a window handle to for example open theme data, so - this function ensures that we get one. -*/ -HWND QWindowsXPStylePrivate::winId(const QWidget *widget) -{ - if (widget) - if (const HWND hwnd = QApplicationPrivate::getHWNDForWidget(const_cast<QWidget *>(widget))) - return hwnd; - - // Find top level with native window (there might be dialogs that do not have one). - const auto topLevels = QApplication::topLevelWidgets(); - for (const QWidget *toplevel : topLevels) { - if (toplevel->windowHandle() && toplevel->windowHandle()->handle()) - if (const HWND topLevelHwnd = QApplicationPrivate::getHWNDForWidget(toplevel)) - return topLevelHwnd; - } - - return GetDesktopWindow(); -} - -/*! \internal - Returns the pointer to a tab widgets body pixmap, scaled to the - height of the screen. This way the theme engine doesn't need to - scale the body for every time we ask for it. (Speed optimization) -*/ -const QPixmap *QWindowsXPStylePrivate::tabBody(QWidget *widget) -{ - if (!tabbody) { - XPThemeData theme(0, 0, QWindowsXPStylePrivate::TabTheme, TABP_BODY); - const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); - - tabbody = new QPixmap(size.width(), QApplication::desktop()->screenGeometry().height()); - QPainter painter(tabbody); - theme.rect = QRect(QPoint(0, 0), size); - drawBackground(theme); - // We fill with the last line of the themedata, that - // way we don't get a tiled pixmap inside big tabs - QPixmap temp(size.width(), 1); - painter.drawPixmap(0, 0, temp, 0, size.height() - 1, -1, -1); - painter.drawTiledPixmap(0, size.height(), size.width(), tabbody->height() - size.height(), temp); - } - return tabbody; -} - -/*! \internal - Returns a native buffer (DIB section) of at least the size of - ( \a x , \a y ). The buffer has a 32 bit depth, to not lose - the alpha values on proper alpha-pixmaps. -*/ -HBITMAP QWindowsXPStylePrivate::buffer(int w, int h) -{ - // If we already have a HBITMAP which is of adequate size, just return that - if (bufferBitmap) { - if (bufferW >= w && bufferH >= h) - return bufferBitmap; - // Not big enough, discard the old one - if (bufferDC && nullBitmap) - SelectObject(bufferDC, nullBitmap); - DeleteObject(bufferBitmap); - bufferBitmap = 0; - } - - w = qMax(bufferW, w); - h = qMax(bufferH, h); - - if (!bufferDC) { - HDC displayDC = GetDC(0); - bufferDC = CreateCompatibleDC(displayDC); - ReleaseDC(0, displayDC); - } - - // Define the header - BITMAPINFO bmi; - memset(&bmi, 0, sizeof(bmi)); - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = w; - bmi.bmiHeader.biHeight = -h; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 32; - bmi.bmiHeader.biCompression = BI_RGB; - - // Create the pixmap - bufferPixels = 0; - bufferBitmap = CreateDIBSection(bufferDC, &bmi, DIB_RGB_COLORS, (void **) &bufferPixels, 0, 0); - GdiFlush(); - nullBitmap = (HBITMAP)SelectObject(bufferDC, bufferBitmap); - - if (Q_UNLIKELY(!bufferBitmap)) { - qErrnoWarning("QWindowsXPStylePrivate::buffer(%dx%d), CreateDIBSection() failed.", w, h); - bufferW = 0; - bufferH = 0; - return 0; - } - if (Q_UNLIKELY(!bufferPixels)) { - qErrnoWarning("QWindowsXPStylePrivate::buffer(%dx%d), CreateDIBSection() did not allocate pixel data.", w, h); - bufferW = 0; - bufferH = 0; - return 0; - } - bufferW = w; - bufferH = h; -#ifdef DEBUG_XP_STYLE - qDebug("Creating new dib section (%d, %d)", w, h); -#endif - return bufferBitmap; -} - -/*! \internal - Returns \c true if the part contains any transparency at all. This does - not indicate what kind of transparency we're dealing with. It can be - - Alpha transparency - - Masked transparency -*/ -bool QWindowsXPStylePrivate::isTransparent(XPThemeData &themeData) -{ - return IsThemeBackgroundPartiallyTransparent(themeData.handle(), themeData.partId, - themeData.stateId); -} - - -/*! \internal - Returns a QRegion of the region of the part -*/ -QRegion QWindowsXPStylePrivate::region(XPThemeData &themeData) -{ - HRGN hRgn = 0; - RECT rect = themeData.toRECT(themeData.rect); - if (!SUCCEEDED(GetThemeBackgroundRegion(themeData.handle(), bufferHDC(), themeData.partId, - themeData.stateId, &rect, &hRgn))) { - return QRegion(); - } - - HRGN dest = CreateRectRgn(0, 0, 0, 0); - const bool success = CombineRgn(dest, hRgn, 0, RGN_COPY) != ERROR; - - QRegion region; - - if (success) { - int numBytes = GetRegionData(dest, 0, 0); - if (numBytes == 0) - return QRegion(); - - char *buf = new char[numBytes]; - if (buf == 0) - return QRegion(); - - RGNDATA *rd = reinterpret_cast<RGNDATA*>(buf); - if (GetRegionData(dest, numBytes, rd) == 0) { - delete [] buf; - return QRegion(); - } - - RECT *r = reinterpret_cast<RECT*>(rd->Buffer); - for (uint i = 0; i < rd->rdh.nCount; ++i) { - QRect rect; - rect.setCoords(r->left, r->top, r->right - 1, r->bottom - 1); - ++r; - region |= rect; - } - - delete [] buf; - } - - DeleteObject(hRgn); - DeleteObject(dest); - - return region; -} - -/*! \internal - Sets the parts region on a window. -*/ -void QWindowsXPStylePrivate::setTransparency(QWidget *widget, XPThemeData &themeData) -{ - HRGN hrgn = themeData.mask(widget); - if (hrgn && widget) - SetWindowRgn(winId(widget), hrgn, true); -} - -/*! \internal - Returns \c true if the native doublebuffer contains pixels with - varying alpha value. -*/ -bool QWindowsXPStylePrivate::hasAlphaChannel(const QRect &rect) -{ - const int startX = rect.left(); - const int startY = rect.top(); - const int w = rect.width(); - const int h = rect.height(); - - int firstAlpha = -1; - for (int y = startY; y < h/2; ++y) { - DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW); - for (int x = startX; x < w; ++x, ++buffer) { - int alpha = (*buffer) >> 24; - if (firstAlpha == -1) - firstAlpha = alpha; - else if (alpha != firstAlpha) - return true; - } - } - return false; -} - -/*! \internal - When the theme engine paints both a true alpha pixmap and a glyph - into our buffer, the glyph might not contain a proper alpha value. - The rule of thumb for premultiplied pixmaps is that the color - values of a pixel can never be higher than the alpha values, so - we use this to our advantage here, and fix all instances where - this occures. -*/ -bool QWindowsXPStylePrivate::fixAlphaChannel(const QRect &rect) -{ - const int startX = rect.left(); - const int startY = rect.top(); - const int w = rect.width(); - const int h = rect.height(); - bool hasFixedAlphaValue = false; - - for (int y = startY; y < h; ++y) { - DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW); - for (int x = startX; x < w; ++x, ++buffer) { - uint pixel = *buffer; - int alpha = qAlpha(pixel); - if (qRed(pixel) > alpha || qGreen(pixel) > alpha || qBlue(pixel) > alpha) { - *buffer |= 0xff000000; - hasFixedAlphaValue = true; - } - } - } - return hasFixedAlphaValue; -} - -/*! \internal - Swaps the alpha values on certain pixels: - 0xFF?????? -> 0x00?????? - 0x00?????? -> 0xFF?????? - Used to determin the mask of a non-alpha transparent pixmap in - the native doublebuffer, and swap the alphas so we may paint - the image as a Premultiplied QImage with drawImage(), and obtain - the mask transparency. -*/ -bool QWindowsXPStylePrivate::swapAlphaChannel(const QRect &rect, bool allPixels) -{ - const int startX = rect.left(); - const int startY = rect.top(); - const int w = rect.width(); - const int h = rect.height(); - bool valueChange = false; - - // Flip the alphas, so that 255-alpha pixels are 0, and 0-alpha are 255. - for (int y = startY; y < h; ++y) { - DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW); - for (int x = startX; x < w; ++x, ++buffer) { - if (allPixels) { - *buffer |= 0xFF000000; - continue; - } - unsigned int alphaValue = (*buffer) & 0xFF000000; - if (alphaValue == 0xFF000000) { - *buffer = 0; - valueChange = true; - } else if (alphaValue == 0) { - *buffer |= 0xFF000000; - valueChange = true; - } - } - } - return valueChange; -} - -enum TransformType { SimpleTransform, HighDpiScalingTransform, ComplexTransform }; - -static inline TransformType transformType(const QTransform &transform, qreal devicePixelRatio) -{ - if (transform.type() <= QTransform::TxTranslate) - return SimpleTransform; - if (transform.type() > QTransform::TxScale) - return ComplexTransform; - return qFuzzyCompare(transform.m11(), devicePixelRatio) - && qFuzzyCompare(transform.m22(), devicePixelRatio) - ? HighDpiScalingTransform : ComplexTransform; -} - -/*! \internal - Main theme drawing function. - Determines the correct lowlevel drawing method depending on several - factors. - Use drawBackgroundThruNativeBuffer() if: - - Painter does not have an HDC - - Theme part is flipped (mirrored horizontally) - else use drawBackgroundDirectly(). - \note drawBackgroundThruNativeBuffer() can return false for large - sizes due to buffer()/CreateDIBSection() failing. -*/ -bool QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData) -{ - if (themeData.rect.isEmpty()) - return true; - - QPainter *painter = themeData.painter; - Q_ASSERT_X(painter != 0, "QWindowsXPStylePrivate::drawBackground()", "Trying to draw a theme part without a painter"); - if (!painter || !painter->isActive()) - return false; - - painter->save(); - - // Access paintDevice via engine since the painter may - // return the clip device which can still be a widget device in case of grabWidget(). - - bool translucentToplevel = false; - const QPaintDevice *paintDevice = painter->device(); - const qreal aditionalDevicePixelRatio = themeData.widget ? themeData.widget->devicePixelRatioF() : qreal(1); - if (paintDevice->devType() == QInternal::Widget) { - const QWidget *window = static_cast<const QWidget *>(paintDevice)->window(); - translucentToplevel = window->testAttribute(Qt::WA_TranslucentBackground); - } - - const TransformType tt = transformType(painter->deviceTransform(), aditionalDevicePixelRatio); - - bool canDrawDirectly = false; - if (themeData.widget && painter->opacity() == 1.0 && !themeData.rotate - && tt != ComplexTransform && !themeData.mirrorVertically - && !translucentToplevel) { - // Draw on backing store DC only for real widgets or backing store images. - const QPaintDevice *enginePaintDevice = painter->paintEngine()->paintDevice(); - switch (enginePaintDevice->devType()) { - case QInternal::Widget: - canDrawDirectly = true; - break; - case QInternal::Image: - // Ensure the backing store has received as resize and is initialized. - if (QBackingStore *bs = backingStoreForWidget(themeData.widget)) - if (bs->size().isValid() && bs->paintDevice() == enginePaintDevice) - canDrawDirectly = true; - } - } - - const HDC dc = canDrawDirectly ? hdcForWidgetBackingStore(themeData.widget) : HDC(0); - const bool result = dc - ? drawBackgroundDirectly(dc, themeData, aditionalDevicePixelRatio) - : drawBackgroundThruNativeBuffer(themeData, aditionalDevicePixelRatio); - painter->restore(); - return result; -} - -static inline QRectF scaleRect(const QRectF &r, qreal factor) -{ - return r.isValid() && factor > 1 - ? QRectF(r.topLeft() * factor, r.size() * factor) - : r; -} - -static QRegion scaleRegion(const QRegion ®ion, qreal factor) -{ - if (region.isEmpty() || qFuzzyCompare(factor, qreal(1))) - return region; - if (region.rectCount() == 1) - return QRegion(scaleRect(QRectF(region.boundingRect()), factor).toRect()); - QRegion result; - foreach (const QRect &rect, region.rects()) - result += QRectF(QPointF(rect.topLeft()) * factor, QSizeF(rect.size() * factor)).toRect(); - return result; -} - -/*! \internal - This function draws the theme parts directly to the paintengines HDC. - Do not use this if you need to perform other transformations on the - resulting data. -*/ -bool QWindowsXPStylePrivate::drawBackgroundDirectly(HDC dc, XPThemeData &themeData, qreal additionalDevicePixelRatio) -{ - QPainter *painter = themeData.painter; - - const QPointF redirectionDelta(painter->deviceMatrix().dx(), painter->deviceMatrix().dy()); - const QRect area = scaleRect(QRectF(themeData.rect), additionalDevicePixelRatio).translated(redirectionDelta).toRect(); - - QRegion sysRgn = painter->paintEngine()->systemClip(); - if (sysRgn.isEmpty()) - sysRgn = area; - else - sysRgn &= area; - if (painter->hasClipping()) - sysRgn &= scaleRegion(painter->clipRegion(), additionalDevicePixelRatio).translated(redirectionDelta.toPoint()); - HRGN hrgn = qt_hrgn_from_qregion(sysRgn); - SelectClipRgn(dc, hrgn); - -#ifdef DEBUG_XP_STYLE - printf("---[ DIRECT PAINTING ]------------------> Name(%-10s) Part(%d) State(%d)\n", - qPrintable(themeData.name), themeData.partId, themeData.stateId); - showProperties(themeData); -#endif - - RECT drawRECT = themeData.toRECT(area); - DTBGOPTS drawOptions; - memset(&drawOptions, 0, sizeof(drawOptions)); - drawOptions.dwSize = sizeof(drawOptions); - drawOptions.rcClip = themeData.toRECT(sysRgn.boundingRect()); - drawOptions.dwFlags = DTBG_CLIPRECT - | (themeData.noBorder ? DTBG_OMITBORDER : 0) - | (themeData.noContent ? DTBG_OMITCONTENT : 0) - | (themeData.mirrorHorizontally ? DTBG_MIRRORDC : 0); - - const HRESULT result = DrawThemeBackgroundEx(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &drawOptions); - SelectClipRgn(dc, 0); - DeleteObject(hrgn); - return SUCCEEDED(result); -} - -/*! \internal - This function uses a secondary Native doublebuffer for painting parts. - It should only be used when the painteengine doesn't provide a proper - HDC for direct painting (e.g. when doing a grabWidget(), painting to - other pixmaps etc), or when special transformations are needed (e.g. - flips (horizonal mirroring only, vertical are handled by the theme - engine). -*/ -bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeData, - qreal additionalDevicePixelRatio) -{ - QPainter *painter = themeData.painter; - QRectF rectF = scaleRect(QRectF(themeData.rect), additionalDevicePixelRatio); - - if ((themeData.rotate + 90) % 180 == 0) { // Catch 90,270,etc.. degree flips. - rectF = QRectF(0, 0, rectF.height(), rectF.width()); - } - rectF.moveTo(0, 0); - QRect rect = rectF.toRect(); - int partId = themeData.partId; - int stateId = themeData.stateId; - int w = rect.width(); - int h = rect.height(); - - // Values initialized later, either from cached values, or from function calls - AlphaChannelType alphaType = UnknownAlpha; - bool stateHasData = true; // We assume so; - bool hasAlpha = false; - bool partIsTransparent; - bool potentialInvalidAlpha; - - QString pixmapCacheKey = QStringLiteral("$qt_xp_"); - pixmapCacheKey.append(themeName(themeData.theme)); - pixmapCacheKey.append(QLatin1Char('p')); - pixmapCacheKey.append(QString::number(partId)); - pixmapCacheKey.append(QLatin1Char('s')); - pixmapCacheKey.append(QString::number(stateId)); - pixmapCacheKey.append(QLatin1Char('s')); - pixmapCacheKey.append(themeData.noBorder ? QLatin1Char('0') : QLatin1Char('1')); - pixmapCacheKey.append(QLatin1Char('b')); - pixmapCacheKey.append(themeData.noContent ? QLatin1Char('0') : QLatin1Char('1')); - pixmapCacheKey.append(QString::number(w)); - pixmapCacheKey.append(QLatin1Char('w')); - pixmapCacheKey.append(QString::number(h)); - pixmapCacheKey.append(QLatin1Char('h')); - pixmapCacheKey.append(QString::number(additionalDevicePixelRatio)); - pixmapCacheKey.append(QLatin1Char('d')); - - QPixmap cachedPixmap; - ThemeMapKey key(themeData); - ThemeMapData data = alphaCache.value(key); - - bool haveCachedPixmap = false; - bool isCached = data.dataValid; - if (isCached) { - partIsTransparent = data.partIsTransparent; - hasAlpha = data.hasAlphaChannel; - alphaType = data.alphaType; - potentialInvalidAlpha = data.hadInvalidAlpha; - - haveCachedPixmap = QPixmapCache::find(pixmapCacheKey, cachedPixmap); - -#ifdef DEBUG_XP_STYLE - char buf[25]; - ::sprintf(buf, "+ Pixmap(%3d, %3d) ]", w, h); - printf("---[ CACHED %s--------> Name(%-10s) Part(%d) State(%d)\n", - haveCachedPixmap ? buf : "]-------------------", - qPrintable(themeData.name), themeData.partId, themeData.stateId); -#endif - } else { - // Not cached, so get values from Theme Engine - BOOL tmt_borderonly = false; - COLORREF tmt_transparentcolor = 0x0; - PROPERTYORIGIN proporigin = PO_NOTFOUND; - GetThemeBool(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERONLY, &tmt_borderonly); - GetThemeColor(themeData.handle(), themeData.partId, themeData.stateId, TMT_TRANSPARENTCOLOR, &tmt_transparentcolor); - GetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_CAPTIONMARGINS, &proporigin); - - partIsTransparent = isTransparent(themeData); - - potentialInvalidAlpha = false; - GetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_GLYPHTYPE, &proporigin); - if (proporigin == PO_PART || proporigin == PO_STATE) { - int tmt_glyphtype = GT_NONE; - GetThemeEnumValue(themeData.handle(), themeData.partId, themeData.stateId, TMT_GLYPHTYPE, &tmt_glyphtype); - potentialInvalidAlpha = partIsTransparent && tmt_glyphtype == GT_IMAGEGLYPH; - } - -#ifdef DEBUG_XP_STYLE - printf("---[ NOT CACHED ]-----------------------> Name(%-10s) Part(%d) State(%d)\n", - qPrintable(themeData.name), themeData.partId, themeData.stateId); - printf("-->partIsTransparen = %d\n", partIsTransparent); - printf("-->potentialInvalidAlpha = %d\n", potentialInvalidAlpha); - showProperties(themeData); -#endif - } - bool wasAlphaSwapped = false; - bool wasAlphaFixed = false; - - // OLD PSDK Workaround ------------------------------------------------------------------------ - // See if we need extra clipping for the older PSDK, which does - // not have a DrawThemeBackgroundEx function for DTGB_OMITBORDER - // and DTGB_OMITCONTENT - bool addBorderContentClipping = false; - QRegion extraClip; - QRect area = rect; - if (themeData.noBorder || themeData.noContent) { - extraClip = area; - // We are running on a system where the uxtheme.dll does not have - // the DrawThemeBackgroundEx function, so we need to clip away - // borders or contents manually. - - int borderSize = 0; - PROPERTYORIGIN origin = PO_NOTFOUND; - GetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &origin); - GetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &borderSize); - - // Clip away border region - if ((origin == PO_CLASS || origin == PO_PART || origin == PO_STATE) && borderSize > 0) { - if (themeData.noBorder) { - extraClip &= area; - area = area.adjusted(-borderSize, -borderSize, borderSize, borderSize); - } - - // Clip away content region - if (themeData.noContent) { - QRegion content = area.adjusted(borderSize, borderSize, -borderSize, -borderSize); - extraClip ^= content; - } - } - addBorderContentClipping = (themeData.noBorder | themeData.noContent); - } - - QImage img; - if (!haveCachedPixmap) { // If the pixmap is not cached, generate it! ------------------------- - if (!buffer(w, h)) // Ensure a buffer of at least (w, h) in size - return false; - HDC dc = bufferHDC(); - - // Clear the buffer - if (alphaType != NoAlpha) { - // Consider have separate "memset" function for small chunks for more speedup - memset(bufferPixels, 0x00, bufferW * h * 4); - } - - // Difference between area and rect - int dx = area.x() - rect.x(); - int dy = area.y() - rect.y(); - - // Adjust so painting rect starts from Origo - rect.moveTo(0,0); - area.moveTo(dx,dy); - DTBGOPTS drawOptions; - drawOptions.dwSize = sizeof(drawOptions); - drawOptions.rcClip = themeData.toRECT(rect); - drawOptions.dwFlags = DTBG_CLIPRECT - | (themeData.noBorder ? DTBG_OMITBORDER : 0) - | (themeData.noContent ? DTBG_OMITCONTENT : 0); - - // Drawing the part into the backing store - RECT wRect(themeData.toRECT(area)); - DrawThemeBackgroundEx(themeData.handle(), dc, themeData.partId, themeData.stateId, &wRect, &drawOptions); - - // If not cached, analyze the buffer data to figure - // out alpha type, and if it contains data - if (!isCached) { - // SHORTCUT: If the part's state has no data, cache it for NOOP later - if (!stateHasData) { - memset(&data, 0, sizeof(data)); - data.dataValid = true; - alphaCache.insert(key, data); - return true; - } - hasAlpha = hasAlphaChannel(rect); - if (!hasAlpha && partIsTransparent) - potentialInvalidAlpha = true; -#if defined(DEBUG_XP_STYLE) && 1 - dumpNativeDIB(w, h); -#endif - } - - // Fix alpha values, if needed - if (potentialInvalidAlpha) - wasAlphaFixed = fixAlphaChannel(rect); - - QImage::Format format; - if ((partIsTransparent && !wasAlphaSwapped) || (!partIsTransparent && hasAlpha)) { - format = QImage::Format_ARGB32_Premultiplied; - alphaType = RealAlpha; - } else if (wasAlphaSwapped) { - format = QImage::Format_ARGB32_Premultiplied; - alphaType = MaskAlpha; - } else { - format = QImage::Format_RGB32; - // The image data we got from the theme engine does not have any transparency, - // thus the alpha channel is set to 0. - // However, Format_RGB32 requires the alpha part to be set to 0xff, thus - // we must flip it from 0x00 to 0xff - swapAlphaChannel(rect, true); - alphaType = NoAlpha; - } -#if defined(DEBUG_XP_STYLE) && 1 - printf("Image format is: %s\n", alphaType == RealAlpha ? "Real Alpha" : alphaType == MaskAlpha ? "Masked Alpha" : "No Alpha"); -#endif - img = QImage(bufferPixels, bufferW, bufferH, format); - img.setDevicePixelRatio(additionalDevicePixelRatio); - } - - // Blitting backing store - bool useRegion = partIsTransparent && !hasAlpha && !wasAlphaSwapped; - - QRegion newRegion; - QRegion oldRegion; - if (useRegion) { - newRegion = region(themeData); - oldRegion = painter->clipRegion(); - painter->setClipRegion(newRegion); -#if defined(DEBUG_XP_STYLE) && 0 - printf("Using region:\n"); - for (const QRect &r : newRegion) - printf(" (%d, %d, %d, %d)\n", r.x(), r.y(), r.right(), r.bottom()); -#endif - } - - if (addBorderContentClipping) - painter->setClipRegion(extraClip, Qt::IntersectClip); - - if (!themeData.mirrorHorizontally && !themeData.mirrorVertically && !themeData.rotate) { - if (!haveCachedPixmap) - painter->drawImage(themeData.rect, img, rect); - else - painter->drawPixmap(themeData.rect, cachedPixmap); - } else { - // This is _slow_! - // Make a copy containing only the necessary data, and mirror - // on all wanted axes. Then draw the copy. - // If cached, the normal pixmap is cached, instead of caching - // all possible orientations for each part and state. - QImage imgCopy; - if (!haveCachedPixmap) - imgCopy = img.copy(rect); - else - imgCopy = cachedPixmap.toImage(); - - if (themeData.rotate) { - QMatrix rotMatrix; - rotMatrix.rotate(themeData.rotate); - imgCopy = imgCopy.transformed(rotMatrix); - } - if (themeData.mirrorHorizontally || themeData.mirrorVertically) { - imgCopy = imgCopy.mirrored(themeData.mirrorHorizontally, themeData.mirrorVertically); - } - painter->drawImage(themeData.rect, - imgCopy); - } - - if (useRegion || addBorderContentClipping) { - if (oldRegion.isEmpty()) - painter->setClipping(false); - else - painter->setClipRegion(oldRegion); - } - - // Cache the pixmap to avoid expensive swapAlphaChannel() calls - if (!haveCachedPixmap && w && h) { - QPixmap pix = QPixmap::fromImage(img).copy(rect); - QPixmapCache::insert(pixmapCacheKey, pix); -#ifdef DEBUG_XP_STYLE - printf("+++Adding pixmap to cache, size(%d, %d), wasAlphaSwapped(%d), wasAlphaFixed(%d), name(%s)\n", - w, h, wasAlphaSwapped, wasAlphaFixed, qPrintable(pixmapCacheKey)); -#endif - } - - // Add to theme part cache - if (!isCached) { - memset(&data, 0, sizeof(data)); - data.dataValid = true; - data.partIsTransparent = partIsTransparent; - data.alphaType = alphaType; - data.hasAlphaChannel = hasAlpha; - data.wasAlphaSwapped = wasAlphaSwapped; - data.hadInvalidAlpha = wasAlphaFixed; - alphaCache.insert(key, data); - } - return true; -} - - -// ------------------------------------------------------------------------------------------------ - -/*! - \class QWindowsXPStyle - \brief The QWindowsXPStyle class provides a Microsoft Windows XP-like look and feel. - - \ingroup appearance - \inmodule QtWidgets - \internal - - \warning This style is only available on the Windows XP platform - because it makes use of Windows XP's style engine. - - Most of the functions are documented in the base classes - QWindowsStyle, QCommonStyle, and QStyle, but the - QWindowsXPStyle overloads of drawComplexControl(), drawControl(), - drawControlMask(), drawPrimitive(), proxy()->subControlRect(), and - sizeFromContents(), are documented here. - - \image qwindowsxpstyle.png - \sa QMacStyle, QWindowsStyle, QFusionStyle -*/ - -/*! - Constructs a QWindowsStyle -*/ -QWindowsXPStyle::QWindowsXPStyle() - : QWindowsStyle(*new QWindowsXPStylePrivate) -{ -} - -/*! - Destroys the style. -*/ -QWindowsXPStyle::~QWindowsXPStyle() -{ -} - -/*! \reimp */ -void QWindowsXPStyle::unpolish(QApplication *app) -{ - QWindowsStyle::unpolish(app); -} - -/*! \reimp */ -void QWindowsXPStyle::polish(QApplication *app) -{ - QWindowsStyle::polish(app); - if (!QWindowsXPStylePrivate::useXP()) - return; -} - -/*! \reimp */ -void QWindowsXPStyle::polish(QWidget *widget) -{ - QWindowsStyle::polish(widget); - if (!QWindowsXPStylePrivate::useXP()) - return; - - if (false -#if QT_CONFIG(abstractbutton) - || qobject_cast<QAbstractButton*>(widget) -#endif - || qobject_cast<QToolButton*>(widget) - || qobject_cast<QTabBar*>(widget) -#if QT_CONFIG(combobox) - || qobject_cast<QComboBox*>(widget) -#endif // QT_CONFIG(combobox) - || qobject_cast<QScrollBar*>(widget) - || qobject_cast<QSlider*>(widget) - || qobject_cast<QHeaderView*>(widget) -#if QT_CONFIG(spinbox) - || qobject_cast<QAbstractSpinBox*>(widget) - || qobject_cast<QSpinBox*>(widget) -#endif // QT_CONFIG(spinbox) - ) { - widget->setAttribute(Qt::WA_Hover); - } - -#if QT_CONFIG(rubberband) - if (qobject_cast<QRubberBand*>(widget)) { - widget->setWindowOpacity(0.6); - } -#endif - if (qobject_cast<QStackedWidget*>(widget) && - qobject_cast<QTabWidget*>(widget->parent())) - widget->parentWidget()->setAttribute(Qt::WA_ContentsPropagated); - - Q_D(QWindowsXPStyle); - if (!d->hasInitColors) { - // Get text color for group box labels - COLORREF cref; - XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ButtonTheme, 0, 0); - GetThemeColor(theme.handle(), BP_GROUPBOX, GBS_NORMAL, TMT_TEXTCOLOR, &cref); - d->groupBoxTextColor = qRgb(GetRValue(cref), GetGValue(cref), GetBValue(cref)); - GetThemeColor(theme.handle(), BP_GROUPBOX, GBS_DISABLED, TMT_TEXTCOLOR, &cref); - d->groupBoxTextColorDisabled = qRgb(GetRValue(cref), GetGValue(cref), GetBValue(cref)); - // Where does this color come from? - //GetThemeColor(theme.handle(), TKP_TICS, TSS_NORMAL, TMT_COLOR, &cref); - d->sliderTickColor = qRgb(165, 162, 148); - d->hasInitColors = true; - } -} - -/*! \reimp */ -void QWindowsXPStyle::polish(QPalette &pal) -{ - QWindowsStyle::polish(pal); - pal.setBrush(QPalette::AlternateBase, pal.base().color().darker(110)); -} - -/*! \reimp */ -void QWindowsXPStyle::unpolish(QWidget *widget) -{ -#if QT_CONFIG(rubberband) - if (qobject_cast<QRubberBand*>(widget)) { - widget->setWindowOpacity(1.0); - } -#endif - Q_D(QWindowsXPStyle); - // Unpolish of widgets is the first thing that - // happens when a theme changes, or the theme - // engine is turned off. So we detect it here. - bool oldState = QWindowsXPStylePrivate::useXP(); - bool newState = QWindowsXPStylePrivate::useXP(true); - if ((oldState != newState) && newState) { - d->cleanup(true); - d->init(true); - } else { - // Cleanup handle map, if just changing style, - // or turning it on. In both cases the values - // already in the map might be old (other style). - d->cleanupHandleMap(); - } - if (false -#if QT_CONFIG(abstractbutton) - || qobject_cast<QAbstractButton*>(widget) -#endif - || qobject_cast<QToolButton*>(widget) - || qobject_cast<QTabBar*>(widget) -#if QT_CONFIG(combobox) - || qobject_cast<QComboBox*>(widget) -#endif // QT_CONFIG(combobox) - || qobject_cast<QScrollBar*>(widget) - || qobject_cast<QSlider*>(widget) - || qobject_cast<QHeaderView*>(widget) -#if QT_CONFIG(spinbox) - || qobject_cast<QAbstractSpinBox*>(widget) - || qobject_cast<QSpinBox*>(widget) -#endif // QT_CONFIG(spinbox) - ) { - widget->setAttribute(Qt::WA_Hover, false); - } - QWindowsStyle::unpolish(widget); -} - -/*! \reimp */ -QRect QWindowsXPStyle::subElementRect(SubElement sr, const QStyleOption *option, const QWidget *widget) const -{ - if (!QWindowsXPStylePrivate::useXP()) { - return QWindowsStyle::subElementRect(sr, option, widget); - } - - QRect rect(option->rect); - switch(sr) { - case SE_DockWidgetCloseButton: - case SE_DockWidgetFloatButton: - rect = QWindowsStyle::subElementRect(sr, option, widget); - return rect.translated(0, 1); - break; - case SE_TabWidgetTabContents: - if (qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) - { - rect = QWindowsStyle::subElementRect(sr, option, widget); - if (sr == SE_TabWidgetTabContents) { - if (const QTabWidget *tabWidget = qobject_cast<const QTabWidget *>(widget)) { - if (tabWidget->documentMode()) - break; - } - - rect.adjust(0, 0, -2, -2); - } - } - break; - case SE_TabWidgetTabBar: { - rect = QWindowsStyle::subElementRect(sr, option, widget); - const QStyleOptionTabWidgetFrame *twfOption = - qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option); - if (twfOption && twfOption->direction == Qt::RightToLeft - && (twfOption->shape == QTabBar::RoundedNorth - || twfOption->shape == QTabBar::RoundedSouth)) - { - QStyleOptionTab otherOption; - otherOption.shape = (twfOption->shape == QTabBar::RoundedNorth - ? QTabBar::RoundedEast : QTabBar::RoundedSouth); - int overlap = proxy()->pixelMetric(PM_TabBarBaseOverlap, &otherOption, widget); - int borderThickness = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget); - rect.adjust(-overlap + borderThickness, 0, -overlap + borderThickness, 0); - } - break;} - - case SE_PushButtonContents: - if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) { - MARGINS borderSize; - if (widget) { - XPThemeData buttontheme(widget, 0, QWindowsXPStylePrivate::ButtonTheme); - HTHEME theme = buttontheme.handle(); - if (theme) { - int stateId; - if (!(option->state & State_Enabled)) - stateId = PBS_DISABLED; - else if (option->state & State_Sunken) - stateId = PBS_PRESSED; - else if (option->state & State_MouseOver) - stateId = PBS_HOT; - else if (btn->features & QStyleOptionButton::DefaultButton) - stateId = PBS_DEFAULTED; - else - stateId = PBS_NORMAL; - - int border = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget); - rect = option->rect.adjusted(border, border, -border, -border); - - if (SUCCEEDED(GetThemeMargins(theme, NULL, BP_PUSHBUTTON, stateId, TMT_CONTENTMARGINS, NULL, &borderSize))) { - rect.adjust(borderSize.cxLeftWidth, borderSize.cyTopHeight, - -borderSize.cxRightWidth, -borderSize.cyBottomHeight); - rect = visualRect(option->direction, option->rect, rect); - } - } - } - } - break; - case SE_ProgressBarContents: - rect = QCommonStyle::subElementRect(SE_ProgressBarGroove, option, widget); - if (option->state & QStyle::State_Horizontal) - rect.adjust(4, 3, -4, -3); - else - rect.adjust(3, 2, -3, -2); - break; - default: - rect = QWindowsStyle::subElementRect(sr, option, widget); - } - return rect; -} - -/*! - \reimp -*/ -void QWindowsXPStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *option, QPainter *p, - const QWidget *widget) const -{ - QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func()); - - if (!QWindowsXPStylePrivate::useXP()) { - QWindowsStyle::drawPrimitive(pe, option, p, widget); - return; - } - - int themeNumber = -1; - int partId = 0; - int stateId = 0; - QRect rect = option->rect; - State flags = option->state; - bool hMirrored = false; - bool vMirrored = false; - bool noBorder = false; - bool noContent = false; - int rotate = 0; - - switch (pe) { - case PE_FrameTabBarBase: - if (const QStyleOptionTabBarBase *tbb - = qstyleoption_cast<const QStyleOptionTabBarBase *>(option)) { - p->save(); - switch (tbb->shape) { - case QTabBar::RoundedNorth: - p->setPen(QPen(tbb->palette.dark(), 0)); - p->drawLine(tbb->rect.topLeft(), tbb->rect.topRight()); - break; - case QTabBar::RoundedWest: - p->setPen(QPen(tbb->palette.dark(), 0)); - p->drawLine(tbb->rect.left(), tbb->rect.top(), tbb->rect.left(), tbb->rect.bottom()); - break; - case QTabBar::RoundedSouth: - p->setPen(QPen(tbb->palette.dark(), 0)); - p->drawLine(tbb->rect.left(), tbb->rect.top(), - tbb->rect.right(), tbb->rect.top()); - break; - case QTabBar::RoundedEast: - p->setPen(QPen(tbb->palette.dark(), 0)); - p->drawLine(tbb->rect.topLeft(), tbb->rect.bottomLeft()); - break; - case QTabBar::TriangularNorth: - case QTabBar::TriangularEast: - case QTabBar::TriangularWest: - case QTabBar::TriangularSouth: - p->restore(); - QWindowsStyle::drawPrimitive(pe, option, p, widget); - return; - } - p->restore(); - } - return; - case PE_PanelButtonBevel: - themeNumber = QWindowsXPStylePrivate::ButtonTheme; - partId = BP_PUSHBUTTON; - if (!(flags & State_Enabled)) - stateId = PBS_DISABLED; - else if ((flags & State_Sunken) || (flags & State_On)) - stateId = PBS_PRESSED; - else if (flags & State_MouseOver) - stateId = PBS_HOT; - //else if (flags & State_ButtonDefault) - // stateId = PBS_DEFAULTED; - else - stateId = PBS_NORMAL; - break; - - case PE_PanelButtonTool: - if (widget && widget->inherits("QDockWidgetTitleButton")) { - if (const QWidget *dw = widget->parentWidget()) - if (dw->isWindow()) - return; - } - themeNumber = QWindowsXPStylePrivate::ToolBarTheme; - partId = TP_BUTTON; - if (!(flags & State_Enabled)) - stateId = TS_DISABLED; - else if (flags & State_Sunken) - stateId = TS_PRESSED; - else if (flags & State_MouseOver) - stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT; - else if (flags & State_On) - stateId = TS_CHECKED; - else if (!(flags & State_AutoRaise)) - stateId = TS_HOT; - else - stateId = TS_NORMAL; - break; - - case PE_IndicatorButtonDropDown: - themeNumber = QWindowsXPStylePrivate::ToolBarTheme; - partId = TP_SPLITBUTTONDROPDOWN; - if (!(flags & State_Enabled)) - stateId = TS_DISABLED; - else if (flags & State_Sunken) - stateId = TS_PRESSED; - else if (flags & State_MouseOver) - stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT; - else if (flags & State_On) - stateId = TS_CHECKED; - else if (!(flags & State_AutoRaise)) - stateId = TS_HOT; - else - stateId = TS_NORMAL; - if (option->direction == Qt::RightToLeft) - hMirrored = true; - break; - - case PE_IndicatorCheckBox: - themeNumber = QWindowsXPStylePrivate::ButtonTheme; - partId = BP_CHECKBOX; - if (!(flags & State_Enabled)) - stateId = CBS_UNCHECKEDDISABLED; - else if (flags & State_Sunken) - stateId = CBS_UNCHECKEDPRESSED; - else if (flags & State_MouseOver) - stateId = CBS_UNCHECKEDHOT; - else - stateId = CBS_UNCHECKEDNORMAL; - - if (flags & State_On) - stateId += CBS_CHECKEDNORMAL-1; - else if (flags & State_NoChange) - stateId += CBS_MIXEDNORMAL-1; - - break; - - case PE_IndicatorRadioButton: - themeNumber = QWindowsXPStylePrivate::ButtonTheme; - partId = BP_RADIOBUTTON; - if (!(flags & State_Enabled)) - stateId = RBS_UNCHECKEDDISABLED; - else if (flags & State_Sunken) - stateId = RBS_UNCHECKEDPRESSED; - else if (flags & State_MouseOver) - stateId = RBS_UNCHECKEDHOT; - else - stateId = RBS_UNCHECKEDNORMAL; - - if (flags & State_On) - stateId += RBS_CHECKEDNORMAL-1; - break; - - case PE_IndicatorDockWidgetResizeHandle: - return; - -case PE_Frame: - { - if (flags & State_Raised) - return; - themeNumber = QWindowsXPStylePrivate::ListViewTheme; - partId = LVP_LISTGROUP; - XPThemeData theme(widget, 0, themeNumber, partId, 0); - - if (!(flags & State_Enabled)) - stateId = ETS_DISABLED; - else - stateId = ETS_NORMAL; - int fillType; - if (GetThemeEnumValue(theme.handle(), partId, stateId, TMT_BGTYPE, &fillType) == S_OK) { - if (fillType == BT_BORDERFILL) { - COLORREF bcRef; - GetThemeColor(theme.handle(), partId, stateId, TMT_BORDERCOLOR, &bcRef); - QColor bordercolor(qRgb(GetRValue(bcRef), GetGValue(bcRef), GetBValue(bcRef))); - QPen oldPen = p->pen(); - // int borderSize = 1; - // GetThemeInt(theme.handle(), partId, stateId, TMT_BORDERCOLOR, &borderSize); - - // Inner white border - p->setPen(QPen(option->palette.base().color(), 1)); - p->drawRect(option->rect.adjusted(1, 1, -2, -2)); - // Outer dark border - p->setPen(QPen(bordercolor, 1)); - p->drawRect(option->rect.adjusted(0, 0, -1, -1)); - p->setPen(oldPen); - return; - } else if (fillType == BT_NONE) { - return; - } - } - break; - } - case PE_FrameLineEdit: { - // we try to check if this lineedit is a delegate on a QAbstractItemView-derived class. - if (QWindowsXPStylePrivate::isItemViewDelegateLineEdit(widget)) { - QPen oldPen = p->pen(); - // Inner white border - p->setPen(QPen(option->palette.base().color(), 1)); - p->drawRect(option->rect.adjusted(1, 1, -2, -2)); - // Outer dark border - p->setPen(QPen(option->palette.shadow().color(), 1)); - p->drawRect(option->rect.adjusted(0, 0, -1, -1)); - p->setPen(oldPen); - return; - } else if (qstyleoption_cast<const QStyleOptionFrame *>(option)) { - themeNumber = QWindowsXPStylePrivate::EditTheme; - partId = EP_EDITTEXT; - noContent = true; - if (!(flags & State_Enabled)) - stateId = ETS_DISABLED; - else - stateId = ETS_NORMAL; - } - break; - } - - case PE_PanelLineEdit: - if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) { - themeNumber = QWindowsXPStylePrivate::EditTheme; - partId = EP_EDITTEXT; - noBorder = true; - bool isEnabled = flags & State_Enabled; - - stateId = isEnabled ? ETS_NORMAL : ETS_DISABLED; - - if (QWindowsXPStylePrivate::isLineEditBaseColorSet(option, widget)) { - p->fillRect(panel->rect, panel->palette.brush(QPalette::Base)); - } else { - XPThemeData theme(0, p, themeNumber, partId, stateId, rect); - if (!theme.isValid()) { - QWindowsStyle::drawPrimitive(pe, option, p, widget); - return; - } - int bgType; - GetThemeEnumValue(theme.handle(), partId, stateId, TMT_BGTYPE, &bgType); - if( bgType == BT_IMAGEFILE ) { - theme.mirrorHorizontally = hMirrored; - theme.mirrorVertically = vMirrored; - theme.noBorder = noBorder; - theme.noContent = noContent; - theme.rotate = rotate; - d->drawBackground(theme); - } else { - QBrush fillColor = option->palette.brush(QPalette::Base); - - if (!isEnabled) { - PROPERTYORIGIN origin = PO_NOTFOUND; - GetThemePropertyOrigin(theme.handle(), theme.partId, theme.stateId, TMT_FILLCOLOR, &origin); - // Use only if the fill property comes from our part - if ((origin == PO_PART || origin == PO_STATE)) { - COLORREF bgRef; - GetThemeColor(theme.handle(), partId, stateId, TMT_FILLCOLOR, &bgRef); - fillColor = QBrush(qRgb(GetRValue(bgRef), GetGValue(bgRef), GetBValue(bgRef))); - } - } - p->fillRect(option->rect, fillColor); - } - } - - if (panel->lineWidth > 0) - proxy()->drawPrimitive(PE_FrameLineEdit, panel, p, widget); - return; - } - break; - - case PE_FrameTabWidget: - if (const QStyleOptionTabWidgetFrame *tab = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) - { - themeNumber = QWindowsXPStylePrivate::TabTheme; - partId = TABP_PANE; - - if (widget) { - bool useGradient = true; - const int maxlength = 256; - wchar_t themeFileName[maxlength]; - wchar_t themeColor[maxlength]; - // Due to a a scaling issue with the XP Silver theme, tab gradients are not used with it - if (GetCurrentThemeName(themeFileName, maxlength, themeColor, maxlength, NULL, 0) == S_OK) { - wchar_t *offset = 0; - if ((offset = wcsrchr(themeFileName, QChar(QLatin1Char('\\')).unicode())) != NULL) { - offset++; - if (!lstrcmp(offset, L"Luna.msstyles") && !lstrcmp(offset, L"Metallic")) { - useGradient = false; - } - } - } - // This should work, but currently there's an error in the ::drawBackgroundDirectly() - // code, when using the HDC directly.. - if (useGradient) { - QStyleOptionTabWidgetFrame frameOpt = *tab; - frameOpt.rect = widget->rect(); - QRect contentsRect = subElementRect(SE_TabWidgetTabContents, &frameOpt, widget); - QRegion reg = option->rect; - reg -= contentsRect; - p->setClipRegion(reg); - XPThemeData theme(widget, p, themeNumber, partId, stateId, rect); - theme.mirrorHorizontally = hMirrored; - theme.mirrorVertically = vMirrored; - d->drawBackground(theme); - p->setClipRect(contentsRect); - partId = TABP_BODY; - } - } - switch (tab->shape) { - case QTabBar::RoundedNorth: - case QTabBar::TriangularNorth: - break; - case QTabBar::RoundedSouth: - case QTabBar::TriangularSouth: - vMirrored = true; - break; - case QTabBar::RoundedEast: - case QTabBar::TriangularEast: - rotate = 90; - break; - case QTabBar::RoundedWest: - case QTabBar::TriangularWest: - rotate = 90; - hMirrored = true; - break; - default: - break; - } - } - break; - - case PE_FrameMenu: - p->save(); - p->setPen(option->palette.dark().color()); - p->drawRect(rect.adjusted(0, 0, -1, -1)); - p->restore(); - return; - - case PE_PanelMenuBar: - break; - - case PE_FrameDockWidget: - if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(option)) - { - themeNumber = QWindowsXPStylePrivate::WindowTheme; - if (flags & State_Active) - stateId = FS_ACTIVE; - else - stateId = FS_INACTIVE; - - int fwidth = proxy()->pixelMetric(PM_DockWidgetFrameWidth, frm, widget); - - XPThemeData theme(widget, p, themeNumber, 0, stateId); - if (!theme.isValid()) - break; - theme.rect = QRect(frm->rect.x(), frm->rect.y(), frm->rect.x()+fwidth, frm->rect.height()-fwidth); theme.partId = WP_SMALLFRAMELEFT; - d->drawBackground(theme); - theme.rect = QRect(frm->rect.width()-fwidth, frm->rect.y(), fwidth, frm->rect.height()-fwidth); - theme.partId = WP_SMALLFRAMERIGHT; - d->drawBackground(theme); - theme.rect = QRect(frm->rect.x(), frm->rect.bottom()-fwidth+1, frm->rect.width(), fwidth); - theme.partId = WP_SMALLFRAMEBOTTOM; - d->drawBackground(theme); - return; - } - break; - - case PE_IndicatorHeaderArrow: - { -#if 0 // XP theme engine doesn't know about this :( - name = QWindowsXPStylePrivate::HeaderTheme; - partId = HP_HEADERSORTARROW; - if (flags & State_Down) - stateId = HSAS_SORTEDDOWN; - else - stateId = HSAS_SORTEDUP; -#else - if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) { - p->save(); - p->setPen(option->palette.dark().color()); - p->translate(0, option->rect.height()/2 - 4); - if (header->sortIndicator & QStyleOptionHeader::SortUp) { // invert logic to follow Windows style guide - p->drawLine(option->rect.x(), option->rect.y(), option->rect.x()+8, option->rect.y()); - p->drawLine(option->rect.x()+1, option->rect.y()+1, option->rect.x()+7, option->rect.y()+1); - p->drawLine(option->rect.x()+2, option->rect.y()+2, option->rect.x()+6, option->rect.y()+2); - p->drawLine(option->rect.x()+3, option->rect.y()+3, option->rect.x()+5, option->rect.y()+3); - p->drawPoint(option->rect.x()+4, option->rect.y()+4); - } else if(header->sortIndicator & QStyleOptionHeader::SortDown) { - p->drawLine(option->rect.x(), option->rect.y()+4, option->rect.x()+8, option->rect.y()+4); - p->drawLine(option->rect.x()+1, option->rect.y()+3, option->rect.x()+7, option->rect.y()+3); - p->drawLine(option->rect.x()+2, option->rect.y()+2, option->rect.x()+6, option->rect.y()+2); - p->drawLine(option->rect.x()+3, option->rect.y()+1, option->rect.x()+5, option->rect.y()+1); - p->drawPoint(option->rect.x()+4, option->rect.y()); - } - p->restore(); - return; - } -#endif - } - break; - - case PE_FrameStatusBarItem: - themeNumber = QWindowsXPStylePrivate::StatusTheme; - partId = SP_PANE; - break; - - case PE_FrameGroupBox: - themeNumber = QWindowsXPStylePrivate::ButtonTheme; - partId = BP_GROUPBOX; - if (!(flags & State_Enabled)) - stateId = GBS_DISABLED; - else - stateId = GBS_NORMAL; - if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(option)) { - if (frame->features & QStyleOptionFrame::Flat) { - // Windows XP does not have a theme part for a flat GroupBox, paint it with the windows style - QRect fr = frame->rect; - QPoint p1(fr.x(), fr.y() + 1); - QPoint p2(fr.x() + fr.width(), p1.y() + 1); - rect = QRect(p1, p2); - themeNumber = -1; - } - } - break; - - case PE_IndicatorProgressChunk: - { - Qt::Orientation orient = Qt::Horizontal; - bool inverted = false; - if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) { - orient = pb->orientation; - inverted = pb->invertedAppearance; - } - if (orient == Qt::Horizontal) { - partId = PP_CHUNK; - rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.height() ); - if (inverted && option->direction == Qt::LeftToRight) - hMirrored = true; - } else { - partId = PP_CHUNKVERT; - rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.height()); - } - themeNumber = QWindowsXPStylePrivate::ProgressTheme; - stateId = 1; - } - break; - - case PE_FrameWindow: - if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(option)) - { - themeNumber = QWindowsXPStylePrivate::WindowTheme; - if (flags & State_Active) - stateId = FS_ACTIVE; - else - stateId = FS_INACTIVE; - - int fwidth = frm->lineWidth + frm->midLineWidth; - - XPThemeData theme(0, p, themeNumber, 0, stateId); - if (!theme.isValid()) - break; - - // May fail due to too-large buffers for large widgets, fall back to Windows style. - theme.rect = QRect(option->rect.x(), option->rect.y()+fwidth, option->rect.x()+fwidth, option->rect.height()-fwidth); - theme.partId = WP_FRAMELEFT; - if (!d->drawBackground(theme)) { - QWindowsStyle::drawPrimitive(pe, option, p, widget); - return; - } - theme.rect = QRect(option->rect.width()-fwidth, option->rect.y()+fwidth, fwidth, option->rect.height()-fwidth); - theme.partId = WP_FRAMERIGHT; - if (!d->drawBackground(theme)) { - QWindowsStyle::drawPrimitive(pe, option, p, widget); - return; - } - theme.rect = QRect(option->rect.x(), option->rect.height()-fwidth, option->rect.width(), fwidth); - theme.partId = WP_FRAMEBOTTOM; - if (!d->drawBackground(theme)) { - QWindowsStyle::drawPrimitive(pe, option, p, widget); - return; - } - theme.rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.y()+fwidth); - theme.partId = WP_CAPTION; - if (!d->drawBackground(theme)) - QWindowsStyle::drawPrimitive(pe, option, p, widget); - return; - } - break; - - case PE_IndicatorBranch: - { - static const int decoration_size = 9; - int mid_h = option->rect.x() + option->rect.width() / 2; - int mid_v = option->rect.y() + option->rect.height() / 2; - int bef_h = mid_h; - int bef_v = mid_v; - int aft_h = mid_h; - int aft_v = mid_v; - QBrush brush(option->palette.dark().color(), Qt::Dense4Pattern); - if (option->state & State_Item) { - if (option->direction == Qt::RightToLeft) - p->fillRect(option->rect.left(), mid_v, bef_h - option->rect.left(), 1, brush); - else - p->fillRect(aft_h, mid_v, option->rect.right() - aft_h + 1, 1, brush); - } - if (option->state & State_Sibling) - p->fillRect(mid_h, aft_v, 1, option->rect.bottom() - aft_v + 1, brush); - if (option->state & (State_Open | State_Children | State_Item | State_Sibling)) - p->fillRect(mid_h, option->rect.y(), 1, bef_v - option->rect.y(), brush); - if (option->state & State_Children) { - int delta = decoration_size / 2; - bef_h -= delta; - bef_v -= delta; - aft_h += delta; - aft_v += delta; - XPThemeData theme(0, p, QWindowsXPStylePrivate::XpTreeViewTheme); - theme.rect = QRect(bef_h, bef_v, decoration_size, decoration_size); - theme.partId = TVP_GLYPH; - theme.stateId = flags & QStyle::State_Open ? GLPS_OPENED : GLPS_CLOSED; - d->drawBackground(theme); - } - } - return; - - case PE_IndicatorToolBarSeparator: - if (option->rect.height() < 3) { - // XP style requires a few pixels for the separator - // to be visible. - QWindowsStyle::drawPrimitive(pe, option, p, widget); - return; - } - themeNumber = QWindowsXPStylePrivate::ToolBarTheme; - partId = TP_SEPARATOR; - - if (option->state & State_Horizontal) - partId = TP_SEPARATOR; - else - partId = TP_SEPARATORVERT; - - break; - - case PE_IndicatorToolBarHandle: - - themeNumber = QWindowsXPStylePrivate::RebarTheme; - partId = RP_GRIPPER; - if (option->state & State_Horizontal) { - partId = RP_GRIPPER; - rect.adjust(0, 0, -2, 0); - } - else { - partId = RP_GRIPPERVERT; - rect.adjust(0, 0, 0, -2); - } - break; - - case PE_IndicatorItemViewItemCheck: { - QStyleOptionButton button; - button.QStyleOption::operator=(*option); - button.state &= ~State_MouseOver; - proxy()->drawPrimitive(PE_IndicatorCheckBox, &button, p, widget); - return; - } - - default: - break; - } - - XPThemeData theme(widget, p, themeNumber, partId, stateId, rect); - if (!theme.isValid()) { - QWindowsStyle::drawPrimitive(pe, option, p, widget); - return; - } - theme.mirrorHorizontally = hMirrored; - theme.mirrorVertically = vMirrored; - theme.noBorder = noBorder; - theme.noContent = noContent; - theme.rotate = rotate; - d->drawBackground(theme); -} - -/*! - \reimp -*/ -void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *p, - const QWidget *widget) const -{ - QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func()); - if (!QWindowsXPStylePrivate::useXP()) { - QWindowsStyle::drawControl(element, option, p, widget); - return; - } - - QRect rect(option->rect); - State flags = option->state; - - int rotate = 0; - bool hMirrored = false; - bool vMirrored = false; - - int themeNumber = -1; - int partId = 0; - int stateId = 0; - switch (element) { - case CE_SizeGrip: - { - themeNumber = QWindowsXPStylePrivate::StatusTheme; - partId = SP_GRIPPER; - XPThemeData theme(0, p, themeNumber, partId, 0); - QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); - size.rheight()--; - if (const QStyleOptionSizeGrip *sg = qstyleoption_cast<const QStyleOptionSizeGrip *>(option)) { - switch (sg->corner) { - case Qt::BottomRightCorner: - rect = QRect(QPoint(rect.right() - size.width(), rect.bottom() - size.height()), size); - break; - case Qt::BottomLeftCorner: - rect = QRect(QPoint(rect.left() + 1, rect.bottom() - size.height()), size); - hMirrored = true; - break; - case Qt::TopRightCorner: - rect = QRect(QPoint(rect.right() - size.width(), rect.top() + 1), size); - vMirrored = true; - break; - case Qt::TopLeftCorner: - rect = QRect(rect.topLeft() + QPoint(1, 1), size); - hMirrored = vMirrored = true; - } - } - } - break; - - case CE_HeaderSection: - themeNumber = QWindowsXPStylePrivate::HeaderTheme; - partId = HP_HEADERITEM; - if (flags & State_Sunken) - stateId = HIS_PRESSED; - else if (flags & State_MouseOver) - stateId = HIS_HOT; - else - stateId = HIS_NORMAL; - break; - - case CE_Splitter: - p->eraseRect(option->rect); - return; - - case CE_PushButtonBevel: - if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) - { - themeNumber = QWindowsXPStylePrivate::ButtonTheme; - partId = BP_PUSHBUTTON; - bool justFlat = ((btn->features & QStyleOptionButton::Flat) && !(flags & (State_On|State_Sunken))) - || ((btn->features & QStyleOptionButton::CommandLinkButton) - && !(flags & State_MouseOver) - && !(btn->features & QStyleOptionButton::DefaultButton)); - if (!(flags & State_Enabled) && !(btn->features & QStyleOptionButton::Flat)) - stateId = PBS_DISABLED; - else if (justFlat) - ; - else if (flags & (State_Sunken | State_On)) - stateId = PBS_PRESSED; - else if (flags & State_MouseOver) - stateId = PBS_HOT; - else if (btn->features & QStyleOptionButton::DefaultButton) - stateId = PBS_DEFAULTED; - else - stateId = PBS_NORMAL; - - if (!justFlat) { - XPThemeData theme(widget, p, themeNumber, partId, stateId, rect); - d->drawBackground(theme); - } - - if (btn->features & QStyleOptionButton::HasMenu) { - int mbiw = 0, mbih = 0; - XPThemeData theme(widget, 0, - QWindowsXPStylePrivate::ToolBarTheme, - TP_SPLITBUTTONDROPDOWN); - if (theme.isValid()) { - const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); - mbiw = size.width(); - mbih = size.height(); - } - - QRect ir = btn->rect; - QStyleOptionButton newBtn = *btn; - newBtn.rect = QRect(ir.right() - mbiw - 1, 1 + (ir.height()/2) - (mbih/2), mbiw, mbih); - proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget); - } - return; - } - break; - case CE_TabBarTab: - if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) - { - stateId = tab->state & State_Enabled ? TIS_NORMAL : TIS_DISABLED; - } - break; - - case CE_TabBarTabShape: - if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) - { - themeNumber = QWindowsXPStylePrivate::TabTheme; - bool isDisabled = !(tab->state & State_Enabled); - bool hasFocus = tab->state & State_HasFocus; - bool isHot = tab->state & State_MouseOver; - bool selected = tab->state & State_Selected; - bool lastTab = tab->position == QStyleOptionTab::End; - bool firstTab = tab->position == QStyleOptionTab::Beginning; - bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab; - bool leftAligned = proxy()->styleHint(SH_TabBar_Alignment, tab, widget) == Qt::AlignLeft; - bool centerAligned = proxy()->styleHint(SH_TabBar_Alignment, tab, widget) == Qt::AlignCenter; - int borderThickness = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget); - int tabOverlap = proxy()->pixelMetric(PM_TabBarTabOverlap, option, widget); - - if (isDisabled) - stateId = TIS_DISABLED; - else if (selected) - stateId = TIS_SELECTED; - else if (hasFocus) - stateId = TIS_FOCUSED; - else if (isHot) - stateId = TIS_HOT; - else - stateId = TIS_NORMAL; - - // Selecting proper part depending on position - if (firstTab || onlyOne) { - if (leftAligned) { - partId = TABP_TABITEMLEFTEDGE; - } else if (centerAligned) { - partId = TABP_TABITEM; - } else { // rightAligned - partId = TABP_TABITEMRIGHTEDGE; - } - } else { - partId = TABP_TABITEM; - } - - if (tab->direction == Qt::RightToLeft - && (tab->shape == QTabBar::RoundedNorth - || tab->shape == QTabBar::RoundedSouth)) { - bool temp = firstTab; - firstTab = lastTab; - lastTab = temp; - } - bool begin = firstTab || onlyOne; - bool end = lastTab || onlyOne; - switch (tab->shape) { - case QTabBar::RoundedNorth: - if (selected) - rect.adjust(begin ? 0 : -tabOverlap, 0, end ? 0 : tabOverlap, borderThickness); - else - rect.adjust(begin? tabOverlap : 0, tabOverlap, end ? -tabOverlap : 0, 0); - break; - case QTabBar::RoundedSouth: - //vMirrored = true; - rotate = 180; // Not 100% correct, but works - if (selected) - rect.adjust(begin ? 0 : -tabOverlap , -borderThickness, end ? 0 : tabOverlap, 0); - else - rect.adjust(begin ? tabOverlap : 0, 0, end ? -tabOverlap : 0 , -tabOverlap); - break; - case QTabBar::RoundedEast: - rotate = 90; - if (selected) { - rect.adjust(-borderThickness, begin ? 0 : -tabOverlap, 0, end ? 0 : tabOverlap); - }else{ - rect.adjust(0, begin ? tabOverlap : 0, -tabOverlap, end ? -tabOverlap : 0); - } - break; - case QTabBar::RoundedWest: - hMirrored = true; - rotate = 90; - if (selected) { - rect.adjust(0, begin ? 0 : -tabOverlap, borderThickness, end ? 0 : tabOverlap); - }else{ - rect.adjust(tabOverlap, begin ? tabOverlap : 0, 0, end ? -tabOverlap : 0); - } - break; - default: - themeNumber = -1; // Do our own painting for triangular - break; - } - - if (!selected) { - switch (tab->shape) { - case QTabBar::RoundedNorth: - rect.adjust(0,0, 0,-1); - break; - case QTabBar::RoundedSouth: - rect.adjust(0,1, 0,0); - break; - case QTabBar::RoundedEast: - rect.adjust( 1,0, 0,0); - break; - case QTabBar::RoundedWest: - rect.adjust(0,0, -1,0); - break; - default: - break; - } - } - } - break; - - case CE_ProgressBarGroove: - { - Qt::Orientation orient = Qt::Horizontal; - if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) - orient = pb->orientation; - partId = (orient == Qt::Horizontal) ? PP_BAR : PP_BARVERT; - themeNumber = QWindowsXPStylePrivate::ProgressTheme; - stateId = 1; - } - break; - - case CE_MenuEmptyArea: - case CE_MenuItem: - if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) - { - int tab = menuitem->tabWidth; - bool dis = !(menuitem->state & State_Enabled); - bool act = menuitem->state & State_Selected; - bool checkable = menuitem->menuHasCheckableItems; - bool checked = checkable ? menuitem->checked : false; - - // windows always has a check column, regardless whether we have an icon or not - int checkcol = qMax(menuitem->maxIconWidth, 12); - - int x, y, w, h; - rect.getRect(&x, &y, &w, &h); - - QBrush fill = menuitem->palette.brush(act ? QPalette::Highlight : QPalette::Button); - p->fillRect(rect, fill); - - if (element == CE_MenuEmptyArea) - break; - - // draw separator ------------------------------------------------- - if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) { - int yoff = y-1 + h / 2; - p->setPen(menuitem->palette.dark().color()); - p->drawLine(x, yoff, x+w, yoff); - ++yoff; - p->setPen(menuitem->palette.light().color()); - p->drawLine(x, yoff, x+w, yoff); - return; - } - - int xpos = x; - - // draw icon ------------------------------------------------------ - if (!menuitem->icon.isNull()) { - QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal; - if (act && !dis) - mode = QIcon::Active; - QPixmap pixmap = checked ? - menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode, QIcon::On) : - menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode); - const int pixw = pixmap.width() / pixmap.devicePixelRatio(); - const int pixh = pixmap.height() / pixmap.devicePixelRatio(); - QRect iconRect(0, 0, pixw, pixh); - iconRect.moveCenter(QRect(xpos, y, checkcol, h).center()); - QRect vIconRect = visualRect(option->direction, option->rect, iconRect); - p->setPen(menuitem->palette.text().color()); - p->setBrush(Qt::NoBrush); - if (checked) - p->drawRect(vIconRect.adjusted(-1, -1, 0, 0)); - p->drawPixmap(vIconRect.topLeft(), pixmap); - - // draw checkmark ------------------------------------------------- - } else if (checked) { - QStyleOptionMenuItem newMi = *menuitem; - newMi.state = State_None; - if (!dis) - newMi.state |= State_Enabled; - if (act) - newMi.state |= State_On; - - QRect checkMarkRect = QRect(menuitem->rect.x() + windowsItemFrame, - menuitem->rect.y() + windowsItemFrame, - checkcol - 2 * windowsItemFrame, - menuitem->rect.height() - 2*windowsItemFrame); - newMi.rect = visualRect(option->direction, option->rect, checkMarkRect); - proxy()->drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, widget); - } - - QColor textColor = dis ? menuitem->palette.text().color() : - act ? menuitem->palette.highlightedText().color() : menuitem->palette.buttonText().color(); - p->setPen(textColor); - - // draw text ------------------------------------------------------ - int xm = windowsItemFrame + checkcol + windowsItemHMargin; - xpos = menuitem->rect.x() + xm; - QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin); - QRect vTextRect = visualRect(option->direction, option->rect, textRect); - QString s = menuitem->text; - if (!s.isEmpty()) { - p->save(); - int t = s.indexOf(QLatin1Char('\t')); - int text_flags = Qt::AlignVCenter|Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine | Qt::AlignLeft; - if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget)) - text_flags |= Qt::TextHideMnemonic; - // draw tab text ---------------- - if (t >= 0) { - QRect vShortcutRect = visualRect(option->direction, option->rect, QRect(textRect.topRight(), menuitem->rect.bottomRight())); - if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) { - p->setPen(menuitem->palette.light().color()); - p->drawText(vShortcutRect.adjusted(1,1,1,1), text_flags, s.mid(t + 1)); - p->setPen(textColor); - } - p->drawText(vShortcutRect, text_flags, s.mid(t + 1)); - s = s.left(t); - } - QFont font = menuitem->font; - if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem) - font.setBold(true); - p->setFont(font); - if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) { - p->setPen(menuitem->palette.light().color()); - p->drawText(vTextRect.adjusted(1,1,1,1), text_flags, s.left(t)); - p->setPen(textColor); - } - p->drawText(vTextRect, text_flags, s); - p->restore(); - } - - // draw sub menu arrow -------------------------------------------- - if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) { - int dim = (h - 2) / 2; - PrimitiveElement arrow; - arrow = (option->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight; - xpos = x + w - windowsArrowHMargin - windowsItemFrame - dim; - QRect vSubMenuRect = visualRect(option->direction, option->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim)); - QStyleOptionMenuItem newMI = *menuitem; - newMI.rect = vSubMenuRect; - newMI.state = dis ? State_None : State_Enabled; - if (act) - newMI.palette.setColor(QPalette::ButtonText, newMI.palette.highlightedText().color()); - proxy()->drawPrimitive(arrow, &newMI, p, widget); - } - } - return; - - case CE_MenuBarItem: - if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) - { - if (mbi->menuItemType == QStyleOptionMenuItem::DefaultItem) - break; - - bool act = mbi->state & State_Selected; - bool dis = !(mbi->state & State_Enabled); - - QBrush fill = mbi->palette.brush(act ? QPalette::Highlight : QPalette::Button); - QPalette::ColorRole textRole = dis ? QPalette::Text: - act ? QPalette::HighlightedText : QPalette::ButtonText; - QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), QIcon::Normal); - - uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine; - if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget)) - alignment |= Qt::TextHideMnemonic; - - p->fillRect(rect, fill); - if (!pix.isNull()) - drawItemPixmap(p, mbi->rect, alignment, pix); - else - drawItemText(p, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole); - } - return; -#if QT_CONFIG(dockwidget) - case CE_DockWidgetTitle: - if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) - { - int buttonMargin = 4; - int mw = proxy()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, dwOpt, widget); - int fw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, dwOpt, widget); - bool isFloating = widget && widget->isWindow(); - bool isActive = dwOpt->state & State_Active; - - const bool verticalTitleBar = dwOpt->verticalTitleBar; - - if (verticalTitleBar) { - rect = rect.transposed(); - - p->translate(rect.left() - 1, rect.top() + rect.width()); - p->rotate(-90); - p->translate(-rect.left() + 1, -rect.top()); - } - QRect r = rect.adjusted(0, 2, -1, -3); - QRect titleRect = r; - - if (dwOpt->closable) { - QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarCloseButton, dwOpt, widget).actualSize(QSize(10, 10)); - titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0); - } - - if (dwOpt->floatable) { - QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarMaxButton, dwOpt, widget).actualSize(QSize(10, 10)); - titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0); - } - - if (isFloating) { - titleRect.adjust(0, -fw, 0, 0); - if (widget != 0 && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey()) - titleRect.adjust(titleRect.height() + mw, 0, 0, 0); - } else { - titleRect.adjust(mw, 0, 0, 0); - if (!dwOpt->floatable && !dwOpt->closable) - titleRect.adjust(0, 0, -mw, 0); - } - - if (!verticalTitleBar) - titleRect = visualRect(dwOpt->direction, r, titleRect); - - if (!isFloating) { - QPen oldPen = p->pen(); - QString titleText = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width()); - p->setPen(dwOpt->palette.color(QPalette::Dark)); - p->drawRect(r); - - if (!titleText.isEmpty()) { - drawItemText(p, titleRect, - Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, dwOpt->palette, - dwOpt->state & State_Enabled, titleText, - QPalette::WindowText); - } - - p->setPen(oldPen); - } else { - themeNumber = QWindowsXPStylePrivate::WindowTheme; - if (isActive) - stateId = CS_ACTIVE; - else - stateId = CS_INACTIVE; - - int titleHeight = rect.height() - 2; - rect = rect.adjusted(-fw, -fw, fw, 0); - - XPThemeData theme(widget, p, themeNumber, 0, stateId); - if (!theme.isValid()) - break; - - // Draw small type title bar - theme.rect = rect; - theme.partId = WP_SMALLCAPTION; - d->drawBackground(theme); - - // Figure out maximal button space on title bar - - QIcon ico = widget->windowIcon(); - bool hasIcon = (ico.cacheKey() != QApplication::windowIcon().cacheKey()); - if (hasIcon) { - QPixmap pxIco = ico.pixmap(titleHeight); - if (!verticalTitleBar && dwOpt->direction == Qt::RightToLeft) - p->drawPixmap(rect.width() - titleHeight - pxIco.width(), rect.bottom() - titleHeight - 2, pxIco); - else - p->drawPixmap(fw, rect.bottom() - titleHeight - 2, pxIco); - } - if (!dwOpt->title.isEmpty()) { - QPen oldPen = p->pen(); - QFont oldFont = p->font(); - QFont titleFont = oldFont; - titleFont.setBold(true); - p->setFont(titleFont); - QString titleText - = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width()); - - int result = TST_NONE; - GetThemeEnumValue(theme.handle(), WP_SMALLCAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWTYPE, &result); - if (result != TST_NONE) { - COLORREF textShadowRef; - GetThemeColor(theme.handle(), WP_SMALLCAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWCOLOR, &textShadowRef); - QColor textShadow = qRgb(GetRValue(textShadowRef), GetGValue(textShadowRef), GetBValue(textShadowRef)); - p->setPen(textShadow); - drawItemText(p, titleRect.adjusted(1, 1, 1, 1), - Qt::AlignLeft | Qt::AlignBottom, dwOpt->palette, - dwOpt->state & State_Enabled, titleText); - } - - COLORREF captionText = GetSysColor(isActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT); - QColor textColor = qRgb(GetRValue(captionText), GetGValue(captionText), GetBValue(captionText)); - p->setPen(textColor); - drawItemText(p, titleRect, - Qt::AlignLeft | Qt::AlignBottom, dwOpt->palette, - dwOpt->state & State_Enabled, titleText); - p->setFont(oldFont); - p->setPen(oldPen); - } - - } - - return; - } - break; -#endif // QT_CONFIG(dockwidget) -#if QT_CONFIG(rubberband) - case CE_RubberBand: - if (qstyleoption_cast<const QStyleOptionRubberBand *>(option)) { - QColor highlight = option->palette.color(QPalette::Active, QPalette::Highlight); - p->save(); - p->setPen(highlight.darker(120)); - QColor dimHighlight(qMin(highlight.red()/2 + 110, 255), - qMin(highlight.green()/2 + 110, 255), - qMin(highlight.blue()/2 + 110, 255), - (widget && widget->isTopLevel())? 255 : 127); - p->setBrush(dimHighlight); - p->drawRect(option->rect.adjusted(0, 0, -1, -1)); - p->restore(); - return; - } - break; -#endif // QT_CONFIG(rubberband) - case CE_HeaderEmptyArea: - if (option->state & State_Horizontal) - { - themeNumber = QWindowsXPStylePrivate::HeaderTheme; - stateId = HIS_NORMAL; - } - else { - QWindowsStyle::drawControl(CE_HeaderEmptyArea, option, p, widget); - return; - } - break; - default: - break; - } - - XPThemeData theme(widget, p, themeNumber, partId, stateId, rect); - if (!theme.isValid()) { - QWindowsStyle::drawControl(element, option, p, widget); - return; - } - - theme.rotate = rotate; - theme.mirrorHorizontally = hMirrored; - theme.mirrorVertically = vMirrored; - d->drawBackground(theme); -} - -QRect QWindowsXPStylePrivate::scrollBarGripperBounds(QStyle::State flags, const QWidget *widget, XPThemeData *theme) -{ - const bool horizontal = flags & QStyle::State_Horizontal; - const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(widget); - const QMargins contentsMargin = - (theme->margins(theme->rect, TMT_SIZINGMARGINS) * factor).toMargins(); - theme->partId = horizontal ? SBP_GRIPPERHORZ : SBP_GRIPPERVERT; - const QSize size = (theme->size() * factor).toSize(); - - const int hSpace = theme->rect.width() - size.width(); - const int vSpace = theme->rect.height() - size.height(); - const bool sufficientSpace = (horizontal && hSpace > (contentsMargin.left() + contentsMargin.right())) - || vSpace > contentsMargin.top() + contentsMargin.bottom(); - return sufficientSpace ? QRect(theme->rect.topLeft() + QPoint(hSpace, vSpace) / 2, size) : QRect(); -} - -/*! - \reimp -*/ -void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option, - QPainter *p, const QWidget *widget) const -{ - QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func()); - - if (!QWindowsXPStylePrivate::useXP()) { - QWindowsStyle::drawComplexControl(cc, option, p, widget); - return; - } - - State flags = option->state; - SubControls sub = option->subControls; - QRect r = option->rect; - - int partId = 0; - int stateId = 0; - if (widget && widget->testAttribute(Qt::WA_UnderMouse) && widget->isActiveWindow()) - flags |= State_MouseOver; - - switch (cc) { -#if QT_CONFIG(spinbox) - case CC_SpinBox: - if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) - { - XPThemeData theme(widget, p, QWindowsXPStylePrivate::SpinTheme); - - if (sb->frame && (sub & SC_SpinBoxFrame)) { - partId = EP_EDITTEXT; - if (!(flags & State_Enabled)) - stateId = ETS_DISABLED; - else if (flags & State_HasFocus) - stateId = ETS_FOCUSED; - else - stateId = ETS_NORMAL; - - XPThemeData ftheme(widget, p, QWindowsXPStylePrivate::EditTheme, - partId, stateId, r); - ftheme.noContent = true; - d->drawBackground(ftheme); - } - if (sub & SC_SpinBoxUp) { - theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget); - partId = SPNP_UP; - if (!(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled) || !(flags & State_Enabled)) - stateId = UPS_DISABLED; - else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken)) - stateId = UPS_PRESSED; - else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_MouseOver)) - stateId = UPS_HOT; - else - stateId = UPS_NORMAL; - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } - if (sub & SC_SpinBoxDown) { - theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget); - partId = SPNP_DOWN; - if (!(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled) || !(flags & State_Enabled)) - stateId = DNS_DISABLED; - else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken)) - stateId = DNS_PRESSED; - else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_MouseOver)) - stateId = DNS_HOT; - else - stateId = DNS_NORMAL; - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } - } - break; -#endif // QT_CONFIG(spinbox) -#if QT_CONFIG(combobox) - case CC_ComboBox: - if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) - { - if (sub & SC_ComboBoxEditField) { - if (cmb->frame) { - partId = EP_EDITTEXT; - if (!(flags & State_Enabled)) - stateId = ETS_DISABLED; - else if (flags & State_HasFocus) - stateId = ETS_FOCUSED; - else - stateId = ETS_NORMAL; - XPThemeData theme(widget, p, QWindowsXPStylePrivate::EditTheme, partId, stateId, r); - d->drawBackground(theme); - } else { - QBrush editBrush = cmb->palette.brush(QPalette::Base); - p->fillRect(option->rect, editBrush); - } - if (!cmb->editable) { - QRect re = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxEditField, widget); - if (option->state & State_HasFocus) { - p->fillRect(re, option->palette.highlight()); - p->setPen(option->palette.highlightedText().color()); - p->setBackground(option->palette.highlight()); - } else { - p->fillRect(re, option->palette.base()); - p->setPen(option->palette.text().color()); - p->setBackground(option->palette.base()); - } - } - } - - if (sub & SC_ComboBoxArrow) { - XPThemeData theme(widget, p, QWindowsXPStylePrivate::ComboboxTheme); - theme.rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget); - partId = CP_DROPDOWNBUTTON; - if (!(flags & State_Enabled)) - stateId = CBXS_DISABLED; - else if (cmb->activeSubControls == SC_ComboBoxArrow && (cmb->state & State_Sunken)) - stateId = CBXS_PRESSED; - else if (cmb->activeSubControls == SC_ComboBoxArrow && (cmb->state & State_MouseOver)) - stateId = CBXS_HOT; - else - stateId = CBXS_NORMAL; - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } - } - break; -#endif // QT_CONFIG(combobox) - case CC_ScrollBar: - if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option)) - { - XPThemeData theme(widget, p, QWindowsXPStylePrivate::ScrollBarTheme); - bool maxedOut = (scrollbar->maximum == scrollbar->minimum); - if (maxedOut) - flags &= ~State_Enabled; - - bool isHorz = flags & State_Horizontal; - bool isRTL = option->direction == Qt::RightToLeft; - if (sub & SC_ScrollBarAddLine) { - theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddLine, widget); - partId = SBP_ARROWBTN; - if (!(flags & State_Enabled)) - stateId = (isHorz ? (isRTL ? ABS_LEFTDISABLED : ABS_RIGHTDISABLED) : ABS_DOWNDISABLED); - else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_Sunken)) - stateId = (isHorz ? (isRTL ? ABS_LEFTPRESSED : ABS_RIGHTPRESSED) : ABS_DOWNPRESSED); - else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_MouseOver)) - stateId = (isHorz ? (isRTL ? ABS_LEFTHOT : ABS_RIGHTHOT) : ABS_DOWNHOT); - else - stateId = (isHorz ? (isRTL ? ABS_LEFTNORMAL : ABS_RIGHTNORMAL) : ABS_DOWNNORMAL); - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } - if (sub & SC_ScrollBarSubLine) { - theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubLine, widget); - partId = SBP_ARROWBTN; - if (!(flags & State_Enabled)) - stateId = (isHorz ? (isRTL ? ABS_RIGHTDISABLED : ABS_LEFTDISABLED) : ABS_UPDISABLED); - else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_Sunken)) - stateId = (isHorz ? (isRTL ? ABS_RIGHTPRESSED : ABS_LEFTPRESSED) : ABS_UPPRESSED); - else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_MouseOver)) - stateId = (isHorz ? (isRTL ? ABS_RIGHTHOT : ABS_LEFTHOT) : ABS_UPHOT); - else - stateId = (isHorz ? (isRTL ? ABS_RIGHTNORMAL : ABS_LEFTNORMAL) : ABS_UPNORMAL); - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } - if (maxedOut) { - theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget); - theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget)); - theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget)); - partId = scrollbar->orientation == Qt::Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT; - stateId = SCRBS_DISABLED; - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } else { - if (sub & SC_ScrollBarSubPage) { - theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget); - partId = flags & State_Horizontal ? SBP_UPPERTRACKHORZ : SBP_UPPERTRACKVERT; - if (!(flags & State_Enabled)) - stateId = SCRBS_DISABLED; - else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_Sunken)) - stateId = SCRBS_PRESSED; - else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_MouseOver)) - stateId = SCRBS_HOT; - else - stateId = SCRBS_NORMAL; - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } - if (sub & SC_ScrollBarAddPage) { - theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget); - partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT; - if (!(flags & State_Enabled)) - stateId = SCRBS_DISABLED; - else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_Sunken)) - stateId = SCRBS_PRESSED; - else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_MouseOver)) - stateId = SCRBS_HOT; - else - stateId = SCRBS_NORMAL; - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } - if (sub & SC_ScrollBarSlider) { - theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget); - if (!(flags & State_Enabled)) - stateId = SCRBS_DISABLED; - else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_Sunken)) - stateId = SCRBS_PRESSED; - else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_MouseOver)) - stateId = SCRBS_HOT; - else - stateId = SCRBS_NORMAL; - - // Draw handle - theme.partId = flags & State_Horizontal ? SBP_THUMBBTNHORZ : SBP_THUMBBTNVERT; - theme.stateId = stateId; - d->drawBackground(theme); - - const QRect gripperBounds = QWindowsXPStylePrivate::scrollBarGripperBounds(flags, widget, &theme); - // Draw gripper if there is enough space - if (!gripperBounds.isEmpty()) { - p->save(); - theme.rect = gripperBounds; - p->setClipRegion(d->region(theme));// Only change inside the region of the gripper - d->drawBackground(theme); // Transparent gripper ontop of background - p->restore(); - } - } - } - } - break; - -#if QT_CONFIG(slider) - case CC_Slider: - if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) - { - XPThemeData theme(widget, p, QWindowsXPStylePrivate::TrackBarTheme); - QRect slrect = slider->rect; - QRegion tickreg = slrect; - if (sub & SC_SliderGroove) { - theme.rect = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget); - if (slider->orientation == Qt::Horizontal) { - partId = TKP_TRACK; - stateId = TRS_NORMAL; - theme.rect = QRect(slrect.left(), theme.rect.center().y() - 2, slrect.width(), 4); - } else { - partId = TKP_TRACKVERT; - stateId = TRVS_NORMAL; - theme.rect = QRect(theme.rect.center().x() - 2, slrect.top(), 4, slrect.height()); - } - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - tickreg -= theme.rect; - } - if (sub & SC_SliderTickmarks) { - int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider, widget); - int ticks = slider->tickPosition; - int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget); - int len = proxy()->pixelMetric(PM_SliderLength, slider, widget); - int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider, widget); - int interval = slider->tickInterval; - if (interval <= 0) { - interval = slider->singleStep; - if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval, - available) - - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, - 0, available) < 3) - interval = slider->pageStep; - } - if (!interval) - interval = 1; - int fudge = len / 2; - int pos; - int bothOffset = (ticks & QSlider::TicksAbove && ticks & QSlider::TicksBelow) ? 1 : 0; - p->setPen(d->sliderTickColor); - QVarLengthArray<QLine, 32> lines; - int v = slider->minimum; - while (v <= slider->maximum + 1) { - if (v == slider->maximum + 1 && interval == 1) - break; - const int v_ = qMin(v, slider->maximum); - int tickLength = (v_ == slider->minimum || v_ >= slider->maximum) ? 4 : 3; - pos = QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, - v_, available) + fudge; - if (slider->orientation == Qt::Horizontal) { - if (ticks & QSlider::TicksAbove) - lines.append(QLine(pos, tickOffset - 1 - bothOffset, - pos, tickOffset - 1 - bothOffset - tickLength)); - - if (ticks & QSlider::TicksBelow) - lines.append(QLine(pos, tickOffset + thickness + bothOffset, - pos, tickOffset + thickness + bothOffset + tickLength)); - } else { - if (ticks & QSlider::TicksAbove) - lines.append(QLine(tickOffset - 1 - bothOffset, pos, - tickOffset - 1 - bothOffset - tickLength, pos)); - - if (ticks & QSlider::TicksBelow) - lines.append(QLine(tickOffset + thickness + bothOffset, pos, - tickOffset + thickness + bothOffset + tickLength, pos)); - } - // in the case where maximum is max int - int nextInterval = v + interval; - if (nextInterval < v) - break; - v = nextInterval; - } - if (lines.size() > 0) { - p->save(); - p->translate(slrect.topLeft()); - p->drawLines(lines.constData(), lines.size()); - p->restore(); - } - } - if (sub & SC_SliderHandle) { - theme.rect = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget); - if (slider->orientation == Qt::Horizontal) { - if (slider->tickPosition == QSlider::TicksAbove) - partId = TKP_THUMBTOP; - else if (slider->tickPosition == QSlider::TicksBelow) - partId = TKP_THUMBBOTTOM; - else - partId = TKP_THUMB; - - if (!(slider->state & State_Enabled)) - stateId = TUS_DISABLED; - else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_Sunken)) - stateId = TUS_PRESSED; - else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_MouseOver)) - stateId = TUS_HOT; - else if (flags & State_HasFocus) - stateId = TUS_FOCUSED; - else - stateId = TUS_NORMAL; - } else { - if (slider->tickPosition == QSlider::TicksLeft) - partId = TKP_THUMBLEFT; - else if (slider->tickPosition == QSlider::TicksRight) - partId = TKP_THUMBRIGHT; - else - partId = TKP_THUMBVERT; - - if (!(slider->state & State_Enabled)) - stateId = TUVS_DISABLED; - else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_Sunken)) - stateId = TUVS_PRESSED; - else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_MouseOver)) - stateId = TUVS_HOT; - else if (flags & State_HasFocus) - stateId = TUVS_FOCUSED; - else - stateId = TUVS_NORMAL; - } - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } - if (slider->state & State_HasFocus) { - QStyleOptionFocusRect fropt; - fropt.QStyleOption::operator=(*slider); - fropt.rect = subElementRect(SE_SliderFocusRect, slider, widget); - proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget); - } - } - break; -#endif -#if QT_CONFIG(toolbutton) - case CC_ToolButton: - if (const QStyleOptionToolButton *toolbutton - = qstyleoption_cast<const QStyleOptionToolButton *>(option)) { - QRect button, menuarea; - button = proxy()->subControlRect(cc, toolbutton, SC_ToolButton, widget); - menuarea = proxy()->subControlRect(cc, toolbutton, SC_ToolButtonMenu, widget); - - State bflags = toolbutton->state & ~State_Sunken; - State mflags = bflags; - bool autoRaise = flags & State_AutoRaise; - if (autoRaise) { - if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) { - bflags &= ~State_Raised; - } - } - - if (toolbutton->state & State_Sunken) { - if (toolbutton->activeSubControls & SC_ToolButton) { - bflags |= State_Sunken; - mflags |= State_MouseOver | State_Sunken; - } else if (toolbutton->activeSubControls & SC_ToolButtonMenu) { - mflags |= State_Sunken; - bflags |= State_MouseOver; - } - } - - QStyleOption tool = *toolbutton; - if (toolbutton->subControls & SC_ToolButton) { - if (flags & (State_Sunken | State_On | State_Raised) || !autoRaise) { - if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup && autoRaise) { - XPThemeData theme(widget, p, QWindowsXPStylePrivate::ToolBarTheme); - theme.partId = TP_SPLITBUTTON; - theme.rect = button; - if (!(bflags & State_Enabled)) - stateId = TS_DISABLED; - else if (bflags & State_Sunken) - stateId = TS_PRESSED; - else if (bflags & State_MouseOver || !(flags & State_AutoRaise)) - stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT; - else if (bflags & State_On) - stateId = TS_CHECKED; - else - stateId = TS_NORMAL; - if (option->direction == Qt::RightToLeft) - theme.mirrorHorizontally = true; - theme.stateId = stateId; - d->drawBackground(theme); - } else { - tool.rect = option->rect; - tool.state = bflags; - if (autoRaise) // for tool bars - proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget); - else - proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p, widget); - } - } - } - - if (toolbutton->state & State_HasFocus) { - QStyleOptionFocusRect fr; - fr.QStyleOption::operator=(*toolbutton); - fr.rect.adjust(3, 3, -3, -3); - if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup) - fr.rect.adjust(0, 0, -proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator, - toolbutton, widget), 0); - proxy()->drawPrimitive(PE_FrameFocusRect, &fr, p, widget); - } - QStyleOptionToolButton label = *toolbutton; - label.state = bflags; - int fw = 2; - if (!autoRaise) - label.state &= ~State_Sunken; - label.rect = button.adjusted(fw, fw, -fw, -fw); - proxy()->drawControl(CE_ToolButtonLabel, &label, p, widget); - - if (toolbutton->subControls & SC_ToolButtonMenu) { - tool.rect = menuarea; - tool.state = mflags; - if (autoRaise) { - proxy()->drawPrimitive(PE_IndicatorButtonDropDown, &tool, p, widget); - } else { - tool.state = mflags; - menuarea.adjust(-2, 0, 0, 0); - // Draw menu button - if ((bflags & State_Sunken) != (mflags & State_Sunken)){ - p->save(); - p->setClipRect(menuarea); - tool.rect = option->rect; - proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p, 0); - p->restore(); - } - // Draw arrow - p->save(); - p->setPen(option->palette.dark().color()); - p->drawLine(menuarea.left(), menuarea.top() + 3, - menuarea.left(), menuarea.bottom() - 3); - p->setPen(option->palette.light().color()); - p->drawLine(menuarea.left() - 1, menuarea.top() + 3, - menuarea.left() - 1, menuarea.bottom() - 3); - - tool.rect = menuarea.adjusted(2, 3, -2, -1); - proxy()->drawPrimitive(PE_IndicatorArrowDown, &tool, p, widget); - p->restore(); - } - } else if (toolbutton->features & QStyleOptionToolButton::HasMenu) { - int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, toolbutton, widget); - QRect ir = toolbutton->rect; - QStyleOptionToolButton newBtn = *toolbutton; - newBtn.rect = QRect(ir.right() + 4 - mbi, ir.height() - mbi + 4, mbi - 5, mbi - 5); - proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget); - } - } - break; -#endif // QT_CONFIG(toolbutton) - - case CC_TitleBar: - { - if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) - { - bool isActive = tb->titleBarState & QStyle::State_Active; - XPThemeData theme(widget, p, QWindowsXPStylePrivate::WindowTheme); - if (sub & SC_TitleBarLabel) { - - partId = (tb->titleBarState & Qt::WindowMinimized) ? WP_MINCAPTION : WP_CAPTION; - theme.rect = option->rect; - if (widget && !widget->isEnabled()) - stateId = CS_DISABLED; - else if (isActive) - stateId = CS_ACTIVE; - else - stateId = CS_INACTIVE; - - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - - QRect ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarLabel, widget); - - int result = TST_NONE; - GetThemeEnumValue(theme.handle(), WP_CAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWTYPE, &result); - if (result != TST_NONE) { - COLORREF textShadowRef; - GetThemeColor(theme.handle(), WP_CAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWCOLOR, &textShadowRef); - QColor textShadow = qRgb(GetRValue(textShadowRef), GetGValue(textShadowRef), GetBValue(textShadowRef)); - p->setPen(textShadow); - p->drawText(ir.x() + 3, ir.y() + 2, ir.width() - 1, ir.height(), - Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text); - } - COLORREF captionText = GetSysColor(isActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT); - QColor textColor = qRgb(GetRValue(captionText), GetGValue(captionText), GetBValue(captionText)); - p->setPen(textColor); - p->drawText(ir.x() + 2, ir.y() + 1, ir.width() - 2, ir.height(), - Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text); - } - if (sub & SC_TitleBarSysMenu && tb->titleBarFlags & Qt::WindowSystemMenuHint) { - theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarSysMenu, widget); - partId = WP_SYSBUTTON; - if ((widget && !widget->isEnabled()) || !isActive) - stateId = SBS_DISABLED; - else if (option->activeSubControls == SC_TitleBarSysMenu && (option->state & State_Sunken)) - stateId = SBS_PUSHED; - else if (option->activeSubControls == SC_TitleBarSysMenu && (option->state & State_MouseOver)) - stateId = SBS_HOT; - else - stateId = SBS_NORMAL; - if (!tb->icon.isNull()) { - tb->icon.paint(p, theme.rect); - } else { - theme.partId = partId; - theme.stateId = stateId; - if (theme.size().isEmpty()) { - int iconSize = proxy()->pixelMetric(PM_SmallIconSize, tb, widget); - QPixmap pm = proxy()->standardIcon(SP_TitleBarMenuButton, tb, widget).pixmap(iconSize, iconSize); - p->save(); - drawItemPixmap(p, theme.rect, Qt::AlignCenter, pm); - p->restore(); - } else { - d->drawBackground(theme); - } - } - } - - if (sub & SC_TitleBarMinButton && tb->titleBarFlags & Qt::WindowMinimizeButtonHint - && !(tb->titleBarState & Qt::WindowMinimized)) { - theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarMinButton, widget); - partId = WP_MINBUTTON; - if (widget && !widget->isEnabled()) - stateId = MINBS_DISABLED; - else if (option->activeSubControls == SC_TitleBarMinButton && (option->state & State_Sunken)) - stateId = MINBS_PUSHED; - else if (option->activeSubControls == SC_TitleBarMinButton && (option->state & State_MouseOver)) - stateId = MINBS_HOT; - else if (!isActive) - stateId = MINBS_INACTIVE; - else - stateId = MINBS_NORMAL; - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } - if (sub & SC_TitleBarMaxButton && tb->titleBarFlags & Qt::WindowMaximizeButtonHint - && !(tb->titleBarState & Qt::WindowMaximized)) { - theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarMaxButton, widget); - partId = WP_MAXBUTTON; - if (widget && !widget->isEnabled()) - stateId = MAXBS_DISABLED; - else if (option->activeSubControls == SC_TitleBarMaxButton && (option->state & State_Sunken)) - stateId = MAXBS_PUSHED; - else if (option->activeSubControls == SC_TitleBarMaxButton && (option->state & State_MouseOver)) - stateId = MAXBS_HOT; - else if (!isActive) - stateId = MAXBS_INACTIVE; - else - stateId = MAXBS_NORMAL; - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } - if (sub & SC_TitleBarContextHelpButton - && tb->titleBarFlags & Qt::WindowContextHelpButtonHint) { - theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarContextHelpButton, widget); - partId = WP_HELPBUTTON; - if (widget && !widget->isEnabled()) - stateId = MINBS_DISABLED; - else if (option->activeSubControls == SC_TitleBarContextHelpButton && (option->state & State_Sunken)) - stateId = MINBS_PUSHED; - else if (option->activeSubControls == SC_TitleBarContextHelpButton && (option->state & State_MouseOver)) - stateId = MINBS_HOT; - else if (!isActive) - stateId = MINBS_INACTIVE; - else - stateId = MINBS_NORMAL; - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } - bool drawNormalButton = (sub & SC_TitleBarNormalButton) - && (((tb->titleBarFlags & Qt::WindowMinimizeButtonHint) - && (tb->titleBarState & Qt::WindowMinimized)) - || ((tb->titleBarFlags & Qt::WindowMaximizeButtonHint) - && (tb->titleBarState & Qt::WindowMaximized))); - if (drawNormalButton) { - theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarNormalButton, widget); - partId = WP_RESTOREBUTTON; - if (widget && !widget->isEnabled()) - stateId = RBS_DISABLED; - else if (option->activeSubControls == SC_TitleBarNormalButton && (option->state & State_Sunken)) - stateId = RBS_PUSHED; - else if (option->activeSubControls == SC_TitleBarNormalButton && (option->state & State_MouseOver)) - stateId = RBS_HOT; - else if (!isActive) - stateId = RBS_INACTIVE; - else - stateId = RBS_NORMAL; - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } - if (sub & SC_TitleBarShadeButton && tb->titleBarFlags & Qt::WindowShadeButtonHint - && !(tb->titleBarState & Qt::WindowMinimized)) { - theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarShadeButton, widget); - partId = WP_MINBUTTON; - if (widget && !widget->isEnabled()) - stateId = MINBS_DISABLED; - else if (option->activeSubControls == SC_TitleBarShadeButton && (option->state & State_Sunken)) - stateId = MINBS_PUSHED; - else if (option->activeSubControls == SC_TitleBarShadeButton && (option->state & State_MouseOver)) - stateId = MINBS_HOT; - else if (!isActive) - stateId = MINBS_INACTIVE; - else - stateId = MINBS_NORMAL; - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } - if (sub & SC_TitleBarUnshadeButton && tb->titleBarFlags & Qt::WindowShadeButtonHint - && tb->titleBarState & Qt::WindowMinimized) { - theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarUnshadeButton, widget); - partId = WP_RESTOREBUTTON; - if (widget && !widget->isEnabled()) - stateId = RBS_DISABLED; - else if (option->activeSubControls == SC_TitleBarUnshadeButton && (option->state & State_Sunken)) - stateId = RBS_PUSHED; - else if (option->activeSubControls == SC_TitleBarUnshadeButton && (option->state & State_MouseOver)) - stateId = RBS_HOT; - else if (!isActive) - stateId = RBS_INACTIVE; - else - stateId = RBS_NORMAL; - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } - if (sub & SC_TitleBarCloseButton && tb->titleBarFlags & Qt::WindowSystemMenuHint) { - theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarCloseButton, widget); - //partId = titlebar->testWFlags(Qt::WA_WState_Tool) ? WP_SMALLCLOSEBUTTON : WP_CLOSEBUTTON; - partId = WP_CLOSEBUTTON; - if (widget && !widget->isEnabled()) - stateId = CBS_DISABLED; - else if (option->activeSubControls == SC_TitleBarCloseButton && (option->state & State_Sunken)) - stateId = CBS_PUSHED; - else if (option->activeSubControls == SC_TitleBarCloseButton && (option->state & State_MouseOver)) - stateId = CBS_HOT; - else if (!isActive) - stateId = CBS_INACTIVE; - else - stateId = CBS_NORMAL; - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); - } - } - } - break; - -#if QT_CONFIG(mdiarea) - case CC_MdiControls: - { - QRect buttonRect; - XPThemeData theme(widget, p, QWindowsXPStylePrivate::WindowTheme, WP_MDICLOSEBUTTON, CBS_NORMAL); - - if (option->subControls & SC_MdiCloseButton) { - buttonRect = proxy()->subControlRect(CC_MdiControls, option, SC_MdiCloseButton, widget); - if (theme.isValid()) { - theme.partId = WP_MDICLOSEBUTTON; - theme.rect = buttonRect; - if (!(flags & State_Enabled)) - theme.stateId = CBS_INACTIVE; - else if (flags & State_Sunken && (option->activeSubControls & SC_MdiCloseButton)) - theme.stateId = CBS_PUSHED; - else if (flags & State_MouseOver && (option->activeSubControls & SC_MdiCloseButton)) - theme.stateId = CBS_HOT; - else - theme.stateId = CBS_NORMAL; - d->drawBackground(theme); - } - } - if (option->subControls & SC_MdiNormalButton) { - buttonRect = proxy()->subControlRect(CC_MdiControls, option, SC_MdiNormalButton, widget); - if (theme.isValid()) { - theme.partId = WP_MDIRESTOREBUTTON; - theme.rect = buttonRect; - if (!(flags & State_Enabled)) - theme.stateId = CBS_INACTIVE; - else if (flags & State_Sunken && (option->activeSubControls & SC_MdiNormalButton)) - theme.stateId = CBS_PUSHED; - else if (flags & State_MouseOver && (option->activeSubControls & SC_MdiNormalButton)) - theme.stateId = CBS_HOT; - else - theme.stateId = CBS_NORMAL; - d->drawBackground(theme); - } - } - if (option->subControls & QStyle::SC_MdiMinButton) { - buttonRect = proxy()->subControlRect(CC_MdiControls, option, SC_MdiMinButton, widget); - if (theme.isValid()) { - theme.partId = WP_MDIMINBUTTON; - theme.rect = buttonRect; - if (!(flags & State_Enabled)) - theme.stateId = CBS_INACTIVE; - else if (flags & State_Sunken && (option->activeSubControls & SC_MdiMinButton)) - theme.stateId = CBS_PUSHED; - else if (flags & State_MouseOver && (option->activeSubControls & SC_MdiMinButton)) - theme.stateId = CBS_HOT; - else - theme.stateId = CBS_NORMAL; - d->drawBackground(theme); - } - } - } - break; -#endif // QT_CONFIG(mdiarea) -#if QT_CONFIG(dial) - case CC_Dial: - if (const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(option)) - QStyleHelper::drawDial(dial, p); - break; -#endif // QT_CONFIG(dial) - default: - QWindowsStyle::drawComplexControl(cc, option, p, widget); - break; - } -} - -static inline Qt::Orientation progressBarOrientation(const QStyleOption *option = 0) -{ - if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) - return pb->orientation; - return Qt::Horizontal; -} - -int QWindowsXPStylePrivate::pixelMetricFromSystemDp(QStyle::PixelMetric pm, const QStyleOption *option, const QWidget *widget) -{ - switch (pm) { - case QStyle::PM_IndicatorWidth: - return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_CHECKBOX, CBS_UNCHECKEDNORMAL).width(); - case QStyle::PM_IndicatorHeight: - return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_CHECKBOX, CBS_UNCHECKEDNORMAL).height(); - case QStyle::PM_ExclusiveIndicatorWidth: - return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL).width(); - case QStyle::PM_ExclusiveIndicatorHeight: - return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL).height(); - case QStyle::PM_ProgressBarChunkWidth: - return progressBarOrientation(option) == Qt::Horizontal - ? XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ProgressTheme, PP_CHUNK).width() - : XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ProgressTheme, PP_CHUNKVERT).height(); - case QStyle::PM_SliderThickness: - return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::TrackBarTheme, TKP_THUMB).height(); - case QStyle::PM_TitleBarHeight: - return widget && (widget->windowType() == Qt::Tool) - ? GetSystemMetrics(SM_CYSMCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME) - : GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME); - case QStyle::PM_MdiSubWindowFrameWidth: - return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::WindowTheme, WP_FRAMELEFT, FS_ACTIVE).width(); - case QStyle::PM_DockWidgetFrameWidth: - return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::WindowTheme, WP_SMALLFRAMERIGHT, FS_ACTIVE).width(); - default: - break; - } - return QWindowsXPStylePrivate::InvalidMetric; -} - -/*! \reimp */ -int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, const QWidget *widget) const -{ - if (!QWindowsXPStylePrivate::useXP()) - return QWindowsStyle::pixelMetric(pm, option, widget); - - int res = QWindowsXPStylePrivate::pixelMetricFromSystemDp(pm, option, widget); - if (res != QWindowsStylePrivate::InvalidMetric) - return qRound(qreal(res) * QWindowsStylePrivate::nativeMetricScaleFactor(widget)); - - res = 0; - switch (pm) { - case PM_MenuBarPanelWidth: - case PM_ButtonDefaultIndicator: - res = 0; - break; - - case PM_DefaultFrameWidth: - res = qobject_cast<const QListView*>(widget) ? 2 : 1; - break; - case PM_MenuPanelWidth: - case PM_SpinBoxFrameWidth: - res = 1; - break; - - case PM_TabBarTabOverlap: - case PM_MenuHMargin: - case PM_MenuVMargin: - res = 2; - break; - - case PM_TabBarBaseOverlap: - if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) { - switch (tab->shape) { - case QTabBar::RoundedNorth: - case QTabBar::TriangularNorth: - case QTabBar::RoundedWest: - case QTabBar::TriangularWest: - res = 1; - break; - case QTabBar::RoundedSouth: - case QTabBar::TriangularSouth: - res = 2; - break; - case QTabBar::RoundedEast: - case QTabBar::TriangularEast: - res = 3; - break; - } - } - break; - - case PM_SplitterWidth: - res = qMax(int(QStyleHelper::dpiScaled(5.)), QApplication::globalStrut().width()); - break; - - case PM_MdiSubWindowMinimizedWidth: - res = 160; - break; - -#ifndef QT_NO_TOOLBAR - case PM_ToolBarHandleExtent: - res = int(QStyleHelper::dpiScaled(8.)); - break; - -#endif // QT_NO_TOOLBAR - case PM_DockWidgetSeparatorExtent: - case PM_DockWidgetTitleMargin: - res = int(QStyleHelper::dpiScaled(4.)); - break; - - case PM_ButtonShiftHorizontal: - case PM_ButtonShiftVertical: - res = qstyleoption_cast<const QStyleOptionToolButton *>(option) ? 1 : 0; - break; - - default: - res = QWindowsStyle::pixelMetric(pm, option, widget); - } - - return res; -} - -/* - This function is used by subControlRect to check if a button - should be drawn for the given subControl given a set of window flags. -*/ -static bool buttonVisible(const QStyle::SubControl sc, const QStyleOptionTitleBar *tb){ - - bool isMinimized = tb->titleBarState & Qt::WindowMinimized; - bool isMaximized = tb->titleBarState & Qt::WindowMaximized; - const uint flags = tb->titleBarFlags; - bool retVal = false; - switch (sc) { - case QStyle::SC_TitleBarContextHelpButton: - if (flags & Qt::WindowContextHelpButtonHint) - retVal = true; - break; - case QStyle::SC_TitleBarMinButton: - if (!isMinimized && (flags & Qt::WindowMinimizeButtonHint)) - retVal = true; - break; - case QStyle::SC_TitleBarNormalButton: - if (isMinimized && (flags & Qt::WindowMinimizeButtonHint)) - retVal = true; - else if (isMaximized && (flags & Qt::WindowMaximizeButtonHint)) - retVal = true; - break; - case QStyle::SC_TitleBarMaxButton: - if (!isMaximized && (flags & Qt::WindowMaximizeButtonHint)) - retVal = true; - break; - case QStyle::SC_TitleBarShadeButton: - if (!isMinimized && flags & Qt::WindowShadeButtonHint) - retVal = true; - break; - case QStyle::SC_TitleBarUnshadeButton: - if (isMinimized && flags & Qt::WindowShadeButtonHint) - retVal = true; - break; - case QStyle::SC_TitleBarCloseButton: - if (flags & Qt::WindowSystemMenuHint) - retVal = true; - break; - case QStyle::SC_TitleBarSysMenu: - if (flags & Qt::WindowSystemMenuHint) - retVal = true; - break; - default : - retVal = true; - } - return retVal; -} - -/*! - \reimp -*/ -QRect QWindowsXPStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *option, - SubControl subControl, const QWidget *widget) const -{ - if (!QWindowsXPStylePrivate::useXP()) - return QWindowsStyle::subControlRect(cc, option, subControl, widget); - - QRect rect; - - switch (cc) { - case CC_TitleBar: - if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) { - if (!buttonVisible(subControl, tb)) - return rect; - const bool isToolTitle = false; - const int height = tb->rect.height(); - const int width = tb->rect.width(); - const int buttonMargin = int(QStyleHelper::dpiScaled(4)); - const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(widget); - int buttonHeight = qRound(qreal(GetSystemMetrics(SM_CYSIZE)) * factor) - - buttonMargin; - int buttonWidth = qRound(qreal(GetSystemMetrics(SM_CXSIZE)) * factor) - - buttonMargin; - const int delta = buttonWidth + 2; - int controlTop = option->rect.bottom() - buttonHeight - 2; - const int frameWidth = proxy()->pixelMetric(PM_MdiSubWindowFrameWidth, option, widget); - const bool sysmenuHint = (tb->titleBarFlags & Qt::WindowSystemMenuHint) != 0; - const bool minimizeHint = (tb->titleBarFlags & Qt::WindowMinimizeButtonHint) != 0; - const bool maximizeHint = (tb->titleBarFlags & Qt::WindowMaximizeButtonHint) != 0; - const bool contextHint = (tb->titleBarFlags & Qt::WindowContextHelpButtonHint) != 0; - const bool shadeHint = (tb->titleBarFlags & Qt::WindowShadeButtonHint) != 0; - bool isMinimized = tb->titleBarState & Qt::WindowMinimized; - bool isMaximized = tb->titleBarState & Qt::WindowMaximized; - int offset = 0; - - switch (subControl) { - case SC_TitleBarLabel: - rect = QRect(frameWidth, 0, width - (buttonWidth + frameWidth + 10), height); - if (isToolTitle) { - if (sysmenuHint) { - rect.adjust(0, 0, -buttonWidth - 3, 0); - } - if (minimizeHint || maximizeHint) - rect.adjust(0, 0, -buttonWidth - 2, 0); - } else { - if (sysmenuHint) { - const int leftOffset = height - 8; - rect.adjust(leftOffset, 0, 0, 0); - } - if (minimizeHint) - rect.adjust(0, 0, -buttonWidth - 2, 0); - if (maximizeHint) - rect.adjust(0, 0, -buttonWidth - 2, 0); - if (contextHint) - rect.adjust(0, 0, -buttonWidth - 2, 0); - if (shadeHint) - rect.adjust(0, 0, -buttonWidth - 2, 0); - } - break; - - case SC_TitleBarContextHelpButton: - if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint) - offset += delta; - Q_FALLTHROUGH(); - case SC_TitleBarMinButton: - if (!isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint)) - offset += delta; - else if (subControl == SC_TitleBarMinButton) - break; - Q_FALLTHROUGH(); - case SC_TitleBarNormalButton: - if (isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint)) - offset += delta; - else if (isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint)) - offset += delta; - else if (subControl == SC_TitleBarNormalButton) - break; - Q_FALLTHROUGH(); - case SC_TitleBarMaxButton: - if (!isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint)) - offset += delta; - else if (subControl == SC_TitleBarMaxButton) - break; - Q_FALLTHROUGH(); - case SC_TitleBarShadeButton: - if (!isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint)) - offset += delta; - else if (subControl == SC_TitleBarShadeButton) - break; - Q_FALLTHROUGH(); - case SC_TitleBarUnshadeButton: - if (isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint)) - offset += delta; - else if (subControl == SC_TitleBarUnshadeButton) - break; - Q_FALLTHROUGH(); - case SC_TitleBarCloseButton: - if (tb->titleBarFlags & Qt::WindowSystemMenuHint) - offset += delta; - else if (subControl == SC_TitleBarCloseButton) - break; - - rect.setRect(width - offset - controlTop + 1, controlTop, - buttonWidth, buttonHeight); - break; - - case SC_TitleBarSysMenu: - { - const int controlTop = 6; - const int controlHeight = height - controlTop - 3; - const int iconExtent = proxy()->pixelMetric(PM_SmallIconSize); - QSize iconSize = tb->icon.actualSize(QSize(iconExtent, iconExtent)); - if (tb->icon.isNull()) - iconSize = QSize(controlHeight, controlHeight); - int hPad = (controlHeight - iconSize.height())/2; - int vPad = (controlHeight - iconSize.width())/2; - rect = QRect(frameWidth + hPad, controlTop + vPad, iconSize.width(), iconSize.height()); - } - break; - default: - break; - } - } - break; - - case CC_ComboBox: - if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) { - int x = cmb->rect.x(), y = cmb->rect.y(), wi = cmb->rect.width(), he = cmb->rect.height(); - int xpos = x; - xpos += wi - 1 - 16; - - switch (subControl) { - case SC_ComboBoxFrame: - rect = cmb->rect; - break; - - case SC_ComboBoxArrow: - rect = QRect(xpos, y+1, 16, he-2); - break; - - case SC_ComboBoxEditField: - rect = QRect(x+2, y+2, wi-3-16, he-4); - break; - - case SC_ComboBoxListBoxPopup: - rect = cmb->rect; - break; - - default: - break; - } - } - break; -#if QT_CONFIG(mdiarea) - case CC_MdiControls: - { - int numSubControls = 0; - if (option->subControls & SC_MdiCloseButton) - ++numSubControls; - if (option->subControls & SC_MdiMinButton) - ++numSubControls; - if (option->subControls & SC_MdiNormalButton) - ++numSubControls; - if (numSubControls == 0) - break; - - int buttonWidth = option->rect.width() / numSubControls; - int offset = 0; - switch (subControl) { - case SC_MdiCloseButton: - // Only one sub control, no offset needed. - if (numSubControls == 1) - break; - offset += buttonWidth; - Q_FALLTHROUGH(); - case SC_MdiNormalButton: - // No offset needed if - // 1) There's only one sub control - // 2) We have a close button and a normal button (offset already added in SC_MdiClose) - if (numSubControls == 1 || (numSubControls == 2 && !(option->subControls & SC_MdiMinButton))) - break; - if (option->subControls & SC_MdiNormalButton) - offset += buttonWidth; - break; - default: - break; - } - rect = QRect(offset, 0, buttonWidth, option->rect.height()); - break; - } -#endif // QT_CONFIG(mdiarea) - - default: - rect = visualRect(option->direction, option->rect, - QWindowsStyle::subControlRect(cc, option, subControl, widget)); - break; - } - return visualRect(option->direction, option->rect, rect); -} - -/*! - \reimp -*/ -QSize QWindowsXPStyle::sizeFromContents(ContentsType ct, const QStyleOption *option, - const QSize &contentsSize, const QWidget *widget) const -{ - if (!QWindowsXPStylePrivate::useXP()) - return QWindowsStyle::sizeFromContents(ct, option, contentsSize, widget); - - QSize sz(contentsSize); - switch (ct) { - case CT_LineEdit: - case CT_ComboBox: - { - XPThemeData buttontheme(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_PUSHBUTTON, PBS_NORMAL); - if (buttontheme.isValid()) { - const qreal factor = QWindowsXPStylePrivate::nativeMetricScaleFactor(widget); - const QMarginsF borderSize = buttontheme.margins() * factor; - if (!borderSize.isNull()) { - const qreal margin = qreal(2) * factor; - sz.rwidth() += qRound(borderSize.left() + borderSize.right() - margin); - sz.rheight() += int(borderSize.bottom() + borderSize.top() - margin - + qreal(1) / factor - 1); - } - const int textMargins = 2*(proxy()->pixelMetric(PM_FocusFrameHMargin) + 1); - sz += QSize(qMax(pixelMetric(QStyle::PM_ScrollBarExtent, option, widget) - + textMargins, 23), 0); //arrow button - } - } - break; - case CT_SpinBox: - { - //Spinbox adds frame twice - sz = QWindowsStyle::sizeFromContents(ct, option, contentsSize, widget); - int border = proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget); - sz -= QSize(2*border, 2*border); - } - break; - case CT_TabWidget: - sz += QSize(6, 6); - break; - case CT_Menu: - sz += QSize(1, 0); - break; -#if QT_CONFIG(menubar) - case CT_MenuBarItem: - if (!sz.isEmpty()) - sz += QSize(windowsItemHMargin * 5 + 1, 6); - break; -#endif - case CT_MenuItem: - if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) - { - if (menuitem->menuItemType != QStyleOptionMenuItem::Separator) { - sz = QWindowsStyle::sizeFromContents(ct, option, sz, widget); - sz.setHeight(sz.height() - 2); - return sz; - } - } - sz = QWindowsStyle::sizeFromContents(ct, option, sz, widget); - break; - - case CT_MdiControls: - if (const QStyleOptionComplex *styleOpt = qstyleoption_cast<const QStyleOptionComplex *>(option)) { - int width = 0; - if (styleOpt->subControls & SC_MdiMinButton) - width += 17 + 1; - if (styleOpt->subControls & SC_MdiNormalButton) - width += 17 + 1; - if (styleOpt->subControls & SC_MdiCloseButton) - width += 17 + 1; - sz = QSize(width, 19); - } else { - sz = QSize(54, 19); - } - break; - - default: - sz = QWindowsStyle::sizeFromContents(ct, option, sz, widget); - break; - } - - return sz; -} - - -/*! \reimp */ -int QWindowsXPStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, - QStyleHintReturn *returnData) const -{ - QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func()); - if (!QWindowsXPStylePrivate::useXP()) - return QWindowsStyle::styleHint(hint, option, widget, returnData); - - int res = 0; - switch (hint) { - - case SH_EtchDisabledText: - res = (qobject_cast<const QLabel*>(widget) != 0); - break; - - case SH_SpinControls_DisableOnBounds: - res = 0; - break; - - case SH_TitleBar_AutoRaise: - case SH_TitleBar_NoBorder: - res = 1; - break; - - case SH_GroupBox_TextLabelColor: - if (!widget || (widget && widget->isEnabled())) - res = d->groupBoxTextColor; - else - res = d->groupBoxTextColorDisabled; - break; - - case SH_Table_GridLineColor: - res = 0xC0C0C0; - break; - - case SH_WindowFrame_Mask: - { - res = 1; - QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask *>(returnData); - const QStyleOptionTitleBar *titlebar = qstyleoption_cast<const QStyleOptionTitleBar *>(option); - if (mask && titlebar) { - // Note certain themes will not return the whole window frame but only the titlebar part when - // queried This function needs to return the entire window mask, hence we will only fetch the mask for the - // titlebar itself and add the remaining part of the window rect at the bottom. - int tbHeight = proxy()->pixelMetric(PM_TitleBarHeight, option, widget); - QRect titleBarRect = option->rect; - titleBarRect.setHeight(tbHeight); - XPThemeData themeData; - if (titlebar->titleBarState & Qt::WindowMinimized) { - themeData = XPThemeData(widget, 0, - QWindowsXPStylePrivate::WindowTheme, - WP_MINCAPTION, CS_ACTIVE, titleBarRect); - } else - themeData = XPThemeData(widget, 0, - QWindowsXPStylePrivate::WindowTheme, - WP_CAPTION, CS_ACTIVE, titleBarRect); - mask->region = d->region(themeData) + - QRect(0, tbHeight, option->rect.width(), option->rect.height() - tbHeight); - } - } - break; -#if QT_CONFIG(rubberband) - case SH_RubberBand_Mask: - if (qstyleoption_cast<const QStyleOptionRubberBand *>(option)) - res = 0; - break; -#endif // QT_CONFIG(rubberband) - - case SH_ItemView_DrawDelegateFrame: - res = 1; - break; - - default: - res =QWindowsStyle::styleHint(hint, option, widget, returnData); - } - - return res; -} - -/*! \reimp */ -QPalette QWindowsXPStyle::standardPalette() const -{ - if (QWindowsXPStylePrivate::useXP() && QApplicationPrivate::sys_pal) - return *QApplicationPrivate::sys_pal; - else - return QWindowsStyle::standardPalette(); -} - -/*! - \reimp -*/ -QPixmap QWindowsXPStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option, - const QWidget *widget) const -{ - if (!QWindowsXPStylePrivate::useXP()) - return QWindowsStyle::standardPixmap(standardPixmap, option, widget); - - switch(standardPixmap) { - case SP_TitleBarMaxButton: - case SP_TitleBarCloseButton: - if (qstyleoption_cast<const QStyleOptionDockWidget *>(option)) - { - if (widget && widget->isWindow()) { - XPThemeData theme(widget, 0, QWindowsXPStylePrivate::WindowTheme, WP_SMALLCLOSEBUTTON, CBS_NORMAL); - if (theme.isValid()) { - const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); - return QIcon(QWindowsStyle::standardPixmap(standardPixmap, option, widget)).pixmap(size); - } - } - } - break; - default: - break; - } - return QWindowsStyle::standardPixmap(standardPixmap, option, widget); -} - -/*! - \reimp -*/ -QIcon QWindowsXPStyle::standardIcon(StandardPixmap standardIcon, - const QStyleOption *option, - const QWidget *widget) const -{ - if (!QWindowsXPStylePrivate::useXP()) { - return QWindowsStyle::standardIcon(standardIcon, option, widget); - } - - QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func()); - switch(standardIcon) { - case SP_TitleBarMaxButton: - if (qstyleoption_cast<const QStyleOptionDockWidget *>(option)) - { - if (d->dockFloat.isNull()) { - XPThemeData themeSize(0, 0, QWindowsXPStylePrivate::WindowTheme, - WP_SMALLCLOSEBUTTON, CBS_NORMAL); - XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme, - WP_MAXBUTTON, MAXBS_NORMAL); - if (theme.isValid()) { - const QSize size = (themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); - QPixmap pm(size); - pm.fill(Qt::transparent); - QPainter p(&pm); - theme.painter = &p; - theme.rect = QRect(QPoint(0, 0), size); - d->drawBackground(theme); - d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::Off); // Normal - pm.fill(Qt::transparent); - theme.stateId = MAXBS_PUSHED; - d->drawBackground(theme); - d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::On); // Pressed - pm.fill(Qt::transparent); - theme.stateId = MAXBS_HOT; - d->drawBackground(theme); - d->dockFloat.addPixmap(pm, QIcon::Active, QIcon::Off); // Hover - pm.fill(Qt::transparent); - theme.stateId = MAXBS_INACTIVE; - d->drawBackground(theme); - d->dockFloat.addPixmap(pm, QIcon::Disabled, QIcon::Off); // Disabled - } - } - if (widget && widget->isWindow()) - return d->dockFloat; - - } - break; - case SP_TitleBarCloseButton: - if (qstyleoption_cast<const QStyleOptionDockWidget *>(option)) - { - if (d->dockClose.isNull()) { - XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme, - WP_SMALLCLOSEBUTTON, CBS_NORMAL); - if (theme.isValid()) { - const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); - QPixmap pm(size); - pm.fill(Qt::transparent); - QPainter p(&pm); - theme.painter = &p; - theme.partId = WP_CLOSEBUTTON; // #### - theme.rect = QRect(QPoint(0, 0), size); - d->drawBackground(theme); - d->dockClose.addPixmap(pm, QIcon::Normal, QIcon::Off); // Normal - pm.fill(Qt::transparent); - theme.stateId = CBS_PUSHED; - d->drawBackground(theme); - d->dockClose.addPixmap(pm, QIcon::Normal, QIcon::On); // Pressed - pm.fill(Qt::transparent); - theme.stateId = CBS_HOT; - d->drawBackground(theme); - d->dockClose.addPixmap(pm, QIcon::Active, QIcon::Off); // Hover - pm.fill(Qt::transparent); - theme.stateId = CBS_INACTIVE; - d->drawBackground(theme); - d->dockClose.addPixmap(pm, QIcon::Disabled, QIcon::Off); // Disabled - } - } - if (widget && widget->isWindow()) - return d->dockClose; - } - break; - case SP_TitleBarNormalButton: - if (qstyleoption_cast<const QStyleOptionDockWidget *>(option)) - { - if (d->dockFloat.isNull()) { - XPThemeData themeSize(0, 0, QWindowsXPStylePrivate::WindowTheme, - WP_SMALLCLOSEBUTTON, CBS_NORMAL); - XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme, - WP_RESTOREBUTTON, RBS_NORMAL); - if (theme.isValid()) { - const QSize size = (themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); - QPixmap pm(size); - pm.fill(Qt::transparent); - QPainter p(&pm); - theme.painter = &p; - theme.rect = QRect(QPoint(0, 0), size); - d->drawBackground(theme); - d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::Off); // Normal - pm.fill(Qt::transparent); - theme.stateId = RBS_PUSHED; - d->drawBackground(theme); - d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::On); // Pressed - pm.fill(Qt::transparent); - theme.stateId = RBS_HOT; - d->drawBackground(theme); - d->dockFloat.addPixmap(pm, QIcon::Active, QIcon::Off); // Hover - pm.fill(Qt::transparent); - theme.stateId = RBS_INACTIVE; - d->drawBackground(theme); - d->dockFloat.addPixmap(pm, QIcon::Disabled, QIcon::Off); // Disabled - } - } - if (widget && widget->isWindow()) - return d->dockFloat; - - } - break; - default: - break; - } - - return QWindowsStyle::standardIcon(standardIcon, option, widget); -} - -/*! - \internal - - Constructs a QWindowsXPStyle object. -*/ -QWindowsXPStyle::QWindowsXPStyle(QWindowsXPStylePrivate &dd) : QWindowsStyle(dd) -{ -} - - -// Debugging code ---------------------------------------------------------------------[ START ]--- -// The code for this point on is not compiled by default, but only used as assisting -// debugging code when you uncomment the DEBUG_XP_STYLE define at the top of the file. - -#ifdef DEBUG_XP_STYLE -// The schema file expects these to be defined by the user. -#define TMT_ENUMDEF 8 -#define TMT_ENUMVAL TEXT('A') -#define TMT_ENUM TEXT('B') -#define SCHEMA_STRINGS // For 2nd pass on schema file -QT_BEGIN_INCLUDE_NAMESPACE -#include <tmschema.h> -QT_END_INCLUDE_NAMESPACE - -// A property's value, type and name combo -struct PropPair { - int propValue; - int propType; - LPCWSTR propName; -}; - -// Operator for sorting of PropPairs -bool operator<(PropPair a, PropPair b) { - return wcscmp(a.propName, b.propName) < 0; -} - -// Our list of all possible properties -static QList<PropPair> all_props; - - -/*! \internal - Dumps a portion of the full native DIB section double buffer. - The DIB section double buffer is only used when doing special - transformations to the theme part, or when the real double - buffer in the paintengine does not have an HDC we may use - directly. - Since we cannot rely on the pixel data we get from Microsoft - when drawing into the DIB section, we use this function to - see the actual data we got, and can determin the appropriate - action. -*/ -void QWindowsXPStylePrivate::dumpNativeDIB(int w, int h) -{ - if (w && h) { - static int pCount = 0; - DWORD *bufPix = (DWORD*)bufferPixels; - - char *bufferDump = new char[bufferH * bufferW * 16]; - char *bufferPos = bufferDump; - - memset(bufferDump, 0, sizeof(bufferDump)); - bufferPos += sprintf(bufferPos, "const int pixelBufferW%d = %d;\n", pCount, w); - bufferPos += sprintf(bufferPos, "const int pixelBufferH%d = %d;\n", pCount, h); - bufferPos += sprintf(bufferPos, "const unsigned DWORD pixelBuffer%d[] = {", pCount); - for (int iy = 0; iy < h; ++iy) { - bufferPos += sprintf(bufferPos, "\n "); - bufPix = (DWORD*)(bufferPixels + (iy * bufferW * 4)); - for (int ix = 0; ix < w; ++ix) { - bufferPos += sprintf(bufferPos, "0x%08x, ", *bufPix); - ++bufPix; - } - } - bufferPos += sprintf(bufferPos, "\n};\n\n"); - printf(bufferDump); - - delete[] bufferDump; - ++pCount; - } -} - -/*! \internal - Shows the value of a given property for a part. -*/ -static void showProperty(XPThemeData &themeData, const PropPair &prop) -{ - PROPERTYORIGIN origin = PO_NOTFOUND; - GetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &origin); - const char *originStr; - switch(origin) { - case PO_STATE: - originStr = "State "; - break; - case PO_PART: - originStr = "Part "; - break; - case PO_CLASS: - originStr = "Class "; - break; - case PO_GLOBAL: - originStr = "Globl "; - break; - case PO_NOTFOUND: - default: - originStr = "Unkwn "; - break; - } - - switch(prop.propType) { - case TMT_STRING: - { - wchar_t buffer[512]; - GetThemeString(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, buffer, 512); - printf(" (%sString) %-20S: %S\n", originStr, prop.propName, buffer); - } - break; - case TMT_ENUM: - { - int result = -1; - GetThemeEnumValue(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result); - printf(" (%sEnum) %-20S: %d\n", originStr, prop.propName, result); - } - break; - case TMT_INT: - { - int result = -1; - GetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result); - printf(" (%sint) %-20S: %d\n", originStr, prop.propName, result); - } - break; - case TMT_BOOL: - { - BOOL result = false; - GetThemeBool(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result); - printf(" (%sbool) %-20S: %d\n", originStr, prop.propName, result); - } - break; - case TMT_COLOR: - { - COLORREF result = 0; - GetThemeColor(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result); - printf(" (%scolor) %-20S: 0x%08X\n", originStr, prop.propName, result); - } - break; - case TMT_MARGINS: - { - MARGINS result; - memset(&result, 0, sizeof(result)); - GetThemeMargins(themeData.handle(), 0, themeData.partId, themeData.stateId, prop.propValue, 0, &result); - printf(" (%smargins) %-20S: (%d, %d, %d, %d)\n", originStr, - prop.propName, result.cxLeftWidth, result.cyTopHeight, result.cxRightWidth, result.cyBottomHeight); - } - break; - case TMT_FILENAME: - { - wchar_t buffer[512]; - GetThemeFilename(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, buffer, 512); - printf(" (%sfilename)%-20S: %S\n", originStr, prop.propName, buffer); - } - break; - case TMT_SIZE: - { - SIZE result1; - SIZE result2; - SIZE result3; - memset(&result1, 0, sizeof(result1)); - memset(&result2, 0, sizeof(result2)); - memset(&result3, 0, sizeof(result3)); - GetThemePartSize(themeData.handle(), 0, themeData.partId, themeData.stateId, 0, TS_MIN, &result1); - GetThemePartSize(themeData.handle(), 0, themeData.partId, themeData.stateId, 0, TS_TRUE, &result2); - GetThemePartSize(themeData.handle(), 0, themeData.partId, themeData.stateId, 0, TS_DRAW, &result3); - printf(" (%ssize) %-20S: Min (%d, %d), True(%d, %d), Draw(%d, %d)\n", originStr, prop.propName, - result1.cx, result1.cy, result2.cx, result2.cy, result3.cx, result3.cy); - } - break; - case TMT_POSITION: - { - POINT result; - memset(&result, 0, sizeof(result)); - GetThemePosition(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result); - printf(" (%sPosition)%-20S: (%d, %d)\n", originStr, prop.propName, result.x, result.y); - } - break; - case TMT_RECT: - { - RECT result; - memset(&result, 0, sizeof(result)); - GetThemeRect(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result); - printf(" (%sRect) %-20S: (%d, %d, %d, %d)\n", originStr, prop.propName, result.left, result.top, result.right, result.bottom); - } - break; - case TMT_FONT: - { - LOGFONT result; - memset(&result, 0, sizeof(result)); - GetThemeFont(themeData.handle(), 0, themeData.partId, themeData.stateId, prop.propValue, &result); - printf(" (%sFont) %-20S: %S height(%d) width(%d) weight(%d)\n", originStr, prop.propName, - result.lfFaceName, result.lfHeight, result.lfWidth, result.lfWeight); - } - break; - case TMT_INTLIST: - { - INTLIST result; - memset(&result, 0, sizeof(result)); - GetThemeIntList(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result); - printf(" (%sInt list)%-20S: { ", originStr, prop.propName); - for (int i = 0; i < result.iValueCount; ++i) - printf("%d ", result.iValues[i]); - printf("}\n"); - } - break; - default: - printf(" %s%S : Unknown property type (%d)!\n", originStr, prop.propName, prop.propType); - } -} - -/*! \internal - Dump all valid properties for a part. - If it's the first time this function is called, then the name, - enum value and documentation of all properties are shown, as - well as all global properties. -*/ -void QWindowsXPStylePrivate::showProperties(XPThemeData &themeData) -{ - if (!all_props.count()) { - const TMSCHEMAINFO *infoTable = GetSchemaInfo(); - for (int i = 0; i < infoTable->iPropCount; ++i) { - int propType = infoTable->pPropTable[i].bPrimVal; - int propValue = infoTable->pPropTable[i].sEnumVal; - LPCWSTR propName = infoTable->pPropTable[i].pszName; - - switch(propType) { - case TMT_ENUMDEF: - case TMT_ENUMVAL: - continue; - default: - if (propType != propValue) { - PropPair prop; - prop.propValue = propValue; - prop.propName = propName; - prop.propType = propType; - all_props.append(prop); - } - } - } - std::sort(all_props.begin(), all_props.end()); - - {// List all properties - printf("part properties count = %d:\n", all_props.count()); - printf(" Enum Property Name Description\n"); - printf("-----------------------------------------------------------\n"); - wchar_t themeName[256]; - pGetCurrentThemeName(themeName, 256, 0, 0, 0, 0); - for (int j = 0; j < all_props.count(); ++j) { - PropPair prop = all_props.at(j); - wchar_t buf[500]; - GetThemeDocumentationProperty(themeName, prop.propName, buf, 500); - printf("%3d: (%4d) %-20S %S\n", j, prop.propValue, prop.propName, buf); - } - } - - {// Show Global values - printf("Global Properties:\n"); - for (int j = 0; j < all_props.count(); ++j) { - PropPair prop = all_props.at(j); - PROPERTYORIGIN origin = PO_NOTFOUND; - GetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &origin); - if (origin == PO_GLOBAL) { - showProperty(themeData, prop); - } - } - } - } - - for (int j = 0; j < all_props.count(); ++j) { - PropPair prop = all_props.at(j); - PROPERTYORIGIN origin = PO_NOTFOUND; - GetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &origin); - if (origin != PO_NOTFOUND) - { - showProperty(themeData, prop); - } - } -} -#endif -// Debugging code -----------------------------------------------------------------------[ END ]--- - - -QT_END_NAMESPACE - -#endif //QT_NO_WINDOWSXP diff --git a/src/widgets/styles/qwindowsxpstyle_p.h b/src/widgets/styles/qwindowsxpstyle_p.h deleted file mode 100644 index 62e3af927c..0000000000 --- a/src/widgets/styles/qwindowsxpstyle_p.h +++ /dev/null @@ -1,109 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef QWINDOWSXPSTYLE_P_H -#define QWINDOWSXPSTYLE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtWidgets/private/qtwidgetsglobal_p.h> -#include <private/qwindowsstyle_p.h> - -QT_BEGIN_NAMESPACE - - -#if QT_CONFIG(style_windowsxp) - -class QWindowsXPStylePrivate; -class QWindowsXPStyle : public QWindowsStyle -{ - Q_OBJECT -public: - QWindowsXPStyle(); - QWindowsXPStyle(QWindowsXPStylePrivate &dd); - ~QWindowsXPStyle(); - - void unpolish(QApplication*); - void polish(QApplication*); - void polish(QWidget*); - void polish(QPalette&); - void unpolish(QWidget*); - - void drawPrimitive(PrimitiveElement pe, const QStyleOption *option, QPainter *p, - const QWidget *widget = 0) const; - void drawControl(ControlElement element, const QStyleOption *option, QPainter *p, - const QWidget *wwidget = 0) const; - QRect subElementRect(SubElement r, const QStyleOption *option, const QWidget *widget = 0) const; - QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *option, SubControl sc, - const QWidget *widget = 0) const; - void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option, QPainter *p, - const QWidget *widget = 0) const; - QSize sizeFromContents(ContentsType ct, const QStyleOption *option, const QSize &contentsSize, - const QWidget *widget = 0) const; - int pixelMetric(PixelMetric pm, const QStyleOption *option = 0, - const QWidget *widget = 0) const; - int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0, - QStyleHintReturn *returnData = 0) const; - - QPalette standardPalette() const; - QPixmap standardPixmap(StandardPixmap standardIcon, const QStyleOption *option, - const QWidget *widget = 0) const; - QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = 0, - const QWidget *widget = 0) const; - -private: - Q_DISABLE_COPY(QWindowsXPStyle) - Q_DECLARE_PRIVATE(QWindowsXPStyle) - friend class QStyleFactory; -}; - -#endif // style_windowsxp - -QT_END_NAMESPACE - -#endif // QWINDOWSXPSTYLE_P_H diff --git a/src/widgets/styles/qwindowsxpstyle_p_p.h b/src/widgets/styles/qwindowsxpstyle_p_p.h deleted file mode 100644 index fb5210cb07..0000000000 --- a/src/widgets/styles/qwindowsxpstyle_p_p.h +++ /dev/null @@ -1,345 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef QWINDOWSXPSTYLE_P_P_H -#define QWINDOWSXPSTYLE_P_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header -// file may change from version to version without notice, or even be removed. -// -// We mean it. -// - -#include <QtWidgets/private/qtwidgetsglobal_p.h> -#include "qwindowsxpstyle_p.h" -#include "qwindowsstyle_p_p.h" -#include <qmap.h> -#include <qt_windows.h> - -#include <uxtheme.h> -#include <vssym32.h> - -#include <limits.h> - -QT_BEGIN_NAMESPACE - -// TMT_TEXTSHADOWCOLOR is wrongly defined in mingw -#if TMT_TEXTSHADOWCOLOR != 3818 -#undef TMT_TEXTSHADOWCOLOR -#define TMT_TEXTSHADOWCOLOR 3818 -#endif -#ifndef TST_NONE -# define TST_NONE 0 -#endif - -// These defines are missing from the tmschema, but still exist as -// states for their parts -#ifndef MINBS_INACTIVE -#define MINBS_INACTIVE 5 -#endif -#ifndef MAXBS_INACTIVE -#define MAXBS_INACTIVE 5 -#endif -#ifndef RBS_INACTIVE -#define RBS_INACTIVE 5 -#endif -#ifndef HBS_INACTIVE -#define HBS_INACTIVE 5 -#endif -#ifndef CBS_INACTIVE -#define CBS_INACTIVE 5 -#endif - -// Uncomment define below to build debug assisting code, and output -// #define DEBUG_XP_STYLE - -#if QT_CONFIG(style_windowsxp) - -// Declarations ----------------------------------------------------------------------------------- -class XPThemeData -{ -public: - explicit XPThemeData(const QWidget *w = 0, QPainter *p = 0, int themeIn = -1, - int part = 0, int state = 0, const QRect &r = QRect()) - : widget(w), painter(p), theme(themeIn), htheme(0), partId(part), stateId(state), - mirrorHorizontally(false), mirrorVertically(false), noBorder(false), - noContent(false), rotate(0), rect(r) - {} - - HRGN mask(QWidget *widget); - HTHEME handle(); - - static RECT toRECT(const QRect &qr); - bool isValid(); - - QSizeF size(); - QMarginsF margins(const QRect &rect, int propId = TMT_CONTENTMARGINS); - QMarginsF margins(int propId = TMT_CONTENTMARGINS); - - static QSizeF themeSize(const QWidget *w = 0, QPainter *p = 0, int themeIn = -1, int part = 0, int state = 0); - static QMarginsF themeMargins(const QRect &rect, const QWidget *w = 0, QPainter *p = 0, int themeIn = -1, - int part = 0, int state = 0, int propId = TMT_CONTENTMARGINS); - static QMarginsF themeMargins(const QWidget *w = 0, QPainter *p = 0, int themeIn = -1, - int part = 0, int state = 0, int propId = TMT_CONTENTMARGINS); - - const QWidget *widget; - QPainter *painter; - - int theme; - HTHEME htheme; - int partId; - int stateId; - - uint mirrorHorizontally : 1; - uint mirrorVertically : 1; - uint noBorder : 1; - uint noContent : 1; - uint rotate; - QRect rect; -}; - -struct ThemeMapKey { - int theme; - int partId; - int stateId; - bool noBorder; - bool noContent; - - ThemeMapKey() : partId(-1), stateId(-1) {} - ThemeMapKey(const XPThemeData &data) - : theme(data.theme), partId(data.partId), stateId(data.stateId), - noBorder(data.noBorder), noContent(data.noContent) {} - -}; - -inline uint qHash(const ThemeMapKey &key) -{ return key.theme ^ key.partId ^ key.stateId; } - -inline bool operator==(const ThemeMapKey &k1, const ThemeMapKey &k2) -{ - return k1.theme == k2.theme - && k1.partId == k2.partId - && k1.stateId == k2.stateId; -} - -enum AlphaChannelType { - UnknownAlpha = -1, // Alpha of part & state not yet known - NoAlpha, // Totally opaque, no need to touch alpha (RGB) - MaskAlpha, // Alpha channel must be fixed (ARGB) - RealAlpha // Proper alpha values from Windows (ARGB_Premultiplied) -}; - -struct ThemeMapData { - AlphaChannelType alphaType; // Which type of alpha on part & state - - bool dataValid : 1; // Only used to detect if hash value is ok - bool partIsTransparent : 1; - bool hasAlphaChannel : 1; // True = part & state has real Alpha - bool wasAlphaSwapped : 1; // True = alpha channel needs to be swapped - bool hadInvalidAlpha : 1; // True = alpha channel contained invalid alpha values - - ThemeMapData() : dataValid(false), partIsTransparent(false), - hasAlphaChannel(false), wasAlphaSwapped(false), hadInvalidAlpha(false) {} -}; - -class QWindowsXPStylePrivate : public QWindowsStylePrivate -{ - Q_DECLARE_PUBLIC(QWindowsXPStyle) -public: - enum Theme { - ButtonTheme, - ComboboxTheme, - EditTheme, - HeaderTheme, - ListViewTheme, - MenuTheme, - ProgressTheme, - RebarTheme, - ScrollBarTheme, - SpinTheme, - TabTheme, - TaskDialogTheme, - ToolBarTheme, - ToolTipTheme, - TrackBarTheme, - XpTreeViewTheme, // '+'/'-' shape treeview indicators (XP) - WindowTheme, - StatusTheme, - VistaTreeViewTheme, // arrow shape treeview indicators (Vista) obtained from "explorer" theme. - NThemes - }; - - QWindowsXPStylePrivate() - : QWindowsStylePrivate(), hasInitColors(false), bufferDC(0), bufferBitmap(0), nullBitmap(0), - bufferPixels(0), bufferW(0), bufferH(0) - { init(); } - - ~QWindowsXPStylePrivate() - { cleanup(); } - - static int pixelMetricFromSystemDp(QStyle::PixelMetric pm, const QStyleOption *option = 0, const QWidget *widget = 0); - static int fixedPixelMetric(QStyle::PixelMetric pm, const QStyleOption *option = 0, const QWidget *widget = 0); - - static HWND winId(const QWidget *widget); - - void init(bool force = false); - void cleanup(bool force = false); - void cleanupHandleMap(); - const QPixmap *tabBody(QWidget *widget); - - HBITMAP buffer(int w = 0, int h = 0); - HDC bufferHDC() - { return bufferDC;} - - static bool useXP(bool update = false); - static QRect scrollBarGripperBounds(QStyle::State flags, const QWidget *widget, XPThemeData *theme); - - bool isTransparent(XPThemeData &themeData); - QRegion region(XPThemeData &themeData); - - void setTransparency(QWidget *widget, XPThemeData &themeData); - bool drawBackground(XPThemeData &themeData); - bool drawBackgroundThruNativeBuffer(XPThemeData &themeData, qreal aditionalDevicePixelRatio); - bool drawBackgroundDirectly(HDC dc, XPThemeData &themeData, qreal aditionalDevicePixelRatio); - - bool hasAlphaChannel(const QRect &rect); - bool fixAlphaChannel(const QRect &rect); - bool swapAlphaChannel(const QRect &rect, bool allPixels = false); - - QRgb groupBoxTextColor; - QRgb groupBoxTextColorDisabled; - QRgb sliderTickColor; - bool hasInitColors; - - static HTHEME createTheme(int theme, HWND hwnd); - static QString themeName(int theme); - static inline bool hasTheme(int theme) { return theme >= 0 && theme < NThemes && m_themes[theme]; } - static bool isItemViewDelegateLineEdit(const QWidget *widget); - static bool isLineEditBaseColorSet(const QStyleOption *option, const QWidget *widget); - - QIcon dockFloat, dockClose; - -private: -#ifdef DEBUG_XP_STYLE - void dumpNativeDIB(int w, int h); - void showProperties(XPThemeData &themeData); -#endif - - static bool initVistaTreeViewTheming(); - static void cleanupVistaTreeViewTheming(); - - static QBasicAtomicInt ref; - static bool use_xp; - static QPixmap *tabbody; - - QHash<ThemeMapKey, ThemeMapData> alphaCache; - HDC bufferDC; - HBITMAP bufferBitmap; - HBITMAP nullBitmap; - uchar *bufferPixels; - int bufferW, bufferH; - - static HWND m_vistaTreeViewHelper; - static HTHEME m_themes[NThemes]; -}; - -inline QSizeF XPThemeData::size() -{ - QSizeF result(0, 0); - if (isValid()) { - SIZE size; - if (SUCCEEDED(GetThemePartSize(handle(), 0, partId, stateId, 0, TS_TRUE, &size))) - result = QSize(size.cx, size.cy); - } - return result; -} - -inline QMarginsF XPThemeData::margins(const QRect &qRect, int propId) -{ - QMarginsF result(0, 0, 0 ,0); - if (isValid()) { - MARGINS margins; - RECT rect = XPThemeData::toRECT(qRect); - if (SUCCEEDED(GetThemeMargins(handle(), 0, partId, stateId, propId, &rect, &margins))) - result = QMargins(margins.cxLeftWidth, margins.cyTopHeight, margins.cxRightWidth, margins.cyBottomHeight); - } - return result; -} - -inline QMarginsF XPThemeData::margins(int propId) -{ - QMarginsF result(0, 0, 0 ,0); - if (isValid()) { - MARGINS margins; - if (SUCCEEDED(GetThemeMargins(handle(), 0, partId, stateId, propId, NULL, &margins))) - result = QMargins(margins.cxLeftWidth, margins.cyTopHeight, margins.cxRightWidth, margins.cyBottomHeight); - } - return result; -} - -inline QSizeF XPThemeData::themeSize(const QWidget *w, QPainter *p, int themeIn, int part, int state) -{ - XPThemeData theme(w, p, themeIn, part, state); - return theme.size(); -} - -inline QMarginsF XPThemeData::themeMargins(const QRect &rect, const QWidget *w, QPainter *p, int themeIn, - int part, int state, int propId) -{ - XPThemeData theme(w, p, themeIn, part, state); - return theme.margins(rect, propId); -} - -inline QMarginsF XPThemeData::themeMargins(const QWidget *w, QPainter *p, int themeIn, - int part, int state, int propId) -{ - XPThemeData theme(w, p, themeIn, part, state); - return theme.margins(propId); -} - -#endif // style_windows - -QT_END_NAMESPACE - -#endif //QWINDOWSXPSTYLE_P_P_H diff --git a/src/widgets/styles/styles.pri b/src/widgets/styles/styles.pri index 481123f0d4..0c0f8b7bc7 100644 --- a/src/widgets/styles/styles.pri +++ b/src/widgets/styles/styles.pri @@ -37,24 +37,6 @@ RESOURCES += styles/qstyle.qrc include($$OUT_PWD/qtwidgets-config.pri) -qtConfig(style-mac) { - HEADERS += \ - styles/qmacstyle_mac_p.h \ - styles/qmacstyle_mac_p_p.h - OBJECTIVE_SOURCES += styles/qmacstyle_mac.mm - LIBS_PRIVATE += -framework Carbon -} - -qtConfig(style-windowsvista) { - HEADERS += styles/qwindowsvistastyle_p.h styles/qwindowsvistastyle_p_p.h - SOURCES += styles/qwindowsvistastyle.cpp -} - -qtConfig(style-windowsxp) { - HEADERS += styles/qwindowsxpstyle_p.h styles/qwindowsxpstyle_p_p.h - SOURCES += styles/qwindowsxpstyle.cpp -} - qtConfig(style-windows) { HEADERS += styles/qwindowsstyle_p.h styles/qwindowsstyle_p_p.h SOURCES += styles/qwindowsstyle.cpp @@ -64,8 +46,3 @@ qtConfig(style-fusion) { HEADERS += styles/qfusionstyle_p.h styles/qfusionstyle_p_p.h SOURCES += styles/qfusionstyle.cpp } - -qtConfig(style-android) { - HEADERS += styles/qandroidstyle_p.h - SOURCES += styles/qandroidstyle.cpp -} |