diff options
Diffstat (limited to 'src/gui/kernel/qpalette.cpp')
-rw-r--r-- | src/gui/kernel/qpalette.cpp | 168 |
1 files changed, 77 insertions, 91 deletions
diff --git a/src/gui/kernel/qpalette.cpp b/src/gui/kernel/qpalette.cpp index 396bd46ea6..256ea52f01 100644 --- a/src/gui/kernel/qpalette.cpp +++ b/src/gui/kernel/qpalette.cpp @@ -1,8 +1,7 @@ // 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 "qpalette.h" -#include "qguiapplication.h" +#include "qpalette_p.h" #include "qguiapplication_p.h" #include "qdatastream.h" #include "qvariant.h" @@ -12,48 +11,11 @@ QT_BEGIN_NAMESPACE -static int qt_palette_count = 1; - -static constexpr QPalette::ResolveMask colorRoleOffset(QPalette::ColorGroup colorGroup) -{ - return qToUnderlying(QPalette::NColorRoles) * qToUnderlying(colorGroup); -} - -static constexpr QPalette::ResolveMask bitPosition(QPalette::ColorGroup colorGroup, - QPalette::ColorRole colorRole) -{ - return colorRole + colorRoleOffset(colorGroup); -} - -static_assert(bitPosition(QPalette::ColorGroup(QPalette::NColorGroups - 1), +static_assert(QPalettePrivate::bitPosition(QPalette::ColorGroup(QPalette::NColorGroups - 1), QPalette::ColorRole(QPalette::NColorRoles - 1)) < sizeof(QPalette::ResolveMask) * CHAR_BIT, "The resolve mask type is not wide enough to fit the entire bit mask."); -class QPalettePrivate -{ -public: - class Data : public QSharedData { - public: - Data() : ser_no(qt_palette_count++) { } - - QBrush br[QPalette::NColorGroups][QPalette::NColorRoles]; - const int ser_no; - }; - - QPalettePrivate(const QExplicitlySharedDataPointer<Data> &data) - : ref(1), detach_no(0), data(data) - { } - QPalettePrivate() - : QPalettePrivate(QExplicitlySharedDataPointer<Data>(new Data)) - { } - - QAtomicInt ref; - QPalette::ResolveMask resolveMask = {0}; - int detach_no; - QExplicitlySharedDataPointer<Data> data; -}; - static QColor qt_mix_colors(QColor a, QColor b) { return QColor((a.red() + b.red()) / 2, (a.green() + b.green()) / 2, @@ -88,6 +50,24 @@ static void qt_placeholder_from_text(QPalette &pal, int alpha = 50) } } +static void qt_ensure_default_accent_color(QPalette &pal) +{ + // have a lighter/darker factor handy, depending on dark/light heuristics + const int lighter = pal.base().color().lightness() > pal.text().color().lightness() ? 130 : 70; + + // Act only for color groups where no accent color is set + for (int i = 0; i < QPalette::NColorGroups; ++i) { + const QPalette::ColorGroup group = static_cast<QPalette::ColorGroup>(i); + if (!pal.isBrushSet(group, QPalette::Accent)) { + // Default to highlight if available, otherwise use a shade of base + const QBrush accentBrush = pal.isBrushSet(group, QPalette::Highlight) + ? pal.brush(group, QPalette::Highlight) + : pal.brush(group, QPalette::Base).color().lighter(lighter); + pal.setBrush(group, QPalette::Accent, accentBrush); + } + } +} + static void qt_palette_from_color(QPalette &pal, const QColor &button) { int h, s, v; @@ -112,6 +92,7 @@ static void qt_palette_from_color(QPalette &pal, const QColor &button) whiteBrush, buttonBrush, buttonBrush); qt_placeholder_from_text(pal); + qt_ensure_default_accent_color(pal); } /*! @@ -313,6 +294,15 @@ static void qt_palette_from_color(QPalette &pal, const QColor &button) */ /*! + \fn const QBrush & QPalette::accent() const + \since 6.6 + + Returns the accent brush of the current color group. + + \sa ColorRole, brush() +*/ + +/*! \fn const QBrush & QPalette::link() const Returns the unvisited link text brush of the current color group. @@ -512,6 +502,13 @@ static void qt_palette_from_color(QPalette &pal, const QColor &button) item. By default, the highlight color is Qt::darkBlue. + \value [since 6.6] Accent + A color that typically contrasts or complements + Base, Window and Button colors. It usually represents + the users' choice of desktop personalisation. + Styling of interactive components is a typical use case. + Unless explicitly set, it defaults to Highlight. + \value HighlightedText A text color that contrasts with \c Highlight. By default, the highlighted text color is Qt::white. @@ -601,6 +598,7 @@ QPalette::QPalette(const QBrush &windowText, const QBrush &button, base, window); qt_placeholder_from_text(*this); + qt_ensure_default_accent_color(*this); } @@ -658,6 +656,7 @@ QPalette::QPalette(const QColor &button, const QColor &window) whiteBrush, baseBrush, windowBrush); qt_placeholder_from_text(*this); + qt_ensure_default_accent_color(*this); } /*! @@ -795,7 +794,7 @@ void QPalette::setBrush(ColorGroup cg, ColorRole cr, const QBrush &b) cg = Active; } - const auto newResolveMask = d->resolveMask | ResolveMask(1) << bitPosition(cg, cr); + const auto newResolveMask = d->resolveMask | ResolveMask(1) << QPalettePrivate::bitPosition(cg, cr); const auto valueChanged = d->data->br[cg][cr] != b; if (valueChanged) { @@ -825,6 +824,10 @@ void QPalette::setBrush(ColorGroup cg, ColorRole cr, const QBrush &b) */ bool QPalette::isBrushSet(ColorGroup cg, ColorRole cr) const { + // NoRole has no resolve mask and should never be set anyway + if (cr == NoRole) + return false; + if (cg == Current) cg = currentGroup; @@ -838,7 +841,7 @@ bool QPalette::isBrushSet(ColorGroup cg, ColorRole cr) const return false; } - return d->resolveMask & (ResolveMask(1) << bitPosition(cg, cr)); + return d->resolveMask & (ResolveMask(1) << QPalettePrivate::bitPosition(cg, cr)); } /*! @@ -852,8 +855,9 @@ void QPalette::detach() if (!d->ref.deref()) delete d; d = x; + } else { + d->detach_no = ++QPalettePrivate::qt_palette_private_count; } - ++d->detach_no; } /*! @@ -872,8 +876,11 @@ void QPalette::detach() Returns \c true (usually quickly) if this palette is equal to \a p; otherwise returns \c false (slowly). - \note The current ColorGroup is not taken into account when - comparing palettes + \note The following is not taken into account when comparing palettes: + \list + \li the \c current ColorGroup + \li ColorRole NoRole \since 6.6 + \endlist \sa operator!=() */ @@ -883,6 +890,9 @@ bool QPalette::operator==(const QPalette &p) const return true; for(int grp = 0; grp < (int)NColorGroups; grp++) { for(int role = 0; role < (int)NColorRoles; role++) { + // Dont't verify NoRole, because it has no resolve bit + if (role == NoRole) + continue; if (d->data->br[grp][role] != p.d->data->br[grp][role]) return false; } @@ -940,7 +950,7 @@ static constexpr QPalette::ResolveMask allResolveMask() QPalette::ResolveMask mask = {0}; for (int role = 0; role < int(QPalette::NColorRoles); ++role) { for (int grp = 0; grp < int(QPalette::NColorGroups); ++grp) { - mask |= (QPalette::ResolveMask(1) << bitPosition(QPalette::ColorGroup(grp), QPalette::ColorRole(role))); + mask |= (QPalette::ResolveMask(1) << QPalettePrivate::bitPosition(QPalette::ColorGroup(grp), QPalette::ColorRole(role))); } } return mask; @@ -966,8 +976,12 @@ QPalette QPalette::resolve(const QPalette &other) const palette.detach(); for (int role = 0; role < int(NColorRoles); ++role) { + // Don't resolve NoRole, its bits are needed for Accent (see bitPosition) + if (role == NoRole) + continue; + for (int grp = 0; grp < int(NColorGroups); ++grp) { - if (!(d->resolveMask & (ResolveMask(1) << bitPosition(ColorGroup(grp), ColorRole(role))))) { + if (!(d->resolveMask & (ResolveMask(1) << QPalettePrivate::bitPosition(ColorGroup(grp), ColorRole(role))))) { palette.d->data.detach(); palette.d->data->br[grp][role] = other.d->data->br[grp][role]; } @@ -1041,6 +1055,9 @@ QDataStream &operator<<(QDataStream &s, const QPalette &p) max = QPalette::AlternateBase + 1; else if (s.version() <= QDataStream::Qt_5_11) max = QPalette::ToolTipText + 1; + else if (s.version() <= QDataStream::Qt_6_5) + max = QPalette::PlaceholderText + 1; + for (int r = 0; r < max; r++) s << p.d->data->br[grp][r]; } @@ -1084,15 +1101,25 @@ QDataStream &operator>>(QDataStream &s, QPalette &p) } else if (s.version() <= QDataStream::Qt_5_11) { p = QPalette(); max = QPalette::ToolTipText + 1; + } else if (s.version() <= QDataStream::Qt_6_5) { + p = QPalette(); + max = QPalette::PlaceholderText + 1; } + QBrush tmp; for(int grp = 0; grp < (int)QPalette::NColorGroups; ++grp) { + const QPalette::ColorGroup group = static_cast<QPalette::ColorGroup>(grp); for(int role = 0; role < max; ++role) { s >> tmp; - p.setBrush((QPalette::ColorGroup)grp, (QPalette::ColorRole)role, tmp); + p.setBrush(group, (QPalette::ColorRole)role, tmp); } + + // Accent defaults to Highlight for stream versions that don't have it. + if (s.version() < QDataStream::Qt_6_6) + p.setBrush(group, QPalette::Accent, p.brush(group, QPalette::Highlight)); } + } return s; } @@ -1139,10 +1166,10 @@ void QPalette::setColorGroup(ColorGroup cg, const QBrush &windowText, const QBru for (int cr = Highlight; cr <= LinkVisited; ++cr) { if (cg == All) { for (int group = Active; group < NColorGroups; ++group) { - d->resolveMask &= ~(ResolveMask(1) << bitPosition(ColorGroup(group), ColorRole(cr))); + d->resolveMask &= ~(ResolveMask(1) << QPalettePrivate::bitPosition(ColorGroup(group), ColorRole(cr))); } } else { - d->resolveMask &= ~(ResolveMask(1) << bitPosition(ColorGroup(cg), ColorRole(cr))); + d->resolveMask &= ~(ResolveMask(1) << QPalettePrivate::bitPosition(ColorGroup(cg), ColorRole(cr))); } } } @@ -1197,47 +1224,6 @@ void QPalette::setColorGroup(ColorGroup cg, const QBrush &foreground, const QBru setBrush(cg, ToolTipText, toolTipText); } -Q_GUI_EXPORT QPalette qt_fusionPalette() -{ - QColor backGround(239, 239, 239); - QColor light = backGround.lighter(150); - QColor mid(backGround.darker(130)); - QColor midLight = mid.lighter(110); - QColor base = Qt::white; - QColor disabledBase(backGround); - QColor dark = backGround.darker(150); - QColor darkDisabled = QColor(209, 209, 209).darker(110); - QColor text = Qt::black; - QColor hightlightedText = Qt::white; - QColor disabledText = QColor(190, 190, 190); - QColor button = backGround; - QColor shadow = dark.darker(135); - QColor disabledShadow = shadow.lighter(150); - QColor placeholder = text; - placeholder.setAlpha(128); - - QPalette fusionPalette(Qt::black,backGround,light,dark,mid,text,base); - fusionPalette.setBrush(QPalette::Midlight, midLight); - fusionPalette.setBrush(QPalette::Button, button); - fusionPalette.setBrush(QPalette::Shadow, shadow); - fusionPalette.setBrush(QPalette::HighlightedText, hightlightedText); - - fusionPalette.setBrush(QPalette::Disabled, QPalette::Text, disabledText); - fusionPalette.setBrush(QPalette::Disabled, QPalette::WindowText, disabledText); - fusionPalette.setBrush(QPalette::Disabled, QPalette::ButtonText, disabledText); - fusionPalette.setBrush(QPalette::Disabled, QPalette::Base, disabledBase); - fusionPalette.setBrush(QPalette::Disabled, QPalette::Dark, darkDisabled); - fusionPalette.setBrush(QPalette::Disabled, QPalette::Shadow, disabledShadow); - - fusionPalette.setBrush(QPalette::Active, QPalette::Highlight, QColor(48, 140, 198)); - fusionPalette.setBrush(QPalette::Inactive, QPalette::Highlight, QColor(48, 140, 198)); - fusionPalette.setBrush(QPalette::Disabled, QPalette::Highlight, QColor(145, 145, 145)); - - fusionPalette.setBrush(QPalette::PlaceholderText, placeholder); - - return fusionPalette; -} - #ifndef QT_NO_DEBUG_STREAM static QString groupsToString(const QPalette &p, QPalette::ColorRole cr) { |