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 <math.h>
00026 #include "ctrl_radialslider.hpp"
00027 #include "../events/evt_mouse.hpp"
00028 #include "../src/generic_bitmap.hpp"
00029 #include "../src/generic_window.hpp"
00030 #include "../src/os_factory.hpp"
00031 #include "../src/os_graphics.hpp"
00032 #include "../utils/position.hpp"
00033 #include "../utils/var_percent.hpp"
00034
00035
00036 CtrlRadialSlider::CtrlRadialSlider( intf_thread_t *pIntf,
00037 const GenericBitmap &rBmpSeq, int numImg,
00038 VarPercent &rVariable, float minAngle,
00039 float maxAngle, const UString &rHelp,
00040 VarBool *pVisible ):
00041 CtrlGeneric( pIntf, rHelp, pVisible ), m_fsm( pIntf ), m_numImg( numImg ),
00042 m_rVariable( rVariable ), m_minAngle( minAngle ), m_maxAngle( maxAngle ),
00043 m_cmdUpDown( this ), m_cmdDownUp( this ),
00044 m_cmdMove( this )
00045 {
00046
00047 OSFactory *pOsFactory = OSFactory::instance( getIntf() );
00048 m_pImgSeq = pOsFactory->createOSGraphics( rBmpSeq.getWidth(),
00049 rBmpSeq.getHeight() );
00050 m_pImgSeq->drawBitmap( rBmpSeq, 0, 0 );
00051
00052 m_width = rBmpSeq.getWidth();
00053 m_height = rBmpSeq.getHeight() / numImg;
00054
00055
00056 m_fsm.addState( "up" );
00057 m_fsm.addState( "down" );
00058
00059
00060 m_fsm.addTransition( "up", "mouse:left:down", "down", &m_cmdUpDown );
00061 m_fsm.addTransition( "down", "mouse:left:up", "up", &m_cmdDownUp );
00062 m_fsm.addTransition( "down", "motion", "down", &m_cmdMove );
00063
00064
00065 m_fsm.setState( "up" );
00066
00067
00068 m_rVariable.addObserver( this );
00069 }
00070
00071
00072 CtrlRadialSlider::~CtrlRadialSlider()
00073 {
00074 m_rVariable.delObserver( this );
00075 SKINS_DELETE( m_pImgSeq );
00076 }
00077
00078
00079 void CtrlRadialSlider::handleEvent( EvtGeneric &rEvent )
00080 {
00081
00082 m_pEvt = &rEvent;
00083
00084 m_fsm.handleTransition( rEvent.getAsString() );
00085 }
00086
00087
00088 bool CtrlRadialSlider::mouseOver( int x, int y ) const
00089 {
00090 return m_pImgSeq->hit( x, y + m_position * m_height );
00091 }
00092
00093
00094 void CtrlRadialSlider::draw( OSGraphics &rImage, int xDest, int yDest )
00095 {
00096 rImage.drawGraphics( *m_pImgSeq, 0, m_position * m_height, xDest, yDest,
00097 m_width, m_height );
00098 }
00099
00100
00101 void CtrlRadialSlider::onUpdate( Subject<VarPercent> &rVariable )
00102 {
00103 m_position = (int)( m_rVariable.get() * m_numImg );
00104 notifyLayout( m_width, m_height );
00105 }
00106
00107
00108 void CtrlRadialSlider::CmdUpDown::execute()
00109 {
00110 EvtMouse *pEvtMouse = (EvtMouse*)m_pParent->m_pEvt;
00111
00112
00113 m_pParent->setCursor( pEvtMouse->getXPos(), pEvtMouse->getYPos(), false );
00114
00115 m_pParent->captureMouse();
00116 }
00117
00118
00119 void CtrlRadialSlider::CmdDownUp::execute()
00120 {
00121 m_pParent->releaseMouse();
00122 }
00123
00124
00125 void CtrlRadialSlider::CmdMove::execute()
00126 {
00127 EvtMouse *pEvtMouse = (EvtMouse*)m_pParent->m_pEvt;
00128
00129
00130 m_pParent->setCursor( pEvtMouse->getXPos(), pEvtMouse->getYPos(), true );
00131 }
00132
00133
00134 void CtrlRadialSlider::setCursor( int posX, int posY, bool blocking )
00135 {
00136
00137 const Position *pPos = getPosition();
00138 if( !pPos )
00139 {
00140 return;
00141 }
00142
00143
00144 int x = posX - pPos->getLeft() - m_width / 2;
00145 int y = posY - pPos->getTop() - m_width / 2;
00146
00147
00148 float r = sqrt((float)(x*x + y*y));
00149 if( r == 0 )
00150 {
00151 return;
00152 }
00153 float angle = acos(y/r);
00154 if( x > 0 )
00155 {
00156 angle = 2*M_PI - angle;
00157 }
00158
00159 if( angle >= m_minAngle && angle <= m_maxAngle )
00160 {
00161 float newVal = (angle - m_minAngle) / (m_maxAngle - m_minAngle);
00162
00163 if( !blocking || fabs( m_rVariable.get() - newVal ) < 0.5 )
00164 {
00165 m_rVariable.set( newVal );
00166 }
00167 }
00168 }
00169