Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#pragma once
8
9#include <AK/Forward.h>
10#include <AK/RefPtr.h>
11#include <LibCore/Forward.h>
12#include <LibGfx/Forward.h>
13#include <LibGfx/WindowTheme.h>
14#include <WindowServer/HitTestResult.h>
15#include <WindowServer/ResizeDirection.h>
16
17namespace WindowServer {
18
19class Button;
20class Menu;
21class MouseEvent;
22class MultiScaleBitmaps;
23class Screen;
24class Window;
25
26class WindowFrame {
27public:
28 class PerScaleRenderedCache {
29 friend class WindowFrame;
30
31 public:
32 void paint(WindowFrame&, Gfx::Painter&, Gfx::IntRect const&);
33 void render(WindowFrame&, Screen&);
34 Optional<HitTestResult> hit_test(WindowFrame&, Gfx::IntPoint, Gfx::IntPoint);
35
36 private:
37 RefPtr<Gfx::Bitmap> m_top_bottom;
38 RefPtr<Gfx::Bitmap> m_left_right;
39 int m_bottom_y { 0 }; // y-offset in m_top_bottom for the bottom half
40 int m_right_x { 0 }; // x-offset in m_left_right for the right half
41 bool m_shadow_dirty { true };
42 bool m_dirty { true };
43 };
44 friend class RenderedCache;
45
46 static void reload_config();
47
48 explicit WindowFrame(Window&);
49 ~WindowFrame();
50
51 void window_was_constructed(Badge<Window>);
52
53 Window& window() { return m_window; }
54 Window const& window() const { return m_window; }
55
56 Gfx::IntRect rect() const;
57 Gfx::IntRect render_rect() const;
58 Gfx::IntRect unconstrained_render_rect() const;
59 Gfx::DisjointIntRectSet opaque_render_rects() const;
60 Gfx::DisjointIntRectSet transparent_render_rects() const;
61
62 void paint(Screen&, Gfx::Painter&, Gfx::IntRect const&);
63 void render(Screen&, Gfx::Painter&);
64 PerScaleRenderedCache* render_to_cache(Screen&);
65
66 void handle_mouse_event(MouseEvent const&);
67 void handle_titlebar_mouse_event(MouseEvent const&);
68 bool handle_titlebar_icon_mouse_event(MouseEvent const&);
69 void handle_border_mouse_event(MouseEvent const&);
70
71 void window_rect_changed(Gfx::IntRect const& old_rect, Gfx::IntRect const& new_rect);
72 void invalidate_titlebar();
73 void invalidate_menubar();
74 void invalidate(Gfx::IntRect relative_rect);
75 void invalidate();
76
77 Gfx::IntRect titlebar_rect() const;
78 Gfx::IntRect titlebar_icon_rect() const;
79 Gfx::IntRect titlebar_text_rect() const;
80
81 Gfx::IntRect menubar_rect() const;
82 int menu_row_count() const;
83
84 void did_set_maximized(Badge<Window>, bool);
85
86 void layout_buttons();
87 void set_button_icons();
88
89 void start_flash_animation();
90
91 bool has_alpha_channel() const { return m_has_alpha_channel; }
92 void set_has_alpha_channel(bool value) { m_has_alpha_channel = value; }
93 bool has_shadow() const;
94
95 void set_opacity(float);
96 float opacity() const { return m_opacity; }
97
98 bool is_opaque() const
99 {
100 if (opacity() < 1.0f)
101 return false;
102 if (has_alpha_channel())
103 return false;
104 return true;
105 }
106
107 void set_dirty(bool re_render_shadow = false)
108 {
109 for (auto& it : m_rendered_cache) {
110 auto& cached = *it.value;
111 cached.m_dirty = true;
112 cached.m_shadow_dirty |= re_render_shadow;
113 }
114 }
115
116 void theme_changed();
117
118 Optional<HitTestResult> hit_test(Gfx::IntPoint);
119
120 void open_menubar_menu(Menu&);
121
122private:
123 void paint_notification_frame(Gfx::Painter&);
124 void paint_normal_frame(Gfx::Painter&);
125 void paint_menubar(Gfx::Painter&);
126 MultiScaleBitmaps const* shadow_bitmap() const;
127 Gfx::IntRect inflated_for_shadow(Gfx::IntRect const&) const;
128 void latch_window_to_screen_edge(ResizeDirection);
129
130 void handle_menubar_mouse_event(MouseEvent const&);
131 void handle_menu_mouse_event(Menu&, MouseEvent const&);
132
133 Gfx::WindowTheme::WindowState window_state_for_theme() const;
134 DeprecatedString computed_title() const;
135
136 Gfx::IntRect constrained_render_rect_to_screen(Gfx::IntRect const&) const;
137 Gfx::IntRect leftmost_titlebar_button_rect() const;
138
139 Window& m_window;
140 Vector<NonnullOwnPtr<Button>> m_buttons;
141 Button* m_close_button { nullptr };
142 Button* m_maximize_button { nullptr };
143 Button* m_minimize_button { nullptr };
144
145 HashMap<int, NonnullOwnPtr<PerScaleRenderedCache>> m_rendered_cache;
146
147 RefPtr<Core::Timer> m_flash_timer;
148 size_t m_flash_counter { 0 };
149 float m_opacity { 1 };
150 bool m_has_alpha_channel { false };
151};
152
153}