TGUI 1.13
Loading...
Searching...
No Matches
Keyboard.hpp
1
2//
3// TGUI - Texus' Graphical User Interface
4// Copyright (C) 2012-2026 Bruno Van de Velde (vdv_b@tgui.eu)
5//
6// This software is provided 'as-is', without any express or implied warranty.
7// In no event will the authors be held liable for any damages arising from the use of this software.
8//
9// Permission is granted to anyone to use this software for any purpose,
10// including commercial applications, and to alter it and redistribute it freely,
11// subject to the following restrictions:
12//
13// 1. The origin of this software must not be misrepresented;
14// you must not claim that you wrote the original software.
15// If you use this software in a product, an acknowledgment
16// in the product documentation would be appreciated but is not required.
17//
18// 2. Altered source versions must be plainly marked as such,
19// and must not be misrepresented as being the original software.
20//
21// 3. This notice may not be removed or altered from any source distribution.
22//
24
25#ifndef TGUI_KEYBOARD_HPP
26#define TGUI_KEYBOARD_HPP
27
29
30#include <TGUI/Config.hpp>
31
32#include <TGUI/Backend/Window/Backend.hpp>
33#include <TGUI/Backend/Window/BackendGui.hpp>
34
35#include <TGUI/Container.hpp>
36#include <TGUI/Event.hpp>
37#include <TGUI/Widgets/ScrollablePanel.hpp>
38
40
41namespace tgui::keyboard
42{
43#ifndef TGUI_REMOVE_DEPRECATED_CODE
44 TGUI_DEPRECATED("Use BackendGui::startTextInput instead")
45 inline void openVirtualKeyboard(const Widget* requestingWidget, FloatRect inputRect)
46 {
47 TGUI_ASSERT(requestingWidget != nullptr, "requestingWidget must not be nullptr");
48 if (!requestingWidget)
49 return;
50
51 const Widget* widget = requestingWidget;
52 while (widget)
53 {
54 const bool defaultOrigin = (widget->getOrigin().x == 0) && (widget->getOrigin().y == 0);
55 const bool scaledOrRotated = (widget->getScale().x != 1) || (widget->getScale().y != 1) || (widget->getRotation() != 0);
56 if (defaultOrigin && !scaledOrRotated)
57 inputRect.setPosition(inputRect.getPosition() + widget->getPosition());
58 else
59 {
60 const Vector2f origin{widget->getOrigin().x * widget->getSize().x, widget->getOrigin().y * widget->getSize().y};
61 if (!scaledOrRotated)
62 inputRect.setPosition(inputRect.getPosition() + widget->getPosition() - origin);
63 else
64 {
65 const Vector2f rotOrigin{widget->getRotationOrigin().x * widget->getSize().x,
66 widget->getRotationOrigin().y * widget->getSize().y};
67 const Vector2f scaleOrigin{widget->getScaleOrigin().x * widget->getSize().x,
68 widget->getScaleOrigin().y * widget->getSize().y};
69
70 Transform transform;
71 transform.translate(widget->getPosition() - origin);
72 transform.rotate(widget->getRotation(), rotOrigin);
73 transform.scale(widget->getScale(), scaleOrigin);
74 inputRect = transform.transformRect(inputRect);
75 }
76 }
77
78 const Container* parent = widget->getParent();
79 if (parent)
80 {
81 inputRect.setPosition(inputRect.getPosition() + parent->getChildWidgetsOffset());
82
83 const auto* panel = dynamic_cast<const ScrollablePanel*>(parent);
84 if (panel)
85 inputRect.setPosition(inputRect.getPosition() - panel->getContentOffset());
86 }
87
88 widget = parent;
89 }
90
91 const auto* gui = requestingWidget->getParentGui();
92 if (gui)
93 {
94 const Vector2f topLeftPos = gui->mapCoordsToPixel(inputRect.getPosition());
95 const Vector2f bottomRightPos = gui->mapCoordsToPixel(inputRect.getPosition() + inputRect.getSize());
96 inputRect = {topLeftPos, bottomRightPos - topLeftPos};
97 }
98
99 TGUI_IGNORE_DEPRECATED_WARNINGS_START
100 getBackend()->openVirtualKeyboard(inputRect);
101 TGUI_IGNORE_DEPRECATED_WARNINGS_END
102 }
103#endif
105
106 [[nodiscard]] inline bool isShiftPressed(const Event::KeyEvent& event)
107 {
108 return event.shift;
109 }
110
112#ifndef TGUI_REMOVE_DEPRECATED_CODE
113 TGUI_DEPRECATED("Use isShiftPressed(gui) instead") [[nodiscard]] inline bool isShiftPressed()
114 {
115 TGUI_IGNORE_DEPRECATED_WARNINGS_START
116 return getBackend()->isKeyboardModifierPressed(Event::KeyModifier::Shift);
117 TGUI_IGNORE_DEPRECATED_WARNINGS_END
118 }
119#endif
121
122 [[nodiscard]] inline bool isShiftPressed(const BackendGui* gui)
123 {
124 return gui->isKeyboardModifierPressed(Event::KeyModifier::Shift);
125 }
126
128#ifndef TGUI_REMOVE_DEPRECATED_CODE
129 TGUI_DEPRECATED("Use BackendGui::stopTextInput instead") inline void closeVirtualKeyboard()
130 {
131 TGUI_IGNORE_DEPRECATED_WARNINGS_START
132 getBackend()->closeVirtualKeyboard();
133 TGUI_IGNORE_DEPRECATED_WARNINGS_END
134 }
135#endif
137
138 [[nodiscard]] inline bool isMultiselectModifierPressed(const Event::KeyEvent& event)
139 {
140#ifdef TGUI_SYSTEM_MACOS
141 return event.system;
142#else
143 return event.control;
144#endif
145 }
146
148#ifndef TGUI_REMOVE_DEPRECATED_CODE
149 TGUI_DEPRECATED("Use isMultiselectModifierPressed(gui) instead") [[nodiscard]] inline bool isMultiselectModifierPressed()
150 {
151 TGUI_IGNORE_DEPRECATED_WARNINGS_START
152 #ifdef TGUI_SYSTEM_MACOS
153 return getBackend()->isKeyboardModifierPressed(Event::KeyModifier::System);
154 #else
155 return getBackend()->isKeyboardModifierPressed(Event::KeyModifier::Control);
156 #endif
157 TGUI_IGNORE_DEPRECATED_WARNINGS_END
158 }
159#endif
161
162 [[nodiscard]] inline bool isMultiselectModifierPressed(const BackendGui* gui)
163 {
164#ifdef TGUI_SYSTEM_MACOS
165 return gui->isKeyboardModifierPressed(Event::KeyModifier::System);
166#else
167 return gui->isKeyboardModifierPressed(Event::KeyModifier::Control);
168#endif
169 }
170
172
173 [[nodiscard]] inline bool isKeyPressCopy(const Event::KeyEvent& event)
174 {
175#ifdef TGUI_SYSTEM_MACOS
176 return (event.code == Event::KeyboardKey::C) && !event.control && !event.alt && !event.shift && event.system;
177#else
178 return (event.code == Event::KeyboardKey::C) && event.control && !event.alt && !event.shift && !event.system;
179#endif
180 }
181
183
184 [[nodiscard]] inline bool isKeyPressCut(const Event::KeyEvent& event)
185 {
186#ifdef TGUI_SYSTEM_MACOS
187 return (event.code == Event::KeyboardKey::X) && !event.control && !event.alt && !event.shift && event.system;
188#else
189 return (event.code == Event::KeyboardKey::X) && event.control && !event.alt && !event.shift && !event.system;
190#endif
191 }
192
194
195 [[nodiscard]] inline bool isKeyPressPaste(const Event::KeyEvent& event)
196 {
197#ifdef TGUI_SYSTEM_MACOS
198 return (event.code == Event::KeyboardKey::V) && !event.control && !event.alt && !event.shift && event.system;
199#else
200 return (event.code == Event::KeyboardKey::V) && event.control && !event.alt && !event.shift && !event.system;
201#endif
202 }
203
205
206 [[nodiscard]] inline bool isKeyPressSelectAll(const Event::KeyEvent& event)
207 {
208#ifdef TGUI_SYSTEM_MACOS
209 return (event.code == Event::KeyboardKey::A) && !event.control && !event.alt && !event.shift && event.system;
210#else
211 return (event.code == Event::KeyboardKey::A) && event.control && !event.alt && !event.shift && !event.system;
212#endif
213 }
214
216
217 [[nodiscard]] inline bool isKeyPressMoveCaretLeft(const Event::KeyEvent& event)
218 {
219 return (event.code == Event::KeyboardKey::Left) && !event.control && !event.alt && !event.system;
220 }
221
223
224 [[nodiscard]] inline bool isKeyPressMoveCaretRight(const Event::KeyEvent& event)
225 {
226 return (event.code == Event::KeyboardKey::Right) && !event.control && !event.alt && !event.system;
227 }
228
230
231 [[nodiscard]] inline bool isKeyPressMoveCaretWordBegin(const Event::KeyEvent& event)
232 {
233#ifdef TGUI_SYSTEM_MACOS
234 return (event.code == Event::KeyboardKey::Left) && !event.control && event.alt && !event.system;
235#else
236 return (event.code == Event::KeyboardKey::Left) && event.control && !event.alt && !event.system;
237#endif
238 }
239
241
242 [[nodiscard]] inline bool isKeyPressMoveCaretWordEnd(const Event::KeyEvent& event)
243 {
244#ifdef TGUI_SYSTEM_MACOS
245 return (event.code == Event::KeyboardKey::Right) && !event.control && event.alt && !event.system;
246#else
247 return (event.code == Event::KeyboardKey::Right) && event.control && !event.alt && !event.system;
248#endif
249 }
250
252
253 [[nodiscard]] inline bool isKeyPressMoveCaretUp(const Event::KeyEvent& event)
254 {
255#ifdef TGUI_SYSTEM_MACOS
256 // Option+UpArrow should actually move to the beginning of the paragraph (or the previous one), but we don't support this
257 return (event.code == Event::KeyboardKey::Up) && !event.control && !event.system;
258#else
259 return (event.code == Event::KeyboardKey::Up) && !event.alt && !event.system;
260#endif
261 }
262
264
265 [[nodiscard]] inline bool isKeyPressMoveCaretDown(const Event::KeyEvent& event)
266 {
267#ifdef TGUI_SYSTEM_MACOS
268 // Option+DownArrow should actually move to the end of the paragraph (or the next one), but we don't support this
269 return (event.code == Event::KeyboardKey::Down) && !event.control && !event.system;
270#else
271 return (event.code == Event::KeyboardKey::Down) && !event.alt && !event.system;
272#endif
273 }
274
276
277 [[nodiscard]] inline bool isKeyPressMoveCaretLineStart(const Event::KeyEvent& event)
278 {
279#ifdef TGUI_SYSTEM_MACOS
280 if ((event.code == Event::KeyboardKey::Left) && !event.control && !event.alt && event.system)
281 return true;
282#endif
283 return (event.code == Event::KeyboardKey::Home) && !event.control && !event.alt && !event.system;
284 }
285
287
288 [[nodiscard]] inline bool isKeyPressMoveCaretLineEnd(const Event::KeyEvent& event)
289 {
290#ifdef TGUI_SYSTEM_MACOS
291 if ((event.code == Event::KeyboardKey::Right) && !event.control && !event.alt && event.system)
292 return true;
293#endif
294 return (event.code == Event::KeyboardKey::End) && !event.control && !event.alt && !event.system;
295 }
296
298
299 [[nodiscard]] inline bool isKeyPressMoveCaretDocumentBegin(const Event::KeyEvent& event)
300 {
301#ifdef TGUI_SYSTEM_MACOS
302 return ((event.code == Event::KeyboardKey::Up) && !event.control && !event.alt && event.system)
303 || ((event.code == Event::KeyboardKey::Home) && !event.control && !event.alt && event.system);
304#else
305 return (event.code == Event::KeyboardKey::Home) && event.control && !event.alt && !event.system;
306#endif
307 }
308
310
311 [[nodiscard]] inline bool isKeyPressMoveCaretDocumentEnd(const Event::KeyEvent& event)
312 {
313#ifdef TGUI_SYSTEM_MACOS
314 return ((event.code == Event::KeyboardKey::Down) && !event.control && !event.alt && event.system)
315 || ((event.code == Event::KeyboardKey::End) && !event.control && !event.alt && event.system);
316#else
317 return (event.code == Event::KeyboardKey::End) && event.control && !event.alt && !event.system;
318#endif
319 }
320
322
323 [[nodiscard]] inline bool isKeyPressDeleteWordLeft(const Event::KeyEvent& event)
324 {
325#ifdef TGUI_SYSTEM_MACOS
326 return (event.code == Event::KeyboardKey::Backspace) && !event.control && event.alt && !event.system;
327#else
328 return (event.code == Event::KeyboardKey::Backspace) && event.control && !event.alt && !event.system;
329#endif
330 }
331
333
334 [[nodiscard]] inline bool isKeyPressDeleteWordRight(const Event::KeyEvent& event)
335 {
336#ifdef TGUI_SYSTEM_MACOS
337 return (event.code == Event::KeyboardKey::Delete) && !event.control && event.alt && !event.system;
338#else
339 return (event.code == Event::KeyboardKey::Delete) && event.control && !event.alt && !event.system;
340#endif
341 }
342} // namespace tgui::keyboard
343
344#endif // TGUI_KEYBOARD_HPP
TGUI_API std::shared_ptr< Backend > getBackend()
Returns the global backend.
@ X
The X key.
Definition Event.hpp:65
@ Down
Down arrow.
Definition Event.hpp:116
@ C
The C key.
Definition Event.hpp:44
@ Up
Up arrow.
Definition Event.hpp:115
@ V
The V key.
Definition Event.hpp:63
@ A
The A key.
Definition Event.hpp:42
@ End
The End key.
Definition Event.hpp:105
@ Home
The Home key.
Definition Event.hpp:106
@ Right
Right arrow.
Definition Event.hpp:114
@ Left
Left arrow.
Definition Event.hpp:113
@ Backspace
The Backspace key.
Definition Event.hpp:101
@ Delete
The Delete key.
Definition Event.hpp:108