mirror of
https://gitlab.gnome.org/GNOME/gimp
synced 2024-10-21 03:52:33 +00:00
app: add an "update" signal to GimpCanvasItem
which gets emitted when the item wants to be redrawn: - Emit "update" it when any item property changes - Groups connect to their children and forward "update" for them - The shell connects to its group of canvas items and exposed the affected area - Remove gimp_display_shell_expose_item() - Move all the shell's item group code into gimpdisplayshell-items.c
This commit is contained in:
parent
d3f19baf0d
commit
d9cd9f8a07
|
@ -72,6 +72,9 @@ static void gimp_canvas_group_draw (GimpCanvasItem *item,
|
|||
cairo_t *cr);
|
||||
static GdkRegion * gimp_canvas_group_get_extents (GimpCanvasItem *item,
|
||||
GimpDisplayShell *shell);
|
||||
static void gimp_canvas_group_child_update (GimpCanvasItem *item,
|
||||
GdkRegion *region,
|
||||
GimpCanvasGroup *group);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GimpCanvasGroup, gimp_canvas_group, GIMP_TYPE_CANVAS_ITEM)
|
||||
|
@ -222,6 +225,17 @@ gimp_canvas_group_get_extents (GimpCanvasItem *item,
|
|||
return region;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_canvas_group_child_update (GimpCanvasItem *item,
|
||||
GdkRegion *region,
|
||||
GimpCanvasGroup *group)
|
||||
{
|
||||
g_signal_emit_by_name (group, "update", region);
|
||||
}
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
||||
GimpCanvasItem *
|
||||
gimp_canvas_group_new (GimpDisplayShell *shell)
|
||||
{
|
||||
|
@ -237,6 +251,7 @@ gimp_canvas_group_add_item (GimpCanvasGroup *group,
|
|||
GimpCanvasItem *item)
|
||||
{
|
||||
GimpCanvasGroupPrivate *private;
|
||||
GdkRegion *region;
|
||||
|
||||
g_return_if_fail (GIMP_IS_CANVAS_GROUP (group));
|
||||
g_return_if_fail (GIMP_IS_CANVAS_ITEM (item));
|
||||
|
@ -251,6 +266,18 @@ gimp_canvas_group_add_item (GimpCanvasGroup *group,
|
|||
gimp_canvas_item_suspend_filling (item);
|
||||
|
||||
private->items = g_list_append (private->items, g_object_ref (item));
|
||||
|
||||
region = gimp_canvas_item_get_extents (item);
|
||||
|
||||
if (region)
|
||||
{
|
||||
g_signal_emit_by_name (group, "update", region);
|
||||
gdk_region_destroy (region);
|
||||
}
|
||||
|
||||
g_signal_connect (item, "update",
|
||||
G_CALLBACK (gimp_canvas_group_child_update),
|
||||
group);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -258,6 +285,7 @@ gimp_canvas_group_remove_item (GimpCanvasGroup *group,
|
|||
GimpCanvasItem *item)
|
||||
{
|
||||
GimpCanvasGroupPrivate *private;
|
||||
GdkRegion *region;
|
||||
|
||||
g_return_if_fail (GIMP_IS_CANVAS_GROUP (group));
|
||||
g_return_if_fail (GIMP_IS_CANVAS_ITEM (item));
|
||||
|
@ -267,6 +295,19 @@ gimp_canvas_group_remove_item (GimpCanvasGroup *group,
|
|||
g_return_if_fail (g_list_find (private->items, item));
|
||||
|
||||
private->items = g_list_remove (private->items, item);
|
||||
|
||||
region = gimp_canvas_item_get_extents (item);
|
||||
|
||||
if (region)
|
||||
{
|
||||
g_signal_emit_by_name (group, "update", region);
|
||||
gdk_region_destroy (region);
|
||||
}
|
||||
|
||||
g_signal_handlers_disconnect_by_func (item,
|
||||
gimp_canvas_group_child_update,
|
||||
group);
|
||||
|
||||
g_object_unref (item);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,9 +23,11 @@
|
|||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "libgimpmath/gimpmath.h"
|
||||
|
||||
#include "display-types.h"
|
||||
|
||||
#include "libgimpmath/gimpmath.h"
|
||||
#include "core/gimpmarshal.h"
|
||||
|
||||
#include "gimpcanvasitem.h"
|
||||
#include "gimpdisplayshell.h"
|
||||
|
@ -40,6 +42,12 @@ enum
|
|||
PROP_HIGHLIGHT
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
UPDATE,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
|
||||
typedef struct _GimpCanvasItemPrivate GimpCanvasItemPrivate;
|
||||
|
||||
|
@ -69,6 +77,10 @@ static void gimp_canvas_item_get_property (GObject *object,
|
|||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void
|
||||
gimp_canvas_item_dispatch_properties_changed (GObject *object,
|
||||
guint n_pspecs,
|
||||
GParamSpec **pspecs);
|
||||
|
||||
static void gimp_canvas_item_real_draw (GimpCanvasItem *item,
|
||||
GimpDisplayShell *shell,
|
||||
|
@ -88,20 +100,34 @@ G_DEFINE_TYPE (GimpCanvasItem, gimp_canvas_item,
|
|||
|
||||
#define parent_class gimp_canvas_item_parent_class
|
||||
|
||||
static guint item_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
|
||||
static void
|
||||
gimp_canvas_item_class_init (GimpCanvasItemClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->constructed = gimp_canvas_item_constructed;
|
||||
object_class->set_property = gimp_canvas_item_set_property;
|
||||
object_class->get_property = gimp_canvas_item_get_property;
|
||||
object_class->constructed = gimp_canvas_item_constructed;
|
||||
object_class->set_property = gimp_canvas_item_set_property;
|
||||
object_class->get_property = gimp_canvas_item_get_property;
|
||||
object_class->dispatch_properties_changed = gimp_canvas_item_dispatch_properties_changed;
|
||||
|
||||
klass->draw = gimp_canvas_item_real_draw;
|
||||
klass->get_extents = gimp_canvas_item_real_get_extents;
|
||||
klass->stroke = gimp_canvas_item_real_stroke;
|
||||
klass->fill = gimp_canvas_item_real_fill;
|
||||
klass->update = NULL;
|
||||
klass->draw = gimp_canvas_item_real_draw;
|
||||
klass->get_extents = gimp_canvas_item_real_get_extents;
|
||||
klass->stroke = gimp_canvas_item_real_stroke;
|
||||
klass->fill = gimp_canvas_item_real_fill;
|
||||
|
||||
item_signals[UPDATE] =
|
||||
g_signal_new ("update",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (GimpCanvasItemClass, update),
|
||||
NULL, NULL,
|
||||
gimp_marshal_VOID__POINTER,
|
||||
G_TYPE_NONE, 1,
|
||||
G_TYPE_POINTER);
|
||||
|
||||
g_object_class_install_property (object_class, PROP_SHELL,
|
||||
g_param_spec_object ("shell",
|
||||
|
@ -202,6 +228,41 @@ gimp_canvas_item_get_property (GObject *object,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_canvas_item_dispatch_properties_changed (GObject *object,
|
||||
guint n_pspecs,
|
||||
GParamSpec **pspecs)
|
||||
{
|
||||
GimpCanvasItem *item = GIMP_CANVAS_ITEM (object);
|
||||
GdkRegion *before;
|
||||
GdkRegion *region;
|
||||
|
||||
before = gimp_canvas_item_get_extents (item);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispatch_properties_changed (object,
|
||||
n_pspecs,
|
||||
pspecs);
|
||||
|
||||
region = gimp_canvas_item_get_extents (item);
|
||||
|
||||
if (! region)
|
||||
{
|
||||
region = before;
|
||||
}
|
||||
else if (before)
|
||||
{
|
||||
gdk_region_union (region, before);
|
||||
gdk_region_destroy (before);
|
||||
}
|
||||
|
||||
if (region)
|
||||
{
|
||||
g_signal_emit (object, item_signals[UPDATE], 0,
|
||||
region);
|
||||
gdk_region_destroy (region);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_canvas_item_real_draw (GimpCanvasItem *item,
|
||||
GimpDisplayShell *shell,
|
||||
|
|
|
@ -44,6 +44,11 @@ struct _GimpCanvasItemClass
|
|||
{
|
||||
GimpObjectClass parent_class;
|
||||
|
||||
/* signals */
|
||||
void (* update) (GimpCanvasItem *item,
|
||||
GdkRegion *region);
|
||||
|
||||
/* virtual functions */
|
||||
void (* draw) (GimpCanvasItem *item,
|
||||
GimpDisplayShell *shell,
|
||||
cairo_t *cr);
|
||||
|
|
|
@ -44,43 +44,15 @@ gimp_display_shell_expose_area (GimpDisplayShell *shell,
|
|||
gtk_widget_queue_draw_area (shell->canvas, x, y, w, h);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_display_shell_expose_region (GimpDisplayShell *shell,
|
||||
gdouble x1,
|
||||
gdouble y1,
|
||||
gdouble x2,
|
||||
gdouble y2,
|
||||
gint border)
|
||||
{
|
||||
const gint x = floor (x1);
|
||||
const gint y = floor (y1);
|
||||
const gint w = ceil (x2) - x;
|
||||
const gint h = ceil (y2) - y;
|
||||
|
||||
gimp_display_shell_expose_area (shell,
|
||||
x - border,
|
||||
y - border,
|
||||
w + 2 * border,
|
||||
h + 2 * border);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_display_shell_expose_item (GimpDisplayShell *shell,
|
||||
GimpCanvasItem *item)
|
||||
gimp_display_shell_expose_region (GimpDisplayShell *shell,
|
||||
GdkRegion *region)
|
||||
{
|
||||
GdkRegion *region;
|
||||
|
||||
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
||||
g_return_if_fail (GIMP_IS_CANVAS_ITEM (item));
|
||||
g_return_if_fail (region != NULL);
|
||||
|
||||
region = gimp_canvas_item_get_extents (item);
|
||||
|
||||
if (region)
|
||||
{
|
||||
gdk_window_invalidate_region (gtk_widget_get_window (shell->canvas),
|
||||
region, TRUE);
|
||||
gdk_region_destroy (region);
|
||||
}
|
||||
gdk_window_invalidate_region (gtk_widget_get_window (shell->canvas),
|
||||
region, TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -95,10 +67,21 @@ gimp_display_shell_expose_vectors (GimpDisplayShell *shell,
|
|||
|
||||
if (gimp_vectors_bounds (vectors, &x1, &y1, &x2, &y2))
|
||||
{
|
||||
gint x, y, w, h;
|
||||
|
||||
gimp_display_shell_transform_xy_f (shell, x1, y1, &x1, &y1);
|
||||
gimp_display_shell_transform_xy_f (shell, x2, y2, &x2, &y2);
|
||||
|
||||
gimp_display_shell_expose_region (shell, x1, y1, x2, y2, 2);
|
||||
x = floor (x1);
|
||||
y = floor (y1);
|
||||
w = ceil (x2) - x;
|
||||
h = ceil (y2) - y;
|
||||
|
||||
gimp_display_shell_expose_area (shell,
|
||||
x - 2,
|
||||
y - 2,
|
||||
w + 4,
|
||||
h + 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,8 @@ void gimp_display_shell_expose_area (GimpDisplayShell *shell,
|
|||
gint y,
|
||||
gint w,
|
||||
gint h);
|
||||
void gimp_display_shell_expose_item (GimpDisplayShell *shell,
|
||||
GimpCanvasItem *item);
|
||||
void gimp_display_shell_expose_region (GimpDisplayShell *shell,
|
||||
GdkRegion *region);
|
||||
void gimp_display_shell_expose_vectors (GimpDisplayShell *shell,
|
||||
GimpVectors *vectors);
|
||||
void gimp_display_shell_expose_full (GimpDisplayShell *shell);
|
||||
|
|
|
@ -550,8 +550,6 @@ gimp_display_shell_guide_add_handler (GimpImage *image,
|
|||
|
||||
gimp_canvas_proxy_group_add_item (group, guide, item);
|
||||
g_object_unref (item);
|
||||
|
||||
gimp_display_shell_expose_item (shell, item);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -560,11 +558,6 @@ gimp_display_shell_guide_remove_handler (GimpImage *image,
|
|||
GimpDisplayShell *shell)
|
||||
{
|
||||
GimpCanvasProxyGroup *group = GIMP_CANVAS_PROXY_GROUP (shell->guides);
|
||||
GimpCanvasItem *item;
|
||||
|
||||
item = gimp_canvas_proxy_group_get_item (group, guide);
|
||||
|
||||
gimp_display_shell_expose_item (shell, item);
|
||||
|
||||
gimp_canvas_proxy_group_remove_item (group, guide);
|
||||
}
|
||||
|
@ -579,14 +572,10 @@ gimp_display_shell_guide_move_handler (GimpImage *image,
|
|||
|
||||
item = gimp_canvas_proxy_group_get_item (group, guide);
|
||||
|
||||
gimp_display_shell_expose_item (shell, item);
|
||||
|
||||
g_object_set (item,
|
||||
"orientation", gimp_guide_get_orientation (guide),
|
||||
"position", gimp_guide_get_position (guide),
|
||||
NULL);
|
||||
|
||||
gimp_display_shell_expose_item (shell, item);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -619,8 +608,6 @@ gimp_display_shell_sample_point_add_handler (GimpImage *image,
|
|||
g_object_set (item,
|
||||
"index", i,
|
||||
NULL);
|
||||
|
||||
gimp_display_shell_expose_item (shell, item);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -630,14 +617,9 @@ gimp_display_shell_sample_point_remove_handler (GimpImage *image,
|
|||
GimpDisplayShell *shell)
|
||||
{
|
||||
GimpCanvasProxyGroup *group = GIMP_CANVAS_PROXY_GROUP (shell->sample_points);
|
||||
GimpCanvasItem *item;
|
||||
GList *list;
|
||||
gint i;
|
||||
|
||||
item = gimp_canvas_proxy_group_get_item (group, sample_point);
|
||||
|
||||
gimp_display_shell_expose_item (shell, item);
|
||||
|
||||
gimp_canvas_proxy_group_remove_item (group, sample_point);
|
||||
|
||||
for (list = gimp_image_get_sample_points (image), i = 1;
|
||||
|
@ -645,14 +627,13 @@ gimp_display_shell_sample_point_remove_handler (GimpImage *image,
|
|||
list = g_list_next (list), i++)
|
||||
{
|
||||
GimpSamplePoint *sample_point = list->data;
|
||||
GimpCanvasItem *item;
|
||||
|
||||
item = gimp_canvas_proxy_group_get_item (group, sample_point);
|
||||
|
||||
g_object_set (item,
|
||||
"index", i,
|
||||
NULL);
|
||||
|
||||
gimp_display_shell_expose_item (shell, item);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -666,14 +647,10 @@ gimp_display_shell_sample_point_move_handler (GimpImage *image,
|
|||
|
||||
item = gimp_canvas_proxy_group_get_item (group, sample_point);
|
||||
|
||||
gimp_display_shell_expose_item (shell, item);
|
||||
|
||||
g_object_set (item,
|
||||
"x", sample_point->x,
|
||||
"y", sample_point->y,
|
||||
NULL);
|
||||
|
||||
gimp_display_shell_expose_item (shell, item);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -24,12 +24,60 @@
|
|||
|
||||
#include "display-types.h"
|
||||
|
||||
#include "gimpcanvasgroup.h"
|
||||
#include "gimpcanvasproxygroup.h"
|
||||
#include "gimpdisplayshell.h"
|
||||
#include "gimpdisplayshell-expose.h"
|
||||
#include "gimpdisplayshell-items.h"
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
|
||||
static void gimp_display_shell_item_update (GimpCanvasItem *item,
|
||||
GdkRegion *region,
|
||||
GimpDisplayShell *shell);
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
||||
void
|
||||
gimp_display_shell_items_init (GimpDisplayShell *shell)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
||||
|
||||
shell->canvas_item = gimp_canvas_group_new (shell);
|
||||
|
||||
shell->guides = gimp_canvas_proxy_group_new (shell);
|
||||
gimp_display_shell_add_item (shell, shell->guides);
|
||||
g_object_unref (shell->guides);
|
||||
|
||||
shell->sample_points = gimp_canvas_proxy_group_new (shell);
|
||||
gimp_display_shell_add_item (shell, shell->sample_points);
|
||||
g_object_unref (shell->sample_points);
|
||||
|
||||
g_signal_connect (shell->canvas_item, "update",
|
||||
G_CALLBACK (gimp_display_shell_item_update),
|
||||
shell);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_display_shell_items_free (GimpDisplayShell *shell)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
||||
|
||||
if (shell->canvas_item)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (shell->canvas_item,
|
||||
gimp_display_shell_item_update,
|
||||
shell);
|
||||
|
||||
g_object_unref (shell->canvas_item);
|
||||
shell->canvas_item = NULL;
|
||||
|
||||
shell->guides = NULL;
|
||||
shell->sample_points = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gimp_display_shell_add_item (GimpDisplayShell *shell,
|
||||
GimpCanvasItem *item)
|
||||
|
@ -38,8 +86,6 @@ gimp_display_shell_add_item (GimpDisplayShell *shell,
|
|||
g_return_if_fail (GIMP_IS_CANVAS_ITEM (item));
|
||||
|
||||
gimp_canvas_group_add_item (GIMP_CANVAS_GROUP (shell->canvas_item), item);
|
||||
|
||||
gimp_display_shell_expose_item (shell, item);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -49,7 +95,16 @@ gimp_display_shell_remove_item (GimpDisplayShell *shell,
|
|||
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
||||
g_return_if_fail (GIMP_IS_CANVAS_ITEM (item));
|
||||
|
||||
gimp_display_shell_expose_item (shell, item);
|
||||
|
||||
gimp_canvas_group_remove_item (GIMP_CANVAS_GROUP (shell->canvas_item), item);
|
||||
}
|
||||
|
||||
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
gimp_display_shell_item_update (GimpCanvasItem *item,
|
||||
GdkRegion *region,
|
||||
GimpDisplayShell *shell)
|
||||
{
|
||||
gimp_display_shell_expose_region (shell, region);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
#define __GIMP_DISPLAY_SHELL_ITEMS_H__
|
||||
|
||||
|
||||
void gimp_display_shell_items_init (GimpDisplayShell *shell);
|
||||
void gimp_display_shell_items_free (GimpDisplayShell *shell);
|
||||
|
||||
void gimp_display_shell_add_item (GimpDisplayShell *shell,
|
||||
GimpCanvasItem *item);
|
||||
void gimp_display_shell_remove_item (GimpDisplayShell *shell,
|
||||
|
|
|
@ -53,7 +53,6 @@
|
|||
#include "tools/tool_manager.h"
|
||||
|
||||
#include "gimpcanvas.h"
|
||||
#include "gimpcanvasproxygroup.h"
|
||||
#include "gimpdisplay.h"
|
||||
#include "gimpdisplayshell.h"
|
||||
#include "gimpdisplayshell-appearance.h"
|
||||
|
@ -64,6 +63,7 @@
|
|||
#include "gimpdisplayshell-expose.h"
|
||||
#include "gimpdisplayshell-filter.h"
|
||||
#include "gimpdisplayshell-handlers.h"
|
||||
#include "gimpdisplayshell-items.h"
|
||||
#include "gimpdisplayshell-progress.h"
|
||||
#include "gimpdisplayshell-render.h"
|
||||
#include "gimpdisplayshell-scale.h"
|
||||
|
@ -291,17 +291,7 @@ gimp_display_shell_init (GimpDisplayShell *shell)
|
|||
GIMP_DISPLAY_RENDER_BUF_WIDTH,
|
||||
GIMP_DISPLAY_RENDER_BUF_HEIGHT);
|
||||
|
||||
shell->canvas_item = gimp_canvas_group_new (shell);
|
||||
|
||||
shell->guides = gimp_canvas_proxy_group_new (shell);
|
||||
gimp_canvas_group_add_item (GIMP_CANVAS_GROUP (shell->canvas_item),
|
||||
shell->guides);
|
||||
g_object_unref (shell->guides);
|
||||
|
||||
shell->sample_points = gimp_canvas_proxy_group_new (shell);
|
||||
gimp_canvas_group_add_item (GIMP_CANVAS_GROUP (shell->canvas_item),
|
||||
shell->sample_points);
|
||||
g_object_unref (shell->sample_points);
|
||||
gimp_display_shell_items_init (shell);
|
||||
|
||||
shell->icon_size = 32;
|
||||
|
||||
|
@ -806,13 +796,7 @@ gimp_display_shell_dispose (GObject *object)
|
|||
shell->mask = NULL;
|
||||
}
|
||||
|
||||
if (shell->canvas_item)
|
||||
{
|
||||
g_object_unref (shell->canvas_item);
|
||||
shell->canvas_item = NULL;
|
||||
shell->guides = NULL;
|
||||
shell->sample_points = NULL;
|
||||
}
|
||||
gimp_display_shell_items_free (shell);
|
||||
|
||||
if (shell->event_history)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue