Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
canvas-event.h
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Authors:
4 * Matthew Jakeman <mjakeman26@outlook.co.nz>
5 * PBS <pbs3141@gmail.com>
6 *
7 * Copyright (C) 2022 Authors
8 *
9 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
10 */
11#ifndef INKSCAPE_UI_WIDGET_EVENTS_CANVAS_EVENT_H
12#define INKSCAPE_UI_WIDGET_EVENTS_CANVAS_EVENT_H
13
14#include <cstdint>
15#include <memory>
16#include <optional>
17
18#include <gdk/gdk.h>
19#include <gdkmm/enums.h>
20#include <gdkmm/event.h>
21#include <2geom/point.h>
22
23#include "enums.h"
25
26namespace Gdk { class Device; }
27
28namespace Inkscape {
29
35{
36 std::optional<double> pressure, xtilt, ytilt;
37};
38
42inline ExtendedInput extinput_from_gdkevent(Gdk::Event const &event)
43{
44 auto read = [&] (Gdk::AxisUse axis) -> std::optional<double> {
45 double tmp;
46 if (event.get_axis(axis, tmp)) {
47 return tmp;
48 } else {
49 return {};
50 }
51 };
52
53 return {
54 .pressure = read(Gdk::AxisUse::PRESSURE),
55 .xtilt = read(Gdk::AxisUse::XTILT),
56 .ytilt = read(Gdk::AxisUse::YTILT)
57 };
58}
59
64{
65 virtual ~CanvasEvent() {}
66
68 virtual EventType type() const = 0;
69
71 unsigned modifiers = 0;
72
74 virtual unsigned modifiersChange() const { return 0; }
75
77 unsigned modifiersAfter() const { return modifiers ^ modifiersChange(); }
78
80 std::shared_ptr<Gdk::Device const> device;
81};
82
88{
89 unsigned modifiersChange() const override
90 {
91 switch (button) {
92 case 1: return GDK_BUTTON1_MASK;
93 case 2: return GDK_BUTTON2_MASK;
94 case 3: return GDK_BUTTON3_MASK;
95 case 4: return GDK_BUTTON4_MASK;
96 case 5: return GDK_BUTTON5_MASK;
97 default: return 0; // Buttons can range at least to 9 but mask defined only to 5.
98 }
99 }
100
103
106
108 unsigned button = 0;
109
111 uint32_t time = 0;
112};
113
119{
120 EventType type() const override { return EventType::BUTTON_PRESS; }
121
123 int num_press = 1;
124
127};
128
134{
135 EventType type() const override { return EventType::BUTTON_RELEASE; }
136};
137
142{
143 unsigned modifiersChange() const override
144 {
145 switch (keyval) {
146 case GDK_KEY_Shift_L:
147 case GDK_KEY_Shift_R:
148 return GDK_SHIFT_MASK;
149 case GDK_KEY_Control_L:
150 case GDK_KEY_Control_R:
151 return GDK_CONTROL_MASK;
152 case GDK_KEY_Alt_L:
153 case GDK_KEY_Alt_R:
154 return GDK_ALT_MASK;
155 case GDK_KEY_Meta_L:
156 case GDK_KEY_Meta_R:
157 return GDK_META_MASK;
158 default:
159 return 0;
160 }
161 }
162
164 uint32_t keyval = 0;
165
167 uint16_t keycode = 0;
168
170 int group = 0;
171
173 uint32_t time = 0;
174
176 std::optional<Geom::Point> pos;
177
179 std::optional<Geom::Point> orig_pos;
180};
181
186{
187 EventType type() const override { return EventType::KEY_PRESS; }
188};
189
194{
195 EventType type() const override { return EventType::KEY_RELEASE; }
196};
197
203{
204 EventType type() const override { return EventType::MOTION; }
205
208
210 uint32_t time = 0;
211
214
217};
218
223{
224 EventType type() const override { return EventType::ENTER; }
225
228};
229
236{
237 EventType type() const override { return EventType::LEAVE; }
238};
239
244{
245 EventType type() const override { return EventType::SCROLL; }
246
249
251 Gdk::ScrollUnit unit = Gdk::ScrollUnit::SURFACE;
252
255};
256
257namespace canvas_event_detail {
258
259template <typename E>
261{
262 return static_cast<E &>(event);
263}
264
265template <typename E>
266E const &cast_helper(CanvasEvent const &event)
267{
268 return static_cast<E const &>(event);
269}
270
271template <typename E>
273{
274 return static_cast<E &&>(event);
275}
276
277} // namespace canvas_event_detail
278
289template <typename E, typename... Fs>
290void inspect_event(E &&event, Fs... funcs)
291{
292 using namespace canvas_event_detail;
293
294 auto overloaded = VariantVisitor{funcs...};
295
296 switch (event.type()) {
297 case EventType::ENTER:
298 overloaded(cast_helper<EnterEvent>(std::forward<E>(event)));
299 break;
300 case EventType::LEAVE:
301 overloaded(cast_helper<LeaveEvent>(std::forward<E>(event)));
302 break;
304 overloaded(cast_helper<MotionEvent>(std::forward<E>(event)));
305 break;
307 overloaded(cast_helper<ButtonPressEvent>(std::forward<E>(event)));
308 break;
310 overloaded(cast_helper<ButtonReleaseEvent>(std::forward<E>(event)));
311 break;
313 overloaded(cast_helper<KeyPressEvent>(std::forward<E>(event)));
314 break;
316 overloaded(cast_helper<KeyReleaseEvent>(std::forward<E>(event)));
317 break;
319 overloaded(cast_helper<ScrollEvent>(std::forward<E>(event)));
320 break;
321 default:
322 break;
323 }
324}
325
326/*
327 * Modifier-testing functions.
328 */
329
331inline constexpr auto INK_GDK_MODIFIER_MASK = GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_ALT_MASK;
332
333inline bool mod_shift(unsigned modifiers) { return modifiers & GDK_SHIFT_MASK; }
334inline bool mod_ctrl(unsigned modifiers) { return modifiers & GDK_CONTROL_MASK; }
335inline bool mod_alt(unsigned modifiers) { return modifiers & GDK_ALT_MASK; }
336inline bool mod_shift_only(unsigned modifiers) { return (modifiers & INK_GDK_MODIFIER_MASK) == GDK_SHIFT_MASK; }
337inline bool mod_ctrl_only(unsigned modifiers) { return (modifiers & INK_GDK_MODIFIER_MASK) == GDK_CONTROL_MASK; }
338inline bool mod_alt_only(unsigned modifiers) { return (modifiers & INK_GDK_MODIFIER_MASK) == GDK_ALT_MASK; }
339inline bool mod_any(unsigned modifiers) { return modifiers & INK_GDK_MODIFIER_MASK; }
340inline bool mod_none(unsigned modifiers) { return !mod_any(modifiers); }
341
342template <unsigned button>
343inline bool mod_button(unsigned modifiers) { return (1 <= button || button <= 5) && (modifiers & (GDK_BUTTON1_MASK << (button - 1))); }
344
345inline bool mod_shift(CanvasEvent const &event) { return mod_shift(event.modifiers); }
346inline bool mod_ctrl(CanvasEvent const &event) { return mod_ctrl(event.modifiers); }
347inline bool mod_alt(CanvasEvent const &event) { return mod_alt(event.modifiers); }
348inline bool mod_shift_only(CanvasEvent const &event) { return mod_shift_only(event.modifiers); }
349inline bool mod_ctrl_only(CanvasEvent const &event) { return mod_ctrl_only(event.modifiers); }
350inline bool mod_alt_only(CanvasEvent const &event) { return mod_alt_only(event.modifiers); }
351inline bool mod_any(CanvasEvent const &event) { return mod_any(event.modifiers); }
352inline bool mod_none(CanvasEvent const &event) { return mod_none(event.modifiers); }
353
354template <unsigned button>
355inline bool mod_button(CanvasEvent const &event) { return mod_button<button>(event.modifiers); }
356
357} // namespace Inkscape
358
359#endif // INKSCAPE_UI_WIDGET_EVENTS_CANVAS_EVENT_H
360
361/*
362 Local Variables:
363 mode:c++
364 c-file-style:"stroustrup"
365 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
366 indent-tabs-mode:nil
367 fill-column:99
368 End:
369*/
370// vim:filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99:
Cartesian point / 2D vector and related operations.
Two-dimensional point that doubles as a vector.
Definition point.h:66
E & cast_helper(CanvasEvent &event)
Helper class to stream background task notifications as a series of messages.
bool mod_alt(unsigned modifiers)
EventType
The type of a CanvasEvent.
Definition enums.h:22
void inspect_event(E &&event, Fs... funcs)
Perform pattern-matching on a CanvasEvent.
bool mod_ctrl_only(unsigned modifiers)
bool mod_ctrl(unsigned modifiers)
bool mod_shift_only(unsigned modifiers)
bool mod_none(unsigned modifiers)
bool mod_shift(unsigned modifiers)
bool mod_alt_only(unsigned modifiers)
bool mod_button(unsigned modifiers)
ExtendedInput extinput_from_gdkevent(Gdk::Event const &event)
Read the extended input data from a Gdk::Event.
bool mod_any(unsigned modifiers)
constexpr auto INK_GDK_MODIFIER_MASK
All modifiers used by Inkscape.
Abstract event for mouse button (left/right/middle).
unsigned modifiersChange() const override
Get the change in the modifiers due to this event.
uint32_t time
Timestamp of the event in milliseconds.
unsigned button
The button that was pressed/released. (Matches GDK_BUTTON_*.)
Geom::Point pos
Location of the cursor, in world coordinates.
Geom::Point orig_pos
Location of the cursor, in GDK event / canvas widget coordinates.
A mouse button (left/right/middle) is pressed.
int num_press
Counter for repeated clicks (e.g. double clicks). Starts at 1 and increments by 1 each time.
EventType type() const override
Return the dynamic type of the CanvasEvent.
ExtendedInput extinput
Extended input data for graphics tablet input. Fields may be empty.
A mouse button (left/right/middle) is released.
EventType type() const override
Return the dynamic type of the CanvasEvent.
Abstract base class for events.
unsigned modifiers
The modifiers mask immediately before the event.
virtual unsigned modifiersChange() const
Get the change in the modifiers due to this event.
unsigned modifiersAfter() const
Get the modifiers mask immediately after the event. (Convenience function.)
virtual EventType type() const =0
Return the dynamic type of the CanvasEvent.
std::shared_ptr< Gdk::Device const > device
The device that sourced the event. May be null.
The pointer has entered a widget or item.
Geom::Point pos
Location of the cursor.
EventType type() const override
Return the dynamic type of the CanvasEvent.
Extended input data associated to events generated by graphics tablets.
std::optional< double > ytilt
std::optional< double > xtilt
std::optional< double > pressure
A key has been pressed.
std::optional< Geom::Point > pos
Location of the cursor, in world coordinates.
uint32_t keyval
The key that was pressed/released. (Matches gdkkeysyms.h.)
unsigned modifiersChange() const override
Get the change in the modifiers due to this event.
int group
The keyboard group.
std::optional< Geom::Point > orig_pos
Location of the cursor, in GDK event / canvas widget coordinates.
uint16_t keycode
The raw code of the key that was pressed/released.
uint32_t time
Timestamp of the event in milliseconds.
A key has been pressed.
EventType type() const override
Return the dynamic type of the CanvasEvent.
A key has been released.
EventType type() const override
Return the dynamic type of the CanvasEvent.
The pointer has exited a widget or item.
EventType type() const override
Return the dynamic type of the CanvasEvent.
Movement of the mouse pointer.
bool control_point_synthesized
Whether this is a fake motion event synthesized by a control point.
EventType type() const override
Return the dynamic type of the CanvasEvent.
ExtendedInput extinput
Extended input data for graphics tablet input. Fields may be empty.
uint32_t time
Timestamp of the event in milliseconds.
Geom::Point pos
Location of the cursor.
Scroll the item or widget by the provided amount.
ExtendedInput extinput
Extended input data for graphics tablet input. Fields may be empty.
Geom::Point delta
The amount scrolled.
EventType type() const override
Return the dynamic type of the CanvasEvent.
Gdk::ScrollUnit unit
The units of the scroll delta.