diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-12-24 20:57:54 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-12-24 21:27:16 +0100 |
commit | a79bac428b7857b9db2d0641daf3b7f2e3deb91f (patch) | |
tree | 7fee3f0764147238e218b79aa1f526c36deeecb0 /Servers | |
parent | cb4e51a7a58d1c536d51484f83239d8cd9009616 (diff) | |
download | serenity-a79bac428b7857b9db2d0641daf3b7f2e3deb91f.zip |
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.
Diffstat (limited to 'Servers')
-rw-r--r-- | Servers/WindowServer/WSButton.cpp | 5 | ||||
-rw-r--r-- | Servers/WindowServer/WSCompositor.cpp | 2 | ||||
-rw-r--r-- | Servers/WindowServer/WSMenu.cpp | 27 | ||||
-rw-r--r-- | Servers/WindowServer/WSMenuManager.cpp | 15 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindowFrame.cpp | 29 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindowManager.cpp | 4 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindowManager.h | 12 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindowSwitcher.cpp | 19 | ||||
-rw-r--r-- | Servers/WindowServer/main.cpp | 4 |
9 files changed, 67 insertions, 50 deletions
diff --git a/Servers/WindowServer/WSButton.cpp b/Servers/WindowServer/WSButton.cpp index f7d9970557..0c6d749d41 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 ee166e4df3..29c6fe0f1b 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 f1bf900259..7d09933a83 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 5db49f1f34..67139e8171 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 2d8755772f..da968a28a1 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 be1f2fb71f..af61885a66 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<WSClientConnection*> notified_clients; for_each_window([&](WSWindow& window) { if (window.client()) { diff --git a/Servers/WindowServer/WSWindowManager.h b/Servers/WindowServer/WSWindowManager.h index 2f19aa9b7d..a7ec2db210 100644 --- a/Servers/WindowServer/WSWindowManager.h +++ b/Servers/WindowServer/WSWindowManager.h @@ -9,6 +9,7 @@ #include <LibDraw/Color.h> #include <LibDraw/DisjointRectSet.h> #include <LibDraw/Painter.h> +#include <LibDraw/Palette.h> #include <LibDraw/Rect.h> #include <WindowServer/WSCursor.h> #include <WindowServer/WSEvent.h> @@ -50,10 +51,15 @@ class WSWindowManager : public CObject { public: static WSWindowManager& the(); - WSWindowManager(); + explicit WSWindowManager(const Palette&); virtual ~WSWindowManager() override; - RefPtr<CConfigFile> wm_config() const { return m_wm_config; } + const Palette& palette() const { return *m_palette; } + + RefPtr<CConfigFile> wm_config() const + { + return m_wm_config; + } void reload_config(bool); void add_window(WSWindow&); @@ -276,6 +282,8 @@ private: WeakPtr<WSButton> m_cursor_tracking_button; WeakPtr<WSButton> m_hovered_button; + NonnullRefPtr<Palette> m_palette; + RefPtr<CConfigFile> m_wm_config; struct AppMetadata { diff --git a/Servers/WindowServer/WSWindowSwitcher.cpp b/Servers/WindowServer/WSWindowSwitcher.cpp index c88074ea37..f98499a43d 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 c629f9464d..c12a53d496 100644 --- a/Servers/WindowServer/main.cpp +++ b/Servers/WindowServer/main.cpp @@ -1,4 +1,5 @@ #include <LibCore/CConfigFile.h> +#include <LibDraw/Palette.h> #include <LibDraw/SystemTheme.h> #include <WindowServer/WSCompositor.h> #include <WindowServer/WSEventLoop.h> @@ -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(); |