Commit 8a3513c0 authored by Olivier Teulière's avatar Olivier Teulière

* skins2: support for custom popup menus, and win32 implementation.

   XML example:
       <PopupMenu id="sample_menu">
           <MenuItem label="Play" action="vlc.play()" />
           <MenuItem label="Pause" action="vlc.pause()" />
           <MenuSeparator />
           <MenuItem label="Show playlist" action="playlist_window.show()" />
           <MenuItem label="Hide playlist" action="playlist_window.hide()" />
           <MenuSeparator />
           <MenuItem label="Quick open file" action="dialogs.fileSimple()" />
       </PopupMenu>

   To call the menu:
       <Button action="sample_menu.show()" ... />

   Known bug: the popup disappears when the user clicks "too fast" on the
   button: the control refreshes itself in an asynchronous way, and the popup
   dislikes it... so click slowly :)
parent 646896fb
...@@ -61,13 +61,14 @@ SOURCES_skins2 = \ ...@@ -61,13 +61,14 @@ SOURCES_skins2 = \
controls/ctrl_video.hpp \ controls/ctrl_video.hpp \
\ \
events/evt_enter.hpp \ events/evt_enter.hpp \
events/evt_generic.hpp \
events/evt_focus.hpp \ events/evt_focus.hpp \
events/evt_generic.hpp \
events/evt_input.cpp \ events/evt_input.cpp \
events/evt_input.hpp \ events/evt_input.hpp \
events/evt_key.cpp \ events/evt_key.cpp \
events/evt_key.hpp \ events/evt_key.hpp \
events/evt_leave.hpp \ events/evt_leave.hpp \
events/evt_menu.hpp \
events/evt_motion.hpp \ events/evt_motion.hpp \
events/evt_mouse.cpp \ events/evt_mouse.cpp \
events/evt_mouse.hpp \ events/evt_mouse.hpp \
...@@ -116,9 +117,12 @@ SOURCES_skins2 = \ ...@@ -116,9 +117,12 @@ SOURCES_skins2 = \
src/os_factory.hpp \ src/os_factory.hpp \
src/os_graphics.hpp \ src/os_graphics.hpp \
src/os_loop.hpp \ src/os_loop.hpp \
src/os_popup.hpp \
src/os_timer.hpp \ src/os_timer.hpp \
src/os_window.hpp \ src/os_window.hpp \
src/os_tooltip.hpp \ src/os_tooltip.hpp \
src/popup.cpp \
src/popup.hpp \
src/scaled_bitmap.cpp \ src/scaled_bitmap.cpp \
src/scaled_bitmap.hpp \ src/scaled_bitmap.hpp \
src/skin_main.cpp \ src/skin_main.cpp \
...@@ -183,6 +187,8 @@ SOURCES_skins2 = \ ...@@ -183,6 +187,8 @@ SOURCES_skins2 = \
win32/win32_graphics.hpp \ win32/win32_graphics.hpp \
win32/win32_loop.cpp \ win32/win32_loop.cpp \
win32/win32_loop.hpp \ win32/win32_loop.hpp \
win32/win32_popup.cpp \
win32/win32_popup.hpp \
win32/win32_timer.cpp \ win32/win32_timer.cpp \
win32/win32_timer.hpp \ win32/win32_timer.hpp \
win32/win32_tooltip.cpp \ win32/win32_tooltip.cpp \
...@@ -200,6 +206,8 @@ SOURCES_skins2 = \ ...@@ -200,6 +206,8 @@ SOURCES_skins2 = \
x11/x11_graphics.hpp \ x11/x11_graphics.hpp \
x11/x11_loop.cpp \ x11/x11_loop.cpp \
x11/x11_loop.hpp \ x11/x11_loop.hpp \
x11/x11_popup.cpp \
x11/x11_popup.hpp \
x11/x11_timer.cpp \ x11/x11_timer.cpp \
x11/x11_timer.hpp \ x11/x11_timer.hpp \
x11/x11_window.cpp \ x11/x11_window.cpp \
...@@ -215,6 +223,8 @@ SOURCES_skins2 = \ ...@@ -215,6 +223,8 @@ SOURCES_skins2 = \
macosx/macosx_graphics.hpp \ macosx/macosx_graphics.hpp \
macosx/macosx_loop.cpp \ macosx/macosx_loop.cpp \
macosx/macosx_loop.hpp \ macosx/macosx_loop.hpp \
macosx/macosx_popup.cpp \
macosx/macosx_popup.hpp \
macosx/macosx_timer.cpp \ macosx/macosx_timer.cpp \
macosx/macosx_timer.hpp \ macosx/macosx_timer.hpp \
macosx/macosx_window.cpp \ macosx/macosx_window.cpp \
......
...@@ -26,8 +26,10 @@ ...@@ -26,8 +26,10 @@
#define CMD_SHOW_WINDOW_HPP #define CMD_SHOW_WINDOW_HPP
#include "cmd_generic.hpp" #include "cmd_generic.hpp"
#include "../src/os_factory.hpp"
#include "../src/top_window.hpp" #include "../src/top_window.hpp"
#include "../src/window_manager.hpp" #include "../src/window_manager.hpp"
#include "../src/popup.hpp"
/// Command to show a window /// Command to show a window
...@@ -95,4 +97,30 @@ class CmdRaiseAll: public CmdGeneric ...@@ -95,4 +97,30 @@ class CmdRaiseAll: public CmdGeneric
WindowManager &m_rWinManager; WindowManager &m_rWinManager;
}; };
/// Command to show a popup menu
class CmdShowPopup: public CmdGeneric
{
public:
CmdShowPopup( intf_thread_t *pIntf, Popup &rPopup ):
CmdGeneric( pIntf ), m_rPopup( rPopup ) {}
virtual ~CmdShowPopup() {}
/// This method does the real job of the command
virtual void execute()
{
int x, y;
OSFactory::instance( getIntf() )->getMousePos( x, y );
m_rPopup.show( x, y );
}
/// Return the type of the command
virtual string getType() const { return "show popup"; }
private:
/// Reference to the popup
Popup &m_rPopup;
};
#endif #endif
/*****************************************************************************
* evt_menu.hpp
*****************************************************************************
* Copyright (C) 2003 the VideoLAN team
* $Id:$
*
* Authors: Olivier Teulière <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 EVT_MENU_HPP
#define EVT_MENU_HPP
#include "evt_generic.hpp"
/// Mouse move event
class EvtMenu: public EvtGeneric
{
public:
EvtMenu( intf_thread_t *pIntf, int itemId ):
EvtGeneric( pIntf ), m_itemId( itemId ) {}
virtual ~EvtMenu() {}
/// Return the type of event
virtual const string getAsString() const { return "menu"; }
// Getter
int getItemId() const { return m_itemId; }
private:
/// Coordinates of the mouse (absolute or relative)
int m_itemId;
};
#endif
...@@ -45,9 +45,11 @@ class EvtMotion: public EvtInput ...@@ -45,9 +45,11 @@ class EvtMotion: public EvtInput
private: private:
/// Coordinates of the mouse (absolute or relative) /// Coordinates of the mouse (absolute or relative)
/// The coordinates are absolute when the event is sent to the /**
/// GenericWindow, but are relative to the window when the event is * The coordinates are absolute when the event is sent to the
/// forwarded to the controls * GenericWindow, but are relative to the window when the event is
* forwarded to the controls
*/
int m_xPos, m_yPos; int m_xPos, m_yPos;
}; };
......
...@@ -93,6 +93,12 @@ OSTooltip *MacOSXFactory::createOSTooltip() ...@@ -93,6 +93,12 @@ OSTooltip *MacOSXFactory::createOSTooltip()
} }
OSPopup *MacOSXFactory::createOSPopup()
{
return new MacOSXPopup( getIntf() );
}
int MacOSXFactory::getScreenWidth() const int MacOSXFactory::getScreenWidth() const
{ {
// TODO // TODO
......
...@@ -37,13 +37,13 @@ class MacOSXFactory: public OSFactory ...@@ -37,13 +37,13 @@ class MacOSXFactory: public OSFactory
/// Initialization method /// Initialization method
virtual bool init(); virtual bool init();
/// Instantiate an object OSGraphics. /// Instantiate an object OSGraphics
virtual OSGraphics *createOSGraphics( int width, int height ); virtual OSGraphics *createOSGraphics( int width, int height );
/// Get the instance of the singleton OSLoop. /// Get the instance of the singleton OSLoop
virtual OSLoop *getOSLoop(); virtual OSLoop *getOSLoop();
/// Destroy the instance of OSLoop. /// Destroy the instance of OSLoop
virtual void destroyOSLoop(); virtual void destroyOSLoop();
/// Instantiate an OSTimer with the given callback /// Instantiate an OSTimer with the given callback
...@@ -57,9 +57,12 @@ class MacOSXFactory: public OSFactory ...@@ -57,9 +57,12 @@ class MacOSXFactory: public OSFactory
bool dragDrop, bool playOnDrop, bool dragDrop, bool playOnDrop,
OSWindow *pParent ); OSWindow *pParent );
/// Instantiate an object OSTooltip. /// Instantiate an object OSTooltip
virtual OSTooltip *createOSTooltip(); virtual OSTooltip *createOSTooltip();
/// Instantiate an object OSPopup
virtual OSPopup *createOSPopup();
/// Get the directory separator /// Get the directory separator
virtual const string &getDirSeparator() const { return m_dirSep; } virtual const string &getDirSeparator() const { return m_dirSep; }
......
/*****************************************************************************
* macosx_popup.cpp
*****************************************************************************
* Copyright (C) 2003 the VideoLAN team
* $Id$
*
* Authors: Olivier Teulière <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.
*****************************************************************************/
#ifdef MACOSX_SKINS
#include "macosx_popup.hpp"
MacOSXPopup::MacOSXPopup( intf_thread_t *pIntf )
: OSPopup( pIntf )
{
// TODO
}
MacOSXPopup::~MacOSXPopup()
{
// TODO
}
void MacOSXPopup::show( int xPos, int yPos )
{
// TODO
}
void MacOSXPopup::hide()
{
// TODO
}
void MacOSXPopup::addItem( const string &rLabel, int pos )
{
// TODO
}
void MacOSXPopup::addSeparator( int pos )
{
// TODO
}
int MacOSXPopup::getPosFromId( int id ) const
{
// TODO
}
#endif
/*****************************************************************************
* macosx_popup.hpp
*****************************************************************************
* Copyright (C) 2003 the VideoLAN team
* $Id$
*
* Authors: Olivier Teulière <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 MACOSX_POPUP_HPP
#define MACOSX_POPUP_HPP
#include "../src/os_popup.hpp"
/// MacOSX implementation of OSPopup
class MacOSXPopup: public OSPopup
{
public:
MacOSXPopup( intf_thread_t *pIntf );
virtual ~MacOSXPopup();
/// Show the popup menu at the given (absolute) corrdinates
virtual void show( int xPos, int yPos );
/// Hide the popup menu
virtual void hide();
/// Append a new menu item with the given label to the popup menu
virtual void addItem( const string &rLabel, int pos );
/// Create a dummy menu item to separate sections
virtual void addSeparator( int pos );
/// Return the position of the item identified by the given id
virtual int getPosFromId( int id ) const;
};
#endif
...@@ -37,10 +37,10 @@ class MacOSXTooltip: public OSTooltip ...@@ -37,10 +37,10 @@ class MacOSXTooltip: public OSTooltip
virtual ~MacOSXTooltip(); virtual ~MacOSXTooltip();
// Show the tooltip /// Show the tooltip
virtual void show( int left, int top, OSGraphics &rText ); virtual void show( int left, int top, OSGraphics &rText );
// Hide the tooltip /// Hide the tooltip
virtual void hide(); virtual void hide();
private: private:
......
...@@ -33,7 +33,10 @@ ...@@ -33,7 +33,10 @@
#include "../src/anchor.hpp" #include "../src/anchor.hpp"
#include "../src/bitmap_font.hpp" #include "../src/bitmap_font.hpp"
#include "../src/ft2_font.hpp" #include "../src/ft2_font.hpp"
#include "../src/generic_layout.hpp"
#include "../src/popup.hpp"
#include "../src/theme.hpp" #include "../src/theme.hpp"
#include "../commands/cmd_generic.hpp"
#include "../controls/ctrl_button.hpp" #include "../controls/ctrl_button.hpp"
#include "../controls/ctrl_checkbox.hpp" #include "../controls/ctrl_checkbox.hpp"
#include "../controls/ctrl_image.hpp" #include "../controls/ctrl_image.hpp"
...@@ -45,6 +48,7 @@ ...@@ -45,6 +48,7 @@
#include "../controls/ctrl_text.hpp" #include "../controls/ctrl_text.hpp"
#include "../controls/ctrl_tree.hpp" #include "../controls/ctrl_tree.hpp"
#include "../controls/ctrl_video.hpp" #include "../controls/ctrl_video.hpp"
#include "../utils/bezier.hpp"
#include "../utils/position.hpp" #include "../utils/position.hpp"
#include "../utils/var_bool.hpp" #include "../utils/var_bool.hpp"
#include "../utils/var_text.hpp" #include "../utils/var_text.hpp"
...@@ -95,6 +99,9 @@ Theme *Builder::build() ...@@ -95,6 +99,9 @@ Theme *Builder::build()
ADD_OBJECTS( BitmapFont ); ADD_OBJECTS( BitmapFont );
ADD_OBJECTS( Font ); ADD_OBJECTS( Font );
ADD_OBJECTS( Window ); ADD_OBJECTS( Window );
// XXX: PopupMenus are created after the windows, so that the Win32Factory
// (at least) can give a valid window handle to the OSPopup objects
ADD_OBJECTS( PopupMenu );
ADD_OBJECTS( Layout ); ADD_OBJECTS( Layout );
ADD_OBJECTS( Anchor ); ADD_OBJECTS( Anchor );
ADD_OBJECTS( Button ); ADD_OBJECTS( Button );
...@@ -106,6 +113,10 @@ Theme *Builder::build() ...@@ -106,6 +113,10 @@ Theme *Builder::build()
ADD_OBJECTS( List ); ADD_OBJECTS( List );
ADD_OBJECTS( Tree ); ADD_OBJECTS( Tree );
ADD_OBJECTS( Video ); ADD_OBJECTS( Video );
// MenuItems must be created after all the rest, so that the IDs of the
// other elements exist and can be parsed in the actions
ADD_OBJECTS( MenuItem );
ADD_OBJECTS( MenuSeparator );
return m_pTheme; return m_pTheme;
} }
...@@ -258,6 +269,47 @@ void Builder::addFont( const BuilderData::Font &rData ) ...@@ -258,6 +269,47 @@ void Builder::addFont( const BuilderData::Font &rData )
} }
void Builder::addPopupMenu( const BuilderData::PopupMenu &rData )
{
Popup *pPopup = new Popup( getIntf(), m_pTheme->getWindowManager() );
m_pTheme->m_popups[rData.m_id] = PopupPtr( pPopup );
}
void Builder::addMenuItem( const BuilderData::MenuItem &rData )
{
Popup *pPopup = m_pTheme->getPopupById( rData.m_popupId );
if( pPopup == NULL )
{
msg_Err( getIntf(), "Unknown popup id: %s", rData.m_popupId.c_str() );
return;
}
CmdGeneric *pCommand = parseAction( rData.m_action );
if( pCommand == NULL )
{
msg_Err( getIntf(), "Invalid action: %s", rData.m_action.c_str() );
return;
}
pPopup->addItem( rData.m_label, *pCommand, rData.m_pos );
}
void Builder::addMenuSeparator( const BuilderData::MenuSeparator &rData )
{
Popup *pPopup = m_pTheme->getPopupById( rData.m_popupId );
if( pPopup == NULL )
{
msg_Err( getIntf(), "Unknown popup id: %s", rData.m_popupId.c_str() );
return;
}
pPopup->addSeparator( rData.m_pos );
}
void Builder::addWindow( const BuilderData::Window &rData ) void Builder::addWindow( const BuilderData::Window &rData )
{ {
TopWindow *pWin = TopWindow *pWin =
...@@ -272,7 +324,7 @@ void Builder::addWindow( const BuilderData::Window &rData ) ...@@ -272,7 +324,7 @@ void Builder::addWindow( const BuilderData::Window &rData )
void Builder::addLayout( const BuilderData::Layout &rData ) void Builder::addLayout( const BuilderData::Layout &rData )
{ {
TopWindow *pWin = m_pTheme->getWindowById(rData.m_windowId); TopWindow *pWin = m_pTheme->getWindowById( rData.m_windowId );
if( pWin == NULL ) if( pWin == NULL )
{ {
msg_Err( getIntf(), "unknown window id: %s", rData.m_windowId.c_str() ); msg_Err( getIntf(), "unknown window id: %s", rData.m_windowId.c_str() );
...@@ -298,7 +350,7 @@ void Builder::addLayout( const BuilderData::Layout &rData ) ...@@ -298,7 +350,7 @@ void Builder::addLayout( const BuilderData::Layout &rData )
void Builder::addAnchor( const BuilderData::Anchor &rData ) void Builder::addAnchor( const BuilderData::Anchor &rData )
{ {
GenericLayout *pLayout = m_pTheme->getLayoutById(rData.m_layoutId); GenericLayout *pLayout = m_pTheme->getLayoutById( rData.m_layoutId );
if( pLayout == NULL ) if( pLayout == NULL )
{ {
msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() ); msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() );
...@@ -333,7 +385,7 @@ void Builder::addButton( const BuilderData::Button &rData ) ...@@ -333,7 +385,7 @@ void Builder::addButton( const BuilderData::Button &rData )
GenericBitmap *pBmpOver = pBmpUp; GenericBitmap *pBmpOver = pBmpUp;
GET_BMP( pBmpOver, rData.m_overId ); GET_BMP( pBmpOver, rData.m_overId );
GenericLayout *pLayout = m_pTheme->getLayoutById(rData.m_layoutId); GenericLayout *pLayout = m_pTheme->getLayoutById( rData.m_layoutId );
if( pLayout == NULL ) if( pLayout == NULL )
{ {
msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() ); msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() );
...@@ -390,7 +442,7 @@ void Builder::addCheckbox( const BuilderData::Checkbox &rData ) ...@@ -390,7 +442,7 @@ void Builder::addCheckbox( const BuilderData::Checkbox &rData )
GenericBitmap *pBmpOver2 = pBmpUp2; GenericBitmap *pBmpOver2 = pBmpUp2;
GET_BMP( pBmpOver2, rData.m_over2Id ); GET_BMP( pBmpOver2, rData.m_over2Id );
GenericLayout *pLayout = m_pTheme->getLayoutById(rData.m_layoutId); GenericLayout *pLayout = m_pTheme->getLayoutById( rData.m_layoutId );
if( pLayout == NULL ) if( pLayout == NULL )
{ {
msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() ); msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() );
...@@ -449,14 +501,14 @@ void Builder::addImage( const BuilderData::Image &rData ) ...@@ -449,14 +501,14 @@ void Builder::addImage( const BuilderData::Image &rData )
GenericBitmap *pBmp = NULL; GenericBitmap *pBmp = NULL;
GET_BMP( pBmp, rData.m_bmpId ); GET_BMP( pBmp, rData.m_bmpId );
GenericLayout *pLayout = m_pTheme->getLayoutById(rData.m_layoutId); GenericLayout *pLayout = m_pTheme->getLayoutById( rData.m_layoutId );
if( pLayout == NULL ) if( pLayout == NULL )
{ {
msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() ); msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() );
return; return;
} }
TopWindow *pWindow = m_pTheme->getWindowById(rData.m_windowId); TopWindow *pWindow = m_pTheme->getWindowById( rData.m_windowId );
if( pWindow == NULL ) if( pWindow == NULL )
{ {
msg_Err( getIntf(), "unknown window id: %s", rData.m_windowId.c_str() ); msg_Err( getIntf(), "unknown window id: %s", rData.m_windowId.c_str() );
...@@ -526,7 +578,7 @@ void Builder::addImage( const BuilderData::Image &rData ) ...@@ -526,7 +578,7 @@ void Builder::addImage( const BuilderData::Image &rData )
void Builder::addText( const BuilderData::Text &rData ) void Builder::addText( const BuilderData::Text &rData )
{ {
GenericLayout *pLayout = m_pTheme->getLayoutById(rData.m_layoutId); GenericLayout *pLayout = m_pTheme->getLayoutById( rData.m_layoutId );
if( pLayout == NULL ) if( pLayout == NULL )
{ {
msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() ); msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() );
...@@ -607,7 +659,7 @@ void Builder::addRadialSlider( const BuilderData::RadialSlider &rData ) ...@@ -607,7 +659,7 @@ void Builder::addRadialSlider( const BuilderData::RadialSlider &rData )
GenericBitmap *pSeq = NULL; GenericBitmap *pSeq = NULL;
GET_BMP( pSeq, rData.m_sequence ); GET_BMP( pSeq, rData.m_sequence );
GenericLayout *pLayout = m_pTheme->getLayoutById(rData.m_layoutId); GenericLayout *pLayout = m_pTheme->getLayoutById( rData.m_layoutId );
if( pLayout == NULL ) if( pLayout == NULL )
{ {
msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() ); msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() );
...@@ -661,7 +713,7 @@ void Builder::addSlider( const BuilderData::Slider &rData ) ...@@ -661,7 +713,7 @@ void Builder::addSlider( const BuilderData::Slider &rData )
GET_BMP( pBgImage, rData.m_imageId ); GET_BMP( pBgImage, rData.m_imageId );
} }
GenericLayout *pLayout = m_pTheme->getLayoutById(rData.m_layoutId); GenericLayout *pLayout = m_pTheme->getLayoutById( rData.m_layoutId );
if( pLayout == NULL ) if( pLayout == NULL )
{ {
msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() ); msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() );
...@@ -737,7 +789,7 @@ void Builder::addList( const BuilderData::List &rData ) ...@@ -737,7 +789,7 @@ void Builder::addList( const BuilderData::List &rData )
GenericBitmap *pBgBmp = NULL; GenericBitmap *pBgBmp = NULL;
GET_BMP( pBgBmp, rData.m_bgImageId ); GET_BMP( pBgBmp, rData.m_bgImageId );
GenericLayout *pLayout = m_pTheme->getLayoutById(rData.m_layoutId); GenericLayout *pLayout = m_pTheme->getLayoutById( rData.m_layoutId );
if( pLayout == NULL ) if( pLayout == NULL )
{ {
msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() ); msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() );
...@@ -793,7 +845,7 @@ void Builder::addTree( const BuilderData::Tree &rData ) ...@@ -793,7 +845,7 @@ void Builder::addTree( const BuilderData::Tree &rData )
GET_BMP( pOpenBmp, rData.m_openImageId ); GET_BMP( pOpenBmp, rData.m_openImageId );
GET_BMP( pClosedBmp, rData.m_closedImageId ); GET_BMP( pClosedBmp, rData.m_closedImageId );
GenericLayout *pLayout = m_pTheme->getLayoutById(rData.m_layoutId); GenericLayout *pLayout = m_pTheme->getLayoutById( rData.m_layoutId );
if( pLayout == NULL ) if( pLayout == NULL )
{ {
msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() ); msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() );
...@@ -840,7 +892,7 @@ void Builder::addTree( const BuilderData::Tree &rData ) ...@@ -840,7 +892,7 @@ void Builder::addTree( const BuilderData::Tree &rData )
void Builder::addVideo( const BuilderData::Video &rData ) void Builder::addVideo( const BuilderData::Video &rData )
{ {
GenericLayout *pLayout = m_pTheme->getLayoutById(rData.m_layoutId); GenericLayout *pLayout = m_pTheme->getLayoutById( rData.m_layoutId );
if( pLayout == NULL ) if( pLayout == NULL )
{ {
msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() ); msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() );
......
...@@ -26,20 +26,18 @@ ...@@ -26,20 +26,18 @@
#define BUILDER_HPP #define BUILDER_HPP
#include "builder_data.hpp" #include "builder_data.hpp"
#include "../src/os_graphics.hpp" #include "../src/skin_common.hpp"
#include "../src/generic_window.hpp"
#include "../src/generic_layout.hpp"
#include "../src/generic_bitmap.hpp"
#include "../src/generic_font.hpp"
#include "../commands/cmd_generic.hpp"
#include "../controls/ctrl_generic.hpp"
#include "../utils/bezier.hpp"
#include <string> #include <string>
#include <list> #include <list>
#include <map> #include <map>
class Theme; class Theme;
class Bezier;
class CmdGeneric;
class GenericFont;
class Position;
class Box;
/// Class for skin construction /// Class for skin construction
...@@ -71,6 +69,9 @@ class Builder: public SkinObject ...@@ -71,6 +69,9 @@ class Builder: public SkinObject
void addSubBitmap( const BuilderData::SubBitmap &rData ); void addSubBitmap( const BuilderData::SubBitmap &rData );
void addBitmapFont( const BuilderData::BitmapFont &rData ); void addBitmapFont( const BuilderData::BitmapFont &rData );
void addFont( const BuilderData::Font &rData ); void addFont( const BuilderData::Font &rData );
void addPopupMenu( const BuilderData::PopupMenu &rData );
void addMenuItem( const BuilderData::MenuItem &rData );
void addMenuSeparator( const BuilderData::MenuSeparator &rData );
void addWindow( const BuilderData::Window &rData ); void addWindow( const BuilderData::Window &rData );
void addLayout( const BuilderData::Layout &rData ); void addLayout( const BuilderData::Layout &rData );
void addAnchor( const BuilderData::Anchor &rData ); void addAnchor( const BuilderData::Anchor &rData );
...@@ -84,7 +85,7 @@ class Builder: public SkinObject ...@@ -84,7 +85,7 @@ class Builder: public SkinObject
void addTree( const BuilderData::Tree &rData ); void addTree( const BuilderData::Tree &rData );
void addVideo( const BuilderData::Video &rData ); void addVideo( const BuilderData::Video &rData );
/// Compute the position of a control /// Compute the position of a control
const Position makePosition( const string &rLeftTop, const Position makePosition( const string &rLeftTop,
const string &rRightBottom, const string &rRightBottom,
int xPos, int yPos, int width, int height, int xPos, int yPos, int width, int height,
......
...@@ -3,6 +3,9 @@ Bitmap id:string fileName:string alphaColor:uint32_t nbFrames:int fps:int ...@@ -3,6 +3,9 @@ Bitmap id:string fileName:string alphaColor:uint32_t nbFrames:int fps:int
SubBitmap id:string parent:string x:int y:int width:int height:int nbFrames:int fps:int SubBitmap id:string parent:string x:int y:int width:int height:int nbFrames:int fps:int
BitmapFont id:string file:string type:string BitmapFont id:string file:string type:string
Font id:string fontFile:string size:int Font id:string fontFile:string size:int
PopupMenu id:string
MenuItem label:string action:string pos:int popupId:string
MenuSeparator pos:int popupId:string
Window id:string xPos:int yPos:int visible:bool dragDrop:bool playOnDrop:bool Window id:string xPos:int yPos:int visible:bool dragDrop:bool playOnDrop:bool
Layout id:string width:int height:int minWidth:int maxWidth:int minHeight:int maxHeight:int windowId:string Layout id:string width:int height:int minWidth:int maxWidth:int minHeight:int maxHeight:int windowId:string
Anchor xPos:int yPos:int range:int priority:int points:string layoutId:string Anchor xPos:int yPos:int range:int priority:int points:string layoutId:string
......
...@@ -112,6 +112,43 @@ m_id( id ), m_fontFile( fontFile ), m_size( size ) {} ...@@ -112,6 +112,43 @@ m_id( id ), m_fontFile( fontFile ), m_size( size ) {}
/// List /// List
list<Font> m_listFont; list<Font> m_listFont;
/// Type definition
struct PopupMenu
{
PopupMenu( const string & id ):
m_id( id ) {}
string m_id;
};
/// List
list<PopupMenu> m_listPopupMenu;
/// Type definition
struct MenuItem
{
MenuItem( const string & label, const string & action, int pos, const string & popupId ):
m_label( label ), m_action( action ), m_pos( pos ), m_popupId( popupId ) {}
string m_label;
string m_action;
int m_pos;
string m_popupId;
};
/// List
list<MenuItem> m_listMenuItem;
/// Type definition
struct MenuSeparator
{
MenuSeparator( int pos, const string & popupId ):
m_pos( pos ), m_popupId( popupId ) {}
int m_pos;
string m_popupId;
};
/// List
list<MenuSeparator> m_listMenuSeparator;
/// Type definition /// Type definition
struct Window struct Window
{ {
......
...@@ -216,7 +216,17 @@ CmdGeneric *Interpreter::parseAction( const string &rAction, Theme *pTheme ) ...@@ -216,7 +216,17 @@ CmdGeneric *Interpreter::parseAction( const string &rAction, Theme *pTheme )
} }
else else
{ {
msg_Err( getIntf(), "Unknown window (%s)", windowId.c_str() ); // It was maybe the id of a popup
Popup *pPopup = pTheme->getPopupById( windowId );
if( pPopup )
{
pCommand = new CmdShowPopup( getIntf(), *pPopup );
}
else
{
msg_Err( getIntf(), "Unknown window or popup (%s)",
windowId.c_str() );
}
} }
} }
else if( rAction.find( ".hide()" ) != string::npos ) else if( rAction.find( ".hide()" ) != string::npos )
......
...@@ -129,6 +129,36 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr ) ...@@ -129,6 +129,36 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
m_pData->m_listBitmapFont.push_back( font ); m_pData->m_listBitmapFont.push_back( font );
} }
else if( rName == "PopupMenu" )
{
RequireDefault( "id" );
m_popupPosList.push_back(0);
m_curPopupId = uniqueId( attr["id"] );
const BuilderData::PopupMenu popup( m_curPopupId );
m_pData->m_listPopupMenu.push_back( popup );
}
else if( rName == "MenuItem" )
{
RequireDefault( "label" );
CheckDefault( "action", "none" );
const BuilderData::MenuItem item( attr["label"], attr["action"],
m_popupPosList.back(),
m_curPopupId );
m_pData->m_listMenuItem.push_back( item );
m_popupPosList.back()++;
}
else if( rName == "MenuSeparator" )
{
const BuilderData::MenuSeparator sep( m_popupPosList.back(),
m_curPopupId );
m_pData->m_listMenuSeparator.push_back( sep );
m_popupPosList.back()++;
}
else if( rName == "Button" ) else if( rName == "Button" )
{ {
RequireDefault( "up" ); RequireDefault( "up" );
...@@ -530,6 +560,11 @@ void SkinParser::handleEndElement( const string &rName ) ...@@ -530,6 +560,11 @@ void SkinParser::handleEndElement( const string &rName )
{ {
m_curTreeId = ""; m_curTreeId = "";
} }
else if( rName == "Popup" )
{
m_curPopupId = "";
m_popupPosList.pop_back();
}
} }
......
...@@ -51,8 +51,11 @@ class SkinParser: public XMLParser ...@@ -51,8 +51,11 @@ class SkinParser: public XMLParser
string m_curBitmapId; string m_curBitmapId;
string m_curWindowId; string m_curWindowId;
string m_curLayoutId; string m_curLayoutId;
string m_curPopupId;
string m_curListId; string m_curListId;
string m_curTreeId; string m_curTreeId;
/// Current position of menu items in the popups
list<int> m_popupPosList;
/// Current offset of the controls /// Current offset of the controls
int m_xOffset, m_yOffset; int m_xOffset, m_yOffset;
list<int> m_xOffsetList, m_yOffsetList; list<int> m_xOffsetList, m_yOffsetList;
......
...@@ -34,7 +34,7 @@ GenericWindow::GenericWindow( intf_thread_t *pIntf, int left, int top, ...@@ -34,7 +34,7 @@ GenericWindow::GenericWindow( intf_thread_t *pIntf, int left, int top,
SkinObject( pIntf ), m_left( left ), m_top( top ), m_width( 0 ), SkinObject( pIntf ), m_left( left ), m_top( top ), m_width( 0 ),
m_height( 0 ), m_varVisible( pIntf ) m_height( 0 ), m_varVisible( pIntf )
{ {
// Get the OSFactory // Get the OSFactory
OSFactory *pOsFactory = OSFactory::instance( getIntf() ); OSFactory *pOsFactory = OSFactory::instance( getIntf() );
// Get the parent OSWindow, if any // Get the parent OSWindow, if any
......
...@@ -32,6 +32,7 @@ class OSWindow; ...@@ -32,6 +32,7 @@ class OSWindow;
class EvtGeneric; class EvtGeneric;
class EvtFocus; class EvtFocus;
class EvtLeave; class EvtLeave;
class EvtMenu;
class EvtMotion; class EvtMotion;
class EvtMouse; class EvtMouse;
class EvtKey; class EvtKey;
...@@ -53,6 +54,7 @@ class GenericWindow: public SkinObject, public Observer<VarBool, void*> ...@@ -53,6 +54,7 @@ class GenericWindow: public SkinObject, public Observer<VarBool, void*>
/// Methods to process OS events. /// Methods to process OS events.
virtual void processEvent( EvtFocus &rEvtFocus ) {} virtual void processEvent( EvtFocus &rEvtFocus ) {}
virtual void processEvent( EvtMenu &rEvtMenu ) {}
virtual void processEvent( EvtMotion &rEvtMotion ) {} virtual void processEvent( EvtMotion &rEvtMotion ) {}
virtual void processEvent( EvtMouse &rEvtMouse ) {} virtual void processEvent( EvtMouse &rEvtMouse ) {}
virtual void processEvent( EvtLeave &rEvtLeave ) {} virtual void processEvent( EvtLeave &rEvtLeave ) {}
......
...@@ -37,6 +37,7 @@ class OSGraphics; ...@@ -37,6 +37,7 @@ class OSGraphics;
class OSLoop; class OSLoop;
class OSWindow; class OSWindow;
class OSTooltip; class OSTooltip;
class OSPopup;
class OSTimer; class OSTimer;
...@@ -53,24 +54,28 @@ class OSFactory: public SkinObject ...@@ -53,24 +54,28 @@ class OSFactory: public SkinObject
kResizeNESW kResizeNESW
}; };
/// Initialization method overloaded in derived classes. /**
/// It must return false if the init failed. * Initialization method overloaded in derived classes.
* It must return false if the init failed.
*/
virtual bool init() { return true; } virtual bool init() { return true; }
/// Get the right instance of OSFactory. /**
/// Returns NULL if initialization of the concrete factory failed. * Get the right instance of OSFactory.
* Returns NULL if initialization of the concrete factory failed.
*/
static OSFactory *instance( intf_thread_t *pIntf ); static OSFactory *instance( intf_thread_t *pIntf );
/// Delete the instance of OSFactory. /// Delete the instance of OSFactory
static void destroy( intf_thread_t *pIntf ); static void destroy( intf_thread_t *pIntf );
/// Instantiate an object OSGraphics. /// Instantiate an object OSGraphics
virtual OSGraphics *createOSGraphics( int width, int height ) = 0; virtual OSGraphics *createOSGraphics( int width, int height ) = 0;
/// Get the instance of the singleton OSLoop. /// Get the instance of the singleton OSLoop
virtual OSLoop *getOSLoop() = 0; virtual OSLoop *getOSLoop() = 0;
/// Destroy the instance of OSLoop. /// Destroy the instance of OSLoop
virtual void destroyOSLoop() = 0; virtual void destroyOSLoop() = 0;
/// ///
...@@ -79,14 +84,17 @@ class OSFactory: public SkinObject ...@@ -79,14 +84,17 @@ class OSFactory: public SkinObject
/// Instantiate an OSTimer with the given command /// Instantiate an OSTimer with the given command
virtual OSTimer *createOSTimer( CmdGeneric &rCmd ) = 0; virtual OSTimer *createOSTimer( CmdGeneric &rCmd ) = 0;
/// Instantiate an object OSWindow. /// Instantiate an object OSWindow
virtual OSWindow *createOSWindow( GenericWindow &rWindow, virtual OSWindow *createOSWindow( GenericWindow &rWindow,
bool dragDrop, bool playOnDrop, bool dragDrop, bool playOnDrop,
OSWindow *pParent ) = 0; OSWindow *pParent ) = 0;
/// Instantiate an object OSTooltip. /// Instantiate an object OSTooltip
virtual OSTooltip *createOSTooltip() = 0; virtual OSTooltip *createOSTooltip() = 0;
/// Instantiate an object OSPopup
virtual OSPopup *createOSPopup() = 0;
/// Get the directory separator /// Get the directory separator
virtual const string &getDirSeparator() const = 0; virtual const string &getDirSeparator() const = 0;
...@@ -110,7 +118,7 @@ class OSFactory: public SkinObject ...@@ -110,7 +118,7 @@ class OSFactory: public SkinObject
virtual void rmDir( const string &rPath ) = 0; virtual void rmDir( const string &rPath ) = 0;
protected: protected:
// Protected because it's a singleton. // Protected because it's a singleton
OSFactory( intf_thread_t* pIntf ): SkinObject( pIntf ) {} OSFactory( intf_thread_t* pIntf ): SkinObject( pIntf ) {}
virtual ~OSFactory() {} virtual ~OSFactory() {}
}; };
......
/*****************************************************************************
* os_popup.hpp
*****************************************************************************
* Copyright (C) 2003 the VideoLAN team
* $Id$
*
* Authors: Cyril Deguet <asmax@via.ecp.fr>
* Olivier Teulière <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 OS_POPUP_HPP
#define OS_POPUP_HPP
#include "skin_common.hpp"
#include <string>
class OSGraphics;
/// Base class for OS specific Popup Windows
class OSPopup: public SkinObject
{
public:
virtual ~OSPopup() {}
/// Show the popup menu at the given (absolute) corrdinates
virtual void show( int xPos, int yPos ) = 0;
/// Hide the popup menu
virtual void hide() = 0;
/// Append a new menu item with the given label to the popup menu
virtual void addItem( const string &rLabel, int pos ) = 0;
/// Create a dummy menu item to separate sections
virtual void addSeparator( int pos ) = 0;
/// Return the position of the item identified by the given id
virtual int getPosFromId( int id ) const = 0;
protected:
OSPopup( intf_thread_t *pIntf ): SkinObject( pIntf ) {}
};
#endif
...@@ -36,10 +36,10 @@ class OSTooltip: public SkinObject ...@@ -36,10 +36,10 @@ class OSTooltip: public SkinObject
public: public:
virtual ~OSTooltip() {} virtual ~OSTooltip() {}
// Show the tooltip /// Show the tooltip
virtual void show( int left, int top, OSGraphics &rText ) = 0; virtual void show( int left, int top, OSGraphics &rText ) = 0;
// Hide the tooltip /// Hide the tooltip
virtual void hide() = 0; virtual void hide() = 0;
protected: protected:
......
/*****************************************************************************
* popup.cpp
*****************************************************************************
* Copyright (C) 2003 the VideoLAN team
* $Id$
*
* 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
* 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 "popup.hpp"
#include "os_factory.hpp"
#include "os_popup.hpp"
#include "window_manager.hpp"
#include "../commands/cmd_generic.hpp"
#include "../events/evt_menu.hpp"
Popup::Popup( intf_thread_t *pIntf, WindowManager &rWindowManager )
: SkinObject( pIntf ), m_rWindowManager( rWindowManager )
{
// Get the OSFactory
OSFactory *pOsFactory = OSFactory::instance( getIntf() );
// Create an OSPopup to handle OS specific processing
m_pOsPopup = pOsFactory->createOSPopup();
}
void Popup::show( int xPos, int yPos )
{
// Notify that we are the active popup menu, so that the window which
// receives our menu events knows whom to forward them
m_rWindowManager.setActivePopup( *this );
m_pOsPopup->show( xPos, yPos );
}
void Popup::hide()
{
m_pOsPopup->hide();
}
void Popup::addItem( const string &rLabel, CmdGeneric &rCmd, int pos )
{
m_pOsPopup->addItem( rLabel, pos );
m_actions[pos] = &rCmd;
}
void Popup::addSeparator( int pos )
{
m_pOsPopup->addSeparator( pos );
m_actions[pos] = NULL;
}
void Popup::handleEvent( const EvtMenu &rEvent )
{
unsigned int n = m_pOsPopup->getPosFromId( rEvent.getItemId() );
if( n >= 0 && n < m_actions.size() && m_actions[n] )
{
m_actions[n]->execute();
}
else
{
// Should never happen
msg_Warn( getIntf(), "Problem in the popup implementation" );
}
}
/*****************************************************************************
* popup.hpp
*****************************************************************************
* Copyright (C) 2003 the VideoLAN team
* $Id$
*
* Authors: Olivier Teulière <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 POPUP_HPP
#define POPUP_HPP
#include "skin_common.hpp"
#include "../utils/pointer.hpp"
#include <string>
#include <map>
class OSPopup;
class TopWindow;
class CmdGeneric;
class WindowManager;
class EvtMenu;
/// Class handling a popup menu
class Popup: public SkinObject
{
public:
Popup( intf_thread_t *pIntf, WindowManager &rWindowManager );
virtual ~Popup() {}
void show( int xPos, int yPos );
void hide();
// XXX: it would be nice to use a UString here, if X11 supports it for
// its menu items (Windows doesn't, unfortunately)
/// Insert a new menu item to the popup menu, at the position pos
void addItem( const string &rLabel, CmdGeneric &rCmd, int pos );
/// Create a dummy menu item to separate sections
void addSeparator( int pos );
/// Execute the action corresponding to the chosen menu item
void handleEvent( const EvtMenu &rEvent );
private:
/// OS specific implementation
OSPopup *m_pOsPopup;
/// Window manager
WindowManager &m_rWindowManager;
/// Actions for the menu items, indexed by the position in the menu
map<int, CmdGeneric *> m_actions;
};
typedef CountedPtr<Popup> PopupPtr;
#endif
...@@ -164,6 +164,11 @@ GenericFont *Theme::getFontById( const string &id ) ...@@ -164,6 +164,11 @@ GenericFont *Theme::getFontById( const string &id )
FIND_FIRST_OBJECT( GenericFontPtr, m_fonts ); FIND_FIRST_OBJECT( GenericFontPtr, m_fonts );
} }
Popup *Theme::getPopupById( const string &id )
{
FIND_OBJECT( PopupPtr, m_popups );
}
TopWindow *Theme::getWindowById( const string &id ) TopWindow *Theme::getWindowById( const string &id )
{ {
FIND_OBJECT( TopWindowPtr, m_windows ); FIND_OBJECT( TopWindowPtr, m_windows );
......
...@@ -25,9 +25,10 @@ ...@@ -25,9 +25,10 @@
#ifndef THEME_HPP #ifndef THEME_HPP
#define THEME_HPP #define THEME_HPP
#include "../src/generic_bitmap.hpp" #include "generic_bitmap.hpp"
#include "../src/generic_font.hpp" #include "generic_font.hpp"
#include "../src/generic_layout.hpp" #include "generic_layout.hpp"
#include "popup.hpp"
#include "../src/window_manager.hpp" #include "../src/window_manager.hpp"
#include "../commands/cmd_generic.hpp" #include "../commands/cmd_generic.hpp"
#include "../utils/bezier.hpp" #include "../utils/bezier.hpp"
...@@ -56,6 +57,7 @@ class Theme: public SkinObject ...@@ -56,6 +57,7 @@ class Theme: public SkinObject
GenericBitmap *getBitmapById( const string &id ); GenericBitmap *getBitmapById( const string &id );
GenericFont *getFontById( const string &id ); GenericFont *getFontById( const string &id );
Popup *getPopupById( const string &id );
TopWindow *getWindowById( const string &id ); TopWindow *getWindowById( const string &id );
GenericLayout *getLayoutById( const string &id ); GenericLayout *getLayoutById( const string &id );
CtrlGeneric *getControlById( const string &id ); CtrlGeneric *getControlById( const string &id );
...@@ -67,6 +69,8 @@ class Theme: public SkinObject ...@@ -67,6 +69,8 @@ class Theme: public SkinObject
map<string, GenericBitmapPtr> m_bitmaps; map<string, GenericBitmapPtr> m_bitmaps;
/// Store the fonts by ID /// Store the fonts by ID
map<string, GenericFontPtr> m_fonts; map<string, GenericFontPtr> m_fonts;
/// Store the popups by ID
map<string, PopupPtr> m_popups;
/// Store the windows by ID /// Store the windows by ID
map<string, TopWindowPtr> m_windows; map<string, TopWindowPtr> m_windows;
/// Store the layouts by ID /// Store the layouts by ID
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "../events/evt_enter.hpp" #include "../events/evt_enter.hpp"
#include "../events/evt_focus.hpp" #include "../events/evt_focus.hpp"
#include "../events/evt_leave.hpp" #include "../events/evt_leave.hpp"
#include "../events/evt_menu.hpp"
#include "../events/evt_motion.hpp" #include "../events/evt_motion.hpp"
#include "../events/evt_mouse.hpp" #include "../events/evt_mouse.hpp"
#include "../events/evt_key.hpp" #include "../events/evt_key.hpp"
...@@ -87,7 +88,21 @@ void TopWindow::processEvent( EvtRefresh &rEvtRefresh ) ...@@ -87,7 +88,21 @@ void TopWindow::processEvent( EvtRefresh &rEvtRefresh )
void TopWindow::processEvent( EvtFocus &rEvtFocus ) void TopWindow::processEvent( EvtFocus &rEvtFocus )
{ {
// fprintf(stderr, rEvtFocus.getAsString().c_str()) ; // fprintf(stderr, rEvtFocus.getAsString().c_str());
}
void TopWindow::processEvent( EvtMenu &rEvtMenu )
{
Popup *pPopup = m_rWindowManager.getActivePopup();
// We should never receive a menu event when there is no active popup!
if( pPopup == NULL )
{
msg_Warn( getIntf(), "Unexpected menu event, ignoring" );
return;
}
pPopup->handleEvent( rEvtMenu );
} }
......
...@@ -50,6 +50,7 @@ class TopWindow: public GenericWindow ...@@ -50,6 +50,7 @@ class TopWindow: public GenericWindow
/// Methods to process OS events. /// Methods to process OS events.
virtual void processEvent( EvtRefresh &rEvtRefresh ); virtual void processEvent( EvtRefresh &rEvtRefresh );
virtual void processEvent( EvtFocus &rEvtFocus ); virtual void processEvent( EvtFocus &rEvtFocus );
virtual void processEvent( EvtMenu &rEvtMenu );
virtual void processEvent( EvtMotion &rEvtMotion ); virtual void processEvent( EvtMotion &rEvtMotion );
virtual void processEvent( EvtMouse &rEvtMouse ); virtual void processEvent( EvtMouse &rEvtMouse );
virtual void processEvent( EvtLeave &rEvtLeave ); virtual void processEvent( EvtLeave &rEvtLeave );
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
WindowManager::WindowManager( intf_thread_t *pIntf ): WindowManager::WindowManager( intf_thread_t *pIntf ):
SkinObject( pIntf ), m_magnet( 0 ), m_pTooltip( NULL ) SkinObject( pIntf ), m_magnet( 0 ), m_pTooltip( NULL ), m_pPopup( NULL )
{ {
// Create and register a variable for the "on top" status // Create and register a variable for the "on top" status
VarManager *pVarManager = VarManager::instance( getIntf() ); VarManager *pVarManager = VarManager::instance( getIntf() );
......
...@@ -37,6 +37,7 @@ class GenericFont; ...@@ -37,6 +37,7 @@ class GenericFont;
class GenericLayout; class GenericLayout;
class Anchor; class Anchor;
class Tooltip; class Tooltip;
class Popup;
/// Window manager for skin windows /// Window manager for skin windows
...@@ -116,16 +117,25 @@ class WindowManager: public SkinObject ...@@ -116,16 +117,25 @@ class WindowManager: public SkinObject
/// Change the active layout of the given window /// Change the active layout of the given window
void setActiveLayout( TopWindow &rWindow, GenericLayout &rLayout ); void setActiveLayout( TopWindow &rWindow, GenericLayout &rLayout );
/// Mark the given popup as active
void setActivePopup( Popup &rPopup ) { m_pPopup = &rPopup; }
/// Return the active popup, or NULL if none is active
Popup * getActivePopup() const { return m_pPopup; }
private: private:
/// Some useful typedefs for lazy people like me /// Some useful typedefs for lazy people like me
typedef set<TopWindow*> WinSet_t; typedef set<TopWindow*> WinSet_t;
typedef list<Anchor*> AncList_t; typedef list<Anchor*> AncList_t;
/// This map represents the graph of anchored windows: it associates /// Dependencies map
/// to a given window all the windows that are directly anchored by it. /**
/// This is not transitive, i.e. if a is in m_dep[b] and if b is in * This map represents the graph of anchored windows: it associates
/// m_dep[c], it doesn't mean that a is in m_dep[c] (in fact, it * to a given window all the windows that are directly anchored by it.
/// would be extremely rare...) * This is not transitive, i.e. if a is in m_dep[b] and if b is in
* m_dep[c], it doesn't mean that a is in m_dep[c] (in fact, it
* would be extremely rare...)
*/
map<TopWindow*, WinSet_t> m_dependencies; map<TopWindow*, WinSet_t> m_dependencies;
/// Store all the windows /// Store all the windows
WinSet_t m_allWindows; WinSet_t m_allWindows;
...@@ -142,12 +152,17 @@ class WindowManager: public SkinObject ...@@ -142,12 +152,17 @@ class WindowManager: public SkinObject
int m_moveAlpha; int m_moveAlpha;
/// Tooltip /// Tooltip
Tooltip *m_pTooltip; Tooltip *m_pTooltip;
/// Active popup, if any
Popup *m_pPopup;
/// Recursively build a set of windows anchored to the one given. /// Recursively build a set of windows anchored to the one given.
void buildDependSet( WinSet_t &rWinSet, TopWindow *pWindow ); void buildDependSet( WinSet_t &rWinSet, TopWindow *pWindow );
/// Check anchoring: this function updates xOffset and yOffset, /// Check anchoring
/// to take care of a new anchoring (if any) /**
* This function updates xOffset and yOffset, to take care of a new
* anchoring (if any)
*/
void checkAnchors( TopWindow *pWindow, void checkAnchors( TopWindow *pWindow,
int &xOffset, int &yOffset ) const; int &xOffset, int &yOffset ) const;
}; };
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "win32_timer.hpp" #include "win32_timer.hpp"
#include "win32_window.hpp" #include "win32_window.hpp"
#include "win32_tooltip.hpp" #include "win32_tooltip.hpp"
#include "win32_popup.hpp"
#include "win32_loop.hpp" #include "win32_loop.hpp"
#include "../src/theme.hpp" #include "../src/theme.hpp"
...@@ -257,6 +258,23 @@ OSTooltip *Win32Factory::createOSTooltip() ...@@ -257,6 +258,23 @@ OSTooltip *Win32Factory::createOSTooltip()
} }
OSPopup *Win32Factory::createOSPopup()
{
// XXX FIXME: this way of getting the handle really sucks!
// In fact, the clean way would be to have in Builder::addPopup() a call
// to pPopup->associateToWindow() (to be written)... but the problem is
// that there is no way to access the OS-dependent window handle from a
// GenericWindow (we cannot eevn access the OSWindow).
if( m_windowMap.begin() == m_windowMap.end() )
{
msg_Err( getIntf(), "No window has been created before the popup!" );
return NULL;
}
return new Win32Popup( getIntf(), m_windowMap.begin()->first );
}
int Win32Factory::getScreenWidth() const int Win32Factory::getScreenWidth() const
{ {
return GetSystemMetrics(SM_CXSCREEN); return GetSystemMetrics(SM_CXSCREEN);
......
...@@ -44,13 +44,13 @@ class Win32Factory: public OSFactory ...@@ -44,13 +44,13 @@ class Win32Factory: public OSFactory
/// Initialization method /// Initialization method
virtual bool init(); virtual bool init();
/// Instantiate an object OSGraphics. /// Instantiate an object OSGraphics
virtual OSGraphics *createOSGraphics( int width, int height ); virtual OSGraphics *createOSGraphics( int width, int height );
/// Get the instance of the singleton OSLoop. /// Get the instance of the singleton OSLoop
virtual OSLoop *getOSLoop(); virtual OSLoop *getOSLoop();
/// Destroy the instance of OSLoop. /// Destroy the instance of OSLoop
virtual void destroyOSLoop(); virtual void destroyOSLoop();
/// ///
...@@ -64,9 +64,12 @@ class Win32Factory: public OSFactory ...@@ -64,9 +64,12 @@ class Win32Factory: public OSFactory
bool dragDrop, bool playOnDrop, bool dragDrop, bool playOnDrop,
OSWindow *pParent ); OSWindow *pParent );
/// Instantiate an object OSTooltip. /// Instantiate an object OSTooltip
virtual OSTooltip *createOSTooltip(); virtual OSTooltip *createOSTooltip();
/// Instantiate an object OSPopup
virtual OSPopup *createOSPopup();
/// Get the directory separator /// Get the directory separator
virtual const string &getDirSeparator() const { return m_dirSep; } virtual const string &getDirSeparator() const { return m_dirSep; }
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "../src/generic_window.hpp" #include "../src/generic_window.hpp"
#include "../events/evt_key.hpp" #include "../events/evt_key.hpp"
#include "../events/evt_leave.hpp" #include "../events/evt_leave.hpp"
#include "../events/evt_menu.hpp"
#include "../events/evt_motion.hpp" #include "../events/evt_motion.hpp"
#include "../events/evt_mouse.hpp" #include "../events/evt_mouse.hpp"
#include "../events/evt_refresh.hpp" #include "../events/evt_refresh.hpp"
...@@ -132,6 +133,12 @@ void Win32Loop::run() ...@@ -132,6 +133,12 @@ void Win32Loop::run()
win.processEvent( evt ); win.processEvent( evt );
break; break;
} }
case WM_COMMAND:
{
EvtMenu evt( getIntf(), LOWORD( msg.wParam ) );
win.processEvent( evt );
break;
}
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
{ {
// Needed to generate WM_MOUSELEAVE events // Needed to generate WM_MOUSELEAVE events
......
/*****************************************************************************
* win32_popup.cpp
*****************************************************************************
* Copyright (C) 2003 the VideoLAN team
* $Id$
*
* 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
* 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.
*****************************************************************************/
#ifdef WIN32_SKINS
#include "win32_popup.hpp"
#include "win32_factory.hpp"
#ifndef TPM_NOANIMATION
const UINT TPM_NOANIMATION = 0x4000L;
#endif
Win32Popup::Win32Popup( intf_thread_t *pIntf, HWND hAssociatedWindow )
: OSPopup( pIntf ), m_hWnd( hAssociatedWindow )
{
// Create the popup menu
m_hMenu = CreatePopupMenu();
if( !m_hMenu )
{
msg_Err( getIntf(), "CreatePopupMenu failed" );
return;
}
}
Win32Popup::~Win32Popup()
{
if( m_hMenu )
DestroyMenu( m_hMenu );
}
void Win32Popup::show( int xPos, int yPos )
{
TrackPopupMenuEx( m_hMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON
| TPM_HORIZONTAL | TPM_NOANIMATION,
xPos, yPos, m_hWnd, NULL );
}
void Win32Popup::hide()
{
SendMessage( m_hWnd, WM_CANCELMODE, 0, 0 );
}
void Win32Popup::addItem( const string &rLabel, int pos )
{
MENUITEMINFO menuItem;
menuItem.cbSize = sizeof( MENUITEMINFO );
// menuItem.fMask = MIIM_FTYPE | MIIM_ID | MIIM_TYPE | MIIM_STRING;
// menuItem.fType = MFT_STRING;
menuItem.fMask = MIIM_ID | MIIM_STRING;
menuItem.wID = pos;
menuItem.dwTypeData = (char*)rLabel.c_str();
menuItem.cch = rLabel.size();
InsertMenuItem( m_hMenu, findInsertionPoint( pos ), TRUE, &menuItem );
}
void Win32Popup::addSeparator( int pos )
{
MENUITEMINFO sepItem;
sepItem.cbSize = sizeof( MENUITEMINFO );
sepItem.fMask = MIIM_FTYPE;
sepItem.fType = MFT_SEPARATOR;
InsertMenuItem( m_hMenu, findInsertionPoint( pos ), TRUE, &sepItem );
}
unsigned int Win32Popup::findInsertionPoint( unsigned int pos ) const
{
// For this simple algorithm, we rely on the fact that in the final state
// of the menu, the ID of each item is equal to its position in the menu
int i = 0;
while( i < GetMenuItemCount( m_hMenu ) &&
GetMenuItemID( m_hMenu, i ) < pos )
{
i++;
}
return i;
}
#endif
/*****************************************************************************
* win32_popup.hpp
*****************************************************************************
* Copyright (C) 2003 the VideoLAN team
* $Id$
*
* Authors: Olivier Teulière <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 WIN32_POPUP_HPP
#define WIN32_POPUP_HPP
#include "../src/os_popup.hpp"
#include <windows.h>
/// Win32 implementation of OSPopup
class Win32Popup: public OSPopup
{
public:
Win32Popup( intf_thread_t *pIntf, HWND hAssociatedWindow );
virtual ~Win32Popup();
/// Show the popup menu at the given (absolute) corrdinates
virtual void show( int xPos, int yPos );
/// Hide the popup menu
virtual void hide();
/// Append a new menu item with the given label to the popup menu
virtual void addItem( const string &rLabel, int pos );
/// Create a dummy menu item to separate sections
virtual void addSeparator( int pos );
/// Return the position of the item identified by the given id
virtual int getPosFromId( int id ) const { return id; }
private:
/// Menu handle
HMENU m_hMenu;
/// Handle of the window which will receive the menu events
HWND m_hWnd;
/**
* Find the item before which to insert another item so that the
* newly added item is at the position pos _when the whole menu has
* been built_ (no assumption is made for the order of insertion of the
* items)
*/
unsigned int findInsertionPoint( unsigned int pos ) const;
};
#endif
...@@ -38,10 +38,10 @@ class Win32Tooltip: public OSTooltip ...@@ -38,10 +38,10 @@ class Win32Tooltip: public OSTooltip
virtual ~Win32Tooltip(); virtual ~Win32Tooltip();
// Show the tooltip /// Show the tooltip
virtual void show( int left, int top, OSGraphics &rText ); virtual void show( int left, int top, OSGraphics &rText );
// Hide the tooltip /// Hide the tooltip
virtual void hide(); virtual void hide();
private: private:
......
...@@ -122,6 +122,12 @@ OSTooltip *X11Factory::createOSTooltip() ...@@ -122,6 +122,12 @@ OSTooltip *X11Factory::createOSTooltip()
} }
OSPopup *X11Factory::createOSPopup()
{
return new X11Popup( getIntf(), *m_pDisplay );
}
int X11Factory::getScreenWidth() const int X11Factory::getScreenWidth() const
{ {
Display *pDisplay = m_pDisplay->getDisplay(); Display *pDisplay = m_pDisplay->getDisplay();
......
...@@ -50,13 +50,13 @@ class X11Factory: public OSFactory ...@@ -50,13 +50,13 @@ class X11Factory: public OSFactory
/// Initialization method /// Initialization method
virtual bool init(); virtual bool init();
/// Instantiate an object OSGraphics. /// Instantiate an object OSGraphics
virtual OSGraphics *createOSGraphics( int width, int height ); virtual OSGraphics *createOSGraphics( int width, int height );
/// Get the instance of the singleton OSLoop. /// Get the instance of the singleton OSLoop
virtual OSLoop *getOSLoop(); virtual OSLoop *getOSLoop();
/// Destroy the instance of OSLoop. /// Destroy the instance of OSLoop
virtual void destroyOSLoop(); virtual void destroyOSLoop();
/// Instantiate an OSTimer with the given command /// Instantiate an OSTimer with the given command
...@@ -70,9 +70,12 @@ class X11Factory: public OSFactory ...@@ -70,9 +70,12 @@ class X11Factory: public OSFactory
bool dragDrop, bool playOnDrop, bool dragDrop, bool playOnDrop,
OSWindow *pParent ); OSWindow *pParent );
/// Instantiate an object OSTooltip. /// Instantiate an object OSTooltip
virtual OSTooltip *createOSTooltip(); virtual OSTooltip *createOSTooltip();
/// Instantiate an object OSPopup
virtual OSPopup *createOSPopup();
/// Get the directory separator /// Get the directory separator
virtual const string &getDirSeparator() const { return m_dirSep; } virtual const string &getDirSeparator() const { return m_dirSep; }
......
/*****************************************************************************
* x11_popup.cpp
*****************************************************************************
* Copyright (C) 2003 the VideoLAN team
* $Id$
*
* Authors: Olivier Teulière <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.
*****************************************************************************/
#ifdef X11_SKINS
#include "x11_popup.hpp"
X11Popup::X11Popup( intf_thread_t *pIntf )
: OSPopup( pIntf )
{
// TODO
}
X11Popup::~X11Popup()
{
// TODO
}
void X11Popup::show( int xPos, int yPos )
{
// TODO
}
void X11Popup::hide()
{
// TODO
}
void X11Popup::addItem( const string &rLabel, int pos )
{
// TODO
}
void X11Popup::addSeparator( int pos )
{
// TODO
}
int X11Popup::getPosFromId( int id ) const
{
// TODO
}
#endif
/*****************************************************************************
* x11_popup.hpp
*****************************************************************************
* Copyright (C) 2003 the VideoLAN team
* $Id$
*
* Authors: Olivier Teulière <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 X11_POPUP_HPP
#define X11_POPUP_HPP
#include "../src/os_popup.hpp"
/// X11 implementation of OSPopup
class X11Popup: public OSPopup
{
public:
X11Popup( intf_thread_t *pIntf );
virtual ~X11Popup();
/// Show the popup menu at the given (absolute) corrdinates
virtual void show( int xPos, int yPos );
/// Hide the popup menu
virtual void hide();
/// Append a new menu item with the given label to the popup menu
virtual void addItem( const string &rLabel, int pos );
/// Create a dummy menu item to separate sections
virtual void addSeparator( int pos );
/// Return the position of the item identified by the given id
virtual int getPosFromId( int id ) const;
};
#endif
...@@ -40,10 +40,10 @@ class X11Tooltip: public OSTooltip ...@@ -40,10 +40,10 @@ class X11Tooltip: public OSTooltip
virtual ~X11Tooltip(); virtual ~X11Tooltip();
// Show the tooltip /// Show the tooltip
virtual void show( int left, int top, OSGraphics &rText ); virtual void show( int left, int top, OSGraphics &rText );
// Hide the tooltip /// Hide the tooltip
virtual void hide(); virtual void hide();
private: private:
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
--> -->
<!ELEMENT Theme (ThemeInfo,(Include|Bitmap|BitmapFont|Font|Window)*)> <!ELEMENT Theme (ThemeInfo,(Include|Bitmap|BitmapFont|Font|PopupMenu|Window)*)>
<!ATTLIST Theme <!ATTLIST Theme
version CDATA #REQUIRED version CDATA #REQUIRED
tooltipfont CDATA "defaultfont" tooltipfont CDATA "defaultfont"
...@@ -46,6 +46,16 @@ ...@@ -46,6 +46,16 @@
file CDATA #REQUIRED file CDATA #REQUIRED
type CDATA "digits" type CDATA "digits"
> >
<!ELEMENT PopupMenu (MenuItem|MenuSeparator)+>
<!ATTLIST PopupMenu
id CDATA #REQUIRED
>
<!ELEMENT MenuItem EMPTY>
<!ATTLIST MenuItem
label CDATA #REQUIRED
action CDATA "none"
>
<!ELEMENT MenuSeparator EMPTY>
<!ELEMENT ThemeInfo EMPTY> <!ELEMENT ThemeInfo EMPTY>
<!ATTLIST ThemeInfo <!ATTLIST ThemeInfo
name CDATA #IMPLIED name CDATA #IMPLIED
......
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