skins2: add a function that differentiates dependent and independent layouts.
[vlc.git] / modules / gui / skins2 / src / generic_layout.cpp
blob779467b4e67a853e24734e2430acea1ac9e408c8
1 /*****************************************************************************
2 * generic_layout.cpp
3 *****************************************************************************
4 * Copyright (C) 2003 the VideoLAN team
5 * $Id$
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 "generic_layout.hpp"
26 #include "top_window.hpp"
27 #include "os_factory.hpp"
28 #include "os_graphics.hpp"
29 #include "var_manager.hpp"
30 #include "anchor.hpp"
31 #include "../controls/ctrl_generic.hpp"
32 #include "../controls/ctrl_video.hpp"
33 #include "../utils/var_bool.hpp"
34 #include <set>
37 GenericLayout::GenericLayout( intf_thread_t *pIntf, int width, int height,
38 int minWidth, int maxWidth, int minHeight,
39 int maxHeight ):
40 SkinObject( pIntf ), m_pWindow( NULL ),
41 m_original_width( width ), m_original_height( height ),
42 m_rect( 0, 0, width, height ),
43 m_minWidth( minWidth ), m_maxWidth( maxWidth ),
44 m_minHeight( minHeight ), m_maxHeight( maxHeight ), m_pVideoCtrlSet(),
45 m_visible( false ), m_pVarActive( NULL )
47 // Get the OSFactory
48 OSFactory *pOsFactory = OSFactory::instance( getIntf() );
49 // Create the graphics buffer
50 m_pImage = pOsFactory->createOSGraphics( width, height );
52 // Create the "active layout" variable and register it in the manager
53 m_pVarActive = new VarBoolImpl( pIntf );
54 VarManager::instance( pIntf )->registerVar( VariablePtr( m_pVarActive ) );
58 GenericLayout::~GenericLayout()
60 delete m_pImage;
62 list<Anchor*>::const_iterator it;
63 for( it = m_anchorList.begin(); it != m_anchorList.end(); ++it )
65 delete *it;
68 list<LayeredControl>::const_iterator iter;
69 for( iter = m_controlList.begin(); iter != m_controlList.end(); ++iter )
71 CtrlGeneric *pCtrl = (*iter).m_pControl;
72 pCtrl->unsetLayout();
78 void GenericLayout::setWindow( TopWindow *pWindow )
80 m_pWindow = pWindow;
84 void GenericLayout::onControlCapture( const CtrlGeneric &rCtrl )
86 // Just forward the request to the window
87 TopWindow *pWindow = getWindow();
88 if( pWindow )
90 pWindow->onControlCapture( rCtrl );
95 void GenericLayout::onControlRelease( const CtrlGeneric &rCtrl )
97 // Just forward the request to the window
98 TopWindow *pWindow = getWindow();
99 if( pWindow )
101 pWindow->onControlRelease( rCtrl );
106 void GenericLayout::addControl( CtrlGeneric *pControl,
107 const Position &rPosition, int layer )
109 if( pControl )
111 // Associate this layout to the control
112 pControl->setLayout( this, rPosition );
114 // Add the control in the list.
115 // This list must remain sorted by layer order
116 list<LayeredControl>::iterator it;
117 for( it = m_controlList.begin(); it != m_controlList.end(); ++it )
119 if( layer < (*it).m_layer )
121 m_controlList.insert( it, LayeredControl( pControl, layer ) );
122 break;
125 // If this control is in front of all the previous ones
126 if( it == m_controlList.end() )
128 m_controlList.push_back( LayeredControl( pControl, layer ) );
131 // Check if it is a video control
132 if( pControl->getType() == "video" )
134 m_pVideoCtrlSet.insert( (CtrlVideo*)pControl );
137 else
139 msg_Dbg( getIntf(), "adding NULL control in the layout" );
144 const list<LayeredControl> &GenericLayout::getControlList() const
146 return m_controlList;
150 void GenericLayout::onControlUpdate( const CtrlGeneric &rCtrl,
151 int width, int height,
152 int xOffSet, int yOffSet )
154 // Do nothing if the layout or control is hidden
155 if( !m_visible )
156 return;
158 const Position *pPos = rCtrl.getPosition();
159 if( width > 0 && height > 0 )
161 // make sure region is within the layout
162 rect region( pPos->getLeft() + xOffSet,
163 pPos->getTop() + yOffSet,
164 width, height );
165 rect layout( 0, 0, m_rect.getWidth(), m_rect.getHeight() );
166 rect inter;
167 if( rect::intersect( layout, region, &inter ) )
169 refreshRect( inter.x, inter.y, inter.width, inter.height );
175 void GenericLayout::resize( int width, int height )
177 // Update the window size
178 m_rect = SkinsRect( 0, 0 , width, height );
180 // Recreate a new image
181 if( m_pImage )
183 delete m_pImage;
184 OSFactory *pOsFactory = OSFactory::instance( getIntf() );
185 m_pImage = pOsFactory->createOSGraphics( width, height );
188 // Notify all the controls that the size has changed and redraw them
189 list<LayeredControl>::const_iterator iter;
190 for( iter = m_controlList.begin(); iter != m_controlList.end(); ++iter )
192 iter->m_pControl->onResize();
195 // Resize and refresh the associated window
196 TopWindow *pWindow = getWindow();
197 if( pWindow )
199 // Resize the window
200 pWindow->resize( width, height );
201 // Change the shape of the window and redraw it
202 refreshAll();
207 void GenericLayout::refreshAll()
209 refreshRect( 0, 0, m_rect.getWidth(), m_rect.getHeight() );
213 void GenericLayout::refreshRect( int x, int y, int width, int height )
215 // Do nothing if the layout is hidden
216 if( !m_visible )
217 return;
219 // update the transparency global mask
220 m_pImage->clear( x, y, width, height );
222 // Draw all the controls of the layout
223 list<LayeredControl>::const_iterator iter;
224 for( iter = m_controlList.begin(); iter != m_controlList.end(); ++iter )
226 CtrlGeneric *pCtrl = (*iter).m_pControl;
227 if( pCtrl->isVisible() )
229 pCtrl->draw( *m_pImage, x, y, width, height );
233 // Refresh the associated window
234 TopWindow *pWindow = getWindow();
235 if( pWindow )
237 // first apply new shape to the window
238 pWindow->updateShape();
240 pWindow->invalidateRect( x, y, width, height );
245 const list<Anchor*>& GenericLayout::getAnchorList() const
247 return m_anchorList;
251 void GenericLayout::addAnchor( Anchor *pAnchor )
253 m_anchorList.push_back( pAnchor );
257 void GenericLayout::onShow()
259 m_visible = true;
261 refreshAll();
265 void GenericLayout::onHide()
267 m_visible = false;