[gnome-builder/wip/gtk4-port: 376/736] libide/gui: add overlay/progress to IdePage




commit 7429d8c88c65cf64b7b4a19c96da82d2308bf6d2
Author: Christian Hergert <chergert redhat com>
Date:   Mon Apr 4 14:27:23 2022 -0700

    libide/gui: add overlay/progress to IdePage
    
    We don't want all of the subclasses to duplicate this effort, so manage
    that directly in IdePage and give API to set progress for the page. Long
    term we could even display short messages along with the operation should
    that become necessary.

 src/libide/gui/ide-page.c               | 100 +++++++++++++++++++++++++++-----
 src/libide/gui/ide-page.h               |   3 +
 src/libide/gui/ide-page.ui              |  26 +++++++++
 src/libide/gui/libide-gui.gresource.xml |   1 +
 4 files changed, 115 insertions(+), 15 deletions(-)
---
diff --git a/src/libide/gui/ide-page.c b/src/libide/gui/ide-page.c
index d117e0b87..ae46fa8f3 100644
--- a/src/libide/gui/ide-page.c
+++ b/src/libide/gui/ide-page.c
@@ -24,6 +24,7 @@
 
 #include <string.h>
 
+#include <libide-gtk.h>
 #include <libide-threading.h>
 
 #include "ide-gui-global.h"
@@ -32,13 +33,17 @@
 
 typedef struct
 {
-  GList        mru_link;
+  GList           mru_link;
 
-  const char  *menu_id;
+  const char     *menu_id;
 
-  guint        failed : 1;
-  guint        modified : 1;
-  guint        can_split : 1;
+  GtkBox         *content_box;
+  GtkOverlay     *overlay;
+  GtkProgressBar *progress_bar;
+
+  guint           failed : 1;
+  guint           modified : 1;
+  guint           can_split : 1;
 } IdePagePrivate;
 
 enum {
@@ -54,8 +59,13 @@ enum {
   N_SIGNALS
 };
 
-G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (IdePage, ide_page, PANEL_TYPE_WIDGET)
+static void buildable_iface_init (GtkBuildableIface *iface);
+
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (IdePage, ide_page, PANEL_TYPE_WIDGET,
+                                  G_ADD_PRIVATE (IdePage)
+                                  G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, buildable_iface_init))
 
+static GtkBuildableIface *parent_buildable;
 static GParamSpec *properties [N_PROPS];
 static guint signals [N_SIGNALS];
 
@@ -264,24 +274,20 @@ ide_page_class_init (IdePageClass *klass)
 
   gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BOX_LAYOUT);
   gtk_widget_class_set_css_name (widget_class, "page");
+  gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/libide-gui/ui/ide-page.ui");
+  gtk_widget_class_bind_template_child_private (widget_class, IdePage, content_box);
+  gtk_widget_class_bind_template_child_private (widget_class, IdePage, overlay);
+  gtk_widget_class_bind_template_child_private (widget_class, IdePage, progress_bar);
 }
 
 static void
 ide_page_init (IdePage *self)
 {
   IdePagePrivate *priv = ide_page_get_instance_private (self);
-  g_autoptr(GSimpleActionGroup) group = g_simple_action_group_new ();
 
-  gtk_widget_set_hexpand (GTK_WIDGET (self), TRUE);
-  gtk_widget_set_vexpand (GTK_WIDGET (self), TRUE);
-  panel_widget_set_icon_name (PANEL_WIDGET (self), "text-x-generic-symbolic");
+  gtk_widget_init_template (GTK_WIDGET (self));
 
   priv->mru_link.data = self;
-
-  /* Add an action group out of convenience to plugins that want to
-   * stash a simple action somewhere.
-   */
-  gtk_widget_insert_action_group (GTK_WIDGET (self), "view", G_ACTION_GROUP (group));
 }
 
 const char *
@@ -487,3 +493,67 @@ ide_page_get_file_or_directory (IdePage *self)
 
   return NULL;
 }
+
+static void
+ide_page_add_child (GtkBuildable *buildable,
+                    GtkBuilder   *builder,
+                    GObject      *object,
+                    const char   *name)
+{
+  IdePage *self = (IdePage *)buildable;
+  IdePagePrivate *priv = ide_page_get_instance_private (self);
+
+  g_assert (IDE_IS_PAGE (self));
+  g_assert (GTK_IS_BUILDER (builder));
+  g_assert (G_IS_OBJECT (object));
+
+  if (GTK_IS_WIDGET (object))
+    {
+      if (g_strcmp0 (name, "content") == 0)
+        {
+          gtk_box_append (priv->content_box, GTK_WIDGET (object));
+          return;
+        }
+    }
+
+  parent_buildable->add_child (buildable, builder, object, name);
+}
+
+static void
+buildable_iface_init (GtkBuildableIface *iface)
+{
+  parent_buildable = g_type_interface_peek_parent (iface);
+  iface->add_child = ide_page_add_child;
+}
+
+/**
+ * ide_page_set_progress:
+ * @self: a #IdePage
+ * @notification: (nullable): an #IdeNotification or %NULL
+ *
+ * Set interactive progress for the page.
+ *
+ * When the operation is completed, the caller shoudl call this method
+ * again and reutrn a value of %NULL for @notification.
+ */
+void
+ide_page_set_progress (IdePage         *self,
+                       IdeNotification *notification)
+{
+  IdePagePrivate *priv = ide_page_get_instance_private (self);
+
+  g_return_if_fail (IDE_IS_PAGE (self));
+  g_return_if_fail (!notification || IDE_IS_NOTIFICATION (notification));
+
+  if (notification == NULL)
+    {
+      ide_gtk_widget_hide_with_fade (GTK_WIDGET (priv->progress_bar));
+      return;
+    }
+
+  gtk_progress_bar_set_fraction (priv->progress_bar, .0);
+  gtk_widget_show (GTK_WIDGET (priv->progress_bar));
+  g_object_bind_property (notification, "progress",
+                          priv->progress_bar, "fraction",
+                          G_BINDING_SYNC_CREATE);
+}
diff --git a/src/libide/gui/ide-page.h b/src/libide/gui/ide-page.h
index 8bdafe0e6..427c32049 100644
--- a/src/libide/gui/ide-page.h
+++ b/src/libide/gui/ide-page.h
@@ -90,5 +90,8 @@ void           ide_page_report_error          (IdePage              *self,
                                                ...) G_GNUC_PRINTF (2, 3);
 IDE_AVAILABLE_IN_ALL
 GFile         *ide_page_get_file_or_directory (IdePage              *self);
+IDE_AVAILABLE_IN_ALL
+void           ide_page_set_progress          (IdePage              *self,
+                                               IdeNotification      *notification);
 
 G_END_DECLS
diff --git a/src/libide/gui/ide-page.ui b/src/libide/gui/ide-page.ui
new file mode 100644
index 000000000..7e000d28e
--- /dev/null
+++ b/src/libide/gui/ide-page.ui
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="IdePage" parent="PanelWidget">
+    <property name="hexpand">true</property>
+    <property name="vexpand">true</property>
+    <property name="icon-name">text-x-generic-symbolic</property>
+    <child>
+      <object class="GtkOverlay" id="overlay">
+        <child>
+          <object class="GtkBox" id="content_box">
+            <property name="orientation">vertical</property>
+          </object>
+        </child>
+        <child type="overlay">
+          <object class="GtkProgressBar" id="progress_bar">
+            <property name="valign">start</property>
+            <property name="hexpand">true</property>
+            <style>
+              <class name="osd"/>
+            </style>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/src/libide/gui/libide-gui.gresource.xml b/src/libide/gui/libide-gui.gresource.xml
index 808da345c..5fbaf7d5e 100644
--- a/src/libide/gui/libide-gui.gresource.xml
+++ b/src/libide/gui/libide-gui.gresource.xml
@@ -18,6 +18,7 @@
     <file preprocess="xml-stripblanks">ide-notification-view.ui</file>
     <file preprocess="xml-stripblanks">ide-notifications-button.ui</file>
     <file preprocess="xml-stripblanks">ide-omni-bar.ui</file>
+    <file preprocess="xml-stripblanks">ide-page.ui</file>
     <file preprocess="xml-stripblanks">ide-preferences-window.ui</file>
     <file preprocess="xml-stripblanks">ide-primary-workspace.ui</file>
     <file preprocess="xml-stripblanks">ide-run-button.ui</file>


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