ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/cf.schmorp.de/dclient/src/frontend/client/input_handler.cpp
Revision: 1.10
Committed: Sun Oct 24 21:48:59 2010 UTC (16 years ago) by sf-pippijn
Branch: MAIN
Changes since 1.9: +1 -1 lines
Log Message:
use unchecked ev default loop retrieval function

File Contents

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