1 /*****************************************************************************
\r
2 * menu.cpp: functions to handle menu items
\r
3 *****************************************************************************
\r
4 * Copyright (C) 2002-2003 VideoLAN
\r
5 * $Id: menu.cpp,v 1.16 2003/05/05 22:23:39 gbazin Exp $
\r
7 * Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
\r
9 * This program is free software; you can redistribute it and/or modify
\r
10 * it under the terms of the GNU General Public License as published by
\r
11 * the Free Software Foundation; either version 2 of the License, or
\r
12 * (at your option) any later version.
\r
14 * This program is distributed in the hope that it will be useful,
\r
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
17 * GNU General Public License for more details.
\r
19 * You should have received a copy of the GNU General Public License
\r
20 * along with this program; if not, write to the Free Software
\r
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
\r
22 *****************************************************************************/
\r
26 #include <vlc/vlc.h>
\r
27 #include <vlc/intf.h>
\r
30 #include "win32_common.h"
\r
32 /*****************************************************************************
\r
33 * TMenusGen::*Click: callbacks for the menuitems
\r
34 ****************************************************************************/
\r
40 /* variables of the audio output */
\r
41 void __fastcall TMenusGen::AoutVarClick( TObject *Sender )
\r
43 TMenuItem * Item = (TMenuItem *)Sender;
\r
45 vlc_object_t * p_aout;
\r
46 p_aout = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_AOUT,
\r
48 if( p_aout == NULL )
\r
50 msg_Warn( p_intf, "cannot set variable (%s)", Item->Caption.c_str() );
\r
54 #error fixme! look at rc.c line 823
\r
55 if( Item->Parent == MenuADevice || Item->Parent == PopupADevice )
\r
57 VarChange( p_aout, "audio-device", MenuADevice, PopupADevice, Item );
\r
59 else if( Item->Parent == MenuChannel || Item->Parent == PopupChannel )
\r
61 VarChange( p_aout, "audio-channels", MenuChannel, PopupChannel, Item );
\r
64 vlc_object_release( p_aout );
\r
67 /* variables of the video output */
\r
68 void __fastcall TMenusGen::VoutVarClick( TObject *Sender )
\r
70 TMenuItem * Item = (TMenuItem *)Sender;
\r
72 vlc_object_t * p_vout;
\r
73 p_vout = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
\r
75 if( p_vout == NULL )
\r
77 msg_Warn( p_intf, "cannot set variable (%s)", Item->Caption.c_str() );
\r
81 if( Item->Parent == MenuVDevice || Item->Parent == PopupVDevice )
\r
83 VarChange( p_vout, "video-device", MenuVDevice, PopupVDevice, Item );
\r
86 vlc_object_release( p_vout );
\r
93 /* Interface modules: we spawn a new interface */
\r
94 void __fastcall TMenusGen::InterfaceModuleClick( TObject *Sender )
\r
96 TMenuItem * Item = (TMenuItem *)Sender;
\r
98 AnsiString IntfName = CleanCaption( Item->Caption );
\r
100 intf_thread_t *p_newintf;
\r
102 p_newintf = intf_Create( p_intf->p_vlc, IntfName.c_str() );
\r
106 p_newintf->b_block = VLC_FALSE;
\r
107 if( intf_RunThread( p_newintf ) )
\r
109 vlc_object_detach( p_newintf );
\r
110 intf_Destroy( p_newintf );
\r
119 void __fastcall TMenusGen::MenuLanguageClick( TObject *Sender )
\r
121 LangChange( MenuLanguage, (TMenuItem *)Sender, PopupLanguage, AUDIO_ES );
\r
124 void __fastcall TMenusGen::PopupLanguageClick( TObject *Sender )
\r
126 LangChange( PopupLanguage, (TMenuItem *)Sender, MenuLanguage, AUDIO_ES );
\r
133 void __fastcall TMenusGen::MenuSubtitleClick( TObject *Sender )
\r
135 LangChange( MenuSubtitles, (TMenuItem *)Sender, PopupSubtitles, SPU_ES );
\r
138 void __fastcall TMenusGen::PopupSubtitleClick( TObject *Sender )
\r
140 LangChange( PopupSubtitles, (TMenuItem *)Sender, MenuSubtitles, SPU_ES );
\r
147 void __fastcall TMenusGen::MenuProgramClick( TObject *Sender )
\r
149 ProgramChange( (TMenuItem *)Sender, PopupProgram );
\r
152 void __fastcall TMenusGen::PopupProgramClick( TObject *Sender )
\r
154 ProgramChange( (TMenuItem *)Sender, MenuProgram );
\r
161 void __fastcall TMenusGen::MenuTitleClick( TObject *Sender )
\r
163 TMenuItem * Item = (TMenuItem *)Sender;
\r
164 TMenuItem * ItemTitle;
\r
165 input_area_t * p_area;
\r
166 unsigned int i_title = Item->Tag;
\r
168 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
\r
169 i_title = __MIN( i_title,
\r
170 p_intf->p_sys->p_input->stream.i_area_nb - 1 );
\r
171 i_title = __MAX( i_title, 1 );
\r
172 p_area = p_intf->p_sys->p_input->stream.pp_areas[i_title];
\r
173 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
\r
175 input_ChangeArea( p_intf->p_sys->p_input, p_area );
\r
177 Item->Checked = true;
\r
178 ItemTitle = Index2Item( PopupNavigation, i_title - 1, false );
\r
179 Index2Item( ItemTitle, 0, false )->Checked = true;
\r
181 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
\r
188 void __fastcall TMenusGen::MenuChapterClick( TObject *Sender )
\r
190 TMenuItem * Item = (TMenuItem *)Sender;
\r
191 TMenuItem * ItemTitle;
\r
192 input_area_t * p_area;
\r
193 unsigned int i_title;
\r
194 unsigned int i_chapter = Item->Tag;
\r
196 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
\r
197 p_area = p_intf->p_sys->p_input->stream.p_selected_area;
\r
198 i_chapter = __MIN( i_chapter, p_area->i_part_nb - 1 );
\r
199 i_chapter = __MAX( i_chapter, 1 );
\r
200 p_area->i_part = i_chapter;
\r
201 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
\r
203 input_ChangeArea( p_intf->p_sys->p_input, p_area );
\r
205 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
\r
206 i_title = p_intf->p_sys->p_input->stream.p_selected_area->i_id;
\r
207 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
\r
209 ItemTitle = Index2Item( PopupNavigation, i_title, false );
\r
210 Index2Item( ItemTitle, i_chapter, false )->Checked = true;
\r
212 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
\r
219 void __fastcall TMenusGen::PopupNavigationClick( TObject *Sender )
\r
221 TMenuItem * Item = (TMenuItem *)Sender;
\r
222 TMenuItem * ItemTitle;
\r
223 input_area_t * p_area;
\r
224 unsigned int i_title = Data2Title( Item->Tag );
\r
225 unsigned int i_chapter = Data2Chapter( Item->Tag );
\r
227 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
\r
228 i_title = __MIN( i_title,
\r
229 p_intf->p_sys->p_input->stream.i_area_nb - 1 );
\r
230 i_title = __MAX( i_title, 1 );
\r
231 p_area = p_intf->p_sys->p_input->stream.pp_areas[i_title];
\r
232 i_chapter = __MIN( i_chapter, p_area->i_part_nb - 1 );
\r
233 i_chapter = __MAX( i_chapter, 1 );
\r
234 p_area->i_part = i_chapter;
\r
235 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
\r
237 input_ChangeArea( p_intf->p_sys->p_input, p_area );
\r
239 Item->Checked = true;
\r
240 ItemTitle = Index2Item( MenuTitle, i_title, false );
\r
241 if( ItemTitle->Checked )
\r
243 /* same title, new chapter */
\r
244 Index2Item( MenuChapter, i_chapter, false )->Checked = true;
\r
248 /* new title => we must rebuild the chapter menu */
\r
249 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
\r
251 MenuChapter, "Chapter",
\r
252 p_intf->p_sys->p_input->stream.p_selected_area->i_part_nb,
\r
253 i_chapter, MenuChapterClick );
\r
254 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
\r
257 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
\r
261 __fastcall TMenusGen::TMenusGen( intf_thread_t *_p_intf ) : TObject()
\r
265 /* Initialize local pointers to menu items of the main window */
\r
266 TMainFrameDlg * p_window = p_intf->p_sys->p_window;
\r
267 if( p_window == NULL )
\r
269 msg_Warn( p_intf, "Main window wasn't created, expect problems..." );
\r
273 MenuChannel = p_window->MenuChannel;
\r
274 PopupChannel = p_window->PopupChannel;
\r
275 MenuADevice = p_window->MenuADevice;
\r
276 PopupADevice = p_window->PopupADevice;
\r
277 MenuVDevice = p_window->MenuVDevice;
\r
278 PopupVDevice = p_window->PopupVDevice;
\r
279 MenuLanguage = p_window->MenuLanguage;
\r
280 PopupLanguage = p_window->PopupLanguage;
\r
281 MenuSubtitles = p_window->MenuSubtitles;
\r
282 PopupSubtitles = p_window->PopupSubtitles;
\r
283 MenuProgram = p_window->MenuProgram;
\r
284 PopupProgram = p_window->PopupProgram;
\r
285 MenuTitle = p_window->MenuTitle;
\r
286 MenuChapter = p_window->MenuChapter;
\r
287 PopupNavigation = p_window->PopupNavigation;
\r
288 MenuAddInterface = p_window->MenuAddInterface;
\r
290 /* Create the "Add interface" menu */
\r
291 SetupModuleMenu( "interface", MenuAddInterface, InterfaceModuleClick );
\r
295 /*****************************************************************************
\r
296 * SetupMenus: This function dynamically generates some menus
\r
297 *****************************************************************************
\r
298 * The lock on p_input->stream must be taken before you call this function
\r
299 *****************************************************************************/
\r
300 void __fastcall TMenusGen::SetupMenus()
\r
302 TMainFrameDlg * p_window = p_intf->p_sys->p_window;
\r
303 input_thread_t * p_input = p_intf->p_sys->p_input;
\r
304 es_descriptor_t * p_audio_es;
\r
305 es_descriptor_t * p_spu_es;
\r
307 p_intf->p_sys->b_chapter_update |= p_intf->p_sys->b_title_update;
\r
308 p_intf->p_sys->b_audio_update |= p_intf->p_sys->b_program_update |
\r
309 p_intf->p_sys->b_title_update;
\r
310 p_intf->p_sys->b_spu_update |= p_intf->p_sys->b_program_update |
\r
311 p_intf->p_sys->b_title_update;
\r
313 if( p_intf->p_sys->b_program_update )
\r
315 pgrm_descriptor_t * p_pgrm;
\r
317 if( p_input->stream.p_new_program )
\r
319 p_pgrm = p_input->stream.p_new_program;
\r
323 p_pgrm = p_input->stream.p_selected_program;
\r
326 ProgramMenu( MenuProgram, p_pgrm, MenuProgramClick );
\r
327 ProgramMenu( PopupProgram, p_pgrm, PopupProgramClick );
\r
329 p_intf->p_sys->b_program_update = VLC_FALSE;
\r
332 if( p_intf->p_sys->b_title_update )
\r
335 // because if the titles go from 1 to X-1, there are X-1 titles
\r
336 RadioMenu( MenuTitle, "Title",
\r
337 p_input->stream.i_area_nb - 1,
\r
338 p_input->stream.p_selected_area->i_id,
\r
341 AnsiString CurrentTitle;
\r
342 CurrentTitle.sprintf( "%d", p_input->stream.p_selected_area->i_id );
\r
343 p_window->LabelTitleCurrent->Caption = CurrentTitle;
\r
345 p_intf->p_sys->b_title_update = VLC_FALSE;
\r
348 if( p_intf->p_sys->b_chapter_update )
\r
350 RadioMenu( MenuChapter, "Chapter",
\r
351 p_input->stream.p_selected_area->i_part_nb - 1,
\r
352 p_input->stream.p_selected_area->i_part,
\r
353 MenuChapterClick );
\r
355 NavigationMenu( PopupNavigation, PopupNavigationClick );
\r
357 AnsiString CurrentChapter;
\r
358 CurrentChapter.sprintf( "%d", p_input->stream.p_selected_area->i_part );
\r
359 p_window->LabelChapterCurrent->Caption = CurrentChapter;
\r
361 p_intf->p_sys->i_part = p_input->stream.p_selected_area->i_part;
\r
363 p_intf->p_sys->b_chapter_update = VLC_FALSE;
\r
366 /* look for selected ES */
\r
370 for( unsigned int i = 0; i < p_input->stream.i_selected_es_number; i++ )
\r
372 if( p_input->stream.pp_selected_es[i]->i_cat == AUDIO_ES )
\r
374 p_audio_es = p_input->stream.pp_selected_es[i];
\r
377 if( p_input->stream.pp_selected_es[i]->i_cat == SPU_ES )
\r
379 p_spu_es = p_input->stream.pp_selected_es[i];
\r
382 this->p_audio_es_old = p_audio_es;
\r
383 this->p_spu_es_old = p_spu_es;
\r
385 vlc_mutex_unlock( &p_input->stream.stream_lock );
\r
388 if( p_intf->p_sys->b_audio_update )
\r
390 LanguageMenu( MenuLanguage, p_audio_es, AUDIO_ES, MenuLanguageClick );
\r
391 LanguageMenu( PopupLanguage, p_audio_es, AUDIO_ES, PopupLanguageClick );
\r
393 p_intf->p_sys->b_audio_update = VLC_FALSE;
\r
396 /* sub picture menus */
\r
397 if( p_intf->p_sys->b_spu_update )
\r
399 LanguageMenu( PopupSubtitles, p_spu_es, SPU_ES, PopupSubtitleClick );
\r
400 LanguageMenu( MenuSubtitles, p_spu_es, SPU_ES, MenuSubtitleClick );
\r
402 p_intf->p_sys->b_spu_update = VLC_FALSE;
\r
405 if( p_intf->p_sys->b_aout_update )
\r
407 aout_instance_t * p_aout;
\r
408 p_aout = (aout_instance_t *)vlc_object_find( p_intf, VLC_OBJECT_AOUT,
\r
411 if( p_aout != NULL )
\r
414 val.b_bool = VLC_FALSE;
\r
416 var_Set( (vlc_object_t *)p_aout, "intf-change", val );
\r
418 #error fixme! look at rc.c line 823
\r
419 SetupVarMenu( (vlc_object_t *)p_aout, "audio-channels",
\r
420 MenuChannel, AoutVarClick );
\r
421 SetupVarMenu( (vlc_object_t *)p_aout, "audio-channels",
\r
422 PopupChannel, AoutVarClick );
\r
424 SetupVarMenu( (vlc_object_t *)p_aout, "audio-device",
\r
425 MenuADevice, AoutVarClick );
\r
426 SetupVarMenu( (vlc_object_t *)p_aout, "audio-device",
\r
427 PopupADevice, AoutVarClick );
\r
429 vlc_object_release( (vlc_object_t *)p_aout );
\r
432 p_intf->p_sys->b_aout_update = VLC_FALSE;
\r
435 if( p_intf->p_sys->b_vout_update )
\r
437 vout_thread_t * p_vout;
\r
438 p_vout = (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
\r
441 if( p_vout != NULL )
\r
444 val.b_bool = VLC_FALSE;
\r
446 var_Set( (vlc_object_t *)p_vout, "intf-change", val );
\r
448 SetupVarMenu( (vlc_object_t *)p_vout, "video-device",
\r
449 MenuVDevice, VoutVarClick );
\r
450 SetupVarMenu( (vlc_object_t *)p_vout, "video-device",
\r
451 PopupVDevice, VoutVarClick );
\r
453 vlc_object_release( (vlc_object_t *)p_vout );
\r
456 p_intf->p_sys->b_vout_update = VLC_FALSE;
\r
459 vlc_mutex_lock( &p_input->stream.stream_lock );
\r
463 /*****************************************************************************
\r
464 * Private functions
\r
465 *****************************************************************************/
\r
466 TMenuItem * TMenusGen::Index2Item( TMenuItem *Root, int i_index,
\r
467 bool SingleColumn )
\r
469 if( SingleColumn || ( i_index < 20 ) )
\r
470 return Root->Items[i_index];
\r
472 return Root->Items[i_index / 10]->Items[i_index % 10];
\r
475 int TMenusGen::Item2Index( TMenuItem *Root, TMenuItem *Item )
\r
477 if( Item->Parent == Root )
\r
478 return Item->MenuIndex;
\r
480 return( 10 * Item->Parent->MenuIndex + Item->MenuIndex );
\r
483 int __fastcall TMenusGen::Data2Title( int data )
\r
485 return (int) (data >> 16 );
\r
488 int __fastcall TMenusGen::Data2Chapter( int data )
\r
490 return (int) (data & 0xffff);
\r
493 int __fastcall TMenusGen::Pos2Data( int title, int chapter )
\r
495 return (int) (( title << 16 ) | ( chapter & 0xffff ));
\r
498 /* This function deletes all the '&' characters in the caption string,
\r
499 * because Borland automatically adds one when (and only when!) you click on
\r
500 * the menuitem. Grrrrr... */
\r
501 AnsiString __fastcall TMenusGen::CleanCaption( AnsiString Caption )
\r
503 while( Caption.LastDelimiter( "&" ) != 0 )
\r
505 Caption.Delete( Caption.LastDelimiter( "&" ), 1 );
\r
511 /****************************************************************************
\r
512 * VarChange: change a variable in a vlc_object_t
\r
513 ****************************************************************************
\r
514 * Change the variable and update the menuitems.
\r
515 ****************************************************************************/
\r
516 void __fastcall TMenusGen::VarChange( vlc_object_t *p_object,
\r
517 const char *psz_variable, TMenuItem *RootMenu, TMenuItem *RootPopup,
\r
523 AnsiString Caption = CleanCaption( Item->Caption );
\r
524 val.psz_string = Caption.c_str();
\r
526 /* set the new value */
\r
527 if( var_Set( p_object, psz_variable, val ) < 0 )
\r
529 msg_Warn( p_object, "cannot set variable (%s)", val.psz_string );
\r
532 i_index = Item->MenuIndex;
\r
533 RootMenu->Items[i_index]->Checked = true;
\r
534 RootPopup->Items[i_index]->Checked = true;
\r
537 /****************************************************************************
\r
538 * LangChange: change audio or subtitles languages
\r
539 ****************************************************************************
\r
540 * Toggle the language, and update the selected menuitems.
\r
541 ****************************************************************************/
\r
542 void __fastcall TMenusGen::LangChange( TMenuItem *RootCurrent, TMenuItem *Item,
\r
543 TMenuItem *RootOther, int i_cat )
\r
545 es_descriptor_t * p_es;
\r
546 es_descriptor_t * p_es_old;
\r
550 /* find the selected ES */
\r
553 /* find selected menu item */
\r
554 i_index = Item2Index( RootCurrent, Item ) - 1;
\r
557 /* 'None' was selected */
\r
562 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
\r
563 p_es = p_intf->p_sys->p_input->stream.pp_es[i_es];
\r
564 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
\r
567 /* find the current ES */
\r
568 if( i_cat == AUDIO_ES )
\r
570 p_es_old = this->p_audio_es_old;
\r
571 this->p_audio_es_old = p_es;
\r
575 p_es_old = this->p_spu_es_old;
\r
576 this->p_spu_es_old = p_es;
\r
579 /* exchange them */
\r
580 input_ToggleES( p_intf->p_sys->p_input, p_es_old, false );
\r
581 input_ToggleES( p_intf->p_sys->p_input, p_es, true );
\r
583 Item->Checked = true;
\r
584 Index2Item( RootOther, i_index + 1, true )->Checked = true;
\r
587 /****************************************************************************
\r
588 * ProgramChange: change the program
\r
589 ****************************************************************************
\r
590 * Toggle the program, and update the selected menuitems.
\r
591 ****************************************************************************/
\r
592 void __fastcall TMenusGen::ProgramChange( TMenuItem *Item,
\r
593 TMenuItem *RootOther )
\r
595 int i_program = Item->Tag;
\r
597 /* toggle the program */
\r
598 input_ChangeProgram( p_intf->p_sys->p_input, (uint16_t)i_program );
\r
600 /* check selected menu items */
\r
601 Item->Checked = true;
\r
602 Index2Item( RootOther, i_program - 1, true )->Checked = true;
\r
604 /* update audio/subtitles menus */
\r
605 p_intf->p_sys->b_audio_update = VLC_TRUE;
\r
606 p_intf->p_sys->b_spu_update = VLC_TRUE;
\r
607 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
\r
609 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
\r
610 p_intf->p_sys->b_audio_update = VLC_FALSE;
\r
611 p_intf->p_sys->b_spu_update = VLC_FALSE;
\r
613 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
\r
616 /*****************************************************************************
\r
617 * SetupVarMenu: build a menu allowing to change a variable
\r
618 *****************************************************************************/
\r
619 void __fastcall TMenusGen::SetupVarMenu( vlc_object_t *p_object,
\r
620 const char *psz_variable, TMenuItem *Root, TNotifyEvent MenuItemClick )
\r
624 char * psz_value = NULL;
\r
627 /* remove previous menu */
\r
630 /* get the current value */
\r
631 if( var_Get( p_object, psz_variable, &val ) < 0 )
\r
635 psz_value = val.psz_string;
\r
637 if( var_Change( p_object, psz_variable, VLC_VAR_GETLIST, &val, NULL ) < 0 )
\r
643 /* append a menuitem for each option */
\r
644 for( i = 0; i < val.p_list->i_count; i++ )
\r
646 Item = new TMenuItem( Root );
\r
647 Item->Caption = val.p_list->p_values[i].psz_string;
\r
648 Item->Hint = val.p_list->p_values[i].psz_string;
\r
649 Item->RadioItem = true;
\r
650 Item->OnClick = MenuItemClick;
\r
651 if( !strcmp( psz_value, val.p_list->p_values[i].psz_string ) )
\r
652 Item->Checked = true;
\r
654 /* Add the item to the submenu */
\r
658 /* enable the menu if there is at least 1 item */
\r
659 Root->Enabled = ( val.p_list->i_count > 0 );
\r
661 /* clean up everything */
\r
662 var_Change( p_object, psz_variable, VLC_VAR_FREELIST, &val, NULL );
\r
663 // free( psz_value );
\r
666 /*****************************************************************************
\r
667 * SetupModuleMenu: build a menu listing all the modules of a given
\r
669 *****************************************************************************/
\r
670 void __fastcall TMenusGen::SetupModuleMenu( const char *psz_capability,
\r
671 TMenuItem *Root, TNotifyEvent MenuItemClick )
\r
673 module_t * p_parser;
\r
674 vlc_list_t *p_list;
\r
677 /* remove previous menu */
\r
679 Root->Enabled = false;
\r
681 p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
\r
682 for( i_index = 0; i_index < p_list->i_count; i_index++ )
\r
684 p_parser = (module_t *)p_list->p_values[i_index].p_object ;
\r
686 if( !strcmp( p_parser->psz_capability, psz_capability ) )
\r
688 TMenuItem *Item = new TMenuItem( Root );
\r
689 Item->Caption = p_parser->psz_object_name;
\r
690 Item->Hint = Item->Caption;
\r
691 Item->OnClick = MenuItemClick;
\r
696 vlc_list_release( p_list );
\r
698 /* be sure that menu is enabled, if there is at least one item */
\r
700 Root->Enabled = true;
\r
703 /*****************************************************************************
\r
704 * ProgramMenu: update the programs menu of the interface
\r
705 *****************************************************************************
\r
706 * Builds the program menu according to what have been found in the PAT
\r
707 * by the input. Useful for multi-programs streams such as DVB ones.
\r
708 *****************************************************************************/
\r
709 void __fastcall TMenusGen::ProgramMenu( TMenuItem *Root,
\r
710 pgrm_descriptor_t *p_pgrm, TNotifyEvent MenuItemClick )
\r
714 /* remove previous menu */
\r
716 Root->Enabled = false;
\r
718 /* create a set of program buttons and append them to the container */
\r
719 for( unsigned int i = 0; i < p_intf->p_sys->p_input->stream.i_pgrm_number;
\r
723 Name.sprintf( "id %d",
\r
724 p_intf->p_sys->p_input->stream.pp_programs[i]->i_number );
\r
726 Item = new TMenuItem( Root );
\r
727 Item->Caption = Name;
\r
729 Item->RadioItem = true;
\r
730 Item->OnClick = MenuItemClick;
\r
732 /* FIXME: temporary hack to save the program id with the Item
\r
733 * It will be used in the callback. */
\r
736 /* check the currently selected program */
\r
737 if( p_pgrm == p_intf->p_sys->p_input->stream.pp_programs[i] )
\r
738 Item->Checked = true;
\r
740 /* add the item to the submenu */
\r
744 /* be sure that menu is enabled if more than 1 program */
\r
745 if( p_intf->p_sys->p_input->stream.i_pgrm_number > 1 )
\r
746 Root->Enabled = true;
\r
749 /*****************************************************************************
\r
750 * RadioMenu: update interactive menus of the interface
\r
751 *****************************************************************************
\r
752 * Sets up menus with information from input
\r
753 * Warning: since this function is designed to be called by management
\r
754 * function, the interface lock has to be taken
\r
755 *****************************************************************************/
\r
756 void __fastcall TMenusGen::RadioMenu( TMenuItem *Root, AnsiString ItemName,
\r
757 int i_nb, int i_selected, TNotifyEvent MenuItemClick )
\r
759 TMenuItem * ItemGroup;
\r
763 /* remove previous menu */
\r
764 Root->Enabled = false;
\r
767 for( int i_item = 1; i_item <= i_nb; i_item++ )
\r
769 /* we group titles/chapters in packets of ten for small screens */
\r
770 if( ( i_item % 10 == 1 ) && ( i_nb > 20 ) )
\r
773 Root->Add( ItemGroup );
\r
775 Name.sprintf( "%ss %d to %d", ItemName, i_item, i_item + 9 );
\r
776 ItemGroup = new TMenuItem( Root );
\r
777 ItemGroup->Hint = Name;
\r
778 ItemGroup->RadioItem = true;
\r
780 /* set the accelerator character */
\r
781 Name.Insert( "&", Name.Length() - 1 );
\r
782 ItemGroup->Caption = Name;
\r
785 Name.sprintf( "%s %d", ItemName, i_item );
\r
786 Item = new TMenuItem( Root );
\r
787 Item->RadioItem = true;
\r
790 /* set the accelerator character */
\r
791 Name.Insert( "&", Name.Length() );
\r
792 Item->Caption = Name;
\r
794 /* FIXME: temporary hack to save i_item with the Item
\r
795 * It will be used in the callback. */
\r
796 Item->Tag = i_item;
\r
798 /* check the currently selected chapter */
\r
799 if( i_selected == i_item )
\r
800 Item->Checked = true;
\r
802 /* setup signal handling */
\r
803 Item->OnClick = MenuItemClick;
\r
806 ItemGroup->Add( Item );
\r
811 // if( ( i_nb > 20 ) && ( i_item % 10 ) ) ?
\r
813 Root->Add( ItemGroup );
\r
815 /* be sure that menu is enabled, if there are several items */
\r
817 Root->Enabled = true;
\r
820 /*****************************************************************************
\r
821 * LanguageMenus: update interactive menus of the interface
\r
822 *****************************************************************************
\r
823 * Sets up menus with information from input:
\r
826 * Warning: since this function is designed to be called by management
\r
827 * function, the interface lock has to be taken
\r
828 *****************************************************************************/
\r
829 void __fastcall TMenusGen::LanguageMenu( TMenuItem *Root, es_descriptor_t *p_es,
\r
830 int i_cat, TNotifyEvent MenuItemClick )
\r
832 TMenuItem * Separator;
\r
836 /* remove previous menu */
\r
838 Root->Enabled = false;
\r
840 /* special case for "off" item */
\r
842 Item = new TMenuItem( Root );
\r
843 Item->RadioItem = true;
\r
845 Item->Caption = Name;
\r
846 Item->OnClick = MenuItemClick;
\r
850 /* separator item */
\r
851 Separator = new TMenuItem( Root );
\r
852 Separator->Caption = "-";
\r
853 Root->Add( Separator );
\r
857 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
\r
859 #define ES p_intf->p_sys->p_input->stream.pp_es[i]
\r
860 /* create a set of language buttons and append them to the Root */
\r
861 for( unsigned int i = 0; i < p_intf->p_sys->p_input->stream.i_es_number;
\r
864 if( ( ES->i_cat == i_cat ) &&
\r
867 p_intf->p_sys->p_input->stream.p_selected_program ) )
\r
870 if( p_intf->p_sys->p_input->stream.pp_es[i]->psz_desc )
\r
871 Name = p_intf->p_sys->p_input->stream.pp_es[i]->psz_desc;
\r
872 if( Name.IsEmpty() )
\r
873 Name.sprintf( "Language %d", i_item );
\r
875 Item = new TMenuItem( Root );
\r
876 Item->RadioItem = true;
\r
878 Item->Caption = Name;
\r
881 /* check the currently selected item */
\r
882 if( p_es == p_intf->p_sys->p_input->stream.pp_es[i] )
\r
883 Item->Checked = true;
\r
885 /* setup signal hanling */
\r
886 Item->OnClick = MenuItemClick;
\r
892 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
\r
894 /* be sure that menu is enabled if non empty */
\r
896 Root->Enabled = true;
\r
899 /*****************************************************************************
\r
900 * NavigationMenu: sets menus for titles and chapters selection
\r
901 *****************************************************************************
\r
902 * Generates two types of menus:
\r
903 * -simple list of titles
\r
904 * -cascaded lists of chapters for each title
\r
905 *****************************************************************************/
\r
906 void __fastcall TMenusGen::NavigationMenu( TMenuItem *Root,
\r
907 TNotifyEvent MenuItemClick )
\r
909 TMenuItem * TitleGroup;
\r
910 TMenuItem * TitleItem;
\r
911 TMenuItem * ChapterGroup;
\r
912 TMenuItem * ChapterItem;
\r
914 unsigned int i_title_nb;
\r
915 unsigned int i_chapter_nb;
\r
918 /* remove previous menu */
\r
919 Root->Enabled = false;
\r
922 i_title_nb = p_intf->p_sys->p_input->stream.i_area_nb - 1;
\r
924 /* loop on titles */
\r
925 for( unsigned int i_title = 1; i_title <= i_title_nb; i_title++ )
\r
927 /* we group titles in packets of ten for small screens */
\r
928 if( ( i_title % 10 == 1 ) && ( i_title_nb > 20 ) )
\r
931 Root->Add( TitleGroup );
\r
933 Name.sprintf( "%d - %d", i_title, i_title + 9 );
\r
934 TitleGroup = new TMenuItem( Root );
\r
935 TitleGroup->RadioItem = true;
\r
936 TitleGroup->Hint = Name;
\r
937 TitleGroup->Caption = Name;
\r
940 Name.sprintf( "Title %d (%d)", i_title,
\r
941 p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb - 1 );
\r
943 TitleItem = new TMenuItem( Root );
\r
944 TitleItem->RadioItem = true;
\r
945 TitleItem->Hint = Name;
\r
946 TitleItem->Caption = Name;
\r
949 p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb - 1;
\r
951 /* loop on chapters */
\r
952 for( unsigned int i_chapter = 1; i_chapter <= i_chapter_nb;
\r
955 /* we group chapters in packets of ten for small screens */
\r
956 if( ( i_chapter % 10 == 1 ) && ( i_chapter_nb > 20 ) )
\r
958 if( i_chapter != 1 )
\r
959 TitleItem->Add( ChapterGroup );
\r
961 Name.sprintf( "%d - %d", i_chapter, i_chapter + 9 );
\r
962 ChapterGroup = new TMenuItem( TitleItem );
\r
963 ChapterGroup->RadioItem = true;
\r
964 ChapterGroup->Hint = Name;
\r
965 ChapterGroup->Caption = Name;
\r
968 Name.sprintf( "Chapter %d", i_chapter );
\r
970 ChapterItem = new TMenuItem( TitleItem );
\r
971 ChapterItem->RadioItem = true;
\r
972 ChapterItem->Hint = Name;
\r
973 ChapterItem->Caption = Name;
\r
975 /* FIXME: temporary hack to save i_title and i_chapter with
\r
976 * ChapterItem, since we will need them in the callback */
\r
977 ChapterItem->Tag = Pos2Data( i_title, i_chapter );
\r
979 #define p_area p_intf->p_sys->p_input->stream.pp_areas[i_title]
\r
980 /* check the currently selected chapter */
\r
982 p_intf->p_sys->p_input->stream.p_selected_area ) &&
\r
983 ( p_area->i_part == i_chapter ) )
\r
985 ChapterItem->Checked = true;
\r
989 /* setup signal handling */
\r
990 ChapterItem->OnClick = MenuItemClick;
\r
992 if( i_chapter_nb > 20 )
\r
993 ChapterGroup->Add( ChapterItem );
\r
995 TitleItem->Add( ChapterItem );
\r
998 if( i_chapter_nb > 20 )
\r
1000 TitleItem->Add( ChapterGroup );
\r
1003 if( p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb
\r
1006 /* be sure that menu is sensitive */
\r
1007 Root->Enabled = true;
\r
1011 if( i_title_nb > 20 )
\r
1012 TitleGroup->Add( TitleItem );
\r
1014 Root->Add( TitleItem );
\r
1017 if( i_title_nb > 20 )
\r
1018 Root->Add( TitleGroup );
\r
1020 /* be sure that menu is sensitive */
\r
1021 Root->Enabled = true;
\r