From f640a7a5eddf0f46a2d1fa366fe6173d600a503e Mon Sep 17 00:00:00 2001 From: Omari Stephens Date: Sat, 24 Dec 2016 22:37:21 +0000 Subject: [PATCH] Pull the search UI construction code out into a distinct function. Also, it looks like the existing code would just leak the search UI widgets. Having the construction code in a distinct function makes it much easier to ensure the appropriate cleanup happens as well. --- src/pan-view/pan-types.h | 16 ++++-- src/pan-view/pan-view-search.c | 92 ++++++++++++++++++++++++++++------ src/pan-view/pan-view-search.h | 6 +++ src/pan-view/pan-view.c | 41 +++------------ 4 files changed, 101 insertions(+), 54 deletions(-) diff --git a/src/pan-view/pan-types.h b/src/pan-view/pan-types.h index 5318b38f..901b2487 100644 --- a/src/pan-view/pan-types.h +++ b/src/pan-view/pan-types.h @@ -169,6 +169,16 @@ struct _PanItem { gboolean queued; }; +typedef struct _PanViewSearchUi PanViewSearchUi; +struct _PanViewSearchUi +{ + GtkWidget *search_box; + GtkWidget *search_entry; + GtkWidget *search_label; + GtkWidget *search_button; + GtkWidget *search_button_arrow; +}; + typedef struct _PanWindow PanWindow; struct _PanWindow { @@ -182,11 +192,7 @@ struct _PanWindow GtkWidget *label_message; GtkWidget *label_zoom; - GtkWidget *search_box; - GtkWidget *search_entry; - GtkWidget *search_label; - GtkWidget *search_button; - GtkWidget *search_button_arrow; + PanViewSearchUi *search_ui; GtkWidget *date_button; diff --git a/src/pan-view/pan-view-search.c b/src/pan-view/pan-view-search.c index 9549cfc3..2577d38f 100644 --- a/src/pan-view/pan-view-search.c +++ b/src/pan-view/pan-view-search.c @@ -27,10 +27,70 @@ #include "pan-util.h" #include "pan-view.h" #include "ui_tabcomp.h" +#include "ui_misc.h" + +PanViewSearchUi *pan_search_ui_new(PanWindow *pw) +{ + PanViewSearchUi *ui = g_new0(PanViewSearchUi, 1); + GtkWidget *combo; + GtkWidget *hbox; + + // Build the actual search UI. + ui->search_box = gtk_hbox_new(FALSE, PREF_PAD_SPACE); + pref_spacer(ui->search_box, 0); + pref_label_new(ui->search_box, _("Find:")); + + hbox = gtk_hbox_new(TRUE, PREF_PAD_SPACE); + gtk_box_pack_start(GTK_BOX(ui->search_box), hbox, TRUE, TRUE, 0); + gtk_widget_show(hbox); + + combo = tab_completion_new_with_history(&ui->search_entry, "", "pan_view_search", -1, + pan_search_activate_cb, pw); + gtk_box_pack_start(GTK_BOX(hbox), combo, TRUE, TRUE, 0); + gtk_widget_show(combo); + + ui->search_label = gtk_label_new(""); + gtk_box_pack_start(GTK_BOX(hbox), ui->search_label, TRUE, TRUE, 0); + gtk_widget_show(ui->search_label); + + // Build the spin-button to show/hide the search UI. + ui->search_button = gtk_toggle_button_new(); + gtk_button_set_relief(GTK_BUTTON(ui->search_button), GTK_RELIEF_NONE); + gtk_button_set_focus_on_click(GTK_BUTTON(ui->search_button), FALSE); + hbox = gtk_hbox_new(FALSE, PREF_PAD_GAP); + gtk_container_add(GTK_CONTAINER(ui->search_button), hbox); + gtk_widget_show(hbox); + ui->search_button_arrow = gtk_arrow_new(GTK_ARROW_UP, GTK_SHADOW_NONE); + gtk_box_pack_start(GTK_BOX(hbox), ui->search_button_arrow, FALSE, FALSE, 0); + gtk_widget_show(ui->search_button_arrow); + pref_label_new(hbox, _("Find")); + + g_signal_connect(G_OBJECT(ui->search_button), "clicked", + G_CALLBACK(pan_search_toggle_cb), pw); + + return ui; +} + +void pan_search_ui_destroy(PanViewSearchUi **ui_ptr) +{ + if (ui_ptr == NULL || *ui_ptr == NULL) return; + + PanViewSearchUi *ui = *ui_ptr; // For convenience. + + // Note that g_clear_object handles already-NULL pointers. + g_clear_object(&ui->search_label); + g_clear_object(&ui->search_button); + g_clear_object(&ui->search_box); + g_clear_object(&ui->search_button_arrow); + g_clear_object(&ui->search_button); + + g_free(ui); + *ui_ptr = NULL; +} static void pan_search_status(PanWindow *pw, const gchar *text) { - gtk_label_set_text(GTK_LABEL(pw->search_label), (text) ? text : ""); + gtk_label_set_text(GTK_LABEL(pw->search_ui->search_label), (text) ? text : ""); } static gint pan_search_by_path(PanWindow *pw, const gchar *path) @@ -340,7 +400,7 @@ void pan_search_activate_cb(const gchar *text, gpointer data) if (!text) return; - tab_completion_append_to_history(pw->search_entry, text); + tab_completion_append_to_history(pw->search_ui->search_entry, text); if (pan_search_by_path(pw, text)) return; @@ -360,7 +420,7 @@ void pan_search_activate(PanWindow *pw) { gchar *text; - text = g_strdup(gtk_entry_get_text(GTK_ENTRY(pw->search_entry))); + text = g_strdup(gtk_entry_get_text(GTK_ENTRY(pw->search_ui->search_entry))); pan_search_activate_cb(text, pw); g_free(text); } @@ -368,48 +428,50 @@ void pan_search_activate(PanWindow *pw) void pan_search_toggle_cb(GtkWidget *button, gpointer data) { PanWindow *pw = data; + PanViewSearchUi *ui = pw->search_ui; gboolean visible; - visible = gtk_widget_get_visible(pw->search_box); + visible = gtk_widget_get_visible(ui->search_box); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)) == visible) return; if (visible) { - gtk_widget_hide(pw->search_box); - gtk_arrow_set(GTK_ARROW(pw->search_button_arrow), GTK_ARROW_UP, GTK_SHADOW_NONE); + gtk_widget_hide(ui->search_box); + gtk_arrow_set(GTK_ARROW(ui->search_button_arrow), GTK_ARROW_UP, GTK_SHADOW_NONE); } else { - gtk_widget_show(pw->search_box); - gtk_arrow_set(GTK_ARROW(pw->search_button_arrow), GTK_ARROW_DOWN, GTK_SHADOW_NONE); - gtk_widget_grab_focus(pw->search_entry); + gtk_widget_show(ui->search_box); + gtk_arrow_set(GTK_ARROW(ui->search_button_arrow), GTK_ARROW_DOWN, GTK_SHADOW_NONE); + gtk_widget_grab_focus(ui->search_entry); } } void pan_search_toggle_visible(PanWindow *pw, gboolean enable) { + PanViewSearchUi *ui = pw->search_ui; if (pw->fs) return; if (enable) { - if (gtk_widget_get_visible(pw->search_box)) + if (gtk_widget_get_visible(ui->search_box)) { - gtk_widget_grab_focus(pw->search_entry); + gtk_widget_grab_focus(ui->search_entry); } else { - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pw->search_button), TRUE); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ui->search_button), TRUE); } } else { - if (gtk_widget_get_visible(pw->search_entry)) + if (gtk_widget_get_visible(ui->search_entry)) { - if (gtk_widget_has_focus(pw->search_entry)) + if (gtk_widget_has_focus(ui->search_entry)) { gtk_widget_grab_focus(GTK_WIDGET(pw->imd->widget)); } - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pw->search_button), FALSE); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ui->search_button), FALSE); } } } diff --git a/src/pan-view/pan-view-search.h b/src/pan-view/pan-view-search.h index c61dd190..88784b72 100644 --- a/src/pan-view/pan-view-search.h +++ b/src/pan-view/pan-view-search.h @@ -30,5 +30,11 @@ void pan_search_activate(PanWindow *pw); void pan_search_activate_cb(const gchar *text, gpointer data); void pan_search_toggle_cb(GtkWidget *button, gpointer data); +// Creates a new PanViewSearchUi instance and returns it. +PanViewSearchUi *pan_search_ui_new(PanWindow *pw); + +// Destroys the specified PanViewSearchUi and sets the pointer to NULL. +void pan_search_ui_destroy(PanViewSearchUi **ui); + #endif /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ diff --git a/src/pan-view/pan-view.c b/src/pan-view/pan-view.c index 4546778c..c3d7f74d 100644 --- a/src/pan-view/pan-view.c +++ b/src/pan-view/pan-view.c @@ -1132,7 +1132,7 @@ static gboolean pan_window_key_press_cb(GtkWidget *widget, GdkEventKey *event, g imd_widget = gtk_container_get_focus_child(GTK_CONTAINER(pw->imd->widget)); focused = (pw->fs || (imd_widget && gtk_widget_has_focus(imd_widget))); on_entry = (gtk_widget_has_focus(pw->path_entry) || - gtk_widget_has_focus(pw->search_entry)); + gtk_widget_has_focus(pw->search_ui->search_entry)); if (focused) { @@ -1246,6 +1246,7 @@ static gboolean pan_window_key_press_cb(GtkWidget *widget, GdkEventKey *event, g if (stop_signal) return stop_signal; + // Don't steal characters from entry boxes. if (!on_entry) { stop_signal = TRUE; @@ -1879,24 +1880,8 @@ static void pan_window_new_real(FileData *dir_fd) /* find bar */ - pw->search_box = gtk_hbox_new(FALSE, PREF_PAD_SPACE); - gtk_box_pack_start(GTK_BOX(vbox), pw->search_box, FALSE, FALSE, 2); - - pref_spacer(pw->search_box, 0); - pref_label_new(pw->search_box, _("Find:")); - - hbox = gtk_hbox_new(TRUE, PREF_PAD_SPACE); - gtk_box_pack_start(GTK_BOX(pw->search_box), hbox, TRUE, TRUE, 0); - gtk_widget_show(hbox); - - combo = tab_completion_new_with_history(&pw->search_entry, "", "pan_view_search", -1, - pan_search_activate_cb, pw); - gtk_box_pack_start(GTK_BOX(hbox), combo, TRUE, TRUE, 0); - gtk_widget_show(combo); - - pw->search_label = gtk_label_new(""); - gtk_box_pack_start(GTK_BOX(hbox), pw->search_label, TRUE, TRUE, 0); - gtk_widget_show(pw->search_label); + pw->search_ui = pan_search_ui_new(pw); + gtk_box_pack_start(GTK_BOX(vbox), pw->search_ui->search_box, FALSE, FALSE, 2); /* status bar */ @@ -1925,21 +1910,9 @@ static void pan_window_new_real(FileData *dir_fd) gtk_container_add(GTK_CONTAINER(frame), pw->label_zoom); gtk_widget_show(pw->label_zoom); - pw->search_button = gtk_toggle_button_new(); - gtk_button_set_relief(GTK_BUTTON(pw->search_button), GTK_RELIEF_NONE); - gtk_button_set_focus_on_click(GTK_BUTTON(pw->search_button), FALSE); - hbox = gtk_hbox_new(FALSE, PREF_PAD_GAP); - gtk_container_add(GTK_CONTAINER(pw->search_button), hbox); - gtk_widget_show(hbox); - pw->search_button_arrow = gtk_arrow_new(GTK_ARROW_UP, GTK_SHADOW_NONE); - gtk_box_pack_start(GTK_BOX(hbox), pw->search_button_arrow, FALSE, FALSE, 0); - gtk_widget_show(pw->search_button_arrow); - pref_label_new(hbox, _("Find")); - - gtk_box_pack_end(GTK_BOX(box), pw->search_button, FALSE, FALSE, 0); - gtk_widget_show(pw->search_button); - g_signal_connect(G_OBJECT(pw->search_button), "clicked", - G_CALLBACK(pan_search_toggle_cb), pw); + // Add the "Find" button to the status bar area. + gtk_box_pack_end(GTK_BOX(box), pw->search_ui->search_button, FALSE, FALSE, 0); + gtk_widget_show(pw->search_ui->search_button); g_signal_connect(G_OBJECT(pw->window), "delete_event", G_CALLBACK(pan_window_delete_cb), pw); -- 2.20.1