interface.cpp 44.2 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
#ifdef wxHAS_TASK_BAR_ICON
400 401
    /* Systray integration */
    p_systray = NULL;
402
    if( config_GetInt( p_intf, "wx-systray" ) )
403
    {
404
        p_systray = new Systray( this, p_intf );
405
    }
406
#endif
407

gbazin's avatar
 
gbazin committed
408 409 410 411 412 413
    /* Creation of the menu bar */
    CreateOurMenuBar();

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

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

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

gbazin's avatar
gbazin committed
429
    /* Video window */
430
    video_window = 0;
431
    if( config_GetInt( p_intf, "wx-embed" ) )
gbazin's avatar
gbazin committed
432
    {
433 434
        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
435 436
    }

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

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

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

452
    SetupHotkeys();
gbazin's avatar
 
gbazin committed
453 454 455

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

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

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

466
    if( ws->GetSettings( WindowSettings::ID_MAIN, b_shown, p, s ) ) Move( p );
467 468

    /* Show extended GUI if requested */
469 470 471 472
    wxCommandEvent dummy;
    if( config_GetInt( p_intf, "wx-extended" ) ) OnExtended( dummy );

    SetIntfMinSize();
473

474 475 476 477
    var_Create( p_intf, "interaction", VLC_VAR_ADDRESS );
    var_AddCallback( p_intf, "interaction", InteractCallback, this );
    p_intf->b_interaction = VLC_TRUE;

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

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

486 487 488 489 490
    if( !IsIconized() )
    {
        ws->SetSettings( WindowSettings::ID_MAIN, true,
                         GetPosition(), GetSize() );
    }
491

492
    PopEventHandler(true);
493

494 495
    if( video_window ) delete video_window;

496
#ifdef wxHAS_TASK_BAR_ICON
497
    if( p_systray ) delete p_systray;
498
#endif
499

500 501 502
    p_intf->b_interaction = VLC_FALSE;
    var_DelCallback( p_intf, "interaction", InteractCallback, this );

503
    if( p_intf->p_sys->p_wxwindow ) delete p_intf->p_sys->p_wxwindow;
gbazin's avatar
 
gbazin committed
504

505

gbazin's avatar
 
gbazin committed
506
    /* Clean up */
gbazin's avatar
 
gbazin committed
507
    delete timer;
gbazin's avatar
 
gbazin committed
508
}
gbazin's avatar
 
gbazin committed
509

510 511 512
void Interface::Init()
{
    /* Misc init */
513
    SetupHotkeys();
514 515
}

516 517 518
void Interface::Update()
{
    /* Misc updates */
519
    ((VLCVolCtrl *)volctrl)->UpdateVolume();
520 521

    if( playlist_manager ) playlist_manager->Update();
522 523
}

524
void Interface::OnControlEvent( wxCommandEvent& event )
gbazin's avatar
gbazin committed
525
{
526 527 528
    switch( event.GetId() )
    {
    case 0:
529 530
        main_sizer->Layout();
        main_sizer->Fit( this );
531 532 533 534 535 536 537 538 539
        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
540 541
}

gbazin's avatar
 
gbazin committed
542 543 544 545 546
/*****************************************************************************
 * Private methods.
 *****************************************************************************/
void Interface::CreateOurMenuBar()
{
547
    int minimal = config_GetInt( p_intf, "wx-minimal" );
548

gbazin's avatar
 
gbazin committed
549
    /* Create the "File" menu */
gbazin's avatar
 
gbazin committed
550
    wxMenu *file_menu = new wxMenu;
551 552 553

    if (!minimal)
    {
554
    file_menu->Append( OpenFileSimple_Event,
gbazin's avatar
gbazin committed
555
                       wxU(_("Quick &Open File...\tCtrl-O")) );
zorglub's avatar
zorglub committed
556 557

    file_menu->AppendSeparator();
gbazin's avatar
gbazin committed
558
    file_menu->Append( OpenFile_Event, wxU(_("Open &File...\tCtrl-F")) );
559
    file_menu->Append( OpenDir_Event, wxU(_("Open Dir&ectory...\tCtrl-E")) );
gbazin's avatar
gbazin committed
560
    file_menu->Append( OpenDisc_Event, wxU(_("Open &Disc...\tCtrl-D")) );
561
    file_menu->Append( OpenNet_Event,
gbazin's avatar
gbazin committed
562 563
                       wxU(_("Open &Network Stream...\tCtrl-N")) );
    file_menu->Append( OpenCapture_Event,
564
                       wxU(_("Open C&apture Device...\tCtrl-A")) );
zorglub's avatar
zorglub committed
565

gbazin's avatar
 
gbazin committed
566
    file_menu->AppendSeparator();
567
    file_menu->Append( Wizard_Event, wxU(_("&Wizard...\tCtrl-W")) );
gbazin's avatar
 
gbazin committed
568
    file_menu->AppendSeparator();
569
    }
gbazin's avatar
gbazin committed
570
    file_menu->Append( Exit_Event, wxU(_("E&xit\tCtrl-X")) );
gbazin's avatar
 
gbazin committed
571

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

584 585 586 587 588
    /* 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
589

gbazin's avatar
 
gbazin committed
590
    /* Create the "Help" menu */
gbazin's avatar
 
gbazin committed
591
    wxMenu *help_menu = new wxMenu;
gbazin's avatar
gbazin committed
592
    help_menu->Append( About_Event, wxU(_("About VLC media player")) );
593 594
    help_menu->AppendSeparator();
    help_menu->Append( UpdateVLC_Event, wxU(_("Check for updates ...")) );
gbazin's avatar
 
gbazin committed
595 596

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

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

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

/* 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
635 636
        GetTextExtentPoint32( hdc, menubar->GetLabelTop(i).c_str(),
                                menubar->GetLabelTop(i).Length(), &sizing );
637 638 639

        // [ SM_CXDLGFRAME + pixels + textextent + pixels + SM_CXDLGFRAME ]
        i_size += sizing.cx + 2 + GetSystemMetrics( SM_CXDLGFRAME ) * 2;
640 641
    }
    ReleaseDC( NULL, hdc );
642
    i_size += GetSystemMetrics( SM_CXSIZEFRAME ) * 2 + 4;
643 644 645
#endif
/* End patch by zcot */

646
    panel_sizer->SetMinSize( i_size, -1 );
647

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

651
#if wxUSE_DRAG_AND_DROP
gbazin's avatar
 
gbazin committed
652 653
    /* Associate drop targets with the menubar */
    menubar->SetDropTarget( new DragAndDrop( p_intf ) );
gbazin's avatar
 
gbazin committed
654
#endif
gbazin's avatar
 
gbazin committed
655 656 657 658
}

void Interface::CreateOurToolBar()
{
659
#define HELP_OPEN N_("Open")
hartman's avatar
hartman committed
660 661 662 663
#define HELP_STOP N_("Stop")
#define HELP_PLAY N_("Play")
#define HELP_PAUSE N_("Pause")
#define HELP_PLO N_("Playlist")
664
#define HELP_SPLO N_("Small playlist")
gbazin's avatar
 
gbazin committed
665 666
#define HELP_PLP N_("Previous playlist item")
#define HELP_PLN N_("Next playlist item")
gbazin's avatar
 
gbazin committed
667 668
#define HELP_SLOW N_("Play slower")
#define HELP_FAST N_("Play faster")
gbazin's avatar
 
gbazin committed
669

670
    int minimal = config_GetInt( p_intf, "wx-minimal" );
671

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

675
    wxToolBar *toolbar =
676
        CreateToolBar( wxTB_HORIZONTAL | wxTB_FLAT );
gbazin's avatar
 
gbazin committed
677

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

680 681
    if (!minimal)
    {
682 683 684
    toolbar->AddTool( OpenFile_Event, wxT(""),
                      wxBitmap( eject_xpm ), wxU(_(HELP_OPEN)) );
    toolbar->AddSeparator();
685
    }
686 687

    wxToolBarToolBase *p_tool = toolbar->AddTool( PlayStream_Event, wxT(""),
688
                      wxBitmap( play_xpm ), wxU(_(HELP_PLAY)), wxITEM_CHECK );
689 690
    p_tool->SetClientData( p_tool );

691 692
    if (!minimal)
    {
693 694
    toolbar->AddTool( StopStream_Event, wxT(""), wxBitmap( stop_xpm ),
                      wxU(_(HELP_STOP)) );
gbazin's avatar
 
gbazin committed
695
    toolbar->AddSeparator();
696

gbazin's avatar
 
gbazin committed
697
    toolbar->AddTool( PrevStream_Event, wxT(""),
698 699 700 701 702
                      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
703
    toolbar->AddTool( NextStream_Event, wxT(""), wxBitmap( next_xpm ),
gbazin's avatar
 
gbazin committed
704
                      wxU(_(HELP_PLN)) );
705
    toolbar->AddSeparator();
706
    toolbar->AddTool( Playlist_Event, wxT(""), wxBitmap( playlist_xpm ),
707
                      wxU(_(HELP_PLO)) );
708 709
    toolbar->AddTool( PlaylistSmall_Event, wxT(""),
                      wxBitmap( playlist_small_xpm ), wxU(_(HELP_SPLO)) );
710
    }
gbazin's avatar
 
gbazin committed
711

712
    wxControl *p_dummy_ctrl =
713
        new wxControl( toolbar, -1, wxDefaultPosition,
714
                       wxSize(16, 16 ), wxBORDER_NONE );
715

716
    toolbar->AddControl( p_dummy_ctrl );
gbazin's avatar
 
gbazin committed
717

718 719
    volctrl = new VLCVolCtrl( p_intf, toolbar );
    toolbar->AddControl( volctrl );
720 721

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

723
#if wxUSE_DRAG_AND_DROP
gbazin's avatar
 
gbazin committed
724 725
    /* Associate drop targets with the toolbar */
    toolbar->SetDropTarget( new DragAndDrop( p_intf ) );
gbazin's avatar
 
gbazin committed
726
#endif
gbazin's avatar
 
gbazin committed
727 728
}

729 730 731 732 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
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;
766 767 768
        case KEY_END: return WXK_END;
        case KEY_INSERT: return WXK_INSERT;
        case KEY_DELETE: return WXK_DELETE;
769 770 771 772 773 774 775 776 777 778 779
        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;
}

780
void Interface::SetupHotkeys()
781
{
782 783
    struct vlc_t::hotkey *p_hotkeys = p_intf->p_vlc->p_hotkeys;
    int i_hotkeys;
784

785 786 787 788 789 790
    /* 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;

791
    wxAcceleratorEntry *p_entries = new wxAcceleratorEntry[i_hotkeys];
792 793

    /* Setup the hotkeys as accelerators */
794
    for( int i = 0; i < i_hotkeys; i++ )
795
    {