From 7c01382e815448a4d9684eccb603a81a8c88d750 Mon Sep 17 00:00:00 2001 From: Gergely Polonkai Date: Tue, 14 Oct 2014 00:22:29 +0200 Subject: [PATCH] Refactor header bar mode changing Fixes #101 --- src/ag-header-bar.c | 106 ++++++++++++++++++++++++----- src/ag-icon-view.c | 38 ++++++----- src/ag-window.c | 107 ++++++++++-------------------- src/resources/ui/ag-header-bar.ui | 3 +- src/resources/ui/ag-window.ui | 2 +- 5 files changed, 149 insertions(+), 107 deletions(-) diff --git a/src/ag-header-bar.c b/src/ag-header-bar.c index 72905c4..0446a81 100644 --- a/src/ag-header-bar.c +++ b/src/ag-header-bar.c @@ -17,6 +17,11 @@ enum { PROP_COUNT }; +enum { + SIGNAL_MODE_CHANGED, + SIGNAL_COUNT +}; + static void ag_header_bar_dispose(GObject *gobject); static void ag_header_bar_finalize(GObject *gobject); @@ -25,6 +30,7 @@ G_DEFINE_TYPE_WITH_PRIVATE(AgHeaderBar, ag_header_bar, GTK_TYPE_HEADER_BAR); #define GET_PRIV(v, o) AgHeaderBarPrivate *v = ag_header_bar_get_instance_private(o); static GParamSpec *properties[PROP_COUNT]; +static guint signals[SIGNAL_COUNT] = { 0 }; static void ag_header_bar_selection_mode_cb(GtkButton *button, @@ -32,22 +38,58 @@ ag_header_bar_selection_mode_cb(GtkButton *button, { GET_PRIV(priv, header_bar); - switch (priv->mode) { - case AG_HEADER_BAR_MODE_LIST: - ag_header_bar_set_mode(header_bar, AG_HEADER_BAR_MODE_SELECTION); + /* If we are not in list mode, this transition is invalid */ + if (priv->mode != AG_HEADER_BAR_MODE_LIST) { + g_warning("Invalid header bar mode transition!"); - break; - - case AG_HEADER_BAR_MODE_SELECTION: - ag_header_bar_set_mode(header_bar, AG_HEADER_BAR_MODE_LIST); - - break; - - default: - g_warning("Invalid header bar mode transition!"); - - break; + return; } + + g_signal_emit( + header_bar, + signals[SIGNAL_MODE_CHANGED], 0, + AG_HEADER_BAR_MODE_SELECTION + ); +} + +static void +ag_header_bar_selection_cancel_cb(GtkButton *button, + AgHeaderBar *header_bar) +{ + GET_PRIV(priv, header_bar); + + /* If we are not in selection mode, this transition is invalid */ + if (priv->mode != AG_HEADER_BAR_MODE_SELECTION) { + g_warning("Invalid header bar mode transition!"); + + return; + } + + g_signal_emit( + header_bar, + signals[SIGNAL_MODE_CHANGED], 0, + AG_HEADER_BAR_MODE_LIST + ); +} + +static void +ag_header_bar_back_cb(GtkButton *button, + AgHeaderBar *header_bar) +{ + GET_PRIV(priv, header_bar); + + /* If we are not in chart mode, this transition is invalid */ + if (priv->mode != AG_HEADER_BAR_MODE_CHART) { + g_warning("Invalid header bar mode transition!"); + + return; + } + + g_signal_emit( + header_bar, + signals[SIGNAL_MODE_CHANGED], 0, + AG_HEADER_BAR_MODE_LIST + ); } static void @@ -56,6 +98,10 @@ ag_header_bar_set_selection_mode(AgHeaderBar *header_bar, gboolean state) GtkStyleContext *style; GET_PRIV(priv, header_bar); + if (state == (priv->mode == AG_HEADER_BAR_MODE_SELECTION)) { + return; + } + style = gtk_widget_get_style_context(GTK_WIDGET(header_bar)); if (state) { @@ -83,13 +129,15 @@ ag_header_bar_set_mode_internal(AgHeaderBar *header_bar, AgHeaderBarMode mode, gboolean force) { + gboolean invalid = FALSE; + AgHeaderBarMode old_mode; GET_PRIV(priv, header_bar); if (!force && (priv->mode == mode)) { return; } - priv->mode = mode; + old_mode = priv->mode; switch (mode) { case AG_HEADER_BAR_MODE_LIST: @@ -124,12 +172,18 @@ ag_header_bar_set_mode_internal(AgHeaderBar *header_bar, break; default: + invalid = TRUE; g_warning("Invalid header bar mode!"); break; } - g_object_notify_by_pspec(G_OBJECT(header_bar), properties[PROP_MODE]); + if (invalid) { + priv->mode = old_mode; + } else { + priv->mode = mode; + g_object_notify_by_pspec(G_OBJECT(header_bar), properties[PROP_MODE]); + } } void @@ -229,6 +283,18 @@ ag_header_bar_class_init(AgHeaderBarClass *klass) properties[PROP_MODE] ); + signals[SIGNAL_MODE_CHANGED] = g_signal_new( + "mode-changed", + AG_TYPE_HEADER_BAR, + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + NULL, + G_TYPE_NONE, + 1, + AG_TYPE_HEADER_BAR_MODE + ); + gtk_widget_class_set_template_from_resource( widget_class, "/eu/polonkai/gergely/Astrognome/ui/ag-header-bar.ui" @@ -254,6 +320,14 @@ ag_header_bar_class_init(AgHeaderBarClass *klass) widget_class, ag_header_bar_selection_mode_cb ); + gtk_widget_class_bind_template_callback( + widget_class, + ag_header_bar_selection_cancel_cb + ); + gtk_widget_class_bind_template_callback( + widget_class, + ag_header_bar_back_cb + ); } static void diff --git a/src/ag-icon-view.c b/src/ag-icon-view.c index a867bcc..41d24f7 100644 --- a/src/ag-icon-view.c +++ b/src/ag-icon-view.c @@ -36,25 +36,27 @@ ag_icon_view_set_mode(AgIconView *icon_view, AgIconViewMode mode) { AgIconViewPrivate *priv = ag_icon_view_get_instance_private(icon_view); - if (priv->mode != mode) { - priv->mode = mode; - - if (mode != AG_ICON_VIEW_MODE_SELECTION) { - ag_icon_view_unselect_all(icon_view); - } - - ag_chart_renderer_set_toggle_visible( - priv->thumb_renderer, - (mode == AG_ICON_VIEW_MODE_SELECTION) - ); - - gtk_widget_queue_draw(GTK_WIDGET(icon_view)); - - g_object_notify_by_pspec( - G_OBJECT(icon_view), - properties[PROP_MODE] - ); + if (priv->mode == mode) { + return; } + + priv->mode = mode; + + if (mode != AG_ICON_VIEW_MODE_SELECTION) { + ag_icon_view_unselect_all(icon_view); + } + + ag_chart_renderer_set_toggle_visible( + priv->thumb_renderer, + (mode == AG_ICON_VIEW_MODE_SELECTION) + ); + + gtk_widget_queue_draw(GTK_WIDGET(icon_view)); + + g_object_notify_by_pspec( + G_OBJECT(icon_view), + properties[PROP_MODE] + ); } AgIconViewMode diff --git a/src/ag-window.c b/src/ag-window.c index 61fd1f5..ffcef1f 100644 --- a/src/ag-window.c +++ b/src/ag-window.c @@ -1299,20 +1299,19 @@ ag_window_set_theme(AgWindow *window, AgDisplayTheme *theme) static void ag_window_tab_changed_cb(GtkStack *tabs, GParamSpec *pspec, AgWindow *window) { - GtkWidget *active_tab; - const gchar *active_tab_name = gtk_stack_get_visible_child_name(tabs); GET_PRIV(window); + GtkWidget *old_tab = priv->current_tab; + GtkWidget *new_tab = gtk_stack_get_visible_child(tabs); + const gchar *active_tab_name = gtk_stack_get_visible_child_name(tabs); - g_debug("Active tab changed: %s", active_tab_name); - - if (active_tab_name == NULL) { + if (old_tab == new_tab) { return; } - active_tab = gtk_stack_get_visible_child(tabs); + g_debug("Active tab changed: %s", active_tab_name); if (strcmp("chart", active_tab_name) == 0) { - gtk_widget_set_size_request(active_tab, 600, 600); + gtk_widget_set_size_request(new_tab, 600, 600); if (priv->theme == NULL) { AgSettings *settings; GSettings *main_settings; @@ -1335,6 +1334,8 @@ ag_window_tab_changed_cb(GtkStack *tabs, GParamSpec *pspec, AgWindow *window) if (strcmp("list", active_tab_name) == 0) { ag_header_bar_set_mode(priv->header_bar, AG_HEADER_BAR_MODE_LIST); } else { + g_debug("Switching header bar to chart mode"); + ag_header_bar_set_mode(priv->header_bar, AG_HEADER_BAR_MODE_CHART); // Note that priv->current_tab is actually the previously selected tab, @@ -1345,7 +1346,7 @@ ag_window_tab_changed_cb(GtkStack *tabs, GParamSpec *pspec, AgWindow *window) } } - priv->current_tab = active_tab; + priv->current_tab = new_tab; } static void @@ -1492,46 +1493,29 @@ ag_window_refresh_action(GSimpleAction *action, } static void -ag_window_set_selection_mode(AgWindow *window, gboolean state) +ag_window_header_bar_mode_change_cb(AgHeaderBar *header_bar, + AgHeaderBarMode mode, + AgWindow *window) { GET_PRIV(window); - if (priv->current_tab != priv->tab_list) { - g_warning("You can activate selection mode only in the list view!"); + switch (mode) { + case AG_HEADER_BAR_MODE_LIST: + ag_window_change_tab(window, "list"); + ag_header_bar_set_mode(header_bar, mode); + ag_icon_view_set_mode(priv->chart_list, AG_ICON_VIEW_MODE_NORMAL); - return; + break; + + case AG_HEADER_BAR_MODE_SELECTION: + ag_header_bar_set_mode(header_bar, mode); + ag_icon_view_set_mode(priv->chart_list, AG_ICON_VIEW_MODE_SELECTION); + + break; + + default: + break; } - - g_debug("Set selection mode: %d", state); - - if (state) { - ag_header_bar_set_mode(priv->header_bar, AG_HEADER_BAR_MODE_SELECTION); - ag_icon_view_set_mode( - priv->chart_list, - AG_ICON_VIEW_MODE_SELECTION - ); - } else { - ag_header_bar_set_mode(priv->header_bar, AG_HEADER_BAR_MODE_LIST); - ag_icon_view_set_mode( - priv->chart_list, - AG_ICON_VIEW_MODE_NORMAL - ); - } -} - -static void -ag_window_header_bar_mode_change_cb(AgHeaderBar *header_bar, - GParamSpec *pspec, - AgWindow *window) -{ - AgHeaderBarMode mode; - - mode = ag_header_bar_get_mode(header_bar); - - ag_window_set_selection_mode( - window, - (mode == AG_HEADER_BAR_MODE_SELECTION) - ); } static void @@ -1543,29 +1527,21 @@ ag_window_icon_view_mode_cb(AgIconView *icon_view, GVariant *state_var = g_variant_new_boolean( (mode == AG_ICON_VIEW_MODE_SELECTION) ); + GET_PRIV(window); + + g_debug("IV mode change: %d", (mode == AG_ICON_VIEW_MODE_SELECTION)); g_action_group_activate_action( G_ACTION_GROUP(window), "selection", state_var ); -} - -static void -ag_window_selection_mode_action(GSimpleAction *action, - GVariant *parameter, - gpointer user_data) -{ - GVariant *state; - gboolean new_state; - AgWindow *window = AG_WINDOW(user_data); - - state = g_action_get_state(G_ACTION(action)); - new_state = !g_variant_get_boolean(state); - g_action_change_state(G_ACTION(action), g_variant_new_boolean(new_state)); - g_variant_unref(state); - - ag_window_set_selection_mode(window, new_state); + ag_header_bar_set_mode( + priv->header_bar, + (mode == AG_ICON_VIEW_MODE_SELECTION) + ? AG_HEADER_BAR_MODE_SELECTION + : AG_HEADER_BAR_MODE_LIST + ); } static void @@ -1680,7 +1656,6 @@ static GActionEntry win_entries[] = { { "new-chart", ag_window_new_chart_action, NULL, NULL, NULL }, { "back", ag_window_back_action, NULL, NULL, NULL }, { "refresh", ag_window_refresh_action, NULL, NULL, NULL }, - { "selection", ag_window_selection_mode_action, "b", "false", NULL }, { "delete", ag_window_delete_action, NULL, NULL, NULL }, { "connection", ag_window_connection_action, "s", "'aspects'", NULL }, }; @@ -2012,12 +1987,6 @@ ag_window_destroy(GtkWidget *widget) GTK_WIDGET_CLASS(ag_window_parent_class)->destroy(widget); } -static void -ag_window_selection_mode_cancel_cb(GtkButton *button, AgWindow *window) -{ - ag_window_set_selection_mode(window, FALSE); -} - static void ag_window_set_property(GObject *gobject, guint prop_id, @@ -2207,10 +2176,6 @@ ag_window_class_init(AgWindowClass *klass) widget_class, ag_window_icon_view_mode_cb ); - gtk_widget_class_bind_template_callback( - widget_class, - ag_window_selection_mode_cancel_cb - ); gtk_widget_class_bind_template_callback( widget_class, ag_window_house_system_changed_cb diff --git a/src/resources/ui/ag-header-bar.ui b/src/resources/ui/ag-header-bar.ui index dd9dc03..ab9a1cb 100644 --- a/src/resources/ui/ag-header-bar.ui +++ b/src/resources/ui/ag-header-bar.ui @@ -55,6 +55,7 @@ True win.back + @@ -99,7 +100,7 @@ True Cancel - + selection diff --git a/src/resources/ui/ag-window.ui b/src/resources/ui/ag-window.ui index 7b99c94..4f7629a 100644 --- a/src/resources/ui/ag-window.ui +++ b/src/resources/ui/ag-window.ui @@ -83,7 +83,7 @@ - +