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

# 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 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 case ndk::key::resize:
325 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 }