mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 06:32:44 +00:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									cb4e51a7a5
								
							
						
					
					
						commit
						a79bac428b
					
				
					 62 changed files with 448 additions and 410 deletions
				
			
		|  | @ -1,4 +1,5 @@ | |||
| #include "GlyphMapWidget.h" | ||||
| #include <LibDraw/Palette.h> | ||||
| #include <LibGUI/GPainter.h> | ||||
| 
 | ||||
| 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); | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| #include "HexEditor.h" | ||||
| #include <AK/StringBuilder.h> | ||||
| #include <Kernel/KeyCode.h> | ||||
| #include <LibDraw/Palette.h> | ||||
| #include <LibGUI/GAction.h> | ||||
| #include <LibGUI/GClipboard.h> | ||||
| #include <LibGUI/GFontDatabase.h> | ||||
|  | @ -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) { | ||||
|  |  | |||
|  | @ -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<GBoxLayout>(Orientation::Vertical)); | ||||
|     widget->layout()->set_spacing(0); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -11,7 +11,6 @@ NetworkStatisticsWidget::NetworkStatisticsWidget(GWidget* parent) | |||
|         set_layout(make<GBoxLayout>(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<GBoxLayout>(Orientation::Vertical)); | ||||
|  |  | |||
|  | @ -53,7 +53,6 @@ int main(int argc, char** argv) | |||
|     auto keeper = GWidget::construct(); | ||||
|     keeper->set_layout(make<GBoxLayout>(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<GWidget> 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<GBoxLayout>(Orientation::Vertical)); | ||||
|         self.layout()->set_margins({ 4, 4, 4, 4 }); | ||||
| 
 | ||||
|  |  | |||
|  | @ -98,13 +98,13 @@ RefPtr<GWindow> create_settings_window(TerminalWidget& terminal, RefPtr<CConfigF | |||
|     auto settings = GWidget::construct(); | ||||
|     window->set_main_widget(settings); | ||||
|     settings->set_fill_with_background_color(true); | ||||
|     settings->set_background_role(ColorRole::Button); | ||||
|     settings->set_layout(make<GBoxLayout>(Orientation::Vertical)); | ||||
|     settings->layout()->set_margins({ 4, 4, 4, 4 }); | ||||
| 
 | ||||
|     auto radio_container = GGroupBox::construct("Bell Mode", settings); | ||||
|     radio_container->set_layout(make<GBoxLayout>(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<GWindow> create_settings_window(TerminalWidget& terminal, RefPtr<CConfigF | |||
|     auto slider_container = GGroupBox::construct("Background Opacity", settings); | ||||
|     slider_container->set_layout(make<GBoxLayout>(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); | ||||
|  |  | |||
|  | @ -1,10 +1,10 @@ | |||
| #include "TextWidget.h" | ||||
| #include <AK/String.h> | ||||
| #include <AK/StringBuilder.h> | ||||
| #include <AK/Vector.h> | ||||
| #include <LibDraw/Palette.h> | ||||
| #include <LibGUI/GPainter.h> | ||||
| 
 | ||||
| #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); | ||||
|  |  | |||
|  | @ -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++) | ||||
|  |  | |||
|  | @ -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()); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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(); | ||||
|  |  | |||
|  | @ -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(); }; | ||||
|  |  | |||
|  | @ -4,94 +4,6 @@ | |||
| #include <ctype.h> | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| 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 { | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
| #include <AK/String.h> | ||||
| #include <AK/Types.h> | ||||
| 
 | ||||
| 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) | ||||
|     { | ||||
|  |  | |||
|  | @ -11,6 +11,7 @@ OBJS = \ | |||
|     Rect.o \
 | ||||
|     StylePainter.o \
 | ||||
|     SystemTheme.o \
 | ||||
|     Palette.o \
 | ||||
|     Emoji.o | ||||
| 
 | ||||
| LIBRARY = libdraw.a | ||||
|  |  | |||
							
								
								
									
										26
									
								
								Libraries/LibDraw/Palette.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								Libraries/LibDraw/Palette.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,26 @@ | |||
| #include <LibDraw/Palette.h> | ||||
| 
 | ||||
| NonnullRefPtr<Palette> 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]; | ||||
| } | ||||
							
								
								
									
										51
									
								
								Libraries/LibDraw/Palette.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								Libraries/LibDraw/Palette.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,51 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <AK/Badge.h> | ||||
| #include <LibDraw/SystemTheme.h> | ||||
| 
 | ||||
| class GApplication; | ||||
| 
 | ||||
| class Palette : public RefCounted<Palette> { | ||||
| public: | ||||
|     static NonnullRefPtr<Palette> 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<GApplication>, SharedBuffer& buffer) { m_theme_buffer = buffer; } | ||||
| 
 | ||||
| private: | ||||
|     explicit Palette(SharedBuffer&); | ||||
| 
 | ||||
|     RefPtr<SharedBuffer> m_theme_buffer; | ||||
| }; | ||||
|  | @ -1,15 +1,16 @@ | |||
| #include <LibDraw/Painter.h> | ||||
| #include <LibDraw/Palette.h> | ||||
| #include <LibDraw/StylePainter.h> | ||||
| 
 | ||||
| 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()) | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ | |||
| #include <LibDraw/Color.h> | ||||
| 
 | ||||
| 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 = {}); | ||||
| }; | ||||
|  |  | |||
|  | @ -41,34 +41,37 @@ RefPtr<SharedBuffer> 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(); | ||||
|  |  | |||
|  | @ -4,43 +4,43 @@ | |||
| #include <LibC/SharedBuffer.h> | ||||
| #include <LibDraw/Color.h> | ||||
| 
 | ||||
| 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(); | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| #include <LibDraw/Palette.h> | ||||
| #include <LibGUI/GAbstractButton.h> | ||||
| #include <LibGUI/GPainter.h> | ||||
| 
 | ||||
|  | @ -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)); | ||||
| } | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| #include <AK/StringBuilder.h> | ||||
| #include <LibDraw/Palette.h> | ||||
| #include <LibGUI/GAbstractColumnView.h> | ||||
| #include <LibGUI/GAction.h> | ||||
| #include <LibGUI/GMenu.h> | ||||
|  | @ -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; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -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 { | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| #include <LibDraw/Palette.h> | ||||
| #include <LibGUI/GAction.h> | ||||
| #include <LibGUI/GApplication.h> | ||||
| #include <LibGUI/GDesktop.h> | ||||
|  | @ -142,3 +143,19 @@ void GApplication::did_delete_last_window(Badge<GWindow>) | |||
|     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; | ||||
| } | ||||
|  |  | |||
|  | @ -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<String>& args() const { return m_args; } | ||||
| 
 | ||||
|     const Palette& palette() const { return *m_palette; } | ||||
|     void set_palette(const Palette&); | ||||
| 
 | ||||
|     void set_system_palette(SharedBuffer&); | ||||
| 
 | ||||
| private: | ||||
|     OwnPtr<CEventLoop> m_event_loop; | ||||
|     OwnPtr<GMenuBar> m_menubar; | ||||
|     RefPtr<Palette> m_palette; | ||||
|     RefPtr<Palette> m_system_palette; | ||||
|     HashMap<GShortcut, GAction*> m_global_shortcut_actions; | ||||
|     class TooltipWindow; | ||||
|     TooltipWindow* m_tooltip_window { nullptr }; | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -1,8 +1,9 @@ | |||
| #include <Kernel/KeyCode.h> | ||||
| #include <LibDraw/CharacterBitmap.h> | ||||
| #include <LibDraw/Palette.h> | ||||
| #include <LibDraw/StylePainter.h> | ||||
| #include <LibGUI/GCheckBox.h> | ||||
| #include <LibGUI/GPainter.h> | ||||
| #include <LibDraw/CharacterBitmap.h> | ||||
| #include <LibDraw/StylePainter.h> | ||||
| 
 | ||||
| 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); | ||||
|  |  | |||
|  | @ -58,7 +58,6 @@ GFilePicker::GFilePicker(Mode mode, const StringView& file_name, const StringVie | |||
|     horizontal_container->set_layout(make<GBoxLayout>(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<GBoxLayout>(Orientation::Vertical)); | ||||
|  |  | |||
|  | @ -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()); | ||||
| } | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| #include <LibDraw/Palette.h> | ||||
| #include <LibDraw/StylePainter.h> | ||||
| #include <LibGUI/GGroupBox.h> | ||||
| #include <LibGUI/GPainter.h> | ||||
| #include <LibDraw/StylePainter.h> | ||||
| 
 | ||||
| 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) | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| #include <AK/StringBuilder.h> | ||||
| #include <Kernel/KeyCode.h> | ||||
| #include <LibDraw/Palette.h> | ||||
| #include <LibGUI/GDragOperation.h> | ||||
| #include <LibGUI/GItemView.h> | ||||
| #include <LibGUI/GModel.h> | ||||
|  | @ -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); | ||||
|     }; | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| #include "GLabel.h" | ||||
| #include <LibGUI/GPainter.h> | ||||
| #include <LibDraw/GraphicsBitmap.h> | ||||
| #include <LibDraw/Palette.h> | ||||
| #include <LibGUI/GLabel.h> | ||||
| #include <LibGUI/GPainter.h> | ||||
| 
 | ||||
| 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); | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| #include <Kernel/KeyCode.h> | ||||
| #include <LibDraw/Palette.h> | ||||
| #include <LibGUI/GListView.h> | ||||
| #include <LibGUI/GPainter.h> | ||||
| #include <LibGUI/GScrollBar.h> | ||||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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); | ||||
| } | ||||
|  |  | |||
|  | @ -1,11 +1,13 @@ | |||
| #include <LibDraw/GraphicsBitmap.h> | ||||
| #include <LibDraw/Palette.h> | ||||
| #include <LibGUI/GPainter.h> | ||||
| #include <LibGUI/GResizeCorner.h> | ||||
| #include <LibGUI/GWindow.h> | ||||
| #include <LibDraw/GraphicsBitmap.h> | ||||
| 
 | ||||
| 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); | ||||
| } | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| #include <LibDraw/CharacterBitmap.h> | ||||
| #include <LibDraw/GraphicsBitmap.h> | ||||
| #include <LibDraw/Palette.h> | ||||
| #include <LibDraw/StylePainter.h> | ||||
| #include <LibGUI/GPainter.h> | ||||
| #include <LibGUI/GScrollBar.h> | ||||
|  | @ -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() | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| #include <LibDraw/Palette.h> | ||||
| #include <LibGUI/GBoxLayout.h> | ||||
| #include <LibGUI/GSplitter.h> | ||||
| #include <LibGUI/GWindow.h> | ||||
|  | @ -6,9 +7,9 @@ GSplitter::GSplitter(Orientation orientation, GWidget* parent) | |||
|     : GFrame(parent) | ||||
|     , m_orientation(orientation) | ||||
| { | ||||
|     set_background_role(ColorRole::Button); | ||||
|     set_layout(make<GBoxLayout>(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(); | ||||
|  |  | |||
|  | @ -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()); | ||||
| } | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| #include <LibDraw/Palette.h> | ||||
| #include <LibDraw/StylePainter.h> | ||||
| #include <LibGUI/GBoxLayout.h> | ||||
| #include <LibGUI/GPainter.h> | ||||
|  | @ -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; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| #include <AK/StringBuilder.h> | ||||
| #include <Kernel/KeyCode.h> | ||||
| #include <LibDraw/Palette.h> | ||||
| #include <LibGUI/GAction.h> | ||||
| #include <LibGUI/GMenu.h> | ||||
| #include <LibGUI/GModel.h> | ||||
|  | @ -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()); | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| #include <AK/QuickSort.h> | ||||
| #include <AK/StringBuilder.h> | ||||
| #include <Kernel/KeyCode.h> | ||||
| #include <LibDraw/Palette.h> | ||||
| #include <LibGUI/GAction.h> | ||||
| #include <LibGUI/GClipboard.h> | ||||
| #include <LibGUI/GFontDatabase.h> | ||||
|  | @ -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; | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| #include <LibDraw/Palette.h> | ||||
| #include <LibGUI/GAction.h> | ||||
| #include <LibGUI/GActionGroup.h> | ||||
| #include <LibGUI/GBoxLayout.h> | ||||
|  | @ -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()); | ||||
| } | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| #include <LibDraw/Palette.h> | ||||
| #include <LibGUI/GPainter.h> | ||||
| #include <LibGUI/GScrollBar.h> | ||||
| #include <LibGUI/GTreeView.h> | ||||
|  | @ -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); | ||||
|                     } | ||||
|                 } | ||||
|  |  | |||
|  | @ -1,26 +1,26 @@ | |||
| #include <AK/Assertions.h> | ||||
| #include <AK/JsonObject.h> | ||||
| #include <LibDraw/GraphicsBitmap.h> | ||||
| #include <LibDraw/Palette.h> | ||||
| #include <LibGUI/GAction.h> | ||||
| #include <LibGUI/GApplication.h> | ||||
| #include <LibGUI/GButton.h> | ||||
| #include <LibGUI/GCheckBox.h> | ||||
| #include <LibGUI/GEvent.h> | ||||
| #include <LibGUI/GGroupBox.h> | ||||
| #include <LibGUI/GLabel.h> | ||||
| #include <LibGUI/GLayout.h> | ||||
| #include <LibGUI/GMenu.h> | ||||
| #include <LibGUI/GPainter.h> | ||||
| #include <LibGUI/GWidget.h> | ||||
| #include <LibGUI/GWindow.h> | ||||
| #include <LibGUI/GWindowServerConnection.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| #include <LibGUI/GButton.h> | ||||
| #include <LibGUI/GCheckBox.h> | ||||
| #include <LibGUI/GGroupBox.h> | ||||
| #include <LibGUI/GLabel.h> | ||||
| #include <LibGUI/GRadioButton.h> | ||||
| #include <LibGUI/GScrollBar.h> | ||||
| #include <LibGUI/GSlider.h> | ||||
| #include <LibGUI/GSpinBox.h> | ||||
| #include <LibGUI/GTextBox.h> | ||||
| #include <LibGUI/GWidget.h> | ||||
| #include <LibGUI/GWindow.h> | ||||
| #include <LibGUI/GWindowServerConnection.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| 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*> GWidget::child_widgets() const | |||
|     } | ||||
|     return widgets; | ||||
| } | ||||
| 
 | ||||
| void GWidget::set_palette(const Palette& palette) | ||||
| { | ||||
|     m_palette = palette; | ||||
| } | ||||
|  |  | |||
|  | @ -9,6 +9,7 @@ | |||
| #include <LibDraw/Font.h> | ||||
| #include <LibDraw/Orientation.h> | ||||
| #include <LibDraw/Rect.h> | ||||
| #include <LibDraw/SystemTheme.h> | ||||
| #include <LibGUI/GEvent.h> | ||||
| #include <LibGUI/GShortcut.h> | ||||
| 
 | ||||
|  | @ -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<GLayout> 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<Font> m_font; | ||||
|  | @ -288,6 +301,8 @@ private: | |||
|     bool m_updates_enabled { true }; | ||||
| 
 | ||||
|     HashMap<GShortcut, GAction*> m_local_shortcut_actions; | ||||
| 
 | ||||
|     NonnullRefPtr<Palette> m_palette; | ||||
| }; | ||||
| 
 | ||||
| template<> | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| #include <LibDraw/Palette.h> | ||||
| #include <LibDraw/SystemTheme.h> | ||||
| #include <LibGUI/GAction.h> | ||||
| #include <LibGUI/GApplication.h> | ||||
|  | @ -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() | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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(); | ||||
|  |  | |||
|  | @ -1,17 +1,20 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <LibDraw/Palette.h> | ||||
| #include <LibDraw/Rect.h> | ||||
| 
 | ||||
| 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 }; | ||||
| }; | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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()) { | ||||
|  |  | |||
|  | @ -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 { | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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(); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling