Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

CEGUIWindow.cpp

Go to the documentation of this file.
00001 /************************************************************************
00002         filename:       CEGUIWindow.cpp
00003         created:        21/2/2004
00004         author:         Paul D Turner
00005         
00006         purpose:        Implements the Window base class
00007 *************************************************************************/
00008 /*************************************************************************
00009     Crazy Eddie's GUI System (http://www.cegui.org.uk)
00010     Copyright (C)2004 - 2005 Paul D Turner (paul@cegui.org.uk)
00011 
00012     This library is free software; you can redistribute it and/or
00013     modify it under the terms of the GNU Lesser General Public
00014     License as published by the Free Software Foundation; either
00015     version 2.1 of the License, or (at your option) any later version.
00016 
00017     This library is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020     Lesser General Public License for more details.
00021 
00022     You should have received a copy of the GNU Lesser General Public
00023     License along with this library; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 *************************************************************************/
00026 #include "CEGUIWindow.h"
00027 #include "CEGUIExceptions.h"
00028 #include "CEGUIWindowManager.h"
00029 #include "CEGUISystem.h"
00030 #include "CEGUIFontManager.h"
00031 #include "CEGUIImagesetManager.h"
00032 #include "CEGUIImageset.h"
00033 #include "CEGUIMouseCursor.h"
00034 #include <algorithm>
00035 #include <cmath>
00036 #include <stdio.h>
00037 
00038 // Start of CEGUI namespace section
00039 namespace CEGUI
00040 {
00041 const String Window::EventNamespace("Window");
00042 
00043 /*************************************************************************
00044         Definitions for Window base class Properties
00045 *************************************************************************/
00046 WindowProperties::AbsoluteHeight        Window::d_absHeightProperty;
00047 WindowProperties::AbsoluteMaxSize       Window::d_absMaxSizeProperty;
00048 WindowProperties::AbsoluteMinSize       Window::d_absMinSizeProperty;
00049 WindowProperties::AbsolutePosition      Window::d_absPositionProperty;
00050 WindowProperties::AbsoluteRect          Window::d_absRectProperty;
00051 WindowProperties::AbsoluteSize          Window::d_absSizeProperty;
00052 WindowProperties::AbsoluteWidth         Window::d_absWidthProperty;
00053 WindowProperties::AbsoluteXPosition     Window::d_absXPosProperty;
00054 WindowProperties::AbsoluteYPosition     Window::d_absYPosProperty;
00055 WindowProperties::Alpha                         Window::d_alphaProperty;
00056 WindowProperties::AlwaysOnTop           Window::d_alwaysOnTopProperty;
00057 WindowProperties::ClippedByParent       Window::d_clippedByParentProperty;
00058 WindowProperties::DestroyedByParent     Window::d_destroyedByParentProperty;
00059 WindowProperties::Disabled                      Window::d_disabledProperty;
00060 WindowProperties::Font                          Window::d_fontProperty;
00061 WindowProperties::Height                        Window::d_heightProperty;
00062 WindowProperties::ID                            Window::d_IDProperty;
00063 WindowProperties::InheritsAlpha         Window::d_inheritsAlphaProperty;
00064 WindowProperties::MetricsMode           Window::d_metricsModeProperty;
00065 WindowProperties::MouseCursorImage      Window::d_mouseCursorProperty;
00066 WindowProperties::Position                      Window::d_positionProperty;
00067 WindowProperties::Rect                          Window::d_rectProperty;
00068 WindowProperties::RelativeHeight        Window::d_relHeightProperty;
00069 WindowProperties::RelativeMaxSize       Window::d_relMaxSizeProperty;
00070 WindowProperties::RelativeMinSize       Window::d_relMinSizeProperty;
00071 WindowProperties::RelativePosition      Window::d_relPositionProperty;
00072 WindowProperties::RelativeRect          Window::d_relRectProperty;
00073 WindowProperties::RelativeSize          Window::d_relSizeProperty;
00074 WindowProperties::RelativeWidth         Window::d_relWidthProperty;
00075 WindowProperties::RelativeXPosition     Window::d_relXPosProperty;
00076 WindowProperties::RelativeYPosition     Window::d_relYPosProperty;
00077 WindowProperties::RestoreOldCapture     Window::d_restoreOldCaptureProperty;
00078 WindowProperties::Size                          Window::d_sizeProperty;
00079 WindowProperties::Text                          Window::d_textProperty;
00080 WindowProperties::Visible                       Window::d_visibleProperty;
00081 WindowProperties::Width                         Window::d_widthProperty;
00082 WindowProperties::XPosition                     Window::d_xPosProperty;
00083 WindowProperties::YPosition                     Window::d_yPosProperty;
00084 WindowProperties::ZOrderChangeEnabled   Window::d_zOrderChangeProperty;
00085 WindowProperties::WantsMultiClickEvents Window::d_wantsMultiClicksProperty;
00086 WindowProperties::MouseButtonDownAutoRepeat Window::d_autoRepeatProperty;
00087 WindowProperties::AutoRepeatDelay   Window::d_autoRepeatDelayProperty;
00088 WindowProperties::AutoRepeatRate    Window::d_autoRepeatRateProperty;
00089 
00090 
00091 /*************************************************************************
00092         static data definitions
00093 *************************************************************************/
00094 Window* Window::d_captureWindow         = NULL;
00095 
00096 
00097 /*************************************************************************
00098         Event name constants
00099 *************************************************************************/
00100 const String Window::EventParentSized( (utf8*)"ParentSized" );
00101 const String Window::EventSized( (utf8*)"Sized" );
00102 const String Window::EventMoved( (utf8*)"Moved" );
00103 const String Window::EventTextChanged( (utf8*)"TextChanged" );
00104 const String Window::EventFontChanged( (utf8*)"FontChanged" );
00105 const String Window::EventAlphaChanged( (utf8*)"AlphaChanged" );
00106 const String Window::EventIDChanged( (utf8*)"IDChanged" );
00107 const String Window::EventActivated( (utf8*)"Activated" );
00108 const String Window::EventDeactivated( (utf8*)"Deactivated" );
00109 const String Window::EventShown( (utf8*)"Shown" );
00110 const String Window::EventHidden( (utf8*)"Hidden" );
00111 const String Window::EventEnabled( (utf8*)"Enabled" );
00112 const String Window::EventDisabled( (utf8*)"Disabled" );
00113 const String Window::EventMetricsModeChanged( (utf8*)"MetricsChanged" );
00114 const String Window::EventClippedByParentChanged( (utf8*)"ClippingChanged" );
00115 const String Window::EventDestroyedByParentChanged( (utf8*)"DestroyedByParentChanged" );
00116 const String Window::EventInheritsAlphaChanged( (utf8*)"InheritAlphaChanged" );
00117 const String Window::EventAlwaysOnTopChanged( (utf8*)"AlwaysOnTopChanged" );
00118 const String Window::EventInputCaptureGained( (utf8*)"CaptureGained" );
00119 const String Window::EventInputCaptureLost( (utf8*)"CaptureLost" );
00120 const String Window::EventRenderingStarted( (utf8*)"StartRender" );
00121 const String Window::EventRenderingEnded( (utf8*)"EndRender" );
00122 const String Window::EventChildAdded( (utf8*)"AddedChild" );
00123 const String Window::EventChildRemoved( (utf8*)"RemovedChild" );
00124 const String Window::EventDestructionStarted( (utf8*)"DestructStart" );
00125 const String Window::EventZOrderChanged( (utf8*)"ZChanged" );
00126 const String Window::EventMouseEnters( (utf8*)"MouseEnter" );
00127 const String Window::EventMouseLeaves( (utf8*)"MouseLeave" );
00128 const String Window::EventMouseMove( (utf8*)"MouseMove" );
00129 const String Window::EventMouseWheel( (utf8*)"MouseWheel" );
00130 const String Window::EventMouseButtonDown( (utf8*)"MouseButtonDown" );
00131 const String Window::EventMouseButtonUp( (utf8*)"MouseButtonUp" );
00132 const String Window::EventMouseClick( (utf8*)"MouseClick" );
00133 const String Window::EventMouseDoubleClick( (utf8*)"MouseDoubleClick" );
00134 const String Window::EventMouseTripleClick( (utf8*)"MouseTripleClick" );
00135 const String Window::EventKeyDown( (utf8*)"KeyDown" );
00136 const String Window::EventKeyUp( (utf8*)"KeyUp" );
00137 const String Window::EventCharacterKey( (utf8*)"CharacterKey" );
00138         
00139         
00140 /*************************************************************************
00141         Constructor
00142 *************************************************************************/
00143 Window::Window(const String& type, const String& name) :
00144         d_type(type),
00145         d_name(name)
00146 {
00147         // basic set-up
00148         d_metricsMode   = Relative;
00149         d_parent                = NULL;
00150         d_font                  = NULL;
00151         d_ID                    = 0;
00152         d_alpha                 = 1.0f;
00153         d_mouseCursor   = (const Image*)DefaultMouseCursor;
00154         d_userData              = NULL;
00155 
00156         // basic settings
00157         d_enabled                       = true;
00158         d_visible                       = true;
00159         d_active                        = false;
00160         d_clippedByParent       = true;
00161         d_destroyedByParent     = true;
00162         d_alwaysOnTop           = false;
00163         d_inheritsAlpha         = true;
00164         d_restoreOldCapture     = false;
00165         d_zOrderingEnabled      = true;
00166     d_wantsMultiClicks  = true;
00167 
00168     // initialise mouse button auto-repeat state
00169     d_repeatButton = NoButton;
00170     d_autoRepeat   = false;
00171     d_repeating    = false;
00172     d_repeatDelay  = 0.3f;
00173     d_repeatRate   = 0.06f;
00174 
00175         // position and size
00176         d_abs_area = Rect(0, 0, 0, 0);
00177         d_rel_area = Rect(0, 0, 0, 0);
00178 
00179         // add events
00180         addStandardEvents();
00181 
00182         // set initial min/max sizes.  These should normally be re-set in derived classes to something appropriate.
00183         setMinimumSize(Size(0.0f, 0.0f));
00184         setMaximumSize(Size(1.0f, 1.0f));
00185 
00186         // add properties
00187         addStandardProperties();
00188 }
00189 
00190 /*************************************************************************
00191         Destructor
00192 *************************************************************************/
00193 Window::~Window(void)
00194 {
00195         releaseInput();
00196 
00197         // signal our imminent destruction
00198         WindowEventArgs args(this);
00199         onDestructionStarted(args);
00200 
00201         // double check we are detached from parent
00202         if (d_parent != NULL)
00203         {
00204                 d_parent->removeChildWindow(this);
00205         }
00206 
00207         cleanupChildren();
00208 }
00209 
00210 
00211 /*************************************************************************
00212         return true if the Window is currently disabled 
00213 *************************************************************************/
00214 bool Window::isDisabled(void) const
00215 {
00216         bool parDisabled = (d_parent == NULL) ? false : d_parent->isDisabled();
00217 
00218         return (!d_enabled) || parDisabled;
00219 }
00220 
00221 
00222 /*************************************************************************
00223         return true if the Window is currently visible.
00224 *************************************************************************/
00225 bool Window::isVisible(void) const
00226 {
00227         bool parVisible = (d_parent == NULL) ? true : d_parent->isVisible();
00228 
00229         return d_visible && parVisible;
00230 }
00231 
00232 
00233 /*************************************************************************
00234         return true if this is the active Window
00235         (the window that receives inputs)       
00236 *************************************************************************/
00237 bool Window::isActive(void) const
00238 {
00239         bool parActive = (d_parent == NULL) ? true : d_parent->isActive();
00240 
00241         return d_active && parActive;
00242 }
00243 
00244 
00245 /*************************************************************************
00246         returns whether a Window with the specified name is currently
00247         attached to this Window as a child.
00248 *************************************************************************/
00249 bool Window::isChild(const String& name) const
00250 {
00251         uint child_count = getChildCount();
00252 
00253         for (uint i = 0; i < child_count; ++i)
00254         {
00255                 if (d_children[i]->getName() == name)
00256                 {
00257                         return true;
00258                 }
00259 
00260         }
00261 
00262         return false;
00263 }
00264 
00265 /*************************************************************************
00266         returns whether at least one window with the given ID code is
00267         attached as a child.
00268 *************************************************************************/
00269 bool Window::isChild(uint ID) const
00270 {
00271         uint child_count = getChildCount();
00272 
00273         for (uint i = 0; i < child_count; ++i)
00274         {
00275                 if (d_children[i]->getID() == ID)
00276                 {
00277                         return true;
00278                 }
00279 
00280         }
00281 
00282         return false;
00283 }
00284 
00285 
00286 /*************************************************************************
00287         return true if the given Window is a child of this window.
00288 *************************************************************************/
00289 bool Window::isChild(const Window* window) const
00290 {
00291         uint child_count = getChildCount();
00292 
00293         for (uint i = 0; i < child_count; ++i)
00294         {
00295                 if (d_children[i] == window)
00296                 {
00297                         return true;
00298                 }
00299 
00300         }
00301 
00302         return false;
00303 }
00304 
00305 
00306 /*************************************************************************
00307         return a pointer to the child window with the specified name.
00308 *************************************************************************/
00309 Window* Window::getChild(const String& name) const
00310 {
00311         uint child_count = getChildCount();
00312 
00313         for (uint i = 0; i < child_count; ++i)
00314         {
00315                 if (d_children[i]->getName() == name)
00316                 {
00317                         return d_children[i];
00318                 }
00319 
00320         }
00321 
00322         throw UnknownObjectException((utf8*)"Window::getChild - The Window object named '" + name +"' is not attached to Window '" + d_name + "'.");
00323 }
00324 
00325 
00326 /*************************************************************************
00327         return a pointer to the first attached child window with the
00328         specified ID.
00329 *************************************************************************/
00330 Window* Window::getChild(uint ID) const
00331 {
00332         uint child_count = getChildCount();
00333 
00334         for (uint i = 0; i < child_count; ++i)
00335         {
00336                 if (d_children[i]->getID() == ID)
00337                 {
00338                         return d_children[i];
00339                 }
00340 
00341         }
00342 
00343         // TODO: Update exception to include ID code
00344         char strbuf[16];
00345         sprintf(strbuf, "%X", ID);
00346         throw UnknownObjectException("Window::getChild - The Window with ID: '" + std::string(strbuf) + "' is not attached to Window '" + d_name + "'.");
00347 }
00348 
00349 
00350 /*************************************************************************
00351         return a pointer to the Window that currently has input focus
00352         starting with this Window.
00353 *************************************************************************/
00354 Window* Window::getActiveChild(void)
00355 {
00356         return const_cast<Window*>(static_cast<const Window*>(this)->getActiveChild());
00357 }
00358 
00359 
00360 /*************************************************************************
00361         return a pointer to the Window that currently has input focus
00362         starting with this Window.
00363 *************************************************************************/
00364 const Window* Window::getActiveChild(void) const
00365 {
00366         // are children can't be active if we are not
00367         if (!isActive())
00368         {
00369                 return NULL;
00370         }
00371 
00372         uint pos = getChildCount();
00373 
00374         while (pos-- > 0)
00375         {
00376                 // don't need full backward scan for activeness as we already know 'this' is active
00377                 if (d_children[pos]->d_active)
00378                 {
00379                         return d_children[pos]->getActiveChild();
00380                 }
00381 
00382         }
00383 
00384         // no child was active, therefore we are the topmost active window
00385         return this;
00386 }
00387 
00388 
00389 /*************************************************************************
00390         return true if the specified Window is some ancestor of this Window
00391 *************************************************************************/
00392 bool Window::isAncestor(const String& name) const
00393 {
00394         // if we have no ancestor then 'name' can't be ancestor
00395         if (d_parent == NULL)
00396         {
00397                 return false;
00398         }
00399 
00400         // check our immediate parent
00401         if (d_parent->getName() == name)
00402         {
00403                 return true;
00404         }
00405 
00406         // not out parent, check back up the family line
00407         return d_parent->isAncestor(name);
00408 }
00409 
00410 
00411 /*************************************************************************
00412         return true if any Window with the given ID is some ancestor of
00413         this Window.    
00414 *************************************************************************/
00415 bool Window::isAncestor(uint ID) const
00416 {
00417         // return false if we have no ancestor
00418         if (d_parent == NULL)
00419         {
00420                 return false;
00421         }
00422 
00423         // check our immediate parent
00424         if (d_parent->getID() == ID)
00425         {
00426                 return true;
00427         }
00428 
00429         // not our parent, check back up the family line
00430         return d_parent->isAncestor(ID);
00431 }
00432 
00433 
00434 /*************************************************************************
00435         return true if the specified Window is some ancestor of this Window.    
00436 *************************************************************************/
00437 bool Window::isAncestor(const Window* window) const
00438 {
00439         // if we have no parent, then return false
00440         if (d_parent == NULL)
00441         {
00442                 return false;
00443         }
00444 
00445         // check our immediate parent
00446         if (d_parent == window)
00447         {
00448                 return true;
00449         }
00450 
00451         // not our parent, check back up the family line
00452         return d_parent->isAncestor(window);
00453 }
00454 
00455 
00456 /*************************************************************************
00457         return the Font object active for the Window.
00458 *************************************************************************/
00459 const Font* Window::getFont(void) const
00460 {
00461         if (d_font == NULL)
00462         {
00463                 return System::getSingleton().getDefaultFont();
00464         }
00465 
00466         return d_font;
00467 }
00468 
00469 
00470 /*************************************************************************
00471         return the effective alpha value that will be used when rendering
00472         this window, taking into account inheritance of parent window(s)
00473         alpha.
00474 *************************************************************************/
00475 float Window::getEffectiveAlpha(void) const
00476 {
00477         if ((d_parent == NULL) || (!inheritsAlpha()))
00478         {
00479                 return d_alpha;
00480         }
00481 
00482         return d_alpha * d_parent->getEffectiveAlpha();
00483 }
00484 
00485 
00486 /*************************************************************************
00487         return a Rect object that describes the Window area.    
00488 *************************************************************************/
00489 Rect Window::getRect(void) const
00490 {
00491         if (getMetricsMode() == Relative)
00492         {
00493                 return d_rel_area;
00494         }
00495         else
00496         {
00497                 return d_abs_area;
00498         }
00499 
00500 }
00501 
00502 
00503 /*************************************************************************
00504         return a Rect object describing the Window area in screen space.
00505 *************************************************************************/
00506 Rect Window::getPixelRect(void) const
00507 {
00508         // clip to parent?
00509         if (isClippedByParent() && (d_parent != NULL))
00510         {
00511                 return getUnclippedPixelRect().getIntersection(d_parent->getInnerRect());
00512         }
00513         // else, clip to screen
00514         else
00515         {
00516                 return getUnclippedPixelRect().getIntersection(System::getSingleton().getRenderer()->getRect());
00517         }
00518 
00519 }
00520 
00521 
00522 /*************************************************************************
00523         return a Rect object describing the clipping area for this window.
00524 *************************************************************************/
00525 Rect Window::getInnerRect(void) const
00526 {
00527         // clip to parent?
00528         if (isClippedByParent() && (d_parent != NULL))
00529         {
00530                 return getUnclippedInnerRect().getIntersection(d_parent->getInnerRect());
00531         }
00532         // else, clip to screen
00533         else
00534         {
00535                 return getUnclippedInnerRect().getIntersection(System::getSingleton().getRenderer()->getRect());
00536         }
00537 
00538 }
00539 
00540 
00541 /*************************************************************************
00542         return a Rect object describing the Window area unclipped, in
00543         screen space.   
00544 *************************************************************************/
00545 Rect Window::getUnclippedPixelRect(void) const
00546 {
00547         if (getMetricsMode() == Relative)
00548         {
00549                 return windowToScreen(Rect(0, 0, 1, 1));
00550         }
00551         else
00552         {
00553                 return windowToScreen(Rect(0, 0, d_abs_area.getWidth(), d_abs_area.getHeight()));
00554         }
00555 }
00556 
00557 
00558 /*************************************************************************
00559         Return a Rect object that describes, unclipped, the inner rectangle
00560         for this window.  The inner rectangle is typically an area that
00561         excludes some frame or other rendering that should not be touched by
00562         subsequent rendering.
00563 *************************************************************************/
00564 Rect Window::getUnclippedInnerRect(void) const
00565 {
00566         return getUnclippedPixelRect();
00567 }
00568 
00569 
00570 /*************************************************************************
00571         check if the given position would hit this window.      
00572 *************************************************************************/
00573 bool Window::isHit(const Point& position) const
00574 {
00575         // cannot be hit if we are disabled.
00576         if (isDisabled())
00577         {
00578                 return false;
00579         }
00580 
00581         Rect clipped_area(getPixelRect());
00582 
00583         if (clipped_area.getWidth() == 0)
00584         {
00585                 return false;
00586         }
00587 
00588         return clipped_area.isPointInRect(position);
00589 }
00590 
00591 /*************************************************************************
00592         return the child Window that is 'hit' by the given position
00593 *************************************************************************/
00594 Window* Window::getChildAtPosition(const Point& position) const
00595 {
00596         ChildList::const_reverse_iterator       child, end;
00597 
00598         end = d_children.rend();
00599 
00600         for (child = d_children.rbegin(); child != end; ++child)
00601         {
00602                 if ((*child)->isVisible())
00603                 {
00604                         // recursively scan children of this child windows...
00605                         Window* wnd = (*child)->getChildAtPosition(position);
00606 
00607                         // return window pointer if we found a 'hit' down the chain somewhere
00608                         if (wnd != NULL)
00609                         {
00610                                 return wnd;
00611                         }
00612                         // none of our childs children were hit, 
00613                         else
00614                         {
00615                                 // see if this child is hit and return it's pointer if it is
00616                                 if ((*child)->isHit(position))
00617                                 {
00618                                         return (*child);
00619                                 }
00620 
00621                         }
00622 
00623                 }
00624 
00625         }
00626 
00627         // nothing hit
00628         return NULL;
00629 }
00630 
00631 
00632 /*************************************************************************
00633         return the current metrics mode employed by the Window
00634 *************************************************************************/
00635 MetricsMode Window::getMetricsMode(void) const
00636 {
00637         if (d_metricsMode == Inherited)
00638         {
00639                 return getInheritedMetricsMode();
00640         }
00641 
00642         return d_metricsMode;
00643 }
00644 
00645 
00646 /*************************************************************************
00647         return the x position of the window.  Interpretation of return value
00648         depends upon the metric type in use by this window.
00649 *************************************************************************/
00650 float Window::getXPosition(void) const
00651 {
00652         if (getMetricsMode() == Relative)
00653         {
00654                 return d_rel_area.d_left;
00655         }
00656 
00657         return d_abs_area.d_left;
00658 }
00659 
00660 
00661 /*************************************************************************
00662         return the y position of the window.  Interpretation of return value
00663         depends upon the metric type in use by this window.
00664 *************************************************************************/
00665 float Window::getYPosition(void) const
00666 {
00667         if (getMetricsMode() == Relative)
00668         {
00669                 return d_rel_area.d_top;
00670         }
00671 
00672         return d_abs_area.d_top;
00673 }
00674 
00675 
00676 /*************************************************************************
00677         return the position of the window.  Interpretation of return value
00678         depends upon the metric type in use by this window.
00679 *************************************************************************/
00680 Point Window::getPosition(void) const
00681 {
00682         if (getMetricsMode() == Relative)
00683         {
00684                 return d_rel_area.getPosition();
00685         }
00686 
00687         return d_abs_area.getPosition();
00688 }
00689 
00690 
00691 /*************************************************************************
00692         return the width of the Window.  Interpretation of return value
00693         depends upon the metric type in use by this window.
00694 *************************************************************************/
00695 float Window::getWidth(void) const
00696 {
00697         if (getMetricsMode() == Relative)
00698         {
00699                 return d_rel_area.getWidth();
00700         }
00701 
00702         return d_abs_area.getWidth();
00703 }
00704 
00705 
00706 /*************************************************************************
00707         return the height of the Window.  Interpretation of return value
00708         depends upon the metric type in use by this window.
00709 *************************************************************************/
00710 float Window::getHeight(void) const
00711 {
00712         if (getMetricsMode() == Relative)
00713         {
00714                 return d_rel_area.getHeight();
00715         }
00716 
00717         return d_abs_area.getHeight();
00718 }
00719 
00720 
00721 /*************************************************************************
00722         return the size of the Window.  Interpretation of return value
00723         depends upon the metric type in use by this window.
00724 *************************************************************************/
00725 Size Window::getSize(void) const
00726 {
00727         if (getMetricsMode() == Relative)
00728         {
00729                 return d_rel_area.getSize();
00730         }
00731 
00732         return d_abs_area.getSize();
00733 }
00734 
00735 
00736 /*************************************************************************
00737         true to have the Window appear on top of all other non always on top
00738         windows, or false to allow the window to be covered by other windows.
00739 *************************************************************************/
00740 void Window::setAlwaysOnTop(bool setting)
00741 {
00742         // only react to an actual change
00743         if (isAlwaysOnTop() != setting)
00744         {
00745                 d_alwaysOnTop = setting;
00746 
00747                 // move us in front of sibling windows with the same 'always-on-top' setting as we have.
00748                 if (d_parent != NULL)
00749                 {
00750                         Window* org_parent = d_parent;
00751 
00752                         org_parent->removeChild_impl(this);
00753                         org_parent->addChild_impl(this);
00754 
00755                         onZChange_impl();
00756                 }
00757 
00758                 WindowEventArgs args(this);
00759                 onAlwaysOnTopChanged(args);
00760         }
00761 
00762 }
00763 
00764 
00765 /*************************************************************************
00766         Set whether this window is enabled or disabled.  A disabled window
00767         normally can not be interacted with, and may have different rendering.
00768 *************************************************************************/
00769 void Window::setEnabled(bool setting)
00770 {
00771         // only react if setting has changed
00772         if (d_enabled != setting)
00773         {
00774                 d_enabled = setting;
00775         WindowEventArgs args(this);
00776                 d_enabled ? onEnabled(args) : onDisabled(args);
00777         }
00778 
00779 }
00780 
00781 
00782 /*************************************************************************
00783         Set whether the Window is visible or hidden.
00784 *************************************************************************/
00785 void Window::setVisible(bool setting)
00786 {
00787         // only react if setting has changed
00788         if (d_visible != setting)
00789         {
00790                 d_visible = setting;
00791         WindowEventArgs args(this);
00792                 d_visible ? onShown(args) : onHidden(args);
00793         }
00794 
00795 }
00796 
00797 
00798 /*************************************************************************
00799         Activate the Window giving it input focus and bringing it to the top
00800         of all non always-on-top Windows.
00801 *************************************************************************/
00802 void Window::activate(void)
00803 {
00804         // force complete release of input capture.
00805         // NB: This is not done via releaseCapture() because that has
00806         // different behaviour depending on the restoreOldCapture setting.
00807         if ((d_captureWindow != NULL) && (d_captureWindow != this))
00808         {
00809                 Window* tmpCapture = d_captureWindow;
00810                 d_captureWindow = NULL;
00811 
00812                 WindowEventArgs args(NULL);
00813                 tmpCapture->onCaptureLost(args);
00814         }
00815 
00816         moveToFront();
00817 }
00818 
00819 
00820 /*************************************************************************
00821         Deactivate the window.  No further inputs will be received by the
00822         window until it is re-activated either programmatically or by the
00823         user interacting with the gui.
00824 *************************************************************************/
00825 void Window::deactivate(void)
00826 {
00827         ActivationEventArgs args(this);
00828         args.otherWindow = NULL;
00829         onDeactivated(args);
00830 }
00831 
00832 
00833 /*************************************************************************
00834         Set whether this Window will be clipped by its parent window(s).
00835 *************************************************************************/
00836 void Window::setClippedByParent(bool setting)
00837 {
00838         // only react if setting has changed
00839         if (d_clippedByParent != setting)
00840         {
00841                 d_clippedByParent = setting;
00842         WindowEventArgs args(this);
00843                 onClippingChanged(args);
00844         }
00845 
00846 }
00847 
00848 
00849 /*************************************************************************
00850         Set the current text string for the Window.
00851 *************************************************************************/
00852 void Window::setText(const String& text)
00853 {
00854         d_text = text;
00855     WindowEventArgs args(this);
00856         onTextChanged(args);
00857 }
00858 
00859 
00860 /*************************************************************************
00861         Set the current width of the Window.  Interpretation of the input
00862         value is dependant upon the current metrics system set for the Window.
00863 *************************************************************************/
00864 void Window::setWidth(float width)
00865 {
00866         setSize(Size(width, getHeight()));
00867 }
00868 
00869 
00870 /*************************************************************************
00871         Set the current height of the Window.  Interpretation of the input
00872         value is dependant upon the current metrics system set for the Window.
00873 *************************************************************************/
00874 void Window::setHeight(float height)
00875 {
00876         setSize(Size(getWidth(), height));
00877 }
00878 
00879 
00880 /*************************************************************************
00881         Set the current size of the Window.  Interpretation of the input value
00882         is dependant upon the current metrics system set for the Window.
00883 *************************************************************************/
00884 void Window::setSize(const Size& size)
00885 {
00886         setSize(getMetricsMode(), size);
00887 }
00888 
00889 
00890 /*************************************************************************
00891         Set the current 'x' position of the Window.  Interpretation of the
00892         input value is dependant upon the current metrics system set for the
00893         Window.
00894 *************************************************************************/
00895 void Window::setXPosition(float x)
00896 {
00897         setPosition(Point(x, getYPosition()));
00898 }
00899 
00900 
00901 /*************************************************************************
00902         Set the current 'y' position of the Window.  Interpretation of the
00903         input value is dependant upon the current metrics system set for the
00904         Window.
00905 *************************************************************************/
00906 void Window::setYPosition(float y)
00907 {
00908         setPosition(Point(getXPosition(), y));
00909 }
00910 
00911 
00912 /*************************************************************************
00913         Set the current position of the Window.  Interpretation of the input
00914         value is dependant upon the current metrics system set for the Window.
00915 *************************************************************************/
00916 void Window::setPosition(const Point& position)
00917 {
00918         setPosition(getMetricsMode(), position);
00919 }
00920 
00921 
00922 /*************************************************************************
00923         Set the current area for the Window, this allows for setting of
00924         position and size at the same time.  Interpretation of the input
00925         value is dependant upon the current metrics system set for the Window.  
00926 *************************************************************************/
00927 void Window::setAreaRect(const Rect& area)
00928 {
00929         setRect(getMetricsMode(), area);
00930 }
00931 
00932 
00933 /*************************************************************************
00934         Set the font used by this Window.
00935 *************************************************************************/
00936 void Window::setFont(const Font* font)
00937 {
00938         d_font = font;
00939     WindowEventArgs args(this);
00940         onFontChanged(args);
00941 }
00942 
00943 
00944 /*************************************************************************
00945         Set the font used by this Window.
00946 *************************************************************************/
00947 void Window::setFont(const String& name)
00948 {
00949         if (name.empty())
00950         {
00951                 setFont(NULL);
00952         }
00953         else
00954         {
00955                 setFont(FontManager::getSingleton().getFont(name));
00956         }
00957         
00958 }
00959 
00960 
00961 /*************************************************************************
00962         Add the named Window as a child of this Window.  If the Window is
00963         already attached to a Window, it is detached before being added to
00964         this Window.    
00965 *************************************************************************/
00966 void Window::addChildWindow(const String& name)
00967 {
00968         addChildWindow(WindowManager::getSingleton().getWindow(name));
00969 }
00970 
00971 
00972 /*************************************************************************
00973         Add the specified Window as a child of this Window.  If the Window
00974         is already attached to a Window, it is detached before being added
00975         to this Window. 
00976 *************************************************************************/
00977 void Window::addChildWindow(Window* window)
00978 {
00979         addChild_impl(window);
00980     WindowEventArgs args(window);
00981         onChildAdded(args);
00982         window->onZChange_impl();
00983 }
00984 
00985 
00986 /*************************************************************************
00987         Remove the named Window from this windows child list.
00988 *************************************************************************/
00989 void Window::removeChildWindow(const String& name)
00990 {
00991         uint child_count = getChildCount();
00992 
00993         for (uint i = 0; i < child_count; ++i)
00994         {
00995                 if (d_children[i]->getName() == name)
00996                 {
00997                         removeChildWindow(d_children[i]);
00998                         return;
00999                 }
01000 
01001         }
01002 
01003 }
01004 
01005 
01006 /*************************************************************************
01007         Remove the specified Window form this windows child list.
01008 *************************************************************************/
01009 void Window::removeChildWindow(Window* window)
01010 {
01011         removeChild_impl(window);
01012     WindowEventArgs args(window);
01013         onChildRemoved(args);
01014         window->onZChange_impl();
01015 }
01016 
01017 
01018 /*************************************************************************
01019         Remove the first child Window with the specified ID.  If there is more
01020         than one attached Window objects with the specified ID, only the fist
01021         one encountered will be removed.        
01022 *************************************************************************/
01023 void Window::removeChildWindow(uint ID)
01024 {
01025         uint child_count = getChildCount();
01026 
01027         for (uint i = 0; i < child_count; ++i)
01028         {
01029                 if (d_children[i]->getID() == ID)
01030                 {
01031                         removeChildWindow(d_children[i]);
01032                         return;
01033                 }
01034 
01035         }
01036 
01037 }
01038 
01039 
01040 /*************************************************************************
01041         Move the Window to the top of the z order.
01042 *************************************************************************/
01043 void Window::moveToFront()
01044 {
01045         // if the window has no parent then we can have no siblings
01046         if (d_parent == NULL)
01047         {
01048                 // perform initial activation if required.
01049                 if (!isActive())
01050                 {
01051             ActivationEventArgs args(this);
01052                         args.otherWindow = NULL;
01053                         onActivated(args);
01054                 }
01055 
01056                 return;
01057         }
01058 
01059         // bring parent window to front of it's siblings...
01060         d_parent->moveToFront();
01061 
01062         // get our sibling window which is currently active (if any)
01063         Window* activeWnd = NULL;
01064 
01065         uint idx = d_parent->getChildCount();
01066 
01067         while (idx-- > 0)
01068         {
01069                 if (d_parent->d_children[idx]->isActive())
01070                 {
01071                         activeWnd = d_parent->d_children[idx];
01072                         break;
01073                 }
01074 
01075         }
01076 
01077         if (d_zOrderingEnabled)
01078         {
01079                 // move us in front of sibling windows with the same 'always-on-top' setting as we have.
01080                 Window* org_parent = d_parent;
01081                 org_parent->removeChild_impl(this);
01082                 org_parent->addChild_impl(this);
01083         }
01084 
01085         // notify ourselves that we have become active
01086         if (activeWnd != this)
01087         {
01088         ActivationEventArgs args(this);
01089                 args.otherWindow = activeWnd;
01090                 onActivated(args);
01091         }
01092 
01093         // notify previously active window that it is no longer active
01094         if ((activeWnd != NULL) && (activeWnd != this))
01095         {
01096         ActivationEventArgs args(activeWnd);
01097                 args.otherWindow = this;
01098                 activeWnd->onDeactivated(args);
01099         }
01100 
01101         // TODO: This could probably be moved above, is anyone relying on ordering of events?
01102         if (d_zOrderingEnabled)
01103         {
01104                 onZChange_impl();
01105         }
01106 
01107 }
01108 
01109 
01110 /*************************************************************************
01111         Move the Window to the bottom of the Z order.
01112 *************************************************************************/
01113 void Window::moveToBack()
01114 {
01115         // if the window is active, de-activate it.
01116         if (isActive())
01117         {
01118         ActivationEventArgs args(this);
01119                 args.otherWindow = NULL;
01120                 onDeactivated(args);
01121         }
01122 
01123         // if the window has no parent then we can have no siblings and have nothing more to do.
01124         if (d_parent == NULL)
01125         {
01126                 return;
01127         }
01128 
01129         if (d_zOrderingEnabled)
01130         {
01131                 // move us behind all sibling windows with the same 'always-on-top' setting as we have.
01132                 Window* org_parent = d_parent;
01133                 d_parent->removeChild_impl(this);
01134 
01135                 ChildList::iterator pos = org_parent->d_children.begin();
01136 
01137                 if (isAlwaysOnTop())
01138                 {
01139                         while ((pos != org_parent->d_children.end()) && (!(*pos)->isAlwaysOnTop()))
01140                         {
01141                                 ++pos;
01142                         }
01143 
01144                 }
01145 
01146                 org_parent->d_children.insert(pos, this);
01147                 setParent(org_parent);
01148 
01149                 onZChange_impl();
01150         }
01151 
01152         d_parent->moveToBack();
01153 }
01154 
01155 
01156 /*************************************************************************
01157         Captures input to this window
01158 *************************************************************************/
01159 bool Window::captureInput(void)
01160 {
01161         // we can only capture if we are the active window
01162         if (!isActive()) {
01163                 return false;
01164         }
01165 
01166         Window* current_capture = d_captureWindow;
01167         d_captureWindow = this;
01168     WindowEventArgs args(this);
01169 
01170         // inform any window which previously had capture that it doesn't anymore!
01171         if ((current_capture != NULL) && (current_capture != this) && (!d_restoreOldCapture)) {
01172                 current_capture->onCaptureLost(args);
01173         }
01174 
01175         if (d_restoreOldCapture) {
01176                 d_oldCapture = current_capture;
01177         }
01178 
01179         onCaptureGained(args);
01180 
01181         return true;
01182 }
01183 
01184 
01185 /*************************************************************************
01186         Releases input capture from this Window.  If this Window does not
01187         have inputs captured, nothing happens.
01188 *************************************************************************/
01189 void Window::releaseInput(void)
01190 {
01191         // if we are not the window that has capture, do nothing
01192         if (!isCapturedByThis()) {
01193                 return;
01194         }
01195 
01196         // restore old captured window if that mode is set
01197         if (d_restoreOldCapture) {
01198                 d_captureWindow = d_oldCapture;
01199 
01200                 // check for case when there was no previously captured window
01201                 if (d_oldCapture != NULL) {
01202                         d_oldCapture = NULL;
01203                         d_captureWindow->moveToFront();
01204                 }
01205 
01206         }
01207         else {
01208                 d_captureWindow = NULL;
01209         }
01210 
01211     WindowEventArgs args(this);
01212         onCaptureLost(args);
01213 }
01214 
01215 
01216 /*************************************************************************
01217         Set whether this window will remember and restore the previous window
01218         that had inputs captured.
01219 *************************************************************************/
01220 void Window::setRestoreCapture(bool setting)
01221 {
01222         d_restoreOldCapture = setting;
01223 
01224         uint child_count = getChildCount();
01225 
01226         for (uint i = 0; i < child_count; ++i)
01227         {
01228                 d_children[i]->setRestoreCapture(setting);
01229         }
01230 
01231 }
01232 
01233 
01234 /*************************************************************************
01235         Set the current alpha value for this window.
01236 *************************************************************************/
01237 void Window::setAlpha(float alpha)
01238 {
01239         d_alpha = alpha;
01240         WindowEventArgs args(this);
01241         onAlphaChanged(args);
01242 }
01243 
01244 
01245 /*************************************************************************
01246         Sets whether this Window will inherit alpha from its parent windows.
01247 *************************************************************************/
01248 void Window::setInheritsAlpha(bool setting)
01249 {
01250         if (d_inheritsAlpha != setting)
01251         {
01252                 // store old effective alpha so we can test if alpha value changes due to new setting.
01253                 float oldAlpha = getEffectiveAlpha();
01254 
01255                 // notify about the setting change.
01256                 d_inheritsAlpha = setting;
01257 
01258                 WindowEventArgs args(this);
01259                 onInheritsAlphaChanged(args);
01260 
01261                 // if effective alpha has changed fire notification about that too
01262                 if (oldAlpha != getEffectiveAlpha())
01263                 {
01264                         args.handled = false;
01265                         onAlphaChanged(args);
01266                 }
01267 
01268         }
01269 
01270 }
01271 
01272 
01273 /*************************************************************************
01274         Signal the System object to redraw (at least) this Window on the next
01275         render cycle.
01276 *************************************************************************/
01277 void Window::requestRedraw(void) const
01278 {
01279         System::getSingleton().signalRedraw();
01280 }
01281 
01282 
01283 /*************************************************************************
01284         Convert the given X co-ordinate from absolute to relative metrics.
01285 *************************************************************************/
01286 float Window::absoluteToRelativeX(float val) const
01287 {
01288         return absoluteToRelativeX_impl(this, val);
01289 }
01290 
01291 
01292 /*************************************************************************
01293         Convert the given Y co-ordinate from absolute to relative metrics.
01294 *************************************************************************/
01295 float Window::absoluteToRelativeY(float val) const
01296 {
01297         return absoluteToRelativeY_impl(this, val);
01298 }
01299 
01300 
01301 /*************************************************************************
01302         Convert the given position from absolute to relative metrics.
01303 *************************************************************************/
01304 Point Window::absoluteToRelative(const Point& pt) const
01305 {
01306         return absoluteToRelative_impl(this, pt);
01307 }
01308 
01309 
01310 /*************************************************************************
01311         Convert the given size from absolute to relative metrics.
01312 *************************************************************************/
01313 Size Window::absoluteToRelative(const Size& sze) const
01314 {
01315         return absoluteToRelative_impl(this, sze);
01316 }
01317 
01318 
01319 /*************************************************************************
01320         Convert the given area from absolute to relative metrics.
01321 *************************************************************************/
01322 Rect Window::absoluteToRelative(const Rect& rect) const
01323 {
01324         return absoluteToRelative_impl(this, rect);
01325 }
01326 
01327 
01328 /*************************************************************************
01329         Convert the given X co-ordinate from relative to absolute metrics.
01330 *************************************************************************/
01331 float Window::relativeToAbsoluteX(float val) const
01332 {
01333         return relativeToAbsoluteX_impl(this, val);
01334 }
01335 
01336 
01337 /*************************************************************************
01338         Convert the given Y co-ordinate from relative to absolute metrics.
01339 *************************************************************************/
01340 float Window::relativeToAbsoluteY(float val) const
01341 {
01342         return relativeToAbsoluteY_impl(this, val);
01343 }
01344 
01345 
01346 /*************************************************************************
01347         Convert the given position from relative to absolute metrics.
01348 *************************************************************************/
01349 Point Window::relativeToAbsolute(const Point& pt) const
01350 {
01351         return relativeToAbsolute_impl(this, pt);
01352 }
01353 
01354 
01355 /*************************************************************************
01356         Convert the given size from relative to absolute metrics.
01357 *************************************************************************/
01358 Size Window::relativeToAbsolute(const Size& sze) const
01359 {
01360         return relativeToAbsolute_impl(this, sze);
01361 }
01362 
01363 
01364 /*************************************************************************
01365         Convert the given area from relative to absolute metrics.
01366 *************************************************************************/
01367 Rect Window::relativeToAbsolute(const Rect& rect) const
01368 {
01369                 return relativeToAbsolute_impl(this, rect);
01370 }
01371 
01372 
01373 /*************************************************************************
01374         Convert a window co-ordinate value, specified in whichever metrics
01375         mode is active, to a screen relative pixel co-ordinate.
01376 *************************************************************************/
01377 float Window::windowToScreenX(float x) const
01378 {
01379         const Window* wnd = this;
01380         float baseX = 0;
01381 
01382         while (wnd != NULL)
01383         {
01384                 baseX += wnd->d_abs_area.d_left;
01385                 wnd = wnd->d_parent;
01386         }
01387 
01388         if (getMetricsMode() == Relative)
01389         {
01390                 return baseX + relativeToAbsoluteX(x);
01391         }
01392         else
01393         {
01394                 return baseX + x;
01395         }
01396 
01397 }
01398 
01399 
01400 /*************************************************************************
01401         Convert a window co-ordinate value, specified in whichever metrics
01402         mode is active, to a screen relative pixel co-ordinate.
01403 *************************************************************************/
01404 float Window::windowToScreenY(float y) const
01405 {
01406         const Window* wnd = this;
01407         float baseY = 0;
01408 
01409         while (wnd != NULL)
01410         {
01411                 baseY += wnd->d_abs_area.d_top;
01412                 wnd = wnd->d_parent;
01413         }
01414 
01415         if (getMetricsMode() == Relative)
01416         {
01417                 return baseY + relativeToAbsoluteY(y);
01418         }
01419         else
01420         {
01421                 return baseY + y;
01422         }
01423 
01424 }
01425 
01426 
01427 /*************************************************************************
01428         Convert a window co-ordinate position, specified in whichever metrics
01429         mode is active, to a screen relative pixel co-ordinate position.
01430 *************************************************************************/
01431 Point Window::windowToScreen(const Point& pt) const
01432 {
01433         const Window* wnd = this;
01434         Point base(0, 0);
01435 
01436         while (wnd != NULL)
01437         {
01438                 base.d_x += wnd->d_abs_area.d_left;
01439                 base.d_y += wnd->d_abs_area.d_top;
01440                 wnd = wnd->d_parent;
01441         }
01442 
01443         if (getMetricsMode() == Relative)
01444         {
01445                 return base + relativeToAbsolute(pt);
01446         }
01447         else
01448         {
01449                 return base + pt;
01450         }
01451 
01452 }
01453 
01454 
01455 /*************************************************************************
01456         Convert a window size value, specified in whichever metrics mode is
01457         active, to a size in pixels.
01458 *************************************************************************/
01459 Size Window::windowToScreen(const Size& sze) const
01460 {
01461         if (getMetricsMode() == Relative)
01462         {
01463                 return Size(sze.d_width * d_abs_area.getWidth(), sze.d_height * d_abs_area.getHeight());
01464         }
01465         else
01466         {
01467                 return sze;
01468         }
01469 
01470 }
01471 
01472 
01473 /*************************************************************************
01474         Convert a window area, specified in whichever metrics mode is
01475         active, to a screen area.
01476 *************************************************************************/
01477 Rect Window::windowToScreen(const Rect& rect) const
01478 {
01479         const Window* wnd = this;
01480         Point base(0, 0);
01481 
01482         while (wnd != NULL)
01483         {
01484                 base.d_x += wnd->d_abs_area.d_left;
01485                 base.d_y += wnd->d_abs_area.d_top;
01486                 wnd = wnd->d_parent;
01487         }
01488 
01489         if (getMetricsMode() == Relative)
01490         {
01491                 return relativeToAbsolute(rect).offset(base);
01492         }
01493         else
01494         {
01495                 Rect tmp(rect);
01496                 return tmp.offset(base);
01497         }
01498 
01499 }
01500 
01501 
01502 /*************************************************************************
01503         Convert a screen relative pixel co-ordinate value to a window
01504         co-ordinate value, specified in whichever metrics mode is active.
01505 *************************************************************************/
01506 float Window::screenToWindowX(float x) const
01507 {
01508         x -= windowToScreenX(0);
01509 
01510         if (getMetricsMode() == Relative)
01511         {
01512                 x /= d_abs_area.getWidth();
01513         }
01514 
01515         return x;
01516 }
01517 
01518 
01519 /*************************************************************************
01520         Convert a screen relative pixel co-ordinate value to a window
01521         co-ordinate value, specified in whichever metrics mode is active.
01522 *************************************************************************/
01523 float Window::screenToWindowY(float y) const
01524 {
01525         y -= windowToScreenY(0);
01526 
01527         if (getMetricsMode() == Relative)
01528         {
01529                 y /= d_abs_area.getHeight();
01530         }
01531 
01532         return y;
01533 }
01534 
01535 
01536 /*************************************************************************
01537         Convert a screen relative pixel position to a window co-ordinate
01538         position, specified in whichever metrics mode is active.
01539 *************************************************************************/
01540 Point Window::screenToWindow(const Point& pt) const
01541 {
01542         Point tmp(pt);
01543 
01544         tmp.d_x -= windowToScreenX(0);
01545         tmp.d_y -= windowToScreenY(0);
01546 
01547         if (getMetricsMode() == Relative)
01548         {
01549                 tmp.d_x /= d_abs_area.getWidth();
01550                 tmp.d_y /= d_abs_area.getHeight();
01551         }
01552 
01553         return tmp;
01554 }
01555 
01556 
01557 /*************************************************************************
01558         Convert a screen size to a window based size
01559 *************************************************************************/
01560 Size Window::screenToWindow(const Size& sze) const
01561 {
01562         Size tmp(sze);
01563 
01564         if (getMetricsMode() == Relative)
01565         {
01566                 tmp.d_width             /= d_abs_area.getWidth();
01567                 tmp.d_height    /= d_abs_area.getHeight();
01568         }
01569 
01570         return tmp;
01571 }
01572 
01573 
01574 /*************************************************************************
01575         Convert a screen area to a window area, specified in whichever
01576         metrics mode is active.
01577 *************************************************************************/
01578 Rect Window::screenToWindow(const Rect& rect) const
01579 {
01580         Rect tmp(rect);
01581 
01582         tmp.d_left              -= windowToScreenX(0);
01583         tmp.d_top               -= windowToScreenY(0);
01584         tmp.d_right             -= windowToScreenX(0);
01585         tmp.d_bottom    -= windowToScreenY(0);
01586 
01587         if (getMetricsMode() == Relative)
01588         {
01589                 tmp.d_left              /= d_abs_area.getWidth();
01590                 tmp.d_top               /= d_abs_area.getHeight();
01591                 tmp.d_right             /= d_abs_area.getWidth();
01592                 tmp.d_bottom    /= d_abs_area.getHeight();
01593         }
01594 
01595         return tmp;
01596 }
01597 
01598 
01599 /*************************************************************************
01600         Causes the Window object to render itself.
01601 *************************************************************************/
01602 void Window::render(void)
01603 {
01604         // don't do anything if window is not visible
01605         if (!isVisible()) {
01606                 return;
01607         }
01608 
01609         // signal rendering started
01610         WindowEventArgs args(this);
01611         onRenderingStarted(args);
01612 
01613         // perform drawing for 'this' Window
01614         Renderer* renderer = System::getSingleton().getRenderer();
01615         drawSelf(renderer->getCurrentZ());
01616         renderer->advanceZValue();
01617 
01618         // render any child windows
01619         uint child_count = getChildCount();
01620 
01621         for (uint i = 0; i < child_count; ++i)
01622         {
01623                 d_children[i]->render();
01624         }
01625 
01626         // signal rendering ended
01627         onRenderingEnded(args);
01628 }
01629 
01630 
01631 /*************************************************************************
01632         Set the parent window for this window object.
01633 *************************************************************************/
01634 void Window::setParent(Window* parent)
01635 {
01636         d_parent = parent;
01637 }
01638 
01639 
01640 /*************************************************************************
01641         Return the pixel Width of the parent element.
01642         This always returns a valid number.
01643 *************************************************************************/
01644 float Window::getParentWidth(void) const
01645 {
01646         if (d_parent == NULL)
01647         {
01648                 return System::getSingleton().getRenderer()->getWidth();
01649         }
01650 
01651         return d_parent->d_abs_area.getWidth();
01652 }
01653 
01654 
01655 /*************************************************************************
01656         Return the pixel Height of the parent element.
01657         This always returns a valid number.
01658 *************************************************************************/
01659 float Window::getParentHeight(void) const
01660 {
01661         if (d_parent == NULL)
01662         {
01663                 return System::getSingleton().getRenderer()->getHeight();
01664         }
01665 
01666         return d_parent->d_abs_area.getHeight();
01667 }
01668 
01669 
01670 /*************************************************************************
01671         Return the pixel size of the parent element.
01672         This always returns a valid object.
01673 *************************************************************************/
01674 Size Window::getParentSize(void) const
01675 {
01676         return getWindowSize_impl(d_parent);
01677 }
01678 
01679 
01680 /*************************************************************************
01681         Add standard Window events
01682 *************************************************************************/
01683 void Window::addStandardEvents(void)
01684 {
01685         // window events
01686         addEvent(EventSized);                                   addEvent(EventMoved);                                   addEvent(EventTextChanged);
01687         addEvent(EventFontChanged);                             addEvent(EventAlphaChanged);                    addEvent(EventIDChanged);
01688         addEvent(EventActivated);                               addEvent(EventDeactivated);                             addEvent(EventShown);
01689         addEvent(EventHidden);                                  addEvent(EventEnabled);                                 addEvent(EventDisabled);
01690         addEvent(EventMetricsModeChanged);              addEvent(EventClippedByParentChanged);  addEvent(EventDestroyedByParentChanged);
01691         addEvent(EventInheritsAlphaChanged);    addEvent(EventAlwaysOnTopChanged);              addEvent(EventInputCaptureGained);
01692         addEvent(EventInputCaptureLost);                addEvent(EventRenderingStarted);                addEvent(EventRenderingEnded);
01693         addEvent(EventChildAdded);                              addEvent(EventChildRemoved);                    addEvent(EventDestructionStarted);
01694         addEvent(EventZOrderChanged);                   addEvent(EventParentSized);
01695 
01696         // general input handling
01697         addEvent(EventMouseEnters);                             addEvent(EventMouseLeaves);                             addEvent(EventMouseMove);
01698         addEvent(EventMouseWheel);                              addEvent(EventMouseButtonDown);                 addEvent(EventMouseButtonUp);
01699         addEvent(EventMouseClick);                              addEvent(EventMouseDoubleClick);                addEvent(EventMouseTripleClick);
01700         addEvent(EventKeyDown);                                 addEvent(EventKeyUp);                                   addEvent(EventCharacterKey);
01701 }
01702 
01703 
01704 /*************************************************************************
01705         Cleanup child windows
01706 *************************************************************************/
01707 void Window::cleanupChildren(void)
01708 {
01709         while(getChildCount() != 0)
01710         {
01711                 Window* wnd = d_children[0];
01712 
01713                 // always remove child
01714                 removeChildWindow(wnd);
01715 
01716                 // destroy child if that is required
01717                 if (wnd->isDestroyedByParent())
01718                 {
01719                         WindowManager::getSingleton().destroyWindow(wnd);
01720                 }
01721 
01722         }
01723 
01724 }
01725 
01726 
01727 /*************************************************************************
01728         Add given window to child list at an appropriate position
01729 *************************************************************************/
01730 void Window::addChild_impl(Window* wnd)
01731 {
01732         // if window is already attached, detach it first (will fire normal events)
01733         if (wnd->getParent() != NULL)
01734         {
01735                 wnd->getParent()->removeChildWindow(wnd);
01736         }
01737 
01738         // calculate position where window should be added
01739         ChildList::reverse_iterator             position = d_children.rbegin();
01740         if (!wnd->isAlwaysOnTop())
01741         {
01742                 position = d_children.rbegin();
01743 
01744                 // find last non-topmost window
01745                 while ((position != d_children.rend()) && ((*position)->isAlwaysOnTop()))
01746                 {
01747                         ++position;
01748                 }
01749 
01750         }
01751 
01752         // add window (just behind 'pos')
01753         d_children.insert(position.base(), wnd);
01754         wnd->setParent(this);
01755 
01756         // Force and update for the area Rects for 'wnd' so they're correct for it's new parent.
01757     WindowEventArgs args(this);
01758         wnd->onParentSized(args);
01759 }
01760 
01761 
01762 /*************************************************************************
01763         Remove given window from child list
01764 *************************************************************************/
01765 void Window::removeChild_impl(Window* wnd)
01766 {
01767         if (!d_children.empty())
01768         {
01769                 ChildList::iterator     position;
01770                 position = std::find(d_children.begin(), d_children.end(), wnd);
01771 
01772                 if (position != d_children.end())
01773                 {
01774                         d_children.erase(position);
01775                         wnd->setParent(NULL);
01776                 }
01777 
01778         }
01779 
01780 }
01781 
01782 
01783 /*************************************************************************
01784         Notify 'this' and all siblings of a ZOrder change event
01785 *************************************************************************/
01786 void Window::onZChange_impl(void)
01787 {
01788         if (d_parent == NULL)
01789         {
01790         WindowEventArgs args(this);
01791                 onZChanged(args);
01792         }
01793         else
01794         {
01795                 uint child_count = d_parent->getChildCount();
01796 
01797                 for (uint i = 0; i < child_count; ++i)
01798                 {
01799             WindowEventArgs args(d_parent->d_children[i]);
01800                         d_parent->d_children[i]->onZChanged(args);
01801                 }
01802 
01803         }
01804 
01805 }
01806 
01807 
01808 /*************************************************************************
01809         
01810 *************************************************************************/
01811 Rect Window::absoluteToRelative_impl(const Window* window, const Rect& rect) const
01812 {
01813         // get size object for whatever we are using as a base for the conversion
01814         Size sz = getWindowSize_impl(window);
01815 
01816         Rect tmp;
01817 
01818         if (sz.d_width)
01819         {
01820                 tmp.d_left      = PixelAligned(rect.d_left) / sz.d_width;
01821                 tmp.d_right = PixelAligned(rect.d_right) / sz.d_width;
01822         }
01823         else
01824         {
01825                 tmp.d_left = tmp.d_right = 0;
01826         }
01827 
01828         if (sz.d_height)
01829         {
01830                 tmp.d_top               = PixelAligned(rect.d_top) / sz.d_height;
01831                 tmp.d_bottom    = PixelAligned(rect.d_bottom) / sz.d_height;
01832         }
01833         else
01834         {
01835                 tmp.d_top = tmp.d_bottom= 0;
01836         }
01837 
01838         return tmp;
01839 }
01840 
01841 
01842 /*************************************************************************
01843 
01844 *************************************************************************/
01845 Size Window::absoluteToRelative_impl(const Window* window, const Size& sz) const
01846 {
01847         // get size object for whatever we are using as a base for the conversion
01848         Size wndsz = getWindowSize_impl(window);
01849 
01850         Size tmp;
01851 
01852         if (wndsz.d_width)
01853         {
01854                 tmp.d_width = PixelAligned(sz.d_width) / wndsz.d_width;
01855         }
01856         else
01857         {
01858                 tmp.d_width = 0;
01859         }
01860 
01861         if (wndsz.d_height)
01862         {
01863                 tmp.d_height = PixelAligned(sz.d_height) / wndsz.d_height;
01864         }
01865         else
01866         {
01867                 tmp.d_height = 0;
01868         }
01869 
01870         return tmp;
01871 }
01872 
01873 
01874 /*************************************************************************
01875 
01876 *************************************************************************/
01877 Point Window::absoluteToRelative_impl(const Window* window, const Point& pt) const
01878 {
01879         // get size object for whatever we are using as a base for the conversion
01880         Size sz = getWindowSize_impl(window);
01881 
01882         Point tmp;
01883 
01884         if (sz.d_width)
01885         {
01886                 tmp.d_x = PixelAligned(pt.d_x) / sz.d_width;
01887         }
01888         else
01889         {
01890                 tmp.d_x = 0;
01891         }
01892 
01893         if (sz.d_height)
01894         {
01895                 tmp.d_y = PixelAligned(pt.d_y) / sz.d_height;
01896         }
01897         else
01898         {
01899                 tmp.d_y = 0;
01900         }
01901 
01902         return tmp;
01903 }
01904 
01905 
01906 /*************************************************************************
01907 
01908 *************************************************************************/
01909 float Window::absoluteToRelativeX_impl(const Window* window, float x) const
01910 {
01911         // get size object for whatever we are using as a base for the conversion
01912         Size sz = getWindowSize_impl(window);
01913 
01914         if (sz.d_width)
01915         {
01916                 return PixelAligned(x) / sz.d_width;
01917         }
01918         else
01919         {
01920                 return 0;
01921         }
01922 }
01923 
01924 
01925 /*************************************************************************
01926 
01927 *************************************************************************/
01928 float Window::absoluteToRelativeY_impl(const Window* window, float y) const
01929 {
01930         // get size object for whatever we are using as a base for the conversion
01931         Size sz = getWindowSize_impl(window);
01932 
01933         if (sz.d_height)
01934         {
01935                 return PixelAligned(y) / sz.d_height;
01936         }
01937         else
01938         {
01939                 return 0;
01940         }
01941 }
01942 
01943 
01944 /*************************************************************************
01945 
01946 *************************************************************************/
01947 Rect Window::relativeToAbsolute_impl(const Window* window, const Rect& rect) const
01948 {
01949         // get size object for whatever we are using as a base for the conversion
01950         Size sz = getWindowSize_impl(window);
01951 
01952         return Rect(
01953                 PixelAligned(rect.d_left * sz.d_width),
01954                 PixelAligned(rect.d_top * sz.d_height),
01955                 PixelAligned(rect.d_right * sz.d_width),
01956                 PixelAligned(rect.d_bottom * sz.d_height)
01957                 );
01958 }
01959 
01960 
01961 /*************************************************************************
01962 
01963 *************************************************************************/
01964 Size Window::relativeToAbsolute_impl(const Window* window, const Size& sz) const
01965 {
01966         // get size object for whatever we are using as a base for the conversion
01967         Size wndsz = getWindowSize_impl(window);
01968 
01969         return Size(
01970                 PixelAligned(sz.d_width * wndsz.d_width),
01971                 PixelAligned(sz.d_height * wndsz.d_height)
01972                 );
01973 }
01974 
01975 
01976 /*************************************************************************
01977 
01978 *************************************************************************/
01979 Point Window::relativeToAbsolute_impl(const Window* window, const Point& pt) const
01980 {
01981         // get size object for whatever we are using as a base for the conversion
01982         Size sz = getWindowSize_impl(window);
01983 
01984         return Point(
01985                 PixelAligned(pt.d_x * sz.d_width),
01986                 PixelAligned(pt.d_y * sz.d_height)
01987                 );
01988 }
01989 
01990 
01991 /*************************************************************************
01992 
01993 *************************************************************************/
01994 float Window::relativeToAbsoluteX_impl(const Window* window, float x) const
01995 {
01996         // get size object for whatever we are using as a base for the conversion
01997         Size sz = getWindowSize_impl(window);
01998 
01999         return PixelAligned(x * sz.d_width);
02000 }
02001 
02002 
02003 /*************************************************************************
02004 
02005 *************************************************************************/
02006 float Window::relativeToAbsoluteY_impl(const Window* window, float y) const
02007 {
02008         // get size object for whatever we are using as a base for the conversion
02009         Size sz = getWindowSize_impl(window);
02010 
02011         return PixelAligned(y * sz.d_height);
02012 }
02013 
02014 
02015 /*************************************************************************
02016         Return size of window.  If window is NULL return size of display.
02017 *************************************************************************/
02018 Size Window::getWindowSize_impl(const Window* window) const
02019 {
02020         if (window == NULL)
02021         {
02022                 return System::getSingleton().getRenderer()->getSize();
02023         }
02024         else
02025         {
02026                 return window->d_abs_area.getSize();
02027         }
02028 
02029 }
02030 
02031 
02032 /*************************************************************************
02033         Return the current maximum size for this window.
02034 *************************************************************************/
02035 Size Window::getMaximumSize(void) const
02036 {
02037         if (getMetricsMode() == Absolute)
02038         {
02039                 return d_maxSize;
02040         }
02041         else
02042         {
02043                 return absoluteToRelative_impl(NULL, d_maxSize);
02044         }
02045 
02046 }
02047 
02048 
02049 /*************************************************************************
02050         Return the current minimum size for this window.
02051 *************************************************************************/
02052 Size Window::getMinimumSize(void) const
02053 {
02054         if (getMetricsMode() == Absolute)
02055         {
02056                 return d_minSize;
02057         }
02058         else
02059         {
02060                 return absoluteToRelative_impl(NULL, d_minSize);
02061         }
02062 
02063 }
02064 
02065 
02066 /*************************************************************************
02067         Set the minimum size for this window.
02068 *************************************************************************/
02069 void Window::setMinimumSize(const Size& sz)
02070 {
02071         if (getMetricsMode() == Absolute)
02072         {
02073                 d_minSize.d_width = PixelAligned(sz.d_width);
02074                 d_minSize.d_height = PixelAligned(sz.d_height);
02075         }
02076         else
02077         {
02078                 d_minSize = relativeToAbsolute_impl(NULL, sz);
02079         }
02080 
02081         // store old size.
02082         Rect old_sz(d_abs_area);
02083 
02084         // limit size as required
02085         d_abs_area.constrainSizeMin(d_minSize);
02086 
02087         // if size has changed, trigger notifications
02088         if (old_sz != d_abs_area)
02089         {
02090         WindowEventArgs args(this);
02091                 onSized(args);
02092         }
02093 
02094 }
02095 
02096 
02097 /*************************************************************************
02098         Set the maximum size for this window.
02099 *************************************************************************/
02100 void Window::setMaximumSize(const Size& sz)
02101 {
02102         if (getMetricsMode() == Absolute)
02103         {
02104                 d_maxSize.d_width = PixelAligned(sz.d_width);
02105                 d_maxSize.d_height = PixelAligned(sz.d_height);
02106         }
02107         else
02108         {
02109                 d_maxSize = relativeToAbsolute_impl(NULL, sz);
02110         }
02111 
02112         // store old size.
02113         Rect old_sz(d_abs_area);
02114 
02115         // limit size as required
02116         d_abs_area.constrainSizeMax(d_maxSize);
02117 
02118         // if size has changed, trigger notifications
02119         if (old_sz != d_abs_area)
02120         {
02121         WindowEventArgs args(this);
02122                 onSized(args);
02123         }
02124 
02125 }
02126 
02127 
02128 /*************************************************************************
02129         Return a pointer to the mouse cursor image to use when the mouse is
02130         within this window.
02131 *************************************************************************/
02132 const Image* Window::getMouseCursor(void) const
02133 {
02134         if (d_mouseCursor != (const Image*)DefaultMouseCursor)
02135         {
02136                 return d_mouseCursor;
02137         }
02138         else
02139         {
02140                 return System::getSingleton().getDefaultMouseCursor();
02141         }
02142 
02143 }
02144 
02145 
02146 /*************************************************************************
02147         Set the mouse cursor image to be used when the mouse enters this
02148         window. 
02149 *************************************************************************/
02150 void Window::setMouseCursor(const String& imageset, const String& image_name)
02151 {
02152         d_mouseCursor = &ImagesetManager::getSingleton().getImageset(imageset)->getImage(image_name);
02153 }
02154 
02155 
02156 /*************************************************************************
02157         Set the current ID for the Window.      
02158 *************************************************************************/
02159 void Window::setID(uint ID)
02160 {
02161         if (d_ID != ID)
02162         {
02163                 d_ID = ID;
02164 
02165                 WindowEventArgs args(this);
02166                 onIDChanged(args);
02167         }
02168 
02169 }
02170 
02171 
02172 /*************************************************************************
02173         set the current metrics mode employed by the Window     
02174 *************************************************************************/
02175 void Window::setMetricsMode(MetricsMode mode)
02176 {
02177         if (d_metricsMode != mode)
02178         {
02179                 MetricsMode oldMode = d_metricsMode;
02180                 d_metricsMode = mode;
02181 
02182                 // only ever trigger the event if the mode is actually changed.
02183                 if ((d_metricsMode != Inherited) || (oldMode != getMetricsMode()))
02184                 {
02185                         WindowEventArgs args(this);
02186                         onMetricsChanged(args);
02187                 }
02188 
02189         }
02190 
02191 }
02192 
02193 
02194 /*************************************************************************
02195         Set whether or not this Window will automatically be destroyed when
02196         its parent Window is destroyed. 
02197 *************************************************************************/
02198 void Window::setDestroyedByParent(bool setting)
02199 {
02200         if (d_destroyedByParent != setting)
02201         {
02202                 d_destroyedByParent = setting;
02203 
02204                 WindowEventArgs args(this);
02205                 onParentDestroyChanged(args);
02206         }
02207 
02208 }
02209 
02210 
02211 /*************************************************************************
02212         Return the inherited metrics mode.  This is either the metrics mode
02213         of our parent, or Relative if we have no parent.        
02214 *************************************************************************/
02215 MetricsMode Window::getInheritedMetricsMode(void) const
02216 {
02217         return (d_parent == NULL) ? Relative : d_parent->getMetricsMode();
02218 }
02219 
02220 
02221 /*************************************************************************
02222         return the x position of the window using the specified metrics system. 
02223 *************************************************************************/
02224 float Window::getXPosition(MetricsMode mode) const
02225 {
02226         // get proper mode to use for inherited.
02227         if (mode == Inherited)
02228         {
02229                 mode = getInheritedMetricsMode();
02230         }
02231 
02232         if (mode == Absolute)
02233         {
02234                 return d_abs_area.d_left;
02235         }
02236         else
02237         {
02238                 return d_rel_area.d_left;
02239         }
02240 
02241 }
02242 
02243 
02244 /*************************************************************************
02245         return the y position of the window using the specified metrics system. 
02246 *************************************************************************/
02247 float Window::getYPosition(MetricsMode mode) const
02248 {
02249         // get proper mode to use for inherited.
02250         if (mode == Inherited)
02251         {
02252                 mode = getInheritedMetricsMode();
02253         }
02254 
02255         if (mode == Absolute)
02256         {
02257                 return d_abs_area.d_top;
02258         }
02259         else
02260         {
02261                 return d_rel_area.d_top;
02262         }
02263 
02264 }
02265 
02266 
02267 /*************************************************************************
02268         return the position of the window using the specified metrics system.   
02269 *************************************************************************/
02270 Point Window::getPosition(MetricsMode mode) const
02271 {
02272         // get proper mode to use for inherited.
02273         if (mode == Inherited)
02274         {
02275                 mode = getInheritedMetricsMode();
02276         }
02277 
02278         if (mode == Absolute)
02279         {
02280                 return d_abs_area.getPosition();
02281         }
02282         else
02283         {
02284                 return d_rel_area.getPosition();
02285         }
02286 
02287 }
02288 
02289 
02290 /*************************************************************************
02291         return the width of the Window using the specified metrics system.      
02292 *************************************************************************/
02293 float Window::getWidth(MetricsMode mode) const
02294 {
02295         // get proper mode to use for inherited.
02296         if (mode == Inherited)
02297         {
02298                 mode = getInheritedMetricsMode();
02299         }
02300 
02301         if (mode == Absolute)
02302         {
02303                 return d_abs_area.getWidth();
02304         }
02305         else
02306         {
02307                 return d_rel_area.getWidth();
02308         }
02309 
02310 }
02311 
02312 
02313 /*************************************************************************
02314         return the height of the Window using the specified metrics system.     
02315 *************************************************************************/
02316 float Window::getHeight(MetricsMode mode) const
02317 {
02318         // get proper mode to use for inherited.
02319         if (mode == Inherited)
02320         {
02321                 mode = getInheritedMetricsMode();
02322         }
02323 
02324         if (mode == Absolute)
02325         {
02326                 return d_abs_area.getHeight();
02327         }
02328         else
02329         {
02330                 return d_rel_area.getHeight();
02331         }
02332 
02333 }
02334 
02335 
02336 /*************************************************************************
02337         return the size of the Window using the specified metrics system.       
02338 *************************************************************************/
02339 Size Window::getSize(MetricsMode mode) const
02340 {
02341         // get proper mode to use for inherited.
02342         if (mode == Inherited)
02343         {
02344                 mode = getInheritedMetricsMode();
02345         }
02346 
02347         if (mode == Absolute)
02348         {
02349                 return d_abs_area.getSize();
02350         }
02351         else
02352         {
02353                 return d_rel_area.getSize();
02354         }
02355 
02356 }
02357 
02358 
02359 /*************************************************************************
02360         return a Rect object that describes the Window area using the
02361         specified metrics system.
02362 *************************************************************************/
02363 Rect Window::getRect(MetricsMode mode) const
02364 {
02365         // get proper mode to use for inherited.
02366         if (mode == Inherited)
02367         {
02368                 mode = getInheritedMetricsMode();
02369         }
02370 
02371         if (mode == Absolute)
02372         {
02373                 return d_abs_area;
02374         }
02375         else
02376         {
02377                 return d_rel_area;
02378         }
02379 
02380 }
02381 
02382 
02383 /*************************************************************************
02384         set the x position of the window using the specified metrics system.    
02385 *************************************************************************/
02386 void Window::setXPosition(MetricsMode mode, float x)
02387 {
02388         setPosition(mode, Point(x, getYPosition(mode)));
02389 }
02390 
02391 
02392 /*************************************************************************
02393         set the y position of the window using the specified metrics system.    
02394 *************************************************************************/
02395 void Window::setYPosition(MetricsMode mode, float y)
02396 {
02397         setPosition(mode, Point(getXPosition(mode), y));
02398 }
02399 
02400 
02401 /*************************************************************************
02402         set the position of the window using the specified metrics system.      
02403 *************************************************************************/
02404 void Window::setPosition(MetricsMode mode, const Point& position)
02405 {
02406         if (mode == Inherited)
02407         {
02408                 mode = getInheritedMetricsMode();
02409         }
02410 
02411         if (mode == Relative)
02412         {
02413                 d_rel_area.setPosition(position);
02414                 d_abs_area = relativeToAbsolute_impl(d_parent, d_rel_area);
02415                 d_abs_area.constrainSize(d_maxSize, d_minSize);
02416         }
02417         else
02418         {
02419                 Point intPos(PixelAligned(position.d_x), PixelAligned(position.d_y));
02420 
02421                 d_abs_area.setPosition(intPos);
02422                 d_rel_area.setPosition(absoluteToRelative_impl(d_parent, position));
02423         }
02424 
02425         WindowEventArgs args(this);
02426         onMoved(args);
02427 }
02428 
02429 
02430 /*************************************************************************
02431         set the width of the Window using the specified metrics system. 
02432 *************************************************************************/
02433 void Window::setWidth(MetricsMode mode, float width)
02434 {
02435         setSize(mode, Size(width, getHeight(mode)));
02436 }
02437 
02438 
02439 /*************************************************************************
02440         set the height of the Window using the specified metrics system.        
02441 *************************************************************************/
02442 void Window::setHeight(MetricsMode mode, float height)
02443 {
02444         setSize(mode, Size(getWidth(mode), height));
02445 }
02446 
02447 
02448 /*************************************************************************
02449         set the size of the Window using the specified metrics system.  
02450 *************************************************************************/
02451 void Window::setSize(MetricsMode mode, const Size& size)
02452 {
02453         if (mode == Inherited)
02454         {
02455                 mode = getInheritedMetricsMode();
02456         }
02457 
02458         if (mode == Relative)
02459         {
02460                 d_rel_area.setSize(size);
02461 
02462                 // update Rect for the other metrics system
02463         d_abs_area = relativeToAbsolute_impl(d_parent, d_rel_area);
02464                 d_abs_area.constrainSize(d_maxSize, d_minSize);
02465         }
02466         else
02467         {
02468                 Size intSize(PixelAligned(size.d_width), PixelAligned(size.d_height));
02469 
02470                 d_abs_area.setSize(intSize);
02471                 d_abs_area.constrainSize(d_maxSize, d_minSize);
02472 
02473                 // update Rect for the other metrics system.
02474                 d_rel_area.setSize(absoluteToRelative_impl(d_parent, size));
02475         }
02476 
02477         WindowEventArgs args(this);
02478         onSized(args);
02479 }
02480 
02481 
02482 /*************************************************************************
02483         set the Rect that describes the Window area using the specified
02484         metrics system. 
02485 *************************************************************************/
02486 void Window::setRect(MetricsMode mode, const Rect& area)
02487 {
02488         if (mode == Inherited)
02489         {
02490                 mode = getInheritedMetricsMode();
02491         }
02492 
02493         if (mode == Relative)
02494         {
02495                 d_rel_area = area;
02496 
02497                 d_abs_area = relativeToAbsolute_impl(d_parent, area);
02498                 d_abs_area.constrainSize(d_maxSize, d_minSize);
02499         }
02500         else
02501         {
02502                 Rect intArea(
02503                         PixelAligned(area.d_left),
02504                         PixelAligned(area.d_top),
02505                         PixelAligned(area.d_right),
02506                         PixelAligned(area.d_bottom)
02507                         );
02508 
02509                 d_abs_area = intArea;
02510                 d_abs_area.constrainSize(d_maxSize, d_minSize);
02511 
02512                 d_rel_area = absoluteToRelative_impl(d_parent, area);
02513         }
02514 
02515         WindowEventArgs args(this);
02516         onMoved(args);
02517         onSized(args);
02518 }
02519 
02520 
02521 /*************************************************************************
02522     Helper method to fire off a mouse button down event.
02523 *************************************************************************/
02524 void Window::generateAutoRepeatEvent(MouseButton button)
02525 {
02526     MouseEventArgs ma(this);
02527     ma.position = MouseCursor::getSingleton().getPosition();
02528     ma.moveDelta = Vector2(0.0f, 0.0f);
02529     ma.button = button;
02530     ma.sysKeys = System::getSingleton().getSystemKeys();
02531     ma.wheelChange = 0;
02532     onMouseButtonDown(ma);
02533 }
02534 
02535 
02536 /*************************************************************************
02537         Add standard CEGUI::Window properties.
02538 *************************************************************************/
02539 void Window::addStandardProperties(void)
02540 {
02541         addProperty(&d_absHeightProperty);
02542         addProperty(&d_absMaxSizeProperty);
02543         addProperty(&d_absMinSizeProperty);
02544         addProperty(&d_absPositionProperty);
02545         addProperty(&d_absRectProperty);
02546         addProperty(&d_absSizeProperty);
02547         addProperty(&d_absWidthProperty);
02548         addProperty(&d_absXPosProperty);
02549         addProperty(&d_absYPosProperty);
02550         addProperty(&d_alphaProperty);
02551         addProperty(&d_alwaysOnTopProperty);
02552         addProperty(&d_clippedByParentProperty);
02553         addProperty(&d_destroyedByParentProperty);
02554         addProperty(&d_disabledProperty);
02555         addProperty(&d_fontProperty);
02556         addProperty(&d_heightProperty);
02557         addProperty(&d_IDProperty);
02558         addProperty(&d_inheritsAlphaProperty);
02559         addProperty(&d_metricsModeProperty);
02560         addProperty(&d_mouseCursorProperty);
02561         addProperty(&d_positionProperty);
02562         addProperty(&d_rectProperty);
02563         addProperty(&d_relHeightProperty);
02564         addProperty(&d_relMaxSizeProperty);
02565         addProperty(&d_relMinSizeProperty);
02566         addProperty(&d_relPositionProperty);
02567         addProperty(&d_relRectProperty);
02568         addProperty(&d_relSizeProperty);
02569         addProperty(&d_relWidthProperty);
02570         addProperty(&d_relXPosProperty);
02571         addProperty(&d_relYPosProperty);
02572         addProperty(&d_restoreOldCaptureProperty);
02573         addProperty(&d_sizeProperty);
02574         addProperty(&d_textProperty);
02575         addProperty(&d_visibleProperty);
02576         addProperty(&d_widthProperty);
02577         addProperty(&d_xPosProperty);
02578         addProperty(&d_yPosProperty);
02579         addProperty(&d_zOrderChangeProperty);
02580     addProperty(&d_wantsMultiClicksProperty);
02581     addProperty(&d_autoRepeatProperty);
02582     addProperty(&d_autoRepeatDelayProperty);
02583     addProperty(&d_autoRepeatRateProperty);
02584 }
02585 
02586 
02587 /*************************************************************************
02588         Return whether z-order changes are enabled.
02589 *************************************************************************/
02590 bool Window::isZOrderingEnabled(void) const
02591 {
02592         return d_zOrderingEnabled;
02593 }
02594 
02595 
02596 /*************************************************************************
02597         Set whether z-order changes are enabled.
02598 *************************************************************************/
02599 void Window::setZOrderingEnabled(bool setting)
02600 {
02601         if (d_zOrderingEnabled != setting)
02602         {
02603                 d_zOrderingEnabled = setting;
02604         }
02605 
02606 }
02607 
02608 
02609 /*************************************************************************
02610     Return whether this window will receive multi-click events or
02611     multiple 'down' events instead.
02612 *************************************************************************/
02613 bool Window::wantsMultiClickEvents(void) const
02614 {
02615     return d_wantsMultiClicks;
02616 }
02617 
02618 
02619 /*************************************************************************
02620     Set whether this window will receive multi-click events or
02621     multiple 'down' events instead.     
02622 *************************************************************************/
02623 void Window::setWantsMultiClickEvents(bool setting)
02624 {
02625     if (d_wantsMultiClicks != setting)
02626     {
02627         d_wantsMultiClicks = setting;
02628 
02629         // TODO: Maybe add a 'setting changed' event for this?
02630     }
02631 
02632 }
02633 
02634 
02635 /*************************************************************************
02636     Return whether mouse button down event autorepeat is enabled for
02637     this window.
02638 *************************************************************************/
02639 bool Window::isMouseAutoRepeatEnabled(void) const
02640 {
02641     return d_autoRepeat;
02642 }
02643 
02644 
02645 /*************************************************************************
02646     Return the current auto-repeat delay setting for this window.
02647 *************************************************************************/
02648 float Window::getAutoRepeatDelay(void) const
02649 {
02650     return d_repeatDelay;
02651 }
02652 
02653     
02654 /*************************************************************************
02655     Return the current auto-repeat rate setting for this window.
02656 *************************************************************************/
02657 float Window::getAutoRepeatRate(void) const
02658 {
02659     return d_repeatRate;
02660 }
02661 
02662 
02663 /*************************************************************************
02664     Set whether mouse button down event autorepeat is enabled for this
02665     window.
02666 *************************************************************************/
02667 void Window::setMouseAutoRepeatEnabled(bool setting)
02668 {
02669     if (d_autoRepeat != setting)
02670     {
02671         d_autoRepeat = setting;
02672         d_repeatButton = NoButton;
02673  
02674         // TODO: Maybe add a 'setting changed' event for this?
02675     }
02676 
02677 }
02678 
02679 
02680 /*************************************************************************
02681     Set the current auto-repeat delay setting for this window.
02682 *************************************************************************/
02683 void Window::setAutoRepeatDelay(float delay)
02684 {
02685     if (d_repeatDelay != delay)
02686     {
02687         d_repeatDelay = delay;
02688 
02689         // TODO: Maybe add a 'setting changed' event for this?
02690     }
02691 
02692 }
02693 
02694     
02695 /*************************************************************************
02696     Set the current auto-repeat rate setting for this window.
02697 *************************************************************************/
02698 void Window::setAutoRepeatRate(float rate)
02699 {
02700     if (d_repeatRate != rate)
02701     {
02702         d_repeatRate = rate;
02703 
02704         // TODO: Maybe add a 'setting changed' event for this?
02705     }
02706 
02707 }
02708 
02709 
02710 /*************************************************************************
02711         Cause window to update itself and any attached children
02712 *************************************************************************/
02713 void Window::update(float elapsed)
02714 {
02715         // perform update for 'this' Window
02716         updateSelf(elapsed);
02717 
02718         // update child windows
02719         uint child_count = getChildCount();
02720 
02721         for (uint i = 0; i < child_count; ++i)
02722         {
02723                 d_children[i]->update(elapsed);
02724         }
02725 
02726 }
02727 
02728 
02729 /*************************************************************************
02730     Perform actual update processing for this Window.
02731 *************************************************************************/
02732 void Window::updateSelf(float elapsed)
02733 {
02734     // Mouse button autorepeat processing.
02735     if (d_autoRepeat && d_repeatButton != NoButton)
02736     {
02737         d_repeatElapsed += elapsed;
02738 
02739         if (d_repeating)
02740         {
02741             if (d_repeatElapsed > d_repeatRate)
02742             {
02743                 d_repeatElapsed -= d_repeatRate;
02744                 // trigger the repeated event
02745                 generateAutoRepeatEvent(d_repeatButton);
02746             }
02747         }
02748         else
02749         {
02750             if (d_repeatElapsed > d_repeatDelay)
02751             {
02752                 d_repeatElapsed = 0;
02753                 d_repeating = true;
02754                 // trigger the repeated event
02755                 generateAutoRepeatEvent(d_repeatButton);
02756             }
02757         }
02758     }
02759 }
02760 
02761 
02763 /*************************************************************************
02764 
02765         Begin event triggers section
02766 
02767 *************************************************************************/
02769 
02770 void Window::onSized(WindowEventArgs& e)
02771 {
02772         // inform children their parent has been re-sized
02773         uint child_count = getChildCount();
02774         for (uint i = 0; i < child_count; ++i)
02775         {
02776                 WindowEventArgs args(this);
02777                 d_children[i]->onParentSized(args);
02778         }
02779 
02780         requestRedraw();
02781 
02782         fireEvent(EventSized, e, EventNamespace);
02783 }
02784 
02785 
02786 void Window::onMoved(WindowEventArgs& e)
02787 {
02788         requestRedraw();
02789         fireEvent(EventMoved, e, EventNamespace);
02790 }
02791 
02792 
02793 void Window::onTextChanged(WindowEventArgs& e)
02794 {
02795         requestRedraw();
02796         fireEvent(EventTextChanged, e, EventNamespace);
02797 }
02798 
02799 
02800 void Window::onFontChanged(WindowEventArgs& e)
02801 {
02802         requestRedraw();
02803         fireEvent(EventFontChanged, e, EventNamespace);
02804 }
02805 
02806 
02807 void Window::onAlphaChanged(WindowEventArgs& e)
02808 {
02809         // scan child list and call this method for all children that inherit alpha
02810         int child_count = getChildCount();
02811 
02812         for (int i = 0; i < child_count; ++i)
02813         {
02814                 if (d_children[i]->inheritsAlpha())
02815                 {
02816             WindowEventArgs args(d_children[i]);
02817                         d_children[i]->onAlphaChanged(args);
02818                 }
02819 
02820         }
02821 
02822         requestRedraw();
02823         fireEvent(EventAlphaChanged, e, EventNamespace);
02824 }
02825 
02826 
02827 void Window::onIDChanged(WindowEventArgs& e)
02828 {
02829         fireEvent(EventIDChanged, e, EventNamespace);
02830 }
02831 
02832 
02833 void Window::onShown(WindowEventArgs& e)
02834 {
02835         requestRedraw();
02836         fireEvent(EventShown, e, EventNamespace);
02837 }
02838 
02839 
02840 void Window::onHidden(WindowEventArgs& e)
02841 {
02842         requestRedraw();
02843         fireEvent(EventHidden, e, EventNamespace);
02844 }
02845 
02846 
02847 void Window::onEnabled(WindowEventArgs& e)
02848 {
02849         requestRedraw();
02850         fireEvent(EventEnabled, e, EventNamespace);
02851 }
02852 
02853 
02854 void Window::onDisabled(WindowEventArgs& e)
02855 {
02856         requestRedraw();
02857         fireEvent(EventDisabled, e, EventNamespace);
02858 }
02859 
02860 
02861 void Window::onMetricsChanged(WindowEventArgs& e)
02862 {
02863         fireEvent(EventMetricsModeChanged, e, EventNamespace);
02864 }
02865 
02866 
02867 void Window::onClippingChanged(WindowEventArgs& e)
02868 {
02869         requestRedraw();
02870         fireEvent(EventClippedByParentChanged, e, EventNamespace);
02871 }
02872 
02873 
02874 void Window::onParentDestroyChanged(WindowEventArgs& e)
02875 {
02876         fireEvent(EventDestroyedByParentChanged, e, EventNamespace);
02877 }
02878 
02879 
02880 void Window::onInheritsAlphaChanged(WindowEventArgs& e)
02881 {
02882         requestRedraw();
02883         fireEvent(EventInheritsAlphaChanged, e, EventNamespace);
02884 }
02885 
02886 
02887 void Window::onAlwaysOnTopChanged(WindowEventArgs& e)
02888 {
02889         requestRedraw();
02890         fireEvent(EventAlwaysOnTopChanged, e, EventNamespace);
02891 }
02892 
02893 
02894 void Window::onCaptureGained(WindowEventArgs& e)
02895 {
02896         fireEvent(EventInputCaptureGained, e, EventNamespace);
02897 }
02898 
02899 
02900 void Window::onCaptureLost(WindowEventArgs& e)
02901 {
02902     // reset auto-repeat state
02903     d_repeatButton = NoButton;
02904 
02905         // handle restore of previous capture window as required.
02906         if (d_restoreOldCapture && (d_oldCapture != NULL)) {
02907                 d_oldCapture->onCaptureLost(e);
02908                 d_oldCapture = NULL;
02909         }
02910 
02911         // handle case where mouse is now in a different window
02912         // (this is a bit of a hack that uses the mouse input injector to handle this for us).
02913         System::getSingleton().injectMouseMove(0, 0);
02914 
02915         fireEvent(EventInputCaptureLost, e, EventNamespace);
02916 }
02917 
02918 
02919 void Window::onRenderingStarted(WindowEventArgs& e)
02920 {
02921         fireEvent(EventRenderingStarted, e, EventNamespace);
02922 }
02923 
02924 
02925 void Window::onRenderingEnded(WindowEventArgs& e)
02926 {
02927         fireEvent(EventRenderingEnded, e, EventNamespace);
02928 }
02929 
02930 
02931 void Window::onZChanged(WindowEventArgs& e)
02932 {
02933         requestRedraw();
02934         fireEvent(EventZOrderChanged, e, EventNamespace);
02935 }
02936 
02937 
02938 void Window::onDestructionStarted(WindowEventArgs& e)
02939 {
02940         fireEvent(EventDestructionStarted, e, EventNamespace);
02941 }
02942 
02943 
02944 void Window::onActivated(ActivationEventArgs& e)
02945 {
02946         d_active = true;
02947         requestRedraw();
02948         fireEvent(EventActivated, e, EventNamespace);
02949 }
02950 
02951 
02952 void Window::onDeactivated(ActivationEventArgs& e)
02953 {
02954         // first de-activate all children
02955         uint child_count = getChildCount();
02956         for (uint i = 0; i < child_count; ++i)
02957         {
02958                 if (d_children[i]->isActive())
02959                 {
02960                         d_children[i]->onDeactivated(e);
02961                 }
02962 
02963         }
02964 
02965         d_active = false;
02966         requestRedraw();
02967         fireEvent(EventDeactivated, e, EventNamespace);
02968 }
02969 
02970 
02971 void Window::onParentSized(WindowEventArgs& e)
02972 {
02973         // synchronise area rects for new parent size
02974         if (getMetricsMode() == Relative)
02975         {
02976                 d_abs_area = relativeToAbsolute_impl(d_parent, d_rel_area);
02977 
02978                 // Check new absolute size and limit to currently set max/min values.  This does not affect relative co-ordinates
02979                 // which must 'recover' after window is again sized so normal relativity can take over.
02980                 d_abs_area.constrainSize(d_maxSize, d_minSize);
02981 
02982                 // perform notifications
02983         WindowEventArgs args(this); 
02984                 onMoved(args);
02985                 onSized(args);
02986 
02987                 // call for a redraw
02988                 requestRedraw();
02989         }
02990         else
02991         {
02992                 d_rel_area = absoluteToRelative_impl(d_parent, d_abs_area);
02993         }
02994 
02995         fireEvent(EventParentSized, e, EventNamespace);
02996 }
02997 
02998 
02999 void Window::onChildAdded(WindowEventArgs& e)
03000 {
03001         requestRedraw();
03002         fireEvent(EventChildAdded, e, EventNamespace);
03003 }
03004 
03005 
03006 void Window::onChildRemoved(WindowEventArgs& e)
03007 {
03008         requestRedraw();
03009         fireEvent(EventChildRemoved, e, EventNamespace);
03010 }
03011 
03012 
03013 void Window::onMouseEnters(MouseEventArgs& e)
03014 {
03015         // set the mouse cursor
03016         MouseCursor::getSingleton().setImage(getMouseCursor());
03017 
03018         fireEvent(EventMouseEnters, e, EventNamespace);
03019 }
03020 
03021 
03022 void Window::onMouseLeaves(MouseEventArgs& e)
03023 {
03024         fireEvent(EventMouseLeaves, e, EventNamespace);
03025 }
03026 
03027 
03028 void Window::onMouseMove(MouseEventArgs& e)
03029 {
03030         fireEvent(EventMouseMove, e, EventNamespace);
03031 }
03032 
03033 
03034 void Window::onMouseWheel(MouseEventArgs& e)
03035 {
03036         fireEvent(EventMouseWheel, e, EventNamespace);
03037 }
03038 
03039 
03040 void Window::onMouseButtonDown(MouseEventArgs& e)
03041 {
03042         if (e.button == LeftButton)
03043         {
03044                 moveToFront();
03045         }
03046 
03047     // if auto repeat is enabled and we are not currently tracking
03048     // the button that was just pushed (need this button check because
03049     // it could be us that generated this event via auto-repeat).
03050     if (d_autoRepeat && d_repeatButton != e.button)
03051     {
03052         d_repeatButton = e.button;
03053         d_repeatElapsed = 0;
03054         d_repeating = false;
03055     }
03056 
03057         fireEvent(EventMouseButtonDown, e, EventNamespace);
03058 }
03059 
03060 
03061 void Window::onMouseButtonUp(MouseEventArgs& e)
03062 {
03063     // reset auto-repeat state
03064     d_repeatButton = NoButton;
03065 
03066         fireEvent(EventMouseButtonUp, e, EventNamespace);
03067 }
03068 
03069 
03070 void Window::onMouseClicked(MouseEventArgs& e)
03071 {
03072         fireEvent(EventMouseClick, e, EventNamespace);
03073 }
03074 
03075 
03076 void Window::onMouseDoubleClicked(MouseEventArgs& e)
03077 {
03078         fireEvent(EventMouseDoubleClick, e, EventNamespace);
03079 }
03080 
03081 
03082 void Window::onMouseTripleClicked(MouseEventArgs& e)
03083 {
03084         fireEvent(EventMouseTripleClick, e, EventNamespace);
03085 }
03086 
03087 
03088 void Window::onKeyDown(KeyEventArgs& e)
03089 {
03090         fireEvent(EventKeyDown, e, EventNamespace);
03091 }
03092 
03093 
03094 void Window::onKeyUp(KeyEventArgs& e)
03095 {
03096         fireEvent(EventKeyUp, e, EventNamespace);
03097 }
03098 
03099 
03100 void Window::onCharacter(KeyEventArgs& e)
03101 {
03102         fireEvent(EventCharacterKey, e, EventNamespace);
03103 }
03104 
03105 } // End of  CEGUI namespace section

Generated on Wed Feb 16 12:41:08 2005 for Crazy Eddies GUI System by  doxygen 1.3.9.1