changeset 2529:74d73f2f5667

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.
author Omari Stephens <xsdg@google.com>
date Sat, 24 Dec 2016 22:37:21 +0000
parents d1b4dd282048
children 949b146aaa23
files src/pan-view/pan-types.h src/pan-view/pan-view-search.c src/pan-view/pan-view-search.h src/pan-view/pan-view.c
diffstat 4 files changed, 101 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- a/src/pan-view/pan-types.h	Sat Dec 24 05:23:02 2016 +0000
+++ b/src/pan-view/pan-types.h	Sat Dec 24 22:37:21 2016 +0000
@@ -169,6 +169,16 @@
 	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 @@
 	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;
 
--- a/src/pan-view/pan-view-search.c	Sat Dec 24 05:23:02 2016 +0000
+++ b/src/pan-view/pan-view-search.c	Sat Dec 24 22:37:21 2016 +0000
@@ -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 @@
 
 	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 @@
 {
 	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_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);
 			}
 		}
 }
--- a/src/pan-view/pan-view-search.h	Sat Dec 24 05:23:02 2016 +0000
+++ b/src/pan-view/pan-view-search.h	Sat Dec 24 22:37:21 2016 +0000
@@ -30,5 +30,11 @@
 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: */
--- a/src/pan-view/pan-view.c	Sat Dec 24 05:23:02 2016 +0000
+++ b/src/pan-view/pan-view.c	Sat Dec 24 22:37:21 2016 +0000
@@ -1132,7 +1132,7 @@
 	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 @@
 
 		if (stop_signal) return stop_signal;
 
+		// Don't steal characters from entry boxes.
 		if (!on_entry)
 			{
 			stop_signal = TRUE;
@@ -1879,24 +1880,8 @@
 
 	/* 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 @@
 	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);