]> git.sesse.net Git - vlc/blobdiff - modules/gui/skins2/controls/ctrl_tree.cpp
Improvements to playtree
[vlc] / modules / gui / skins2 / controls / ctrl_tree.cpp
index b9c9fc9890f8d66f10fbd13f9c32542d51cfbdf4..6e6d2fe35c74a24438624fe8b2d8d115689c4abf 100644 (file)
@@ -67,7 +67,7 @@ CtrlTree::CtrlTree( intf_thread_t *pIntf,
     m_rTree.addObserver( this );
     m_rTree.getPositionVar().addObserver( this );
 
-    m_lastPos = m_rTree.begin();
+    m_firstPos = m_rTree.begin();
 
     makeImage();
 }
@@ -130,16 +130,30 @@ int CtrlTree::maxItems()
 }
 
 
-void CtrlTree::onUpdate( Subject<VarTree> &rTree )
+void CtrlTree::onUpdate( Subject<VarTree, tree_update*> &rTree,
+                         tree_update *arg )
 {
-    // Invalidate the position when the tree is updated
-    m_lastPos = m_rTree.begin();
-
-    autoScroll();
+    if( arg->i_type == 0 ) // Item update
+    {
+        autoScroll();
+        makeImage();
+    }
+    else if ( arg->i_type == 1 ) // Global change or deletion
+    {
+        makeImage();
+    }
+    else if ( arg->i_type == 2 ) // Item-append
+    {
+        /* TODO: Check if the item should be visible. If it is, makeImage
+         * Else, do nothing
+         */
+        makeImage();
+    }
+    notifyLayout();
     m_pLastSelected = NULL;
 }
 
-void CtrlTree::onUpdate( Subject<VarPercent> &rPercent )
+void CtrlTree::onUpdate( Subject<VarPercent, void*> &rPercent, void* arg)
 {
     // Determine what is the first item to display
     VarTree::Iterator it = m_rTree.begin();
@@ -155,10 +169,10 @@ void CtrlTree::onUpdate( Subject<VarPercent> &rPercent )
 #endif
         it = m_rTree.getVisibleItem(lrint( (1.0 - rVarPos.get()) * (double)excessItems ) + 1);
     }
-    if( m_lastPos != it )
+    if( m_firstPos != it )
     {
         // Redraw the control if the position has changed
-        m_lastPos = it;
+        m_firstPos = it;
         makeImage();
         notifyLayout();
     }
@@ -166,7 +180,7 @@ void CtrlTree::onUpdate( Subject<VarPercent> &rPercent )
 
 void CtrlTree::onResize()
 {
-// FIXME : shouldn't be the same as the onUpdate function ... but i'm lazy
+    // 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();
 
@@ -182,34 +196,9 @@ void CtrlTree::onResize()
         it = m_rTree.getVisibleItem(lrint( (1.0 - rVarPos.get()) * (double)excessItems ) + 1);
     }
     // Redraw the control if the position has changed
-    m_lastPos = it;
+    m_firstPos = 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.getVisibleItem( excessItems );
-    }
-    makeImage();
-    notifyLayout();
-#endif
 }
 
 void CtrlTree::onPositionChange()
@@ -243,6 +232,7 @@ void CtrlTree::handleEvent( EvtGeneric &rEvent )
                         m_pLastSelected = &*it;
                     }
                 }
+                //ensureVisible( it );
             }
             else if( key == KEY_DOWN )
             {
@@ -262,6 +252,7 @@ void CtrlTree::handleEvent( EvtGeneric &rEvent )
                 {
                     previousWasSelected = ( &*it == m_pLastSelected );
                 }
+                //ensureVisible( it );
             }
             else if( key == KEY_RIGHT )
             {
@@ -396,18 +387,28 @@ void CtrlTree::handleEvent( EvtGeneric &rEvent )
         else if( rEvent.getAsString().find( "mouse:left:down" ) !=
                  string::npos )
         {
-            // Unselect any previously selected item
-            for( it = m_rTree.begin(); it != m_rTree.end();
-                 it = m_rTree.getNextVisibleItem( it ) )
+            it = findItemAtPos(yPos);
+            if( it->size() && xPos > (it->depth() - 1) * itemImageWidth()
+                && xPos < it->depth() * itemImageWidth() )
             {
-                it->m_selected = false;
+                // Fold/unfold the item
+                it->m_expanded = !it->m_expanded;
             }
-            // Select the new item
-            it = findItemAtPos(yPos);
-            if( it != m_rTree.end() )
+            else
             {
-                it->m_selected = true;
-                m_pLastSelected = &*it;
+                // Unselect any previously selected item
+                VarTree::Iterator it2;
+                for( it2 = m_rTree.begin(); it2 != m_rTree.end();
+                     it2 = m_rTree.getNextVisibleItem( it2 ) )
+                {
+                    it2->m_selected = false;
+                }
+                // Select the new item
+                if( it != m_rTree.end() )
+                {
+                    it->m_selected = true;
+                    m_pLastSelected = &*it;
+                }
             }
         }
 
@@ -417,18 +418,10 @@ void CtrlTree::handleEvent( EvtGeneric &rEvent )
             it = findItemAtPos(yPos);
             if( it != m_rTree.end() )
             {
-                if( it->size() && xPos < it->depth() * itemImageWidth() )
-                {
-                    it->m_expanded = !it->m_expanded;
-                }
-                else
-                {
-                    // Execute the action associated to this item
-                    m_rTree.action( &*it );
-                }
+               // Execute the action associated to this item
+               m_rTree.action( &*it );
             }
         }
-
         // Redraw the control
         makeImage();
         notifyLayout();
@@ -468,47 +461,66 @@ void CtrlTree::draw( OSGraphics &rImage, int xDest, int yDest )
     }
 }
 
-void CtrlTree::autoScroll()
+bool CtrlTree::ensureVisible( VarTree::Iterator item )
 {
-    // Find the current playing stream
-    int playIndex = 0;
+    // Find the item to focus
+    int focusItemIndex = 0;
     VarTree::Iterator it;
     for( it = m_rTree.begin(); it != m_rTree.end();
          it = m_rTree.getNextVisibleItem( it ) )
     {
         if( it->m_playing ) break;
-        playIndex++;
+        focusItemIndex++;
     }
+   return  ensureVisible( focusItemIndex );
+}
 
-    if( it == m_rTree.end() ) return;
-
-    // Find  m_lastPos
-    int lastPosIndex = 0;
+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 ) )
     {
-        if( it == m_lastPos ) break;
-        lastPosIndex++;
+        if( it == m_firstPos ) break;
+        firstPosIndex++;
     }
 
-    if( it == m_rTree.end() ) return;
+    if( it == m_rTree.end() ) return false;
 
 
     if( it != m_rTree.end()
-        && ( playIndex < lastPosIndex
-           || playIndex > lastPosIndex + maxItems() ) )
+        && ( focusItemIndex < firstPosIndex
+           || focusItemIndex > firstPosIndex + maxItems() ) )
     {
         // Scroll to have the playing stream visible
         VarPercent &rVarPos = m_rTree.getPositionVar();
-        rVarPos.set( 1.0 - (double)playIndex / (double)m_rTree.visibleItems() );
+        rVarPos.set( 1.0 - (double)focusItemIndex /
+                           (double)m_rTree.visibleItems() );
+        return true;
     }
-    else
+    return false;
+}
+
+void CtrlTree::autoScroll()
+{
+    // Find the current playing stream
+    int playIndex = 0;
+    VarTree::Iterator it;
+    for( it = m_rTree.begin(); it != m_rTree.end();
+         it = m_rTree.getNextVisibleItem( it ) )
     {
-        makeImage();
-        notifyLayout();
+        if( it->m_playing ) break;
+        playIndex++;
     }
+
+    if( it == m_rTree.end() ) return;
+
+    ensureVisible( playIndex );
 }
 
+
 void CtrlTree::makeImage()
 {
     if( m_pImage )
@@ -531,7 +543,7 @@ void CtrlTree::makeImage()
     OSFactory *pOsFactory = OSFactory::instance( getIntf() );
     m_pImage = pOsFactory->createOSGraphics( width, height );
 
-    VarTree::Iterator it = m_lastPos;
+    VarTree::Iterator it = m_firstPos;
 
     if( m_pBgBitmap )
     {
@@ -575,12 +587,11 @@ void CtrlTree::makeImage()
             bgColor = ( bgColor == m_bgColor1 ? m_bgColor2 : m_bgColor1 );
         }
     }
-//    fprintf( stderr, "done\n");
 
     int bitmapWidth = itemImageWidth();
 
     int yPos = 0;
-    it = m_lastPos;
+    it = m_firstPos;
     while( it != m_rTree.end() && yPos < height )
     {
         const GenericBitmap *m_pCurBitmap;
@@ -629,14 +640,17 @@ void CtrlTree::makeImage()
         }
         it = m_rTree.getNextVisibleItem( it );
     }
+    /* TODO: Reposition percentage var to accomodate if it's not suitable anymore
+     * (if we expanded a node)
+     */
 }
 
 VarTree::Iterator CtrlTree::findItemAtPos( int pos )
 {
-    // The first item is m_lastPos.
+    // The first item is m_firstPos.
     // We decrement pos as we try the other items, until pos == 0.
     VarTree::Iterator it;
-    for( it = m_lastPos; it != m_rTree.end() && pos != 0;
+    for( it = m_firstPos; it != m_rTree.end() && pos != 0;
          it = m_rTree.getNextVisibleItem( it ) )
     {
         pos--;
@@ -644,4 +658,3 @@ VarTree::Iterator CtrlTree::findItemAtPos( int pos )
 
     return it;
 }
-