Create new playlists on the stack

- Only works for new sets
- Set a callback function when created
- Add a right-click menu to the ocarina treeview
- Remove songs from playlist when picking next song

Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
This commit is contained in:
Bryan Schumaker 2012-03-25 08:49:49 -04:00
parent 78787d9cf5
commit 15aabfcff0
14 changed files with 197 additions and 11 deletions

View File

@ -12,6 +12,11 @@ enum PlaylistFlags {
PL_STATIC = (1 << 1),
};
enum PlaylistType {
PLIST_SET,
PLIST_QUEUE,
};
#define RENDER(x) \
if (renderer) { \
renderer->x; \
@ -28,7 +33,9 @@ namespace libsaria
private:
unsigned int flags;
list<Track *>::iterator cur;
void incr_iter();
Track *picked_next();
protected:
string name;

View File

@ -21,6 +21,8 @@ namespace libsaria
virtual void insert_prepare();
virtual void insert(Track *, unsigned int);
virtual void insert_done();
virtual void remove_index(unsigned int);
};
}; /* Namespace: libsaria */

View File

@ -18,7 +18,9 @@ namespace libsaria
};
Playlist *new_playlist(string, unsigned int);
//void add_to_playlist(list<sid_t> &);
void set_on_new_playlist(void (*)(Playlist *));
void create_new_playlist(list<Track *> &, PlaylistType);
Playlist *stack_top();
void stack_top_pop();
void stack_init();

View File

@ -14,20 +14,26 @@ namespace ocarina
GtkWidget *box;
GtkWidget *treeview;
GtkListStore *liststore;
GtkTreeSelection *treesel;
void set_label_text();
void setup_treeview();
public:
Playlist(unsigned int);
Playlist(libsaria::Playlist *);
~Playlist();
void right_click(guint, guint64);
void list_selected_tracks(list<libsaria::Track *> &);
void set_playlist(libsaria::Playlist *);
void insert_prepare();
void insert(libsaria::Track *, unsigned int);
void insert_done();
void remove_index(unsigned int);
};
namespace playlist

View File

@ -16,8 +16,9 @@ namespace libsaria
void Playlist::add_sorted(list<Track *> &tracks)
{
list<Track *> copy;
list<Track *>::iterator it, cur;
list<Track *>::iterator it, cur_it;
unsigned int ins_index;
bool update_cur = (plist.size() == 0);
RENDER(insert_prepare());
tracks.sort(compare_tracks);
@ -27,8 +28,8 @@ namespace libsaria
ins_index = 0;
it = tracks.begin();
for (cur = plist.begin(); cur != plist.end(); cur++) {
if ((*cur) == (*it)) {
for (cur_it = plist.begin(); cur_it != plist.end(); cur_it++) {
if ((*cur_it) == (*it)) {
RENDER( insert(*it, ins_index) );
if (it++ == tracks.end())
break;
@ -36,6 +37,9 @@ namespace libsaria
ins_index++;
}
if (update_cur)
cur = plist.begin();
RENDER(insert_done());
}

View File

@ -1,8 +1,9 @@
// Copyright (c) 2012 Bryan Schumaker.
#include <libsaria/playlist.h>
//#include <libsaria/renderer.h>
#include <libsaria/renderer.h>
#include <libsaria/index.h>
#include <libsaria/prefs.h>
#include <libsaria/print.h>
#include <stdlib.h>
@ -24,6 +25,26 @@ namespace libsaria
if (cur == plist.end())
cur = plist.begin();
}
Track *Playlist::picked_next()
{
Track *res = (*cur);
unsigned int index = 0;
list<Track *>::iterator it;
if (flags & PL_NO_DRAIN)
return res;
for (it = plist.begin(); it != cur; it++)
index++;
cur = plist.erase(cur);
if (cur == plist.end())
cur = plist.begin();
RENDER(remove_index(index));
return res;
}
/*
bool Playlist::pick_next(list<Track *>::iterator &it)
{
@ -81,11 +102,16 @@ namespace libsaria
if (size == 0)
return NULL;
if (size == 1) {
cur = plist.begin();
return picked_next();
}
n = rand() % ((size * 3) / 4);
for (unsigned int i = 0; i < n; i++)
incr_iter();
return (*cur);
return picked_next();
}
/*Track *Playlist::next()

View File

@ -32,6 +32,10 @@ namespace libsaria
{
}
void PlaylistRenderer::remove_index(unsigned int index)
{
}
/*void PlaylistRenderer::set_playlist(Playlist *plist, bool del_render)
{
playlist = plist;

View File

@ -7,6 +7,9 @@
#include <sstream>
using namespace std;
static unsigned int next_playlist = 0;
static void (*on_new_playlist)(libsaria::Playlist *) = NULL;
static list<libsaria::Playlist *> playlist_stack;
/*static void plist_loaded()
@ -14,6 +17,13 @@ static list<libsaria::Playlist *> playlist_stack;
trigger_callback(NEW_PLAYLIST);
}*/
static string get_next_name()
{
stringstream s;
s << next_playlist;
return s.str();
}
namespace libsaria
{
@ -30,12 +40,29 @@ namespace libsaria
track->play_now();
}
Playlist *new_playlist(string file, unsigned int flags)
void set_on_new_playlist(void (*func)(Playlist *))
{
/*Playlist *plist = new Playlist(file, flags);
stack_playlist(plist);
return plist;*/
return NULL;
on_new_playlist = func;
}
void create_new_playlist(list<Track *> &tracks, PlaylistType type)
{
Playlist *plist;
switch (type) {
case PLIST_SET:
plist = new Set("Set_" + get_next_name(), PL_NONE);
break;
case PLIST_QUEUE:
return;
};
if (on_new_playlist)
on_new_playlist(plist);
plist->add_tracks(tracks);
stack::push(plist);
next_playlist++;
}
/*void add_to_playlist(list<sid_t> &ids)

View File

@ -1,14 +1,21 @@
// Copyright (c) 2011 Bryan Schumaker
#include <ocarina/playlist.h>
#include <libsaria/library.h>
#include <libsaria/stack.h>
static ocarina::Playlist library_renderer(PL_STATIC);
namespace ocarina
{
void on_new_playlist(libsaria::Playlist *plist)
{
new Playlist(plist);
}
void playlist::init()
{
libsaria::set_on_new_playlist(on_new_playlist);
library_renderer.set_playlist(libsaria::library::get_playlist());
}

View File

@ -38,4 +38,12 @@ namespace ocarina
set_label_text();
}
void Playlist::remove_index(unsigned int index)
{
GtkTreeIter iter;
gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(liststore), &iter, NULL, index);
gtk_list_store_remove(liststore, &iter);
set_label_text();
}
};

63
ocarina/playlist/menu.cpp Normal file
View File

@ -0,0 +1,63 @@
// Copyright (c) 2012 Bryan Schumaker
#include <ocarina/playlist.h>
#include "playlist.h"
#include <libsaria/stack.h>
#include <libsaria/track.h>
#include <list>
using namespace std;
#define BUTTON_RIGHT 3
static void new_playlist(ocarina::Playlist *plist, PlaylistType type)
{
list<libsaria::Track *> tracks;
plist->list_selected_tracks(tracks);
libsaria::create_new_playlist(tracks, type);
}
static void new_queue(GtkMenuItem *menu, gpointer data)
{
new_playlist((ocarina::Playlist *)data, PLIST_QUEUE);
}
static void new_set(GtkMenuItem *menu, gpointer data)
{
new_playlist((ocarina::Playlist *)data, PLIST_SET);
}
static GtkWidget *menu_item(const char *text, void (*func)(GtkMenuItem *, gpointer),
ocarina::Playlist *plist)
{
GtkWidget *widget = gtk_menu_item_new_with_label(text);
g_signal_connect(widget, "activate", G_CALLBACK(func), plist);
return widget;
}
void show_rc_menu(GtkWidget *widget, GdkEvent *event, gpointer data)
{
ocarina::Playlist *plist = (ocarina::Playlist *)data;
if (event->button.button != BUTTON_RIGHT)
return;
plist->right_click(event->button.button, event->button.time);
}
namespace ocarina
{
void Playlist::right_click(guint button, guint64 time)
{
GtkWidget *menu = gtk_menu_new();
GtkWidget *queue = menu_item("Add to new queue", new_queue, this);
GtkWidget *set = menu_item("Add to new set", new_set, this);
gtk_menu_append(GTK_MENU(menu), queue);
gtk_menu_append(GTK_MENU(menu), set);
gtk_widget_show_all(menu);
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, button, time);
}
}

View File

@ -2,9 +2,21 @@
#include <ocarina/playlist.h>
#include <ocarina/body.h>
#include <libsaria/track.h>
#include <sstream>
using namespace std;
static void selected_foreach_list(GtkTreeModel *model, GtkTreePath *path,
GtkTreeIter *iter, gpointer data)
{
libsaria::Track *track;
list<libsaria::Track *> *tracks = (list<libsaria::Track *> *)data;
gtk_tree_model_get(model, iter, 0, &track, -1);
tracks->push_back(track);
}
namespace ocarina
{
@ -12,6 +24,11 @@ namespace ocarina
{
}
Playlist::Playlist(libsaria::Playlist *plist): libsaria::PlaylistRenderer(PL_NONE)
{
set_playlist(plist);
}
Playlist::~Playlist()
{
}
@ -28,6 +45,11 @@ namespace ocarina
gtk_label_set_text(GTK_LABEL(label), text.c_str());
}
void Playlist::list_selected_tracks(list<libsaria::Track *> &tracks)
{
gtk_tree_selection_selected_foreach(treesel, selected_foreach_list, &tracks);
}
void Playlist::set_playlist(libsaria::Playlist *p)
{
libsaria::PlaylistRenderer::set_playlist(p);

View File

@ -0,0 +1,2 @@
// Copyright (c) 2012 Bryan Schumaker
void show_rc_menu(GtkWidget *widget, GdkEvent *event, gpointer data);

View File

@ -1,5 +1,7 @@
// Copyright (c) 2012 Bryan Schumaker
#include <ocarina/playlist.h>
#include "playlist.h"
#include <libsaria/track.h>
struct column_info {
@ -86,7 +88,11 @@ namespace ocarina
treeview = gtk_tree_view_new();
liststore = setup_liststore(treeview);
treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
gtk_tree_selection_set_mode(treesel, GTK_SELECTION_MULTIPLE);
g_signal_connect(treeview, "row-activated", G_CALLBACK(track_selected), NULL);
g_signal_connect(treeview, "button-release-event", G_CALLBACK(show_rc_menu), this);
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE);
gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(liststore));