]> git.sesse.net Git - vlc/blob - modules/gui/wxwindows/timer.cpp
Fix disc buttons
[vlc] / modules / gui / wxwindows / timer.cpp
1 /*****************************************************************************
2  * timer.cpp : wxWindows plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2000-2005 VideoLAN
5  * $Id$
6  *
7  * Authors: Gildas Bazin <gbazin@videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>                                      /* malloc(), free() */
28 #include <errno.h>                                                 /* ENOMEM */
29 #include <string.h>                                            /* strerror() */
30 #include <stdio.h>
31
32 #include <vlc/vlc.h>
33 #include <vlc/aout.h>
34 #include <vlc/intf.h>
35
36 #include "vlc_meta.h"
37
38 #include "wxwindows.h"
39 #include <wx/timer.h>
40
41 //void DisplayStreamDate( wxControl *, intf_thread_t *, int );
42
43 /* Callback prototypes */
44 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
45                         vlc_value_t old_val, vlc_value_t new_val, void *param );
46 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
47                        vlc_value_t old_val, vlc_value_t new_val, void *param );
48
49 /*****************************************************************************
50  * Constructor.
51  *****************************************************************************/
52 Timer::Timer( intf_thread_t *_p_intf, Interface *_p_main_interface )
53 {
54     p_intf = _p_intf;
55     p_main_interface = _p_main_interface;
56     b_init = 0;
57     i_old_playing_status = PAUSE_S;
58     i_old_rate = INPUT_RATE_DEFAULT;
59
60     /* Register callback for the intf-popupmenu variable */
61     playlist_t *p_playlist =
62         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
63                                        FIND_ANYWHERE );
64     if( p_playlist != NULL )
65     {
66         var_AddCallback( p_playlist, "intf-popupmenu", PopupMenuCB, p_intf );
67         var_AddCallback( p_playlist, "intf-show", IntfShowCB, p_intf );
68         vlc_object_release( p_playlist );
69     }
70
71     Start( 100 /*milliseconds*/, wxTIMER_CONTINUOUS );
72 }
73
74 Timer::~Timer()
75 {
76     /* Unregister callback */
77     playlist_t *p_playlist =
78         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
79                                        FIND_ANYWHERE );
80     if( p_playlist != NULL )
81     {
82         var_DelCallback( p_playlist, "intf-popupmenu", PopupMenuCB, p_intf );
83         var_DelCallback( p_playlist, "intf-show", IntfShowCB, p_intf );
84         vlc_object_release( p_playlist );
85     }
86
87     vlc_mutex_lock( &p_intf->change_lock );
88     if( p_intf->p_sys->p_input ) vlc_object_release( p_intf->p_sys->p_input );
89     p_intf->p_sys->p_input = NULL;
90     vlc_mutex_unlock( &p_intf->change_lock );
91 }
92
93 /*****************************************************************************
94  * Private methods.
95  *****************************************************************************/
96
97 /*****************************************************************************
98  * Manage: manage main thread messages
99  *****************************************************************************
100  * In this function, called approx. 10 times a second, we check what the
101  * main program wanted to tell us.
102  *****************************************************************************/
103 void Timer::Notify()
104 {
105 #if defined( __WXMSW__ ) /* Work-around a bug with accelerators */
106     if( !b_init )
107     {
108         p_main_interface->Init();
109         b_init = VLC_TRUE;
110     }
111 #endif
112
113     vlc_mutex_lock( &p_intf->change_lock );
114
115     /* Update the input */
116     if( p_intf->p_sys->p_input == NULL )
117     {
118         playlist_t *p_playlist =
119             (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
120                                            FIND_ANYWHERE );
121         if( p_playlist != NULL )
122         {
123             LockPlaylist( p_intf->p_sys, p_playlist );
124             p_intf->p_sys->p_input = p_playlist->p_input;
125             if( p_intf->p_sys->p_input )
126                 vlc_object_yield( p_intf->p_sys->p_input );
127             UnlockPlaylist( p_intf->p_sys, p_playlist );
128             vlc_object_release( p_playlist );
129         }
130
131         /* Refresh interface */
132         if( p_intf->p_sys->p_input )
133         {
134             p_main_interface->slider->SetValue( 0 );
135
136             char *psz_now_playing = vlc_input_item_GetInfo(
137                 p_intf->p_sys->p_input->input.p_item,
138                 _("Meta-information"), _( "Now Playing" ) );
139             if( psz_now_playing && *psz_now_playing )
140             {
141                 p_main_interface->statusbar->SetStatusText(
142                     wxString(wxU(psz_now_playing)) + wxT( " - " ) +
143                     wxU(p_intf->p_sys->p_input->input.p_item->psz_name), 2 );
144             }
145             else
146             {
147                 p_main_interface->statusbar->SetStatusText(
148                     wxU(p_intf->p_sys->p_input->input.p_item->psz_name), 2 );
149             }
150             free( psz_now_playing );
151
152             p_main_interface->TogglePlayButton( PLAYING_S );
153 #ifdef wxHAS_TASK_BAR_ICON
154             if( p_main_interface->p_systray )
155             {
156                 p_main_interface->p_systray->UpdateTooltip( wxU(p_intf->p_sys->p_input->input.p_item->psz_name) + wxString(wxT(" - ")) + wxU(_("Playing")));
157             }
158 #endif
159             i_old_playing_status = PLAYING_S;
160         }
161     }
162     else if( p_intf->p_sys->p_input->b_dead )
163     {
164         //controls auto-hide after a timer
165         p_main_interface->m_controls_timer.Start(200, wxTIMER_ONE_SHOT);
166
167         p_main_interface->TogglePlayButton( PAUSE_S );
168         i_old_playing_status = PAUSE_S;
169
170         p_main_interface->statusbar->SetStatusText( wxT(""), 0 );
171         p_main_interface->statusbar->SetStatusText( wxT(""), 2 );
172
173 #ifdef wxHAS_TASK_BAR_ICON
174         if( p_main_interface->p_systray )
175         {
176             p_main_interface->p_systray->UpdateTooltip( wxString(wxT("VLC media player - ")) + wxU(_("Stopped")) );
177         }
178 #endif
179         vlc_object_release( p_intf->p_sys->p_input );
180         p_intf->p_sys->p_input = NULL;
181     }
182
183     if( p_intf->p_sys->p_input )
184     {
185         input_thread_t *p_input = p_intf->p_sys->p_input;
186         vlc_value_t val;
187
188         if( !p_input->b_die )
189         {
190             vlc_value_t pos;
191
192             //prevent the controls from auto-hiding
193             p_main_interface->m_controls_timer.Stop();
194
195             /* New input or stream map change */
196             p_intf->p_sys->b_playing = 1;
197
198             /* Update the item name */
199             char *psz_now_playing = vlc_input_item_GetInfo(
200                 p_intf->p_sys->p_input->input.p_item,
201                 _("Meta-information"), _( "Now Playing" ) );
202             if( psz_now_playing && *psz_now_playing )
203             {
204                 p_main_interface->statusbar->SetStatusText(
205                     wxString(wxU(psz_now_playing)) + wxT( " - " ) +
206                     wxU(p_intf->p_sys->p_input->input.p_item->psz_name), 2 );
207             }
208             else
209             {
210                 p_main_interface->statusbar->SetStatusText(
211                     wxU(p_intf->p_sys->p_input->input.p_item->psz_name), 2 );
212             }
213             free( psz_now_playing );
214
215             /* Manage the slider */
216             var_Get( p_input, "position", &pos );
217
218             var_Change( p_input, "title", VLC_VAR_CHOICESCOUNT, &val, NULL );
219             if( val.i_int > 0 && !p_main_interface->disc_frame->IsShown() )
220             {
221                 vlc_value_t val;
222
223                     #define HELP_MENU N_("Menu")
224                     #define HELP_PCH N_("Previous chapter")
225                     #define HELP_NCH N_("Next chapter")
226                     #define HELP_PTR N_("Previous track")
227                     #define HELP_NTR N_("Next track")
228
229                 var_Change( p_input, "chapter", VLC_VAR_CHOICESCOUNT, &val,
230                             NULL );
231
232                 if( val.i_int > 0 )
233                 {
234                     p_main_interface->disc_menu_button->Show();
235                     p_main_interface->disc_sizer->Show(
236                         p_main_interface->disc_menu_button );
237                     p_main_interface->disc_sizer->Layout();
238                     p_main_interface->disc_sizer->Fit(
239                         p_main_interface->disc_frame );
240                     p_main_interface->disc_menu_button->SetToolTip(
241                         wxU(_( HELP_MENU ) ) );
242                     p_main_interface->disc_prev_button->SetToolTip(
243                         wxU(_( HELP_PCH ) ) );
244                     p_main_interface->disc_next_button->SetToolTip(
245                         wxU(_( HELP_NCH ) ) );
246                 }
247                 else
248                 {
249                     p_main_interface->disc_menu_button->Hide();
250                     p_main_interface->disc_sizer->Hide(
251                         p_main_interface->disc_menu_button );
252
253                     p_main_interface->disc_prev_button->SetToolTip(
254                         wxU(_( HELP_PTR ) ) );
255                     p_main_interface->disc_next_button->SetToolTip(
256                         wxU(_( HELP_NTR ) ) );
257                 }
258
259                 p_main_interface->ShowDiscFrame();
260             }
261             else if( val.i_int == 0 && p_main_interface->disc_frame->IsShown() )
262             {
263                 p_main_interface->HideDiscFrame();
264             }
265
266
267             if( pos.f_float > 0.0 &&
268                 !p_main_interface->slider_frame->IsShown() )
269             {
270                 /* Show the slider if it's position is significant */
271                 p_main_interface->ShowSlider();
272             }
273             else if( pos.f_float <= 0.0 )
274             {
275                 p_main_interface->m_slider_timer.Start(200, wxTIMER_ONE_SHOT);
276             }
277
278             if( p_intf->p_sys->b_playing &&
279                 p_main_interface->slider_frame->IsShown() )
280             {
281                 /* Update the slider if the user isn't dragging it. */
282                 if( p_intf->p_sys->b_slider_free )
283                 {
284                     char psz_time[ MSTRTIME_MAX_SIZE ];
285                     char psz_total[ MSTRTIME_MAX_SIZE ];
286                     vlc_value_t time;
287                     mtime_t i_seconds;
288
289                     /* Update the value */
290                     if( pos.f_float >= 0.0 )
291                     {
292                         p_intf->p_sys->i_slider_pos =
293                             (int)(SLIDER_MAX_POS * pos.f_float);
294
295                         p_main_interface->slider->SetValue(
296                             p_intf->p_sys->i_slider_pos );
297
298                         var_Get( p_intf->p_sys->p_input, "time", &time );
299                         i_seconds = time.i_time / 1000000;
300                         secstotimestr ( psz_time, i_seconds );
301
302                         var_Get( p_intf->p_sys->p_input, "length",  &time );
303                         i_seconds = time.i_time / 1000000;
304                         secstotimestr ( psz_total, i_seconds );
305
306                         p_main_interface->statusbar->SetStatusText(
307                             wxU(psz_time) + wxString(wxT(" / ")) +
308                             wxU(psz_total), 0 );
309                     }
310                 }
311             }
312
313             /* Take care of the volume, etc... */
314             p_main_interface->Update();
315
316             /* Manage Playing status */
317             var_Get( p_input, "state", &val );
318             if( i_old_playing_status != val.i_int )
319             {
320                 if( val.i_int == PAUSE_S )
321                 {
322                     p_main_interface->TogglePlayButton( PAUSE_S );
323                 }
324                 else
325                 {
326                     p_main_interface->TogglePlayButton( PLAYING_S );
327                 }
328 #ifdef wxHAS_TASK_BAR_ICON
329                 if( p_main_interface->p_systray )
330                 {
331                     if( val.i_int == PAUSE_S )
332                     {
333                         p_main_interface->p_systray->UpdateTooltip( wxU(p_intf->p_sys->p_input->input.p_item->psz_name) + wxString(wxT(" - ")) + wxU(_("Paused")));
334                     }
335                     else
336                     {
337                         p_main_interface->p_systray->UpdateTooltip( wxU(p_intf->p_sys->p_input->input.p_item->psz_name) + wxString(wxT(" - ")) + wxU(_("Playing")));
338                     }
339                 }
340 #endif
341                 i_old_playing_status = val.i_int;
342             }
343
344             /* Manage Speed status */
345             var_Get( p_input, "rate", &val );
346             if( i_old_rate != val.i_int )
347             {
348                 p_main_interface->statusbar->SetStatusText(
349                     wxString::Format(wxT("x%.2f"),
350                     (float)INPUT_RATE_DEFAULT / val.i_int ), 1 );
351                 i_old_rate = val.i_int;
352             }
353         }
354     }
355     else if( p_intf->p_sys->b_playing && !p_intf->b_die )
356     {
357         p_intf->p_sys->b_playing = 0;
358         p_main_interface->TogglePlayButton( PAUSE_S );
359         i_old_playing_status = PAUSE_S;
360     }
361
362     /* Show the interface, if requested */
363     if( p_intf->p_sys->b_intf_show )
364     {
365         p_main_interface->Raise();
366         p_intf->p_sys->b_intf_show = VLC_FALSE;
367     }
368
369     if( p_intf->b_die )
370     {
371         vlc_mutex_unlock( &p_intf->change_lock );
372
373         /* Prepare to die, young Skywalker */
374         p_main_interface->Close(TRUE);
375         return;
376     }
377
378     vlc_mutex_unlock( &p_intf->change_lock );
379 }
380
381 /*****************************************************************************
382  * PopupMenuCB: callback triggered by the intf-popupmenu playlist variable.
383  *  We don't show the menu directly here because we don't want the
384  *  caller to block for a too long time.
385  *****************************************************************************/
386 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
387                         vlc_value_t old_val, vlc_value_t new_val, void *param )
388 {
389     intf_thread_t *p_intf = (intf_thread_t *)param;
390
391     if( p_intf->p_sys->pf_show_dialog )
392     {
393         p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU,
394                                        new_val.b_bool, 0 );
395     }
396
397     return VLC_SUCCESS;
398 }
399
400
401 /*****************************************************************************
402  * IntfShowCB: callback triggered by the intf-show playlist variable.
403  *****************************************************************************/
404 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
405                        vlc_value_t old_val, vlc_value_t new_val, void *param )
406 {
407     intf_thread_t *p_intf = (intf_thread_t *)param;
408     p_intf->p_sys->b_intf_show = VLC_TRUE;
409
410     return VLC_SUCCESS;
411 }