ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/deliantra/dclient/src/frontend/client/input_handler.cpp
Revision: 1.1
Committed: Sun Oct 17 08:15:11 2010 UTC (16 years ago) by sf-pippijn
Branch: MAIN
Log Message:
initial import

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