diff options
Diffstat (limited to 'src/widgets/styles/qwindowsstyle.cpp')
-rw-r--r-- | src/widgets/styles/qwindowsstyle.cpp | 233 |
1 files changed, 64 insertions, 169 deletions
diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp index e6198540a3..bae182b467 100644 --- a/src/widgets/styles/qwindowsstyle.cpp +++ b/src/widgets/styles/qwindowsstyle.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qwindowsstyle_p.h" #include "qwindowsstyle_p_p.h" @@ -124,26 +88,6 @@ enum QSliderDirection { SlUp, SlDown, SlLeft, SlRight }; QWindowsStylePrivate::QWindowsStylePrivate() = default; -qreal QWindowsStylePrivate::appDevicePixelRatio() -{ - return qApp->devicePixelRatio(); -} - -bool QWindowsStylePrivate::isDarkMode() -{ - bool result = false; -#ifdef Q_OS_WIN - using QWindowsApplication = QNativeInterface::Private::QWindowsApplication; - // Windows only: Return whether dark mode style support is desired and - // dark mode is in effect. - if (auto windowsApp = dynamic_cast<QWindowsApplication *>(QGuiApplicationPrivate::platformIntegration())) { - result = windowsApp->isDarkMode() - && windowsApp->darkModeHandling().testFlag(QWindowsApplication::DarkModeStyle); - } -#endif - return result; -} - // Returns \c true if the toplevel parent of \a widget has seen the Alt-key bool QWindowsStylePrivate::hasSeenAlt(const QWidget *widget) const { @@ -168,19 +112,20 @@ bool QWindowsStyle::eventFilter(QObject *o, QEvent *e) widget = widget->window(); // Alt has been pressed - find all widgets that care - QList<QWidget *> l = widget->findChildren<QWidget *>(); + const QList<QWidget *> children = widget->findChildren<QWidget *>(); auto ignorable = [](QWidget *w) { return w->isWindow() || !w->isVisible() || w->style()->styleHint(SH_UnderlineShortcut, nullptr, w); }; - l.removeIf(ignorable); // Update states before repainting d->seenAlt.append(widget); d->alt_down = true; // Repaint all relevant widgets - for (int pos = 0; pos < l.size(); ++pos) - l.at(pos)->update(); + for (QWidget *w : children) { + if (!ignorable(w)) + w->update(); + } } break; case QEvent::KeyRelease: @@ -190,9 +135,9 @@ bool QWindowsStyle::eventFilter(QObject *o, QEvent *e) // Update state and repaint the menu bars. d->alt_down = false; #if QT_CONFIG(menubar) - QList<QMenuBar *> l = widget->findChildren<QMenuBar *>(); - for (int i = 0; i < l.size(); ++i) - l.at(i)->update(); + const QList<QMenuBar *> menuBars = widget->findChildren<QMenuBar *>(); + for (QWidget *w : menuBars) + w->update(); #endif } break; @@ -312,28 +257,33 @@ void QWindowsStyle::polish(QPalette &pal) int QWindowsStylePrivate::pixelMetricFromSystemDp(QStyle::PixelMetric pm, const QStyleOption *, const QWidget *widget) { #if defined(Q_OS_WIN) + // The pixel metrics are in device indepentent pixels; + // hardcode DPI to 1x 96 DPI. + const int dpi = 96; + switch (pm) { case QStyle::PM_DockWidgetFrameWidth: - return GetSystemMetrics(SM_CXFRAME); - - case QStyle::PM_TitleBarHeight: - if (widget && (widget->windowType() == Qt::Tool)) { - // MS always use one less than they say - return GetSystemMetrics(SM_CYSMCAPTION) - 1; - } - return GetSystemMetrics(SM_CYCAPTION) - 1; + return GetSystemMetricsForDpi(SM_CXFRAME, dpi); + + case QStyle::PM_TitleBarHeight: { + const int resizeBorderThickness = + GetSystemMetricsForDpi(SM_CXSIZEFRAME, dpi) + GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi); + if (widget && (widget->windowType() == Qt::Tool)) + return GetSystemMetricsForDpi(SM_CYSMCAPTION, dpi) + resizeBorderThickness; + return GetSystemMetricsForDpi(SM_CYCAPTION, dpi) + resizeBorderThickness; + } case QStyle::PM_ScrollBarExtent: { NONCLIENTMETRICS ncm; - ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT); - if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0)) + ncm.cbSize = sizeof(NONCLIENTMETRICS); + if (SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0, dpi)) return qMax(ncm.iScrollHeight, ncm.iScrollWidth); } break; case QStyle::PM_MdiSubWindowFrameWidth: - return GetSystemMetrics(SM_CYFRAME); + return GetSystemMetricsForDpi(SM_CYFRAME, dpi); default: break; @@ -405,22 +355,10 @@ static QScreen *screenOf(const QWidget *w) } // Calculate the overall scale factor to obtain Qt Device Independent -// Pixels from a native Windows size. Divide by devicePixelRatio -// and account for secondary screens with differing logical DPI. +// Pixels from a native Windows size. qreal QWindowsStylePrivate::nativeMetricScaleFactor(const QWidget *widget) { - qreal result = qreal(1) / QWindowsStylePrivate::devicePixelRatio(widget); - if (QGuiApplicationPrivate::screen_list.size() > 1) { - const QScreen *primaryScreen = QGuiApplication::primaryScreen(); - const QScreen *screen = screenOf(widget); - if (screen != primaryScreen) { - const qreal primaryLogicalDpi = primaryScreen->handle()->logicalDpi().first; - const qreal logicalDpi = screen->handle()->logicalDpi().first; - if (!qFuzzyCompare(primaryLogicalDpi, logicalDpi)) - result *= logicalDpi / primaryLogicalDpi; - } - } - return result; + return qreal(1) / QHighDpiScaling::factor(screenOf(widget)); } /*! @@ -430,7 +368,7 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW { int ret = QWindowsStylePrivate::pixelMetricFromSystemDp(pm, opt, widget); if (ret != QWindowsStylePrivate::InvalidMetric) - return qRound(qreal(ret) * QWindowsStylePrivate::nativeMetricScaleFactor(widget)); + return ret; ret = QWindowsStylePrivate::fixedPixelMetric(pm); if (ret != QWindowsStylePrivate::InvalidMetric) @@ -440,7 +378,7 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW switch (pm) { case PM_MaximumDragDistance: - ret = QCommonStyle::pixelMetric(PM_MaximumDragDistance); + ret = QCommonStyle::pixelMetric(PM_MaximumDragDistance, opt, widget); if (ret == -1) ret = 60; break; @@ -497,46 +435,6 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW QPixmap QWindowsStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget) const { -#if defined(Q_OS_WIN) - QPixmap desktopIcon; - switch(standardPixmap) { - case SP_DriveCDIcon: - case SP_DriveDVDIcon: - case SP_DriveNetIcon: - case SP_DriveHDIcon: - case SP_DriveFDIcon: - case SP_FileIcon: - case SP_FileLinkIcon: - case SP_DirLinkIcon: - case SP_DirClosedIcon: - case SP_DesktopIcon: - case SP_ComputerIcon: - case SP_DirOpenIcon: - case SP_FileDialogNewFolder: - case SP_DirHomeIcon: - case SP_TrashIcon: - case SP_VistaShield: - if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { - QPlatformTheme::StandardPixmap sp = static_cast<QPlatformTheme::StandardPixmap>(standardPixmap); - desktopIcon = theme->standardPixmap(sp, QSizeF(16, 16)); - } - break; - case SP_MessageBoxInformation: - case SP_MessageBoxWarning: - case SP_MessageBoxCritical: - case SP_MessageBoxQuestion: - if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { - QPlatformTheme::StandardPixmap sp = static_cast<QPlatformTheme::StandardPixmap>(standardPixmap); - desktopIcon = theme->standardPixmap(sp, QSizeF()); - } - break; - default: - break; - } - if (!desktopIcon.isNull()) { - return desktopIcon; - } -#endif // Q_OS_WIN return QCommonStyle::standardPixmap(standardPixmap, opt, widget); } @@ -547,9 +445,14 @@ int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWid int ret = 0; switch (hint) { - case SH_EtchDisabledText: - ret = d_func()->isDarkMode() ? 0 : 1; + case SH_EtchDisabledText: { + const QPalette pal = opt ? opt->palette + : widget ? widget->palette() + : QPalette(); + ret = pal.window().color().lightness() > pal.text().color().lightness() + ? 1 : 0; break; + } case SH_Slider_SnapToValue: case SH_PrintDialog_RightAlignButtons: case SH_FontDialog_SelectAssociatedText: @@ -604,12 +507,12 @@ int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWid ret = 1; } } -#ifndef QT_NO_ACCESSIBILITY +#if QT_CONFIG(accessibility) if (!ret && opt && opt->type == QStyleOption::SO_MenuItem && QStyleHelper::isInstanceOf(opt->styleObject, QAccessible::MenuItem) && opt->styleObject->property("_q_showUnderlined").toBool()) ret = 1; -#endif // QT_NO_ACCESSIBILITY +#endif // QT_CONFIG(accessibility) break; } #endif // Q_OS_WIN @@ -853,7 +756,7 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, } #endif // QT_CONFIG(itemviews) if (!(opt->state & State_Off)) { - QPointF points[6]; + std::array<QPointF, 6> points; qreal scaleh = opt->rect.width() / 12.0; qreal scalev = opt->rect.height() / 12.0; points[0] = { opt->rect.x() + qreal(3.5) * scaleh, opt->rect.y() + qreal(5.5) * scalev }; @@ -864,7 +767,7 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, points[5] = { points[4].x() - 4 * scaleh, points[4].y() + 4 * scalev }; p->setPen(QPen(opt->palette.text().color(), 0)); p->setBrush(opt->palette.text().color()); - p->drawPolygon(points, 6); + p->drawPolygon(points.data(), static_cast<int>(points.size())); } if (doRestore) p->restore(); @@ -1157,9 +1060,7 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, opt, widget), mode, QIcon::On); else pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, opt, widget), mode); - const int pixw = pixmap.width() / pixmap.devicePixelRatio(); - const int pixh = pixmap.height() / pixmap.devicePixelRatio(); - QRect pmr(0, 0, pixw, pixh); + QRect pmr(QPoint(0, 0), pixmap.deviceIndependentSize().toSize()); pmr.moveCenter(vCheckRect.center()); p->setPen(menuitem->palette.text().color()); p->drawPixmap(pmr.topLeft(), pixmap); @@ -1169,7 +1070,7 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai if (!dis) newMi.state |= State_Enabled; if (act) - newMi.state |= State_On; + newMi.state |= State_On | State_Selected; newMi.rect = visualRect(opt->direction, menuitem->rect, QRect(menuitem->rect.x() + QWindowsStylePrivate::windowsItemFrame, menuitem->rect.y() + QWindowsStylePrivate::windowsItemFrame, checkcol - 2 * QWindowsStylePrivate::windowsItemFrame, @@ -1192,7 +1093,7 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai QStringView s(menuitem->text); if (!s.isEmpty()) { // draw text p->save(); - int t = s.indexOf(QLatin1Char('\t')); + qsizetype t = s.indexOf(u'\t'); int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine; if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget)) text_flags |= Qt::TextHideMnemonic; @@ -1618,11 +1519,8 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai default: break; } - if (opt->direction == Qt::RightToLeft){ //reverse layout changes the order of Beginning/end - bool tmp = paintLeftBorder; - paintRightBorder=paintLeftBorder; - paintLeftBorder=tmp; - } + if (opt->direction == Qt::RightToLeft) //reverse layout changes the order of Beginning/end + std::swap(paintLeftBorder, paintRightBorder); break; case Qt::RightToolBarArea : switch (toolbar->positionOfLine){ @@ -1834,7 +1732,7 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai titleRect.height(), titleRect.width()); } proxy()->drawItemText(p, titleRect, - Qt::AlignLeft | Qt::AlignVCenter, palette, + Qt::AlignLeft | Qt::AlignVCenter | Qt::TextHideMnemonic, palette, dwOpt->state & State_Enabled, dwOpt->title, floating ? (active ? QPalette::BrightText : QPalette::Window) : QPalette::WindowText); p->setFont(oldFont); @@ -1997,39 +1895,36 @@ void QWindowsStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComp QSliderDirection dir; if (orient == Qt::Horizontal) - if (tickAbove) - dir = SlUp; - else - dir = SlDown; + dir = tickAbove ? SlUp : SlDown; else - if (tickAbove) - dir = SlLeft; - else - dir = SlRight; - - QPolygon a; + dir = tickAbove ? SlLeft : SlRight; + std::array<QPoint, 5> points; int d = 0; switch (dir) { case SlUp: - y1 = y1 + wi/2; + y1 = y1 + wi / 2; d = (wi + 1) / 2 - 1; - a.setPoints(5, x1,y1, x1,y2, x2,y2, x2,y1, x1+d,y1-d); + points = {QPoint(x1, y1), QPoint(x1, y2), QPoint(x2, y2), + QPoint(x2, y1), QPoint(x1 + d, y1 - d)}; break; case SlDown: - y2 = y2 - wi/2; + y2 = y2 - wi / 2; d = (wi + 1) / 2 - 1; - a.setPoints(5, x1,y1, x1,y2, x1+d,y2+d, x2,y2, x2,y1); + points = {QPoint(x1, y1), QPoint(x1, y2), QPoint(x1 + d, y2 + d), + QPoint(x2, y2), QPoint(x2, y1)}; break; case SlLeft: d = (he + 1) / 2 - 1; - x1 = x1 + he/2; - a.setPoints(5, x1,y1, x1-d,y1+d, x1,y2, x2,y2, x2,y1); + x1 = x1 + he / 2; + points = {QPoint(x1, y1), QPoint(x1 - d, y1 + d), QPoint(x1,y2), + QPoint(x2, y2), QPoint(x2, y1)}; break; case SlRight: d = (he + 1) / 2 - 1; - x2 = x2 - he/2; - a.setPoints(5, x1,y1, x1,y2, x2,y2, x2+d,y1+d, x2,y1); + x2 = x2 - he / 2; + points = {QPoint(x1, y1), QPoint(x1, y2), QPoint(x2, y2), + QPoint(x2 + d, y1 + d), QPoint(x2, y1)}; break; } @@ -2039,7 +1934,7 @@ void QWindowsStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComp Qt::BGMode oldMode = p->backgroundMode(); p->setBackgroundMode(Qt::OpaqueMode); p->drawRect(x1, y1, x2-x1+1, y2-y1+1); - p->drawPolygon(a); + p->drawPolygon(points.data(), static_cast<int>(points.size())); p->setBrush(oldBrush); p->setBackgroundMode(oldMode); @@ -2350,7 +2245,7 @@ QSize QWindowsStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, } int maxpmw = mi->maxIconWidth; int tabSpacing = 20; - if (mi->text.contains(QLatin1Char('\t'))) + if (mi->text.contains(u'\t')) w += tabSpacing; else if (mi->menuItemType == QStyleOptionMenuItem::SubMenu) w += 2 * QWindowsStylePrivate::windowsArrowHMargin; |