33 |
33 |
34 static String g_input; |
34 static String g_input; |
35 static int g_cursor = 0; |
35 static int g_cursor = 0; |
36 static int g_pan = 0; |
36 static int g_pan = 0; |
37 static bool g_needRefresh = false; |
37 static bool g_needRefresh = false; |
|
38 static bool g_needStatusBarRender = false; |
|
39 static bool g_needInputRender = false; |
|
40 static String g_statusBarText; |
|
41 static struct { char ch; int x; } g_cursorChar; |
|
42 static Vector<String> g_output = {""}; |
|
43 static int g_outputScroll = 0; |
38 |
44 |
39 // ------------------------------------------------------------------------------------------------- |
45 // ------------------------------------------------------------------------------------------------- |
40 // |
46 // |
41 static FUNCTION |
47 static FUNCTION |
42 interface_sessions_width() -> int |
48 interface_sessions_width() -> int |
59 // ------------------------------------------------------------------------------------------------- |
65 // ------------------------------------------------------------------------------------------------- |
60 // |
66 // |
61 static FUNCTION |
67 static FUNCTION |
62 interface_render_log_area() -> void |
68 interface_render_log_area() -> void |
63 { |
69 { |
64 |
70 int height = LINES - 3; |
|
71 int start = max (0, g_output.size() - height - 1); |
|
72 int end = min (g_output.size(), start + height); |
|
73 int y = 1; |
|
74 assert (end - start <= height); |
|
75 |
|
76 for (int i = start; i < end; ++i) |
|
77 { |
|
78 mvhline (y, 0, ' ', COLS); |
|
79 mvprintw (y++, 0, "%s", g_output[i].chars()); |
|
80 } |
65 } |
81 } |
66 |
82 |
67 // ------------------------------------------------------------------------------------------------- |
83 // ------------------------------------------------------------------------------------------------- |
68 // |
84 // |
69 static FUNCTION |
85 static FUNCTION |
99 // AFTER the part that comes afterwards. This is to ensure that the cursor is placed at the |
115 // AFTER the part that comes afterwards. This is to ensure that the cursor is placed at the |
100 // position where our cursor is. It looks nice like that. :) |
116 // position where our cursor is. It looks nice like that. :) |
101 mvprintw (y, 0, "%s", prompt); |
117 mvprintw (y, 0, "%s", prompt); |
102 mvprintw (y, strlen (prompt) + displayTextBegin.length(), "%s", displayTextEnd.chars()); |
118 mvprintw (y, strlen (prompt) + displayTextBegin.length(), "%s", displayTextEnd.chars()); |
103 mvprintw (y, strlen (prompt), "%s", displayTextBegin.chars()); |
119 mvprintw (y, strlen (prompt), "%s", displayTextBegin.chars()); |
|
120 g_cursorChar.ch = g_cursor != 0 ? g_input[g_cursor - 1] : '\0'; |
|
121 g_cursorChar.x = strlen (prompt) + displayTextBegin.length() - 1; |
104 g_needRefresh = true; |
122 g_needRefresh = true; |
|
123 g_needInputRender = false; |
105 } |
124 } |
106 |
125 |
107 // ------------------------------------------------------------------------------------------------- |
126 // ------------------------------------------------------------------------------------------------- |
108 // |
127 // |
109 static FUNCTION |
128 static FUNCTION |
110 interface_render_statusbar() -> void |
129 interface_render_statusbar() -> void |
111 { |
130 { |
112 |
131 int y = LINES - 1; |
|
132 mvhline (y, 0, ' ', COLS); |
|
133 mvprintw (y, 0, "%s", g_statusBarText.chars()); |
|
134 g_needRefresh = true; |
|
135 g_needStatusBarRender = false; |
|
136 } |
|
137 |
|
138 // ------------------------------------------------------------------------------------------------- |
|
139 // |
|
140 static FUNCTION |
|
141 set_statusbar_text (const String& a) -> void |
|
142 { |
|
143 g_statusBarText = a; |
|
144 g_needStatusBarRender = true; |
113 } |
145 } |
114 |
146 |
115 // ------------------------------------------------------------------------------------------------- |
147 // ------------------------------------------------------------------------------------------------- |
116 // |
148 // |
117 static FUNCTION |
149 static FUNCTION |
119 { |
151 { |
120 interface_render_titlebar(); |
152 interface_render_titlebar(); |
121 interface_render_log_area(); |
153 interface_render_log_area(); |
122 interface_render_statusbar(); |
154 interface_render_statusbar(); |
123 interface_render_input(); |
155 interface_render_input(); |
124 g_needRefresh = true; |
156 } |
|
157 |
|
158 // ------------------------------------------------------------------------------------------------- |
|
159 // |
|
160 static FUNCTION |
|
161 interface_position_cursor() -> void |
|
162 { |
|
163 int y = LINES - 2; |
|
164 |
|
165 if (g_cursorChar.ch != '\0') |
|
166 mvprintw (y, g_cursorChar.x, "%c", g_cursorChar.ch); |
|
167 else |
|
168 mvprintw (y, 1, " "); |
125 } |
169 } |
126 |
170 |
127 // ------------------------------------------------------------------------------------------------- |
171 // ------------------------------------------------------------------------------------------------- |
128 // |
172 // |
129 FUNCTION |
173 FUNCTION |
145 // |
189 // |
146 FUNCTION |
190 FUNCTION |
147 Interface::handle_input() -> void |
191 Interface::handle_input() -> void |
148 { |
192 { |
149 int ch = ::getch(); |
193 int ch = ::getch(); |
150 |
194 set_statusbar_text (String::from_number (ch)); |
151 if (ch == KEY_F(1)) |
195 |
152 { |
196 if (ch >= 0x20 and ch <= 0x7E) |
|
197 { |
|
198 g_input.insert (g_cursor++, char (ch)); |
|
199 g_needInputRender = true; |
|
200 } |
|
201 else switch (ch) |
|
202 { |
|
203 case KEY_F(1): |
153 endwin(); |
204 endwin(); |
154 exit (EXIT_SUCCESS); |
205 exit (EXIT_SUCCESS); |
155 } |
206 break; |
156 else if (ch >= 0x20 and ch <= 0x7E) |
207 |
157 { |
208 case KEY_LEFT: |
158 g_input.insert (g_cursor++, char (ch)); |
|
159 interface_render_input(); |
|
160 refresh(); |
|
161 } |
|
162 else if (ch == KEY_LEFT) |
|
163 { |
|
164 if (g_cursor > 0) |
209 if (g_cursor > 0) |
165 { |
210 { |
166 g_cursor--; |
211 g_cursor--; |
167 interface_render_input(); |
212 g_needInputRender = true; |
168 } |
213 } |
169 } |
214 break; |
170 else if (ch == KEY_RIGHT) |
215 |
171 { |
216 case KEY_RIGHT: |
172 if (g_cursor < g_input.length()) |
217 if (g_cursor < g_input.length()) |
173 { |
218 { |
174 g_cursor++; |
219 g_cursor++; |
175 interface_render_input(); |
220 g_needInputRender = true; |
176 } |
221 } |
177 } |
222 break; |
178 else if (ch == KEY_HOME) |
223 |
179 { |
224 case KEY_HOME: |
180 if (g_cursor != 0) |
225 if (g_cursor != 0) |
181 { |
226 { |
182 g_cursor = 0; |
227 g_cursor = 0; |
183 interface_render_input(); |
228 g_needInputRender = true; |
184 } |
229 } |
185 } |
230 break; |
186 else if (ch == KEY_END) |
231 |
187 { |
232 case KEY_END: |
188 if (g_cursor != g_input.length()) |
233 if (g_cursor != g_input.length()) |
189 { |
234 { |
190 g_cursor = g_input.length(); |
235 g_cursor = g_input.length(); |
191 interface_render_input(); |
236 g_needInputRender = true; |
192 } |
237 } |
193 } |
238 break; |
194 else if (ch == KEY_BACKSPACE) |
239 |
195 { |
240 case KEY_BACKSPACE: |
196 if (not g_input.is_empty() and g_cursor > 0) |
241 if (g_cursor > 0) |
197 { |
242 { |
198 g_input.remove_at (--g_cursor); |
243 g_input.remove_at (--g_cursor); |
199 interface_render_input(); |
244 g_needInputRender = true; |
200 } |
245 } |
201 } |
246 break; |
|
247 |
|
248 case KEY_DC: |
|
249 if (g_cursor < g_input.length()) |
|
250 { |
|
251 g_input.remove_at (g_cursor); |
|
252 g_needInputRender = true; |
|
253 } |
|
254 break; |
|
255 } |
|
256 |
|
257 if (g_needStatusBarRender) interface_render_statusbar(); |
|
258 if (g_needInputRender) interface_render_input(); |
202 |
259 |
203 if (g_needRefresh) |
260 if (g_needRefresh) |
204 { |
261 { |
|
262 interface_position_cursor(); |
205 refresh(); |
263 refresh(); |
206 g_needRefresh = false; |
264 g_needRefresh = false; |
207 } |
265 } |
208 } |
266 } |
209 |
267 |
210 FUNCTION print_to_console (const String& a) -> void |
268 FUNCTION print_to_console (const String& a) -> void |
211 { |
269 { |
212 |
270 for (char ch : a) |
213 } |
271 { |
|
272 if (ch == '\n') |
|
273 { |
|
274 g_output << ""; |
|
275 continue; |
|
276 } |
|
277 |
|
278 g_output[g_output.size() - 1] += ch; |
|
279 } |
|
280 |
|
281 interface_render_log_area(); |
|
282 interface_position_cursor(); |
|
283 refresh(); |
|
284 } |