diff options
author | MacDue <macdue@dueutil.tech> | 2022-05-02 21:34:33 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-05-03 22:00:14 +0200 |
commit | 44c0672d59a97464f0d52dfae466ce0230fe5ba9 (patch) | |
tree | 72e37d67d083f731e1d440274076ec4aa493a82d | |
parent | 2cf36a1ca232f0e296ea81fb6870d823a33ebdf0 (diff) | |
download | serenity-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.cpp | 11 | ||||
-rw-r--r-- | Userland/Services/WindowServer/Button.h | 9 | ||||
-rw-r--r-- | Userland/Services/WindowServer/WindowFrame.cpp | 45 |
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 |