1// Aseprite
2// Copyright (C) 2018-2022 Igara Studio S.A.
3// Copyright (C) 2001-2018 David Capello
4//
5// This program is distributed under the terms of
6// the End-User License Agreement for Aseprite.
7
8#ifndef APP_UI_KEY_H_INCLUDED
9#define APP_UI_KEY_H_INCLUDED
10#pragma once
11
12#include "app/commands/params.h"
13#include "app/ui/key_context.h"
14#include "base/convert_to.h"
15#include "base/vector2d.h"
16#include "ui/accelerator.h"
17
18#include <memory>
19#include <utility>
20#include <vector>
21
22namespace ui {
23 class Message;
24}
25
26namespace app {
27 class Command;
28 class KeyboardShortcuts;
29
30 namespace tools {
31 class Tool;
32 }
33
34 enum class KeySource {
35 Original,
36 ExtensionDefined,
37 UserDefined
38 };
39
40 enum class KeyType {
41 Command,
42 Tool,
43 Quicktool,
44 Action,
45 WheelAction,
46 DragAction,
47 };
48
49 // TODO This should be called "KeyActionModifier" or something similar
50 enum class KeyAction {
51 None = 0x00000000,
52 CopySelection = 0x00000001,
53 SnapToGrid = 0x00000002,
54 AngleSnap = 0x00000004,
55 MaintainAspectRatio = 0x00000008,
56 LockAxis = 0x00000010,
57 AddSelection = 0x00000020,
58 SubtractSelection = 0x00000040,
59 IntersectSelection = 0x00000080,
60 AutoSelectLayer = 0x00000100,
61 LeftMouseButton = 0x00000200,
62 RightMouseButton = 0x00000400,
63 StraightLineFromLastPoint = 0x00000800,
64 MoveOrigin = 0x00001000,
65 SquareAspect = 0x00002000,
66 DrawFromCenter = 0x00004000,
67 ScaleFromCenter = 0x00008000,
68 AngleSnapFromLastPoint = 0x00010000,
69 RotateShape = 0x00020000,
70 FineControl = 0x00040000,
71 };
72
73 enum class WheelAction {
74 None,
75 Zoom,
76 VScroll,
77 HScroll,
78 FgColor,
79 BgColor,
80 FgTile,
81 BgTile,
82 Frame,
83 BrushSize,
84 BrushAngle,
85 ToolSameGroup,
86 ToolOtherGroup,
87 Layer,
88 InkType,
89 InkOpacity,
90 LayerOpacity,
91 CelOpacity,
92 Alpha,
93 HslHue,
94 HslSaturation,
95 HslLightness,
96 HsvHue,
97 HsvSaturation,
98 HsvValue,
99
100 // Range
101 First = Zoom,
102 Last = HsvValue,
103 };
104
105 inline KeyAction operator&(KeyAction a, KeyAction b) {
106 return KeyAction(int(a) & int(b));
107 }
108
109 class Key;
110 using KeyPtr = std::shared_ptr<Key>;
111 using Keys = std::vector<KeyPtr>;
112 using KeySourceAccelList = std::vector<std::pair<KeySource, ui::Accelerator>>;
113 using DragVector = base::Vector2d<double>;
114
115 class Key {
116 public:
117 Key(const Key& key);
118 Key(Command* command, const Params& params,
119 const KeyContext keyContext);
120 Key(const KeyType type, tools::Tool* tool);
121 explicit Key(const KeyAction action,
122 const KeyContext keyContext);
123 explicit Key(const WheelAction action);
124 static KeyPtr MakeDragAction(WheelAction dragAction);
125
126 KeyType type() const { return m_type; }
127 const ui::Accelerators& accels() const;
128 const KeySourceAccelList addsKeys() const { return m_adds; }
129 const KeySourceAccelList delsKeys() const { return m_dels; }
130
131 void add(const ui::Accelerator& accel,
132 const KeySource source,
133 KeyboardShortcuts& globalKeys);
134 const ui::Accelerator* isPressed(const ui::Message* msg,
135 KeyboardShortcuts& globalKeys) const;
136 bool isPressed() const;
137 bool isLooselyPressed() const;
138
139 bool hasAccel(const ui::Accelerator& accel) const;
140 bool hasUserDefinedAccels() const;
141
142 // The KeySource indicates from where the key was disabled
143 // (e.g. if it was removed from an extension-defined file, or from
144 // user-defined).
145 void disableAccel(const ui::Accelerator& accel,
146 const KeySource source);
147
148 // Resets user accelerators to the original & extension-defined ones.
149 void reset();
150
151 void copyOriginalToUser();
152
153 // for KeyType::Command
154 Command* command() const { return m_command; }
155 const Params& params() const { return m_params; }
156 KeyContext keycontext() const { return m_keycontext; }
157 // for KeyType::Tool or Quicktool
158 tools::Tool* tool() const { return m_tool; }
159 // for KeyType::Action
160 KeyAction action() const { return m_action; }
161 // for KeyType::WheelAction / KeyType::DragAction
162 WheelAction wheelAction() const { return m_wheelAction; }
163 // for KeyType::DragAction
164 DragVector dragVector() const { return m_dragVector; }
165 void setDragVector(const DragVector& v) { m_dragVector = v; }
166
167 std::string triggerString() const;
168
169 private:
170 KeyType m_type;
171 KeySourceAccelList m_adds;
172 KeySourceAccelList m_dels;
173 // Final list of accelerators after processing the
174 // addition/deletion of extension-defined & user-defined keys.
175 mutable std::unique_ptr<ui::Accelerators> m_accels;
176 KeyContext m_keycontext;
177
178 // for KeyType::Command
179 Command* m_command;
180 Params m_params;
181
182 tools::Tool* m_tool; // for KeyType::Tool or Quicktool
183 KeyAction m_action; // for KeyType::Action
184 WheelAction m_wheelAction; // for KeyType::WheelAction / DragAction
185 DragVector m_dragVector; // for KeyType::DragAction
186 };
187
188 std::string convertKeyContextToUserFriendlyString(KeyContext keyContext);
189
190} // namespace app
191
192namespace base {
193
194 template<> app::KeyAction convert_to(const std::string& from);
195 template<> std::string convert_to(const app::KeyAction& from);
196
197 template<> app::WheelAction convert_to(const std::string& from);
198 template<> std::string convert_to(const app::WheelAction& from);
199
200} // namespace base
201
202#endif
203