]> git.sesse.net Git - vlc/blob - modules/gui/skins2/src/theme.cpp
b7df897b7d71e9af10b2d1f3c6a0f5ccc6885b4d
[vlc] / modules / gui / skins2 / src / theme.cpp
1 /*****************************************************************************
2  * theme.cpp
3  *****************************************************************************
4  * Copyright (C) 2003 the VideoLAN team
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 along
21  * with this program; if not, write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 #include "theme.hpp"
26 #include "top_window.hpp"
27 #include <sstream>
28
29
30 Theme::~Theme()
31 {
32     // Be sure things are destroyed in the right order (XXX check)
33     m_layouts.clear();
34     m_controls.clear();
35     m_windows.clear();
36     m_bitmaps.clear();
37     m_fonts.clear();
38     m_commands.clear();
39     m_vars.clear();
40     m_curves.clear();
41 }
42
43
44 void Theme::loadConfig()
45 {
46     msg_Dbg( getIntf(), "loading theme configuration");
47
48     // Get config from vlcrc file
49     char *save = config_GetPsz( getIntf(), "skins2-config" );
50     if( !save ) return;
51
52     // Is there an existing config?
53     if( !strcmp( save, "" ) )
54     {
55         // Show the windows as indicated by the XML file
56         m_windowManager.showAll( true );
57         free( save );
58         return;
59     }
60
61     istringstream inStream(save);
62     free( save );
63
64     char sep;
65     string winId, layId;
66     int x, y, width, height, visible;
67     bool somethingVisible = false;
68     while( !inStream.eof() )
69     {
70         inStream >> sep;
71         if( sep != '[' ) goto invalid;
72         inStream >> winId >> layId >> x >> y >> width >> height >> visible >> sep >> ws;
73         if( sep != ']' ) goto invalid;
74
75         // Try to find the window and the layout
76         map<string, TopWindowPtr>::const_iterator itWin;
77         map<string, GenericLayoutPtr>::const_iterator itLay;
78         itWin = m_windows.find( winId );
79         itLay = m_layouts.find( layId );
80         if( itWin == m_windows.end() || itLay == m_layouts.end() )
81         {
82             goto invalid;
83         }
84         TopWindow *pWin = itWin->second.get();
85         GenericLayout *pLayout = itLay->second.get();
86
87         // Restore the layout
88         m_windowManager.setActiveLayout( *pWin, *pLayout );
89         if( pLayout->getWidth() != width ||
90             pLayout->getHeight() != height )
91         {
92             m_windowManager.startResize( *pLayout, WindowManager::kResizeSE );
93             m_windowManager.resize( *pLayout, width, height );
94             m_windowManager.stopResize();
95         }
96         // Move the window (which incidentally takes care of the anchoring)
97         m_windowManager.startMove( *pWin );
98         m_windowManager.move( *pWin, x, y );
99         m_windowManager.stopMove();
100         if( visible )
101         {
102             somethingVisible = true;
103             m_windowManager.show( *pWin );
104         }
105     }
106
107     if( !somethingVisible )
108     {
109         goto invalid;
110     }
111     return;
112
113 invalid:
114     msg_Warn( getIntf(), "invalid config: %s", inStream.str().c_str() );
115     // Restore the visibility defined in the theme
116     m_windowManager.showAll( true );
117 }
118
119
120 void Theme::saveConfig()
121 {
122     msg_Dbg( getIntf(), "saving theme configuration");
123
124     map<string, TopWindowPtr>::const_iterator itWin;
125     map<string, GenericLayoutPtr>::const_iterator itLay;
126     ostringstream outStream;
127     for( itWin = m_windows.begin(); itWin != m_windows.end(); itWin++ )
128     {
129         TopWindow *pWin = itWin->second.get();
130
131         // Find the layout id for this window
132         string layoutId;
133         const GenericLayout *pLayout = &pWin->getActiveLayout();
134         for( itLay = m_layouts.begin(); itLay != m_layouts.end(); itLay++ )
135         {
136             if( itLay->second.get() == pLayout )
137             {
138                 layoutId = itLay->first;
139             }
140         }
141
142         outStream << '[' << itWin->first << ' ' << layoutId << ' '
143             << pWin->getLeft() << ' ' << pWin->getTop() << ' '
144             << pLayout->getWidth() << ' ' << pLayout->getHeight() << ' '
145             << (pWin->getVisibleVar().get() ? 1 : 0) << ']';
146     }
147
148     // Save config to file
149     config_PutPsz( getIntf(), "skins2-config", outStream.str().c_str() );
150 }
151
152
153 // Takes an ID of the form "id1;id2;id3", and returns the object
154 // corresponding to the first valid ID. If no ID is valid, it returns NULL.
155 // XXX The string handling here probably could be improved.
156 template<class T> typename T::pointer
157 Theme::IDmap<T>::find_first_object( const string &id ) const
158 {
159     string rightPart = id;
160     string::size_type pos;
161     do
162     {
163         pos = rightPart.find( ";" );
164         string leftPart = rightPart.substr( 0, pos );
165
166         typename T::pointer p = find_object( leftPart );
167         if( p ) return p;
168
169         if( pos != string::npos )
170         {
171             rightPart = rightPart.substr( pos, rightPart.size() );
172             rightPart =
173                 rightPart.substr( rightPart.find_first_not_of( " \t;" ),
174                                   rightPart.size() );
175         }
176     }
177     while( pos != string::npos );
178     return NULL;
179 }
180
181 GenericBitmap *Theme::getBitmapById( const string &id ) const
182 {
183     return m_bitmaps.find_first_object( id );
184 }
185
186 GenericFont *Theme::getFontById( const string &id ) const
187 {
188     return m_fonts.find_first_object( id );
189 }
190