comparison ext/guichan-0.8.1/src/focushandler.cpp @ 0:4a0efb7baf70

* Datasets becomes the new trunk and retires after that :-)
author mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222
date Sun, 29 Jun 2008 18:44:17 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4a0efb7baf70
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 }