chiark / gitweb /
Rearrange choose columns. The track name column is now last by
[disorder] / disobedience / choose.c
index a564a1166415028e9fe09f1dcb3140a16a197ab1..8813ad345bd117922cacb0d4d1422f35087579f6 100644 (file)
@@ -35,7 +35,6 @@
  * TODO:
  * - sweep up contracted nodes
  * - update when content may have changed (e.g. after a rescan)
- * - searching!
  * - proper sorting
  */
 
@@ -51,8 +50,11 @@ GtkWidget *choose_view;
 /** @brief The selection tree's selection */
 GtkTreeSelection *choose_selection;
 
-/** @brief Map choosedata types to names */
-static const char *const choose_type_map[] = { "track", "dir" };
+/** @brief Count of file listing operations in flight */
+static int choose_list_in_flight;
+
+/** @brief Count of files inserted in current batch of listing operations */
+static int choose_inserted;
 
 static char *choose_get_string(GtkTreeIter *iter, int column) {
   gchar *gs;
@@ -126,6 +128,16 @@ static gboolean choose_set_state_callback(GtkTreeModel attribute((unused)) *mode
                        LENGTH_COLUMN, length,
                        STATE_COLUMN, queued(track),
                        -1);
+    if(choose_is_search_result(track))
+      gtk_tree_store_set(choose_store, it,
+                         BG_COLUMN, SEARCH_RESULT_BG,
+                         FG_COLUMN, SEARCH_RESULT_FG,
+                         -1);
+    else
+      gtk_tree_store_set(choose_store, it,
+                         BG_COLUMN, (char *)0,
+                         FG_COLUMN, (char *)0,
+                         -1);
   }
   return FALSE;                         /* continue walking */
 }
@@ -212,7 +224,7 @@ static void choose_populate(GtkTreeRowReference *parent_ref,
   }
   /* Add nodes we don't have */
   int inserted = 0;
-  //fprintf(stderr, " inserting new %s nodes\n", choose_type_map[type]);
+  //fprintf(stderr, " inserting new %s nodes\n", isfile ? "track" : "dir");
   const char *typename = isfile ? "track" : "dir";
   for(int n = 0; n < nvec; ++n) {
     if(!found[n]) {
@@ -257,6 +269,18 @@ static void choose_populate(GtkTreeRowReference *parent_ref,
     gtk_tree_row_reference_free(parent_ref);
     gtk_tree_path_free(parent_path);
   }
+  /* We only notify others that we've inserted tracks when there are no more
+   * insertions pending, so that they don't have to keep track of how many
+   * requests they've made.  */
+  choose_inserted += inserted;
+  if(--choose_list_in_flight == 0) {
+    /* Notify interested parties that we inserted some tracks, AFTER making
+     * sure that the row is properly expanded */
+    if(choose_inserted) {
+      event_raise("choose-inserted-tracks", parent_it);
+      choose_inserted = 0;
+    }
+  }
 }
 
 static void choose_dirs_completed(void *v,
@@ -327,6 +351,7 @@ static void choose_row_expanded(GtkTreeView attribute((unused)) *treeview,
                         gtk_tree_row_reference_new(GTK_TREE_MODEL(choose_store),
                                                    path));
   /* The row references are destroyed in the _completed handlers. */
+  choose_list_in_flight += 2;
 }
 
 /** @brief Create the choose tab */
@@ -338,6 +363,8 @@ GtkWidget *choose_widget(void) {
                                     G_TYPE_STRING,
                                     G_TYPE_BOOLEAN,
                                     G_TYPE_STRING,
+                                    G_TYPE_STRING,
+                                    G_TYPE_STRING,
                                     G_TYPE_STRING);
 
   /* Create the view */
@@ -347,16 +374,18 @@ GtkWidget *choose_widget(void) {
   /* Create cell renderers and columns */
   /* TODO use a table */
   {
-    GtkCellRenderer *r = gtk_cell_renderer_text_new();
+    GtkCellRenderer *r = gtk_cell_renderer_toggle_new();
     GtkTreeViewColumn *c = gtk_tree_view_column_new_with_attributes
-      ("Track",
+      ("Queued",
        r,
-       "text", NAME_COLUMN,
+       "active", STATE_COLUMN,
+       "visible", ISFILE_COLUMN,
        (char *)0);
     gtk_tree_view_column_set_resizable(c, TRUE);
     gtk_tree_view_column_set_reorderable(c, TRUE);
-    g_object_set(c, "expand", TRUE, (char *)0);
     gtk_tree_view_append_column(GTK_TREE_VIEW(choose_view), c);
+    g_signal_connect(r, "toggled",
+                     G_CALLBACK(choose_state_toggled), 0);
   }
   {
     GtkCellRenderer *r = gtk_cell_renderer_text_new();
@@ -371,18 +400,19 @@ GtkWidget *choose_widget(void) {
     gtk_tree_view_append_column(GTK_TREE_VIEW(choose_view), c);
   }
   {
-    GtkCellRenderer *r = gtk_cell_renderer_toggle_new();
+    GtkCellRenderer *r = gtk_cell_renderer_text_new();
     GtkTreeViewColumn *c = gtk_tree_view_column_new_with_attributes
-      ("Queued",
+      ("Track",
        r,
-       "active", STATE_COLUMN,
-       "visible", ISFILE_COLUMN,
+       "text", NAME_COLUMN,
+       "background", BG_COLUMN,
+       "foreground", FG_COLUMN,
        (char *)0);
     gtk_tree_view_column_set_resizable(c, TRUE);
     gtk_tree_view_column_set_reorderable(c, TRUE);
+    g_object_set(c, "expand", TRUE, (char *)0);
     gtk_tree_view_append_column(GTK_TREE_VIEW(choose_view), c);
-    g_signal_connect(r, "toggled",
-                     G_CALLBACK(choose_state_toggled), 0);
+    gtk_tree_view_set_expander_column(GTK_TREE_VIEW(choose_view), c);
   }
   
   /* The selection should support multiple things being selected */
@@ -400,15 +430,24 @@ GtkWidget *choose_widget(void) {
 
   event_register("queue-list-changed", choose_set_state, 0);
   event_register("playing-track-changed", choose_set_state, 0);
+  event_register("search-results-changed", choose_set_state, 0);
   
   /* Fill the root */
   disorder_eclient_files(client, choose_files_completed, "", NULL, NULL); 
   disorder_eclient_dirs(client, choose_dirs_completed, "", NULL, NULL); 
-  
+
   /* Make the widget scrollable */
   GtkWidget *scrolled = scroll_widget(choose_view);
-  g_object_set_data(G_OBJECT(scrolled), "type", (void *)&choose_tabtype);
-  return scrolled;
+
+  /* Pack vertically with the search widget */
+  GtkWidget *vbox = gtk_vbox_new(FALSE/*homogenous*/, 1/*spacing*/);
+  gtk_box_pack_start(GTK_BOX(vbox), scrolled,
+                     TRUE/*expand*/, TRUE/*fill*/, 0/*padding*/);
+  gtk_box_pack_end(GTK_BOX(vbox), choose_search_widget(),
+                   FALSE/*expand*/, FALSE/*fill*/, 0/*padding*/);
+  
+  g_object_set_data(G_OBJECT(vbox), "type", (void *)&choose_tabtype);
+  return vbox;
 }
 
 /*