HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
keyboard_modifiers.hpp
1// Copyright Take Vos 2020.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "../required.hpp"
8#include "../exception.hpp"
9#include "../strings.hpp"
10#include <cstdint>
11
12namespace tt {
13
19enum class keyboard_modifiers : uint8_t {
20 None = 0x00,
21 Shift = 0x01,
22 Control = 0x02,
23 Alt = 0x04,
24 Super = 0x08,
25};
26
27[[nodiscard]] constexpr keyboard_modifiers operator|(keyboard_modifiers lhs, keyboard_modifiers rhs) noexcept
28{
29 return static_cast<keyboard_modifiers>(static_cast<uint8_t>(lhs) | static_cast<uint8_t>(rhs));
30}
31
32constexpr keyboard_modifiers &operator|=(keyboard_modifiers &lhs, keyboard_modifiers rhs) noexcept
33{
34 lhs = lhs | rhs;
35 return lhs;
36}
37
38[[nodiscard]] constexpr bool operator>=(keyboard_modifiers lhs, keyboard_modifiers rhs) noexcept
39{
40 ttlet lhs_ = static_cast<uint8_t>(lhs);
41 ttlet rhs_ = static_cast<uint8_t>(rhs);
42 return (lhs_ & rhs_) == rhs_;
43}
44
48inline keyboard_modifiers to_keyboard_modifiers(std::string_view s)
49{
50 if (std::ssize(s) == 0) {
51 throw parse_error("Empty keyboard modifier");
52 }
53
54 // Remove the canonical trailing '+'.
55 ttlet s_lower = to_lower((s.back() == '+') ? s.substr(0, std::ssize(s) - 1) : s);
56
57 if (s_lower == "shift") {
58 return keyboard_modifiers::Shift;
59 } else if (s_lower == "control" || s_lower == "ctrl" || s_lower == "cntr") {
60 return keyboard_modifiers::Control;
61 } else if (s_lower == "alt" || s_lower == "option" || s_lower == "meta") {
62 return keyboard_modifiers::Alt;
63 } else if (s_lower == "windows" || s_lower == "win" || s_lower == "command" || s_lower == "cmd" || s_lower == "super") {
64 return keyboard_modifiers::Super;
65 } else {
66 throw parse_error("Unknown keyboard modifier '{}'", s);
67 }
68}
69
70inline std::string to_string(keyboard_modifiers modifiers)
71{
72 auto r = std::string{};
73
74 if (modifiers >= keyboard_modifiers::Shift) {
75 r += "shift+";
76 }
77 if (modifiers >= keyboard_modifiers::Control) {
78 r += "control+";
79 }
80 if (modifiers >= keyboard_modifiers::Alt) {
81 r += "alt+";
82 }
83 if (modifiers >= keyboard_modifiers::Super) {
84 r += "super+";
85 }
86
87 return r;
88}
89
90inline std::ostream &operator<<(std::ostream &lhs, keyboard_modifiers const &rhs)
91{
92 return lhs << to_string(rhs);
93}
94
95} // namespace tt
96
97namespace std {
98
99template<>
100struct hash<tt::keyboard_modifiers> {
101 [[nodiscard]] size_t operator()(tt::keyboard_modifiers const &rhs) const noexcept
102 {
103 return std::hash<uint8_t>{}(static_cast<uint8_t>(rhs));
104 }
105};
106
107template<typename CharT>
108struct std::formatter<tt::keyboard_modifiers, CharT> : std::formatter<std::string_view, CharT> {
109 auto format(tt::keyboard_modifiers const &t, auto &fc)
110 {
111 return std::formatter<std::string_view, CharT>::format(tt::to_string(t), fc);
112 }
113};
114
115} // namespace std
constexpr alignment operator|(vertical_alignment lhs, horizontal_alignment rhs) noexcept
Combine vertical and horizontal alignment.
Definition alignment.hpp:91
STL namespace.
T operator()(T... args)
T operator>=(T... args)
T to_string(T... args)