interface.cpp 43 KB
Newer Older
gbazin's avatar
   
gbazin committed
1
/*****************************************************************************
2
 * interface.cpp : wxWidgets plugin for vlc
gbazin's avatar
   
gbazin committed
3
 *****************************************************************************
4
 * Copyright (C) 2000-2006 the VideoLAN team
gbazin's avatar
gbazin committed
5
 * $Id$
gbazin's avatar
   
gbazin committed
6
 *
7
 * Authors: Gildas Bazin <gbazin@videolan.org>
gbazin's avatar
   
gbazin 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
 *
gbazin's avatar
   
gbazin committed
14
15
16
17
18
19
20
 * 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
dionoea's avatar
dionoea committed
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
gbazin's avatar
   
gbazin committed
22
23
24
25
26
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/
27
#include "interface.hpp"
28
#include "playlist_manager.hpp"
29
30
31
32
33
#include "extrapanel.hpp"
#include "timer.hpp"
#include "video.hpp"
#include <vlc_keys.h>

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
34
#include "charset.h"
gbazin's avatar
   
gbazin committed
35

36
37
#include <vlc/aout.h>
#include "charset.h"
gbazin's avatar
   
gbazin committed
38

39
40
#include <vlc_interaction.h>

41
42
#include <wx/splitter.h>

gbazin's avatar
   
gbazin committed
43
44
45
46
/* include the toolbar graphics */
#include "bitmaps/play.xpm"
#include "bitmaps/pause.xpm"
#include "bitmaps/stop.xpm"
47
#include "bitmaps/prev.xpm"
gbazin's avatar
   
gbazin committed
48
#include "bitmaps/next.xpm"
49
#include "bitmaps/eject.xpm"
gbazin's avatar
   
gbazin committed
50
#include "bitmaps/slow.xpm"
51
#include "bitmaps/fast.xpm"
52
#include "bitmaps/playlist.xpm"
53
#include "bitmaps/playlist_small.xpm"
54
#include "bitmaps/speaker.xpm"
55
#include "bitmaps/speaker_mute.xpm"
gbazin's avatar
   
gbazin committed
56

57
58
#define TOOLBAR_BMP_WIDTH 16
#define TOOLBAR_BMP_HEIGHT 16
gbazin's avatar
   
gbazin committed
59

gbazin's avatar
   
gbazin committed
60
/* include the icon graphic */
Sam Hocevar's avatar
Sam Hocevar committed
61
#include "../../../share/vlc32x32.xpm"
62
/* include a small icon graphic for the systray icon */
63
#ifdef wxHAS_TASK_BAR_ICON
64
#include "../../../share/vlc16x16.xpm"
65
#endif
gbazin's avatar
   
gbazin committed
66

zorglub's avatar
zorglub committed
67
68
69
/*****************************************************************************
 * Local prototypes
 *****************************************************************************/
70
71
static int InteractCallback( vlc_object_t *, const char *, vlc_value_t,
                             vlc_value_t, void *);
zorglub's avatar
zorglub committed
72

gbazin's avatar
   
gbazin committed
73
74
75
/*****************************************************************************
 * Local class declarations.
 *****************************************************************************/
gbazin's avatar
   
gbazin committed
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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:

};
gbazin's avatar
   
gbazin committed
95

96
97
class wxVolCtrl;
class VLCVolCtrl : public wxControl
gbazin's avatar
   
gbazin committed
98
99
{
public:
100
101
    VLCVolCtrl( intf_thread_t *p_intf, wxWindow *p_parent );
    virtual ~VLCVolCtrl() {};
gbazin's avatar
   
gbazin committed
102

103
104
    virtual void OnPaint( wxPaintEvent &event );
    void OnChange( wxMouseEvent& event );
105
    void UpdateVolume();
gbazin's avatar
   
gbazin committed
106

107
  private:
108
    DECLARE_EVENT_TABLE()
gbazin's avatar
   
gbazin committed
109

110
111
    wxVolCtrl *gauge;
    int i_y_offset;
112
    vlc_bool_t b_mute;
gbazin's avatar
   
gbazin committed
113
114
115
    intf_thread_t *p_intf;
};

116
BEGIN_EVENT_TABLE(VLCVolCtrl, wxControl)
117
    EVT_PAINT(VLCVolCtrl::OnPaint)
118

gbazin's avatar
   
gbazin committed
119
    /* Mouse events */
120
    EVT_LEFT_UP(VLCVolCtrl::OnChange)
gbazin's avatar
   
gbazin committed
121
122
END_EVENT_TABLE()

123
124
125
126
127
class Splitter : public wxSplitterWindow
{
public:
    Splitter( wxWindow *p_parent, intf_thread_t *_p_intf )
      : wxSplitterWindow( p_parent, -1, wxDefaultPosition, wxSize(0,0),
128
129
130
#if defined( __WXMSW__ )
                          wxCLIP_CHILDREN ),
#else
131
                          wxCLIP_CHILDREN | wxSP_3DSASH ),
132
#endif
133
        p_intf(_p_intf), b_video(0), i_delay(0)
134
135
    {
        SetSashSize( 0 );
136
137
138
139
140
141
142
143
144
145

        wxSize size = wxSize(-1, 150);
        wxPoint p = wxPoint(0,0);
        bool b_dummy;
        WindowSettings *ws = p_intf->p_sys->p_window_settings;
        ws->GetSettings( WindowSettings::ID_SMALL_PLAYLIST, b_dummy, p, size );

        i_width = size.GetWidth();
        i_sash_position = size.GetHeight();
        b_show_on_start = !!p.x;
146
147
    }

148
149
150
151
152
153
154
    virtual ~Splitter()
    {
        WindowSettings *ws = p_intf->p_sys->p_window_settings;
        ws->SetSettings( WindowSettings::ID_SMALL_PLAYLIST, true,
                         wxPoint(!!GetWindow2(),0),
                         wxSize(i_width, i_sash_position) );
    };
155
156
157

    virtual bool Split( wxWindow* window1, wxWindow* window2 )
    {
158
159
        SetSashSize( 0 );
        wxSize size = wxSize( i_width, i_sash_position );
160
161
        if( window2->GetSizer() ) window2->GetSizer()->SetMinSize( size );

162
163
164
165
        return wxSplitterWindow::SplitHorizontally( window1, window2,
                                                    -i_sash_position );
    }

166
167
168
169
170
171
    virtual bool Unsplit( wxWindow* window )
    {
        SetSashSize( 0 );
        return wxSplitterWindow::Unsplit( window );
    }

172
173
    bool ShowOnStart() { return b_show_on_start; }

174
175
176
177
178
private:
    DECLARE_EVENT_TABLE()

    void OnSize( wxSizeEvent &event )
    {
179
180
181
182
183
        /* If we display video, then resize the video window */
        if( GetWindow2() &&
            p_intf->p_sys->p_video_window && p_intf->p_sys->p_video_sizer &&
            p_intf->p_sys->p_video_sizer->GetMinSize() != wxSize(0,0) )
        {
184
185
186
            if( !b_video ) i_delay = mdate() + 1000000;
            b_video = VLC_TRUE;

187
188
189
            SetSashSize( -1 );

#if defined( __WXMSW__ )
190
            SetSashPosition( event.GetSize().GetHeight() - i_sash_position );
191
192
193
194
#else
            SetSashPosition( event.GetSize().GetHeight() -
                             i_sash_position - GetSashSize() );
#endif
195
196
197
198
199
        }
        else if( GetWindow2() && GetWindow1() && GetWindow1()->GetSizer() )
        {
            wxSize size = GetWindow1()->GetSizer()->GetMinSize();

200
201
202
            if( b_video ) i_delay = mdate() + 1000000;
            b_video = VLC_FALSE;

203
204
            if( event.GetSize().GetHeight() - size.GetHeight() )
            {
205
206
                SetSashSize( 0 );

207
208
                SetSashPosition( size.GetHeight() ? size.GetHeight() : 1 );

209
210
211
212
213
214
215
216
217
218
                if( i_delay < mdate() )
                {
                    i_sash_position = event.GetSize().GetHeight() -
                        size.GetHeight();
                    i_width = event.GetSize().GetWidth();

                    size = wxSize( i_width, i_sash_position );
                    if( GetWindow2()->GetSizer() )
                        GetWindow2()->GetSizer()->SetMinSize( size );
                }
219
220
221
            }
        }

222
223
224
225
226
227
        event.Skip();
    }

    void OnSashPosChanged( wxSplitterEvent &event )
    {
        if( !GetSize().GetHeight() ){ event.Skip(); return; }
228
229
230
231
232
233
234
235
236

        if( i_delay < mdate() )
        {
            i_sash_position = GetSize().GetHeight() - event.GetSashPosition();

            wxSize size = wxSize( i_width, i_sash_position );
            if( GetWindow2()->GetSizer() )
                GetWindow2()->GetSizer()->SetMinSize( size );
        }
237
238
239
240
241
        event.Skip();
    }

    intf_thread_t *p_intf;
    int i_sash_position;
242
    int i_width;
243
244
    vlc_bool_t b_video;
    mtime_t i_delay;
245
    vlc_bool_t b_show_on_start;
246
247
248
249
250
251
252
};

BEGIN_EVENT_TABLE(Splitter, wxSplitterWindow)
    EVT_SIZE( Splitter::OnSize )
    EVT_SPLITTER_SASH_POS_CHANGED(-1, Splitter::OnSashPosChanged)
END_EVENT_TABLE()

gbazin's avatar
   
gbazin committed
253
254
255
256
/*****************************************************************************
 * Event Table.
 *****************************************************************************/

gbazin's avatar
gbazin committed
257
258
DEFINE_LOCAL_EVENT_TYPE( wxEVT_INTF );

gbazin's avatar
   
gbazin committed
259
260
261
262
/* IDs for the controls and the menu commands */
enum
{
    /* menu items */
zorglub's avatar
zorglub committed
263
    MenuDummy_Event = wxID_HIGHEST + 1000,
gbazin's avatar
   
gbazin committed
264
    Exit_Event = wxID_HIGHEST,
gbazin's avatar
   
gbazin committed
265
    OpenFileSimple_Event,
zorglub's avatar
zorglub committed
266
    OpenAdv_Event,
gbazin's avatar
   
gbazin committed
267
    OpenFile_Event,
268
    OpenDir_Event,
gbazin's avatar
   
gbazin committed
269
270
    OpenDisc_Event,
    OpenNet_Event,
gbazin's avatar
gbazin committed
271
    OpenCapture_Event,
gbazin's avatar
   
gbazin committed
272
    OpenSat_Event,
zorglub's avatar
zorglub committed
273
    OpenOther_Event,
gbazin's avatar
   
gbazin committed
274
275
    EjectDisc_Event,

276
    Wizard_Event,
zorglub's avatar
zorglub committed
277

278
    Playlist_Event,
279
    PlaylistSmall_Event,
gbazin's avatar
   
gbazin committed
280
    Logs_Event,
281
    FileInfo_Event,
gbazin's avatar
   
gbazin committed
282
283

    Prefs_Event,
gbazin's avatar
gbazin committed
284
285
    Extended_Event,
    Bookmarks_Event,
gbazin's avatar
   
gbazin committed
286
    Skins_Event,
gbazin's avatar
   
gbazin committed
287
288
289
290

    StopStream_Event,
    PlayStream_Event,
    PrevStream_Event,
gbazin's avatar
   
gbazin committed
291
    NextStream_Event,
gbazin's avatar
   
gbazin committed
292
293
    SlowStream_Event,
    FastStream_Event,
gbazin's avatar
   
gbazin committed
294
295
296
297

    /* 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) */
298
    About_Event = wxID_ABOUT,
299
    UpdateVLC_Event,
300
    VLM_Event,
301

302
    Iconize_Event,
gbazin's avatar
   
gbazin committed
303
304
};

305
306
DEFINE_LOCAL_EVENT_TYPE( wxEVT_INTERACTION );

gbazin's avatar
   
gbazin committed
307
308
309
310
BEGIN_EVENT_TABLE(Interface, wxFrame)
    /* Menu events */
    EVT_MENU(Exit_Event, Interface::OnExit)
    EVT_MENU(About_Event, Interface::OnAbout)
311
    EVT_MENU(UpdateVLC_Event, Interface::OnShowDialog)
312
    EVT_MENU(VLM_Event, Interface::OnShowDialog)
gbazin's avatar
   
gbazin committed
313
314

    EVT_MENU(Playlist_Event, Interface::OnShowDialog)
315
    EVT_MENU(PlaylistSmall_Event, Interface::OnSmallPlaylist)
gbazin's avatar
   
gbazin committed
316
317
318
    EVT_MENU(Logs_Event, Interface::OnShowDialog)
    EVT_MENU(FileInfo_Event, Interface::OnShowDialog)
    EVT_MENU(Prefs_Event, Interface::OnShowDialog)
gbazin's avatar
   
gbazin committed
319

gbazin's avatar
   
gbazin committed
320
321
    EVT_MENU_OPEN(Interface::OnMenuOpen)

322
    EVT_MENU( Extended_Event, Interface::OnExtended )
zorglub's avatar
zorglub committed
323

324
    EVT_MENU( Bookmarks_Event, Interface::OnShowDialog)
zorglub's avatar
zorglub committed
325

gbazin's avatar
   
gbazin committed
326
#if defined( __WXMSW__ ) || defined( __WXMAC__ )
gbazin's avatar
   
gbazin committed
327
    EVT_CONTEXT_MENU(Interface::OnContextMenu2)
gbazin's avatar
   
gbazin committed
328
#endif
gbazin's avatar
   
gbazin committed
329
    EVT_RIGHT_UP(Interface::OnContextMenu)
gbazin's avatar
   
gbazin committed
330

gbazin's avatar
   
gbazin committed
331
    /* Toolbar events */
gbazin's avatar
   
gbazin committed
332
    EVT_MENU(OpenFileSimple_Event, Interface::OnShowDialog)
zorglub's avatar
zorglub committed
333
    EVT_MENU(OpenAdv_Event, Interface::OnShowDialog)
gbazin's avatar
   
gbazin committed
334
    EVT_MENU(OpenFile_Event, Interface::OnShowDialog)
335
    EVT_MENU(OpenDir_Event, Interface::OnShowDialog)
gbazin's avatar
   
gbazin committed
336
337
    EVT_MENU(OpenDisc_Event, Interface::OnShowDialog)
    EVT_MENU(OpenNet_Event, Interface::OnShowDialog)
gbazin's avatar
gbazin committed
338
    EVT_MENU(OpenCapture_Event, Interface::OnShowDialog)
gbazin's avatar
   
gbazin committed
339
    EVT_MENU(OpenSat_Event, Interface::OnShowDialog)
340
    EVT_MENU(Wizard_Event, Interface::OnShowDialog)
gbazin's avatar
   
gbazin committed
341
342
343
344
    EVT_MENU(StopStream_Event, Interface::OnStopStream)
    EVT_MENU(PlayStream_Event, Interface::OnPlayStream)
    EVT_MENU(PrevStream_Event, Interface::OnPrevStream)
    EVT_MENU(NextStream_Event, Interface::OnNextStream)
gbazin's avatar
   
gbazin committed
345
346
    EVT_MENU(SlowStream_Event, Interface::OnSlowStream)
    EVT_MENU(FastStream_Event, Interface::OnFastStream)
gbazin's avatar
   
gbazin committed
347

gbazin's avatar
gbazin committed
348
    /* Custom events */
349
350
    EVT_COMMAND(0, wxEVT_INTF, Interface::OnControlEvent)
    EVT_COMMAND(1, wxEVT_INTF, Interface::OnControlEvent)
351
352

    EVT_COMMAND( -1, wxEVT_INTERACTION, Interface::OnInteraction )
gbazin's avatar
   
gbazin committed
353
354
355
356
357
END_EVENT_TABLE()

/*****************************************************************************
 * Constructor.
 *****************************************************************************/
358
Interface::Interface( intf_thread_t *_p_intf, long style ):
gbazin's avatar
   
gbazin committed
359
    wxFrame( NULL, -1, wxT("VLC media player"),
360
             wxDefaultPosition, wxSize(700,100), style )
gbazin's avatar
   
gbazin committed
361
362
363
{
    /* Initializations */
    p_intf = _p_intf;
zorglub's avatar
zorglub committed
364
    b_extra = VLC_FALSE;
365
    extra_frame = 0;
366
    playlist_manager = 0;
gbazin's avatar
   
gbazin committed
367

zorglub's avatar
zorglub committed
368

gbazin's avatar
   
gbazin committed
369
    /* Give our interface a nice little icon */
bigben's avatar
bigben committed
370
    SetIcon( wxIcon( vlc_xpm ) );
gbazin's avatar
   
gbazin committed
371

372
373
374
    /* Create a splitter window that will fill in the interface window.
     * We need a splitter bar in order to make the embedded playlist
     * resizable. */
375
    splitter = new Splitter( this, p_intf );
376
    main_sizer = new wxBoxSizer( wxVERTICAL );
377
    main_sizer->Add( splitter, 1, wxEXPAND );
378
    SetSizer( main_sizer );
379
380
381

    /* Create a main panel that will fill in the interface window */
    main_panel = new wxPanel( splitter, -1, wxPoint(0,0), wxSize(0,0),
382
                              wxCLIP_CHILDREN );
383
    main_panel->SetFocus();
gbazin's avatar
   
gbazin committed
384

385
386
387
#if defined(__WXGTK20__) && wxCHECK_VERSION(2,5,6)
    /* As ugly as your butt! Please remove when wxWidgets 2.6 fixed their
     * Accelerators bug. */
388
    main_panel->m_imData = 0;
389
    m_imData = 0;
390
#endif
391
392
393
394

    /* Create a sizer for the main frame */
    panel_sizer = new wxBoxSizer( wxVERTICAL );
    main_panel->SetSizer( panel_sizer );
zorglub's avatar
zorglub committed
395

396
397
398
    /* Put this in the splitter */
    splitter->Initialize( main_panel );

399
400
/* wxCocoa pretends to support this, but at least 2.6.x doesn't */
#ifndef __APPLE__
401
#ifdef wxHAS_TASK_BAR_ICON
402
403
    /* Systray integration */
    p_systray = NULL;
404
    if( config_GetInt( p_intf, "wx-systray" ) )
405
    {
406
        p_systray = new Systray( this, p_intf );
407
    }
408
#endif
409
#endif
410

gbazin's avatar
   
gbazin committed
411
412
413
414
415
416
    /* Creation of the menu bar */
    CreateOurMenuBar();

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

417
    /* Creation of the status bar
gbazin's avatar
   
gbazin committed
418
419
     * Helptext for menu items and toolbar tools will automatically get
     * displayed here. */
420
    int i_status_width[3] = {100, 40, -1};
gbazin's avatar
   
gbazin committed
421
422
423
424
    statusbar = CreateStatusBar( 3 );                            /* 2 fields */
    statusbar->SetStatusWidths( 3, i_status_width );
    statusbar->SetStatusText( wxString::Format(wxT("x%.2f"), 1.0), 1 );

425
    /* Get minimum window size to prevent user from glitching it */
426
    splitter->SetSizeHints( -1, 0 );
427
428
429
    panel_sizer->Layout(); panel_sizer->Fit( main_panel );
    main_sizer->Layout(); main_sizer->Fit( this );
    main_min_size = GetSize();
430
    splitter->SetSizeHints( -1, -1 );
431

gbazin's avatar
gbazin committed
432
    /* Video window */
433
    video_window = 0;
434
    if( config_GetInt( p_intf, "wx-embed" ) )
gbazin's avatar
gbazin committed
435
    {
436
437
        video_window = CreateVideoWindow( p_intf, main_panel );
        panel_sizer->Add( p_intf->p_sys->p_video_sizer, 1, wxEXPAND, 0 );
gbazin's avatar
gbazin committed
438
439
    }

440
441
442
    /* Creation of the input manager panel */
    input_manager = new InputManager( p_intf, this, main_panel );
    panel_sizer->Add( input_manager, 0, wxEXPAND , 0 );
443

gbazin's avatar
   
gbazin committed
444
    /* Layout everything */
445
    splitter->SetSizeHints( -1, 0 );
446
447
    panel_sizer->Layout(); panel_sizer->Fit( main_panel );
    main_sizer->Layout(); main_sizer->Fit( this );
448
    splitter->SetSizeHints( -1, -1 );
gbazin's avatar
   
gbazin committed
449

450
#if wxUSE_DRAG_AND_DROP
gbazin's avatar
   
gbazin committed
451
452
    /* Associate drop targets with the main interface */
    SetDropTarget( new DragAndDrop( p_intf ) );
gbazin's avatar
   
gbazin committed
453
#endif
454

455
    SetupHotkeys();
gbazin's avatar
   
gbazin committed
456
457
458

    /* Start timer */
    timer = new Timer( p_intf, this );
459

460
    /* Restore previous position / settings */
461
462
    WindowSettings *ws = p_intf->p_sys->p_window_settings;
    wxPoint p;
463
464
    wxSize s;
    bool b_shown;
465
466
467
468

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

469
    if( ws->GetSettings( WindowSettings::ID_MAIN, b_shown, p, s ) ) Move( p );
470
471

    /* Show extended GUI if requested */
472
473
474
475
    wxCommandEvent dummy;
    if( config_GetInt( p_intf, "wx-extended" ) ) OnExtended( dummy );

    SetIntfMinSize();
476

477
478
479
480
    var_Create( p_intf, "interaction", VLC_VAR_ADDRESS );
    var_AddCallback( p_intf, "interaction", InteractCallback, this );
    p_intf->b_interaction = VLC_TRUE;

481
482
    /* Show embedded playlist if requested */
    if( splitter->ShowOnStart() ) OnSmallPlaylist( dummy );
gbazin's avatar
   
gbazin committed
483
484
485
486
}

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

489
490
491
492
493
    if( !IsIconized() )
    {
        ws->SetSettings( WindowSettings::ID_MAIN, true,
                         GetPosition(), GetSize() );
    }
494

495
    PopEventHandler(true);
496

497
498
    if( video_window ) delete video_window;

499
500
/* wxCocoa pretends to support this, but at least 2.6.x doesn't */
#ifndef __APPLE__
501
#ifdef wxHAS_TASK_BAR_ICON
502
    if( p_systray ) delete p_systray;
503
#endif
504
#endif
505

506
507
508
    p_intf->b_interaction = VLC_FALSE;
    var_DelCallback( p_intf, "interaction", InteractCallback, this );

509
    if( p_intf->p_sys->p_wxwindow ) delete p_intf->p_sys->p_wxwindow;
gbazin's avatar
   
gbazin committed
510

511

gbazin's avatar
   
gbazin committed
512
    /* Clean up */
gbazin's avatar
   
gbazin committed
513
    delete timer;
gbazin's avatar
   
gbazin committed
514
}
gbazin's avatar
   
gbazin committed
515

516
517
518
void Interface::Init()
{
    /* Misc init */
519
    SetupHotkeys();
520
521
}

522
523
524
void Interface::Update()
{
    /* Misc updates */
525
    ((VLCVolCtrl *)volctrl)->UpdateVolume();
526
527

    if( playlist_manager ) playlist_manager->Update();
528
529
}

530
void Interface::OnControlEvent( wxCommandEvent& event )
gbazin's avatar
gbazin committed
531
{
532
533
534
    switch( event.GetId() )
    {
    case 0:
535
536
        main_sizer->Layout();
        main_sizer->Fit( this );
537
538
539
540
541
542
543
544
545
        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;
    }
gbazin's avatar
gbazin committed
546
547
}

gbazin's avatar
   
gbazin committed
548
549
550
551
552
/*****************************************************************************
 * Private methods.
 *****************************************************************************/
void Interface::CreateOurMenuBar()
{
553
    int minimal = config_GetInt( p_intf, "wx-minimal" );
554

gbazin's avatar
   
gbazin committed
555
    /* Create the "File" menu */
gbazin's avatar
   
gbazin committed
556
    wxMenu *file_menu = new wxMenu;
557
558
559

    if (!minimal)
    {
560
    file_menu->Append( OpenFileSimple_Event,
gbazin's avatar
gbazin committed
561
                       wxU(_("Quick &Open File...\tCtrl-O")) );
zorglub's avatar
zorglub committed
562
563

    file_menu->AppendSeparator();
gbazin's avatar
gbazin committed
564
    file_menu->Append( OpenFile_Event, wxU(_("Open &File...\tCtrl-F")) );
565
    file_menu->Append( OpenDir_Event, wxU(_("Open Dir&ectory...\tCtrl-E")) );
gbazin's avatar
gbazin committed
566
    file_menu->Append( OpenDisc_Event, wxU(_("Open &Disc...\tCtrl-D")) );
567
    file_menu->Append( OpenNet_Event,
gbazin's avatar
gbazin committed
568
569
                       wxU(_("Open &Network Stream...\tCtrl-N")) );
    file_menu->Append( OpenCapture_Event,
570
                       wxU(_("Open C&apture Device...\tCtrl-A")) );
zorglub's avatar
zorglub committed
571

gbazin's avatar
   
gbazin committed
572
    file_menu->AppendSeparator();
573
    file_menu->Append( Wizard_Event, wxU(_("&Wizard...\tCtrl-W")) );
gbazin's avatar
   
gbazin committed
574
    file_menu->AppendSeparator();
575
    }
gbazin's avatar
gbazin committed
576
    file_menu->Append( Exit_Event, wxU(_("E&xit\tCtrl-X")) );
gbazin's avatar
   
gbazin committed
577

gbazin's avatar
   
gbazin committed
578
    /* Create the "View" menu */
gbazin's avatar
   
gbazin committed
579
    wxMenu *view_menu = new wxMenu;
580
581
    if (!minimal)
    {
gbazin's avatar
gbazin committed
582
    view_menu->Append( Playlist_Event, wxU(_("&Playlist...\tCtrl-P")) );
583
    }
gbazin's avatar
gbazin committed
584
    view_menu->Append( Logs_Event, wxU(_("&Messages...\tCtrl-M")) );
585
    view_menu->Append( FileInfo_Event,
gbazin's avatar
gbazin committed
586
                       wxU(_("Stream and Media &info...\tCtrl-I")) );
587
    view_menu->Append( VLM_Event,
588
                       wxU(_("VLM Control...\tCtrl-V")) );
gbazin's avatar
   
gbazin committed
589

590
591
592
593
594
    /* 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 );
gbazin's avatar
   
gbazin committed
595

gbazin's avatar
   
gbazin committed
596
    /* Create the "Help" menu */
gbazin's avatar
   
gbazin committed
597
    wxMenu *help_menu = new wxMenu;
gbazin's avatar
gbazin committed
598
    help_menu->Append( About_Event, wxU(_("About VLC media player")) );
599
600
    help_menu->AppendSeparator();
    help_menu->Append( UpdateVLC_Event, wxU(_("Check for updates ...")) );
gbazin's avatar
   
gbazin committed
601
602

    /* Append the freshly created menus to the menu bar... */
603
    wxMenuBar *menubar = new wxMenuBar();
gbazin's avatar
   
gbazin committed
604
605
    menubar->Append( file_menu, wxU(_("&File")) );
    menubar->Append( view_menu, wxU(_("&View")) );
gbazin's avatar
   
gbazin committed
606
    menubar->Append( p_settings_menu, wxU(_("&Settings")) );
gbazin's avatar
   
gbazin committed
607
608
    menubar->Append( p_audio_menu, wxU(_("&Audio")) );
    menubar->Append( p_video_menu, wxU(_("&Video")) );
gbazin's avatar
   
gbazin committed
609
    menubar->Append( p_navig_menu, wxU(_("&Navigation")) );
gbazin's avatar
   
gbazin committed
610
    menubar->Append( help_menu, wxU(_("&Help")) );
gbazin's avatar
   
gbazin committed
611
612
613
614

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

615
616
    /* Find out size of menu bar */
    int i_size = 0;
617
    for( unsigned int i = 0; i < menubar->GetMenuCount(); i++ )
618
619
620
    {
        int i_width, i_height;
        menubar->GetTextExtent( menubar->GetLabelTop(i), &i_width, &i_height );
621
622
        i_size += i_width +
#if defined(__WXGTK__)
623
            22 /* approximate margin */;
624
#else
625
#if (wxMAJOR_VERSION <= 2) && (wxMINOR_VERSION <= 5) && (wxRELEASE_NUMBER < 3)
626
            4 /* approximate margin */;
627
#else
628
            18 /* approximate margin */;
629
#endif
630
#endif
631
    }
632
633
634
635
636
637
638
639
640

/* Patch by zcot for menu wrapping */
#if defined(WIN32)
    /* Find out size of msw menu bar */
    i_size = 0;
    SIZE sizing;
    HDC hdc = GetDC( NULL );
    for( unsigned int i = 0; i < menubar->GetMenuCount(); i++ )
    {
zorglub's avatar
zorglub committed
641
642
        GetTextExtentPoint32( hdc, menubar->GetLabelTop(i).c_str(),
                                menubar->GetLabelTop(i).Length(), &sizing );
643
644
645

        // [ SM_CXDLGFRAME + pixels + textextent + pixels + SM_CXDLGFRAME ]
        i_size += sizing.cx + 2 + GetSystemMetrics( SM_CXDLGFRAME ) * 2;
646
647
    }
    ReleaseDC( NULL, hdc );
648
    i_size += GetSystemMetrics( SM_CXSIZEFRAME ) * 2 + 4;
649
650
651
#endif
/* End patch by zcot */

652
    panel_sizer->SetMinSize( i_size, -1 );
653

gbazin's avatar
   
gbazin committed
654
655
656
    /* Intercept all menu events in our custom event handler */
    PushEventHandler( new MenuEvtHandler( p_intf, this ) );

657
#if wxUSE_DRAG_AND_DROP
gbazin's avatar
   
gbazin committed
658
659
    /* Associate drop targets with the menubar */
    menubar->SetDropTarget( new DragAndDrop( p_intf ) );
gbazin's avatar
   
gbazin committed
660
#endif
gbazin's avatar
   
gbazin committed
661
662
663
664
}

void Interface::CreateOurToolBar()
{
665
#define HELP_OPEN N_("Open")
hartman's avatar
hartman committed
666
667
668
669
#define HELP_STOP N_("Stop")
#define HELP_PLAY N_("Play")
#define HELP_PAUSE N_("Pause")
#define HELP_PLO N_("Playlist")
670
#define HELP_SPLO N_("Small playlist")
gbazin's avatar
   
gbazin committed
671
672
#define HELP_PLP N_("Previous playlist item")
#define HELP_PLN N_("Next playlist item")
gbazin's avatar
   
gbazin committed
673
674
#define HELP_SLOW N_("Play slower")
#define HELP_FAST N_("Play faster")
gbazin's avatar
   
gbazin committed
675

676
    int minimal = config_GetInt( p_intf, "wx-minimal" );
677

gbazin's avatar
   
gbazin committed
678
679
    wxLogNull LogDummy; /* Hack to suppress annoying log message on the win32
                         * version because we don't include wx.rc */
gbazin's avatar
   
gbazin committed
680

681
    wxToolBar *toolbar =
682
        CreateToolBar( wxTB_HORIZONTAL | wxTB_FLAT );
gbazin's avatar
   
gbazin committed
683

gbazin's avatar
   
gbazin committed
684
685
    toolbar->SetToolBitmapSize( wxSize(TOOLBAR_BMP_WIDTH,TOOLBAR_BMP_HEIGHT) );

686
687
    if (!minimal)
    {
688
689
690
    toolbar->AddTool( OpenFile_Event, wxT(""),
                      wxBitmap( eject_xpm ), wxU(_(HELP_OPEN)) );
    toolbar->AddSeparator();
691
    }
692
693

    wxToolBarToolBase *p_tool = toolbar->AddTool( PlayStream_Event, wxT(""),
694
                      wxBitmap( play_xpm ), wxU(_(HELP_PLAY)), wxITEM_CHECK );
695
696
    p_tool->SetClientData( p_tool );

697
698
    if (!minimal)
    {
699
700
    toolbar->AddTool( StopStream_Event, wxT(""), wxBitmap( stop_xpm ),
                      wxU(_(HELP_STOP)) );
gbazin's avatar
   
gbazin committed
701
    toolbar->AddSeparator();
702

gbazin's avatar
   
gbazin committed
703
    toolbar->AddTool( PrevStream_Event, wxT(""),
704
705
706
707
708
                      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)) );
gbazin's avatar
   
gbazin committed
709
    toolbar->AddTool( NextStream_Event, wxT(""), wxBitmap( next_xpm ),
gbazin's avatar
   
gbazin committed
710
                      wxU(_(HELP_PLN)) );
711
    toolbar->AddSeparator();
712
    toolbar->AddTool( Playlist_Event, wxT(""), wxBitmap( playlist_xpm ),
713
                      wxU(_(HELP_PLO)) );
714
715
    toolbar->AddTool( PlaylistSmall_Event, wxT(""),
                      wxBitmap( playlist_small_xpm ), wxU(_(HELP_SPLO)) );
716
    }
gbazin's avatar
   
gbazin committed
717

718
    wxControl *p_dummy_ctrl =
719
        new wxControl( toolbar, -1, wxDefaultPosition,
720
                       wxSize(16, 16 ), wxBORDER_NONE );
721

722
    toolbar->AddControl( p_dummy_ctrl );
gbazin's avatar
   
gbazin committed
723

724
725
    volctrl = new VLCVolCtrl( p_intf, toolbar );
    toolbar->AddControl( volctrl );
726
727

    toolbar->Realize();
gbazin's avatar
   
gbazin committed
728

729
#if wxUSE_DRAG_AND_DROP
gbazin's avatar
   
gbazin committed
730
731
    /* Associate drop targets with the toolbar */
    toolbar->SetDropTarget( new DragAndDrop( p_intf ) );
gbazin's avatar
   
gbazin committed
732
#endif
gbazin's avatar
   
gbazin committed
733
734
}

735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
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;
772
773
774
        case KEY_END: return WXK_END;
        case KEY_INSERT: return WXK_INSERT;
        case KEY_DELETE: return WXK_DELETE;
775
776
777
778
779
780
781
782
783
784
785
        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;
}

786
void Interface::SetupHotkeys()
787
{
788
789
    struct vlc_t::hotkey *p_hotkeys = p_intf->p_vlc->p_hotkeys;
    int i_hotkeys;
790

791
792
793
794
795
796
    /* 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;

797
    wxAcceleratorEntry *p_entries = new wxAcceleratorEntry[i_hotkeys];
798
799

    /* Setup the hotkeys as accelerators */
800
    for( int i = 0; i < i_hotkeys; i++ )
801
    {
802
803
804
805
        int i_mod = ConvertHotkeyModifiers( p_hotkeys[i].i_key );
        int i_key = ConvertHotkey( p_hotkeys[i].i_key );

#ifdef WIN32
806
807
        if( !(p_hotkeys[i].i_key & KEY_SPECIAL) && i_mod )
            i_key = toupper(i_key);
808
809
810
#endif

        p_entries[i].Set( i_mod, i_key,
811
812
                          p_intf->p_sys->i_first_hotkey_event + i );
    }
zorglub's avatar
zorglub committed
813

814
    wxAcceleratorTable accel( i_hotkeys, p_entries );
zorglub's avatar
zorglub committed
815

816
817
818
819
820
821
822
823
    if( !accel.Ok() )
    {
        msg_Err( p_intf, "invalid accelerator table" );
    }
    else
    {
        SetAcceleratorTable( accel );
    }
824
825

    delete [] p_entries;
826
827
}

828
void Interface::SetIntfMinSize()
zorglub's avatar
zorglub committed
829
{
830
    wxSize ms = main_min_size;
zorglub's avatar
zorglub committed
831

832
    if( extra_frame && extra_frame->IsShown() )
833
    {
834
835
836
        ms.SetHeight( ms.GetHeight() + ext_min_size.GetHeight() );
        if( ext_min_size.GetWidth() > ms.GetWidth() )
            ms.SetWidth( ext_min_size.GetWidth() );
837
    }
838

839
    SetSizeHints( ms.GetWidth(), ms.GetHeight() );
zorglub's avatar
zorglub committed
840
841
}

gbazin's avatar
   
gbazin committed
842
/*****************************************************************************
gbazin's avatar
   
gbazin committed
843
 * Event Handlers.
gbazin's avatar
   
gbazin committed
844
 *****************************************************************************/
845
void Interface::OnMenuOpen( wxMenuEvent& event )
gbazin's avatar
   
gbazin committed
846
{
847
848
#if defined( __WXMSW__ )
#   define GetEventObject GetMenu
849
#endif
850
851

    if( event.GetEventObject() == p_settings_menu )
gbazin's avatar
   
gbazin committed
852
    {
853
854
855
856
        p_settings_menu = SettingsMenu( p_intf, this, p_settings_menu );

        /* Add static items */
        p_settings_menu->AppendCheckItem( Extended_Event,
857
            wxU(_("Extended &GUI\tCtrl-G") ) );
858
        if( b_extra ) p_settings_menu->Check( Extended_Event, TRUE );
859
860
861
862
        p_settings_menu->Append( Bookmarks_Event,
                                 wxU(_("&Bookmarks...\tCtrl-B") ) );
        p_settings_menu->Append( Prefs_Event,
                                 wxU(_("Preference&s...\tCtrl-S")) );
gbazin's avatar
   
gbazin committed
863
    }
864

gbazin's avatar
   
gbazin committed
865
    else if( event.GetEventObject() == p_audio_menu )
gbazin's avatar
   
gbazin committed
866
    {
867
        p_audio_menu = AudioMenu( p_intf, this, p_audio_menu );
gbazin's avatar
   
gbazin committed
868
    }
869

gbazin's avatar
   
gbazin committed
870
871
    else if( event.GetEventObject() == p_video_menu )
    {
872
        p_video_menu = VideoMenu( p_intf, this, p_video_menu );
gbazin's avatar
   
gbazin committed
873
    }
874

gbazin's avatar
   
gbazin committed
875
876
    else if( event.GetEventObject() == p_navig_menu )
    {
877
        p_navig_menu = NavigMenu( p_intf, this, p_navig_menu );
gbazin's avatar
   
gbazin committed
878
    }
879
880
881
882

#if defined( __WXMSW__ )
#   undef GetEventObject
#endif
gbazin's avatar
   
gbazin committed
883
884
}

gbazin's avatar
   
gbazin committed
885
#if defined( __WXMSW__ ) || defined( __WXMAC__ )
gbazin's avatar
   
gbazin committed
886
void Interface::OnContextMenu2(wxContextMenuEvent& event)
gbazin's avatar
   
gbazin committed
887
{
gbazin's avatar