Gtk3 Theme: Fix disabled colors for texts
Previously, disabled text colors were a darker version of the normal text color. However, when the text color is black, the darker version is also black, making the disabled text indistinguishable from the enabled text. To fix this issue, a source struct called `MixSources` has been implemented. This struct contains the mixing sources. For disabled texts, a mix of the background and text color sources creates a more sensible appearance, making the disabled text look more like the control's background color. This solution does not require access to the system's color scheme, as the disabled color depends only on the background and foreground colors. Fixes: QTBUG-123449 Pick-to: 6.7 6.5 Change-Id: I469e4fc05ddd4851120b89646bd7ab17a3ee2c00 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Axel Spoerl <axel.spoerl@qt.io> (cherry picked from commit 21a070052716c8ce1c471817b985f43e5b19af0c) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
267e378d14
commit
4b7ad06dc4
@ -211,6 +211,15 @@ const QJsonDocument QGtk3Json::save(const QGtk3Storage::PaletteMap &map)
|
||||
}
|
||||
break;
|
||||
|
||||
case QGtk3Storage::SourceType::Mixed: {
|
||||
sourceObject.insert(ceColorGroup, fromColorGroup(s.mix.sourceGroup));
|
||||
QJsonArray colorRoles;
|
||||
colorRoles << fromColorRole(s.mix.colorRole1)
|
||||
<< fromColorRole(s.mix.colorRole2);
|
||||
sourceObject.insert(ceColorRole, colorRoles);
|
||||
}
|
||||
break;
|
||||
|
||||
case QGtk3Storage::SourceType::Invalid:
|
||||
break;
|
||||
}
|
||||
@ -387,6 +396,26 @@ bool QGtk3Json::load(QGtk3Storage::PaletteMap &map, const QJsonDocument &doc)
|
||||
}
|
||||
break;
|
||||
|
||||
case QGtk3Storage::SourceType::Mixed: {
|
||||
if (!sourceObject[ceColorRole].isArray()) {
|
||||
qCInfo(lcQGtk3Interface) << "Mixed brush missing the array of color roles for palette:" << paletteName
|
||||
<< "Brush" << colorRoleName;
|
||||
return false;
|
||||
}
|
||||
QJsonArray colorRoles = sourceObject[ceColorRole].toArray();
|
||||
if (colorRoles.size() < 2) {
|
||||
qCInfo(lcQGtk3Interface) << "Mixed brush missing enough color roles for palette" << paletteName
|
||||
<< "Brush" << colorRoleName;
|
||||
return false;
|
||||
}
|
||||
const QPalette::ColorRole colorRole1 = toColorRole(colorRoles[0].toString());
|
||||
const QPalette::ColorRole colorRole2 = toColorRole(colorRoles[1].toString());
|
||||
GETSTR(sourceObject, ceColorGroup);
|
||||
const QPalette::ColorGroup sourceGroup = toColorGroup(value);
|
||||
s = QGtk3Storage::Source(sourceGroup, colorRole1, colorRole2);
|
||||
}
|
||||
break;
|
||||
|
||||
case QGtk3Storage::SourceType::Invalid:
|
||||
qInfo(lcQGtk3Interface) << "Invalid source type for palette" << paletteName
|
||||
<< "Brush." << colorRoleName;
|
||||
|
@ -75,6 +75,31 @@ QBrush QGtk3Storage::brush(const Source &source, const BrushMap &map) const
|
||||
return b;
|
||||
}
|
||||
|
||||
case SourceType::Mixed: {
|
||||
// check the mixing source to be valid and be a Gtk source
|
||||
constexpr auto check_source = [](const Source &source) -> bool
|
||||
{
|
||||
return source.isValid() && (source.sourceType == SourceType::Gtk);
|
||||
};
|
||||
|
||||
const Source source1 = brush(TargetBrush(source.mix.sourceGroup,
|
||||
source.mix.colorRole1), map);
|
||||
if (!check_source(source1))
|
||||
return QBrush();
|
||||
|
||||
const Source source2 = brush(TargetBrush(source.mix.sourceGroup,
|
||||
source.mix.colorRole2), map);
|
||||
if (!check_source(source2))
|
||||
return QBrush();
|
||||
|
||||
const QBrush brush2 = brush(source2, map);
|
||||
// the output brush is a copy of the brush from the first source
|
||||
QBrush brush1 = brush(source1, map);
|
||||
// only color is mixed
|
||||
brush1.setColor(MixSources::mixColors(brush1.color(), brush2.color()));
|
||||
return brush1;
|
||||
}
|
||||
|
||||
case SourceType::Fixed:
|
||||
return source.fix.fixedBrush;
|
||||
|
||||
@ -413,6 +438,7 @@ const QGtk3Storage::PaletteMap QGtk3Storage::savePalettes() const
|
||||
break;
|
||||
case SourceType::Fixed:
|
||||
case SourceType::Modified:
|
||||
case SourceType::Mixed:
|
||||
case SourceType::Invalid:
|
||||
break;
|
||||
}
|
||||
@ -554,10 +580,22 @@ void QGtk3Storage::createMapping()
|
||||
|
||||
GTK(button, Foreground, ACTIVE);
|
||||
ADD(Inactive, WindowText);
|
||||
LIGHTER(Normal, WindowText, 50);
|
||||
ADD(Disabled, Text);
|
||||
ADD(Disabled, WindowText);
|
||||
ADD(Disabled, ButtonText);
|
||||
|
||||
auto ADD_MIX = [&map](QPalette::ColorGroup targetGroup,
|
||||
QPalette::ColorRole targetRole,
|
||||
QPalette::ColorGroup sourceGroup,
|
||||
QPalette::ColorRole role1,
|
||||
QPalette::ColorRole role2)
|
||||
{
|
||||
const Source source{sourceGroup, role1, role2};
|
||||
map.insert(TargetBrush(targetGroup, targetRole), source);
|
||||
};
|
||||
ADD_MIX(QPalette::Disabled, QPalette::Text,
|
||||
QPalette::Normal, QPalette::Base, QPalette::Text);
|
||||
ADD_MIX(QPalette::Disabled, QPalette::WindowText,
|
||||
QPalette::Normal, QPalette::Window, QPalette::WindowText);
|
||||
ADD_MIX(QPalette::Disabled, QPalette::ButtonText,
|
||||
QPalette::Normal, QPalette::Button, QPalette::ButtonText);
|
||||
|
||||
GTK(button, Text, NORMAL);
|
||||
ADD(Inactive, ButtonText);
|
||||
|
@ -41,6 +41,7 @@ public:
|
||||
Gtk,
|
||||
Fixed,
|
||||
Modified,
|
||||
Mixed,
|
||||
Invalid
|
||||
};
|
||||
Q_ENUM(SourceType)
|
||||
@ -80,6 +81,27 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// Mixed source: Populate a brush by mixing two brushes.
|
||||
// Useful for creating disabled color by mixing,
|
||||
// for example the background and foreground colors.
|
||||
struct MixSources {
|
||||
QPalette::ColorGroup sourceGroup; // source group of the mixing color roles
|
||||
QPalette::ColorRole colorRole1;
|
||||
QPalette::ColorRole colorRole2;
|
||||
QDebug operator<<(QDebug dbg)
|
||||
{
|
||||
return dbg << "QGtkStorage::MixSources(sourceGroup=" << sourceGroup
|
||||
<< ", colorRole1=" << colorRole1
|
||||
<< ", colorRole2=" << colorRole2 << ")";
|
||||
}
|
||||
static inline QColor mixColors(const QColor &color1, const QColor &color2)
|
||||
{
|
||||
return QColor{ (color1.red() + color2.red()) / 2,
|
||||
(color1.green() + color2.green()) / 2,
|
||||
(color1.blue() + color2.blue()) / 2 };
|
||||
}
|
||||
};
|
||||
|
||||
// Fixed source: Populate a brush with fixed values rather than reading GTK
|
||||
struct FixedSource {
|
||||
QBrush fixedBrush;
|
||||
@ -95,6 +117,7 @@ public:
|
||||
Gtk3Source gtk3;
|
||||
RecursiveSource rec;
|
||||
FixedSource fix;
|
||||
MixSources mix;
|
||||
|
||||
// GTK constructor
|
||||
Source(QGtk3Interface::QGtkWidget wtype, QGtk3Interface::QGtkColorSource csource,
|
||||
@ -118,7 +141,7 @@ public:
|
||||
rec.lighter = p_lighter;
|
||||
}
|
||||
|
||||
// Recursive ocnstructor for color modification
|
||||
// Recursive constructor for color modification
|
||||
Source(QPalette::ColorGroup group, QPalette::ColorRole role,
|
||||
Qt::ColorScheme scheme, int p_red, int p_green, int p_blue)
|
||||
: sourceType(SourceType::Modified)
|
||||
@ -145,6 +168,16 @@ public:
|
||||
rec.deltaBlue = p_blue;
|
||||
}
|
||||
|
||||
// Mixed constructor for color modification
|
||||
Source(QPalette::ColorGroup sourceGroup,
|
||||
QPalette::ColorRole role1, QPalette::ColorRole role2)
|
||||
: sourceType(SourceType::Mixed)
|
||||
{
|
||||
mix.sourceGroup = sourceGroup;
|
||||
mix.colorRole1 = role1;
|
||||
mix.colorRole2 = role2;
|
||||
}
|
||||
|
||||
// Fixed Source constructor
|
||||
Source(const QBrush &brush) : sourceType(SourceType::Fixed)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user