summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMacDue <macdue@dueutil.tech>2022-05-02 21:34:33 +0100
committerLinus Groh <mail@linusgroh.de>2022-05-03 22:00:14 +0200
commit44c0672d59a97464f0d52dfae466ce0230fe5ba9 (patch)
tree72e37d67d083f731e1d440274076ec4aa493a82d
parent2cf36a1ca232f0e296ea81fb6870d823a33ebdf0 (diff)
downloadserenity-44c0672d59a97464f0d52dfae466ce0230fe5ba9.zip
WindowServer: Support hover icons for title buttons
This allows adding "-hover.png" variants of the title button icons. This can be useful for themes which use the TitleButtonsIconOnly flag, which otherwise don't have a way of showing the hover state.
-rw-r--r--Userland/Services/WindowServer/Button.cpp11
-rw-r--r--Userland/Services/WindowServer/Button.h9
-rw-r--r--Userland/Services/WindowServer/WindowFrame.cpp45
3 files changed, 43 insertions, 22 deletions
diff --git a/Userland/Services/WindowServer/Button.cpp b/Userland/Services/WindowServer/Button.cpp
index 2e578738c6..d6d9769ec5 100644
--- a/Userland/Services/WindowServer/Button.cpp
+++ b/Userland/Services/WindowServer/Button.cpp
@@ -31,13 +31,18 @@ void Button::paint(Screen& screen, Gfx::Painter& painter)
if (m_style == Style::Normal)
Gfx::StylePainter::paint_button(painter, rect(), palette, Gfx::ButtonStyle::Normal, m_pressed, m_hovered);
- if (m_icon) {
- auto& bitmap = m_icon->bitmap(screen.scale_factor());
+ auto paint_icon = [&](auto& multiscale_bitmap) {
+ auto& bitmap = multiscale_bitmap->bitmap(screen.scale_factor());
auto icon_location = rect().center().translated(-(bitmap.width() / 2), -(bitmap.height() / 2));
if (m_pressed)
painter.translate(1, 1);
painter.blit(icon_location, bitmap, bitmap.rect());
- }
+ };
+
+ if (m_icon.hover_bitmap && m_hovered)
+ paint_icon(m_icon.hover_bitmap);
+ else if (m_icon.bitmap)
+ paint_icon(m_icon.bitmap);
}
void Button::on_mouse_event(MouseEvent const& event)
diff --git a/Userland/Services/WindowServer/Button.h b/Userland/Services/WindowServer/Button.h
index bd65713261..d6643c2193 100644
--- a/Userland/Services/WindowServer/Button.h
+++ b/Userland/Services/WindowServer/Button.h
@@ -40,7 +40,12 @@ public:
bool is_visible() const { return m_visible; }
- void set_icon(RefPtr<MultiScaleBitmaps> const& icon) { m_icon = icon; }
+ struct Icon {
+ RefPtr<MultiScaleBitmaps> bitmap { nullptr };
+ RefPtr<MultiScaleBitmaps> hover_bitmap { nullptr };
+ };
+
+ void set_icon(Icon const& icon) { m_icon = icon; }
enum class Style {
Normal,
@@ -52,7 +57,7 @@ public:
private:
WindowFrame& m_frame;
Gfx::IntRect m_relative_rect;
- RefPtr<MultiScaleBitmaps> m_icon;
+ Icon m_icon;
bool m_pressed { false };
bool m_visible { true };
bool m_hovered { false };
diff --git a/Userland/Services/WindowServer/WindowFrame.cpp b/Userland/Services/WindowServer/WindowFrame.cpp
index 6daa53b1fb..6d241b40c4 100644
--- a/Userland/Services/WindowServer/WindowFrame.cpp
+++ b/Userland/Services/WindowServer/WindowFrame.cpp
@@ -35,11 +35,11 @@ static Gfx::WindowTheme::WindowType to_theme_window_type(WindowType type)
}
}
-static RefPtr<MultiScaleBitmaps> s_minimize_icon;
-static RefPtr<MultiScaleBitmaps> s_maximize_icon;
-static RefPtr<MultiScaleBitmaps> s_restore_icon;
-static RefPtr<MultiScaleBitmaps> s_close_icon;
-static RefPtr<MultiScaleBitmaps> s_close_modified_icon;
+static Button::Icon s_minimize_icon;
+static Button::Icon s_maximize_icon;
+static Button::Icon s_restore_icon;
+static Button::Icon s_close_icon;
+static Button::Icon s_close_modified_icon;
static RefPtr<MultiScaleBitmaps> s_active_window_shadow;
static RefPtr<MultiScaleBitmaps> s_inactive_window_shadow;
@@ -125,7 +125,7 @@ void WindowFrame::set_button_icons()
: Button::Style::Normal;
if (m_window.is_closeable()) {
- m_close_button->set_icon(m_window.is_modified() ? *s_close_modified_icon : *s_close_icon);
+ m_close_button->set_icon(m_window.is_modified() ? s_close_modified_icon : s_close_icon);
m_close_button->set_style(button_style);
}
if (m_window.is_minimizable()) {
@@ -133,7 +133,7 @@ void WindowFrame::set_button_icons()
m_minimize_button->set_style(button_style);
}
if (m_window.is_resizable()) {
- m_maximize_button->set_icon(m_window.is_maximized() ? *s_restore_icon : *s_maximize_icon);
+ m_maximize_button->set_icon(m_window.is_maximized() ? s_restore_icon : s_maximize_icon);
m_maximize_button->set_style(button_style);
}
}
@@ -142,21 +142,32 @@ void WindowFrame::reload_config()
{
String icons_path = WindowManager::the().palette().title_button_icons_path();
- auto reload_icon = [&](RefPtr<MultiScaleBitmaps>& icon, StringView path, StringView default_path) {
+ auto reload_bitmap = [&](RefPtr<MultiScaleBitmaps>& multiscale_bitmap, StringView path, StringView default_path = "") {
StringBuilder full_path;
full_path.append(icons_path);
full_path.append(path);
- if (icon)
- icon->load(full_path.to_string(), default_path);
+ if (multiscale_bitmap)
+ multiscale_bitmap->load(full_path.string_view(), default_path);
else
- icon = MultiScaleBitmaps::create(full_path.to_string(), default_path);
+ multiscale_bitmap = MultiScaleBitmaps::create(full_path.string_view(), default_path);
};
- reload_icon(s_minimize_icon, "window-minimize.png", "/res/icons/16x16/downward-triangle.png");
- reload_icon(s_maximize_icon, "window-maximize.png", "/res/icons/16x16/upward-triangle.png");
- reload_icon(s_restore_icon, "window-restore.png", "/res/icons/16x16/window-restore.png");
- reload_icon(s_close_icon, "window-close.png", "/res/icons/16x16/window-close.png");
- reload_icon(s_close_modified_icon, "window-close-modified.png", "/res/icons/16x16/window-close-modified.png");
+ auto reload_icon = [&](Button::Icon& icon, StringView name, StringView default_path) {
+ StringBuilder full_name;
+ full_name.append(name);
+ full_name.append(".png");
+ reload_bitmap(icon.bitmap, full_name.string_view(), default_path);
+ // Note: No default for hover bitmaps
+ full_name.clear();
+ full_name.append(name);
+ full_name.append("-hover.png");
+ reload_bitmap(icon.hover_bitmap, full_name.string_view());
+ };
+ reload_icon(s_minimize_icon, "window-minimize", "/res/icons/16x16/downward-triangle.png");
+ reload_icon(s_maximize_icon, "window-maximize", "/res/icons/16x16/upward-triangle.png");
+ reload_icon(s_restore_icon, "window-restore", "/res/icons/16x16/window-restore.png");
+ reload_icon(s_close_icon, "window-close", "/res/icons/16x16/window-close.png");
+ reload_icon(s_close_modified_icon, "window-close-modified", "/res/icons/16x16/window-close-modified.png");
auto load_shadow = [](String const& path, String& last_path, RefPtr<MultiScaleBitmaps>& shadow_bitmap) {
if (path.is_empty()) {
@@ -217,7 +228,7 @@ bool WindowFrame::has_shadow() const
void WindowFrame::did_set_maximized(Badge<Window>, bool maximized)
{
VERIFY(m_maximize_button);
- m_maximize_button->set_icon(maximized ? *s_restore_icon : *s_maximize_icon);
+ m_maximize_button->set_icon(maximized ? s_restore_icon : s_maximize_icon);
}
Gfx::IntRect WindowFrame::menubar_rect() const