Files
qelectrotech-source-mirror/sources/qetpalette.h
T
Jeff Patterson 1c8e7ed052 Give Fusion a palette it can draw with on macOS
main.cpp has forced the Fusion style on macOS since 2019, but the palette
still came from Qt's macOS platform theme, which is built for the native
style. It hands Fusion a Window, Button and Base that are the same color,
a Dark lighter than Light, and in dark mode an Inactive ButtonText of
black. Fusion derives its frames, gradients and indicators from those
roles, so fields had no edges, the radio buttons in the text alignment
dialog vanished, and the "Handles" combo box in the diagram editor
toolbar drew its text black on a dark combo the moment the window lost
focus. Light mode had the same flatness, with Window, Button and Base
all white.

Add QET::Palette (sources/qetpalette.{h,cpp}) with a light and a dark
palette laid out the way Fusion expects, and install one from
QETApp::initStyle() on macOS when the running style is Fusion, choosing
by the platform palette's lightness and keeping the platform's accent
color when it reads at 4.5:1. On macOS the base palette is now applied
whether or not "use system colors" is checked, since the system palette
cannot be drawn by Fusion; that setting only decides whether style.css
is layered on top (#467). On Qt 6.5+ the app follows the OS light/dark
switch through QStyleHints::colorSchemeChanged.

Other platforms are untouched: Fusion is Qt's default style on Linux
desktops without a platform theme, and the palette there carries the
user's desktop colors. Making Fusion and this palette the default
everywhere is discussed in #870.

tests/qttest/tst_qetpalette checks every text role pair at WCAG 4.5:1
(3:1 disabled), that Inactive equals Active, and paints a Fusion combo
box, radio buttons, buttons and a line edit on the offscreen platform to
measure the ink against its background. Set QET_TEST_DUMP_DIR to keep
the rendered images.
2026-09-16 04:39:31 -05:00

94 lines
3.0 KiB
C++

/*
Copyright 2006-2026 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QET_PALETTE_H
#define QET_PALETTE_H
#include <QPalette>
class QStyle;
/**
Palettes tuned for the Fusion style.
main.cpp forces the Fusion style on macOS, but the palette still comes
from Qt's macOS platform theme, which is built for the native style.
That palette gives Window, Button and Base the same color, makes Dark
lighter than Light, and in dark mode sets the Inactive ButtonText to
black. Fusion derives its outlines, gradients and indicator colors from
those roles, so under that palette controls lose their edges, radio
indicators vanish, and combo box text turns black as soon as the window
loses focus.
This namespace provides a light and a dark palette with the role
separation Fusion expects, and the WCAG 2 contrast helper the tests use
to keep them readable.
*/
namespace QET {
namespace Palette {
/**
@return true when the style draws with Fusion's rules,
i.e. its object name is "fusion".
*/
bool styleIsFusion(const QStyle *style);
/**
@return true when the palette's Window color is dark
(lightness below 128).
*/
bool isDark(const QPalette &palette);
/**
WCAG 2 contrast ratio between two opaque colors, from 1 (equal)
to 21 (black on white). Normal text needs at least 4.5, large
text and non-text controls at least 3.
*/
double contrastRatio(const QColor &a, const QColor &b);
/**
A light palette with the role separation Fusion expects: Window
and Button a light grey, Base white, Text black, and Inactive
equal to Active so nothing changes when the window loses focus.
*/
QPalette fusionLight();
/**
A dark palette with the same role separation: Window a mid
grey, Button lighter than Window, Base darker than Window, Text
light, and Inactive equal to Active.
*/
QPalette fusionDark();
/**
Copy the Highlight and HighlightedText colors of the platform
palette into ours, so the user's accent color survives, but only
when the pair reads at 4.5:1 or better. Otherwise ours is kept.
*/
QPalette withPlatformAccent(QPalette palette, const QPalette &platform);
/**
The palette QET should use under Fusion, given the palette the
platform handed to the application: fusionDark() when the
platform palette is dark, fusionLight() otherwise, with the
platform's accent color kept when it is readable.
*/
QPalette forFusion(const QPalette &platform);
}
}
#endif