summaryrefslogtreecommitdiff
path: root/Servers
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-12-24 20:57:54 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-12-24 21:27:16 +0100
commita79bac428b7857b9db2d0641daf3b7f2e3deb91f (patch)
tree7fee3f0764147238e218b79aa1f526c36deeecb0 /Servers
parentcb4e51a7a58d1c536d51484f83239d8cd9009616 (diff)
downloadserenity-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.cpp5
-rw-r--r--Servers/WindowServer/WSCompositor.cpp2
-rw-r--r--Servers/WindowServer/WSMenu.cpp27
-rw-r--r--Servers/WindowServer/WSMenuManager.cpp15
-rw-r--r--Servers/WindowServer/WSWindowFrame.cpp29
-rw-r--r--Servers/WindowServer/WSWindowManager.cpp4
-rw-r--r--Servers/WindowServer/WSWindowManager.h12
-rw-r--r--Servers/WindowServer/WSWindowSwitcher.cpp19
-rw-r--r--Servers/WindowServer/main.cpp4
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();