Commit 1d163084 authored by Antoine Cellerier's avatar Antoine Cellerier

Add attribute flat="true/false" to Playtree. When flat is true, only the

leafs will be displayed (like the old style playlist). Once we're sure
that this works fine, we can ditch the old skins2 playlist code.
parent b8acb8c0
......@@ -22,6 +22,7 @@
*****************************************************************************/
#include <math.h>
#include "../utils/var_bool.hpp"
#include "ctrl_tree.hpp"
#include "../src/os_factory.hpp"
#include "../src/os_graphics.hpp"
......@@ -55,7 +56,8 @@ CtrlTree::CtrlTree( intf_thread_t *pIntf,
uint32_t bgColor2,
uint32_t selColor,
const UString &rHelp,
VarBool *pVisible ):
VarBool *pVisible,
VarBool *pFlat ):
CtrlGeneric( pIntf,rHelp, pVisible), m_rTree( rTree), m_rFont( rFont ),
m_pBgBitmap( pBgBitmap ), m_pItemBitmap( pItemBitmap ),
m_pOpenBitmap( pOpenBitmap ), m_pClosedBitmap( pClosedBitmap ),
......@@ -67,7 +69,9 @@ CtrlTree::CtrlTree( intf_thread_t *pIntf,
m_rTree.addObserver( this );
m_rTree.getPositionVar().addObserver( this );
m_firstPos = m_rTree.begin();
m_flat = pFlat->get();
m_firstPos = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
makeImage();
}
......@@ -85,6 +89,8 @@ CtrlTree::~CtrlTree()
int CtrlTree::itemHeight()
{
int itemHeight = m_rFont.getSize();
if( !m_flat )
{
if( m_pClosedBitmap )
{
itemHeight = __MAX( m_pClosedBitmap->getHeight(), itemHeight );
......@@ -93,6 +99,7 @@ int CtrlTree::itemHeight()
{
itemHeight = __MAX( m_pOpenBitmap->getHeight(), itemHeight );
}
}
if( m_pItemBitmap )
{
itemHeight = __MAX( m_pItemBitmap->getHeight(), itemHeight );
......@@ -104,6 +111,8 @@ int CtrlTree::itemHeight()
int CtrlTree::itemImageWidth()
{
int bitmapWidth = 5;
if( !m_flat )
{
if( m_pClosedBitmap )
{
bitmapWidth = __MAX( m_pClosedBitmap->getWidth(), bitmapWidth );
......@@ -112,6 +121,7 @@ int CtrlTree::itemImageWidth()
{
bitmapWidth = __MAX( m_pOpenBitmap->getWidth(), bitmapWidth );
}
}
if( m_pItemBitmap )
{
bitmapWidth = __MAX( m_pItemBitmap->getWidth(), bitmapWidth );
......@@ -145,11 +155,13 @@ void CtrlTree::onUpdate( Subject<VarTree, tree_update*> &rTree,
/// \todo handle delete in a more clever way
else if ( arg->i_type == 1 ) // Global change or deletion
{
m_firstPos = m_rTree.begin();
m_firstPos = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
makeImage();
}
else if ( arg->i_type == 2 ) // Item-append
{
if( m_flat && m_firstPos->size() )
m_firstPos = m_rTree.getNextLeaf( m_firstPos );
/// \todo Check if the item is really visible in the view
// (we only check if it in the document)
if( arg->b_visible == true )
......@@ -162,9 +174,12 @@ void CtrlTree::onUpdate( Subject<VarTree, tree_update*> &rTree,
/* Make sure firstPos and lastSelected are still valid */
while( m_firstPos->m_deleted && m_firstPos != m_rTree.root()->begin() )
{
m_firstPos = m_rTree.getPrevVisibleItem( m_firstPos );
m_firstPos = m_flat ? m_rTree.getPrevLeaf( m_firstPos )
: m_rTree.getPrevVisibleItem( m_firstPos );
}
if( m_firstPos->m_deleted ) m_firstPos = m_rTree.root()->begin();
if( m_firstPos->m_deleted )
m_firstPos = m_flat ? m_rTree.firstLeaf()
: m_rTree.root()->begin();
if( arg->b_visible == true )
{
......@@ -177,11 +192,15 @@ void CtrlTree::onUpdate( Subject<VarTree, tree_update*> &rTree,
void CtrlTree::onUpdate( Subject<VarPercent, void*> &rPercent, void* arg)
{
// Determine what is the first item to display
VarTree::Iterator it = m_rTree.begin();
VarTree::Iterator it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
if( m_dontMove ) return;
int excessItems = m_rTree.visibleItems() - maxItems();
int excessItems;
if( m_flat )
excessItems = m_rTree.countLeafs() - maxItems();
else
excessItems = m_rTree.visibleItems() - maxItems();
if( excessItems > 0)
{
......@@ -190,7 +209,10 @@ void CtrlTree::onUpdate( Subject<VarPercent, void*> &rPercent, void* arg)
#ifdef _MSC_VER
# define lrint (int)
#endif
it = m_rTree.getVisibleItem(lrint( (1.0 - rVarPos.get()) * (double)excessItems ) + 1);
if( m_flat )
it = m_rTree.getLeaf(lrint( (1.0 - rVarPos.get()) * (double)excessItems ) + 1 );
else
it = m_rTree.getVisibleItem(lrint( (1.0 - rVarPos.get()) * (double)excessItems ) + 1 );
}
if( m_firstPos != it )
{
......@@ -204,9 +226,13 @@ void CtrlTree::onUpdate( Subject<VarPercent, void*> &rPercent, void* arg)
void CtrlTree::onResize()
{
// Determine what is the first item to display
VarTree::Iterator it = m_rTree.begin();
VarTree::Iterator it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
int excessItems = m_rTree.visibleItems() - maxItems();
int excessItems;
if( m_flat )
excessItems = m_rTree.countLeafs() - maxItems();
else
excessItems = m_rTree.visibleItems() - maxItems();
if( excessItems > 0)
{
......@@ -215,7 +241,10 @@ void CtrlTree::onResize()
#ifdef _MSC_VER
# define lrint (int)
#endif
it = m_rTree.getVisibleItem(lrint( (1.0 - rVarPos.get()) * (double)excessItems ) + 1);
if( m_flat )
it = m_rTree.getLeaf(lrint( (1.0 - rVarPos.get()) * (double)excessItems ) + 1 );
else
it = m_rTree.getVisibleItem(lrint( (1.0 - rVarPos.get()) * (double)excessItems ) + 1 );
}
// Redraw the control if the position has changed
m_firstPos = it;
......@@ -243,9 +272,12 @@ void CtrlTree::handleEvent( EvtGeneric &rEvent )
if( key == KEY_DELETE )
{
/* Find first non selected item before m_pLastSelected */
VarTree::Iterator it_sel = m_rTree.begin();
for( it = m_rTree.begin(); it != m_rTree.end();
it = m_rTree.getNextVisibleItem( it ) )
VarTree::Iterator it_sel = m_flat ? m_rTree.firstLeaf()
: m_rTree.begin();
for( it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
it != m_rTree.end();
it = m_flat ? m_rTree.getNextLeaf( it )
: m_rTree.getNextVisibleItem( it ) )
{
if( &*it == m_pLastSelected ) break;
if( !it->m_selected ) it_sel = it;
......@@ -265,7 +297,8 @@ void CtrlTree::handleEvent( EvtGeneric &rEvent )
while( i >= 0 )
{
VarTree::Iterator it_old = it;
it = m_rTree.getNextVisibleItem( it );
it = m_flat ? m_rTree.getNextLeaf( it )
: m_rTree.getNextVisibleItem( it );
/* End is already visible, dont' scroll */
if( it == m_rTree.end() )
{
......@@ -289,9 +322,10 @@ void CtrlTree::handleEvent( EvtGeneric &rEvent )
int i = maxItems();
while( i >= maxItems()/2 )
{
it = m_rTree.getPrevVisibleItem( it );
it = m_flat ? m_rTree.getPrevLeaf( it )
: m_rTree.getPrevVisibleItem( it );
/* End is already visible, dont' scroll */
if( it == m_rTree.begin() )
if( it == ( m_flat ? m_rTree.firstLeaf() : m_rTree.begin() ) )
{
break;
}
......@@ -304,10 +338,13 @@ void CtrlTree::handleEvent( EvtGeneric &rEvent )
}
for( it = m_rTree.begin(); it != m_rTree.end();
it = m_rTree.getNextVisibleItem( it ) )
for( it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
it != m_rTree.end();
it = m_flat ? m_rTree.getNextLeaf( it )
: m_rTree.getNextVisibleItem( it ) )
{
VarTree::Iterator next = m_rTree.getNextVisibleItem( it );
VarTree::Iterator next = m_flat ? m_rTree.getNextLeaf( it )
: m_rTree.getNextVisibleItem( it );
if( key == KEY_UP )
{
// Scroll up one item
......@@ -345,7 +382,8 @@ void CtrlTree::handleEvent( EvtGeneric &rEvent )
}
// Fix last tree item selection
if( m_rTree.getNextVisibleItem( it ) == m_rTree.end()
if( ( m_flat ? m_rTree.getNextLeaf( it )
: m_rTree.getNextVisibleItem( it ) ) == m_rTree.end()
&& &*it == m_pLastSelected )
{
(*it).m_selected = true;
......@@ -428,8 +466,10 @@ void CtrlTree::handleEvent( EvtGeneric &rEvent )
VarTree::Iterator itClicked = findItemAtPos( yPos );
// Flag to know if the current item must be selected
bool select = false;
for( it = m_rTree.begin(); it != m_rTree.end();
it = m_rTree.getNextVisibleItem( it ) )
for( it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
it != m_rTree.end();
it = m_flat ? m_rTree.getNextLeaf( it )
: m_rTree.getNextVisibleItem( it ) )
{
bool nextSelect = select;
if( it == itClicked || &*it == m_pLastSelected )
......@@ -465,8 +505,10 @@ void CtrlTree::handleEvent( EvtGeneric &rEvent )
VarTree::Iterator itClicked = findItemAtPos( yPos );
// Flag to know if the current item must be selected
bool select = false;
for( it = m_rTree.begin(); it != m_rTree.end();
it = m_rTree.getNextVisibleItem( it ) )
for( it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
it != m_rTree.end();
it = m_flat ? m_rTree.getNextLeaf( it )
: m_rTree.getNextVisibleItem( it ) )
{
bool nextSelect = select;
if( it == itClicked || &*it == m_pLastSelected )
......@@ -491,8 +533,9 @@ void CtrlTree::handleEvent( EvtGeneric &rEvent )
it = findItemAtPos(yPos);
if( it != m_rTree.end() )
{
if( it->size() && xPos > (it->depth() - 1) * itemImageWidth()
if( ( it->size() && xPos > (it->depth() - 1) * itemImageWidth()
&& xPos < it->depth() * itemImageWidth() )
&& !m_flat )
{
// Fold/unfold the item
it->m_expanded = !it->m_expanded;
......@@ -502,8 +545,10 @@ void CtrlTree::handleEvent( EvtGeneric &rEvent )
{
// Unselect any previously selected item
VarTree::Iterator it2;
for( it2 = m_rTree.begin(); it2 != m_rTree.end();
it2 = m_rTree.getNextVisibleItem( it2 ) )
for( it2 = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
it2 != m_rTree.end();
it2 = m_flat ? m_rTree.getNextLeaf( it2 )
: m_rTree.getNextVisibleItem( it2 ) )
{
it2->m_selected = false;
}
......@@ -537,7 +582,8 @@ void CtrlTree::handleEvent( EvtGeneric &rEvent )
int direction = ((EvtScroll&)rEvent).getDirection();
double percentage = m_rTree.getPositionVar().get();
double step = 2.0 / (double)m_rTree.visibleItems();
double step = 2.0 / (double)( m_flat ? m_rTree.countLeafs()
: m_rTree.visibleItems() );
if( direction == EvtScroll::kUp )
{
percentage += step;
......@@ -555,8 +601,10 @@ void CtrlTree::handleEvent( EvtGeneric &rEvent )
VarTree::Iterator it;
int i = 0;
int iFirst = 0;
for( it = m_rTree.begin(); it != m_rTree.end();
it = m_rTree.getNextVisibleItem( it ) )
for( it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
it != m_rTree.end();
it = m_flat ? m_rTree.getNextLeaf( it )
: m_rTree.getNextVisibleItem( it ) )
{
i++;
if( it == m_firstPos )
......@@ -566,8 +614,10 @@ void CtrlTree::handleEvent( EvtGeneric &rEvent )
}
}
iFirst += maxItems();
if( iFirst >= m_rTree.visibleItems() ) iFirst = m_rTree.visibleItems();
float f_new = (float)iFirst / (float)m_rTree.visibleItems();
if( iFirst >= m_flat ? m_rTree.countLeafs() : m_rTree.visibleItems() )
iFirst = m_flat ? m_rTree.countLeafs() : m_rTree.visibleItems();
float f_new = (float)iFirst / (float)( m_flat ? m_rTree.countLeafs()
:m_rTree.visibleItems() );
m_dontMove = true;
m_rTree.getPositionVar().set( 1.0 - f_new );
m_dontMove = false;
......@@ -598,8 +648,10 @@ bool CtrlTree::ensureVisible( VarTree::Iterator item )
m_rTree.ensureExpanded( item );
for( it = m_rTree.begin(); it != m_rTree.end();
it = m_rTree.getNextVisibleItem( it ) )
for( it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
it != m_rTree.end();
it = m_flat ? m_rTree.getNextLeaf( it )
: m_rTree.getNextVisibleItem( it ) )
{
if( it->m_id == item->m_id ) break;
focusItemIndex++;
......@@ -612,8 +664,10 @@ bool CtrlTree::ensureVisible( int focusItemIndex )
// Find m_firstPos
VarTree::Iterator it;
int firstPosIndex = 0;
for( it = m_rTree.begin(); it != m_rTree.end();
it = m_rTree.getNextVisibleItem( it ) )
for( it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
it != m_rTree.end();
it = m_flat ? m_rTree.getNextLeaf( it )
: m_rTree.getNextVisibleItem( it ) )
{
if( it == m_firstPos ) break;
firstPosIndex++;
......@@ -629,7 +683,8 @@ bool CtrlTree::ensureVisible( int focusItemIndex )
// Scroll to have the wanted stream visible
VarPercent &rVarPos = m_rTree.getPositionVar();
rVarPos.set( 1.0 - (double)focusItemIndex /
(double)m_rTree.visibleItems() );
(double)( m_flat ? m_rTree.countLeafs()
: m_rTree.visibleItems() ) );
return true;
}
return false;
......@@ -641,8 +696,10 @@ void CtrlTree::autoScroll()
int playIndex = 0;
VarTree::Iterator it;
for( it = m_rTree.begin(); it != m_rTree.end();
it = m_rTree.getNextItem( it ) )
for( it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
it != m_rTree.end();
it = m_flat ? m_rTree.getNextLeaf( it )
: m_rTree.getNextItem( it ) )
{
if( it->m_playing )
{
......@@ -650,8 +707,10 @@ void CtrlTree::autoScroll()
break;
}
}
for( it = m_rTree.begin(); it != m_rTree.end();
it = m_rTree.getNextVisibleItem( it ) )
for( it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
it != m_rTree.end();
it = m_flat ? m_rTree.getNextLeaf( it )
: m_rTree.getNextVisibleItem( it ) )
{
if( it->m_playing )
break;
......@@ -710,7 +769,8 @@ void CtrlTree::makeImage()
}
do
{
it = m_rTree.getNextVisibleItem( it );
it = m_flat ? m_rTree.getNextLeaf( it )
: m_rTree.getNextVisibleItem( it );
} while( it->m_deleted );
}
}
......@@ -730,7 +790,8 @@ void CtrlTree::makeImage()
m_pImage->fillRect( 0, yPos, width, rectHeight, color );
do
{
it = m_rTree.getNextVisibleItem( it );
it = m_flat ? m_rTree.getNextLeaf( it )
: m_rTree.getNextVisibleItem( it );
} while( it->m_deleted );
}
else
......@@ -754,7 +815,7 @@ void CtrlTree::makeImage()
// Draw the text
if( pStr != NULL )
{
int depth = it->depth();
int depth = m_flat ? 1 : it->depth();
GenericBitmap *pText = m_rFont.drawString( *pStr, color, width - bitmapWidth * depth );
if( !pText )
{
......@@ -796,7 +857,8 @@ void CtrlTree::makeImage()
delete pText;
}
do {
it = m_rTree.getNextVisibleItem( it );
it = m_flat ? m_rTree.getNextLeaf( it )
: m_rTree.getNextVisibleItem( it );
} while( it->m_deleted );
}
stats_TimerStop( getIntf(), STATS_TIMER_SKINS_PLAYTREE_IMAGE );
......@@ -808,7 +870,8 @@ VarTree::Iterator CtrlTree::findItemAtPos( int pos )
// We decrement pos as we try the other items, until pos == 0.
VarTree::Iterator it;
for( it = m_firstPos; it != m_rTree.end() && pos != 0;
it = m_rTree.getNextVisibleItem( it ) )
it = m_flat ? m_rTree.getNextLeaf( it )
: m_rTree.getNextVisibleItem( it ) )
{
pos--;
}
......
......@@ -50,7 +50,8 @@ class CtrlTree: public CtrlGeneric, public Observer<VarTree, tree_update*>,
uint32_t bgColor2,
uint32_t selColor,
const UString &rHelp,
VarBool *pVisible );
VarBool *pVisible,
VarBool *pFlat );
virtual ~CtrlTree();
/// Handle an event on the control
......@@ -114,6 +115,9 @@ class CtrlTree: public CtrlGeneric, public Observer<VarTree, tree_update*>,
/// Don't move if the position variable is updated
bool m_dontMove;
/// Do we want to "flaten" the tree ?
bool m_flat;
/// Method called when the tree variable is modified
virtual void onUpdate( Subject<VarTree, tree_update*> &rTree ,
tree_update *);
......
......@@ -871,13 +871,14 @@ void Builder::addTree( const BuilderData::Tree &rData )
// Get the visibility variable
// XXX check when it is null
VarBool *pVisible = pInterpreter->getVarBool( rData.m_visible, m_pTheme );
VarBool *pFlat = pInterpreter->getVarBool( rData.m_flat, 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 );
UString( getIntf(), rData.m_help.c_str() ), pVisible, pFlat );
// Compute the position of the control
const Position pos = makePosition( rData.m_leftTop, rData.m_rightBottom,
......
......@@ -16,5 +16,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 imageId:string nbHoriz:int nbVert:int padHoriz:int padVert:int 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
Tree id:string xPos:int yPos:int visible:string flat: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 autoResize:bool help:string layer:int windowId:string layoutId:string
......@@ -396,13 +396,14 @@ m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_visible( visible ), m_width( width
/// 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 ) {}
Tree( const string & id, int xPos, int yPos, const string & visible, const string & flat, 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_flat( flat ), 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 ) {}
string m_id;
int m_xPos;
int m_yPos;
string m_visible;
string m_flat;
int m_width;
int m_height;
string m_leftTop;
......
......@@ -341,6 +341,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
m_curTreeId = uniqueId( attr["id"] );
const BuilderData::Tree treeData( m_curTreeId, atoi( attr["x"] ) +
m_xOffset, atoi( attr["y"] ) + m_yOffset, attr["visible"],
attr["flat"],
atoi( attr["width"]), atoi( attr["height"] ),
attr["lefttop"], attr["rightbottom"],
attr["font"], "playtree",
......
......@@ -225,10 +225,12 @@ VarTree::Iterator VarTree::getVisibleItem( int n )
while( it != end() )
{
n--;
if( n <= 0 ) return it;
if( n <= 0 )
return it;
if( it->m_expanded )
{
int i = n - it->visibleItems();
int i;
i = n - it->visibleItems();
if( i <= 0 ) return it->getVisibleItem( n );
n = i;
}
......@@ -237,6 +239,29 @@ VarTree::Iterator VarTree::getVisibleItem( int n )
return end();
}
VarTree::Iterator VarTree::getLeaf( int n )
{
Iterator it = begin();
while( it != end() )
{
if( it->size() )
{
int i;
i = n - it->countLeafs();
if( i <= 0 ) return it->getLeaf( n );
n = i;
}
else
{
n--;
if( n <= 0 )
return it;
}
it++;
}
return end();
}
VarTree::Iterator VarTree::getNextVisibleItem( Iterator it )
{
if( it->m_expanded && it->size() )
......@@ -260,9 +285,7 @@ VarTree::Iterator VarTree::getPrevVisibleItem( Iterator it )
{
VarTree::Iterator it_old = it;
if( it == root()->begin() || it == ++(root()->begin()) ) return it;
if( it->parent() )
{
}
/* Was it the first child of its parent ? */
if( it->parent() && it == it->parent()->begin() )
{
......@@ -300,6 +323,49 @@ VarTree::Iterator VarTree::getNextItem( Iterator it )
return it;
}
VarTree::Iterator VarTree::getPrevItem( Iterator it )
{
VarTree::Iterator it_old = it;
if( it == root()->begin() || it == ++(root()->begin()) ) return it;
/* Was it the first child of its parent ? */
if( it->parent() && it == it->parent()->begin() )
{
/* Yes, get previous uncle */
it = it_old->prev_uncle();
}
else
it--;
/* We have found an expanded uncle, take its last child */
while( it != root()->begin() && it->size() )
{
it = it->end();
it--;
}
return it;
}
VarTree::Iterator VarTree::getNextLeaf( Iterator it )
{
do
{
it = getNextItem( it );
}
while( it != root()->end() && it->size() );
return it;
}
VarTree::Iterator VarTree::getPrevLeaf( Iterator it )
{
do
{
it = getPrevItem( it );
}
while( it != root()->begin() && it->size() ); /* FIXME ? */
if( it == root()->begin() ) it = firstLeaf();
return it;
}
VarTree::Iterator VarTree::findById( int id )
{
......@@ -327,3 +393,25 @@ void VarTree::ensureExpanded( VarTree::Iterator it )
current = current->parent();
}
}
int VarTree::countLeafs()
{
if( size() == 0 ) return 1;
int i_count = 0;
Iterator it = begin();
while( it != end() )
{
i_count += it->countLeafs();
it++;
}
return i_count;
}
VarTree::Iterator VarTree::firstLeaf()
{
Iterator b = root()->begin();
if( b->size() ) return getNextLeaf( b );
return b;
}
......@@ -119,15 +119,8 @@ class VarTree: public Variable, public Subject<VarTree, tree_update*>
return parent;
}
/// Get depth (root depth is 0)
int depth()
{
VarTree *parent = this;
int depth = 0;
while( ( parent = parent->parent() ) != NULL )
depth++;
return depth;
}
/// Get first leaf
Iterator firstLeaf();
void removeChild( VarTree::Iterator item )
{
......@@ -147,9 +140,15 @@ class VarTree: public Variable, public Subject<VarTree, tree_update*>
/// Count the number of items that should be displayed if the playlist window wasn't limited
int visibleItems();
/// Count the number of leafs in the tree
int countLeafs();
/// Return iterator to the n'th visible item
Iterator getVisibleItem( int n );
/// Return iterator to the n'th leaf
Iterator getLeaf( int n );
/// Given an iterator to a visible item, return the next visible item
Iterator getNextVisibleItem( Iterator it );
......@@ -159,12 +158,32 @@ class VarTree: public Variable, public Subject<VarTree, tree_update*>
/// Given an iterator to an item, return the next item
Iterator getNextItem( Iterator it );
/// Given an iterator to an item, return the previous item
Iterator getPrevItem( Iterator it );
/// Given an iterator to an item, return the next leaf
Iterator getNextLeaf( Iterator it );
/// Given an iterator to an item, return the previous leaf
Iterator getPrevLeaf( Iterator it );
/// Find a children node with the given id
Iterator findById( int id );
/// Ensure an item is expanded
void ensureExpanded( VarTree::Iterator );
/// Get depth (root depth is 0)
int depth()
{
VarTree *parent = this;
int depth = 0;
while( ( parent = parent->parent() ) != NULL )
depth++;
return depth;
}
private:
/// List of children
list<VarTree> m_children;
......
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