ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/cf.schmorp.de/dclient/src/frontend/client/input_handler.cpp
Revision: 1.11
Committed: Fri Jan 21 22:08:48 2011 UTC (15 years, 9 months ago) by sf-pippijn
Branch: MAIN
Changes since 1.10: +0 -2 lines
Log Message:
not needed, anymore

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