summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmmanuele Bassi <ebassi@gnome.org>2019-03-04 15:03:34 +0000
committerEmmanuele Bassi <ebassi@gnome.org>2019-03-26 00:11:27 +0000
commitd6dfa41f1079db2bfb111a551ffab4f86c3ea816 (patch)
treeba71c5a0b806f143f8b4eab0957466ea1d85a3db
parent8cf06befc030dfe70f63b0c9e103f25f213f9dd3 (diff)
downloadgtk+-d6dfa41f1079db2bfb111a551ffab4f86c3ea816.tar.gz
Add GtkBinLayout
Like GtkBin, but lets you lay out multiple children instead of just one.
-rw-r--r--gtk/gtk.h1
-rw-r--r--gtk/gtkbinlayout.c115
-rw-r--r--gtk/gtkbinlayout.h21
-rw-r--r--gtk/meson.build2
4 files changed, 139 insertions, 0 deletions
diff --git a/gtk/gtk.h b/gtk/gtk.h
index e7118344ab..27a29e951f 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -45,6 +45,7 @@
#include <gtk/gtkaspectframe.h>
#include <gtk/gtkassistant.h>
#include <gtk/gtkbin.h>
+#include <gtk/gtkbinlayout.h>
#include <gtk/gtkbindings.h>
#include <gtk/gtkborder.h>
#include <gtk/gtkboxlayout.h>
diff --git a/gtk/gtkbinlayout.c b/gtk/gtkbinlayout.c
new file mode 100644
index 0000000000..d5cc211e7e
--- /dev/null
+++ b/gtk/gtkbinlayout.c
@@ -0,0 +1,115 @@
+/* gtkbinlayout.c: Layout manager for bin-like widgets
+ *
+ * Copyright 2019 GNOME Foundation
+ *
+ * SPDX-License-Identifier: LGPL 2.1+
+ */
+
+/**
+ * SECTION:gtkbinlayout
+ * @Title: GtkBinLayout
+ * @Short_description: A layout manager for bin-like widgets
+ * @Include: gtk/gtk.h
+ *
+ * GtkBinLayout is a #GtkLayoutManager subclass useful for create "bins" of
+ * widgets. GtkBinLayout will stack each child of a widget on top of each
+ * other, using the #GtkWidget:hexpand, #GtkWidget:vexpand, #GtkWidget:halign,
+ * and #GtkWidget:valign properties of each child to determine where they
+ * should be positioned.
+ */
+
+#include "config.h"
+
+#include "gtkbinlayout.h"
+
+#include "gtkwidgetprivate.h"
+
+struct _GtkBinLayout
+{
+ GtkLayoutManager parent_instance;
+};
+
+G_DEFINE_TYPE (GtkBinLayout, gtk_bin_layout, GTK_TYPE_LAYOUT_MANAGER)
+
+static void
+gtk_bin_layout_measure (GtkLayoutManager *layout_manager,
+ GtkWidget *widget,
+ GtkOrientation orientation,
+ int for_size,
+ int *minimum,
+ int *natural,
+ int *minimum_baseline,
+ int *natural_baseline)
+{
+ GtkWidget *child;
+
+ child = _gtk_widget_get_first_child (widget);
+ while (child != NULL)
+ {
+ GtkWidget *next = _gtk_widget_get_next_sibling (child);
+
+ if (gtk_widget_get_visible (child))
+ {
+ int child_min = 0;
+ int child_nat = 0;
+
+ gtk_widget_measure (child, orientation, for_size, &child_min, &child_nat, NULL, NULL);
+
+ *minimum = MAX (*minimum, child_min);
+ *natural = MAX (*natural, child_nat);
+ }
+
+ child = next;
+ }
+}
+
+static void
+gtk_bin_layout_allocate (GtkLayoutManager *layout_manager,
+ GtkWidget *widget,
+ int width,
+ int height,
+ int baseline)
+{
+ GtkWidget *child;
+
+ child = _gtk_widget_get_first_child (widget);
+ while (child != NULL)
+ {
+ GtkWidget *next = _gtk_widget_get_next_sibling (child);
+
+ if (child && gtk_widget_get_visible (child))
+ gtk_widget_size_allocate (child,
+ &(GtkAllocation) {
+ 0, 0,
+ width, height
+ }, baseline);
+
+ child = next;
+ }
+}
+static void
+gtk_bin_layout_class_init (GtkBinLayoutClass *klass)
+{
+ GtkLayoutManagerClass *layout_manager_class = GTK_LAYOUT_MANAGER_CLASS (klass);
+
+ layout_manager_class->measure = gtk_bin_layout_measure;
+ layout_manager_class->allocate = gtk_bin_layout_allocate;
+}
+
+static void
+gtk_bin_layout_init (GtkBinLayout *self)
+{
+}
+
+/**
+ * gtk_bin_layout_new:
+ *
+ * Creates a new #GtkBinLayout instance.
+ *
+ * Returns: the newly created #GtkBinLayout
+ */
+GtkLayoutManager *
+gtk_bin_layout_new (void)
+{
+ return g_object_new (GTK_TYPE_BIN_LAYOUT, NULL);
+}
diff --git a/gtk/gtkbinlayout.h b/gtk/gtkbinlayout.h
new file mode 100644
index 0000000000..b19581f2eb
--- /dev/null
+++ b/gtk/gtkbinlayout.h
@@ -0,0 +1,21 @@
+/* gtkbinlayout.h: Layout manager for bin-like widgets
+ *
+ * Copyright 2019 GNOME Foundation
+ *
+ * SPDX-License-Identifier: LGPL 2.1+
+ */
+#pragma once
+
+#include <gtk/gtklayoutmanager.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_BIN_LAYOUT (gtk_bin_layout_get_type ())
+
+GDK_AVAILABLE_IN_ALL
+G_DECLARE_FINAL_TYPE (GtkBinLayout, gtk_bin_layout, GTK, BIN_LAYOUT, GtkLayoutManager)
+
+GDK_AVAILABLE_IN_ALL
+GtkLayoutManager * gtk_bin_layout_new (void);
+
+G_END_DECLS
diff --git a/gtk/meson.build b/gtk/meson.build
index fbc221a0c3..b6a5457876 100644
--- a/gtk/meson.build
+++ b/gtk/meson.build
@@ -164,6 +164,7 @@ gtk_public_sources = files([
'gtkaspectframe.c',
'gtkassistant.c',
'gtkbin.c',
+ 'gtkbinlayout.c',
'gtkbindings.c',
'gtkborder.c',
'gtkboxlayout.c',
@@ -420,6 +421,7 @@ gtk_public_headers = files([
'gtkaspectframe.h',
'gtkassistant.h',
'gtkbin.h',
+ 'gtkbinlayout.h',
'gtkbindings.h',
'gtkborder.h',
'gtkbox.h',