diff options
author | Benjamin Otte <otte@redhat.com> | 2022-07-08 07:24:42 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2022-07-08 07:29:09 +0200 |
commit | ad2f4a27be8c205c0e5033a8170df7af248bd9d2 (patch) | |
tree | fe9cc9fba2c03701606a2b34b5b8e86d29a36a5e | |
parent | fd4a717ddae5cd47c029d51dc413bad034f62f1e (diff) | |
download | gtk+-ad2f4a27be8c205c0e5033a8170df7af248bd9d2.tar.gz |
canvas: Completely rework bounds computation
Instead of using a descriptive language to describe how to compute the
bounds, just set a vfunc and let the application provide a function.
That saves a lot of code - but makes the canvas rely on user code.
-rw-r--r-- | demos/gtk-demo/canvas_intro.c | 58 | ||||
-rw-r--r-- | demos/gtk-demo/canvas_planarity.c | 127 | ||||
-rw-r--r-- | demos/gtk-demo/canvas_puzzle.c | 68 | ||||
-rw-r--r-- | gtk/gtk.h | 1 | ||||
-rw-r--r-- | gtk/gtkcanvas.c | 106 | ||||
-rw-r--r-- | gtk/gtkcanvas.h | 2 | ||||
-rw-r--r-- | gtk/gtkcanvasbox.c | 203 | ||||
-rw-r--r-- | gtk/gtkcanvasbox.h | 45 | ||||
-rw-r--r-- | gtk/gtkcanvasboxprivate.h | 34 | ||||
-rw-r--r-- | gtk/gtkcanvasitem.c | 274 | ||||
-rw-r--r-- | gtk/gtkcanvasitem.h | 14 | ||||
-rw-r--r-- | gtk/gtkcanvasitemprivate.h | 8 | ||||
-rw-r--r-- | gtk/gtkcanvasvector.c | 181 | ||||
-rw-r--r-- | gtk/gtkcanvasvector.h | 75 | ||||
-rw-r--r-- | gtk/gtkcanvasvectorimpl.c | 512 | ||||
-rw-r--r-- | gtk/gtkcanvasvectorprivate.h | 115 | ||||
-rw-r--r-- | gtk/gtktypes.h | 1 | ||||
-rw-r--r-- | gtk/meson.build | 3 |
18 files changed, 372 insertions, 1455 deletions
diff --git a/demos/gtk-demo/canvas_intro.c b/demos/gtk-demo/canvas_intro.c index 2ef1846321..4bf99fb3ec 100644 --- a/demos/gtk-demo/canvas_intro.c +++ b/demos/gtk-demo/canvas_intro.c @@ -10,31 +10,51 @@ #define WIDTH 400 #define HEIGHT 300 +static gboolean +center_item (GtkCanvasItem *ci, + GtkCanvasBox *out_box, + gpointer unused) +{ + const GtkCanvasBox *viewport; + GtkWidget *widget; + int width, height; + + /* We need to check if the viewport is available. + * If the canvas was scrolling, it might not be avaiable yet. + */ + viewport = gtk_canvas_get_viewport (gtk_canvas_item_get_canvas (ci)); + if (viewport == NULL) + return FALSE; + + /* Measure the widget min for min so that it will line-break. */ + widget = gtk_canvas_item_get_widget (ci); + gtk_widget_measure (widget, GTK_ORIENTATION_HORIZONTAL, -1, &width, NULL, NULL, NULL); + gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL, width, &height, NULL, NULL, NULL); + + /* Initialize the bounds for this widget: + * - the point is the center of the canvas' viewport + * - the size is the one we just computed + * - we want the origin point to be at the center + */ + gtk_canvas_box_init (out_box, + viewport->size.width * 0.5, + viewport->size.height * 0.5, + 0, 0, + 0.5, 0.5); + + return TRUE; +} + static void bind_item (GtkListItemFactory *factory, GtkCanvasItem *ci) { - GtkCanvasVector *point; - const GtkCanvasVector *size; - GtkCanvasBox *box; - gtk_canvas_item_set_widget (ci, gtk_canvas_item_get_item (ci)); - /* Also center the item, so we do something interesting */ - point = gtk_canvas_vector_new (0, 0); - box = gtk_canvas_box_new (point, - gtk_canvas_get_viewport_size (gtk_canvas_item_get_canvas (ci)), - 0.0, 0.0); - gtk_canvas_vector_free (point); - - point = gtk_canvas_vector_new_from_box (box, 0.5, 0.5); - gtk_canvas_box_free (box); - size = gtk_canvas_vector_get_item_measure (ci, GTK_CANVAS_ITEM_MEASURE_MIN_FOR_MIN); - box = gtk_canvas_box_new (point, size, 0.5, 0.5); - gtk_canvas_vector_free (point); - - gtk_canvas_item_set_bounds (ci, box); - gtk_canvas_box_free (box); + /* Set a function to compute the position */ + gtk_canvas_item_set_compute_bounds (ci, + center_item, + NULL, NULL); } GtkWidget * diff --git a/demos/gtk-demo/canvas_planarity.c b/demos/gtk-demo/canvas_planarity.c index 93ab37571b..f10c84fa34 100644 --- a/demos/gtk-demo/canvas_planarity.c +++ b/demos/gtk-demo/canvas_planarity.c @@ -78,7 +78,7 @@ struct _PlanarityVertex { GObject parent_instance; - graphene_point_t position; + GtkOrigin position; }; #define PLANARITY_TYPE_VERTEX (planarity_vertex_get_type ()) @@ -97,14 +97,15 @@ planarity_vertex_init (PlanarityVertex *self) } static PlanarityVertex * -planarity_vertex_new (float x, - float y) +planarity_vertex_new (float horizontal, + float vertical) { PlanarityVertex *self; self = g_object_new (PLANARITY_TYPE_VERTEX, NULL); - graphene_point_init (&self->position, x, y); + self->position.horizontal = horizontal; + self->position.vertical = vertical; return self; } @@ -147,54 +148,83 @@ planarity_edge_new (PlanarityVertex *from, return edge; } -static void -set_item_position (GtkCanvasItem *ci) +static gboolean +set_vertex_bounds (GtkCanvasItem *ci, + GtkCanvasBox *out_box, + gpointer user_data) { PlanarityVertex *vertex = gtk_canvas_item_get_item (ci); - GtkCanvasVector *point, *size; - GtkCanvasBox *box, *viewport; - float x = vertex->position.x; - float y = vertex->position.y; - - point = gtk_canvas_vector_new (0, 0); - viewport = gtk_canvas_box_new (point, - gtk_canvas_get_viewport_size (gtk_canvas_item_get_canvas (ci)), - 0.0, 0.0); - gtk_canvas_vector_free (point); - - point = gtk_canvas_vector_new_from_box (viewport, x, y); - gtk_canvas_box_free (viewport); - size = gtk_canvas_vector_new (0, 0); - box = gtk_canvas_box_new (point, size, x, y); - gtk_canvas_vector_free (point); - gtk_canvas_vector_free (size); - - gtk_canvas_item_set_bounds (ci, box); - gtk_canvas_box_free (box); + const GtkCanvasBox *viewport; + + viewport = gtk_canvas_get_viewport (gtk_canvas_item_get_canvas (ci)); + if (viewport == NULL) + return FALSE; + + gtk_canvas_box_init (out_box, + viewport->size.width * vertex->position.horizontal, + viewport->size.height * vertex->position.vertical, + 0, 0, + vertex->position.horizontal, + vertex->position.vertical); + + return TRUE; } static void -move_item (GtkGestureDrag *gesture, - double x, - double y, - GtkCanvasItem *ci) +move_vertex (GtkGestureDrag *gesture, + double x, + double y, + GtkCanvasItem *ci) { GtkCanvas *canvas = gtk_canvas_item_get_canvas (ci); - GtkWidget *widget = gtk_canvas_item_get_widget (ci); PlanarityVertex *vertex = gtk_canvas_item_get_item (ci); - x /= (gtk_widget_get_width (GTK_WIDGET (canvas)) - gtk_widget_get_width (widget)); - y /= (gtk_widget_get_height (GTK_WIDGET (canvas)) - gtk_widget_get_height (widget)); + x /= gtk_widget_get_width (GTK_WIDGET (canvas)); + y /= gtk_widget_get_height (GTK_WIDGET (canvas)); + + vertex->position.horizontal = CLAMP (vertex->position.horizontal + x, 0, 1); + vertex->position.vertical = CLAMP (vertex->position.vertical + y, 0, 1); - vertex->position = GRAPHENE_POINT_INIT (CLAMP (vertex->position.x + x, 0, 1), CLAMP (vertex->position.y + y, 0, 1)); - set_item_position (ci); + gtk_canvas_item_invalidate_bounds (ci); +} + +static gboolean +set_edge_bounds (GtkCanvasItem *ci, + GtkCanvasBox *out_box, + gpointer user_data) +{ + PlanarityEdge *edge = gtk_canvas_item_get_item (ci); + GtkCanvas *canvas = gtk_canvas_item_get_canvas (ci); + GtkCanvasItem *from_item, *to_item; + const GtkCanvasBox *from_box, *to_box; + graphene_rect_t from_rect, to_rect; + graphene_point_t from_center, to_center; + + from_item = gtk_canvas_lookup_item (canvas, edge->from); + to_item = gtk_canvas_lookup_item (canvas, edge->to); + from_box = gtk_canvas_item_get_allocation (from_item); + to_box = gtk_canvas_item_get_allocation (to_item); + if (from_box == NULL || to_box == NULL) + return FALSE; + + gtk_canvas_box_to_rect (from_box, &from_rect); + gtk_canvas_box_to_rect (to_box, &to_rect); + graphene_rect_get_center (&from_rect, &from_center); + graphene_rect_get_center (&to_rect, &to_center); + + gtk_canvas_box_init (out_box, + from_center.x, from_center.y, + to_center.x - from_center.x, + to_center.y - from_center.y, + 0, 0); + + return TRUE; } static void bind_item (GtkListItemFactory *factory, GtkCanvasItem *ci) { - GtkCanvasBox *box; gpointer item; item = gtk_canvas_item_get_item (ci); @@ -207,34 +237,17 @@ bind_item (GtkListItemFactory *factory, widget = gtk_image_new_from_icon_name ("media-record-symbolic"); gtk_image_set_icon_size (GTK_IMAGE (widget), GTK_ICON_SIZE_LARGE); gesture = gtk_gesture_drag_new (); - g_signal_connect (gesture, "drag-update", G_CALLBACK (move_item), ci); - g_signal_connect (gesture, "drag-end", G_CALLBACK (move_item), ci); + g_signal_connect (gesture, "drag-update", G_CALLBACK (move_vertex), ci); + g_signal_connect (gesture, "drag-end", G_CALLBACK (move_vertex), ci); gtk_widget_add_controller (widget, GTK_EVENT_CONTROLLER (gesture)); gtk_canvas_item_set_widget (ci, widget); - set_item_position (ci); + gtk_canvas_item_set_compute_bounds (ci, set_vertex_bounds, NULL, NULL); } else if (PLANARITY_IS_EDGE (item)) { - GtkCanvas *canvas = gtk_canvas_item_get_canvas (ci); - PlanarityEdge *edge = PLANARITY_EDGE (item); - GtkCanvasItem *from_item, *to_item; - const GtkCanvasBox *from_box, *to_box; - GtkCanvasVector *from_point, *to_point; - gtk_canvas_item_set_widget (ci, gtk_diagonal_line_new ()); - - from_item = gtk_canvas_lookup_item (canvas, edge->from); - to_item = gtk_canvas_lookup_item (canvas, edge->to); - from_box = gtk_canvas_box_get_item_allocation (from_item); - to_box = gtk_canvas_box_get_item_allocation (to_item); - from_point = gtk_canvas_vector_new_from_box (from_box, 0.5, 0.5); - to_point = gtk_canvas_vector_new_from_box (to_box, 0.5, 0.5); - box = gtk_canvas_box_new_points (from_point, to_point); - gtk_canvas_item_set_bounds (ci, box); - gtk_canvas_box_free (box); - gtk_canvas_vector_free (from_point); - gtk_canvas_vector_free (to_point); + gtk_canvas_item_set_compute_bounds (ci, set_edge_bounds, NULL, NULL); } } diff --git a/demos/gtk-demo/canvas_puzzle.c b/demos/gtk-demo/canvas_puzzle.c index f1ee30703b..4fe20c3327 100644 --- a/demos/gtk-demo/canvas_puzzle.c +++ b/demos/gtk-demo/canvas_puzzle.c @@ -9,32 +9,25 @@ #include "puzzlepiece.h" -static void -set_item_position (GtkCanvasItem *ci, - float x, - float y) +static gboolean +set_position_from_origin (GtkCanvasItem *ci, + GtkCanvasBox *out_box, + gpointer user_data) { - GtkCanvasVector *point, *size; - GtkCanvasBox *box, *viewport; - - x = CLAMP (x, 0, 1); - y = CLAMP (y, 0, 1); - - point = gtk_canvas_vector_new (0, 0); - viewport = gtk_canvas_box_new (point, - gtk_canvas_get_viewport_size (gtk_canvas_item_get_canvas (ci)), - 0.0, 0.0); - gtk_canvas_vector_free (point); - - point = gtk_canvas_vector_new_from_box (viewport, x, y); - gtk_canvas_box_free (viewport); - size = gtk_canvas_vector_new (0, 0); - box = gtk_canvas_box_new (point, size, x, y); - gtk_canvas_vector_free (point); - gtk_canvas_vector_free (size); - - gtk_canvas_item_set_bounds (ci, box); - gtk_canvas_box_free (box); + GtkOrigin *origin = g_object_get_data (G_OBJECT (ci), "position"); + const GtkCanvasBox *viewport = gtk_canvas_get_viewport (gtk_canvas_item_get_canvas (ci)); + + if (viewport == NULL) + return FALSE; + + gtk_canvas_box_init (out_box, + viewport->size.width * origin->horizontal, + viewport->size.height * origin->vertical, + 0, 0, + origin->horizontal, + origin->vertical); + + return TRUE; } static void @@ -44,14 +37,15 @@ move_item (GtkGestureDrag *gesture, GtkCanvasItem *ci) { GtkCanvas *canvas = gtk_canvas_item_get_canvas (ci); - graphene_rect_t bounds; + GtkOrigin *origin = g_object_get_data (G_OBJECT (ci), "position"); - if (!gtk_canvas_box_eval (gtk_canvas_item_get_bounds (ci), &bounds)) - return; + origin->horizontal += x / gtk_widget_get_width (GTK_WIDGET (canvas)); + 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); - set_item_position (ci, - (bounds.origin.x + x) / (gtk_widget_get_width (GTK_WIDGET (canvas)) - bounds.size.width), - (bounds.origin.y + y) / (gtk_widget_get_height (GTK_WIDGET (canvas)) - bounds.size.height)); + gtk_canvas_item_invalidate_bounds (ci); } static void @@ -60,6 +54,7 @@ bind_item (GtkListItemFactory *factory, { GtkWidget *widget; GtkGesture *gesture; + GtkOrigin *origin; widget = gtk_picture_new_for_paintable (gtk_canvas_item_get_item (ci)); gtk_picture_set_can_shrink (GTK_PICTURE (widget), FALSE); @@ -69,8 +64,15 @@ bind_item (GtkListItemFactory *factory, gtk_widget_add_controller (widget, GTK_EVENT_CONTROLLER (gesture)); gtk_canvas_item_set_widget (ci, widget); - /* Also center the item, so we do something interesting */ - set_item_position (ci, g_random_double (), g_random_double ()); + /* Set a random position */ + origin = g_new (GtkOrigin, 1); + origin->horizontal = g_random_double (); + 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); } static GListModel * @@ -62,7 +62,6 @@ #include <gtk/gtkcanvas.h> #include <gtk/gtkcanvasbox.h> #include <gtk/gtkcanvasitem.h> -#include <gtk/gtkcanvasvector.h> #include <gtk/gtkcellarea.h> #include <gtk/gtkcellareabox.h> #include <gtk/gtkcellareacontext.h> diff --git a/gtk/gtkcanvas.c b/gtk/gtkcanvas.c index 2d5527ea08..2a78fddfa2 100644 --- a/gtk/gtkcanvas.c +++ b/gtk/gtkcanvas.c @@ -23,7 +23,6 @@ #include "gtkcanvasbox.h" #include "gtkcanvasitemprivate.h" -#include "gtkcanvasvectorprivate.h" #include "gtkintl.h" #include "gtklistitemfactory.h" #include "gtkwidgetprivate.h" @@ -53,7 +52,8 @@ struct _GtkCanvas GtkCanvasItems items; GHashTable *item_lookup; - GtkCanvasVector viewport_size; + GtkCanvasBox viewport; + guint viewport_valid : 1; }; enum @@ -164,7 +164,6 @@ gtk_canvas_finalize (GObject *object) GtkCanvas *self = GTK_CANVAS (object); g_hash_table_unref (self->item_lookup); - gtk_canvas_vector_finish (&self->viewport_size); G_OBJECT_CLASS (gtk_canvas_parent_class)->finalize (object); } @@ -218,15 +217,17 @@ gtk_canvas_set_property (GObject *object, } static void -gtk_canvas_validate_variables (GtkCanvas *self) +gtk_canvas_invalidate_allocation (GtkCanvas *self) { int i; + self->viewport_valid = FALSE; + for (i = 0; i < gtk_canvas_items_get_size (&self->items); i++) { GtkCanvasItem *ci = gtk_canvas_items_get (&self->items, i); - gtk_canvas_item_validate_variables (ci); + gtk_canvas_item_invalidate_allocation (ci); } } @@ -240,9 +241,13 @@ gtk_canvas_allocate (GtkWidget *widget, gboolean missing, force, success; gsize i; - gtk_canvas_validate_variables (self); + gtk_canvas_invalidate_allocation (self); - gtk_canvas_vector_init_constant (gtk_canvas_vector_get_variable (&self->viewport_size), width, height); + self->viewport_valid = TRUE; + gtk_canvas_box_init (&self->viewport, + 0, 0, + width, height, + 0, 0); force = FALSE; do @@ -254,71 +259,17 @@ gtk_canvas_allocate (GtkWidget *widget, for (i = 0; i < gtk_canvas_items_get_size (&self->items); i++) { GtkCanvasItem *ci = gtk_canvas_items_get (&self->items, i); - GtkWidget *child = gtk_canvas_item_get_widget (ci); - const GtkCanvasBox *bounds; - graphene_rect_t rect; - int x, y, w, h; - if (child == NULL || gtk_canvas_item_has_allocation (ci)) + if (gtk_canvas_item_has_allocation (ci)) continue; - bounds = gtk_canvas_item_get_bounds (ci); - if (!gtk_canvas_box_eval (bounds, &rect)) - { - if (force) - { - rect = *graphene_rect_zero (); - /* XXX: set force to FALSE? */ - } - else - { - missing = TRUE; - continue; - } - } - - if (gtk_widget_get_request_mode (child) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH) - { - gtk_widget_measure (child, GTK_ORIENTATION_HORIZONTAL, -1, &w, NULL, NULL, NULL); - w = MAX (w, ceil (ABS (rect.size.width))); - gtk_widget_measure (child, GTK_ORIENTATION_VERTICAL, w, &h, NULL, NULL, NULL); - h = MAX (h, ceil (ABS (rect.size.height))); - } - else - { - gtk_widget_measure (child, GTK_ORIENTATION_VERTICAL, -1, &h, NULL, NULL, NULL); - h = MAX (h, ceil (ABS (rect.size.height))); - gtk_widget_measure (child, GTK_ORIENTATION_HORIZONTAL, h, &w, NULL, NULL, NULL); - w = MAX (w, ceil (ABS (rect.size.width))); - } - - if (rect.size.width < 0) - w = -w; - if (rect.size.height < 0) - h = -h; - if (ABS (w) > ABS (rect.size.width) || ABS (h) > ABS (rect.size.height)) - { - graphene_vec2_t origin; - - if (!gtk_canvas_vector_eval (gtk_canvas_box_get_origin (bounds), &origin)) - graphene_vec2_init_from_vec2 (&origin, graphene_vec2_zero ()); - - if (ABS (w) > ABS (rect.size.width)) - x = round (rect.origin.x + graphene_vec2_get_x (&origin) * (rect.size.width - w)); - else - x = round (rect.origin.x); - if (ABS (h) > ABS (rect.size.height)) - y = round (rect.origin.y + graphene_vec2_get_y (&origin) * (rect.size.height - h)); - else - y = round (rect.origin.y); - } - else + if (!gtk_canvas_item_allocate (ci, force)) { - x = round (rect.origin.x); - y = round (rect.origin.y); + g_assert (!force); + missing = TRUE; + continue; } - gtk_canvas_item_allocate (ci, &GRAPHENE_RECT_INIT (x, y, w, h)); success = TRUE; } if (!success) @@ -380,8 +331,6 @@ static void gtk_canvas_init (GtkCanvas *self) { self->item_lookup = g_hash_table_new (g_direct_hash, g_direct_equal); - - gtk_canvas_vector_init_variable (&self->viewport_size, "viewport.size"); } /** @@ -554,8 +503,23 @@ gtk_canvas_lookup_item (GtkCanvas *self, return g_hash_table_lookup (self->item_lookup, item); } -const GtkCanvasVector * -gtk_canvas_get_viewport_size (GtkCanvas *self) +/** + * gtk_canvas_get_viewport: + * @self: a `GtkCanvas` + * + * Gets the viewport of the canvas. If no viewport is available, + * in particular if it has not been determined during size + * allocation, %NULL is returned. + * + * Returns: The viewport + **/ +const GtkCanvasBox * +gtk_canvas_get_viewport (GtkCanvas *self) { - return &self->viewport_size; + g_return_val_if_fail (GTK_IS_CANVAS (self), NULL); + + if (!self->viewport_valid) + return NULL; + + return &self->viewport; } diff --git a/gtk/gtkcanvas.h b/gtk/gtkcanvas.h index 75e8f8b093..98e7a398e8 100644 --- a/gtk/gtkcanvas.h +++ b/gtk/gtkcanvas.h @@ -54,7 +54,7 @@ GtkCanvasItem * gtk_canvas_lookup_item (GtkCanvas gpointer item); GDK_AVAILABLE_IN_ALL -const GtkCanvasVector * gtk_canvas_get_viewport_size (GtkCanvas *self); +const GtkCanvasBox * gtk_canvas_get_viewport (GtkCanvas *self); G_END_DECLS diff --git a/gtk/gtkcanvasbox.c b/gtk/gtkcanvasbox.c index 56388c2bab..cb5a175afa 100644 --- a/gtk/gtkcanvasbox.c +++ b/gtk/gtkcanvasbox.c @@ -29,141 +29,12 @@ #include "config.h" -#include "gtkcanvasboxprivate.h" - -/* {{{ Boilerplate */ +#include "gtkcanvasbox.h" G_DEFINE_BOXED_TYPE (GtkCanvasBox, gtk_canvas_box, gtk_canvas_box_copy, gtk_canvas_box_free) -void -gtk_canvas_box_init (GtkCanvasBox *self, - const GtkCanvasVector *point, - const GtkCanvasVector *size, - const GtkCanvasVector *origin) -{ - gtk_canvas_vector_init_copy (&self->point, point); - gtk_canvas_vector_init_copy (&self->size, size); - gtk_canvas_vector_init_copy (&self->origin, origin); -} - -void -gtk_canvas_box_init_copy (GtkCanvasBox *self, - const GtkCanvasBox *source) -{ - gtk_canvas_box_init (self, &source->point, &source->size, &source->origin); -} - -void -gtk_canvas_box_finish (GtkCanvasBox *self) -{ - gtk_canvas_vector_finish (&self->point); - gtk_canvas_vector_finish (&self->size); - gtk_canvas_vector_finish (&self->origin); -} - -void -gtk_canvas_box_init_variable (GtkCanvasBox *self, - const char *format, - ...) -{ - char *name; - va_list args; - - va_start (args, format); - name = g_strdup_vprintf (format, args); - va_end (args); - - gtk_canvas_vector_init_variable (&self->point, "%s.point", name); - gtk_canvas_vector_init_variable (&self->size, "%s.size", name); - gtk_canvas_vector_init_variable (&self->origin, "%s.origin", name); - - g_free (name); -} - -void -gtk_canvas_box_update_variable (GtkCanvasBox *self, - const GtkCanvasBox *other) -{ - gtk_canvas_vector_init_copy (gtk_canvas_vector_get_variable (&self->point), &other->point); - gtk_canvas_vector_init_copy (gtk_canvas_vector_get_variable (&self->size), &other->size); - gtk_canvas_vector_init_copy (gtk_canvas_vector_get_variable (&self->origin), &other->origin); -} - -/** - * gtk_canvas_box_new_points: - * @point1: the first point - * @point2: the second point - * - * Creates a new box describing the rectangle between the two - * points - * - * Returns: a new box - **/ -GtkCanvasBox * -gtk_canvas_box_new_points (const GtkCanvasVector *point1, - const GtkCanvasVector *point2) -{ - GtkCanvasVector size, origin; - GtkCanvasBox *result; - graphene_vec2_t minus_one; - - g_return_val_if_fail (point1 != NULL, NULL); - g_return_val_if_fail (point2 != NULL, NULL); - - graphene_vec2_init (&minus_one, -1.f, -1.f); - gtk_canvas_vector_init_sum (&size, - graphene_vec2_one (), - point2, - &minus_one, - point1, - NULL); - gtk_canvas_vector_init_constant (&origin, 0, 0); - result = g_slice_new (GtkCanvasBox); - gtk_canvas_box_init (result, (GtkCanvasVector *) point1, &size, &origin); - gtk_canvas_vector_finish (&size); - gtk_canvas_vector_finish (&origin); - - return result; -} - -/** - * gtk_canvas_box_new: - * @point: the origin point of the box - * @size: size of the box - * @origin_x: x coordinate of origin - * @origin_y: y coordinate of origin - * - * Creates a new box of the given size relative to the given point. - * The origin describes where in the box the point is located. - * (0, 0) means the point describes the top left of the box, (1, 1) - * describes the bottom right, and (0.5, 0.5) is the center. - * - * Returns: a new box - **/ -GtkCanvasBox * -gtk_canvas_box_new (const GtkCanvasVector *point, - const GtkCanvasVector *size, - float origin_x, - float origin_y) -{ - GtkCanvasBox *self; - GtkCanvasVector origin; - - g_return_val_if_fail (point != NULL, NULL); - g_return_val_if_fail (size != NULL, NULL); - - gtk_canvas_vector_init_constant (&origin, origin_x, origin_y); - - self = g_slice_new (GtkCanvasBox); - gtk_canvas_box_init (self, point, size, &origin); - - gtk_canvas_vector_finish (&origin); - - return self; -} - GtkCanvasBox * gtk_canvas_box_copy (const GtkCanvasBox *self) { @@ -171,8 +42,7 @@ gtk_canvas_box_copy (const GtkCanvasBox *self) g_return_val_if_fail (self != NULL, NULL); - copy = g_slice_new (GtkCanvasBox); - gtk_canvas_box_init_copy (copy, self); + copy = g_slice_dup (GtkCanvasBox, self); return copy; } @@ -180,59 +50,32 @@ gtk_canvas_box_copy (const GtkCanvasBox *self) void gtk_canvas_box_free (GtkCanvasBox *self) { - gtk_canvas_box_finish (self); - g_slice_free (GtkCanvasBox, self); } -gboolean -gtk_canvas_box_eval (const GtkCanvasBox *self, - graphene_rect_t *rect) -{ - graphene_vec2_t point, size, origin; - - g_return_val_if_fail (self != NULL, FALSE); - g_return_val_if_fail (rect != NULL, FALSE); - - if (!gtk_canvas_vector_eval (&self->point, &point) || - !gtk_canvas_vector_eval (&self->size, &size) || - !gtk_canvas_vector_eval (&self->origin, &origin)) - { - *rect = *graphene_rect_zero (); - return FALSE; - } - - graphene_vec2_multiply (&origin, &size, &origin); - graphene_vec2_subtract (&point, &origin, &point); - - *rect = GRAPHENE_RECT_INIT (graphene_vec2_get_x (&point), - graphene_vec2_get_y (&point), - graphene_vec2_get_x (&size), - graphene_vec2_get_y (&size)); - - return TRUE; -} - -const GtkCanvasVector * -gtk_canvas_box_get_point (const GtkCanvasBox *self) -{ - g_return_val_if_fail (self != NULL, NULL); - - return &self->point; -} - -const GtkCanvasVector * -gtk_canvas_box_get_size (const GtkCanvasBox *self) +void +gtk_canvas_box_init (GtkCanvasBox *self, + float point_x, + float point_y, + float width, + float height, + float origin_horizontal, + float origin_vertical) { - g_return_val_if_fail (self != NULL, NULL); - - return &self->size; + self->point.x = point_x; + self->point.y = point_y; + self->size.width = width; + self->size.height = height; + self->origin.horizontal = origin_horizontal; + self->origin.vertical = origin_vertical; } -const GtkCanvasVector * -gtk_canvas_box_get_origin (const GtkCanvasBox *self) +void +gtk_canvas_box_to_rect (const GtkCanvasBox *self, + graphene_rect_t *rect) { - g_return_val_if_fail (self != NULL, NULL); - - return &self->origin; + rect->size = self->size; + rect->origin = GRAPHENE_POINT_INIT (self->point.x - self->origin.horizontal * self->size.width, + self->point.y - self->origin.vertical * self->size.height); + graphene_rect_normalize (rect); } diff --git a/gtk/gtkcanvasbox.h b/gtk/gtkcanvasbox.h index 2f08699f5a..e9bba1bc83 100644 --- a/gtk/gtkcanvasbox.h +++ b/gtk/gtkcanvasbox.h @@ -30,6 +30,20 @@ G_BEGIN_DECLS +typedef struct _GtkOrigin GtkOrigin; + +struct _GtkOrigin { + float horizontal; + float vertical; +}; + +struct _GtkCanvasBox +{ + graphene_point_t point; + graphene_size_t size; + GtkOrigin origin; +}; + #define GTK_TYPE_CANVAS_BOX (gtk_canvas_box_get_type ()) GDK_AVAILABLE_IN_ALL @@ -41,30 +55,17 @@ GDK_AVAILABLE_IN_ALL void gtk_canvas_box_free (GtkCanvasBox *self); GDK_AVAILABLE_IN_ALL -const GtkCanvasVector * gtk_canvas_box_get_point (const GtkCanvasBox *self) G_GNUC_PURE; -GDK_AVAILABLE_IN_ALL -const GtkCanvasVector * gtk_canvas_box_get_size (const GtkCanvasBox *self) G_GNUC_PURE; -GDK_AVAILABLE_IN_ALL -const GtkCanvasVector * gtk_canvas_box_get_origin (const GtkCanvasBox *self) G_GNUC_PURE; - -GDK_AVAILABLE_IN_ALL -gboolean gtk_canvas_box_eval (const GtkCanvasBox *self, - graphene_rect_t *rect) G_GNUC_WARN_UNUSED_RESULT; - -GDK_AVAILABLE_IN_ALL -GtkCanvasBox * gtk_canvas_box_new (const GtkCanvasVector *point, - const GtkCanvasVector *size, - float origin_x, - float origin_y); -GDK_AVAILABLE_IN_ALL -GtkCanvasBox * gtk_canvas_box_new_points (const GtkCanvasVector *point1, - const GtkCanvasVector *point2); +void gtk_canvas_box_init (GtkCanvasBox *self, + float point_x, + float point_y, + float width, + float height, + float origin_horizontal, + float origin_vertical); GDK_AVAILABLE_IN_ALL -const GtkCanvasBox * gtk_canvas_box_get_item_bounds (GtkCanvasItem *item); -GDK_AVAILABLE_IN_ALL -const GtkCanvasBox * gtk_canvas_box_get_item_allocation (GtkCanvasItem *item); - +void gtk_canvas_box_to_rect (const GtkCanvasBox *self, + graphene_rect_t *rect); G_END_DECLS #endif /* __GTK_BOX_H__ */ diff --git a/gtk/gtkcanvasboxprivate.h b/gtk/gtkcanvasboxprivate.h deleted file mode 100644 index 1d6256495e..0000000000 --- a/gtk/gtkcanvasboxprivate.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef __GTK_CANVAS_BOX_PRIVATE_H__ -#define __GTK_CANVAS_BOX_PRIVATE_H__ - -#include "gtkcanvasbox.h" - -#include "gtkcanvasvectorprivate.h" - -G_BEGIN_DECLS - -struct _GtkCanvasBox -{ - GtkCanvasVector point; - GtkCanvasVector size; - GtkCanvasVector origin; -}; - - -void gtk_canvas_box_init (GtkCanvasBox *self, - const GtkCanvasVector *point, - const GtkCanvasVector *size, - const GtkCanvasVector *origin); -void gtk_canvas_box_init_copy (GtkCanvasBox *self, - const GtkCanvasBox *source); -void gtk_canvas_box_finish (GtkCanvasBox *self); - -void gtk_canvas_box_init_variable (GtkCanvasBox *self, - const char *format, - ...) G_GNUC_PRINTF(2,3); -void gtk_canvas_box_update_variable (GtkCanvasBox *self, - const GtkCanvasBox *other); - -G_END_DECLS - -#endif /* __GTK_CANVAS_BOX_PRIVATE_H__ */ diff --git a/gtk/gtkcanvasitem.c b/gtk/gtkcanvasitem.c index 0ed91e7291..e19c9017e1 100644 --- a/gtk/gtkcanvasitem.c +++ b/gtk/gtkcanvasitem.c @@ -22,7 +22,7 @@ #include "gtkcanvasitemprivate.h" #include "gtkcanvas.h" -#include "gtkcanvasboxprivate.h" +#include "gtkcanvasbox.h" #include "gtkintl.h" #include "gtklistitemfactoryprivate.h" #include "gtkwidget.h" @@ -41,17 +41,19 @@ struct _GtkCanvasItem GtkCanvas *canvas; gpointer item; GtkWidget *widget; + GtkCanvasItemComputeBoundsFunc compute_bounds_func; + gpointer user_data; + GDestroyNotify user_destroy; + GtkCanvasBox bounds; - GtkCanvasBox bounds_var; - GtkCanvasBox allocation_var; + GtkCanvasBox allocation; - GtkCanvasVector size_vecs[4]; + guint has_allocation : 1; }; enum { PROP_0, - PROP_BOUNDS, PROP_CANVAS, PROP_ITEM, PROP_WIDGET, @@ -74,23 +76,12 @@ gtk_canvas_item_dispose (GObject *object) g_assert (self->item == NULL); g_assert (self->widget == NULL); - G_OBJECT_CLASS (gtk_canvas_item_parent_class)->dispose (object); -} + if (self->user_destroy) + self->user_destroy (self->user_data); + self->user_destroy = NULL; + self->user_data = NULL; -static void -gtk_canvas_item_finalize (GObject *object) -{ - GtkCanvasItem *self = GTK_CANVAS_ITEM (object); - int i; - - for (i = 0; i < 4; i++) - gtk_canvas_vector_finish (&self->size_vecs[i]); - - gtk_canvas_box_finish (&self->bounds); - gtk_canvas_box_finish (&self->bounds_var); - gtk_canvas_box_finish (&self->allocation_var); - - G_OBJECT_CLASS (gtk_canvas_item_parent_class)->finalize (object); + G_OBJECT_CLASS (gtk_canvas_item_parent_class)->dispose (object); } static void @@ -103,10 +94,6 @@ gtk_canvas_item_get_property (GObject *object, switch (property_id) { - case PROP_BOUNDS: - g_value_set_boxed (value, &self->bounds); - break; - case PROP_CANVAS: g_value_set_object (value, self->canvas); break; @@ -135,10 +122,6 @@ gtk_canvas_item_set_property (GObject *object, switch (property_id) { - case PROP_BOUNDS: - gtk_canvas_item_set_bounds (self, g_value_get_boxed (value)); - break; - case PROP_WIDGET: gtk_canvas_item_set_widget (self, g_value_get_object (value)); break; @@ -155,21 +138,10 @@ gtk_canvas_item_class_init (GtkCanvasItemClass *klass) GObjectClass *gobject_class = G_OBJECT_CLASS (klass); gobject_class->dispose = gtk_canvas_item_dispose; - gobject_class->finalize = gtk_canvas_item_finalize; gobject_class->get_property = gtk_canvas_item_get_property; gobject_class->set_property = gtk_canvas_item_set_property; /** - * GtkCanvasItem:bounds: (attributes org.gtk.Property.get=gtk_canvas_item_get_bounds org.gtk.Property.set=gtk_canvas_item_set_bounds) - * - * The bounds to place the widget into. - */ - properties[PROP_BOUNDS] = - g_param_spec_boxed ("bounds", NULL, NULL, - GTK_TYPE_CANVAS_BOX, - G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); - - /** * GtkCanvasItem:canvas: (attributes org.gtk.Property.get=gtk_canvas_item_get_canvas org.gtk.Property.set=gtk_canvas_item_set_canvas) * * The canvas this item belongs to or %NULL if the canvas has been destroyed @@ -205,17 +177,6 @@ gtk_canvas_item_class_init (GtkCanvasItemClass *klass) static void gtk_canvas_item_init (GtkCanvasItem *self) { - gtk_canvas_vector_init_variable (&self->size_vecs[0], "item%p.min_for_min", self); - gtk_canvas_vector_init_variable (&self->size_vecs[1], "item%p.min_for_nat", self); - gtk_canvas_vector_init_variable (&self->size_vecs[2], "item%p.nat_for_min", self); - gtk_canvas_vector_init_variable (&self->size_vecs[3], "item%p.nat_for_nat", self); - - gtk_canvas_vector_init_constant (&self->bounds.point, 0, 0); - gtk_canvas_vector_init_copy (&self->bounds.size, &self->size_vecs[GTK_CANVAS_ITEM_MEASURE_NAT_FOR_NAT]); - gtk_canvas_vector_init_constant (&self->bounds.origin, 0.5, 0.5); - gtk_canvas_box_init_variable (&self->bounds_var, "item%p.bounds", self); - gtk_canvas_box_update_variable (&self->bounds_var, &self->bounds); - gtk_canvas_box_init_variable (&self->allocation_var, "item%p.allocation", self); } GtkCanvasItem * @@ -236,70 +197,72 @@ gtk_canvas_item_new (GtkCanvas *canvas, } void -gtk_canvas_item_validate_variables (GtkCanvasItem *self) +gtk_canvas_item_invalidate_allocation (GtkCanvasItem *self) { - int w[4], h[4], i; + self->has_allocation = FALSE; +} - if (self->widget == NULL) +gboolean +gtk_canvas_item_allocate (GtkCanvasItem *self, + gboolean force) +{ + int w, h; + + g_assert (!self->has_allocation); + + if (!self->compute_bounds_func) { - memset (w, 0, sizeof (w)); - memset (h, 0, sizeof (h)); + gtk_canvas_box_init (&self->bounds, 0, 0, 0, 0, 0.5, 0.5); } - else + else if (!self->compute_bounds_func (self, &self->bounds, self->user_data)) + { + if (!force) + return FALSE; + gtk_canvas_box_init (&self->bounds, 0, 0, 0, 0, 0.5, 0.5); + } + + if (self->widget) { if (gtk_widget_get_request_mode (self->widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH) { - gtk_widget_measure (self->widget, GTK_ORIENTATION_HORIZONTAL, -1, &w[0], &w[2], NULL, NULL); - w[1] = w[0]; - gtk_widget_measure (self->widget, GTK_ORIENTATION_VERTICAL, w[0], &h[0], &h[1], NULL, NULL); - w[3] = w[2]; - gtk_widget_measure (self->widget, GTK_ORIENTATION_VERTICAL, w[2], &h[2], &h[3], NULL, NULL); + gtk_widget_measure (self->widget, GTK_ORIENTATION_HORIZONTAL, -1, &w, NULL, NULL, NULL); + w = MAX (w, ceil (ABS (self->bounds.size.width))); + gtk_widget_measure (self->widget, GTK_ORIENTATION_VERTICAL, w, &h, NULL, NULL, NULL); + h = MAX (h, ceil (ABS (self->bounds.size.height))); } else { - gtk_widget_measure (self->widget, GTK_ORIENTATION_VERTICAL, -1, &h[0], &h[2], NULL, NULL); - h[1] = h[0]; - gtk_widget_measure (self->widget, GTK_ORIENTATION_HORIZONTAL, h[0], &w[0], &w[1], NULL, NULL); - h[3] = h[2]; - gtk_widget_measure (self->widget, GTK_ORIENTATION_HORIZONTAL, h[2], &w[2], &w[3], NULL, NULL); + gtk_widget_measure (self->widget, GTK_ORIENTATION_VERTICAL, -1, &h, NULL, NULL, NULL); + h = MAX (h, ceil (ABS (self->bounds.size.height))); + gtk_widget_measure (self->widget, GTK_ORIENTATION_HORIZONTAL, h, &w, NULL, NULL, NULL); + w = MAX (w, ceil (ABS (self->bounds.size.width))); } - } - for (i = 0; i < 4; i++) + if (self->bounds.size.width >= 0) + w = MAX (self->bounds.size.width, w); + else + w = MIN (self->bounds.size.width, -w); + if (self->bounds.size.height >= 0) + h = MAX (self->bounds.size.height, h); + else + h = MIN (self->bounds.size.height, -h); + } + else { - gtk_canvas_vector_init_constant ( - gtk_canvas_vector_get_variable (&self->size_vecs[i]), - 0, 0); + w = 0; + h = 0; } - gtk_canvas_vector_init_invalid ( - gtk_canvas_vector_get_variable (&self->allocation_var.point)); - gtk_canvas_vector_init_invalid ( - gtk_canvas_vector_get_variable (&self->allocation_var.size)); - gtk_canvas_vector_init_invalid ( - gtk_canvas_vector_get_variable (&self->allocation_var.origin)); -} + gtk_canvas_box_init (&self->allocation, + round (self->bounds.point.x - self->bounds.origin.horizontal * w) + + self->bounds.origin.horizontal * w, + round (self->bounds.point.y - self->bounds.origin.vertical * h) + + self->bounds.origin.vertical * h, + w, h, + self->bounds.origin.horizontal, self->bounds.origin.vertical); + self->has_allocation = TRUE; -void -gtk_canvas_item_allocate (GtkCanvasItem *self, - graphene_rect_t *rect) -{ - graphene_vec2_t origin; - - if (!gtk_canvas_vector_eval (&self->bounds.origin, &origin)) - graphene_vec2_init_from_vec2 (&origin, graphene_vec2_zero ()); - - gtk_canvas_vector_init_constant ( - gtk_canvas_vector_get_variable (&self->allocation_var.point), - rect->origin.x + graphene_vec2_get_x (&origin) * rect->size.width, - rect->origin.y + graphene_vec2_get_y (&origin) * rect->size.height); - gtk_canvas_vector_init_constant ( - gtk_canvas_vector_get_variable (&self->allocation_var.size), - rect->size.width, rect->size.height); - gtk_canvas_vector_init_constant ( - gtk_canvas_vector_get_variable (&self->allocation_var.origin), - graphene_vec2_get_x (&origin), - graphene_vec2_get_y (&origin)); + return TRUE; } void @@ -312,13 +275,9 @@ gtk_canvas_item_allocate_widget (GtkCanvasItem *self, if (self->widget == NULL) return; - if (!gtk_canvas_box_eval (&self->allocation_var, &allocation)) - { - /* gtkcanvas.c will not call this function otherwise */ - g_assert_not_reached (); - } - + gtk_canvas_box_to_rect (&self->allocation, &allocation); graphene_rect_normalize (&allocation); + gtk_widget_size_allocate (self->widget, &(GtkAllocation) { allocation.origin.x - dx, @@ -331,32 +290,7 @@ gtk_canvas_item_allocate_widget (GtkCanvasItem *self, gboolean gtk_canvas_item_has_allocation (GtkCanvasItem *self) { - return !gtk_canvas_vector_is_invalid (gtk_canvas_vector_get_variable (&self->allocation_var.point)); -} - -const GtkCanvasVector * -gtk_canvas_vector_get_item_measure (GtkCanvasItem *item, - GtkCanvasItemMeasure measure) -{ - g_return_val_if_fail (GTK_IS_CANVAS_ITEM (item), NULL); - - return &item->size_vecs[measure]; -} - -const GtkCanvasBox * -gtk_canvas_box_get_item_bounds (GtkCanvasItem *item) -{ - g_return_val_if_fail (GTK_IS_CANVAS_ITEM (item), NULL); - - return &item->bounds_var; -} - -const GtkCanvasBox * -gtk_canvas_box_get_item_allocation (GtkCanvasItem *item) -{ - g_return_val_if_fail (GTK_IS_CANVAS_ITEM (item), NULL); - - return &item->allocation_var; + return self->has_allocation; } /** @@ -395,45 +329,99 @@ gtk_canvas_item_get_item (GtkCanvasItem *self) } /** - * gtk_canvas_item_set_bounds: (attributes org.gtk.Method.set_property=bounds) + * gtk_canvas_item_set_compute_bounds: * @self: a `GtkCanvasItem` - * @bounds: (transfer none): the bounds to allocate the widget in + * @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. * - * Sets the box to allocate the widget into. + * 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_bounds (GtkCanvasItem *self, - const GtkCanvasBox *bounds) +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)); - g_return_if_fail (bounds != NULL); - gtk_canvas_box_init_copy (&self->bounds, bounds); - gtk_canvas_box_update_variable (&self->bounds_var, bounds); + 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) +{ + g_return_if_fail (GTK_IS_CANVAS_ITEM (self)); if (self->canvas) gtk_widget_queue_allocate (GTK_WIDGET (self->canvas)); - - g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_BOUNDS]); } /** - * gtk_canvas_item_get_bounds: (attributes org.gtk.Method.get_property=bounds) + * gtk_canvas_item_get_bounds: * @self: a `GtkCanvasItem` * * Gets the bounds that are used to allocate the widget * - * Returns: (transfer none): The bounds + * If the bounds are not known yet - for example when called during the size + * allocation phase before this item has succesfully computed its bounds - + * this function returns %NULL. + * + * See also gtk_canvas_item_get_allocation(). + * + * Returns: (transfer none) (nullable): The bounds */ const GtkCanvasBox * gtk_canvas_item_get_bounds (GtkCanvasItem *self) { g_return_val_if_fail (GTK_IS_CANVAS_ITEM (self), NULL); + if (!self->has_allocation) + return NULL; + return &self->bounds; } /** + * gtk_canvas_item_get_allocation: + * @self: a `GtkCanvasItem` + * + * Gets the allocation assigned to the widget. + * + * If the bounds are not known yet - for example when called during the size + * allocation phase before this item has succesfully computed its bounds - + * this function returns %NULL. + * + * Compared with gtk_canvas_item_get_bounds(), this function returns the actual + * box used to allocate the widget, which may be different from the bounds + * to conform to its size requirements. + * + * Returns: (transfer none) (nullable): The allocation + */ +const GtkCanvasBox * +gtk_canvas_item_get_allocation (GtkCanvasItem *self) +{ + g_return_val_if_fail (GTK_IS_CANVAS_ITEM (self), NULL); + + if (!self->has_allocation) + return NULL; + + return &self->allocation; +} + +/** * gtk_canvas_item_set_widget: (attributes org.gtk.Method.set_property=widget) * @self: a `GtkCanvasItem` * @widget: (nullable) (transfer none): the widget to use diff --git a/gtk/gtkcanvasitem.h b/gtk/gtkcanvasitem.h index 15f3ae7bf4..488656aa2f 100644 --- a/gtk/gtkcanvasitem.h +++ b/gtk/gtkcanvasitem.h @@ -35,6 +35,9 @@ 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 @@ -47,10 +50,17 @@ GDK_AVAILABLE_IN_ALL GtkWidget * gtk_canvas_item_get_widget (GtkCanvasItem *self); GDK_AVAILABLE_IN_ALL -void gtk_canvas_item_set_bounds (GtkCanvasItem *self, - const GtkCanvasBox *box); +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); + GDK_AVAILABLE_IN_ALL const GtkCanvasBox * gtk_canvas_item_get_bounds (GtkCanvasItem *self); +GDK_AVAILABLE_IN_ALL +const GtkCanvasBox * gtk_canvas_item_get_allocation (GtkCanvasItem *self); G_END_DECLS diff --git a/gtk/gtkcanvasitemprivate.h b/gtk/gtkcanvasitemprivate.h index cf1adbfc24..f52377cecd 100644 --- a/gtk/gtkcanvasitemprivate.h +++ b/gtk/gtkcanvasitemprivate.h @@ -3,16 +3,14 @@ #include "gtkcanvasitem.h" -#include "gtkcanvasvectorprivate.h" - G_BEGIN_DECLS GtkCanvasItem * gtk_canvas_item_new (GtkCanvas *canvas, gpointer item); -void gtk_canvas_item_validate_variables (GtkCanvasItem *self); -void gtk_canvas_item_allocate (GtkCanvasItem *self, - graphene_rect_t *rect); +void gtk_canvas_item_invalidate_allocation (GtkCanvasItem *self); +gboolean gtk_canvas_item_allocate (GtkCanvasItem *self, + gboolean force); void gtk_canvas_item_allocate_widget (GtkCanvasItem *self, float dx, float dy); diff --git a/gtk/gtkcanvasvector.c b/gtk/gtkcanvasvector.c deleted file mode 100644 index 8ba16b073f..0000000000 --- a/gtk/gtkcanvasvector.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright © 2022 Benjamin Otte - * - * 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/>. - * - * Authors: Benjamin Otte <otte@gnome.org> - */ - - -/** - * GtkCanvasVector: - * - * `GtkCanvasVector` describes a point, size or scale in the coordinate - * system of a `GtkCanvas`. - * - * Vectors are automatically-updating expressions that can track other vectors - * in the canvas, and constructing the vectors to place `GtkCanvasItem`s on the - * canvas is the main thing about `GtkCanvas`. - */ - -#include "config.h" - -#include "gtkcanvasvectorprivate.h" - -#include "gtkcanvasboxprivate.h" - -G_DEFINE_BOXED_TYPE (GtkCanvasVector, gtk_canvas_vector, - gtk_canvas_vector_copy, - gtk_canvas_vector_free) - -static GtkCanvasVector * -gtk_canvas_vector_alloc (void) -{ - return g_slice_new (GtkCanvasVector); -} - -/** - * gtk_canvas_vector_new: - * @x: x coordinate - * @y: y coordinate - * - * Creates a new vector at the given coordinate. - * - * Returns: a new vector - **/ -GtkCanvasVector * -gtk_canvas_vector_new (float x, - float y) -{ - GtkCanvasVector *self; - - self = gtk_canvas_vector_alloc (); - gtk_canvas_vector_init_constant (self, x, y); - - return self; -} - -/** - * gtk_canvas_vector_new_from_box: - * @box: a box - * @origin_x: x coordinate of box origin - * @origin_y: y coordinate of box origin - * - * Creates a vector relative to the given box. - * - * The origin describes where in the box the vector is, with - * (0, 0) being the top left and (1, 1) being the bottom right - * corner of the box. - * - * Returns: a new vector - **/ -GtkCanvasVector * -gtk_canvas_vector_new_from_box (const GtkCanvasBox *box, - float origin_x, - float origin_y) -{ - GtkCanvasVector *self; - GtkCanvasVector mult; - graphene_vec2_t origin, minus_one; - - g_return_val_if_fail (box != NULL, NULL); - - graphene_vec2_init (&origin, origin_x, origin_y); - graphene_vec2_init (&minus_one, -1, -1); - gtk_canvas_vector_init_multiply (&mult, &box->origin, &box->size); - - self = gtk_canvas_vector_alloc (); - gtk_canvas_vector_init_sum (self, - graphene_vec2_one (), - &box->point, - &origin, - &box->size, - &minus_one, - &mult, - NULL); - - gtk_canvas_vector_finish (&mult); - - return self; -} - -/** - * gtk_canvas_vector_new_distance: - * @from: point from where to compute the distance - * @to: point to where to compute the distance - * - * Creates a size for the given distance. Note that both width and height - * can be negative if the coordinate of @to is smaller than @from in the - * corresponding dimension. - * - * Returns: a new size - **/ -GtkCanvasVector * -gtk_canvas_vector_new_distance (const GtkCanvasVector *from, - const GtkCanvasVector *to) -{ - GtkCanvasVector *self; - graphene_vec2_t minus_one; - - g_return_val_if_fail (from != NULL, NULL); - g_return_val_if_fail (to != NULL, NULL); - - graphene_vec2_init (&minus_one, -1.f, -1.f); - - self = gtk_canvas_vector_alloc (); - gtk_canvas_vector_init_sum (self, - graphene_vec2_one (), - from, - &minus_one, - to, - NULL); - - return self; -} - -char * -gtk_canvas_vector_to_string (const GtkCanvasVector *self) -{ - GString *string; - - g_return_val_if_fail (self != NULL, NULL); - - string = g_string_new (""); - - gtk_canvas_vector_print (self, string); - - return g_string_free (string, FALSE); -} - -GtkCanvasVector * -gtk_canvas_vector_copy (const GtkCanvasVector *self) -{ - GtkCanvasVector *copy; - - g_return_val_if_fail (self != NULL, NULL); - - copy = gtk_canvas_vector_alloc (); - gtk_canvas_vector_init_copy (copy, self); - - return copy; -} - -void -gtk_canvas_vector_free (GtkCanvasVector *self) -{ - gtk_canvas_vector_finish (self); - - g_slice_free (GtkCanvasVector, self); -} - diff --git a/gtk/gtkcanvasvector.h b/gtk/gtkcanvasvector.h deleted file mode 100644 index 7af8fc2f7b..0000000000 --- a/gtk/gtkcanvasvector.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright © 2022 Benjamin Otte - * - * 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/>. - * - * Authors: Benjamin Otte <otte@gnome.org> - */ - - -#ifndef __GTK_CANVAS_VECTOR_H__ -#define __GTK_CANVAS_VECTOR_H__ - -#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) -#error "Only <gtk/gtk.h> can be included directly." -#endif - -#include <gtk/gtktypes.h> -#include <graphene.h> - -G_BEGIN_DECLS - -#define GTK_TYPE_CANVAS_VECTOR (gtk_canvas_vector_get_type ()) - -GDK_AVAILABLE_IN_ALL -GType gtk_canvas_vector_get_type (void) G_GNUC_CONST; - -GDK_AVAILABLE_IN_ALL -GtkCanvasVector * gtk_canvas_vector_copy (const GtkCanvasVector *self); -GDK_AVAILABLE_IN_ALL -void gtk_canvas_vector_free (GtkCanvasVector *self); - -GDK_AVAILABLE_IN_ALL -gboolean gtk_canvas_vector_eval (const GtkCanvasVector *self, - graphene_vec2_t *result) G_GNUC_WARN_UNUSED_RESULT; -GDK_AVAILABLE_IN_ALL -char * gtk_canvas_vector_to_string (const GtkCanvasVector *self); -GDK_AVAILABLE_IN_ALL -void gtk_canvas_vector_print (const GtkCanvasVector *self, - GString *string); - -GDK_AVAILABLE_IN_ALL -GtkCanvasVector * gtk_canvas_vector_new (float x, - float y); -GDK_AVAILABLE_IN_ALL -GtkCanvasVector * gtk_canvas_vector_new_distance (const GtkCanvasVector *from, - const GtkCanvasVector *to); -GDK_AVAILABLE_IN_ALL -GtkCanvasVector * gtk_canvas_vector_new_from_box (const GtkCanvasBox *box, - float origin_x, - float origin_y); - -typedef enum { - GTK_CANVAS_ITEM_MEASURE_MIN_FOR_MIN, - GTK_CANVAS_ITEM_MEASURE_MIN_FOR_NAT, - GTK_CANVAS_ITEM_MEASURE_NAT_FOR_MIN, - GTK_CANVAS_ITEM_MEASURE_NAT_FOR_NAT -} GtkCanvasItemMeasure; - -GDK_AVAILABLE_IN_ALL -const GtkCanvasVector * gtk_canvas_vector_get_item_measure (GtkCanvasItem *item, - GtkCanvasItemMeasure measure); -G_END_DECLS - -#endif /* __GTK_VECTOR_H__ */ diff --git a/gtk/gtkcanvasvectorimpl.c b/gtk/gtkcanvasvectorimpl.c deleted file mode 100644 index 6b1d657b38..0000000000 --- a/gtk/gtkcanvasvectorimpl.c +++ /dev/null @@ -1,512 +0,0 @@ -/* - * Copyright © 2022 Benjamin Otte - * - * 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/>. - * - * Authors: Benjamin Otte <otte@gnome.org> - */ - - -/** - * GtkCanvasVector: - * - * `GtkCanvasVector` describes a vector in a `GtkCanvas`. - */ - -#include "config.h" - -#include "gtkcanvasvectorprivate.h" - -/* {{{ Boilerplate */ - -struct _GtkCanvasVectorClass -{ - const char *type_name; - - void (* copy) (GtkCanvasVector *self, - const GtkCanvasVector *source); - void (* finish) (GtkCanvasVector *self); - void (* print) (const GtkCanvasVector *self, - GString *string); - gboolean (* eval) (const GtkCanvasVector *self, - graphene_vec2_t *result); -}; - -/* }}} */ -/* {{{ INVALID */ - -static void -gtk_canvas_vector_invalid_copy (GtkCanvasVector *vector, - const GtkCanvasVector *source_vector) -{ - gtk_canvas_vector_init_invalid (vector); -} - -static void -gtk_canvas_vector_invalid_finish (GtkCanvasVector *vector) -{ -} - -static void -gtk_canvas_vector_invalid_print (const GtkCanvasVector *vector, - GString *string) -{ - g_string_append (string, "#error"); -} - -static gboolean -gtk_canvas_vector_invalid_eval (const GtkCanvasVector *vector, - graphene_vec2_t *result) -{ - return FALSE; -} - -static const GtkCanvasVectorClass GTK_CANVAS_VECTOR_INVALID_CLASS = -{ - "GtkCanvasVectorInvalid", - gtk_canvas_vector_invalid_copy, - gtk_canvas_vector_invalid_finish, - gtk_canvas_vector_invalid_print, - gtk_canvas_vector_invalid_eval, -}; - -void -gtk_canvas_vector_init_invalid (GtkCanvasVector *vector) -{ - vector->class = >K_CANVAS_VECTOR_INVALID_CLASS; -} - -gboolean -gtk_canvas_vector_is_invalid (GtkCanvasVector *vector) -{ - return vector->class == >K_CANVAS_VECTOR_INVALID_CLASS; -} - -/* }}} */ -/* {{{ CONSTANT */ - -static void -gtk_canvas_vector_constant_copy (GtkCanvasVector *vector, - const GtkCanvasVector *source_vector) -{ - const GtkCanvasVectorConstant *source = &source_vector->constant; - - gtk_canvas_vector_init_constant_from_vector (vector, &source->value); -} - -static void -gtk_canvas_vector_constant_finish (GtkCanvasVector *vector) -{ -} - -static void -gtk_canvas_vector_constant_print (const GtkCanvasVector *vector, - GString *string) -{ - const GtkCanvasVectorConstant *self = &vector->constant; - - g_string_append_printf (string, "[%g, %g]", - graphene_vec2_get_x (&self->value), - graphene_vec2_get_y (&self->value)); -} - -static gboolean -gtk_canvas_vector_constant_eval (const GtkCanvasVector *vector, - graphene_vec2_t *result) -{ - const GtkCanvasVectorConstant *self = &vector->constant; - - graphene_vec2_init_from_vec2 (result, &self->value); - - return TRUE; -} - -static const GtkCanvasVectorClass GTK_CANVAS_VECTOR_CONSTANT_CLASS = -{ - "GtkCanvasVectorConstant", - gtk_canvas_vector_constant_copy, - gtk_canvas_vector_constant_finish, - gtk_canvas_vector_constant_print, - gtk_canvas_vector_constant_eval, -}; - -void -gtk_canvas_vector_init_constant_from_vector (GtkCanvasVector *vector, - const graphene_vec2_t *value) -{ - GtkCanvasVectorConstant *self = &vector->constant; - - self->class = >K_CANVAS_VECTOR_CONSTANT_CLASS; - graphene_vec2_init_from_vec2 (&self->value, value); -} - -void -gtk_canvas_vector_init_constant (GtkCanvasVector *vector, - float x, - float y) -{ - graphene_vec2_t v; - - graphene_vec2_init (&v, x, y); - gtk_canvas_vector_init_constant_from_vector (vector, &v); -} - -/* }}} */ -/* {{{ SUM */ - -static void -gtk_canvas_vector_sum_copy (GtkCanvasVector *vector, - const GtkCanvasVector *source_vector); - -static void -gtk_canvas_vector_sum_finish (GtkCanvasVector *vector) -{ - GtkCanvasVectorSum *self = &vector->sum; - gsize i; - - for (i = 0; i < self->n_summands; i++) - { - gtk_canvas_vector_finish (&self->summands[i].value); - } - - g_free (self->summands); -} - -static void -gtk_canvas_vector_sum_print (const GtkCanvasVector *vector, - GString *string) -{ - const GtkCanvasVectorSum *self = &vector->sum; - gsize i; - - for (i = 0; i < self->n_summands; i++) - { - if (i > 0) - g_string_append (string, " + "); - if (!graphene_vec2_equal (&self->summands[i].scale, graphene_vec2_one())) - { - g_string_append_printf (string, "[%g, %g] * ", - graphene_vec2_get_x (&self->summands[i].scale), - graphene_vec2_get_y (&self->summands[i].scale)); - } - gtk_canvas_vector_print (&self->summands[i].value, string); - } -} - -static gboolean -gtk_canvas_vector_sum_eval (const GtkCanvasVector *vector, - graphene_vec2_t *result) -{ - const GtkCanvasVectorSum *self = &vector->sum; - gsize i; - - if (!gtk_canvas_vector_eval (&self->summands[0].value, result)) - return FALSE; - graphene_vec2_multiply (&self->summands[0].scale, result, result); - - for (i = 1; i < self->n_summands; i++) - { - graphene_vec2_t tmp; - - if (!gtk_canvas_vector_eval (&self->summands[i].value, &tmp)) - return FALSE; - graphene_vec2_multiply (&self->summands[i].scale, &tmp, &tmp); - graphene_vec2_add (&tmp, result, result); - } - - return TRUE; -} - -static const GtkCanvasVectorClass GTK_CANVAS_VECTOR_SUM_CLASS = -{ - "GtkCanvasVectorSum", - gtk_canvas_vector_sum_copy, - gtk_canvas_vector_sum_finish, - gtk_canvas_vector_sum_print, - gtk_canvas_vector_sum_eval, -}; - -static void -gtk_canvas_vector_sum_copy (GtkCanvasVector *vector, - const GtkCanvasVector *source_vector) -{ - GtkCanvasVectorSum *self = &vector->sum; - const GtkCanvasVectorSum *source = &source_vector->sum; - gsize i; - - self->class = >K_CANVAS_VECTOR_SUM_CLASS; - self->summands = g_new (GtkCanvasVectorSummand, source->n_summands); - self->n_summands = source->n_summands; - for (i = 0; i < self->n_summands; i++) - { - graphene_vec2_init_from_vec2 (&self->summands[i].scale, - &source->summands[i].scale); - gtk_canvas_vector_init_copy (&self->summands[i].value, - &source->summands[i].value); - } -} - -void -gtk_canvas_vector_init_sum (GtkCanvasVector *vector, - const graphene_vec2_t *scale, - ...) -{ - GtkCanvasVectorSum *self = &vector->sum; - GArray *array; - GtkCanvasVectorSummand summand; - va_list args; - - g_assert (scale != NULL); - - self->class = >K_CANVAS_VECTOR_SUM_CLASS; - - array = g_array_new (FALSE, FALSE, sizeof (GtkCanvasVectorSummand)); - va_start (args, scale); - - while (scale) - { - graphene_vec2_init_from_vec2 (&summand.scale, scale); - gtk_canvas_vector_init_copy (&summand.value, va_arg (args, const GtkCanvasVector *)); - g_array_append_val (array, summand); - scale = va_arg (args, const graphene_vec2_t *); - } - va_end (args); - - self->n_summands = array->len; - self->summands = (GtkCanvasVectorSummand *) g_array_free (array, FALSE); -} - -/* }}} */ -/* {{{ MULTIPLY */ - -static void -gtk_canvas_vector_multiply_copy (GtkCanvasVector *vector, - const GtkCanvasVector *source_vector) -{ - const GtkCanvasVectorMultiply *source = &source_vector->multiply; - - gtk_canvas_vector_init_multiply (vector, source->a, source->b); -} - -static void -gtk_canvas_vector_multiply_finish (GtkCanvasVector *vector) -{ - const GtkCanvasVectorMultiply *self = &vector->multiply; - - gtk_canvas_vector_free (self->a); - gtk_canvas_vector_free (self->b); -} - -static void -gtk_canvas_vector_multiply_print (const GtkCanvasVector *vector, - GString *string) -{ - const GtkCanvasVectorMultiply *self = &vector->multiply; - - gtk_canvas_vector_print (self->a, string); - g_string_append (string, " * "); - gtk_canvas_vector_print (self->b, string); -} - -static gboolean -gtk_canvas_vector_multiply_eval (const GtkCanvasVector *vector, - graphene_vec2_t *result) -{ - const GtkCanvasVectorMultiply *self = &vector->multiply; - graphene_vec2_t a, b; - - if (!gtk_canvas_vector_eval (self->a, &a) || - !gtk_canvas_vector_eval (self->b, &b)) - return FALSE; - - graphene_vec2_multiply (&a, &b, result); - return TRUE; -} - -static const GtkCanvasVectorClass GTK_CANVAS_VECTOR_MULTIPLY_CLASS = -{ - "GtkCanvasVectorMultiply", - gtk_canvas_vector_multiply_copy, - gtk_canvas_vector_multiply_finish, - gtk_canvas_vector_multiply_print, - gtk_canvas_vector_multiply_eval, -}; - -void -gtk_canvas_vector_init_multiply (GtkCanvasVector *vector, - const GtkCanvasVector *a, - const GtkCanvasVector *b) -{ - GtkCanvasVectorMultiply *self = &vector->multiply; - - self->class = >K_CANVAS_VECTOR_MULTIPLY_CLASS; - - self->a = gtk_canvas_vector_copy (a); - self->b = gtk_canvas_vector_copy (b); -} - -/* }}} */ -/* {{{ VARIABLE */ - -static void -gtk_canvas_vector_init_variable_with_variable (GtkCanvasVector *vector, - const char *name, - GtkCanvasVector *variable); - -static void -gtk_canvas_vector_variable_copy (GtkCanvasVector *vector, - const GtkCanvasVector *source_vector) -{ - const GtkCanvasVectorVariable *source = &source_vector->variable; - - gtk_canvas_vector_init_variable_with_variable (vector, - source->name, - g_rc_box_acquire (source->variable)); -} - -static void -gtk_canvas_vector_variable_finish (GtkCanvasVector *vector) -{ - const GtkCanvasVectorVariable *self = &vector->variable; - - g_free (self->name); - g_rc_box_release (self->variable); -} - -static void -gtk_canvas_vector_variable_print (const GtkCanvasVector *vector, - GString *string) -{ - const GtkCanvasVectorVariable *self = &vector->variable; - - g_string_append (string, self->name); -} - -static gboolean -gtk_canvas_vector_variable_eval (const GtkCanvasVector *vector, - graphene_vec2_t *result) -{ - const GtkCanvasVectorVariable *self = &vector->variable; - - return gtk_canvas_vector_eval (self->variable, result); -} - -static const GtkCanvasVectorClass GTK_CANVAS_VECTOR_VARIABLE_CLASS = -{ - "GtkCanvasVectorVariable", - gtk_canvas_vector_variable_copy, - gtk_canvas_vector_variable_finish, - gtk_canvas_vector_variable_print, - gtk_canvas_vector_variable_eval, -}; - -static void -gtk_canvas_vector_init_variable_with_variable (GtkCanvasVector *vector, - const char *name, - GtkCanvasVector *variable) -{ - GtkCanvasVectorVariable *self = &vector->variable; - - self->class = >K_CANVAS_VECTOR_VARIABLE_CLASS; - - self->name = g_strdup (name); - self->variable = variable; -} - -void -gtk_canvas_vector_init_variable (GtkCanvasVector *vector, - const char *format, - ...) -{ - GtkCanvasVector *variable; - char *name; - va_list args; - - variable = g_rc_box_new (GtkCanvasVector); - gtk_canvas_vector_init_invalid (variable); - - va_start (args, format); - name = g_strdup_vprintf (format, args); - va_end (args); - - gtk_canvas_vector_init_variable_with_variable (vector, name, variable); - - g_free (name); -} - -GtkCanvasVector * -gtk_canvas_vector_get_variable (GtkCanvasVector *vector) -{ - GtkCanvasVectorVariable *self = &vector->variable; - - g_return_val_if_fail (self->class == >K_CANVAS_VECTOR_VARIABLE_CLASS, NULL); - - return self->variable; -} - -/* }}} */ -/* {{{ PUBLIC API */ - -void -gtk_canvas_vector_init_copy (GtkCanvasVector *self, - const GtkCanvasVector *source) -{ - source->class->copy (self, source); -} - -void -gtk_canvas_vector_finish (GtkCanvasVector *self) -{ - self->class->finish (self); -} - -/** - * gtk_canvas_vector_eval: - * @self: a `GtkCanvasVector` - * @result: (out) (caller-allocates): The current value - * of the vector - * - * Evaluates the given vector and returns its x and y value. - * - * If the vector currently has no value - because it - * references and object that has been deleted or because - * the value is in the process of being updated - %FALSE - * is returned. Think of this as an exception being raised. - * - * Returns: %FALSE if the vector currently has no value. - **/ -gboolean -gtk_canvas_vector_eval (const GtkCanvasVector *self, - graphene_vec2_t *result) -{ - g_return_val_if_fail (self != NULL, FALSE); - g_return_val_if_fail (result != NULL, FALSE); - - if (self->class->eval (self, result)) - return TRUE; - - graphene_vec2_init_from_vec2 (result, graphene_vec2_zero ()); - return FALSE; -} - -void -gtk_canvas_vector_print (const GtkCanvasVector *self, - GString *string) -{ - g_return_if_fail (self != NULL); - g_return_if_fail (string != NULL); - - self->class->print (self, string); -} - diff --git a/gtk/gtkcanvasvectorprivate.h b/gtk/gtkcanvasvectorprivate.h deleted file mode 100644 index 86171e62fb..0000000000 --- a/gtk/gtkcanvasvectorprivate.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright © 2022 Benjamin Otte - * - * 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/>. - * - * Authors: Benjamin Otte <otte@gnome.org> - */ - -#ifndef __GTK_CANVAS_VECTOR_PRIVATE_H__ -#define __GTK_CANVAS_VECTOR_PRIVATE_H__ - -#include "gtkcanvasvector.h" - -#include <graphene.h> - -G_BEGIN_DECLS - -typedef struct _GtkCanvasVector GtkCanvasVector; -typedef struct _GtkCanvasVectorClass GtkCanvasVectorClass; -typedef struct _GtkCanvasVectorConstant GtkCanvasVectorConstant; -typedef struct _GtkCanvasVectorMultiply GtkCanvasVectorMultiply; -typedef struct _GtkCanvasVectorSum GtkCanvasVectorSum; -typedef struct _GtkCanvasVectorSummand GtkCanvasVectorSummand; -typedef struct _GtkCanvasVectorVariable GtkCanvasVectorVariable; - -struct _GtkCanvasVectorConstant -{ - const GtkCanvasVectorClass *class; - - graphene_vec2_t value; -}; - -struct _GtkCanvasVectorMultiply -{ - const GtkCanvasVectorClass *class; - - GtkCanvasVector *a; - GtkCanvasVector *b; -}; - -struct _GtkCanvasVectorSum -{ - const GtkCanvasVectorClass *class; - - graphene_vec2_t constant; - - gsize n_summands; - GtkCanvasVectorSummand *summands; -}; - -struct _GtkCanvasVectorVariable -{ - const GtkCanvasVectorClass *class; - - char *name; - /* a GtkRcBox */ - GtkCanvasVector *variable; -}; - -struct _GtkCanvasVector -{ - union { - const GtkCanvasVectorClass *class; - GtkCanvasVectorConstant constant; - GtkCanvasVectorMultiply multiply; - GtkCanvasVectorSum sum; - GtkCanvasVectorVariable variable; - }; -}; - -struct _GtkCanvasVectorSummand -{ - graphene_vec2_t scale; - GtkCanvasVector value; -}; - - -void gtk_canvas_vector_init_copy (GtkCanvasVector *self, - const GtkCanvasVector *source); -void gtk_canvas_vector_finish (GtkCanvasVector *self); - -void gtk_canvas_vector_init_invalid (GtkCanvasVector *vector); -void gtk_canvas_vector_init_constant (GtkCanvasVector *vector, - float x, - float y); -void gtk_canvas_vector_init_constant_from_vector (GtkCanvasVector *vector, - const graphene_vec2_t *value); -void gtk_canvas_vector_init_sum (GtkCanvasVector *vector, - const graphene_vec2_t *scale, - ...) G_GNUC_NULL_TERMINATED; -void gtk_canvas_vector_init_multiply (GtkCanvasVector *vector, - const GtkCanvasVector *a, - const GtkCanvasVector *b); - -void gtk_canvas_vector_init_variable (GtkCanvasVector *vector, - const char *format, - ...) G_GNUC_PRINTF(2,3); -GtkCanvasVector * gtk_canvas_vector_get_variable (GtkCanvasVector *vector); - -gboolean gtk_canvas_vector_is_invalid (GtkCanvasVector *vector); - -G_END_DECLS - -#endif /* __GTK_CANVAS_VECTOR_PRIVATE_H__ */ diff --git a/gtk/gtktypes.h b/gtk/gtktypes.h index da949a6bd9..cbf6045163 100644 --- a/gtk/gtktypes.h +++ b/gtk/gtktypes.h @@ -40,7 +40,6 @@ typedef struct _GtkBuilderScope GtkBuilderScope; typedef struct _GtkCanvas GtkCanvas; typedef struct _GtkCanvasBox GtkCanvasBox; typedef struct _GtkCanvasItem GtkCanvasItem; -typedef struct _GtkCanvasVector GtkCanvasVector; typedef struct _GtkCssStyleChange GtkCssStyleChange; typedef struct _GtkEventController GtkEventController; typedef struct _GtkGesture GtkGesture; diff --git a/gtk/meson.build b/gtk/meson.build index 594808de9e..35b2774400 100644 --- a/gtk/meson.build +++ b/gtk/meson.build @@ -32,7 +32,6 @@ gtk_private_sources = files([ 'gtkbuilderprecompile.c', 'gtkbuiltinicon.c', 'gtkcellareaboxcontext.c', - 'gtkcanvasvectorimpl.c', 'gtkcoloreditor.c', 'gtkcolorplane.c', 'gtkcolorpicker.c', @@ -186,7 +185,6 @@ gtk_public_sources = files([ 'gtkcanvas.c', 'gtkcanvasbox.c', 'gtkcanvasitem.c', - 'gtkcanvasvector.c', 'gtkcellarea.c', 'gtkcellareabox.c', 'gtkcellareacontext.c', @@ -481,7 +479,6 @@ gtk_public_headers = files([ 'gtkcanvas.h', 'gtkcanvasbox.h', 'gtkcanvasitem.h', - 'gtkcanvasvector.h', 'gtkcenterbox.h', 'gtkcenterlayout.h', 'gtkcellarea.h', |