ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/cf.schmorp.de/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

# Content
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 }