00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "ctrl_slider.hpp"
00026 #include "../events/evt_enter.hpp"
00027 #include "../events/evt_mouse.hpp"
00028 #include "../events/evt_scroll.hpp"
00029 #include "../src/generic_bitmap.hpp"
00030 #include "../src/top_window.hpp"
00031 #include "../src/os_factory.hpp"
00032 #include "../src/os_graphics.hpp"
00033 #include "../utils/position.hpp"
00034 #include "../utils/var_percent.hpp"
00035
00036
00037 #define RANGE 40
00038 #define SCROLL_STEP 0.05f
00039
00040
00041 CtrlSliderCursor::CtrlSliderCursor( intf_thread_t *pIntf,
00042 const GenericBitmap &rBmpUp,
00043 const GenericBitmap &rBmpOver,
00044 const GenericBitmap &rBmpDown,
00045 const Bezier &rCurve,
00046 VarPercent &rVariable,
00047 VarBool *pVisible,
00048 const UString &rTooltip,
00049 const UString &rHelp ):
00050 CtrlGeneric( pIntf, rHelp, pVisible ), m_fsm( pIntf ),
00051 m_rVariable( rVariable ), m_tooltip( rTooltip ),
00052 m_width( rCurve.getWidth() ), m_height( rCurve.getHeight() ),
00053 m_cmdOverDown( this ), m_cmdDownOver( this ),
00054 m_cmdOverUp( this ), m_cmdUpOver( this ),
00055 m_cmdMove( this ), m_cmdScroll( this ),
00056 m_lastPercentage( 0 ), m_xOffset( 0 ), m_yOffset( 0 ),
00057 m_pEvt( NULL ), m_rCurve( rCurve )
00058 {
00059
00060 OSFactory *pOsFactory = OSFactory::instance( getIntf() );
00061 m_pImgUp = pOsFactory->createOSGraphics( rBmpUp.getWidth(),
00062 rBmpUp.getHeight() );
00063 m_pImgUp->drawBitmap( rBmpUp, 0, 0 );
00064 m_pImgDown = pOsFactory->createOSGraphics( rBmpDown.getWidth(),
00065 rBmpDown.getHeight() );
00066 m_pImgDown->drawBitmap( rBmpDown, 0, 0 );
00067 m_pImgOver = pOsFactory->createOSGraphics( rBmpOver.getWidth(),
00068 rBmpOver.getHeight() );
00069 m_pImgOver->drawBitmap( rBmpOver, 0, 0 );
00070
00071
00072 m_fsm.addState( "up" );
00073 m_fsm.addState( "over" );
00074 m_fsm.addState( "down" );
00075
00076
00077 m_fsm.addTransition( "over", "mouse:left:down", "down",
00078 &m_cmdOverDown );
00079 m_fsm.addTransition( "down", "mouse:left:up", "over",
00080 &m_cmdDownOver );
00081 m_fsm.addTransition( "over", "leave", "up", &m_cmdOverUp );
00082 m_fsm.addTransition( "up", "enter", "over", &m_cmdUpOver );
00083 m_fsm.addTransition( "down", "motion", "down", &m_cmdMove );
00084 m_fsm.addTransition( "over", "scroll", "over", &m_cmdScroll );
00085
00086
00087 m_fsm.setState( "up" );
00088 m_pImg = m_pImgUp;
00089
00090
00091 m_rVariable.addObserver( this );
00092
00093
00094 m_lastPercentage = m_rVariable.get();
00095 }
00096
00097
00098 CtrlSliderCursor::~CtrlSliderCursor()
00099 {
00100 m_rVariable.delObserver( this );
00101 SKINS_DELETE( m_pImgUp );
00102 SKINS_DELETE( m_pImgDown );
00103 SKINS_DELETE( m_pImgOver );
00104 }
00105
00106
00107 void CtrlSliderCursor::handleEvent( EvtGeneric &rEvent )
00108 {
00109
00110 m_pEvt = &rEvent;
00111
00112 m_fsm.handleTransition( rEvent.getAsString() );
00113 }
00114
00115
00116 bool CtrlSliderCursor::mouseOver( int x, int y ) const
00117 {
00118 if( m_pImg )
00119 {
00120
00121 int xPos, yPos;
00122 m_rCurve.getPoint( m_rVariable.get(), xPos, yPos );
00123
00124
00125 float factorX, factorY;
00126 getResizeFactors( factorX, factorY );
00127 xPos = (int)(xPos * factorX);
00128 yPos = (int)(yPos * factorY);
00129
00130 return m_pImg->hit( x - xPos + m_pImg->getWidth() / 2,
00131 y - yPos + m_pImg->getHeight() / 2 );
00132 }
00133 else
00134 {
00135 return false;
00136 }
00137 }
00138
00139
00140 void CtrlSliderCursor::draw( OSGraphics &rImage, int xDest, int yDest )
00141 {
00142 if( m_pImg )
00143 {
00144
00145 int xPos, yPos;
00146 m_rCurve.getPoint( m_rVariable.get(), xPos, yPos );
00147
00148
00149 float factorX, factorY;
00150 getResizeFactors( factorX, factorY );
00151 xPos = (int)(xPos * factorX);
00152 yPos = (int)(yPos * factorY);
00153
00154
00155 rImage.drawGraphics( *m_pImg, 0, 0,
00156 xDest + xPos - m_pImg->getWidth() / 2,
00157 yDest + yPos - m_pImg->getHeight() / 2 );
00158 }
00159 }
00160
00161
00162 void CtrlSliderCursor::onUpdate( Subject<VarPercent> &rVariable )
00163 {
00164
00165 if( m_pImg )
00166 {
00167 notifyLayout( m_rCurve.getWidth() + m_pImg->getWidth(),
00168 m_rCurve.getHeight() + m_pImg->getHeight(),
00169 - m_pImg->getWidth() / 2,
00170 - m_pImg->getHeight() / 2 );
00171 }
00172 else
00173 notifyLayout();
00174 }
00175
00176
00177 void CtrlSliderCursor::CmdOverDown::execute()
00178 {
00179 EvtMouse *pEvtMouse = (EvtMouse*)m_pParent->m_pEvt;
00180
00181
00182 float factorX, factorY;
00183 m_pParent->getResizeFactors( factorX, factorY );
00184
00185
00186 const Position *pPos = m_pParent->getPosition();
00187
00188
00189 int tempX, tempY;
00190 m_pParent->m_rCurve.getPoint( m_pParent->m_rVariable.get(), tempX, tempY );
00191 m_pParent->m_xOffset = pEvtMouse->getXPos() - pPos->getLeft()
00192 - (int)(tempX * factorX);
00193 m_pParent->m_yOffset = pEvtMouse->getYPos() - pPos->getTop()
00194 - (int)(tempY * factorY);
00195
00196 m_pParent->captureMouse();
00197 m_pParent->m_pImg = m_pParent->m_pImgDown;
00198 if( m_pParent->m_pImg )
00199 {
00200 m_pParent->notifyLayout(
00201 m_pParent->m_rCurve.getWidth() + m_pParent->m_pImg->getWidth(),
00202 m_pParent->m_rCurve.getHeight() + m_pParent->m_pImg->getHeight(),
00203 - m_pParent->m_pImg->getWidth() / 2,
00204 - m_pParent->m_pImg->getHeight() / 2 );
00205 }
00206 else
00207 m_pParent->notifyLayout();
00208 }
00209
00210
00211 void CtrlSliderCursor::CmdDownOver::execute()
00212 {
00213
00214 m_pParent->m_lastPercentage = m_pParent->m_rVariable.get();
00215
00216 m_pParent->releaseMouse();
00217 m_pParent->m_pImg = m_pParent->m_pImgUp;
00218 if( m_pParent->m_pImg )
00219 {
00220 m_pParent->notifyLayout(
00221 m_pParent->m_rCurve.getWidth() + m_pParent->m_pImg->getWidth(),
00222 m_pParent->m_rCurve.getHeight() + m_pParent->m_pImg->getHeight(),
00223 - m_pParent->m_pImg->getWidth() / 2,
00224 - m_pParent->m_pImg->getHeight() / 2 );
00225 }
00226 else
00227 m_pParent->notifyLayout();
00228 }
00229
00230
00231 void CtrlSliderCursor::CmdUpOver::execute()
00232 {
00233 m_pParent->m_pImg = m_pParent->m_pImgOver;
00234 if( m_pParent->m_pImg )
00235 {
00236 m_pParent->notifyLayout(
00237 m_pParent->m_rCurve.getWidth() + m_pParent->m_pImg->getWidth(),
00238 m_pParent->m_rCurve.getHeight() + m_pParent->m_pImg->getHeight(),
00239 - m_pParent->m_pImg->getWidth() / 2,
00240 - m_pParent->m_pImg->getHeight() / 2 );
00241 }
00242 else
00243 m_pParent->notifyLayout();
00244 }
00245
00246
00247 void CtrlSliderCursor::CmdOverUp::execute()
00248 {
00249 m_pParent->m_pImg = m_pParent->m_pImgUp;
00250 if( m_pParent->m_pImg )
00251 {
00252 m_pParent->notifyLayout(
00253 m_pParent->m_rCurve.getWidth() + m_pParent->m_pImg->getWidth(),
00254 m_pParent->m_rCurve.getHeight() + m_pParent->m_pImg->getHeight(),
00255 - m_pParent->m_pImg->getWidth() / 2,
00256 - m_pParent->m_pImg->getHeight() / 2 );
00257 }
00258 else
00259 m_pParent->notifyLayout();
00260 }
00261
00262
00263 void CtrlSliderCursor::CmdMove::execute()
00264 {
00265 EvtMouse *pEvtMouse = (EvtMouse*)m_pParent->m_pEvt;
00266
00267
00268 const Position *pPos = m_pParent->getPosition();
00269
00270
00271 float factorX, factorY;
00272 m_pParent->getResizeFactors( factorX, factorY );
00273
00274
00275 float relX = pEvtMouse->getXPos() - pPos->getLeft() - m_pParent->m_xOffset;
00276 float relY = pEvtMouse->getYPos() - pPos->getTop() - m_pParent->m_yOffset;
00277
00278 int relXPond = (int)(relX / factorX);
00279 int relYPond = (int)(relY / factorY);
00280
00281
00282 if( m_pParent->m_rCurve.getMinDist( relXPond, relYPond ) < RANGE )
00283 {
00284 float percentage = m_pParent->m_rCurve.getNearestPercent( relXPond,
00285 relYPond );
00286 m_pParent->m_rVariable.set( percentage );
00287 }
00288 else
00289 {
00290 m_pParent->m_rVariable.set( m_pParent->m_lastPercentage );
00291 }
00292 }
00293
00294 void CtrlSliderCursor::CmdScroll::execute()
00295 {
00296 EvtScroll *pEvtScroll = (EvtScroll*)m_pParent->m_pEvt;
00297
00298 int direction = pEvtScroll->getDirection();
00299
00300 float percentage = m_pParent->m_rVariable.get();
00301 if( direction == EvtScroll::kUp )
00302 {
00303 percentage += SCROLL_STEP;
00304 }
00305 else
00306 {
00307 percentage -= SCROLL_STEP;
00308 }
00309
00310 m_pParent->m_rVariable.set( percentage );
00311 }
00312
00313
00314 void CtrlSliderCursor::getResizeFactors( float &rFactorX,
00315 float &rFactorY ) const
00316 {
00317
00318 const Position *pPos = getPosition();
00319
00320 rFactorX = 1.0;
00321 rFactorY = 1.0;
00322
00323
00324 if( m_width > 0 )
00325 {
00326 rFactorX = (float)pPos->getWidth() / (float)m_width;
00327 }
00328 if( m_height > 0 )
00329 {
00330 rFactorY = (float)pPos->getHeight() / (float)m_height;
00331 }
00332 }
00333
00334
00335
00336 CtrlSliderBg::CtrlSliderBg( intf_thread_t *pIntf, CtrlSliderCursor &rCursor,
00337 const Bezier &rCurve, VarPercent &rVariable,
00338 int thickness, VarBool *pVisible,
00339 const UString &rHelp ):
00340 CtrlGeneric( pIntf, rHelp, pVisible ), m_rCursor( rCursor ),
00341 m_rVariable( rVariable ), m_thickness( thickness ), m_rCurve( rCurve ),
00342 m_width( rCurve.getWidth() ), m_height( rCurve.getHeight() )
00343 {
00344 }
00345
00346
00347 bool CtrlSliderBg::mouseOver( int x, int y ) const
00348 {
00349
00350 float factorX, factorY;
00351 getResizeFactors( factorX, factorY );
00352
00353 return (m_rCurve.getMinDist( (int)(x / factorX),
00354 (int)(y / factorY) ) < m_thickness );
00355 }
00356
00357
00358 void CtrlSliderBg::handleEvent( EvtGeneric &rEvent )
00359 {
00360 if( rEvent.getAsString().find( "mouse:left:down" ) != string::npos )
00361 {
00362
00363 float factorX, factorY;
00364 getResizeFactors( factorX, factorY );
00365
00366
00367 const Position *pPos = getPosition();
00368
00369
00370 EvtMouse &rEvtMouse = (EvtMouse&)rEvent;
00371 int x = rEvtMouse.getXPos();
00372 int y = rEvtMouse.getYPos();
00373 m_rVariable.set( m_rCurve.getNearestPercent(
00374 (int)((x - pPos->getLeft()) / factorX),
00375 (int)((y - pPos->getTop()) / factorY) ) );
00376
00377
00378 EvtMouse evt( getIntf(), x, y, EvtMouse::kLeft, EvtMouse::kDown );
00379 TopWindow *pWin = getWindow();
00380 if( pWin )
00381 {
00382 EvtEnter evtEnter( getIntf() );
00383
00384 pWin->forwardEvent( evtEnter, m_rCursor );
00385 pWin->forwardEvent( evt, m_rCursor );
00386 }
00387 }
00388 else if( rEvent.getAsString().find( "scroll" ) != string::npos )
00389 {
00390 int direction = ((EvtScroll&)rEvent).getDirection();
00391
00392 float percentage = m_rVariable.get();
00393 if( direction == EvtScroll::kUp )
00394 {
00395 percentage += SCROLL_STEP;
00396 }
00397 else
00398 {
00399 percentage -= SCROLL_STEP;
00400 }
00401
00402 m_rVariable.set( percentage );
00403 }
00404 }
00405
00406
00407 void CtrlSliderBg::getResizeFactors( float &rFactorX, float &rFactorY ) const
00408 {
00409
00410 const Position *pPos = getPosition();
00411
00412 rFactorX = 1.0;
00413 rFactorY = 1.0;
00414
00415
00416 if( m_width > 0 )
00417 {
00418 rFactorX = (float)pPos->getWidth() / (float)m_width;
00419 }
00420 if( m_height > 0 )
00421 {
00422 rFactorY = (float)pPos->getHeight() / (float)m_height;
00423 }
00424 }
00425