[gtk/wip/layout-manager: 133/136] Add GtkBinLayout



commit 40fd1ad1a1b1dbb1605ced6779cb2269c646ea40
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Mon Mar 4 15:03:34 2019 +0000

    Add GtkBinLayout
    
    Like GtkBin, but lets you lay out multiple children instead of just one.

 gtk/gtk.h          |   1 +
 gtk/gtkbinlayout.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 gtk/gtkbinlayout.h |  21 ++++++++++
 gtk/meson.build    |   2 +
 4 files changed, 139 insertions(+)
---
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 5c79107b27..43f38c0e99 100644
--- a/gtk/meson.build
+++ b/gtk/meson.build
@@ -169,6 +169,7 @@ gtk_public_sources = files([
   'gtkaspectframe.c',
   'gtkassistant.c',
   'gtkbin.c',
+  'gtkbinlayout.c',
   'gtkbindings.c',
   'gtkborder.c',
   'gtkboxlayout.c',
@@ -425,6 +426,7 @@ gtk_public_headers = files([
   'gtkaspectframe.h',
   'gtkassistant.h',
   'gtkbin.h',
+  'gtkbinlayout.h',
   'gtkbindings.h',
   'gtkborder.h',
   'gtkbox.h',


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