]> git.sesse.net Git - vlc/blobdiff - modules/gui/skins2/utils/var_tree.cpp
skins2: transform getNextSibling into getNextSiblingOrUncle
[vlc] / modules / gui / skins2 / utils / var_tree.cpp
index f76c89dceeeea30b7fa01f4ccb6094be046425b4..f861298b407bdddfb1f81139ab1bb6598572e8bd 100644 (file)
@@ -1,10 +1,11 @@
 /*****************************************************************************
  * var_tree.cpp
  *****************************************************************************
- * Copyright (C) 2005 VideoLAN
+ * Copyright (C) 2005 the VideoLAN team
  * $Id$
  *
  * Authors: Antoine Cellerier <dionoea@videolan.org>
+ *          ClĂ©ment Stenac <zorglub@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
@@ -28,7 +29,8 @@ const string VarTree::m_type = "tree";
 
 VarTree::VarTree( intf_thread_t *pIntf )
     : Variable( pIntf ), m_id( 0 ), m_selected( false ), m_playing( false ),
-    m_expanded( false ), m_pData( NULL ), m_pParent( NULL )
+    m_expanded( false ), m_deleted( false ),
+    m_pData( NULL ), m_pParent( NULL ), m_readonly( false )
 {
     // Create the position variable
     m_cPosition = VariablePtr( new VarPercent( pIntf ) );
@@ -37,10 +39,12 @@ VarTree::VarTree( intf_thread_t *pIntf )
 
 VarTree::VarTree( intf_thread_t *pIntf, VarTree *pParent, int id,
                   const UStringPtr &rcString, bool selected, bool playing,
-                  bool expanded, void *pData )
+                  bool expanded, bool readonly,
+                  void *pData )
     : Variable( pIntf ), m_id( id ), m_cString( rcString ),
     m_selected( selected ), m_playing( playing ), m_expanded( expanded ),
-    m_pData( pData ), m_pParent( pParent )
+    m_deleted( false ), m_pData( pData ), m_pParent( pParent ),
+    m_readonly( readonly )
 {
     // Create the position variable
     m_cPosition = VariablePtr( new VarPercent( pIntf ) );
@@ -53,10 +57,12 @@ VarTree::~VarTree()
 }
 
 void VarTree::add( int id, const UStringPtr &rcString, bool selected,
-                   bool playing, bool expanded, void *pData )
+                   bool playing, bool expanded, bool readonly,
+                   void *pData )
 {
     m_children.push_back( VarTree( getIntf(), this, id, rcString, selected,
-                                   playing, expanded, pData ) );
+                                   playing, expanded, readonly,
+                                   pData ) );
 }
 
 void VarTree::delSelected()
@@ -105,9 +111,34 @@ VarTree::ConstIterator VarTree::operator[]( int n ) const
     return it;
 }
 
+VarTree::Iterator VarTree::getNextSiblingOrUncle()
+{
+    VarTree *p_parent = parent();
+    if( p_parent )
+    {
+        Iterator it = p_parent->begin();
+        while( it != p_parent->end() && &(*it) != this ) ++it;
+        if( it != p_parent->end() )
+        {
+            Iterator current = it;
+            ++it;
+            if( it != p_parent->end() )
+                return it;
+            else
+                return current->next_uncle();
+        }
+        else
+        {
+            msg_Err( getIntf(), "should never occur" );
+            return end();
+        }
+    }
+    return end();
+}
+
 /* find iterator to next ancestor
  * ... which means parent++ or grandparent++ or grandgrandparent++ ... */
-VarTree::Iterator VarTree::uncle()
+VarTree::Iterator VarTree::next_uncle()
 {
     VarTree *p_parent = parent();
     if( p_parent != NULL )
@@ -139,15 +170,36 @@ VarTree::Iterator VarTree::uncle()
     return root()->end();
 }
 
-void VarTree::checkParents( VarTree *pParent )
+VarTree::Iterator VarTree::prev_uncle()
 {
-    m_pParent = pParent;
-    Iterator it = begin();
-    while( it != end() )
+    VarTree *p_parent = parent();
+    if( p_parent != NULL )
     {
-        it->checkParents( this );
-        it++;
+        VarTree *p_grandparent = p_parent->parent();
+        while( p_grandparent != NULL )
+        {
+            Iterator it = p_grandparent->end();
+            while( it != p_grandparent->begin() && &(*it) != p_parent ) it--;
+            if( it != p_grandparent->begin() )
+            {
+                it--;
+                if( it != p_grandparent->begin() )
+                {
+                    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()->begin();
 }
 
 int VarTree::visibleItems()
@@ -171,10 +223,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;
         }
@@ -183,6 +237,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() )
@@ -196,12 +273,35 @@ VarTree::Iterator VarTree::getNextVisibleItem( Iterator it )
         // Was 'it' the last brother? If so, look for uncles
         if( it_old->parent() && it_old->parent()->end() == it )
         {
-            it = it_old->uncle();
+            it = it_old->next_uncle();
         }
     }
     return it;
 }
 
+VarTree::Iterator VarTree::getPrevVisibleItem( 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->m_expanded )
+    {
+            it = it->end();
+            it--;
+    }
+    return it;
+}
+
 VarTree::Iterator VarTree::getNextItem( Iterator it )
 {
     if( it->size() )
@@ -215,12 +315,55 @@ VarTree::Iterator VarTree::getNextItem( Iterator it )
         // Was 'it' the last brother? If so, look for uncles
         if( it_old->parent() && it_old->parent()->end() == it )
         {
-            it = it_old->uncle();
+            it = it_old->next_uncle();
         }
     }
     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 )
 {
@@ -248,3 +391,33 @@ 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;
+}
+
+void VarTree::cascadeDelete()
+{
+    m_deleted = true;
+    for( Iterator it = begin(); it != end(); ++it )
+    {
+        it->cascadeDelete();
+    }
+}