diff --git a/ChangeLog b/ChangeLog index ce002b2774..59aaafdbdc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +2006-08-31 Michael Natterer + + * app/core/gimpgradient.[ch] (gimp_gradient_has_fg_bg_segments): + new funtion which returns TRUE if any of the gradient's segments + refer to FG of BG. + + (gimp_gradient_segment_get_left_color_type) + (gimp_gradient_segment_set_left_color_type) + (gimp_gradient_segment_get_right_color_type) + (gimp_gradient_segment_set_right_color_type): new accessors for + the new GimpGradientColor stuff. + + (gimp_gradient_segment_split_midpoint) + (gimp_gradient_segment_range_flip) + (gimp_gradient_segment_range_replicate): split, flip and replicate + the segments' color_types too. + + * app/widgets/gimpviewrenderer.[ch]: added virtual functions + ::set_context() and ::invalidate() and call them. + + * app/widgets/gimpviewrenderergradient.[ch]: implement the virtual + functions. Connect to the context's "foreground-changed" and + "background-changed" signals if the gradient contains FG or BG + colors and invalidate the renderer whenever they change. + + * app/core/gimp-gradients.c: removed signal connections which + invalidated the gradients on FG/BG changes of the user context. + 2006-08-31 Sven Neumann * plug-ins/pygimp/plug-ins/happy-valley-relief.py: fixed a typo. diff --git a/app/core/gimp-gradients.c b/app/core/gimp-gradients.c index e4425e4126..2c9da26c54 100644 --- a/app/core/gimp-gradients.c +++ b/app/core/gimp-gradients.c @@ -23,13 +23,10 @@ #include -#include "libgimpcolor/gimpcolor.h" - #include "core-types.h" #include "gimp.h" #include "gimpcontainer.h" -#include "gimpcontext.h" #include "gimpdatafactory.h" #include "gimpgradient.h" @@ -44,12 +41,9 @@ /* local function prototypes */ -static GimpGradient * gimp_gradients_add_gradient (Gimp *gimp, - const gchar *name, - const gchar *id); -static void gimp_gradients_color_changed (GimpContext *context, - const GimpRGB *fg, - Gimp *gimp); +static GimpGradient * gimp_gradients_add_gradient (Gimp *gimp, + const gchar *name, + const gchar *id); /* public functions */ @@ -80,13 +74,6 @@ gimp_gradients_init (Gimp *gimp) _("FG to Transparent"), FG_TRANSPARENT_KEY); gradient->segments->right_color_type = GIMP_GRADIENT_COLOR_FOREGROUND_TRANSPARENT; - - g_signal_connect (gimp->user_context, "foreground-changed", - G_CALLBACK (gimp_gradients_color_changed), - gimp); - g_signal_connect (gimp->user_context, "background-changed", - G_CALLBACK (gimp_gradients_color_changed), - gimp); } @@ -112,27 +99,3 @@ gimp_gradients_add_gradient (Gimp *gimp, return gradient; } - -static void -gimp_gradients_color_changed (GimpContext *context, - const GimpRGB *color, - Gimp *gimp) -{ - GimpGradient *gradient; - - gradient = g_object_get_data (G_OBJECT (gimp), FG_BG_RGB_KEY); - if (gradient) - gimp_viewable_invalidate_preview (GIMP_VIEWABLE (gradient)); - - gradient = g_object_get_data (G_OBJECT (gimp), FG_BG_HSV_CCW_KEY); - if (gradient) - gimp_viewable_invalidate_preview (GIMP_VIEWABLE (gradient)); - - gradient = g_object_get_data (G_OBJECT (gimp), FG_BG_HSV_CW_KEY); - if (gradient) - gimp_viewable_invalidate_preview (GIMP_VIEWABLE (gradient)); - - gradient = g_object_get_data (G_OBJECT (gimp), FG_TRANSPARENT_KEY); - if (gradient) - gimp_viewable_invalidate_preview (GIMP_VIEWABLE (gradient)); -} diff --git a/app/core/gimpgradient.c b/app/core/gimpgradient.c index 54799b2bc8..701db8f9c6 100644 --- a/app/core/gimpgradient.c +++ b/app/core/gimpgradient.c @@ -515,6 +515,22 @@ gimp_gradient_get_segment_at (GimpGradient *gradient, return gimp_gradient_get_segment_at_internal (gradient, NULL, pos); } +gboolean +gimp_gradient_has_fg_bg_segments (GimpGradient *gradient) +{ + GimpGradientSegment *segment; + + g_return_val_if_fail (GIMP_IS_GRADIENT (gradient), FALSE); + + for (segment = gradient->segments; segment; segment = segment->next) + if (segment->left_color_type != GIMP_GRADIENT_COLOR_FIXED || + segment->right_color_type != GIMP_GRADIENT_COLOR_FIXED) + return TRUE; + + return FALSE; +} + + /* gradient segment functions */ GimpGradientSegment * @@ -660,12 +676,11 @@ gimp_gradient_segment_split_midpoint (GimpGradient *gradient, /* Set colors of both segments */ - newseg->right_color = lseg->right_color; + newseg->right_color_type = lseg->right_color_type; + newseg->right_color = lseg->right_color; - lseg->right_color.r = newseg->left_color.r = color.r; - lseg->right_color.g = newseg->left_color.g = color.g; - lseg->right_color.b = newseg->left_color.b = color.b; - lseg->right_color.a = newseg->left_color.a = color.a; + lseg->right_color_type = newseg->left_color_type = GIMP_GRADIENT_COLOR_FIXED; + lseg->right_color = newseg->left_color = color; /* Set parameters of new segment */ @@ -717,6 +732,9 @@ gimp_gradient_segment_split_uniform (GimpGradient *gradient, seg->right = lseg->left + (i + 1) * seg_len; seg->middle = (seg->left + seg->right) / 2.0; + seg->left_color_type = GIMP_GRADIENT_COLOR_FIXED; + seg->right_color_type = GIMP_GRADIENT_COLOR_FIXED; + gimp_gradient_get_color_at (gradient, context, lseg, seg->left, FALSE, &seg->left_color); gimp_gradient_get_color_at (gradient, context, lseg, @@ -736,9 +754,11 @@ gimp_gradient_segment_split_uniform (GimpGradient *gradient, /* Fix edges */ - tmp->left_color = lseg->left_color; + tmp->left_color_type = lseg->left_color_type; + tmp->left_color = lseg->left_color; - seg->right_color = lseg->right_color; + seg->right_color_type = lseg->right_color_type; + seg->right_color = lseg->right_color; tmp->left = lseg->left; seg->right = lseg->right; /* To squish accumulative error */ @@ -826,6 +846,56 @@ gimp_gradient_segment_set_right_color (GimpGradient *gradient, gimp_data_thaw (GIMP_DATA (gradient)); } +GimpGradientColor +gimp_gradient_segment_get_left_color_type (GimpGradient *gradient, + GimpGradientSegment *seg) +{ + g_return_val_if_fail (GIMP_IS_GRADIENT (gradient), 0); + g_return_val_if_fail (seg != NULL, 0); + + return seg->left_color_type; +} + +void +gimp_gradient_segment_set_left_color_type (GimpGradient *gradient, + GimpGradientSegment *seg, + GimpGradientColor color_type) +{ + g_return_if_fail (GIMP_IS_GRADIENT (gradient)); + g_return_if_fail (seg != NULL); + + gimp_data_freeze (GIMP_DATA (gradient)); + + seg->left_color_type = color_type; + + gimp_data_thaw (GIMP_DATA (gradient)); +} + +GimpGradientColor +gimp_gradient_segment_get_right_color_type (GimpGradient *gradient, + GimpGradientSegment *seg) +{ + g_return_val_if_fail (GIMP_IS_GRADIENT (gradient), 0); + g_return_val_if_fail (seg != NULL, 0); + + return seg->right_color_type; +} + +void +gimp_gradient_segment_set_right_color_type (GimpGradient *gradient, + GimpGradientSegment *seg, + GimpGradientColor color_type) +{ + g_return_if_fail (GIMP_IS_GRADIENT (gradient)); + g_return_if_fail (seg != NULL); + + gimp_data_freeze (GIMP_DATA (gradient)); + + seg->right_color_type = color_type; + + gimp_data_thaw (GIMP_DATA (gradient)); +} + gdouble gimp_gradient_segment_get_left_pos (GimpGradient *gradient, GimpGradientSegment *seg) @@ -1152,9 +1222,11 @@ gimp_gradient_segment_range_flip (GimpGradient *gradient, seg->middle = left + right - oseg->middle; seg->right = left + right - oseg->left; - seg->left_color = oseg->right_color; + seg->left_color_type = oseg->right_color_type; + seg->left_color = oseg->right_color; - seg->right_color = oseg->left_color; + seg->right_color_type = oseg->left_color_type; + seg->right_color = oseg->left_color; switch (oseg->type) { @@ -1309,8 +1381,11 @@ gimp_gradient_segment_range_replicate (GimpGradient *gradient, seg->middle = new_left + factor * (oseg->middle - sel_left); seg->right = new_left + factor * (oseg->right - sel_left); - seg->left_color = oseg->left_color; - seg->right_color = oseg->right_color; + seg->left_color_type = oseg->left_color_type; + seg->left_color = oseg->left_color; + + seg->right_color_type = oseg->right_color_type; + seg->right_color = oseg->right_color; seg->type = oseg->type; seg->color = oseg->color; diff --git a/app/core/gimpgradient.h b/app/core/gimpgradient.h index 13e76cbd95..fee0ed6c68 100644 --- a/app/core/gimpgradient.h +++ b/app/core/gimpgradient.h @@ -83,6 +83,8 @@ GimpGradientSegment * gimp_gradient_get_color_at (GimpGradient *gradien GimpGradientSegment * gimp_gradient_get_segment_at (GimpGradient *grad, gdouble pos); +gboolean gimp_gradient_has_fg_bg_segments (GimpGradient *gradient); + /* gradient segment functions */ @@ -125,6 +127,27 @@ void gimp_gradient_segment_set_right_color (GimpGradient *gradient, GimpGradientSegment *seg, const GimpRGB *color); + +GimpGradientColor +gimp_gradient_segment_get_left_color_type (GimpGradient *gradient, + GimpGradientSegment *seg); + +void +gimp_gradient_segment_set_left_color_type (GimpGradient *gradient, + GimpGradientSegment *seg, + GimpGradientColor color_type); + + +GimpGradientColor +gimp_gradient_segment_get_right_color_type (GimpGradient *gradient, + GimpGradientSegment *seg); + +void +gimp_gradient_segment_set_right_color_type (GimpGradient *gradient, + GimpGradientSegment *seg, + GimpGradientColor color_type); + + /* Position Setting/Getting Routines */ /* (Setters return the position after it was set) */ gdouble gimp_gradient_segment_get_left_pos (GimpGradient *gradient, diff --git a/app/widgets/gimpviewrenderer.c b/app/widgets/gimpviewrenderer.c index 46b9803c5d..94708824c4 100644 --- a/app/widgets/gimpviewrenderer.c +++ b/app/widgets/gimpviewrenderer.c @@ -51,23 +51,26 @@ enum }; -static void gimp_view_renderer_dispose (GObject *object); -static void gimp_view_renderer_finalize (GObject *object); +static void gimp_view_renderer_dispose (GObject *object); +static void gimp_view_renderer_finalize (GObject *object); -static gboolean gimp_view_renderer_idle_update (GimpViewRenderer *renderer); -static void gimp_view_renderer_real_draw (GimpViewRenderer *renderer, - GdkWindow *window, - GtkWidget *widget, - const GdkRectangle *draw_area, - const GdkRectangle *expose_area); -static void gimp_view_renderer_real_render (GimpViewRenderer *renderer, - GtkWidget *widget); +static gboolean gimp_view_renderer_idle_update (GimpViewRenderer *renderer); +static void gimp_view_renderer_real_set_context (GimpViewRenderer *renderer, + GimpContext *context); +static void gimp_view_renderer_real_invalidate (GimpViewRenderer *renderer); +static void gimp_view_renderer_real_draw (GimpViewRenderer *renderer, + GdkWindow *window, + GtkWidget *widget, + const GdkRectangle *draw_area, + const GdkRectangle *expose_area); +static void gimp_view_renderer_real_render (GimpViewRenderer *renderer, + GtkWidget *widget); -static void gimp_view_renderer_size_changed (GimpViewRenderer *renderer, - GimpViewable *viewable); -static GdkGC * gimp_view_renderer_create_gc (GimpViewRenderer *renderer, - GdkWindow *window, - GtkWidget *widget); +static void gimp_view_renderer_size_changed (GimpViewRenderer *renderer, + GimpViewable *viewable); +static GdkGC * gimp_view_renderer_create_gc (GimpViewRenderer *renderer, + GdkWindow *window, + GtkWidget *widget); G_DEFINE_TYPE (GimpViewRenderer, gimp_view_renderer, G_TYPE_OBJECT) @@ -100,6 +103,8 @@ gimp_view_renderer_class_init (GimpViewRendererClass *klass) object_class->finalize = gimp_view_renderer_finalize; klass->update = NULL; + klass->set_context = gimp_view_renderer_real_set_context; + klass->invalidate = gimp_view_renderer_real_invalidate; klass->draw = gimp_view_renderer_real_draw; klass->render = gimp_view_renderer_real_render; @@ -153,6 +158,9 @@ gimp_view_renderer_dispose (GObject *object) if (renderer->viewable) gimp_view_renderer_set_viewable (renderer, NULL); + if (renderer->context) + gimp_view_renderer_set_context (renderer, NULL); + gimp_view_renderer_remove_idle (renderer); G_OBJECT_CLASS (parent_class)->dispose (object); @@ -200,10 +208,12 @@ gimp_view_renderer_new_internal (GimpContext *context, renderer = g_object_new (gimp_view_renderer_type_from_viewable_type (viewable_type), NULL); - renderer->context = context; renderer->viewable_type = viewable_type; renderer->is_popup = is_popup ? TRUE : FALSE; + if (context) + gimp_view_renderer_set_context (renderer, context); + return renderer; } @@ -272,7 +282,8 @@ gimp_view_renderer_set_context (GimpViewRenderer *renderer, if (context != renderer->context) { - renderer->context = context; + GIMP_VIEW_RENDERER_GET_CLASS (renderer)->set_context (renderer, + context); if (renderer->viewable) gimp_view_renderer_invalidate (renderer); @@ -521,9 +532,12 @@ gimp_view_renderer_invalidate (GimpViewRenderer *renderer) g_return_if_fail (GIMP_IS_VIEW_RENDERER (renderer)); if (renderer->idle_id) - g_source_remove (renderer->idle_id); + { + g_source_remove (renderer->idle_id); + renderer->idle_id = 0; + } - renderer->needs_render = TRUE; + GIMP_VIEW_RENDERER_GET_CLASS (renderer)->invalidate (renderer); renderer->idle_id = g_idle_add_full (G_PRIORITY_LOW, @@ -669,6 +683,19 @@ gimp_view_renderer_idle_update (GimpViewRenderer *renderer) return FALSE; } +static void +gimp_view_renderer_real_set_context (GimpViewRenderer *renderer, + GimpContext *context) +{ + renderer->context = context; +} + +static void +gimp_view_renderer_real_invalidate (GimpViewRenderer *renderer) +{ + renderer->needs_render = TRUE; +} + static void gimp_view_renderer_real_draw (GimpViewRenderer *renderer, GdkWindow *window, diff --git a/app/widgets/gimpviewrenderer.h b/app/widgets/gimpviewrenderer.h index e52aed07cb..f96b1bb6f3 100644 --- a/app/widgets/gimpviewrenderer.h +++ b/app/widgets/gimpviewrenderer.h @@ -78,16 +78,19 @@ struct _GimpViewRendererClass gint frame_top; /* signals */ - void (* update) (GimpViewRenderer *renderer); + void (* update) (GimpViewRenderer *renderer); /* virtual functions */ - void (* draw) (GimpViewRenderer *renderer, - GdkWindow *window, - GtkWidget *widget, - const GdkRectangle *draw_area, - const GdkRectangle *expose_area); - void (* render) (GimpViewRenderer *renderer, - GtkWidget *widget); + void (* set_context) (GimpViewRenderer *renderer, + GimpContext *context); + void (* invalidate) (GimpViewRenderer *renderer); + void (* draw) (GimpViewRenderer *renderer, + GdkWindow *window, + GtkWidget *widget, + const GdkRectangle *draw_area, + const GdkRectangle *expose_area); + void (* render) (GimpViewRenderer *renderer, + GtkWidget *widget); }; diff --git a/app/widgets/gimpviewrenderergradient.c b/app/widgets/gimpviewrenderergradient.c index 54f9dfb794..3b3be06334 100644 --- a/app/widgets/gimpviewrenderergradient.c +++ b/app/widgets/gimpviewrenderergradient.c @@ -36,10 +36,13 @@ #include "gimpviewrenderergradient.h" -static void gimp_view_renderer_gradient_finalize (GObject *object); +static void gimp_view_renderer_gradient_finalize (GObject *object); -static void gimp_view_renderer_gradient_render (GimpViewRenderer *renderer, - GtkWidget *widget); +static void gimp_view_renderer_gradient_set_context (GimpViewRenderer *renderer, + GimpContext *context); +static void gimp_view_renderer_gradient_invalidate (GimpViewRenderer *renderer); +static void gimp_view_renderer_gradient_render (GimpViewRenderer *renderer, + GtkWidget *widget); G_DEFINE_TYPE (GimpViewRendererGradient, gimp_view_renderer_gradient, @@ -54,9 +57,11 @@ gimp_view_renderer_gradient_class_init (GimpViewRendererGradientClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); GimpViewRendererClass *renderer_class = GIMP_VIEW_RENDERER_CLASS (klass); - object_class->finalize = gimp_view_renderer_gradient_finalize; + object_class->finalize = gimp_view_renderer_gradient_finalize; - renderer_class->render = gimp_view_renderer_gradient_render; + renderer_class->set_context = gimp_view_renderer_gradient_set_context; + renderer_class->invalidate = gimp_view_renderer_gradient_invalidate; + renderer_class->render = gimp_view_renderer_gradient_render; } static void @@ -90,6 +95,88 @@ gimp_view_renderer_gradient_finalize (GObject *object) G_OBJECT_CLASS (parent_class)->finalize (object); } +static void +gimp_view_renderer_gradient_fg_bg_changed (GimpContext *context, + const GimpRGB *color, + GimpViewRenderer *renderer) +{ + g_printerr ("%s: invalidating %s\n", G_STRFUNC, + gimp_object_get_name (GIMP_OBJECT (renderer->viewable))); + + gimp_view_renderer_invalidate (renderer); +} + +static void +gimp_view_renderer_gradient_set_context (GimpViewRenderer *renderer, + GimpContext *context) +{ + GimpViewRendererGradient *rendergrad; + + rendergrad = GIMP_VIEW_RENDERER_GRADIENT (renderer); + + if (renderer->context && rendergrad->has_fg_bg_segments) + { + g_signal_handlers_disconnect_by_func (renderer->context, + gimp_view_renderer_gradient_fg_bg_changed, + renderer); + } + + GIMP_VIEW_RENDERER_CLASS (parent_class)->set_context (renderer, context); + + if (renderer->context && rendergrad->has_fg_bg_segments) + { + g_signal_connect (renderer->context, "foreground-changed", + G_CALLBACK (gimp_view_renderer_gradient_fg_bg_changed), + renderer); + g_signal_connect (renderer->context, "background-changed", + G_CALLBACK (gimp_view_renderer_gradient_fg_bg_changed), + renderer); + + gimp_view_renderer_gradient_fg_bg_changed (renderer->context, + NULL, + renderer); + } +} + +static void +gimp_view_renderer_gradient_invalidate (GimpViewRenderer *renderer) +{ + GimpViewRendererGradient *rendergrad; + gboolean has_fg_bg_segments = FALSE; + + rendergrad = GIMP_VIEW_RENDERER_GRADIENT (renderer); + + if (renderer->viewable) + has_fg_bg_segments = + gimp_gradient_has_fg_bg_segments (GIMP_GRADIENT (renderer->viewable)); + + if (rendergrad->has_fg_bg_segments != has_fg_bg_segments) + { + if (renderer->context) + { + if (rendergrad->has_fg_bg_segments) + { + g_signal_handlers_disconnect_by_func (renderer->context, + gimp_view_renderer_gradient_fg_bg_changed, + renderer); + } + else + { + g_signal_connect (renderer->context, "foreground-changed", + G_CALLBACK (gimp_view_renderer_gradient_fg_bg_changed), + renderer); + g_signal_connect (renderer->context, "background-changed", + G_CALLBACK (gimp_view_renderer_gradient_fg_bg_changed), + renderer); + } + } + + rendergrad->has_fg_bg_segments = has_fg_bg_segments; + } + + GIMP_VIEW_RENDERER_CLASS (parent_class)->invalidate (renderer); +} + static void gimp_view_renderer_gradient_render (GimpViewRenderer *renderer, GtkWidget *widget) diff --git a/app/widgets/gimpviewrenderergradient.h b/app/widgets/gimpviewrenderergradient.h index 7c3a78a834..741fbe9bcc 100644 --- a/app/widgets/gimpviewrenderergradient.h +++ b/app/widgets/gimpviewrenderergradient.h @@ -45,6 +45,7 @@ struct _GimpViewRendererGradient gdouble right; gboolean reverse; + gboolean has_fg_bg_segments; }; struct _GimpViewRendererGradientClass