From 0d26b16638421761d2719a082c110cd1b8a3903b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Stenac?= <zorglub@videolan.org> Date: Sun, 4 Dec 2005 19:27:20 +0000 Subject: [PATCH] Improve ensureVisible --- modules/gui/skins2/controls/ctrl_tree.cpp | 32 ++++++++++++++++++----- modules/gui/skins2/src/vlcproc.cpp | 11 ++++---- modules/gui/skins2/utils/var_tree.cpp | 32 +++++++++++++++++++++++ modules/gui/skins2/utils/var_tree.hpp | 7 +++++ modules/gui/skins2/vars/playtree.cpp | 8 ++++++ modules/gui/skins2/vars/playtree.hpp | 3 +++ 6 files changed, 81 insertions(+), 12 deletions(-) diff --git a/modules/gui/skins2/controls/ctrl_tree.cpp b/modules/gui/skins2/controls/ctrl_tree.cpp index 572afce62afe..f5c9dc77970b 100644 --- a/modules/gui/skins2/controls/ctrl_tree.cpp +++ b/modules/gui/skins2/controls/ctrl_tree.cpp @@ -147,7 +147,10 @@ void CtrlTree::onUpdate( Subject<VarTree, tree_update*> &rTree, /* TODO: Check if the item should be visible. If it is, makeImage * Else, do nothing */ - makeImage(); + if( arg->b_visible == true ) + { + makeImage(); + } } notifyLayout(); m_pLastSelected = NULL; @@ -232,7 +235,7 @@ void CtrlTree::handleEvent( EvtGeneric &rEvent ) m_pLastSelected = &*it; } } - //ensureVisible( it ); + ensureVisible( it ); } else if( key == KEY_DOWN ) { @@ -252,7 +255,7 @@ void CtrlTree::handleEvent( EvtGeneric &rEvent ) { previousWasSelected = ( &*it == m_pLastSelected ); } - //ensureVisible( it ); + ensureVisible( it ); } else if( key == KEY_RIGHT ) { @@ -466,13 +469,16 @@ bool CtrlTree::ensureVisible( VarTree::Iterator item ) // Find the item to focus int focusItemIndex = 0; VarTree::Iterator it; + + m_rTree.ensureExpanded( item ); + for( it = m_rTree.begin(); it != m_rTree.end(); it = m_rTree.getNextVisibleItem( it ) ) { - if( it->m_playing ) break; + if( it == item ) break; focusItemIndex++; } - return ensureVisible( focusItemIndex ); + return ensureVisible( focusItemIndex ); } bool CtrlTree::ensureVisible( int focusItemIndex ) @@ -494,7 +500,7 @@ bool CtrlTree::ensureVisible( int focusItemIndex ) && ( focusItemIndex < firstPosIndex || focusItemIndex > firstPosIndex + maxItems() ) ) { - // Scroll to have the playing stream visible + // Scroll to have the wanted stream visible VarPercent &rVarPos = m_rTree.getPositionVar(); rVarPos.set( 1.0 - (double)focusItemIndex / (double)m_rTree.visibleItems() ); @@ -508,15 +514,27 @@ 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.getNextItem( it ) ) + { + if( it->m_playing ) + { + m_rTree.ensureExpanded( it ); + break; + } + } for( it = m_rTree.begin(); it != m_rTree.end(); it = m_rTree.getNextVisibleItem( it ) ) { - if( it->m_playing ) break; + if( it->m_playing ) + break; playIndex++; } if( it == m_rTree.end() ) return; + ensureVisible( playIndex ); } diff --git a/modules/gui/skins2/src/vlcproc.cpp b/modules/gui/skins2/src/vlcproc.cpp index 6b6bd198872d..2ea2a19de385 100644 --- a/modules/gui/skins2/src/vlcproc.cpp +++ b/modules/gui/skins2/src/vlcproc.cpp @@ -421,17 +421,18 @@ int VlcProc::onItemAppend( vlc_object_t *pObj, const char *pVariable, memcpy( p_add, newVal.p_address, sizeof( playlist_add_t ) ) ; + CmdGenericPtr ptrTree; + CmdPlaytreeAppend *pCmdTree = new CmdPlaytreeAppend( pThis->getIntf(), + p_add ); + ptrTree = CmdGenericPtr( pCmdTree ); + // Create a playlist notify command (for old style playlist) CmdNotifyPlaylist *pCmd = new CmdNotifyPlaylist( pThis->getIntf() ); - // Create a playtree notify command (for new style playtree) - CmdPlaytreeAppend *pCmdTree = new CmdPlaytreeAppend( pThis->getIntf(), - p_add ); - // Push the command in the asynchronous command queue AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() ); pQueue->push( CmdGenericPtr( pCmd ) ); - pQueue->push( CmdGenericPtr( pCmdTree ), false ); + pQueue->push( ptrTree , false ); return VLC_SUCCESS; } diff --git a/modules/gui/skins2/utils/var_tree.cpp b/modules/gui/skins2/utils/var_tree.cpp index b9753c76f756..eff1bb4c1ae2 100644 --- a/modules/gui/skins2/utils/var_tree.cpp +++ b/modules/gui/skins2/utils/var_tree.cpp @@ -202,6 +202,26 @@ VarTree::Iterator VarTree::getNextVisibleItem( Iterator it ) return it; } +VarTree::Iterator VarTree::getNextItem( Iterator it ) +{ + if( it->size() ) + { + it = it->begin(); + } + else + { + VarTree::Iterator it_old = it; + it++; + // Was 'it' the last brother? If so, look for uncles + if( it_old->parent() && it_old->parent()->end() == it ) + { + it = it_old->uncle(); + } + } + return it; +} + + VarTree::Iterator VarTree::findById( int id ) { for (Iterator it = begin(); it != end(); ++it ) @@ -216,3 +236,15 @@ VarTree::Iterator VarTree::findById( int id ) return end(); } + +void VarTree::ensureExpanded( VarTree::Iterator it ) +{ + /// Don't expand ourselves, only our parents + VarTree *current = &(*it); + current = current->parent(); + while( current->parent() != NULL ) + { + current->m_expanded = true; + current = current->parent(); + } +} diff --git a/modules/gui/skins2/utils/var_tree.hpp b/modules/gui/skins2/utils/var_tree.hpp index de93deaa98be..1cebb8f234f8 100644 --- a/modules/gui/skins2/utils/var_tree.hpp +++ b/modules/gui/skins2/utils/var_tree.hpp @@ -37,6 +37,7 @@ typedef struct tree_update int i_type; int i_parent; int i_id; + bool b_visible; } tree_update; /// Tree variable @@ -138,9 +139,15 @@ class VarTree: public Variable, public Subject<VarTree, tree_update*> /// Given an iterator to a visible item, return the next visible item Iterator getNextVisibleItem( Iterator it ); + /// Given an iterator to an item, return the next item + Iterator getNextItem( Iterator it ); + /// Find a children node with the given id Iterator findById( int id ); + /// Ensure an item is expanded + void ensureExpanded( VarTree::Iterator ); + private: /// List of children list<VarTree> m_children; diff --git a/modules/gui/skins2/vars/playtree.cpp b/modules/gui/skins2/vars/playtree.cpp index 0f3b28267d04..bcfaa7824a56 100644 --- a/modules/gui/skins2/vars/playtree.cpp +++ b/modules/gui/skins2/vars/playtree.cpp @@ -34,6 +34,8 @@ Playtree::Playtree( intf_thread_t *pIntf ): VarTree( pIntf ) // Get the VLC playlist object m_pPlaylist = pIntf->p_sys->p_playlist; + i_items_to_append = 0; + // Try to guess the current charset char *pCharset; vlc_current_charset( &pCharset ); @@ -77,6 +79,7 @@ void Playtree::delSelected() } } } + // TODO: Do this better buildTree(); tree_update descr; descr.i_type = 1; @@ -135,6 +138,8 @@ void Playtree::onUpdateItem( int id ) void Playtree::onAppend( playlist_add_t *p_add ) { + i_items_to_append --; + Iterator node = findById( p_add->i_node ); if( node != end() ) { @@ -152,6 +157,7 @@ void Playtree::onAppend( playlist_add_t *p_add ) tree_update descr; descr.i_id = p_add->i_item; descr.i_parent = p_add->i_node; + descr.b_visible = node->m_expanded; descr.i_type = 2; notify( &descr ); } @@ -178,6 +184,8 @@ void Playtree::buildTree() clear(); vlc_mutex_lock( &m_pPlaylist->object_lock ); + i_items_to_append = 0; + playlist_view_t *p_view; p_view = playlist_ViewFind( m_pPlaylist, VIEW_CATEGORY ); /* TODO : let the user chose the view type */ diff --git a/modules/gui/skins2/vars/playtree.hpp b/modules/gui/skins2/vars/playtree.hpp index 0dbff10af190..40d01db8f57a 100644 --- a/modules/gui/skins2/vars/playtree.hpp +++ b/modules/gui/skins2/vars/playtree.hpp @@ -48,6 +48,9 @@ class Playtree: public VarTree /// Function called to notify playlist item append void onAppend( playlist_add_t * ); + /// Items waiting to be appended + int i_items_to_append; + private: /// VLC playlist object playlist_t *m_pPlaylist; -- GitLab