1 /*****************************************************************************
2 * theme.cpp: Theme class
3 *****************************************************************************
4 * Copyright (C) 2003 VideoLAN
5 * $Id: theme.cpp,v 1.13 2003/04/29 20:36:56 ipkiss Exp $
7 * Authors: Olivier Teulière <ipkiss@via.ecp.fr>
8 * Emmanuel Puig <karibu@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., 59 Temple Place - Suite 330, Boston, MA 02111,
24 *****************************************************************************/
27 //--- VLC -------------------------------------------------------------------
30 //--- SKIN ------------------------------------------------------------------
31 #include "../os_api.h"
33 #include "../os_window.h"
37 #include "../os_event.h"
38 #include "../controls/generic.h"
41 #include "skin_common.h"
45 //---------------------------------------------------------------------------
47 //---------------------------------------------------------------------------
48 Theme::Theme( intf_thread_t *_p_intf )
51 BmpBank = new BitmapBank( p_intf );
52 FntBank = new FontBank( p_intf );
53 EvtBank = new EventBank( p_intf );
54 OffBank = new OffSetBank( p_intf );
55 ConstructPlaylist = false;
58 ShowInTaskbar = false;
61 //---------------------------------------------------------------------------
65 list<SkinWindow *>::const_iterator win;
66 for( win = WindowList.begin(); win != WindowList.end(); win++ )
68 delete (OSWindow *)(*win);
75 //---------------------------------------------------------------------------
76 void Theme::ShowTheme()
78 // Get parameters form vlcrc config file
79 if( ShowInTray != (bool)config_GetInt( p_intf, "show_in_tray" ) )
82 if( ShowInTaskbar != (bool)config_GetInt( p_intf, "show_in_taskbar" ) )
85 list<SkinWindow *>::const_iterator win;
89 // Synchronize control to visible aspect
90 for( win = WindowList.begin(); win != WindowList.end(); win++ )
92 // Synchronize windows visibility
93 if( (*win)->OnStartThemeVisible )
95 evt1 = (Event *)new OSEvent( p_intf, (*win), WINDOW_OPEN, 1, 0 );
96 evt2 = (Event *)new OSEvent( p_intf, (*win), WINDOW_CLOSE, 0, 0 );
100 evt1 = (Event *)new OSEvent( p_intf, (*win), WINDOW_OPEN, 0, 0 );
101 evt2 = (Event *)new OSEvent( p_intf, (*win), WINDOW_CLOSE, 1, 0 );
103 evt1->PostSynchroMessage( true );
104 evt2->PostSynchroMessage( true );
107 // Initialize magnetism
111 OSAPI_PostMessage( NULL, VLC_SHOW, 0, 0 );
113 //---------------------------------------------------------------------------
114 void Theme::CreateSystemMenu()
116 AddSystemMenu( "Open file...", EvtBank->Get( "open" ) );
117 AddSystemMenu( "Change skin...", EvtBank->Get( "load_skin" ) );
118 AddSystemMenu( "Preferences...", NULL );
119 AddSystemMenu( "SEPARATOR", 0 );
120 AddSystemMenu( "Exit", EvtBank->Get( "quit" ) );
122 //---------------------------------------------------------------------------
123 void Theme::LoadConfig()
125 // Get config from vlcrc file
126 char *save = config_GetPsz( p_intf, "skin_config" );
131 list<SkinWindow *>::const_iterator win;
135 // Get config for each window
136 for( win = WindowList.begin(); win != WindowList.end(); win++ )
139 scan = sscanf( &save[i * 13], "(%4d,%4d,%1d)", &x, &y, &v );
141 // If config has the correct number of arguments
144 (*win)->Move( x, y );
145 (*win)->OnStartThemeVisible = (bool)v;
152 //---------------------------------------------------------------------------
153 void Theme::SaveConfig()
155 // Initialize char where config is stored
156 char *save = new char[400];
157 list<SkinWindow *>::const_iterator win;
161 // Save config of every window
162 for( win = WindowList.begin(); win != WindowList.end(); win++ )
165 (*win)->GetPos( x, y );
166 sprintf( &save[i * 13], "(%4d,%4d,%1d)", x, y,
167 (*win)->OnStartThemeVisible );
171 // Save config to file
172 config_PutPsz( p_intf, "skin_config", save );
173 config_PutInt( p_intf, "show_in_tray", (int)ShowInTray );
174 config_PutInt( p_intf, "show_in_taskbar", (int)ShowInTaskbar );
175 config_SaveConfigFile( p_intf, "skins" );
181 //---------------------------------------------------------------------------
182 void Theme::StartTheme( int magnet )
186 //---------------------------------------------------------------------------
187 void Theme::InitTheme()
189 // Initialize the events
192 // Initialize the controls
195 // Initialize the windows
198 //---------------------------------------------------------------------------
199 void Theme::InitWindows()
201 for( list<SkinWindow *>::const_iterator win = WindowList.begin();
202 win != WindowList.end(); win++ )
207 //---------------------------------------------------------------------------
208 void Theme::InitControls()
210 for( list<SkinWindow *>::const_iterator win = WindowList.begin();
211 win != WindowList.end(); win++ )
213 for( unsigned int i = 0; i < (*win)->ControlList.size(); i++ )
215 (*win)->ControlList[i]->Init();
219 //---------------------------------------------------------------------------
220 SkinWindow * Theme::GetWindow( string name )
222 for( list<SkinWindow *>::const_iterator win = WindowList.begin();
223 win != WindowList.end(); win++ )
225 if( name == OSAPI_GetWindowTitle( *win ) )
232 //---------------------------------------------------------------------------
233 void Theme::MoveSkin( SkinWindow *wnd, int left, int top )
235 int x, y, oldx, oldy;
237 list<Anchor *>::const_iterator anc;
238 list<Anchor *>::const_iterator hang;
239 wnd->GetPos( oldx, oldy );
241 // Move child windows recursively
242 for( anc = wnd->AnchorList.begin(); anc != wnd->AnchorList.end(); anc++ )
244 for( hang = (*anc)->HangList.begin(); hang != (*anc)->HangList.end();
247 win = (*hang)->GetParent();
248 // Check that the window hasn't already moved (this avoids
249 // infinite recursion with circular anchoring)
253 MoveSkin( win, left, top );
259 wnd->Move( oldx + left, oldy + top );
261 //---------------------------------------------------------------------------
262 bool Theme::MoveSkinMagnet( SkinWindow *wnd, int left, int top )
265 // If magnetism not activate
268 wnd->Move( left, top );
272 // Screen bounds initialization
276 OSAPI_GetScreenSize( Sx, Sy );
278 wnd->GetSize( width, height );
279 wnd->GetPos( Wx, Wy );
281 // Magnetism with screen bounds
282 if( left < Magnet && left > -Magnet)
284 else if( left + width > Sx - Magnet && left + width < Sx + Magnet )
285 NewLeft = Sx - width;
286 if( top < Magnet && top > -Magnet )
288 else if( top + height > Sy - Magnet && top + height < Sy + Magnet )
289 NewTop = Sy - height;
292 HangToAnchors( wnd, NewLeft, NewTop );
294 // All windows can be moved
295 list<SkinWindow *>::const_iterator win;
296 for( win = WindowList.begin(); win != WindowList.end(); win++ )
297 (*win)->Moved = false;
300 MoveSkin( wnd, NewLeft - Wx, NewTop - Wy );
304 //---------------------------------------------------------------------------
305 void Theme::HangToAnchors( SkinWindow *wnd, int &x, int &y, bool init )
307 // Magnetism initialization
308 int win_x, win_y, win_anchor_x, win_anchor_y, wnd_anchor_x, wnd_anchor_y;
309 list<SkinWindow *>::const_iterator win;
310 list<Anchor *>::const_iterator win_anchor, wnd_anchor;
312 // Parse list of windows
313 for( win = WindowList.begin(); win != WindowList.end(); win++ )
315 // If window is moved window
317 continue; // Check next window
319 // If window is hidden
322 if( (*win)->IsHidden() )
323 continue; // Check next window
327 if( !(*win)->OnStartThemeVisible )
328 continue; // Check next window
331 // Parse anchor lists
332 for( wnd_anchor = wnd->AnchorList.begin();
333 wnd_anchor != wnd->AnchorList.end(); wnd_anchor++ )
335 for( win_anchor = (*win)->AnchorList.begin();
336 win_anchor != (*win)->AnchorList.end(); win_anchor++ )
338 if( (*wnd_anchor)->GetPriority() <
339 (*win_anchor)->GetPriority() )
341 // Parent anchor is win and child is wnd !!!
343 if( !(*win_anchor)->Hang( (*wnd_anchor), x, y ) )
345 // If child is in parent list and parent doesn't hang
347 if( (*win_anchor)->IsInList( (*wnd_anchor) ) )
348 (*win_anchor)->Remove( (*wnd_anchor) );
352 // If parent hangs child and child is not yet in list
353 if( !(*win_anchor)->IsInList( (*wnd_anchor) ) )
355 (*win_anchor)->Add( (*wnd_anchor) );
358 // Move window to stick anchor
359 (*wnd_anchor)->GetPos( wnd_anchor_x, wnd_anchor_y );
360 (*win_anchor)->GetPos( win_anchor_x, win_anchor_y );
361 (*win)->GetPos( win_x, win_y );
363 x = win_x + win_anchor_x - wnd_anchor_x;
364 y = win_y + win_anchor_y - wnd_anchor_y;
370 else if( (*win_anchor)->Hang( (*wnd_anchor), x, y ) )
372 if( !(*wnd_anchor)->IsInList( *win_anchor ) )
374 // Move window to stick anchor
375 (*wnd_anchor)->GetPos( wnd_anchor_x, wnd_anchor_y );
376 (*win_anchor)->GetPos( win_anchor_x, win_anchor_y );
377 (*win)->GetPos( win_x, win_y );
379 x = win_x + win_anchor_x - wnd_anchor_x;
380 y = win_y + win_anchor_y - wnd_anchor_y;
389 //---------------------------------------------------------------------------
390 void Theme::CheckAnchors()
392 list<SkinWindow *>::const_iterator win;
395 for( win = WindowList.begin(); win != WindowList.end(); win++ )
397 (*win)->GetPos( x, y );
398 HangToAnchors( (*win), x, y, true );
399 (*win)->Move( x, y );
402 //---------------------------------------------------------------------------