Commit c7e38315 authored by Antoine Cellerier's avatar Antoine Cellerier

* Playtree start. Basic functionalities work. Still needs a lot of

   work, cleaning and fixing. I'll continue this weekend.
parent 4d282645
......@@ -20,6 +20,8 @@ SOURCES_skins2 = \
commands/cmd_on_top.hpp \
commands/cmd_playlist.cpp \
commands/cmd_playlist.hpp \
commands/cmd_playtree.cpp \
commands/cmd_playtree.hpp \
commands/cmd_minimize.cpp \
commands/cmd_minimize.hpp \
commands/cmd_quit.cpp \
......@@ -41,6 +43,8 @@ SOURCES_skins2 = \
controls/ctrl_image.hpp \
controls/ctrl_list.cpp \
controls/ctrl_list.hpp \
controls/ctrl_tree.cpp \
controls/ctrl_tree.hpp \
controls/ctrl_move.cpp \
controls/ctrl_move.hpp \
controls/ctrl_resize.cpp \
......@@ -153,9 +157,13 @@ SOURCES_skins2 = \
utils/var_percent.hpp \
utils/var_text.cpp \
utils/var_text.hpp \
utils/var_tree.cpp \
utils/var_tree.hpp \
\
vars/playlist.cpp \
vars/playlist.hpp \
vars/playtree.cpp \
vars/playtree.hpp \
vars/time.cpp \
vars/time.hpp \
vars/volume.cpp \
......
......@@ -48,6 +48,8 @@ typedef CmdDialogs<12> CmdDlgPlaylistLoad;
typedef CmdDialogs<13> CmdDlgPlaylistSave;
typedef CmdDialogs<14> CmdDlgDirectory;
typedef CmdDialogs<15> CmdDlgStreamingWizard;
typedef CmdDialogs<16> CmdDlgPlaytreeLoad;
typedef CmdDialogs<17> CmdDlgPlaytreeSave;
/// Generic "Open dialog" command
......
/*****************************************************************************
* cmd_playtree.cpp
*****************************************************************************
* Copyright (C) 2005 VideoLAN
* $Id: cmd_playlist.cpp 10101 2005-03-02 16:47:31Z robux4 $
*
* Authors: Antoine Cellerier <dionoea@videolan.org>
*
* 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 "cmd_playtree.hpp"
#include "../src/vlcproc.hpp"
#include "../utils/var_bool.hpp"
void CmdPlaytreeDel::execute()
{
m_rTree.delSelected();
}
void CmdPlaytreeSort::execute()
{
// TODO
}
void CmdPlaytreeNext::execute()
{
// TODO
}
void CmdPlaytreePrevious::execute()
{
// TODO
}
void CmdPlaytreeRandom::execute()
{
// TODO
}
void CmdPlaytreeLoop::execute()
{
// TODO
}
void CmdPlaytreeRepeat::execute()
{
// TODO
}
void CmdPlaytreeLoad::execute()
{
// TODO
}
void CmdPlaytreeSave::execute()
{
// TODO
}
/*****************************************************************************
* cmd_playtree.hpp
*****************************************************************************
* Copyright (C) 2005 VideoLAN
* $Id: cmd_playlist.hpp 9934 2005-02-15 13:55:08Z courmisch $
*
* Authors: Antoine Cellerier <dionoea@videolan.org>
*
* 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 CMD_PLAYTREE_HPP
#define CMD_PLAYTREE_HPP
#include "cmd_generic.hpp"
#include "../utils/var_tree.hpp"
// TODO : implement branch specific stuff
/// Command to delete the selected items from a tree
class CmdPlaytreeDel: public CmdGeneric
{
public:
CmdPlaytreeDel( intf_thread_t *pIntf, VarTree &rTree ):
CmdGeneric( pIntf ), m_rTree( rTree ) {}
virtual ~CmdPlaytreeDel() {}
/// This method does the real job of the command
virtual void execute();
/// Return the type of the command
virtual string getType() const { return "playtree del"; }
private:
/// Tree
VarTree &m_rTree;
};
/// Command to sort the playtree
DEFINE_COMMAND( PlaytreeSort, "playtree sort" )
/// Command to jump to the next item
DEFINE_COMMAND( PlaytreeNext, "playtree next" )
/// Command to jump to the previous item
DEFINE_COMMAND( PlaytreePrevious, "playtree previous" )
/// Command to set the random state
class CmdPlaytreeRandom: public CmdGeneric
{
public:
CmdPlaytreeRandom( intf_thread_t *pIntf, bool value ):
CmdGeneric( pIntf ), m_value( value ) {}
virtual ~CmdPlaytreeRandom() {}
/// This method does the real job of the command
virtual void execute();
/// Return the type of the command
virtual string getType() const { return "playtree random"; }
private:
/// Random state
bool m_value;
};
/// Command to set the loop state
class CmdPlaytreeLoop: public CmdGeneric
{
public:
CmdPlaytreeLoop( intf_thread_t *pIntf, bool value ):
CmdGeneric( pIntf ), m_value( value ) {}
virtual ~CmdPlaytreeLoop() {}
/// This method does the real job of the command
virtual void execute();
/// Return the type of the command
virtual string getType() const { return "playtree loop"; }
private:
/// Loop state
bool m_value;
};
/// Command to set the repeat state
class CmdPlaytreeRepeat: public CmdGeneric
{
public:
CmdPlaytreeRepeat( intf_thread_t *pIntf, bool value ):
CmdGeneric( pIntf ), m_value( value ) {}
virtual ~CmdPlaytreeRepeat() {}
/// This method does the real job of the command
virtual void execute();
/// Return the type of the command
virtual string getType() const { return "playtree repeat"; }
private:
/// Loop state
bool m_value;
};
/// Command to load a playlist
class CmdPlaytreeLoad: public CmdGeneric
{
public:
CmdPlaytreeLoad( intf_thread_t *pIntf, bool value ):
CmdGeneric( pIntf ), m_value( value ) {}
virtual ~CmdPlaytreeLoad() {}
/// This method does the real job of the command
virtual void execute();
/// Return the type of the command
virtual string getType() const { return "playtree load"; }
private:
/// Loop state
bool m_value;
};
/// Command to save a playlist
class CmdPlaytreeSave: public CmdGeneric
{
public:
CmdPlaytreeSave( intf_thread_t *pIntf, bool value ):
CmdGeneric( pIntf ), m_value( value ) {}
virtual ~CmdPlaytreeSave() {}
/// This method does the real job of the command
virtual void execute();
/// Return the type of the command
virtual string getType() const { return "playtree save"; }
private:
/// Loop state
bool m_value;
};
#endif
......@@ -25,6 +25,7 @@
#include "../src/vlcproc.hpp"
#include "../utils/var_text.hpp"
#include "../vars/playlist.hpp"
#include "../vars/playtree.hpp"
void CmdNotifyPlaylist::execute()
......@@ -34,6 +35,13 @@ void CmdNotifyPlaylist::execute()
rVar.onChange();
}
void CmdNotifyPlaytree::execute()
{
// Notify the playtree variable
Playtree &rVar = VlcProc::instance( getIntf() )->getPlaytreeVar();
rVar.onChange();
}
void CmdSetText::execute()
{
......
......@@ -31,6 +31,8 @@ class VarText;
/// Command to notify the playlist of a change
DEFINE_COMMAND( NotifyPlaylist, "notify playlist" )
/// Command to notify the playtree of a change
DEFINE_COMMAND( NotifyPlaytree, "notify playtree" )
/// Command to set a text variable
......
......@@ -481,8 +481,8 @@ void CtrlList::makeImage()
int yPos = 0;
for( it = m_rList[m_lastPos]; it != m_rList.end() && yPos < height; it++ )
{
UString *pStr = (UString*)((*it).m_cString.get());
uint32_t color = ( (*it).m_playing ? m_playColor : m_fgColor );
UString *pStr = (UString*)(it->m_cString.get());
uint32_t color = ( it->m_playing ? m_playColor : m_fgColor );
// Draw the text
GenericBitmap *pText = m_rFont.drawString( *pStr, color, width );
......
/*****************************************************************************
* ctrl_tree.cpp
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: ctrl_list.cpp 11009 2005-05-14 14:39:05Z ipkiss $
*
* Authors: Antoine Cellerier <dionoea@videolan.org>
*
* 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 <math.h>
#include "ctrl_tree.hpp"
#include "../src/os_factory.hpp"
#include "../src/os_graphics.hpp"
#include "../src/generic_bitmap.hpp"
#include "../src/generic_font.hpp"
#include "../src/scaled_bitmap.hpp"
#include "../utils/position.hpp"
#include "../utils/ustring.hpp"
#include "../events/evt_key.hpp"
#include "../events/evt_mouse.hpp"
#include "../events/evt_scroll.hpp"
#include "vlc_keys.h"
#ifdef sun
# include "solaris_specific.h" // for lrint
#endif
#define SCROLL_STEP 0.05
#define LINE_INTERVAL 1 // Number of pixels inserted between 2 lines
CtrlTree::CtrlTree( intf_thread_t *pIntf,
VarTree &rTree,
const GenericFont &rFont,
const GenericBitmap *pBgBitmap,
const GenericBitmap *pItemBitmap,
const GenericBitmap *pOpenBitmap,
const GenericBitmap *pClosedBitmap,
uint32_t fgColor,
uint32_t playColor,
uint32_t bgColor1,
uint32_t bgColor2,
uint32_t selColor,
const UString &rHelp,
VarBool *pVisible ):
CtrlGeneric( pIntf,rHelp, pVisible), m_rTree( rTree), m_rFont( rFont ),
m_pBgBitmap( pBgBitmap ), m_pItemBitmap( pItemBitmap ),
m_pOpenBitmap( pOpenBitmap ), m_pClosedBitmap( pClosedBitmap ),
m_fgColor( fgColor ), m_playColor( playColor ), m_bgColor1( bgColor1 ),
m_bgColor2( bgColor2 ), m_selColor( selColor ),
m_pLastSelected( NULL ), m_pImage( NULL )
{
// Observe the tree and position variables
m_rTree.addObserver( this );
m_rTree.getPositionVar().addObserver( this );
m_lastPos = m_rTree.begin();
makeImage();
}
CtrlTree::~CtrlTree()
{
m_rTree.getPositionVar().delObserver( this );
m_rTree.delObserver( this );
if( m_pImage )
{
delete m_pImage;
}
}
int CtrlTree::itemHeight()
{
int itemHeight = m_rFont.getSize();
if( m_pClosedBitmap )
{
itemHeight = __MAX( m_pClosedBitmap->getHeight(), itemHeight );
}
if( m_pOpenBitmap )
{
itemHeight = __MAX( m_pOpenBitmap->getHeight(), itemHeight );
}
if( m_pItemBitmap )
{
itemHeight = __MAX( m_pItemBitmap->getHeight(), itemHeight );
}
itemHeight += LINE_INTERVAL;
return itemHeight;
}
int CtrlTree::maxItems()
{
const Position *pPos = getPosition();
if( !pPos )
{
return -1;
}
return pPos->getHeight() / itemHeight();
}
void CtrlTree::onUpdate( Subject<VarTree> &rTree )
{
autoScroll();
m_pLastSelected = NULL;
}
void CtrlTree::onUpdate( Subject<VarPercent> &rPercent )
{
// Determine what is the first item to display
VarTree::Iterator it = m_rTree.begin();
int excessItems = m_rTree.visibleItems() - maxItems();
if( excessItems > 0)
{
VarPercent &rVarPos = m_rTree.getPositionVar();
// a simple (int)(...) causes rounding errors !
#ifdef _MSC_VER
# define lrint (int)
#endif
it = m_rTree.visibleItem(lrint( (1.0 - rVarPos.get()) * (double)excessItems ) + 1); /* FIXME : shouldn't need this +1 */
}
if( m_lastPos != it )
{
// Redraw the control if the position has changed
m_lastPos = it;
makeImage();
notifyLayout();
}
}
void CtrlTree::onResize()
{
// FIXME : shouldn't be the same as the onUpdate function ... but i'm lazy
// Determine what is the first item to display
VarTree::Iterator it = m_rTree.begin();
int excessItems = m_rTree.visibleItems() - maxItems();
if( excessItems > 0)
{
VarPercent &rVarPos = m_rTree.getPositionVar();
// a simple (int)(...) causes rounding errors !
#ifdef _MSC_VER
# define lrint (int)
#endif
it = m_rTree.visibleItem(lrint( (1.0 - rVarPos.get()) * (double)excessItems ) + 1); /* FIXME : shouldn't need this +1 */
}
// Redraw the control if the position has changed
m_lastPos = it;
makeImage();
notifyLayout();
#if 0
// Determine what is the first item to display
VarTree::Iterator it = m_rTree.begin();
int excessItems = m_rTree.visibleItems() - maxItems();
if( excessItems > 0)
{
/* FIXME VarPercent &rVarPos = m_rTree.getPositionVar();
double newVal = 1.0 - (double)m_lastPos / excessItems;
if( newVal >= 0 )
{
// Change the position to keep the same first displayed item
rVarPos.set( 1.0 - (double)m_lastPos / excessItems );
}
else
{
// We cannot keep the current first item
m_lastPos = excessItems;
}*/
it = m_rTree.visibleItem( excessItems );
}
makeImage();
notifyLayout();
#endif
}
void CtrlTree::onPositionChange()
{
makeImage();
notifyLayout();
}
#define IT_DISP_LOOP_END( a ) \
if( a ->m_expanded && a ->size() ) \
{ \
a = a ->begin(); \
} \
else \
{ \
VarTree::Iterator it_old = a; \
a ++; \
if( it_old->parent() && it_old->parent()->end() == a ) \
{ \
a = it_old->uncle(); \
} \
}
void CtrlTree::handleEvent( EvtGeneric &rEvent )
{
// TODO TODO FIXME TODO TODO
if( rEvent.getAsString().find( "key:down" ) != string::npos )
{
int key = ((EvtKey&)rEvent).getKey();
VarTree::Iterator it = m_rTree.begin();
bool previousWasSelected = false;
while( it != m_rTree.end() )
{
VarTree::Iterator next = it;
IT_DISP_LOOP_END( next );
if( key == KEY_UP )
{
//Scroll up one item
if( ( it->parent()
&& it != it->parent()->begin() )
|| &*it != m_pLastSelected )
{
bool nextWasSelected = ( &*next == m_pLastSelected );
it->m_selected = nextWasSelected;
if( nextWasSelected )
{
m_pLastSelected = &*it;
}
}
}
else if( key == KEY_DOWN )
{
// Scroll down one item
if( ( it->parent()
&& next != it->parent()->end() )
|| &*it != m_pLastSelected )
{
(*it).m_selected = previousWasSelected;
}
if( previousWasSelected )
{
m_pLastSelected = &*it;
previousWasSelected = false;
}
else
{
previousWasSelected = ( &*it == m_pLastSelected );
}
}
else if( key == KEY_RIGHT )
{
// Go down one level
if( it->m_expanded )
{
if( it->size() )
{
/* FIXME : finir */
m_pLastSelected = &*(it->begin());
}
}
else
{
it->m_expanded = true;
}
}
else if( key == KEY_LEFT )
{
// Go up one level (and close node)
// TODO
it->m_expanded = false;
}
it = next;
}
// Redraw the control
makeImage();
notifyLayout();
}
else if( rEvent.getAsString().find( "mouse:left" ) != string::npos )
{
EvtMouse &rEvtMouse = (EvtMouse&)rEvent;
const Position *pos = getPosition();
int yPos = ( rEvtMouse.getYPos() - pos->getTop() ) / itemHeight();
VarTree::Iterator it;
int index = 0;
// TODO : add all other mouse controls
/**/ if( rEvent.getAsString().find( "mouse:left:down" ) !=
string::npos )
{
for( it = m_lastPos; it != m_rTree.end(); )
{
if( index == yPos )
{
it->m_selected = true;
m_pLastSelected = &*it;
}
else
{
it->m_selected = false;
}
index ++;
IT_DISP_LOOP_END( it );
}
}
else if( rEvent.getAsString().find( "mouse:left:dblclick" ) !=
string::npos )
{
for( it = m_lastPos; it != m_rTree.end(); )
{
if( index == yPos )
{
it->m_selected = true;
m_pLastSelected = &*it;
// Execute the action associated to this item
m_rTree.action( &*it );
}
else
{
it->m_selected = false;
}
index ++;
IT_DISP_LOOP_END( it );
}
}
// Redraw the control
makeImage();
notifyLayout();
}
else if( rEvent.getAsString().find( "scroll" ) != string::npos )
{
int direction = ((EvtScroll&)rEvent).getDirection();
double percentage = m_rTree.getPositionVar().get();
if( direction == EvtScroll::kUp )
{
percentage += SCROLL_STEP;
}
else
{
percentage -= SCROLL_STEP;
}
m_rTree.getPositionVar().set( percentage );
}
}
bool CtrlTree::mouseOver( int x, int y ) const
{
const Position *pPos = getPosition();
return ( pPos
? x >= 0 && x <= pPos->getWidth() && y >= 0 && y <= pPos->getHeight()
: false);
}
void CtrlTree::draw( OSGraphics &rImage, int xDest, int yDest )
{
if( m_pImage )
{
rImage.drawGraphics( *m_pImage, 0, 0, xDest, yDest );
}
}
void CtrlTree::autoScroll()
{
// TODO FIXME TODO
makeImage();
notifyLayout();
}
void CtrlTree::makeImage()
{
if( m_pImage )
{
delete m_pImage;
}
// Get the size of the control
const Position *pPos = getPosition();
if( !pPos )
{
return;
}
int width = pPos->getWidth();
int height = pPos->getHeight();
int i_itemHeight = itemHeight();
// Create an image
OSFactory *pOsFactory = OSFactory::instance( getIntf() );
m_pImage = pOsFactory->createOSGraphics( width, height );
VarTree::Iterator it = m_lastPos;
if( m_pBgBitmap )
{
// Draw the background bitmap
ScaledBitmap bmp( getIntf(), *m_pBgBitmap, width, height );
m_pImage->drawBitmap( bmp, 0, 0 );
// FIXME : Take care of the selection color
for( int yPos = 0; yPos < height; yPos += i_itemHeight )
{
int rectHeight = __MIN( i_itemHeight, height - yPos );
if( it != m_rTree.end() )
{
if( (*it).m_selected )
{
m_pImage->fillRect( 0, yPos, width, rectHeight,
m_selColor );
}
IT_DISP_LOOP_END( it );
}
}
}
else
{
// FIXME (TRYME)
// Fill background with background color
uint32_t bgColor = m_bgColor1;
m_pImage->fillRect( 0, 0, width, height, bgColor );
for( int yPos = 0; yPos < height; yPos += i_itemHeight )
{
int rectHeight = __MIN( i_itemHeight, height - yPos );
if( it != m_rTree.end() )
{
uint32_t color = ( it->m_selected ? m_selColor : bgColor );
m_pImage->fillRect( 0, yPos, width, rectHeight, color );
IT_DISP_LOOP_END( it );
}
else
{
m_pImage->fillRect( 0, yPos, width, rectHeight, bgColor );
}
bgColor = ( bgColor == m_bgColor1 ? m_bgColor2 : m_bgColor1 );
}
}
// fprintf( stderr, "done\n");
int bitmapWidth = 5;
if( m_pClosedBitmap )
{
bitmapWidth = __MAX( m_pClosedBitmap->getWidth(), bitmapWidth );
}
if( m_pOpenBitmap )
{
bitmapWidth = __MAX( m_pOpenBitmap->getWidth(), bitmapWidth );
}
if( m_pItemBitmap )
{
bitmapWidth = __MAX( m_pItemBitmap->getWidth(), bitmapWidth );
}
bitmapWidth += 2;
// FIXME : Draw the items
int yPos = 0;
it = m_lastPos;
while( it != m_rTree.end() && yPos < height )
{
const GenericBitmap *m_pCurBitmap;
UString *pStr = (UString*)(it->m_cString.get());
uint32_t color = ( it->m_playing ? m_playColor : m_fgColor );
// Draw the text
if( pStr != NULL ){
int depth = it->depth();
GenericBitmap *pText = m_rFont.drawString( *pStr, color, width - bitmapWidth * depth );
if( !pText )
{
return;
}
m_pCurBitmap = it->size() ? ( it->m_expanded ? m_pOpenBitmap : m_pClosedBitmap ) : m_pItemBitmap ;
if( m_pCurBitmap )
{
int yPos2 = yPos+(i_itemHeight-m_pCurBitmap->getHeight()+1)/2;
m_pImage->drawBitmap( *m_pCurBitmap, 0, 0, bitmapWidth * (depth - 1 ), yPos2, m_pCurBitmap->getWidth(), __MIN( m_pCurBitmap->getHeight(), height - yPos2), true );
}
else
{
/* it would be nice to draw something */
}
yPos += i_itemHeight - pText->getHeight();
int ySrc = 0;
if( yPos < 0 )
{
ySrc = - yPos;
yPos = 0;
}
int lineHeight = __MIN( pText->getHeight() - ySrc, height - yPos );
m_pImage->drawBitmap( *pText, 0, ySrc, bitmapWidth * depth, yPos,
pText->getWidth(),
lineHeight, true );
yPos += (pText->getHeight() - ySrc );
delete pText;
}
IT_DISP_LOOP_END( it );
}
}
/*****************************************************************************
* ctrl_tree.hpp
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: ctrl_list.hpp 11009 2005-05-14 14:39:05Z ipkiss $
*
* Authors: Antoine Cellerier
*
* 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 CTRL_TREE_HPP
#define CTRL_TREE_HPP
#include "ctrl_generic.hpp"
#include "../utils/observer.hpp"
#include "../utils/var_tree.hpp"
class OSGraphics;
class GenericFont;
class GenericBitmap;
/// Class for control tree
class CtrlTree: public CtrlGeneric, public Observer<VarTree>,
public Observer<VarPercent>
{
public:
CtrlTree( intf_thread_t *pIntf,
VarTree &rTree,
const GenericFont &rFont,
const GenericBitmap *pBgBitmap,
const GenericBitmap *pItemBitmap,
const GenericBitmap *pOpenBitmap,
const GenericBitmap *pClosedBitmap,
uint32_t fgColor,
uint32_t playColor,
uint32_t bgColor1,
uint32_t bgColor2,
uint32_t selColor,
const UString &rHelp,
VarBool *pVisible );
virtual ~CtrlTree();
/// Handle an event on the control
virtual void handleEvent( EvtGeneric &rEvent );
/// Check whether coordinates are inside the control
virtual bool mouseOver( int x, int y ) const;
/// Draw the control on the given graphics
virtual void draw( OSGraphics &rImage, int xDest, int yDest );
/// Called when the layout is resized
virtual void onResize();
/// Return true if the control can gain the focus
virtual bool isFocusable() const { return true; }
/// Get the type of control (custom RTTI)
virtual string getType() const { return "tree"; }
private:
/// Tree associated to the control
VarTree &m_rTree;
/// Font
const GenericFont &m_rFont;
/// Background bitmap
const GenericBitmap *m_pBgBitmap;
/// Item (leaf) bitmap
// (TODO : add different bitmaps for different item types
// like in the wx playlist)
const GenericBitmap *m_pItemBitmap;
/// Open (expanded) node bitmap
const GenericBitmap *m_pOpenBitmap;
/// Closed node bitmap
const GenericBitmap *m_pClosedBitmap;
/// Color of normal test
uint32_t m_fgColor;
/// Color of the playing item
uint32_t m_playColor;
/// Background colors, used when no background bitmap is given
uint32_t m_bgColor1, m_bgColor2;
/// Background of selected items
uint32_t m_selColor;
/// Pointer on the last selected item in the tree
VarTree *m_pLastSelected;
/// Image of the control
OSGraphics *m_pImage;
/// Last position
VarTree::Iterator m_lastPos;
/// Method called when the tree variable is modified
virtual void onUpdate( Subject<VarTree> &rTree );
// Method called when the position variable of the tree is modified
virtual void onUpdate( Subject<VarPercent> &rPercent );
/// Called when the position is set
virtual void onPositionChange();
/// Compute the number of lines that can be displayed
int maxItems();
/// Compute the item's height (depends on fonts and images used)
int itemHeight();
/// Check if the tree must be scrolled
void autoScroll();
/// Draw the image of the control
void makeImage();
};
#endif
......@@ -43,6 +43,7 @@
#include "../controls/ctrl_slider.hpp"
#include "../controls/ctrl_radialslider.hpp"
#include "../controls/ctrl_text.hpp"
#include "../controls/ctrl_tree.hpp"
#include "../controls/ctrl_video.hpp"
#include "../utils/position.hpp"
#include "../utils/var_bool.hpp"
......@@ -101,6 +102,7 @@ Theme *Builder::build()
ADD_OBJECTS( RadialSlider );
ADD_OBJECTS( Slider );
ADD_OBJECTS( List );
ADD_OBJECTS( Tree );
ADD_OBJECTS( Video );
return m_pTheme;
......@@ -628,6 +630,62 @@ void Builder::addList( const BuilderData::List &rData )
m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pList );
}
void Builder::addTree( const BuilderData::Tree &rData )
{
// Get the bitmaps, if any
GenericBitmap *pBgBmp = NULL;
GenericBitmap *pItemBmp = NULL;
GenericBitmap *pOpenBmp = NULL;
GenericBitmap *pClosedBmp = NULL;
GET_BMP( pBgBmp, rData.m_bgImageId );
GET_BMP( pItemBmp, rData.m_itemImageId );
GET_BMP( pOpenBmp, rData.m_openImageId );
GET_BMP( pClosedBmp, rData.m_closedImageId );
GenericLayout *pLayout = m_pTheme->getLayoutById(rData.m_layoutId);
if( pLayout == NULL )
{
msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() );
return;
}
GenericFont *pFont = getFont( rData.m_fontId );
if( pFont == NULL )
{
msg_Err( getIntf(), "Unknown font id: %s", rData.m_fontId.c_str() );
return;
}
// Get the list variable
Interpreter *pInterpreter = Interpreter::instance( getIntf() );
VarTree *pVar = pInterpreter->getVarTree( rData.m_var, m_pTheme );
if( pVar == NULL )
{
msg_Err( getIntf(), "No such list variable: %s", rData.m_var.c_str() );
return;
}
// Get the visibility variable
// XXX check when it is null
VarBool *pVisible = pInterpreter->getVarBool( rData.m_visible, m_pTheme );
// Create the list control
CtrlTree *pTree = new CtrlTree( getIntf(), *pVar, *pFont, pBgBmp,
pItemBmp, pOpenBmp, pClosedBmp,
rData.m_fgColor, rData.m_playColor, rData.m_bgColor1,
rData.m_bgColor2, rData.m_selColor,
UString( getIntf(), rData.m_help.c_str() ), pVisible );
// Compute the position of the control
const Position pos = makePosition( rData.m_leftTop, rData.m_rightBottom,
rData.m_xPos, rData.m_yPos,
rData.m_width, rData.m_height,
*pLayout );
pLayout->addControl( pTree, pos, rData.m_layer );
m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pTree );
}
void Builder::addVideo( const BuilderData::Video &rData )
{
......
......@@ -77,6 +77,7 @@ class Builder: public SkinObject
void addRadialSlider( const BuilderData::RadialSlider &rData );
void addSlider( const BuilderData::Slider &rData );
void addList( const BuilderData::List &rData );
void addTree( const BuilderData::Tree &rData );
void addVideo( const BuilderData::Video &rData );
/// Compute the position of a control
......
......@@ -12,4 +12,5 @@ Text id:string xPos:int yPos:int visible:string fontId:string text:string width:
RadialSlider id:string visible:string xPos:int yPos:int leftTop:string rightBottom:string sequence:string nbImages:int minAngle:float maxAngle:float value:string tooltip:string help:string layer:int windowId:string layoutId:string
Slider id:string visible:string xPos:int yPos:int leftTop:string rightBottom:string upId:string downId:string overId:string points:string thickness:int value:string tooltip:string help:string layer:int windowId:string layoutId:string
List id:string xPos:int yPos:int visible:string width:int height:int leftTop:string rightBottom:string fontId:string var:string bgImageId:string fgColor:uint32_t playColor:uint32_t bgColor1:uint32_t bgColor2:uint32_t selColor:uint32_t help:string layer:int windowId:string layoutId:string
Tree id:string xPos:int yPos:int visible:string width:int height:int leftTop:string rightBottom:string fontId:string var:string bgImageId:string itemImageId:string openImageId:string closedImageId:string fgColor:uint32_t playColor:uint32_t bgColor1:uint32_t bgColor2:uint32_t selColor:uint32_t help:string layer:int windowId:string layoutId:string
Video id:string xPos:int yPos:int width:int height:int leftTop:string rightBottom:string visible:string help:string layer:int windowId:string layoutId:string
......@@ -5,7 +5,7 @@
* $Id$
*
* Authors: Cyril Deguet <asmax@via.ecp.fr>
* Olivier Teulière <ipkiss@via.ecp.fr>
* 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
......@@ -328,6 +328,39 @@ m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_visible( visible ), m_width( width
/// List
list<List> m_listList;
/// Type definition
struct Tree
{
Tree( const string & id, int xPos, int yPos, const string & visible, int width, int height, const string & leftTop, const string & rightBottom, const string & fontId, const string & var, const string & bgImageId, const string & itemImageId, const string & openImageId, const string & closedImageId, uint32_t fgColor, uint32_t playColor, uint32_t bgColor1, uint32_t bgColor2, uint32_t selColor, const string & help, int layer, const string & windowId, const string & layoutId ):
m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_visible( visible ), m_width( width ), m_height( height ), m_leftTop( leftTop ), m_rightBottom( rightBottom ), m_fontId( fontId ), m_var( var ), m_bgImageId( bgImageId ), m_itemImageId( itemImageId ), m_openImageId( openImageId ), m_closedImageId( closedImageId ), m_fgColor( fgColor ), m_playColor( playColor ), m_bgColor1( bgColor1 ), m_bgColor2( bgColor2 ), m_selColor( selColor ), m_help( help ), m_layer( layer ), m_windowId( windowId ), m_layoutId( layoutId ) {}
const string m_id;
int m_xPos;
int m_yPos;
const string m_visible;
int m_width;
int m_height;
const string m_leftTop;
const string m_rightBottom;
const string m_fontId;
const string m_var;
const string m_bgImageId;
const string m_itemImageId;
const string m_openImageId;
const string m_closedImageId;
uint32_t m_fgColor;
uint32_t m_playColor;
uint32_t m_bgColor1;
uint32_t m_bgColor2;
uint32_t m_selColor;
const string m_help;
int m_layer;
const string m_windowId;
const string m_layoutId;
};
/// List
list<Tree> m_listTree;
/// Type definition
struct Video
{
......
......@@ -18,7 +18,7 @@ hppfile.write(
* $Id$
*
* Authors: Cyril Deguet <asmax@via.ecp.fr>
* Olivier Teulire <ipkiss@via.ecp.fr>
* 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
......
......@@ -26,6 +26,7 @@
#include "expr_evaluator.hpp"
#include "../commands/cmd_muxer.hpp"
#include "../commands/cmd_playlist.hpp"
#include "../commands/cmd_playtree.hpp"
#include "../commands/cmd_dialogs.hpp"
#include "../commands/cmd_dummy.hpp"
#include "../commands/cmd_layout.hpp"
......@@ -79,6 +80,27 @@ Interpreter::Interpreter( intf_thread_t *pIntf ): SkinObject( pIntf )
CmdGenericPtr( new CmdPlaylistRepeat( getIntf(), true ) );
m_commandMap["playlist.setRepeat(false)"] =
CmdGenericPtr( new CmdPlaylistRepeat( getIntf(), false ) );
REGISTER_CMD( "playtree.load()", CmdDlgPlaytreeLoad )
REGISTER_CMD( "playtree.save()", CmdDlgPlaytreeSave )
REGISTER_CMD( "playtree.add()", CmdDlgAdd )
VarTree &rVarTree = VlcProc::instance( getIntf() )->getPlaytreeVar();
m_commandMap["playtree.del()"] =
CmdGenericPtr( new CmdPlaytreeDel( getIntf(), rVarTree ) );
REGISTER_CMD( "playtree.next()", CmdPlaytreeNext )
REGISTER_CMD( "playtree.previous()", CmdPlaytreePrevious )
REGISTER_CMD( "playtree.sort()", CmdPlaytreeSort )
m_commandMap["playtree.setRandom(true)"] =
CmdGenericPtr( new CmdPlaytreeRandom( getIntf(), true ) );
m_commandMap["playtree.setRandom(false)"] =
CmdGenericPtr( new CmdPlaytreeRandom( getIntf(), false ) );
m_commandMap["playtree.setLoop(true)"] =
CmdGenericPtr( new CmdPlaytreeLoop( getIntf(), true ) );
m_commandMap["playtree.setLoop(false)"] =
CmdGenericPtr( new CmdPlaytreeLoop( getIntf(), false ) );
m_commandMap["playtree.setRepeat(true)"] =
CmdGenericPtr( new CmdPlaytreeRepeat( getIntf(), true ) );
m_commandMap["playtree.setRepeat(false)"] =
CmdGenericPtr( new CmdPlaytreeRepeat( getIntf(), false ) );
REGISTER_CMD( "vlc.fullscreen()", CmdFullscreen )
REGISTER_CMD( "vlc.play()", CmdPlay )
REGISTER_CMD( "vlc.pause()", CmdPause )
......@@ -362,3 +384,10 @@ VarList *Interpreter::getVarList( const string &rName, Theme *pTheme )
return pVar;
}
VarTree *Interpreter::getVarTree( const string &rName, Theme *pTheme )
{
// Try to get the variable from the variable manager
VarManager *pVarManager = VarManager::instance( getIntf() );
VarTree *pVar = (VarTree*)pVarManager->getVar( rName, "tree" );
return pVar;
}
......@@ -31,6 +31,7 @@
class Theme;
class VarBool;
class VarList;
class VarTree;
class VarPercent;
......@@ -59,6 +60,9 @@ class Interpreter: public SkinObject
/// Returns the list variable corresponding to the given name
VarList *getVarList( const string &rName, Theme *pTheme );
/// Returns the tree variable corresponding to the given name
VarTree *getVarTree( const string &rName, Theme *pTheme );
private:
/// Map of global commands
map<string, CmdGenericPtr> m_commandMap;
......
......@@ -239,6 +239,46 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
m_data.m_listList.push_back( listData );
}
else if( rName == "Playtree" )
{
RequireDefault( "id" );
RequireDefault( "font" );
CheckDefault( "visible", "true" );
CheckDefault( "x", "0" );
CheckDefault( "y", "0" );
CheckDefault( "width", "0" );
CheckDefault( "height", "0" );
CheckDefault( "lefttop", "lefttop" );
CheckDefault( "rightbottom", "lefttop" );
CheckDefault( "bgimage", "none" );
CheckDefault( "itemimage", "none" );
CheckDefault( "openimage", "none" );
CheckDefault( "closedimage", "none" );
CheckDefault( "fgcolor", "#000000" );
CheckDefault( "playcolor", "#FF0000" );
CheckDefault( "bgcolor1", "#FFFFFF" );
CheckDefault( "bgcolor2", "#FFFFFF" );
CheckDefault( "selcolor", "#0000FF" );
CheckDefault( "help", "" );
m_curListId = uniqueId( attr["id"] );
const BuilderData::Tree treeData( m_curListId, atoi( attr["x"] ) +
m_xOffset, atoi( attr["y"] ) + m_yOffset, attr["visible"],
atoi( attr["width"]), atoi( attr["height"] ),
attr["lefttop"], attr["rightbottom"],
attr["font"], "playtree",
attr["bgimage"], attr["itemimage"],
attr["openimage"], attr["closedimage"],
convertColor( attr["fgcolor"] ),
convertColor( attr["playcolor"] ),
convertColor( attr["bgcolor1"] ),
convertColor( attr["bgcolor2"] ),
convertColor( attr["selcolor"] ), attr["help"],
m_curLayer, m_curWindowId, m_curLayoutId );
m_curLayer++;
m_data.m_listTree.push_back( treeData );
}
else if( rName == "RadialSlider" )
{
RequireDefault( "sequence" );
......@@ -291,6 +331,8 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
{
// Slider associated to a list
newValue = "playlist.slider";
// FIXME
newValue = "playtree.slider";
}
const BuilderData::Slider slider( uniqueId( attr["id"] ),
attr["visible"],
......@@ -409,7 +451,7 @@ void SkinParser::handleEndElement( const string &rName )
m_yOffsetList.pop_back();
}
else if( rName == "Playlist" )
else if( rName == "Playlist" || rName == "Playtree" )
{
m_curListId = "";
}
......
......@@ -27,6 +27,7 @@
#include "../commands/cmd_change_skin.hpp"
#include "../commands/cmd_quit.hpp"
#include "../commands/cmd_playlist.hpp"
#include "../commands/cmd_playtree.hpp"
/// Callback called when a new skin is chosen
......@@ -71,6 +72,7 @@ void Dialogs::showPlaylistLoadCB( intf_dialog_args_t *pArg )
// Push the command in the asynchronous command queue
AsyncQueue *pQueue = AsyncQueue::instance( pIntf );
pQueue->remove( "load playlist" );
pQueue->remove( "load playtree" );
pQueue->push( CmdGenericPtr( pCmd ) );
}
}
......@@ -89,6 +91,7 @@ void Dialogs::showPlaylistSaveCB( intf_dialog_args_t *pArg )
// Push the command in the asynchronous command queue
AsyncQueue *pQueue = AsyncQueue::instance( pIntf );
pQueue->remove( "load playlist" );
pQueue->remove( "load playtree" );
pQueue->push( CmdGenericPtr( pCmd ) );
}
}
......
......@@ -80,6 +80,12 @@ VlcProc::VlcProc( intf_thread_t *pIntf ): SkinObject( pIntf ), m_pVout( NULL ),
REGISTER_VAR( m_cVarRandom, VarBoolImpl, "playlist.isRandom" )
REGISTER_VAR( m_cVarLoop, VarBoolImpl, "playlist.isLoop" )
REGISTER_VAR( m_cVarRepeat, VarBoolImpl, "playlist.isRepeat" )
REGISTER_VAR( m_cPlaytree, Playtree, "playtree" )
pVarManager->registerVar( getPlaytreeVar().getPositionVarPtr(),
"playtree.slider" );
REGISTER_VAR( m_cVarRandom, VarBoolImpl, "playtree.isRandom" )
REGISTER_VAR( m_cVarLoop, VarBoolImpl, "playtree.isLoop" )
REGISTER_VAR( m_cVarRepeat, VarBoolImpl, "playtree.isRepeat" )
REGISTER_VAR( m_cVarTime, StreamTime, "time" )
REGISTER_VAR( m_cVarVolume, Volume, "volume" )
REGISTER_VAR( m_cVarMute, VarBoolImpl, "vlc.isMute" )
......@@ -292,11 +298,15 @@ int VlcProc::onIntfChange( vlc_object_t *pObj, const char *pVariable,
// Create a playlist notify command
CmdNotifyPlaylist *pCmd = new CmdNotifyPlaylist( pThis->getIntf() );
// Create a playtree notify command
CmdNotifyPlaytree *pCmdTree = new CmdNotifyPlaytree( pThis->getIntf() );
// Push the command in the asynchronous command queue
AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
pQueue->remove( "notify playlist" );
pQueue->remove( "notify playtree" );
pQueue->push( CmdGenericPtr( pCmd ) );
pQueue->push( CmdGenericPtr( pCmdTree ) );
return VLC_SUCCESS;
}
......@@ -337,11 +347,15 @@ int VlcProc::onItemChange( vlc_object_t *pObj, const char *pVariable,
// Create a playlist notify command
// TODO: selective update
CmdNotifyPlaylist *pCmd = new CmdNotifyPlaylist( pThis->getIntf() );
// Create a playtree notify command
CmdNotifyPlaytree *pCmdTree = new CmdNotifyPlaytree( pThis->getIntf() );
// Push the command in the asynchronous command queue
AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
pQueue->remove( "notify playlist" );
pQueue->remove( "notify playtree" );
pQueue->push( CmdGenericPtr( pCmd ) );
pQueue->push( CmdGenericPtr( pCmdTree ) );
return VLC_SUCCESS;
}
......@@ -362,10 +376,14 @@ int VlcProc::onPlaylistChange( vlc_object_t *pObj, const char *pVariable,
// Create a playlist notify command
// TODO: selective update
CmdNotifyPlaylist *pCmd = new CmdNotifyPlaylist( pThis->getIntf() );
// Create a playtree notify command
CmdNotifyPlaytree *pCmdTree = new CmdNotifyPlaytree( pThis->getIntf() );
// Push the command in the asynchronous command queue
pQueue->remove( "notify playlist" );
pQueue->remove( "notify playtree" );
pQueue->push( CmdGenericPtr( pCmd ) );
pQueue->push( CmdGenericPtr( pCmdTree ) );
return VLC_SUCCESS;
}
......
......@@ -28,6 +28,7 @@
#include <set>
#include "../vars/playlist.hpp"
#include "../vars/playtree.hpp"
#include "../vars/time.hpp"
#include "../vars/volume.hpp"
#include "../utils/var_text.hpp"
......@@ -51,6 +52,9 @@ class VlcProc: public SkinObject
/// Getter for the playlist variable
Playlist &getPlaylistVar() { return *((Playlist*)m_cPlaylist.get()); }
/// Getter for the playtree variable
Playtree &getPlaytreeVar() { return *((Playtree*)m_cPlaytree.get()); }
/// Getter for the time variable
StreamTime &getTimeVar() { return *((StreamTime*)(m_cVarTime.get())); }
......@@ -88,6 +92,8 @@ class VlcProc: public SkinObject
OSTimer *m_pTimer;
/// Playlist variable
VariablePtr m_cPlaylist;
/// Playtree variable FIXME
VariablePtr m_cPlaytree;
VariablePtr m_cVarRandom;
VariablePtr m_cVarLoop;
VariablePtr m_cVarRepeat;
......
/*****************************************************************************
* var_tree.cpp
*****************************************************************************
* Copyright (C) 2005 VideoLAN
* $Id: var_bool.hpp 9934 2005-02-15 13:55:08Z courmisch $
*
* Authors: Antoine Cellerier <dionoea@videolan.org>
*
* 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 "var_tree.hpp"
const string VarTree::m_type = "tree";
VarTree::VarTree( intf_thread_t *pIntf, VarTree *m_pParent2 )
:Variable( pIntf )
{
m_selected = false;
m_playing = false;
m_expanded = true;
m_pData = NULL;
m_pParent = m_pParent2;
// Create the position variable
m_cPosition = VariablePtr( new VarPercent( pIntf ) );
getPositionVar().set( 1.0 );
}
VarTree::~VarTree()
{
// TODO : check that children are deleted
}
void VarTree::add( const UStringPtr &rcString, bool selected, bool playing, bool expanded, void *pData )
{
m_children.push_back( VarTree( getIntf(), this ) );
back().m_cString = rcString;
back().m_selected = selected;
back().m_playing = playing;
back().m_expanded = expanded;
back().m_pData = pData;
notify();
}
void VarTree::delSelected()
{
Iterator it = begin();
while( it != end() )
{
//dig down the tree
if( size() ) it->delSelected();
//stay on some level
if( it->m_selected )
{
Iterator oldIt = it;
it++;
m_children.erase( oldIt );
}
else
{
it++;
}
}
notify();
}
void VarTree::clear()
{
m_children.clear();
}
VarTree::Iterator VarTree::operator[]( int n )
{
Iterator it;
int i;
for( it = begin(), i = 0;
i < n && it != end();
it++, i++ );
return it;
}
VarTree::ConstIterator VarTree::operator[]( int n ) const
{
ConstIterator it;
int i;
for( it = begin(), i = 0;
i < n && it != end();
it++, i++ );
return it;
}
/* find iterator to next ancestor
* ... which means parent++ or grandparent++ or grandgrandparent++ ... */
VarTree::Iterator VarTree::uncle()
{
// fprintf( stderr, "trying to find uncle\n");
VarTree *p_parent = parent();
if( p_parent != NULL )
{
VarTree *p_grandparent = p_parent->parent();
while( p_grandparent != NULL )
{
Iterator it = p_grandparent->begin();
while( !(it == p_grandparent->end()) && &(*it) != p_parent ) it++;
if( it != p_grandparent->end() )
{
it++;
if( it != p_grandparent->end() )
{
return it;
}
}
if( p_grandparent->parent() )
{
p_parent = p_grandparent;
p_grandparent = p_parent->parent();
}
else
p_grandparent = NULL;
}
}
/* if we didn't return before, it means that we've reached the end */
return root()->end();
}
void VarTree::checkParents( VarTree *m_pParent2 )
{
m_pParent = m_pParent2;
Iterator it = begin();
while( it!=end() )
{
it->checkParents( this );
it++;
}
}
int VarTree::visibleItems()
{
int i_count = size();
Iterator it = begin();
while( it != end() )
{
if( it->m_expanded )
{
i_count += it->visibleItems();
}
it++;
}
return i_count;
}
VarTree::Iterator VarTree::visibleItem( int n )
{
Iterator it = begin();
while( it != end() )
{
n--;
if( n <= 0 ) return it;
if( it->m_expanded )
{
int i = n - it->visibleItems();
if( i <= 0 ) return it->visibleItem( n );
n = i;
}
it++;
}
return end();
}
/*****************************************************************************
* var_tree.hpp
*****************************************************************************
* Copyright (C) 2005 VideoLAN
* $Id: var_bool.hpp 9934 2005-02-15 13:55:08Z courmisch $
*
* Authors: Antoine Cellerier <dionoea@videolan.org>
*
* 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 VAR_TREE_HPP
#define VAR_TREE_HPP
#include <list>
#include "variable.hpp"
#include "observer.hpp"
#include "ustring.hpp"
#include "var_percent.hpp"
/// Tree variable
class VarTree: public Variable, public Subject<VarTree>
{
public:
VarTree( intf_thread_t *pIntf, VarTree *m_pParent2 );
virtual ~VarTree();
/// Get the variable type
virtual const string &getType() const { return m_type; }
/// Add a pointer on string in the children's list
virtual void add( const UStringPtr &rcString, bool selected=true, bool playing=true, bool expanded=true, void *pData=NULL );
/// Remove the selected item from the children's list
virtual void delSelected();
/// Remove all elements from the children's list
virtual void clear();
UStringPtr m_cString;
bool m_selected;
bool m_playing;
bool m_expanded;
void *m_pData;
/// Get the number of children
int size() const { return m_children.size(); }
/// Iterators
typedef list<VarTree>::iterator Iterator;
typedef list<VarTree>::const_iterator ConstIterator;
/// Begining of the children's list
Iterator begin() { return m_children.begin(); }
ConstIterator begin() const { return m_children.begin(); }
/// End of children's list
Iterator end() { return m_children.end(); }
ConstIterator end() const { return m_children.end(); }
/// Back of children's list
VarTree &back() { return m_children.back(); }
/// Return an iterator on the n'th element of the children's list
Iterator operator[]( int n );
ConstIterator operator[]( int n ) const;
/// Parent node
VarTree *parent() { return m_pParent; }
void VarTree::checkParents( VarTree *m_pParent2 );
Iterator uncle();
/// Get root node
VarTree *root() { VarTree *parent=this; while( parent->parent() != NULL ) parent = parent->parent(); return parent; }
/// Get depth (root depth is 0)
int depth() { VarTree *parent=this; int depth=0; while( ( parent = parent->parent() ) != NULL ) depth++; return depth; }
/// Execute the action associated to this item
virtual void action( VarTree *pItem ) {}
/// Get a reference on the position variable
VarPercent &getPositionVar() const
{ return *((VarPercent*)m_cPosition.get()); }
/// Get a counted pointer on the position variable
const VariablePtr &getPositionVarPtr() const { return m_cPosition; }
/// Count the number of items that should be displayed if the playlist window wasn't limited
int visibleItems();
/// Return iterator to the n'th visible item
Iterator visibleItem( int n );
private:
// intf_thread_t *pIntf;
///list of children
list<VarTree> m_children;
///Pointer to parent node
VarTree *m_pParent;
///Variable type
static const string m_type;
/// Position variable
VariablePtr m_cPosition;
};
#endif
/*****************************************************************************
* playtree.cpp
*****************************************************************************
* Copyright (C) 2005 VideoLAN
* $Id: playlist.hpp 8659 2004-09-07 21:16:49Z gbazin $
*
* Authors: Antoine Cellerier <dionoea@videolan.org>
*
* 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 <vlc/vlc.h>
#include "playtree.hpp"
#include "../utils/ustring.hpp"
#include "charset.h"
Playtree::Playtree( intf_thread_t *pIntf )
:VarTree( pIntf, /*m_parent = */NULL )
{
// Get the VLC playlist object
m_pPlaylist = pIntf->p_sys->p_playlist;
// Try to guess the current charset
char *pCharset;
vlc_current_charset( &pCharset );
iconvHandle = vlc_iconv_open( "UTF-8", pCharset );
msg_Dbg( pIntf, "Using character encoding: %s", pCharset );
free( pCharset );
if( iconvHandle == (vlc_iconv_t)-1 )
{
msg_Warn( pIntf, "Unable to do requested conversion" );
}
buildTree();
}
Playtree::~Playtree()
{
if( iconvHandle != (vlc_iconv_t)-1 ) vlc_iconv_close( iconvHandle );
// TODO : check that everything is destroyed
}
void Playtree::delSelected()
{
// TODO
notify();
}
void Playtree::action( VarTree *pItem )
{
vlc_mutex_lock( &m_pPlaylist->object_lock );
VarTree::Iterator it;
if( pItem->size() )
{
it = pItem->begin();
while( it->size() ) it = it->begin();
}
playlist_Control( m_pPlaylist,
PLAYLIST_VIEWPLAY,
m_pPlaylist->status.i_view,
pItem->size()
? (playlist_item_t *)pItem->m_pData
: (playlist_item_t *)pItem->parent()->m_pData,
pItem->size()
? (playlist_item_t *)it->m_pData
: (playlist_item_t *)pItem->m_pData
);
vlc_mutex_unlock( &m_pPlaylist->object_lock );
}
void Playtree::onChange()
{
/* FIXME : updateTree could be a nice idea so we don't have to
* start from scratch each time the playlist changes */
buildTree();
notify();
}
void Playtree::buildNode( playlist_item_t *p_node, VarTree &m_pNode )
{
fprintf( stderr, "Playtree::buildNode\n");
for( int i = 0; i < p_node->i_children; i++ )
{
fprintf( stderr, ""__FILE__ "%d : adding playtree item : %s\n", __LINE__, p_node->pp_children[i]->input.psz_name );
UString *pName = new UString( getIntf(), p_node->pp_children[i]->input.psz_name );
m_pNode.add( UStringPtr( pName ),
false,
m_pPlaylist->status.p_item == p_node->pp_children[i],
true,
p_node->pp_children[i] );
if( p_node->pp_children[i]->i_children )
{
buildNode( p_node->pp_children[i], m_pNode.back() );
}
}
}
void Playtree::buildTree()
{
clear();
vlc_mutex_lock( &m_pPlaylist->object_lock );
playlist_view_t *p_view;
p_view = playlist_ViewFind( m_pPlaylist, VIEW_CATEGORY );
/* TODO : let the user chose the view type */
clear();
/* XXX : do we need Playlist::clear() instead of VarTree::clear() ? */
/* Set the root's name */
UString *pName = new UString( getIntf(), p_view->p_root->input.psz_name );
m_cString = UStringPtr( pName );
buildNode( p_view->p_root, *this );
vlc_mutex_unlock( &m_pPlaylist->object_lock );
checkParents( NULL );
}
/*****************************************************************************
* playtree.hpp
*****************************************************************************
* Copyright (C) 2005 VideoLAN
* $Id: playlist.hpp 8659 2004-09-07 21:16:49Z gbazin $
*
* Authors: Antoine Cellerier <dionoea@videolan.org>
*
* 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 PLAYTREE_HPP
#define PLAYTREE_HPP
#include "../utils/var_tree.hpp"
/// Variable for VLC playlist (new tree format)
class Playtree: public VarTree
{
public:
Playtree( intf_thread_t *pIntf );
virtual ~Playtree();
/// Remove the selected elements from the list
virtual void delSelected();
/// Execute the action associated to this item
virtual void action( VarTree *pItem );
/// Function called to notify playlist changes
void onChange();
private:
/// VLC playlist object
playlist_t *m_pPlaylist;
/// Iconv handle
vlc_iconv_t iconvHandle;
/// Build the list from the VLC playlist
void buildTree();
/// Update Node's children
void buildNode( playlist_item_t *p_node, VarTree &m_pNode );
};
#endif
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