7#include "keyboard_key.hpp"
9#include "../utility/utility.hpp"
10#include "../codec/codec.hpp"
11#include "../macros.hpp"
12#include <unordered_map>
17hi_export_module(hikogui.GUI : keyboard_bindings);
19hi_export
namespace hi {
inline namespace v1 {
27 void add_system_binding(keyboard_key key,
gui_event_type command)
noexcept
29 bindings[key].add_system_command(command);
32 void add_ignored_binding(keyboard_key key,
gui_event_type command)
noexcept
34 bindings[key].add_ignored_command(command);
37 void add_user_binding(keyboard_key key,
gui_event_type command)
noexcept
39 bindings[key].add_user_command(command);
49 if (event == gui_event_type::keyboard_down) {
50 auto const i = bindings.
find(keyboard_key{
event.keyboard_modifiers,
event.key()});
51 if (i != bindings.
cend()) {
52 for (
auto& e : i->second.get_events()) {
71 void load_bindings(std::filesystem::path
const& path,
bool system_binding =
false)
73 auto const data = parse_JSON(path);
76 hi_check(data.contains(
"bindings"),
"Missing key 'bindings' at top level.");
78 auto const binding_list = data[
"bindings"];
80 holds_alternative<datum::vector_type>(binding_list),
"Expecting array value for key 'bindings' at top level.");
82 for (
auto const& binding : binding_list) {
83 hi_check(holds_alternative<datum::map_type>(binding),
"Expecting object for a binding, got {}", binding);
86 binding.contains(
"key") && binding.contains(
"command"),
87 "Expecting required 'key' and 'command' for a binding, got {}",
90 auto const key_name =
static_cast<std::string>(binding[
"key"]);
91 auto const key = keyboard_key(key_name);
93 auto command_name =
static_cast<std::string>(binding[
"command"]);
96 bool ignored_binding =
false;
97 if (command_name.size() >= 1 && command_name[0] ==
'-') {
98 ignored_binding =
true;
99 command_name = command_name.
substr(1);
103 if (command == gui_event_type::none) {
104 throw parse_error(std::format(
"Could not parse command '{}'", command_name));
107 if (ignored_binding) {
108 add_ignored_binding(key, command);
109 }
else if (system_binding) {
110 add_system_binding(key, command);
112 add_user_binding(key, command);
117 throw io_error(std::format(
"{}: Could not load keyboard bindings.\n{}", path.string(), e.
what()));
157 if (i == ignored.
cend()) {
166 if (i == user.
cend()) {
172 void update_cache() noexcept
174 cache.
reserve(ssize(system) + ssize(user));
176 for (
auto const cmd :
system) {
178 if (i == cache.
cend()) {
183 for (
auto const cmd : ignored) {
185 if (i != cache.
cend()) {
190 for (
auto const cmd : user) {
192 if (i == cache.
cend()) {
208inline keyboard_bindings& keyboard_bindings::global() noexcept
210 if (not detail::keyboard_bindings_global) {
211 detail::keyboard_bindings_global = std::make_unique<keyboard_bindings>();
213 return *detail::keyboard_bindings_global;
216inline void load_user_keyboard_bindings(std::filesystem::path
const& path)
218 return keyboard_bindings::global().load_bindings(path,
false);
221inline void load_system_keyboard_bindings(std::filesystem::path
const& path)
223 return keyboard_bindings::global().load_bindings(path,
true);
226inline generator<gui_event> translate_keyboard_event(gui_event event)
noexcept
228 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
The HikoGUI namespace.
Definition array_generic.hpp:20
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:208
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
A user interface event.
Definition gui_event.hpp:82
Definition keyboard_bindings.hpp:21
void clear() noexcept
Clear all bindings.
Definition keyboard_bindings.hpp:64
void load_bindings(std::filesystem::path const &path, bool system_binding=false)
Load bindings from a JSON file.
Definition keyboard_bindings.hpp:71
generator< gui_event > translate(gui_event event) const noexcept
translate a key press in the empty-context to a command.
Definition keyboard_bindings.hpp:47
Exception thrown during parsing on an error.
Definition exception_intf.hpp:48
Exception thrown during I/O on an error.
Definition exception_intf.hpp:173
T emplace_back(T... args)