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;
class GenericBitmap;
/// Class for control tree
class CtrlTree: public CtrlGeneric, public Observer<VarTree, tree_update>,
public Observer<VarPercent>
class CtrlTree: public CtrlGeneric, public Observer<VarTree, tree_update>
{
public:
typedef VarTree::IteratorVisible Iterator;
CtrlTree( intf_thread_t *pIntf,
VarTree &rTree,
const GenericFont &rFont,
......@@ -76,7 +77,7 @@ public:
/// Make sure an item is visible
/// \param item an iterator to a tree item
/// \return true if it changed the position
bool ensureVisible( VarTree::Iterator item );
bool ensureVisible( const Iterator& it );
private:
/// Tree associated to the control
......@@ -95,6 +96,9 @@ private:
const GenericBitmap *m_pClosedBitmap;
/// scaled bitmap
GenericBitmap *m_pScaledBitmap;
/// Image of the control
OSGraphics *m_pImage;
/// Color of normal test
uint32_t m_fgColor;
/// Color of the playing item
......@@ -103,31 +107,30 @@ private:
uint32_t m_bgColor1, m_bgColor2;
/// Background of selected items
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
bool m_dontMove;
/// First item in the visible area
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 ?
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
virtual void onUpdate( Subject<VarTree, tree_update> &rTree ,
virtual void onUpdate( Subject<VarTree, tree_update> &rTree,
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
virtual void onPositionChange();
/// Compute the number of lines that can be displayed
int maxItems();
float maxItems();
/// Compute the item's height (depends on fonts and images used)
int itemHeight();
......@@ -135,21 +138,21 @@ private:
/// Compute the width of an item's bitmap
int itemImageWidth();
/// Check if the tree must be scrolled
void autoScroll();
/// Draw the image of the control
void makeImage();
/// Return the n'th displayed item (starting at position 0)
/**
* Return m_rTree.end() if such an item cannot be found (n < 0, or
* n too big)
*/
VarTree::Iterator findItemAtPos( int n );
/// check if id is within the visible control
bool isItemVisible( int id );
Iterator findItemAtPos( int n );
/// return the nearest item
Iterator getNearestItem( const Iterator& it );
/// return whether the item is visible or not
bool isItemVisible( const Iterator& it );
void setSliderFromFirst();
Iterator getFirstFromSlider();
void setScrollStep();
};
#endif
......@@ -35,7 +35,8 @@ class VarPercent;
class VarPercent: public Variable, public Subject<VarPercent>
{
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() { }
/// Get the variable type
......@@ -46,13 +47,19 @@ public:
virtual float get() const { return m_value; }
/// 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:
/// Variable type
static const string m_type;
/// Percent value
float m_value;
/// preferred step (for scrolling)
float m_step;
};
#endif
This diff is collapsed.
......@@ -26,47 +26,41 @@
#define VAR_TREE_HPP
#include <list>
#include <assert.h>
#include "variable.hpp"
#include "observer.hpp"
#include "ustring.hpp"
#include "var_percent.hpp"
/// Description of an update to the tree
typedef struct tree_update
{
enum type_t
{
UpdateItem,
AppendItem,
DeleteItem,
ResetAll,
};
enum type_t type;
int i_id;
bool b_active_item;
} tree_update;
class VarTree;
struct tree_update;
/// Tree variable
class VarTree: public Variable, public Subject<VarTree, tree_update>
class VarTree: public Variable,
public Subject<VarTree, tree_update>,
public Observer<VarPercent>
{
public:
VarTree( intf_thread_t *pIntf );
VarTree( intf_thread_t *pIntf, VarTree *pParent, int id,
const UStringPtr &rcString, bool selected, bool playing,
bool expanded, bool readonly, void *pData );
bool expanded, bool readonly );
VarTree( const VarTree& );
virtual ~VarTree();
/// Iterators
typedef list<VarTree>::iterator Iterator;
typedef list<VarTree>::const_iterator ConstIterator;
/// Get the variable type
virtual const string &getType() const { return m_type; }
/// Add a pointer on string in the children's list
virtual void add( int id, const UStringPtr &rcString, bool selected,
bool playing, bool expanded, bool readonly, void *pData );
virtual Iterator add( int id, const UStringPtr &rcString, bool selected,
bool playing, bool expanded, bool readonly, int pos = -1 );
/// Remove the selected item from the children's list
virtual void delSelected();
......@@ -75,7 +69,6 @@ public:
virtual void clear();
inline int getId() { return m_id; }
inline void *getData() { return m_pData; }
inline UString* getString() {return (UString*)m_cString.get(); }
inline void setString( UStringPtr val ) { m_cString = val; }
......@@ -83,43 +76,101 @@ public:
inline bool isSelected() { return m_selected; };
inline bool isPlaying() { return m_playing; };
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 setPlaying( bool val ) { m_playing = 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 toggleExpanded() { m_expanded = !m_expanded; }
inline void toggleExpanded() { setExpanded( !m_expanded ); }
/// Get the number of children
int size() const { return m_children.size(); }
/// Iterators
typedef list<VarTree>::iterator Iterator;
typedef list<VarTree>::const_iterator ConstIterator;
/// iterator over visible items
class IteratorVisible : public Iterator
{
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;
}
IteratorVisible getParent()
{
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;
};
/// Begining of the children's list
Iterator begin() { return m_children.begin(); }
ConstIterator begin() const { return m_children.begin(); }
/// Beginning of the children's list
IteratorVisible begin()
{
return IteratorVisible(
m_flat ? firstLeaf() : m_children.begin(), this );
}
/// End of children's list
Iterator end() { return m_children.end(); }
ConstIterator end() const { return m_children.end(); }
IteratorVisible end() { return IteratorVisible( m_children.end(), this ); }
/// Back of children's list
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
VarTree *parent() { return m_pParent; }
/// Get next sibling
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 prev_uncle();
......@@ -131,7 +182,7 @@ public:
void removeChild( Iterator it ) { m_children.erase( it ); }
/// 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
VarPercent &getPositionVar() const
......@@ -171,17 +222,21 @@ public:
/// Given an iterator to an item, return the previous leaf
Iterator getPrevLeaf( Iterator it );
/// return rank of visible item starting from 1
int getRank( const Iterator& it, bool flat );
/// Given an iterator to an item, return the parent item
Iterator getParent( Iterator it );
/// Find a children node with the given id
Iterator findById( int id );
/// return index of visible item (starting from 0)
int getIndex( const Iterator& it );
/// Ensure an item is expanded
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)
int depth()
......@@ -193,6 +248,17 @@ public:
return depth;
}
virtual void onUpdateSlider() {}
void unselectTree();
VarTree::IteratorVisible getItem( int index );
protected:
/// List of children
list<VarTree> m_children;
private:
/// Get root node
......@@ -204,14 +270,10 @@ private:
return parent;
}
/// List of children
list<VarTree> m_children;
/// Pointer to parent node
VarTree *m_pParent;
int m_id;
void *m_pData;
UStringPtr m_cString;
/// indicators
......@@ -219,7 +281,8 @@ private:
bool m_selected;
bool m_playing;
bool m_expanded;
bool m_deleted;
bool m_flat;
bool m_dontMove;
/// Variable type
static const string m_type;
......@@ -228,4 +291,23 @@ private:
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
This diff is collapsed.
......@@ -28,6 +28,8 @@
#include <vlc_playlist.h>
#include "../utils/var_tree.hpp"
#include <map>
/// Variable for VLC playlist (new tree format)
class Playtree: public VarTree
{
......@@ -56,13 +58,25 @@ public:
/// Function called to notify playlist item delete
void onDelete( int );
///
void onUpdateSlider();
///
void insertItems( VarTree& item, const list<string>& files, bool start );
private:
/// VLC playlist object
playlist_t *m_pPlaylist;
///
map< int, VarTree* > m_allItems;
/// Build the list from the VLC playlist
void buildTree();
/// Retrieve an iterator from playlist_item_t->id
Iterator findById( int id );
/// Update Node's children
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