Skip to content

Commit 122893d

Browse files
committed
refactor(navigator): key bindings
1 parent 7f9b056 commit 122893d

File tree

3 files changed

+96
-55
lines changed

3 files changed

+96
-55
lines changed

src/rime/gear/key_binding_processor.h

+2-3
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@
66
#define RIME_KEY_BINDING_PROCESSOR_H_
77

88
#include <rime/common.h>
9+
#include <rime/config.h>
10+
#include <rime/context.h>
911
#include <rime/key_event.h>
1012
#include <rime/processor.h>
1113

1214
namespace rime {
1315

14-
class Config;
15-
class Context;
16-
1716
template <class T>
1817
class KeyBindingProcessor {
1918
public:

src/rime/gear/navigator.cc

+78-45
Original file line numberDiff line numberDiff line change
@@ -11,63 +11,96 @@
1111
#include <rime/engine.h>
1212
#include <rime/key_event.h>
1313
#include <rime/key_table.h>
14+
#include <rime/schema.h>
1415
#include <rime/gear/navigator.h>
1516
#include <rime/gear/translator_commons.h>
1617

1718
namespace rime {
1819

20+
static Navigator::ActionDef navigation_actions[] = {
21+
{ "rewind", &Navigator::Rewind },
22+
{ "left_by_char", &Navigator::LeftByChar },
23+
{ "right_by_char", &Navigator::RightByChar },
24+
{ "left_by_syllable", &Navigator::LeftBySyllable },
25+
{ "right_by_syllable", &Navigator::RightBySyllable },
26+
{ "home", &Navigator::Home },
27+
{ "end", &Navigator::End },
28+
Navigator::kActionNoop
29+
};
30+
31+
Navigator::Navigator(const Ticket& ticket)
32+
: Processor(ticket), KeyBindingProcessor<Navigator>(navigation_actions) {
33+
// Default key binding.
34+
Bind({XK_Left, 0}, &Navigator::Rewind);
35+
Bind({XK_Left, kControlMask}, &Navigator::LeftBySyllable);
36+
Bind({XK_KP_Left, 0}, &Navigator::LeftByChar);
37+
Bind({XK_Right, 0}, &Navigator::RightByChar);
38+
Bind({XK_Right, kControlMask}, &Navigator::RightBySyllable);
39+
Bind({XK_KP_Right, 0}, &Navigator::RightByChar);
40+
Bind({XK_Home, 0}, &Navigator::Home);
41+
Bind({XK_KP_Home, 0}, &Navigator::Home);
42+
Bind({XK_End, 0}, &Navigator::End);
43+
Bind({XK_KP_End, 0}, &Navigator::End);
44+
45+
Config* config = engine_->schema()->config();
46+
KeyBindingProcessor::LoadConfig(config, "navigator");
47+
}
48+
1949
ProcessResult Navigator::ProcessKeyEvent(const KeyEvent& key_event) {
2050
if (key_event.release())
2151
return kNoop;
2252
Context* ctx = engine_->context();
2353
if (!ctx->IsComposing())
2454
return kNoop;
25-
int ch = key_event.keycode();
26-
if (ch == XK_Left || ch == XK_KP_Left) {
27-
BeginMove(ctx);
28-
if (key_event.ctrl() || key_event.shift()) {
29-
size_t confirmed_pos = ctx->composition().GetConfirmedPosition();
30-
JumpLeft(ctx, confirmed_pos) || End(ctx);
31-
}
32-
else {
33-
// take a jump leftwards when there are multiple spans,
34-
// but not from the middle of a span.
35-
(spans_.Count() > 1 &&
36-
spans_.HasVertex(ctx->caret_pos())
37-
? JumpLeft(ctx) : Left(ctx)) || End(ctx);
38-
}
39-
return kAccepted;
40-
}
41-
if (ch == XK_Right || ch == XK_KP_Right) {
42-
BeginMove(ctx);
43-
if (key_event.ctrl() || key_event.shift()) {
44-
size_t confirmed_pos = ctx->composition().GetConfirmedPosition();
45-
JumpRight(ctx, confirmed_pos) || End(ctx);
46-
}
47-
else {
48-
Right(ctx) || Home(ctx);
49-
}
50-
return kAccepted;
51-
}
52-
if (ch == XK_Home || ch == XK_KP_Home) {
53-
BeginMove(ctx);
54-
Home(ctx);
55-
return kAccepted;
56-
}
57-
if (ch == XK_End || ch == XK_KP_End) {
58-
BeginMove(ctx);
59-
End(ctx);
60-
return kAccepted;
61-
}
62-
// not handled
63-
return kNoop;
55+
return KeyBindingProcessor::ProcessKeyEvent(key_event, ctx);
56+
}
57+
58+
void Navigator::LeftBySyllable(Context* ctx) {
59+
BeginMove(ctx);
60+
size_t confirmed_pos = ctx->composition().GetConfirmedPosition();
61+
JumpLeft(ctx, confirmed_pos) || GoToEnd(ctx);
62+
}
63+
64+
void Navigator::LeftByChar(Context* ctx) {
65+
BeginMove(ctx);
66+
MoveLeft(ctx) || GoToEnd(ctx);
67+
}
68+
69+
void Navigator::Rewind(Context* ctx) {
70+
BeginMove(ctx);
71+
// take a jump leftwards when there are multiple spans,
72+
// but not from the middle of a span.
73+
(
74+
spans_.Count() > 1 && spans_.HasVertex(ctx->caret_pos())
75+
? JumpLeft(ctx) : MoveLeft(ctx)
76+
) || GoToEnd(ctx);
77+
}
78+
79+
void Navigator::RightBySyllable(Context* ctx) {
80+
BeginMove(ctx);
81+
size_t confirmed_pos = ctx->composition().GetConfirmedPosition();
82+
JumpRight(ctx, confirmed_pos) || GoToEnd(ctx);
83+
}
84+
85+
void Navigator::RightByChar(Context* ctx) {
86+
BeginMove(ctx);
87+
MoveRight(ctx) || GoHome(ctx);
88+
}
89+
90+
void Navigator::Home(Context* ctx) {
91+
BeginMove(ctx);
92+
GoHome(ctx);
93+
}
94+
95+
void Navigator::End(Context* ctx) {
96+
BeginMove(ctx);
97+
GoToEnd(ctx);
6498
}
6599

66100
void Navigator::BeginMove(Context* ctx) {
67101
ctx->ConfirmPreviousSelection();
68102
// update spans
69-
size_t caret_pos = ctx->caret_pos();
70-
if (input_ != ctx->input() || caret_pos > spans_.end()) {
103+
if (input_ != ctx->input() || ctx->caret_pos() > spans_.end()) {
71104
input_ = ctx->input();
72105
spans_.Clear();
73106
for (const auto &seg : ctx->composition()) {
@@ -109,7 +142,7 @@ bool Navigator::JumpRight(Context* ctx, size_t start_pos) {
109142
return false;
110143
}
111144

112-
bool Navigator::Left(Context* ctx) {
145+
bool Navigator::MoveLeft(Context* ctx) {
113146
DLOG(INFO) << "navigate left.";
114147
size_t caret_pos = ctx->caret_pos();
115148
if (caret_pos == 0)
@@ -118,7 +151,7 @@ bool Navigator::Left(Context* ctx) {
118151
return true;
119152
}
120153

121-
bool Navigator::Right(Context* ctx) {
154+
bool Navigator::MoveRight(Context* ctx) {
122155
DLOG(INFO) << "navigate right.";
123156
size_t caret_pos = ctx->caret_pos();
124157
if (caret_pos >= ctx->input().length())
@@ -127,7 +160,7 @@ bool Navigator::Right(Context* ctx) {
127160
return true;
128161
}
129162

130-
bool Navigator::Home(Context* ctx) {
163+
bool Navigator::GoHome(Context* ctx) {
131164
DLOG(INFO) << "navigate home.";
132165
size_t caret_pos = ctx->caret_pos();
133166
const Composition& comp = ctx->composition();
@@ -151,7 +184,7 @@ bool Navigator::Home(Context* ctx) {
151184
return false;
152185
}
153186

154-
bool Navigator::End(Context* ctx) {
187+
bool Navigator::GoToEnd(Context* ctx) {
155188
DLOG(INFO) << "navigate end.";
156189
size_t end_pos = ctx->input().length();
157190
if (ctx->caret_pos() != end_pos) {

src/rime/gear/navigator.h

+16-7
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,33 @@
1010
#include <rime/common.h>
1111
#include <rime/component.h>
1212
#include <rime/processor.h>
13+
#include <rime/gear/key_binding_processor.h>
1314
#include <rime/gear/translator_commons.h>
1415

1516
namespace rime {
1617

17-
class Navigator : public Processor {
18+
class Navigator : public Processor, public KeyBindingProcessor<Navigator> {
1819
public:
19-
Navigator(const Ticket& ticket) : Processor(ticket) {}
20+
explicit Navigator(const Ticket& ticket);
2021

21-
virtual ProcessResult ProcessKeyEvent(const KeyEvent& key_event);
22+
ProcessResult ProcessKeyEvent(const KeyEvent& key_event) override;
23+
24+
Handler Rewind;
25+
Handler LeftByChar;
26+
Handler RightByChar;
27+
Handler LeftBySyllable;
28+
Handler RightBySyllable;
29+
Handler Home;
30+
Handler End;
2231

2332
private:
2433
void BeginMove(Context* ctx);
2534
bool JumpLeft(Context* ctx, size_t start_pos = 0);
2635
bool JumpRight(Context* ctx, size_t start_pos = 0);
27-
bool Left(Context* ctx);
28-
bool Right(Context* ctx);
29-
bool Home(Context* ctx);
30-
bool End(Context* ctx);
36+
bool MoveLeft(Context* ctx);
37+
bool MoveRight(Context* ctx);
38+
bool GoHome(Context* ctx);
39+
bool GoToEnd(Context* ctx);
3140

3241
string input_;
3342
Spans spans_;

0 commit comments

Comments
 (0)