1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2003 the VideoLAN team
7 * Authors: Cyril Deguet <asmax@via.ecp.fr>
8 * Olivier Teulière <ipkiss@via.ecp.fr>
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.
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.
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 *****************************************************************************/
25 #include "ctrl_checkbox.hpp"
26 #include "../events/evt_generic.hpp"
27 #include "../commands/cmd_generic.hpp"
28 #include "../src/generic_bitmap.hpp"
29 #include "../src/os_factory.hpp"
30 #include "../src/os_graphics.hpp"
31 #include "../utils/var_bool.hpp"
34 CtrlCheckbox::CtrlCheckbox( intf_thread_t *pIntf,
35 const GenericBitmap &rBmpUp1,
36 const GenericBitmap &rBmpOver1,
37 const GenericBitmap &rBmpDown1,
38 const GenericBitmap &rBmpUp2,
39 const GenericBitmap &rBmpOver2,
40 const GenericBitmap &rBmpDown2,
41 CmdGeneric &rCommand1, CmdGeneric &rCommand2,
42 const UString &rTooltip1,
43 const UString &rTooltip2,
44 VarBool &rVariable, const UString &rHelp,
46 CtrlGeneric( pIntf, rHelp, pVisible ), m_fsm( pIntf ),
47 m_rVariable( rVariable ),
48 m_rCommand1( rCommand1 ), m_rCommand2( rCommand2 ),
49 m_tooltip1( rTooltip1 ), m_tooltip2( rTooltip2 ),
50 m_imgUp1( pIntf, rBmpUp1 ), m_imgOver1( pIntf, rBmpOver1 ),
51 m_imgDown1( pIntf, rBmpDown1 ), m_imgUp2( pIntf, rBmpUp2 ),
52 m_imgOver2( pIntf, rBmpOver2 ), m_imgDown2( pIntf, rBmpDown2 ),
53 m_cmdUpOverDownOver( this ), m_cmdDownOverUpOver( this ),
54 m_cmdDownOverDown( this ), m_cmdDownDownOver( this ),
55 m_cmdUpOverUp( this ), m_cmdUpUpOver( this ),
56 m_cmdDownUp( this ), m_cmdUpHidden( this ),
60 m_fsm.addState( "up" );
61 m_fsm.addState( "down" );
62 m_fsm.addState( "upOver" );
63 m_fsm.addState( "downOver" );
64 m_fsm.addState( "hidden" );
67 m_fsm.addTransition( "upOver", "mouse:left:down", "downOver",
68 &m_cmdUpOverDownOver );
69 m_fsm.addTransition( "upOver", "mouse:left:dblclick", "downOver",
70 &m_cmdUpOverDownOver );
71 m_fsm.addTransition( "downOver", "mouse:left:up", "upOver",
72 &m_cmdDownOverUpOver );
73 m_fsm.addTransition( "downOver", "leave", "down", &m_cmdDownOverDown );
74 m_fsm.addTransition( "down", "enter", "downOver", &m_cmdDownDownOver );
75 m_fsm.addTransition( "upOver", "leave", "up", &m_cmdUpOverUp );
76 m_fsm.addTransition( "up", "enter", "upOver", &m_cmdUpUpOver );
77 m_fsm.addTransition( "down", "mouse:left:up", "up", &m_cmdDownUp );
78 // XXX: It would be easy to use a "ANY" initial state to handle these
79 // four lines in only one. But till now it isn't worthwhile...
80 m_fsm.addTransition( "up", "special:hide", "hidden", &m_cmdUpHidden );
81 m_fsm.addTransition( "down", "special:hide", "hidden", &m_cmdUpHidden );
82 m_fsm.addTransition( "upOver", "special:hide", "hidden", &m_cmdUpHidden );
83 m_fsm.addTransition( "downOver", "special:hide", "hidden", &m_cmdUpHidden );
84 m_fsm.addTransition( "hidden", "special:show", "up", &m_cmdHiddenUp );
86 // Observe the variable
87 m_rVariable.addObserver( this );
90 m_fsm.setState( "up" );
91 if( !m_rVariable.get() )
94 m_pImgOver = &m_imgOver1;
95 m_pImgDown = &m_imgDown1;
96 m_pImgCurrent = m_pImgUp;
97 m_pCommand = &m_rCommand1;
98 m_pTooltip = &m_tooltip1;
102 m_pImgUp = &m_imgUp2;
103 m_pImgOver = &m_imgOver2;
104 m_pImgDown = &m_imgDown2;
105 m_pImgCurrent = m_pImgUp;
106 m_pCommand = &m_rCommand2;
107 m_pTooltip = &m_tooltip2;
112 CtrlCheckbox::~CtrlCheckbox()
116 m_pImgCurrent->stopAnim();
117 m_pImgCurrent->delObserver( this );
119 m_rVariable.delObserver( this );
123 void CtrlCheckbox::handleEvent( EvtGeneric &rEvent )
125 m_fsm.handleTransition( rEvent.getAsString() );
129 bool CtrlCheckbox::mouseOver( int x, int y ) const
133 return m_pImgCurrent->hit( x, y );
142 void CtrlCheckbox::draw( OSGraphics &rImage, int xDest, int yDest, int w, int h )
147 const Position *pPos = getPosition();
148 // rect region( pPos->getLeft(), pPos->getTop(),
149 // pPos->getWidth(), pPos->getHeight() );
150 rect region( pPos->getLeft(), pPos->getTop(),
151 m_pImgCurrent->getWidth(), m_pImgCurrent->getHeight() );
152 rect clip( xDest, yDest, w, h );
154 if( rect::intersect( region, clip, &inter ) )
156 // Draw the current image
157 m_pImgCurrent->draw( rImage,
158 inter.x, inter.y, inter.width, inter.height,
159 inter.x - pPos->getLeft(),
160 inter.y - pPos->getTop() );
165 void CtrlCheckbox::setImage( AnimBitmap *pImg )
167 if( pImg == m_pImgCurrent )
170 AnimBitmap *pOldImg = m_pImgCurrent;
171 m_pImgCurrent = pImg;
176 pOldImg->delObserver( this );
182 pImg->addObserver( this );
185 notifyLayoutMaxSize( pOldImg, pImg );
189 void CtrlCheckbox::CmdUpOverDownOver::execute()
191 m_pParent->captureMouse();
192 m_pParent->setImage( m_pParent->m_pImgDown );
196 void CtrlCheckbox::CmdDownOverUpOver::execute()
198 m_pParent->releaseMouse();
199 m_pParent->setImage( m_pParent->m_pImgUp );
200 // Execute the command
201 m_pParent->m_pCommand->execute();
205 void CtrlCheckbox::CmdDownOverDown::execute()
207 m_pParent->setImage( m_pParent->m_pImgUp );
211 void CtrlCheckbox::CmdDownDownOver::execute()
213 m_pParent->setImage( m_pParent->m_pImgDown );
217 void CtrlCheckbox::CmdUpUpOver::execute()
219 m_pParent->setImage( m_pParent->m_pImgOver );
223 void CtrlCheckbox::CmdUpOverUp::execute()
225 m_pParent->setImage( m_pParent->m_pImgUp );
229 void CtrlCheckbox::CmdDownUp::execute()
231 m_pParent->releaseMouse();
235 void CtrlCheckbox::CmdUpHidden::execute()
237 m_pParent->setImage( NULL );
241 void CtrlCheckbox::CmdHiddenUp::execute()
243 m_pParent->setImage( m_pParent->m_pImgUp );
247 void CtrlCheckbox::onVarBoolUpdate( VarBool &rVariable )
254 void CtrlCheckbox::onUpdate( Subject<AnimBitmap> &rBitmap, void *arg )
256 (void)rBitmap;(void)arg;
257 notifyLayout( m_pImgCurrent->getWidth(), m_pImgCurrent->getHeight() );
261 void CtrlCheckbox::changeButton()
263 // Are we using the first set of images or the second one?
264 if( m_pImgUp == &m_imgUp1 )
266 m_pImgUp = &m_imgUp2;
267 m_pImgOver = &m_imgOver2;
268 m_pImgDown = &m_imgDown2;
269 m_pTooltip = &m_tooltip2;
270 m_pCommand = &m_rCommand2;
274 m_pImgUp = &m_imgUp1;
275 m_pImgOver = &m_imgOver1;
276 m_pImgDown = &m_imgDown1;
277 m_pTooltip = &m_tooltip1;
278 m_pCommand = &m_rCommand1;
280 // XXX: We assume that the checkbox is up
281 setImage( m_pImgUp );
283 // Notify the window the tooltip has changed
284 notifyTooltipChange();