- properties(ntracks, tracks);
-}
-
-static void select_dir(struct choosenode *cn,
- void attribute((unused)) *wfu) {
- int n;
-
- clear_selection(root);
- for(n = 0; n < cn->children.nvec; ++n)
- set_selection(cn->children.vec[n], 1);
-}
-
-/** @brief Ensure @p cn is expanded and then call @p callback */
-static void call_with_dir(struct choosenode *cn,
- when_filled_callback *whenfilled,
- void *wfu) {
- if(!(cn->flags & CN_EXPANDABLE))
- return; /* something went wrong */
- if(cn->flags & CN_EXPANDED)
- /* @p cn is already open */
- whenfilled(cn, wfu);
- else {
- /* @p cn is not open, arrange for the callback to go off when it is
- * opened */
- cn->whenfilled = whenfilled;
- cn->wfu = wfu;
- expand_node(cn, 0/*not contingnet upon search*/);
- }
-}
-
-/** @brief Called when the directory menu's play option is activated */
-static void activate_dir_play(GtkMenuItem attribute((unused)) *menuitem,
- gpointer user_data) {
- struct choosenode *const cn = (struct choosenode *)user_data;
-
- call_with_dir(cn, play_dir, 0);
-}
-
-/** @brief Called when the directory menu's properties option is activated */
-static void activate_dir_properties(GtkMenuItem attribute((unused)) *menuitem,
- gpointer user_data) {
- struct choosenode *const cn = (struct choosenode *)user_data;
-
- call_with_dir(cn, properties_dir, 0);
-}
-
-/** @brief Called when the directory menu's select option is activated */
-static void activate_dir_select(GtkMenuItem attribute((unused)) *menuitem,
- gpointer user_data) {
- struct choosenode *const cn = (struct choosenode *)user_data;
-
- call_with_dir(cn, select_dir, 0);
-}
-
-/** @brief Determine whether the directory menu's play option should be sensitive */
-static gboolean sensitive_dir_play(struct choosenode attribute((unused)) *cn) {
- return !!(disorder_eclient_state(client) & DISORDER_CONNECTED);
-}
-
-/** @brief Determine whether the directory menu's properties option should be sensitive */
-static gboolean sensitive_dir_properties(struct choosenode attribute((unused)) *cn) {
- return !!(disorder_eclient_state(client) & DISORDER_CONNECTED);
-}
-
-/** @brief Determine whether the directory menu's select option should be sensitive */
-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) {
- 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 Called when the edit menu's properties option is activated */
-static void choose_properties_activate(GtkWidget attribute((unused)) *w) {
- 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 Main menu callbacks for Choose screen */
-static const struct tabtype tabtype_choose = {
- choose_properties_sensitive,
- choose_selectall_sensitive,
- choose_properties_activate,
- choose_selectall_activate,
-};
-
-/* Public entry points ----------------------------------------------------- */
-
-/** @brief Called to entirely reset the choose screen */
-static void choose_reset(void) {
- if(root)
- undisplay_tree(root);
- root = newnode(0/*parent*/, "<root>", "All files", "",
- CN_EXPANDABLE, fill_root_node);
- expand_node(root, 0); /* will call redisplay_tree */
-}
-
-/** @brief Create a track choice widget */
-GtkWidget *choose_widget(void) {
- int n;
- GtkWidget *scrolled;
- GtkWidget *vbox, *hbox, *clearsearch;
-
- /*
- * +--vbox-------------------------------------------------------+
- * | +-hbox----------------------------------------------------+ |
- * | | searchentry | clearsearch | |
- * | +---------------------------------------------------------+ |
- * | +-scrolled------------------------------------------------+ |
- * | | +-chooselayout------------------------------------++--+ | |
- * | | | Tree structure is manually layed out in here ||^^| | |
- * | | | || | | |
- * | | | || | | |
- * | | | || | | |
- * | | | ||vv| | |
- * | | +-------------------------------------------------++--+ | |
- * | | +-------------------------------------------------+ | |
- * | | |< >| | |
- * | | +-------------------------------------------------+ | |
- * | +---------------------------------------------------------+ |
- * +-------------------------------------------------------------+
- */
-
- /* Text entry box for search terms */
- NW(entry);
- searchentry = gtk_entry_new();
- g_signal_connect(searchentry, "changed", G_CALLBACK(searchentry_changed), 0);
- gtk_tooltips_set_tip(tips, searchentry, "Enter search terms here; search is automatic", "");
-
- /* Cancel button to clear the search */
- NW(button);
- clearsearch = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
- gtk_widget_modify_bg(clearsearch, GTK_STATE_NORMAL, &tool_bg);
- gtk_widget_modify_bg(clearsearch, GTK_STATE_ACTIVE, &tool_active);
- gtk_widget_modify_bg(clearsearch, GTK_STATE_PRELIGHT, &tool_active);
- gtk_widget_modify_bg(clearsearch, GTK_STATE_SELECTED, &tool_active);
- g_signal_connect(G_OBJECT(clearsearch), "clicked",
- G_CALLBACK(clearsearch_clicked), 0);
- gtk_tooltips_set_tip(tips, clearsearch, "Clear search terms", "");
-
- /* Up and down buttons to find previous/next results; initially they are not
- * usable as there are no search results. */
- prevsearch = iconbutton("up.png", "Previous search result");
- g_signal_connect(G_OBJECT(prevsearch), "clicked",
- G_CALLBACK(prev_clicked), 0);
- gtk_widget_set_sensitive(prevsearch, 0);
- gtk_widget_modify_bg(prevsearch, GTK_STATE_NORMAL, &tool_bg);
- gtk_widget_modify_bg(prevsearch, GTK_STATE_ACTIVE, &tool_active);
- gtk_widget_modify_bg(prevsearch, GTK_STATE_PRELIGHT, &tool_active);
- gtk_widget_modify_bg(prevsearch, GTK_STATE_SELECTED, &tool_active);
- gtk_widget_modify_bg(prevsearch, GTK_STATE_INSENSITIVE, &tool_active);
- nextsearch = iconbutton("down.png", "Next search result");
- g_signal_connect(G_OBJECT(nextsearch), "clicked",
- G_CALLBACK(next_clicked), 0);
- gtk_widget_set_sensitive(nextsearch, 0);
- gtk_widget_modify_bg(nextsearch, GTK_STATE_NORMAL, &tool_bg);
- gtk_widget_modify_bg(nextsearch, GTK_STATE_ACTIVE, &tool_active);
- gtk_widget_modify_bg(nextsearch, GTK_STATE_PRELIGHT, &tool_active);
- gtk_widget_modify_bg(nextsearch, GTK_STATE_SELECTED, &tool_active);
- gtk_widget_modify_bg(nextsearch, GTK_STATE_INSENSITIVE, &tool_active);
-
- /* hbox packs the search tools button together on a line */
- NW(hbox);
- hbox = gtk_hbox_new(FALSE/*homogeneous*/, 1/*spacing*/);
- gtk_box_pack_start(GTK_BOX(hbox), searchentry,
- TRUE/*expand*/, TRUE/*fill*/, 0/*padding*/);
- gtk_box_pack_start(GTK_BOX(hbox), prevsearch,
- FALSE/*expand*/, FALSE/*fill*/, 0/*padding*/);
- gtk_box_pack_start(GTK_BOX(hbox), nextsearch,
- FALSE/*expand*/, FALSE/*fill*/, 0/*padding*/);
- gtk_box_pack_start(GTK_BOX(hbox), clearsearch,
- FALSE/*expand*/, FALSE/*fill*/, 0/*padding*/);
-
- /* chooselayout contains the currently visible subset of the track
- * namespace */
- NW(layout);
- chooselayout = gtk_layout_new(0, 0);
- gtk_widget_modify_bg(chooselayout, GTK_STATE_NORMAL, &layout_bg);
- choose_reset();
- register_reset(choose_reset);
- /* Create the popup menus */
- NW(menu);
- track_menu = gtk_menu_new();
- g_signal_connect(track_menu, "destroy", G_CALLBACK(gtk_widget_destroyed),
- &track_menu);
- for(n = 0; track_menuitems[n].name; ++n) {
- NW(menu_item);
- track_menuitems[n].w =
- gtk_menu_item_new_with_label(track_menuitems[n].name);
- gtk_menu_attach(GTK_MENU(track_menu), track_menuitems[n].w,
- 0, 1, n, n + 1);
- }
- NW(menu);
- dir_menu = gtk_menu_new();
- g_signal_connect(dir_menu, "destroy", G_CALLBACK(gtk_widget_destroyed),
- &dir_menu);
- for(n = 0; dir_menuitems[n].name; ++n) {
- NW(menu_item);
- dir_menuitems[n].w =
- gtk_menu_item_new_with_label(dir_menuitems[n].name);
- gtk_menu_attach(GTK_MENU(dir_menu), dir_menuitems[n].w,
- 0, 1, n, n + 1);
- }
- /* The layout is scrollable */
- scrolled = scroll_widget(chooselayout);
- vadjust = gtk_layout_get_vadjustment(GTK_LAYOUT(chooselayout));
-
- /* The scrollable layout and the search hbox go together in a vbox */
- NW(vbox);
- vbox = gtk_vbox_new(FALSE/*homogenous*/, 1/*spacing*/);
- gtk_box_pack_start(GTK_BOX(vbox), hbox,
- FALSE/*expand*/, FALSE/*fill*/, 0/*padding*/);
- gtk_box_pack_end(GTK_BOX(vbox), scrolled,
- TRUE/*expand*/, TRUE/*fill*/, 0/*padding*/);
-
- g_object_set_data(G_OBJECT(vbox), "type", (void *)&tabtype_choose);
- return vbox;
-}
-
-/** @brief Called when something we care about here might have changed */
-void choose_update(void) {
- redisplay_tree("choose_update");