new funtion which returns TRUE if any of the gradient's segments refer to

2006-08-31  Michael Natterer  <mitch@gimp.org>

	* 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.
This commit is contained in:
Michael Natterer 2006-08-31 18:47:13 +00:00 committed by Michael Natterer
parent 50a8cde19a
commit 663b44c988
8 changed files with 290 additions and 83 deletions

View File

@ -1,3 +1,31 @@
2006-08-31 Michael Natterer <mitch@gimp.org>
* 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 <sven@gimp.org>
* plug-ins/pygimp/plug-ins/happy-valley-relief.py: fixed a typo.

View File

@ -23,13 +23,10 @@
#include <glib-object.h>
#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));
}

View File

@ -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;

View File

@ -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,

View File

@ -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,

View File

@ -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);
};

View File

@ -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)

View File

@ -45,6 +45,7 @@ struct _GimpViewRendererGradient
gdouble right;
gboolean reverse;
gboolean has_fg_bg_segments;
};
struct _GimpViewRendererGradientClass