librime: key_binding_processor_impl.h Source File

| librime 1.2 Rime Input Method Engine, the core library

key_binding_processor_impl.h
Go to the documentation of this file.
1//
2// Copyright RIME Developers
3// Distributed under the BSD License
4//
5
6namespace rime {
7
8template <class T, int N>
9const typename KeyBindingProcessor<T, N>::ActionDef
10 KeyBindingProcessor<T, N>::kActionNoop = {"noop", nullptr};
11
12template <class T, int N>
13 ProcessResult KeyBindingProcessor<T, N>::ProcessKeyEvent(
14 const KeyEvent& key_event,
15 Context* ctx,
16 int keymap_selector,
17 int fallback_options) {
18 auto& keymap = get_keymap(keymap_selector);
19 // exact match
20 if (Accept(key_event, ctx, keymap)) {
21 return kAccepted;
22 }
23 // try to match the fallback options
24 if (key_event.ctrl() || key_event.alt()) {
25 return kNoop;
26 }
27 if (key_event.shift()) {
28 if ((fallback_options & ShiftAsControl) != 0) {
29 KeyEvent shift_as_control{
30 key_event.keycode(),
31 (key_event.modifier() & ~kShiftMask) | kControlMask};
32 if (Accept(shift_as_control, ctx, keymap)) {
33 return kAccepted;
34 }
35 }
36 if ((fallback_options & IgnoreShift) != 0) {
37 KeyEvent ignore_shift{key_event.keycode(),
38 key_event.modifier() & ~kShiftMask};
39 if (Accept(ignore_shift, ctx, keymap)) {
40 return kAccepted;
41 }
42 }
43 }
44 // not handled
45 return kNoop;
46}
47
48template <class T, int N>
49 typename KeyBindingProcessor<T, N>::Keymap&
50KeyBindingProcessor<T, N>::get_keymap(int keymap_selector) {
51 DCHECK_LT(keymap_selector, N);
52 return keymaps_[keymap_selector];
53}
54
55template <class T, int N>
56 bool KeyBindingProcessor<T, N>::Accept(const KeyEvent& key_event,
57 Context* ctx,
58 Keymap& keymap) {
59 auto binding = keymap.find(key_event);
60 if (binding != keymap.end()) {
61 auto action = binding->second;
62 if (RIME_THIS_CALL_AS(T, action)(ctx)) {
63 DLOG(INFO) << "action key accepted: " << key_event.repr();
64 return true;
65 }
66 }
67 return false;
68}
69
70template <class T, int N>
71 void KeyBindingProcessor<T, N>::Keymap::Bind(KeyEvent key_event,
72 HandlerPtr action) {
73 if (action) {
74 (*this)[key_event] = action;
75 } else {
76 this->erase(key_event);
77 }
78}
79
80template <class T, int N>
81 void KeyBindingProcessor<T, N>::LoadConfig(Config* config,
82 const string& section,
83 int keymap_selector) {
84 auto& keymap = get_keymap(keymap_selector);
85 if (auto bindings = config->GetMap(section + "/bindings")) {
86 for (auto it = bindings->begin(); it != bindings->end(); ++it) {
87 auto value = As<ConfigValue>(it->second);
88 if (!value) {
89 continue;
90 }
91 auto* p = action_definitions_;
92 while (p->action && p->name != value->str()) {
93 ++p;
94 }
95 if (!p->action && p->name != value->str()) {
96 LOG(WARNING) << "[" << section << "] invalid action: " << value->str();
97 continue;
98 }
99 KeyEvent ke;
100 if (!ke.Parse(it->first)) {
101 LOG(WARNING) << "[" << section << "] invalid key: " << it->first;
102 continue;
103 }
104 keymap.Bind(ke, p->action);
105 }
106 }
107}
108
109} // namespace rime
kControlMask
@ kControlMask
Definition key_table.h:17
kShiftMask
@ kShiftMask
Definition key_table.h:15
RIME_THIS_CALL_AS
#define RIME_THIS_CALL_AS(T, f)
Definition common.h:37
DLOG
#define DLOG(severity)
Definition no_logging.h:53
DCHECK_LT
#define DCHECK_LT(val1, val2)
Definition no_logging.h:65
LOG
#define LOG(severity)
Definition no_logging.h:31
rime
Definition algebra.cc:12
rime::As
an< X > As(const an< Y > &ptr)
Definition common.h:67
rime::ProcessResult
ProcessResult
Definition processor.h:18
rime::kNoop
@ kNoop
Definition processor.h:21
rime::kAccepted
@ kAccepted
Definition processor.h:20
rime::Config
Definition config_component.h:21
rime::Config::GetMap
RIME_DLL an< ConfigMap > GetMap(const string &path)
Definition config_component.cc:111
rime::Context
Definition context.h:19
rime::KeyBindingProcessor::Accept
bool Accept(const KeyEvent &key_event, Context *ctx, Keymap &keymap)
Definition key_binding_processor_impl.h:56
rime::KeyBindingProcessor::get_keymap
Keymap & get_keymap(int keymap_selector=0)
Definition key_binding_processor_impl.h:50
rime::KeyBindingProcessor::HandlerPtr
bool(T::*)(Context *ctx) HandlerPtr
Definition key_binding_processor.h:20
rime::KeyBindingProcessor::LoadConfig
void LoadConfig(Config *config, const string &section, int kemap_selector=0)
Definition key_binding_processor_impl.h:81
rime::KeyBindingProcessor::ShiftAsControl
@ ShiftAsControl
Definition key_binding_processor.h:24
rime::KeyBindingProcessor::IgnoreShift
@ IgnoreShift
Definition key_binding_processor.h:25
rime::KeyBindingProcessor::kActionNoop
static const ActionDef kActionNoop
Definition key_binding_processor.h:34
rime::KeyBindingProcessor::ProcessKeyEvent
ProcessResult ProcessKeyEvent(const KeyEvent &key_event, Context *ctx, int keymap_selector=0, int fallback_options=FallbackOptions::None)
Definition key_binding_processor_impl.h:13
rime::KeyBindingProcessor::ActionDef
Definition key_binding_processor.h:29
rime::KeyBindingProcessor::Keymap
Definition key_binding_processor.h:48
rime::KeyBindingProcessor::Keymap::Bind
void Bind(KeyEvent key_event, HandlerPtr action)
Definition key_binding_processor_impl.h:71
rime::KeyEvent
Definition key_event.h:17
rime::KeyEvent::modifier
int modifier() const
Definition key_event.h:26
rime::KeyEvent::ctrl
bool ctrl() const
Definition key_event.h:30
rime::KeyEvent::repr
RIME_DLL string repr() const
Definition key_event.cc:19
rime::KeyEvent::keycode
int keycode() const
Definition key_event.h:24
rime::KeyEvent::alt
bool alt() const
Definition key_event.h:31
rime::KeyEvent::Parse
RIME_DLL bool Parse(const string &repr)
Definition key_event.cc:51
rime::KeyEvent::shift
bool shift() const
Definition key_event.h:29