[gnome-builder] gui: allow changing placeholder/empty-state for frames



commit 0dd9fee7c12e831b4c5b948b1397bcea2c878091
Author: Christian Hergert <chergert redhat com>
Date:   Sat Apr 27 11:43:40 2019 -0700

    gui: allow changing placeholder/empty-state for frames

 src/libide/gui/ide-frame-empty-state.c  |  46 ++++++++++++++
 src/libide/gui/ide-frame-empty-state.h  |  37 ++++++++++++
 src/libide/gui/ide-frame-empty-state.ui | 104 ++++++++++++++++++++++++++++++++
 src/libide/gui/ide-frame.c              |  37 +++++++++++-
 src/libide/gui/ide-frame.ui             |  95 ++---------------------------
 src/libide/gui/libide-gui.gresource.xml |   1 +
 src/libide/gui/libide-gui.h             |   1 +
 src/libide/gui/meson.build              |   2 +
 8 files changed, 229 insertions(+), 94 deletions(-)
---
diff --git a/src/libide/gui/ide-frame-empty-state.c b/src/libide/gui/ide-frame-empty-state.c
new file mode 100644
index 000000000..b6dd28092
--- /dev/null
+++ b/src/libide/gui/ide-frame-empty-state.c
@@ -0,0 +1,46 @@
+/* ide-frame-empty-state.c
+ *
+ * Copyright 2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "ide-frame-empty-state"
+
+#include "config.h"
+
+#include "ide-frame-empty-state.h"
+
+struct _IdeFrameEmptyState
+{
+  GtkBin parent_instance;
+};
+
+G_DEFINE_TYPE (IdeFrameEmptyState, ide_frame_empty_state, GTK_TYPE_BIN)
+
+static void
+ide_frame_empty_state_class_init (IdeFrameEmptyStateClass *klass)
+{
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/libide-gui/ui/ide-frame-empty-state.ui");
+}
+
+static void
+ide_frame_empty_state_init (IdeFrameEmptyState *self)
+{
+  gtk_widget_init_template (GTK_WIDGET (self));
+}
diff --git a/src/libide/gui/ide-frame-empty-state.h b/src/libide/gui/ide-frame-empty-state.h
new file mode 100644
index 000000000..60e5035b2
--- /dev/null
+++ b/src/libide/gui/ide-frame-empty-state.h
@@ -0,0 +1,37 @@
+/* ide-frame-empty-state.h
+ *
+ * Copyright 2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#if !defined (IDE_GUI_INSIDE) && !defined (IDE_GUI_COMPILATION)
+# error "Only <libide-gui.h> can be included directly."
+#endif
+
+#include <gtk/gtk.h>
+#include <libide-core.h>
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_FRAME_EMPTY_STATE (ide_frame_empty_state_get_type())
+
+IDE_AVAILABLE_IN_3_34
+G_DECLARE_FINAL_TYPE (IdeFrameEmptyState, ide_frame_empty_state, IDE, FRAME_EMPTY_STATE, GtkBin)
+
+G_END_DECLS
diff --git a/src/libide/gui/ide-frame-empty-state.ui b/src/libide/gui/ide-frame-empty-state.ui
new file mode 100644
index 000000000..2df16d48a
--- /dev/null
+++ b/src/libide/gui/ide-frame-empty-state.ui
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="IdeFrameEmptyState" parent="GtkBin">
+    <child>
+      <object class="DzlBox">
+        <property name="expand">false</property>
+        <property name="halign">center</property>
+        <property name="orientation">vertical</property>
+        <property name="valign">center</property>
+        <property name="max-width-request">275</property>
+        <property name="margin">32</property>
+        <property name="spacing">6</property>
+        <property name="visible">true</property>
+        <child>
+          <object class="GtkLabel">
+            <property name="label" translatable="yes">Open a File or Terminal</property>
+            <property name="margin-bottom">6</property>
+            <property name="visible">true</property>
+            <style>
+              <class name="dim-label"/>
+            </style>
+            <attributes>
+              <attribute name="weight" value="bold"/>
+              <attribute name="scale" value="1.2"/>
+            </attributes>
+          </object>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="label" translatable="yes">Use the page switcher above or use one of the 
following:</property>
+            <property name="justify">center</property>
+            <property name="margin-bottom">18</property>
+            <property name="visible">true</property>
+            <property name="wrap">true</property>
+            <style>
+              <class name="dim-label"/>
+            </style>
+            <attributes>
+              <attribute name="scale" value=".909"/>
+            </attributes>
+          </object>
+        </child>
+        <child>
+          <object class="IdeShortcutLabel">
+            <property name="title" translatable="yes">Search</property>
+            <property name="action">win.global-search</property>
+            <property name="visible">true</property>
+              <!-- Remove after auto accel tracking -->
+            <property name="accel">Ctrl+.</property>
+          </object>
+        </child>
+        <child>
+          <object class="IdeShortcutLabel">
+            <property name="title" translatable="yes">Project sidebar</property>
+            <property name="action">editor.sidebar</property>
+            <property name="visible">true</property>
+              <!-- Remove after auto accel tracking -->
+            <property name="accel">F9</property>
+          </object>
+        </child>
+        <child>
+          <object class="IdeShortcutLabel">
+            <property name="title" translatable="yes">File chooser</property>
+            <property name="action">editor.open-file</property>
+            <property name="visible">true</property>
+              <!-- Remove after auto accel tracking -->
+            <property name="accel">Ctrl+O</property>
+          </object>
+        </child>
+        <child>
+          <object class="IdeShortcutLabel">
+            <property name="title" translatable="yes">New terminal</property>
+            <property name="action">win.new-terminal</property>
+            <property name="visible">true</property>
+              <!-- Remove after auto accel tracking -->
+            <property name="accel">Ctrl+Shift+T</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox">
+            <property name="homogeneous">true</property>
+            <property name="margin-top">18</property>
+            <property name="spacing">6</property>
+            <property name="visible">true</property>
+            <child>
+              <object class="GtkButton">
+                <property name="action-name">editor.open-file</property>
+                <property name="label" translatable="yes">Open File…</property>
+                <property name="visible">true</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkButton">
+                <property name="action-name">win.new-terminal</property>
+                <property name="label" translatable="yes">New Terminal</property>
+                <property name="visible">true</property>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/src/libide/gui/ide-frame.c b/src/libide/gui/ide-frame.c
index 5f2d1749d..67c445cca 100644
--- a/src/libide/gui/ide-frame.c
+++ b/src/libide/gui/ide-frame.c
@@ -79,7 +79,7 @@ typedef struct
   IdePage              *pan_page;
 
   /* Template references */
-  DzlBox               *empty_state;
+  GtkBox               *empty_placeholder;
   DzlEmptyState        *failed_state;
   IdeFrameHeader       *header;
   GtkStack             *stack;
@@ -107,11 +107,13 @@ enum {
   N_SIGNALS
 };
 
+static void buildable_iface_init     (GtkBuildableIface   *iface);
 static void list_model_iface_init    (GListModelInterface *iface);
 static void animation_state_complete (gpointer             data);
 
 G_DEFINE_TYPE_WITH_CODE (IdeFrame, ide_frame, GTK_TYPE_BOX,
                          G_ADD_PRIVATE (IdeFrame)
+                         G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, buildable_iface_init)
                          G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, list_model_iface_init))
 
 static GParamSpec *properties [N_PROPS];
@@ -238,7 +240,7 @@ ide_frame_notify_visible_child (IdeFrame   *self,
   else if (visible_child != NULL)
     gtk_stack_set_visible_child (priv->top_stack, GTK_WIDGET (priv->stack));
   else
-    gtk_stack_set_visible_child (priv->top_stack, GTK_WIDGET (priv->empty_state));
+    gtk_stack_set_visible_child (priv->top_stack, GTK_WIDGET (priv->empty_placeholder));
 
   /* Allow the header to update settings */
   _ide_frame_header_update (priv->header, IDE_PAGE (visible_child));
@@ -873,7 +875,7 @@ ide_frame_class_init (IdeFrameClass *klass)
 
   gtk_widget_class_set_css_name (widget_class, "ideframe");
   gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/libide-gui/ui/ide-frame.ui");
-  gtk_widget_class_bind_template_child_private (widget_class, IdeFrame, empty_state);
+  gtk_widget_class_bind_template_child_private (widget_class, IdeFrame, empty_placeholder);
   gtk_widget_class_bind_template_child_private (widget_class, IdeFrame, failed_state);
   gtk_widget_class_bind_template_child_private (widget_class, IdeFrame, header);
   gtk_widget_class_bind_template_child_private (widget_class, IdeFrame, stack);
@@ -1411,3 +1413,32 @@ ide_frame_add_with_depth (IdeFrame  *self,
                                      "position", position,
                                      NULL);
 }
+
+static void
+ide_frame_add_child (GtkBuildable *buildable,
+                     GtkBuilder   *builder,
+                     GObject      *object,
+                     const gchar  *type)
+{
+  IdeFrame *self = (IdeFrame *)buildable;
+  IdeFramePrivate *priv = ide_frame_get_instance_private (self);
+  GtkBuildableIface *parent = g_type_interface_peek_parent (GTK_BUILDABLE_GET_IFACE (buildable));
+
+  if (g_strcmp0 (type, "placeholder") == 0 && GTK_IS_WIDGET (object))
+    {
+      gtk_container_foreach (GTK_CONTAINER (priv->empty_placeholder),
+                             (GtkCallback) gtk_widget_destroy,
+                             NULL);
+      gtk_container_add (GTK_CONTAINER (priv->empty_placeholder), GTK_WIDGET (object));
+    }
+  else
+    {
+      parent->add_child (buildable, builder, object, type);
+    }
+}
+
+static void
+buildable_iface_init (GtkBuildableIface *iface)
+{
+  iface->add_child = ide_frame_add_child;
+}
diff --git a/src/libide/gui/ide-frame.ui b/src/libide/gui/ide-frame.ui
index 3dc728752..793826110 100644
--- a/src/libide/gui/ide-frame.ui
+++ b/src/libide/gui/ide-frame.ui
@@ -19,100 +19,13 @@
             <property name="interpolate-size">false</property>
             <property name="visible">true</property>
             <child>
-              <object class="DzlBox" id="empty_state">
-                <property name="expand">false</property>
-                <property name="halign">center</property>
-                <property name="orientation">vertical</property>
-                <property name="valign">center</property>
-                <property name="max-width-request">275</property>
-                <property name="margin">32</property>
-                <property name="spacing">6</property>
+              <object class="GtkBox" id="empty_placeholder">
+                <property name="expand">true</property>
                 <property name="visible">true</property>
                 <child>
-                  <object class="GtkLabel">
-                    <property name="label" translatable="yes">Open a File or Terminal</property>
-                    <property name="margin-bottom">6</property>
-                    <property name="visible">true</property>
-                    <style>
-                      <class name="dim-label"/>
-                    </style>
-                    <attributes>
-                      <attribute name="weight" value="bold"/>
-                      <attribute name="scale" value="1.2"/>
-                    </attributes>
-                  </object>
-                </child>
-                <child>
-                  <object class="GtkLabel">
-                    <property name="label" translatable="yes">Use the page switcher above or use one of the 
following:</property>
-                    <property name="justify">center</property>
-                    <property name="margin-bottom">18</property>
-                    <property name="visible">true</property>
-                    <property name="wrap">true</property>
-                    <style>
-                      <class name="dim-label"/>
-                    </style>
-                    <attributes>
-                      <attribute name="scale" value=".909"/>
-                    </attributes>
-                  </object>
-                </child>
-                <child>
-                  <object class="IdeShortcutLabel">
-                    <property name="title" translatable="yes">Search</property>
-                    <property name="action">win.global-search</property>
-                    <property name="visible">true</property>
-                    <!-- Remove after auto accel tracking -->
-                    <property name="accel">Ctrl+.</property>
-                  </object>
-                </child>
-                <child>
-                  <object class="IdeShortcutLabel">
-                    <property name="title" translatable="yes">Project sidebar</property>
-                    <property name="action">editor.sidebar</property>
-                    <property name="visible">true</property>
-                    <!-- Remove after auto accel tracking -->
-                    <property name="accel">F9</property>
-                  </object>
-                </child>
-                <child>
-                  <object class="IdeShortcutLabel">
-                    <property name="title" translatable="yes">File chooser</property>
-                    <property name="action">editor.open-file</property>
-                    <property name="visible">true</property>
-                    <!-- Remove after auto accel tracking -->
-                    <property name="accel">Ctrl+O</property>
-                  </object>
-                </child>
-                <child>
-                  <object class="IdeShortcutLabel">
-                    <property name="title" translatable="yes">New terminal</property>
-                    <property name="action">win.new-terminal</property>
-                    <property name="visible">true</property>
-                    <!-- Remove after auto accel tracking -->
-                    <property name="accel">Ctrl+Shift+T</property>
-                  </object>
-                </child>
-                <child>
-                  <object class="GtkBox">
-                    <property name="homogeneous">true</property>
-                    <property name="margin-top">18</property>
-                    <property name="spacing">6</property>
+                  <object class="IdeFrameEmptyState">
+                    <property name="expand">true</property>
                     <property name="visible">true</property>
-                    <child>
-                      <object class="GtkButton">
-                        <property name="action-name">editor.open-file</property>
-                        <property name="label" translatable="yes">Open File…</property>
-                        <property name="visible">true</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkButton">
-                        <property name="action-name">win.new-terminal</property>
-                        <property name="label" translatable="yes">New Terminal</property>
-                        <property name="visible">true</property>
-                      </object>
-                    </child>
                   </object>
                 </child>
               </object>
diff --git a/src/libide/gui/libide-gui.gresource.xml b/src/libide/gui/libide-gui.gresource.xml
index 26d5ce256..35e623849 100644
--- a/src/libide/gui/libide-gui.gresource.xml
+++ b/src/libide/gui/libide-gui.gresource.xml
@@ -7,6 +7,7 @@
     <file preprocess="xml-stripblanks">ide-environment-editor-row.ui</file>
     <file preprocess="xml-stripblanks">ide-frame-header.ui</file>
     <file preprocess="xml-stripblanks">ide-frame.ui</file>
+    <file preprocess="xml-stripblanks">ide-frame-empty-state.ui</file>
     <file preprocess="xml-stripblanks">ide-header-bar.ui</file>
     <file preprocess="xml-stripblanks">ide-notification-list-box-row.ui</file>
     <file preprocess="xml-stripblanks">ide-notification-view.ui</file>
diff --git a/src/libide/gui/libide-gui.h b/src/libide/gui/libide-gui.h
index 55d74e5c7..85afe78e7 100644
--- a/src/libide/gui/libide-gui.h
+++ b/src/libide/gui/libide-gui.h
@@ -37,6 +37,7 @@
 #include "ide-environment-editor.h"
 #include "ide-frame.h"
 #include "ide-frame-addin.h"
+#include "ide-frame-empty-state.h"
 #include "ide-frame-header.h"
 #include "ide-header-bar.h"
 #include "ide-fancy-tree-view.h"
diff --git a/src/libide/gui/meson.build b/src/libide/gui/meson.build
index bc80da2c6..b174408ae 100644
--- a/src/libide/gui/meson.build
+++ b/src/libide/gui/meson.build
@@ -17,6 +17,7 @@ libide_gui_public_headers = [
   'ide-environment-editor.h',
   'ide-fancy-tree-view.h',
   'ide-frame-addin.h',
+  'ide-frame-empty-state.h',
   'ide-frame-header.h',
   'ide-frame.h',
   'ide-grid-column.h',
@@ -119,6 +120,7 @@ libide_gui_public_sources = [
   'ide-environment-editor.c',
   'ide-fancy-tree-view.c',
   'ide-frame-addin.c',
+  'ide-frame-empty-state.c',
   'ide-frame-header.c',
   'ide-frame.c',
   'ide-grid-column.c',


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