7#include "keyboard_key.hpp"
9#include "../utility/utility.hpp"
10#include "../codec/codec.hpp"
11#include "../coroutine/module.hpp"
12#include "../macros.hpp"
13#include <unordered_map>
17namespace hi {
inline namespace v1 {
25 void add_system_binding(keyboard_key key,
gui_event_type command)
noexcept
27 bindings[key].add_system_command(command);
30 void add_ignored_binding(keyboard_key key,
gui_event_type command)
noexcept
32 bindings[key].add_ignored_command(command);
35 void add_user_binding(keyboard_key key,
gui_event_type command)
noexcept
37 bindings[key].add_user_command(command);
47 if (event == gui_event_type::keyboard_down) {
48 hilet i = bindings.find(keyboard_key{
event.keyboard_modifiers,
event.key()});
49 if (i != bindings.cend()) {
50 for (
auto &e : i->second.get_events()) {
69 void load_bindings(std::filesystem::path
const& path,
bool system_binding =
false)
71 hilet data = parse_JSON(path);
74 hi_check(data.contains(
"bindings"),
"Missing key 'bindings' at top level.");
76 hilet binding_list = data[
"bindings"];
78 holds_alternative<datum::vector_type>(binding_list),
"Expecting array value for key 'bindings' at top level.");
80 for (hilet& binding : binding_list) {
81 hi_check(holds_alternative<datum::map_type>(binding),
"Expecting object for a binding, got {}", binding);
84 binding.contains(
"key") && binding.contains(
"command"),
85 "Expecting required 'key' and 'command' for a binding, got {}",
88 hilet key_name =
static_cast<std::string>(binding[
"key"]);
89 hilet key = keyboard_key(key_name);
91 auto command_name =
static_cast<std::string>(binding[
"command"]);
94 bool ignored_binding =
false;
95 if (command_name.size() >= 1 && command_name[0] ==
'-') {
96 ignored_binding =
true;
97 command_name = command_name.substr(1);
101 if (command == gui_event_type::none) {
102 throw parse_error(std::format(
"Could not parse command '{}'", command_name));
105 if (ignored_binding) {
106 add_ignored_binding(key, command);
107 }
else if (system_binding) {
108 add_system_binding(key, command);
110 add_user_binding(key, command);
115 throw io_error(std::format(
"{}: Could not load keyboard bindings.\n{}", path.string(), e.
what()));
136 std::vector<gui_event> cache = {};
138 [[nodiscard]] std::vector<gui_event>
const& get_events() const noexcept
145 hilet i =
std::find(system.cbegin(), system.cend(), cmd);
146 if (i == system.cend()) {
147 system.push_back(cmd);
154 hilet i =
std::find(ignored.cbegin(), ignored.cend(), cmd);
155 if (i == ignored.cend()) {
156 ignored.push_back(cmd);
163 hilet i =
std::find(user.cbegin(), user.cend(), cmd);
164 if (i == user.cend()) {
170 void update_cache() noexcept
172 cache.
reserve(ssize(system) + ssize(user));
174 for (hilet cmd : system) {
175 hilet i =
std::find(cache.cbegin(), cache.cend(), cmd);
176 if (i == cache.cend()) {
177 cache.emplace_back(cmd);
181 for (hilet cmd : ignored) {
182 hilet i =
std::find(cache.cbegin(), cache.cend(), cmd);
183 if (i != cache.cend()) {
188 for (hilet cmd : user) {
189 hilet i =
std::find(cache.cbegin(), cache.cend(), cmd);
190 if (i == cache.cend()) {
191 cache.emplace_back(cmd);
197 inline static std::unique_ptr<keyboard_bindings> _global;
201 std::unordered_map<keyboard_key, commands_t> bindings;
207 _global = std::make_unique<keyboard_bindings>();
212inline void load_user_keyboard_bindings(std::filesystem::path
const& path)
214 return keyboard_bindings::global().
load_bindings(path,
false);
217inline void load_system_keyboard_bindings(std::filesystem::path
const& path)
219 return keyboard_bindings::global().load_bindings(path,
true);
222inline generator<gui_event> translate_keyboard_event(
gui_event event)
noexcept
224 for (
auto &e : keyboard_bindings::global().translate(event)) {
Definition of GUI event types.
gui_event_type
GUI event type.
Definition gui_event_type.hpp:24
geometry/margins.hpp
Definition lookahead_iterator.hpp:5
The HikoGUI API version 1.
Definition lookahead_iterator.hpp:6
constexpr gui_event_type to_gui_event_type(std::string_view name) noexcept
Convert a name to a GUI event type.
Definition gui_event_type.hpp:202
A user interface event.
Definition gui_event.hpp:75
Definition keyboard_bindings.hpp:19
void clear() noexcept
Clear all bindings.
Definition keyboard_bindings.hpp:62
void load_bindings(std::filesystem::path const &path, bool system_binding=false)
Load bindings from a JSON file.
Definition keyboard_bindings.hpp:69
generator< gui_event > translate(gui_event event) const noexcept
translate a key press in the empty-context to a command.
Definition keyboard_bindings.hpp:45
Exception thrown during parsing on an error.
Definition exception_intf.hpp:47
Exception thrown during I/O on an error.
Definition exception_intf.hpp:172