1 /*****************************************************************************
2 * menu.cpp: functions to handle menu items
3 *****************************************************************************
4 * Copyright (C) 2002-2003 VideoLAN
5 * $Id: menu.cpp,v 1.9 2003/01/24 12:01:03 sam Exp $
7 * Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
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.
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.
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 *****************************************************************************/
30 #include "win32_common.h"
32 /*****************************************************************************
33 * TMenusGen::*Click: callbacks for the menuitems
34 ****************************************************************************/
40 /* variables of the audio output */
41 void __fastcall TMenusGen::AoutVarClick( TObject *Sender )
43 TMenuItem * Item = (TMenuItem *)Sender;
45 vlc_object_t * p_aout;
46 p_aout = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_AOUT,
50 msg_Warn( p_intf, "cannot set variable (%s)", Item->Caption.c_str() );
54 if( Item->Parent == MenuADevice || Item->Parent == PopupADevice )
56 VarChange( p_aout, "audio-device", MenuADevice, PopupADevice, Item );
58 else if( Item->Parent == MenuChannel || Item->Parent == PopupChannel )
60 VarChange( p_aout, "audio-channels", MenuChannel, PopupChannel, Item );
63 vlc_object_release( p_aout );
66 /* variables of the video output */
67 void __fastcall TMenusGen::VoutVarClick( TObject *Sender )
69 TMenuItem * Item = (TMenuItem *)Sender;
71 vlc_object_t * p_vout;
72 p_vout = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
76 msg_Warn( p_intf, "cannot set variable (%s)", Item->Caption.c_str() );
80 if( Item->Parent == MenuVDevice || Item->Parent == PopupVDevice )
82 VarChange( p_vout, "video-device", MenuVDevice, PopupVDevice, Item );
85 vlc_object_release( p_vout );
92 /* Interface modules: we spawn a new interface */
\r
93 void __fastcall TMenusGen::InterfaceModuleClick( TObject *Sender )
\r
95 TMenuItem * Item = (TMenuItem *)Sender;
\r
97 AnsiString IntfName = CleanCaption( Item->Caption );
\r
99 intf_thread_t *p_newintf;
\r
100 char *psz_oldmodule = config_GetPsz( p_intf->p_vlc, "intf" );
\r
102 config_PutPsz( p_intf->p_vlc, "intf", IntfName.c_str() );
\r
103 p_newintf = intf_Create( p_intf->p_vlc );
\r
104 config_PutPsz( p_intf->p_vlc, "intf", psz_oldmodule );
\r
106 if( psz_oldmodule )
\r
108 free( psz_oldmodule );
\r
113 p_newintf->b_block = VLC_FALSE;
\r
114 if( intf_RunThread( p_newintf ) )
\r
116 vlc_object_detach( p_newintf );
\r
117 intf_Destroy( p_newintf );
\r
126 void __fastcall TMenusGen::MenuLanguageClick( TObject *Sender )
128 LangChange( MenuLanguage, (TMenuItem *)Sender, PopupLanguage, AUDIO_ES );
131 void __fastcall TMenusGen::PopupLanguageClick( TObject *Sender )
133 LangChange( PopupLanguage, (TMenuItem *)Sender, MenuLanguage, AUDIO_ES );
140 void __fastcall TMenusGen::MenuSubtitleClick( TObject *Sender )
142 LangChange( MenuSubtitles, (TMenuItem *)Sender, PopupSubtitles, SPU_ES );
145 void __fastcall TMenusGen::PopupSubtitleClick( TObject *Sender )
147 LangChange( PopupSubtitles, (TMenuItem *)Sender, MenuSubtitles, SPU_ES );
154 void __fastcall TMenusGen::MenuProgramClick( TObject *Sender )
156 ProgramChange( (TMenuItem *)Sender, PopupProgram );
159 void __fastcall TMenusGen::PopupProgramClick( TObject *Sender )
161 ProgramChange( (TMenuItem *)Sender, MenuProgram );
168 void __fastcall TMenusGen::MenuTitleClick( TObject *Sender )
170 TMenuItem * Item = (TMenuItem *)Sender;
171 TMenuItem * ItemTitle;
172 input_area_t * p_area;
173 unsigned int i_title = Item->Tag;
175 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
176 i_title = __MIN( i_title,
177 p_intf->p_sys->p_input->stream.i_area_nb - 1 );
178 i_title = __MAX( i_title, 1 );
179 p_area = p_intf->p_sys->p_input->stream.pp_areas[i_title];
180 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
182 input_ChangeArea( p_intf->p_sys->p_input, p_area );
184 Item->Checked = true;
185 ItemTitle = Index2Item( PopupNavigation, i_title - 1, false );
186 Index2Item( ItemTitle, 0, false )->Checked = true;
188 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
195 void __fastcall TMenusGen::MenuChapterClick( TObject *Sender )
197 TMenuItem * Item = (TMenuItem *)Sender;
198 TMenuItem * ItemTitle;
199 input_area_t * p_area;
200 unsigned int i_title;
201 unsigned int i_chapter = Item->Tag;
203 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
204 p_area = p_intf->p_sys->p_input->stream.p_selected_area;
205 i_chapter = __MIN( i_chapter, p_area->i_part_nb - 1 );
206 i_chapter = __MAX( i_chapter, 1 );
207 p_area->i_part = i_chapter;
208 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
210 input_ChangeArea( p_intf->p_sys->p_input, p_area );
212 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
213 i_title = p_intf->p_sys->p_input->stream.p_selected_area->i_id;
214 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
216 ItemTitle = Index2Item( PopupNavigation, i_title, false );
217 Index2Item( ItemTitle, i_chapter, false )->Checked = true;
219 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
226 void __fastcall TMenusGen::PopupNavigationClick( TObject *Sender )
228 TMenuItem * Item = (TMenuItem *)Sender;
229 TMenuItem * ItemTitle;
230 input_area_t * p_area;
231 unsigned int i_title = Data2Title( Item->Tag );
232 unsigned int i_chapter = Data2Chapter( Item->Tag );
234 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
235 i_title = __MIN( i_title,
236 p_intf->p_sys->p_input->stream.i_area_nb - 1 );
237 i_title = __MAX( i_title, 1 );
238 p_area = p_intf->p_sys->p_input->stream.pp_areas[i_title];
239 i_chapter = __MIN( i_chapter, p_area->i_part_nb - 1 );
240 i_chapter = __MAX( i_chapter, 1 );
241 p_area->i_part = i_chapter;
242 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
244 input_ChangeArea( p_intf->p_sys->p_input, p_area );
246 Item->Checked = true;
247 ItemTitle = Index2Item( MenuTitle, i_title, false );
248 if( ItemTitle->Checked )
250 /* same title, new chapter */
251 Index2Item( MenuChapter, i_chapter, false )->Checked = true;
255 /* new title => we must rebuild the chapter menu */
256 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
258 MenuChapter, "Chapter",
259 p_intf->p_sys->p_input->stream.p_selected_area->i_part_nb,
260 i_chapter, MenuChapterClick );
261 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
264 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
268 __fastcall TMenusGen::TMenusGen( intf_thread_t *_p_intf ) : TObject()
272 /* Initialize local pointers to menu items of the main window */
273 TMainFrameDlg * p_window = p_intf->p_sys->p_window;
274 if( p_window == NULL )
276 msg_Warn( p_intf, "Main window wasn't created, expect problems..." );
280 MenuChannel = p_window->MenuChannel;
281 PopupChannel = p_window->PopupChannel;
282 MenuADevice = p_window->MenuADevice;
283 PopupADevice = p_window->PopupADevice;
284 MenuVDevice = p_window->MenuVDevice;
285 PopupVDevice = p_window->PopupVDevice;
286 MenuLanguage = p_window->MenuLanguage;
287 PopupLanguage = p_window->PopupLanguage;
288 MenuSubtitles = p_window->MenuSubtitles;
289 PopupSubtitles = p_window->PopupSubtitles;
290 MenuProgram = p_window->MenuProgram;
291 PopupProgram = p_window->PopupProgram;
292 MenuTitle = p_window->MenuTitle;
293 MenuChapter = p_window->MenuChapter;
294 PopupNavigation = p_window->PopupNavigation;
295 MenuAddInterface = p_window->MenuAddInterface;
297 /* Create the "Add interface" menu */
299 SetupModuleMenu( "inerface", MenuAddInterface, InterfaceModuleClick );
304 /*****************************************************************************
305 * SetupMenus: This function dynamically generates some menus
306 *****************************************************************************
307 * The lock on p_input->stream must be taken before you call this function
308 *****************************************************************************/
309 void __fastcall TMenusGen::SetupMenus()
311 TMainFrameDlg * p_window = p_intf->p_sys->p_window;
312 input_thread_t * p_input = p_intf->p_sys->p_input;
313 es_descriptor_t * p_audio_es;
314 es_descriptor_t * p_spu_es;
316 p_intf->p_sys->b_chapter_update |= p_intf->p_sys->b_title_update;
317 p_intf->p_sys->b_audio_update |= p_intf->p_sys->b_program_update |
318 p_intf->p_sys->b_title_update;
319 p_intf->p_sys->b_spu_update |= p_intf->p_sys->b_program_update |
320 p_intf->p_sys->b_title_update;
322 if( p_intf->p_sys->b_program_update )
324 pgrm_descriptor_t * p_pgrm;
326 if( p_input->stream.p_new_program )
328 p_pgrm = p_input->stream.p_new_program;
332 p_pgrm = p_input->stream.p_selected_program;
335 ProgramMenu( MenuProgram, p_pgrm, MenuProgramClick );
336 ProgramMenu( PopupProgram, p_pgrm, PopupProgramClick );
338 p_intf->p_sys->b_program_update = VLC_FALSE;
341 if( p_intf->p_sys->b_title_update )
344 // because if the titles go from 1 to X-1, there are X-1 titles
345 RadioMenu( MenuTitle, "Title",
346 p_input->stream.i_area_nb - 1,
347 p_input->stream.p_selected_area->i_id,
350 AnsiString CurrentTitle;
351 CurrentTitle.sprintf( "%d", p_input->stream.p_selected_area->i_id );
352 p_window->LabelTitleCurrent->Caption = CurrentTitle;
354 p_intf->p_sys->b_title_update = VLC_FALSE;
357 if( p_intf->p_sys->b_chapter_update )
359 RadioMenu( MenuChapter, "Chapter",
360 p_input->stream.p_selected_area->i_part_nb - 1,
361 p_input->stream.p_selected_area->i_part,
364 NavigationMenu( PopupNavigation, PopupNavigationClick );
366 AnsiString CurrentChapter;
367 CurrentChapter.sprintf( "%d", p_input->stream.p_selected_area->i_part );
368 p_window->LabelChapterCurrent->Caption = CurrentChapter;
370 p_intf->p_sys->i_part = p_input->stream.p_selected_area->i_part;
372 p_intf->p_sys->b_chapter_update = VLC_FALSE;
375 /* look for selected ES */
379 for( unsigned int i = 0; i < p_input->stream.i_selected_es_number; i++ )
381 if( p_input->stream.pp_selected_es[i]->i_cat == AUDIO_ES )
383 p_audio_es = p_input->stream.pp_selected_es[i];
386 if( p_input->stream.pp_selected_es[i]->i_cat == SPU_ES )
388 p_spu_es = p_input->stream.pp_selected_es[i];
391 this->p_audio_es_old = p_audio_es;
392 this->p_spu_es_old = p_spu_es;
394 vlc_mutex_unlock( &p_input->stream.stream_lock );
397 if( p_intf->p_sys->b_audio_update )
399 LanguageMenu( MenuLanguage, p_audio_es, AUDIO_ES, MenuLanguageClick );
400 LanguageMenu( PopupLanguage, p_audio_es, AUDIO_ES, PopupLanguageClick );
402 p_intf->p_sys->b_audio_update = VLC_FALSE;
405 /* sub picture menus */
406 if( p_intf->p_sys->b_spu_update )
408 LanguageMenu( PopupSubtitles, p_spu_es, SPU_ES, PopupSubtitleClick );
409 LanguageMenu( MenuSubtitles, p_spu_es, SPU_ES, MenuSubtitleClick );
411 p_intf->p_sys->b_spu_update = VLC_FALSE;
414 if( p_intf->p_sys->b_aout_update )
416 aout_instance_t * p_aout;
417 p_aout = (aout_instance_t *)vlc_object_find( p_intf, VLC_OBJECT_AOUT,
423 val.b_bool = VLC_FALSE;
425 var_Set( (vlc_object_t *)p_aout, "intf-change", val );
427 SetupVarMenu( (vlc_object_t *)p_aout, "audio-channels",
428 MenuChannel, AoutVarClick );
429 SetupVarMenu( (vlc_object_t *)p_aout, "audio-channels",
430 PopupChannel, AoutVarClick );
432 SetupVarMenu( (vlc_object_t *)p_aout, "audio-device",
433 MenuADevice, AoutVarClick );
434 SetupVarMenu( (vlc_object_t *)p_aout, "audio-device",
435 PopupADevice, AoutVarClick );
437 vlc_object_release( (vlc_object_t *)p_aout );
440 p_intf->p_sys->b_aout_update = VLC_FALSE;
443 if( p_intf->p_sys->b_vout_update )
445 vout_thread_t * p_vout;
446 p_vout = (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
452 val.b_bool = VLC_FALSE;
454 var_Set( (vlc_object_t *)p_vout, "intf-change", val );
456 SetupVarMenu( (vlc_object_t *)p_vout, "video-device",
457 MenuVDevice, VoutVarClick );
458 SetupVarMenu( (vlc_object_t *)p_vout, "video-device",
459 PopupVDevice, VoutVarClick );
461 vlc_object_release( (vlc_object_t *)p_vout );
464 p_intf->p_sys->b_vout_update = VLC_FALSE;
467 vlc_mutex_lock( &p_input->stream.stream_lock );
471 /*****************************************************************************
473 *****************************************************************************/
474 TMenuItem * TMenusGen::Index2Item( TMenuItem *Root, int i_index,
477 if( SingleColumn || ( i_index < 20 ) )
478 return Root->Items[i_index];
480 return Root->Items[i_index / 10]->Items[i_index % 10];
483 int TMenusGen::Item2Index( TMenuItem *Root, TMenuItem *Item )
485 if( Item->Parent == Root )
486 return Item->MenuIndex;
488 return( 10 * Item->Parent->MenuIndex + Item->MenuIndex );
491 int __fastcall TMenusGen::Data2Title( int data )
493 return (int) (data >> 16 );
496 int __fastcall TMenusGen::Data2Chapter( int data )
498 return (int) (data & 0xffff);
501 int __fastcall TMenusGen::Pos2Data( int title, int chapter )
503 return (int) (( title << 16 ) | ( chapter & 0xffff ));
506 /* This function deletes all the '&' characters in the caption string,
507 * because Borland automatically adds one when (and only when!) you click on
\r
508 * the menuitem. Grrrrr... */
\r
509 AnsiString __fastcall TMenusGen::CleanCaption( AnsiString Caption )
\r
511 while( Caption.LastDelimiter( "&" ) != 0 )
\r
513 Caption.Delete( Caption.LastDelimiter( "&" ), 1 );
\r
519 /****************************************************************************
520 * VarChange: change a variable in a vlc_object_t
521 ****************************************************************************
522 * Change the variable and update the menuitems.
523 ****************************************************************************/
524 void __fastcall TMenusGen::VarChange( vlc_object_t *p_object,
525 const char *psz_variable, TMenuItem *RootMenu, TMenuItem *RootPopup,
531 AnsiString Caption = CleanCaption( Item->Caption );
532 val.psz_string = Caption.c_str();
534 /* set the new value */
535 if( var_Set( p_object, psz_variable, val ) < 0 )
537 msg_Warn( p_object, "cannot set variable (%s)", val.psz_string );
540 i_index = Item->MenuIndex;
541 RootMenu->Items[i_index]->Checked = true;
542 RootPopup->Items[i_index]->Checked = true;
545 /****************************************************************************
546 * LangChange: change audio or subtitles languages
547 ****************************************************************************
548 * Toggle the language, and update the selected menuitems.
549 ****************************************************************************/
550 void __fastcall TMenusGen::LangChange( TMenuItem *RootCurrent, TMenuItem *Item,
551 TMenuItem *RootOther, int i_cat )
553 es_descriptor_t * p_es;
554 es_descriptor_t * p_es_old;
558 /* find the selected ES */
561 /* find selected menu item */
562 i_index = Item2Index( RootCurrent, Item ) - 1;
565 /* 'None' was selected */
570 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
571 p_es = p_intf->p_sys->p_input->stream.pp_es[i_es];
572 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
575 /* find the current ES */
576 if( i_cat == AUDIO_ES )
578 p_es_old = this->p_audio_es_old;
579 this->p_audio_es_old = p_es;
583 p_es_old = this->p_spu_es_old;
584 this->p_spu_es_old = p_es;
588 input_ToggleES( p_intf->p_sys->p_input, p_es_old, false );
589 input_ToggleES( p_intf->p_sys->p_input, p_es, true );
591 Item->Checked = true;
592 Index2Item( RootOther, i_index + 1, true )->Checked = true;
595 /****************************************************************************
596 * ProgramChange: change the program
597 ****************************************************************************
598 * Toggle the program, and update the selected menuitems.
599 ****************************************************************************/
600 void __fastcall TMenusGen::ProgramChange( TMenuItem *Item,
601 TMenuItem *RootOther )
603 int i_program = Item->Tag;
605 /* toggle the program */
606 input_ChangeProgram( p_intf->p_sys->p_input, (uint16_t)i_program );
608 /* check selected menu items */
609 Item->Checked = true;
610 Index2Item( RootOther, i_program - 1, true )->Checked = true;
612 /* update audio/subtitles menus */
613 p_intf->p_sys->b_audio_update = VLC_TRUE;
614 p_intf->p_sys->b_spu_update = VLC_TRUE;
615 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
617 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
618 p_intf->p_sys->b_audio_update = VLC_FALSE;
619 p_intf->p_sys->b_spu_update = VLC_FALSE;
621 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
624 /*****************************************************************************
625 * SetupVarMenu: build a menu allowing to change a variable
626 *****************************************************************************/
627 void __fastcall TMenusGen::SetupVarMenu( vlc_object_t *p_object,
628 const char *psz_variable, TMenuItem *Root, TNotifyEvent MenuItemClick )
632 char * psz_value = NULL;
635 /* remove previous menu */
638 /* get the current value */
639 if( var_Get( p_object, psz_variable, &val ) < 0 )
643 psz_value = val.psz_string;
645 if( var_Change( p_object, psz_variable, VLC_VAR_GETLIST, &val ) < 0 )
651 /* append a menuitem for each option */
652 for( i = 0; i < val.p_list->i_count; i++ )
654 Item = new TMenuItem( Root );
655 Item->Caption = val.p_list->p_values[i].psz_string;
656 Item->Hint = val.p_list->p_values[i].psz_string;
657 Item->RadioItem = true;
658 Item->OnClick = MenuItemClick;
659 if( !strcmp( psz_value, val.p_list->p_values[i].psz_string ) )
660 Item->Checked = true;
662 /* Add the item to the submenu */
666 /* enable the menu if there is at least 1 item */
667 Root->Enabled = ( val.p_list->i_count > 0 );
669 /* clean up everything */
670 var_Change( p_object, psz_variable, VLC_VAR_FREELIST, &val );
671 // free( psz_value );
674 /*****************************************************************************
675 * SetupModuleMenu: build a menu listing all the modules of a given
677 *****************************************************************************/
678 void __fastcall TMenusGen::SetupModuleMenu( const char *psz_capability,
679 TMenuItem *Root, TNotifyEvent MenuItemClick )
685 /* remove previous menu */
\r
687 Root->Enabled = false;
689 list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
\r
690 for( i_index = 0; i_index < list.i_count; i_index++ )
\r
692 p_parser = (module_t *)list.p_values[i_index].p_object ;
\r
694 if( !strcmp( p_parser->psz_capability, psz_capability ) )
\r
696 TMenuItem *Item = new TMenuItem( Root );
\r
697 Item->Caption = p_parser->psz_object_name;
\r
698 Item->Hint = Item->Caption;
\r
699 Item->OnClick = MenuItemClick;
\r
704 vlc_list_release( &list );
\r
706 /* be sure that menu is enabled, if there is at least one item */
708 Root->Enabled = true;
711 /*****************************************************************************
712 * ProgramMenu: update the programs menu of the interface
713 *****************************************************************************
714 * Builds the program menu according to what have been found in the PAT
715 * by the input. Useful for multi-programs streams such as DVB ones.
716 *****************************************************************************/
717 void __fastcall TMenusGen::ProgramMenu( TMenuItem *Root,
718 pgrm_descriptor_t *p_pgrm, TNotifyEvent MenuItemClick )
722 /* remove previous menu */
724 Root->Enabled = false;
726 /* create a set of program buttons and append them to the container */
727 for( unsigned int i = 0; i < p_intf->p_sys->p_input->stream.i_pgrm_number;
731 Name.sprintf( "id %d",
732 p_intf->p_sys->p_input->stream.pp_programs[i]->i_number );
734 Item = new TMenuItem( Root );
735 Item->Caption = Name;
737 Item->RadioItem = true;
738 Item->OnClick = MenuItemClick;
740 /* FIXME: temporary hack to save the program id with the Item
741 * It will be used in the callback. */
744 /* check the currently selected program */
745 if( p_pgrm == p_intf->p_sys->p_input->stream.pp_programs[i] )
746 Item->Checked = true;
748 /* add the item to the submenu */
752 /* be sure that menu is enabled if more than 1 program */
753 if( p_intf->p_sys->p_input->stream.i_pgrm_number > 1 )
754 Root->Enabled = true;
757 /*****************************************************************************
758 * RadioMenu: update interactive menus of the interface
759 *****************************************************************************
760 * Sets up menus with information from input
761 * Warning: since this function is designed to be called by management
762 * function, the interface lock has to be taken
763 *****************************************************************************/
764 void __fastcall TMenusGen::RadioMenu( TMenuItem *Root, AnsiString ItemName,
765 int i_nb, int i_selected, TNotifyEvent MenuItemClick )
767 TMenuItem * ItemGroup;
771 /* remove previous menu */
772 Root->Enabled = false;
775 for( int i_item = 1; i_item <= i_nb; i_item++ )
777 /* we group titles/chapters in packets of ten for small screens */
778 if( ( i_item % 10 == 1 ) && ( i_nb > 20 ) )
781 Root->Add( ItemGroup );
783 Name.sprintf( "%ss %d to %d", ItemName, i_item, i_item + 9 );
784 ItemGroup = new TMenuItem( Root );
785 ItemGroup->Hint = Name;
786 ItemGroup->RadioItem = true;
788 /* set the accelerator character */
789 Name.Insert( "&", Name.Length() - 1 );
790 ItemGroup->Caption = Name;
793 Name.sprintf( "%s %d", ItemName, i_item );
794 Item = new TMenuItem( Root );
795 Item->RadioItem = true;
798 /* set the accelerator character */
799 Name.Insert( "&", Name.Length() );
800 Item->Caption = Name;
802 /* FIXME: temporary hack to save i_item with the Item
803 * It will be used in the callback. */
806 /* check the currently selected chapter */
807 if( i_selected == i_item )
808 Item->Checked = true;
810 /* setup signal handling */
811 Item->OnClick = MenuItemClick;
814 ItemGroup->Add( Item );
819 // if( ( i_nb > 20 ) && ( i_item % 10 ) ) ?
821 Root->Add( ItemGroup );
823 /* be sure that menu is enabled, if there are several items */
825 Root->Enabled = true;
828 /*****************************************************************************
829 * LanguageMenus: update interactive menus of the interface
830 *****************************************************************************
831 * Sets up menus with information from input:
834 * Warning: since this function is designed to be called by management
835 * function, the interface lock has to be taken
836 *****************************************************************************/
837 void __fastcall TMenusGen::LanguageMenu( TMenuItem *Root, es_descriptor_t *p_es,
838 int i_cat, TNotifyEvent MenuItemClick )
840 TMenuItem * Separator;
844 /* remove previous menu */
846 Root->Enabled = false;
848 /* special case for "off" item */
850 Item = new TMenuItem( Root );
851 Item->RadioItem = true;
853 Item->Caption = Name;
854 Item->OnClick = MenuItemClick;
859 Separator = new TMenuItem( Root );
860 Separator->Caption = "-";
861 Root->Add( Separator );
865 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
867 #define ES p_intf->p_sys->p_input->stream.pp_es[i]
868 /* create a set of language buttons and append them to the Root */
869 for( unsigned int i = 0; i < p_intf->p_sys->p_input->stream.i_es_number;
872 if( ( ES->i_cat == i_cat ) &&
875 p_intf->p_sys->p_input->stream.p_selected_program ) )
878 Name = p_intf->p_sys->p_input->stream.pp_es[i]->psz_desc;
880 Name.sprintf( "Language %d", i_item );
882 Item = new TMenuItem( Root );
883 Item->RadioItem = true;
885 Item->Caption = Name;
888 /* check the currently selected item */
889 if( p_es == p_intf->p_sys->p_input->stream.pp_es[i] )
890 Item->Checked = true;
892 /* setup signal hanling */
893 Item->OnClick = MenuItemClick;
899 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
901 /* be sure that menu is enabled if non empty */
903 Root->Enabled = true;
906 /*****************************************************************************
907 * NavigationMenu: sets menus for titles and chapters selection
908 *****************************************************************************
909 * Generates two types of menus:
910 * -simple list of titles
911 * -cascaded lists of chapters for each title
912 *****************************************************************************/
913 void __fastcall TMenusGen::NavigationMenu( TMenuItem *Root,
914 TNotifyEvent MenuItemClick )
916 TMenuItem * TitleGroup;
917 TMenuItem * TitleItem;
918 TMenuItem * ChapterGroup;
919 TMenuItem * ChapterItem;
921 unsigned int i_title_nb;
922 unsigned int i_chapter_nb;
925 /* remove previous menu */
926 Root->Enabled = false;
929 i_title_nb = p_intf->p_sys->p_input->stream.i_area_nb;
932 for( unsigned int i_title = 1; i_title <= i_title_nb; i_title++ )
934 /* we group titles in packets of ten for small screens */
935 if( ( i_title % 10 == 1 ) && ( i_title_nb > 20 ) )
938 Root->Add( TitleGroup );
940 Name.sprintf( "%d - %d", i_title, i_title + 9 );
941 TitleGroup = new TMenuItem( Root );
942 TitleGroup->RadioItem = true;
943 TitleGroup->Hint = Name;
944 TitleGroup->Caption = Name;
947 Name.sprintf( "Title %d (%d)", i_title,
948 p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb - 1 );
950 TitleItem = new TMenuItem( Root );
951 TitleItem->RadioItem = true;
952 TitleItem->Hint = Name;
953 TitleItem->Caption = Name;
956 p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb - 1;
958 /* loop on chapters */
959 for( unsigned int i_chapter = 1; i_chapter <= i_chapter_nb;
962 /* we group chapters in packets of ten for small screens */
963 if( ( i_chapter % 10 == 1 ) && ( i_chapter_nb > 20 ) )
966 TitleItem->Add( ChapterGroup );
968 Name.sprintf( "%d - %d", i_chapter, i_chapter + 9 );
969 ChapterGroup = new TMenuItem( TitleItem );
970 ChapterGroup->RadioItem = true;
971 ChapterGroup->Hint = Name;
972 ChapterGroup->Caption = Name;
975 Name.sprintf( "Chapter %d", i_chapter );
977 ChapterItem = new TMenuItem( TitleItem );
978 ChapterItem->RadioItem = true;
979 ChapterItem->Hint = Name;
980 ChapterItem->Caption = Name;
982 /* FIXME: temporary hack to save i_title and i_chapter with
983 * ChapterItem, since we will need them in the callback */
984 ChapterItem->Tag = Pos2Data( i_title, i_chapter );
986 #define p_area p_intf->p_sys->p_input->stream.pp_areas[i_title]
987 /* check the currently selected chapter */
989 p_intf->p_sys->p_input->stream.p_selected_area ) &&
990 ( p_area->i_part == i_chapter ) )
992 ChapterItem->Checked = true;
996 /* setup signal handling */
997 ChapterItem->OnClick = MenuItemClick;
999 if( i_chapter_nb > 20 )
1000 ChapterGroup->Add( ChapterItem );
1002 TitleItem->Add( ChapterItem );
1005 if( i_chapter_nb > 20 )
1007 TitleItem->Add( ChapterGroup );
1010 if( p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb
1013 /* be sure that menu is sensitive */
1014 Root->Enabled = true;
1018 if( i_title_nb > 20 )
1019 TitleGroup->Add( TitleItem );
1021 Root->Add( TitleItem );
1024 if( i_title_nb > 20 )
1025 Root->Add( TitleGroup );
1027 /* be sure that menu is sensitive */
1028 Root->Enabled = true;