]> git.sesse.net Git - vlc/blob - modules/gui/skins2/src/generic_layout.cpp
* skins2/src/skin_main.cpp: New demux2 module to load automatically a skin.
[vlc] / modules / gui / skins2 / src / generic_layout.cpp
1 /*****************************************************************************
2  * generic_layout.cpp
3  *****************************************************************************
4  * Copyright (C) 2003 VideoLAN
5  * $Id$
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 "generic_layout.hpp"
26 #include "top_window.hpp"
27 #include "os_factory.hpp"
28 #include "os_graphics.hpp"
29 #include "../controls/ctrl_generic.hpp"
30
31
32 GenericLayout::GenericLayout( intf_thread_t *pIntf, int width, int height,
33                               int minWidth, int maxWidth, int minHeight,
34                               int maxHeight ):
35     SkinObject( pIntf ), m_pWindow( NULL ), m_width( width ),
36     m_height( height ), m_minWidth( minWidth ), m_maxWidth( maxWidth ),
37     m_minHeight( minHeight ), m_maxHeight( maxHeight )
38 {
39     // Get the OSFactory
40     OSFactory *pOsFactory = OSFactory::instance( getIntf() );
41     // Create the graphics buffer
42     m_pImage = pOsFactory->createOSGraphics( width, height );
43 }
44
45
46 GenericLayout::~GenericLayout()
47 {
48     if( m_pImage )
49     {
50         delete m_pImage;
51     }
52 }
53
54
55 void GenericLayout::setWindow( TopWindow *pWindow )
56 {
57     m_pWindow = pWindow;
58 }
59
60
61 void GenericLayout::onControlCapture( const CtrlGeneric &rCtrl )
62 {
63     // Just forward the request to the window
64     TopWindow *pWindow = getWindow();
65     if( pWindow )
66     {
67         pWindow->onControlCapture( rCtrl );
68     }
69 }
70
71
72 void GenericLayout::onControlRelease( const CtrlGeneric &rCtrl )
73 {
74     // Just forward the request to the window
75     TopWindow *pWindow = getWindow();
76     if( pWindow )
77     {
78         pWindow->onControlRelease( rCtrl );
79     }
80 }
81
82
83 void GenericLayout::addControl( CtrlGeneric *pControl,
84                               const Position &rPosition, int layer )
85 {
86     if( pControl )
87     {
88         // Associate this layout to the control
89         pControl->setLayout( this, rPosition );
90
91         // Draw the control
92         pControl->draw( *m_pImage, rPosition.getLeft(), rPosition.getTop() );
93
94         // Add the control in the list.
95         // This list must remain sorted by layer order 
96         list<LayeredControl>::iterator it;
97         for( it = m_controlList.begin(); it != m_controlList.end(); it++ )
98         {
99             if( layer < (*it).m_layer )
100             {
101                 m_controlList.insert( it, LayeredControl( pControl, layer ) );
102                 break;
103             }
104         }
105         // If this control is in front of all the previous ones
106         if( it == m_controlList.end() )
107         {
108             m_controlList.push_back( LayeredControl( pControl, layer ) );
109         }
110     }
111     else
112     {
113         msg_Dbg( getIntf(), "Adding NULL control in the layout" );
114     }
115 }
116
117
118 const list<LayeredControl> &GenericLayout::getControlList() const
119 {
120     return m_controlList;
121 }
122
123
124 void GenericLayout::onControlUpdate( const CtrlGeneric &rCtrl )
125 {
126     // TODO: refresh only the needed area if possible
127     refreshAll();
128 }
129
130
131 void GenericLayout::resize( int width, int height )
132 {
133     if( width == m_width && height == m_height )
134     {
135         return;
136     }
137
138     // Update the window size
139     m_width = width;
140     m_height = height;
141
142     // Recreate a new image
143     if( m_pImage )
144     {
145         delete m_pImage;
146         OSFactory *pOsFactory = OSFactory::instance( getIntf() );
147         m_pImage = pOsFactory->createOSGraphics( width, height );
148     }
149
150     // Notify all the controls that the size has changed and redraw them
151     list<LayeredControl>::const_iterator iter;
152     for( iter = m_controlList.begin(); iter != m_controlList.end(); iter++ )
153     {
154         (*iter).m_pControl->onResize();
155         const Position *pPos = (*iter).m_pControl->getPosition();
156         if( pPos )
157         {
158             (*iter).m_pControl->draw( *m_pImage, pPos->getLeft(),
159                                       pPos->getTop() );
160         }
161     }
162
163     // Resize and refresh the associated window
164     TopWindow *pWindow = getWindow();
165     if( pWindow )
166     {
167         // Resize the window
168         pWindow->refresh( 0, 0, width, height );
169         pWindow->resize( width, height );
170         pWindow->refresh( 0, 0, width, height );
171
172         // Change the shape of the window and redraw it
173         pWindow->updateShape();
174         pWindow->refresh( 0, 0, width, height );
175     }
176 }
177
178
179 void GenericLayout::refreshAll()
180 {
181     // Draw all the controls of the layout
182     list<LayeredControl>::const_iterator iter;
183     for( iter = m_controlList.begin(); iter != m_controlList.end(); iter++ )
184     {
185         CtrlGeneric *pCtrl = (*iter).m_pControl;
186         const Position *pPos = pCtrl->getPosition();
187         if( pCtrl->isVisible() && pPos )
188         {
189             pCtrl->draw( *m_pImage, pPos->getLeft(), pPos->getTop() );
190         }
191     }
192
193     // Refresh the associated window
194     TopWindow *pWindow = getWindow();
195     if( pWindow )
196     {
197         pWindow->refresh( 0, 0, m_width, m_height );
198     }
199 }
200
201
202 const list<Anchor*>& GenericLayout::getAnchorList() const
203 {
204     return m_anchorList;
205 }
206
207
208 void GenericLayout::addAnchor( Anchor *pAnchor )
209 {
210     m_anchorList.push_back( pAnchor );
211 }
212