[gtk/wip/otte/canvas: 1/2] canvas: Use a signal for compute-bounds
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/canvas: 1/2] canvas: Use a signal for compute-bounds
- Date: Fri, 8 Jul 2022 15:34:25 +0000 (UTC)
commit bcd04595ddcbfc9cf77fcd6354201d14255228b4
Author: Benjamin Otte <otte redhat com>
Date: Fri Jul 8 17:31:38 2022 +0200
canvas: Use a signal for compute-bounds
Profiling indicates that this is about 30% slower for this chunk of
code, but considering that it bumped time taken in the Puzzle demo (with
40.000 pieces) from 18% to 22%, it doesn't seem too relevant.
The Puzzle demo does nothing but placing items and drawing them after
all.
demos/gtk-demo/canvas_intro.c | 4 +-
demos/gtk-demo/canvas_planarity.c | 4 +-
demos/gtk-demo/canvas_puzzle.c | 5 +--
gtk/gtkcanvasitem.c | 92 ++++++++++++++++++++-------------------
gtk/gtkcanvasitem.h | 8 ----
5 files changed, 51 insertions(+), 62 deletions(-)
---
diff --git a/demos/gtk-demo/canvas_intro.c b/demos/gtk-demo/canvas_intro.c
index 4bf99fb3ec..0bc7f3cac6 100644
--- a/demos/gtk-demo/canvas_intro.c
+++ b/demos/gtk-demo/canvas_intro.c
@@ -52,9 +52,7 @@ bind_item (GtkListItemFactory *factory,
gtk_canvas_item_set_widget (ci, gtk_canvas_item_get_item (ci));
/* Set a function to compute the position */
- gtk_canvas_item_set_compute_bounds (ci,
- center_item,
- NULL, NULL);
+ g_signal_connect (ci, "compute-bounds", G_CALLBACK (center_item), NULL);
}
GtkWidget *
diff --git a/demos/gtk-demo/canvas_planarity.c b/demos/gtk-demo/canvas_planarity.c
index f10c84fa34..99340bc80f 100644
--- a/demos/gtk-demo/canvas_planarity.c
+++ b/demos/gtk-demo/canvas_planarity.c
@@ -242,12 +242,12 @@ bind_item (GtkListItemFactory *factory,
gtk_widget_add_controller (widget, GTK_EVENT_CONTROLLER (gesture));
gtk_canvas_item_set_widget (ci, widget);
- gtk_canvas_item_set_compute_bounds (ci, set_vertex_bounds, NULL, NULL);
+ g_signal_connect (ci, "compute-bounds", G_CALLBACK (set_vertex_bounds), NULL);
}
else if (PLANARITY_IS_EDGE (item))
{
gtk_canvas_item_set_widget (ci, gtk_diagonal_line_new ());
- gtk_canvas_item_set_compute_bounds (ci, set_edge_bounds, NULL, NULL);
+ g_signal_connect (ci, "compute-bounds", G_CALLBACK (set_edge_bounds), NULL);
}
}
diff --git a/demos/gtk-demo/canvas_puzzle.c b/demos/gtk-demo/canvas_puzzle.c
index 4fe20c3327..13222d5a35 100644
--- a/demos/gtk-demo/canvas_puzzle.c
+++ b/demos/gtk-demo/canvas_puzzle.c
@@ -43,7 +43,6 @@ move_item (GtkGestureDrag *gesture,
origin->vertical += y / gtk_widget_get_height (GTK_WIDGET (canvas));
origin->horizontal = CLAMP (origin->horizontal, 0, 1);
origin->vertical = CLAMP (origin->vertical, 0, 1);
- g_print ("%g %g\n", origin->horizontal, origin->vertical);
gtk_canvas_item_invalidate_bounds (ci);
}
@@ -70,9 +69,7 @@ bind_item (GtkListItemFactory *factory,
origin->vertical = g_random_double ();
g_object_set_data_full (G_OBJECT (ci), "position", origin, g_free);
- gtk_canvas_item_set_compute_bounds (ci,
- set_position_from_origin,
- NULL, NULL);
+ g_signal_connect (ci, "compute-bounds", G_CALLBACK (set_position_from_origin), NULL);
}
static GListModel *
diff --git a/gtk/gtkcanvasitem.c b/gtk/gtkcanvasitem.c
index e19c9017e1..38ff9549a1 100644
--- a/gtk/gtkcanvasitem.c
+++ b/gtk/gtkcanvasitem.c
@@ -25,6 +25,8 @@
#include "gtkcanvasbox.h"
#include "gtkintl.h"
#include "gtklistitemfactoryprivate.h"
+#include "gtkmarshalers.h"
+#include "gtkprivate.h"
#include "gtkwidget.h"
/**
@@ -41,9 +43,6 @@ struct _GtkCanvasItem
GtkCanvas *canvas;
gpointer item;
GtkWidget *widget;
- GtkCanvasItemComputeBoundsFunc compute_bounds_func;
- gpointer user_data;
- GDestroyNotify user_destroy;
GtkCanvasBox bounds;
GtkCanvasBox allocation;
@@ -61,9 +60,15 @@ enum
N_PROPS
};
+enum {
+ COMPUTE_BOUNDS,
+ LAST_SIGNAL
+};
+
G_DEFINE_FINAL_TYPE (GtkCanvasItem, gtk_canvas_item, G_TYPE_OBJECT)
static GParamSpec *properties[N_PROPS] = { NULL, };
+static guint signals[LAST_SIGNAL] = { 0 };
static void
gtk_canvas_item_dispose (GObject *object)
@@ -76,11 +81,6 @@ gtk_canvas_item_dispose (GObject *object)
g_assert (self->item == NULL);
g_assert (self->widget == NULL);
- if (self->user_destroy)
- self->user_destroy (self->user_data);
- self->user_destroy = NULL;
- self->user_data = NULL;
-
G_OBJECT_CLASS (gtk_canvas_item_parent_class)->dispose (object);
}
@@ -172,6 +172,41 @@ gtk_canvas_item_class_init (GtkCanvasItemClass *klass)
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
+
+ /**
+ * GtkCanvasItem::compute-bounds
+ * @self: the `GtkCanvasItem`
+ * @bounds: (type Gtk.CanvasBox) (out caller-allocates): return
+ * location for the bounds
+ *
+ * Emitted to determine the bounds for the widget of this canvasitem
+ * during a size allocation cycle.
+ *
+ * A handler for this signal should fill @bounds with
+ * the desired box to place the widget in.
+ *
+ * If the size depends on other items and cannot be computed yet,
+ * handlers should return %FALSE and the signal will then be emitted
+ * again once more items have been allocated.
+ *
+ * Because of that signal handlers are expected to be pure - not set
+ * any properties or have other side effects - and idempotent -
+ * return the same result if called multiple times in order.
+ *
+ * returns: %TRUE if @bounds was set successfully
+ */
+ signals[COMPUTE_BOUNDS] =
+ g_signal_new (I_("compute-bounds"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ _gtk_boolean_handled_accumulator, NULL,
+ _gtk_marshal_BOOLEAN__BOXED,
+ G_TYPE_BOOLEAN, 1,
+ GTK_TYPE_CANVAS_BOX | G_SIGNAL_TYPE_STATIC_SCOPE);
+ g_signal_set_va_marshaller (signals[COMPUTE_BOUNDS],
+ G_TYPE_FROM_CLASS (gobject_class),
+ _gtk_marshal_BOOLEAN__BOXEDv);
}
static void
@@ -206,15 +241,14 @@ gboolean
gtk_canvas_item_allocate (GtkCanvasItem *self,
gboolean force)
{
+ gboolean result;
int w, h;
g_assert (!self->has_allocation);
- if (!self->compute_bounds_func)
- {
- gtk_canvas_box_init (&self->bounds, 0, 0, 0, 0, 0.5, 0.5);
- }
- else if (!self->compute_bounds_func (self, &self->bounds, self->user_data))
+ g_signal_emit (self, signals[COMPUTE_BOUNDS], 0, &self->bounds, &result);
+
+ if (!result)
{
if (!force)
return FALSE;
@@ -328,38 +362,6 @@ gtk_canvas_item_get_item (GtkCanvasItem *self)
return self->item;
}
-/**
- * gtk_canvas_item_set_compute_bounds:
- * @self: a `GtkCanvasItem`
- * @compute_bounds_func: the function to compute bounds
- * @user_data: (nullable): user data to pass to @compute_bounds_func
- * @user_destroy: destroy notify for @user_data
- *
- * Sets the function to call to compute bounds during allocation.
- *
- * This function may be called multiple times if it returned %FALSE
- * previously.
- *
- * Because of that the function is expected to be pure - not set
- * any properties or have other side effects - and idempotent -
- * return the same result if called multiple times in order.
- */
-void
-gtk_canvas_item_set_compute_bounds (GtkCanvasItem *self,
- GtkCanvasItemComputeBoundsFunc compute_bounds_func,
- gpointer user_data,
- GDestroyNotify user_destroy)
-{
- g_return_if_fail (GTK_IS_CANVAS_ITEM (self));
-
- if (self->user_destroy)
- self->user_destroy (self->user_data);
-
- self->compute_bounds_func = compute_bounds_func;
- self->user_data = user_data;
- self->user_destroy = user_destroy;
-}
-
void
gtk_canvas_item_invalidate_bounds (GtkCanvasItem *self)
{
diff --git a/gtk/gtkcanvasitem.h b/gtk/gtkcanvasitem.h
index 488656aa2f..9db1d0bf94 100644
--- a/gtk/gtkcanvasitem.h
+++ b/gtk/gtkcanvasitem.h
@@ -35,9 +35,6 @@ G_BEGIN_DECLS
GDK_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (GtkCanvasItem, gtk_canvas_item, GTK, CANVAS_ITEM, GObject)
-typedef gboolean (* GtkCanvasItemComputeBoundsFunc) (GtkCanvasItem *ci,
- GtkCanvasBox *out_box,
- gpointer user_data);
GDK_AVAILABLE_IN_ALL
GtkCanvas * gtk_canvas_item_get_canvas (GtkCanvasItem *self);
GDK_AVAILABLE_IN_ALL
@@ -49,11 +46,6 @@ void gtk_canvas_item_set_widget (GtkCanvasItem
GDK_AVAILABLE_IN_ALL
GtkWidget * gtk_canvas_item_get_widget (GtkCanvasItem *self);
-GDK_AVAILABLE_IN_ALL
-void gtk_canvas_item_set_compute_bounds (GtkCanvasItem *self,
- GtkCanvasItemComputeBoundsFunc
compute_bounds_func,
- gpointer user_data,
- GDestroyNotify user_destroy);
GDK_AVAILABLE_IN_ALL
void gtk_canvas_item_invalidate_bounds (GtkCanvasItem *self);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]