* ALL: experimental code for stream (dvd) navigation through object variables.
[vlc.git] / modules / gui / wxwindows / popup.cpp
1 /*****************************************************************************
2  * popup.cpp : wxWindows plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2000-2001 VideoLAN
5  * $Id: popup.cpp,v 1.4 2003/03/11 23:56:54 gbazin Exp $
6  *
7  * Authors: Gildas Bazin <gbazin@netcourrier.com>
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
34 #ifdef WIN32                                                 /* mingw32 hack */
35 #undef Yield
36 #undef CreateDialog
37 #endif
38
39 /* Let vlc take care of the i18n stuff */
40 #define WXINTL_NO_GETTEXT_MACRO
41
42 #include <wx/wxprec.h>
43 #include <wx/wx.h>
44 #include <wx/listctrl.h>
45
46 #include <vlc/intf.h>
47
48 #include "wxwindows.h"
49
50 /*****************************************************************************
51  * Event Table.
52  *****************************************************************************/
53
54 /* IDs for the controls and the menu commands */
55 enum
56 {
57     /* menu items */
58     Close_Event = wxID_HIGHEST + 1000,
59     MenuDummy_Event,
60     MenuLast_Event,
61 };
62
63 BEGIN_EVENT_TABLE(PopupMenu, wxMenu)
64     /* Menu events */
65     EVT_MENU(Close_Event, PopupMenu::OnClose)
66     EVT_MENU(MenuDummy_Event, PopupMenu::OnEntrySelected)
67
68 END_EVENT_TABLE()
69
70 BEGIN_EVENT_TABLE(PopupEvtHandler, wxEvtHandler)
71     EVT_MENU(-1, PopupEvtHandler::OnMenuEvent)
72 END_EVENT_TABLE()
73
74 /*****************************************************************************
75  * Constructor.
76  *****************************************************************************/
77 PopupMenu::PopupMenu( intf_thread_t *_p_intf, Interface *_p_main_interface ):
78     wxMenu( )
79 {
80     vlc_object_t *p_object;
81
82     /* Initializations */
83     p_intf = _p_intf;
84     p_main_interface = _p_main_interface;
85     i_item_id = MenuLast_Event;
86
87     /* Audio menu */
88     Append( MenuDummy_Event, _("Audio menu") );
89     AppendSeparator();
90     p_object = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_AOUT,
91                                                 FIND_ANYWHERE );
92     if( p_object == NULL ) return;
93
94     CreateMenuEntry( "audio-device", p_object );
95     CreateMenuEntry( "audio-channels", p_object );
96
97     vlc_object_release( p_object );
98
99     /* Video menu */
100     AppendSeparator();
101     Append( MenuDummy_Event, _("Video menu") );
102     AppendSeparator();
103     p_object = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
104                                                 FIND_ANYWHERE );
105     if( p_object == NULL ) return;
106
107     CreateMenuEntry( "fullscreen", p_object );
108
109     vlc_object_release( p_object );
110
111     /* Input menu */
112     AppendSeparator();
113     Append( MenuDummy_Event, _("Input menu") );
114     AppendSeparator();
115     p_object = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
116                                                 FIND_ANYWHERE );
117     if( p_object == NULL ) return;
118
119     CreateMenuEntry( "title", p_object );
120     CreateMenuEntry( "chapter", p_object );
121     CreateMenuEntry( "navigation", p_object );
122
123     vlc_object_release( p_object );
124
125     /* Misc stuff */
126     AppendSeparator();
127     Append( Close_Event, _("&Close") );
128
129     /* Intercept all menu events in our custom event handler */
130     p_main_interface->p_popup_menu = this;
131     p_main_interface->PushEventHandler(
132         new PopupEvtHandler( p_intf, p_main_interface ) );
133
134     wxPoint mousepos = wxGetMousePosition();
135     p_main_interface->PopupMenu( this,
136                                  p_main_interface->ScreenToClient(mousepos).x,
137                                  p_main_interface->ScreenToClient(mousepos).y
138                                  );
139 }
140
141 PopupMenu::~PopupMenu()
142 {
143 }
144
145 /*****************************************************************************
146  * Private methods.
147  *****************************************************************************/
148 void PopupMenu::OnClose( wxCommandEvent& WXUNUSED(event) )
149 {
150     p_intf->b_die = VLC_TRUE;
151 }
152
153 void PopupMenu::OnEntrySelected( wxCommandEvent& WXUNUSED(event) )
154 {
155 }
156
157 void PopupMenu::CreateMenuEntry( char *psz_var, vlc_object_t *p_object )
158 {
159     vlc_value_t val, val1;
160     int i_type;
161
162     /* Check the type of the object variable */
163     i_type = var_Type( p_object, psz_var );
164
165     if( i_type & VLC_VAR_HASCHOICE )
166     {
167         Append( MenuDummy_Event, psz_var,
168                 CreateSubMenu( psz_var, p_object ),
169                 "YEAAAARRRGGGHHH HEEELLPPPPPP" );
170         return;
171     }
172
173     if( var_Get( p_object, psz_var, &val ) < 0 )
174     {
175         return;
176     }
177
178     wxMenuItemExt *menuitem;
179
180     switch( i_type )
181     {
182     case VLC_VAR_VOID:
183         menuitem = new wxMenuItemExt( this, i_item_id++, psz_var,
184                                       "", wxITEM_NORMAL, strdup(psz_var),
185                                       p_object->i_object_id, val );
186         Append( menuitem );
187         break;
188
189     case VLC_VAR_BOOL:
190         val1.b_bool = !val.b_bool;
191         menuitem = new wxMenuItemExt( this, i_item_id++, psz_var,
192                                       "", wxITEM_CHECK, strdup(psz_var),
193                                       p_object->i_object_id, val1 );
194         Append( menuitem );
195         Check( i_item_id - 1, val.b_bool ? TRUE : FALSE );
196         break;
197
198     case VLC_VAR_STRING:
199         break;
200
201     default:
202         break;
203     }
204
205 }
206
207 wxMenu *PopupMenu::CreateSubMenu( char *psz_var, vlc_object_t *p_object )
208 {
209     wxMenu *menu = new wxMenu;
210     vlc_value_t val;
211     vlc_value_t val_list;
212     int i_type, i;
213
214     /* Check the type of the object variable */
215     i_type = var_Type( p_object, psz_var );
216
217     if( var_Get( p_object, psz_var, &val ) < 0 )
218     {
219         return NULL;
220     }
221
222     if( var_Change( p_object, psz_var, VLC_VAR_GETLIST, &val_list ) < 0 )
223     {
224         return NULL;
225     }
226
227     for( i = 0; i < val_list.p_list->i_count; i++ )
228     {
229         vlc_value_t another_val;
230         wxMenuItemExt *menuitem;
231
232         switch( i_type & VLC_VAR_TYPE )
233         {
234         case VLC_VAR_VARIABLE:
235           menu->Append( MenuDummy_Event,
236                         val_list.p_list->p_values[i].psz_string,
237                         CreateSubMenu( val_list.p_list->p_values[i].psz_string,
238                                        p_object ),
239                         "YEAAAARRRGGGHHH HEEELLPPPPPP" );
240           break;
241
242         case VLC_VAR_STRING:
243           another_val.psz_string =
244               strdup(val_list.p_list->p_values[i].psz_string);
245           menuitem =
246               new wxMenuItemExt( this, i_item_id++, another_val.psz_string,
247                                  "", wxITEM_RADIO, strdup(psz_var),
248                                  p_object->i_object_id,
249                                  another_val );
250
251           menu->Append( menuitem );
252
253           if( !strcmp( val.psz_string,
254                        val_list.p_list->p_values[i].psz_string ) )
255               menu->Check( i_item_id - 1, TRUE );
256           break;
257
258         case VLC_VAR_INTEGER:
259           menuitem =
260               new wxMenuItemExt( this, i_item_id++,
261                                  wxString::Format(_("%d"),
262                                  val_list.p_list->p_values[i].i_int),
263                                  "", wxITEM_RADIO, strdup(psz_var),
264                                  p_object->i_object_id,
265                                  val_list.p_list->p_values[i] );
266
267           menu->Append( menuitem );
268
269           if( !((i_type & VLC_VAR_FLAGS) & VLC_VAR_ISCOMMAND) &&
270               val_list.p_list->p_values[i].i_int == val.i_int )
271               menu->Check( i_item_id - 1, TRUE );
272           break;
273
274         default:
275           break;
276         }
277     }
278
279     var_Change( p_object, psz_var, VLC_VAR_FREELIST, &val_list );
280
281     return menu;
282 }
283
284 /*****************************************************************************
285  * A small helper class which intercepts all popup menu events
286  *****************************************************************************/
287 PopupEvtHandler::PopupEvtHandler( intf_thread_t *_p_intf,
288                                   Interface *_p_main_interface )
289 {
290     /* Initializations */
291     p_intf = _p_intf;
292     p_main_interface = _p_main_interface;
293 }
294
295 PopupEvtHandler::~PopupEvtHandler()
296 {
297 }
298
299 void PopupEvtHandler::OnMenuEvent( wxCommandEvent& event )
300 {
301     wxMenuItemExt *p_menuitem = (wxMenuItemExt *)
302         p_main_interface->p_popup_menu->FindItem( event.GetId() );
303
304     if( p_menuitem )
305     {
306         vlc_object_t *p_object;
307
308         p_object = (vlc_object_t *)vlc_object_get( p_intf,
309                                                    p_menuitem->i_object_id );
310         if( p_object == NULL ) return;
311
312         var_Set( p_object, p_menuitem->psz_var, p_menuitem->val );
313
314         vlc_object_release( p_object );
315     }
316     else
317         event.Skip();
318 }