![[]](/images/special/trans.gif)
LibN2L-4 Library Code ReferenceClassesCompounds Files Members Method Index Full Reference cGuiSlider.cppGo to the documentation of this file.00001 /************************************************************************ 00002 Nova-2 Library (libN2L, or simply n2l) Game development C++ Library 00003 Copyright (C) 2002 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 "gui/cGuiSlider.h" 00026 00027 #include "n2l/dynVars.h" 00028 #include "n2l/resourceManagement.h" 00029 #include "n2l/events.h" 00030 00031 #include "gui/cGuiFactory.h" 00032 00033 namespace n2l 00034 { 00035 # ifdef N2L_PASSIVE_GUI_REG 00036 tBool cGuiSlider::smRegistered = 00037 cGuiFactory::current().registerLoader( 00038 "n2l::cGuiSlider", cGuiElement::loadNew<cGuiSlider> ); 00039 # endif 00040 00041 /**************************************************************************/ 00042 cGuiSlider::cGuiSlider() : 00043 mMin(0), 00044 mMax(100), 00045 mValue(0), 00046 mRequestedRange(1), 00047 mAlignment( Align_Vertical ), 00048 mSwapWheel(false), 00049 mOverSlider(false), 00050 mDownOnSlider(false) 00051 { 00052 for (tSint i=State_Normal; i<State_NumStates; ++i) { 00053 mFills[ Prop_Background ][i].colour( 00054 cColour(0.8f,0.8f,0.8f, 1.0f) ); 00055 mFills[ Prop_Slider ][i].colour( cColour(1.0f,1.0f,1.0f, 1.0f) ); 00056 } 00057 00058 dimensionChanged(); 00059 } 00060 00061 /**************************************************************************/ 00062 cGuiSlider::cGuiSlider( const cVfsNodeInterface &iNode ) : 00063 mMin(0), 00064 mMax(100), 00065 mValue(0), 00066 mRequestedRange(1), 00067 mAlignment( Align_Vertical ), 00068 mSwapWheel(false), 00069 mOverSlider(false), 00070 mDownOnSlider(false) 00071 { 00072 for (tSint i=State_Normal; i<State_NumStates; ++i) { 00073 mFills[ Prop_Background ][i].colour( 00074 cColour(0.8f,0.8f,0.8f, 1.0f) ); 00075 mFills[ Prop_Slider ][i].colour( cColour(1.0f,1.0f,1.0f, 1.0f) ); 00076 } 00077 00078 load(iNode); 00079 } 00080 00081 /**************************************************************************/ 00082 cGuiSlider::cGuiSlider( const cDynVar &iDefinition ) : 00083 mMin(0), 00084 mMax(100), 00085 mValue(0), 00086 mRequestedRange(1), 00087 mAlignment( Align_Vertical ), 00088 mSwapWheel(false), 00089 mOverSlider(false), 00090 mDownOnSlider(false) 00091 { 00092 for (tSint i=State_Normal; i<State_NumStates; ++i) { 00093 mFills[ Prop_Background ][i].colour( 00094 cColour(0.8f,0.8f,0.8f, 1.0f) ); 00095 mFills[ Prop_Slider ][i].colour( cColour(1.0f,1.0f,1.0f, 1.0f) ); 00096 } 00097 00098 load(iDefinition); 00099 } 00100 00101 /**************************************************************************/ 00102 cGuiSlider::~cGuiSlider() 00103 { 00104 } 00105 00106 /**************************************************************************/ 00107 void cGuiSlider::load( const cVfsNodeInterface &iNode ) 00108 { 00109 cDynVar def; 00110 validateAndDecode( def, iNode, "n2l::cGuiSlider" ); 00111 load( def ); 00112 } 00113 00114 /**************************************************************************/ 00115 void cGuiSlider::load( const cDynVar & iDefinition ) 00116 { 00117 // Load parent properties 00118 cGuiInteractive::load( iDefinition ); 00119 00120 if (iDefinition["fill"]) { 00121 for (tSint p=Prop_Background; p!=Prop_NumProps; ++p) { 00122 if (iDefinition["fill"].keyExists(p)) { 00123 for (tSint s=State_Normal; s!=State_NumStates; ++s) 00124 if (iDefinition["fill"][p].keyExists(s)) { 00125 if (iDefinition["fill"][p][s].isArray()) 00126 fill(tProp(p), tState(s), 00127 iDefinition["fill"][p][s] ); 00128 else 00129 fill(tProp(p), tState(s), 00130 *cResourceManager::get<cGuiFill>( 00131 iDefinition["fill"][p][s] ) ); 00132 } // if defi.. 00133 } // if prop 00134 } // for props 00135 } // if fills 00136 00137 if (iDefinition.keyExists("range")) range(iDefinition["range"]); 00138 if (iDefinition.keyExists("min")) min(iDefinition["min"]); 00139 if (iDefinition.keyExists("max")) max(iDefinition["max"]); 00140 if (iDefinition.keyExists("value")) value(iDefinition["value"]); 00141 if (iDefinition.keyExists("swapWheel")) 00142 swapWheel(iDefinition["swapWheel"]); 00143 00144 if (iDefinition.keyExists("alignment")) 00145 alignment( tAlignment(tSint(iDefinition["alignment"])) ); 00146 00147 dimensionChanged(); 00148 } 00149 00150 /**************************************************************************/ 00151 void cGuiSlider::draw() const 00152 { 00153 tState sliderState( State_Normal ); 00154 tState backgroundState( State_Normal ); 00155 00156 // What do we show? 00157 if (mDownOnSlider) 00158 sliderState = State_Down; 00159 else if (mOverSlider) 00160 sliderState = State_Over; 00161 00162 mFills[Prop_Background][backgroundState].draw(outerPos(),outerSize()); 00163 mFills[Prop_Slider][sliderState].draw( mSliderPos,mSliderSize ); 00164 } 00165 00166 /**************************************************************************/ 00167 void cGuiSlider::align( const tAlignment iAlign ) 00168 { 00169 mAlignment = iAlign; 00170 dimensionChanged(); 00171 } 00172 00173 /**************************************************************************/ 00174 void cGuiSlider::min( const tValue &iValue ) 00175 { 00176 mMin = iValue; 00177 dimensionChanged(); 00178 } 00179 00180 /**************************************************************************/ 00181 void cGuiSlider::value( const tValue &iValue ) 00182 { 00183 mValue = iValue; 00184 if (mValue<mMin) mValue=mMin; 00185 else if (mValue>(mMax-mRange)) mValue=(mMax-mRange); 00186 dimensionChanged(); 00187 00188 // Broadcast our event. 00189 tActionData actionData( tActionData::Array ); 00190 actionData.insert("name",mName); 00191 actionData.insert("min",mMin); 00192 actionData.insert("max",mMax); 00193 actionData.insert("value",mValue); 00194 broadcastAction( GuiActionType_SliderValueChanged, actionData ); 00195 } 00196 00197 /**************************************************************************/ 00198 const cGuiSlider::tValue & cGuiSlider::value() const 00199 { 00200 return mValue; 00201 } 00202 00203 /**************************************************************************/ 00204 void cGuiSlider::range( const tValue &iValue ) 00205 { 00206 mRequestedRange = iValue; 00207 dimensionChanged(); 00208 } 00209 00210 /**************************************************************************/ 00211 void cGuiSlider::max( const tValue &iValue ) 00212 { 00213 mMax = iValue; 00214 dimensionChanged(); 00215 } 00216 00217 /**************************************************************************/ 00218 void cGuiSlider::swapWheel( const tBool iSwap ) 00219 { 00220 mSwapWheel = iSwap; 00221 } 00222 00223 /**************************************************************************/ 00224 const tBool cGuiSlider::swapWheel() const 00225 { 00226 return mSwapWheel; 00227 } 00228 00229 /**************************************************************************/ 00230 void cGuiSlider::fill( const tProp iProp, 00231 const tState iState, 00232 const cGuiFill & iFill ) 00233 { 00234 if (iProp<Prop_Background || iProp>=Prop_NumProps) 00235 throw cOutOfBoundsException( "cGuiSlider::fill", 00236 "Property out of range" ); 00237 if (iState<State_Normal || iState>=State_NumStates) 00238 throw cOutOfBoundsException( "cGuiSlider::fill", 00239 "State out of range" ); 00240 00241 mFills[iProp][iState] = iFill; 00242 } 00243 00244 /**************************************************************************/ 00245 const cGuiSlider::tValue & cGuiSlider::min() const 00246 { 00247 return mMin; 00248 } 00249 00250 00251 /**************************************************************************/ 00252 const cGuiSlider::tValue & cGuiSlider::max() const 00253 { 00254 return mMax; 00255 } 00256 00257 /**************************************************************************/ 00258 const cGuiSlider::tValue & cGuiSlider::range() const 00259 { 00260 return mRequestedRange; 00261 } 00262 00263 /**************************************************************************/ 00264 void cGuiSlider::systemEvent( 00265 const cAutoPtr<const cEventInterface> &i_iEvent ) 00266 { 00267 switch (i_iEvent->type()) 00268 { 00269 case EventType_MouseMotion: { 00270 const cAutoPtr<const cMouseMotionEvent> Motion(i_iEvent); 00271 mouseMove( Motion->pos() ); 00272 00273 break; 00274 } 00275 00276 case EventType_MouseButton: { 00277 const cAutoPtr<const cMouseButtonEvent> Button(i_iEvent); 00278 mouseClickAt( *Button ); 00279 } 00280 00281 default: 00282 // Nothing. 00283 break; 00284 } // switch 00285 } 00286 00287 /**************************************************************************/ 00288 void cGuiSlider::mouseClickAt( const cMouseButtonEvent &iClick ) 00289 { 00290 // Do normal hotspot processing 00291 cGuiInteractive::mouseClickAt(iClick); 00292 if (iClick.button() == MouseButton_Left) { 00293 if (iClick.pressed()) { 00294 // Left Pressed 00295 if (iClick.pos().x()>=mSliderPos.x() && 00296 iClick.pos().x()<=(mSliderPos.x()+mSliderSize.x()) && 00297 iClick.pos().y()>=mSliderPos.y() && 00298 iClick.pos().y()<=(mSliderPos.y()+mSliderSize.y())) 00299 { 00300 mDownOnSlider = true; 00301 mDownOffset = iClick.pos()-mSliderPos; 00302 } else if (isOver()) { 00303 // Is over and pressed. 00304 if (mAlignment==Align_Vertical) { 00305 if (iClick.pos().y()<mSliderPos.y()) 00306 value(mValue-mRange); 00307 else value(mValue+mRange); 00308 } else { 00309 if (iClick.pos().x()<mSliderPos.x()) 00310 value(mValue-mRange); 00311 else value(mValue+mRange); 00312 } 00313 } 00314 } else { 00315 // Left Released 00316 mDownOnSlider = false; 00317 } 00318 } else if ( iClick.button() == MouseButton_Up && 00319 iClick.pressed() && collides(iClick.pos()) ) { 00320 if (mSwapWheel) 00321 scrollMinus(); 00322 else 00323 scrollPlus(); 00324 } else if ( iClick.button() == MouseButton_Down && 00325 iClick.pressed() && collides(iClick.pos()) ) { 00326 if (mSwapWheel) 00327 scrollPlus(); 00328 else 00329 scrollMinus(); 00330 } 00331 } 00332 00333 /**************************************************************************/ 00334 void cGuiSlider::scrollRangePCent( const tFloat &iPCent ) 00335 { 00336 value( mValue + mRange*iPCent ); 00337 } 00338 00339 /**************************************************************************/ 00340 void cGuiSlider::scrollPlus() 00341 { 00342 scrollRangePCent( 0.1f ); 00343 } 00344 00345 /**************************************************************************/ 00346 void cGuiSlider::scrollMinus() 00347 { 00348 scrollRangePCent( -0.1f ); 00349 } 00350 00351 /**************************************************************************/ 00352 void cGuiSlider::alignment( const tAlignment iAlignment ) 00353 { 00354 if (mAlignment<0 || mAlignment>=Align_NumAlignments) 00355 throw cOutOfBoundsException( "cGuiSlider::alignment", 00356 "No such alignment: " + asString(tUint(iAlignment))); 00357 mAlignment = iAlignment; 00358 dimensionChanged(); 00359 } 00360 00361 /**************************************************************************/ 00362 void cGuiSlider::mouseMove( const tGuiPos &iPos ) 00363 { 00364 // Do normal hotspot processing 00365 cGuiInteractive::mouseMove(iPos); 00366 if (isOver()) { 00367 if (iPos.x()>=mSliderPos.x() && 00368 iPos.x()<=(mSliderPos.x()+mSliderSize.x()) && 00369 iPos.y()>=mSliderPos.y() && 00370 iPos.y()<=(mSliderPos.y()+mSliderSize.y())) 00371 mOverSlider = true; 00372 else mOverSlider = false; 00373 } else { 00374 mOverSlider = false; 00375 } 00376 00377 // Regardless, if the slider is down, follow the mouse. 00378 if (mDownOnSlider) { 00379 tGuiPos newSliderPos( iPos-mDownOffset-innerPos() ); 00380 if (mAlignment==Align_Vertical) 00381 value( newSliderPos.y()/mValueToPosScale + mMin ); 00382 else 00383 value( newSliderPos.x()/mValueToPosScale + mMin ); 00384 } 00385 } 00386 00387 /**************************************************************************/ 00388 void cGuiSlider::dimensionChanged() 00389 { 00390 cGuiInteractive::dimensionChanged(); 00391 00392 mRange = n2l_min(mRequestedRange,max()-min()); 00393 if (mAlignment==Align_Vertical) { 00394 mValueToPosScale = innerSize().y()/(mMax-mMin); 00395 00396 mSliderPos.x( innerPos().x() ); 00397 mSliderPos.y( innerPos().y()+(mValue-mMin)*mValueToPosScale ); 00398 00399 mSliderSize.x( innerSize().x() ); 00400 mSliderSize.y( mRange*mValueToPosScale ); 00401 00402 } else { 00403 mValueToPosScale = innerSize().x()/(mMax-mMin); 00404 00405 mSliderPos.x( innerPos().x()+(mValue-mMin)*mValueToPosScale ); 00406 mSliderPos.y( innerPos().y() ); 00407 00408 mSliderSize.x( mRange*mValueToPosScale ); 00409 mSliderSize.y( innerSize().y() ); 00410 } 00411 } 00412 00413 /**************************************************************************/ 00414 const cAutoPtr<cGuiElement> cGuiSlider::clone() const 00415 { 00416 cAutoPtr<cGuiElement> newElement( new cGuiSlider ); 00417 cloneInto( newElement ); 00418 return newElement; 00419 } 00420 00421 /**************************************************************************/ 00422 void cGuiSlider::cloneInto( const cAutoPtr<cGuiSlider> &i_ioElement ) const 00423 { 00424 // Parent Properties first 00425 cGuiInteractive::cloneInto( i_ioElement ); 00426 00427 for (tSint p=Prop_Background; p!=Prop_NumProps; ++p) 00428 for (tSint s=State_Normal; s!=State_NumStates; ++s) 00429 i_ioElement->fill( tProp(p), tState(s), mFills[p][s] ); 00430 00431 i_ioElement->min( mMin ); 00432 i_ioElement->max( mMax ); 00433 i_ioElement->range( mRequestedRange ); 00434 i_ioElement->value( mValue ); 00435 i_ioElement->swapWheel( mSwapWheel ); 00436 i_ioElement->alignment( mAlignment ); 00437 } 00438 00439 } // namespace n2l |