[gtk] infobar: Inherit from GtkContainer



commit d223752c55be49c53a4663a5510aaf338395dbaa
Author: Timm Bäder <mail baedert org>
Date:   Wed Aug 28 08:13:18 2019 +0200

    infobar: Inherit from GtkContainer
    
    infobars being a GtkBox doesn't make sense.
    Also implement infobars without exposing internal children.
    
    Closes #1957 because it adds the bottom border.

 demos/widget-factory/widget-factory.ui |   2 +-
 gtk/gtkinfobar.c                       | 105 ++++++++++++++++++++++++++++-----
 gtk/gtkinfobar.h                       |   2 +-
 gtk/theme/Adwaita/_common.scss         |   7 +++
 gtk/ui/gtkinfobar.ui                   |  41 -------------
 testsuite/gtk/builder.c                |  26 +++-----
 6 files changed, 108 insertions(+), 75 deletions(-)
---
diff --git a/demos/widget-factory/widget-factory.ui b/demos/widget-factory/widget-factory.ui
index 867c074806..91f1c4b211 100644
--- a/demos/widget-factory/widget-factory.ui
+++ b/demos/widget-factory/widget-factory.ui
@@ -2114,7 +2114,7 @@ microphone-sensitivity-medium-symbolic</property>
                                       <object class="GtkInfoBar" id="infobar">
                                         <property name="visible">0</property>
                                         <property name="show-close-button">1</property>
-                                        <child internal-child="content_area">
+                                        <child>
                                           <object class="GtkBox">
                                             <child>
                                               <object class="GtkLabel">
diff --git a/gtk/gtkinfobar.c b/gtk/gtkinfobar.c
index a76692a89c..2b6747c752 100644
--- a/gtk/gtkinfobar.c
+++ b/gtk/gtkinfobar.c
@@ -48,6 +48,7 @@
 #include "gtkstylecontext.h"
 #include "gtktypebuiltins.h"
 #include "gtkwidgetprivate.h"
+#include "gtkbinlayout.h"
 
 /**
  * SECTION:gtkinfobar
@@ -124,6 +125,8 @@
  * GtkInfoBar has a single CSS node with name infobar. The node may get
  * one of the style classes .info, .warning, .error or .question, depending
  * on the message type.
+ * If the info bar shows a close button, that button will have the .close
+ * style class applied.
  */
 
 enum
@@ -139,12 +142,12 @@ typedef struct _GtkInfoBarClass GtkInfoBarClass;
 
 struct _GtkInfoBar
 {
-  GtkBox parent_instance;
+  GtkContainer parent_instance;
 };
 
 struct _GtkInfoBarClass
 {
-  GtkBoxClass parent_class;
+  GtkContainerClass parent_class;
 
   void (* response) (GtkInfoBar *info_bar, gint response_id);
   void (* close)    (GtkInfoBar *info_bar);
@@ -198,9 +201,14 @@ static void      gtk_info_bar_buildable_custom_finished    (GtkBuildable  *build
                                                             GObject       *child,
                                                             const gchar   *tagname,
                                                             gpointer       user_data);
+static void      gtk_info_bar_buildable_add_child          (GtkBuildable *buildable,
+                                                            GtkBuilder   *builder,
+                                                            GObject      *child,
+                                                            const char   *type);
 
 
-G_DEFINE_TYPE_WITH_CODE (GtkInfoBar, gtk_info_bar, GTK_TYPE_BOX,
+
+G_DEFINE_TYPE_WITH_CODE (GtkInfoBar, gtk_info_bar, GTK_TYPE_CONTAINER,
                          G_ADD_PRIVATE (GtkInfoBar)
                          G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
                                                 gtk_info_bar_buildable_interface_init))
@@ -320,18 +328,55 @@ gtk_info_bar_close (GtkInfoBar *info_bar)
                          GTK_RESPONSE_CANCEL);
 }
 
+static void
+gtk_info_bar_add (GtkContainer *container,
+                  GtkWidget    *child)
+{
+  GtkInfoBar *self = GTK_INFO_BAR (container);
+  GtkInfoBarPrivate *priv = gtk_info_bar_get_instance_private (self);
+
+  gtk_container_add (GTK_CONTAINER (priv->content_area), child);
+}
+
+static void
+gtk_info_bar_remove (GtkContainer *container,
+                     GtkWidget    *child)
+{
+  GtkInfoBar *self = GTK_INFO_BAR (container);
+  GtkInfoBarPrivate *priv = gtk_info_bar_get_instance_private (self);
+
+  gtk_container_remove (GTK_CONTAINER (priv->content_area), child);
+}
+
+static void
+gtk_info_bar_dispose (GObject *object)
+{
+  GtkInfoBar *self = GTK_INFO_BAR (object);
+  GtkInfoBarPrivate *priv = gtk_info_bar_get_instance_private (self);
+
+  g_clear_pointer (&priv->revealer, gtk_widget_unparent);
+
+  G_OBJECT_CLASS (gtk_info_bar_parent_class)->dispose (object);
+}
+
 static void
 gtk_info_bar_class_init (GtkInfoBarClass *klass)
 {
-  GtkWidgetClass *widget_class;
   GObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+  GtkContainerClass *container_class;
   GtkBindingSet *binding_set;
 
-  widget_class = GTK_WIDGET_CLASS (klass);
   object_class = G_OBJECT_CLASS (klass);
+  widget_class = GTK_WIDGET_CLASS (klass);
+  container_class = GTK_CONTAINER_CLASS (klass);
 
   object_class->get_property = gtk_info_bar_get_property;
   object_class->set_property = gtk_info_bar_set_property;
+  object_class->dispose = gtk_info_bar_dispose;
+
+  container_class->add = gtk_info_bar_add;
+  container_class->remove = gtk_info_bar_remove;
 
   klass->close = gtk_info_bar_close;
 
@@ -411,15 +456,8 @@ gtk_info_bar_class_init (GtkInfoBarClass *klass)
 
   gtk_binding_entry_add_signal (binding_set, GDK_KEY_Escape, 0, "close", 0);
 
-  /* Bind class to template
-   */
-  gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/ui/gtkinfobar.ui");
-  gtk_widget_class_bind_template_child_internal_private (widget_class, GtkInfoBar, content_area);
-  gtk_widget_class_bind_template_child_internal_private (widget_class, GtkInfoBar, action_area);
-  gtk_widget_class_bind_template_child_private (widget_class, GtkInfoBar, close_button);
-  gtk_widget_class_bind_template_child_private (widget_class, GtkInfoBar, revealer);
-
   gtk_widget_class_set_css_name (widget_class, I_("infobar"));
+  gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
 }
 
 static void
@@ -435,14 +473,34 @@ gtk_info_bar_init (GtkInfoBar *info_bar)
 {
   GtkInfoBarPrivate *priv = gtk_info_bar_get_instance_private (info_bar);
   GtkWidget *widget = GTK_WIDGET (info_bar);
+  GtkWidget *main_box;
 
   /* message-type is a CONSTRUCT property, so we init to a value
    * different from its default to trigger its property setter
    * during construction */
   priv->message_type = GTK_MESSAGE_OTHER;
 
-  gtk_widget_init_template (widget);
+  priv->revealer = gtk_revealer_new ();
+  gtk_revealer_set_reveal_child (GTK_REVEALER (priv->revealer), TRUE);
+  gtk_widget_set_parent (priv->revealer, widget);
+
+  main_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+  gtk_container_add (GTK_CONTAINER (priv->revealer), main_box);
+
+  priv->content_area = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+  gtk_widget_set_hexpand (priv->content_area, TRUE);
+  gtk_container_add (GTK_CONTAINER (main_box), priv->content_area);
+
+  priv->action_area = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+  gtk_widget_set_halign (priv->action_area, GTK_ALIGN_END);
+  gtk_widget_set_valign (priv->action_area, GTK_ALIGN_CENTER);
+  gtk_container_add (GTK_CONTAINER (main_box), priv->action_area);
 
+  priv->close_button = gtk_button_new_from_icon_name ("window-close-symbolic");
+  gtk_widget_hide (priv->close_button);
+  gtk_widget_set_valign (priv->close_button, GTK_ALIGN_CENTER);
+  gtk_style_context_add_class (gtk_widget_get_style_context (priv->close_button), "close");
+  gtk_container_add (GTK_CONTAINER (main_box), priv->close_button);
   g_signal_connect (priv->close_button, "clicked",
                     G_CALLBACK (close_button_clicked_cb), info_bar);
 }
@@ -453,6 +511,8 @@ static void
 gtk_info_bar_buildable_interface_init (GtkBuildableIface *iface)
 {
   parent_buildable_iface = g_type_interface_peek_parent (iface);
+
+  iface->add_child = gtk_info_bar_buildable_add_child;
   iface->custom_tag_start = gtk_info_bar_buildable_custom_tag_start;
   iface->custom_finished = gtk_info_bar_buildable_custom_finished;
 }
@@ -996,6 +1056,23 @@ gtk_info_bar_buildable_custom_finished (GtkBuildable *buildable,
   g_slice_free (SubParserData, data);
 }
 
+static void
+gtk_info_bar_buildable_add_child (GtkBuildable *buildable,
+                                  GtkBuilder   *builder,
+                                  GObject      *child,
+                                  const char   *type)
+{
+  GtkInfoBar *info_bar = GTK_INFO_BAR (buildable);
+  GtkInfoBarPrivate *priv = gtk_info_bar_get_instance_private (info_bar);
+
+  if (!type)
+    gtk_container_add (GTK_CONTAINER (priv->content_area), GTK_WIDGET (child));
+  else if (g_strcmp0 (type, "action") == 0)
+    gtk_container_add (GTK_CONTAINER (priv->action_area), GTK_WIDGET (child));
+  else
+    parent_buildable_iface->add_child (buildable, builder, child, type);
+}
+
 /**
  * gtk_info_bar_set_message_type:
  * @info_bar: a #GtkInfoBar
diff --git a/gtk/gtkinfobar.h b/gtk/gtkinfobar.h
index 2236176c3a..873d4e5baf 100644
--- a/gtk/gtkinfobar.h
+++ b/gtk/gtkinfobar.h
@@ -33,7 +33,7 @@
 #error "Only <gtk/gtk.h> can be included directly."
 #endif
 
-#include <gtk/gtkbox.h>
+#include <gtk/gtkwidget.h>
 #include <gtk/gtkenums.h>
 
 G_BEGIN_DECLS
diff --git a/gtk/theme/Adwaita/_common.scss b/gtk/theme/Adwaita/_common.scss
index 8bc9f71c91..6446bf8636 100644
--- a/gtk/theme/Adwaita/_common.scss
+++ b/gtk/theme/Adwaita/_common.scss
@@ -4210,6 +4210,13 @@ infobar {
 
     &:backdrop { text-shadow: none; }
 
+    > revealer > box {
+      padding-top: 8px; padding-bottom: 8px;
+      border-bottom: 1px solid lighten($borders_color, 5%);
+      border-spacing: 12px;
+    }
+    > revealer { padding-left: 8px; padding-right: 8px; }
+
     button {
       // FIXME: extend selection mode buttons
       @include button(normal, $bg_color, $fg_color, none);
diff --git a/testsuite/gtk/builder.c b/testsuite/gtk/builder.c
index 31e6915da4..89636bc3bb 100644
--- a/testsuite/gtk/builder.c
+++ b/testsuite/gtk/builder.c
@@ -2171,7 +2171,7 @@ test_message_area (void)
   const gchar buffer[] =
     "<interface>"
     "  <object class=\"GtkInfoBar\" id=\"infobar1\">"
-    "    <child internal-child=\"content_area\">"
+    "    <child>"
     "      <object class=\"GtkBox\" id=\"contentarea1\">"
     "        <property name=\"orientation\">horizontal</property>"
     "        <child>"
@@ -2181,14 +2181,9 @@ test_message_area (void)
     "        </child>"
     "      </object>"
     "    </child>"
-    "    <child internal-child=\"action_area\">"
-    "      <object class=\"GtkBox\" id=\"actionarea1\">"
-    "       <property name=\"orientation\">vertical</property>"
-    "        <child>"
-    "          <object class=\"GtkButton\" id=\"button_ok\">"
-    "            <property name=\"label\">gtk-ok</property>"
-    "          </object>"
-    "        </child>"
+    "    <child type=\"action\">"
+    "      <object class=\"GtkButton\" id=\"button_ok\">"
+    "        <property name=\"label\">gtk-ok</property>"
     "      </object>"
     "    </child>"
     "    <action-widgets>"
@@ -2389,7 +2384,7 @@ test_no_ids (void)
   const gchar buffer[] =
     "<interface>"
     "  <object class=\"GtkInfoBar\">"
-    "    <child internal-child=\"content_area\">"
+    "    <child>"
     "      <object class=\"GtkBox\">"
     "        <property name=\"orientation\">horizontal</property>"
     "        <child>"
@@ -2399,14 +2394,9 @@ test_no_ids (void)
     "        </child>"
     "      </object>"
     "    </child>"
-    "    <child internal-child=\"action_area\">"
-    "      <object class=\"GtkBox\">"
-    "       <property name=\"orientation\">vertical</property>"
-    "        <child>"
-    "          <object class=\"GtkButton\" id=\"button_ok\">"
-    "            <property name=\"label\">gtk-ok</property>"
-    "          </object>"
-    "        </child>"
+    "    <child type=\"action\">"
+    "      <object class=\"GtkButton\" id=\"button_ok\">"
+    "        <property name=\"label\">gtk-ok</property>"
     "      </object>"
     "    </child>"
     "    <action-widgets>"


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