ctrl_radialslider.cpp
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:5k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * ctrl_radialslider.cpp
  3.  *****************************************************************************
  4.  * Copyright (C) 2003 VideoLAN
  5.  * $Id: ctrl_radialslider.cpp 6961 2004-03-05 17:34:23Z sam $
  6.  *
  7.  * Authors: Cyril Deguet     <asmax@via.ecp.fr>
  8.  *          Olivier Teuli鑢e <ipkiss@via.ecp.fr>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  23.  *****************************************************************************/
  24. #include <math.h>
  25. #include "ctrl_radialslider.hpp"
  26. #include "../events/evt_mouse.hpp"
  27. #include "../src/generic_bitmap.hpp"
  28. #include "../src/generic_window.hpp"
  29. #include "../src/os_factory.hpp"
  30. #include "../src/os_graphics.hpp"
  31. #include "../utils/position.hpp"
  32. #include "../utils/var_percent.hpp"
  33. CtrlRadialSlider::CtrlRadialSlider( intf_thread_t *pIntf,
  34.                                     const GenericBitmap &rBmpSeq, int numImg,
  35.                                     VarPercent &rVariable, float minAngle,
  36.                                     float maxAngle, const UString &rHelp,
  37.                                     VarBool *pVisible ):
  38.     CtrlGeneric( pIntf, rHelp, pVisible ), m_fsm( pIntf ), m_numImg( numImg ),
  39.     m_rVariable( rVariable ), m_minAngle( minAngle ), m_maxAngle( maxAngle ),
  40.     m_cmdUpDown( this, &transUpDown ), m_cmdDownUp( this, &transDownUp ),
  41.     m_cmdMove( this, &transMove ), m_position( 0 ), m_lastPos( 0 )
  42. {
  43.     // Build the images of the sequence
  44.     OSFactory *pOsFactory = OSFactory::instance( getIntf() );
  45.     m_pImgSeq = pOsFactory->createOSGraphics( rBmpSeq.getWidth(),
  46.                                               rBmpSeq.getHeight() );
  47.     m_pImgSeq->drawBitmap( rBmpSeq, 0, 0 );
  48.     m_width = rBmpSeq.getWidth();
  49.     m_height = rBmpSeq.getHeight() / numImg;
  50.     // States
  51.     m_fsm.addState( "up" );
  52.     m_fsm.addState( "down" );
  53.     // Transitions
  54.     m_fsm.addTransition( "up", "mouse:left:down", "down", &m_cmdUpDown );
  55.     m_fsm.addTransition( "down", "mouse:left:up", "up", &m_cmdDownUp );
  56.     m_fsm.addTransition( "down", "motion", "down", &m_cmdMove );
  57.     // Initial state
  58.     m_fsm.setState( "up" );
  59.     // Observe the variable
  60.     m_rVariable.addObserver( this );
  61. }
  62. CtrlRadialSlider::~CtrlRadialSlider()
  63. {
  64.     m_rVariable.delObserver( this );
  65.     SKINS_DELETE( m_pImgSeq );
  66. }
  67. void CtrlRadialSlider::handleEvent( EvtGeneric &rEvent )
  68. {
  69.     // Save the event to use it in callbacks
  70.     m_pEvt = &rEvent;
  71.     m_fsm.handleTransition( rEvent.getAsString() );
  72. }
  73. bool CtrlRadialSlider::mouseOver( int x, int y ) const
  74. {
  75.     return m_pImgSeq->hit( x, y + m_position * m_height );
  76. }
  77. void CtrlRadialSlider::draw( OSGraphics &rImage, int xDest, int yDest )
  78. {
  79.     rImage.drawGraphics( *m_pImgSeq, 0, m_position * m_height, xDest, yDest,
  80.                          m_width, m_height );
  81. }
  82. void CtrlRadialSlider::onUpdate( Subject<VarPercent> &rVariable )
  83. {
  84.     m_position = (int)( m_rVariable.get() * m_numImg );
  85.     notifyLayout();
  86. }
  87. void CtrlRadialSlider::transUpDown( SkinObject *pCtrl )
  88. {
  89.     CtrlRadialSlider *pThis = (CtrlRadialSlider*)pCtrl;
  90.     EvtMouse *pEvtMouse = (EvtMouse*)pThis->m_pEvt;
  91.     // Change the position of the cursor, in non-blocking mode
  92.     pThis->setCursor( pEvtMouse->getXPos(), pEvtMouse->getYPos(), false );
  93.     pThis->captureMouse();
  94. }
  95. void CtrlRadialSlider::transDownUp( SkinObject *pCtrl )
  96. {
  97.     CtrlRadialSlider *pThis = (CtrlRadialSlider*)pCtrl;
  98.     pThis->releaseMouse();
  99. }
  100. void CtrlRadialSlider::transMove( SkinObject *pCtrl )
  101. {
  102.     CtrlRadialSlider *pThis = (CtrlRadialSlider*)pCtrl;
  103.     EvtMouse *pEvtMouse = (EvtMouse*)pThis->m_pEvt;
  104.     // Change the position of the cursor, in blocking mode
  105.     pThis->setCursor( pEvtMouse->getXPos(), pEvtMouse->getYPos(), true );
  106. }
  107. void CtrlRadialSlider::setCursor( int posX, int posY, bool blocking )
  108. {
  109.     // Get the position of the control
  110.     const Position *pPos = getPosition();
  111.     if( !pPos )
  112.     {
  113.         return;
  114.     }
  115.     // Compute the position relative to the center
  116.     int x = posX - pPos->getLeft() - m_width / 2;
  117.     int y = posY - pPos->getTop() - m_width / 2;
  118.     // Compute the polar coordinates. angle is -(-j,OM)
  119.     float r = sqrt(x*x + y*y);
  120.     if( r == 0 )
  121.     {
  122.         return;
  123.     }
  124.     float angle = acos(y/r);
  125.     if( x > 0 )
  126.     {
  127.         angle = 2*M_PI - angle;
  128.     }
  129.     if( angle >= m_minAngle && angle <= m_maxAngle )
  130.     {
  131.         float newVal = (angle - m_minAngle) / (m_maxAngle - m_minAngle);
  132.         // Avoid too fast moves of the cursor if blocking mode
  133.         if( !blocking || fabs( m_rVariable.get() - newVal ) < 0.5 )
  134.         {
  135.             m_rVariable.set( newVal );
  136.         }
  137.     }
  138. }