Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

ctrl_radialslider.cpp

00001 /*****************************************************************************
00002  * ctrl_radialslider.cpp
00003  *****************************************************************************
00004  * Copyright (C) 2003 the VideoLAN team
00005  * $Id: ctrl_radialslider.cpp 12207 2005-08-15 15:54:32Z asmax $
00006  *
00007  * Authors: Cyril Deguet     <[email protected]>
00008  *          Olivier Teulière <[email protected]>
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
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     // Build the images of the sequence
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     // States
00056     m_fsm.addState( "up" );
00057     m_fsm.addState( "down" );
00058 
00059     // Transitions
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     // Initial state
00065     m_fsm.setState( "up" );
00066 
00067     // Observe the variable
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     // Save the event to use it in callbacks
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     // Change the position of the cursor, in non-blocking mode
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     // Change the position of the cursor, in blocking mode
00130     m_pParent->setCursor( pEvtMouse->getXPos(), pEvtMouse->getYPos(), true );
00131 }
00132 
00133 
00134 void CtrlRadialSlider::setCursor( int posX, int posY, bool blocking )
00135 {
00136     // Get the position of the control
00137     const Position *pPos = getPosition();
00138     if( !pPos )
00139     {
00140         return;
00141     }
00142 
00143     // Compute the position relative to the center
00144     int x = posX - pPos->getLeft() - m_width / 2;
00145     int y = posY - pPos->getTop() - m_width / 2;
00146 
00147     // Compute the polar coordinates. angle is -(-j,OM)
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         // Avoid too fast moves of the cursor if blocking mode
00163         if( !blocking || fabs( m_rVariable.get() - newVal ) < 0.5 )
00164         {
00165             m_rVariable.set( newVal );
00166         }
00167     }
00168 }
00169 

Generated on Tue Dec 20 10:14:41 2005 for vlc-0.8.4a by  doxygen 1.4.2