![[]](/images/special/trans.gif)
LibN2L-4 Library Code ReferenceClassesCompounds Files Members Method Index Full Reference cGuiSButton.cppGo 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 |