1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
|
/*
* Copyright (c) 2021, the SerenityOS developers.
* Copyright (c) 2023, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/IntrusiveList.h>
#include <AK/Vector.h>
#include <AK/WeakPtr.h>
#include <LibGfx/Painter.h>
#include <LibGfx/Palette.h>
#include <WindowServer/MultiScaleBitmaps.h>
#include <WindowServer/Screen.h>
namespace WindowServer {
class Animation;
class Screen;
class TileWindowOverlay;
class Window;
class WindowStack;
class Overlay {
friend class Compositor;
public:
virtual ~Overlay();
enum class ZOrder {
SnapWindow,
WindowGeometry,
Dnd,
WindowStackSwitch,
ScreenNumber,
};
[[nodiscard]] virtual ZOrder zorder() const = 0;
virtual void render(Gfx::Painter&, Screen const&) = 0;
Gfx::IntRect const& rect() const { return m_rect; }
Gfx::IntRect const& current_render_rect() const { return m_current_rect; }
void set_enabled(bool);
bool is_enabled() const { return m_list_node.is_in_list(); }
virtual void theme_changed()
{
rect_changed(m_rect);
}
bool invalidate();
protected:
Overlay() = default;
void set_rect(Gfx::IntRect const&);
virtual void rect_changed(Gfx::IntRect const&) {};
private:
[[nodiscard]] bool apply_render_rect()
{
bool needs_invalidation = m_invalidated;
m_invalidated = false;
m_current_rect = m_rect;
return needs_invalidation;
}
Gfx::IntRect m_rect;
Gfx::IntRect m_current_rect;
Vector<Screen*, default_screen_count> m_screens;
IntrusiveListNode<Overlay> m_list_node;
bool m_invalidated { false };
};
class BitmapOverlay : public Overlay {
public:
virtual RefPtr<Gfx::Bitmap> create_bitmap(int) = 0;
virtual void render(Gfx::Painter&, Screen const&) override;
protected:
BitmapOverlay();
void clear_bitmaps();
virtual void rect_changed(Gfx::IntRect const&) override;
private:
RefPtr<MultiScaleBitmaps> m_bitmaps;
};
class RectangularOverlay : public Overlay {
public:
static constexpr int default_minimum_size = 10;
static constexpr int default_frame_thickness = 5;
virtual void render(Gfx::Painter&, Screen const&) override;
virtual void render_overlay_bitmap(Gfx::Painter&) = 0;
protected:
RectangularOverlay();
static Gfx::IntRect calculate_frame_rect(Gfx::IntRect const&);
void set_content_rect(Gfx::IntRect const&);
void clear_bitmaps();
virtual void rect_changed(Gfx::IntRect const&) override;
void invalidate_content();
private:
RefPtr<MultiScaleBitmaps> m_rendered_bitmaps;
bool m_content_invalidated { false };
};
class ScreenNumberOverlay : public RectangularOverlay {
public:
static constexpr int default_offset = 20;
static constexpr int default_size = 120;
static constexpr int screen_number_padding = 10;
ScreenNumberOverlay(Screen&);
static Gfx::IntRect calculate_content_rect_for_screen(Screen&);
virtual ZOrder zorder() const override { return ZOrder::ScreenNumber; }
virtual void render_overlay_bitmap(Gfx::Painter&) override;
static void pick_font();
private:
Gfx::Font const& font();
Screen& m_screen;
static Gfx::Font const* s_font;
};
class WindowGeometryOverlay : public RectangularOverlay {
public:
WindowGeometryOverlay(Window&);
void window_rect_changed();
virtual ZOrder zorder() const override { return ZOrder::WindowGeometry; }
virtual void render_overlay_bitmap(Gfx::Painter&) override;
void set_actual_rect();
void start_or_stop_move_to_tile_overlay_animation(TileWindowOverlay*);
private:
void update_rect();
WeakPtr<Window> m_window;
DeprecatedString m_label;
Gfx::IntRect m_label_rect;
Gfx::IntRect m_ideal_overlay_rect;
struct {
RefPtr<Animation> animation;
float progress { 0.0f };
Gfx::IntRect tile_overlay_rect_at_start;
Gfx::IntRect current_rect;
Optional<Gfx::IntRect> starting_rect;
} m_move_into_overlay_rect_animation;
};
class DndOverlay : public BitmapOverlay {
public:
DndOverlay(DeprecatedString const&, Gfx::Bitmap const*);
void cursor_moved()
{
update_rect();
}
virtual ZOrder zorder() const override { return ZOrder::Dnd; }
virtual RefPtr<Gfx::Bitmap> create_bitmap(int) override;
private:
Gfx::Font const& font();
void update_rect();
RefPtr<Gfx::Bitmap const> m_bitmap;
DeprecatedString m_text;
Gfx::IntRect m_label_rect;
};
class WindowStackSwitchOverlay : public RectangularOverlay {
public:
static constexpr int default_screen_rect_width = 40;
static constexpr int default_screen_rect_height = 30;
static constexpr int default_screen_rect_margin = 16;
static constexpr int default_screen_rect_padding = 8;
WindowStackSwitchOverlay(Screen&, WindowStack&);
virtual ZOrder zorder() const override { return ZOrder::WindowStackSwitch; }
virtual void render_overlay_bitmap(Gfx::Painter&) override;
private:
Gfx::IntSize m_content_size;
int const m_rows;
int const m_columns;
int const m_target_row;
int const m_target_column;
};
class TileWindowOverlay : public Overlay {
public:
TileWindowOverlay(Window&, Gfx::IntRect const&, Gfx::Palette&&);
virtual ZOrder zorder() const override { return ZOrder::SnapWindow; }
virtual void render(Gfx::Painter&, Screen const&) override;
void set_overlay_rect(Gfx::IntRect const& rect)
{
set_rect(rect);
}
void set_tiled_frame_rect(Gfx::IntRect const& rect) { m_tiled_frame_rect = rect; }
Gfx::IntRect const& tiled_frame_rect() const { return m_tiled_frame_rect; }
bool is_window(Window& window) const { return &m_window == &window; }
private:
Window& m_window;
Gfx::IntRect m_tiled_frame_rect;
Gfx::Palette m_palette;
};
}
|