int choose_auto_expanding;
-static GtkWidget *choose_search_entry;
+GtkWidget *choose_search_entry;
static GtkWidget *choose_next;
static GtkWidget *choose_prev;
static GtkWidget *choose_clear;
} else {
gtk_widget_set_sensitive(choose_next, FALSE);
gtk_widget_set_sensitive(choose_prev, FALSE);
+ choose_n_search_results = 0;
+ choose_search_results = 0;
+ choose_n_search_references = 0;
+ choose_search_references = 0;
}
event_raise("search-results-changed", 0);
}
return TRUE;
}
-static void choose_next_clicked(GtkButton attribute((unused)) *button,
- gpointer attribute((unused)) userdata) {
+void choose_next_clicked(GtkButton attribute((unused)) *button,
+ gpointer attribute((unused)) userdata) {
+ if(!choose_n_search_results)
+ return;
/* Find the last visible row */
GtkTreePath *endpath;
gboolean endvalid = choose_get_visible_range(GTK_TREE_VIEW(choose_view),
}
gtk_tree_path_free(path);
}
+ /* We didn't find one. Loop back to the first. */
+ for(int n = 0; n < choose_n_search_references; ++n) {
+ GtkTreePath *path
+ = gtk_tree_row_reference_get_path(choose_search_references[n]);
+ if(!path)
+ continue;
+ choose_make_path_visible(path, 0.5);
+ gtk_tree_path_free(path);
+ return;
+ }
}
-static void choose_prev_clicked(GtkButton attribute((unused)) *button,
- gpointer attribute((unused)) userdata) {
+void choose_prev_clicked(GtkButton attribute((unused)) *button,
+ gpointer attribute((unused)) userdata) {
/* TODO can we de-dupe with choose_next_clicked? Probably yes. */
+ if(!choose_n_search_results)
+ return;
/* Find the first visible row */
GtkTreePath *startpath;
gboolean startvalid = choose_get_visible_range(GTK_TREE_VIEW(choose_view),
}
gtk_tree_path_free(path);
}
+ /* We didn't find one. Loop down to the last. */
+ for(int n = choose_n_search_references - 1; n >= 0; --n) {
+ GtkTreePath *path
+ = gtk_tree_row_reference_get_path(choose_search_references[n]);
+ if(!path)
+ continue;
+ choose_make_path_visible(path, 0.5);
+ gtk_tree_path_free(path);
+ return;
+ }
}
/** @brief Called when the cancel search button is clicked */
#include "disobedience.h"
#include "choose.h"
+#include <gdk/gdkkeysyms.h>
/** @brief The current selection tree */
GtkTreeStore *choose_store;
//fprintf(stderr, "choose_list_in_flight -> %d+\n", choose_list_in_flight);
}
+/** @brief Called for key-*-event on the main view
+ *
+ * Switches focus to the
+ */
+static gboolean choose_key_event(GtkWidget attribute((unused)) *widget,
+ GdkEventKey *event,
+ gpointer attribute((unused)) user_data) {
+ /*fprintf(stderr, "choose_key_event type=%d state=%#x keyval=%#x\n",
+ event->type, event->state, event->keyval);*/
+ switch(event->keyval) {
+ case GDK_Page_Up:
+ case GDK_Page_Down:
+ case GDK_Up:
+ case GDK_Down:
+ case GDK_Home:
+ case GDK_End:
+ return FALSE; /* We'll take these */
+ case 'f': case 'F':
+ /* ^F is expected to start a search. We implement this by focusing the
+ * search entry box. */
+ if((event->state & ~(GDK_LOCK_MASK|GDK_SHIFT_MASK)) == GDK_CONTROL_MASK
+ && event->type == GDK_KEY_PRESS) {
+ gtk_widget_grab_focus(user_data);
+ return FALSE;
+ }
+ break;
+ case 'g': case 'G':
+ /* ^G is expected to go the next match. We simulate a click on the 'next'
+ * button. */
+ if((event->state & ~(GDK_LOCK_MASK|GDK_SHIFT_MASK)) == GDK_CONTROL_MASK
+ && event->type == GDK_KEY_PRESS) {
+ choose_next_clicked(0, 0);
+ return FALSE;
+ }
+ break;
+ }
+ gtk_widget_event(user_data, (GdkEvent *)event);
+ return TRUE;
+}
+
/** @brief Create the choose tab */
GtkWidget *choose_widget(void) {
/* Create the tree store. */
FALSE/*expand*/, FALSE/*fill*/, 0/*padding*/);
g_object_set_data(G_OBJECT(vbox), "type", (void *)&choose_tabtype);
+
+ /* Redirect keyboard activity to the search widget */
+ g_signal_connect(choose_view, "key-press-event",
+ G_CALLBACK(choose_key_event), choose_search_entry);
+ g_signal_connect(choose_view, "key-release-event",
+ G_CALLBACK(choose_key_event), choose_search_entry);
+
return vbox;
}
extern GtkTreeSelection *choose_selection;
extern const struct tabtype choose_tabtype;
extern int choose_auto_expanding;
+extern GtkWidget *choose_search_entry;
struct choosedata *choose_iter_to_data(GtkTreeIter *iter);
struct choosedata *choose_path_to_data(GtkTreePath *path);
GtkWidget *choose_search_widget(void);
int choose_is_search_result(const char *track);
void choose_auto_collapse(void);
+void choose_next_clicked(GtkButton *button,
+ gpointer userdata);
+void choose_prev_clicked(GtkButton *button,
+ gpointer userdata);
#endif /* CHOOSE_H */