16
16
17
17
namespace rime {
18
18
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
+
19
27
Selector::Selector (const Ticket& ticket) : Processor(ticket) {
20
28
}
21
29
@@ -28,6 +36,25 @@ ProcessResult Selector::ProcessKeyEvent(const KeyEvent& key_event) {
28
36
Segment& current_segment (ctx->composition ().back ());
29
37
if (!current_segment.menu || current_segment.HasTag (" raw" ))
30
38
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
+ }
31
58
int ch = key_event.keycode ();
32
59
if (ch == XK_Prior || ch == XK_KP_Prior) {
33
60
PageUp (ctx);
@@ -38,46 +65,54 @@ ProcessResult Selector::ProcessKeyEvent(const KeyEvent& key_event) {
38
65
return kAccepted ;
39
66
}
40
67
if (ch == XK_Up || ch == XK_KP_Up) {
41
- if (ctx->get_option (" _horizontal" )) {
42
- PageUp (ctx);
43
- } else {
68
+ if (next_candidate == kDirectionDown ) {
44
69
CursorUp (ctx);
70
+ } else if (next_page == kDirectionDown ) {
71
+ PageUp (ctx);
45
72
}
46
73
return kAccepted ;
47
74
}
48
75
if (ch == XK_Down || ch == XK_KP_Down) {
49
- if (ctx->get_option (" _horizontal" )) {
50
- PageDown (ctx);
51
- } else {
76
+ if (next_candidate == kDirectionDown ) {
52
77
CursorDown (ctx);
78
+ } else if (next_page == kDirectionDown ) {
79
+ PageDown (ctx);
53
80
}
54
81
return kAccepted ;
55
82
}
56
83
if (ch == XK_Left || ch == XK_KP_Left) {
57
84
if (!key_event.ctrl () &&
58
85
!key_event.shift () &&
59
86
ctx->caret_pos () == ctx->input ().length ()) {
60
- if (ctx-> get_option ( " _horizontal " ) &&
87
+ if (next_candidate == kDirectionRight &&
61
88
CursorUp (ctx)) {
62
89
return kAccepted ;
63
90
}
64
- if (ctx-> get_option ( " _vertical " ) ) {
91
+ if (next_candidate == kDirectionLeft ) {
65
92
CursorDown (ctx);
66
93
return kAccepted ;
67
94
}
95
+ if (next_page == kDirectionLeft ) {
96
+ PageDown (ctx);
97
+ return kAccepted ;
98
+ }
68
99
}
69
100
return kNoop ;
70
101
}
71
102
if (ch == XK_Right || ch == XK_KP_Right) {
72
103
if (!key_event.ctrl () &&
73
104
!key_event.shift () &&
74
105
ctx->caret_pos () == ctx->input ().length ()) {
75
- if (ctx-> get_option ( " _horizontal " ) ) {
106
+ if (next_candidate == kDirectionRight ) {
76
107
CursorDown (ctx);
77
108
return kAccepted ;
78
109
}
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);
81
116
return kAccepted ;
82
117
}
83
118
}
0 commit comments