1// Aseprite UI Library
2// Copyright (C) 2018-2022 Igara Studio S.A.
3// Copyright (C) 2001-2017 David Capello
4//
5// This file is released under the terms of the MIT license.
6// Read LICENSE.txt for more information.
7
8#ifndef UI_MANAGER_H_INCLUDED
9#define UI_MANAGER_H_INCLUDED
10#pragma once
11
12#include "gfx/region.h"
13#include "ui/display.h"
14#include "ui/keys.h"
15#include "ui/message_type.h"
16#include "ui/mouse_button.h"
17#include "ui/pointer_type.h"
18#include "ui/widget.h"
19
20namespace os {
21 class EventQueue;
22 class Window;
23}
24
25namespace ui {
26
27 class LayoutIO;
28 class Timer;
29 class Window;
30
31 class Manager : public Widget {
32 public:
33 static Manager* getDefault() { return m_defaultManager; }
34 static bool widgetAssociatedToManager(Widget* widget);
35
36 Manager(const os::WindowRef& nativeWindow);
37 ~Manager();
38
39 Display* display() const { return &const_cast<Manager*>(this)->m_display; }
40
41 static Display* getDisplayFromNativeWindow(os::Window* window);
42
43 // Executes the main message loop.
44 void run();
45
46 // Refreshes all real displays with the UI content.
47 void flipAllDisplays();
48
49 void updateAllDisplaysWithNewScale(int scale);
50
51 // Adds the given "msg" message to the queue of messages to be
52 // dispached. "msg" cannot be used after this function, it'll be
53 // automatically deleted.
54 void enqueueMessage(Message* msg);
55
56 // Returns true if there are messages in the queue to be
57 // dispatched through dispatchMessages().
58 bool generateMessages();
59 void dispatchMessages();
60
61 void addToGarbage(Widget* widget);
62 void collectGarbage();
63
64 Window* getTopWindow();
65 Window* getDesktopWindow();
66 Window* getForegroundWindow();
67 Display* getForegroundDisplay();
68
69 Widget* getFocus();
70 Widget* getMouse();
71 Widget* getCapture();
72
73 void setFocus(Widget* widget);
74 void setMouse(Widget* widget);
75 void setCapture(Widget* widget);
76 void attractFocus(Widget* widget);
77 void focusFirstChild(Widget* widget);
78 void freeFocus();
79 void freeMouse();
80 void freeCapture();
81 void freeWidget(Widget* widget);
82 void removeMessagesFor(Widget* widget);
83 void removeMessagesFor(Widget* widget, MessageType type);
84 void removeMessagesForTimer(Timer* timer);
85 void removeMessagesForDisplay(Display* display);
86 void removePaintMessagesForDisplay(Display* display);
87
88 void addMessageFilter(int message, Widget* widget);
89 void removeMessageFilter(int message, Widget* widget);
90 void removeMessageFilterFor(Widget* widget);
91
92 LayoutIO* getLayoutIO();
93
94 bool isFocusMovementMessage(Message* msg);
95 bool processFocusMovementMessage(Message* msg);
96
97 Widget* pickFromScreenPos(const gfx::Point& screenPos) const override;
98
99 void _openWindow(Window* window, bool center);
100 void _closeWindow(Window* window, bool redraw_background);
101 void _runModalWindow(Window* window);
102 void _updateMouseWidgets();
103 void _closingAppWithException();
104
105 protected:
106 bool onProcessMessage(Message* msg) override;
107 void onInvalidateRegion(const gfx::Region& region) override;
108 void onResize(ResizeEvent& ev) override;
109 void onSizeHint(SizeHintEvent& ev) override;
110 void onBroadcastMouseMessage(const gfx::Point& screenPos,
111 WidgetsList& targets) override;
112 void onInitTheme(InitThemeEvent& ev) override;
113 virtual LayoutIO* onGetLayoutIO();
114 virtual void onNewDisplayConfiguration(Display* display);
115
116 private:
117 void generateSetCursorMessage(Display* display,
118 const gfx::Point& mousePos,
119 KeyModifiers modifiers,
120 PointerType pointerType);
121 void generateMessagesFromOSEvents();
122
123 void handleMouseMove(Display* display,
124 const gfx::Point& mousePos,
125 const KeyModifiers modifiers,
126 const PointerType pointerType,
127 const float pressure);
128 void handleMouseDown(Display* display,
129 const gfx::Point& mousePos,
130 MouseButton mouseButton,
131 KeyModifiers modifiers,
132 PointerType pointerType,
133 const float pressure);
134 void handleMouseUp(Display* display,
135 const gfx::Point& mousePos,
136 MouseButton mouseButton,
137 KeyModifiers modifiers,
138 PointerType pointerType);
139 void handleMouseDoubleClick(Display* display,
140 const gfx::Point& mousePos,
141 MouseButton mouseButton,
142 KeyModifiers modifiers,
143 PointerType pointerType,
144 const float pressure);
145 void handleMouseWheel(Display* display,
146 const gfx::Point& mousePos,
147 KeyModifiers modifiers,
148 PointerType pointerType,
149 const gfx::Point& wheelDelta,
150 bool preciseWheel);
151 void handleTouchMagnify(Display* display,
152 const gfx::Point& mousePos,
153 const KeyModifiers modifiers,
154 const double magnification);
155 void handleWindowZOrder();
156 void updateMouseWidgets(const gfx::Point& mousePos,
157 Display* display);
158
159 int pumpQueue();
160 bool sendMessageToWidget(Message* msg, Widget* widget);
161
162 static Widget* findLowestCommonAncestor(Widget* a, Widget* b);
163 static bool someParentIsFocusStop(Widget* widget);
164 static Widget* findMagneticWidget(Widget* widget);
165 static Message* newMouseMessage(
166 MessageType type,
167 Display* display,
168 Widget* widget,
169 const gfx::Point& mousePos,
170 PointerType pointerType,
171 MouseButton button,
172 KeyModifiers modifiers,
173 const gfx::Point& wheelDelta = gfx::Point(0, 0),
174 bool preciseWheel = false,
175 float pressure = 0.0f);
176 void broadcastKeyMsg(Message* msg);
177
178 static Manager* m_defaultManager;
179
180 WidgetsList m_garbage;
181 Display m_display;
182 os::EventQueue* m_eventQueue;
183
184 // This member is used to make freeWidget() a no-op when we
185 // restack a window if the user clicks on it.
186 Widget* m_lockedWindow;
187
188 // Last pressed mouse button.
189 MouseButton m_mouseButton;
190 };
191
192} // namespace ui
193
194#endif
195