From ee7552f86d9438d415cbe61fd897e5c768f4f1a4 Mon Sep 17 00:00:00 2001 Message-Id: From: Mark Wooding Date: Wed, 11 Jun 2008 10:53:11 +0100 Subject: [PATCH] Fix edit menu (and simplify its implementation a bit). Organization: Straylight/Edgeware From: Richard Kettlewell --- disobedience/added.c | 1 + disobedience/choose.c | 44 +++++++----------------------------- disobedience/disobedience.c | 2 +- disobedience/disobedience.h | 13 ++++++----- disobedience/menu.c | 21 +++++++++++------ disobedience/queue-generic.c | 13 +++++++---- disobedience/queue-generic.h | 4 ++++ disobedience/queue-menu.c | 42 ++++++++++++++++++++++++++++++++++ disobedience/queue.c | 12 +++++++--- disobedience/recent.c | 1 + 10 files changed, 95 insertions(+), 58 deletions(-) diff --git a/disobedience/added.c b/disobedience/added.c index 8eef894..038c439 100644 --- a/disobedience/added.c +++ b/disobedience/added.c @@ -85,6 +85,7 @@ static struct queue_menuitem added_menuitems[] = { }; struct queuelike ql_added = { + .name = "added", .init = added_init, .columns = added_columns, .ncolumns = sizeof added_columns / sizeof *added_columns, diff --git a/disobedience/choose.c b/disobedience/choose.c index 353ed98..ff5e72b 100644 --- a/disobedience/choose.c +++ b/disobedience/choose.c @@ -1,3 +1,4 @@ + /* * This file is part of DisOrder * Copyright (C) 2006-2008 Richard Kettlewell @@ -1377,48 +1378,18 @@ static gboolean sensitive_dir_select(struct choosenode attribute((unused)) *cn) return TRUE; } - - /* Main menu plumbing ------------------------------------------------------ */ /** @brief Determine whether the edit menu's properties option should be sensitive */ -static int choose_properties_sensitive(GtkWidget attribute((unused)) *w) { +static int choose_properties_sensitive(void attribute((unused)) *extra) { return !!files_selected && (disorder_eclient_state(client) & DISORDER_CONNECTED); } -/** @brief Determine whether the edit menu's select all option should be sensitive - * - * TODO not implemented, see also choose_selectall_activate() - */ -static int choose_selectall_sensitive(GtkWidget attribute((unused)) *w) { - return FALSE; -} - -/** @brief Determine whether the edit menu's select none option should be sensitive - * - * TODO not implemented, see also choose_selectnone_activate() - */ -static int choose_selectnone_sensitive(GtkWidget attribute((unused)) *w) { - return FALSE; -} - /** @brief Called when the edit menu's properties option is activated */ -static void choose_properties_activate(GtkWidget attribute((unused)) *w) { +static void choose_properties_activate(void attribute((unused)) *extra) { activate_track_properties(0, 0); } -/** @brief Called when the edit menu's select all option is activated - * - * TODO not implemented, see choose_selectall_sensitive() */ -static void choose_selectall_activate(GtkWidget attribute((unused)) *w) { -} - -/** @brief Called when the edit menu's select none option is activated - * - * TODO not implemented, see choose_selectnone_sensitive() */ -static void choose_selectnone_activate(GtkWidget attribute((unused)) *w) { -} - /** @brief Called when the choose tab is selected */ static void choose_tab_selected(void) { gtk_widget_grab_focus(searchentry); @@ -1427,12 +1398,13 @@ static void choose_tab_selected(void) { /** @brief Main menu callbacks for Choose screen */ static const struct tabtype tabtype_choose = { choose_properties_sensitive, - choose_selectall_sensitive, - choose_selectnone_sensitive, + NULL/*choose_selectall_sensitive*/, + NULL/*choose_selectnone_sensitive*/, choose_properties_activate, - choose_selectall_activate, - choose_selectnone_activate, + NULL/*choose_selectall_activate*/, + NULL/*choose_selectnone_activate*/, choose_tab_selected, + 0 }; /* Public entry points ----------------------------------------------------- */ diff --git a/disobedience/disobedience.c b/disobedience/disobedience.c index b9866f7..5acadf8 100644 --- a/disobedience/disobedience.c +++ b/disobedience/disobedience.c @@ -125,7 +125,7 @@ static void tab_switched(GtkNotebook *notebook, menu_update(page_num); GtkWidget *const tab = gtk_notebook_get_nth_page(notebook, page_num); const struct tabtype *const t = g_object_get_data(G_OBJECT(tab), "type"); - if(!t) return; /* TODO */ + assert(t != 0); if(t->selected) t->selected(); } diff --git a/disobedience/disobedience.h b/disobedience/disobedience.h index e332e82..2beb032 100644 --- a/disobedience/disobedience.h +++ b/disobedience/disobedience.h @@ -87,13 +87,14 @@ struct callbackdata { * have some callbacks to set them appropriately. */ struct tabtype { - int (*properties_sensitive)(GtkWidget *tab); - int (*selectall_sensitive)(GtkWidget *tab); - int (*selectnone_sensitive)(GtkWidget *tab); - void (*properties_activate)(GtkWidget *tab); - void (*selectall_activate)(GtkWidget *tab); - void (*selectnone_activate)(GtkWidget *tab); + int (*properties_sensitive)(void *extra); + int (*selectall_sensitive)(void *extra); + int (*selectnone_sensitive)(void *extra); + void (*properties_activate)(void *extra); + void (*selectall_activate)(void *extra); + void (*selectnone_activate)(void *extra); void (*selected)(void); + void *extra; }; /** @brief Button definitions */ diff --git a/disobedience/menu.c b/disobedience/menu.c index eb20988..8dcae3c 100644 --- a/disobedience/menu.c +++ b/disobedience/menu.c @@ -58,7 +58,8 @@ static void select_all(gpointer attribute((unused)) callback_data, (GTK_NOTEBOOK(tabs), gtk_notebook_current_page(GTK_NOTEBOOK(tabs))); const struct tabtype *t = g_object_get_data(G_OBJECT(tab), "type"); - t->selectall_activate(tab); + if(t->selectall_activate) + t->selectall_activate(t->extra); } /** @brief Called when the select none option is activated @@ -72,7 +73,8 @@ static void select_none(gpointer attribute((unused)) callback_data, (GTK_NOTEBOOK(tabs), gtk_notebook_current_page(GTK_NOTEBOOK(tabs))); const struct tabtype *t = g_object_get_data(G_OBJECT(tab), "type"); - t->selectnone_activate(tab); + if(t->selectnone_activate) + t->selectnone_activate(t->extra); } /** @brief Called when the track properties option is activated @@ -86,7 +88,8 @@ static void properties_item(gpointer attribute((unused)) callback_data, (GTK_NOTEBOOK(tabs), gtk_notebook_current_page(GTK_NOTEBOOK(tabs))); const struct tabtype *t = g_object_get_data(G_OBJECT(tab), "type"); - t->properties_activate(tab); + if(t->properties_activate) + t->properties_activate(t->extra); } /** @brief Called when the login option is activated */ @@ -117,6 +120,8 @@ static void settings(gpointer attribute((unused)) callback_data, * Determines option sensitivity according to the current tab and adjusts the * widgets accordingly. Knows about @ref DISORDER_CONNECTED so the callbacks * need not. + * + * TODO: base this on menu popup instead? */ void menu_update(int page) { if(tabs) { @@ -125,15 +130,17 @@ void menu_update(int page) { page < 0 ? gtk_notebook_current_page(GTK_NOTEBOOK(tabs)) : page); const struct tabtype *t = g_object_get_data(G_OBJECT(tab), "type"); - if(!t) return; /* TODO */ assert(t != 0); gtk_widget_set_sensitive(properties_widget, - (t->properties_sensitive(tab) + (t->properties_sensitive + && t->properties_sensitive(t->extra) && (disorder_eclient_state(client) & DISORDER_CONNECTED))); gtk_widget_set_sensitive(selectall_widget, - t->selectall_sensitive(tab)); + t->selectall_sensitive + && t->selectall_sensitive(t->extra)); gtk_widget_set_sensitive(selectnone_widget, - t->selectnone_sensitive(tab)); + t->selectnone_sensitive + && t->selectnone_sensitive(t->extra)); } } diff --git a/disobedience/queue-generic.c b/disobedience/queue-generic.c index 4db5750..39f60ab 100644 --- a/disobedience/queue-generic.c +++ b/disobedience/queue-generic.c @@ -35,6 +35,11 @@ * NB that while in the server the playing track is not in the queue, in * Disobedience, the playing does live in @c ql_queue.q, despite its different * status to everything else found in that list. + * + * To do: + * - drag and drop queue rearrangement + * - edit menu + * - display playing row in a different color? */ #include "disobedience.h" #include "queue-generic.h" @@ -399,10 +404,6 @@ GtkWidget *init_queuelike(struct queuelike *ql) { ql->selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(ql->view)); gtk_tree_selection_set_mode(ql->selection, GTK_SELECTION_MULTIPLE); - /* Remember what the view belongs to */ - //g_object_set_data(G_OBJECT(ql->view), "type", (void *)&tabtype_queue); - /* TODO tabtype */ - g_object_set_data(G_OBJECT(ql->view), "queue", ql); /* Catch button presses */ g_signal_connect(ql->view, "button-press-event", G_CALLBACK(ql_button_release), ql); @@ -412,7 +413,9 @@ GtkWidget *init_queuelike(struct queuelike *ql) { ql->init(); - return scroll_widget(ql->view); + GtkWidget *scrolled = scroll_widget(ql->view); + g_object_set_data(G_OBJECT(scrolled), "type", (void *)ql_tabtype(ql)); + return scrolled; } /* diff --git a/disobedience/queue-generic.h b/disobedience/queue-generic.h index 9ca1f80..c2cb119 100644 --- a/disobedience/queue-generic.h +++ b/disobedience/queue-generic.h @@ -72,6 +72,9 @@ struct queuelike { /* Things filled in by the caller: */ + /** @brief Name for this tab */ + const char *name; + /** @brief Initialization function */ void (*init)(void); @@ -148,6 +151,7 @@ const char *column_namepart(const struct queue_entry *q, const char *data); const char *column_length(const struct queue_entry *q, const char *data); +struct tabtype *ql_tabtype(struct queuelike *ql); #endif /* QUEUE_GENERIC_H */ diff --git a/disobedience/queue-menu.c b/disobedience/queue-menu.c index b76ed81..5254871 100644 --- a/disobedience/queue-menu.c +++ b/disobedience/queue-menu.c @@ -164,6 +164,48 @@ gboolean ql_button_release(GtkWidget*widget, return FALSE; } +static int ql_tab_selectall_sensitive(void *extra) { + return ql_selectall_sensitive(extra); +} + +static void ql_tab_selectall_activate(void *extra) { + ql_selectall_activate(NULL, extra); +} + +static int ql_tab_selectnone_sensitive(void *extra) { + return ql_selectnone_sensitive(extra); +} + +static void ql_tab_selectnone_activate(void *extra) { + ql_selectnone_activate(NULL, extra); +} + +static int ql_tab_properties_sensitive(void *extra) { + return ql_properties_sensitive(extra); +} + +static void ql_tab_properties_activate(void *extra) { + ql_properties_activate(NULL, extra); +} + +struct tabtype *ql_tabtype(struct queuelike *ql) { + static const struct tabtype ql_tabtype = { + ql_tab_properties_sensitive, + ql_tab_selectall_sensitive, + ql_tab_selectnone_sensitive, + ql_tab_properties_activate, + ql_tab_selectall_activate, + ql_tab_selectnone_activate, + 0, + 0 + }; + + struct tabtype *t = xmalloc(sizeof *t); + *t = ql_tabtype; + t->extra = ql; + return t; +} + /* Local Variables: c-basic-offset:2 diff --git a/disobedience/queue.c b/disobedience/queue.c index 06c761c..87930b7 100644 --- a/disobedience/queue.c +++ b/disobedience/queue.c @@ -34,9 +34,14 @@ time_t last_playing; static void queue_playing_changed(void) { struct queue_entry *q = xmalloc(sizeof *q); - *q = *actual_playing_track; - q->next = actual_queue; - playing_track = q; + if(actual_playing_track) { + *q = *actual_playing_track; + q->next = actual_queue; + playing_track = q; + } else { + playing_track = NULL; + q = actual_queue; + } time(&last_playing); /* for column_length() */ ql_new_queue(&ql_queue, q); /* Tell anyone who cares */ @@ -134,6 +139,7 @@ static struct queue_menuitem queue_menuitems[] = { }; struct queuelike ql_queue = { + .name = "queue", .init = queue_init, .columns = queue_columns, .ncolumns = sizeof queue_columns / sizeof *queue_columns, diff --git a/disobedience/recent.c b/disobedience/recent.c index ea7b26e..01647ab 100644 --- a/disobedience/recent.c +++ b/disobedience/recent.c @@ -82,6 +82,7 @@ static struct queue_menuitem recent_menuitems[] = { }; struct queuelike ql_recent = { + .name = "recent", .init = recent_init, .columns = recent_columns, .ncolumns = sizeof recent_columns / sizeof *recent_columns, -- [mdw]