Skip to content

Commit

Permalink
Pull the search UI construction code out into a distinct function.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
xsdg committed Jul 3, 2017
1 parent b2335bb commit f640a7a
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 54 deletions.
16 changes: 11 additions & 5 deletions src/pan-view/pan-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -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;

Expand Down
92 changes: 77 additions & 15 deletions src/pan-view/pan-view-search.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;

Expand All @@ -360,56 +420,58 @@ 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);
}

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);
}
}
}
6 changes: 6 additions & 0 deletions src/pan-view/pan-view-search.h
Original file line number Diff line number Diff line change
Expand Up @@ -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: */
41 changes: 7 additions & 34 deletions src/pan-view/pan-view.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 */

Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit f640a7a

Please sign in to comment.