Commit a9beb407 authored by Erwan Tulou's avatar Erwan Tulou

skins2: fix some important playlist limitations or bugs

This patch includes the following :
  - fix item misplacement (items were only appended instead of being inserted)
  - fix slider scrolling that could not adapt to the real size of the playlist
  - enhance drag&drop by allowing users to finely insert item being dropped
    into either the playlist or the media library.
  - optimise refresh (only rebuild playtree in case of visible item)
  - remove keeping a reference to a playlist_item_t* (since it is not
    refcounted, a lookup from the playlist with proper lock mechanism
    is needed)
  - remove the m_deleted flag (corner cases were never dealt with) and
    replace it with a notification prior to deletion
  - implement operator++ to simplify iterating visible items (cosmetics)

A deeper redesign/simplification and support for the new sql playlist would be a good thing though.
parent 1653a66d
This diff is collapsed.
...@@ -34,10 +34,11 @@ class GenericFont; ...@@ -34,10 +34,11 @@ class GenericFont;
class GenericBitmap; class GenericBitmap;
/// Class for control tree /// Class for control tree
class CtrlTree: public CtrlGeneric, public Observer<VarTree, tree_update>, class CtrlTree: public CtrlGeneric, public Observer<VarTree, tree_update>
public Observer<VarPercent>
{ {
public: public:
typedef VarTree::IteratorVisible Iterator;
CtrlTree( intf_thread_t *pIntf, CtrlTree( intf_thread_t *pIntf,
VarTree &rTree, VarTree &rTree,
const GenericFont &rFont, const GenericFont &rFont,
...@@ -76,7 +77,7 @@ public: ...@@ -76,7 +77,7 @@ public:
/// Make sure an item is visible /// Make sure an item is visible
/// \param item an iterator to a tree item /// \param item an iterator to a tree item
/// \return true if it changed the position /// \return true if it changed the position
bool ensureVisible( VarTree::Iterator item ); bool ensureVisible( const Iterator& it );
private: private:
/// Tree associated to the control /// Tree associated to the control
...@@ -95,6 +96,9 @@ private: ...@@ -95,6 +96,9 @@ private:
const GenericBitmap *m_pClosedBitmap; const GenericBitmap *m_pClosedBitmap;
/// scaled bitmap /// scaled bitmap
GenericBitmap *m_pScaledBitmap; GenericBitmap *m_pScaledBitmap;
/// Image of the control
OSGraphics *m_pImage;
/// Color of normal test /// Color of normal test
uint32_t m_fgColor; uint32_t m_fgColor;
/// Color of the playing item /// Color of the playing item
...@@ -103,31 +107,30 @@ private: ...@@ -103,31 +107,30 @@ private:
uint32_t m_bgColor1, m_bgColor2; uint32_t m_bgColor1, m_bgColor2;
/// Background of selected items /// Background of selected items
uint32_t m_selColor; uint32_t m_selColor;
/// Pointer on the last selected item in the tree
VarTree *m_pLastSelected;
/// Image of the control
OSGraphics *m_pImage;
/// First item in the visible area
VarTree::Iterator m_firstPos;
/// Don't move if the position variable is updated /// First item in the visible area
bool m_dontMove; Iterator m_firstPos;
/// Pointer on the last clicked item in the tree
Iterator m_lastClicked;
///
Iterator m_itOver;
/// Do we want to "flaten" the tree ? /// Do we want to "flaten" the tree ?
bool m_flat; bool m_flat;
/// Number of visible lines
float m_capacity;
/// flag for item deletion
bool m_bRefreshOnDelete;
/// Method called when the tree variable is modified /// Method called when the tree variable is modified
virtual void onUpdate( Subject<VarTree, tree_update> &rTree , virtual void onUpdate( Subject<VarTree, tree_update> &rTree,
tree_update *); tree_update *);
// Method called when the position variable of the tree is modified
virtual void onUpdate( Subject<VarPercent> &rPercent , void *);
/// Called when the position is set /// Called when the position is set
virtual void onPositionChange(); virtual void onPositionChange();
/// Compute the number of lines that can be displayed /// Compute the number of lines that can be displayed
int maxItems(); float maxItems();
/// Compute the item's height (depends on fonts and images used) /// Compute the item's height (depends on fonts and images used)
int itemHeight(); int itemHeight();
...@@ -135,21 +138,21 @@ private: ...@@ -135,21 +138,21 @@ private:
/// Compute the width of an item's bitmap /// Compute the width of an item's bitmap
int itemImageWidth(); int itemImageWidth();
/// Check if the tree must be scrolled
void autoScroll();
/// Draw the image of the control /// Draw the image of the control
void makeImage(); void makeImage();
/// Return the n'th displayed item (starting at position 0) /// Return the n'th displayed item (starting at position 0)
/** Iterator findItemAtPos( int n );
* Return m_rTree.end() if such an item cannot be found (n < 0, or
* n too big) /// return the nearest item
*/ Iterator getNearestItem( const Iterator& it );
VarTree::Iterator findItemAtPos( int n );
/// return whether the item is visible or not
/// check if id is within the visible control bool isItemVisible( const Iterator& it );
bool isItemVisible( int id );
void setSliderFromFirst();
Iterator getFirstFromSlider();
void setScrollStep();
}; };
#endif #endif
...@@ -35,7 +35,8 @@ class VarPercent; ...@@ -35,7 +35,8 @@ class VarPercent;
class VarPercent: public Variable, public Subject<VarPercent> class VarPercent: public Variable, public Subject<VarPercent>
{ {
public: public:
VarPercent( intf_thread_t *pIntf ): Variable( pIntf ), m_value( 0 ) { } VarPercent( intf_thread_t *pIntf ) :
Variable( pIntf ), m_value( 0 ), m_step( .05f ) {}
virtual ~VarPercent() { } virtual ~VarPercent() { }
/// Get the variable type /// Get the variable type
...@@ -46,13 +47,19 @@ public: ...@@ -46,13 +47,19 @@ public:
virtual float get() const { return m_value; } virtual float get() const { return m_value; }
/// Get the variable preferred step /// Get the variable preferred step
virtual float getStep() const { return .05f; } virtual float getStep() const { return m_step; }
virtual void setStep( float val ) { m_step = val; }
/// Increment or decrement variable
void increment( int num ) { return set( m_value + num * m_step ); }
private: private:
/// Variable type /// Variable type
static const string m_type; static const string m_type;
/// Percent value /// Percent value
float m_value; float m_value;
/// preferred step (for scrolling)
float m_step;
}; };
#endif #endif
This diff is collapsed.
...@@ -26,47 +26,41 @@ ...@@ -26,47 +26,41 @@
#define VAR_TREE_HPP #define VAR_TREE_HPP
#include <list> #include <list>
#include <assert.h>
#include "variable.hpp" #include "variable.hpp"
#include "observer.hpp" #include "observer.hpp"
#include "ustring.hpp" #include "ustring.hpp"
#include "var_percent.hpp" #include "var_percent.hpp"
/// Description of an update to the tree class VarTree;
typedef struct tree_update struct tree_update;
{
enum type_t
{
UpdateItem,
AppendItem,
DeleteItem,
ResetAll,
};
enum type_t type;
int i_id;
bool b_active_item;
} tree_update;
/// Tree variable /// Tree variable
class VarTree: public Variable, public Subject<VarTree, tree_update> class VarTree: public Variable,
public Subject<VarTree, tree_update>,
public Observer<VarPercent>
{ {
public: public:
VarTree( intf_thread_t *pIntf ); VarTree( intf_thread_t *pIntf );
VarTree( intf_thread_t *pIntf, VarTree *pParent, int id, VarTree( intf_thread_t *pIntf, VarTree *pParent, int id,
const UStringPtr &rcString, bool selected, bool playing, const UStringPtr &rcString, bool selected, bool playing,
bool expanded, bool readonly, void *pData ); bool expanded, bool readonly );
VarTree( const VarTree& );
virtual ~VarTree(); virtual ~VarTree();
/// Iterators
typedef list<VarTree>::iterator Iterator;
typedef list<VarTree>::const_iterator ConstIterator;
/// Get the variable type /// Get the variable type
virtual const string &getType() const { return m_type; } virtual const string &getType() const { return m_type; }
/// Add a pointer on string in the children's list /// Add a pointer on string in the children's list
virtual void add( int id, const UStringPtr &rcString, bool selected, virtual Iterator add( int id, const UStringPtr &rcString, bool selected,
bool playing, bool expanded, bool readonly, void *pData ); bool playing, bool expanded, bool readonly, int pos = -1 );
/// Remove the selected item from the children's list /// Remove the selected item from the children's list
virtual void delSelected(); virtual void delSelected();
...@@ -75,7 +69,6 @@ public: ...@@ -75,7 +69,6 @@ public:
virtual void clear(); virtual void clear();
inline int getId() { return m_id; } inline int getId() { return m_id; }
inline void *getData() { return m_pData; }
inline UString* getString() {return (UString*)m_cString.get(); } inline UString* getString() {return (UString*)m_cString.get(); }
inline void setString( UStringPtr val ) { m_cString = val; } inline void setString( UStringPtr val ) { m_cString = val; }
...@@ -83,43 +76,101 @@ public: ...@@ -83,43 +76,101 @@ public:
inline bool isSelected() { return m_selected; }; inline bool isSelected() { return m_selected; };
inline bool isPlaying() { return m_playing; }; inline bool isPlaying() { return m_playing; };
inline bool isExpanded() { return m_expanded; }; inline bool isExpanded() { return m_expanded; };
inline bool isDeleted() { return m_deleted; }; inline bool isFlat() { return m_flat; };
inline void setSelected( bool val ) { m_selected = val; } inline void setSelected( bool val ) { m_selected = val; }
inline void setPlaying( bool val ) { m_playing = val; } inline void setPlaying( bool val ) { m_playing = val; }
inline void setExpanded( bool val ) { m_expanded = val; } inline void setExpanded( bool val ) { m_expanded = val; }
inline void setDeleted( bool val ) { m_deleted = val; } inline void setFlat( bool val ) { m_flat = val; }
inline void toggleSelected() { m_selected = !m_selected; } inline void toggleSelected() { m_selected = !m_selected; }
inline void toggleExpanded() { m_expanded = !m_expanded; } inline void toggleExpanded() { setExpanded( !m_expanded ); }
/// Get the number of children /// Get the number of children
int size() const { return m_children.size(); } int size() const { return m_children.size(); }
/// Iterators /// iterator over visible items
typedef list<VarTree>::iterator Iterator; class IteratorVisible : public Iterator
typedef list<VarTree>::const_iterator ConstIterator; {
public:
IteratorVisible( const VarTree::Iterator& it, VarTree* pRootTree )
: VarTree::Iterator( it ), m_pRootTree( pRootTree ) {}
IteratorVisible& operator++()
{
Iterator& it = *this;
assert( it != end() );
it = isFlat() ? m_pRootTree->getNextLeaf( it ) :
m_pRootTree->getNextVisibleItem( it );
return *this;
}
IteratorVisible& operator--()
{
Iterator& it = *this;
it = isFlat() ? m_pRootTree->getPrevLeaf( it ) :
m_pRootTree->getPrevVisibleItem( it );
return *this;
}
/// Begining of the children's list IteratorVisible getParent()
Iterator begin() { return m_children.begin(); } {
ConstIterator begin() const { return m_children.begin(); } IteratorVisible& it = *this;
if( it->parent() && it->parent() != m_pRootTree )
{
return IteratorVisible( it->parent()->getSelf(), m_pRootTree );
}
return end();
}
private:
inline IteratorVisible begin() { return m_pRootTree->begin(); }
inline IteratorVisible end() { return m_pRootTree->end(); }
inline bool isFlat() { return m_pRootTree->m_flat; }
VarTree* m_pRootTree;
};
/// Beginning of the children's list
IteratorVisible begin()
{
return IteratorVisible(
m_flat ? firstLeaf() : m_children.begin(), this );
}
/// End of children's list /// End of children's list
Iterator end() { return m_children.end(); } IteratorVisible end() { return IteratorVisible( m_children.end(), this ); }
ConstIterator end() const { return m_children.end(); }
/// Back of children's list /// Back of children's list
VarTree &back() { return m_children.back(); } VarTree &back() { return m_children.back(); }
/// Return an iterator on the n'th element of the children's list
Iterator operator[]( int n );
ConstIterator operator[]( int n ) const;
/// Parent node /// Parent node
VarTree *parent() { return m_pParent; } VarTree *parent() { return m_pParent; }
/// Get next sibling /// Get next sibling
Iterator getNextSiblingOrUncle(); Iterator getNextSiblingOrUncle();
Iterator getPrevSiblingOrUncle();
Iterator getSelf()
{
assert( m_pParent );
Iterator it = m_pParent->m_children.begin();
for( ; &*it != this && it != m_pParent->m_children.end(); ++it );
assert( it != m_pParent->m_children.end() );
return it;
}
int getIndex()
{
if( m_pParent )
{
int i_pos = 0;
for( Iterator it = m_pParent->m_children.begin();
it != m_pParent->m_children.end(); ++it, i_pos++ )
if( &(*it) == this )
return i_pos;
}
return -1;
}
Iterator next_uncle(); Iterator next_uncle();
Iterator prev_uncle(); Iterator prev_uncle();
...@@ -131,7 +182,7 @@ public: ...@@ -131,7 +182,7 @@ public:
void removeChild( Iterator it ) { m_children.erase( it ); } void removeChild( Iterator it ) { m_children.erase( it ); }
/// Execute the action associated to this item /// Execute the action associated to this item
virtual void action( VarTree *pItem ) { (void)pItem; } virtual void action( VarTree *pItem ) { VLC_UNUSED(pItem); }
/// Get a reference on the position variable /// Get a reference on the position variable
VarPercent &getPositionVar() const VarPercent &getPositionVar() const
...@@ -171,17 +222,21 @@ public: ...@@ -171,17 +222,21 @@ public:
/// Given an iterator to an item, return the previous leaf /// Given an iterator to an item, return the previous leaf
Iterator getPrevLeaf( Iterator it ); Iterator getPrevLeaf( Iterator it );
/// return rank of visible item starting from 1 /// Given an iterator to an item, return the parent item
int getRank( const Iterator& it, bool flat ); Iterator getParent( Iterator it );
/// Find a children node with the given id /// return index of visible item (starting from 0)
Iterator findById( int id ); int getIndex( const Iterator& it );
/// Ensure an item is expanded /// Ensure an item is expanded
void ensureExpanded( const Iterator& it ); void ensureExpanded( const Iterator& it );
/// flag a whole subtree for deletion ///
void cascadeDelete(); Iterator getItemFromSlider();
void setSliderFromItem( const Iterator& it );
///
void onUpdate( Subject<VarPercent> &rPercent, void* arg);
/// Get depth (root depth is 0) /// Get depth (root depth is 0)
int depth() int depth()
...@@ -193,6 +248,17 @@ public: ...@@ -193,6 +248,17 @@ public:
return depth; return depth;
} }
virtual void onUpdateSlider() {}
void unselectTree();
VarTree::IteratorVisible getItem( int index );
protected:
/// List of children
list<VarTree> m_children;
private: private:
/// Get root node /// Get root node
...@@ -204,14 +270,10 @@ private: ...@@ -204,14 +270,10 @@ private:
return parent; return parent;
} }
/// List of children
list<VarTree> m_children;
/// Pointer to parent node /// Pointer to parent node
VarTree *m_pParent; VarTree *m_pParent;
int m_id; int m_id;
void *m_pData;
UStringPtr m_cString; UStringPtr m_cString;
/// indicators /// indicators
...@@ -219,7 +281,8 @@ private: ...@@ -219,7 +281,8 @@ private:
bool m_selected; bool m_selected;
bool m_playing; bool m_playing;
bool m_expanded; bool m_expanded;
bool m_deleted; bool m_flat;
bool m_dontMove;
/// Variable type /// Variable type
static const string m_type; static const string m_type;
...@@ -228,4 +291,23 @@ private: ...@@ -228,4 +291,23 @@ private:
VariablePtr m_cPosition; VariablePtr m_cPosition;
}; };
/// Description of an update to the tree
typedef struct tree_update
{
enum type_t
{
ItemUpdated,
ItemInserted,
ItemDeleted,
DeletingItem,
ResetAll,
SliderChanged,
};
enum type_t type;
VarTree::IteratorVisible it;
tree_update( enum type_t t, VarTree::IteratorVisible item ) :
type( t ), it( item ) {}
} tree_update;
#endif #endif
This diff is collapsed.
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#include <vlc_playlist.h> #include <vlc_playlist.h>
#include "../utils/var_tree.hpp" #include "../utils/var_tree.hpp"
#include <map>
/// Variable for VLC playlist (new tree format) /// Variable for VLC playlist (new tree format)
class Playtree: public VarTree class Playtree: public VarTree
{ {
...@@ -56,13 +58,25 @@ public: ...@@ -56,13 +58,25 @@ public:
/// Function called to notify playlist item delete /// Function called to notify playlist item delete
void onDelete( int ); void onDelete( int );
///
void onUpdateSlider();
///
void insertItems( VarTree& item, const list<string>& files, bool start );
private: private:
/// VLC playlist object /// VLC playlist object
playlist_t *m_pPlaylist; playlist_t *m_pPlaylist;
///
map< int, VarTree* > m_allItems;
/// Build the list from the VLC playlist /// Build the list from the VLC playlist
void buildTree(); void buildTree();
/// Retrieve an iterator from playlist_item_t->id
Iterator findById( int id );
/// Update Node's children /// Update Node's children
void buildNode( playlist_item_t *p_node, VarTree &m_pNode ); void buildNode( playlist_item_t *p_node, VarTree &m_pNode );
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment