]> git.sesse.net Git - vlc/blob - modules/gui/skins2/utils/var_tree.hpp
Contribs: fix xml2 installation on OSX
[vlc] / modules / gui / skins2 / utils / var_tree.hpp
1 /*****************************************************************************
2  * var_tree.hpp
3  *****************************************************************************
4  * Copyright (C) 2005 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Antoine Cellerier <dionoea@videolan.org>
8  *          ClĂ©ment Stenac <zorglub@videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License along
21  * with this program; if not, write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 #ifndef VAR_TREE_HPP
26 #define VAR_TREE_HPP
27
28 #include <list>
29 #include <assert.h>
30
31 #include "variable.hpp"
32 #include "observer.hpp"
33 #include "ustring.hpp"
34 #include "var_percent.hpp"
35
36 class VarTree;
37 struct tree_update;
38
39 /// Tree variable
40 class VarTree: public Variable,
41                public Subject<VarTree, tree_update>,
42                public Observer<VarPercent>
43 {
44 public:
45     VarTree( intf_thread_t *pIntf );
46
47     VarTree( intf_thread_t *pIntf, VarTree *pParent, int id,
48              const UStringPtr &rcString, bool selected, bool playing,
49              bool expanded, bool readonly );
50     VarTree( const VarTree& );
51
52     virtual ~VarTree();
53
54     /// Iterators
55     typedef list<VarTree>::iterator Iterator;
56     typedef list<VarTree>::const_iterator ConstIterator;
57
58     /// Get the variable type
59     virtual const string &getType() const { return m_type; }
60
61     /// Add a pointer on string in the children's list
62     virtual Iterator add( int id, const UStringPtr &rcString, bool selected,
63                     bool playing, bool expanded, bool readonly, int pos = -1 );
64
65     /// Remove the selected item from the children's list
66     virtual void delSelected();
67
68     /// Remove all elements from the children's list
69     virtual void clear();
70
71     inline int  getId() { return m_id; }
72     inline UString* getString() {return (UString*)m_cString.get(); }
73     inline void setString( UStringPtr val ) { m_cString = val; }
74
75     inline bool isReadonly() { return m_readonly; };
76     inline bool isSelected() { return m_selected; };
77     inline bool isPlaying() { return m_playing; };
78     inline bool isExpanded() { return m_expanded; };
79     inline bool isFlat() { return m_flat; };
80
81     inline void setSelected( bool val ) { m_selected = val; }
82     inline void setPlaying( bool val ) { m_playing = val; }
83     inline void setExpanded( bool val ) { m_expanded = val; }
84     inline void setFlat( bool val ) { m_flat = val; }
85
86     inline void toggleSelected() { m_selected = !m_selected; }
87     inline void toggleExpanded() { setExpanded( !m_expanded ); }
88
89     /// Get the number of children
90     int size() const { return m_children.size(); }
91
92     /// iterator over visible items
93     class IteratorVisible : public Iterator
94     {
95         public:
96         IteratorVisible( const VarTree::Iterator& it, VarTree* pRootTree )
97             : VarTree::Iterator( it ), m_pRootTree( pRootTree ) {}
98
99         IteratorVisible& operator++()
100         {
101             Iterator& it = *this;
102             assert( it != end() );
103             it = isFlat() ? m_pRootTree->getNextLeaf( it ) :
104                             m_pRootTree->getNextVisibleItem( it );
105             return *this;
106         }
107
108         IteratorVisible& operator--()
109         {
110             Iterator& it = *this;
111             it = isFlat() ? m_pRootTree->getPrevLeaf( it ) :
112                             m_pRootTree->getPrevVisibleItem( it );
113             return *this;
114         }
115
116         IteratorVisible getParent()
117         {
118             IteratorVisible& it = *this;
119             if( it->parent() && it->parent() != m_pRootTree )
120             {
121                 return IteratorVisible( it->parent()->getSelf(), m_pRootTree );
122             }
123             return end();
124         }
125
126         private:
127         inline IteratorVisible begin() { return m_pRootTree->begin(); }
128         inline IteratorVisible end()   { return m_pRootTree->end(); }
129         inline bool isFlat()           { return m_pRootTree->m_flat; }
130         VarTree* m_pRootTree;
131     };
132
133     /// Beginning of the children's list
134     IteratorVisible begin()
135     {
136         return IteratorVisible(
137                m_flat ? firstLeaf() : m_children.begin(), this );
138     }
139
140     /// End of children's list
141     IteratorVisible end() { return IteratorVisible( m_children.end(), this ); }
142
143     /// Back of children's list
144     VarTree &back() { return m_children.back(); }
145
146     /// Parent node
147     VarTree *parent() { return m_pParent; }
148
149     /// Get next sibling
150     Iterator getNextSiblingOrUncle();
151     Iterator getPrevSiblingOrUncle();
152
153     Iterator getSelf()
154     {
155         assert( m_pParent );
156         Iterator it = m_pParent->m_children.begin();
157         for( ; &*it != this && it != m_pParent->m_children.end(); ++it );
158         assert( it != m_pParent->m_children.end() );
159         return it;
160     }
161
162     int getIndex()
163     {
164         if( m_pParent )
165         {
166             int i_pos = 0;
167             for( Iterator it = m_pParent->m_children.begin();
168                  it != m_pParent->m_children.end(); ++it, i_pos++ )
169                 if( &(*it) == this )
170                     return i_pos;
171         }
172         return -1;
173     }
174
175     Iterator next_uncle();
176     Iterator prev_uncle();
177
178     /// Get first leaf
179     Iterator firstLeaf();
180
181     /// Remove a child
182     void removeChild( Iterator it ) { m_children.erase( it ); }
183
184     /// Execute the action associated to this item
185     virtual void action( VarTree *pItem ) { VLC_UNUSED(pItem); }
186
187     /// Get a reference on the position variable
188     VarPercent &getPositionVar() const
189     { return *((VarPercent*)m_cPosition.get()); }
190
191     /// Get a counted pointer on the position variable
192     const VariablePtr &getPositionVarPtr() const { return m_cPosition; }
193
194     /// Count the number of items that should be displayed if the
195     /// playlist window wasn't limited
196     int visibleItems();
197
198     /// Count the number of leafs in the tree
199     int countLeafs();
200
201     /// Return iterator to the n'th visible item
202     Iterator getVisibleItem( int n );
203
204     /// Return iterator to the n'th leaf
205     Iterator getLeaf( int n );
206
207     /// Given an iterator to a visible item, return the next visible item
208     Iterator getNextVisibleItem( Iterator it );
209
210     /// Given an it to a visible item, return the previous visible item
211     Iterator getPrevVisibleItem( Iterator it );
212
213     /// Given an iterator to an item, return the next item
214     Iterator getNextItem( Iterator it );
215
216     /// Given an iterator to an item, return the previous item
217     Iterator getPrevItem( Iterator it );
218
219     /// Given an iterator to an item, return the next leaf
220     Iterator getNextLeaf( Iterator it );
221
222     /// Given an iterator to an item, return the previous leaf
223     Iterator getPrevLeaf( Iterator it );
224
225     /// Given an iterator to an item, return the parent item
226     Iterator getParent( Iterator it );
227
228     /// return index of visible item (starting from 0)
229     int getIndex( const Iterator& it );
230
231     /// Ensure an item is expanded
232     void ensureExpanded( const Iterator& it );
233
234     ///
235     Iterator getItemFromSlider();
236     void setSliderFromItem( const Iterator& it );
237
238     ///
239     void onUpdate( Subject<VarPercent> &rPercent, void* arg);
240
241     /// Get depth (root depth is 0)
242     int depth()
243     {
244         VarTree *parent = this;
245         int depth = 0;
246         while( ( parent = parent->parent() ) != NULL )
247             depth++;
248         return depth;
249     }
250
251     virtual void onUpdateSlider() {}
252
253     void unselectTree();
254
255     VarTree::IteratorVisible getItem( int index );
256
257 protected:
258
259     /// List of children
260     list<VarTree> m_children;
261
262 private:
263
264     /// Get root node
265     VarTree *root()
266     {
267         VarTree *parent = this;
268         while( parent->parent() != NULL )
269             parent = parent->parent();
270         return parent;
271     }
272
273     /// Pointer to parent node
274     VarTree *m_pParent;
275
276     int m_id;
277     UStringPtr m_cString;
278
279     /// indicators
280     bool m_readonly;
281     bool m_selected;
282     bool m_playing;
283     bool m_expanded;
284     bool m_flat;
285     bool m_dontMove;
286
287     /// Variable type
288     static const string m_type;
289
290     /// Position variable
291     VariablePtr m_cPosition;
292 };
293
294 /// Description of an update to the tree
295 typedef struct tree_update
296 {
297     enum type_t
298     {
299         ItemUpdated,
300         ItemInserted,
301         ItemDeleted,
302         DeletingItem,
303         ResetAll,
304         SliderChanged,
305     };
306     enum type_t type;
307     VarTree::IteratorVisible it;
308
309     tree_update( enum type_t t, VarTree::IteratorVisible item ) :
310         type( t ), it( item ) {}
311 } tree_update;
312
313 #endif