[gnome-control-center] window: Use a HdyLeaflet



commit 0ca61a5bde84eae4b874a231ecfb2c21ae98e124
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Thu Oct 25 14:06:05 2018 +0200

    window: Use a HdyLeaflet
    
    This allows the window to be folded to show either the sidebar or the
    panel when not enough space is available.

 shell/cc-window.c  | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++---
 shell/cc-window.ui | 75 ++++++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 133 insertions(+), 16 deletions(-)
---
diff --git a/shell/cc-window.c b/shell/cc-window.c
index 40e76a7a1..fb28b4ab5 100644
--- a/shell/cc-window.c
+++ b/shell/cc-window.c
@@ -57,11 +57,13 @@ struct _CcWindow
   GtkWidget  *stack;
   GtkWidget  *header;
   GtkWidget  *header_box;
+  GtkWidget  *main_leaflet;
   GtkWidget  *list_scrolled;
   GtkWidget  *panel_headerbar;
   GtkWidget  *search_scrolled;
   GtkWidget  *panel_list;
   GtkWidget  *previous_button;
+  GtkWidget  *back_revealer;
   GtkWidget  *top_right_box;
   GtkWidget  *search_button;
   GtkWidget  *search_bar;
@@ -80,6 +82,8 @@ struct _CcWindow
 
   CcPanel *active_panel;
   GSettings *settings;
+
+  CcPanelListView previous_list_view;
 };
 
 static void     cc_shell_iface_init         (CcShellInterface      *iface);
@@ -155,6 +159,13 @@ remove_all_custom_widgets (CcWindow *self)
   CC_EXIT;
 }
 
+static void
+on_sidebar_activated_cb (CcPanel  *panel,
+                         CcWindow *self)
+{
+  hdy_leaflet_set_visible_child_name (HDY_LEAFLET (self->main_leaflet), "panel");
+}
+
 static gboolean
 activate_panel (CcWindow          *self,
                 const gchar       *id,
@@ -186,6 +197,8 @@ activate_panel (CcWindow          *self,
   /* Begin the profile */
   g_timer_start (timer);
 
+  if (self->current_panel)
+    g_signal_handlers_disconnect_by_data (self->current_panel, self);
   self->current_panel = GTK_WIDGET (cc_panel_loader_load_by_name (CC_SHELL (self), id, parameters));
   cc_shell_set_active_panel (CC_SHELL (self), CC_PANEL (self->current_panel));
   gtk_widget_show (self->current_panel);
@@ -205,6 +218,10 @@ activate_panel (CcWindow          *self,
 
   sidebar_widget = cc_panel_get_sidebar_widget (CC_PANEL (self->current_panel));
   cc_panel_list_add_sidebar_widget (CC_PANEL_LIST (self->panel_list), sidebar_widget);
+  /* Ensure we show the panel when when the leaflet is folded and a sidebar
+   * widget's row is activated.
+   */
+  g_signal_connect_object (self->current_panel, "sidebar-activated", G_CALLBACK (on_sidebar_activated_cb), 
self, 0);
 
   /* Finish profiling */
   g_timer_stop (timer);
@@ -405,6 +422,7 @@ set_active_panel_from_id (CcShell      *shell,
                           const gchar  *start_id,
                           GVariant     *parameters,
                           gboolean      add_to_history,
+                          gboolean      force_moving_to_the_panel,
                           GError      **error)
 {
   g_autoptr(GIcon) gicon = NULL;
@@ -413,17 +431,22 @@ set_active_panel_from_id (CcShell      *shell,
   GtkTreeIter iter;
   GtkWidget *old_panel;
   CcWindow *self;
+  CcPanelListView view;
   gboolean activated;
   gboolean found;
 
   CC_ENTRY;
 
   self = CC_WINDOW (shell);
+  view = cc_panel_list_get_view (CC_PANEL_LIST (self->panel_list));
 
   /* When loading the same panel again, just set its parameters */
   if (g_strcmp0 (self->current_panel_id, start_id) == 0)
     {
       g_object_set (G_OBJECT (self->current_panel), "parameters", parameters, NULL);
+      if (force_moving_to_the_panel || self->previous_list_view == view)
+        hdy_leaflet_set_visible_child_name (HDY_LEAFLET (self->main_leaflet), "panel");
+      self->previous_list_view = view;
       CC_RETURN (TRUE);
     }
 
@@ -457,6 +480,9 @@ set_active_panel_from_id (CcShell      *shell,
   if (add_to_history)
     add_current_panel_to_history (shell, start_id);
 
+  if (force_moving_to_the_panel)
+    hdy_leaflet_set_visible_child_name (HDY_LEAFLET (self->main_leaflet), "panel");
+
   g_free (self->current_panel_id);
   self->current_panel_id = g_strdup (start_id);
 
@@ -506,12 +532,39 @@ switch_to_previous_panel (CcWindow *self)
 
   g_debug ("Going to previous panel (%s)", previous_panel_id);
 
-  set_active_panel_from_id (CC_SHELL (self), previous_panel_id, NULL, FALSE, NULL);
+  set_active_panel_from_id (CC_SHELL (self), previous_panel_id, NULL, FALSE, FALSE, NULL);
 
   CC_EXIT;
 }
 
 /* Callbacks */
+static void
+update_fold_state (CcWindow *shell)
+{
+  GtkWidget *header_child = hdy_leaflet_get_visible_child (HDY_LEAFLET (shell->header_box));
+  HdyFold fold = hdy_leaflet_get_fold (HDY_LEAFLET (shell->header_box));
+
+  hdy_header_group_set_focus (shell->header_group, fold == HDY_FOLD_FOLDED ? GTK_HEADER_BAR (header_child) : 
NULL);
+
+  gtk_revealer_set_reveal_child (GTK_REVEALER (shell->back_revealer), fold == HDY_FOLD_FOLDED);
+}
+
+static void
+notify_header_visible_child_cb (HdyLeaflet *leaflet,
+                                GParamSpec *pspec,
+                                CcWindow   *shell)
+{
+  update_fold_state (shell);
+}
+
+static void
+notify_fold_cb (HdyLeaflet *leaflet,
+                GParamSpec *pspec,
+                CcWindow   *shell)
+{
+  update_fold_state (shell);
+}
+
 static void
 show_panel_cb (CcPanelList *panel_list,
                const gchar *panel_id,
@@ -520,7 +573,7 @@ show_panel_cb (CcPanelList *panel_list,
   if (!panel_id)
     return;
 
-  set_active_panel_from_id (CC_SHELL (self), panel_id, NULL, TRUE, NULL);
+  set_active_panel_from_id (CC_SHELL (self), panel_id, NULL, TRUE, FALSE, NULL);
 }
 
 static void
@@ -534,6 +587,13 @@ search_entry_activate_cb (GtkEntry *entry,
   gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (self->search_bar), !changed);
 }
 
+static void
+back_button_clicked_cb (GtkButton *button,
+                        CcWindow  *shell)
+{
+  hdy_leaflet_set_visible_child_name (HDY_LEAFLET (shell->main_leaflet), "sidebar");
+}
+
 static void
 previous_button_clicked_cb (GtkButton *button,
                             CcWindow  *shell)
@@ -668,7 +728,7 @@ cc_window_set_active_panel_from_id (CcShell      *shell,
                                     GVariant     *parameters,
                                     GError      **error)
 {
-  return set_active_panel_from_id (shell, start_id, parameters, TRUE, error);
+  return set_active_panel_from_id (shell, start_id, parameters, TRUE, TRUE, error);
 }
 
 static void
@@ -842,12 +902,14 @@ cc_window_class_init (CcWindowClass *klass)
 
   gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/ControlCenter/gtk/cc-window.ui");
 
+  gtk_widget_class_bind_template_child (widget_class, CcWindow, back_revealer);
   gtk_widget_class_bind_template_child (widget_class, CcWindow, development_warning_dialog);
   gtk_widget_class_bind_template_child (widget_class, CcWindow, header);
   gtk_widget_class_bind_template_child (widget_class, CcWindow, header_box);
   gtk_widget_class_bind_template_child (widget_class, CcWindow, header_group);
   gtk_widget_class_bind_template_child (widget_class, CcWindow, header_sizegroup);
   gtk_widget_class_bind_template_child (widget_class, CcWindow, list_scrolled);
+  gtk_widget_class_bind_template_child (widget_class, CcWindow, main_leaflet);
   gtk_widget_class_bind_template_child (widget_class, CcWindow, panel_headerbar);
   gtk_widget_class_bind_template_child (widget_class, CcWindow, panel_list);
   gtk_widget_class_bind_template_child (widget_class, CcWindow, previous_button);
@@ -857,7 +919,10 @@ cc_window_class_init (CcWindowClass *klass)
   gtk_widget_class_bind_template_child (widget_class, CcWindow, stack);
   gtk_widget_class_bind_template_child (widget_class, CcWindow, top_right_box);
 
+  gtk_widget_class_bind_template_callback (widget_class, back_button_clicked_cb);
   gtk_widget_class_bind_template_callback (widget_class, gdk_window_set_cb);
+  gtk_widget_class_bind_template_callback (widget_class, notify_header_visible_child_cb);
+  gtk_widget_class_bind_template_callback (widget_class, notify_fold_cb);
   gtk_widget_class_bind_template_callback (widget_class, on_development_warning_dialog_responded_cb);
   gtk_widget_class_bind_template_callback (widget_class, previous_button_clicked_cb);
   gtk_widget_class_bind_template_callback (widget_class, search_entry_activate_cb);
@@ -879,10 +944,13 @@ cc_window_init (CcWindow *self)
   self->settings = g_settings_new ("org.gnome.ControlCenter");
   self->custom_widgets = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
   self->previous_panels = g_queue_new ();
+  self->previous_list_view = cc_panel_list_get_view (CC_PANEL_LIST (self->panel_list));
 
   /* Add a custom CSS class on development builds */
   if (in_flatpak_sandbox ())
     add_development_build_css (self);
+
+  update_fold_state (self);
 }
 
 CcWindow *
diff --git a/shell/cc-window.ui b/shell/cc-window.ui
index 67c71e9d0..b2bcb05ea 100644
--- a/shell/cc-window.ui
+++ b/shell/cc-window.ui
@@ -10,9 +10,11 @@
     <signal name="map-event" handler="window_map_event_cb" object="CcWindow" swapped="no" />
     <signal name="key-press-event" handler="window_key_press_event_cb" object="CcWindow" swapped="no" 
after="yes" />
     <child>
-      <object class="GtkBox" id="main_hbox">
+      <object class="HdyLeaflet" id="main_leaflet">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
+        <property name="mode-transition-type">slide</property>
+        <property name="child-transition-type">slide</property>
         <child>
           <object class="GtkBox" id="sidebar_box">
             <property name="visible">True</property>
@@ -74,9 +76,7 @@
             </child>
           </object>
           <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">0</property>
+            <property name="name">sidebar</property>
           </packing>
         </child>
         <child>
@@ -88,11 +88,6 @@
               <class name="sidebar"/>
             </style>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
         </child>
         <child>
           <object class="GtkStack" id="stack">
@@ -106,9 +101,7 @@
             </style>
           </object>
           <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">2</property>
+            <property name="name">panel</property>
           </packing>
         </child>
       </object>
@@ -118,10 +111,17 @@
         <property name="visible">True</property>
         <property name="can_focus">False</property>
         <child>
-          <object class="GtkBox" id="header_box">
+          <object class="HdyLeaflet" id="header_box">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
             <property name="orientation">horizontal</property>
+            <property name="mode-transition-type" bind-source="main_leaflet" 
bind-property="mode-transition-type" bind-flags="bidirectional|sync-create"/>
+            <property name="mode-transition-duration" bind-source="main_leaflet" 
bind-property="mode-transition-duration" bind-flags="bidirectional|sync-create"/>
+            <property name="child-transition-type" bind-source="main_leaflet" 
bind-property="child-transition-type" bind-flags="bidirectional|sync-create"/>
+            <property name="child-transition-duration" bind-source="main_leaflet" 
bind-property="child-transition-duration" bind-flags="bidirectional|sync-create"/>
+            <property name="visible-child-name" bind-source="main_leaflet" 
bind-property="visible-child-name" bind-flags="bidirectional|sync-create"/>
+            <signal name="notify::visible-child" handler="notify_header_visible_child_cb" swapped="no"/>
+            <signal name="notify::fold" handler="notify_fold_cb" object="CcWindow" after="yes" swapped="no"/>
             <child>
               <object class="GtkHeaderBar" id="header">
                 <property name="visible">True</property>
@@ -199,6 +199,9 @@
                   </packing>
                 </child>
               </object>
+              <packing>
+                <property name="name">sidebar</property>
+              </packing>
             </child>
             <child>
               <object class="GtkSeparator" id="header_separator">
@@ -216,6 +219,40 @@
                 <property name="can_focus">False</property>
                 <property name="hexpand">True</property>
                 <property name="show_close_button">True</property>
+                <child>
+                  <object class="GtkRevealer" id="back_revealer">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="transition-type">crossfade</property>
+                    <property name="transition-duration" bind-source="main_leaflet" 
bind-property="mode-transition-duration" bind-flags="bidirectional|sync-create"/>
+                    <child>
+                      <object class="GtkButton" id="back">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="receives_default">False</property>
+                        <property name="valign">center</property>
+                        <property name="use-underline">True</property>
+                        <signal name="clicked" handler="back_button_clicked_cb" object="CcWindow" 
swapped="no" />
+                        <style>
+                          <class name="image-button"/>
+                        </style>
+                        <child internal-child="accessible">
+                          <object class="AtkObject" id="a11y-back">
+                            <property name="accessible-name" translatable="yes">Back</property>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkImage" id="back_image">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="icon_name">go-previous-symbolic</property>
+                            <property name="icon_size">1</property>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
                 <child>
                   <object class="GtkBox" id="top_right_box">
                     <property name="visible">True</property>
@@ -226,6 +263,9 @@
                   </packing>
                 </child>
               </object>
+              <packing>
+                <property name="name">panel</property>
+              </packing>
             </child>
           </object>
         </child>
@@ -257,6 +297,15 @@
     </widgets>
   </object>
 
+  <!-- Synchronize separators -->
+  <object class="GtkSizeGroup">
+    <property name="mode">horizontal</property>
+    <widgets>
+      <widget name="header_separator"/>
+      <widget name="panel_separator"/>
+    </widgets>
+  </object>
+
   <!-- Synchronize right header and panel -->
   <object class="GtkSizeGroup">
     <property name="mode">horizontal</property>


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