Commit 61417b91 authored by jaycox's avatar jaycox
Browse files

merged the registered clone option from the hollywood branch. Made the


	* app/clone.c: merged the registered clone option from the
 	hollywood branch.  Made the source for unaligned clones reset
 	after each stroke.  Make sure we don't crash if the source
 	drawable gets destroyed.
parent 4f553ed2
1999-02-05 Jay Cox <jaycox@earthlink.net>
* app/clone.c: merged the registered clone option from the
hollywood branch. Made the source for unaligned clones reset
after each stroke. Make sure we don't crash if the source
drawable gets destroyed.
Thu Feb 4 17:22:25 EST 1999 Peter Teichman <pat4@acpub.duke.edu>
* app/convolve.c: added pressure support for the Convolve tool
......
......@@ -42,6 +42,13 @@ typedef enum
PatternClone
} CloneType;
typedef enum
{
AlignNo,
AlignYes,
AlignRegister
} AlignType;
/* forward function declarations */
static void clone_draw (Tool *);
static void clone_motion (PaintCore *, GimpDrawable *, GimpDrawable *, CloneType, int, int);
......@@ -62,7 +69,7 @@ typedef struct _CloneOptions CloneOptions;
struct _CloneOptions
{
CloneType type;
int aligned;
AlignType aligned;
};
/* local variables */
......@@ -80,24 +87,17 @@ static CloneOptions *clone_options = NULL;
static void
clone_toggle_update (GtkWidget *widget,
gpointer data)
clone_type_callback (GtkWidget *w,
gpointer client_data)
{
int *toggle_val;
toggle_val = (int *) data;
if (GTK_TOGGLE_BUTTON (widget)->active)
*toggle_val = TRUE;
else
*toggle_val = FALSE;
clone_options->type =(CloneType) client_data;
}
static void
clone_type_callback (GtkWidget *w,
align_type_callback (GtkWidget *w,
gpointer client_data)
{
clone_options->type =(CloneType) client_data;
clone_options->aligned =(AlignType) client_data;
}
static CloneOptions *
......@@ -106,7 +106,6 @@ create_clone_options (void)
CloneOptions *options;
GtkWidget *vbox;
GtkWidget *label;
GtkWidget *aligned_toggle;
GtkWidget *radio_frame;
GtkWidget *radio_box;
GtkWidget *radio_button;
......@@ -117,11 +116,17 @@ create_clone_options (void)
N_("Image Source"),
N_("Pattern Source")
};
char *align_names[3] =
{
N_("Non Aligned"),
N_("Aligned"),
N_("Registered")
};
/* the new options structure */
options = (CloneOptions *) g_malloc (sizeof (CloneOptions));
options->type = ImageClone;
options->aligned = TRUE;
options->aligned = AlignNo;
/* the main vbox */
vbox = gtk_vbox_new (FALSE, 1);
......@@ -152,21 +157,63 @@ create_clone_options (void)
gtk_widget_show (radio_box);
gtk_widget_show (radio_frame);
/* the aligned toggle button */
aligned_toggle = gtk_check_button_new_with_label (_("Aligned"));
gtk_box_pack_start (GTK_BOX (vbox), aligned_toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (aligned_toggle), "toggled",
(GtkSignalFunc) clone_toggle_update,
&options->aligned);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (aligned_toggle), options->aligned);
gtk_widget_show (aligned_toggle);
/* the radio frame and box */
radio_frame = gtk_frame_new (_("Alignment"));
gtk_box_pack_start (GTK_BOX (vbox), radio_frame, FALSE, FALSE, 0);
radio_box = gtk_vbox_new (FALSE, 1);
gtk_container_add (GTK_CONTAINER (radio_frame), radio_box);
/* the radio buttons */
group = NULL;
for (i = 0; i < 3; i++)
{
radio_button = gtk_radio_button_new_with_label (group, align_names[i]);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button));
gtk_signal_connect (GTK_OBJECT (radio_button), "toggled",
(GtkSignalFunc) align_type_callback,
(void *)((long) i));
gtk_box_pack_start (GTK_BOX (radio_box), radio_button, FALSE, FALSE, 0);
gtk_widget_show (radio_button);
}
gtk_widget_show (radio_box);
gtk_widget_show (radio_frame);
/* Register this selection options widget with the main tools options dialog */
tools_register_options (CLONE, vbox);
return options;
}
static void
clone_src_drawable_destroyed_cb(GimpDrawable *drawable,
GimpDrawable **src_drawable)
{
if (drawable == *src_drawable)
{
*src_drawable = NULL;
the_src_gdisp = NULL;
}
}
static void
clone_set_src_drawable(GimpDrawable *drawable)
{
if (src_drawable_ == drawable)
return;
if (src_drawable_)
gtk_signal_disconnect_by_data(GTK_OBJECT (src_drawable_), &src_drawable_);
src_drawable_ = drawable;
if (drawable)
{
gtk_signal_connect (GTK_OBJECT (drawable),
"destroy",
GTK_SIGNAL_FUNC (clone_src_drawable_destroyed_cb),
&src_drawable_);
}
}
void *
clone_paint_func (PaintCore *paint_core,
GimpDrawable *drawable,
......@@ -175,6 +222,7 @@ clone_paint_func (PaintCore *paint_core,
GDisplay * gdisp;
GDisplay * src_gdisp;
int x1, y1, x2, y2;
static int orig_src_x, orig_src_y;
gdisp = (GDisplay *) active_tool->gdisp_ptr;
......@@ -198,17 +246,21 @@ clone_paint_func (PaintCore *paint_core,
{
dest_x = x1;
dest_y = y1;
if (first)
if (clone_options->aligned == AlignRegister)
{
offset_x = 0;
offset_y = 0;
}
else if (first)
{
offset_x = src_x - dest_x;
offset_y = src_y - dest_y;
first = FALSE;
}
else
{
src_x = dest_x + offset_x;
src_y = dest_y + offset_y;
}
src_x = dest_x + offset_x;
src_y = dest_y + offset_y;
clone_motion (paint_core, drawable, src_drawable_, clone_options->type, offset_x, offset_y);
}
......@@ -220,14 +272,17 @@ clone_paint_func (PaintCore *paint_core,
if (paint_core->state & ControlMask)
{
the_src_gdisp = gdisp;
src_drawable_ = drawable;
clone_set_src_drawable(drawable);
src_x = paint_core->curx;
src_y = paint_core->cury;
first = TRUE;
}
else if (clone_options->aligned == FALSE)
else if (clone_options->aligned == AlignNo)
{
first = TRUE;
orig_src_x = src_x;
orig_src_y = src_y;
}
if (clone_options->type == PatternClone)
if (!get_active_pattern ())
g_message (_("No patterns available for this operation."));
......@@ -235,6 +290,11 @@ clone_paint_func (PaintCore *paint_core,
case FINISH_PAINT :
draw_core_stop (paint_core->core, active_tool);
if (clone_options->aligned == AlignNo && !first)
{
src_x = orig_src_x;
src_y = orig_src_y;
}
return NULL;
break;
......@@ -611,9 +671,9 @@ clone_invoker (Argument *args)
double src_x, src_y;
int num_strokes;
double *stroke_array;
CloneType int_value;
int int_value;
int i;
drawable = NULL;
num_strokes = 0;
......
......@@ -42,6 +42,13 @@ typedef enum
PatternClone
} CloneType;
typedef enum
{
AlignNo,
AlignYes,
AlignRegister
} AlignType;
/* forward function declarations */
static void clone_draw (Tool *);
static void clone_motion (PaintCore *, GimpDrawable *, GimpDrawable *, CloneType, int, int);
......@@ -62,7 +69,7 @@ typedef struct _CloneOptions CloneOptions;
struct _CloneOptions
{
CloneType type;
int aligned;
AlignType aligned;
};
/* local variables */
......@@ -80,24 +87,17 @@ static CloneOptions *clone_options = NULL;
static void
clone_toggle_update (GtkWidget *widget,
gpointer data)
clone_type_callback (GtkWidget *w,
gpointer client_data)
{
int *toggle_val;
toggle_val = (int *) data;
if (GTK_TOGGLE_BUTTON (widget)->active)
*toggle_val = TRUE;
else
*toggle_val = FALSE;
clone_options->type =(CloneType) client_data;
}
static void
clone_type_callback (GtkWidget *w,
align_type_callback (GtkWidget *w,
gpointer client_data)
{
clone_options->type =(CloneType) client_data;
clone_options->aligned =(AlignType) client_data;
}
static CloneOptions *
......@@ -106,7 +106,6 @@ create_clone_options (void)
CloneOptions *options;
GtkWidget *vbox;
GtkWidget *label;
GtkWidget *aligned_toggle;
GtkWidget *radio_frame;
GtkWidget *radio_box;
GtkWidget *radio_button;
......@@ -117,11 +116,17 @@ create_clone_options (void)
N_("Image Source"),
N_("Pattern Source")
};
char *align_names[3] =
{
N_("Non Aligned"),
N_("Aligned"),
N_("Registered")
};
/* the new options structure */
options = (CloneOptions *) g_malloc (sizeof (CloneOptions));
options->type = ImageClone;
options->aligned = TRUE;
options->aligned = AlignNo;
/* the main vbox */
vbox = gtk_vbox_new (FALSE, 1);
......@@ -152,21 +157,63 @@ create_clone_options (void)
gtk_widget_show (radio_box);
gtk_widget_show (radio_frame);
/* the aligned toggle button */
aligned_toggle = gtk_check_button_new_with_label (_("Aligned"));
gtk_box_pack_start (GTK_BOX (vbox), aligned_toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (aligned_toggle), "toggled",
(GtkSignalFunc) clone_toggle_update,
&options->aligned);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (aligned_toggle), options->aligned);
gtk_widget_show (aligned_toggle);
/* the radio frame and box */
radio_frame = gtk_frame_new (_("Alignment"));
gtk_box_pack_start (GTK_BOX (vbox), radio_frame, FALSE, FALSE, 0);
radio_box = gtk_vbox_new (FALSE, 1);
gtk_container_add (GTK_CONTAINER (radio_frame), radio_box);
/* the radio buttons */
group = NULL;
for (i = 0; i < 3; i++)
{
radio_button = gtk_radio_button_new_with_label (group, align_names[i]);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button));
gtk_signal_connect (GTK_OBJECT (radio_button), "toggled",
(GtkSignalFunc) align_type_callback,
(void *)((long) i));
gtk_box_pack_start (GTK_BOX (radio_box), radio_button, FALSE, FALSE, 0);
gtk_widget_show (radio_button);
}
gtk_widget_show (radio_box);
gtk_widget_show (radio_frame);
/* Register this selection options widget with the main tools options dialog */
tools_register_options (CLONE, vbox);
return options;
}
static void
clone_src_drawable_destroyed_cb(GimpDrawable *drawable,
GimpDrawable **src_drawable)
{
if (drawable == *src_drawable)
{
*src_drawable = NULL;
the_src_gdisp = NULL;
}
}
static void
clone_set_src_drawable(GimpDrawable *drawable)
{
if (src_drawable_ == drawable)
return;
if (src_drawable_)
gtk_signal_disconnect_by_data(GTK_OBJECT (src_drawable_), &src_drawable_);
src_drawable_ = drawable;
if (drawable)
{
gtk_signal_connect (GTK_OBJECT (drawable),
"destroy",
GTK_SIGNAL_FUNC (clone_src_drawable_destroyed_cb),
&src_drawable_);
}
}
void *
clone_paint_func (PaintCore *paint_core,
GimpDrawable *drawable,
......@@ -175,6 +222,7 @@ clone_paint_func (PaintCore *paint_core,
GDisplay * gdisp;
GDisplay * src_gdisp;
int x1, y1, x2, y2;
static int orig_src_x, orig_src_y;
gdisp = (GDisplay *) active_tool->gdisp_ptr;
......@@ -198,17 +246,21 @@ clone_paint_func (PaintCore *paint_core,
{
dest_x = x1;
dest_y = y1;
if (first)
if (clone_options->aligned == AlignRegister)
{
offset_x = 0;
offset_y = 0;
}
else if (first)
{
offset_x = src_x - dest_x;
offset_y = src_y - dest_y;
first = FALSE;
}
else
{
src_x = dest_x + offset_x;
src_y = dest_y + offset_y;
}
src_x = dest_x + offset_x;
src_y = dest_y + offset_y;
clone_motion (paint_core, drawable, src_drawable_, clone_options->type, offset_x, offset_y);
}
......@@ -220,14 +272,17 @@ clone_paint_func (PaintCore *paint_core,
if (paint_core->state & ControlMask)
{
the_src_gdisp = gdisp;
src_drawable_ = drawable;
clone_set_src_drawable(drawable);
src_x = paint_core->curx;
src_y = paint_core->cury;
first = TRUE;
}
else if (clone_options->aligned == FALSE)
else if (clone_options->aligned == AlignNo)
{
first = TRUE;
orig_src_x = src_x;
orig_src_y = src_y;
}
if (clone_options->type == PatternClone)
if (!get_active_pattern ())
g_message (_("No patterns available for this operation."));
......@@ -235,6 +290,11 @@ clone_paint_func (PaintCore *paint_core,
case FINISH_PAINT :
draw_core_stop (paint_core->core, active_tool);
if (clone_options->aligned == AlignNo && !first)
{
src_x = orig_src_x;
src_y = orig_src_y;
}
return NULL;
break;
......@@ -611,9 +671,9 @@ clone_invoker (Argument *args)
double src_x, src_y;
int num_strokes;
double *stroke_array;
CloneType int_value;
int int_value;
int i;
drawable = NULL;
num_strokes = 0;
......
......@@ -42,6 +42,13 @@ typedef enum
PatternClone
} CloneType;
typedef enum
{
AlignNo,
AlignYes,
AlignRegister
} AlignType;
/* forward function declarations */
static void clone_draw (Tool *);
static void clone_motion (PaintCore *, GimpDrawable *, GimpDrawable *, CloneType, int, int);
......@@ -62,7 +69,7 @@ typedef struct _CloneOptions CloneOptions;
struct _CloneOptions
{
CloneType type;
int aligned;
AlignType aligned;
};
/* local variables */
......@@ -80,24 +87,17 @@ static CloneOptions *clone_options = NULL;
static void
clone_toggle_update (GtkWidget *widget,
gpointer data)
clone_type_callback (GtkWidget *w,
gpointer client_data)
{
int *toggle_val;
toggle_val = (int *) data;
if (GTK_TOGGLE_BUTTON (widget)->active)
*toggle_val = TRUE;
else
*toggle_val = FALSE;
clone_options->type =(CloneType) client_data;
}
static void
clone_type_callback (GtkWidget *w,
align_type_callback (GtkWidget *w,
gpointer client_data)
{
clone_options->type =(CloneType) client_data;
clone_options->aligned =(AlignType) client_data;
}
static CloneOptions *
......@@ -106,7 +106,6 @@ create_clone_options (void)
CloneOptions *options;
GtkWidget *vbox;
GtkWidget *label;
GtkWidget *aligned_toggle;
GtkWidget *radio_frame;
GtkWidget *radio_box;
GtkWidget *radio_button;
......@@ -117,11 +116,17 @@ create_clone_options (void)
N_("Image Source"),
N_("Pattern Source")
};
char *align_names[3] =
{
N_("Non Aligned"),
N_("Aligned"),
N_("Registered")
};
/* the new options structure */
options = (CloneOptions *) g_malloc (sizeof (CloneOptions));
options->type = ImageClone;
options->aligned = TRUE;
options->aligned = AlignNo;
/* the main vbox */
vbox = gtk_vbox_new (FALSE, 1);
......@@ -152,21 +157,63 @@ create_clone_options (void)
gtk_widget_show (radio_box);
gtk_widget_show (radio_frame);
/* the aligned toggle button */
aligned_toggle = gtk_check_button_new_with_label (_("Aligned"));
gtk_box_pack_start (GTK_BOX (vbox), aligned_toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (aligned_toggle), "toggled",
(GtkSignalFunc) clone_toggle_update,
&options->aligned);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (aligned_toggle), options->aligned);
gtk_widget_show (aligned_toggle);
/* the radio frame and box */
radio_frame = gtk_frame_new (_("Alignment"));
gtk_box_pack_start (GTK_BOX (vbox), radio_frame, FALSE, FALSE, 0);
radio_box = gtk_vbox_new (FALSE, 1);
gtk_container_add (GTK_CONTAINER (radio_frame), radio_box);
/* the radio buttons */
group = NULL;
for (i = 0; i < 3; i++)
{
radio_button = gtk_radio_button_new_with_label (group, align_names[i]);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio_button));
gtk_signal_connect (GTK_OBJECT (radio_button), "toggled",
(GtkSignalFunc) align_type_callback,
(void *)((long) i));
gtk_box_pack_start (GTK_BOX (radio_box), radio_button, FALSE, FALSE, 0);
gtk_widget_show (radio_button);
}
gtk_widget_show (radio_box);
gtk_widget_show (radio_frame);
/* Register this selection options widget with the main tools options dialog */
tools_register_options (CLONE, vbox);
return options;
}
static void
clone_src_drawable_destroyed_cb(GimpDrawable *drawable,
GimpDrawable **src_drawable)
{
if (drawable == *src_drawable)
{
*src_drawable = NULL;
the_src_gdisp = NULL;
}
}
static void
clone_set_src_drawable(GimpDrawable *drawable)
{
if (src_drawable_ == drawable)
return;
if (src_drawable_)
gtk_signal_disconnect_by_data(GTK_OBJECT (src_drawable_), &src_drawable_);
src_drawable_ = drawable;
if (drawable)
{
gtk_signal_connect (GTK_OBJECT (drawable),
"destroy",
GTK_SIGNAL_FUNC (clone_src_drawable_destroyed_cb),
&src_drawable_);
}
}
void *
clone_paint_func (PaintCore *paint_core,
GimpDrawable *drawable,
......@@ -175,6 +222,7 @@ clone_paint_func (PaintCore *paint_core,
GDisplay * gdisp;
GDisplay * src_gdisp;
int x1, y1, x2, y2;
static int orig_src_x, orig_src_y;
gdisp = (GDisplay *) active_tool->gdisp_ptr;
......@@ -198,17 +246,21 @@ clone_paint_func (PaintCore *paint_core,
{
dest_x = x1;
dest_y = y1;
if (first)
if (clone_options->aligned == AlignRegister)
{
offset_x = 0;
offset_y = 0;
}
else if (first)
{