ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/cf.schmorp.de/dclient/src/frontend/client/input_handler.cpp
Revision: 1.6
Committed: Mon Oct 18 16:38:03 2010 UTC (16 years ago) by sf-pippijn
Branch: MAIN
Changes since 1.5: +3 -1 lines
Log Message:
support msg colours

File Contents

# Content
1 #include "deliantra/sender.h"
2
3 #include "dclient/input_handler.h"
4 #include "dclient/render_glyph.h"
5 #include "dclient/widgets.h"
6 #include "dclient/widgets/inventory.h"
7 #include "dclient/widgets/map.h"
8 #include "dclient/widgets/query.h"
9 #include "dclient/widgets/stats.h"
10
11 #include "adt/bind.h"
12
13 #include <ndk++/application.hh>
14 #include <ndk++/color.hh>
15
16 #include <curses.h>
17
18 #include <map>
19
20 typedef unsigned long flags_t;
21
22 enum class flags
23 : flags_t
24 {
25 none,
26 firing = 1 << 0,
27 running = 1 << 1,
28
29 COUNT
30 };
31
32 static flags &
33 operator += (flags &lhs, flags rhs)
34 {
35 return lhs = flags (flags_t (lhs) | flags_t (rhs));
36 }
37
38 static flags &
39 operator -= (flags &lhs, flags rhs)
40 {
41 return lhs = flags (flags_t (lhs) & ~flags_t (rhs));
42 }
43
44 static bool
45 operator & (flags lhs, flags rhs)
46 {
47 return flags_t (lhs) & flags_t (rhs);
48 }
49
50
51 enum class action
52 {
53 none,
54
55 north,
56 northeast,
57 east,
58 southeast,
59 south,
60 southwest,
61 west,
62 northwest,
63
64 run,
65 fire,
66 stay_fire,
67
68 quit,
69 redraw,
70 resize,
71 maximise,
72 input_mode,
73
74 apply,
75 take,
76
77 COUNT
78 };
79
80
81 struct input_handler::pimpl
82 : sender
83 {
84 pimpl ( interface::communicator &comm
85 , interface::service_manager &svs
86 , widgets &ui
87 );
88
89 void perform (ncurses::panel *sender, action cmd, action arg = action::none);
90
91 ndk::event::result on_kbd_common (ndk::keyboard const &ev);
92 ndk::event::result on_kbd_map (ndk::keyboard const &ev);
93
94 void on_command (std::string const &cmd);
95
96 interface::service_manager &svs;
97
98 widgets &ui;
99 std::string esc;
100 flags state;
101 };
102
103 input_handler::pimpl::pimpl ( interface::communicator &comm
104 , interface::service_manager &svs
105 , widgets &ui
106 )
107 : sender (comm)
108 , svs (svs)
109 , ui (ui)
110 , state (flags::none)
111 {
112 auto kbd_common = ndk::slot (&pimpl::on_kbd_common, this);
113
114 ui.map->events ()->on_keyboard (kbd_common);
115 ui.info->events ()->on_keyboard (kbd_common);
116 ui.stats->events ()->on_keyboard (kbd_common);
117 ui.inventory->events ()->on_keyboard (kbd_common);
118 ui.container->events ()->on_keyboard (kbd_common);
119 ui.invmenu->events ()->on_keyboard (kbd_common);
120 ui.query->events ()->on_keyboard (kbd_common);
121
122 ui.map->events ()->on_keyboard (ndk::slot (&pimpl::on_kbd_map, this));
123
124 ui.input->on_commit () = ndk::slot (&pimpl::on_command, this);
125 }
126
127 void
128 input_handler::pimpl::perform (ncurses::panel *sender, action cmd, action arg)
129 {
130 if (state & flags::running)
131 {
132 send ("command", "run_stop");
133 state -= flags::running;
134 }
135 if (state & flags::firing)
136 {
137 send ("command", "fire_stop");
138 state -= flags::firing;
139 }
140
141 switch (cmd)
142 {
143 case action::none:
144 break;
145
146 // direction commands
147 case action::north: send ("command", "north" ); break;
148 case action::northeast: send ("command", "northeast"); break;
149 case action::east: send ("command", "east" ); break;
150 case action::southeast: send ("command", "southeast"); break;
151 case action::south: send ("command", "south" ); break;
152 case action::southwest: send ("command", "southwest"); break;
153 case action::west: send ("command", "west" ); break;
154 case action::northwest: send ("command", "northwest"); break;
155
156 // running
157 case action::run:
158 send ("command", "run ", int (arg));
159 state += flags::running;
160 break;
161
162 // firing
163 case action::fire:
164 send ("command", "fire ", int (arg));
165 state += flags::firing;
166 break;
167
168 case action::stay_fire:
169 send ("command", "stay fire");
170 break;
171
172 // control commands
173 case action::quit:
174 svs.stop ();
175 break;
176
177 case action::redraw:
178 redrawwin (stdscr);
179 break;
180
181 case action::resize:
182 ui.resize ();
183 break;
184
185 case action::maximise:
186 if (ui.maximised)
187 ui.maximised = nullptr;
188 else
189 ui.maximised = sender;
190 perform (sender, action::resize);
191 break;
192
193 case action::input_mode:
194 ui.input->visualize ();
195 ui.input->focus ();
196 break;
197
198 // action commands
199 case action::apply:
200 send ("command", "apply");
201 break;
202
203 case action::take:
204 send ("command", "take");
205 break;
206
207 // never happens
208 case action::COUNT:
209 abort ();
210 }
211 }
212
213 ndk::event::result
214 input_handler::pimpl::on_kbd_common (ndk::keyboard const &ev)
215 {
216 switch (ev.code ())
217 {
218 case ndk::key::error:
219 throw "ERR";
220
221 // control actions
222 case ndk::key::ctrl_d:
223 case 'q':
224 perform (ev.sender (), action::quit);
225 return ndk::event::accepted;
226
227 case ndk::key::ctrl_l:
228 perform (ev.sender (), action::redraw);
229 return ndk::event::accepted;
230
231 case ndk::key::resize:
232 perform (ev.sender (), action::resize);
233 return ndk::event::accepted;
234
235 case ndk::key::F10:
236 perform (ev.sender (), action::maximise);
237 return ndk::event::accepted;
238
239 default:
240 return ndk::event::ignored;
241 }
242 }
243
244 ndk::event::result
245 input_handler::pimpl::on_kbd_map (ndk::keyboard const &ev)
246 {
247 switch (ev.code ())
248 {
249 // moving
250 case 'j':
251 case '2':
252 case ndk::key::down:
253 perform (ev.sender (), action::south);
254 return ndk::event::accepted;
255 case 'k':
256 case '8':
257 case ndk::key::up:
258 perform (ev.sender (), action::north);
259 return ndk::event::accepted;
260 case 'h':
261 case '4':
262 case ndk::key::left:
263 perform (ev.sender (), action::west);
264 return ndk::event::accepted;
265 case 'l':
266 case '6':
267 case ndk::key::right:
268 perform (ev.sender (), action::east);
269 return ndk::event::accepted;
270 case '7':
271 case ndk::key::home:
272 perform (ev.sender (), action::northwest);
273 return ndk::event::accepted;
274 case '9':
275 case ndk::key::pg_up:
276 perform (ev.sender (), action::northeast);
277 return ndk::event::accepted;
278 case '5':
279 case ndk::key::numpad_center:
280 perform (ev.sender (), action::stay_fire);
281 return ndk::event::accepted;
282 case '1':
283 case ndk::key::end:
284 perform (ev.sender (), action::southwest);
285 return ndk::event::accepted;
286 case '3':
287 case ndk::key::pg_dn:
288 perform (ev.sender (), action::southeast);
289 return ndk::event::accepted;
290
291 case ' ':
292 perform (ev.sender (), action::apply);
293 return ndk::event::accepted;
294 case ',':
295 perform (ev.sender (), action::take);
296 return ndk::event::accepted;
297 case ndk::key::enter:
298 case 'i':
299 perform (ev.sender (), action::input_mode);
300 return ndk::event::accepted;
301 case 'c':
302 ui.input->set_text ("chat ");
303 perform (ev.sender (), action::input_mode);
304 return ndk::event::accepted;
305 case '"':
306 ui.input->set_text ("say ");
307 perform (ev.sender (), action::input_mode);
308 return ndk::event::accepted;
309 case '\'':
310 ui.input->set_text ("tell ");
311 perform (ev.sender (), action::input_mode);
312 return ndk::event::accepted;
313
314 // firing
315 case 'J':
316 case ndk::key::shift_down:
317 perform (ev.sender (), action::fire, action::south);
318 return ndk::event::accepted;
319 case 'K':
320 case ndk::key::shift_up:
321 perform (ev.sender (), action::fire, action::north);
322 return ndk::event::accepted;
323 case 'H':
324 case ndk::key::shift_left:
325 perform (ev.sender (), action::fire, action::west);
326 return ndk::event::accepted;
327 case 'L':
328 case ndk::key::shift_right:
329 perform (ev.sender (), action::fire, action::east);
330 return ndk::event::accepted;
331 case ndk::key::shift_home:
332 perform (ev.sender (), action::fire, action::northwest);
333 return ndk::event::accepted;
334 case ndk::key::shift_pg_up:
335 perform (ev.sender (), action::fire, action::northeast);
336 return ndk::event::accepted;
337 case ndk::key::shift_end:
338 perform (ev.sender (), action::fire, action::southwest);
339 return ndk::event::accepted;
340 case ndk::key::shift_pg_dn:
341 perform (ev.sender (), action::fire, action::southeast);
342 return ndk::event::accepted;
343
344 // running
345 //case 'J':
346 case ndk::key::ctrl_down:
347 perform (ev.sender (), action::run, action::south);
348 return ndk::event::accepted;
349 //case 'K':
350 case ndk::key::ctrl_up:
351 perform (ev.sender (), action::run, action::north);
352 return ndk::event::accepted;
353 //case 'H':
354 case ndk::key::ctrl_left:
355 perform (ev.sender (), action::run, action::west);
356 return ndk::event::accepted;
357 //case 'L':
358 case ndk::key::ctrl_right:
359 perform (ev.sender (), action::run, action::east);
360 return ndk::event::accepted;
361 case ndk::key::ctrl_home:
362 perform (ev.sender (), action::run, action::northwest);
363 return ndk::event::accepted;
364 case ndk::key::ctrl_pg_up:
365 perform (ev.sender (), action::run, action::northeast);
366 return ndk::event::accepted;
367 case ndk::key::ctrl_end:
368 perform (ev.sender (), action::run, action::southwest);
369 return ndk::event::accepted;
370 case ndk::key::ctrl_pg_dn:
371 perform (ev.sender (), action::run, action::southeast);
372 return ndk::event::accepted;
373
374 case ndk::key::ctrl_l:
375 case ndk::key::F10:
376 case ndk::key::resize:
377 case ndk::key::tab:
378 return ndk::event::ignored;
379
380 case ndk::key::unknown:
381 return ndk::event::ignored;
382
383 default:
384 if (getenv ("DCLIENT_FATAL"))
385 throw ev.code ();
386 else
387 {
388 ui.info->add_text (ndi_color (3, 0), "unknown keycode: 0%03o\n", ev.code ());
389 ui.info->visualize ();
390 return ndk::event::ignored;
391 }
392 }
393 }
394
395 void
396 input_handler::pimpl::on_command (std::string const &cmd)
397 {
398 if (!cmd.empty ())
399 send ("command", cmd);
400
401 ui.map->focus ();
402 ui.input->set_text ("");
403 ui.input->hide ();
404 ndk::app ().cursor_off (); // FIXME: should be done automatically
405 }
406
407
408 input_handler::input_handler ( interface::communicator &comm
409 , interface::service_manager &svs
410 , widgets &ui
411 )
412 : impl (new pimpl (comm, svs, ui))
413 {
414 }
415
416 input_handler::~input_handler ()
417 {
418 delete impl;
419 }
420
421 void
422 input_handler::handle_read (boost::system::error_code const &error, size_t length)
423 {
424 ndk::app ().process (getch ());
425 }