From a79bac428b7857b9db2d0641daf3b7f2e3deb91f Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Tue, 24 Dec 2019 20:57:54 +0100 Subject: [PATCH] LibGUI+LibDraw: Add "Palette" concept for scoped color theming GApplication now has a palette. This palette contains all the system theme colors by default, and is inherited by a new top-level GWidget. New child widgets inherit their parents palette. It is possible to override the GApplication palette, and the palette of any GWidget. The Palette object contains a bunch of colors, each corresponding to a ColorRole. Each role has a convenience getter as well. Each GWidget now has a background_role() and foreground_role(), which are then looked up in their current palette when painting. This means that you no longer alter the background color of a widget by setting it directly, rather you alter either its background role, or the widget's palette. --- Applications/FontEditor/GlyphMapWidget.cpp | 3 +- Applications/HexEditor/HexEditor.cpp | 3 +- Applications/IRCClient/IRCAppWindow.cpp | 1 - Applications/PaintBrush/PaletteWidget.cpp | 1 - Applications/PaintBrush/ToolboxWidget.cpp | 1 - .../SystemMonitor/NetworkStatisticsWidget.cpp | 1 - Applications/SystemMonitor/main.cpp | 7 +- Applications/Terminal/main.cpp | 5 +- Applications/Welcome/TextWidget.cpp | 6 +- Demos/Fire/Fire.cpp | 4 +- DevTools/HackStudio/Editor.cpp | 2 +- DevTools/HackStudio/FormWidget.cpp | 1 - DevTools/VisualBuilder/VBForm.cpp | 1 - Games/Minesweeper/Field.cpp | 1 - Libraries/LibDraw/Color.cpp | 88 ------------------- Libraries/LibDraw/Color.h | 34 +------ Libraries/LibDraw/Makefile | 1 + Libraries/LibDraw/Palette.cpp | 26 ++++++ Libraries/LibDraw/Palette.h | 51 +++++++++++ Libraries/LibDraw/StylePainter.cpp | 79 +++++++++-------- Libraries/LibDraw/StylePainter.h | 15 ++-- Libraries/LibDraw/SystemTheme.cpp | 59 +++++++------ Libraries/LibDraw/SystemTheme.h | 72 +++++++-------- Libraries/LibGUI/GAbstractButton.cpp | 3 +- Libraries/LibGUI/GAbstractColumnView.cpp | 11 +-- Libraries/LibGUI/GAbstractColumnView.h | 2 +- Libraries/LibGUI/GApplication.cpp | 17 ++++ Libraries/LibGUI/GApplication.h | 10 +++ Libraries/LibGUI/GButton.cpp | 2 +- Libraries/LibGUI/GCheckBox.cpp | 13 +-- Libraries/LibGUI/GFilePicker.cpp | 1 - Libraries/LibGUI/GFrame.cpp | 2 +- Libraries/LibGUI/GGroupBox.cpp | 11 ++- Libraries/LibGUI/GItemView.cpp | 12 +-- Libraries/LibGUI/GLabel.cpp | 7 +- Libraries/LibGUI/GListView.cpp | 10 ++- Libraries/LibGUI/GProgressBar.cpp | 2 +- Libraries/LibGUI/GResizeCorner.cpp | 6 +- Libraries/LibGUI/GScrollBar.cpp | 13 +-- Libraries/LibGUI/GSlider.cpp | 4 +- Libraries/LibGUI/GSplitter.cpp | 7 +- Libraries/LibGUI/GStatusBar.cpp | 2 +- Libraries/LibGUI/GTabWidget.cpp | 17 ++-- Libraries/LibGUI/GTableView.cpp | 25 +++--- Libraries/LibGUI/GTextEditor.cpp | 18 ++-- Libraries/LibGUI/GToolBar.cpp | 9 +- Libraries/LibGUI/GTreeView.cpp | 16 ++-- Libraries/LibGUI/GWidget.cpp | 28 +++--- Libraries/LibGUI/GWidget.h | 17 +++- Libraries/LibGUI/GWindowServerConnection.cpp | 2 + Libraries/LibHTML/HtmlView.cpp | 4 +- Libraries/LibHTML/Layout/LayoutImage.cpp | 2 +- Libraries/LibHTML/RenderingContext.h | 6 +- Servers/WindowServer/WSButton.cpp | 5 +- Servers/WindowServer/WSCompositor.cpp | 2 +- Servers/WindowServer/WSMenu.cpp | 27 +++--- Servers/WindowServer/WSMenuManager.cpp | 15 ++-- Servers/WindowServer/WSWindowFrame.cpp | 29 +++--- Servers/WindowServer/WSWindowManager.cpp | 4 +- Servers/WindowServer/WSWindowManager.h | 12 ++- Servers/WindowServer/WSWindowSwitcher.cpp | 19 ++-- Servers/WindowServer/main.cpp | 4 +- 62 files changed, 448 insertions(+), 410 deletions(-) create mode 100644 Libraries/LibDraw/Palette.cpp create mode 100644 Libraries/LibDraw/Palette.h diff --git a/Applications/FontEditor/GlyphMapWidget.cpp b/Applications/FontEditor/GlyphMapWidget.cpp index e8b88ae62d9..1e65cf8d774 100644 --- a/Applications/FontEditor/GlyphMapWidget.cpp +++ b/Applications/FontEditor/GlyphMapWidget.cpp @@ -1,4 +1,5 @@ #include "GlyphMapWidget.h" +#include #include GlyphMapWidget::GlyphMapWidget(Font& mutable_font, GWidget* parent) @@ -74,7 +75,7 @@ void GlyphMapWidget::paint_event(GPaintEvent& event) font().max_glyph_width(), font().glyph_height()); if (glyph == m_selected_glyph) { - painter.fill_rect(outer_rect, SystemColor::Selection); + painter.fill_rect(outer_rect, palette().selection()); painter.draw_glyph(inner_rect.location(), glyph, Color::White); } else { painter.draw_glyph(inner_rect.location(), glyph, Color::Black); diff --git a/Applications/HexEditor/HexEditor.cpp b/Applications/HexEditor/HexEditor.cpp index 2c772f5bded..fbc0e29bc7f 100644 --- a/Applications/HexEditor/HexEditor.cpp +++ b/Applications/HexEditor/HexEditor.cpp @@ -1,6 +1,7 @@ #include "HexEditor.h" #include #include +#include #include #include #include @@ -492,7 +493,7 @@ void HexEditor::paint_event(GPaintEvent& event) text_color = Color::Red; } - Color highlight_color = SystemColor::Selection; + Color highlight_color = palette().selection(); auto highlight_flag = false; if (m_selection_start > -1 && m_selection_end > -1) { if (byte_position >= m_selection_start && byte_position <= m_selection_end) { diff --git a/Applications/IRCClient/IRCAppWindow.cpp b/Applications/IRCClient/IRCAppWindow.cpp index 3cb8c861ee4..299511dd02b 100644 --- a/Applications/IRCClient/IRCAppWindow.cpp +++ b/Applications/IRCClient/IRCAppWindow.cpp @@ -156,7 +156,6 @@ void IRCAppWindow::setup_widgets() auto widget = GWidget::construct(); set_main_widget(widget); widget->set_fill_with_background_color(true); - widget->set_background_color(SystemColor::Window); widget->set_layout(make(Orientation::Vertical)); widget->layout()->set_spacing(0); diff --git a/Applications/PaintBrush/PaletteWidget.cpp b/Applications/PaintBrush/PaletteWidget.cpp index bd8775cda8d..a081f26a7fa 100644 --- a/Applications/PaintBrush/PaletteWidget.cpp +++ b/Applications/PaintBrush/PaletteWidget.cpp @@ -51,7 +51,6 @@ PaletteWidget::PaletteWidget(PaintableWidget& paintable_widget, GWidget* parent) set_frame_shadow(FrameShadow::Raised); set_frame_thickness(0); set_fill_with_background_color(true); - set_background_color(SystemColor::Window); set_size_policy(SizePolicy::Fill, SizePolicy::Fixed); set_preferred_size(0, 34); diff --git a/Applications/PaintBrush/ToolboxWidget.cpp b/Applications/PaintBrush/ToolboxWidget.cpp index 80e83d61746..44be7121baa 100644 --- a/Applications/PaintBrush/ToolboxWidget.cpp +++ b/Applications/PaintBrush/ToolboxWidget.cpp @@ -35,7 +35,6 @@ private: ToolboxWidget::ToolboxWidget(GWidget* parent) : GFrame(parent) { - set_background_color(SystemColor::Window); set_fill_with_background_color(true); set_frame_thickness(1); diff --git a/Applications/SystemMonitor/NetworkStatisticsWidget.cpp b/Applications/SystemMonitor/NetworkStatisticsWidget.cpp index c7eb3c39329..a4eb9837172 100644 --- a/Applications/SystemMonitor/NetworkStatisticsWidget.cpp +++ b/Applications/SystemMonitor/NetworkStatisticsWidget.cpp @@ -11,7 +11,6 @@ NetworkStatisticsWidget::NetworkStatisticsWidget(GWidget* parent) set_layout(make(Orientation::Vertical)); layout()->set_margins({ 4, 4, 4, 4 }); set_fill_with_background_color(true); - set_background_color(SystemColor::Window); auto adapters_group_box = GGroupBox::construct("Adapters", this); adapters_group_box->set_layout(make(Orientation::Vertical)); diff --git a/Applications/SystemMonitor/main.cpp b/Applications/SystemMonitor/main.cpp index f67bde0f166..c09bfe86c12 100644 --- a/Applications/SystemMonitor/main.cpp +++ b/Applications/SystemMonitor/main.cpp @@ -53,7 +53,6 @@ int main(int argc, char** argv) auto keeper = GWidget::construct(); keeper->set_layout(make(Orientation::Vertical)); keeper->set_fill_with_background_color(true); - keeper->set_background_color(SystemColor::Window); keeper->layout()->set_margins({ 4, 4, 4, 4 }); auto tabwidget = GTabWidget::construct(keeper); @@ -192,7 +191,7 @@ class ProgressBarPaintingDelegate final : public GTableCellPaintingDelegate { public: virtual ~ProgressBarPaintingDelegate() override {} - virtual void paint(GPainter& painter, const Rect& a_rect, const GModel& model, const GModelIndex& index) override + virtual void paint(GPainter& painter, const Rect& a_rect, const Palette& palette, const GModel& model, const GModelIndex& index) override { auto rect = a_rect.shrunken(2, 2); auto percentage = model.data(index, GModel::Role::Custom).to_int(); @@ -201,7 +200,7 @@ public: String text; if (data.is_string()) text = data.as_string(); - StylePainter::paint_progress_bar(painter, rect, 0, 100, percentage, text); + StylePainter::paint_progress_bar(painter, rect, palette, 0, 100, percentage, text); painter.draw_rect(rect, Color::Black); } }; @@ -355,7 +354,7 @@ NonnullRefPtr build_graphs_tab() graphs_container->on_first_show = [](auto& self) { self.set_fill_with_background_color(true); - self.set_background_color(SystemColor::Window); + self.set_background_role(ColorRole::Button); self.set_layout(make(Orientation::Vertical)); self.layout()->set_margins({ 4, 4, 4, 4 }); diff --git a/Applications/Terminal/main.cpp b/Applications/Terminal/main.cpp index 528bc65ddf9..235a48e2861 100644 --- a/Applications/Terminal/main.cpp +++ b/Applications/Terminal/main.cpp @@ -98,13 +98,13 @@ RefPtr create_settings_window(TerminalWidget& terminal, RefPtrset_main_widget(settings); settings->set_fill_with_background_color(true); + settings->set_background_role(ColorRole::Button); settings->set_layout(make(Orientation::Vertical)); settings->layout()->set_margins({ 4, 4, 4, 4 }); auto radio_container = GGroupBox::construct("Bell Mode", settings); radio_container->set_layout(make(Orientation::Vertical)); radio_container->layout()->set_margins({ 6, 16, 6, 6 }); - radio_container->set_fill_with_background_color(true); radio_container->set_size_policy(SizePolicy::Fill, SizePolicy::Fixed); radio_container->set_preferred_size(100, 70); @@ -119,12 +119,9 @@ RefPtr create_settings_window(TerminalWidget& terminal, RefPtrset_layout(make(Orientation::Vertical)); slider_container->layout()->set_margins({ 6, 16, 6, 6 }); - slider_container->set_fill_with_background_color(true); slider_container->set_size_policy(SizePolicy::Fill, SizePolicy::Fixed); slider_container->set_preferred_size(100, 50); auto slider = GSlider::construct(Orientation::Horizontal, slider_container); - slider->set_fill_with_background_color(true); - slider->set_background_color(SystemColor::Window); slider->on_value_changed = [&terminal, &config](int value) { terminal.set_opacity(value); diff --git a/Applications/Welcome/TextWidget.cpp b/Applications/Welcome/TextWidget.cpp index 6da59a21638..a9b5e67f1c8 100644 --- a/Applications/Welcome/TextWidget.cpp +++ b/Applications/Welcome/TextWidget.cpp @@ -1,10 +1,10 @@ +#include "TextWidget.h" #include #include #include +#include #include -#include "TextWidget.h" - TextWidget::TextWidget(GWidget* parent) : GFrame(parent) { @@ -49,7 +49,7 @@ void TextWidget::paint_event(GPaintEvent& event) text_rect.set_width(text_rect.width() - indent * 2); if (is_enabled()) { - painter.draw_text(text_rect, line, m_text_alignment, foreground_color(), TextElision::None); + painter.draw_text(text_rect, line, m_text_alignment, palette().color(foreground_role()), TextElision::None); } else { painter.draw_text(text_rect.translated(1, 1), line, font(), text_alignment(), Color::White, TextElision::Right); painter.draw_text(text_rect, line, font(), text_alignment(), Color::from_rgb(0x808080), TextElision::Right); diff --git a/Demos/Fire/Fire.cpp b/Demos/Fire/Fire.cpp index 8c2aaed32d3..0bac9260297 100644 --- a/Demos/Fire/Fire.cpp +++ b/Demos/Fire/Fire.cpp @@ -31,7 +31,7 @@ #define FIRE_HEIGHT 168 #define FIRE_MAX 29 -const Color palette[] = { +static const Color s_palette[] = { Color(0x07, 0x07, 0x07), Color(0x1F, 0x07, 0x07), Color(0x2F, 0x0F, 0x07), Color(0x47, 0x0F, 0x07), Color(0x57, 0x17, 0x07), Color(0x67, 0x1F, 0x07), Color(0x77, 0x1F, 0x07), Color(0x9F, 0x2F, 0x07), Color(0xAF, 0x3F, 0x07), @@ -93,7 +93,7 @@ Fire::Fire(GWidget* parent) /* Initialize fire palette */ for (int i = 0; i < 30; i++) - bitmap->set_palette_color(i, palette[i]); + bitmap->set_palette_color(i, s_palette[i]); /* Set remaining entries to white */ for (int i = 30; i < 256; i++) diff --git a/DevTools/HackStudio/Editor.cpp b/DevTools/HackStudio/Editor.cpp index 57167ef7af2..c7b1fc07565 100644 --- a/DevTools/HackStudio/Editor.cpp +++ b/DevTools/HackStudio/Editor.cpp @@ -68,7 +68,7 @@ void Editor::paint_event(GPaintEvent& event) rect.set_width(rect.width() - vertical_scrollbar().width()); if (horizontal_scrollbar().is_visible()) rect.set_height(rect.height() - horizontal_scrollbar().height()); - painter.draw_rect(rect, SystemColor::Selection); + painter.draw_rect(rect, palette().selection()); } } diff --git a/DevTools/HackStudio/FormWidget.cpp b/DevTools/HackStudio/FormWidget.cpp index 08506beaded..c3316547d8c 100644 --- a/DevTools/HackStudio/FormWidget.cpp +++ b/DevTools/HackStudio/FormWidget.cpp @@ -7,7 +7,6 @@ FormWidget::FormWidget(FormEditorWidget& parent) : GWidget(&parent) { set_fill_with_background_color(true); - set_background_color(SystemColor::Window); set_relative_rect(5, 5, 400, 300); set_greedy_for_hits(true); diff --git a/DevTools/VisualBuilder/VBForm.cpp b/DevTools/VisualBuilder/VBForm.cpp index 5181414c38c..d3466c6c602 100644 --- a/DevTools/VisualBuilder/VBForm.cpp +++ b/DevTools/VisualBuilder/VBForm.cpp @@ -25,7 +25,6 @@ VBForm::VBForm(const String& name, GWidget* parent) { s_current = this; set_fill_with_background_color(true); - set_background_color(SystemColor::Window); set_greedy_for_hits(true); m_context_menu = GMenu::construct(); diff --git a/Games/Minesweeper/Field.cpp b/Games/Minesweeper/Field.cpp index 70e4f2a0c26..0813f1d5ca8 100644 --- a/Games/Minesweeper/Field.cpp +++ b/Games/Minesweeper/Field.cpp @@ -121,7 +121,6 @@ Field::Field(GLabel& flag_label, GLabel& time_label, GButton& face_button, GWidg m_number_bitmap[i] = GraphicsBitmap::load_from_file(String::format("/res/icons/minesweeper/%u.png", i + 1)); set_fill_with_background_color(true); - set_background_color(SystemColor::Window); reset(); m_face_button.on_click = [this](auto&) { reset(); }; diff --git a/Libraries/LibDraw/Color.cpp b/Libraries/LibDraw/Color.cpp index 3644c4bf4bd..1b1bf469d5c 100644 --- a/Libraries/LibDraw/Color.cpp +++ b/Libraries/LibDraw/Color.cpp @@ -4,94 +4,6 @@ #include #include -Color::Color(SystemColor system_color) -{ - auto& theme = current_system_theme(); - switch (system_color) { - case SystemColor::Window: - m_value = theme.window.value(); - break; - case SystemColor::WindowText: - m_value = theme.window_text.value(); - break; - case SystemColor::Base: - m_value = theme.base.value(); - break; - case SystemColor::ThreedShadow1: - m_value = theme.threed_shadow1.value(); - break; - case SystemColor::ThreedShadow2: - m_value = theme.threed_shadow2.value(); - break; - case SystemColor::ThreedHighlight: - m_value = theme.threed_highlight.value(); - break; - case SystemColor::Button: - m_value = theme.button.value(); - break; - case SystemColor::ButtonText: - m_value = theme.button_text.value(); - break; - case SystemColor::HoverHighlight: - m_value = theme.hover_highlight.value(); - break; - case SystemColor::Selection: - m_value = theme.selection.value(); - break; - case SystemColor::SelectionText: - m_value = theme.selection_text.value(); - break; - case SystemColor::DesktopBackground: - m_value = theme.desktop_background.value(); - break; - case SystemColor::ActiveWindowBorder1: - m_value = theme.active_window_border1.value(); - break; - case SystemColor::ActiveWindowBorder2: - m_value = theme.active_window_border2.value(); - break; - case SystemColor::ActiveWindowTitle: - m_value = theme.active_window_title.value(); - break; - case SystemColor::InactiveWindowBorder1: - m_value = theme.inactive_window_border1.value(); - break; - case SystemColor::InactiveWindowBorder2: - m_value = theme.inactive_window_border2.value(); - break; - case SystemColor::InactiveWindowTitle: - m_value = theme.inactive_window_title.value(); - break; - case SystemColor::MovingWindowBorder1: - m_value = theme.moving_window_border1.value(); - break; - case SystemColor::MovingWindowBorder2: - m_value = theme.moving_window_border2.value(); - break; - case SystemColor::MovingWindowTitle: - m_value = theme.moving_window_title.value(); - break; - case SystemColor::HighlightWindowBorder1: - m_value = theme.highlight_window_border1.value(); - break; - case SystemColor::HighlightWindowBorder2: - m_value = theme.highlight_window_border2.value(); - break; - case SystemColor::HighlightWindowTitle: - m_value = theme.highlight_window_title.value(); - break; - case SystemColor::MenuStripe: - m_value = theme.menu_stripe.value(); - break; - case SystemColor::MenuBase: - m_value = theme.menu_base.value(); - break; - case SystemColor::MenuSelection: - m_value = theme.menu_selection.value(); - break; - } -} - Color::Color(NamedColor named) { struct { diff --git a/Libraries/LibDraw/Color.h b/Libraries/LibDraw/Color.h index a8873630184..467dffd9858 100644 --- a/Libraries/LibDraw/Color.h +++ b/Libraries/LibDraw/Color.h @@ -4,6 +4,7 @@ #include #include +enum class ColorRole; typedef u32 RGBA32; inline constexpr u32 make_rgb(u8 r, u8 g, u8 b) @@ -11,38 +12,6 @@ inline constexpr u32 make_rgb(u8 r, u8 g, u8 b) return ((r << 16) | (g << 8) | b); } -enum class SystemColor { - DesktopBackground, - ActiveWindowBorder1, - ActiveWindowBorder2, - ActiveWindowTitle, - InactiveWindowBorder1, - InactiveWindowBorder2, - InactiveWindowTitle, - MovingWindowBorder1, - MovingWindowBorder2, - MovingWindowTitle, - HighlightWindowBorder1, - HighlightWindowBorder2, - HighlightWindowTitle, - MenuStripe, - MenuBase, - MenuSelection, - Window, - WindowText, - Button, - ButtonText, - Base, - ThreedHighlight, - ThreedShadow1, - ThreedShadow2, - HoverHighlight, - Selection, - SelectionText, - - DisabledText = ThreedShadow1, -}; - class Color { public: enum NamedColor { @@ -71,7 +40,6 @@ public: Color() {} Color(NamedColor); - Color(SystemColor); Color(u8 r, u8 g, u8 b) : m_value(0xff000000 | (r << 16) | (g << 8) | b) { diff --git a/Libraries/LibDraw/Makefile b/Libraries/LibDraw/Makefile index d6bc6f0b22c..a0490675aa9 100644 --- a/Libraries/LibDraw/Makefile +++ b/Libraries/LibDraw/Makefile @@ -11,6 +11,7 @@ OBJS = \ Rect.o \ StylePainter.o \ SystemTheme.o \ + Palette.o \ Emoji.o LIBRARY = libdraw.a diff --git a/Libraries/LibDraw/Palette.cpp b/Libraries/LibDraw/Palette.cpp new file mode 100644 index 00000000000..2570dfacfb4 --- /dev/null +++ b/Libraries/LibDraw/Palette.cpp @@ -0,0 +1,26 @@ +#include + +NonnullRefPtr Palette::create_with_shared_buffer(SharedBuffer& buffer) +{ + return adopt(*new Palette(buffer)); +} + +Palette::Palette(SharedBuffer& buffer) + : m_theme_buffer(buffer) +{ +} + +Palette::~Palette() +{ +} + +const SystemTheme& Palette::theme() const +{ + return *(const SystemTheme*)m_theme_buffer->data(); +} + +Color Palette::color(ColorRole role) const +{ + ASSERT((int)role < (int)ColorRole::__Count); + return theme().color[(int)role]; +} diff --git a/Libraries/LibDraw/Palette.h b/Libraries/LibDraw/Palette.h new file mode 100644 index 00000000000..e7cbd222117 --- /dev/null +++ b/Libraries/LibDraw/Palette.h @@ -0,0 +1,51 @@ +#pragma once + +#include +#include + +class GApplication; + +class Palette : public RefCounted { +public: + static NonnullRefPtr create_with_shared_buffer(SharedBuffer&); + ~Palette(); + + Color window() const { return color(ColorRole::Window); } + Color window_text() const { return color(ColorRole::WindowText); } + Color selection() const { return color(ColorRole::Selection); } + Color selection_text() const { return color(ColorRole::SelectionText); } + Color desktop_background() const { return color(ColorRole::DesktopBackground); } + Color active_window_border1() const { return color(ColorRole::ActiveWindowBorder1); } + Color active_window_border2() const { return color(ColorRole::ActiveWindowBorder2); } + Color active_window_title() const { return color(ColorRole::ActiveWindowTitle); } + Color inactive_window_border1() const { return color(ColorRole::InactiveWindowBorder1); } + Color inactive_window_border2() const { return color(ColorRole::InactiveWindowBorder2); } + Color inactive_window_title() const { return color(ColorRole::InactiveWindowTitle); } + Color moving_window_border1() const { return color(ColorRole::MovingWindowBorder1); } + Color moving_window_border2() const { return color(ColorRole::MovingWindowBorder2); } + Color moving_window_title() const { return color(ColorRole::MovingWindowTitle); } + Color highlight_window_border1() const { return color(ColorRole::HighlightWindowBorder1); } + Color highlight_window_border2() const { return color(ColorRole::HighlightWindowBorder2); } + Color highlight_window_title() const { return color(ColorRole::HighlightWindowTitle); } + Color menu_stripe() const { return color(ColorRole::MenuStripe); } + Color menu_base() const { return color(ColorRole::MenuBase); } + Color menu_selection() const { return color(ColorRole::MenuSelection); } + Color base() const { return color(ColorRole::Base); } + Color button() const { return color(ColorRole::Button); } + Color button_text() const { return color(ColorRole::ButtonText); } + Color threed_highlight() const { return color(ColorRole::ThreedHighlight); } + Color threed_shadow1() const { return color(ColorRole::ThreedShadow1); } + Color threed_shadow2() const { return color(ColorRole::ThreedShadow2); } + Color hover_highlight() const { return color(ColorRole::ThreedHighlight); } + + Color color(ColorRole) const; + + const SystemTheme& theme() const; + + void replace_internal_buffer(Badge, SharedBuffer& buffer) { m_theme_buffer = buffer; } + +private: + explicit Palette(SharedBuffer&); + + RefPtr m_theme_buffer; +}; diff --git a/Libraries/LibDraw/StylePainter.cpp b/Libraries/LibDraw/StylePainter.cpp index 2d93fa4f3fe..e8b40fd6f8c 100644 --- a/Libraries/LibDraw/StylePainter.cpp +++ b/Libraries/LibDraw/StylePainter.cpp @@ -1,15 +1,16 @@ #include +#include #include -void StylePainter::paint_tab_button(Painter& painter, const Rect& rect, bool active, bool hovered, bool enabled) +void StylePainter::paint_tab_button(Painter& painter, const Rect& rect, const Palette& palette, bool active, bool hovered, bool enabled) { - Color base_color = SystemColor::Button; - Color highlight_color2 = SystemColor::ThreedHighlight; - Color shadow_color1 = SystemColor::ThreedShadow1; - Color shadow_color2 = SystemColor::ThreedShadow2; + Color base_color = palette.button(); + Color highlight_color2 = palette.threed_highlight(); + Color shadow_color1 = palette.threed_shadow1(); + Color shadow_color2 = palette.threed_shadow2(); if (hovered && enabled && !active) - base_color = StylePainter::hover_highlight_color(); + base_color = palette.hover_highlight(); PainterStateSaver saver(painter); painter.translate(rect.location()); @@ -42,20 +43,20 @@ void StylePainter::paint_tab_button(Painter& painter, const Rect& rect, bool act shadow_color2); } -static void paint_button_new(Painter& painter, const Rect& rect, bool pressed, bool checked, bool hovered, bool enabled) +static void paint_button_new(Painter& painter, const Rect& rect, const Palette& palette, bool pressed, bool checked, bool hovered, bool enabled) { - Color button_color = SystemColor::Button; - Color highlight_color2 = SystemColor::ThreedHighlight; - Color shadow_color1 = SystemColor::ThreedShadow1; - Color shadow_color2 = SystemColor::ThreedShadow2; + Color button_color = palette.button(); + Color highlight_color2 = palette.threed_highlight(); + Color shadow_color1 = palette.threed_shadow1(); + Color shadow_color2 = palette.threed_shadow2(); if (checked && enabled) { if (hovered) - button_color = SystemColor::HoverHighlight; + button_color = palette.hover_highlight(); else - button_color = SystemColor::Button; + button_color = palette.button(); } else if (hovered && enabled) - button_color = StylePainter::hover_highlight_color(); + button_color = palette.hover_highlight(); PainterStateSaver saver(painter); painter.translate(rect.location()); @@ -87,14 +88,14 @@ static void paint_button_new(Painter& painter, const Rect& rect, bool pressed, b } } -void StylePainter::paint_button(Painter& painter, const Rect& rect, ButtonStyle button_style, bool pressed, bool hovered, bool checked, bool enabled) +void StylePainter::paint_button(Painter& painter, const Rect& rect, const Palette& palette, ButtonStyle button_style, bool pressed, bool hovered, bool checked, bool enabled) { if (button_style == ButtonStyle::Normal) - return paint_button_new(painter, rect, pressed, checked, hovered, enabled); + return paint_button_new(painter, rect, palette, pressed, checked, hovered, enabled); - Color button_color = SystemColor::Button; - Color highlight_color = SystemColor::ThreedHighlight; - Color shadow_color = Color(96, 96, 96); + Color button_color = palette.button(); + Color highlight_color = palette.threed_highlight(); + Color shadow_color = palette.threed_shadow1(); if (button_style == ButtonStyle::CoolBar && !enabled) return; @@ -127,27 +128,27 @@ void StylePainter::paint_button(Painter& painter, const Rect& rect, ButtonStyle } } -void StylePainter::paint_surface(Painter& painter, const Rect& rect, bool paint_vertical_lines, bool paint_top_line) +void StylePainter::paint_surface(Painter& painter, const Rect& rect, const Palette& palette, bool paint_vertical_lines, bool paint_top_line) { - painter.fill_rect({ rect.x(), rect.y() + 1, rect.width(), rect.height() - 2 }, SystemColor::Button); - painter.draw_line(rect.top_left(), rect.top_right(), paint_top_line ? SystemColor::ThreedHighlight : SystemColor::Button); - painter.draw_line(rect.bottom_left(), rect.bottom_right(), SystemColor::ThreedShadow1); + painter.fill_rect({ rect.x(), rect.y() + 1, rect.width(), rect.height() - 2 }, palette.button()); + painter.draw_line(rect.top_left(), rect.top_right(), paint_top_line ? palette.threed_highlight() : palette.button()); + painter.draw_line(rect.bottom_left(), rect.bottom_right(), palette.threed_shadow1()); if (paint_vertical_lines) { - painter.draw_line(rect.top_left().translated(0, 1), rect.bottom_left().translated(0, -1), SystemColor::ThreedHighlight); - painter.draw_line(rect.top_right(), rect.bottom_right().translated(0, -1), SystemColor::ThreedShadow1); + painter.draw_line(rect.top_left().translated(0, 1), rect.bottom_left().translated(0, -1), palette.threed_highlight()); + painter.draw_line(rect.top_right(), rect.bottom_right().translated(0, -1), palette.threed_shadow1()); } } -void StylePainter::paint_frame(Painter& painter, const Rect& rect, FrameShape shape, FrameShadow shadow, int thickness, bool skip_vertical_lines) +void StylePainter::paint_frame(Painter& painter, const Rect& rect, const Palette& palette, FrameShape shape, FrameShadow shadow, int thickness, bool skip_vertical_lines) { Color top_left_color; Color bottom_right_color; - Color dark_shade = SystemColor::ThreedShadow1; - Color light_shade = SystemColor::ThreedHighlight; + Color dark_shade = palette.threed_shadow1(); + Color light_shade = palette.threed_highlight(); if (shape == FrameShape::Container && thickness >= 2) { if (shadow == FrameShadow::Raised) { - dark_shade = SystemColor::ThreedShadow2; + dark_shade = palette.threed_shadow2(); } } @@ -175,10 +176,10 @@ void StylePainter::paint_frame(Painter& painter, const Rect& rect, FrameShape sh if (shape == FrameShape::Container && thickness >= 2) { Color top_left_color; Color bottom_right_color; - Color dark_shade = SystemColor::ThreedShadow2; - Color light_shade = SystemColor::Button; + Color dark_shade = palette.threed_shadow2(); + Color light_shade = palette.button(); if (shadow == FrameShadow::Raised) { - dark_shade = SystemColor::ThreedShadow1; + dark_shade = palette.threed_shadow1(); top_left_color = light_shade; bottom_right_color = dark_shade; } else if (shadow == FrameShadow::Sunken) { @@ -205,12 +206,12 @@ void StylePainter::paint_frame(Painter& painter, const Rect& rect, FrameShape sh } } -void StylePainter::paint_window_frame(Painter& painter, const Rect& rect) +void StylePainter::paint_window_frame(Painter& painter, const Rect& rect, const Palette& palette) { - Color base_color = SystemColor::Button; - Color dark_shade = SystemColor::ThreedShadow2; - Color mid_shade = SystemColor::ThreedShadow1; - Color light_shade = SystemColor::ThreedHighlight; + Color base_color = palette.button(); + Color dark_shade = palette.threed_shadow2(); + Color mid_shade = palette.threed_shadow1(); + Color light_shade = palette.threed_highlight(); painter.draw_line(rect.top_left(), rect.top_right(), base_color); painter.draw_line(rect.top_left().translated(0, 1), rect.bottom_left(), base_color); @@ -227,7 +228,7 @@ void StylePainter::paint_window_frame(Painter& painter, const Rect& rect) painter.draw_line(rect.bottom_left().translated(2, -2), rect.bottom_right().translated(-2, -2), base_color); } -void StylePainter::paint_progress_bar(Painter& painter, const Rect& rect, int min, int max, int value, const StringView& text) +void StylePainter::paint_progress_bar(Painter& painter, const Rect& rect, const Palette& palette, int min, int max, int value, const StringView& text) { // First we fill the entire widget with the gradient. This incurs a bit of // overdraw but ensures a consistent look throughout the progression. @@ -249,7 +250,7 @@ void StylePainter::paint_progress_bar(Painter& painter, const Rect& rect, int mi Rect hole_rect { (int)progress_width, 0, (int)(rect.width() - progress_width), rect.height() }; hole_rect.move_by(rect.location()); PainterStateSaver saver(painter); - painter.fill_rect(hole_rect, Color::White); + painter.fill_rect(hole_rect, palette.base()); painter.add_clip_rect(hole_rect); if (!text.is_null()) diff --git a/Libraries/LibDraw/StylePainter.h b/Libraries/LibDraw/StylePainter.h index d40ad6d3368..89baa7e4d4f 100644 --- a/Libraries/LibDraw/StylePainter.h +++ b/Libraries/LibDraw/StylePainter.h @@ -3,6 +3,7 @@ #include class Painter; +class Palette; class Rect; enum class ButtonStyle { @@ -25,12 +26,10 @@ enum class FrameShape { class StylePainter { public: - static void paint_button(Painter&, const Rect&, ButtonStyle, bool pressed, bool hovered = false, bool checked = false, bool enabled = true); - static void paint_tab_button(Painter&, const Rect&, bool active, bool hovered, bool enabled); - static void paint_surface(Painter&, const Rect&, bool paint_vertical_lines = true, bool paint_top_line = true); - static void paint_frame(Painter&, const Rect&, FrameShape, FrameShadow, int thickness, bool skip_vertical_lines = false); - static void paint_window_frame(Painter&, const Rect&); - static void paint_progress_bar(Painter&, const Rect&, int min, int max, int value, const StringView& text = {}); - - static Color hover_highlight_color() { return SystemColor::HoverHighlight; } + static void paint_button(Painter&, const Rect&, const Palette&, ButtonStyle, bool pressed, bool hovered = false, bool checked = false, bool enabled = true); + static void paint_tab_button(Painter&, const Rect&, const Palette&, bool active, bool hovered, bool enabled); + static void paint_surface(Painter&, const Rect&, const Palette&, bool paint_vertical_lines = true, bool paint_top_line = true); + static void paint_frame(Painter&, const Rect&, const Palette&, FrameShape, FrameShadow, int thickness, bool skip_vertical_lines = false); + static void paint_window_frame(Painter&, const Rect&, const Palette&); + static void paint_progress_bar(Painter&, const Rect&, const Palette&, int min, int max, int value, const StringView& text = {}); }; diff --git a/Libraries/LibDraw/SystemTheme.cpp b/Libraries/LibDraw/SystemTheme.cpp index d05040105b6..1ca8ede2ebb 100644 --- a/Libraries/LibDraw/SystemTheme.cpp +++ b/Libraries/LibDraw/SystemTheme.cpp @@ -41,34 +41,37 @@ RefPtr load_system_theme(const String& path) return color.value(); }; - data->desktop_background = get("DesktopBackground"); - data->threed_highlight = get("ThreedHighlight"); - data->threed_shadow1 = get("ThreedShadow1"); - data->threed_shadow2 = get("ThreedShadow2"); - data->hover_highlight = get("HoverHighlight"); - data->selection = get("Selection"); - data->selection_text = get("SelectionText"); - data->window = get("Window"); - data->window_text = get("WindowText"); - data->base = get("Base"); - data->button = get("Button"); - data->button_text = get("ButtonText"); - data->desktop_background = get("DesktopBackground"); - data->active_window_border1 = get("ActiveWindowBorder1"); - data->active_window_border2 = get("ActiveWindowBorder2"); - data->active_window_title = get("ActiveWindowTitle"); - data->inactive_window_border1 = get("InactiveWindowBorder1"); - data->inactive_window_border2 = get("InactiveWindowBorder2"); - data->inactive_window_title = get("InactiveWindowTitle"); - data->moving_window_border1 = get("MovingWindowBorder1"); - data->moving_window_border2 = get("MovingWindowBorder2"); - data->moving_window_title = get("MovingWindowTitle"); - data->highlight_window_border1 = get("HighlightWindowBorder1"); - data->highlight_window_border2 = get("HighlightWindowBorder2"); - data->highlight_window_title = get("HighlightWindowTitle"); - data->menu_stripe = get("MenuStripe"); - data->menu_base = get("MenuBase"); - data->menu_selection = get("MenuSelection"); +#define DO_COLOR(x) \ + data->color[(int)ColorRole::x] = get(#x) + + DO_COLOR(DesktopBackground); + DO_COLOR(ThreedHighlight); + DO_COLOR(ThreedShadow1); + DO_COLOR(ThreedShadow2); + DO_COLOR(HoverHighlight); + DO_COLOR(Selection); + DO_COLOR(SelectionText); + DO_COLOR(Window); + DO_COLOR(WindowText); + DO_COLOR(Base); + DO_COLOR(Button); + DO_COLOR(ButtonText); + DO_COLOR(DesktopBackground); + DO_COLOR(ActiveWindowBorder1); + DO_COLOR(ActiveWindowBorder2); + DO_COLOR(ActiveWindowTitle); + DO_COLOR(InactiveWindowBorder1); + DO_COLOR(InactiveWindowBorder2); + DO_COLOR(InactiveWindowTitle); + DO_COLOR(MovingWindowBorder1); + DO_COLOR(MovingWindowBorder2); + DO_COLOR(MovingWindowTitle); + DO_COLOR(HighlightWindowBorder1); + DO_COLOR(HighlightWindowBorder2); + DO_COLOR(HighlightWindowTitle); + DO_COLOR(MenuStripe); + DO_COLOR(MenuBase); + DO_COLOR(MenuSelection); buffer->seal(); buffer->share_globally(); diff --git a/Libraries/LibDraw/SystemTheme.h b/Libraries/LibDraw/SystemTheme.h index 80c6c32089d..4150dbef41c 100644 --- a/Libraries/LibDraw/SystemTheme.h +++ b/Libraries/LibDraw/SystemTheme.h @@ -4,43 +4,43 @@ #include #include +enum class ColorRole { + NoRole, + DesktopBackground, + ActiveWindowBorder1, + ActiveWindowBorder2, + ActiveWindowTitle, + InactiveWindowBorder1, + InactiveWindowBorder2, + InactiveWindowTitle, + MovingWindowBorder1, + MovingWindowBorder2, + MovingWindowTitle, + HighlightWindowBorder1, + HighlightWindowBorder2, + HighlightWindowTitle, + MenuStripe, + MenuBase, + MenuSelection, + Window, + WindowText, + Button, + ButtonText, + Base, + ThreedHighlight, + ThreedShadow1, + ThreedShadow2, + HoverHighlight, + Selection, + SelectionText, + + __Count, + + DisabledText = ThreedShadow1, +}; + struct SystemTheme { - Color desktop_background; - - Color active_window_border1; - Color active_window_border2; - Color active_window_title; - - Color inactive_window_border1; - Color inactive_window_border2; - Color inactive_window_title; - - Color moving_window_border1; - Color moving_window_border2; - Color moving_window_title; - - Color highlight_window_border1; - Color highlight_window_border2; - Color highlight_window_title; - - Color menu_stripe; - Color menu_base; - Color menu_selection; - - Color window; - Color window_text; - Color base; - Color button; - Color button_text; - - Color threed_highlight; - Color threed_shadow1; - Color threed_shadow2; - - Color hover_highlight; - - Color selection; - Color selection_text; + Color color[(int)ColorRole::__Count]; }; const SystemTheme& current_system_theme(); diff --git a/Libraries/LibGUI/GAbstractButton.cpp b/Libraries/LibGUI/GAbstractButton.cpp index ae3e14ec6cd..4aabeaa3ab4 100644 --- a/Libraries/LibGUI/GAbstractButton.cpp +++ b/Libraries/LibGUI/GAbstractButton.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -154,7 +155,7 @@ void GAbstractButton::paint_text(GPainter& painter, const Rect& rect, const Font if (text().is_empty()) return; - painter.draw_text(clipped_rect, text(), font, text_alignment, SystemColor::ButtonText, TextElision::Right); + painter.draw_text(clipped_rect, text(), font, text_alignment, palette().button_text(), TextElision::Right); if (is_focused()) painter.draw_rect(clipped_rect.inflated(6, 4), Color(140, 140, 140)); } diff --git a/Libraries/LibGUI/GAbstractColumnView.cpp b/Libraries/LibGUI/GAbstractColumnView.cpp index 0c5578f7205..d1d339e1718 100644 --- a/Libraries/LibGUI/GAbstractColumnView.cpp +++ b/Libraries/LibGUI/GAbstractColumnView.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -99,9 +100,9 @@ void GAbstractColumnView::paint_headers(GPainter& painter) if (!headers_visible()) return; int exposed_width = max(content_size().width(), width()); - painter.fill_rect({ 0, 0, exposed_width, header_height() }, SystemColor::Window); - painter.draw_line({ 0, 0 }, { exposed_width - 1, 0 }, SystemColor::ThreedHighlight); - painter.draw_line({ 0, header_height() - 1 }, { exposed_width - 1, header_height() - 1 }, SystemColor::ThreedShadow1); + painter.fill_rect({ 0, 0, exposed_width, header_height() }, palette().button()); + painter.draw_line({ 0, 0 }, { exposed_width - 1, 0 }, palette().threed_highlight()); + painter.draw_line({ 0, header_height() - 1 }, { exposed_width - 1, header_height() - 1 }, palette().threed_shadow1()); int x_offset = 0; int column_count = model()->column_count(); for (int column_index = 0; column_index < column_count; ++column_index) { @@ -112,7 +113,7 @@ void GAbstractColumnView::paint_headers(GPainter& painter) Rect cell_rect(x_offset, 0, column_width + horizontal_padding() * 2, header_height()); bool pressed = column_index == m_pressed_column_header_index && m_pressed_column_header_is_pressed; bool hovered = column_index == m_hovered_column_header_index && model()->column_metadata(column_index).sortable == GModel::ColumnMetadata::Sortable::True; - StylePainter::paint_button(painter, cell_rect, ButtonStyle::Normal, pressed, hovered); + StylePainter::paint_button(painter, cell_rect, palette(), ButtonStyle::Normal, pressed, hovered); String text; if (is_key_column) { StringBuilder builder; @@ -129,7 +130,7 @@ void GAbstractColumnView::paint_headers(GPainter& painter) auto text_rect = cell_rect.translated(horizontal_padding(), 0); if (pressed) text_rect.move_by(1, 1); - painter.draw_text(text_rect, text, header_font(), TextAlignment::CenterLeft, SystemColor::ButtonText); + painter.draw_text(text_rect, text, header_font(), TextAlignment::CenterLeft, palette().button_text()); x_offset += column_width + horizontal_padding() * 2; } } diff --git a/Libraries/LibGUI/GAbstractColumnView.h b/Libraries/LibGUI/GAbstractColumnView.h index bf782dc4daa..dfac52926fa 100644 --- a/Libraries/LibGUI/GAbstractColumnView.h +++ b/Libraries/LibGUI/GAbstractColumnView.h @@ -9,7 +9,7 @@ class GTableCellPaintingDelegate { public: virtual ~GTableCellPaintingDelegate() {} - virtual void paint(GPainter&, const Rect&, const GModel&, const GModelIndex&) = 0; + virtual void paint(GPainter&, const Rect&, const Palette&, const GModel&, const GModelIndex&) = 0; }; class GAbstractColumnView : public GAbstractView { diff --git a/Libraries/LibGUI/GApplication.cpp b/Libraries/LibGUI/GApplication.cpp index ffa89e79f33..5635dafc8fa 100644 --- a/Libraries/LibGUI/GApplication.cpp +++ b/Libraries/LibGUI/GApplication.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -142,3 +143,19 @@ void GApplication::did_delete_last_window(Badge) if (m_quit_when_last_window_deleted) m_event_loop->quit(0); } + +void GApplication::set_system_palette(SharedBuffer& buffer) +{ + if (!m_system_palette) + m_system_palette = Palette::create_with_shared_buffer(buffer); + else + m_system_palette->replace_internal_buffer({}, buffer); + + if (!m_palette) + m_palette = m_system_palette; +} + +void GApplication::set_palette(const Palette& palette) +{ + m_palette = palette; +} diff --git a/Libraries/LibGUI/GApplication.h b/Libraries/LibGUI/GApplication.h index ad8e57e76e5..539ebef04f3 100644 --- a/Libraries/LibGUI/GApplication.h +++ b/Libraries/LibGUI/GApplication.h @@ -10,7 +10,10 @@ class GAction; class GKeyEvent; class GMenuBar; class GWindow; +class GWindowServerConnection; +class Palette; class Point; +class SharedBuffer; class GApplication { public: @@ -39,9 +42,16 @@ public: const String& invoked_as() const { return m_invoked_as; } const Vector& args() const { return m_args; } + const Palette& palette() const { return *m_palette; } + void set_palette(const Palette&); + + void set_system_palette(SharedBuffer&); + private: OwnPtr m_event_loop; OwnPtr m_menubar; + RefPtr m_palette; + RefPtr m_system_palette; HashMap m_global_shortcut_actions; class TooltipWindow; TooltipWindow* m_tooltip_window { nullptr }; diff --git a/Libraries/LibGUI/GButton.cpp b/Libraries/LibGUI/GButton.cpp index c35bbdbb6f0..305224fbfe3 100644 --- a/Libraries/LibGUI/GButton.cpp +++ b/Libraries/LibGUI/GButton.cpp @@ -27,7 +27,7 @@ void GButton::paint_event(GPaintEvent& event) GPainter painter(*this); painter.add_clip_rect(event.rect()); - StylePainter::paint_button(painter, rect(), m_button_style, is_being_pressed(), is_hovered(), is_checked(), is_enabled()); + StylePainter::paint_button(painter, rect(), palette(), m_button_style, is_being_pressed(), is_hovered(), is_checked(), is_enabled()); if (text().is_empty() && !m_icon) return; diff --git a/Libraries/LibGUI/GCheckBox.cpp b/Libraries/LibGUI/GCheckBox.cpp index 958e93a15c3..6378d569e6f 100644 --- a/Libraries/LibGUI/GCheckBox.cpp +++ b/Libraries/LibGUI/GCheckBox.cpp @@ -1,8 +1,9 @@ #include +#include +#include +#include #include #include -#include -#include static const char* s_checked_bitmap_data = { " " @@ -48,14 +49,14 @@ void GCheckBox::paint_event(GPaintEvent& event) text_rect.set_height(font().glyph_height()); if (fill_with_background_color()) - painter.fill_rect(rect(), background_color()); + painter.fill_rect(rect(), palette().window()); Rect box_rect { 0, height() / 2 - s_box_height / 2 - 1, s_box_width, s_box_height }; - painter.fill_rect(box_rect, SystemColor::Base); - StylePainter::paint_frame(painter, box_rect, FrameShape::Container, FrameShadow::Sunken, 2); + painter.fill_rect(box_rect, palette().base()); + StylePainter::paint_frame(painter, box_rect, palette(), FrameShape::Container, FrameShadow::Sunken, 2); if (is_being_pressed()) painter.draw_rect(box_rect.shrunken(4, 4), Color::MidGray); @@ -63,7 +64,7 @@ void GCheckBox::paint_event(GPaintEvent& event) if (is_checked()) { if (!s_checked_bitmap) s_checked_bitmap = &CharacterBitmap::create_from_ascii(s_checked_bitmap_data, s_checked_bitmap_width, s_checked_bitmap_height).leak_ref(); - painter.draw_bitmap(box_rect.shrunken(4, 4).location(), *s_checked_bitmap, SystemColor::ButtonText); + painter.draw_bitmap(box_rect.shrunken(4, 4).location(), *s_checked_bitmap, palette().button_text()); } paint_text(painter, text_rect, font(), TextAlignment::TopLeft); diff --git a/Libraries/LibGUI/GFilePicker.cpp b/Libraries/LibGUI/GFilePicker.cpp index 28d19d197d8..48d03d96c3b 100644 --- a/Libraries/LibGUI/GFilePicker.cpp +++ b/Libraries/LibGUI/GFilePicker.cpp @@ -58,7 +58,6 @@ GFilePicker::GFilePicker(Mode mode, const StringView& file_name, const StringVie horizontal_container->set_layout(make(Orientation::Horizontal)); horizontal_container->layout()->set_margins({ 4, 4, 4, 4 }); horizontal_container->set_fill_with_background_color(true); - horizontal_container->set_background_color(SystemColor::Window); auto vertical_container = GWidget::construct(horizontal_container.ptr()); vertical_container->set_layout(make(Orientation::Vertical)); diff --git a/Libraries/LibGUI/GFrame.cpp b/Libraries/LibGUI/GFrame.cpp index 8854bb5e03f..1097c2de858 100644 --- a/Libraries/LibGUI/GFrame.cpp +++ b/Libraries/LibGUI/GFrame.cpp @@ -18,5 +18,5 @@ void GFrame::paint_event(GPaintEvent& event) GPainter painter(*this); painter.add_clip_rect(event.rect()); - StylePainter::paint_frame(painter, rect(), m_shape, m_shadow, m_thickness, spans_entire_window_horizontally()); + StylePainter::paint_frame(painter, rect(), palette(), m_shape, m_shadow, m_thickness, spans_entire_window_horizontally()); } diff --git a/Libraries/LibGUI/GGroupBox.cpp b/Libraries/LibGUI/GGroupBox.cpp index 3d977902622..dda28157e53 100644 --- a/Libraries/LibGUI/GGroupBox.cpp +++ b/Libraries/LibGUI/GGroupBox.cpp @@ -1,6 +1,7 @@ +#include +#include #include #include -#include GGroupBox::GGroupBox(GWidget* parent) : GGroupBox({}, parent) @@ -11,8 +12,6 @@ GGroupBox::GGroupBox(const StringView& title, GWidget* parent) : GWidget(parent) , m_title(title) { - set_fill_with_background_color(true); - set_background_color(SystemColor::Window); } GGroupBox::~GGroupBox() @@ -28,11 +27,11 @@ void GGroupBox::paint_event(GPaintEvent& event) 0, font().glyph_height() / 2, width(), height() - font().glyph_height() / 2 }; - StylePainter::paint_frame(painter, frame_rect, FrameShape::Box, FrameShadow::Sunken, 2); + StylePainter::paint_frame(painter, frame_rect, palette(), FrameShape::Box, FrameShadow::Sunken, 2); Rect text_rect { 4, 0, font().width(m_title) + 6, font().glyph_height() }; - painter.fill_rect(text_rect, background_color()); - painter.draw_text(text_rect, m_title, TextAlignment::Center, foreground_color()); + painter.fill_rect(text_rect, palette().button()); + painter.draw_text(text_rect, m_title, TextAlignment::Center, palette().button_text()); } void GGroupBox::set_title(const StringView& title) diff --git a/Libraries/LibGUI/GItemView.cpp b/Libraries/LibGUI/GItemView.cpp index 4d1fae39638..15581486b70 100644 --- a/Libraries/LibGUI/GItemView.cpp +++ b/Libraries/LibGUI/GItemView.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -186,12 +187,13 @@ void GItemView::doubleclick_event(GMouseEvent& event) void GItemView::paint_event(GPaintEvent& event) { + Color widget_background_color = palette().color(background_role()); GFrame::paint_event(event); GPainter painter(*this); painter.add_clip_rect(widget_inner_rect()); painter.add_clip_rect(event.rect()); - painter.fill_rect(event.rect(), SystemColor::Base); + painter.fill_rect(event.rect(), widget_background_color); painter.translate(-horizontal_scrollbar().value(), -vertical_scrollbar().value()); auto column_metadata = model()->column_metadata(m_model_column); @@ -201,9 +203,9 @@ void GItemView::paint_event(GPaintEvent& event) bool is_selected_item = selection().contains(model()->index(item_index, m_model_column)); Color background_color; if (is_selected_item) { - background_color = is_focused() ? Color(SystemColor::Selection) : Color::from_rgb(0x606060); + background_color = is_focused() ? palette().selection() : Color::from_rgb(0x606060); } else { - background_color = SystemColor::Base; + background_color = widget_background_color; } Rect item_rect = this->item_rect(item_index); @@ -228,9 +230,9 @@ void GItemView::paint_event(GPaintEvent& event) Color text_color; if (is_selected_item) - text_color = SystemColor::SelectionText; + text_color = palette().selection_text(); else - text_color = model()->data(model_index, GModel::Role::ForegroundColor).to_color(SystemColor::WindowText); + text_color = model()->data(model_index, GModel::Role::ForegroundColor).to_color(palette().color(foreground_role())); painter.fill_rect(text_rect, background_color); painter.draw_text(text_rect, item_text.to_string(), font, TextAlignment::Center, text_color, TextElision::Right); }; diff --git a/Libraries/LibGUI/GLabel.cpp b/Libraries/LibGUI/GLabel.cpp index 5c797fe99e8..622c1e14ff1 100644 --- a/Libraries/LibGUI/GLabel.cpp +++ b/Libraries/LibGUI/GLabel.cpp @@ -1,6 +1,7 @@ -#include "GLabel.h" -#include #include +#include +#include +#include GLabel::GLabel(GWidget* parent) : GFrame(parent) @@ -58,7 +59,7 @@ void GLabel::paint_event(GPaintEvent& event) text_rect.set_width(text_rect.width() - indent * 2); if (is_enabled()) { - painter.draw_text(text_rect, text(), m_text_alignment, foreground_color(), TextElision::Right); + painter.draw_text(text_rect, text(), m_text_alignment, palette().window_text(), TextElision::Right); } else { painter.draw_text(text_rect.translated(1, 1), text(), font(), text_alignment(), Color::White, TextElision::Right); painter.draw_text(text_rect, text(), font(), text_alignment(), Color::from_rgb(0x808080), TextElision::Right); diff --git a/Libraries/LibGUI/GListView.cpp b/Libraries/LibGUI/GListView.cpp index 34467100dc6..d9971469ca2 100644 --- a/Libraries/LibGUI/GListView.cpp +++ b/Libraries/LibGUI/GListView.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -6,6 +7,7 @@ GListView::GListView(GWidget* parent) : GAbstractView(parent) { + set_background_role(ColorRole::Base); set_frame_shape(FrameShape::Container); set_frame_shadow(FrameShadow::Sunken); set_frame_thickness(2); @@ -104,12 +106,12 @@ void GListView::paint_event(GPaintEvent& event) Color background_color; if (is_selected_row) { - background_color = is_focused() ? Color(SystemColor::SelectionText) : Color::from_rgb(0x606060); + background_color = is_focused() ? palette().selection_text() : Color::from_rgb(0x606060); } else { if (alternating_row_colors() && (painted_item_index % 2)) background_color = Color(210, 210, 210); else - background_color = SystemColor::Base; + background_color = palette().color(background_role()); } auto column_metadata = model()->column_metadata(m_model_column); @@ -129,7 +131,7 @@ void GListView::paint_event(GPaintEvent& event) if (is_selected_row) text_color = Color::White; else - text_color = model()->data(index, GModel::Role::ForegroundColor).to_color(SystemColor::WindowText); + text_color = model()->data(index, GModel::Role::ForegroundColor).to_color(palette().color(foreground_role())); auto text_rect = row_rect; text_rect.move_by(horizontal_padding(), 0); text_rect.set_width(text_rect.width() - horizontal_padding() * 2); @@ -140,7 +142,7 @@ void GListView::paint_event(GPaintEvent& event) }; Rect unpainted_rect(0, painted_item_index * item_height(), exposed_width, height()); - painter.fill_rect(unpainted_rect, SystemColor::Base); + painter.fill_rect(unpainted_rect, palette().color(background_role())); } int GListView::item_count() const diff --git a/Libraries/LibGUI/GProgressBar.cpp b/Libraries/LibGUI/GProgressBar.cpp index b10775b2dd7..30730e4e75b 100644 --- a/Libraries/LibGUI/GProgressBar.cpp +++ b/Libraries/LibGUI/GProgressBar.cpp @@ -58,5 +58,5 @@ void GProgressBar::paint_event(GPaintEvent& event) progress_text = builder.to_string(); } - StylePainter::paint_progress_bar(painter, rect, m_min, m_max, m_value, progress_text); + StylePainter::paint_progress_bar(painter, rect, palette(), m_min, m_max, m_value, progress_text); } diff --git a/Libraries/LibGUI/GResizeCorner.cpp b/Libraries/LibGUI/GResizeCorner.cpp index 6016422a6a5..fd08587ea7b 100644 --- a/Libraries/LibGUI/GResizeCorner.cpp +++ b/Libraries/LibGUI/GResizeCorner.cpp @@ -1,11 +1,13 @@ +#include +#include #include #include #include -#include GResizeCorner::GResizeCorner(GWidget* parent) : GWidget(parent) { + set_background_role(ColorRole::Button); set_size_policy(SizePolicy::Fixed, SizePolicy::Fixed); set_preferred_size(16, 16); m_bitmap = GraphicsBitmap::load_from_file("/res/icons/resize-corner.png"); @@ -20,7 +22,7 @@ void GResizeCorner::paint_event(GPaintEvent& event) { GPainter painter(*this); painter.add_clip_rect(event.rect()); - painter.fill_rect(rect(), SystemColor::Button); + painter.fill_rect(rect(), palette().color(background_role())); painter.blit({ 0, 0 }, *m_bitmap, m_bitmap->rect()); GWidget::paint_event(event); } diff --git a/Libraries/LibGUI/GScrollBar.cpp b/Libraries/LibGUI/GScrollBar.cpp index 24eed4761b1..0b89f806c68 100644 --- a/Libraries/LibGUI/GScrollBar.cpp +++ b/Libraries/LibGUI/GScrollBar.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -203,18 +204,18 @@ void GScrollBar::paint_event(GPaintEvent& event) GPainter painter(*this); painter.add_clip_rect(event.rect()); - painter.fill_rect(rect(), Color(SystemColor::Button).lightened()); + painter.fill_rect(rect(), palette().button().lightened()); - StylePainter::paint_button(painter, decrement_button_rect(), ButtonStyle::Normal, false, m_hovered_component == Component::DecrementButton); - StylePainter::paint_button(painter, increment_button_rect(), ButtonStyle::Normal, false, m_hovered_component == Component::IncrementButton); + StylePainter::paint_button(painter, decrement_button_rect(), palette(), ButtonStyle::Normal, false, m_hovered_component == Component::DecrementButton); + StylePainter::paint_button(painter, increment_button_rect(), palette(), ButtonStyle::Normal, false, m_hovered_component == Component::IncrementButton); if (length(orientation()) > default_button_size()) { - painter.draw_bitmap(decrement_button_rect().location().translated(3, 3), orientation() == Orientation::Vertical ? *s_up_arrow_bitmap : *s_left_arrow_bitmap, has_scrubber() ? SystemColor::ButtonText : SystemColor::DisabledText); - painter.draw_bitmap(increment_button_rect().location().translated(3, 3), orientation() == Orientation::Vertical ? *s_down_arrow_bitmap : *s_right_arrow_bitmap, has_scrubber() ? SystemColor::ButtonText : SystemColor::DisabledText); + painter.draw_bitmap(decrement_button_rect().location().translated(3, 3), orientation() == Orientation::Vertical ? *s_up_arrow_bitmap : *s_left_arrow_bitmap, has_scrubber() ? palette().button_text() : palette().threed_shadow1()); + painter.draw_bitmap(increment_button_rect().location().translated(3, 3), orientation() == Orientation::Vertical ? *s_down_arrow_bitmap : *s_right_arrow_bitmap, has_scrubber() ? palette().button_text() : palette().threed_shadow1()); } if (has_scrubber()) - StylePainter::paint_button(painter, scrubber_rect(), ButtonStyle::Normal, false, m_hovered_component == Component::Scrubber || m_scrubber_in_use); + StylePainter::paint_button(painter, scrubber_rect(), palette(), ButtonStyle::Normal, false, m_hovered_component == Component::Scrubber || m_scrubber_in_use); } void GScrollBar::on_automatic_scrolling_timer_fired() diff --git a/Libraries/LibGUI/GSlider.cpp b/Libraries/LibGUI/GSlider.cpp index 730b1d27ad5..16b2223b854 100755 --- a/Libraries/LibGUI/GSlider.cpp +++ b/Libraries/LibGUI/GSlider.cpp @@ -62,8 +62,8 @@ void GSlider::paint_event(GPaintEvent& event) track_rect.center_horizontally_within(inner_rect()); } - StylePainter::paint_frame(painter, track_rect, FrameShape::Panel, FrameShadow::Sunken, 1); - StylePainter::paint_button(painter, knob_rect(), ButtonStyle::Normal, false, m_knob_hovered); + StylePainter::paint_frame(painter, track_rect, palette(), FrameShape::Panel, FrameShadow::Sunken, 1); + StylePainter::paint_button(painter, knob_rect(), palette(), ButtonStyle::Normal, false, m_knob_hovered); } Rect GSlider::knob_rect() const diff --git a/Libraries/LibGUI/GSplitter.cpp b/Libraries/LibGUI/GSplitter.cpp index b1dc2244620..5ca33bf9d71 100644 --- a/Libraries/LibGUI/GSplitter.cpp +++ b/Libraries/LibGUI/GSplitter.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -6,9 +7,9 @@ GSplitter::GSplitter(Orientation orientation, GWidget* parent) : GFrame(parent) , m_orientation(orientation) { + set_background_role(ColorRole::Button); set_layout(make(orientation)); set_fill_with_background_color(true); - set_background_color(SystemColor::Window); layout()->set_spacing(3); } @@ -18,14 +19,14 @@ GSplitter::~GSplitter() void GSplitter::enter_event(CEvent&) { - set_background_color(StylePainter::hover_highlight_color()); + set_background_role(ColorRole::HoverHighlight); window()->set_override_cursor(m_orientation == Orientation::Horizontal ? GStandardCursor::ResizeHorizontal : GStandardCursor::ResizeVertical); update(); } void GSplitter::leave_event(CEvent&) { - set_background_color(SystemColor::Window); + set_background_role(ColorRole::Button); if (!m_resizing) window()->set_override_cursor(GStandardCursor::None); update(); diff --git a/Libraries/LibGUI/GStatusBar.cpp b/Libraries/LibGUI/GStatusBar.cpp index 2624f94423d..1c8a6e341d5 100644 --- a/Libraries/LibGUI/GStatusBar.cpp +++ b/Libraries/LibGUI/GStatusBar.cpp @@ -66,5 +66,5 @@ void GStatusBar::paint_event(GPaintEvent& event) { GPainter painter(*this); painter.add_clip_rect(event.rect()); - StylePainter::paint_surface(painter, rect(), !spans_entire_window_horizontally()); + StylePainter::paint_surface(painter, rect(), palette(), !spans_entire_window_horizontally()); } diff --git a/Libraries/LibGUI/GTabWidget.cpp b/Libraries/LibGUI/GTabWidget.cpp index 49f07dc4be9..927ba54de31 100644 --- a/Libraries/LibGUI/GTabWidget.cpp +++ b/Libraries/LibGUI/GTabWidget.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -6,8 +7,6 @@ GTabWidget::GTabWidget(GWidget* parent) : GWidget(parent) { - set_fill_with_background_color(true); - set_background_color(SystemColor::Window); } GTabWidget::~GTabWidget() @@ -112,19 +111,19 @@ void GTabWidget::paint_event(GPaintEvent& event) auto container_rect = this->container_rect(); auto padding_rect = container_rect; for (int i = 0; i < container_padding(); ++i) { - painter.draw_rect(padding_rect, background_color()); + painter.draw_rect(padding_rect, palette().button()); padding_rect.shrink(2, 2); } - StylePainter::paint_frame(painter, container_rect, FrameShape::Container, FrameShadow::Raised, 2); + StylePainter::paint_frame(painter, container_rect, palette(), FrameShape::Container, FrameShadow::Raised, 2); for (int i = 0; i < m_tabs.size(); ++i) { if (m_tabs[i].widget == m_active_widget) continue; bool hovered = i == m_hovered_tab_index; auto button_rect = this->button_rect(i); - StylePainter::paint_tab_button(painter, button_rect, false, hovered, m_tabs[i].widget->is_enabled()); - painter.draw_text(button_rect.translated(0, 1), m_tabs[i].title, TextAlignment::Center, SystemColor::ButtonText); + StylePainter::paint_tab_button(painter, button_rect, palette(), false, hovered, m_tabs[i].widget->is_enabled()); + painter.draw_text(button_rect.translated(0, 1), m_tabs[i].title, TextAlignment::Center, palette().button_text()); } for (int i = 0; i < m_tabs.size(); ++i) { @@ -132,9 +131,9 @@ void GTabWidget::paint_event(GPaintEvent& event) continue; bool hovered = i == m_hovered_tab_index; auto button_rect = this->button_rect(i); - StylePainter::paint_tab_button(painter, button_rect, true, hovered, m_tabs[i].widget->is_enabled()); - painter.draw_text(button_rect.translated(0, 1), m_tabs[i].title, TextAlignment::Center, SystemColor::ButtonText); - painter.draw_line(button_rect.bottom_left().translated(1, 1), button_rect.bottom_right().translated(-1, 1), SystemColor::Button); + StylePainter::paint_tab_button(painter, button_rect, palette(), true, hovered, m_tabs[i].widget->is_enabled()); + painter.draw_text(button_rect.translated(0, 1), m_tabs[i].title, TextAlignment::Center, palette().button_text()); + painter.draw_line(button_rect.bottom_left().translated(1, 1), button_rect.bottom_right().translated(-1, 1), palette().button()); break; } } diff --git a/Libraries/LibGUI/GTableView.cpp b/Libraries/LibGUI/GTableView.cpp index c0ebd6ff95b..e4a90e7d91a 100644 --- a/Libraries/LibGUI/GTableView.cpp +++ b/Libraries/LibGUI/GTableView.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -12,6 +13,7 @@ GTableView::GTableView(GWidget* parent) : GAbstractColumnView(parent) { + set_background_role(ColorRole::Base); } GTableView::~GTableView() @@ -20,12 +22,13 @@ GTableView::~GTableView() void GTableView::paint_event(GPaintEvent& event) { + Color widget_background_color = palette().color(background_role()); GFrame::paint_event(event); GPainter painter(*this); painter.add_clip_rect(frame_inner_rect()); painter.add_clip_rect(event.rect()); - painter.fill_rect(event.rect(), SystemColor::Base); + painter.fill_rect(event.rect(), widget_background_color); painter.translate(frame_thickness(), frame_thickness()); painter.translate(-horizontal_scrollbar().value(), -vertical_scrollbar().value()); @@ -53,15 +56,15 @@ void GTableView::paint_event(GPaintEvent& event) Color background_color; Color key_column_background_color; if (is_selected_row) { - background_color = is_focused() ? Color(SystemColor::Selection) : Color::from_rgb(0x606060); - key_column_background_color = is_focused() ? Color(SystemColor::Selection) : Color::from_rgb(0x606060); + background_color = is_focused() ? palette().selection() : Color::from_rgb(0x606060); + key_column_background_color = is_focused() ? palette().selection() : Color::from_rgb(0x606060); } else { if (alternating_row_colors() && (painted_item_index % 2)) { - background_color = Color(SystemColor::Base).darkened(0.8f); - key_column_background_color = Color(SystemColor::Base).darkened(0.7f); + background_color = widget_background_color.darkened(0.8f); + key_column_background_color = widget_background_color.darkened(0.7f); } else { - background_color = SystemColor::Base; - key_column_background_color = Color(SystemColor::Base).darkened(0.9f); + background_color = widget_background_color; + key_column_background_color = widget_background_color.darkened(0.9f); } } painter.fill_rect(row_rect(painted_item_index), background_color); @@ -82,7 +85,7 @@ void GTableView::paint_event(GPaintEvent& event) auto cell_index = model()->index(row_index, column_index); if (auto* delegate = column_data(column_index).cell_painting_delegate.ptr()) { - delegate->paint(painter, cell_rect, *model(), cell_index); + delegate->paint(painter, cell_rect, palette(), *model(), cell_index); } else { auto data = model()->data(cell_index); if (data.is_bitmap()) { @@ -93,9 +96,9 @@ void GTableView::paint_event(GPaintEvent& event) } else { Color text_color; if (is_selected_row) - text_color = SystemColor::SelectionText; + text_color = palette().selection_text(); else - text_color = model()->data(cell_index, GModel::Role::ForegroundColor).to_color(SystemColor::WindowText); + text_color = model()->data(cell_index, GModel::Role::ForegroundColor).to_color(palette().color(foreground_role())); painter.draw_text(cell_rect, data.to_string(), font, column_metadata.text_alignment, text_color, TextElision::Right); } } @@ -105,7 +108,7 @@ void GTableView::paint_event(GPaintEvent& event) }; Rect unpainted_rect(0, header_height() + painted_item_index * item_height(), exposed_width, height()); - painter.fill_rect(unpainted_rect, SystemColor::Base); + painter.fill_rect(unpainted_rect, widget_background_color); // Untranslate the painter vertically and do the column headers. painter.translate(0, vertical_scrollbar().value()); diff --git a/Libraries/LibGUI/GTextEditor.cpp b/Libraries/LibGUI/GTextEditor.cpp index cca6dcf6753..accd3890d6e 100644 --- a/Libraries/LibGUI/GTextEditor.cpp +++ b/Libraries/LibGUI/GTextEditor.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -295,6 +296,7 @@ Rect GTextEditor::visible_text_rect_in_inner_coordinates() const void GTextEditor::paint_event(GPaintEvent& event) { + Color widget_background_color = palette().color(background_role()); // NOTE: This ensures that spans are updated before we look at them. flush_pending_change_notification_if_needed(); @@ -303,15 +305,15 @@ void GTextEditor::paint_event(GPaintEvent& event) GPainter painter(*this); painter.add_clip_rect(widget_inner_rect()); painter.add_clip_rect(event.rect()); - painter.fill_rect(event.rect(), SystemColor::Base); + painter.fill_rect(event.rect(), widget_background_color); painter.translate(frame_thickness(), frame_thickness()); auto ruler_rect = ruler_rect_in_inner_coordinates(); if (m_ruler_visible) { - painter.fill_rect(ruler_rect, Color(SystemColor::Base).darkened(0.85f)); - painter.draw_line(ruler_rect.top_right(), ruler_rect.bottom_right(), Color(SystemColor::Base).darkened(0.5f)); + painter.fill_rect(ruler_rect, widget_background_color.darkened(0.85f)); + painter.draw_line(ruler_rect.top_right(), ruler_rect.bottom_right(), widget_background_color.darkened(0.5f)); } painter.translate(-horizontal_scrollbar().value(), -vertical_scrollbar().value()); @@ -333,7 +335,7 @@ void GTextEditor::paint_event(GPaintEvent& event) String::number(i + 1), is_current_line ? Font::default_bold_font() : font(), TextAlignment::TopRight, - is_current_line ? Color(SystemColor::Base).darkened(0.6f) : Color(SystemColor::Base).darkened(0.7f)); + is_current_line ? widget_background_color.darkened(0.6f) : widget_background_color.darkened(0.7f)); } } @@ -369,13 +371,13 @@ void GTextEditor::paint_event(GPaintEvent& event) size_t visual_line_index = 0; for_each_visual_line(line_index, [&](const Rect& visual_line_rect, const StringView& visual_line_text, size_t start_of_visual_line) { if (is_multi_line() && line_index == m_cursor.line()) - painter.fill_rect(visual_line_rect, Color(SystemColor::Base).darkened(0.9f)); + painter.fill_rect(visual_line_rect, widget_background_color.darkened(0.9f)); #ifdef DEBUG_GTEXTEDITOR painter.draw_rect(visual_line_rect, Color::Cyan); #endif if (!document().has_spans()) { // Fast-path for plain text - painter.draw_text(visual_line_rect, visual_line_text, m_text_alignment, SystemColor::WindowText); + painter.draw_text(visual_line_rect, visual_line_text, m_text_alignment, palette().color(foreground_role())); } else { int advance = font().glyph_width(' ') + font().glyph_spacing(); Rect character_rect = { visual_line_rect.location(), { font().glyph_width(' '), line_height() } }; @@ -424,7 +426,7 @@ void GTextEditor::paint_event(GPaintEvent& event) visual_line_rect.height() }; - painter.fill_rect(selection_rect, SystemColor::Selection); + painter.fill_rect(selection_rect, palette().selection()); size_t start_of_selection_within_visual_line = (size_t)max(0, (int)selection_start_column_within_line - (int)start_of_visual_line); size_t end_of_selection_within_visual_line = selection_end_column_within_line - start_of_visual_line; @@ -434,7 +436,7 @@ void GTextEditor::paint_event(GPaintEvent& event) end_of_selection_within_visual_line - start_of_selection_within_visual_line }; - painter.draw_text(selection_rect, visual_selected_text, TextAlignment::CenterLeft, SystemColor::SelectionText); + painter.draw_text(selection_rect, visual_selected_text, TextAlignment::CenterLeft, palette().selection_text()); } } ++visual_line_index; diff --git a/Libraries/LibGUI/GToolBar.cpp b/Libraries/LibGUI/GToolBar.cpp index 107a4068f46..3ae764498ee 100644 --- a/Libraries/LibGUI/GToolBar.cpp +++ b/Libraries/LibGUI/GToolBar.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -71,8 +72,8 @@ public: GPainter painter(*this); painter.add_clip_rect(event.rect()); painter.translate(rect().center().x() - 1, 0); - painter.draw_line({ 0, 0 }, { 0, rect().bottom() }, SystemColor::ThreedShadow1); - painter.draw_line({ 1, 0 }, { 1, rect().bottom() }, SystemColor::ThreedHighlight); + painter.draw_line({ 0, 0 }, { 0, rect().bottom() }, palette().threed_shadow1()); + painter.draw_line({ 1, 0 }, { 1, rect().bottom() }, palette().threed_highlight()); } }; @@ -90,7 +91,7 @@ void GToolBar::paint_event(GPaintEvent& event) painter.add_clip_rect(event.rect()); if (m_has_frame) - StylePainter::paint_surface(painter, rect(), x() != 0, y() != 0); + StylePainter::paint_surface(painter, rect(), palette(), x() != 0, y() != 0); else - painter.fill_rect(event.rect(), background_color()); + painter.fill_rect(event.rect(), palette().button()); } diff --git a/Libraries/LibGUI/GTreeView.cpp b/Libraries/LibGUI/GTreeView.cpp index 4bd569e21d7..a74b36768b3 100644 --- a/Libraries/LibGUI/GTreeView.cpp +++ b/Libraries/LibGUI/GTreeView.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -23,6 +24,7 @@ GTreeView::MetadataForIndex& GTreeView::ensure_metadata_for_index(const GModelIn GTreeView::GTreeView(GWidget* parent) : GAbstractColumnView(parent) { + set_background_role(ColorRole::Base); set_size_columns_to_fit_content(true); set_headers_visible(false); m_expand_bitmap = GraphicsBitmap::load_from_file("/res/icons/treeview-expand.png"); @@ -146,7 +148,7 @@ void GTreeView::paint_event(GPaintEvent& event) GPainter painter(*this); painter.add_clip_rect(frame_inner_rect()); painter.add_clip_rect(event.rect()); - painter.fill_rect(event.rect(), SystemColor::Base); + painter.fill_rect(event.rect(), palette().color(background_role())); if (!model()) return; @@ -178,21 +180,21 @@ void GTreeView::paint_event(GPaintEvent& event) bool is_selected_row = selection().contains(index); - Color text_color = SystemColor::WindowText; + Color text_color = palette().color(foreground_role()); if (is_selected_row) text_color = Color::White; Color background_color; Color key_column_background_color; if (is_selected_row) { - background_color = is_focused() ? Color(SystemColor::Selection) : Color::from_rgb(0x606060); - key_column_background_color = is_focused() ? Color(SystemColor::Selection) : Color::from_rgb(0x606060); + background_color = is_focused() ? palette().selection() : Color::from_rgb(0x606060); + key_column_background_color = is_focused() ? palette().selection() : Color::from_rgb(0x606060); } else { if (alternating_row_colors() && (painted_row_index % 2)) { background_color = Color(220, 220, 220); key_column_background_color = Color(200, 200, 200); } else { - background_color = SystemColor::Base; + background_color = palette().color(background_role()); key_column_background_color = Color(220, 220, 220); } } @@ -215,7 +217,7 @@ void GTreeView::paint_event(GPaintEvent& event) auto cell_index = model.sibling(index.row(), column_index, index.parent()); if (auto* delegate = column_data(column_index).cell_painting_delegate.ptr()) { - delegate->paint(painter, cell_rect, model, cell_index); + delegate->paint(painter, cell_rect, palette(), model, cell_index); } else { auto data = model.data(cell_index); @@ -226,7 +228,7 @@ void GTreeView::paint_event(GPaintEvent& event) painter.blit(cell_rect.location(), *bitmap, bitmap->rect()); } else { if (!is_selected_row) - text_color = model.data(cell_index, GModel::Role::ForegroundColor).to_color(SystemColor::WindowText); + text_color = model.data(cell_index, GModel::Role::ForegroundColor).to_color(palette().color(foreground_role())); painter.draw_text(cell_rect, data.to_string(), font, column_metadata.text_alignment, text_color, TextElision::Right); } } diff --git a/Libraries/LibGUI/GWidget.cpp b/Libraries/LibGUI/GWidget.cpp index e55ca522af4..71c472c0f21 100644 --- a/Libraries/LibGUI/GWidget.cpp +++ b/Libraries/LibGUI/GWidget.cpp @@ -1,26 +1,26 @@ #include #include #include +#include #include #include +#include +#include #include +#include +#include #include #include #include -#include -#include -#include -#include - -#include -#include -#include -#include #include #include #include #include #include +#include +#include +#include +#include REGISTER_GWIDGET(GButton) REGISTER_GWIDGET(GCheckBox) @@ -67,9 +67,8 @@ const GWidgetClassRegistration* GWidgetClassRegistration::find(const String& cla GWidget::GWidget(GWidget* parent) : CObject(parent, true) , m_font(Font::default_font()) + , m_palette(GApplication::the().palette()) { - m_background_color = SystemColor::Window; - m_foreground_color = SystemColor::WindowText; } GWidget::~GWidget() @@ -173,7 +172,7 @@ void GWidget::handle_paint_event(GPaintEvent& event) ASSERT(is_visible()); if (fill_with_background_color()) { GPainter painter(*this); - painter.fill_rect(event.rect(), background_color()); + painter.fill_rect(event.rect(), palette().color(background_role())); } else { #ifdef DEBUG_WIDGET_UNDERDRAW // FIXME: This is a bit broken. @@ -693,3 +692,8 @@ Vector GWidget::child_widgets() const } return widgets; } + +void GWidget::set_palette(const Palette& palette) +{ + m_palette = palette; +} diff --git a/Libraries/LibGUI/GWidget.h b/Libraries/LibGUI/GWidget.h index 59a336c9477..b993a84f8d0 100644 --- a/Libraries/LibGUI/GWidget.h +++ b/Libraries/LibGUI/GWidget.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -16,11 +17,12 @@ extern GWidgetClassRegistration registration_##class_name; \ GWidgetClassRegistration registration_##class_name(#class_name, [](GWidget* parent) { return class_name::construct(parent); }); -class GraphicsBitmap; class GAction; class GLayout; class GMenu; class GWindow; +class GraphicsBitmap; +class Palette; enum class SizePolicy { Fixed, @@ -149,6 +151,12 @@ public: void move_by(int x, int y) { move_by({ x, y }); } void move_by(const Point& delta) { set_relative_rect({ relative_position().translated(delta), size() }); } + ColorRole background_role() const { return m_background_role; } + void set_background_role(ColorRole role) { m_background_role = role; } + + ColorRole foreground_role() const { return m_foreground_role; } + void set_foreground_role(ColorRole role) { m_foreground_role = role; } + Color background_color() const { return m_background_color; } Color foreground_color() const { return m_foreground_color; } @@ -230,6 +238,9 @@ public: void do_layout(); + const Palette& palette() const { return *m_palette; } + void set_palette(const Palette&); + protected: explicit GWidget(GWidget* parent = nullptr); @@ -271,6 +282,8 @@ private: OwnPtr m_layout; Rect m_relative_rect; + ColorRole m_background_role { ColorRole::Window }; + ColorRole m_foreground_role { ColorRole::WindowText }; Color m_background_color; Color m_foreground_color; NonnullRefPtr m_font; @@ -288,6 +301,8 @@ private: bool m_updates_enabled { true }; HashMap m_local_shortcut_actions; + + NonnullRefPtr m_palette; }; template<> diff --git a/Libraries/LibGUI/GWindowServerConnection.cpp b/Libraries/LibGUI/GWindowServerConnection.cpp index d7f98e8ce8c..b1e64476294 100644 --- a/Libraries/LibGUI/GWindowServerConnection.cpp +++ b/Libraries/LibGUI/GWindowServerConnection.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -25,6 +26,7 @@ static void set_system_theme_from_shared_buffer_id(int id) auto system_theme = SharedBuffer::create_from_shared_buffer_id(id); ASSERT(system_theme); set_system_theme(*system_theme); + GApplication::the().set_system_palette(*system_theme); } void GWindowServerConnection::handshake() diff --git a/Libraries/LibHTML/HtmlView.cpp b/Libraries/LibHTML/HtmlView.cpp index cb72d44d611..db6f0943176 100644 --- a/Libraries/LibHTML/HtmlView.cpp +++ b/Libraries/LibHTML/HtmlView.cpp @@ -118,7 +118,7 @@ void HtmlView::paint_event(GPaintEvent& event) painter.add_clip_rect(event.rect()); if (!layout_root()) { - painter.fill_rect(event.rect(), background_color()); + painter.fill_rect(event.rect(), palette().color(background_role())); return; } @@ -131,7 +131,7 @@ void HtmlView::paint_event(GPaintEvent& event) painter.translate(frame_thickness(), frame_thickness()); painter.translate(-horizontal_scrollbar().value(), -vertical_scrollbar().value()); - RenderingContext context { painter }; + RenderingContext context(painter, palette()); context.set_should_show_line_box_borders(m_should_show_line_box_borders); context.set_viewport_rect(visible_content_rect()); layout_root()->render(context); diff --git a/Libraries/LibHTML/Layout/LayoutImage.cpp b/Libraries/LibHTML/Layout/LayoutImage.cpp index 2666d2149b3..43213bbc443 100644 --- a/Libraries/LibHTML/Layout/LayoutImage.cpp +++ b/Libraries/LibHTML/Layout/LayoutImage.cpp @@ -43,7 +43,7 @@ void LayoutImage::render(RenderingContext& context) if (renders_as_alt_text()) { context.painter().set_font(Font::default_font()); - StylePainter::paint_frame(context.painter(), enclosing_int_rect(rect()), FrameShape::Container, FrameShadow::Sunken, 2); + StylePainter::paint_frame(context.painter(), enclosing_int_rect(rect()), context.palette(), FrameShape::Container, FrameShadow::Sunken, 2); auto alt = node().alt(); if (alt.is_empty()) alt = node().src(); diff --git a/Libraries/LibHTML/RenderingContext.h b/Libraries/LibHTML/RenderingContext.h index ee048035abb..7994b61cb00 100644 --- a/Libraries/LibHTML/RenderingContext.h +++ b/Libraries/LibHTML/RenderingContext.h @@ -1,17 +1,20 @@ #pragma once +#include #include class GPainter; class RenderingContext { public: - explicit RenderingContext(GPainter& painter) + explicit RenderingContext(GPainter& painter, const Palette& palette) : m_painter(painter) + , m_palette(palette) { } GPainter& painter() const { return m_painter; } + const Palette& palette() const { return m_palette; } bool should_show_line_box_borders() const { return m_should_show_line_box_borders; } void set_should_show_line_box_borders(bool value) { m_should_show_line_box_borders = value; } @@ -21,6 +24,7 @@ public: private: GPainter& m_painter; + const Palette& m_palette; Rect m_viewport_rect; bool m_should_show_line_box_borders { false }; }; diff --git a/Servers/WindowServer/WSButton.cpp b/Servers/WindowServer/WSButton.cpp index f7d9970557d..0c6d749d41f 100644 --- a/Servers/WindowServer/WSButton.cpp +++ b/Servers/WindowServer/WSButton.cpp @@ -18,14 +18,15 @@ WSButton::~WSButton() void WSButton::paint(Painter& painter) { + auto& palette = WSWindowManager::the().palette(); PainterStateSaver saver(painter); painter.translate(relative_rect().location()); - StylePainter::paint_button(painter, rect(), ButtonStyle::Normal, m_pressed, m_hovered); + StylePainter::paint_button(painter, rect(), palette, ButtonStyle::Normal, m_pressed, m_hovered); auto x_location = rect().center(); x_location.move_by(-(m_bitmap->width() / 2), -(m_bitmap->height() / 2)); if (m_pressed) x_location.move_by(1, 1); - painter.draw_bitmap(x_location, *m_bitmap, SystemColor::ButtonText); + painter.draw_bitmap(x_location, *m_bitmap, palette.button_text()); } void WSButton::on_mouse_event(const WSMouseEvent& event) diff --git a/Servers/WindowServer/WSCompositor.cpp b/Servers/WindowServer/WSCompositor.cpp index ee166e4df33..29c6fe0f1bc 100644 --- a/Servers/WindowServer/WSCompositor.cpp +++ b/Servers/WindowServer/WSCompositor.cpp @@ -113,7 +113,7 @@ void WSCompositor::compose() if (wm.any_opaque_window_contains_rect(dirty_rect)) continue; // FIXME: If the wallpaper is opaque, no need to fill with color! - m_back_painter->fill_rect(dirty_rect, SystemColor::DesktopBackground); + m_back_painter->fill_rect(dirty_rect, wm.palette().desktop_background()); if (m_wallpaper) { if (m_wallpaper_mode == WallpaperMode::Simple) { m_back_painter->blit(dirty_rect.location(), *m_wallpaper, dirty_rect); diff --git a/Servers/WindowServer/WSMenu.cpp b/Servers/WindowServer/WSMenu.cpp index f1bf9002591..7d09933a83a 100644 --- a/Servers/WindowServer/WSMenu.cpp +++ b/Servers/WindowServer/WSMenu.cpp @@ -126,6 +126,7 @@ WSWindow& WSMenu::ensure_menu_window() void WSMenu::draw() { + auto& palette = WSWindowManager::the().palette(); m_theme_index_at_last_paint = WSWindowManager::the().theme_index(); ASSERT(menu_window()); @@ -133,8 +134,8 @@ void WSMenu::draw() Painter painter(*menu_window()->backing_store()); Rect rect { {}, menu_window()->size() }; - painter.fill_rect(rect.shrunken(6, 6), SystemColor::MenuBase); - StylePainter::paint_window_frame(painter, rect); + painter.fill_rect(rect.shrunken(6, 6), palette.menu_base()); + StylePainter::paint_window_frame(painter, rect, palette); int width = this->width(); if (!s_checked_bitmap) @@ -148,15 +149,15 @@ void WSMenu::draw() } Rect stripe_rect { frame_thickness(), frame_thickness(), s_stripe_width, height() - frame_thickness() * 2 }; - painter.fill_rect(stripe_rect, SystemColor::MenuStripe); - painter.draw_line(stripe_rect.top_right(), stripe_rect.bottom_right(), Color(SystemColor::MenuStripe).darkened()); + painter.fill_rect(stripe_rect, palette.menu_stripe()); + painter.draw_line(stripe_rect.top_right(), stripe_rect.bottom_right(), palette.menu_stripe().darkened()); for (auto& item : m_items) { if (item.type() == WSMenuItem::Text) { - Color text_color = SystemColor::WindowText; + Color text_color = palette.window_text(); if (&item == m_hovered_item && item.is_enabled()) { - painter.fill_rect(item.rect(), SystemColor::MenuSelection); - painter.draw_rect(item.rect(), Color(SystemColor::MenuSelection).darkened()); + painter.fill_rect(item.rect(), palette.menu_selection()); + painter.draw_rect(item.rect(), palette.menu_selection().darkened()); text_color = Color::White; } else if (!item.is_enabled()) { text_color = Color::MidGray; @@ -166,10 +167,10 @@ void WSMenu::draw() Rect checkmark_rect { item.rect().x() + 7, 0, s_checked_bitmap_width, s_checked_bitmap_height }; checkmark_rect.center_vertically_within(text_rect); Rect checkbox_rect = checkmark_rect.inflated(4, 4); - painter.fill_rect(checkbox_rect, SystemColor::Base); - StylePainter::paint_frame(painter, checkbox_rect, FrameShape::Container, FrameShadow::Sunken, 2); + painter.fill_rect(checkbox_rect, palette.base()); + StylePainter::paint_frame(painter, checkbox_rect, palette, FrameShape::Container, FrameShadow::Sunken, 2); if (item.is_checked()) { - painter.draw_bitmap(checkmark_rect.location(), *s_checked_bitmap, SystemColor::ButtonText); + painter.draw_bitmap(checkmark_rect.location(), *s_checked_bitmap, palette.button_text()); } } else if (item.icon()) { Rect icon_rect { item.rect().x() + 3, 0, s_item_icon_width, s_item_icon_width }; @@ -189,13 +190,13 @@ void WSMenu::draw() s_submenu_arrow_bitmap_height }; submenu_arrow_rect.center_vertically_within(item.rect()); - painter.draw_bitmap(submenu_arrow_rect.location(), submenu_arrow_bitmap, SystemColor::WindowText); + painter.draw_bitmap(submenu_arrow_rect.location(), submenu_arrow_bitmap, palette.window_text()); } } else if (item.type() == WSMenuItem::Separator) { Point p1(item.rect().translated(stripe_rect.width() + 4, 0).x(), item.rect().center().y() - 1); Point p2(width - 7, item.rect().center().y() - 1); - painter.draw_line(p1, p2, SystemColor::ThreedShadow1); - painter.draw_line(p1.translated(0, 1), p2.translated(0, 1), SystemColor::ThreedHighlight); + painter.draw_line(p1, p2, palette.threed_shadow1()); + painter.draw_line(p1.translated(0, 1), p2.translated(0, 1), palette.threed_highlight()); } } } diff --git a/Servers/WindowServer/WSMenuManager.cpp b/Servers/WindowServer/WSMenuManager.cpp index 5db49f1f34e..67139e81716 100644 --- a/Servers/WindowServer/WSMenuManager.cpp +++ b/Servers/WindowServer/WSMenuManager.cpp @@ -44,6 +44,7 @@ bool WSMenuManager::is_open(const WSMenu& menu) const void WSMenuManager::draw() { auto& wm = WSWindowManager::the(); + auto& palette = wm.palette(); auto menubar_rect = this->menubar_rect(); if (m_needs_window_resize) { @@ -83,14 +84,14 @@ void WSMenuManager::draw() Painter painter(*window().backing_store()); - painter.fill_rect(menubar_rect, SystemColor::Window); - painter.draw_line({ 0, menubar_rect.bottom() }, { menubar_rect.right(), menubar_rect.bottom() }, SystemColor::ThreedShadow1); + painter.fill_rect(menubar_rect, palette.window()); + painter.draw_line({ 0, menubar_rect.bottom() }, { menubar_rect.right(), menubar_rect.bottom() }, palette.threed_shadow1()); int index = 0; wm.for_each_active_menubar_menu([&](WSMenu& menu) { - Color text_color = SystemColor::WindowText; + Color text_color = palette.window_text(); if (is_open(menu)) { - painter.fill_rect(menu.rect_in_menubar(), SystemColor::MenuSelection); - painter.draw_rect(menu.rect_in_menubar(), Color(SystemColor::MenuSelection).darkened()); + painter.fill_rect(menu.rect_in_menubar(), palette.menu_selection()); + painter.draw_rect(menu.rect_in_menubar(), palette.menu_selection().darkened()); text_color = Color::White; } painter.draw_text( @@ -103,7 +104,7 @@ void WSMenuManager::draw() return IterationDecision::Continue; }); - painter.draw_text(m_username_rect, m_username, Font::default_bold_font(), TextAlignment::CenterRight, SystemColor::WindowText); + painter.draw_text(m_username_rect, m_username, Font::default_bold_font(), TextAlignment::CenterRight, palette.window_text()); time_t now = time(nullptr); auto* tm = localtime(&now); @@ -115,7 +116,7 @@ void WSMenuManager::draw() tm->tm_min, tm->tm_sec); - painter.draw_text(m_time_rect, time_text, wm.font(), TextAlignment::CenterRight, SystemColor::WindowText); + painter.draw_text(m_time_rect, time_text, wm.font(), TextAlignment::CenterRight, palette.window_text()); for (auto& applet : m_applets) { if (!applet) diff --git a/Servers/WindowServer/WSWindowFrame.cpp b/Servers/WindowServer/WSWindowFrame.cpp index 2d8755772fb..da968a28a12 100644 --- a/Servers/WindowServer/WSWindowFrame.cpp +++ b/Servers/WindowServer/WSWindowFrame.cpp @@ -153,6 +153,7 @@ void WSWindowFrame::paint(Painter& painter) if (m_window.type() != WSWindowType::Normal) return; + auto& palette = WSWindowManager::the().palette(); auto& window = m_window; auto titlebar_rect = title_bar_rect(); @@ -170,29 +171,29 @@ void WSWindowFrame::paint(Painter& painter) auto& wm = WSWindowManager::the(); if (&window == wm.m_highlight_window) { - border_color = SystemColor::HighlightWindowBorder1; - border_color2 = SystemColor::HighlightWindowBorder2; - title_color = SystemColor::HighlightWindowTitle; + border_color = palette.highlight_window_border1(); + border_color2 = palette.highlight_window_border2(); + title_color = palette.highlight_window_title(); } else if (&window == wm.m_move_window) { - border_color = SystemColor::MovingWindowBorder1; - border_color2 = SystemColor::MovingWindowBorder2; - title_color = SystemColor::MovingWindowTitle; + border_color = palette.moving_window_border1(); + border_color2 = palette.moving_window_border2(); + title_color = palette.moving_window_title(); } else if (&window == wm.m_active_window) { - border_color = SystemColor::ActiveWindowBorder1; - border_color2 = SystemColor::ActiveWindowBorder2; - title_color = SystemColor::ActiveWindowTitle; + border_color = palette.active_window_border1(); + border_color2 = palette.active_window_border2(); + title_color = palette.active_window_title(); } else { - border_color = SystemColor::InactiveWindowBorder1; - border_color2 = SystemColor::InactiveWindowBorder2; - title_color = SystemColor::InactiveWindowTitle; + border_color = palette.inactive_window_border1(); + border_color2 = palette.inactive_window_border2(); + title_color = palette.inactive_window_title(); } - StylePainter::paint_window_frame(painter, outer_rect); + StylePainter::paint_window_frame(painter, outer_rect, palette); if (!window.show_titlebar()) return; - painter.draw_line(titlebar_rect.bottom_left().translated(0, 1), titlebar_rect.bottom_right().translated(0, 1), SystemColor::Button); + painter.draw_line(titlebar_rect.bottom_left().translated(0, 1), titlebar_rect.bottom_right().translated(0, 1), palette.button()); auto leftmost_button_rect = m_buttons.is_empty() ? Rect() : m_buttons.last().relative_rect(); diff --git a/Servers/WindowServer/WSWindowManager.cpp b/Servers/WindowServer/WSWindowManager.cpp index be1f2fb71fe..af61885a66e 100644 --- a/Servers/WindowServer/WSWindowManager.cpp +++ b/Servers/WindowServer/WSWindowManager.cpp @@ -42,7 +42,8 @@ WSWindowManager& WSWindowManager::the() return *s_the; } -WSWindowManager::WSWindowManager() +WSWindowManager::WSWindowManager(const Palette& palette) + : m_palette(palette) { s_the = this; @@ -132,6 +133,7 @@ WSWindowManager::WSWindowManager() auto new_theme = load_system_theme(theme.path); ASSERT(new_theme); set_system_theme(*new_theme); + m_palette = Palette::create_with_shared_buffer(*new_theme); HashTable notified_clients; for_each_window([&](WSWindow& window) { if (window.client()) { diff --git a/Servers/WindowServer/WSWindowManager.h b/Servers/WindowServer/WSWindowManager.h index 2f19aa9b7d0..a7ec2db210e 100644 --- a/Servers/WindowServer/WSWindowManager.h +++ b/Servers/WindowServer/WSWindowManager.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -50,10 +51,15 @@ class WSWindowManager : public CObject { public: static WSWindowManager& the(); - WSWindowManager(); + explicit WSWindowManager(const Palette&); virtual ~WSWindowManager() override; - RefPtr wm_config() const { return m_wm_config; } + const Palette& palette() const { return *m_palette; } + + RefPtr wm_config() const + { + return m_wm_config; + } void reload_config(bool); void add_window(WSWindow&); @@ -276,6 +282,8 @@ private: WeakPtr m_cursor_tracking_button; WeakPtr m_hovered_button; + NonnullRefPtr m_palette; + RefPtr m_wm_config; struct AppMetadata { diff --git a/Servers/WindowServer/WSWindowSwitcher.cpp b/Servers/WindowServer/WSWindowSwitcher.cpp index c88074ea376..f98499a43d3 100644 --- a/Servers/WindowServer/WSWindowSwitcher.cpp +++ b/Servers/WindowServer/WSWindowSwitcher.cpp @@ -70,9 +70,10 @@ void WSWindowSwitcher::on_key_event(const WSKeyEvent& event) void WSWindowSwitcher::draw() { + auto& palette = WSWindowManager::the().palette(); Painter painter(*m_switcher_window->backing_store()); - painter.fill_rect({ {}, m_rect.size() }, SystemColor::Window); - painter.draw_rect({ {}, m_rect.size() }, SystemColor::ThreedShadow2); + painter.fill_rect({ {}, m_rect.size() }, palette.window()); + painter.draw_rect({ {}, m_rect.size() }, palette.threed_shadow2()); for (int index = 0; index < m_windows.size(); ++index) { auto& window = *m_windows.at(index); Rect item_rect { @@ -84,21 +85,21 @@ void WSWindowSwitcher::draw() Color text_color; Color rect_text_color; if (index == m_selected_index) { - painter.fill_rect(item_rect, SystemColor::Selection); - text_color = SystemColor::SelectionText; - rect_text_color = SystemColor::ThreedShadow1; + painter.fill_rect(item_rect, palette.selection()); + text_color = palette.selection_text(); + rect_text_color = palette.threed_shadow1(); } else { - text_color = SystemColor::WindowText; - rect_text_color = SystemColor::ThreedShadow2; + text_color = palette.window_text(); + rect_text_color = palette.threed_shadow2(); } item_rect.shrink(item_padding(), 0); Rect thumbnail_rect = { item_rect.location().translated(0, 5), { thumbnail_width(), thumbnail_height() } }; if (window.backing_store()) { painter.draw_scaled_bitmap(thumbnail_rect, *window.backing_store(), window.backing_store()->rect()); - StylePainter::paint_frame(painter, thumbnail_rect.inflated(4, 4), FrameShape::Container, FrameShadow::Sunken, 2); + StylePainter::paint_frame(painter, thumbnail_rect.inflated(4, 4), palette, FrameShape::Container, FrameShadow::Sunken, 2); } Rect icon_rect = { thumbnail_rect.bottom_right().translated(-window.icon().width(), -window.icon().height()), { window.icon().width(), window.icon().height() } }; - painter.fill_rect(icon_rect, SystemColor::Window); + painter.fill_rect(icon_rect, palette.window()); painter.blit(icon_rect.location(), window.icon(), window.icon().rect()); painter.draw_text(item_rect.translated(thumbnail_width() + 12, 0), window.title(), WSWindowManager::the().window_title_font(), TextAlignment::CenterLeft, text_color); painter.draw_text(item_rect, window.rect().to_string(), TextAlignment::CenterRight, rect_text_color); diff --git a/Servers/WindowServer/main.cpp b/Servers/WindowServer/main.cpp index c629f9464d9..c12a53d4966 100644 --- a/Servers/WindowServer/main.cpp +++ b/Servers/WindowServer/main.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -25,13 +26,14 @@ int main(int, char**) auto theme = load_system_theme(String::format("/res/themes/%s.ini", theme_name.characters())); ASSERT(theme); set_system_theme(*theme); + auto palette = Palette::create_with_shared_buffer(*theme); WSEventLoop loop; WSScreen screen(wm_config->read_num_entry("Screen", "Width", 1024), wm_config->read_num_entry("Screen", "Height", 768)); WSCompositor::the(); - auto wm = WSWindowManager::construct(); + auto wm = WSWindowManager::construct(*palette); dbgprintf("Entering WindowServer main loop.\n"); loop.exec();