summaryrefslogtreecommitdiff
path: root/gtk/gtkinfobar.c
diff options
context:
space:
mode:
authorTimm Bäder <mail@baedert.org>2019-08-28 08:13:18 +0200
committerTimm Bäder <mail@baedert.org>2019-09-09 17:36:25 +0200
commitd223752c55be49c53a4663a5510aaf338395dbaa (patch)
tree05dc9ab0f7370de2290dec55572bd349f7c8e81e /gtk/gtkinfobar.c
parent74208e9e0c8a4df42d88779c8a05b9313f119df5 (diff)
downloadgtk+-d223752c55be49c53a4663a5510aaf338395dbaa.tar.gz
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.
Diffstat (limited to 'gtk/gtkinfobar.c')
-rw-r--r--gtk/gtkinfobar.c105
1 files changed, 91 insertions, 14 deletions
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))
@@ -321,17 +329,54 @@ gtk_info_bar_close (GtkInfoBar *info_bar)
}
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