gui/view: Add a right-click menu

Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2016-01-22 11:22:14 -05:00
parent c9eb9d724b
commit 8e6b963eb8
4 changed files with 110 additions and 214 deletions

View File

@ -84,8 +84,6 @@ Tab :: Tab(queue *pq)
tab_builder->get_widget_derived("QueueWindow", tab_window);
tab_window->init(tab_pq);
tab_window->q_treeview->signal_button_press_event().connect(sigc::mem_fun(*this,
&Tab :: on_button_pressed), false);
for (unsigned int i = 0; i < tab_window->q_treeview->get_n_columns(); i++)
tab_window->q_treeview->get_column(i)->signal_clicked().connect(
@ -155,113 +153,6 @@ void Tab :: tab_unmap()
queue_mapping.erase(tab_pq);
}
void Tab :: tab_selected_ids(std::vector<unsigned int> &ids)
{
Glib::RefPtr<Gtk::TreeSelection> sel = tab_window->q_treeview->get_selection();
std::vector<Gtk::TreeModel::Path> rows = sel->get_selected_rows();
GtkTreePath *path;
struct track *track;
for (unsigned int i = 0; i < rows.size(); i++) {
path = rows[i].gobj();
track = gui_queue_model_path_get_track(gui_queue(tab_pq)->gq_model,
path);
ids.push_back(track->tr_dbe.dbe_index);
}
sel->unselect_all();
}
void Tab :: tab_queue_add(queue *pq)
{
std::vector<unsigned int> ids;
tab_selected_ids(ids);
for (unsigned int i = 0; i < ids.size(); i++)
queue_add(pq, track_get(ids[i]));
}
bool Tab :: tab_queue_selected(bool random)
{
unsigned int flags = random ? Q_RANDOM : 0;
if (tempq_count() >= 10)
return true;
queue *pq = tempq_alloc(flags);
on_pq_created(pq, tempq_count() - 1);
gui_sidebar_add(gui_queue(pq));
tab_queue_add(pq);
return true;
}
bool Tab :: tab_add_to_queue(unsigned int n)
{
if (n >= tempq_count())
return true;
queue *pq = tempq_get(n);
tab_queue_add(pq);
return true;
}
bool Tab :: tab_add_to_playlist(enum playlist_t plist)
{
std::vector<unsigned int> ids;
tab_selected_ids(ids);
for (unsigned int i = 0; i < ids.size(); i++) {
if (plist == PL_HIDDEN)
collection_ban(track_get(ids[i]));
else
playlist_add(plist, track_get(ids[i]));
}
return true;
}
bool Tab :: tab_favorite_selected()
{
return tab_add_to_playlist(PL_FAVORITED);
}
void Tab :: tab_ban_selected()
{
tab_add_to_playlist(PL_HIDDEN);
}
/**
*
* Tab callback functions
*
*/
void Tab :: on_show_rc_menu()
{
std::string item;
unsigned int size = tempq_count();
if (size == 0) {
Glib :: wrap(GTK_MENU_ITEM(gui_builder_widget("o_add_to_pq")), false)->hide();
return;
}
Glib :: wrap(GTK_MENU_ITEM(gui_builder_widget("o_add_to_pq")), false)->show();
if (size == 10)
Glib :: wrap(GTK_MENU_ITEM(gui_builder_widget("o_new_pq")), false)->hide();
else
Glib :: wrap(GTK_MENU_ITEM(gui_builder_widget("o_new_pq")), false)->show();
for (unsigned int i = 0; i < 10; i++) {
item = "o_pq_";
item += '0' + i;
if (i < size)
Glib :: wrap(GTK_MENU_ITEM(gui_builder_widget(item.c_str())), false)->show();
else
Glib :: wrap(GTK_MENU_ITEM(gui_builder_widget(item.c_str())), false)->hide();
}
}
/**
@ -284,20 +175,6 @@ void Tab :: on_column_clicked(unsigned int col)
sigc::mem_fun(*this, &Tab::tab_dec_sort_count), 2);
}
bool Tab :: on_button_pressed(GdkEventButton *button)
{
if (button->button != 3)
return false;
Gtk::TreeModel::Path path;
if (tab_window->q_treeview->get_path_at_pos(button->x, button->y, path))
tab_window->q_treeview->get_selection()->select(path);
on_show_rc_menu();
Glib :: wrap(GTK_MENU(gui_builder_widget("o_rc_menu")), false)->popup(button->button, button->time);
return true;
}
/**
@ -325,16 +202,6 @@ static Tab *find_tab(int num)
return NULL;
}
static Tab *cur_tab()
{
std::map<queue *, Tab *>::iterator it;
for (it = queue_mapping.begin(); it != queue_mapping.end(); it++) {
if (it->second->tab_is_cur())
return it->second;
}
return NULL;
}
static void on_switch_page(Gtk::Widget *page, int num)
{
Tab *tab = find_tab(num);
@ -344,41 +211,6 @@ static void on_switch_page(Gtk::Widget *page, int num)
Glib :: wrap(GTK_LABEL(gui_builder_widget("o_queue_time")), false)->set_text("");
}
static void on_new_pq()
{
Tab *tab = cur_tab();
if (tab)
tab->tab_queue_selected(false);
}
static void on_add_to_favs()
{
Tab *tab = cur_tab();
if (tab)
tab->tab_favorite_selected();
}
static void on_add_to_banned()
{
Tab *tab = cur_tab();
if (tab)
tab->tab_ban_selected();
}
static void on_add_to_queue(unsigned int n)
{
Tab *tab = cur_tab();
if (tab)
tab->tab_add_to_queue(n);
}
static void init_menu_item(const std::string &pq, unsigned int n)
{
Glib :: wrap(GTK_MENU_ITEM(gui_builder_widget(pq.c_str())), false)->signal_activate().connect(
sigc::bind<unsigned int> (sigc::ptr_fun(on_add_to_queue), n));
}
static bool on_window_key_pressed(GdkEventKey *event)
{
Gtk::Notebook *notebook = Glib :: wrap(GTK_NOTEBOOK(gui_builder_widget("o_notebook")), false);
@ -414,20 +246,6 @@ void init_tabs()
struct Gtk::Notebook *notebook = Glib :: wrap(GTK_NOTEBOOK(gui_builder_widget("o_notebook")), false);
notebook->signal_switch_page().connect(sigc::ptr_fun(on_switch_page));
/* Menu signals */
Glib :: wrap(GTK_MENU(gui_builder_widget("o_rc_menu")), false)->show_all();
Glib :: wrap(GTK_MENU_ITEM(gui_builder_widget("o_new_pq")), false)->signal_activate().connect(
sigc::ptr_fun(on_new_pq));
Glib :: wrap(GTK_MENU_ITEM(gui_builder_widget("o_add_to_favorites")), false)->signal_activate().connect(
sigc::ptr_fun(on_add_to_favs));
Glib :: wrap(GTK_MENU_ITEM(gui_builder_widget("o_add_to_banned")), false)->signal_activate().connect(
sigc::ptr_fun(on_add_to_banned));
for (unsigned int i = 0; i < 10; i++) {
std::string pq = "o_pq_";
pq += '0' + i;
init_menu_item(pq, i);
}
/* Initialize other tabs */
init_history_tab();
init_collection_tab();

View File

@ -2,6 +2,7 @@
* Copyright 2016 (c) Anna Schumaker.
*/
#include <core/audio.h>
#include <core/collection.h>
#include <core/playlist.h>
#include <core/tempq.h>
#include <gui/builder.h>
@ -105,17 +106,17 @@ static void __view_delete_selection(GtkTreeSelection *selection)
g_list_free_full(rows, (GDestroyNotify) gtk_tree_path_free);
}
void __view_keypress(GtkTreeView *treeview, GdkEventKey *event, gpointer data)
static void __view_process_selection(GtkTreeView *treeview, unsigned int keyval)
{
GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
unsigned int flags = 0;
struct queue *queue;
switch (event->keyval) {
switch (keyval) {
case GDK_KEY_KP_0 ... GDK_KEY_KP_9:
event->keyval = (event->keyval - GDK_KEY_KP_0) + GDK_KEY_0;
keyval = (keyval - GDK_KEY_KP_0) + GDK_KEY_0;
case GDK_KEY_0 ... GDK_KEY_9:
queue = tempq_get(event->keyval - GDK_KEY_0);
queue = tempq_get(keyval - GDK_KEY_0);
if (queue)
gtk_tree_selection_selected_foreach(selection,
__view_add_to_queue, queue);
@ -138,6 +139,82 @@ void __view_keypress(GtkTreeView *treeview, GdkEventKey *event, gpointer data)
}
}
void __view_keypress(GtkTreeView *treeview, GdkEventKey *event, gpointer data)
{
__view_process_selection(treeview, event->keyval);
}
void __view_rc_new_queue(GtkMenuItem *item, gpointer data)
{
__view_process_selection(view_treeview, GDK_KEY_q);
}
void __view_rc_add_to_queue(GtkMenuItem *item, gpointer data)
{
unsigned int i;
gchar *name;
for (i = 0; i < 10; i++) {
name = g_strdup_printf("o_queue_%d", i);
if (GTK_WIDGET(item) == gui_builder_widget(name))
__view_process_selection(view_treeview, GDK_KEY_0 + i);
g_free(name);
}
}
void __view_rc_add_favorites(GtkMenuItem *item, gpointer data)
{
__view_process_selection(view_treeview, GDK_KEY_f);
}
void __view_rc_add_hidden(GtkMenuItem *item, gpointer data)
{
GtkTreeSelection *selection = gtk_tree_view_get_selection(view_treeview);
GList *rows = gtk_tree_selection_get_selected_rows(selection, NULL);
GList *cur = g_list_reverse(rows);
while (cur) {
collection_ban(__view_filter_get_track(cur->data));
cur = g_list_next(cur);
}
g_list_free_full(rows, (GDestroyNotify) gtk_tree_path_free);
}
bool __view_button_press(GtkTreeView *treeview, GdkEventButton *event,
gpointer data)
{
GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
GtkMenu *menu = GTK_MENU(gui_builder_widget("o_menu"));
unsigned int i, size = tempq_count();
GtkTreePath *path;
gchar *name;
if (event->button != 3)
return false;
/* Select path if it isn't already selected */
if (gtk_tree_view_get_path_at_pos(treeview, event->x, event->y,
&path, NULL, NULL, NULL))
{
gtk_tree_selection_select_path(selection, path);
gtk_tree_path_free(path);
}
/* Determine which menu items can be shown */
gtk_widget_set_visible(gui_builder_widget("o_new_queue"), size < 10);
gtk_widget_set_visible(gui_builder_widget("o_add_to_queue"), size > 0);
for (i = 0; i < 10; i++) {
name = g_strdup_printf("o_queue_%d", i);
gtk_widget_set_visible(gui_builder_widget(name), i < size);
g_free(name);
}
gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event->button, event->time);
return true;
}
void gui_view_init()
{
GtkTreeViewColumn *col;

View File

@ -49,24 +49,11 @@ public:
void tab_runtime_changed();
void tab_display_sorting();
void tab_focus_search();
void tab_selected_ids(std::vector<unsigned int> &);
void tab_queue_add(queue *);
bool tab_queue_selected(bool);
bool tab_add_to_queue(unsigned int);
bool tab_add_to_playlist(enum playlist_t);
bool tab_favorite_selected();
void tab_ban_selected();
/**
* internal callback functions that can be overridden if necessary
*/
virtual void on_show_rc_menu();
/**
* GTK-MM callback functions
*/
void on_column_clicked(unsigned int);
bool on_button_pressed(GdkEventButton *);
};

View File

@ -66,20 +66,21 @@
<property name="icon_name">emblem-favorite</property>
<property name="icon_size">1</property>
</object>
<object class="GtkMenu" id="o_rc_menu">
<object class="GtkMenu" id="o_menu">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImageMenuItem" id="o_new_pq">
<object class="GtkImageMenuItem" id="o_new_queue">
<property name="label" translatable="yes">New Queue</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="image">image12</property>
<property name="use_stock">False</property>
<signal name="activate" handler="__view_rc_new_queue" swapped="no"/>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="o_add_to_pq">
<object class="GtkImageMenuItem" id="o_add_to_queue">
<property name="label" translatable="yes">Add to Queue</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
@ -90,83 +91,93 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkMenuItem" id="o_pq_0">
<object class="GtkMenuItem" id="o_queue_0">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Queue 0</property>
<property name="use_underline">True</property>
<signal name="activate" handler="__view_rc_add_to_queue" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="o_pq_1">
<object class="GtkMenuItem" id="o_queue_1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Queue 1</property>
<property name="use_underline">True</property>
<signal name="activate" handler="__view_rc_add_to_queue" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="o_pq_2">
<object class="GtkMenuItem" id="o_queue_2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Queue 2</property>
<property name="use_underline">True</property>
<signal name="activate" handler="__view_rc_add_to_queue" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="o_pq_3">
<object class="GtkMenuItem" id="o_queue_3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Queue 3</property>
<property name="use_underline">True</property>
<signal name="activate" handler="__view_rc_add_to_queue" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="o_pq_4">
<object class="GtkMenuItem" id="o_queue_4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Queue 4</property>
<property name="use_underline">True</property>
<signal name="activate" handler="__view_rc_add_to_queue" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="o_pq_5">
<object class="GtkMenuItem" id="o_queue_5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Queue 5</property>
<property name="use_underline">True</property>
<signal name="activate" handler="__view_rc_add_to_queue" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="o_pq_6">
<object class="GtkMenuItem" id="o_queue_6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Queue 6</property>
<property name="use_underline">True</property>
<signal name="activate" handler="__view_rc_add_to_queue" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="o_pq_7">
<object class="GtkMenuItem" id="o_queue_7">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Queue 7</property>
<property name="use_underline">True</property>
<signal name="activate" handler="__view_rc_add_to_queue" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="o_pq_8">
<object class="GtkMenuItem" id="o_queue_8">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Queue 8</property>
<property name="use_underline">True</property>
<signal name="activate" handler="__view_rc_add_to_queue" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="o_pq_9">
<object class="GtkMenuItem" id="o_queue_9">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Queue 9</property>
<property name="use_underline">True</property>
<signal name="activate" handler="__view_rc_add_to_queue" swapped="no"/>
</object>
</child>
</object>
@ -191,15 +202,17 @@
<property name="can_focus">False</property>
<property name="image">image20</property>
<property name="use_stock">False</property>
<signal name="activate" handler="__view_rc_add_favorites" swapped="no"/>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="o_add_to_banned">
<property name="label" translatable="yes">Banned</property>
<object class="GtkImageMenuItem" id="o_add_to_hidden">
<property name="label" translatable="yes">Hidden</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="image">image19</property>
<property name="use_stock">False</property>
<signal name="activate" handler="__view_rc_add_hidden" swapped="no"/>
</object>
</child>
</object>
@ -1110,6 +1123,7 @@
<property name="enable_search">False</property>
<property name="rubber_banding">True</property>
<property name="tooltip_column">9</property>
<signal name="button-press-event" handler="__view_button_press" swapped="no"/>
<signal name="key-press-event" handler="__view_keypress" swapped="no"/>
<signal name="row-activated" handler="__view_row_activated" swapped="no"/>
<child internal-child="selection">