HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
KeyboardModifiers.hpp
1// Copyright 2020 Pokitec
2// All rights reserved.
3
4#pragma once
5
6#include "TTauri/Foundation/required.hpp"
7#include "TTauri/Foundation/exceptions.hpp"
8#include "TTauri/Foundation/strings.hpp"
9#include <cstdint>
10
11namespace tt {
12
18enum class KeyboardModifiers : uint8_t {
19 None = 0x00,
20 Shift = 0x01,
21 Control = 0x02,
22 Alt = 0x04,
23 Super = 0x08,
24};
25
26[[nodiscard]] constexpr KeyboardModifiers operator|(KeyboardModifiers lhs, KeyboardModifiers rhs) noexcept
27{
28 return static_cast<KeyboardModifiers>(static_cast<uint8_t>(lhs) | static_cast<uint8_t>(rhs));
29}
30
31constexpr KeyboardModifiers &operator|=(KeyboardModifiers &lhs, KeyboardModifiers rhs) noexcept
32{
33 lhs = lhs | rhs;
34 return lhs;
35}
36
37[[nodiscard]] constexpr bool operator>=(KeyboardModifiers lhs, KeyboardModifiers rhs) noexcept {
38 ttlet lhs_ = static_cast<uint8_t>(lhs);
39 ttlet rhs_ = static_cast<uint8_t>(rhs);
40 return (lhs_ & rhs_) == rhs_;
41}
42
46inline KeyboardModifiers to_KeyboardModifiers(std::string_view s)
47{
48 if (ssize(s) == 0) {
49 TTAURI_THROW(parse_error("Empty keyboard modifier"));
50 }
51
52 // Remove the canonical trailing '+'.
53 ttlet s_lower = to_lower(
54 (s.back() == '+') ? s.substr(0, ssize(s) - 1) : s
55 );
56
57 if (s_lower == "shift") {
58 return KeyboardModifiers::Shift;
59 } else if (s_lower == "control" || s_lower == "ctrl" || s_lower == "cntr") {
60 return KeyboardModifiers::Control;
61 } else if (s_lower == "alt" || s_lower == "option" || s_lower == "meta") {
62 return KeyboardModifiers::Alt;
63 } else if (
64 s_lower == "windows" || s_lower == "win" ||
65 s_lower == "command" || s_lower == "cmd" ||
66 s_lower == "super"
67 ) {
68 return KeyboardModifiers::Super;
69 } else {
70 TTAURI_THROW(parse_error("Unknown keyboard modifier '{}'", s));
71 }
72}
73
74inline std::string to_string(KeyboardModifiers modifiers)
75{
76 auto r = std::string{};
77
78 if (modifiers >= KeyboardModifiers::Shift) {
79 r += "shift+";
80 }
81 if (modifiers >= KeyboardModifiers::Control) {
82 r += "control+";
83 }
84 if (modifiers >= KeyboardModifiers::Alt) {
85 r += "alt+";
86 }
87 if (modifiers >= KeyboardModifiers::Super) {
88 r += "super+";
89 }
90
91 return r;
92}
93
94inline std::ostream &operator<<(std::ostream &lhs, KeyboardModifiers const &rhs)
95{
96 return lhs << to_string(rhs);
97}
98
99}
100
101namespace std {
102
103template<>
104struct hash<tt::KeyboardModifiers> {
105 [[nodiscard]] size_t operator() (tt::KeyboardModifiers const &rhs) const noexcept {
106 return std::hash<uint8_t>{}(static_cast<uint8_t>(rhs));
107 }
108};
109
110}
STL namespace.
T operator()(T... args)
T operator>=(T... args)
T to_string(T... args)