comparison ext/guichan-0.8.1/src/widget.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/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 }