]> git.sesse.net Git - vlc/blob - modules/gui/skins2/controls/ctrl_checkbox.cpp
* controls/*, src/generic_window.cpp, src/generic_layout.cpp: a visibiliy
[vlc] / modules / gui / skins2 / controls / ctrl_checkbox.cpp
1 /*****************************************************************************
2  * ctrl_checkbox.cpp
3  *****************************************************************************
4  * Copyright (C) 2003 VideoLAN
5  * $Id: ctrl_checkbox.cpp,v 1.3 2004/02/29 16:49:55 asmax Exp $
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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
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"
32
33
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,
45                             VarBool *pVisible ):
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_cmdUpOverDownOver( this, &transUpOverDownOver ),
51     m_cmdDownOverUpOver( this, &transDownOverUpOver ),
52     m_cmdDownOverDown( this, &transDownOverDown ),
53     m_cmdDownDownOver( this, &transDownDownOver ),
54     m_cmdUpOverUp( this, &transUpOverUp ),
55     m_cmdUpUpOver( this, &transUpUpOver ),
56     m_cmdDownUp( this, &transDownUp ),
57     m_cmdUpHidden( this, &transUpHidden ),
58     m_cmdHiddenUp( this, &transHiddenUp )
59 {
60     // Build the images of the checkbox
61     OSFactory *pOsFactory = OSFactory::instance( pIntf );
62     m_pImgUp1 = pOsFactory->createOSGraphics( rBmpUp1.getWidth(),
63                                               rBmpUp1.getHeight() );
64     m_pImgUp1->drawBitmap( rBmpUp1, 0, 0 );
65     m_pImgDown1 = pOsFactory->createOSGraphics( rBmpDown1.getWidth(),
66                                                 rBmpDown1.getHeight() );
67     m_pImgDown1->drawBitmap( rBmpDown1, 0, 0 );
68     m_pImgOver1 = pOsFactory->createOSGraphics( rBmpOver1.getWidth(),
69                                                 rBmpOver1.getHeight() );
70     m_pImgOver1->drawBitmap( rBmpOver1, 0, 0 );
71
72     m_pImgUp2 = pOsFactory->createOSGraphics( rBmpUp2.getWidth(),
73                                               rBmpUp2.getHeight() );
74     m_pImgUp2->drawBitmap( rBmpUp2, 0, 0 );
75     m_pImgDown2 = pOsFactory->createOSGraphics( rBmpDown2.getWidth(),
76                                                 rBmpDown2.getHeight() );
77     m_pImgDown2->drawBitmap( rBmpDown2, 0, 0 );
78     m_pImgOver2 = pOsFactory->createOSGraphics( rBmpOver2.getWidth(),
79                                                 rBmpOver2.getHeight() );
80     m_pImgOver2->drawBitmap( rBmpOver2, 0, 0 );
81
82     // States
83     m_fsm.addState( "up" );
84     m_fsm.addState( "down" );
85     m_fsm.addState( "upOver" );
86     m_fsm.addState( "downOver" );
87     m_fsm.addState( "hidden" );
88
89     // Transitions
90     m_fsm.addTransition( "upOver", "mouse:left:down", "downOver",
91                          &m_cmdUpOverDownOver );
92     m_fsm.addTransition( "downOver", "mouse:left:up", "upOver",
93                          &m_cmdDownOverUpOver );
94     m_fsm.addTransition( "downOver", "leave", "down", &m_cmdDownOverDown );
95     m_fsm.addTransition( "down", "enter", "downOver", &m_cmdDownDownOver );
96     m_fsm.addTransition( "upOver", "leave", "up", &m_cmdUpOverUp );
97     m_fsm.addTransition( "up", "enter", "upOver", &m_cmdUpUpOver );
98     m_fsm.addTransition( "down", "mouse:left:up", "up", &m_cmdDownUp );
99     // XXX: It would be easy to use a "ANY" initial state to handle these
100     // four lines in only one. But till now it isn't worthwhile...
101     m_fsm.addTransition( "up", "special:hide", "hidden", &m_cmdUpHidden );
102     m_fsm.addTransition( "down", "special:hide", "hidden", &m_cmdUpHidden );
103     m_fsm.addTransition( "upOver", "special:hide", "hidden", &m_cmdUpHidden );
104     m_fsm.addTransition( "downOver", "special:hide", "hidden", &m_cmdUpHidden );
105     m_fsm.addTransition( "hidden", "special:show", "up", &m_cmdHiddenUp );
106
107     // Observe the variable
108     m_rVariable.addObserver( this );
109
110     // Initial state
111     m_fsm.setState( "up" );
112     if( !m_rVariable.get() )
113     {
114         m_pImgUp = m_pImgUp1;
115         m_pImgOver = m_pImgOver1;
116         m_pImgDown = m_pImgDown1;
117         m_pImgCurrent = m_pImgUp;
118         m_pCommand = &m_rCommand1;
119         m_pTooltip = &m_tooltip1;
120     }
121     else
122     {
123         m_pImgUp = m_pImgUp2;
124         m_pImgOver = m_pImgOver2;
125         m_pImgDown = m_pImgDown2;
126         m_pImgCurrent = m_pImgDown;
127         m_pCommand = &m_rCommand2;
128         m_pTooltip = &m_tooltip2;
129     }
130 }
131
132
133 CtrlCheckbox::~CtrlCheckbox()
134 {
135     m_rVariable.delObserver( this );
136     SKINS_DELETE( m_pImgUp1 );
137     SKINS_DELETE( m_pImgDown1 );
138     SKINS_DELETE( m_pImgOver1 );
139     SKINS_DELETE( m_pImgUp2 );
140     SKINS_DELETE( m_pImgDown2 );
141     SKINS_DELETE( m_pImgOver2 );
142 }
143
144
145 void CtrlCheckbox::handleEvent( EvtGeneric &rEvent )
146 {
147     m_fsm.handleTransition( rEvent.getAsString() );
148 }
149
150
151 bool CtrlCheckbox::mouseOver( int x, int y ) const
152 {
153     if( m_pImgCurrent )
154     {
155         return m_pImgCurrent->hit( x, y );
156     }
157     else
158     {
159         return false;
160     }
161 }
162
163
164 void CtrlCheckbox::draw( OSGraphics &rImage, int xDest, int yDest )
165 {
166     if( m_pImgCurrent )
167     {
168         // Draw the current image
169         rImage.drawGraphics( *m_pImgCurrent, 0, 0, xDest, yDest );
170     }
171 }
172
173
174 void CtrlCheckbox::transUpOverDownOver( SkinObject *pCtrl )
175 {
176     CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
177     pThis->captureMouse();
178     pThis->m_pImgCurrent = pThis->m_pImgDown;
179     pThis->notifyLayout();
180 }
181
182
183 void CtrlCheckbox::transDownOverUpOver( SkinObject *pCtrl )
184 {
185     CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
186     pThis->releaseMouse();
187
188     // Invert the state variable
189     pThis->m_pImgCurrent = pThis->m_pImgUp;
190     pThis->notifyLayout();
191
192     // Execute the command
193     pThis->m_pCommand->execute();
194 }
195
196
197 void CtrlCheckbox::transDownOverDown( SkinObject *pCtrl )
198 {
199     CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
200     pThis->m_pImgCurrent = pThis->m_pImgUp;
201     pThis->notifyLayout();
202 }
203
204
205 void CtrlCheckbox::transDownDownOver( SkinObject *pCtrl )
206 {
207     CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
208     pThis->m_pImgCurrent = pThis->m_pImgDown;
209     pThis->notifyLayout();
210 }
211
212
213 void CtrlCheckbox::transUpUpOver( SkinObject *pCtrl )
214 {
215     CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
216     pThis->m_pImgCurrent = pThis->m_pImgOver;
217     pThis->notifyLayout();
218 }
219
220
221 void CtrlCheckbox::transUpOverUp( SkinObject *pCtrl )
222 {
223     CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
224     pThis->m_pImgCurrent = pThis->m_pImgUp;
225     pThis->notifyLayout();
226 }
227
228
229 void CtrlCheckbox::transDownUp( SkinObject *pCtrl )
230 {
231     CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
232     pThis->releaseMouse();
233 }
234
235
236 void CtrlCheckbox::transUpHidden( SkinObject *pCtrl )
237 {
238     CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
239     pThis->m_pImgCurrent = NULL;
240     pThis->notifyLayout();
241 }
242
243
244 void CtrlCheckbox::transHiddenUp( SkinObject *pCtrl )
245 {
246     CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
247     pThis->m_pImgCurrent = pThis->m_pImgUp;
248     pThis->notifyLayout();
249 }
250
251
252 void CtrlCheckbox::onVarBoolUpdate( VarBool &rVariable )
253 {
254     changeButton();
255 }
256
257
258 void CtrlCheckbox::changeButton()
259 {
260     // Are we using the first set of images or the second one?
261     if( m_pImgUp == m_pImgUp1 )
262     {
263         m_pImgUp = m_pImgUp2;
264         m_pImgOver = m_pImgOver2;
265         m_pImgDown = m_pImgDown2;
266         m_pTooltip = &m_tooltip2;
267         m_pCommand = &m_rCommand2;
268     }
269     else
270     {
271         m_pImgUp = m_pImgUp1;
272         m_pImgOver = m_pImgOver1;
273         m_pImgDown = m_pImgDown1;
274         m_pTooltip = &m_tooltip1;
275         m_pCommand = &m_rCommand1;
276     }
277     // XXX: We assume that the checkbox is up
278     m_pImgCurrent = m_pImgUp;
279
280     // Notify the window the tooltip has changed
281     notifyTooltipChange();
282     // Refresh
283     notifyLayout();
284 }
285