AaronCameron.net
Not Left, nor right. Just correct.
Not a Member? - Login or Create an Account
Sunday the 20th of May 2012 @ 05:05pm
Front Page Journal Projects Your Profile About
[]

LibN2L-4 Library Code Reference

Classes
Compounds
Files
Members
Method Index
Full Reference

cGuiSButton.cpp

Go to the documentation of this file.
00001 /************************************************************************
00002 Nova-2 Library (libN2L, or simply n2l) Game development C++ Library
00003 Copyright (C) 2003  Aaron Cameron
00004 
00005 This library is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU Lesser General Public
00007 License as published by the Free Software Foundation; either
00008 version 2.1 of the License, or (at your option) any later version.
00009 
00010 This library is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 Lesser General Public License for more details.
00014 
00015 You should have received a copy of the GNU Lesser General Public
00016 License along with this library; if not, write to the Free Software
00017 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00018 
00019 A copy of the GNU Lesser General Public License has been provided with
00020 this library in the file 'COPYING'.
00021 
00022 Contact information for the author of this library has been provided
00023 with this library in the file 'AUTHOR'.
00024 ************************************************************************/
00025 #include "cGuiSButton.h"
00026 
00027 #include "n2l/dynVars.h"
00028 #include "n2l/vfs.h"
00029 #include "n2l/resourceManagement.h"
00030 #include "n2l/audio.h"
00031 
00032 #include "gui/cGuiSimpleCallbackAction.h"
00033 
00034 #include "gui/cGuiFactory.h"
00035 
00036 /******************************************************************************/
00037 namespace n2l
00038 {
00039 #   ifdef N2L_PASSIVE_GUI_REG
00040         tBool cGuiSButton::smRegistered =
00041             cGuiFactory::current().registerLoader(
00042             "n2l::cGuiSButton", cGuiElement::loadNew<cGuiSButton> );
00043 #   endif
00044 
00045     /**************************************************************************/
00046     cGuiSButton::cGuiSButton()
00047     {
00048         reset();
00049     }
00050 
00051     /**************************************************************************/
00052     cGuiSButton::cGuiSButton( const cVfsNodeInterface &iNode )
00053     {
00054         reset();
00055         load( iNode );
00056     }
00057 
00058     /**************************************************************************/
00059     cGuiSButton::cGuiSButton( const cDynVar &iDef )
00060     {
00061         reset();
00062         load( iDef );
00063     }
00064 
00065     /**************************************************************************/
00066     cGuiSButton::~cGuiSButton()
00067     {
00068     }
00069 
00070     /**************************************************************************/
00071     void cGuiSButton::load( const cVfsNodeInterface &iNode )
00072     {
00073         cDynVar def;
00074         validateAndDecode( def, iNode, "n2l::cGuiSButton" );
00075         load( def );
00076     }
00077 
00078     /**************************************************************************/
00079     void cGuiSButton::load( const cDynVar &iDef )
00080     {
00081         // Load parent properties
00082         cGuiInteractive::load( iDef );
00083     
00084         if (iDef["label"])
00085             label( iDef["label"] );
00086 
00087         if (iDef.keyExists("fill")) {
00088             const cDynVar &Tmp = iDef["fill"];
00089             if (Tmp.isArray())
00090                 fill( Tmp );
00091             else
00092                 fill( *cResourceManager::get<cGuiFill>( Tmp ) );
00093         }
00094 
00095         if (iDef.keyExists("textStyle")) {
00096             const cDynVar &Tmp = iDef["textStyle"];
00097             if (Tmp.isArray())
00098                 textStyle( Tmp );
00099             else
00100                 textStyle( *cResourceManager::get<cGuiTextStyle>( Tmp ) );
00101         }
00102 
00103         if (iDef.keyExists("buttonType"))
00104             type( tType(tSint(iDef["buttonType"])) );
00105         else if (iDef.keyExists("type"))
00106             type( tType(tSint(iDef["type"])) );
00107 
00108         if (iDef.keyExists("toggledOn"))
00109             toggledOn( iDef["toggledOn"] );
00110 
00111         if (iDef.keyExists("enabled"))
00112             enabled( iDef["enabled"] );
00113 
00114         // Load the button accelerator
00115         if (iDef.keyExists("accelKey")) {
00116             tKey tmpKey =
00117                 cEventTypeLookups::lookupTypeByName(iDef["accelKey"]);
00118             if (tmpKey == Key_Unknown)
00119                 throw cBadDataUseException("cGuiSButton::load", "The provided "
00120                     "acceleration key wasn\'t recognized: " +
00121                     tString(iDef["accelKey"]) );
00122             tKeyMods tmpMod = KMod_None;
00123             if (iDef.keyExists("accelMod")) {
00124                 if (iDef["accelMod"] == "none")
00125                     tmpMod = KMod_None;
00126                 else if (iDef["accelMod"] == "shift")
00127                     tmpMod = KMod_Shift;
00128                 else if (iDef["accelMod"] == "ctrl")
00129                     tmpMod = KMod_Ctrl;
00130                 else if (iDef["accelMod"] == "alt")
00131                     tmpMod = KMod_Alt;
00132                 else if (iDef["accelMod"] == "meta")
00133                     tmpMod = KMod_Meta;
00134                 else throw cBadDataUseException("cGuiSButton::load",
00135                     "The provided acceleration key mod wasn\'t recognized: " +
00136                     tString(iDef["accelMod"]) );
00137             }
00138             setAccel( tmpKey, tmpMod );
00139         }
00140     }
00141 
00142     /**************************************************************************/
00143     void cGuiSButton::draw() const
00144     {
00145         mFill.draw( outerPos(), outerSize() );
00146 
00147         if (!mLabel.empty())
00148             mTextStyle.draw( innerPos(), innerSize(), mLabel );
00149     }
00150 
00151     /**************************************************************************/
00152     void cGuiSButton::fill( const cGuiFill &iFill )
00153     {
00154         mFill = iFill;
00155     }
00156 
00157     /**************************************************************************/
00158     const cGuiFill &cGuiSButton::fill() const
00159     {
00160         return mFill;
00161     }
00162 
00163     /**************************************************************************/
00164     void cGuiSButton::label( const tString &iLabel )
00165     {
00166         mLabel = iLabel;
00167     }
00168 
00169     /**************************************************************************/
00170     const tString & cGuiSButton::label() const
00171     {
00172         return mLabel;
00173     }
00174 
00175     /**************************************************************************/
00176     const cGuiTextStyle &cGuiSButton::textStyle() const
00177     {
00178         return mTextStyle;
00179     }
00180 
00181     /**************************************************************************/
00182     void cGuiSButton::textStyle( const cGuiTextStyle &iStyle )
00183     {
00184         mTextStyle = iStyle;
00185     }
00186 
00187     /**************************************************************************/
00188     void cGuiSButton::boundCheckType( const tType iType ) const
00189     {
00190         if (iType<0 || iType>=Type_NumTypes)
00191             throw cOutOfBoundsException( "cGuiSButton::boundCheckType",
00192                 "Type out of range" );
00193     }
00194 
00195     /**************************************************************************/
00196     void cGuiSButton::type( const tType iType )
00197     {
00198         boundCheckType( iType );
00199         mType = iType;
00200     }
00201 
00202     /**************************************************************************/
00203     const cGuiSButton::tType cGuiSButton::type() const
00204     {
00205         return mType;
00206     }
00207 
00208     /**************************************************************************/
00209     void cGuiSButton::toggledOn( const tBool iToggled )
00210     {
00211         mToggledOn = iToggled;
00212     }
00213 
00214     /**************************************************************************/    
00215     const tBool cGuiSButton::toggledOn() const
00216     {
00217         return mToggledOn;
00218     }
00219 
00220     /**************************************************************************/    
00221     void cGuiSButton::enabled( const tBool iEnabled )
00222     {
00223         mEnabled = iEnabled;
00224         
00225         tActionData actionData( tActionData::Array );
00226         addExtraDisabledData(actionData);
00227 
00228         broadcastAction( GuiActionType_DisableChanged, actionData );
00229     }
00230 
00231     /**************************************************************************/    
00232     const tBool cGuiSButton::enabled() const
00233     {
00234         return mEnabled;
00235     }
00236 
00237     /**************************************************************************/
00238     void cGuiSButton::setAccel( const tKey &iKey, const tKeyMods &iMods )
00239     {
00240         mUseAccel = true;
00241         mKey = iKey;
00242         mKeyMod = iMods;
00243     }
00244     
00245     /**************************************************************************/
00246     void cGuiSButton::clearAccel()
00247     {
00248         mUseAccel = false;
00249     }
00250 
00251     /**************************************************************************/
00252     void cGuiSButton::prop( const tString &iName, const cDynVar &iVal,
00253         const tString &iInnerKey )
00254     {
00255         if (iName == "label") 
00256             label( iVal );
00257 
00258         else if (iName == "fill") {
00259             if (iInnerKey.empty()) {
00260                 if (iVal.isArray())
00261                     fill( iVal );
00262                 else
00263                     fill( *cResourceManager::get<cGuiFill>(iVal) );
00264             } else
00265                 mFill.prop( iInnerKey, iVal );
00266 
00267         } else if (iName == "textStyle") {
00268             if (iInnerKey.empty()) {
00269                 if (iVal.isArray())
00270                     textStyle( iVal );
00271                 else
00272                     textStyle( *cResourceManager::get<cGuiTextStyle>(iVal) );
00273             } else
00274                 mTextStyle.prop( iInnerKey, iVal );
00275         }
00276 
00277 
00278         else cGuiInteractive::prop( iName, iVal );
00279     }
00280 
00281     /**************************************************************************/
00282     const cDynVar cGuiSButton::prop( const tString &iName,
00283         const tString &iInnerKey ) const
00284     {
00285         cDynVar oVal = cDynVar::Null;
00286         
00287         if (iName == "label")
00288             oVal = label();
00289 
00290         else if (iName == "fill" && !iInnerKey.empty())
00291             return mFill.prop( iInnerKey );
00292 
00293         else
00294             return cGuiInteractive::prop( iName );
00295 
00296         return oVal;
00297     }
00298 
00299     /**************************************************************************/
00300     const cAutoPtr<cGuiElement> cGuiSButton::clone() const
00301     {
00302         cAutoPtr<cGuiSButton> newElement( new cGuiSButton );
00303         cloneInto( newElement );
00304         return newElement;
00305     }
00306 
00307     /**************************************************************************/
00308     void cGuiSButton::cloneInto( const cAutoPtr<cGuiSButton> &ioElement ) const
00309     {
00310         // Parent Properties first
00311         cGuiInteractive::cloneInto( ioElement );
00312         
00313         //  Now our properties.
00314         ioElement->label( label() );
00315         ioElement->toggledOn( toggledOn() );
00316         ioElement->type( type() );
00317         ioElement->enabled( enabled() );
00318 
00319         ioElement->mUseAccel = mUseAccel;
00320         ioElement->mKey = mKey;
00321         ioElement->mKeyMod = mKeyMod;
00322 
00323         ioElement->fill( fill() );
00324         ioElement->textStyle( textStyle() );
00325 
00326     }
00327 
00328     /**************************************************************************/
00329     void cGuiSButton::reset()
00330     {
00331         mLabel = "Button";
00332         mType = Type_Push;
00333         mToggledOn = false;
00334         mEnabled = true;
00335 
00336         bindAction( GuiActionType_Clicked,
00337             new cGuiSimpleCallbackAction<cGuiSButton::clickedCallback>,
00338             false );
00339                     
00340         bindAction( GuiActionType_Keystroke,
00341             new cGuiSimpleCallbackAction<cGuiSButton::keystrokeCallback>,
00342             false );
00343         bindAction( GuiActionType_KeystrokeOutside,
00344             new cGuiSimpleCallbackAction<cGuiSButton::keystrokeCallback>,
00345             false );
00346 
00347     }
00348 
00349     /**************************************************************************/
00350     void cGuiSButton::clickedCallback(  cGuiElement *const ioElement,
00351         const tGuiActionType iType, const tActionData &iData )
00352     {
00353         cGuiSButton *const button( dynamic_cast<cGuiSButton*>(ioElement) );
00354         // Do the toggle if we need to
00355         if (button->mType==Type_Toggle)
00356             button->mToggledOn = !button->mToggledOn;
00357     }
00358 
00359     /**************************************************************************/
00360     void cGuiSButton::keystrokeCallback( cGuiElement *const i_ioElement,
00361         const tGuiActionType iType, const tActionData &iData )
00362     {
00363         cGuiSButton *const button( dynamic_cast<cGuiSButton*>(i_ioElement) );
00364 
00365         // Do we just ignore it?
00366         if (!button->mUseAccel || !iData["pressed"]) return;
00367         tKey tmpKey = tKey(tSint(iData["key"]));
00368         tKeyMod tmpMod = tKeyMod(tSint(iData["mods"]));
00369 
00370         if (tmpKey== button->mKey && (tmpMod & button->mKeyMod ||
00371             button->mKeyMod == KMod_None) )
00372         {
00373             // This may eventually not work, but for the moment it 
00374             // should be fine.
00375 
00376             // Ok, I've already been diddled by this.  We can't set the
00377             // event up in the constructor because it is treated as a
00378             // system position (that means it may be scaled automatically).
00379             // Instead we need to use the regular set method for the position.
00380             cMouseButtonEvent tmpEvent( button->pos(), MouseButton_Left, true );
00381             tmpEvent.pos( button->pos() );
00382             button->mouseClickAt( tmpEvent );
00383             tmpEvent.pressed(false);
00384             button->mouseClickAt( tmpEvent );
00385         }
00386     }
00387 
00388     /**************************************************************************/
00389     void cGuiSButton::addExtraClickedData( tActionData &oData )
00390     {
00391         cGuiInteractive::addExtraClickedData(oData);
00392 
00393         // Send ! toggled because we get called before the callback
00394         // which changes our status
00395         if (mType==Type_Toggle)
00396             oData.insert( "toggled", tSint(!mToggledOn) );
00397 
00398         oData.insert( "enabled", tSint(mEnabled) );
00399     }
00400 
00401     /**************************************************************************/
00402     void cGuiSButton::addExtraOverData( tActionData &oData )
00403     {
00404         cGuiInteractive::addExtraOverData(oData);
00405         
00406         oData.insert( "enabled", tSint(mEnabled) );
00407         if (mType==Type_Toggle)
00408             oData.insert( "toggled", tSint(mToggledOn) );
00409     }
00410 
00411     /**************************************************************************/
00412     void cGuiSButton::addExtraOutData( tActionData &oData )
00413     {
00414         cGuiInteractive::addExtraOutData(oData);
00415         
00416         oData.insert( "enabled", tSint(mEnabled) );
00417         if (mType==Type_Toggle)
00418             oData.insert( "toggled", tSint(mToggledOn) );
00419     }
00420 
00421     /**************************************************************************/
00422     void cGuiSButton::addExtraPressedData( tActionData &oData )
00423     {
00424         cGuiInteractive::addExtraPressedData(oData);
00425         
00426         oData.insert( "enabled", tSint(mEnabled) );
00427         if (mType==Type_Toggle)
00428             oData.insert( "toggled", tSint(mToggledOn) );
00429     }
00430 
00431     /**************************************************************************/
00432     void cGuiSButton::addExtraReleasedData( tActionData &oData )
00433     {
00434         cGuiInteractive::addExtraReleasedData(oData);
00435         
00436         oData.insert( "enabled", tSint(mEnabled) );
00437         if (mType==Type_Toggle)
00438             oData.insert( "toggled", tSint(mToggledOn) );
00439     }
00440 
00441     /**************************************************************************/
00442     void cGuiSButton::addExtraDisabledData( tActionData &oData )
00443     {
00444         oData.insert( "enabled", mEnabled );
00445     }
00446 
00447 } // namespace n2l
©2012 Aaron Cameron