comparison ext/guichan-0.8.2/src/focushandler.cpp @ 378:64738befdf3b

bringing in the changes from the build_system_rework branch in preparation for the 0.3.0 release. This commit will require the Jan2010 devkit. Clients will also need to be modified to the new way to import fife.
author vtchill@33b003aa-7bff-0310-803a-e67f0ece8222
date Mon, 11 Jan 2010 23:34:52 +0000
parents
children
comparison
equal deleted inserted replaced
377:fe6fb0e0ed23 378:64738befdf3b
1 /* _______ __ __ __ ______ __ __ _______ __ __
2 * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
3 * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
4 * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
5 * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
6 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
7 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
8 *
9 * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
10 *
11 *
12 * Per Larsson a.k.a finalman
13 * Olof Naessén a.k.a jansem/yakslem
14 *
15 * Visit: http://guichan.sourceforge.net
16 *
17 * License: (BSD)
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in
25 * the documentation and/or other materials provided with the
26 * distribution.
27 * 3. Neither the name of Guichan nor the names of its contributors may
28 * be used to endorse or promote products derived from this software
29 * without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
37 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
38 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
39 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
40 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 */
43
44 /*
45 * For comments regarding functions please see the header file.
46 */
47
48 #include "guichan/focushandler.hpp"
49
50 #include "guichan/focuslistener.hpp"
51 #include "guichan/exception.hpp"
52 #include "guichan/widget.hpp"
53
54 namespace gcn
55 {
56 FocusHandler::FocusHandler()
57 :mFocusedWidget(NULL),
58 mModalFocusedWidget(NULL),
59 mModalMouseInputFocusedWidget(NULL),
60 mDraggedWidget(NULL),
61 mLastWidgetWithMouse(NULL),
62 mLastWidgetWithModalFocus(NULL),
63 mLastWidgetWithModalMouseInputFocus(NULL),
64 mLastWidgetPressed(NULL)
65 {
66
67 }
68
69 void FocusHandler::requestFocus(Widget* widget)
70 {
71 if (widget == NULL
72 || widget == mFocusedWidget)
73 {
74 return;
75 }
76
77 unsigned int i = 0;
78 int toBeFocusedIndex = -1;
79 for (i = 0; i < mWidgets.size(); ++i)
80 {
81 if (mWidgets[i] == widget)
82 {
83 toBeFocusedIndex = i;
84 break;
85 }
86 }
87
88 if (toBeFocusedIndex < 0)
89 {
90 throw GCN_EXCEPTION("Trying to focus a none existing widget.");
91 }
92
93 Widget *oldFocused = mFocusedWidget;
94
95 if (oldFocused != widget)
96 {
97 mFocusedWidget = mWidgets.at(toBeFocusedIndex);
98
99 if (oldFocused != NULL)
100 {
101 Event focusEvent(oldFocused);
102 distributeFocusLostEvent(focusEvent);
103 }
104
105 Event focusEvent(mWidgets.at(toBeFocusedIndex));
106 distributeFocusGainedEvent(focusEvent);
107 }
108 }
109
110 void FocusHandler::requestModalFocus(Widget* widget)
111 {
112 if (mModalFocusedWidget != NULL && mModalFocusedWidget != widget)
113 {
114 throw GCN_EXCEPTION("Another widget already has modal focus.");
115 }
116
117 mModalFocusedWidget = widget;
118
119 if (mFocusedWidget != NULL
120 && !mFocusedWidget->isModalFocused())
121 {
122 focusNone();
123 }
124 }
125
126 void FocusHandler::requestModalMouseInputFocus(Widget* widget)
127 {
128 if (mModalMouseInputFocusedWidget != NULL
129 && mModalMouseInputFocusedWidget != widget)
130 {
131 throw GCN_EXCEPTION("Another widget already has modal input focus.");
132 }
133
134 mModalMouseInputFocusedWidget = widget;
135 }
136
137 void FocusHandler::releaseModalFocus(Widget* widget)
138 {
139 if (mModalFocusedWidget == widget)
140 {
141 mModalFocusedWidget = NULL;
142 }
143 }
144
145 void FocusHandler::releaseModalMouseInputFocus(Widget* widget)
146 {
147 if (mModalMouseInputFocusedWidget == widget)
148 {
149 mModalMouseInputFocusedWidget = NULL;
150 }
151 }
152
153 Widget* FocusHandler::getFocused() const
154 {
155 return mFocusedWidget;
156 }
157
158 Widget* FocusHandler::getModalFocused() const
159 {
160 return mModalFocusedWidget;
161 }
162
163 Widget* FocusHandler::getModalMouseInputFocused() const
164 {
165 return mModalMouseInputFocusedWidget;
166 }
167
168 void FocusHandler::focusNext()
169 {
170 int i;
171 int focusedWidget = -1;
172 for (i = 0; i < (int)mWidgets.size(); ++i)
173 {
174 if (mWidgets[i] == mFocusedWidget)
175 {
176 focusedWidget = i;
177 }
178 }
179 int focused = focusedWidget;
180
181 // i is a counter that ensures that the following loop
182 // won't get stuck in an infinite loop
183 i = (int)mWidgets.size();
184 do
185 {
186 ++focusedWidget;
187
188 if (i==0)
189 {
190 focusedWidget = -1;
191 break;
192 }
193
194 --i;
195
196 if (focusedWidget >= (int)mWidgets.size())
197 {
198 focusedWidget = 0;
199 }
200
201 if (focusedWidget == focused)
202 {
203 return;
204 }
205 }
206 while (!mWidgets.at(focusedWidget)->isFocusable());
207
208 if (focusedWidget >= 0)
209 {
210 mFocusedWidget = mWidgets.at(focusedWidget);
211
212 Event focusEvent(mFocusedWidget);
213 distributeFocusGainedEvent(focusEvent);
214 }
215
216 if (focused >= 0)
217 {
218 Event focusEvent(mWidgets.at(focused));
219 distributeFocusLostEvent(focusEvent);
220 }
221 }
222
223 void FocusHandler::focusPrevious()
224 {
225 if (mWidgets.size() == 0)
226 {
227 mFocusedWidget = NULL;
228 return;
229 }
230
231 int i;
232 int focusedWidget = -1;
233 for (i = 0; i < (int)mWidgets.size(); ++i)
234 {
235 if (mWidgets[i] == mFocusedWidget)
236 {
237 focusedWidget = i;
238 }
239 }
240 int focused = focusedWidget;
241
242 // i is a counter that ensures that the following loop
243 // won't get stuck in an infinite loop
244 i = (int)mWidgets.size();
245 do
246 {
247 --focusedWidget;
248
249 if (i==0)
250 {
251 focusedWidget = -1;
252 break;
253 }
254
255 --i;
256
257 if (focusedWidget <= 0)
258 {
259 focusedWidget = mWidgets.size() - 1;
260 }
261
262 if (focusedWidget == focused)
263 {
264 return;
265 }
266 }
267 while (!mWidgets.at(focusedWidget)->isFocusable());
268
269 if (focusedWidget >= 0)
270 {
271 mFocusedWidget = mWidgets.at(focusedWidget);
272 Event focusEvent(mFocusedWidget);
273 distributeFocusGainedEvent(focusEvent);
274 }
275
276 if (focused >= 0)
277 {
278 Event focusEvent(mWidgets.at(focused));
279 distributeFocusLostEvent(focusEvent);
280 }
281 }
282
283 bool FocusHandler::isFocused(const Widget* widget) const
284 {
285 return mFocusedWidget == widget;
286 }
287
288 void FocusHandler::add(Widget* widget)
289 {
290 mWidgets.push_back(widget);
291 }
292
293 void FocusHandler::remove(Widget* widget)
294 {
295 if (isFocused(widget))
296 {
297 mFocusedWidget = NULL;
298 }
299
300 WidgetIterator iter;
301
302 for (iter = mWidgets.begin(); iter != mWidgets.end(); ++iter)
303 {
304 if ((*iter) == widget)
305 {
306 mWidgets.erase(iter);
307 break;
308 }
309 }
310
311 if (mDraggedWidget == widget)
312 {
313 mDraggedWidget = NULL;
314 return;
315 }
316
317 if (mLastWidgetWithMouse == widget)
318 {
319 mLastWidgetWithMouse = NULL;
320 return;
321 }
322
323 if (mLastWidgetWithModalFocus == widget)
324 {
325 mLastWidgetWithModalFocus = NULL;
326 return;
327 }
328
329 if (mLastWidgetWithModalMouseInputFocus == widget)
330 {
331 mLastWidgetWithModalMouseInputFocus = NULL;
332 return;
333 }
334
335 if (mLastWidgetPressed == widget)
336 {
337 mLastWidgetPressed = NULL;
338 return;
339 }
340 }
341
342 void FocusHandler::focusNone()
343 {
344 if (mFocusedWidget != NULL)
345 {
346 Widget* focused = mFocusedWidget;
347 mFocusedWidget = NULL;
348
349 Event focusEvent(focused);
350 distributeFocusLostEvent(focusEvent);
351 }
352 }
353
354 void FocusHandler::tabNext()
355 {
356 if (mFocusedWidget != NULL)
357 {
358 if (!mFocusedWidget->isTabOutEnabled())
359 {
360 return;
361 }
362 }
363
364 if (mWidgets.size() == 0)
365 {
366 mFocusedWidget = NULL;
367 return;
368 }
369
370 int i;
371 int focusedWidget = -1;
372 for (i = 0; i < (int)mWidgets.size(); ++i)
373 {
374 if (mWidgets[i] == mFocusedWidget)
375 {
376 focusedWidget = i;
377 }
378 }
379 int focused = focusedWidget;
380 bool done = false;
381
382 // i is a counter that ensures that the following loop
383 // won't get stuck in an infinite loop
384 i = (int)mWidgets.size();
385 do
386 {
387 ++focusedWidget;
388
389 if (i==0)
390 {
391 focusedWidget = -1;
392 break;
393 }
394
395 --i;
396
397 if (focusedWidget >= (int)mWidgets.size())
398 {
399 focusedWidget = 0;
400 }
401
402 if (focusedWidget == focused)
403 {
404 return;
405 }
406
407 if (mWidgets.at(focusedWidget)->isFocusable() &&
408 mWidgets.at(focusedWidget)->isTabInEnabled() &&
409 (mModalFocusedWidget == NULL ||
410 mWidgets.at(focusedWidget)->isModalFocused()))
411 {
412 done = true;
413 }
414 }
415 while (!done);
416
417 if (focusedWidget >= 0)
418 {
419 mFocusedWidget = mWidgets.at(focusedWidget);
420 Event focusEvent(mFocusedWidget);
421 distributeFocusGainedEvent(focusEvent);
422 }
423
424 if (focused >= 0)
425 {
426 Event focusEvent(mWidgets.at(focused));
427 distributeFocusLostEvent(focusEvent);
428 }
429 }
430
431 void FocusHandler::tabPrevious()
432 {
433 if (mFocusedWidget != NULL)
434 {
435 if (!mFocusedWidget->isTabOutEnabled())
436 {
437 return;
438 }
439 }
440
441 if (mWidgets.size() == 0)
442 {
443 mFocusedWidget = NULL;
444 return;
445 }
446
447 int i;
448 int focusedWidget = -1;
449 for (i = 0; i < (int)mWidgets.size(); ++i)
450 {
451 if (mWidgets[i] == mFocusedWidget)
452 {
453 focusedWidget = i;
454 }
455 }
456 int focused = focusedWidget;
457 bool done = false;
458
459 // i is a counter that ensures that the following loop
460 // won't get stuck in an infinite loop
461 i = (int)mWidgets.size();
462 do
463 {
464 --focusedWidget;
465
466 if (i==0)
467 {
468 focusedWidget = -1;
469 break;
470 }
471
472 --i;
473
474 if (focusedWidget <= 0)
475 {
476 focusedWidget = mWidgets.size() - 1;
477 }
478
479 if (focusedWidget == focused)
480 {
481 return;
482 }
483
484 if (mWidgets.at(focusedWidget)->isFocusable() &&
485 mWidgets.at(focusedWidget)->isTabInEnabled() &&
486 (mModalFocusedWidget == NULL ||
487 mWidgets.at(focusedWidget)->isModalFocused()))
488 {
489 done = true;
490 }
491 }
492 while (!done);
493
494 if (focusedWidget >= 0)
495 {
496 mFocusedWidget = mWidgets.at(focusedWidget);
497 Event focusEvent(mFocusedWidget);
498 distributeFocusGainedEvent(focusEvent);
499 }
500
501 if (focused >= 0)
502 {
503 Event focusEvent(mWidgets.at(focused));
504 distributeFocusLostEvent(focusEvent);
505 }
506 }
507
508 void FocusHandler::distributeFocusLostEvent(const Event& focusEvent)
509 {
510 Widget* sourceWidget = focusEvent.getSource();
511
512 std::list<FocusListener*> focusListeners = sourceWidget->_getFocusListeners();
513
514 // Send the event to all focus listeners of the widget.
515 for (std::list<FocusListener*>::iterator it = focusListeners.begin();
516 it != focusListeners.end();
517 ++it)
518 {
519 (*it)->focusLost(focusEvent);
520 }
521 }
522
523 void FocusHandler::distributeFocusGainedEvent(const Event& focusEvent)
524 {
525 Widget* sourceWidget = focusEvent.getSource();
526
527 std::list<FocusListener*> focusListeners = sourceWidget->_getFocusListeners();
528
529 // Send the event to all focus listeners of the widget.
530 for (std::list<FocusListener*>::iterator it = focusListeners.begin();
531 it != focusListeners.end();
532 ++it)
533 {
534 (*it)->focusGained(focusEvent);
535 }
536 }
537
538 Widget* FocusHandler::getDraggedWidget()
539 {
540 return mDraggedWidget;
541 }
542
543 void FocusHandler::setDraggedWidget(Widget* draggedWidget)
544 {
545 mDraggedWidget = draggedWidget;
546 }
547
548 Widget* FocusHandler::getLastWidgetWithMouse()
549 {
550 return mLastWidgetWithMouse;
551 }
552
553 void FocusHandler::setLastWidgetWithMouse(Widget* lastWidgetWithMouse)
554 {
555 mLastWidgetWithMouse = lastWidgetWithMouse;
556 }
557
558 Widget* FocusHandler::getLastWidgetWithModalFocus()
559 {
560 return mLastWidgetWithModalFocus;
561 }
562
563 void FocusHandler::setLastWidgetWithModalFocus(Widget* lastWidgetWithModalFocus)
564 {
565 mLastWidgetWithModalFocus = lastWidgetWithModalFocus;
566 }
567
568 Widget* FocusHandler::getLastWidgetWithModalMouseInputFocus()
569 {
570 return mLastWidgetWithModalMouseInputFocus;
571 }
572
573 void FocusHandler::setLastWidgetWithModalMouseInputFocus(Widget* lastWidgetWithModalMouseInputFocus)
574 {
575 mLastWidgetWithModalMouseInputFocus = lastWidgetWithModalMouseInputFocus;
576 }
577
578 Widget* FocusHandler::getLastWidgetPressed()
579 {
580 return mLastWidgetPressed;
581 }
582
583 void FocusHandler::setLastWidgetPressed(Widget* lastWidgetPressed)
584 {
585 mLastWidgetPressed = lastWidgetPressed;
586 }
587 }