comparison ext/guichan-0.8.2/src/widget.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/widget.hpp"
49
50 #include "guichan/actionevent.hpp"
51 #include "guichan/actionlistener.hpp"
52 #include "guichan/basiccontainer.hpp"
53 #include "guichan/deathlistener.hpp"
54 #include "guichan/defaultfont.hpp"
55 #include "guichan/event.hpp"
56 #include "guichan/exception.hpp"
57 #include "guichan/focushandler.hpp"
58 #include "guichan/graphics.hpp"
59 #include "guichan/keyinput.hpp"
60 #include "guichan/keylistener.hpp"
61 #include "guichan/mouseinput.hpp"
62 #include "guichan/mouselistener.hpp"
63 #include "guichan/widgetlistener.hpp"
64
65 namespace gcn
66 {
67 Font* Widget::mGlobalFont = NULL;
68 DefaultFont Widget::mDefaultFont;
69 std::list<Widget*> Widget::mWidgets;
70
71 Widget::Widget()
72 : mForegroundColor(0x000000),
73 mBackgroundColor(0xffffff),
74 mBaseColor(0x808090),
75 mSelectionColor(0xc3d9ff),
76 mFocusHandler(NULL),
77 mInternalFocusHandler(NULL),
78 mParent(NULL),
79 mFrameSize(0),
80 mFocusable(false),
81 mVisible(true),
82 mTabIn(true),
83 mTabOut(true),
84 mEnabled(true),
85 mCurrentFont(NULL)
86 {
87 mWidgets.push_back(this);
88 }
89
90 Widget::~Widget()
91 {
92 DeathListenerIterator iter;
93
94 for (iter = mDeathListeners.begin(); iter != mDeathListeners.end(); ++iter)
95 {
96 Event event(this);
97 (*iter)->death(event);
98 }
99
100 _setFocusHandler(NULL);
101
102 mWidgets.remove(this);
103 }
104
105 void Widget::drawFrame(Graphics* graphics)
106 {
107 Color faceColor = getBaseColor();
108 Color highlightColor, shadowColor;
109 int alpha = getBaseColor().a;
110 int width = getWidth() + getFrameSize() * 2 - 1;
111 int height = getHeight() + getFrameSize() * 2 - 1;
112 highlightColor = faceColor + 0x303030;
113 highlightColor.a = alpha;
114 shadowColor = faceColor - 0x303030;
115 shadowColor.a = alpha;
116
117 unsigned int i;
118 for (i = 0; i < getFrameSize(); ++i)
119 {
120 graphics->setColor(shadowColor);
121 graphics->drawLine(i,i, width - i, i);
122 graphics->drawLine(i,i + 1, i, height - i - 1);
123 graphics->setColor(highlightColor);
124 graphics->drawLine(width - i,i + 1, width - i, height - i);
125 graphics->drawLine(i,height - i, width - i - 1, height - i);
126 }
127 }
128
129 void Widget::_setParent(Widget* parent)
130 {
131 mParent = parent;
132 }
133
134 Widget* Widget::getParent() const
135 {
136 return mParent;
137 }
138
139 void Widget::setWidth(int width)
140 {
141 Rectangle newDimension = mDimension;
142 newDimension.width = width;
143
144 setDimension(newDimension);
145 }
146
147 int Widget::getWidth() const
148 {
149 return mDimension.width;
150 }
151
152 void Widget::setHeight(int height)
153 {
154 Rectangle newDimension = mDimension;
155 newDimension.height = height;
156
157 setDimension(newDimension);
158 }
159
160 int Widget::getHeight() const
161 {
162 return mDimension.height;
163 }
164
165 void Widget::setX(int x)
166 {
167 Rectangle newDimension = mDimension;
168 newDimension.x = x;
169
170 setDimension(newDimension);
171 }
172
173 int Widget::getX() const
174 {
175 return mDimension.x;
176 }
177
178 void Widget::setY(int y)
179 {
180 Rectangle newDimension = mDimension;
181 newDimension.y = y;
182
183 setDimension(newDimension);
184 }
185
186 int Widget::getY() const
187 {
188 return mDimension.y;
189 }
190
191 void Widget::setPosition(int x, int y)
192 {
193 Rectangle newDimension = mDimension;
194 newDimension.x = x;
195 newDimension.y = y;
196
197 setDimension(newDimension);
198 }
199
200 void Widget::setDimension(const Rectangle& dimension)
201 {
202 Rectangle oldDimension = mDimension;
203 mDimension = dimension;
204
205 if (mDimension.width != oldDimension.width
206 || mDimension.height != oldDimension.height)
207 {
208 distributeResizedEvent();
209 }
210
211 if (mDimension.x != oldDimension.x
212 || mDimension.y != oldDimension.y)
213 {
214 distributeMovedEvent();
215 }
216 }
217
218 void Widget::setFrameSize(unsigned int frameSize)
219 {
220 mFrameSize = frameSize;
221 }
222
223 unsigned int Widget::getFrameSize() const
224 {
225 return mFrameSize;
226 }
227
228 const Rectangle& Widget::getDimension() const
229 {
230 return mDimension;
231 }
232
233 const std::string& Widget::getActionEventId() const
234 {
235 return mActionEventId;
236 }
237
238 void Widget::setActionEventId(const std::string& actionEventId)
239 {
240 mActionEventId = actionEventId;
241 }
242
243 bool Widget::isFocused() const
244 {
245 if (!mFocusHandler)
246 {
247 return false;
248 }
249
250 return (mFocusHandler->isFocused(this));
251 }
252
253 void Widget::setFocusable(bool focusable)
254 {
255 if (!focusable && isFocused())
256 {
257 mFocusHandler->focusNone();
258 }
259
260 mFocusable = focusable;
261 }
262
263 bool Widget::isFocusable() const
264 {
265 return mFocusable && isVisible() && isEnabled();
266 }
267
268 void Widget::requestFocus()
269 {
270 if (mFocusHandler == NULL)
271 {
272 throw GCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
273 }
274
275 if (isFocusable())
276 {
277 mFocusHandler->requestFocus(this);
278 }
279 }
280
281 void Widget::requestMoveToTop()
282 {
283 if (mParent)
284 {
285 mParent->moveToTop(this);
286 }
287 }
288
289 void Widget::requestMoveToBottom()
290 {
291 if (mParent)
292 {
293 mParent->moveToBottom(this);
294 }
295 }
296
297 void Widget::setVisible(bool visible)
298 {
299 if (!visible && isFocused())
300 {
301 mFocusHandler->focusNone();
302 }
303
304 if (visible)
305 {
306 distributeShownEvent();
307 }
308 else if(!visible)
309 {
310 distributeHiddenEvent();
311 }
312
313 mVisible = visible;
314 }
315
316 bool Widget::isVisible() const
317 {
318 if (getParent() == NULL)
319 {
320 return mVisible;
321 }
322 else
323 {
324 return mVisible && getParent()->isVisible();
325 }
326 }
327
328 void Widget::setBaseColor(const Color& color)
329 {
330 mBaseColor = color;
331 }
332
333 const Color& Widget::getBaseColor() const
334 {
335 return mBaseColor;
336 }
337
338 void Widget::setForegroundColor(const Color& color)
339 {
340 mForegroundColor = color;
341 }
342
343 const Color& Widget::getForegroundColor() const
344 {
345 return mForegroundColor;
346 }
347
348 void Widget::setBackgroundColor(const Color& color)
349 {
350 mBackgroundColor = color;
351 }
352
353 const Color& Widget::getBackgroundColor() const
354 {
355 return mBackgroundColor;
356 }
357
358 void Widget::setSelectionColor(const Color& color)
359 {
360 mSelectionColor = color;
361 }
362
363 const Color& Widget::getSelectionColor() const
364 {
365 return mSelectionColor;
366 }
367
368 void Widget::_setFocusHandler(FocusHandler* focusHandler)
369 {
370 if (mFocusHandler)
371 {
372 releaseModalFocus();
373 mFocusHandler->remove(this);
374 }
375
376 if (focusHandler)
377 {
378 focusHandler->add(this);
379 }
380
381 mFocusHandler = focusHandler;
382 }
383
384 FocusHandler* Widget::_getFocusHandler()
385 {
386 return mFocusHandler;
387 }
388
389 void Widget::addActionListener(ActionListener* actionListener)
390 {
391 mActionListeners.push_back(actionListener);
392 }
393
394 void Widget::removeActionListener(ActionListener* actionListener)
395 {
396 mActionListeners.remove(actionListener);
397 }
398
399 void Widget::addDeathListener(DeathListener* deathListener)
400 {
401 mDeathListeners.push_back(deathListener);
402 }
403
404 void Widget::removeDeathListener(DeathListener* deathListener)
405 {
406 mDeathListeners.remove(deathListener);
407 }
408
409 void Widget::addKeyListener(KeyListener* keyListener)
410 {
411 mKeyListeners.push_back(keyListener);
412 }
413
414 void Widget::removeKeyListener(KeyListener* keyListener)
415 {
416 mKeyListeners.remove(keyListener);
417 }
418
419 void Widget::addFocusListener(FocusListener* focusListener)
420 {
421 mFocusListeners.push_back(focusListener);
422 }
423
424 void Widget::removeFocusListener(FocusListener* focusListener)
425 {
426 mFocusListeners.remove(focusListener);
427 }
428
429 void Widget::addMouseListener(MouseListener* mouseListener)
430 {
431 mMouseListeners.push_back(mouseListener);
432 }
433
434 void Widget::removeMouseListener(MouseListener* mouseListener)
435 {
436 mMouseListeners.remove(mouseListener);
437 }
438
439 void Widget::addWidgetListener(WidgetListener* widgetListener)
440 {
441 mWidgetListeners.push_back(widgetListener);
442 }
443
444 void Widget::removeWidgetListener(WidgetListener* widgetListener)
445 {
446 mWidgetListeners.remove(widgetListener);
447 }
448
449 void Widget::getAbsolutePosition(int& x, int& y) const
450 {
451 if (getParent() == NULL)
452 {
453 x = mDimension.x;
454 y = mDimension.y;
455 return;
456 }
457
458 int parentX;
459 int parentY;
460
461 getParent()->getAbsolutePosition(parentX, parentY);
462
463 x = parentX + mDimension.x + getParent()->getChildrenArea().x;
464 y = parentY + mDimension.y + getParent()->getChildrenArea().y;
465 }
466
467 Font* Widget::getFont() const
468 {
469 if (mCurrentFont == NULL)
470 {
471 if (mGlobalFont == NULL)
472 {
473 return &mDefaultFont;
474 }
475
476 return mGlobalFont;
477 }
478
479 return mCurrentFont;
480 }
481
482 void Widget::setGlobalFont(Font* font)
483 {
484 mGlobalFont = font;
485
486 std::list<Widget*>::iterator iter;
487 for (iter = mWidgets.begin(); iter != mWidgets.end(); ++iter)
488 {
489 if ((*iter)->mCurrentFont == NULL)
490 {
491 (*iter)->fontChanged();
492 }
493 }
494 }
495
496 void Widget::setFont(Font* font)
497 {
498 mCurrentFont = font;
499 fontChanged();
500 }
501
502 bool Widget::widgetExists(const Widget* widget)
503 {
504 bool result = false;
505
506 std::list<Widget*>::iterator iter;
507 for (iter = mWidgets.begin(); iter != mWidgets.end(); ++iter)
508 {
509 if (*iter == widget)
510 {
511 return true;
512 }
513 }
514
515 return result;
516 }
517
518 bool Widget::isTabInEnabled() const
519 {
520 return mTabIn;
521 }
522
523 void Widget::setTabInEnabled(bool enabled)
524 {
525 mTabIn = enabled;
526 }
527
528 bool Widget::isTabOutEnabled() const
529 {
530 return mTabOut;
531 }
532
533 void Widget::setTabOutEnabled(bool enabled)
534 {
535 mTabOut = enabled;
536 }
537
538 void Widget::setSize(int width, int height)
539 {
540 Rectangle newDimension = mDimension;
541 newDimension.width = width;
542 newDimension.height = height;
543
544 setDimension(newDimension);
545 }
546
547 void Widget::setEnabled(bool enabled)
548 {
549 mEnabled = enabled;
550 }
551
552 bool Widget::isEnabled() const
553 {
554 return mEnabled && isVisible();
555 }
556
557 void Widget::requestModalFocus()
558 {
559 if (mFocusHandler == NULL)
560 {
561 throw GCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
562 }
563
564 mFocusHandler->requestModalFocus(this);
565 }
566
567 void Widget::requestModalMouseInputFocus()
568 {
569 if (mFocusHandler == NULL)
570 {
571 throw GCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
572 }
573
574 mFocusHandler->requestModalMouseInputFocus(this);
575 }
576
577 void Widget::releaseModalFocus()
578 {
579 if (mFocusHandler == NULL)
580 {
581 return;
582 }
583
584 mFocusHandler->releaseModalFocus(this);
585 }
586
587 void Widget::releaseModalMouseInputFocus()
588 {
589 if (mFocusHandler == NULL)
590 {
591 return;
592 }
593
594 mFocusHandler->releaseModalMouseInputFocus(this);
595 }
596
597 bool Widget::isModalFocused() const
598 {
599 if (mFocusHandler == NULL)
600 {
601 throw GCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
602 }
603
604 if (getParent() != NULL)
605 {
606 return (mFocusHandler->getModalFocused() == this)
607 || getParent()->isModalFocused();
608 }
609
610 return mFocusHandler->getModalFocused() == this;
611 }
612
613 bool Widget::isModalMouseInputFocused() const
614 {
615 if (mFocusHandler == NULL)
616 {
617 throw GCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
618 }
619
620 if (getParent() != NULL)
621 {
622 return (mFocusHandler->getModalMouseInputFocused() == this)
623 || getParent()->isModalMouseInputFocused();
624 }
625
626 return mFocusHandler->getModalMouseInputFocused() == this;
627 }
628
629 Widget *Widget::getWidgetAt(int x, int y)
630 {
631 return NULL;
632 }
633
634 const std::list<MouseListener*>& Widget::_getMouseListeners()
635 {
636 return mMouseListeners;
637 }
638
639 const std::list<KeyListener*>& Widget::_getKeyListeners()
640 {
641 return mKeyListeners;
642 }
643
644 const std::list<FocusListener*>& Widget::_getFocusListeners()
645 {
646 return mFocusListeners;
647 }
648
649 Rectangle Widget::getChildrenArea()
650 {
651 return Rectangle(0, 0, 0, 0);
652 }
653
654 FocusHandler* Widget::_getInternalFocusHandler()
655 {
656 return mInternalFocusHandler;
657 }
658
659 void Widget::setInternalFocusHandler(FocusHandler* focusHandler)
660 {
661 mInternalFocusHandler = focusHandler;
662 }
663
664 void Widget::setId(const std::string& id)
665 {
666 mId = id;
667 }
668
669 const std::string& Widget::getId()
670 {
671 return mId;
672 }
673
674 void Widget::distributeResizedEvent()
675 {
676 WidgetListenerIterator iter;
677
678 for (iter = mWidgetListeners.begin(); iter != mWidgetListeners.end(); ++iter)
679 {
680 Event event(this);
681 (*iter)->widgetResized(event);
682 }
683 }
684
685 void Widget::distributeMovedEvent()
686 {
687 WidgetListenerIterator iter;
688
689 for (iter = mWidgetListeners.begin(); iter != mWidgetListeners.end(); ++iter)
690 {
691 Event event(this);
692 (*iter)->widgetMoved(event);
693 }
694 }
695
696 void Widget::distributeHiddenEvent()
697 {
698 WidgetListenerIterator iter;
699
700 for (iter = mWidgetListeners.begin(); iter != mWidgetListeners.end(); ++iter)
701 {
702 Event event(this);
703 (*iter)->widgetHidden(event);
704 }
705 }
706
707 void Widget::distributeActionEvent()
708 {
709 ActionListenerIterator iter;
710 for (iter = mActionListeners.begin(); iter != mActionListeners.end(); ++iter)
711 {
712 ActionEvent actionEvent(this, mActionEventId);
713 (*iter)->action(actionEvent);
714 }
715 }
716
717 void Widget::distributeShownEvent()
718 {
719 WidgetListenerIterator iter;
720
721 for (iter = mWidgetListeners.begin(); iter != mWidgetListeners.end(); ++iter)
722 {
723 Event event(this);
724 (*iter)->widgetShown(event);
725 }
726 }
727
728 void Widget::showPart(Rectangle rectangle)
729 {
730 if (mParent != NULL)
731 {
732 mParent->showWidgetPart(this, rectangle);
733 }
734 }
735 }