1 /*****************************************************************************
2 * theme.cpp: Theme class
3 *****************************************************************************
4 * Copyright (C) 2003 VideoLAN
5 * $Id: theme.cpp,v 1.3 2003/03/19 18:14:48 karibu 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 ------------------------------------------------------------------
33 #include "os_window.h"
35 #include "os_dialog.h"
43 #include "skin_common.h"
47 //---------------------------------------------------------------------------
49 //---------------------------------------------------------------------------
50 Theme::Theme( intf_thread_t *_p_intf )
53 BmpBank = new BitmapBank( p_intf );
54 FntBank = new FontBank( p_intf );
55 EvtBank = new EventBank( p_intf );
56 OffBank = new OffSetBank( p_intf );
58 ConstructPlaylist = false;
61 ShowInTaskbar = false;
64 //---------------------------------------------------------------------------
68 list<Window *>::const_iterator win;
69 for( win = WindowList.begin(); win != WindowList.end(); win++ )
71 delete (OSWindow *)(*win);
73 delete (OSLogWindow *)Log;
79 //---------------------------------------------------------------------------
80 void Theme::ShowTheme()
82 // Get parameters form vlcrc config file
83 if( ShowInTray != (bool)config_GetInt( p_intf, "show_in_tray" ) )
86 if( ShowInTaskbar != (bool)config_GetInt( p_intf, "show_in_taskbar" ) )
89 list<Window *>::const_iterator win;
93 // Synchronize control to visible aspect
94 for( win = WindowList.begin(); win != WindowList.end(); win++ )
96 // Synchronize windows visibility
97 if( (*win)->OnStartThemeVisible )
99 evt1 = (Event *)new OSEvent( p_intf, (*win), WINDOW_OPEN, 1, 0 );
100 evt2 = (Event *)new OSEvent( p_intf, (*win), WINDOW_CLOSE, 0, 0 );
104 evt1 = (Event *)new OSEvent( p_intf, (*win), WINDOW_OPEN, 0, 0 );
105 evt2 = (Event *)new OSEvent( p_intf, (*win), WINDOW_CLOSE, 1, 0 );
107 evt1->PostSynchroMessage( true );
108 evt2->PostSynchroMessage( true );
111 // Initialize magnetism
115 OSAPI_PostMessage( NULL, VLC_SHOW, 0, 0 );
117 //---------------------------------------------------------------------------
118 void Theme::CreateSystemMenu()
120 AddSystemMenu( "Open file...", EvtBank->Get( "open" ) );
121 AddSystemMenu( "Change skin...", EvtBank->Get( "load_skin" ) );
122 AddSystemMenu( "Preferences...", NULL );
123 AddSystemMenu( "SEPARATOR", 0 );
124 AddSystemMenu( "Exit", EvtBank->Get( "quit" ) );
126 //---------------------------------------------------------------------------
127 void Theme::LoadConfig()
129 // Get config from vlcrc file
130 char *save = config_GetPsz( p_intf, "skin_config" );
135 list<Window *>::const_iterator win;
139 // Get config for each window
140 for( win = WindowList.begin(); win != WindowList.end(); win++ )
143 scan = sscanf( &save[i * 13], "(%4d,%4d,%1d)", &x, &y, &v );
145 // If config has the correct number of arguments
148 (*win)->Move( x, y );
149 (*win)->OnStartThemeVisible = (bool)v;
156 //---------------------------------------------------------------------------
157 void Theme::SaveConfig()
159 // Initialize char where config is stored
160 char *save = new char[400];
161 list<Window *>::const_iterator win;
165 // Save config of every window
166 for( win = WindowList.begin(); win != WindowList.end(); win++ )
169 (*win)->GetPos( x, y );
170 sprintf( &save[i * 13], "(%4d,%4d,%1d)", x, y,
171 (*win)->OnStartThemeVisible );
175 // Save config to file
176 config_PutPsz( p_intf, "skin_config", save );
177 config_PutInt( p_intf, "show_in_tray", (int)ShowInTray );
178 config_PutInt( p_intf, "show_in_taskbar", (int)ShowInTaskbar );
179 config_SaveConfigFile( p_intf, "skins" );
185 //---------------------------------------------------------------------------
186 void Theme::StartTheme( bool log, int magnet )
191 Log = (LogWindow *)new OSLogWindow( p_intf );
194 //---------------------------------------------------------------------------
195 void Theme::InitTheme()
197 // Initialize the events
200 // Initialize the controls
203 // Initialize the windows
206 //---------------------------------------------------------------------------
207 void Theme::InitWindows()
209 for( list<Window *>::const_iterator win = WindowList.begin();
210 win != WindowList.end(); win++ )
215 //---------------------------------------------------------------------------
216 void Theme::InitControls()
218 for( list<Window *>::const_iterator win = WindowList.begin();
219 win != WindowList.end(); win++ )
221 for( unsigned int i = 0; i < (*win)->ControlList.size(); i++ )
223 (*win)->ControlList[i]->Init();
227 //---------------------------------------------------------------------------
228 Window * Theme::GetWindow( string name )
230 for( list<Window *>::const_iterator win = WindowList.begin();
231 win != WindowList.end(); win++ )
233 if( name == OSAPI_GetWindowTitle( *win ) )
240 //---------------------------------------------------------------------------
241 void Theme::MoveSkin( Window *wnd, int left, int top )
243 int x, y, oldx, oldy;
245 list<Anchor *>::const_iterator anc;
246 list<Anchor *>::const_iterator hang;
247 wnd->GetPos( oldx, oldy );
249 // Move child windows recursively
250 for( anc = wnd->AnchorList.begin(); anc != wnd->AnchorList.end(); anc++ )
252 for( hang = (*anc)->HangList.begin(); hang != (*anc)->HangList.end();
255 win = (*hang)->GetParent();
257 MoveSkin( win, left, top );
261 // Move window only if has not been moved yet
265 wnd->Move( oldx + left, oldy + top );
268 //---------------------------------------------------------------------------
269 bool Theme::MoveSkinMagnet( Window *wnd, int left, int top )
272 // If magnetism not activate
275 wnd->Move( left, top );
279 // Screen bounds initialization
283 OSAPI_GetScreenSize( Sx, Sy );
285 wnd->GetSize( width, height );
286 wnd->GetPos( Wx, Wy );
288 // Magnetism with screen bounds
289 if( left < Magnet && left > -Magnet)
291 else if( left + width > Sx - Magnet && left + width < Sx + Magnet )
292 NewLeft = Sx - width;
293 if( top < Magnet && top > -Magnet )
295 else if( top + height > Sy - Magnet && top + height < Sy + Magnet )
296 NewTop = Sy - height;
299 HangToAnchors( wnd, NewLeft, NewTop );
301 // All windows can be moved
302 list<Window *>::const_iterator win;
303 for( win = WindowList.begin(); win != WindowList.end(); win++ )
304 (*win)->Moved = false;
307 MoveSkin( wnd, NewLeft - Wx, NewTop - Wy );
311 //---------------------------------------------------------------------------
312 void Theme::HangToAnchors( Window *wnd, int &x, int &y, bool init )
314 // Magnetism initialization
315 int win_x, win_y, win_anchor_x, win_anchor_y, wnd_anchor_x, wnd_anchor_y;
316 list<Window *>::const_iterator win;
317 list<Anchor *>::const_iterator win_anchor, wnd_anchor;
319 // Parse list of windows
320 for( win = WindowList.begin(); win != WindowList.end(); win++ )
322 // If window is moved window
324 continue; // Check next window
326 // If window is hidden
329 if( (*win)->IsHidden() )
330 continue; // Check next window
334 if( !(*win)->OnStartThemeVisible )
335 continue; // Check next window
338 // Parse anchor lists
339 for( wnd_anchor = wnd->AnchorList.begin();
340 wnd_anchor != wnd->AnchorList.end(); wnd_anchor++ )
342 for( win_anchor = (*win)->AnchorList.begin();
343 win_anchor != (*win)->AnchorList.end(); win_anchor++ )
345 if( (*wnd_anchor)->GetPriority() <
346 (*win_anchor)->GetPriority() )
348 // Parent anchor is win and child is wnd !!!
351 if( !(*win_anchor)->Hang( (*wnd_anchor), x, y ) )
353 // If child is in parent list and parent doesn't hang ch
354 if( (*win_anchor)->IsInList( (*wnd_anchor) ) )
355 (*win_anchor)->Remove( (*wnd_anchor) );
359 // If parent hang child and child is not still in list
360 if( !(*win_anchor)->IsInList( (*wnd_anchor) ) )
361 (*win_anchor)->Add( (*wnd_anchor) );
363 // Move window to stick anchor
364 (*wnd_anchor)->GetPos( wnd_anchor_x, wnd_anchor_y );
365 (*win_anchor)->GetPos( win_anchor_x, win_anchor_y );
366 (*win)->GetPos( win_x, win_y );
368 x = win_x + win_anchor_x - wnd_anchor_x;
369 y = win_y + win_anchor_y - wnd_anchor_y;
375 else if( (*win_anchor)->Hang( (*wnd_anchor), x, y ) )
377 // Move window to stick anchor
378 (*wnd_anchor)->GetPos( wnd_anchor_x, wnd_anchor_y );
379 (*win_anchor)->GetPos( win_anchor_x, win_anchor_y );
380 (*win)->GetPos( win_x, win_y );
382 x = win_x + win_anchor_x - wnd_anchor_x;
383 y = win_y + win_anchor_y - wnd_anchor_y;
391 //---------------------------------------------------------------------------
392 void Theme::CheckAnchors()
394 list<Window *>::const_iterator win;
397 for( win = WindowList.begin(); win != WindowList.end(); win++ )
399 (*win)->GetPos( x, y );
400 HangToAnchors( (*win), x, y, true );
403 //---------------------------------------------------------------------------
404 void Theme::UpdateLog( msg_subscription_t *Sub )
409 //---------------------------------------------------------------------------
410 void Theme::ShowLog( int show )
425 if( Log->IsVisible() )
431 //---------------------------------------------------------------------------
432 void Theme::ClearLog()
437 //---------------------------------------------------------------------------