]> git.sesse.net Git - vlc/blob - modules/gui/skins2/utils/var_tree.cpp
* all: don't rebuild the whole playtree when an item is updated
[vlc] / modules / gui / skins2 / utils / var_tree.cpp
1 /*****************************************************************************
2  * var_tree.cpp
3  *****************************************************************************
4  * Copyright (C) 2005 VideoLAN
5  * $Id: var_bool.hpp 9934 2005-02-15 13:55:08Z courmisch $
6  *
7  * Authors: Antoine Cellerier <dionoea@videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 #include "var_tree.hpp"
25
26
27 const string VarTree::m_type = "tree";
28
29 VarTree::VarTree( intf_thread_t *pIntf )
30     : Variable( pIntf ), m_id( 0 ), m_selected( false ), m_playing( false ),
31     m_expanded( true ), m_pData( NULL ), m_pParent( NULL )
32 {
33     // Create the position variable
34     m_cPosition = VariablePtr( new VarPercent( pIntf ) );
35     getPositionVar().set( 1.0 );
36 }
37
38 VarTree::VarTree( intf_thread_t *pIntf, VarTree *pParent, int id,
39                   const UStringPtr &rcString, bool selected, bool playing,
40                   bool expanded, void *pData )
41     : Variable( pIntf ), m_id( id ), m_cString( rcString ),
42     m_selected( selected ), m_playing( playing ), m_expanded( expanded ),
43     m_pData( pData ), m_pParent( pParent )
44 {
45     // Create the position variable
46     m_cPosition = VariablePtr( new VarPercent( pIntf ) );
47     getPositionVar().set( 1.0 );
48 }
49
50 VarTree::~VarTree()
51 {
52 // TODO : check that children are deleted
53 }
54
55 void VarTree::add( int id, const UStringPtr &rcString, bool selected,
56                    bool playing, bool expanded, void *pData )
57 {
58     m_children.push_back( VarTree( getIntf(), this, id, rcString, selected,
59                                    playing, expanded, pData ) );
60     notify();
61 }
62
63 void VarTree::delSelected()
64 {
65     Iterator it = begin();
66     while( it != end() )
67     {
68         //dig down the tree
69         if( size() ) it->delSelected();
70         //stay on some level
71         if( it->m_selected )
72         {
73             Iterator oldIt = it;
74             it++;
75             m_children.erase( oldIt );
76         }
77         else
78         {
79             it++;
80         }
81     }
82     notify();
83 }
84
85 void VarTree::clear()
86 {
87     m_children.clear();
88 }
89
90 VarTree::Iterator VarTree::operator[]( int n )
91 {
92     Iterator it;
93     int i;
94     for( it = begin(), i = 0;
95          i < n && it != end();
96          it++, i++ );
97     return it;
98 }
99
100 VarTree::ConstIterator VarTree::operator[]( int n ) const
101 {
102     ConstIterator it;
103     int i;
104     for( it = begin(), i = 0;
105          i < n && it != end();
106          it++, i++ );
107     return it;
108 }
109
110 /* find iterator to next ancestor
111  * ... which means parent++ or grandparent++ or grandgrandparent++ ... */
112 VarTree::Iterator VarTree::uncle()
113 {
114     VarTree *p_parent = parent();
115     if( p_parent != NULL )
116     {
117         VarTree *p_grandparent = p_parent->parent();
118         while( p_grandparent != NULL )
119         {
120             Iterator it = p_grandparent->begin();
121             while( it != p_grandparent->end() && &(*it) != p_parent ) it++;
122             if( it != p_grandparent->end() )
123             {
124                 it++;
125                 if( it != p_grandparent->end() )
126                 {
127                     return it;
128                 }
129             }
130             if( p_grandparent->parent() )
131             {
132                 p_parent = p_grandparent;
133                 p_grandparent = p_parent->parent();
134             }
135             else
136                 p_grandparent = NULL;
137         }
138     }
139
140     /* if we didn't return before, it means that we've reached the end */
141     return root()->end();
142 }
143
144 void VarTree::checkParents( VarTree *pParent )
145 {
146     m_pParent = pParent;
147     Iterator it = begin();
148     while( it != end() )
149     {
150         it->checkParents( this );
151         it++;
152     }
153 }
154
155 int VarTree::visibleItems()
156 {
157     int i_count = size();
158     Iterator it = begin();
159     while( it != end() )
160     {
161         if( it->m_expanded )
162         {
163             i_count += it->visibleItems();
164         }
165         it++;
166     }
167     return i_count;
168 }
169
170 VarTree::Iterator VarTree::getVisibleItem( int n )
171 {
172     Iterator it = begin();
173     while( it != end() )
174     {
175         n--;
176         if( n <= 0 ) return it;
177         if( it->m_expanded )
178         {
179             int i = n - it->visibleItems();
180             if( i <= 0 ) return it->getVisibleItem( n );
181             n = i;
182         }
183         it++;
184     }
185     return end();
186 }
187
188 VarTree::Iterator VarTree::getNextVisibleItem( Iterator it )
189 {
190     if( it->m_expanded && it->size() )
191     {
192         it = it->begin();
193     }
194     else
195     {
196         VarTree::Iterator it_old = it;
197         it++;
198         // Was 'it' the last brother? If so, look for uncles
199         if( it_old->parent() && it_old->parent()->end() == it )
200         {
201             it = it_old->uncle();
202         }
203     }
204     return it;
205 }
206
207 VarTree::Iterator VarTree::findById( int id )
208 {
209     for (Iterator it = begin(); it != end(); ++it )
210     {
211         if( it->m_id == id )
212         {
213             return it;
214         }
215         Iterator result = it->findById( id );
216         if( result != it->end() ) return result;
217     }
218     return end();
219 }
220