Game Accessibility Library logo SourceForge.net Logo
Game Accessibility Suite: CATGUI/CATSkin.cpp Source File

CATSkin.cpp

Go to the documentation of this file.
00001 //---------------------------------------------------------------------------
00002 /// \file CATSkin.cpp
00003 /// \brief Root skin class
00004 /// \ingroup CATGUI
00005 ///
00006 /// Copyright (c) 2003-2008 by Michael Ellison.
00007 /// See COPYING.txt for the \ref gaslicense License (MIT License).
00008 ///
00009 // $Author: mikeellison $
00010 // $Date: 2008-01-29 07:01:23 -0600 (Tue, 29 Jan 2008) $
00011 // $Revision:   $
00012 // $NoKeywords: $
00013 //
00014 //---------------------------------------------------------------------------
00015 #include "CATSkin.h"
00016 #include "CATWindow.h"
00017 #include "CATControl.h"
00018 #include "CATApp.h"
00019 #include "CATEventDefs.h"
00020 #include "CATGuiFactory.h"
00021 /// This is the maximum frequence for updating other window's controls
00022 /// in response to a command of the same name.
00023 const CATFloat32 kUPDATESPEED = 0.05f;
00024 
00025 //---------------------------------------------------------------------------
00026 /// CATSkin constructor (inherited from CATXMLObject)
00027 /// \param element - Type name ("Skin")
00028 /// \param attribs - attribute information for the window
00029 /// \param parent - parent XML object (should be NULL)
00030 //---------------------------------------------------------------------------
00031 CATSkin::CATSkin(  const CATString&               element, 
00032                  const CATString&               skinRootDir,
00033                  const CATString&               skinPath)
00034                  : CATGuiObj(element,  skinRootDir)
00035 {
00036     fTemplateCtr = 0;
00037     fUpdateTime = 0;
00038     fSkinRoot = skinRootDir;
00039     fSkinPath = skinPath;
00040 }
00041 
00042 //---------------------------------------------------------------------------
00043 /// CATSkin destructor
00044 //---------------------------------------------------------------------------
00045 CATSkin::~CATSkin()
00046 {
00047     this->CloseAll();
00048 
00049 }
00050 
00051 // ParseAttributes() parses the known attributes for an object.
00052 CATResult CATSkin::ParseAttributes()
00053 {
00054     CATResult result = CATGuiObj::ParseAttributes();
00055     CATString attrib;
00056 
00057     fAuthor     = GetAttribute(L"Author");
00058     fURL        = GetAttribute(L"URL");
00059     fCopyright  = GetAttribute(L"Copyright");
00060     return result;
00061 }
00062 
00063 //---------------------------------------------------------------------------
00064 // RectFromAttribs() recalculates the control's rectangle from
00065 // the attributes.  This can only be called after ParseAttributes() has
00066 // loaded the images.
00067 //---------------------------------------------------------------------------
00068 CATResult CATSkin::RectFromAttribs()
00069 {
00070     // Skins don't have rects.
00071     this->fRect.Set(0,0,0,0);
00072     return CAT_SUCCESS;
00073 }
00074 
00075 //---------------------------------------------------------------------------
00076 // Retrieve the root directory of the skin.
00077 //---------------------------------------------------------------------------
00078 CATString CATSkin::GetRootDir()
00079 {
00080     return fSkinRoot;
00081 }
00082 
00083 //---------------------------------------------------------------------------
00084 // Retrieve the full path to the skin's .XML file.
00085 //---------------------------------------------------------------------------
00086 CATString CATSkin::GetPath()
00087 {  
00088     return fSkinPath;
00089 }
00090 
00091 //---------------------------------------------------------------------------
00092 // Retrieve the author's name for the skin
00093 //---------------------------------------------------------------------------
00094 CATString CATSkin::GetAuthor()
00095 {
00096     return GetAttribute(L"Author");
00097 }
00098 
00099 //---------------------------------------------------------------------------
00100 // Retrieve the author's URL
00101 //---------------------------------------------------------------------------
00102 CATString CATSkin::GetUrl()
00103 {
00104     return GetAttribute(L"AuthorUrl");
00105 }
00106 
00107 //---------------------------------------------------------------------------
00108 // Retrieve the skin's copyright string.
00109 //---------------------------------------------------------------------------
00110 CATString CATSkin::GetCopyright()
00111 {
00112     return GetAttribute(L"Copyright");
00113 }
00114 
00115 //---------------------------------------------------------------------------
00116 // GetWindowByName() - Retrieve a window by name
00117 //---------------------------------------------------------------------------
00118 CATWindow* CATSkin::GetWindowByName(const CATString& name)
00119 {
00120     CATXMLObject* curWindow = 0;
00121 
00122     CATUInt32 i;
00123     CATUInt32 numChildren = GetNumChildren();
00124     for (i = 0; i < numChildren; i++)
00125     {
00126         curWindow = GetChild(i);
00127         if (name.Compare( ((CATGuiObj*)curWindow)->GetName()) == 0)
00128         {
00129             return (CATWindow*)curWindow;
00130         }
00131     }
00132 
00133     return 0;
00134 }
00135 
00136 
00137 //---------------------------------------------------------------------------
00138 /// Get a stack of all the controls 
00139 /// that reference a specific command in a window.
00140 /// \param command - the string command of the controls to get
00141 /// \param controlStack - a stack to add the controls to
00142 /// \return CAT_SUCCESS on success.
00143 //---------------------------------------------------------------------------
00144 CATResult CATSkin::GetControlsByCommand( const CATString& windowName,
00145                                         const CATString& command,
00146                                         CATStack<CATControl*>& controlStack)
00147 {
00148     CATWindow* wnd = GetWindowByName(windowName);
00149     if (wnd == 0)
00150     {
00151         return CATRESULTDESC(CAT_ERR_SKIN_WINDOW_NOT_FOUND, windowName);
00152     }
00153 
00154     return this->GetControlsByCommand(wnd,command,controlStack);
00155 }
00156 CATResult CATSkin::GetControlsByCommand( CATWindow* wnd, 
00157                                         const CATString& command,
00158                                         CATStack<CATControl*>& controlStack)
00159 {
00160     if (wnd == 0)
00161     {
00162         return CATRESULT(CAT_ERR_SKIN_WINDOW_NOT_FOUND);
00163     }
00164 
00165     CATUInt32 numChildren = wnd->GetNumChildren();
00166     CATUInt32 i;
00167 
00168     CATXMLObject* curObj = 0;
00169     for (i = 0; i < numChildren; i++)
00170     {
00171         curObj = wnd->GetChild(i);
00172         CATControl* curControl = (CATControl*)curObj;
00173         if (curControl->GetCommand().GetCmdString().Compare(command) == 0)
00174         {
00175             controlStack.Push(curControl);
00176         }
00177     }
00178 
00179     return CAT_SUCCESS;   
00180 }
00181 
00182 //---------------------------------------------------------------------------
00183 CATResult CATSkin::OnEvent(const CATEvent& event, CATInt32& retVal)
00184 {
00185     CATResult result      = CAT_SUCCESS;
00186     CATResult testResult  = CAT_SUCCESS;
00187     CATXMLObject* curWindow = 0;
00188 
00189 
00190     CATInt32 lRes = 0;
00191 
00192     // Handle any events the skin cares about....
00193     switch (event.fEventCode)
00194     {
00195         // When windows are shown or hidden, we should notify any controls that
00196         // may be used to toggle them with the DoWindow command of the new state...
00197     case CATEVENT_WINDOW_SHOWN:
00198         result = this->OnEvent( CATEvent(CATEVENT_GUI_VAL_CHANGE_MATCHPARAM_ONLY,
00199             0,0,0,0,1.0f,"DoWindow",event.fStringParam1),lRes);
00200         break;
00201     case CATEVENT_WINDOW_HIDDEN:
00202         result = this->OnEvent( CATEvent(CATEVENT_GUI_VAL_CHANGE_MATCHPARAM_ONLY,
00203             0,0,0,0,0.0f,"DoWindow",event.fStringParam1),lRes);
00204         break;
00205     }
00206 
00207     // Now pass 'em on to children
00208     CATUInt32 numChildren = GetNumChildren();
00209     CATUInt32 i;
00210 
00211     for (i = 0; i < numChildren; i++)
00212     {
00213         curWindow = GetChild(i);
00214         testResult = ((CATWindow*)curWindow)->OnEvent(event, retVal);      
00215         if (result == CAT_SUCCESS)
00216         {
00217             result = testResult;
00218         }
00219     }  
00220     return result;
00221 }
00222 
00223 void CATSkin::OnCommand(CATCommand& command, CATControl* ctrl, CATWindow* wnd)
00224 {   
00225     // Some commands should periodically (or immediately) update all of the
00226     // windows before the command is executed, in order to make the GUI
00227     // seem responsive.  In those cases, tag the updateWindows value
00228     // to true.
00229     bool updateWindows = false;
00230 
00231     // By default, all commands go on to the app for full processing.
00232     // However, certain commands may not need to, or must be modified before
00233     // going to the app (e.g. "SetValue"). 
00234     // In these cases, the command should be processed by its handler here
00235     // and processCommand should be set to false.
00236     bool processCommand = true;
00237     CATString cmdString = command.GetCmdString();
00238     CATInt32 evRes = 0;
00239 
00240     if (cmdString.Compare("SetValue") == 0)
00241     {
00242         // SetValue is a special command, that just sets the value of
00243         // a different command string to something specific.  
00244         // It does not affect other controls with the command string of "SetValue".
00245         //    
00246         this->OnEvent(CATEvent(  CATEVENT_GUI_VAL_CHANGE, 
00247                                 0,
00248                                 0,
00249                                 0,
00250                                 0,
00251                                 command.GetValue(), 
00252                                 command.GetTarget(),
00253                                 command.GetStringParam(),
00254                                 "",
00255                                 ctrl), 
00256                        evRes);   
00257 
00258         // SetValue forces windows to update immediately, since it should typically
00259         // NOT be used on knobs (doesn't make sense to....)
00260         updateWindows = (evRes != 0);
00261         processCommand = false;
00262 
00263         // Send the actual command, not the SetValue, to the app once here.
00264         CATCommand subCommand(command.GetTarget(), command.GetValue(), command.GetStringParam(), "");
00265         gApp->OnCommand(command,0,0,this);
00266     }
00267     /// DoWindow() opens or closes a window, depending on the value of the command.
00268     else if (cmdString.Compare("DoWindow") == 0)
00269     {
00270         CATResult result = CAT_SUCCESS;
00271         CATWindow* wndOpen = 0;
00272         result = OpenWindow(command.GetStringParam(),wndOpen,0);
00273 
00274         if (wndOpen)
00275         {
00276             if (wndOpen->IsVisible())
00277             {
00278                 wndOpen->SetActive();
00279             }
00280         }
00281 
00282         if (CATFAILED(result))
00283         {
00284             gApp->DisplayError(result);
00285         }
00286     }
00287     else
00288     {
00289         if (wnd->IsTemplate())
00290         {
00291             // Templates only reflect commands within a window. Otherwise,
00292             // multiple instances of the same window would have cross-chat,
00293             // even though the instrument may NOT be the same!
00294             wnd->OnEvent(CATEvent(  CATEVENT_GUI_VAL_CHANGE, 
00295                                     0,
00296                                     0,
00297                                     0,
00298                                     0,
00299                                     command.GetValue(), 
00300                                     cmdString,
00301                                     command.GetStringParam(),
00302                                     "",
00303                                     ctrl), 
00304                          evRes);   
00305         }
00306         else
00307         {
00308             // Update any controls that use the same name for all other commands.
00309             // i.e. reflection of value between controls      
00310             this->OnEvent(CATEvent( CATEVENT_GUI_VAL_CHANGE, 
00311                                     0,
00312                                     0,
00313                                     0,
00314                                     0,
00315                                     command.GetValue(), 
00316                                     cmdString,
00317                                     command.GetStringParam(),
00318                                     "",
00319                                     ctrl), 
00320                           evRes);   
00321         }
00322 
00323         // Normal command reflection only forces window updates if they have not been
00324         // updated recently, to reduce processor load when performing fast updates.
00325         // Even if not forced, the windows will eventually update - they've been marked
00326         // invalid already.
00327         if (evRes != 0)
00328         {                     
00329             if ( ((CATFloat32)(clock() - fUpdateTime)) / (CATFloat32)CLOCKS_PER_SEC > kUPDATESPEED )
00330             {
00331                 updateWindows = true;
00332                 fUpdateTime = clock();
00333             }
00334         }
00335     }
00336 
00337 
00338     // Skin-level commands that should be reflected and stuff...
00339     if (cmdString.Compare("Browser",7) == 0)
00340     {      
00341         if (cmdString.Compare("Go",0,7) == 0)
00342         {         
00343             CATTRACE((CATString)"Browser Go: " << command.GetStringParam());
00344             this->OnEvent(CATEvent( CATEVENT_BROWSER_GO,0,0,0,0,0,
00345                                     command.GetStringParam(),
00346                                     command.GetTarget()),
00347                           evRes);
00348         }
00349         else if (cmdString.Compare("Refresh",0,7) == 0)
00350         {
00351             this->OnEvent(CATEvent( CATEVENT_BROWSER_REFRESH,0,0,0,0,0,"",command.GetTarget()),evRes);
00352         }
00353         else if (cmdString.Compare("Stop",0,7) == 0)
00354         {
00355             this->OnEvent(CATEvent( CATEVENT_BROWSER_STOP,0,0,0,0,0,"",command.GetTarget()),evRes);
00356         }
00357         else if (cmdString.Compare("Back",0,7) == 0)
00358         {
00359             this->OnEvent(CATEvent( CATEVENT_BROWSER_BACK,0,0,0,0,0,"",command.GetTarget()),evRes);
00360         }
00361         else if (cmdString.Compare("Forward",0,7) == 0)
00362         {
00363             this->OnEvent(CATEvent( CATEVENT_BROWSER_FORWARD,0,0,0,0,0,"",command.GetTarget()),evRes);
00364         }
00365         else if (cmdString.Compare("Zoom",0,7) == 0)
00366         {
00367             this->OnEvent(CATEvent( CATEVENT_BROWSER_ZOOM,0,0,0,0,command.GetValue(),"",command.GetTarget()),evRes);
00368         }
00369     }
00370 
00371     // Update windows if it's time and someone was set...
00372     if (updateWindows)
00373     {
00374         this->OnEvent(CATEvent(CATEVENT_GUI_UPDATE),evRes);
00375     }
00376 
00377     if (processCommand)
00378     {
00379         gApp->OnCommand(command,ctrl,wnd,this);   
00380     }
00381 }
00382 
00383 // OpenWindow() opens a window from the skin by name.
00384 // If the window is already open, then it just returns the handle.
00385 //
00386 // \param wndName - name of the window to open
00387 // \param window - ref to receive window if opened or already open.
00388 // \return CATResult - CAT_SUCCESS on success
00389 // CAT_STAT_SKIN_WINDOW_ALREADY_OPEN if the window is already open
00390 // CAT_ERR_SKIN_WINDOW_NOT_FOUND if window not found
00391 CATResult CATSkin::OpenWindow(const CATString& wndName, CATWindow*& window, CATWindow* parent, CATPOINT* origin)
00392 {
00393     window = this->GetWindowByName(wndName);
00394 
00395     if (window == 0)
00396     {
00397         return CATRESULT(CAT_ERR_SKIN_WINDOW_NOT_FOUND);
00398     }
00399 
00400     if (window->IsVisible())
00401     {
00402         return CATRESULT(CAT_STAT_SKIN_WINDOW_ALREADY_OPEN);
00403     }    
00404 
00405     window->Show(parent,origin);
00406 
00407     return CAT_SUCCESS;
00408 }
00409 
00410 // CloseWindow() closes the window from the skin by name.
00411 //
00412 // \param wndName - name of window to close      
00413 // \return CATResult - CAT_SUCCESS on success.
00414 //
00415 // Returns an error if the window is not open (CAT_ERR_SKIN_WINDOW_NOT_OPEN)
00416 // Or CAT_ERR_SKIN_WINDOW_NOT_FOUND if the window does not exist.
00417 CATResult CATSkin::CloseWindow(const CATString& wndName)
00418 {
00419     CATWindow* window = this->GetWindowByName(wndName);
00420 
00421     if (window == 0)
00422     {
00423         return CATRESULT(CAT_ERR_SKIN_WINDOW_NOT_FOUND);
00424     }
00425 
00426     if (window->IsVisible() == false)
00427     {
00428         return CATRESULT(CAT_ERR_SKIN_WINDOW_NOT_OPEN);
00429     }
00430 
00431     window->Hide(true);
00432 
00433     return CAT_SUCCESS;
00434 }
00435 
00436 void CATSkin::CloseAll()
00437 {
00438     CATXMLObject* curWindow = 0;
00439     CATUInt32 numChildren = GetNumChildren();
00440     for (CATUInt32 i = 0; i < numChildren; i++)
00441     {
00442         curWindow = GetChild(i);
00443         ((CATWindow*)curWindow)->Hide(true);
00444     }
00445 }
00446 
00447 /// Load() loads the skin in.
00448 CATResult CATSkin::Load(  CATPROGRESSCB             progressCB,
00449                         void*                           progressParam,
00450                         CATFloat32                      progMin,
00451                         CATFloat32                      progMax)
00452 {
00453     CATResult result = CAT_SUCCESS;
00454     result = CATGuiObj::Load(progressCB, progressParam, progMin, progMax);
00455     return result;
00456 }

Generated on Mon Feb 11 04:09:56 2008 for Game Accessibility Suite by doxygen 1.5.4