interface.cpp 44.6 KB
Newer Older
Gildas Bazin's avatar
 
Gildas Bazin committed
1
/*****************************************************************************
2
 * interface.cpp : wxWidgets plugin for vlc
Gildas Bazin's avatar
 
Gildas Bazin committed
3
 *****************************************************************************
4
 * Copyright (C) 2000-2005 the VideoLAN team
Gildas Bazin's avatar
Gildas Bazin committed
5
 * $Id$
Gildas Bazin's avatar
 
Gildas Bazin committed
6
 *
7
 * Authors: Gildas Bazin <gbazin@videolan.org>
Gildas Bazin's avatar
 
Gildas Bazin committed
8 9 10 11 12
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
13
 *
Gildas Bazin's avatar
 
Gildas Bazin committed
14 15 16 17 18 19 20 21 22 23 24 25 26
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/
Gildas Bazin's avatar
 
Gildas Bazin committed
27
#include <vlc/vlc.h>
Gildas Bazin's avatar
 
Gildas Bazin committed
28
#include <vlc/aout.h>
29
#include <vlc/vout.h>
30
#include <vlc/input.h>
Gildas Bazin's avatar
 
Gildas Bazin committed
31
#include <vlc/intf.h>
Gildas Bazin's avatar
 
Gildas Bazin committed
32

33
#include "wxwidgets.h"
Gildas Bazin's avatar
 
Gildas Bazin committed
34 35 36 37 38

/* include the toolbar graphics */
#include "bitmaps/play.xpm"
#include "bitmaps/pause.xpm"
#include "bitmaps/stop.xpm"
39
#include "bitmaps/prev.xpm"
Gildas Bazin's avatar
 
Gildas Bazin committed
40
#include "bitmaps/next.xpm"
41
#include "bitmaps/eject.xpm"
Gildas Bazin's avatar
 
Gildas Bazin committed
42
#include "bitmaps/slow.xpm"
43
#include "bitmaps/fast.xpm"
44
#include "bitmaps/playlist.xpm"
45
#include "bitmaps/speaker.xpm"
46
#include "bitmaps/speaker_mute.xpm"
Gildas Bazin's avatar
 
Gildas Bazin committed
47

48 49
#define TOOLBAR_BMP_WIDTH 16
#define TOOLBAR_BMP_HEIGHT 16
Gildas Bazin's avatar
 
Gildas Bazin committed
50

Gildas Bazin's avatar
 
Gildas Bazin committed
51
/* include the icon graphic */
Sam Hocevar's avatar
Sam Hocevar committed
52
#include "../../../share/vlc32x32.xpm"
53
/* include a small icon graphic for the systray icon */
54
#ifdef wxHAS_TASK_BAR_ICON
55
#include "../../../share/vlc16x16.xpm"
56
#endif
Gildas Bazin's avatar
 
Gildas Bazin committed
57 58 59 60

/*****************************************************************************
 * Local class declarations.
 *****************************************************************************/
Gildas Bazin's avatar
 
Gildas Bazin committed
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
class wxMenuExt: public wxMenu
{
public:
    /* Constructor */
    wxMenuExt( wxMenu* parentMenu, int id, const wxString& text,
                   const wxString& helpString, wxItemKind kind,
                   char *_psz_var, int _i_object_id, vlc_value_t _val,
                   int _i_val_type );

    virtual ~wxMenuExt() {};

    char *psz_var;
    int  i_val_type;
    int  i_object_id;
    vlc_value_t val;

private:

};
Gildas Bazin's avatar
 
Gildas Bazin committed
80

81 82
class wxVolCtrl;
class VLCVolCtrl : public wxControl
Gildas Bazin's avatar
 
Gildas Bazin committed
83 84
{
public:
85 86
    VLCVolCtrl( intf_thread_t *p_intf, wxWindow *p_parent );
    virtual ~VLCVolCtrl() {};
Gildas Bazin's avatar
 
Gildas Bazin committed
87

88 89
    virtual void OnPaint( wxPaintEvent &event );
    void OnChange( wxMouseEvent& event );
90
    void UpdateVolume();
Gildas Bazin's avatar
 
Gildas Bazin committed
91

92 93
  private:
    DECLARE_EVENT_TABLE()
Gildas Bazin's avatar
 
Gildas Bazin committed
94

95 96
    wxVolCtrl *gauge;
    int i_y_offset;
97
    vlc_bool_t b_mute;
Gildas Bazin's avatar
 
Gildas Bazin committed
98 99 100
    intf_thread_t *p_intf;
};

101 102 103
BEGIN_EVENT_TABLE(VLCVolCtrl, wxControl)
   EVT_PAINT(VLCVolCtrl::OnPaint)

Gildas Bazin's avatar
 
Gildas Bazin committed
104
    /* Mouse events */
105
    EVT_LEFT_UP(VLCVolCtrl::OnChange)
Gildas Bazin's avatar
 
Gildas Bazin committed
106 107
END_EVENT_TABLE()

Gildas Bazin's avatar
 
Gildas Bazin committed
108 109 110 111
/*****************************************************************************
 * Event Table.
 *****************************************************************************/

Gildas Bazin's avatar
Gildas Bazin committed
112 113
DEFINE_LOCAL_EVENT_TYPE( wxEVT_INTF );

Gildas Bazin's avatar
 
Gildas Bazin committed
114 115 116 117
/* IDs for the controls and the menu commands */
enum
{
    /* menu items */
118
    MenuDummy_Event = wxID_HIGHEST + 1000,
Gildas Bazin's avatar
 
Gildas Bazin committed
119
    Exit_Event = wxID_HIGHEST,
Gildas Bazin's avatar
 
Gildas Bazin committed
120
    OpenFileSimple_Event,
121
    OpenAdv_Event,
Gildas Bazin's avatar
 
Gildas Bazin committed
122
    OpenFile_Event,
123
    OpenDir_Event,
Gildas Bazin's avatar
 
Gildas Bazin committed
124 125
    OpenDisc_Event,
    OpenNet_Event,
Gildas Bazin's avatar
Gildas Bazin committed
126
    OpenCapture_Event,
Gildas Bazin's avatar
 
Gildas Bazin committed
127
    OpenSat_Event,
128
    OpenOther_Event,
Gildas Bazin's avatar
 
Gildas Bazin committed
129 130
    EjectDisc_Event,

131
    Wizard_Event,
132

133
    Playlist_Event,
Gildas Bazin's avatar
 
Gildas Bazin committed
134
    Logs_Event,
135
    FileInfo_Event,
Gildas Bazin's avatar
 
Gildas Bazin committed
136 137

    Prefs_Event,
Gildas Bazin's avatar
Gildas Bazin committed
138
    Extended_Event,
139
//    Undock_Event,
Gildas Bazin's avatar
Gildas Bazin committed
140
    Bookmarks_Event,
Gildas Bazin's avatar
 
Gildas Bazin committed
141
    Skins_Event,
Gildas Bazin's avatar
 
Gildas Bazin committed
142 143 144 145 146

    SliderScroll_Event,
    StopStream_Event,
    PlayStream_Event,
    PrevStream_Event,
Gildas Bazin's avatar
 
Gildas Bazin committed
147
    NextStream_Event,
Gildas Bazin's avatar
 
Gildas Bazin committed
148 149
    SlowStream_Event,
    FastStream_Event,
Gildas Bazin's avatar
 
Gildas Bazin committed
150

151 152 153 154
    DiscMenu_Event,
    DiscPrev_Event,
    DiscNext_Event,

Gildas Bazin's avatar
 
Gildas Bazin committed
155 156 157
    /* it is important for the id corresponding to the "About" command to have
     * this standard value as otherwise it won't be handled properly under Mac
     * (where it is special and put into the "Apple" menu) */
158
    About_Event = wxID_ABOUT,
159
    UpdateVLC_Event,
160 161

    Iconize_Event
Gildas Bazin's avatar
 
Gildas Bazin committed
162 163 164 165 166 167
};

BEGIN_EVENT_TABLE(Interface, wxFrame)
    /* Menu events */
    EVT_MENU(Exit_Event, Interface::OnExit)
    EVT_MENU(About_Event, Interface::OnAbout)
168
    EVT_MENU(UpdateVLC_Event, Interface::OnShowDialog)
Gildas Bazin's avatar
 
Gildas Bazin committed
169 170 171 172 173

    EVT_MENU(Playlist_Event, Interface::OnShowDialog)
    EVT_MENU(Logs_Event, Interface::OnShowDialog)
    EVT_MENU(FileInfo_Event, Interface::OnShowDialog)
    EVT_MENU(Prefs_Event, Interface::OnShowDialog)
Gildas Bazin's avatar
 
Gildas Bazin committed
174

Gildas Bazin's avatar
 
Gildas Bazin committed
175 176
    EVT_MENU_OPEN(Interface::OnMenuOpen)

177 178
    EVT_MENU( Extended_Event, Interface::OnExtended )
//    EVT_MENU( Undock_Event, Interface::OnUndock )
Clément Stenac's avatar
Clément Stenac committed
179

180
    EVT_MENU( Bookmarks_Event, Interface::OnShowDialog)
Clément Stenac's avatar
Clément Stenac committed
181

Gildas Bazin's avatar
 
Gildas Bazin committed
182
#if defined( __WXMSW__ ) || defined( __WXMAC__ )
Gildas Bazin's avatar
 
Gildas Bazin committed
183
    EVT_CONTEXT_MENU(Interface::OnContextMenu2)
Gildas Bazin's avatar
 
Gildas Bazin committed
184
#endif
Gildas Bazin's avatar
 
Gildas Bazin committed
185
    EVT_RIGHT_UP(Interface::OnContextMenu)
Gildas Bazin's avatar
 
Gildas Bazin committed
186

Gildas Bazin's avatar
 
Gildas Bazin committed
187
    /* Toolbar events */
Gildas Bazin's avatar
 
Gildas Bazin committed
188
    EVT_MENU(OpenFileSimple_Event, Interface::OnShowDialog)
189
    EVT_MENU(OpenAdv_Event, Interface::OnShowDialog)
Gildas Bazin's avatar
 
Gildas Bazin committed
190
    EVT_MENU(OpenFile_Event, Interface::OnShowDialog)
191
    EVT_MENU(OpenDir_Event, Interface::OnShowDialog)
Gildas Bazin's avatar
 
Gildas Bazin committed
192 193
    EVT_MENU(OpenDisc_Event, Interface::OnShowDialog)
    EVT_MENU(OpenNet_Event, Interface::OnShowDialog)
Gildas Bazin's avatar
Gildas Bazin committed
194
    EVT_MENU(OpenCapture_Event, Interface::OnShowDialog)
Gildas Bazin's avatar
 
Gildas Bazin committed
195
    EVT_MENU(OpenSat_Event, Interface::OnShowDialog)
196
    EVT_MENU(Wizard_Event, Interface::OnShowDialog)
Gildas Bazin's avatar
 
Gildas Bazin committed
197 198 199 200
    EVT_MENU(StopStream_Event, Interface::OnStopStream)
    EVT_MENU(PlayStream_Event, Interface::OnPlayStream)
    EVT_MENU(PrevStream_Event, Interface::OnPrevStream)
    EVT_MENU(NextStream_Event, Interface::OnNextStream)
Gildas Bazin's avatar
 
Gildas Bazin committed
201 202
    EVT_MENU(SlowStream_Event, Interface::OnSlowStream)
    EVT_MENU(FastStream_Event, Interface::OnFastStream)
Gildas Bazin's avatar
 
Gildas Bazin committed
203

204 205 206 207 208
    /* Disc Buttons events */
    EVT_BUTTON(DiscMenu_Event, Interface::OnDiscMenu)
    EVT_BUTTON(DiscPrev_Event, Interface::OnDiscPrev)
    EVT_BUTTON(DiscNext_Event, Interface::OnDiscNext)

Gildas Bazin's avatar
 
Gildas Bazin committed
209 210
    /* Slider events */
    EVT_COMMAND_SCROLL(SliderScroll_Event, Interface::OnSliderUpdate)
Clément Stenac's avatar
Clément Stenac committed
211

Gildas Bazin's avatar
Gildas Bazin committed
212
    /* Custom events */
213 214
    EVT_COMMAND(0, wxEVT_INTF, Interface::OnControlEvent)
    EVT_COMMAND(1, wxEVT_INTF, Interface::OnControlEvent)
Clément Stenac's avatar
Clément Stenac committed
215 216

    EVT_TIMER(ID_CONTROLS_TIMER, Interface::OnControlsTimer)
Clément Stenac's avatar
Clément Stenac committed
217
    EVT_TIMER(ID_SLIDER_TIMER, Interface::OnSliderTimer)
Gildas Bazin's avatar
 
Gildas Bazin committed
218 219 220 221 222
END_EVENT_TABLE()

/*****************************************************************************
 * Constructor.
 *****************************************************************************/
223
Interface::Interface( intf_thread_t *_p_intf, long style ):
Gildas Bazin's avatar
 
Gildas Bazin committed
224
    wxFrame( NULL, -1, wxT("VLC media player"),
225
             wxDefaultPosition, wxSize(700,100), style )
Gildas Bazin's avatar
 
Gildas Bazin committed
226 227 228
{
    /* Initializations */
    p_intf = _p_intf;
Gildas Bazin's avatar
 
Gildas Bazin committed
229
    i_old_playing_status = PAUSE_S;
Clément Stenac's avatar
Clément Stenac committed
230
    b_extra = VLC_FALSE;
231 232
//    b_undock = VLC_FALSE;

233

234
    extra_window = NULL;
Gildas Bazin's avatar
 
Gildas Bazin committed
235

Gildas Bazin's avatar
 
Gildas Bazin committed
236
    /* Give our interface a nice little icon */
237
    SetIcon( wxIcon( vlc_xpm ) );
Gildas Bazin's avatar
 
Gildas Bazin committed
238 239

    /* Create a sizer for the main frame */
Clément Stenac's avatar
Clément Stenac committed
240
    frame_sizer = new wxBoxSizer( wxVERTICAL );
Gildas Bazin's avatar
 
Gildas Bazin committed
241 242
    SetSizer( frame_sizer );

243 244 245
    /* Create a dummy widget that can get the keyboard focus */
    wxWindow *p_dummy = new wxWindow( this, 0, wxDefaultPosition,
                                      wxSize(0,0) );
246 247 248 249
#if defined(__WXGTK20__) && wxCHECK_VERSION(2,5,6)
    /* As ugly as your butt! Please remove when wxWidgets 2.6 fixed their
     * Accelerators bug. */
    p_dummy->m_imData = 0;
250
    m_imData = 0;
251
#endif
252
    p_dummy->SetFocus();
253
    frame_sizer->Add( p_dummy, 0, 0 );
Clément Stenac's avatar
Clément Stenac committed
254

255
#ifdef wxHAS_TASK_BAR_ICON
256 257
    /* Systray integration */
    p_systray = NULL;
258
    if ( config_GetInt( p_intf, "wx-systray" ) )
259
    {
260
        p_systray = new Systray(this, p_intf);
261
        p_systray->SetIcon( wxIcon( vlc16x16_xpm ), wxT("VLC media player") );
262 263 264 265 266
        if ( (! p_systray->IsOk()) || (! p_systray->IsIconInstalled()) )
        {
            msg_Warn(p_intf, "Cannot set systray icon, weird things may happen");
        }
    }
267
#endif
268

Gildas Bazin's avatar
 
Gildas Bazin committed
269 270 271 272 273 274
    /* Creation of the menu bar */
    CreateOurMenuBar();

    /* Creation of the tool bar */
    CreateOurToolBar();

Clément Stenac's avatar
Clément Stenac committed
275
    /* Create the extra panel */
276
    extra_frame = new ExtraPanel( p_intf, this );
Clément Stenac's avatar
Clément Stenac committed
277 278 279
    frame_sizer->Add( extra_frame, 0, wxEXPAND , 0 );
    frame_sizer->Hide( extra_frame );

280
    /* Creation of the status bar
Gildas Bazin's avatar
 
Gildas Bazin committed
281 282
     * Helptext for menu items and toolbar tools will automatically get
     * displayed here. */
Gildas Bazin's avatar
 
Gildas Bazin committed
283 284 285 286 287
    int i_status_width[3] = {-6, -2, -9};
    statusbar = CreateStatusBar( 3 );                            /* 2 fields */
    statusbar->SetStatusWidths( 3, i_status_width );
    statusbar->SetStatusText( wxString::Format(wxT("x%.2f"), 1.0), 1 );

Gildas Bazin's avatar
Gildas Bazin committed
288
    /* Video window */
289
    video_window = 0;
290
    if( config_GetInt( p_intf, "wx-embed" ) )
Gildas Bazin's avatar
Gildas Bazin committed
291
    {
292 293
        video_window = CreateVideoWindow( p_intf, this );
        frame_sizer->Add( p_intf->p_sys->p_video_sizer, 1, wxEXPAND, 0 );
Gildas Bazin's avatar
Gildas Bazin committed
294 295
    }

296 297 298 299 300 301 302 303
    /* Creation of the slider sub-window */
    CreateOurSlider();
    frame_sizer->Add( slider_frame, 0, wxEXPAND , 0 );
    frame_sizer->Hide( slider_frame );

    /* Make sure we've got the right background colour */
    SetBackgroundColour( slider_frame->GetBackgroundColour() );

Gildas Bazin's avatar
 
Gildas Bazin committed
304 305
    /* Layout everything */
    frame_sizer->Layout();
Gildas Bazin's avatar
 
Gildas Bazin committed
306
    frame_sizer->Fit(this);
Gildas Bazin's avatar
 
Gildas Bazin committed
307

308
#if wxUSE_DRAG_AND_DROP
Gildas Bazin's avatar
 
Gildas Bazin committed
309 310
    /* Associate drop targets with the main interface */
    SetDropTarget( new DragAndDrop( p_intf ) );
Gildas Bazin's avatar
 
Gildas Bazin committed
311
#endif
312

313
    SetupHotkeys();
Gildas Bazin's avatar
 
Gildas Bazin committed
314

Clément Stenac's avatar
Clément Stenac committed
315
    m_controls_timer.SetOwner(this, ID_CONTROLS_TIMER);
Clément Stenac's avatar
Clément Stenac committed
316
    m_slider_timer.SetOwner(this, ID_SLIDER_TIMER);
Clément Stenac's avatar
Clément Stenac committed
317

Gildas Bazin's avatar
 
Gildas Bazin committed
318 319
    /* Start timer */
    timer = new Timer( p_intf, this );
320 321 322 323 324 325 326 327 328 329 330

    /* */
    WindowSettings *ws = p_intf->p_sys->p_window_settings;
    wxPoint p;
    wxSize  s;
    bool    b_shown;

    ws->SetScreen( wxSystemSettings::GetMetric( wxSYS_SCREEN_X ),
                   wxSystemSettings::GetMetric( wxSYS_SCREEN_Y ) );

    if( ws->GetSettings( WindowSettings::ID_MAIN, b_shown, p, s ) )
331
        Move( p );
Gildas Bazin's avatar
 
Gildas Bazin committed
332 333 334 335
}

Interface::~Interface()
{
336 337
    WindowSettings *ws = p_intf->p_sys->p_window_settings;

338 339 340 341 342
    if( !IsIconized() )
    {
        ws->SetSettings( WindowSettings::ID_MAIN, true,
                         GetPosition(), GetSize() );
    }
343

344 345
    if( video_window ) delete video_window;

346
#ifdef wxHAS_TASK_BAR_ICON
347
    if( p_systray ) delete p_systray;
348
#endif
349

350
    if( p_intf->p_sys->p_wxwindow ) delete p_intf->p_sys->p_wxwindow;
Gildas Bazin's avatar
 
Gildas Bazin committed
351

Gildas Bazin's avatar
 
Gildas Bazin committed
352
    /* Clean up */
Gildas Bazin's avatar
 
Gildas Bazin committed
353
    delete timer;
Gildas Bazin's avatar
 
Gildas Bazin committed
354
}
Gildas Bazin's avatar
 
Gildas Bazin committed
355

356 357 358 359 360 361
void Interface::Init()
{
    /* Misc init */
    SetupHotkeys();
}

362 363 364
void Interface::Update()
{
    /* Misc updates */
365
    ((VLCVolCtrl *)volctrl)->UpdateVolume();
366 367
}

368
void Interface::OnControlEvent( wxCommandEvent& event )
Gildas Bazin's avatar
Gildas Bazin committed
369
{
370 371 372
    switch( event.GetId() )
    {
    case 0:
Clément Stenac's avatar
Clément Stenac committed
373
        {
374
          if( p_intf->p_sys->b_video_autosize )
Clément Stenac's avatar
Clément Stenac committed
375
          {
376 377
        frame_sizer->Layout();
        frame_sizer->Fit(this);
Clément Stenac's avatar
Clément Stenac committed
378 379
          }
        }
380 381 382 383 384 385 386 387 388
        break;

    case 1:
        long i_style = GetWindowStyle();
        if( event.GetInt() ) i_style |= wxSTAY_ON_TOP;
        else i_style &= ~wxSTAY_ON_TOP;
        SetWindowStyle( i_style );
        break;
    }
Gildas Bazin's avatar
Gildas Bazin committed
389 390
}

Gildas Bazin's avatar
 
Gildas Bazin committed
391 392 393 394 395
/*****************************************************************************
 * Private methods.
 *****************************************************************************/
void Interface::CreateOurMenuBar()
{
396
    int minimal = config_GetInt( p_intf, "wx-minimal" );
397

Gildas Bazin's avatar
 
Gildas Bazin committed
398
    /* Create the "File" menu */
Gildas Bazin's avatar
 
Gildas Bazin committed
399
    wxMenu *file_menu = new wxMenu;
400 401 402

    if (!minimal)
    {
403
    file_menu->Append( OpenFileSimple_Event,
Gildas Bazin's avatar
Gildas Bazin committed
404
                       wxU(_("Quick &Open File...\tCtrl-O")) );
405 406

    file_menu->AppendSeparator();
Gildas Bazin's avatar
Gildas Bazin committed
407
    file_menu->Append( OpenFile_Event, wxU(_("Open &File...\tCtrl-F")) );
408
    file_menu->Append( OpenDir_Event, wxU(_("Open Dir&ectory...\tCtrl-E")) );
Gildas Bazin's avatar
Gildas Bazin committed
409
    file_menu->Append( OpenDisc_Event, wxU(_("Open &Disc...\tCtrl-D")) );
410
    file_menu->Append( OpenNet_Event,
Gildas Bazin's avatar
Gildas Bazin committed
411 412
                       wxU(_("Open &Network Stream...\tCtrl-N")) );
    file_menu->Append( OpenCapture_Event,
413
                       wxU(_("Open C&apture Device...\tCtrl-A")) );
414

Gildas Bazin's avatar
 
Gildas Bazin committed
415
    file_menu->AppendSeparator();
416
    file_menu->Append( Wizard_Event, wxU(_("&Wizard...\tCtrl-W")) );
Gildas Bazin's avatar
 
Gildas Bazin committed
417
    file_menu->AppendSeparator();
418
    }
Gildas Bazin's avatar
Gildas Bazin committed
419
    file_menu->Append( Exit_Event, wxU(_("E&xit\tCtrl-X")) );
Gildas Bazin's avatar
 
Gildas Bazin committed
420

Gildas Bazin's avatar
 
Gildas Bazin committed
421
    /* Create the "View" menu */
Gildas Bazin's avatar
 
Gildas Bazin committed
422
    wxMenu *view_menu = new wxMenu;
423 424
    if (!minimal)
    {
Gildas Bazin's avatar
Gildas Bazin committed
425
    view_menu->Append( Playlist_Event, wxU(_("&Playlist...\tCtrl-P")) );
426
    }
Gildas Bazin's avatar
Gildas Bazin committed
427
    view_menu->Append( Logs_Event, wxU(_("&Messages...\tCtrl-M")) );
428
    view_menu->Append( FileInfo_Event,
Gildas Bazin's avatar
Gildas Bazin committed
429
                       wxU(_("Stream and Media &info...\tCtrl-I")) );
Gildas Bazin's avatar
 
Gildas Bazin committed
430

431 432 433 434 435
    /* Create the "Auto-generated" menus */
    p_settings_menu = SettingsMenu( p_intf, this );
    p_audio_menu = AudioMenu( p_intf, this );
    p_video_menu = VideoMenu( p_intf, this );
    p_navig_menu = NavigMenu( p_intf, this );
Gildas Bazin's avatar
 
Gildas Bazin committed
436

Gildas Bazin's avatar
 
Gildas Bazin committed
437
    /* Create the "Help" menu */
Gildas Bazin's avatar
 
Gildas Bazin committed
438
    wxMenu *help_menu = new wxMenu;
Gildas Bazin's avatar
Gildas Bazin committed
439
    help_menu->Append( About_Event, wxU(_("About VLC media player")) );
440 441
    help_menu->AppendSeparator();
    help_menu->Append( UpdateVLC_Event, wxU(_("Check for updates ...")) );
Gildas Bazin's avatar
 
Gildas Bazin committed
442 443

    /* Append the freshly created menus to the menu bar... */
444
    wxMenuBar *menubar = new wxMenuBar();
Gildas Bazin's avatar
 
Gildas Bazin committed
445 446
    menubar->Append( file_menu, wxU(_("&File")) );
    menubar->Append( view_menu, wxU(_("&View")) );
Gildas Bazin's avatar
 
Gildas Bazin committed
447
    menubar->Append( p_settings_menu, wxU(_("&Settings")) );
Gildas Bazin's avatar
 
Gildas Bazin committed
448 449
    menubar->Append( p_audio_menu, wxU(_("&Audio")) );
    menubar->Append( p_video_menu, wxU(_("&Video")) );
Gildas Bazin's avatar
 
Gildas Bazin committed
450
    menubar->Append( p_navig_menu, wxU(_("&Navigation")) );
Gildas Bazin's avatar
 
Gildas Bazin committed
451
    menubar->Append( help_menu, wxU(_("&Help")) );
Gildas Bazin's avatar
 
Gildas Bazin committed
452 453 454 455

    /* Attach the menu bar to the frame */
    SetMenuBar( menubar );

456 457
    /* Find out size of menu bar */
    int i_size = 0;
458
    for( unsigned int i = 0; i < menubar->GetMenuCount(); i++ )
459 460 461
    {
        int i_width, i_height;
        menubar->GetTextExtent( menubar->GetLabelTop(i), &i_width, &i_height );
462 463
        i_size += i_width +
#if defined(__WXGTK__)
464
            22 /* approximate margin */;
465
#else
466
#if (wxMAJOR_VERSION <= 2) && (wxMINOR_VERSION <= 5) && (wxRELEASE_NUMBER < 3)
467
            4 /* approximate margin */;
468
#else
469
            18 /* approximate margin */;
470
#endif
471
#endif
472 473 474
    }
    frame_sizer->SetMinSize( i_size, -1 );

Gildas Bazin's avatar
 
Gildas Bazin committed
475 476 477
    /* Intercept all menu events in our custom event handler */
    PushEventHandler( new MenuEvtHandler( p_intf, this ) );

478
#if wxUSE_DRAG_AND_DROP
Gildas Bazin's avatar
 
Gildas Bazin committed
479 480
    /* Associate drop targets with the menubar */
    menubar->SetDropTarget( new DragAndDrop( p_intf ) );
Gildas Bazin's avatar
 
Gildas Bazin committed
481
#endif
Gildas Bazin's avatar
 
Gildas Bazin committed
482 483 484 485
}

void Interface::CreateOurToolBar()
{
486
#define HELP_OPEN N_("Open")
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
487 488 489 490
#define HELP_STOP N_("Stop")
#define HELP_PLAY N_("Play")
#define HELP_PAUSE N_("Pause")
#define HELP_PLO N_("Playlist")
Gildas Bazin's avatar
 
Gildas Bazin committed
491 492
#define HELP_PLP N_("Previous playlist item")
#define HELP_PLN N_("Next playlist item")
Gildas Bazin's avatar
 
Gildas Bazin committed
493 494
#define HELP_SLOW N_("Play slower")
#define HELP_FAST N_("Play faster")
Gildas Bazin's avatar
 
Gildas Bazin committed
495

496
    int minimal = config_GetInt( p_intf, "wx-minimal" );
497

Gildas Bazin's avatar
 
Gildas Bazin committed
498 499
    wxLogNull LogDummy; /* Hack to suppress annoying log message on the win32
                         * version because we don't include wx.rc */
Gildas Bazin's avatar
 
Gildas Bazin committed
500

501
    wxToolBar *toolbar =
502
        CreateToolBar( wxTB_HORIZONTAL | wxTB_FLAT );
Gildas Bazin's avatar
 
Gildas Bazin committed
503

Gildas Bazin's avatar
 
Gildas Bazin committed
504 505
    toolbar->SetToolBitmapSize( wxSize(TOOLBAR_BMP_WIDTH,TOOLBAR_BMP_HEIGHT) );

506 507
    if (!minimal)
    {
508 509 510
    toolbar->AddTool( OpenFile_Event, wxT(""),
                      wxBitmap( eject_xpm ), wxU(_(HELP_OPEN)) );
    toolbar->AddSeparator();
511
    }
512 513

    wxToolBarToolBase *p_tool = toolbar->AddTool( PlayStream_Event, wxT(""),
514
                      wxBitmap( play_xpm ), wxU(_(HELP_PLAY)), wxITEM_CHECK );
515 516
    p_tool->SetClientData( p_tool );

517 518
    if (!minimal)
    {
519 520
    toolbar->AddTool( StopStream_Event, wxT(""), wxBitmap( stop_xpm ),
                      wxU(_(HELP_STOP)) );
Gildas Bazin's avatar
 
Gildas Bazin committed
521
    toolbar->AddSeparator();
522

Gildas Bazin's avatar
 
Gildas Bazin committed
523
    toolbar->AddTool( PrevStream_Event, wxT(""),
524 525 526 527 528
                      wxBitmap( prev_xpm ), wxU(_(HELP_PLP)) );
    toolbar->AddTool( SlowStream_Event, wxT(""),
                      wxBitmap( slow_xpm ), wxU(_(HELP_SLOW)) );
    toolbar->AddTool( FastStream_Event, wxT(""),
                      wxBitmap( fast_xpm ), wxU(_(HELP_FAST)) );
Gildas Bazin's avatar
 
Gildas Bazin committed
529
    toolbar->AddTool( NextStream_Event, wxT(""), wxBitmap( next_xpm ),
Gildas Bazin's avatar
 
Gildas Bazin committed
530
                      wxU(_(HELP_PLN)) );
531
    toolbar->AddSeparator();
532
    toolbar->AddTool( Playlist_Event, wxT(""), wxBitmap( playlist_xpm ),
533
                      wxU(_(HELP_PLO)) );
534
    }
Gildas Bazin's avatar
 
Gildas Bazin committed
535

536
    wxControl *p_dummy_ctrl =
537
        new wxControl( toolbar, -1, wxDefaultPosition,
538
                       wxSize(35, 16 ), wxBORDER_NONE );
539

540
    toolbar->AddControl( p_dummy_ctrl );
Gildas Bazin's avatar
 
Gildas Bazin committed
541

542 543
    volctrl = new VLCVolCtrl( p_intf, toolbar );
    toolbar->AddControl( volctrl );
544 545

    toolbar->Realize();
Gildas Bazin's avatar
 
Gildas Bazin committed
546

547
#if wxUSE_DRAG_AND_DROP
Gildas Bazin's avatar
 
Gildas Bazin committed
548 549
    /* Associate drop targets with the toolbar */
    toolbar->SetDropTarget( new DragAndDrop( p_intf ) );
Gildas Bazin's avatar
 
Gildas Bazin committed
550
#endif
Gildas Bazin's avatar
 
Gildas Bazin committed
551 552
}

Gildas Bazin's avatar
 
Gildas Bazin committed
553
void Interface::CreateOurSlider()
Gildas Bazin's avatar
 
Gildas Bazin committed
554
{
Gildas Bazin's avatar
 
Gildas Bazin committed
555
    /* Create a new frame and sizer containing the slider */
Gildas Bazin's avatar
 
Gildas Bazin committed
556
    slider_frame = new wxPanel( this, -1, wxDefaultPosition, wxDefaultSize );
Gildas Bazin's avatar
 
Gildas Bazin committed
557
    slider_frame->SetAutoLayout( TRUE );
558 559
    slider_sizer = new wxBoxSizer( wxHORIZONTAL );
    //slider_sizer->SetMinSize( -1, 50 );
Gildas Bazin's avatar
 
Gildas Bazin committed
560 561 562 563

    /* Create slider */
    slider = new wxSlider( slider_frame, SliderScroll_Event, 0, 0,
                           SLIDER_MAX_POS, wxDefaultPosition, wxDefaultSize );
Gildas Bazin's avatar
 
Gildas Bazin committed
564

565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584
    /* Add Disc Buttons */
    disc_frame = new wxPanel( slider_frame, -1, wxDefaultPosition,
                              wxDefaultSize );
    disc_frame->SetAutoLayout( TRUE );
    disc_sizer = new wxBoxSizer( wxHORIZONTAL );

    disc_menu_button = new wxBitmapButton( disc_frame, DiscMenu_Event,
                                           wxBitmap( playlist_xpm ) );
    disc_prev_button = new wxBitmapButton( disc_frame, DiscPrev_Event,
                                           wxBitmap( prev_xpm ) );
    disc_next_button = new wxBitmapButton( disc_frame, DiscNext_Event,
                                           wxBitmap( next_xpm ) );

    disc_sizer->Add( disc_menu_button, 1, wxEXPAND | wxLEFT | wxRIGHT, 1 );
    disc_sizer->Add( disc_prev_button, 1, wxEXPAND | wxLEFT | wxRIGHT, 1 );
    disc_sizer->Add( disc_next_button, 1, wxEXPAND | wxLEFT | wxRIGHT, 1 );

    disc_frame->SetSizer( disc_sizer );
    disc_sizer->Layout();

Gildas Bazin's avatar
 
Gildas Bazin committed
585
    /* Add everything to the frame */
586 587 588 589 590 591 592 593 594
    slider_sizer->Add( slider, 1, wxEXPAND | wxALL, 5 );
    slider_sizer->Add( disc_frame, 0, wxALL, 2 );
    slider_frame->SetSizer( slider_sizer );

    disc_frame->Hide();
    slider_sizer->Hide( disc_frame );

    slider_sizer->Layout();
    slider_sizer->Fit( slider_frame );
Gildas Bazin's avatar
 
Gildas Bazin committed
595 596 597

    /* Hide the slider by default */
    slider_frame->Hide();
Gildas Bazin's avatar
 
Gildas Bazin committed
598 599
}

600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636
static int ConvertHotkeyModifiers( int i_hotkey )
{
    int i_accel_flags = 0;
    if( i_hotkey & KEY_MODIFIER_ALT ) i_accel_flags |= wxACCEL_ALT;
    if( i_hotkey & KEY_MODIFIER_CTRL ) i_accel_flags |= wxACCEL_CTRL;
    if( i_hotkey & KEY_MODIFIER_SHIFT ) i_accel_flags |= wxACCEL_SHIFT;
    if( !i_accel_flags ) i_accel_flags = wxACCEL_NORMAL;
    return i_accel_flags;
}

static int ConvertHotkey( int i_hotkey )
{
    int i_key = i_hotkey & ~KEY_MODIFIER;
    if( i_key & KEY_ASCII ) return i_key & KEY_ASCII;
    else if( i_key & KEY_SPECIAL )
    {
        switch ( i_key )
        {
        case KEY_LEFT: return WXK_LEFT;
        case KEY_RIGHT: return WXK_RIGHT;
        case KEY_UP: return WXK_UP;
        case KEY_DOWN: return WXK_DOWN;
        case KEY_SPACE: return WXK_SPACE;
        case KEY_ENTER: return WXK_RETURN;
        case KEY_F1: return WXK_F1;
        case KEY_F2: return WXK_F2;
        case KEY_F3: return WXK_F3;
        case KEY_F4: return WXK_F4;
        case KEY_F5: return WXK_F5;
        case KEY_F6: return WXK_F6;
        case KEY_F7: return WXK_F7;
        case KEY_F8: return WXK_F8;
        case KEY_F9: return WXK_F9;
        case KEY_F10: return WXK_F10;
        case KEY_F11: return WXK_F11;
        case KEY_F12: return WXK_F12;
        case KEY_HOME: return WXK_HOME;
637 638 639
        case KEY_END: return WXK_END;
        case KEY_INSERT: return WXK_INSERT;
        case KEY_DELETE: return WXK_DELETE;
640 641 642 643 644 645 646 647 648 649 650
        case KEY_MENU: return WXK_MENU;
        case KEY_ESC: return WXK_ESCAPE;
        case KEY_PAGEUP: return WXK_PRIOR;
        case KEY_PAGEDOWN: return WXK_NEXT;
        case KEY_TAB: return WXK_TAB;
        case KEY_BACKSPACE: return WXK_BACK;
        }
    }
    return WXK_F24;
}

651
void Interface::SetupHotkeys()
652
{
653 654
    struct vlc_t::hotkey *p_hotkeys = p_intf->p_vlc->p_hotkeys;
    int i_hotkeys;
655

656 657 658 659 660 661
    /* Count number of hoteys */
    for( i_hotkeys = 0; p_hotkeys[i_hotkeys].psz_action != NULL; i_hotkeys++ );

    p_intf->p_sys->i_first_hotkey_event = wxID_HIGHEST + 7000;
    p_intf->p_sys->i_hotkeys = i_hotkeys;

662
    wxAcceleratorEntry *p_entries = new wxAcceleratorEntry[i_hotkeys];
663 664

    /* Setup the hotkeys as accelerators */
665
    for( int i = 0; i < i_hotkeys; i++ )
666
    {
667 668 669 670
        int i_mod = ConvertHotkeyModifiers( p_hotkeys[i].i_key );
        int i_key = ConvertHotkey( p_hotkeys[i].i_key );

#ifdef WIN32
671 672
        if( !(p_hotkeys[i].i_key & KEY_SPECIAL) && i_mod )
            i_key = toupper(i_key);
673 674 675
#endif

        p_entries[i].Set( i_mod, i_key,
676 677
                          p_intf->p_sys->i_first_hotkey_event + i );
    }
Clément Stenac's avatar
Clément Stenac committed
678

679
    wxAcceleratorTable accel( i_hotkeys, p_entries );
Clément Stenac's avatar
Clément Stenac committed
680

681 682 683 684 685 686 687 688
    if( !accel.Ok() )
    {
        msg_Err( p_intf, "invalid accelerator table" );
    }
    else
    {
        SetAcceleratorTable( accel );
    }
689 690

    delete [] p_entries;
691 692
}

693
void Interface::HideSlider( bool layout )
Clément Stenac's avatar
Clément Stenac committed
694
{
695
    ShowSlider( false, layout );
Clément Stenac's avatar
Clément Stenac committed
696 697
}

698
void Interface::ShowSlider( bool show, bool layout )
Clément Stenac's avatar
Clément Stenac committed
699
{
700
    if( show )
701
    {
702 703 704
        //prevent the hide timers from hiding it now
        m_slider_timer.Stop();
        m_controls_timer.Stop();
705

706 707
        //prevent continuous layout
        if( slider_frame->IsShown() ) return;
708
    }
709 710 711 712 713
    else
    {
        //prevent continuous layout
        if( !slider_frame->IsShown() ) return;
    }
Clément Stenac's avatar
Clément Stenac committed
714

715 716 717 718 719 720
    if( layout && p_intf->p_sys->b_video_autosize )
        UpdateVideoWindow( p_intf, video_window );

    slider_frame->Show( show );
    frame_sizer->Show( slider_frame, show );

721
    if( layout )
Clément Stenac's avatar
Clément Stenac committed
722
    {
723
        frame_sizer->Layout();
724
        if( p_intf->p_sys->b_video_autosize ) frame_sizer->Fit( this );
Clément Stenac's avatar
Clément Stenac committed
725 726 727
    }
}

728
void Interface::HideDiscFrame( bool layout )
Clément Stenac's avatar
Clément Stenac committed
729
{
730
    ShowDiscFrame( false, layout );
Clément Stenac's avatar
Clément Stenac committed
731 732
}

733
void Interface::ShowDiscFrame( bool show, bool layout )
Clément Stenac's avatar
Clément Stenac committed
734
{
735
    if( show )
736
    {
737 738
        //prevent the hide timer from hiding it now
        m_controls_timer.Stop();
739

740 741
        //prevent continuous layout
        if( disc_frame->IsShown() ) return;
742
    }
743 744 745 746 747
    else
    {
        //prevent continuous layout
        if( !disc_frame->IsShown() ) return;
    }
Clément Stenac's avatar
Clément Stenac committed
748

749 750 751 752 753 754
    if( layout && p_intf->p_sys->b_video_autosize )
        UpdateVideoWindow( p_intf, video_window );

    disc_frame->Show( show );
    slider_sizer->Show( disc_frame, show );

755
    if( layout )
Clément Stenac's avatar
Clément Stenac committed
756
    {
757 758 759
        slider_sizer->Layout();
        if( p_intf->p_sys->b_video_autosize )
            slider_sizer->Fit( slider_frame );
Clément Stenac's avatar
Clément Stenac committed
760 761 762
    }
}

Gildas Bazin's avatar
 
Gildas Bazin committed
763
/*****************************************************************************
Gildas Bazin's avatar
 
Gildas Bazin committed
764
 * Event Handlers.
Gildas Bazin's avatar
 
Gildas Bazin committed
765
 *****************************************************************************/
766
void Interface::OnControlsTimer( wxTimerEvent& WXUNUSED(event) )
Clément Stenac's avatar
Clément Stenac committed
767
{
768 769 770
    if( p_intf->p_sys->b_video_autosize )
        UpdateVideoWindow( p_intf, video_window );

771 772 773 774 775 776 777 778 779 780 781
    /* Hide slider and Disc Buttons */
    //postpone layout, we'll do it ourselves
    HideDiscFrame( false );
    HideSlider( false );

    slider_sizer->Layout();
    if( p_intf->p_sys->b_video_autosize )
    {
        slider_sizer->Fit( slider_frame );
        frame_sizer->Fit( this );
    }
Clément Stenac's avatar
Clément Stenac committed
782
}
Clément Stenac's avatar
Clément Stenac committed
783

784 785 786
void Interface::OnSliderTimer( wxTimerEvent& WXUNUSED(event) )
{
    HideSlider();
Clément Stenac's avatar
Clément Stenac committed
787 788
}

789
void Interface::OnMenuOpen( wxMenuEvent& event )
Gildas Bazin's avatar
 
Gildas Bazin committed
790
{
791 792
#if defined( __WXMSW__ )
#   define GetEventObject GetMenu
793
#endif
794 795

    if( event.GetEventObject() == p_settings_menu )
Gildas Bazin's avatar
 
Gildas Bazin committed
796
    {
797 798 799 800
        p_settings_menu = SettingsMenu( p_intf, this, p_settings_menu );

        /* Add static items */
        p_settings_menu->AppendCheckItem( Extended_Event,
801
            wxU(_("Extended &GUI\tCtrl-G") ) );
802
        if( b_extra ) p_settings_menu->Check( Extended_Event, TRUE );
803 804 805 806 807
#if 0
        p_settings_menu->AppendCheckItem( Undock_Event,
            wxU(_("&Undock Ext. GUI") ) );
        if( b_undock ) p_settings_menu->Check( Undock_Event, TRUE );
#endif
808 809 810 811
        p_settings_menu->Append( Bookmarks_Event,
                                 wxU(_("&Bookmarks...\tCtrl-B") ) );
        p_settings_menu->Append( Prefs_Event,
                                 wxU(_("Preference&s...\tCtrl-S")) );
Gildas Bazin's avatar
 
Gildas Bazin committed
812
    }
813

Gildas Bazin's avatar
 
Gildas Bazin committed
814
    else if( event.GetEventObject() == p_audio_menu )
Gildas Bazin's avatar
 
Gildas Bazin committed
815
    {
816
        p_audio_menu = AudioMenu( p_intf, this, p_audio_menu );
Gildas Bazin's avatar
 
Gildas Bazin committed
817
    }
818

Gildas Bazin's avatar
 
Gildas Bazin committed
819 820
    else if( event.GetEventObject() == p_video_menu )
    {
821
        p_video_menu = VideoMenu( p_intf, this, p_video_menu );
Gildas Bazin's avatar
 
Gildas Bazin committed
822
    }
823

Gildas Bazin's avatar
 
Gildas Bazin committed
824 825
    else if( event.GetEventObject() == p_navig_menu )
    {
826
        p_navig_menu = NavigMenu( p_intf, this, p_navig_menu );
Gildas Bazin's avatar
 
Gildas Bazin committed
827
    }
828 829 830 831

#if defined( __WXMSW__ )
#   undef GetEventObject
#endif
Gildas Bazin's avatar
 
Gildas Bazin committed
832 833
}

Gildas Bazin's avatar
 
Gildas Bazin committed
834
#if defined( __WXMSW__ ) || defined( __WXMAC__ )
Gildas Bazin's avatar
 
Gildas Bazin committed
835
void Interface::OnContextMenu2(wxContextMenuEvent& event)
Gildas Bazin's avatar
 
Gildas Bazin committed
836
{
Gildas Bazin's avatar
 
Gildas Bazin committed
837 838 839 840 841 842 843
    /* Only show the context menu for the main interface */
    if( GetId() != event.GetId() )
    {
        event.Skip();
        return;
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
844
    if( p_intf->p_sys->pf_show_dialog )
845
        p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU, 1, 0 );
Gildas Bazin's avatar
 
Gildas Bazin committed
846
}
Gildas Bazin's avatar
 
Gildas Bazin committed
847
#endif
Gildas Bazin's avatar
 
Gildas Bazin committed
848 849
void Interface::OnContextMenu(wxMouseEvent& event)
{
Gildas Bazin's avatar
 
Gildas Bazin committed
850
    if( p_intf->p_sys->pf_show_dialog )
851
        p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU, 1, 0 );
Gildas Bazin's avatar
 
Gildas Bazin committed
852
}
Gildas Bazin's avatar
 
Gildas Bazin committed
853

Gildas Bazin's avatar
 
Gildas Bazin committed
854 855 856 857 858 859 860 861 862
void Interface::OnExit( wxCommandEvent& WXUNUSED(event) )
{
    /* TRUE is to force the frame to close. */
    Close(TRUE);
}

void Interface::OnAbout( wxCommandEvent& WXUNUSED(event) )
{
    wxString msg;
Sam Hocevar's avatar
Sam Hocevar committed
863
    msg.Printf( wxString(wxT("VLC media player " PACKAGE_VERSION)) +
864
        wxU(_(" (wxWidgets interface)\n\n")) +