Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
controller.h
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
5/*
6 * Authors:
7 * Daniel Boles <dboles.src+inkscape@gmail.com>
8 *
9 * Copyright (C) 2023 Daniel Boles
10 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
11 */
12
13#ifndef SEEN_UI_CONTROLLER_H
14#define SEEN_UI_CONTROLLER_H
15
16#include <gdkmm/enums.h>
17#include <gtkmm/gesture.h>
18#include <utility>
19
22
24// This will be needed in GTK4 as enums are scoped there, so bitwise is tougher.
25[[nodiscard]] inline bool has_flag(Gdk::ModifierType const state,
26 Gdk::ModifierType const flags)
27 { return (state & flags) != Gdk::ModifierType{}; }
28
29// migration aid for above, to later replace GdkModifierType w Gdk::ModifierType
30[[nodiscard]] inline bool has_flag(GdkModifierType const state,
31 GdkModifierType const flags)
32 { return (state & flags) != GdkModifierType{}; }
33
34// We add the requirement that slots return an EventSequenceState, which if itʼs
35// not NONE we set on the controller. This makes it easier & less error-prone to
36// migrate code that returned a bool whether GdkEvent is handled, to Controllers
37// & their way of claiming the sequence if handled – as then we only require end
38// users to change their returned type/value – rather than need them to manually
39// call controller.set_state(), which is easy to forget & unlike a return cannot
40// be enforced by the compiler. So… this wraps a callerʼs slot that returns that
41// state & uses it, with a void-returning wrapper as thatʼs what GTK/mm expects.
42template <typename Slot>
43[[nodiscard]] auto use_state(Slot &&slot)
44{
45 return [slot = std::forward<Slot>(slot)](auto &controller, auto &&...args) {
46 if constexpr (std::is_convertible_v<Slot, bool>) {
47 if (!slot)
48 return;
49 }
50 Gtk::EventSequenceState const state = slot(controller, std::forward<decltype(args)>(args)...);
51 if (state != Gtk::EventSequenceState::NONE) {
52 controller.set_state(state);
53 }
54 };
55}
56
57template <typename Slot, typename Controller>
58[[nodiscard]] auto use_state(Slot &&slot, Controller &controller)
59{
60 return [&controller, new_slot = use_state(std::forward<Slot>(slot))](auto &&...args) {
61 return new_slot(controller, std::forward<decltype(args)>(args)...);
62 };
63}
64
65} // namespace Inkscape::UI::Controller
66
67#endif // SEEN_UI_CONTROLLER_H
68
69/*
70 Local Variables:
71 mode:c++
72 c-file-style:"stroustrup"
73 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
74 indent-tabs-mode:nil
75 fill-column:99
76 End:
77*/
78// vim:filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99:
Utilities to more easily use Gtk::EventController & subclasses like Gesture.
Definition controller.h:21
auto use_state(Slot &&slot)
Definition controller.h:43
bool has_flag(Gdk::ModifierType const state, Gdk::ModifierType const flags)
Helper to query if ModifierType state contains one or more of given flag(s).
Definition controller.h:25