ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/dclient/src/frontend/client/input_handler.cpp
Revision: 1.2
Committed: Mon Oct 18 14:11:49 2010 UTC (16 years ago) by sf-pippijn
Branch: MAIN
Changes since 1.1: +1 -9 lines
Log Message:
check and log but do not die when ncurses stuff fails

File Contents

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