[gtkmm] Gtk: Add LayoutManager and LayoutChild
- From: Kjell Ahlstedt <kjellahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtkmm] Gtk: Add LayoutManager and LayoutChild
- Date: Mon, 1 Apr 2019 17:08:24 +0000 (UTC)
commit 6946fb2d1550f7b2a367ca5710ab5fe60b600c71
Author: Kjell Ahlstedt <kjellahlstedt gmail com>
Date: Mon Apr 1 19:06:13 2019 +0200
Gtk: Add LayoutManager and LayoutChild
.gitignore | 4 ++
gtk/gtkmm.h | 2 +
gtk/src/filelist.am | 2 +
gtk/src/layoutchild.ccg | 19 ++++++++
gtk/src/layoutchild.hg | 68 +++++++++++++++++++++++++++++
gtk/src/layoutmanager.ccg | 74 ++++++++++++++++++++++++++++++++
gtk/src/layoutmanager.hg | 107 ++++++++++++++++++++++++++++++++++++++++++++++
gtk/src/widget.ccg | 14 ++++++
gtk/src/widget.hg | 12 ++++++
tools/m4/convert_gtk.m4 | 9 ++++
10 files changed, 311 insertions(+)
---
diff --git a/.gitignore b/.gitignore
index 2b6c8714..b4d07944 100644
--- a/.gitignore
+++ b/.gitignore
@@ -317,6 +317,10 @@ gtk/gtkmm/label.cc
gtk/gtkmm/label.h
gtk/gtkmm/layout.cc
gtk/gtkmm/layout.h
+gtk/gtkmm/layoutchild.cc
+gtk/gtkmm/layoutchild.h
+gtk/gtkmm/layoutmanager.cc
+gtk/gtkmm/layoutmanager.h
gtk/gtkmm/levelbar.cc
gtk/gtkmm/levelbar.h
gtk/gtkmm/linkbutton.cc
diff --git a/gtk/gtkmm.h b/gtk/gtkmm.h
index b39535a0..e95703dc 100644
--- a/gtk/gtkmm.h
+++ b/gtk/gtkmm.h
@@ -178,6 +178,8 @@ extern const int gtkmm_micro_version;
#include <gtkmm/calendar.h>
#include <gtkmm/label.h>
#include <gtkmm/layout.h>
+#include <gtkmm/layoutchild.h>
+#include <gtkmm/layoutmanager.h>
#include <gtkmm/levelbar.h>
#include <gtkmm/listbox.h>
#include <gtkmm/listboxrow.h>
diff --git a/gtk/src/filelist.am b/gtk/src/filelist.am
index 769c1854..e86f8a9f 100644
--- a/gtk/src/filelist.am
+++ b/gtk/src/filelist.am
@@ -105,6 +105,8 @@ gtkmm_files_any_hg = \
infobar.hg \
label.hg \
layout.hg \
+ layoutchild.hg \
+ layoutmanager.hg \
levelbar.hg \
linkbutton.hg \
listbox.hg \
diff --git a/gtk/src/layoutchild.ccg b/gtk/src/layoutchild.ccg
new file mode 100644
index 00000000..48ec443e
--- /dev/null
+++ b/gtk/src/layoutchild.ccg
@@ -0,0 +1,19 @@
+/* Copyright (C) 2019 The gtkmm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtkmm/layoutmanager.h>
+#include <gtkmm/widget.h>
+#include <gtk/gtk.h>
diff --git a/gtk/src/layoutchild.hg b/gtk/src/layoutchild.hg
new file mode 100644
index 00000000..f6a8fd4a
--- /dev/null
+++ b/gtk/src/layoutchild.hg
@@ -0,0 +1,68 @@
+/* Copyright (C) 2019 The gtkmm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glibmm/object.h>
+#include <glibmm/refptr.h>
+
+_DEFS(gtkmm,gtk)
+_PINCLUDE(glibmm/private/object_p.h)
+
+namespace Gtk
+{
+class LayoutManager;
+class Widget;
+
+/** An object containing layout properties.
+ *
+ * %Gtk:LayoutChild is the base class for objects that are meant to hold
+ * layout properties. If a Gtk::LayoutManager has per-child properties,
+ * like their packing type, or the horizontal and vertical span, or the
+ * icon name, then the layout manager should use a %Gtk::LayoutChild
+ * implementation to store those properties.
+ *
+ * A %Gtk::LayoutChild instance is only ever valid while a widget is part
+ * of a layout.
+ *
+ * @newin{3,96}
+ */
+class LayoutChild : public Glib::Object
+{
+ _CLASS_GOBJECT(LayoutChild, GtkLayoutChild, GTK_LAYOUT_CHILD, Glib::Object, GObject)
+
+protected:
+ /** There is no create() method that corresponds to this constructor,
+ * because only derived classes shall be created.
+ */
+ _CTOR_DEFAULT
+
+public:
+ // No create() because only derived classes shall be instantiated.
+
+ _WRAP_METHOD(Glib::RefPtr<LayoutManager> get_layout_manager(),
+ gtk_layout_child_get_layout_manager, refreturn)
+ _WRAP_METHOD(Glib::RefPtr<const LayoutManager> get_layout_manager() const,
+ gtk_layout_child_get_layout_manager, refreturn, constversion)
+
+ _WRAP_METHOD(Widget* get_child_widget(), gtk_layout_child_get_child_widget)
+ _WRAP_METHOD(const Widget* get_child_widget() const, gtk_layout_child_get_child_widget, constversion)
+
+ _WRAP_PROPERTY("layout-manager", Glib::RefPtr<LayoutManager>)
+ _WRAP_PROPERTY("child-widget", Widget*)
+
+ // There are no signals or vfuncs.
+};
+
+} // namespace Gtk
diff --git a/gtk/src/layoutmanager.ccg b/gtk/src/layoutmanager.ccg
new file mode 100644
index 00000000..d9c5d3aa
--- /dev/null
+++ b/gtk/src/layoutmanager.ccg
@@ -0,0 +1,74 @@
+/* Copyright (C) 2019 The gtkmm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtkmm/layoutchild.h>
+#include <gtkmm/widget.h>
+#include <gtk/gtk.h>
+
+namespace Gtk
+{
+// This vfunc callback is custom implemented because we want the output
+// arguments of the C++ vfunc to be int& (not int*), and the vfunc_callback
+// function may be called from gtk with NULL pointers.
+void LayoutManager_Class::measure_vfunc_callback(GtkLayoutManager* self,
+ GtkWidget* widget, GtkOrientation orientation, int for_size,
+ int* minimum, int* natural, int* minimum_baseline, int* natural_baseline)
+{
+ const auto obj_base = static_cast<Glib::ObjectBase*>(
+ Glib::ObjectBase::_get_current_wrapper((GObject*)self));
+
+ // Non-gtkmmproc-generated custom classes implicitly call the default
+ // Glib::ObjectBase constructor, which sets is_derived_. But gtkmmproc-
+ // generated classes can use this optimisation, which avoids the unnecessary
+ // parameter conversions if there is no possibility of the virtual function
+ // being overridden:
+ if (obj_base && obj_base->is_derived_())
+ {
+ const auto obj = dynamic_cast<CppObjectType* const>(obj_base);
+ if (obj) // This can be NULL during destruction.
+ {
+ try // Trap C++ exceptions which would normally be lost because this is a C callback.
+ {
+ // Call the virtual member method, which derived classes might override.
+ int no_minimum = 0;
+ int no_natural = 0;
+ int no_minimum_baseline = 0;
+ int no_natural_baseline = 0;
+ obj->measure_vfunc(*Glib::wrap(widget),
+ static_cast<Orientation>(orientation), for_size,
+ (minimum ? *minimum : no_minimum),
+ (natural ? *natural : no_natural),
+ (minimum_baseline ? *minimum_baseline : no_minimum_baseline),
+ (natural_baseline ? *natural_baseline : no_natural_baseline));
+ return;
+ }
+ catch (...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+ }
+ }
+
+ BaseClassType *const base = static_cast<BaseClassType*>(
+ g_type_class_peek_parent(G_OBJECT_GET_CLASS(self)) // Get the parent class of the object class (The
original underlying C class).
+ );
+
+ // Call the original underlying C function:
+ if(base && base->measure)
+ (*base->measure)(self, widget, orientation, for_size, minimum, natural, minimum_baseline,
natural_baseline);
+}
+
+} // namespace Gtk
diff --git a/gtk/src/layoutmanager.hg b/gtk/src/layoutmanager.hg
new file mode 100644
index 00000000..2d57c3cb
--- /dev/null
+++ b/gtk/src/layoutmanager.hg
@@ -0,0 +1,107 @@
+/* Copyright (C) 2019 The gtkmm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glibmm/object.h>
+#include <glibmm/refptr.h>
+#include <gtkmm/enums.h>
+
+_DEFS(gtkmm,gtk)
+_PINCLUDE(glibmm/private/object_p.h)
+
+namespace Gtk
+{
+class LayoutChild;
+class Widget;
+
+/** Base class for layout manager.
+ *
+ * Layout managers are delegate classes that handle the preferred size
+ * and the allocation of a container widget.
+ *
+ * You typically subclass %Gtk::LayoutManager if you want to implement a
+ * layout policy for the children of a widget, or if you want to determine
+ * the size of a widget depending on its contents.
+ *
+ * Each Gtk::Widget can only have one %Gtk::LayoutManager instance associated to it
+ * at any given time; it is possible, though, to replace the layout manager
+ * instance using Gtk::Widget::set_layout_manager().
+ *
+ * ## Layout properties
+ *
+ * A layout manager can expose properties for controlling the layout of
+ * each child, by creating an object type derived from Gtk::LayoutChild
+ * and installing the properties on it as normal GObject properties.
+ *
+ * Each Gtk::LayoutChild instance storing the layout properties for a
+ * specific child is created through the get_layout_child()
+ * method; a %Gtk::LayoutManager controls the creation of its Gtk::LayoutChild
+ * instances by overriding the create_layout_child_vfunc() virtual function.
+ *
+ * The Gtk::LayoutChild::property_layout_manager() and Gtk::LayoutChild::property_child_widget()
+ * properties on the newly created Gtk::LayoutChild instance are mandatory. The
+ * %Gtk::LayoutManager will cache the newly created Gtk::LayoutChild instance until
+ * the widget is removed from its parent, or the parent removes the layout manager.
+ *
+ * Each %Gtk::LayoutManager instance creating a Gtk::LayoutChild should use
+ * get_layout_child() every time it needs to query the
+ * layout properties; each Gtk::LayoutChild instance should call
+ * layout_changed() every time a property is updated, in
+ * order to queue a new size measuring and allocation.
+ *
+ * @newin{3,96}
+ */
+class LayoutManager : public Glib::Object
+{
+ _CLASS_GOBJECT(LayoutManager, GtkLayoutManager, GTK_LAYOUT_MANAGER, Glib::Object, GObject)
+
+protected:
+ /** There is no create() method that corresponds to this constructor,
+ * because only derived classes shall be created.
+ */
+ _CTOR_DEFAULT
+
+public:
+ // No create() because only derived classes shall be instantiated.
+
+ _WRAP_METHOD(void measure(Widget& widget, Orientation orientation, int for_size,
+ int& minimum, int& natural, int& minimum_baseline, int& natural_baseline) const,
+ gtk_layout_manager_measure)
+ _WRAP_METHOD(void allocate(Widget& widget, int width, int height, int baseline),
+ gtk_layout_manager_allocate)
+ _WRAP_METHOD(SizeRequestMode get_request_mode() const, gtk_layout_manager_get_request_mode)
+ _WRAP_METHOD(Widget* get_widget(), gtk_layout_manager_get_widget)
+ _WRAP_METHOD(const Widget* get_widget() const, gtk_layout_manager_get_widget, constversion)
+ _WRAP_METHOD(void layout_changed() const, gtk_layout_manager_layout_changed)
+ _WRAP_METHOD(Glib::RefPtr<LayoutChild> get_layout_child(Widget& child),
+ gtk_layout_manager_get_layout_child, refreturn)
+ _WRAP_METHOD(Glib::RefPtr<const LayoutChild> get_layout_child(Widget& child) const,
+ gtk_layout_manager_get_layout_child, refreturn, constversion)
+
+protected:
+ _WRAP_VFUNC(SizeRequestMode get_request_mode(const Widget& widget) const, get_request_mode)
+ _WRAP_VFUNC(void measure(const Widget& widget, Orientation orientation, int for_size,
+ int& minimum, int& natural, int& minimum_baseline, int& natural_baseline) const,
+ measure, custom_vfunc_callback)
+ _WRAP_VFUNC(void allocate(const Widget& widget, int width, int height, int baseline),
+ allocate)
+#m4 _CONVERSION(`Glib::RefPtr<LayoutChild>', `GtkLayoutChild*', __CONVERT_REFPTR_TO_P)
+ _WRAP_VFUNC(Glib::RefPtr<LayoutChild> create_layout_child(const Widget& widget,
+ const Widget& for_child), create_layout_child, refreturn)
+
+ // There are no signals or properties.
+};
+
+} // namespace Gtk
diff --git a/gtk/src/widget.ccg b/gtk/src/widget.ccg
index 48f20f80..b50faf3b 100644
--- a/gtk/src/widget.ccg
+++ b/gtk/src/widget.ccg
@@ -31,6 +31,7 @@
#include <gtkmm/selectiondata_private.h>
#include <gtkmm/tooltip.h>
#include <gtkmm/snapshot.h>
+#include <gtkmm/layoutmanager.h>
#include <gtk/gtk.h>
@@ -319,6 +320,19 @@ void Widget::reparent(Container& new_parent)
}
}
+void Widget::set_layout_manager(const Glib::RefPtr<LayoutManager>& layout_manager)
+{
+ // gtk_widget_set_layout_manager() does not take a ref.
+ if (layout_manager)
+ layout_manager->reference();
+ gtk_widget_set_layout_manager(gobj(), Glib::unwrap(layout_manager));
+}
+
+void Widget::unset_layout_manager()
+{
+ gtk_widget_set_layout_manager(gobj(), nullptr);
+}
+
void Widget::unset_name()
{
gtk_widget_set_name(gobj(), nullptr);
diff --git a/gtk/src/widget.hg b/gtk/src/widget.hg
index 12b81c95..969e2225 100644
--- a/gtk/src/widget.hg
+++ b/gtk/src/widget.hg
@@ -71,6 +71,7 @@ class Window;
class Root;
class Container;
class EventController;
+class LayoutManager;
class Settings;
class Snapshot;
class Tooltip;
@@ -132,6 +133,16 @@ public:
int& minimum_baseline, int& natural_baseline) const, gtk_widget_measure)
_WRAP_METHOD(void get_preferred_size(Requisition& minimum_size, Requisition& natural_size) const,
gtk_widget_get_preferred_size)
+ _WRAP_METHOD_DOCS_ONLY(gtk_widget_set_layout_manager)
+ void set_layout_manager(const Glib::RefPtr<LayoutManager>& layout_manager);
+ /** Undoes the effect of a previous call to set_layout_manager().
+ */
+ void unset_layout_manager();
+ _WRAP_METHOD(Glib::RefPtr<LayoutManager> get_layout_manager(),
+ gtk_widget_get_layout_manager, refreturn)
+ _WRAP_METHOD(Glib::RefPtr<const LayoutManager> get_layout_manager() const,
+ gtk_widget_get_layout_manager, refreturn, constversion)
+
_WRAP_METHOD(void add_accelerator(const Glib::ustring& accel_signal, const Glib::RefPtr<AccelGroup>&
accel_group,
guint accel_key, Gdk::ModifierType accel_mods, AccelFlags accel_flags),
gtk_widget_add_accelerator)
@@ -752,6 +763,7 @@ dnl
_WRAP_PROPERTY("overflow", Overflow, newin "3,96")
_WRAP_PROPERTY("scale-factor", int)
_WRAP_PROPERTY("css-name", Glib::ustring)
+ _WRAP_PROPERTY("layout-manager", Glib::RefPtr<LayoutManager>)
protected:
diff --git a/tools/m4/convert_gtk.m4 b/tools/m4/convert_gtk.m4
index 161a3a3e..369d4f93 100644
--- a/tools/m4/convert_gtk.m4
+++ b/tools/m4/convert_gtk.m4
@@ -250,6 +250,7 @@ _CONVERSION(`RadioButton&',`GtkRadioButton*',`($3).gobj()')
# Ptr (gtk+) -> Ref (Gtkmm)
_CONVERSION(`GtkWidget*', `Widget&', `*Glib::wrap($3)')
+_CONVERSION(`GtkWidget*', `const Widget&', `*Glib::wrap($3)')
# Ref (Gtkmm) -> GtkWidget* Ptr (gtk+)
define(`__FR2PD',`($`'3).Gtk::Widget::gobj()')
@@ -581,6 +582,14 @@ _CONVERSION(`GtkWidgetPath*',`WidgetPath',`Glib::wrap($3, true)')
_CONVERSION(`const GtkWidgetPath*',`WidgetPath',`Glib::wrap(const_cast<GtkWidgetPath*>($3), true)')
_CONVERSION(`const WidgetPath&',`GtkWidgetPath*',`const_cast<WidgetPath&>($3).gobj()')
+# LayoutChild, LayoutManager
+_CONVERSION(`GtkLayoutManager*',`Glib::RefPtr<LayoutManager>',`Glib::wrap($3)')
+_CONVERSION(`GtkLayoutManager*',`Glib::RefPtr<const LayoutManager>',`Glib::wrap($3)')
+_CONVERSION(`const Glib::RefPtr<LayoutManager>&',`GtkLayoutManager*',__CONVERT_REFPTR_TO_P)
+
+_CONVERSION(`GtkLayoutChild*',`Glib::RefPtr<LayoutChild>',`Glib::wrap($3)')
+_CONVERSION(`GtkLayoutChild*',`Glib::RefPtr<const LayoutChild>',`Glib::wrap($3)')
+
# Used by LockButton
_CONVERSION(`Glib::RefPtr<Gio::Permission>&',`GPermission*',__CONVERT_REFPTR_TO_P)
_CONVERSION(`const Glib::RefPtr<const
Gio::Permission>&',`GPermission*',__CONVERT_CONST_REFPTR_TO_P_SUN(Gio::Permission))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]