Skip to content

Commit c498f71

Browse files
committed
feat(selector): support 4 combinations of horizontal/vertical text orientation and stacked/linear candidate list layout
1 parent 2ed780b commit c498f71

File tree

1 file changed

+46
-11
lines changed

1 file changed

+46
-11
lines changed

src/rime/gear/selector.cc

+46-11
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@
1616

1717
namespace rime {
1818

19+
// Direction of candidate list.
20+
using Direction = int;
21+
constexpr Direction kDirectionVoid = -1;
22+
constexpr Direction kDirectionDown = 0;
23+
constexpr Direction kDirectionLeft = 1;
24+
constexpr Direction kDirectionUp = 2;
25+
constexpr Direction kDirectionRight = 3;
26+
1927
Selector::Selector(const Ticket& ticket) : Processor(ticket) {
2028
}
2129

@@ -28,6 +36,25 @@ ProcessResult Selector::ProcessKeyEvent(const KeyEvent& key_event) {
2836
Segment& current_segment(ctx->composition().back());
2937
if (!current_segment.menu || current_segment.HasTag("raw"))
3038
return kNoop;
39+
bool is_linear_candidate_list = ctx->get_option("_linear");
40+
bool is_vertical_text = ctx->get_option("_vertical");
41+
// Deprecated. equivalent to {_linear: true, _vertical: false}
42+
bool is_horizontal_layout = ctx->get_option("_horizontal");
43+
Direction next_candidate = kDirectionDown;
44+
Direction next_page = kDirectionDown;
45+
if (is_vertical_text) {
46+
// +90 degrees
47+
next_candidate = (next_candidate + 1) % 4;
48+
next_page = (next_page + 1) % 4;
49+
}
50+
if (is_linear_candidate_list || is_horizontal_layout) {
51+
// -90 degrees
52+
next_candidate = (next_candidate + 3) % 4;
53+
}
54+
if (next_page == next_candidate) {
55+
// this is no-op. just to clarify that arrow keys don't change page.
56+
next_page = kDirectionVoid;
57+
}
3158
int ch = key_event.keycode();
3259
if (ch == XK_Prior || ch == XK_KP_Prior) {
3360
PageUp(ctx);
@@ -38,46 +65,54 @@ ProcessResult Selector::ProcessKeyEvent(const KeyEvent& key_event) {
3865
return kAccepted;
3966
}
4067
if (ch == XK_Up || ch == XK_KP_Up) {
41-
if (ctx->get_option("_horizontal")) {
42-
PageUp(ctx);
43-
} else {
68+
if (next_candidate == kDirectionDown) {
4469
CursorUp(ctx);
70+
} else if (next_page == kDirectionDown) {
71+
PageUp(ctx);
4572
}
4673
return kAccepted;
4774
}
4875
if (ch == XK_Down || ch == XK_KP_Down) {
49-
if (ctx->get_option("_horizontal")) {
50-
PageDown(ctx);
51-
} else {
76+
if (next_candidate == kDirectionDown) {
5277
CursorDown(ctx);
78+
} else if (next_page == kDirectionDown) {
79+
PageDown(ctx);
5380
}
5481
return kAccepted;
5582
}
5683
if (ch == XK_Left || ch == XK_KP_Left) {
5784
if (!key_event.ctrl() &&
5885
!key_event.shift() &&
5986
ctx->caret_pos() == ctx->input().length()) {
60-
if (ctx->get_option("_horizontal") &&
87+
if (next_candidate == kDirectionRight &&
6188
CursorUp(ctx)) {
6289
return kAccepted;
6390
}
64-
if (ctx->get_option("_vertical")) {
91+
if (next_candidate == kDirectionLeft) {
6592
CursorDown(ctx);
6693
return kAccepted;
6794
}
95+
if (next_page == kDirectionLeft) {
96+
PageDown(ctx);
97+
return kAccepted;
98+
}
6899
}
69100
return kNoop;
70101
}
71102
if (ch == XK_Right || ch == XK_KP_Right) {
72103
if (!key_event.ctrl() &&
73104
!key_event.shift() &&
74105
ctx->caret_pos() == ctx->input().length()) {
75-
if (ctx->get_option("_horizontal")) {
106+
if (next_candidate == kDirectionRight) {
76107
CursorDown(ctx);
77108
return kAccepted;
78109
}
79-
if (ctx->get_option("_vertical") &&
80-
CursorUp(ctx)) {
110+
if (next_candidate == kDirectionLeft) {
111+
CursorUp(ctx);
112+
return kAccepted;
113+
}
114+
if (next_page == kDirectionLeft) {
115+
PageUp(ctx);
81116
return kAccepted;
82117
}
83118
}

0 commit comments

Comments
 (0)