forked from aseprite/aseprite
-
Notifications
You must be signed in to change notification settings - Fork 0
/
message.h
258 lines (219 loc) · 8.37 KB
/
message.h
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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
// Aseprite UI Library
// Copyright (C) 2018-2023 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef UI_MESSAGE_H_INCLUDED
#define UI_MESSAGE_H_INCLUDED
#pragma once
#include "base/paths.h"
#include "gfx/point.h"
#include "gfx/rect.h"
#include "ui/base.h"
#include "ui/keys.h"
#include "ui/message_type.h"
#include "ui/mouse_button.h"
#include "ui/pointer_type.h"
#include <functional>
namespace ui {
class Display;
class Timer;
class Widget;
class Message {
enum Flags {
FromFilter = 1, // Sent from pre-filter
PropagateToChildren = 2,
PropagateToParent = 4,
};
public:
Message(MessageType type,
KeyModifiers modifiers = kKeyUninitializedModifier);
virtual ~Message();
MessageType type() const { return m_type; }
Display* display() const { return m_display; }
Widget* recipient() const { return m_recipient; }
bool fromFilter() const { return hasFlag(FromFilter); }
void setFromFilter(const bool state) { setFlag(FromFilter, state); }
KeyModifiers modifiers() const { return m_modifiers; }
bool shiftPressed() const { return (m_modifiers & kKeyShiftModifier) == kKeyShiftModifier; }
bool ctrlPressed() const { return (m_modifiers & kKeyCtrlModifier) == kKeyCtrlModifier; }
bool altPressed() const { return (m_modifiers & kKeyAltModifier) == kKeyAltModifier; }
bool cmdPressed() const { return (m_modifiers & kKeyCmdModifier) == kKeyCmdModifier; }
bool winPressed() const { return (m_modifiers & kKeyWinModifier) == kKeyWinModifier; }
bool onlyShiftPressed() const { return m_modifiers == kKeyShiftModifier; }
bool onlyCtrlPressed() const { return m_modifiers == kKeyCtrlModifier; }
bool onlyAltPressed() const { return m_modifiers == kKeyAltModifier; }
bool onlyCmdPressed() const { return m_modifiers == kKeyCmdModifier; }
bool onlyWinPressed() const { return m_modifiers == kKeyWinModifier; }
void setDisplay(Display* display);
void setRecipient(Widget* widget);
void removeRecipient(Widget* widget);
bool propagateToChildren() const { return hasFlag(PropagateToChildren); }
bool propagateToParent() const { return hasFlag(PropagateToParent); }
void setPropagateToChildren(const bool state) { setFlag(PropagateToChildren, state); }
void setPropagateToParent(const bool state) { setFlag(PropagateToParent, state); }
Widget* commonAncestor() { return m_commonAncestor; }
void setCommonAncestor(Widget* widget) { m_commonAncestor = widget; }
private:
bool hasFlag(const Flags flag) const {
return (m_flags & flag) == flag;
}
void setFlag(const Flags flag, const bool state) {
m_flags = (state ? (m_flags | flag):
(m_flags & ~flag));
}
MessageType m_type; // Type of message
int m_flags; // Special flags for this message
Display* m_display;
Widget* m_recipient; // Recipient of this message
Widget* m_commonAncestor; // Common ancestor between the Leave <-> Enter messages
KeyModifiers m_modifiers; // Key modifiers pressed when message was created
};
class CallbackMessage : public Message {
public:
CallbackMessage(std::function<void()>&& callback)
: Message(kCallbackMessage)
, m_callback(std::move(callback)) { }
void call() {
m_callback();
}
private:
std::function<void()> m_callback;
};
class KeyMessage : public Message {
public:
KeyMessage(MessageType type,
KeyScancode scancode,
KeyModifiers modifiers,
int unicodeChar,
int repeat);
KeyScancode scancode() const { return m_scancode; }
int unicodeChar() const { return m_unicodeChar; }
int repeat() const { return m_repeat; }
bool isDeadKey() const { return m_isDead; }
void setDeadKey(bool state) { m_isDead = state; }
private:
KeyScancode m_scancode;
int m_unicodeChar;
int m_repeat; // repeat=0 means the first time the key is pressed
bool m_isDead;
};
class PaintMessage : public Message {
public:
PaintMessage(int count, const gfx::Rect& rect)
: Message(kPaintMessage)
, m_count(count)
, m_rect(rect) {
}
int count() const { return m_count; }
const gfx::Rect& rect() const { return m_rect; }
private:
int m_count; // Cound=0 if it's last msg of draw-chain
gfx::Rect m_rect; // Area to draw
};
class MouseMessage : public Message {
public:
MouseMessage(MessageType type,
PointerType pointerType,
MouseButton button,
KeyModifiers modifiers,
const gfx::Point& pos,
const gfx::Point& wheelDelta = gfx::Point(0, 0),
bool preciseWheel = false,
float pressure = 0.0f)
: Message(type, modifiers),
m_pointerType(pointerType),
m_button(button),
m_pos(pos),
m_wheelDelta(wheelDelta),
m_preciseWheel(preciseWheel),
m_pressure(pressure) {
}
// Copy other MouseMessage converting its type
MouseMessage(MessageType type,
const MouseMessage& other,
const gfx::Point& newPosition)
: Message(type, other.modifiers()),
m_pointerType(other.pointerType()),
m_button(other.button()),
m_pos(newPosition),
m_wheelDelta(other.wheelDelta()),
m_preciseWheel(other.preciseWheel()),
m_pressure(other.pressure()) {
}
PointerType pointerType() const { return m_pointerType; }
MouseButton button() const { return m_button; }
bool left() const { return (m_button == kButtonLeft); }
bool right() const { return (m_button == kButtonRight); }
bool middle() const { return (m_button == kButtonMiddle); }
gfx::Point wheelDelta() const { return m_wheelDelta; }
bool preciseWheel() const { return m_preciseWheel; }
float pressure() const { return m_pressure; }
const gfx::Point& position() const { return m_pos; }
// Returns the mouse message position relative to the given
// "anotherDisplay" (the m_pos field is relative to m_display).
gfx::Point positionForDisplay(Display* anotherDisplay) const;
// Absolute position of this message on the screen.
gfx::Point screenPosition() const;
private:
PointerType m_pointerType;
MouseButton m_button; // Pressed button
gfx::Point m_pos; // Mouse position
gfx::Point m_wheelDelta; // Wheel axis variation
bool m_preciseWheel;
float m_pressure;
};
class TouchMessage : public Message {
public:
TouchMessage(MessageType type,
KeyModifiers modifiers,
const gfx::Point& pos,
double magnification)
: Message(type, modifiers),
m_pos(pos),
m_magnification(magnification) {
}
// Copy other TouchMessage converting its type
TouchMessage(MessageType type,
const TouchMessage& other,
const gfx::Point& newPosition)
: Message(type, other.modifiers()),
m_pos(newPosition),
m_magnification(other.magnification()) {
}
const gfx::Point& position() const { return m_pos; }
double magnification() const { return m_magnification; }
private:
gfx::Point m_pos; // Mouse position
double m_magnification;
};
class TimerMessage : public Message {
public:
TimerMessage(int count, Timer* timer)
: Message(kTimerMessage), m_count(count), m_timer(timer) {
}
int count() const { return m_count; }
Timer* timer() { return m_timer; }
// Used by Manager::removeMessagesForTimer() to invalidate the
// message. It's like removing the message from the queue, but
// without touching the queue in case that we're iterating it
// (which can happen if we remove the timer from a kTimerMessage
// handler).
void _resetTimer() { m_timer = nullptr; }
private:
int m_count; // Accumulated calls
Timer* m_timer; // Timer handle
};
class DropFilesMessage : public Message {
public:
DropFilesMessage(const base::paths& files)
: Message(kDropFilesMessage)
, m_files(files) {
}
const base::paths& files() const { return m_files; }
private:
base::paths m_files;
};
} // namespace ui
#endif