1 /*****************************************************************************
2 * interface.cpp : wxWidgets plugin for vlc
3 *****************************************************************************
4 * Copyright (C) 2000-2006 the VideoLAN team
7 * Authors: Gildas Bazin <gbazin@videolan.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include "interface.hpp"
28 #include "playlist_manager.hpp"
29 #include "extrapanel.hpp"
34 #include "vlc_charset.h"
37 #include "vlc_charset.h"
39 #include <vlc_interface.h>
41 #include <wx/splitter.h>
43 #include <wx/utils.h> /* wxLaunchDefaultBrowser() */
45 /* include the toolbar graphics */
46 #include "bitmaps/play.xpm"
47 #include "bitmaps/pause.xpm"
48 #include "bitmaps/stop.xpm"
49 #include "bitmaps/prev.xpm"
50 #include "bitmaps/next.xpm"
51 #include "bitmaps/eject.xpm"
52 #include "bitmaps/slow.xpm"
53 #include "bitmaps/fast.xpm"
54 #include "bitmaps/playlist.xpm"
55 #include "bitmaps/playlist_small.xpm"
56 #include "bitmaps/speaker.xpm"
57 #include "bitmaps/speaker_mute.xpm"
59 #define TOOLBAR_BMP_WIDTH 16
60 #define TOOLBAR_BMP_HEIGHT 16
62 /* include the icon graphic */
63 #include "../../../share/vlc32x32.xpm"
64 /* include a small icon graphic for the systray icon */
65 #ifdef wxHAS_TASK_BAR_ICON
66 #include "../../../share/vlc16x16.xpm"
69 /*****************************************************************************
71 *****************************************************************************/
72 static int InteractCallback( vlc_object_t
*, const char *, vlc_value_t
,
75 /*****************************************************************************
76 * Local class declarations.
77 *****************************************************************************/
78 class wxMenuExt
: public wxMenu
82 wxMenuExt( wxMenu
* parentMenu
, int id
, const wxString
& text
,
83 const wxString
& helpString
, wxItemKind kind
,
84 char *_psz_var
, int _i_object_id
, vlc_value_t _val
,
87 virtual ~wxMenuExt() {};
98 class Splitter
: public wxSplitterWindow
101 Splitter( wxWindow
*p_parent
, intf_thread_t
*_p_intf
)
102 : wxSplitterWindow( p_parent
, -1, wxDefaultPosition
, wxSize(0,0),
103 #if defined( __WXMSW__ )
106 wxCLIP_CHILDREN
| wxSP_3DSASH
),
108 p_intf(_p_intf
), b_video(0), i_delay(0)
112 wxSize size
= wxSize(-1, 150);
113 wxPoint p
= wxPoint(0,0);
115 WindowSettings
*ws
= p_intf
->p_sys
->p_window_settings
;
116 ws
->GetSettings( WindowSettings::ID_SMALL_PLAYLIST
, b_dummy
, p
, size
);
118 i_width
= size
.GetWidth();
119 i_sash_position
= size
.GetHeight();
120 b_show_on_start
= !!p
.x
;
125 WindowSettings
*ws
= p_intf
->p_sys
->p_window_settings
;
126 ws
->SetSettings( WindowSettings::ID_SMALL_PLAYLIST
, true,
127 wxPoint(!!GetWindow2(),0),
128 wxSize(i_width
, i_sash_position
) );
131 virtual bool Split( wxWindow
* window1
, wxWindow
* window2
)
134 wxSize size
= wxSize( i_width
, i_sash_position
);
135 if( window2
->GetSizer() ) window2
->GetSizer()->SetMinSize( size
);
137 return wxSplitterWindow::SplitHorizontally( window1
, window2
,
141 virtual bool Unsplit( wxWindow
* window
)
144 return wxSplitterWindow::Unsplit( window
);
147 bool ShowOnStart() { return b_show_on_start
; }
150 DECLARE_EVENT_TABLE()
152 void OnSize( wxSizeEvent
&event
)
154 /* If we display video, then resize the video window */
156 p_intf
->p_sys
->p_video_window
&& p_intf
->p_sys
->p_video_sizer
&&
157 p_intf
->p_sys
->p_video_sizer
->GetMinSize() != wxSize(0,0) )
159 if( !b_video
) i_delay
= mdate() + 1000000;
164 #if defined( __WXMSW__ )
165 SetSashPosition( event
.GetSize().GetHeight() - i_sash_position
);
167 SetSashPosition( event
.GetSize().GetHeight() -
168 i_sash_position
- GetSashSize() );
171 else if( GetWindow2() && GetWindow1() && GetWindow1()->GetSizer() )
173 wxSize size
= GetWindow1()->GetSizer()->GetMinSize();
175 if( b_video
) i_delay
= mdate() + 1000000;
178 if( event
.GetSize().GetHeight() - size
.GetHeight() )
182 SetSashPosition( size
.GetHeight() ? size
.GetHeight() : 1 );
184 if( i_delay
< mdate() )
186 i_sash_position
= event
.GetSize().GetHeight() -
188 i_width
= event
.GetSize().GetWidth();
190 size
= wxSize( i_width
, i_sash_position
);
191 if( GetWindow2()->GetSizer() )
192 GetWindow2()->GetSizer()->SetMinSize( size
);
200 void OnSashPosChanged( wxSplitterEvent
&event
)
202 if( !GetSize().GetHeight() ){ event
.Skip(); return; }
204 if( i_delay
< mdate() )
206 i_sash_position
= GetSize().GetHeight() - event
.GetSashPosition();
208 wxSize size
= wxSize( i_width
, i_sash_position
);
209 if( GetWindow2()->GetSizer() )
210 GetWindow2()->GetSizer()->SetMinSize( size
);
215 intf_thread_t
*p_intf
;
220 vlc_bool_t b_show_on_start
;
223 BEGIN_EVENT_TABLE(Splitter
, wxSplitterWindow
)
224 EVT_SIZE( Splitter::OnSize
)
225 EVT_SPLITTER_SASH_POS_CHANGED(-1, Splitter::OnSashPosChanged
)
228 /*****************************************************************************
230 *****************************************************************************/
232 DEFINE_LOCAL_EVENT_TYPE( wxEVT_INTF
);
234 /* IDs for the controls and the menu commands */
238 MenuDummy_Event
= wxID_HIGHEST
+ 1000,
239 Exit_Event
= wxID_HIGHEST
,
240 OpenFileSimple_Event
,
272 /* it is important for the id corresponding to the "About" command to have
273 * this standard value as otherwise it won't be handled properly under Mac
274 * (where it is special and put into the "Apple" menu) */
275 About_Event
= wxID_ABOUT
,
286 DEFINE_LOCAL_EVENT_TYPE( wxEVT_INTERACTION
);
288 BEGIN_EVENT_TABLE(Interface
, wxFrame
)
290 EVT_MENU(Exit_Event
, Interface::OnExit
)
291 EVT_MENU(About_Event
, Interface::OnAbout
)
292 EVT_MENU(OnWebLink_Event
, Interface::OnWebLink
)
293 EVT_MENU(OnWebHelp_Event
, Interface::OnWebHelp
)
295 EVT_MENU(UpdateVLC_Event
, Interface::OnShowDialog
)
297 //EVT_MENU(VLM_Event, Interface::OnShowDialog)
299 EVT_MENU(Playlist_Event
, Interface::OnShowDialog
)
300 EVT_MENU(PlaylistSmall_Event
, Interface::OnSmallPlaylist
)
301 EVT_MENU(Logs_Event
, Interface::OnShowDialog
)
302 EVT_MENU(FileInfo_Event
, Interface::OnShowDialog
)
303 EVT_MENU(Prefs_Event
, Interface::OnShowDialog
)
305 EVT_MENU_OPEN(Interface::OnMenuOpen
)
307 EVT_MENU( Extended_Event
, Interface::OnExtended
)
309 EVT_MENU( Bookmarks_Event
, Interface::OnShowDialog
)
311 #if defined( __WXMSW__ ) || defined( __WXMAC__ )
312 EVT_CONTEXT_MENU(Interface::OnContextMenu2
)
314 EVT_RIGHT_UP(Interface::OnContextMenu
)
317 EVT_MENU(OpenFileSimple_Event
, Interface::OnShowDialog
)
318 EVT_MENU(OpenAdv_Event
, Interface::OnShowDialog
)
319 EVT_MENU(OpenFile_Event
, Interface::OnShowDialog
)
320 EVT_MENU(OpenDir_Event
, Interface::OnShowDialog
)
321 EVT_MENU(OpenDisc_Event
, Interface::OnShowDialog
)
322 EVT_MENU(OpenNet_Event
, Interface::OnShowDialog
)
323 EVT_MENU(OpenCapture_Event
, Interface::OnShowDialog
)
324 EVT_MENU(OpenSat_Event
, Interface::OnShowDialog
)
325 EVT_MENU(Wizard_Event
, Interface::OnShowDialog
)
326 EVT_MENU(StopStream_Event
, Interface::OnStopStream
)
327 EVT_MENU(PlayStream_Event
, Interface::OnPlayStream
)
328 EVT_MENU(PrevStream_Event
, Interface::OnPrevStream
)
329 EVT_MENU(NextStream_Event
, Interface::OnNextStream
)
330 EVT_MENU(SlowStream_Event
, Interface::OnSlowStream
)
331 EVT_MENU(FastStream_Event
, Interface::OnFastStream
)
332 EVT_MENU(ToggleMute_Event
, Interface::OnToggleMute
)
333 EVT_COMMAND_SCROLL(SlideVolume_Event
, Interface::OnSlideVolume
)
336 EVT_COMMAND(0, wxEVT_INTF
, Interface::OnControlEvent
)
337 EVT_COMMAND(1, wxEVT_INTF
, Interface::OnControlEvent
)
339 EVT_COMMAND( -1, wxEVT_INTERACTION
, Interface::OnInteraction
)
342 /*****************************************************************************
344 *****************************************************************************/
345 Interface::Interface( intf_thread_t
*_p_intf
, long style
):
346 wxFrame( NULL
, -1, wxT("VLC media player"),
347 wxDefaultPosition
, wxSize(700,100), style
)
349 /* Initializations */
353 playlist_manager
= 0;
354 i_update_counter
= 0;
357 /* Give our interface a nice little icon */
358 SetIcon( wxIcon( (const char**) vlc_xpm
) );
360 /* Create a splitter window that will fill in the interface window.
361 * We need a splitter bar in order to make the embedded playlist
363 splitter
= new Splitter( this, p_intf
);
364 main_sizer
= new wxBoxSizer( wxVERTICAL
);
365 main_sizer
->Add( splitter
, 1, wxEXPAND
);
366 SetSizer( main_sizer
);
368 /* Create a main panel that will fill in the interface window */
369 main_panel
= new wxPanel( splitter
, -1, wxPoint(0,0), wxSize(0,0),
371 main_panel
->SetFocus();
373 #if defined(__WXGTK20__) && wxCHECK_VERSION(2,5,6)
374 /* As ugly as your butt! Please remove when wxWidgets 2.6 fixed their
375 * Accelerators bug. */
376 main_panel
->m_imData
= 0;
380 /* Create a sizer for the main frame */
381 panel_sizer
= new wxBoxSizer( wxVERTICAL
);
382 main_panel
->SetSizer( panel_sizer
);
384 /* Put this in the splitter */
385 splitter
->Initialize( main_panel
);
387 /* wxCocoa pretends to support this, but at least 2.6.x doesn't */
389 #ifdef wxHAS_TASK_BAR_ICON
390 /* Systray integration */
392 if( config_GetInt( p_intf
, "wx-systray" ) )
394 p_systray
= new Systray( this, p_intf
);
399 /* Creation of the menu bar */
402 /* Creation of the tool bar */
405 /* Creation of the status bar
406 * Helptext for menu items and toolbar tools will automatically get
408 int i_status_width
[3] = {150, 55, -1};
409 statusbar
= CreateStatusBar( 3 ); /* 2 fields */
410 statusbar
->SetStatusWidths( 3, i_status_width
);
411 statusbar
->SetStatusText( wxString::Format(wxT("x%.2f"), 1.0), 1 );
413 /* Get minimum window size to prevent user from glitching it */
414 splitter
->SetSizeHints( -1, 0 );
415 panel_sizer
->Layout(); panel_sizer
->Fit( main_panel
);
416 main_sizer
->Layout(); main_sizer
->Fit( this );
417 main_min_size
= GetSize();
418 /* FIXME HACK as far as i understan (i.e. not a lot) the toolbar
419 * doesn't take the labels into account when it returns its size */
421 if( config_GetInt(p_intf
, "wx-labels") )
423 main_min_size
.SetWidth(800);
425 splitter
->SetSizeHints( -1, -1 );
429 if( config_GetInt( p_intf
, "wx-embed" ) )
431 video_window
= CreateVideoWindow( p_intf
, main_panel
);
432 panel_sizer
->Add( p_intf
->p_sys
->p_video_sizer
, 1, wxEXPAND
, 0 );
435 /* Creation of the input manager panel */
436 input_manager
= new InputManager( p_intf
, this, main_panel
);
437 panel_sizer
->Add( input_manager
, 0, wxEXPAND
, 0 );
439 /* Layout everything */
440 splitter
->SetSizeHints( -1, 0 );
441 panel_sizer
->Layout(); panel_sizer
->Fit( main_panel
);
442 main_sizer
->Layout(); main_sizer
->Fit( this );
443 splitter
->SetSizeHints( -1, -1 );
445 #if wxUSE_DRAG_AND_DROP
446 /* Associate drop targets with the main interface */
447 SetDropTarget( new DragAndDrop( p_intf
) );
453 timer
= new Timer( p_intf
, this );
455 /* Restore previous position / settings */
456 WindowSettings
*ws
= p_intf
->p_sys
->p_window_settings
;
461 ws
->SetScreen( wxSystemSettings::GetMetric( wxSYS_SCREEN_X
),
462 wxSystemSettings::GetMetric( wxSYS_SCREEN_Y
) );
464 if( ws
->GetSettings( WindowSettings::ID_MAIN
, b_shown
, p
, s
) ) Move( p
);
466 /* Show extended GUI if requested */
467 wxCommandEvent dummy
;
468 if( config_GetInt( p_intf
, "wx-extended" ) ) OnExtended( dummy
);
472 var_Create( p_intf
, "interaction", VLC_VAR_ADDRESS
);
473 var_AddCallback( p_intf
, "interaction", InteractCallback
, this );
474 p_intf
->b_interaction
= VLC_TRUE
;
476 /* Show embedded playlist if requested */
477 if( splitter
->ShowOnStart() ) OnSmallPlaylist( dummy
);
480 Interface::~Interface()
482 WindowSettings
*ws
= p_intf
->p_sys
->p_window_settings
;
486 ws
->SetSettings( WindowSettings::ID_MAIN
, true,
487 GetPosition(), GetSize() );
490 PopEventHandler(true);
494 /* wxCocoa pretends to support this, but at least 2.6.x doesn't */
496 #ifdef wxHAS_TASK_BAR_ICON
501 p_intf
->b_interaction
= VLC_FALSE
;
502 var_DelCallback( p_intf
, "interaction", InteractCallback
, this );
504 delete p_intf
->p_sys
->p_wxwindow
;
511 void Interface::Init()
517 void Interface::Update()
521 if( playlist_manager
) playlist_manager
->Update();
526 void Interface::OnControlEvent( wxCommandEvent
& event
)
528 switch( event
.GetId() )
531 main_sizer
->Layout();
532 main_sizer
->Fit( this );
536 long i_style
= GetWindowStyle();
537 if( event
.GetInt() ) i_style
|= wxSTAY_ON_TOP
;
538 else i_style
&= ~wxSTAY_ON_TOP
;
539 SetWindowStyle( i_style
);
544 /*****************************************************************************
546 *****************************************************************************/
547 void Interface::CreateOurMenuBar()
549 int minimal
= config_GetInt( p_intf
, "wx-minimal" );
551 /* Create the "File" menu */
552 wxMenu
*file_menu
= new wxMenu
;
556 file_menu
->Append( OpenFileSimple_Event
,
557 wxU(_("Quick &Open File...\tCtrl-O")) );
559 file_menu
->AppendSeparator();
560 file_menu
->Append( OpenFile_Event
, wxU(_("Open &File...\tCtrl-F")) );
561 file_menu
->Append( OpenDir_Event
, wxU(_("Open Dir&ectory...\tCtrl-E")) );
562 file_menu
->Append( OpenDisc_Event
, wxU(_("Open &Disc...\tCtrl-D")) );
563 file_menu
->Append( OpenNet_Event
,
564 wxU(_("Open &Network Stream...\tCtrl-N")) );
565 file_menu
->Append( OpenCapture_Event
,
566 wxU(_("Open C&apture Device...\tCtrl-A")) );
568 file_menu
->AppendSeparator();
569 file_menu
->Append( Wizard_Event
, wxU(_("&Wizard...\tCtrl-W")) );
570 file_menu
->AppendSeparator();
572 file_menu
->Append( Exit_Event
, wxU(_("E&xit\tCtrl-X")) );
574 /* Create the "View" menu */
575 wxMenu
*view_menu
= new wxMenu
;
578 view_menu
->Append( Playlist_Event
, wxU(_("&Playlist...\tCtrl-P")) );
580 view_menu
->Append( Logs_Event
, wxU(_("&Messages...\tCtrl-M")) );
581 view_menu
->Append( FileInfo_Event
,
582 wxU(_("Stream and Media &Info...\tCtrl-I")) );
584 view_menu
->Append( VLM_Event
,
585 wxU(_("VLM Control...\tCtrl-V")) );
588 /* Create the "Auto-generated" menus */
589 p_settings_menu
= SettingsMenu( p_intf
, this );
590 p_audio_menu
= AudioMenu( p_intf
, this );
591 p_video_menu
= VideoMenu( p_intf
, this );
592 p_navig_menu
= NavigMenu( p_intf
, this );
594 /* Create the "Help" menu */
595 wxMenu
*help_menu
= new wxMenu
;
596 help_menu
->Append( OnWebLink_Event
, wxU(_("VideoLAN's Website")) );
597 help_menu
->Append( OnWebHelp_Event
, wxU(_("Online Help")) );
598 help_menu
->AppendSeparator();
599 help_menu
->Append( About_Event
, wxU(_("About...")) );
601 help_menu
->AppendSeparator();
602 help_menu
->Append( UpdateVLC_Event
, wxU(_("Check for Updates...")) );
605 /* Append the freshly created menus to the menu bar... */
606 wxMenuBar
*menubar
= new wxMenuBar();
607 menubar
->Append( file_menu
, wxU(_("&File")) );
608 menubar
->Append( view_menu
, wxU(_("V&iew")) );
609 menubar
->Append( p_settings_menu
, wxU(_("&Settings")) );
610 menubar
->Append( p_audio_menu
, wxU(_("&Audio")) );
611 menubar
->Append( p_video_menu
, wxU(_("&Video")) );
612 menubar
->Append( p_navig_menu
, wxU(_("&Navigation")) );
613 menubar
->Append( help_menu
, wxU(_("&Help")) );
615 /* Attach the menu bar to the frame */
616 SetMenuBar( menubar
);
618 /* Find out size of menu bar */
620 for( unsigned int i
= 0; i
< menubar
->GetMenuCount(); i
++ )
622 int i_width
, i_height
;
623 menubar
->GetTextExtent( menubar
->GetLabelTop(i
), &i_width
, &i_height
);
625 #if defined(__WXGTK__)
626 22 /* approximate margin */;
628 #if (wxMAJOR_VERSION <= 2) && (wxMINOR_VERSION <= 5) && (wxRELEASE_NUMBER < 3)
629 4 /* approximate margin */;
631 18 /* approximate margin */;
636 /* Patch by zcot for menu wrapping */
638 /* Find out size of msw menu bar */
641 HDC hdc
= GetDC( NULL
);
642 for( unsigned int i
= 0; i
< menubar
->GetMenuCount(); i
++ )
644 GetTextExtentPoint32( hdc
, menubar
->GetLabelTop(i
).c_str(),
645 menubar
->GetLabelTop(i
).Length(), &sizing
);
647 // [ SM_CXDLGFRAME + pixels + textextent + pixels + SM_CXDLGFRAME ]
648 i_size
+= sizing
.cx
+ 2 + GetSystemMetrics( SM_CXDLGFRAME
) * 2;
650 ReleaseDC( NULL
, hdc
);
651 i_size
+= GetSystemMetrics( SM_CXSIZEFRAME
) * 2 + 4;
653 /* End patch by zcot */
655 panel_sizer
->SetMinSize( i_size
, -1 );
657 /* Intercept all menu events in our custom event handler */
658 PushEventHandler( new MenuEvtHandler( p_intf
, this ) );
660 #if wxUSE_DRAG_AND_DROP
661 /* Associate drop targets with the menubar */
662 menubar
->SetDropTarget( new DragAndDrop( p_intf
) );
666 void Interface::CreateOurToolBar()
668 #define HELP_OPEN N_("Open")
669 #define HELP_STOP N_("Stop")
670 #define HELP_PLAY N_("Play")
671 #define HELP_PAUSE N_("Pause")
672 #define HELP_PLO N_("Playlist")
673 #define HELP_SPLO N_("Embedded playlist")
674 #define HELP_PLP N_("Previous playlist item")
675 #define HELP_PLN N_("Next playlist item")
676 #define HELP_SLOW N_("Play slower")
677 #define HELP_FAST N_("Play faster")
678 #define HELP_VOL N_("Toggle mute/unmute of the audio")
680 #define LABEL_OPEN N_("Open")
681 #define LABEL_STOP N_("Stop")
682 #define LABEL_PLAY N_("Play")
683 #define LABEL_PAUSE N_("Pause")
684 #define LABEL_PLO N_("Playlist")
685 #define LABEL_SPLO N_("Embedded playlist")
686 #define LABEL_PLP N_("Previous")
687 #define LABEL_PLN N_("Next")
688 #define LABEL_SLOW N_("Slower")
689 #define LABEL_FAST N_("Faster")
690 #define LABEL_VOL N_("Mute")
692 int minimal
= config_GetInt( p_intf
, "wx-minimal" );
693 bool label
= config_GetInt( p_intf
, "wx-labels" );
695 wxLogNull LogDummy
; /* Hack to suppress annoying log message on the win32
696 * version because we don't include wx.rc */
699 CreateToolBar( label
?wxTB_HORIZONTAL
| wxTB_FLAT
|wxTB_TEXT
:
700 wxTB_HORIZONTAL
| wxTB_FLAT
);
702 toolbar
->SetToolBitmapSize( wxSize(TOOLBAR_BMP_WIDTH
,TOOLBAR_BMP_HEIGHT
) );
706 toolbar
->AddTool( OpenFile_Event
, wxU(LABEL_OPEN
),
707 wxBitmap( eject_xpm
), wxU(_(HELP_OPEN
)) );
708 toolbar
->AddSeparator();
711 wxToolBarToolBase
*p_tool
= toolbar
->AddTool( PlayStream_Event
, wxU(LABEL_PLAY
),
712 wxBitmap( play_xpm
), wxU(_(HELP_PLAY
)), wxITEM_CHECK
);
713 p_tool
->SetClientData( p_tool
);
717 toolbar
->AddTool( StopStream_Event
, wxU(LABEL_STOP
), wxBitmap( stop_xpm
),
719 toolbar
->AddSeparator();
721 toolbar
->AddTool( PrevStream_Event
, wxU(LABEL_PLP
),
722 wxBitmap( prev_xpm
), wxU(_(HELP_PLP
)) );
723 toolbar
->AddTool( SlowStream_Event
, wxU(LABEL_SLOW
),
724 wxBitmap( slow_xpm
), wxU(_(HELP_SLOW
)) );
725 toolbar
->AddTool( FastStream_Event
, wxU(LABEL_FAST
),
726 wxBitmap( fast_xpm
), wxU(_(HELP_FAST
)) );
727 toolbar
->AddTool( NextStream_Event
, wxU(LABEL_PLN
), wxBitmap( next_xpm
),
729 toolbar
->AddSeparator();
730 if( config_GetInt( p_intf
, "wx-playlist-view" ) != 1 )
731 toolbar
->AddTool( Playlist_Event
, wxU(LABEL_PLO
),
732 wxBitmap( playlist_xpm
), wxU(_(HELP_PLO
)) );
733 if( config_GetInt( p_intf
, "wx-playlist-view" ) >= 1 )
734 toolbar
->AddTool( PlaylistSmall_Event
, wxU(LABEL_SPLO
),
735 wxBitmap( playlist_small_xpm
), wxU(_(HELP_SPLO
)) );
738 wxToolBarToolBase
*v_tool
= toolbar
->AddTool( ToggleMute_Event
,
739 wxU(LABEL_VOL
), wxBitmap( speaker_xpm
),
740 wxU(_(HELP_VOL
)), wxITEM_CHECK
);
741 v_tool
->SetClientData( v_tool
);
743 wxSlider
*v_gauge
= new wxSlider(toolbar
, SlideVolume_Event
, 256, 0,
744 AOUT_VOLUME_MAX
, wxDefaultPosition
,
745 wxSize(64,TOOLBAR_BMP_HEIGHT
), wxSL_HORIZONTAL
);
746 toolbar
->AddControl(v_gauge
);
750 #if wxUSE_DRAG_AND_DROP
751 /* Associate drop targets with the toolbar */
752 toolbar
->SetDropTarget( new DragAndDrop( p_intf
) );
756 static int ConvertHotkeyModifiers( int i_hotkey
)
758 int i_accel_flags
= 0;
759 if( i_hotkey
& KEY_MODIFIER_ALT
) i_accel_flags
|= wxACCEL_ALT
;
760 if( i_hotkey
& KEY_MODIFIER_CTRL
) i_accel_flags
|= wxACCEL_CTRL
;
761 if( i_hotkey
& KEY_MODIFIER_SHIFT
) i_accel_flags
|= wxACCEL_SHIFT
;
762 if( !i_accel_flags
) i_accel_flags
= wxACCEL_NORMAL
;
763 return i_accel_flags
;
766 static int ConvertHotkey( int i_hotkey
)
768 int i_key
= i_hotkey
& ~KEY_MODIFIER
;
769 if( i_key
& KEY_ASCII
) return i_key
& KEY_ASCII
;
770 else if( i_key
& KEY_SPECIAL
)
774 case KEY_LEFT
: return WXK_LEFT
;
775 case KEY_RIGHT
: return WXK_RIGHT
;
776 case KEY_UP
: return WXK_UP
;
777 case KEY_DOWN
: return WXK_DOWN
;
778 case KEY_SPACE
: return WXK_SPACE
;
779 case KEY_ENTER
: return WXK_RETURN
;
780 case KEY_F1
: return WXK_F1
;
781 case KEY_F2
: return WXK_F2
;
782 case KEY_F3
: return WXK_F3
;
783 case KEY_F4
: return WXK_F4
;
784 case KEY_F5
: return WXK_F5
;
785 case KEY_F6
: return WXK_F6
;
786 case KEY_F7
: return WXK_F7
;
787 case KEY_F8
: return WXK_F8
;
788 case KEY_F9
: return WXK_F9
;
789 case KEY_F10
: return WXK_F10
;
790 case KEY_F11
: return WXK_F11
;
791 case KEY_F12
: return WXK_F12
;
792 case KEY_HOME
: return WXK_HOME
;
793 case KEY_END
: return WXK_END
;
794 case KEY_INSERT
: return WXK_INSERT
;
795 case KEY_DELETE
: return WXK_DELETE
;
796 case KEY_MENU
: return WXK_MENU
;
797 case KEY_ESC
: return WXK_ESCAPE
;
798 case KEY_PAGEUP
: return WXK_PRIOR
;
799 case KEY_PAGEDOWN
: return WXK_NEXT
;
800 case KEY_TAB
: return WXK_TAB
;
801 case KEY_BACKSPACE
: return WXK_BACK
;
807 void Interface::SetupHotkeys()
809 struct libvlc_int_t::hotkey
*p_hotkeys
= p_intf
->p_libvlc
->p_hotkeys
;
812 /* Count number of hoteys */
813 for( i_hotkeys
= 0; p_hotkeys
[i_hotkeys
].psz_action
!= NULL
; i_hotkeys
++ );
815 p_intf
->p_sys
->i_first_hotkey_event
= wxID_HIGHEST
+ 7000;
816 p_intf
->p_sys
->i_hotkeys
= i_hotkeys
;
818 wxAcceleratorEntry
*p_entries
= new wxAcceleratorEntry
[i_hotkeys
];
820 /* Setup the hotkeys as accelerators */
821 for( int i
= 0; i
< i_hotkeys
; i
++ )
823 int i_mod
= ConvertHotkeyModifiers( p_hotkeys
[i
].i_key
);
824 int i_key
= ConvertHotkey( p_hotkeys
[i
].i_key
);
827 if( !(p_hotkeys
[i
].i_key
& KEY_SPECIAL
) && i_mod
)
828 i_key
= toupper(i_key
);
831 p_entries
[i
].Set( i_mod
, i_key
,
832 p_intf
->p_sys
->i_first_hotkey_event
+ i
);
835 wxAcceleratorTable
accel( i_hotkeys
, p_entries
);
839 msg_Err( p_intf
, "invalid accelerator table" );
843 SetAcceleratorTable( accel
);
849 void Interface::SetIntfMinSize()
851 wxSize ms
= main_min_size
;
853 if( extra_frame
&& extra_frame
->IsShown() )
855 ms
.SetHeight( ms
.GetHeight() + ext_min_size
.GetHeight() );
856 if( ext_min_size
.GetWidth() > ms
.GetWidth() )
857 ms
.SetWidth( ext_min_size
.GetWidth() );
860 SetSizeHints( ms
.GetWidth(), ms
.GetHeight() );
863 /*****************************************************************************
865 *****************************************************************************/
866 void Interface::OnMenuOpen( wxMenuEvent
& event
)
868 #if defined( __WXMSW__ )
869 # define GetEventObject GetMenu
872 if( event
.GetEventObject() == p_settings_menu
)
874 p_settings_menu
= SettingsMenu( p_intf
, this, p_settings_menu
);
876 /* Add static items */
877 p_settings_menu
->AppendCheckItem( Extended_Event
,
878 wxU(_("Extended &GUI\tCtrl-G") ) );
879 if( b_extra
) p_settings_menu
->Check( Extended_Event
, TRUE
);
880 p_settings_menu
->Append( Bookmarks_Event
,
881 wxU(_("&Bookmarks...\tCtrl-B") ) );
882 p_settings_menu
->Append( Prefs_Event
,
883 wxU(_("Preference&s...\tCtrl-S")) );
886 else if( event
.GetEventObject() == p_audio_menu
)
888 p_audio_menu
= AudioMenu( p_intf
, this, p_audio_menu
);
891 else if( event
.GetEventObject() == p_video_menu
)
893 p_video_menu
= VideoMenu( p_intf
, this, p_video_menu
);
896 else if( event
.GetEventObject() == p_navig_menu
)
898 p_navig_menu
= NavigMenu( p_intf
, this, p_navig_menu
);
901 #if defined( __WXMSW__ )
902 # undef GetEventObject
906 #if defined( __WXMSW__ ) || defined( __WXMAC__ )
907 void Interface::OnContextMenu2(wxContextMenuEvent
& event
)
909 /* Only show the context menu for the main interface */
910 if( GetId() != event
.GetId() )
916 if( p_intf
->p_sys
->pf_show_dialog
)
917 p_intf
->p_sys
->pf_show_dialog( p_intf
, INTF_DIALOG_POPUPMENU
, 1, 0 );
920 void Interface::OnContextMenu(wxMouseEvent
& event
)
922 if( p_intf
->p_sys
->pf_show_dialog
)
923 p_intf
->p_sys
->pf_show_dialog( p_intf
, INTF_DIALOG_POPUPMENU
, 1, 0 );
926 void Interface::OnExit( wxCommandEvent
& WXUNUSED(event
) )
928 /* TRUE is to force the frame to close. */
932 void Interface::OnAbout( wxCommandEvent
& WXUNUSED(event
) )
935 msg
.Printf( wxString(wxT("VLC media player " VERSION_MESSAGE
)) +
936 wxU(_(" (wxWidgets interface)\n\n")) +
937 wxU(_("(c) " COPYRIGHT_YEARS
" - the VideoLAN Team\n\n")) +
938 wxU(_("Compiled by "))+ wxU(VLC_CompileBy())+ wxU("@") +
939 wxU(VLC_CompileHost())+ wxT(".")+ wxU(VLC_CompileDomain())+ wxT(".\n") +
940 wxU(_("Compiler: "))+ wxU(VLC_Compiler())+wxT( ".\n") +
941 wxU(_("Based on Git commit: "))+wxU(VLC_Changeset())+wxT(".\n\n") +
943 wxU( vlc_wraptext(LICENSE_MSG
,WRAPCOUNT
) ) + wxT("\n\n") +
945 wxU( LICENSE_MSG
) + wxT("\n\n") +
947 wxU(_("The VideoLAN team <videolan@videolan.org>\n"
948 "http://www.videolan.org/\n\n")) );
949 wxMessageBox( msg
, wxString::Format(wxU(_("About %s")),
950 wxT("VLC media player")), wxOK
| wxICON_INFORMATION
, this );
953 void Interface::OnWebLink( wxCommandEvent
& WXUNUSED(event
) )
955 wxLaunchDefaultBrowser( wxU("http://videolan.org/") );
958 void Interface::OnWebHelp( wxCommandEvent
& WXUNUSED(event
) )
960 wxLaunchDefaultBrowser( wxU("http://videolan.org/doc/") );
963 void Interface::OnShowDialog( wxCommandEvent
& event
)
965 if( p_intf
->p_sys
->pf_show_dialog
)
969 switch( event
.GetId() )
971 case OpenFileSimple_Event
:
972 i_id
= INTF_DIALOG_FILE_SIMPLE
;
975 i_id
= INTF_DIALOG_FILE
;
978 i_id
= INTF_DIALOG_FILE
;
981 i_id
= INTF_DIALOG_DIRECTORY
;
984 i_id
= INTF_DIALOG_DISC
;
987 i_id
= INTF_DIALOG_NET
;
989 case OpenCapture_Event
:
990 i_id
= INTF_DIALOG_CAPTURE
;
993 i_id
= INTF_DIALOG_SAT
;
996 i_id
= INTF_DIALOG_PLAYLIST
;
999 i_id
= INTF_DIALOG_MESSAGES
;
1001 case FileInfo_Event
:
1002 i_id
= INTF_DIALOG_FILEINFO
;
1005 i_id
= INTF_DIALOG_PREFS
;
1008 i_id
= INTF_DIALOG_WIZARD
;
1010 case Bookmarks_Event
:
1011 i_id
= INTF_DIALOG_BOOKMARKS
;
1014 case UpdateVLC_Event
:
1015 i_id
= INTF_DIALOG_UPDATEVLC
;
1020 i_id
= INTF_DIALOG_VLM
;
1024 i_id
= INTF_DIALOG_FILE
;
1028 p_intf
->p_sys
->pf_show_dialog( p_intf
, i_id
, 1, 0 );
1032 void Interface::OnExtended( wxCommandEvent
& WXUNUSED(event
) )
1034 UpdateVideoWindow( p_intf
, video_window
);
1038 /* Create the extra panel */
1039 extra_frame
= new ExtraPanel( p_intf
, main_panel
);
1040 panel_sizer
->Add( extra_frame
, 0, wxEXPAND
, 0 );
1041 ext_min_size
= extra_frame
->GetBestSize();
1045 panel_sizer
->Show( extra_frame
, b_extra
);
1048 main_sizer
->Layout();
1049 main_sizer
->Fit( this );
1052 void Interface::OnSmallPlaylist( wxCommandEvent
& WXUNUSED(event
) )
1054 UpdateVideoWindow( p_intf
, video_window
);
1056 if( !playlist_manager
)
1058 /* Create the extra panel */
1059 playlist_manager
= new PlaylistManager( p_intf
, splitter
);
1062 if( !splitter
->IsSplit() ) splitter
->Split( main_panel
, playlist_manager
);
1063 else splitter
->Unsplit( playlist_manager
);
1066 main_sizer
->Layout();
1067 main_sizer
->Fit( this );
1070 void Interface::OnPlayStream( wxCommandEvent
& WXUNUSED(event
) )
1075 void Interface::PlayStream()
1077 wxCommandEvent dummy
;
1078 playlist_t
*p_playlist
=
1079 (playlist_t
*)vlc_object_find( p_intf
, VLC_OBJECT_PLAYLIST
,
1081 if( p_playlist
== NULL
) return;
1083 if( !playlist_IsEmpty(p_playlist
) && p_playlist
->i_enabled
)
1087 input_thread_t
*p_input
= (input_thread_t
*)vlc_object_find( p_intf
,
1090 if( p_input
== NULL
)
1092 /* No stream was playing, start one */
1093 playlist_Play( p_playlist
);
1094 vlc_object_release( p_playlist
);
1095 input_manager
->Update();
1099 var_Get( p_input
, "state", &state
);
1100 if( state
.i_int
!= PAUSE_S
)
1102 /* A stream is being played, pause it */
1103 state
.i_int
= PAUSE_S
;
1107 /* Stream is paused, resume it */
1108 state
.i_int
= PLAYING_S
;
1110 var_Set( p_input
, "state", state
);
1112 vlc_object_release( p_input
);
1113 vlc_object_release( p_playlist
);
1114 input_manager
->Update();
1118 /* If the playlist is empty, open a file requester instead */
1119 vlc_object_release( p_playlist
);
1120 OnShowDialog( dummy
);
1121 GetToolBar()->ToggleTool( PlayStream_Event
, false );
1125 void Interface::OnStopStream( wxCommandEvent
& WXUNUSED(event
) )
1129 void Interface::StopStream()
1131 playlist_t
* p_playlist
=
1132 (playlist_t
*)vlc_object_find( p_intf
, VLC_OBJECT_PLAYLIST
,
1134 if( p_playlist
== NULL
)
1139 playlist_Stop( p_playlist
);
1140 vlc_object_release( p_playlist
);
1141 input_manager
->Update();
1144 void Interface::OnPrevStream( wxCommandEvent
& WXUNUSED(event
) )
1149 void Interface::PrevStream()
1151 playlist_t
* p_playlist
=
1152 (playlist_t
*)vlc_object_find( p_intf
, VLC_OBJECT_PLAYLIST
,
1154 if( p_playlist
== NULL
)
1159 playlist_Prev( p_playlist
);
1160 vlc_object_release( p_playlist
);
1163 void Interface::OnNextStream( wxCommandEvent
& WXUNUSED(event
) )
1168 void Interface::NextStream()
1170 playlist_t
* p_playlist
=
1171 (playlist_t
*)vlc_object_find( p_intf
, VLC_OBJECT_PLAYLIST
,
1173 if( p_playlist
== NULL
)
1177 playlist_Next( p_playlist
);
1178 vlc_object_release( p_playlist
);
1181 void Interface::OnSlowStream( wxCommandEvent
& WXUNUSED(event
) )
1183 input_thread_t
*p_input
=
1184 (input_thread_t
*)vlc_object_find( p_intf
, VLC_OBJECT_INPUT
,
1188 vlc_value_t val
; val
.b_bool
= VLC_TRUE
;
1190 var_Set( p_input
, "rate-slower", val
);
1191 vlc_object_release( p_input
);
1195 void Interface::OnFastStream( wxCommandEvent
& WXUNUSED(event
) )
1197 input_thread_t
*p_input
=
1198 (input_thread_t
*)vlc_object_find( p_intf
, VLC_OBJECT_INPUT
,
1202 vlc_value_t val
; val
.b_bool
= VLC_TRUE
;
1204 var_Set( p_input
, "rate-faster", val
);
1205 vlc_object_release( p_input
);
1209 void Interface::OnToggleMute ( wxCommandEvent
& WXUNUSED(event
) )
1211 aout_VolumeMute(p_intf
, NULL
);
1216 void Interface::SyncVolume()
1218 wxToolBarToolBase
*p_tool
= (wxToolBarToolBase
*)
1219 GetToolBar()->GetToolClientData( ToggleMute_Event
);
1220 if ( !p_tool
) return;
1222 audio_volume_t i_volume
;
1223 aout_VolumeGet(p_intf
, &i_volume
);
1225 /* Updating the Mute Button... IF the slider is completely moved to the left,
1226 * the mute icon is shown too. */
1227 p_tool
->SetNormalBitmap( wxBitmap( i_volume
? speaker_xpm
: speaker_mute_xpm
) );
1228 GetToolBar()->Realize();
1229 #if defined( __WXMSW__ )
1230 /* Needed to work around a bug in wxToolBar::Realize() */
1231 GetToolBar()->SetSize( GetSize().GetWidth(),
1232 GetToolBar()->GetSize().GetHeight() );
1233 GetToolBar()->Update();
1235 /* the Toggle to true and false is nescessary; otherwise, the Icon
1236 * is not repainted */
1237 GetToolBar()->ToggleTool( ToggleMute_Event
, true );
1238 GetToolBar()->ToggleTool( ToggleMute_Event
, false );
1239 GetToolBar()->Update();
1242 void Interface::OnSlideVolume( wxScrollEvent
& WXUNUSED(event
))
1244 wxSlider
*p_tool
= (wxSlider
*)
1245 GetToolBar()->FindControl( SlideVolume_Event
);
1246 if ( !p_tool
) return;
1248 aout_VolumeSet(p_intf
, p_tool
->GetValue());
1253 void Interface::TogglePlayButton( int i_playing_status
)
1255 wxToolBarToolBase
*p_tool
= (wxToolBarToolBase
*)
1256 GetToolBar()->GetToolClientData( PlayStream_Event
);
1257 if( !p_tool
) return;
1259 if( i_playing_status
== PLAYING_S
)
1261 p_tool
->SetNormalBitmap( wxBitmap( pause_xpm
) );
1262 p_tool
->SetLabel( wxU(_("Pause")) );
1263 p_tool
->SetShortHelp( wxU(_(HELP_PAUSE
)) );
1267 p_tool
->SetNormalBitmap( wxBitmap( play_xpm
) );
1268 p_tool
->SetLabel( wxU(_("Play")) );
1269 p_tool
->SetShortHelp( wxU(_(HELP_PLAY
)) );
1272 GetToolBar()->Realize();
1274 #if defined( __WXMSW__ )
1275 /* Needed to work around a bug in wxToolBar::Realize() */
1276 GetToolBar()->SetSize( GetSize().GetWidth(),
1277 GetToolBar()->GetSize().GetHeight() );
1278 GetToolBar()->Update();
1281 GetToolBar()->ToggleTool( PlayStream_Event
, true );
1282 GetToolBar()->ToggleTool( PlayStream_Event
, false );
1285 void Interface::OnInteraction( wxCommandEvent
& event
)
1287 interaction_dialog_t
*p_dialog
= (interaction_dialog_t
*)
1288 event
.GetClientData();
1290 intf_dialog_args_t
*p_arg
= new intf_dialog_args_t
;
1291 p_arg
->p_dialog
= p_dialog
;
1292 p_arg
->p_intf
= p_intf
;
1294 p_intf
->p_sys
->pf_show_dialog( p_intf
, INTF_DIALOG_INTERACTION
,
1299 static int InteractCallback( vlc_object_t
*p_this
,
1300 const char *psz_var
, vlc_value_t old_val
,
1301 vlc_value_t new_val
, void *param
)
1303 Interface
*p_interface
= (Interface
*)param
;
1304 /*interaction_dialog_t *p_dialog = (interaction_dialog_t*)(new_val.p_address);*/
1306 wxCommandEvent
event( wxEVT_INTERACTION
, -1 );
1307 event
.SetClientData( new_val
.p_address
);
1308 p_interface
->AddPendingEvent( event
);
1312 #if wxUSE_DRAG_AND_DROP
1313 /*****************************************************************************
1314 * Definition of DragAndDrop class.
1315 *****************************************************************************/
1316 DragAndDrop::DragAndDrop( intf_thread_t
*_p_intf
, vlc_bool_t _b_enqueue
)
1319 b_enqueue
= _b_enqueue
;
1322 bool DragAndDrop::OnDropFiles( wxCoord
, wxCoord
,
1323 const wxArrayString
& filenames
)
1325 /* Add dropped files to the playlist */
1327 playlist_t
*p_playlist
=
1328 (playlist_t
*)vlc_object_find( p_intf
, VLC_OBJECT_PLAYLIST
,
1330 if( p_playlist
== NULL
)
1335 /* If we drag & drop a subtitle file, add it on the fly */
1336 if( filenames
.GetCount() == 1 )
1338 char *psz_utf8
= wxDnDFromLocale( filenames
[0] );
1339 input_thread_t
*p_input
= (input_thread_t
*)vlc_object_find( p_intf
,
1340 VLC_OBJECT_INPUT
, FIND_ANYWHERE
);
1343 if( input_AddSubtitles( p_input
, psz_utf8
, VLC_TRUE
) )
1345 vlc_object_release( p_input
);
1346 wxDnDLocaleFree( psz_utf8
);
1347 vlc_object_release( p_playlist
);
1350 vlc_object_release( p_input
);
1352 wxDnDLocaleFree( psz_utf8
);
1355 for( size_t i
= 0; i
< filenames
.GetCount(); i
++ )
1357 char *psz_utf8
= wxDnDFromLocale( filenames
[i
] );
1359 playlist_Add( p_playlist
, psz_utf8
, NULL
,
1360 PLAYLIST_APPEND
| ((i
| b_enqueue
) ? 0 : PLAYLIST_GO
),
1361 PLAYLIST_END
, VLC_TRUE
, VLC_FALSE
);
1363 wxDnDLocaleFree( psz_utf8
);
1366 vlc_object_release( p_playlist
);
1372 /*****************************************************************************
1374 *****************************************************************************/
1376 /* wxCocoa pretends to support this, but at least 2.6.x doesn't */
1378 #ifdef wxHAS_TASK_BAR_ICON
1380 BEGIN_EVENT_TABLE(Systray
, wxTaskBarIcon
)
1383 EVT_TASKBAR_LEFT_DCLICK(Systray::OnLeftClick
)
1385 EVT_TASKBAR_LEFT_DOWN(Systray::OnLeftClick
)
1388 EVT_MENU(Iconize_Event
, Systray::OnMenuIconize
)
1389 EVT_MENU(Exit_Event
, Systray::OnExit
)
1390 EVT_MENU(PlayStream_Event
, Systray::OnPlayStream
)
1391 EVT_MENU(NextStream_Event
, Systray::OnNextStream
)
1392 EVT_MENU(PrevStream_Event
, Systray::OnPrevStream
)
1393 EVT_MENU(StopStream_Event
, Systray::OnStopStream
)
1396 Systray::Systray( Interface
*_p_main_interface
, intf_thread_t
*_p_intf
)
1398 p_main_interface
= _p_main_interface
;
1401 SetIcon( wxIcon( (const char**) vlc16x16_xpm
), wxT("VLC media player") );
1402 if( !IsOk() || !IsIconInstalled() )
1404 msg_Warn(p_intf
, "cannot set systray icon, weird things may happen");
1408 /* Event handlers */
1409 void Systray::OnMenuIconize( wxCommandEvent
& event
)
1411 p_main_interface
->Show( ! p_main_interface
->IsShown() );
1412 if ( p_main_interface
->IsShown() ) p_main_interface
->Raise();
1415 void Systray::OnLeftClick( wxTaskBarIconEvent
& event
)
1417 wxCommandEvent cevent
;
1418 OnMenuIconize(cevent
);
1421 void Systray::OnExit( wxCommandEvent
& event
)
1423 p_main_interface
->Close(TRUE
);
1426 void Systray::OnPrevStream( wxCommandEvent
& event
)
1428 p_main_interface
->PrevStream();
1431 void Systray::OnNextStream( wxCommandEvent
& event
)
1433 p_main_interface
->NextStream();
1436 void Systray::OnPlayStream( wxCommandEvent
& event
)
1438 p_main_interface
->PlayStream();
1441 void Systray::OnStopStream( wxCommandEvent
& event
)
1443 p_main_interface
->StopStream();
1446 /* Systray popup menu */
1447 wxMenu
* Systray::CreatePopupMenu()
1449 int minimal
= config_GetInt( p_intf
, "wx-minimal" );
1451 wxMenu
* systray_menu
= new wxMenu
;
1452 systray_menu
->Append( Exit_Event
, wxU(_("Quit VLC")) );
1453 systray_menu
->AppendSeparator();
1454 systray_menu
->Append( PlayStream_Event
, wxU(_("Play/Pause")) );
1458 systray_menu
->Append( PrevStream_Event
, wxU(_("Previous")) );
1459 systray_menu
->Append( NextStream_Event
, wxU(_("Next")) );
1460 systray_menu
->Append( StopStream_Event
, wxU(_("Stop")) );
1462 systray_menu
->AppendSeparator();
1463 systray_menu
->Append( Iconize_Event
, wxU(_("Show/Hide Interface")) );
1464 return systray_menu
;
1467 void Systray::UpdateTooltip( const wxChar
* tooltip
)
1469 SetIcon( wxIcon( (const char**) vlc16x16_xpm
), tooltip
);