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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * ctrl_checkbox.cpp
  3.  *****************************************************************************
  4.  * Copyright (C) 2003 the VideoLAN team
  5.  * $Id: 89c2c57ea21d749d140acc92466d7dd452299adb $
  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 "ctrl_checkbox.hpp"
  25. #include "../events/evt_generic.hpp"
  26. #include "../commands/cmd_generic.hpp"
  27. #include "../src/generic_bitmap.hpp"
  28. #include "../src/os_factory.hpp"
  29. #include "../src/os_graphics.hpp"
  30. #include "../utils/var_bool.hpp"
  31. CtrlCheckbox::CtrlCheckbox( intf_thread_t *pIntf,
  32.                             const GenericBitmap &rBmpUp1,
  33.                             const GenericBitmap &rBmpOver1,
  34.                             const GenericBitmap &rBmpDown1,
  35.                             const GenericBitmap &rBmpUp2,
  36.                             const GenericBitmap &rBmpOver2,
  37.                             const GenericBitmap &rBmpDown2,
  38.                             CmdGeneric &rCommand1, CmdGeneric &rCommand2,
  39.                             const UString &rTooltip1,
  40.                             const UString &rTooltip2,
  41.                             VarBool &rVariable, const UString &rHelp,
  42.                             VarBool *pVisible ):
  43.     CtrlGeneric( pIntf, rHelp, pVisible ), m_fsm( pIntf ),
  44.     m_rVariable( rVariable ),
  45.     m_rCommand1( rCommand1 ), m_rCommand2( rCommand2 ),
  46.     m_tooltip1( rTooltip1 ), m_tooltip2( rTooltip2 ),
  47.     m_imgUp1( pIntf, rBmpUp1 ), m_imgOver1( pIntf, rBmpOver1 ),
  48.     m_imgDown1( pIntf, rBmpDown1 ), m_imgUp2( pIntf, rBmpUp2 ),
  49.     m_imgOver2( pIntf, rBmpOver2 ), m_imgDown2( pIntf, rBmpDown2 ),
  50.     m_cmdUpOverDownOver( this ), m_cmdDownOverUpOver( this ),
  51.     m_cmdDownOverDown( this ), m_cmdDownDownOver( this ),
  52.     m_cmdUpOverUp( this ), m_cmdUpUpOver( this ),
  53.     m_cmdDownUp( this ), m_cmdUpHidden( this ),
  54.     m_cmdHiddenUp( this )
  55. {
  56.     // States
  57.     m_fsm.addState( "up" );
  58.     m_fsm.addState( "down" );
  59.     m_fsm.addState( "upOver" );
  60.     m_fsm.addState( "downOver" );
  61.     m_fsm.addState( "hidden" );
  62.     // Transitions
  63.     m_fsm.addTransition( "upOver", "mouse:left:down", "downOver",
  64.                          &m_cmdUpOverDownOver );
  65.     m_fsm.addTransition( "upOver", "mouse:left:dblclick", "downOver",
  66.                          &m_cmdUpOverDownOver );
  67.     m_fsm.addTransition( "downOver", "mouse:left:up", "upOver",
  68.                          &m_cmdDownOverUpOver );
  69.     m_fsm.addTransition( "downOver", "leave", "down", &m_cmdDownOverDown );
  70.     m_fsm.addTransition( "down", "enter", "downOver", &m_cmdDownDownOver );
  71.     m_fsm.addTransition( "upOver", "leave", "up", &m_cmdUpOverUp );
  72.     m_fsm.addTransition( "up", "enter", "upOver", &m_cmdUpUpOver );
  73.     m_fsm.addTransition( "down", "mouse:left:up", "up", &m_cmdDownUp );
  74.     // XXX: It would be easy to use a "ANY" initial state to handle these
  75.     // four lines in only one. But till now it isn't worthwhile...
  76.     m_fsm.addTransition( "up", "special:hide", "hidden", &m_cmdUpHidden );
  77.     m_fsm.addTransition( "down", "special:hide", "hidden", &m_cmdUpHidden );
  78.     m_fsm.addTransition( "upOver", "special:hide", "hidden", &m_cmdUpHidden );
  79.     m_fsm.addTransition( "downOver", "special:hide", "hidden", &m_cmdUpHidden );
  80.     m_fsm.addTransition( "hidden", "special:show", "up", &m_cmdHiddenUp );
  81.     // Observe the variable
  82.     m_rVariable.addObserver( this );
  83.     // Initial state
  84.     m_fsm.setState( "up" );
  85.     if( !m_rVariable.get() )
  86.     {
  87.         m_pImgUp = &m_imgUp1;
  88.         m_pImgOver = &m_imgOver1;
  89.         m_pImgDown = &m_imgDown1;
  90.         m_pImgCurrent = m_pImgUp;
  91.         m_pCommand = &m_rCommand1;
  92.         m_pTooltip = &m_tooltip1;
  93.     }
  94.     else
  95.     {
  96.         m_pImgUp = &m_imgUp2;
  97.         m_pImgOver = &m_imgOver2;
  98.         m_pImgDown = &m_imgDown2;
  99.         m_pImgCurrent = m_pImgUp;
  100.         m_pCommand = &m_rCommand2;
  101.         m_pTooltip = &m_tooltip2;
  102.     }
  103. }
  104. CtrlCheckbox::~CtrlCheckbox()
  105. {
  106.     m_rVariable.delObserver( this );
  107. }
  108. void CtrlCheckbox::handleEvent( EvtGeneric &rEvent )
  109. {
  110.     m_fsm.handleTransition( rEvent.getAsString() );
  111. }
  112. bool CtrlCheckbox::mouseOver( int x, int y ) const
  113. {
  114.     if( m_pImgCurrent )
  115.     {
  116.         return m_pImgCurrent->hit( x, y );
  117.     }
  118.     else
  119.     {
  120.         return false;
  121.     }
  122. }
  123. void CtrlCheckbox::draw( OSGraphics &rImage, int xDest, int yDest )
  124. {
  125.     if( m_pImgCurrent )
  126.     {
  127.         // Draw the current image
  128.         m_pImgCurrent->draw( rImage, xDest, yDest );
  129.     }
  130. }
  131. void CtrlCheckbox::setImage( AnimBitmap *pImg )
  132. {
  133.     AnimBitmap *pOldImg = m_pImgCurrent;
  134.     m_pImgCurrent = pImg;
  135.     if( pOldImg )
  136.     {
  137.         pOldImg->stopAnim();
  138.         pOldImg->delObserver( this );
  139.     }
  140.     if( pImg )
  141.     {
  142.         pImg->startAnim();
  143.         pImg->addObserver( this );
  144.     }
  145.     notifyLayoutMaxSize( pOldImg, pImg );
  146. }
  147. void CtrlCheckbox::CmdUpOverDownOver::execute()
  148. {
  149.     m_pParent->captureMouse();
  150.     m_pParent->setImage( m_pParent->m_pImgDown );
  151. }
  152. void CtrlCheckbox::CmdDownOverUpOver::execute()
  153. {
  154.     m_pParent->releaseMouse();
  155.     // There is a little trick here: since we update the image of the control
  156.     // before executing the command, there is no way that the observed variable
  157.     // can have changed, so changeButton() has not been called, and m_pImgUp is
  158.     // still the "old" up state. That's why we don't use it, and use the other
  159.     // one instead. Otherwise, we would notice a "phantom effect", where the
  160.     // old up image is displayed for a few milliseconds, until the variable is
  161.     // updated and the correct up image is displayed.
  162.     // Executing the action before refreshing the state wouldn't work, because
  163.     // the variable may be updated asynchronously (when triggered by a callback
  164.     // from an object variable).
  165.     // Invert the state variable
  166.     if( m_pParent->m_pImgUp == &m_pParent->m_imgUp1 )
  167.         m_pParent->setImage( &m_pParent->m_imgUp2 );
  168.     else
  169.         m_pParent->setImage( &m_pParent->m_imgUp1 );
  170.     // Execute the command
  171.     m_pParent->m_pCommand->execute();
  172. }
  173. void CtrlCheckbox::CmdDownOverDown::execute()
  174. {
  175.     m_pParent->setImage( m_pParent->m_pImgUp );
  176. }
  177. void CtrlCheckbox::CmdDownDownOver::execute()
  178. {
  179.     m_pParent->setImage( m_pParent->m_pImgDown );
  180. }
  181. void CtrlCheckbox::CmdUpUpOver::execute()
  182. {
  183.     m_pParent->setImage( m_pParent->m_pImgOver );
  184. }
  185. void CtrlCheckbox::CmdUpOverUp::execute()
  186. {
  187.     m_pParent->setImage( m_pParent->m_pImgUp );
  188. }
  189. void CtrlCheckbox::CmdDownUp::execute()
  190. {
  191.     m_pParent->releaseMouse();
  192. }
  193. void CtrlCheckbox::CmdUpHidden::execute()
  194. {
  195.     m_pParent->setImage( NULL );
  196. }
  197. void CtrlCheckbox::CmdHiddenUp::execute()
  198. {
  199.     m_pParent->setImage( m_pParent->m_pImgUp );
  200. }
  201. void CtrlCheckbox::onVarBoolUpdate( VarBool &rVariable )
  202. {
  203.     changeButton();
  204. }
  205. void CtrlCheckbox::onUpdate( Subject<AnimBitmap> &rBitmap, void *arg )
  206. {
  207.     notifyLayout();
  208. }
  209. void CtrlCheckbox::changeButton()
  210. {
  211.     // Are we using the first set of images or the second one?
  212.     if( m_pImgUp == &m_imgUp1 )
  213.     {
  214.         m_pImgUp = &m_imgUp2;
  215.         m_pImgOver = &m_imgOver2;
  216.         m_pImgDown = &m_imgDown2;
  217.         m_pTooltip = &m_tooltip2;
  218.         m_pCommand = &m_rCommand2;
  219.     }
  220.     else
  221.     {
  222.         m_pImgUp = &m_imgUp1;
  223.         m_pImgOver = &m_imgOver1;
  224.         m_pImgDown = &m_imgDown1;
  225.         m_pTooltip = &m_tooltip1;
  226.         m_pCommand = &m_rCommand1;
  227.     }
  228.     // XXX: We assume that the checkbox is up
  229.     setImage( m_pImgUp );
  230.     // Notify the window the tooltip has changed
  231.     notifyTooltipChange();
  232.     // Refresh
  233.     notifyLayout();
  234. }