Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#pragma once
28
29#include <Kernel/KeyCode.h>
30#include <LibCore/Event.h>
31#include <LibGfx/Point.h>
32#include <LibGfx/Rect.h>
33#include <LibGUI/WindowType.h>
34
35namespace GUI {
36
37class Event : public Core::Event {
38public:
39 enum Type {
40 Show = 1000,
41 Hide,
42 Paint,
43 MultiPaint,
44 Resize,
45 MouseMove,
46 MouseDown,
47 MouseDoubleClick,
48 MouseUp,
49 MouseWheel,
50 Enter,
51 Leave,
52 KeyDown,
53 KeyUp,
54 WindowEntered,
55 WindowLeft,
56 WindowBecameInactive,
57 WindowBecameActive,
58 FocusIn,
59 FocusOut,
60 WindowCloseRequest,
61 ContextMenu,
62 EnabledChange,
63 DragMove,
64 Drop,
65
66 __Begin_WM_Events,
67 WM_WindowRemoved,
68 WM_WindowStateChanged,
69 WM_WindowRectChanged,
70 WM_WindowIconBitmapChanged,
71 __End_WM_Events,
72 };
73
74 Event() {}
75 explicit Event(Type type)
76 : Core::Event(type)
77 {
78 }
79 virtual ~Event() {}
80
81 bool is_key_event() const { return type() == KeyUp || type() == KeyDown; }
82 bool is_paint_event() const { return type() == Paint; }
83};
84
85class WMEvent : public Event {
86public:
87 WMEvent(Type type, int client_id, int window_id)
88 : Event(type)
89 , m_client_id(client_id)
90 , m_window_id(window_id)
91 {
92 }
93
94 int client_id() const { return m_client_id; }
95 int window_id() const { return m_window_id; }
96
97private:
98 int m_client_id { -1 };
99 int m_window_id { -1 };
100};
101
102class WMWindowRemovedEvent : public WMEvent {
103public:
104 WMWindowRemovedEvent(int client_id, int window_id)
105 : WMEvent(Event::Type::WM_WindowRemoved, client_id, window_id)
106 {
107 }
108};
109
110class WMWindowStateChangedEvent : public WMEvent {
111public:
112 WMWindowStateChangedEvent(int client_id, int window_id, const StringView& title, const Gfx::Rect& rect, bool is_active, WindowType window_type, bool is_minimized)
113 : WMEvent(Event::Type::WM_WindowStateChanged, client_id, window_id)
114 , m_title(title)
115 , m_rect(rect)
116 , m_window_type(window_type)
117 , m_active(is_active)
118 , m_minimized(is_minimized)
119 {
120 }
121
122 String title() const { return m_title; }
123 Gfx::Rect rect() const { return m_rect; }
124 bool is_active() const { return m_active; }
125 WindowType window_type() const { return m_window_type; }
126 bool is_minimized() const { return m_minimized; }
127
128private:
129 String m_title;
130 Gfx::Rect m_rect;
131 WindowType m_window_type;
132 bool m_active;
133 bool m_minimized;
134};
135
136class WMWindowRectChangedEvent : public WMEvent {
137public:
138 WMWindowRectChangedEvent(int client_id, int window_id, const Gfx::Rect& rect)
139 : WMEvent(Event::Type::WM_WindowRectChanged, client_id, window_id)
140 , m_rect(rect)
141 {
142 }
143
144 Gfx::Rect rect() const { return m_rect; }
145
146private:
147 Gfx::Rect m_rect;
148};
149
150class WMWindowIconBitmapChangedEvent : public WMEvent {
151public:
152 WMWindowIconBitmapChangedEvent(int client_id, int window_id, int icon_buffer_id, const Gfx::Size& icon_size)
153 : WMEvent(Event::Type::WM_WindowIconBitmapChanged, client_id, window_id)
154 , m_icon_buffer_id(icon_buffer_id)
155 , m_icon_size(icon_size)
156 {
157 }
158
159 int icon_buffer_id() const { return m_icon_buffer_id; }
160 const Gfx::Size& icon_size() const { return m_icon_size; }
161
162private:
163 int m_icon_buffer_id;
164 Gfx::Size m_icon_size;
165};
166
167class MultiPaintEvent final : public Event {
168public:
169 explicit MultiPaintEvent(const Vector<Gfx::Rect, 32>& rects, const Gfx::Size& window_size)
170 : Event(Event::MultiPaint)
171 , m_rects(rects)
172 , m_window_size(window_size)
173 {
174 }
175
176 const Vector<Gfx::Rect, 32>& rects() const { return m_rects; }
177 Gfx::Size window_size() const { return m_window_size; }
178
179private:
180 Vector<Gfx::Rect, 32> m_rects;
181 Gfx::Size m_window_size;
182};
183
184class PaintEvent final : public Event {
185public:
186 explicit PaintEvent(const Gfx::Rect& rect, const Gfx::Size& window_size = {})
187 : Event(Event::Paint)
188 , m_rect(rect)
189 , m_window_size(window_size)
190 {
191 }
192
193 Gfx::Rect rect() const { return m_rect; }
194 Gfx::Size window_size() const { return m_window_size; }
195
196private:
197 Gfx::Rect m_rect;
198 Gfx::Size m_window_size;
199};
200
201class ResizeEvent final : public Event {
202public:
203 explicit ResizeEvent(const Gfx::Size& old_size, const Gfx::Size& size)
204 : Event(Event::Resize)
205 , m_old_size(old_size)
206 , m_size(size)
207 {
208 }
209
210 const Gfx::Size& old_size() const { return m_old_size; }
211 const Gfx::Size& size() const { return m_size; }
212
213private:
214 Gfx::Size m_old_size;
215 Gfx::Size m_size;
216};
217
218class ContextMenuEvent final : public Event {
219public:
220 explicit ContextMenuEvent(const Gfx::Point& position, const Gfx::Point& screen_position)
221 : Event(Event::ContextMenu)
222 , m_position(position)
223 , m_screen_position(screen_position)
224 {
225 }
226
227 const Gfx::Point& position() const { return m_position; }
228 const Gfx::Point& screen_position() const { return m_screen_position; }
229
230private:
231 Gfx::Point m_position;
232 Gfx::Point m_screen_position;
233};
234
235class ShowEvent final : public Event {
236public:
237 ShowEvent()
238 : Event(Event::Show)
239 {
240 }
241};
242
243class HideEvent final : public Event {
244public:
245 HideEvent()
246 : Event(Event::Hide)
247 {
248 }
249};
250
251enum MouseButton : u8 {
252 None = 0,
253 Left = 1,
254 Right = 2,
255 Middle = 4,
256};
257
258class KeyEvent final : public Event {
259public:
260 KeyEvent(Type type, int key, u8 modifiers)
261 : Event(type)
262 , m_key(key)
263 , m_modifiers(modifiers)
264 {
265 }
266
267 int key() const { return m_key; }
268 bool ctrl() const { return m_modifiers & Mod_Ctrl; }
269 bool alt() const { return m_modifiers & Mod_Alt; }
270 bool shift() const { return m_modifiers & Mod_Shift; }
271 bool logo() const { return m_modifiers & Mod_Logo; }
272 u8 modifiers() const { return m_modifiers; }
273 String text() const { return m_text; }
274
275private:
276 friend class WindowServerConnection;
277 int m_key { 0 };
278 u8 m_modifiers { 0 };
279 String m_text;
280};
281
282class MouseEvent final : public Event {
283public:
284 MouseEvent(Type type, const Gfx::Point& position, unsigned buttons, MouseButton button, unsigned modifiers, int wheel_delta)
285 : Event(type)
286 , m_position(position)
287 , m_buttons(buttons)
288 , m_button(button)
289 , m_modifiers(modifiers)
290 , m_wheel_delta(wheel_delta)
291 {
292 }
293
294 Gfx::Point position() const { return m_position; }
295 int x() const { return m_position.x(); }
296 int y() const { return m_position.y(); }
297 MouseButton button() const { return m_button; }
298 unsigned buttons() const { return m_buttons; }
299 unsigned modifiers() const { return m_modifiers; }
300 int wheel_delta() const { return m_wheel_delta; }
301
302private:
303 Gfx::Point m_position;
304 unsigned m_buttons { 0 };
305 MouseButton m_button { MouseButton::None };
306 unsigned m_modifiers { 0 };
307 int m_wheel_delta { 0 };
308};
309
310class DragEvent final : public Event {
311public:
312 DragEvent(Type type, const Gfx::Point& position, const String& data_type)
313 : Event(type)
314 , m_position(position)
315 , m_data_type(data_type)
316 {
317 }
318
319 const Gfx::Point& position() const { return m_position; }
320 const String& data_type() const { return m_data_type; }
321
322private:
323 Gfx::Point m_position;
324 String m_data_type;
325};
326
327class DropEvent final : public Event {
328public:
329 DropEvent(const Gfx::Point&, const String& text, NonnullRefPtr<Core::MimeData> mime_data);
330
331 ~DropEvent();
332
333 const Gfx::Point& position() const { return m_position; }
334 const String& text() const { return m_text; }
335 const Core::MimeData& mime_data() const { return m_mime_data; }
336
337private:
338 Gfx::Point m_position;
339 String m_text;
340 NonnullRefPtr<Core::MimeData> m_mime_data;
341};
342
343}