ctrl_radialslider.cpp
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:5k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * ctrl_radialslider.cpp
  3.  *****************************************************************************
  4.  * Copyright (C) 2003 the VideoLAN team
  5.  * $Id: b12a51da99ce3debc69ec3427d86f588d6217573 $
  6.  *
  7.  * Authors: Cyril Deguet     <asmax@via.ecp.fr>
  8.  *          Olivier Teulière <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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, 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 ), m_cmdDownUp( this ),
  41.     m_cmdMove( this )
  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.                                  void *arg  )
  84. {
  85.     m_position = (int)( m_rVariable.get() * m_numImg );
  86.     notifyLayout( m_width, m_height );
  87. }
  88. void CtrlRadialSlider::CmdUpDown::execute()
  89. {
  90.     EvtMouse *pEvtMouse = (EvtMouse*)m_pParent->m_pEvt;
  91.     // Change the position of the cursor, in non-blocking mode
  92.     m_pParent->setCursor( pEvtMouse->getXPos(), pEvtMouse->getYPos(), false );
  93.     m_pParent->captureMouse();
  94. }
  95. void CtrlRadialSlider::CmdDownUp::execute()
  96. {
  97.     m_pParent->releaseMouse();
  98. }
  99. void CtrlRadialSlider::CmdMove::execute()
  100. {
  101.     EvtMouse *pEvtMouse = (EvtMouse*)m_pParent->m_pEvt;
  102.     // Change the position of the cursor, in blocking mode
  103.     m_pParent->setCursor( pEvtMouse->getXPos(), pEvtMouse->getYPos(), true );
  104. }
  105. void CtrlRadialSlider::setCursor( int posX, int posY, bool blocking )
  106. {
  107.     // Get the position of the control
  108.     const Position *pPos = getPosition();
  109.     if( !pPos )
  110.     {
  111.         return;
  112.     }
  113.     // Compute the position relative to the center
  114.     int x = posX - pPos->getLeft() - m_width / 2;
  115.     int y = posY - pPos->getTop() - m_width / 2;
  116.     // Compute the polar coordinates. angle is -(-j,OM)
  117.     float r = sqrt((float)(x*x + y*y));
  118.     if( r == 0 )
  119.     {
  120.         return;
  121.     }
  122.     float angle = acos(y/r);
  123.     if( x > 0 )
  124.     {
  125.         angle = 2*M_PI - angle;
  126.     }
  127.     if( angle >= m_minAngle && angle <= m_maxAngle )
  128.     {
  129.         float newVal = (angle - m_minAngle) / (m_maxAngle - m_minAngle);
  130.         // Avoid too fast moves of the cursor if blocking mode
  131.         if( !blocking || fabs( m_rVariable.get() - newVal ) < 0.5 )
  132.         {
  133.             m_rVariable.set( newVal );
  134.         }
  135.     }
  136. }