Commit 7822e559 authored by VideoLAN's avatar VideoLAN

* ./modules/win32/menu.cpp: reorganized the code for menus generation,

   and got rid of the global variable (at last!) in the win32 interface.

Please check that navigation and language selection aren't too much
broken for DVDs...
parent a71b1c8c
......@@ -398,7 +398,7 @@ void __fastcall TMainFrameDlg::PrevTitleActionExecute( TObject *Sender )
p_intf->p_sys->b_title_update = 1;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
SetupMenus( p_intf );
p_intf->p_sys->p_menus->SetupMenus();
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
}
}
......@@ -412,14 +412,14 @@ void __fastcall TMainFrameDlg::NextTitleActionExecute( TObject *Sender )
if( i_id < p_intf->p_sys->p_input->stream.i_area_nb )
{
p_area = p_intf->p_sys->p_input->stream.pp_areas[i_id];
p_area = p_intf->p_sys->p_input->stream.pp_areas[i_id];
input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area );
input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
p_intf->p_sys->b_title_update = 1;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
SetupMenus( p_intf );
p_intf->p_sys->p_menus->SetupMenus();
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
}
}
......@@ -439,7 +439,7 @@ void __fastcall TMainFrameDlg::PrevChapterActionExecute( TObject *Sender )
p_intf->p_sys->b_chapter_update = 1;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
SetupMenus( p_intf );
p_intf->p_sys->p_menus->SetupMenus();
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
}
}
......@@ -449,7 +449,7 @@ void __fastcall TMainFrameDlg::NextChapterActionExecute( TObject *Sender )
input_area_t * p_area;
p_area = p_intf->p_sys->p_input->stream.p_selected_area;
if( p_area->i_part < p_area->i_part_nb )
{
p_area->i_part++;
......@@ -459,7 +459,7 @@ void __fastcall TMainFrameDlg::NextChapterActionExecute( TObject *Sender )
p_intf->p_sys->b_chapter_update = 1;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
SetupMenus( p_intf );
p_intf->p_sys->p_menus->SetupMenus();
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
}
}
......@@ -512,7 +512,7 @@ void __fastcall TMainFrameDlg::ModeManage()
if( p_intf->p_sys->p_input != NULL )
{
switch( p_intf->p_sys->p_input->stream.i_method & 0xf0 )
{
{
case INPUT_METHOD_FILE:
GroupBoxFile->Visible = true;
ActiveGB = GroupBoxFile;
......@@ -580,7 +580,7 @@ void __fastcall TMainFrameDlg::ModeManage()
else
{
/* add space between tolbar and statusbar when
* nothing is displayed; isn't it nicer ? :) */
* nothing is displayed; isn't it nicer ? :) */
i_Height += 17;
}
......
......@@ -9,7 +9,7 @@
* 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.
*
*
* 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
......
/*****************************************************************************
* menu.cpp: functions to handle menu items
*****************************************************************************
* Copyright (C) 2002 VideoLAN
*
* Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
*
* 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.
*
* 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
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include <vcl.h>
//#pragma hdrstop
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include "menu.h"
#include "win32_common.h"
/****************************************************************************
* Local Prototypes
****************************************************************************/
extern intf_thread_t *p_intfGlobal;
static TMenuItem *Index2Item( TMenuItem *, int, bool );
static int Item2Index( TMenuItem *, TMenuItem * );
static void __fastcall LangChange( TMenuItem *, TMenuItem *, TMenuItem *, int );
static void __fastcall ProgramChange( TMenuItem *, TMenuItem * );
static void __fastcall RadioMenu( TMenuItem *, AnsiString,
int, int, TNotifyEvent );
static void __fastcall ProgramMenu( TMenuItem *, pgrm_descriptor_t *,
TNotifyEvent );
static void __fastcall LanguageMenu( TMenuItem *t, es_descriptor_t *,
int, TNotifyEvent );
static void __fastcall NavigationMenu( TMenuItem *, TNotifyEvent );
static TMenuItem *Index2Item( TMenuItem *Root, int i_index, bool SingleColumn )
{
if( SingleColumn || ( i_index < 20 ) )
{
return Root->Items[i_index];
}
else
{
return Root->Items[i_index / 10]->Items[i_index % 10];
}
}
static int Item2Index( TMenuItem *Root, TMenuItem *Item )
{
if( Item->Parent == Root )
{
return Item->MenuIndex;
}
else
{
return( 10 * Item->Parent->MenuIndex + Item->MenuIndex );
}
}
/****************************************************************************
* LangChange: change audio or subtitles languages
****************************************************************************
* Toggle the language, and update the selected menuitems.
****************************************************************************/
static void __fastcall LangChange( TMenuItem *RootCurrent, TMenuItem *Item,
TMenuItem *RootOther, int i_cat )
{
intf_thread_t * p_intf = p_intfGlobal;
es_descriptor_t * p_es;
es_descriptor_t * p_es_old;
int i_index;
int i_es;
/* find the selected ES */
i_es = Item->Tag;
/* find selected menu item */
i_index = Item2Index( RootCurrent, Item ) - 1;
if( i_index < 0 )
{
/* 'None' was selected */
p_es = NULL;
}
else
{
vlc_mutex_lock( &p_intfGlobal->p_sys->p_input->stream.stream_lock );
p_es = p_intfGlobal->p_sys->p_input->stream.pp_es[i_es];
vlc_mutex_unlock( &p_intfGlobal->p_sys->p_input->stream.stream_lock );
}
/* find the current ES */
if( i_cat == AUDIO_ES )
{
p_es_old = p_intf->p_sys->p_audio_es_old;
p_intf->p_sys->p_audio_es_old = p_es;
}
else
{
p_es_old = p_intf->p_sys->p_spu_es_old;
p_intf->p_sys->p_spu_es_old = p_es;
}
/* exchange them */
input_ToggleES( p_intfGlobal->p_sys->p_input, p_es_old, false );
input_ToggleES( p_intfGlobal->p_sys->p_input, p_es, true );
Item->Checked = true;
Index2Item( RootOther, i_index + 1, true )->Checked = true;
}
/****************************************************************************
* ProgramChange: change the program
****************************************************************************
* Toggle the program, and update the selected menuitems.
****************************************************************************/
static void __fastcall ProgramChange( TMenuItem *Item, TMenuItem *RootOther )
{
intf_thread_t * p_intf = p_intfGlobal;
int i_program = Item->Tag;
/* toggle the program */
input_ChangeProgram( p_intfGlobal->p_sys->p_input, (u16)i_program );
/* check selected menu items */
Item->Checked = true;
Index2Item( RootOther, i_program - 1, true )->Checked = true;
/* update audio/subtitles menus */
p_intf->p_sys->b_audio_update = 1;
p_intf->p_sys->b_spu_update = 1;
vlc_mutex_lock( &p_intfGlobal->p_sys->p_input->stream.stream_lock );
SetupMenus( p_intf );
vlc_mutex_unlock( &p_intfGlobal->p_sys->p_input->stream.stream_lock );
p_intf->p_sys->b_audio_update = 0;
p_intf->p_sys->b_spu_update = 0;
input_SetStatus( p_intfGlobal->p_sys->p_input, INPUT_STATUS_PLAY );
}
/****************************************************************************
* TMainFrameDlg::*Click: callbacks for the menuitems
****************************************************************************
* These functions need to be in a class, or we won't be able to pass them
* as arguments (since TNotifyEvent uses __closure)
****************************************************************************/
/*
* Audio
*/
void __fastcall TMainFrameDlg::MenuAudioClick( TObject *Sender )
{
LangChange( MenuAudio, (TMenuItem *)Sender, PopupAudio, AUDIO_ES );
}
void __fastcall TMainFrameDlg::PopupAudioClick( TObject *Sender )
{
LangChange( PopupAudio, (TMenuItem *)Sender, MenuAudio, AUDIO_ES );
}
/*
* Subtitles
*/
void __fastcall TMainFrameDlg::MenuSubtitleClick( TObject *Sender )
{
LangChange( MenuSubtitles, (TMenuItem *)Sender, PopupSubtitles, SPU_ES );
}
void __fastcall TMainFrameDlg::PopupSubtitleClick( TObject *Sender )
{
LangChange( PopupSubtitles, (TMenuItem *)Sender, MenuSubtitles, SPU_ES );
}
/*
* Program
*/
void __fastcall TMainFrameDlg::MenuProgramClick( TObject *Sender )
{
ProgramChange( (TMenuItem *)Sender, PopupProgram );
}
void __fastcall TMainFrameDlg::PopupProgramClick( TObject *Sender )
{
ProgramChange( (TMenuItem *)Sender, MenuProgram );
}
/*
* Navigation
*/
void __fastcall TMainFrameDlg::PopupNavigationClick( TObject *Sender )
{
TMenuItem * Item = (TMenuItem *)Sender;
TMenuItem * ItemTitle;
input_area_t * p_area;
int i_title = DATA2TITLE( Item->Tag );
int i_chapter = DATA2CHAPTER( Item->Tag );
p_area = p_intfGlobal->p_sys->p_input->stream.pp_areas[i_title];
p_area->i_part = i_chapter;
input_ChangeArea( p_intfGlobal->p_sys->p_input, (input_area_t*)p_area );
Item->Checked = true;
ItemTitle = Index2Item( MenuTitle, i_title - 1, false );
if( ItemTitle->Checked )
{
/* same title, new chapter */
Index2Item( MenuChapter, i_chapter - 1, false )->Checked = true;
}
else
{
/* new title => we must rebuild the chapter menu */
vlc_mutex_lock( &p_intfGlobal->p_sys->p_input->stream.stream_lock );
RadioMenu( MenuChapter, "Chapter",
p_intfGlobal->p_sys->p_input->stream.p_selected_area->i_part_nb,
i_chapter, MenuChapterClick );
vlc_mutex_unlock( &p_intfGlobal->p_sys->p_input->stream.stream_lock );
}
input_SetStatus( p_intfGlobal->p_sys->p_input, INPUT_STATUS_PLAY );
}
/*
* Title
*/
void __fastcall TMainFrameDlg::MenuTitleClick( TObject *Sender )
{
TMenuItem * Item = (TMenuItem *)Sender;
TMenuItem * ItemTitle;
int i_title = Item->Tag;
input_ChangeArea( p_intfGlobal->p_sys->p_input,
p_intfGlobal->p_sys->p_input->stream.pp_areas[i_title] );
Item->Checked = true;
ItemTitle = Index2Item( PopupNavigation, i_title - 1, false );
Index2Item( ItemTitle, 0, false )->Checked = true;
input_SetStatus( p_intfGlobal->p_sys->p_input, INPUT_STATUS_PLAY );
}
/*
* Chapter
*/
void __fastcall TMainFrameDlg::MenuChapterClick( TObject *Sender )
{
TMenuItem * Item = (TMenuItem *)Sender;
TMenuItem * ItemTitle;
input_area_t * p_area;
int i_title;
int i_chapter = Item->Tag;
p_area = p_intfGlobal->p_sys->p_input->stream.p_selected_area;
p_area->i_part = i_chapter;
input_ChangeArea( p_intfGlobal->p_sys->p_input, (input_area_t*)p_area );
i_title = p_intfGlobal->p_sys->p_input->stream.p_selected_area->i_id;
ItemTitle = Index2Item( PopupNavigation, i_title - 1, false );
Index2Item( ItemTitle, i_chapter - 1, false )->Checked = true;
input_SetStatus( p_intfGlobal->p_sys->p_input, INPUT_STATUS_PLAY );
}
/****************************************************************************
* Functions to generate menus
****************************************************************************/
/*****************************************************************************
* RadioMenu: update interactive menus of the interface
*****************************************************************************
* Sets up menus with information from input
* Warning: since this function is designed to be called by management
* function, the interface lock has to be taken
*****************************************************************************/
static void __fastcall RadioMenu( TMenuItem * Root, AnsiString ItemName,
int i_nb, int i_selected,
TNotifyEvent MenuItemClick )
{
TMenuItem * ItemGroup;
TMenuItem * Item;
TMenuItem * ItemActive;
AnsiString Name;
int i_item;
/* remove previous menu */
Root->Enabled = false;
Root->Clear();
ItemActive = NULL;
for( i_item = 0; i_item < i_nb; i_item++ )
{
/* we group titles/chapters in packets of ten for small screens */
if( ( i_item % 10 == 0 ) && ( i_nb > 20 ) )
{
if( i_item != 0 )
{
Root->Add( ItemGroup );
}
Name.sprintf( "%ss %d to %d", ItemName, i_item + 1, i_item + 10 );
ItemGroup = new TMenuItem( Root );
ItemGroup->Hint = Name;
/* set the accelerator character */
Name.Insert( "&", Name.Length() - 1 );
ItemGroup->Caption = Name;
}
Name.sprintf( "%s %d", ItemName, i_item + 1 );
Item = new TMenuItem( Root );
Item->RadioItem = true;
Item->Hint = Name;
/* set the accelerator character */
Name.Insert( "&", Name.Length() );
Item->Caption = Name;
/* FIXME: temporary hack to save i_item with the Item
* It will be used in the callback. */
Item->Tag = i_item + 1;
if( i_selected == i_item + 1 )
{
ItemActive = Item;
}
/* setup signal handling */
Item->OnClick = MenuItemClick;
if( i_nb > 20 )
{
ItemGroup->Add( Item );
}
else
{
Root->Add( Item );
}
}
// if( ( i_nb > 20 ) && ( i_item % 10 ) ) ?
if( i_nb > 20 )
{
Root->Add( ItemGroup );
}
/* check currently selected chapter */
if( ItemActive != NULL )
{
ItemActive->Checked = true;
}
/* be sure that menu is enabled, if there are several items */
if( i_nb > 1 )
{
Root->Enabled = true;
}
}
/*****************************************************************************
* ProgramMenu: update the programs menu of the interface
*****************************************************************************
* Builds the program menu according to what have been found in the PAT
* by the input. Useful for multi-programs streams such as DVB ones.
*****************************************************************************/
static void __fastcall ProgramMenu( TMenuItem * Root,
pgrm_descriptor_t * p_pgrm,
TNotifyEvent MenuItemClick )
{
TMenuItem * Item;
TMenuItem * ItemActive;
AnsiString Name;
int i;
/* remove previous menu */
Root->Clear();
Root->Enabled = false;
ItemActive = NULL;
/* create a set of program buttons and append them to the container */
for( i = 0; i < p_intfGlobal->p_sys->p_input->stream.i_pgrm_number; i++ )
{
Name.sprintf( "id %d",
p_intfGlobal->p_sys->p_input->stream.pp_programs[i]->i_number );
Item = new TMenuItem( Root );
Item->Caption = Name;
Item->Hint = Name;
Item->RadioItem = true;
Item->OnClick = MenuItemClick;
/* FIXME: temporary hack to save the program id with the Item
* It will be used in the callback. */
Item->Tag = i + 1;
if( p_pgrm == p_intfGlobal->p_sys->p_input->stream.pp_programs[i] )
{
/* don't lose Item when we append into menu */
ItemActive = Item;
}
/* Add the item to the submenu */
Root->Add( Item );
}
/* check currently selected program */
if( ItemActive != NULL )
{
ItemActive->Checked = true;
}
/* be sure that menu is enabled if more than 1 program */
if( p_intfGlobal->p_sys->p_input->stream.i_pgrm_number > 1 )
{
Root->Enabled = true;
}
}
/*****************************************************************************
* LanguageMenus: update interactive menus of the interface
*****************************************************************************
* Sets up menus with information from input:
* - languages
* - sub-pictures
* Warning: since this function is designed to be called by management
* function, the interface lock has to be taken
*****************************************************************************/
static void __fastcall LanguageMenu( TMenuItem * Root, es_descriptor_t * p_es,
int i_cat, TNotifyEvent MenuItemClick )
{
TMenuItem * Separator;
TMenuItem * Item;
TMenuItem * ItemActive;
AnsiString Name;
int i_item;
int i;
/* remove previous menu */
Root->Clear();
Root->Enabled = false;
/* special case for "off" item */
Name = "None";
Item = new TMenuItem( Root );
Item->RadioItem = true;
Item->Hint = Name;
Item->Caption = Name;
Item->OnClick = MenuItemClick;
Item->Tag = -1;
Root->Add( Item );
/* separator item */
Separator = new TMenuItem( Root );
Separator->Caption = "-";
Root->Add( Separator );
ItemActive = NULL;
i_item = 0;
vlc_mutex_lock( &p_intfGlobal->p_sys->p_input->stream.stream_lock );
#define ES p_intfGlobal->p_sys->p_input->stream.pp_es[i]
/* create a set of language buttons and append them to the Root */
for( i = 0; i < p_intfGlobal->p_sys->p_input->stream.i_es_number; i++ )
{
if( ( ES->i_cat == i_cat ) &&
( !ES->p_pgrm ||
ES->p_pgrm ==
p_intfGlobal->p_sys->p_input->stream.p_selected_program ) )
{
i_item++;
Name = p_intfGlobal->p_sys->p_input->stream.pp_es[i]->psz_desc;
if( Name.IsEmpty() )
{
Name.sprintf( "Language %d", i_item );
}
Item = new TMenuItem( Root );
Item->RadioItem = true;
Item->Hint = Name;
Item->Caption = Name;
Item->Tag = i;
if( p_es == p_intfGlobal->p_sys->p_input->stream.pp_es[i] )
{
/* don't lose Item when we append into menu */
ItemActive = Item;
}
/* setup signal hanling */
Item->OnClick = MenuItemClick;
Root->Add( Item );
}
}
#undef ES
vlc_mutex_unlock( &p_intfGlobal->p_sys->p_input->stream.stream_lock );
/* check currently selected item */
if( ItemActive != NULL )
{
ItemActive->Checked = true;
}
/* be sure that menu is enabled if non empty */
if( i_item > 0 )
{
Root->Enabled = true;
}
}
/*****************************************************************************
* NavigationMenu: sets menus for titles and chapters selection
*****************************************************************************
* Generates two types of menus:
* -simple list of titles
* -cascaded lists of chapters for each title
*****************************************************************************/
static void __fastcall NavigationMenu( TMenuItem * Root,
TNotifyEvent MenuItemClick )
{
TMenuItem * TitleGroup;
TMenuItem * TitleItem;
TMenuItem * ItemActive;
TMenuItem * ChapterGroup;
TMenuItem * ChapterItem;
AnsiString Name;
int i_title;
int i_chapter;
int i_title_nb;
int i_chapter_nb;
/* remove previous menu */
Root->Enabled = false;
Root->Clear();
ItemActive = NULL;
i_title_nb = p_intfGlobal->p_sys->p_input->stream.i_area_nb;
/* loop on titles */
for( i_title = 1; i_title < i_title_nb; i_title++ )
{
/* we group titles in packets of ten for small screens */
if( ( i_title % 10 == 1 ) && ( i_title_nb > 20 ) )
{
if( i_title != 1 )
{
Root->Add( TitleGroup );
}
Name.sprintf( "%d - %d", i_title, i_title + 9 );
TitleGroup = new TMenuItem( Root );
TitleGroup->RadioItem = true;
TitleGroup->Hint = Name;
TitleGroup->Caption = Name;
}
Name.sprintf( "Title %d (%d)", i_title,
p_intfGlobal->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb );
{
TitleItem = new TMenuItem( Root );
TitleItem->RadioItem = true;
TitleItem->Hint = Name;
TitleItem->Caption = Name;
i_chapter_nb =
p_intfGlobal->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb;
/* loop on chapters */
for( i_chapter = 0; i_chapter < i_chapter_nb; i_chapter++ )
{
/* we group chapters in packets of ten for small screens */
if( ( i_chapter % 10 == 0 ) && ( i_chapter_nb > 20 ) )
{
if( i_chapter != 0 )
{
TitleItem->Add( ChapterGroup );
}
Name.sprintf( "%d - %d", i_chapter + 1, i_chapter + 10 );
ChapterGroup = new TMenuItem( TitleItem );
ChapterGroup->RadioItem = true;
ChapterGroup->Hint = Name;
ChapterGroup->Caption = Name;
}
Name.sprintf( "Chapter %d", i_chapter + 1 );
ChapterItem = new TMenuItem( TitleItem );
ChapterItem->RadioItem = true;
ChapterItem->Hint = Name;
ChapterItem->Caption = Name;
/* FIXME: temporary hack to save i_title and i_chapter with
* ChapterItem, since we will need them in the callback */
ChapterItem->Tag = (int)POS2DATA( i_title, i_chapter + 1 );
#define p_area p_intfGlobal->p_sys->p_input->stream.pp_areas[i_title]
if( ( p_area ==
p_intfGlobal->p_sys->p_input->stream.p_selected_area ) &&
( p_area->i_part == i_chapter + 1 ) )
{
ItemActive = ChapterItem;
}
#undef p_area
/* setup signal hanling */
ChapterItem->OnClick = MenuItemClick;
if( i_chapter_nb > 20 )
{
ChapterGroup->Add( ChapterItem );
}
else
{
TitleItem->Add( ChapterItem );
}
}
if( i_chapter_nb > 20 )
{
TitleItem->Add( ChapterGroup );
}
if( p_intfGlobal->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb
> 1 )
{
/* be sure that menu is sensitive */
Root->Enabled = true;
}
}
if( i_title_nb > 20 )
{
TitleGroup->Add( TitleItem );
}
else
{
Root->Add( TitleItem );
}
}
if( i_title_nb > 20 )
{
Root->Add( TitleGroup );
}
/* Default selected chapter */
if( ItemActive != NULL )
{
ItemActive->Checked = true;
}
/* be sure that menu is sensitive */
Root->Enabled = true;
}
/*****************************************************************************
* SetupMenus: function that generates title/chapter/audio/subpic
* menus with help from preceding functions
*****************************************************************************/
int __fastcall SetupMenus( intf_thread_t * p_intf )
{
TMainFrameDlg * p_window = p_intf->p_sys->p_window;
es_descriptor_t * p_audio_es;
es_descriptor_t * p_spu_es;
int i;
p_intf->p_sys->b_chapter_update |= p_intf->p_sys->b_title_update;
p_intf->p_sys->b_audio_update |= p_intf->p_sys->b_title_update |
p_intf->p_sys->b_program_update;
p_intf->p_sys->b_spu_update |= p_intf->p_sys->b_title_update |
p_intf->p_sys->b_program_update;
if( p_intf->p_sys->b_program_update )
{
pgrm_descriptor_t * p_pgrm;
if( p_intfGlobal->p_sys->p_input->stream.p_new_program )
{
p_pgrm = p_intfGlobal->p_sys->p_input->stream.p_new_program;
}
else
{
p_pgrm = p_intfGlobal->p_sys->p_input->stream.p_selected_program;
}
ProgramMenu( p_window->MenuProgram, p_pgrm,
p_window->MenuProgramClick );
ProgramMenu( p_window->PopupProgram, p_pgrm,
p_window->PopupProgramClick );
p_intf->p_sys->b_program_update = 0;
}
if( p_intf->p_sys->b_title_update )
{
RadioMenu( p_window->MenuTitle, "Title",
//why "-1" ?
p_intfGlobal->p_sys->p_input->stream.i_area_nb - 1,
p_intfGlobal->p_sys->p_input->stream.p_selected_area->i_id,
p_window->MenuTitleClick );
AnsiString CurrentTitle;
CurrentTitle.sprintf( "%d",
p_intfGlobal->p_sys->p_input->stream.p_selected_area->i_id );
p_window->LabelTitleCurrent->Caption = CurrentTitle;
p_intf->p_sys->b_title_update = 0;
}
if( p_intf->p_sys->b_chapter_update )
{
RadioMenu( p_window->MenuChapter, "Chapter",
p_intfGlobal->p_sys->p_input->stream.p_selected_area->i_part_nb,
p_intfGlobal->p_sys->p_input->stream.p_selected_area->i_part,
p_window->MenuChapterClick );
NavigationMenu( p_window->PopupNavigation,
p_window->PopupNavigationClick );
AnsiString CurrentChapter;
CurrentChapter.sprintf( "%d",
p_intfGlobal->p_sys->p_input->stream.p_selected_area->i_part );
p_window->LabelChapterCurrent->Caption = CurrentChapter;
p_intf->p_sys->i_part =
p_intfGlobal->p_sys->p_input->stream.p_selected_area->i_part;
p_intf->p_sys->b_chapter_update = 0;
}
/* look for selected ES */
p_audio_es = NULL;
p_spu_es = NULL;
for( i = 0; i < p_intfGlobal->p_sys->p_input->stream.i_selected_es_number; i++ )
{
if( p_intfGlobal->p_sys->p_input->stream.pp_selected_es[i]->i_cat
== AUDIO_ES )
{
p_audio_es = p_intfGlobal->p_sys->p_input->stream.pp_selected_es[i];
p_intfGlobal->p_sys->p_audio_es_old = p_audio_es;
}
if( p_intfGlobal->p_sys->p_input->stream.pp_selected_es[i]->i_cat
== SPU_ES )
{
p_spu_es = p_intfGlobal->p_sys->p_input->stream.pp_selected_es[i];
p_intfGlobal->p_sys->p_spu_es_old = p_spu_es;
}
}
vlc_mutex_unlock( &p_intfGlobal->p_sys->p_input->stream.stream_lock );
/* audio menus */
if( p_intf->p_sys->b_audio_update )
{
LanguageMenu( p_window->MenuAudio, p_audio_es, AUDIO_ES,
p_window->MenuAudioClick );
LanguageMenu( p_window->PopupAudio, p_audio_es, AUDIO_ES,
p_window->PopupAudioClick );
p_intf->p_sys->b_audio_update = 0;
}
/* sub picture menus */
if( p_intf->p_sys->b_spu_update )
{
LanguageMenu( p_window->PopupSubtitles, p_spu_es, SPU_ES,
p_window->PopupSubtitleClick );
LanguageMenu( p_window->MenuSubtitles, p_spu_es, SPU_ES,
p_window->MenuSubtitleClick );
p_intf->p_sys->b_spu_update = 0;
}
vlc_mutex_lock( &p_intfGlobal->p_sys->p_input->stream.stream_lock );
return true;
}
/*****************************************************************************
* menu.cpp: functions to handle menu items
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: menu.cpp,v 1.2 2002/12/13 03:52:58 videolan Exp $
*
* Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
*
* 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.
*
* 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
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include <vcl.h>
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include "menu.h"
#include "win32_common.h"
/*****************************************************************************
* TMenusGen::*Click: callbacks for the menuitems
****************************************************************************
* These functions need to be in a class, or we won't be able to pass them
* as arguments (since TNotifyEvent uses __closure)
****************************************************************************/
/*
* Audio
*/
void __fastcall TMenusGen::MenuAudioClick( TObject *Sender )
{
LangChange( MenuAudio, (TMenuItem *)Sender, PopupAudio, AUDIO_ES );
}
void __fastcall TMenusGen::PopupAudioClick( TObject *Sender )
{
LangChange( PopupAudio, (TMenuItem *)Sender, MenuAudio, AUDIO_ES );
}
/*
* Subtitles
*/
void __fastcall TMenusGen::MenuSubtitleClick( TObject *Sender )
{
LangChange( MenuSubtitles, (TMenuItem *)Sender,
PopupSubtitles, SPU_ES );
}
void __fastcall TMenusGen::PopupSubtitleClick( TObject *Sender )
{
LangChange( PopupSubtitles, (TMenuItem *)Sender,
MenuSubtitles, SPU_ES );
}
/*
* Program
*/
void __fastcall TMenusGen::MenuProgramClick( TObject *Sender )
{
ProgramChange( (TMenuItem *)Sender, PopupProgram );
}
void __fastcall TMenusGen::PopupProgramClick( TObject *Sender )
{
ProgramChange( (TMenuItem *)Sender, MenuProgram );
}
/*
* Title
*/
void __fastcall TMenusGen::MenuTitleClick( TObject *Sender )
{
TMenuItem * Item = (TMenuItem *)Sender;
TMenuItem * ItemTitle;
int i_title = Item->Tag;
input_ChangeArea( p_intf->p_sys->p_input,
p_intf->p_sys->p_input->stream.pp_areas[i_title] );
Item->Checked = true;
ItemTitle = Index2Item( PopupNavigation, i_title - 1, false );
Index2Item( ItemTitle, 0, false )->Checked = true;
input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
}
/*
* Chapter
*/
void __fastcall TMenusGen::MenuChapterClick( TObject *Sender )
{
TMenuItem * Item = (TMenuItem *)Sender;
TMenuItem * ItemTitle;
input_area_t * p_area;
int i_title;
int i_chapter = Item->Tag;
p_area = p_intf->p_sys->p_input->stream.p_selected_area;
p_area->i_part = i_chapter;
input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area );
i_title = p_intf->p_sys->p_input->stream.p_selected_area->i_id;
ItemTitle = Index2Item( PopupNavigation, i_title - 1, false );
Index2Item( ItemTitle, i_chapter - 1, false )->Checked = true;
input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
}
/*
* Navigation
*/
void __fastcall TMenusGen::PopupNavigationClick( TObject *Sender )
{
TMenuItem * Item = (TMenuItem *)Sender;
TMenuItem * ItemTitle;
input_area_t * p_area;
int i_title = Data2Title( Item->Tag );
int i_chapter = Data2Chapter( Item->Tag );
p_area = p_intf->p_sys->p_input->stream.pp_areas[i_title];
p_area->i_part = i_chapter;
input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area );
Item->Checked = true;
ItemTitle = Index2Item( MenuTitle, i_title - 1, false );
if( ItemTitle->Checked )
{
/* same title, new chapter */
Index2Item( MenuChapter, i_chapter - 1, false )->Checked = true;
}
else
{
/* new title => we must rebuild the chapter menu */
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
RadioMenu(
MenuChapter, "Chapter",
p_intf->p_sys->p_input->stream.p_selected_area->i_part_nb,
i_chapter, MenuChapterClick );
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
}
input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
}
__fastcall TMenusGen::TMenusGen( intf_thread_t *_p_intf ) : TObject()
{
p_intf = _p_intf;
/* Initialize local pointers to menu items of the main window */
TMainFrameDlg * p_window = p_intf->p_sys->p_window;
if( p_window == NULL )
{
msg_Err( p_intf, "Main window wasn't created, expect problems..." );
return;
}
MenuAudio = p_window->MenuAudio;
PopupAudio = p_window->PopupAudio;
MenuSubtitles = p_window->MenuSubtitles;
PopupSubtitles = p_window->PopupSubtitles;
MenuProgram = p_window->MenuProgram;
PopupProgram = p_window->PopupProgram;
MenuTitle = p_window->MenuTitle;
MenuChapter = p_window->MenuChapter;
PopupNavigation = p_window->PopupNavigation;
}
void __fastcall TMenusGen::SetupMenus()
{
TMainFrameDlg * p_window = p_intf->p_sys->p_window;
input_thread_t *p_input = p_intf->p_sys->p_input;
es_descriptor_t * p_audio_es;
es_descriptor_t * p_spu_es;
p_intf->p_sys->b_chapter_update |= p_intf->p_sys->b_title_update;
p_intf->p_sys->b_audio_update |= p_intf->p_sys->b_program_update;
// p_intf->p_sys->b_audio_update |= p_intf->p_sys->b_title_update;
p_intf->p_sys->b_spu_update |= p_intf->p_sys->b_program_update;
// p_intf->p_sys->b_spu_update |= p_intf->p_sys->b_title_update;
if( p_intf->p_sys->b_program_update )
{
pgrm_descriptor_t * p_pgrm;
if( p_input->stream.p_new_program )
{
p_pgrm = p_input->stream.p_new_program;
}
else
{
p_pgrm = p_input->stream.p_selected_program;
}
ProgramMenu( p_window->MenuProgram, p_pgrm, MenuProgramClick );
ProgramMenu( p_window->PopupProgram, p_pgrm, PopupProgramClick );
p_intf->p_sys->b_program_update = 0;
}
if( p_intf->p_sys->b_title_update )
{
// why "-1" ?
RadioMenu( p_window->MenuTitle, "Title",
p_input->stream.i_area_nb - 1,
p_input->stream.p_selected_area->i_id,
MenuTitleClick );
AnsiString CurrentTitle;
CurrentTitle.sprintf( "%d", p_input->stream.p_selected_area->i_id );
p_window->LabelTitleCurrent->Caption = CurrentTitle;
p_intf->p_sys->b_title_update = 0;
}
if( p_intf->p_sys->b_chapter_update )
{
RadioMenu( p_window->MenuChapter, "Chapter",
p_input->stream.p_selected_area->i_part_nb,
p_input->stream.p_selected_area->i_part,
MenuChapterClick );
NavigationMenu( p_window->PopupNavigation,
PopupNavigationClick );
AnsiString CurrentChapter;
CurrentChapter.sprintf( "%d", p_input->stream.p_selected_area->i_part );
p_window->LabelChapterCurrent->Caption = CurrentChapter;
p_intf->p_sys->i_part = p_input->stream.p_selected_area->i_part;
p_intf->p_sys->b_chapter_update = 0;
}
/* look for selected ES */
p_audio_es = NULL;
p_spu_es = NULL;
for( int i = 0; i < p_input->stream.i_selected_es_number; i++ )
{
if( p_input->stream.pp_selected_es[i]->i_cat == AUDIO_ES )
{
p_audio_es = p_input->stream.pp_selected_es[i];
}
if( p_input->stream.pp_selected_es[i]->i_cat == SPU_ES )
{
p_spu_es = p_input->stream.pp_selected_es[i];
}
}
this->p_audio_es_old = p_audio_es;
this->p_spu_es_old = p_spu_es;
vlc_mutex_unlock( &p_input->stream.stream_lock );
/* audio menus */
if( p_intf->p_sys->b_audio_update )
{
LanguageMenu( p_window->MenuAudio, p_audio_es, AUDIO_ES,
MenuAudioClick );
LanguageMenu( p_window->PopupAudio, p_audio_es, AUDIO_ES,
PopupAudioClick );
p_intf->p_sys->b_audio_update = 0;
}
/* sub picture menus */
if( p_intf->p_sys->b_spu_update )
{
LanguageMenu( p_window->PopupSubtitles, p_spu_es, SPU_ES,
PopupSubtitleClick );
LanguageMenu( p_window->MenuSubtitles, p_spu_es, SPU_ES,
MenuSubtitleClick );
p_intf->p_sys->b_spu_update = 0;
}
vlc_mutex_lock( &p_input->stream.stream_lock );
}
/*****************************************************************************
* Private functions
*****************************************************************************/
TMenuItem * TMenusGen::Index2Item( TMenuItem *Root, int i_index, bool SingleColumn )
{
if( SingleColumn || ( i_index < 20 ) )
return Root->Items[i_index];
else
return Root->Items[i_index / 10]->Items[i_index % 10];
}
int TMenusGen::Item2Index( TMenuItem *Root, TMenuItem *Item )
{
if( Item->Parent == Root )
return Item->MenuIndex;
else
return( 10 * Item->Parent->MenuIndex + Item->MenuIndex );
}
int __fastcall TMenusGen::Data2Title( int data )
{
return (int) (data >> 16 );
}
int __fastcall TMenusGen::Data2Chapter( int data )
{
return (int) (data & 0xffff);
}
int __fastcall TMenusGen::Pos2Data( int title, int chapter )
{
return (int) (( title << 16 ) | ( chapter & 0xffff ));
}
/****************************************************************************
* LangChange: change audio or subtitles languages
****************************************************************************
* Toggle the language, and update the selected menuitems.
****************************************************************************/
void __fastcall TMenusGen::LangChange( TMenuItem *RootCurrent, TMenuItem *Item,
TMenuItem *RootOther, int i_cat )
{
es_descriptor_t * p_es;
es_descriptor_t * p_es_old;
int i_index;
int i_es;
/* find the selected ES */
i_es = Item->Tag;
/* find selected menu item */
i_index = Item2Index( RootCurrent, Item ) - 1;
if( i_index < 0 )
{
/* 'None' was selected */
p_es = NULL;
}
else
{
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
p_es = p_intf->p_sys->p_input->stream.pp_es[i_es];
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
}
/* find the current ES */
if( i_cat == AUDIO_ES )
{
p_es_old = this->p_audio_es_old;
this->p_audio_es_old = p_es;
}
else
{
p_es_old = this->p_spu_es_old;
this->p_spu_es_old = p_es;
}
/* exchange them */
input_ToggleES( p_intf->p_sys->p_input, p_es_old, false );
input_ToggleES( p_intf->p_sys->p_input, p_es, true );
Item->Checked = true;
Index2Item( RootOther, i_index + 1, true )->Checked = true;
}
/****************************************************************************
* ProgramChange: change the program
****************************************************************************
* Toggle the program, and update the selected menuitems.
****************************************************************************/
void __fastcall TMenusGen::ProgramChange( TMenuItem *Item,
TMenuItem *RootOther )
{
int i_program = Item->Tag;
/* toggle the program */
input_ChangeProgram( p_intf->p_sys->p_input, (uint16_t)i_program );
/* check selected menu items */
Item->Checked = true;
Index2Item( RootOther, i_program - 1, true )->Checked = true;
/* update audio/subtitles menus */
p_intf->p_sys->b_audio_update = 1;
p_intf->p_sys->b_spu_update = 1;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
SetupMenus();
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
p_intf->p_sys->b_audio_update = 0;
p_intf->p_sys->b_spu_update = 0;
input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
}
/*****************************************************************************
* ProgramMenu: update the programs menu of the interface
*****************************************************************************
* Builds the program menu according to what have been found in the PAT
* by the input. Useful for multi-programs streams such as DVB ones.
*****************************************************************************/
void __fastcall TMenusGen::ProgramMenu( TMenuItem *Root,
pgrm_descriptor_t *p_pgrm, TNotifyEvent MenuItemClick)
{
TMenuItem * Item;
TMenuItem * ItemActive;
/* remove previous menu */
Root->Clear();
Root->Enabled = false;
ItemActive = NULL;
/* create a set of program buttons and append them to the container */
for( int i = 0; i < p_intf->p_sys->p_input->stream.i_pgrm_number; i++ )
{
AnsiString Name;
Name.sprintf( "id %d",
p_intf->p_sys->p_input->stream.pp_programs[i]->i_number );
Item = new TMenuItem( Root );
Item->Caption = Name;
Item->Hint = Name;
Item->RadioItem = true;
Item->OnClick = MenuItemClick;
/* FIXME: temporary hack to save the program id with the Item
* It will be used in the callback. */
Item->Tag = i + 1;
if( p_pgrm == p_intf->p_sys->p_input->stream.pp_programs[i] )
{
/* don't lose Item when we append into menu */
ItemActive = Item;
}
/* Add the item to the submenu */
Root->Add( Item );
}
/* check currently selected program */
if( ItemActive != NULL )
{
ItemActive->Checked = true;
}
/* be sure that menu is enabled if more than 1 program */
if( p_intf->p_sys->p_input->stream.i_pgrm_number > 1 )
{
Root->Enabled = true;
}
}
/*****************************************************************************
* RadioMenu: update interactive menus of the interface
*****************************************************************************
* Sets up menus with information from input
* Warning: since this function is designed to be called by management
* function, the interface lock has to be taken
*****************************************************************************/
void __fastcall TMenusGen::RadioMenu( TMenuItem *Root, AnsiString ItemName,
int i_nb, int i_selected, TNotifyEvent MenuItemClick )
{
TMenuItem * ItemGroup;
TMenuItem * Item;
TMenuItem * ItemActive;
AnsiString Name;
/* remove previous menu */
Root->Enabled = false;
Root->Clear();
ItemActive = NULL;
for( int i_item = 0; i_item < i_nb; i_item++ )
{
/* we group titles/chapters in packets of ten for small screens */
if( ( i_item % 10 == 0 ) && ( i_nb > 20 ) )
{
if( i_item != 0 )
{
Root->Add( ItemGroup );
}
Name.sprintf( "%ss %d to %d", ItemName, i_item + 1, i_item + 10 );
ItemGroup = new TMenuItem( Root );
ItemGroup->Hint = Name;
ItemGroup->RadioItem = true;
/* set the accelerator character */
Name.Insert( "&", Name.Length() - 1 );
ItemGroup->Caption = Name;
}
Name.sprintf( "%s %d", ItemName, i_item + 1 );
Item = new TMenuItem( Root );
Item->RadioItem = true;
Item->Hint = Name;
/* set the accelerator character */
Name.Insert( "&", Name.Length() );
Item->Caption = Name;
/* FIXME: temporary hack to save i_item with the Item
* It will be used in the callback. */
Item->Tag = i_item + 1;
if( i_selected == i_item + 1 )
{
ItemActive = Item;
}
/* setup signal handling */
Item->OnClick = MenuItemClick;
if( i_nb > 20 )
ItemGroup->Add( Item );
else
Root->Add( Item );
}
// if( ( i_nb > 20 ) && ( i_item % 10 ) ) ?
if( i_nb > 20 )
{
Root->Add( ItemGroup );
}
/* check currently selected chapter */
if( ItemActive != NULL )
{
ItemActive->Checked = true;
}
/* be sure that menu is enabled, if there are several items */
if( i_nb > 1 )
{
Root->Enabled = true;
}
}
/*****************************************************************************
* LanguageMenus: update interactive menus of the interface
*****************************************************************************
* Sets up menus with information from input:
* - languages
* - sub-pictures
* Warning: since this function is designed to be called by management
* function, the interface lock has to be taken
*****************************************************************************/
void __fastcall TMenusGen::LanguageMenu( TMenuItem *Root, es_descriptor_t *p_es,
int i_cat, TNotifyEvent MenuItemClick )
{
TMenuItem * Separator;
TMenuItem * Item;
TMenuItem * ItemActive;
AnsiString Name;
/* remove previous menu */
Root->Clear();
Root->Enabled = false;
/* special case for "off" item */
Name = "None";
Item = new TMenuItem( Root );
Item->RadioItem = true;
Item->Hint = Name;
Item->Caption = Name;
Item->OnClick = MenuItemClick;
Item->Tag = -1;
Root->Add( Item );
/* separator item */
Separator = new TMenuItem( Root );
Separator->Caption = "-";
Root->Add( Separator );
ItemActive = NULL;
int i_item = 0;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
#define ES p_intf->p_sys->p_input->stream.pp_es[i]
/* create a set of language buttons and append them to the Root */
for( int i = 0; i < p_intf->p_sys->p_input->stream.i_es_number; i++ )
{
if( ( ES->i_cat == i_cat ) &&
( !ES->p_pgrm ||
ES->p_pgrm ==
p_intf->p_sys->p_input->stream.p_selected_program ) )
{
i_item++;
Name = p_intf->p_sys->p_input->stream.pp_es[i]->psz_desc;
if( Name.IsEmpty() )
{
Name.sprintf( "Language %d", i_item );
}
Item = new TMenuItem( Root );
Item->RadioItem = true;
Item->Hint = Name;
Item->Caption = Name;
Item->Tag = i;
if( p_es == p_intf->p_sys->p_input->stream.pp_es[i] )
{
/* don't lose Item when we append into menu */
ItemActive = Item;
}
/* setup signal hanling */
Item->OnClick = MenuItemClick;
Root->Add( Item );
}
}
#undef ES
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
/* check currently selected item */
if( ItemActive != NULL )
{
ItemActive->Checked = true;
}
/* be sure that menu is enabled if non empty */
if( i_item > 0 )
{
Root->Enabled = true;
}
}
/*****************************************************************************
* NavigationMenu: sets menus for titles and chapters selection
*****************************************************************************
* Generates two types of menus:
* -simple list of titles
* -cascaded lists of chapters for each title
*****************************************************************************/
void __fastcall TMenusGen::NavigationMenu( TMenuItem *Root,
TNotifyEvent MenuItemClick )
{
TMenuItem * TitleGroup;
TMenuItem * TitleItem;
TMenuItem * ItemActive;
TMenuItem * ChapterGroup;
TMenuItem * ChapterItem;
AnsiString Name;
int i_title_nb;
int i_chapter_nb;
/* remove previous menu */
Root->Enabled = false;
Root->Clear();
ItemActive = NULL;
i_title_nb = p_intf->p_sys->p_input->stream.i_area_nb;
/* loop on titles */
for( int i_title = 1; i_title < i_title_nb; i_title++ )
{
/* we group titles in packets of ten for small screens */
if( ( i_title % 10 == 1 ) && ( i_title_nb > 20 ) )
{
if( i_title != 1 )
{
Root->Add( TitleGroup );
}
Name.sprintf( "%d - %d", i_title, i_title + 9 );
TitleGroup = new TMenuItem( Root );
TitleGroup->RadioItem = true;
TitleGroup->Hint = Name;
TitleGroup->Caption = Name;
}
Name.sprintf( "Title %d (%d)", i_title,
p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb );
{
TitleItem = new TMenuItem( Root );
TitleItem->RadioItem = true;
TitleItem->Hint = Name;
TitleItem->Caption = Name;
i_chapter_nb =
p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb;
/* loop on chapters */
for( int i_chapter = 0; i_chapter < i_chapter_nb; i_chapter++ )
{
/* we group chapters in packets of ten for small screens */
if( ( i_chapter % 10 == 0 ) && ( i_chapter_nb > 20 ) )
{
if( i_chapter != 0 )
{
TitleItem->Add( ChapterGroup );
}
Name.sprintf( "%d - %d", i_chapter + 1, i_chapter + 10 );
ChapterGroup = new TMenuItem( TitleItem );
ChapterGroup->RadioItem = true;
ChapterGroup->Hint = Name;
ChapterGroup->Caption = Name;
}
Name.sprintf( "Chapter %d", i_chapter + 1 );
ChapterItem = new TMenuItem( TitleItem );
ChapterItem->RadioItem = true;
ChapterItem->Hint = Name;
ChapterItem->Caption = Name;
/* FIXME: temporary hack to save i_title and i_chapter with
* ChapterItem, since we will need them in the callback */
ChapterItem->Tag = Pos2Data( i_title, i_chapter + 1 );
#define p_area p_intf->p_sys->p_input->stream.pp_areas[i_title]
if( ( p_area ==
p_intf->p_sys->p_input->stream.p_selected_area ) &&
( p_area->i_part == i_chapter + 1 ) )
{
ItemActive = ChapterItem;
}
#undef p_area
/* setup signal handling */
ChapterItem->OnClick = MenuItemClick;
if( i_chapter_nb > 20 )
ChapterGroup->Add( ChapterItem );
else
TitleItem->Add( ChapterItem );
}
if( i_chapter_nb > 20 )
{
TitleItem->Add( ChapterGroup );
}
if( p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb
> 1 )
{
/* be sure that menu is sensitive */
Root->Enabled = true;
}
}
if( i_title_nb > 20 )
TitleGroup->Add( TitleItem );
else
Root->Add( TitleItem );
}
if( i_title_nb > 20 )
{
Root->Add( TitleGroup );
}
/* Default selected chapter */
if( ItemActive != NULL )
{
ItemActive->Checked = true;
}
/* be sure that menu is sensitive */
Root->Enabled = true;
}
/*****************************************************************************
* menu.h: prototypes for menu functions
*****************************************************************************
* Copyright (C) 2002 VideoLAN
*
* Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
*
* 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.
*
* 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
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
int __fastcall SetupMenus( intf_thread_t * );
/*****************************************************************************
* Convert user_data structures to title and chapter information
*****************************************************************************/
#define DATA2TITLE( data ) ( (int)((long)(data)) >> 16 )
#define DATA2CHAPTER( data ) ( (int)((long)(data)) & 0xffff )
#define POS2DATA( title, chapter ) ( NULL + ( ((title) << 16) \
| ((chapter) & 0xffff)) )
/*****************************************************************************
* menu.h: prototypes for menu functions
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: menu.h,v 1.2 2002/12/13 03:52:58 videolan Exp $
*
* Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
*
* 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.
*
* 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
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#ifndef menuH
#define menuH
//----------------------------------------------------------------------------
class TMenusGen : public TObject
{
private:
intf_thread_t *p_intf;
/* local pointers to main window menu items */
TMenuItem *MenuAudio;
TMenuItem *PopupAudio;
TMenuItem *MenuSubtitles;
TMenuItem *PopupSubtitles;
TMenuItem *MenuProgram;
TMenuItem *PopupProgram;
TMenuItem *MenuTitle;
TMenuItem *MenuChapter;
TMenuItem *PopupNavigation;
/* Language information */
es_descriptor_t * p_audio_es_old;
es_descriptor_t * p_spu_es_old;
/* Helpful functions */
int Item2Index( TMenuItem *Root, TMenuItem *Item );
TMenuItem *Index2Item( TMenuItem *Root, int i_index, bool SingleColumn );
int __fastcall Data2Title( int data );
int __fastcall Data2Chapter( int data );
int __fastcall Pos2Data( int title, int chapter );
void __fastcall LangChange( TMenuItem *, TMenuItem *, TMenuItem *, int );
void __fastcall ProgramChange( TMenuItem *, TMenuItem * );
void __fastcall ProgramMenu( TMenuItem *, pgrm_descriptor_t *,
TNotifyEvent );
void __fastcall RadioMenu( TMenuItem *, AnsiString, int, int,
TNotifyEvent );
void __fastcall LanguageMenu( TMenuItem *, es_descriptor_t *, int,
TNotifyEvent );
void __fastcall NavigationMenu( TMenuItem *, TNotifyEvent );
public:
__fastcall TMenusGen( intf_thread_t *_p_intf );
/* menu generation */
void __fastcall SetupMenus();
/* callbacks for menuitems */
void __fastcall MenuAudioClick( TObject *Sender );
void __fastcall PopupAudioClick( TObject *Sender );
void __fastcall MenuSubtitleClick( TObject *Sender );
void __fastcall PopupSubtitleClick( TObject *Sender );
void __fastcall MenuProgramClick( TObject *Sender );
void __fastcall PopupProgramClick( TObject *Sender );
void __fastcall MenuTitleClick( TObject *Sender );
void __fastcall MenuChapterClick( TObject *Sender );
void __fastcall PopupNavigationClick( TObject *Sender );
};
//----------------------------------------------------------------------------
#endif
......@@ -662,7 +662,7 @@ void __fastcall TPreferencesDlg::CreateConfigDialog( char *psz_module_name )
break;
default:
msg_Warn( p_intf, "unknown config type" );
msg_Warn( p_intf, "unknown config type: %i", p_item->i_type );
break;
}
......
......@@ -2,14 +2,15 @@
* win32.cpp : Win32 interface plugin for vlc
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: win32.cpp,v 1.5 2002/12/13 03:52:58 videolan Exp $
*
* Authors: Olivier Teulire <ipkiss@via.ecp.fr>
* Authors: Olivier Teulire <ipkiss@via.ecp.fr>
*
* 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.
*
*
* 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
......@@ -50,8 +51,6 @@ static void Run ( intf_thread_t * );
int Win32Manage( void *p_data );
intf_thread_t *p_intfGlobal;
/*****************************************************************************
* Open: initialize interface
*****************************************************************************/
......@@ -67,7 +66,6 @@ static int Open ( vlc_object_t *p_this )
return( 1 );
};
p_intfGlobal = p_intf;
p_intf->pf_run = Run;
p_intf->p_sys->p_sub = msg_Subscribe( p_intf );
......@@ -109,6 +107,7 @@ static void Run( intf_thread_t *p_intf )
p_intf->p_sys->p_window = new TMainFrameDlg( NULL, p_intf );
p_intf->p_sys->p_playwin = new TPlaylistDlg( NULL, p_intf );
p_intf->p_sys->p_messages = new TMessagesDlg( NULL, p_intf );
p_intf->p_sys->p_menus = new TMenusGen( p_intf );
/* show main window and wait until it is closed */
p_intf->p_sys->p_window->ShowModal();
......@@ -116,6 +115,7 @@ static void Run( intf_thread_t *p_intf )
if( p_intf->p_sys->p_disc ) delete p_intf->p_sys->p_disc;
if( p_intf->p_sys->p_network ) delete p_intf->p_sys->p_network;
if( p_intf->p_sys->p_preferences ) delete p_intf->p_sys->p_preferences;
delete p_intf->p_sys->p_menus;
delete p_intf->p_sys->p_messages;
delete p_intf->p_sys->p_playwin;
}
......@@ -158,7 +158,7 @@ int Win32Manage( intf_thread_t *p_intf )
vlc_object_release( p_intf->p_sys->p_input );
p_intf->p_sys->p_input = NULL;
}
if( p_intf->p_sys->p_input )
{
input_thread_t *p_input = p_intf->p_sys->p_input;
......@@ -171,7 +171,7 @@ int Win32Manage( intf_thread_t *p_intf )
if( p_input->stream.b_changed )
{
p_intf->p_sys->p_window->ModeManage();
SetupMenus( p_intf );
p_intf->p_sys->p_menus->SetupMenus();
p_intf->p_sys->b_playing = 1;
}
......@@ -209,7 +209,7 @@ int Win32Manage( intf_thread_t *p_intf )
/* Update the display */
// TrackBar->Invalidate();
# undef p_area
}
......@@ -217,7 +217,7 @@ int Win32Manage( intf_thread_t *p_intf )
p_input->stream.p_selected_area->i_part )
{
// p_intf->p_sys->b_chapter_update = 1;
SetupMenus( p_intf );
p_intf->p_sys->p_menus->SetupMenus();
}
}
......@@ -239,7 +239,7 @@ int Win32Manage( intf_thread_t *p_intf )
/* Just in case */
return( FALSE );
}
vlc_mutex_unlock( &p_intf->change_lock );
return( TRUE );
......
......@@ -62,6 +62,7 @@ struct intf_sys_t
TDiscDlg * p_disc; /* disc selection window */
TNetworkDlg * p_network; /* network stream window */
TPreferencesDlg * p_preferences; /* preferences window */
TMenusGen * p_menus; /* object for menu generation */
/* The slider */
off_t OldValue; /* previous value */
......@@ -78,10 +79,6 @@ struct intf_sys_t
TLabel * p_label_chapter;
int i_part; /* current chapter */
/* Language information */
es_descriptor_t * p_audio_es_old;
es_descriptor_t * p_spu_es_old;
/* The input thread */
input_thread_t * p_input;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment