work, cleaning and fixing. I'll continue this weekend.
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 \
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 \
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 \
typedef CmdDialogs<13> CmdDlgPlaylistSave;
typedef CmdDialogs<14> CmdDlgDirectory;
typedef CmdDialogs<15> CmdDlgStreamingWizard;
+typedef CmdDialogs<16> CmdDlgPlaytreeLoad;
+typedef CmdDialogs<17> CmdDlgPlaytreeSave;
/// Generic "Open dialog" command
--- /dev/null
+/*****************************************************************************
+ * 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
+}
--- /dev/null
+/*****************************************************************************
+ * 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
#include "../src/vlcproc.hpp"
#include "../utils/var_text.hpp"
#include "../vars/playlist.hpp"
+#include "../vars/playtree.hpp"
void CmdNotifyPlaylist::execute()
rVar.onChange();
}
+void CmdNotifyPlaytree::execute()
+{
+ // Notify the playtree variable
+ Playtree &rVar = VlcProc::instance( getIntf() )->getPlaytreeVar();
+ rVar.onChange();
+}
+
void CmdSetText::execute()
{
/// 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
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 );
--- /dev/null
+/*****************************************************************************
+ * 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 );
+ }
+}
--- /dev/null
+/*****************************************************************************
+ * 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
#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"
ADD_OBJECTS( RadialSlider );
ADD_OBJECTS( Slider );
ADD_OBJECTS( List );
+ ADD_OBJECTS( Tree );
ADD_OBJECTS( Video );
return m_pTheme;
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 )
{
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
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
* $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
/// 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
{
* $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
#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"
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 )
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;
+}
class Theme;
class VarBool;
class VarList;
+class VarTree;
class VarPercent;
/// 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;
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" );
{
// Slider associated to a list
newValue = "playlist.slider";
+ // FIXME
+ newValue = "playtree.slider";
}
const BuilderData::Slider slider( uniqueId( attr["id"] ),
attr["visible"],
m_yOffsetList.pop_back();
}
- else if( rName == "Playlist" )
+ else if( rName == "Playlist" || rName == "Playtree" )
{
m_curListId = "";
}
#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
// 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 ) );
}
}
// 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 ) );
}
}
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" )
// 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;
}
// 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;
}
// 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;
}
#include <set>
#include "../vars/playlist.hpp"
+#include "../vars/playtree.hpp"
#include "../vars/time.hpp"
#include "../vars/volume.hpp"
#include "../utils/var_text.hpp"
/// 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())); }
OSTimer *m_pTimer;
/// Playlist variable
VariablePtr m_cPlaylist;
+ /// Playtree variable FIXME
+ VariablePtr m_cPlaytree;
VariablePtr m_cVarRandom;
VariablePtr m_cVarLoop;
VariablePtr m_cVarRepeat;
--- /dev/null
+/*****************************************************************************
+ * 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();
+}
--- /dev/null
+/*****************************************************************************
+ * 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
--- /dev/null
+/*****************************************************************************
+ * 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, "\e[32;1mPlaytree::buildNode\e[0m\n");
+ for( int i = 0; i < p_node->i_children; i++ )
+ {
+ fprintf( stderr, "\e[33;1m"__FILE__ "%d :\e[0m 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 );
+}
--- /dev/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