shell: Make the "home" button act as a "previous" button

Keep history of the visited panels, when navigating between
them through links, or activated through the shell's menu items,
and go back to the overview when the history is empty.

https://bugzilla.gnome.org/show_bug.cgi?id=643322
This commit is contained in:
Bastien Nocera 2013-02-19 11:18:46 +01:00
parent 91924726f1
commit 6cb6404e7e

View file

@ -73,13 +73,14 @@ struct _CcWindowPrivate
GtkWidget *main_vbox; GtkWidget *main_vbox;
GtkWidget *scrolled_window; GtkWidget *scrolled_window;
GtkWidget *search_scrolled; GtkWidget *search_scrolled;
GtkWidget *home_button; GtkWidget *previous_button;
GtkWidget *top_right_box; GtkWidget *top_right_box;
GtkWidget *search_entry; GtkWidget *search_entry;
GtkWidget *lock_button; GtkWidget *lock_button;
GtkWidget *current_panel_box; GtkWidget *current_panel_box;
GtkWidget *current_panel; GtkWidget *current_panel;
char *current_panel_id; char *current_panel_id;
GQueue *previous_panels;
GPtrArray *custom_widgets; GPtrArray *custom_widgets;
@ -101,6 +102,11 @@ enum
PROP_ACTIVE_PANEL PROP_ACTIVE_PANEL
}; };
static gboolean cc_window_set_active_panel_from_id (CcShell *shell,
const gchar *start_id,
const gchar **argv,
GError **err);
/* Notebook helpers */ /* Notebook helpers */
static GtkWidget * static GtkWidget *
notebook_get_selected_page (GtkWidget *notebook) notebook_get_selected_page (GtkWidget *notebook)
@ -240,6 +246,24 @@ _shell_remove_all_custom_widgets (CcWindowPrivate *priv)
g_ptr_array_set_size (priv->custom_widgets, 0); g_ptr_array_set_size (priv->custom_widgets, 0);
} }
static void
add_current_panel_to_history (CcShell *shell,
const char *start_id)
{
CcWindowPrivate *priv;
g_return_if_fail (start_id != NULL);
priv = CC_WINDOW (shell)->priv;
if (!priv->current_panel_id ||
g_strcmp0 (priv->current_panel_id, start_id) == 0)
return;
g_queue_push_head (priv->previous_panels, g_strdup (priv->current_panel_id));
g_debug ("Added '%s' to the previous panels", priv->current_panel_id);
}
static void static void
shell_show_overview_page (CcWindow *self) shell_show_overview_page (CcWindow *self)
{ {
@ -253,6 +277,10 @@ shell_show_overview_page (CcWindow *self)
priv->current_panel_box = NULL; priv->current_panel_box = NULL;
g_clear_pointer (&priv->current_panel_id, g_free); g_clear_pointer (&priv->current_panel_id, g_free);
/* Clear the panel history */
g_queue_free_full (self->priv->previous_panels, g_free);
self->priv->previous_panels = g_queue_new ();
/* clear the search text */ /* clear the search text */
g_free (priv->filter_string); g_free (priv->filter_string);
priv->filter_string = g_strdup (""); priv->filter_string = g_strdup ("");
@ -294,7 +322,7 @@ item_activated_cb (CcShellCategoryView *view,
gchar *id, gchar *id,
CcWindow *shell) CcWindow *shell)
{ {
cc_shell_set_active_panel_from_id (CC_SHELL (shell), id, NULL, NULL); cc_window_set_active_panel_from_id (CC_SHELL (shell), id, NULL, NULL);
} }
static gboolean static gboolean
@ -695,7 +723,7 @@ on_search_row_activated (GtkTreeView *treeview,
-1); -1);
if (id) if (id)
cc_shell_set_active_panel_from_id (CC_SHELL (shell), id, NULL, NULL); cc_window_set_active_panel_from_id (CC_SHELL (shell), id, NULL, NULL);
gtk_tree_selection_unselect_all (selection); gtk_tree_selection_unselect_all (selection);
@ -876,10 +904,20 @@ setup_model (CcWindow *shell)
} }
static void static void
home_button_clicked_cb (GtkButton *button, previous_button_clicked_cb (GtkButton *button,
CcWindow *shell) CcWindow *shell)
{ {
shell_show_overview_page (shell); g_debug ("Num previous panels? %d", g_queue_get_length (shell->priv->previous_panels));
if (g_queue_is_empty (shell->priv->previous_panels)) {
shell_show_overview_page (shell);
} else {
char *panel_name;
panel_name = g_queue_pop_head (shell->priv->previous_panels);
g_debug ("About to go to previous panel '%s'", panel_name);
cc_window_set_active_panel_from_id (CC_SHELL (shell), panel_name, NULL, NULL);
g_free (panel_name);
}
} }
static void static void
@ -897,7 +935,7 @@ notebook_page_notify_cb (GtkNotebook *notebook,
if (child == priv->scrolled_window || child == priv->search_scrolled) if (child == priv->scrolled_window || child == priv->search_scrolled)
{ {
gtk_widget_hide (priv->home_button); gtk_widget_hide (priv->previous_button);
gtk_widget_show (priv->search_entry); gtk_widget_show (priv->search_entry);
gtk_widget_hide (priv->lock_button); gtk_widget_hide (priv->lock_button);
@ -908,7 +946,7 @@ notebook_page_notify_cb (GtkNotebook *notebook,
} }
else else
{ {
gtk_widget_show (priv->home_button); gtk_widget_show (priv->previous_button);
gtk_widget_hide (priv->search_entry); gtk_widget_hide (priv->search_entry);
/* set the scrolled window small so that it doesn't force /* set the scrolled window small so that it doesn't force
the window to be larger than this panel */ the window to be larger than this panel */
@ -935,10 +973,10 @@ _shell_embed_widget_in_header (CcShell *shell,
/* CcShell implementation */ /* CcShell implementation */
static gboolean static gboolean
_shell_set_active_panel_from_id (CcShell *shell, cc_window_set_active_panel_from_id (CcShell *shell,
const gchar *start_id, const gchar *start_id,
const gchar **argv, const gchar **argv,
GError **err) GError **err)
{ {
GtkTreeIter iter; GtkTreeIter iter;
gboolean iter_valid; gboolean iter_valid;
@ -1021,6 +1059,16 @@ _shell_set_active_panel_from_id (CcShell *shell,
return TRUE; return TRUE;
} }
static gboolean
_shell_set_active_panel_from_id (CcShell *shell,
const gchar *start_id,
const gchar **argv,
GError **err)
{
add_current_panel_to_history (shell, start_id);
return cc_window_set_active_panel_from_id (shell, start_id, argv, err);
}
static GtkWidget * static GtkWidget *
_shell_get_toplevel (CcShell *shell) _shell_get_toplevel (CcShell *shell)
{ {
@ -1103,6 +1151,12 @@ cc_window_dispose (GObject *object)
g_clear_object (&priv->search_filter); g_clear_object (&priv->search_filter);
g_clear_object (&priv->active_panel); g_clear_object (&priv->active_panel);
if (priv->previous_panels)
{
g_queue_free_full (priv->previous_panels, g_free);
priv->previous_panels = NULL;
}
G_OBJECT_CLASS (cc_window_parent_class)->dispose (object); G_OBJECT_CLASS (cc_window_parent_class)->dispose (object);
} }
@ -1378,14 +1432,14 @@ create_header (CcWindow *self)
image = gtk_image_new_from_icon_name ("go-previous-symbolic", GTK_ICON_SIZE_MENU); image = gtk_image_new_from_icon_name ("go-previous-symbolic", GTK_ICON_SIZE_MENU);
gtk_widget_show (image); gtk_widget_show (image);
priv->home_button = button = gtk_button_new (); priv->previous_button = button = gtk_button_new ();
gtk_button_set_image (GTK_BUTTON (button), image); gtk_button_set_image (GTK_BUTTON (button), image);
gtk_widget_set_no_show_all (button, TRUE); gtk_widget_set_no_show_all (button, TRUE);
accessible = gtk_widget_get_accessible (button); accessible = gtk_widget_get_accessible (button);
atk_object_set_name (accessible, _("All Settings")); atk_object_set_name (accessible, _("All Settings"));
gd_header_bar_pack_start (GD_HEADER_BAR (priv->header), button); gd_header_bar_pack_start (GD_HEADER_BAR (priv->header), button);
g_signal_connect (button, "clicked", G_CALLBACK (home_button_clicked_cb), self); g_signal_connect (button, "clicked", G_CALLBACK (previous_button_clicked_cb), self);
context = gtk_widget_get_style_context (priv->home_button); context = gtk_widget_get_style_context (priv->previous_button);
gtk_style_context_add_class (context, "image-button"); gtk_style_context_add_class (context, "image-button");
priv->top_right_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); priv->top_right_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
@ -1451,6 +1505,8 @@ cc_window_init (CcWindow *self)
create_window (self); create_window (self);
self->priv->previous_panels = g_queue_new ();
/* keep a list of custom widgets to unload on panel change */ /* keep a list of custom widgets to unload on panel change */
priv->custom_widgets = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); priv->custom_widgets = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);