[nautilus/wip/gbsneto/view-menu] view: handle the view menu



commit 85108c509265e22b8752a4de7bd102b887b16ad9
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Tue Aug 11 18:20:37 2015 -0300

    view: handle the view menu
    
    NautilusToolbar is the current widget responsible for
    handling the view's menu.
    
    Since we're isolating the view from the other widgets,
    we don't really want the toolbar handling the menu
    that is essencially the view's work.
    
    Fix that by adding the code related to the menu to the
    view.

 src/nautilus-toolbar.c     |   50 ++++++++++++++++--
 src/nautilus-view.c        |  120 ++++++++++++++++++++++++++++++++++++++++++-
 src/nautilus-view.h        |    2 +
 src/nautilus-window-slot.c |   24 +++++++++
 src/nautilus-window-slot.h |    2 +
 5 files changed, 189 insertions(+), 9 deletions(-)
---
diff --git a/src/nautilus-toolbar.c b/src/nautilus-toolbar.c
index 3607c90..7c85585 100644
--- a/src/nautilus-toolbar.c
+++ b/src/nautilus-toolbar.c
@@ -91,6 +91,7 @@ struct _NautilusToolbarPrivate {
         /* active slot & bindings */
         NautilusWindowSlot *active_slot;
         GBinding *icon_binding;
+        GBinding *view_widget_binding;
 };
 
 enum {
@@ -734,7 +735,7 @@ nautilus_toolbar_init (NautilusToolbar *self)
                                          self->priv->location_entry);
 
        builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-toolbar-view-menu.xml");
-       self->priv->view_menu_widget =  GTK_WIDGET (gtk_builder_get_object (builder, "view_menu_widget"));
+       self->priv->view_menu_widget =  g_object_ref (gtk_builder_get_object (builder, "view_menu_widget"));
        self->priv->zoom_level_scale = GTK_WIDGET (gtk_builder_get_object (builder, "zoom_level_scale"));
        self->priv->zoom_adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "zoom_adjustment"));
 
@@ -747,8 +748,8 @@ nautilus_toolbar_init (NautilusToolbar *self)
 
        g_signal_connect (self->priv->view_menu_widget, "closed",
                          G_CALLBACK (view_menu_popover_closed), self);
-       gtk_menu_button_set_popover (GTK_MENU_BUTTON (self->priv->view_button),
-                                    self->priv->view_menu_widget);
+       //gtk_menu_button_set_popover (GTK_MENU_BUTTON (self->priv->view_button),
+       //                           self->priv->view_menu_widget);
        g_object_unref (builder);
 
        builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-toolbar-action-menu.xml");
@@ -980,15 +981,44 @@ nautilus_toolbar_set_show_location_entry (NautilusToolbar *self,
        }
 }
 
+static gboolean
+nautilus_toolbar_view_widget_transform_to (GBinding     *binding,
+                                           const GValue *from_value,
+                                           GValue       *to_value,
+                                           gpointer      user_data)
+{
+        NautilusToolbar *toolbar;
+        GtkWidget *view_widget;
+
+        toolbar = NAUTILUS_TOOLBAR (user_data);
+        view_widget = g_value_get_object (from_value);
+
+        gtk_widget_set_sensitive (toolbar->priv->view_button, view_widget != NULL);
+
+        if (view_widget) {
+                if (!GTK_IS_POPOVER (view_widget)) {
+                        GtkWidget *popover;
+
+                        popover = gtk_popover_new (toolbar->priv->view_button);
+                        gtk_container_add (GTK_CONTAINER (popover), view_widget);
+
+                        view_widget = popover;
+                }
+        }
+
+        g_value_set_object (to_value, view_widget);
+
+        return TRUE;
+}
+
 void
 nautilus_toolbar_set_active_slot (NautilusToolbar    *toolbar,
                                   NautilusWindowSlot *slot)
 {
         g_return_if_fail (NAUTILUS_IS_TOOLBAR (toolbar));
 
-        if (toolbar->priv->icon_binding) {
-                g_clear_pointer (&toolbar->priv->icon_binding, g_binding_unbind);
-        }
+        g_clear_pointer (&toolbar->priv->icon_binding, g_binding_unbind);
+        g_clear_pointer (&toolbar->priv->view_widget_binding, g_binding_unbind);
 
         if (toolbar->priv->active_slot != slot) {
                 toolbar->priv->active_slot = slot;
@@ -1003,6 +1033,14 @@ nautilus_toolbar_set_active_slot (NautilusToolbar    *toolbar,
                         toolbar->priv->icon_binding = g_object_bind_property (slot, "icon",
                                                                               toolbar->priv->view_icon, 
"gicon",
                                                                               G_BINDING_DEFAULT);
+                        toolbar->priv->view_widget_binding =
+                                        g_object_bind_property_full (slot, "view-widget",
+                                                                     toolbar->priv->view_button, "popover",
+                                                                     G_BINDING_DEFAULT,
+                                                                     (GBindingTransformFunc) 
nautilus_toolbar_view_widget_transform_to,
+                                                                     NULL,
+                                                                     toolbar,
+                                                                     NULL);
                 }
 
         }
diff --git a/src/nautilus-view.c b/src/nautilus-view.c
index ecdcb60..91ea947 100644
--- a/src/nautilus-view.c
+++ b/src/nautilus-view.c
@@ -142,6 +142,7 @@ enum {
        PROP_WINDOW_SLOT = 1,
        PROP_SUPPORTS_ZOOMING,
         PROP_ICON,
+        PROP_VIEW_WIDGET,
        NUM_PROPERTIES
 };
 
@@ -239,6 +240,18 @@ struct NautilusViewDetails
         guint floating_bar_set_status_timeout_id;
         guint floating_bar_loading_timeout_id;
         GtkWidget *floating_bar;
+
+        /* View menu */
+        GtkWidget *view_menu_widget;
+        GtkWidget *view_icon;
+        GtkWidget *sort_menu;
+        GtkWidget *sort_trash_time;
+        GtkWidget *sort_search_relevance;
+        GtkWidget *visible_columns;
+        GtkWidget *stop;
+        GtkWidget *reload;
+        GtkAdjustment *zoom_adjustment;
+        GtkWidget *zoom_level_scale;
 };
 
 typedef struct {
@@ -610,6 +623,23 @@ nautilus_view_get_icon (NautilusView *view)
 }
 
 /**
+ * nautilus_view_get_view_widget:
+ * @view: a #NautilusView
+ *
+ * Retrieves the view menu, as a #GtkWidget. If it's %NULL,
+ * the button renders insensitive.
+ *
+ * Returns: (transfer none): a #GtkWidget for the view menu
+ */
+GtkWidget*
+nautilus_view_get_view_widget (NautilusView *view)
+{
+        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
+
+        return view->details->view_menu_widget;
+}
+
+/**
  * nautilus_view_can_rename_file
  *
  * Determine whether a file can be renamed.
@@ -1531,6 +1561,15 @@ action_select_pattern (GSimpleAction *action,
 }
 
 static void
+zoom_level_changed (GtkRange     *range,
+                    NautilusView *view)
+{
+        g_action_group_change_action_state (view->details->view_action_group,
+                                            "zoom-to-level",
+                                            g_variant_new_int32 (gtk_range_get_value (range)));
+}
+
+static void
 reveal_newly_added_folder (NautilusView *view, NautilusFile *new_file,
                           NautilusDirectory *directory, GFile *target_location)
 {
@@ -6751,6 +6790,52 @@ nautilus_view_update_context_menus (NautilusView *view)
        NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->update_context_menus (view);
 }
 
+static void
+nautilus_view_reset_view_menu (NautilusView *view)
+{
+       GActionGroup *view_action_group;
+       GVariant *variant;
+       GVariantIter iter;
+       gboolean show_sort_trash, show_sort_search, show_sort_access, show_sort_modification, enable_sort;
+       const gchar *hint;
+
+       /* Allow actions from the current view to be activated through
+        * the view menu and action menu of the toolbar */
+       view_action_group = nautilus_view_get_action_group (view);
+        gtk_widget_insert_action_group (GTK_WIDGET (view),
+                                       "view",
+                                       G_ACTION_GROUP (view_action_group));
+
+       gtk_widget_set_visible (view->details->visible_columns,
+                               g_action_group_has_action (view_action_group, "visible-columns"));
+
+       enable_sort = g_action_group_get_action_enabled (view_action_group, "sort");
+       show_sort_trash = show_sort_search = show_sort_modification = show_sort_access = FALSE;
+       gtk_widget_set_visible (view->details->sort_menu, enable_sort);
+
+       if (enable_sort) {
+               variant = g_action_group_get_action_state_hint (view_action_group, "sort");
+               g_variant_iter_init (&iter, variant);
+
+               while (g_variant_iter_next (&iter, "&s", &hint)) {
+                       if (g_strcmp0 (hint, "trash-time") == 0)
+                               show_sort_trash = TRUE;
+                       if (g_strcmp0 (hint, "search-relevance") == 0)
+                               show_sort_search = TRUE;
+               }
+
+               g_variant_unref (variant);
+       }
+
+       gtk_widget_set_visible (view->details->sort_trash_time, show_sort_trash);
+       gtk_widget_set_visible (view->details->sort_search_relevance, show_sort_search);
+
+       variant = g_action_group_get_action_state (view_action_group, "zoom-to-level");
+       gtk_adjustment_set_value (view->details->zoom_adjustment,
+                                 g_variant_get_int32 (variant));
+       g_variant_unref (variant);
+}
+
 /* Convenience function to reset the menus owned by the view but managed on
  * the toolbar, and update them with the current state.
  * It will also update the actions state, which will also update children
@@ -6759,7 +6844,6 @@ nautilus_view_update_context_menus (NautilusView *view)
 void
 nautilus_view_update_toolbar_menus (NautilusView *view)
 {
-       NautilusToolbar *toolbar;
        NautilusWindow *window;
 
        g_assert (NAUTILUS_IS_VIEW (view));
@@ -6772,8 +6856,7 @@ nautilus_view_update_toolbar_menus (NautilusView *view)
                return;
        }
        window = nautilus_view_get_window (view);
-       toolbar = NAUTILUS_TOOLBAR (nautilus_window_get_toolbar (window));
-       nautilus_toolbar_reset_menus (toolbar);
+       nautilus_view_reset_view_menu (view);
        nautilus_window_reset_menus (window);
 
        nautilus_view_update_actions_state (view);
@@ -7453,6 +7536,10 @@ nautilus_view_get_property (GObject    *object,
                 g_value_set_object (value, nautilus_view_get_icon (view));
                 break;
 
+        case PROP_VIEW_WIDGET:
+                g_value_set_object (value, nautilus_view_get_view_widget (view));
+                break;
+
         default:
                 g_assert_not_reached ();
 
@@ -7715,6 +7802,13 @@ nautilus_view_class_init (NautilusViewClass *klass)
                                      G_TYPE_ICON,
                                      G_PARAM_READABLE);
 
+        properties[PROP_VIEW_WIDGET] =
+                g_param_spec_object ("view-widget",
+                                     "View widget",
+                                     "The view's widget that will appear under the view menu button",
+                                     GTK_TYPE_WIDGET,
+                                     G_PARAM_READABLE);
+
        g_object_class_install_properties (oclass, NUM_PROPERTIES, properties);
 }
 
@@ -7745,6 +7839,26 @@ nautilus_view_init (NautilusView *view)
         gtk_widget_add_events (GTK_WIDGET (view),
                                GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
 
+        /* View menu */
+        builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-toolbar-view-menu.xml");
+       view->details->view_menu_widget =  g_object_ref (gtk_builder_get_object (builder, 
"view_menu_widget"));
+       view->details->zoom_level_scale = GTK_WIDGET (gtk_builder_get_object (builder, "zoom_level_scale"));
+       view->details->zoom_adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "zoom_adjustment"));
+
+       view->details->sort_menu =  GTK_WIDGET (gtk_builder_get_object (builder, "sort_menu"));
+       view->details->sort_trash_time =  GTK_WIDGET (gtk_builder_get_object (builder, "sort_trash_time"));
+       view->details->sort_search_relevance =  GTK_WIDGET (gtk_builder_get_object (builder, 
"sort_search_relevance"));
+       view->details->visible_columns =  GTK_WIDGET (gtk_builder_get_object (builder, "visible_columns"));
+       view->details->reload =  GTK_WIDGET (gtk_builder_get_object (builder, "reload"));
+       view->details->stop =  GTK_WIDGET (gtk_builder_get_object (builder, "stop"));
+
+        gtk_popover_set_relative_to (GTK_POPOVER (view->details->view_menu_widget), GTK_WIDGET (view));
+
+        g_signal_connect (view->details->zoom_level_scale, "value-changed",
+                          G_CALLBACK (zoom_level_changed), view);
+
+        g_object_unref (builder);
+
         /* Scrolled Window */
         view->details->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (view->details->scrolled_window),
diff --git a/src/nautilus-view.h b/src/nautilus-view.h
index b30210d..b6e73ce 100644
--- a/src/nautilus-view.h
+++ b/src/nautilus-view.h
@@ -394,4 +394,6 @@ gboolean          nautilus_view_is_search                  (NautilusView      *v
 
 GIcon*            nautilus_view_get_icon                   (NautilusView      *view);
 
+GtkWidget*        nautilus_view_get_view_widget            (NautilusView      *view);
+
 #endif /* NAUTILUS_VIEW_H */
diff --git a/src/nautilus-window-slot.c b/src/nautilus-window-slot.c
index 43f5841..0c5e393 100644
--- a/src/nautilus-window-slot.c
+++ b/src/nautilus-window-slot.c
@@ -56,6 +56,7 @@ enum {
 enum {
        PROP_WINDOW = 1,
         PROP_ICON,
+        PROP_VIEW_WIDGET,
        NUM_PROPERTIES
 };
 
@@ -531,6 +532,9 @@ nautilus_window_slot_get_property (GObject *object,
         case PROP_ICON:
                 g_value_set_object (value, nautilus_window_slot_get_icon (slot));
                 break;
+        case PROP_VIEW_WIDGET:
+                g_value_set_object (value, nautilus_window_slot_get_view_widget (slot));
+                break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
                break;
@@ -2273,6 +2277,7 @@ nautilus_window_slot_switch_new_content_view (NautilusWindowSlot *slot)
                gtk_widget_show (widget);
 
                 g_object_notify_by_pspec (G_OBJECT (slot), properties[PROP_ICON]);
+                g_object_notify_by_pspec (G_OBJECT (slot), properties[PROP_VIEW_WIDGET]);
        }
 }
 
@@ -2461,6 +2466,13 @@ nautilus_window_slot_class_init (NautilusWindowSlotClass *klass)
                                     G_TYPE_ICON,
                                     G_PARAM_READABLE);
 
+        properties[PROP_VIEW_WIDGET] =
+               g_param_spec_object ("view-widget",
+                                    "Widget for the view menu",
+                                    "The widget for the view's menu",
+                                    GTK_TYPE_WIDGET,
+                                    G_PARAM_READABLE);
+
        g_object_class_install_properties (oclass, NUM_PROPERTIES, properties);
        g_type_class_add_private (klass, sizeof (NautilusWindowSlotDetails));
 }
@@ -2681,3 +2693,15 @@ nautilus_window_slot_get_icon (NautilusWindowSlot *slot)
 
         return view ? nautilus_view_get_icon (view) : NULL;
 }
+
+GtkWidget*
+nautilus_window_slot_get_view_widget (NautilusWindowSlot *slot)
+{
+        NautilusView *view;
+
+        g_return_val_if_fail (NAUTILUS_IS_WINDOW_SLOT (slot), NULL);
+
+        view = nautilus_window_slot_get_current_view (slot);
+
+        return view ? nautilus_view_get_view_widget (view) : NULL;
+}
diff --git a/src/nautilus-window-slot.h b/src/nautilus-window-slot.h
index 5b96570..36d27bc 100644
--- a/src/nautilus-window-slot.h
+++ b/src/nautilus-window-slot.h
@@ -129,4 +129,6 @@ void nautilus_window_slot_display_view_selection_failure   (NautilusWindow *wind
 
 GIcon*   nautilus_window_slot_get_icon                     (NautilusWindowSlot *slot);
 
+GtkWidget* nautilus_window_slot_get_view_widget            (NautilusWindowSlot *slot);
+
 #endif /* NAUTILUS_WINDOW_SLOT_H */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]