/* * Copyright (c) 2018-2020, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include "HitTestResult.h" #include #include #include #include #include #include namespace WindowServer { class Button; class Menu; class MouseEvent; class MultiScaleBitmaps; class Screen; class Window; class WindowFrame { public: class PerScaleRenderedCache { friend class WindowFrame; public: void paint(WindowFrame&, Gfx::Painter&, Gfx::IntRect const&); void render(WindowFrame&, Screen&); Optional hit_test(WindowFrame&, Gfx::IntPoint const&, Gfx::IntPoint const&); private: RefPtr m_top_bottom; RefPtr m_left_right; int m_bottom_y { 0 }; // y-offset in m_top_bottom for the bottom half int m_right_x { 0 }; // x-offset in m_left_right for the right half bool m_shadow_dirty { true }; bool m_dirty { true }; }; friend class RenderedCache; static void reload_config(); explicit WindowFrame(Window&); ~WindowFrame(); void window_was_constructed(Badge); Window& window() { return m_window; } Window const& window() const { return m_window; } Gfx::IntRect rect() const; Gfx::IntRect render_rect() const; Gfx::IntRect unconstrained_render_rect() const; Gfx::DisjointIntRectSet opaque_render_rects() const; Gfx::DisjointIntRectSet transparent_render_rects() const; void paint(Screen&, Gfx::Painter&, Gfx::IntRect const&); void render(Screen&, Gfx::Painter&); PerScaleRenderedCache* render_to_cache(Screen&); void handle_mouse_event(MouseEvent const&); void handle_titlebar_mouse_event(MouseEvent const&); bool handle_titlebar_icon_mouse_event(MouseEvent const&); void handle_border_mouse_event(MouseEvent const&); void window_rect_changed(Gfx::IntRect const& old_rect, Gfx::IntRect const& new_rect); void invalidate_titlebar(); void invalidate_menubar(); void invalidate(Gfx::IntRect relative_rect); void invalidate(); Gfx::IntRect titlebar_rect() const; Gfx::IntRect titlebar_icon_rect() const; Gfx::IntRect titlebar_text_rect() const; Gfx::IntRect menubar_rect() const; int menu_row_count() const; void did_set_maximized(Badge, bool); void layout_buttons(); void set_button_icons(); void start_flash_animation(); bool has_alpha_channel() const { return m_has_alpha_channel; } void set_has_alpha_channel(bool value) { m_has_alpha_channel = value; } bool has_shadow() const; void set_opacity(float); float opacity() const { return m_opacity; } bool is_opaque() const { if (opacity() < 1.0f) return false; if (has_alpha_channel()) return false; return true; } void set_dirty(bool re_render_shadow = false) { for (auto& it : m_rendered_cache) { auto& cached = *it.value; cached.m_dirty = true; cached.m_shadow_dirty |= re_render_shadow; } } void theme_changed(); Optional hit_test(Gfx::IntPoint const&); void open_menubar_menu(Menu&); private: void paint_notification_frame(Gfx::Painter&); void paint_normal_frame(Gfx::Painter&); void paint_menubar(Gfx::Painter&); MultiScaleBitmaps const* shadow_bitmap() const; Gfx::IntRect inflated_for_shadow(Gfx::IntRect const&) const; void handle_menubar_mouse_event(MouseEvent const&); void handle_menu_mouse_event(Menu&, MouseEvent const&); Gfx::WindowTheme::WindowState window_state_for_theme() const; String computed_title() const; Gfx::IntRect constrained_render_rect_to_screen(Gfx::IntRect const&) const; Gfx::IntRect leftmost_titlebar_button_rect() const; Window& m_window; NonnullOwnPtrVector