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;