Mercurial > fife-parpg
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 } |