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

# 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     #include <ndk++/application.hh>
14 sf-pippijn 1.6 #include <ndk++/color.hh>
15 sf-pippijn 1.1
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 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     pimpl ( interface::communicator &comm
85     , interface::service_manager &svs
86     , widgets &ui
87     );
88    
89 sf-pippijn 1.3 void perform (ncurses::panel *sender, action cmd, action arg = action::none);
90 sf-pippijn 1.1
91 sf-pippijn 1.3 ndk::event::result on_kbd_common (ndk::keyboard const &ev);
92     ndk::event::result on_kbd_map (ndk::keyboard const &ev);
93 sf-pippijn 1.1
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 sf-pippijn 1.3 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 sf-pippijn 1.1 }
126    
127     void
128 sf-pippijn 1.3 input_handler::pimpl::perform (ncurses::panel *sender, action cmd, action arg)
129 sf-pippijn 1.1 {
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 sf-pippijn 1.3 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 sf-pippijn 1.1 case action::input_mode:
194 sf-pippijn 1.3 ui.input->visualize ();
195     ui.input->focus ();
196 sf-pippijn 1.1 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 sf-pippijn 1.3 input_handler::pimpl::on_kbd_common (ndk::keyboard const &ev)
215 sf-pippijn 1.1 {
216     switch (ev.code ())
217     {
218     case ndk::key::error:
219     throw "ERR";
220    
221 sf-pippijn 1.3 // 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 sf-pippijn 1.1 // moving
250     case 'j':
251     case '2':
252     case ndk::key::down:
253 sf-pippijn 1.3 perform (ev.sender (), action::south);
254 sf-pippijn 1.1 return ndk::event::accepted;
255     case 'k':
256     case '8':
257     case ndk::key::up:
258 sf-pippijn 1.3 perform (ev.sender (), action::north);
259 sf-pippijn 1.1 return ndk::event::accepted;
260     case 'h':
261     case '4':
262     case ndk::key::left:
263 sf-pippijn 1.3 perform (ev.sender (), action::west);
264 sf-pippijn 1.1 return ndk::event::accepted;
265     case 'l':
266     case '6':
267     case ndk::key::right:
268 sf-pippijn 1.3 perform (ev.sender (), action::east);
269 sf-pippijn 1.1 return ndk::event::accepted;
270     case '7':
271     case ndk::key::home:
272 sf-pippijn 1.3 perform (ev.sender (), action::northwest);
273 sf-pippijn 1.1 return ndk::event::accepted;
274     case '9':
275     case ndk::key::pg_up:
276 sf-pippijn 1.3 perform (ev.sender (), action::northeast);
277 sf-pippijn 1.1 return ndk::event::accepted;
278     case '5':
279     case ndk::key::numpad_center:
280 sf-pippijn 1.3 perform (ev.sender (), action::stay_fire);
281 sf-pippijn 1.1 return ndk::event::accepted;
282     case '1':
283     case ndk::key::end:
284 sf-pippijn 1.3 perform (ev.sender (), action::southwest);
285 sf-pippijn 1.1 return ndk::event::accepted;
286     case '3':
287     case ndk::key::pg_dn:
288 sf-pippijn 1.3 perform (ev.sender (), action::southeast);
289 sf-pippijn 1.1 return ndk::event::accepted;
290    
291     case ' ':
292 sf-pippijn 1.3 perform (ev.sender (), action::apply);
293 sf-pippijn 1.1 return ndk::event::accepted;
294     case ',':
295 sf-pippijn 1.3 perform (ev.sender (), action::take);
296 sf-pippijn 1.1 return ndk::event::accepted;
297     case ndk::key::enter:
298     case 'i':
299 sf-pippijn 1.3 perform (ev.sender (), action::input_mode);
300 sf-pippijn 1.1 return ndk::event::accepted;
301     case 'c':
302 sf-pippijn 1.3 ui.input->set_text ("chat ");
303     perform (ev.sender (), action::input_mode);
304 sf-pippijn 1.1 return ndk::event::accepted;
305     case '"':
306 sf-pippijn 1.3 ui.input->set_text ("say ");
307     perform (ev.sender (), action::input_mode);
308 sf-pippijn 1.1 return ndk::event::accepted;
309     case '\'':
310 sf-pippijn 1.3 ui.input->set_text ("tell ");
311     perform (ev.sender (), action::input_mode);
312 sf-pippijn 1.1 return ndk::event::accepted;
313    
314     // firing
315     case 'J':
316     case ndk::key::shift_down:
317 sf-pippijn 1.3 perform (ev.sender (), action::fire, action::south);
318 sf-pippijn 1.1 return ndk::event::accepted;
319     case 'K':
320     case ndk::key::shift_up:
321 sf-pippijn 1.3 perform (ev.sender (), action::fire, action::north);
322 sf-pippijn 1.1 return ndk::event::accepted;
323     case 'H':
324     case ndk::key::shift_left:
325 sf-pippijn 1.3 perform (ev.sender (), action::fire, action::west);
326 sf-pippijn 1.1 return ndk::event::accepted;
327     case 'L':
328     case ndk::key::shift_right:
329 sf-pippijn 1.3 perform (ev.sender (), action::fire, action::east);
330 sf-pippijn 1.1 return ndk::event::accepted;
331     case ndk::key::shift_home:
332 sf-pippijn 1.3 perform (ev.sender (), action::fire, action::northwest);
333 sf-pippijn 1.1 return ndk::event::accepted;
334     case ndk::key::shift_pg_up:
335 sf-pippijn 1.3 perform (ev.sender (), action::fire, action::northeast);
336 sf-pippijn 1.1 return ndk::event::accepted;
337     case ndk::key::shift_end:
338 sf-pippijn 1.3 perform (ev.sender (), action::fire, action::southwest);
339 sf-pippijn 1.1 return ndk::event::accepted;
340     case ndk::key::shift_pg_dn:
341 sf-pippijn 1.3 perform (ev.sender (), action::fire, action::southeast);
342 sf-pippijn 1.1 return ndk::event::accepted;
343    
344     // running
345     //case 'J':
346     case ndk::key::ctrl_down:
347 sf-pippijn 1.3 perform (ev.sender (), action::run, action::south);
348 sf-pippijn 1.1 return ndk::event::accepted;
349     //case 'K':
350     case ndk::key::ctrl_up:
351 sf-pippijn 1.3 perform (ev.sender (), action::run, action::north);
352 sf-pippijn 1.1 return ndk::event::accepted;
353     //case 'H':
354     case ndk::key::ctrl_left:
355 sf-pippijn 1.3 perform (ev.sender (), action::run, action::west);
356 sf-pippijn 1.1 return ndk::event::accepted;
357     //case 'L':
358     case ndk::key::ctrl_right:
359 sf-pippijn 1.3 perform (ev.sender (), action::run, action::east);
360 sf-pippijn 1.1 return ndk::event::accepted;
361     case ndk::key::ctrl_home:
362 sf-pippijn 1.3 perform (ev.sender (), action::run, action::northwest);
363 sf-pippijn 1.1 return ndk::event::accepted;
364     case ndk::key::ctrl_pg_up:
365 sf-pippijn 1.3 perform (ev.sender (), action::run, action::northeast);
366 sf-pippijn 1.1 return ndk::event::accepted;
367     case ndk::key::ctrl_end:
368 sf-pippijn 1.3 perform (ev.sender (), action::run, action::southwest);
369 sf-pippijn 1.1 return ndk::event::accepted;
370     case ndk::key::ctrl_pg_dn:
371 sf-pippijn 1.3 perform (ev.sender (), action::run, action::southeast);
372 sf-pippijn 1.1 return ndk::event::accepted;
373    
374 sf-pippijn 1.5 case ndk::key::ctrl_l:
375 sf-pippijn 1.4 case ndk::key::F10:
376     case ndk::key::resize:
377 sf-pippijn 1.1 case ndk::key::tab:
378     return ndk::event::ignored;
379    
380     case ndk::key::unknown:
381 sf-pippijn 1.3 return ndk::event::ignored;
382 sf-pippijn 1.1
383     default:
384     if (getenv ("DCLIENT_FATAL"))
385     throw ev.code ();
386     else
387     {
388 sf-pippijn 1.6 ui.info->add_text (ndi_color (3, 0), "unknown keycode: 0%03o\n", ev.code ());
389 sf-pippijn 1.3 ui.info->visualize ();
390     return ndk::event::ignored;
391 sf-pippijn 1.1 }
392     }
393     }
394    
395     void
396     input_handler::pimpl::on_command (std::string const &cmd)
397     {
398 sf-pippijn 1.3 if (!cmd.empty ())
399     send ("command", cmd);
400 sf-pippijn 1.1
401     ui.map->focus ();
402 sf-pippijn 1.3 ui.input->set_text ("");
403     ui.input->hide ();
404 sf-pippijn 1.1 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     }