Commit 8b178fcb authored by Sven Neumann's avatar Sven Neumann

Implemented the "removed" signal for channels and connected qmask to it

to keep the buttons in sync when a qmask channels gets deleted manually.
Fixes bug #2516.


-Sven
parent b1307d88
Thu Jan 20 18:07:21 CET 2000 Sven Neumann <sven@gimp.org>
* app/channel.c
* app/channel.h
* app/gimpimage.c
* app/layer.c
* app/qmask.c: implemented the "removed" signal for channels and
connected qmask to it to keep the buttons in sync when a qmask
channels gets deleted manually. Fixes bug #2516.
Thu Jan 20 16:56:00 CET 2000 Sven Neumann <sven@gimp.org>
* plug-ins/gdyntext/gdyntext.c: backported the bugfix from
......
......@@ -53,21 +53,40 @@ typedef struct _EditQmaskOptions EditQmaskOptions;
/* Global variables */
/* Static variables */
/* Prototypes */
static void edit_qmask_channel_query (GDisplay *gdisp);
static void edit_qmask_channel_query (GDisplay *gdisp);
static void edit_qmask_query_ok_callback (GtkWidget *widget,
gpointer client_data);
static void edit_qmask_query_cancel_callback (GtkWidget *widget,
gpointer client_data);
static void qmask_query_scale_update (GtkAdjustment *adjustment,
gdouble *scale_val);
static void qmask_removed_callback (GtkObject *qmask,
gpointer data);
/* Actual code */
static void
qmask_query_scale_update (GtkAdjustment *adjustment, gdouble *scale_val)
qmask_query_scale_update (GtkAdjustment *adjustment,
gdouble *scale_val)
{
*scale_val = adjustment->value;
}
static void
qmask_removed_callback (GtkObject *qmask,
gpointer data)
{
GDisplay *gdisp = (GDisplay*) data;
if (!gdisp->gimage)
return;
gdisp->gimage->qmask_state = 0;
qmask_buttons_update (gdisp);
}
void
qmask_buttons_update (GDisplay *gdisp)
{
......@@ -114,9 +133,9 @@ qmask_click_handler (GtkWidget *widget,
if ((event->type == GDK_2BUTTON_PRESS) &&
(event->button == 1))
{
edit_qmask_channel_query(gdisp);
}
{
edit_qmask_channel_query(gdisp);
}
}
void
......@@ -129,11 +148,11 @@ qmask_deactivate (GtkWidget *w,
if (gdisp)
{
gimg = gdisp->gimage;
if (!gimg) return;
if (!gimg)
return;
if (!gdisp->gimage->qmask_state) {
if (!gdisp->gimage->qmask_state)
return; /* if already set do nothing */
}
undo_push_group_start (gimg, QMASK_UNDO);
......@@ -168,20 +187,21 @@ qmask_activate (GtkWidget *w,
if (gdisp)
{
gimg = gdisp->gimage;
if (!gimg) return;
if (!gimg)
return;
if (gdisp->gimage->qmask_state) {
if (gdisp->gimage->qmask_state)
return; /* If already set, do nothing */
}
/* Set the defaults */
opacity = (double) gimg->qmask_opacity;
color = gimg->qmask_color;
if ( (gmask = gimp_image_get_channel_by_name (gimg, "Qmask")) ) {
gimg->qmask_state = 1; /* if the user was clever and created his own */
return;
}
if ( (gmask = gimp_image_get_channel_by_name (gimg, "Qmask")) )
{
gimg->qmask_state = 1; /* if the user was clever and created his own */
return;
}
undo_push_group_start (gimg, QMASK_UNDO);
if (gimage_mask_is_empty(gimg))
......@@ -216,6 +236,10 @@ qmask_activate (GtkWidget *w,
}
undo_push_group_end(gimg);
gdisplays_flush();
/* connect to the removed signal, so the buttons get updated */
gtk_signal_connect (GTK_OBJECT (gmask), "removed",
GTK_SIGNAL_FUNC (qmask_removed_callback), gdisp);
}
}
......@@ -301,8 +325,9 @@ edit_qmask_channel_query (GDisplay * gdisp)
gtk_widget_show (options->query_box);
}
static void edit_qmask_query_ok_callback (GtkWidget *widget,
gpointer client_data)
static void
edit_qmask_query_ok_callback (GtkWidget *widget,
gpointer client_data)
{
EditQmaskOptions *options;
Channel *channel;
......@@ -325,27 +350,27 @@ static void edit_qmask_query_ok_callback (GtkWidget *widget,
tmpcolp = channel_get_color(channel);
for (i = 0; i < 3; i++)
{ /* don't update if color hasn't changed */
tmpcol[i] = tmpcolp[i]; /* initialize to same values */
if (options->color_panel->color[i] != tmpcolp[i])
{
tmpcol[i] = options->color_panel->color[i];
update = TRUE;
}
tmpcol[i] = tmpcolp[i]; /* initialize to same values */
if (options->color_panel->color[i] != tmpcolp[i])
{
tmpcol[i] = options->color_panel->color[i];
update = TRUE;
}
}
if (update)
{
channel_set_opacity(channel, 100*opacity/255);
channel_set_color(channel,tmpcol);
channel_update (channel);
}
{
channel_set_opacity(channel, 100*opacity/255);
channel_set_color(channel,tmpcol);
channel_update (channel);
}
}
/* update the qmask color no matter what */
for (i = 0; i < 3; i++)
{ /* TODO: should really have accessor functions for gimage private stuff */
options->gimage->qmask_color[i] = options->color_panel->color[i];
options->gimage->qmask_opacity = (gint) 100*opacity/255;
}
{ /* TODO: should really have accessor functions for gimage private stuff */
options->gimage->qmask_color[i] = options->color_panel->color[i];
options->gimage->qmask_opacity = (gint) 100*opacity/255;
}
color_panel_free (options->color_panel);
gtk_widget_destroy (options->query_box);
......@@ -364,3 +389,8 @@ edit_qmask_query_cancel_callback (GtkWidget *widget,
gtk_widget_destroy (options->query_box);
g_free (options);
}
......@@ -53,21 +53,40 @@ typedef struct _EditQmaskOptions EditQmaskOptions;
/* Global variables */
/* Static variables */
/* Prototypes */
static void edit_qmask_channel_query (GDisplay *gdisp);
static void edit_qmask_channel_query (GDisplay *gdisp);
static void edit_qmask_query_ok_callback (GtkWidget *widget,
gpointer client_data);
static void edit_qmask_query_cancel_callback (GtkWidget *widget,
gpointer client_data);
static void qmask_query_scale_update (GtkAdjustment *adjustment,
gdouble *scale_val);
static void qmask_removed_callback (GtkObject *qmask,
gpointer data);
/* Actual code */
static void
qmask_query_scale_update (GtkAdjustment *adjustment, gdouble *scale_val)
qmask_query_scale_update (GtkAdjustment *adjustment,
gdouble *scale_val)
{
*scale_val = adjustment->value;
}
static void
qmask_removed_callback (GtkObject *qmask,
gpointer data)
{
GDisplay *gdisp = (GDisplay*) data;
if (!gdisp->gimage)
return;
gdisp->gimage->qmask_state = 0;
qmask_buttons_update (gdisp);
}
void
qmask_buttons_update (GDisplay *gdisp)
{
......@@ -114,9 +133,9 @@ qmask_click_handler (GtkWidget *widget,
if ((event->type == GDK_2BUTTON_PRESS) &&
(event->button == 1))
{
edit_qmask_channel_query(gdisp);
}
{
edit_qmask_channel_query(gdisp);
}
}
void
......@@ -129,11 +148,11 @@ qmask_deactivate (GtkWidget *w,
if (gdisp)
{
gimg = gdisp->gimage;
if (!gimg) return;
if (!gimg)
return;
if (!gdisp->gimage->qmask_state) {
if (!gdisp->gimage->qmask_state)
return; /* if already set do nothing */
}
undo_push_group_start (gimg, QMASK_UNDO);
......@@ -168,20 +187,21 @@ qmask_activate (GtkWidget *w,
if (gdisp)
{
gimg = gdisp->gimage;
if (!gimg) return;
if (!gimg)
return;
if (gdisp->gimage->qmask_state) {
if (gdisp->gimage->qmask_state)
return; /* If already set, do nothing */
}
/* Set the defaults */
opacity = (double) gimg->qmask_opacity;
color = gimg->qmask_color;
if ( (gmask = gimp_image_get_channel_by_name (gimg, "Qmask")) ) {
gimg->qmask_state = 1; /* if the user was clever and created his own */
return;
}
if ( (gmask = gimp_image_get_channel_by_name (gimg, "Qmask")) )
{
gimg->qmask_state = 1; /* if the user was clever and created his own */
return;
}
undo_push_group_start (gimg, QMASK_UNDO);
if (gimage_mask_is_empty(gimg))
......@@ -216,6 +236,10 @@ qmask_activate (GtkWidget *w,
}
undo_push_group_end(gimg);
gdisplays_flush();
/* connect to the removed signal, so the buttons get updated */
gtk_signal_connect (GTK_OBJECT (gmask), "removed",
GTK_SIGNAL_FUNC (qmask_removed_callback), gdisp);
}
}
......@@ -301,8 +325,9 @@ edit_qmask_channel_query (GDisplay * gdisp)
gtk_widget_show (options->query_box);
}
static void edit_qmask_query_ok_callback (GtkWidget *widget,
gpointer client_data)
static void
edit_qmask_query_ok_callback (GtkWidget *widget,
gpointer client_data)
{
EditQmaskOptions *options;
Channel *channel;
......@@ -325,27 +350,27 @@ static void edit_qmask_query_ok_callback (GtkWidget *widget,
tmpcolp = channel_get_color(channel);
for (i = 0; i < 3; i++)
{ /* don't update if color hasn't changed */
tmpcol[i] = tmpcolp[i]; /* initialize to same values */
if (options->color_panel->color[i] != tmpcolp[i])
{
tmpcol[i] = options->color_panel->color[i];
update = TRUE;
}
tmpcol[i] = tmpcolp[i]; /* initialize to same values */
if (options->color_panel->color[i] != tmpcolp[i])
{
tmpcol[i] = options->color_panel->color[i];
update = TRUE;
}
}
if (update)
{
channel_set_opacity(channel, 100*opacity/255);
channel_set_color(channel,tmpcol);
channel_update (channel);
}
{
channel_set_opacity(channel, 100*opacity/255);
channel_set_color(channel,tmpcol);
channel_update (channel);
}
}
/* update the qmask color no matter what */
for (i = 0; i < 3; i++)
{ /* TODO: should really have accessor functions for gimage private stuff */
options->gimage->qmask_color[i] = options->color_panel->color[i];
options->gimage->qmask_opacity = (gint) 100*opacity/255;
}
{ /* TODO: should really have accessor functions for gimage private stuff */
options->gimage->qmask_color[i] = options->color_panel->color[i];
options->gimage->qmask_opacity = (gint) 100*opacity/255;
}
color_panel_free (options->color_panel);
gtk_widget_destroy (options->query_box);
......@@ -364,3 +389,8 @@ edit_qmask_query_cancel_callback (GtkWidget *widget,
gtk_widget_destroy (options->query_box);
g_free (options);
}
......@@ -31,6 +31,7 @@
#include "parasitelist.h"
#include "temp_buf.h"
#include "undo.h"
#include "gimpsignal.h"
#include "gimppreviewcache.h"
#include "libgimp/gimpintl.h"
......@@ -42,19 +43,16 @@
#include "gimplut.h"
#include "lut_funcs.h"
/*
enum {
REMOVED,
LAST_SIGNAL
};
*/
static void gimp_channel_class_init (GimpChannelClass *klass);
static void gimp_channel_init (GimpChannel *channel);
static void gimp_channel_destroy (GtkObject *object);
/*
static gint channel_signals[LAST_SIGNAL] = { 0 };
*/
static guint channel_signals[LAST_SIGNAL] = { 0 };
static GimpDrawableClass *parent_class = NULL;
......@@ -91,9 +89,11 @@ gimp_channel_class_init (GimpChannelClass *class)
object_class = (GtkObjectClass*) class;
parent_class = gtk_type_class (gimp_drawable_get_type ());
/*
channel_signals[REMOVED] =
gimp_signal_new ("removed",
0, object_class->type, 0, gimp_sigtype_void);
gtk_object_class_add_signals (object_class, channel_signals, LAST_SIGNAL);
*/
object_class->destroy = gimp_channel_destroy;
}
......@@ -307,6 +307,22 @@ gimp_channel_destroy (GtkObject *object)
}
/* The removed signal is sent out when the channel is no longer
* associcated with an image. It's needed because channels aren't
* destroyed immediately, but kept around for undo purposes. Connect
* to the removed signal to update bits of UI that are tied to a
* particular layer. */
void
channel_removed (Channel *channel,
gpointer image)
{
g_return_if_fail (channel != NULL);
g_return_if_fail (GIMP_IS_CHANNEL (channel));
gtk_signal_emit (GTK_OBJECT (channel), channel_signals[REMOVED]);
}
void
channel_scale (Channel *channel,
gint new_width,
......
......@@ -88,6 +88,7 @@ void channel_set_color (Channel *, guchar *);
Channel * channel_get_ID (gint);
void channel_delete (Channel *);
void channel_removed (Channel *, gpointer);
void channel_scale (Channel *, gint, gint);
void channel_resize (Channel *, gint, gint, gint, gint);
void channel_update (Channel *);
......
......@@ -31,6 +31,7 @@
#include "parasitelist.h"
#include "temp_buf.h"
#include "undo.h"
#include "gimpsignal.h"
#include "gimppreviewcache.h"
#include "libgimp/gimpintl.h"
......@@ -42,19 +43,16 @@
#include "gimplut.h"
#include "lut_funcs.h"
/*
enum {
REMOVED,
LAST_SIGNAL
};
*/
static void gimp_channel_class_init (GimpChannelClass *klass);
static void gimp_channel_init (GimpChannel *channel);
static void gimp_channel_destroy (GtkObject *object);
/*
static gint channel_signals[LAST_SIGNAL] = { 0 };
*/
static guint channel_signals[LAST_SIGNAL] = { 0 };
static GimpDrawableClass *parent_class = NULL;
......@@ -91,9 +89,11 @@ gimp_channel_class_init (GimpChannelClass *class)
object_class = (GtkObjectClass*) class;
parent_class = gtk_type_class (gimp_drawable_get_type ());
/*
channel_signals[REMOVED] =
gimp_signal_new ("removed",
0, object_class->type, 0, gimp_sigtype_void);
gtk_object_class_add_signals (object_class, channel_signals, LAST_SIGNAL);
*/
object_class->destroy = gimp_channel_destroy;
}
......@@ -307,6 +307,22 @@ gimp_channel_destroy (GtkObject *object)
}
/* The removed signal is sent out when the channel is no longer
* associcated with an image. It's needed because channels aren't
* destroyed immediately, but kept around for undo purposes. Connect
* to the removed signal to update bits of UI that are tied to a
* particular layer. */
void
channel_removed (Channel *channel,
gpointer image)
{
g_return_if_fail (channel != NULL);
g_return_if_fail (GIMP_IS_CHANNEL (channel));
gtk_signal_emit (GTK_OBJECT (channel), channel_signals[REMOVED]);
}
void
channel_scale (Channel *channel,
gint new_width,
......
......@@ -88,6 +88,7 @@ void channel_set_color (Channel *, guchar *);
Channel * channel_get_ID (gint);
void channel_delete (Channel *);
void channel_removed (Channel *, gpointer);
void channel_scale (Channel *, gint, gint);
void channel_resize (Channel *, gint, gint, gint, gint);
void channel_update (Channel *);
......
......@@ -31,6 +31,7 @@
#include "parasitelist.h"
#include "temp_buf.h"
#include "undo.h"
#include "gimpsignal.h"
#include "gimppreviewcache.h"
#include "libgimp/gimpintl.h"
......@@ -42,19 +43,16 @@
#include "gimplut.h"
#include "lut_funcs.h"
/*
enum {
REMOVED,
LAST_SIGNAL
};
*/
static void gimp_channel_class_init (GimpChannelClass *klass);
static void gimp_channel_init (GimpChannel *channel);
static void gimp_channel_destroy (GtkObject *object);
/*
static gint channel_signals[LAST_SIGNAL] = { 0 };
*/
static guint channel_signals[LAST_SIGNAL] = { 0 };
static GimpDrawableClass *parent_class = NULL;
......@@ -91,9 +89,11 @@ gimp_channel_class_init (GimpChannelClass *class)
object_class = (GtkObjectClass*) class;
parent_class = gtk_type_class (gimp_drawable_get_type ());
/*
channel_signals[REMOVED] =
gimp_signal_new ("removed",
0, object_class->type, 0, gimp_sigtype_void);
gtk_object_class_add_signals (object_class, channel_signals, LAST_SIGNAL);
*/
object_class->destroy = gimp_channel_destroy;
}
......@@ -307,6 +307,22 @@ gimp_channel_destroy (GtkObject *object)
}
/* The removed signal is sent out when the channel is no longer
* associcated with an image. It's needed because channels aren't
* destroyed immediately, but kept around for undo purposes. Connect
* to the removed signal to update bits of UI that are tied to a
* particular layer. */
void
channel_removed (Channel *channel,
gpointer image)
{
g_return_if_fail (channel != NULL);
g_return_if_fail (GIMP_IS_CHANNEL (channel));
gtk_signal_emit (GTK_OBJECT (channel), channel_signals[REMOVED]);
}
void
channel_scale (Channel *channel,
gint new_width,
......
......@@ -88,6 +88,7 @@ void channel_set_color (Channel *, guchar *);
Channel * channel_get_ID (gint);
void channel_delete (Channel *);
void channel_removed (Channel *, gpointer);
void channel_scale (Channel *, gint, gint);
void channel_resize (Channel *, gint, gint, gint, gint);
void channel_update (Channel *);
......
......@@ -3110,6 +3110,9 @@ gimp_image_remove_channel (GimpImage *gimage,
if (drawable_visible (GIMP_DRAWABLE(channel)))
drawable_update (GIMP_DRAWABLE(channel), 0, 0, drawable_width (GIMP_DRAWABLE(channel)), drawable_height (GIMP_DRAWABLE(channel)));
/* Send out REMOVED signal from channel */
channel_removed (channel, gimage);
/* Important to push the undo here in case the push fails */
undo_push_channel (gimage, CHANNEL_REMOVE_UNDO, cu);
......
......@@ -3110,6 +3110,9 @@ gimp_image_remove_channel (GimpImage *gimage,
if (drawable_visible (GIMP_DRAWABLE(channel)))
drawable_update (GIMP_DRAWABLE(channel), 0, 0, drawable_width (GIMP_DRAWABLE(channel)), drawable_height (GIMP_DRAWABLE(channel)));
/* Send out REMOVED signal from channel */
channel_removed (channel, gimage);
/* Important to push the undo here in case the push fails */
undo_push_channel (gimage, CHANNEL_REMOVE_UNDO, cu);
......
......@@ -3110,6 +3110,9 @@ gimp_image_remove_channel (GimpImage *gimage,
if (drawable_visible (GIMP_DRAWABLE(channel)))
drawable_update (GIMP_DRAWABLE(channel), 0, 0, drawable_width (GIMP_DRAWABLE(channel)), drawable_height (GIMP_DRAWABLE(channel)));
/* Send out REMOVED signal from channel */
channel_removed (channel, gimage);
/* Important to push the undo here in case the push fails */
undo_push_channel (gimage, CHANNEL_REMOVE_UNDO, cu);
......
......@@ -53,21 +53,40 @@ typedef struct _EditQmaskOptions EditQmaskOptions;
/* Global variables */
/* Static variables */
/* Prototypes */
static void edit_qmask_channel_query (GDisplay *gdisp);
static void edit_qmask_channel_query (GDisplay *gdisp);
static void edit_qmask_query_ok_callback (GtkWidget *widget,
gpointer client_data);
static void edit_qmask_query_cancel_callback (GtkWidget *widget,
gpointer client_data);
static void qmask_query_scale_update (GtkAdjustment *adjustment,
gdouble *scale_val);
static void qmask_removed_callback (GtkObject *qmask,
gpointer data);
/* Actual code */
static void
qmask_query_scale_update (GtkAdjustment *adjustment, gdouble *scale_val)
qmask_query_scale_update (GtkAdjustment *adjustment,
gdouble *scale_val)
{
*scale_val = adjustment->value;
}
static void
qmask_removed_callback (GtkObject *qmask,
gpointer data)
{
GDisplay *gdisp = (GDisplay*) data;
if (!gdisp->gimage)
return;
gdisp->gimage->qmask_state = 0;
qmask_buttons_update (gdisp);
}
void
qmask_buttons_update (GDisplay *gdisp)
{
......@@ -114,9 +133,9 @@ qmask_click_handler (GtkWidget *widget,
if ((event->type == GDK_2BUTTON_PRESS) &&
(event->button == 1))
{
edit_qmask_channel_query(gdisp);
}
{
edit_qmask_channel_query(gdisp);
}
}
void
......@@ -129,11 +148,11 @@ qmask_deactivate (GtkWidget *w,
if (gdisp)
{
gimg = gdisp->gimage;
if (!gimg) return;
if (!gimg)
return;
if (!gdisp->gimage->qmask_state) {
if (!gdisp->gimage->qmask_state)
return; /* if already set do nothing */
}
undo_push_group_start (gimg, QMASK_UNDO);
......@@ -168,20 +187,21 @@ qmask_activate (GtkWidget *w,
if (gdisp)
{
gimg = gdisp->gimage;
if (!gimg) return;
if (!gimg)
return;
if (gdisp->gimage->qmask_state) {
if (gdisp->gimage->qmask_state)
return; /* If already set, do nothing */
}
/* Set the defaults */
opacity = (double) gimg->qmask_opacity;
color = gimg->qmask_color;
if ( (gmask = gimp_image_get_channel_by_name (gimg, "Qmask")) ) {
gimg->qmask_state = 1; /* if the user was clever and created his own */
return;
}
if ( (gmask = gimp_image_get_channel_by_name (gimg, "Qmask")) )
{
gimg->qmask_state = 1; /* if the user was clever and created his own */
return;
}
undo_push_group_start (gimg, QMASK_UNDO);
if (gimage_mask_is_empty(gimg))
......@@ -216,6 +236,10 @@ qmask_activate (GtkWidget *w,
}
undo_push_group_end(gimg);
gdisplays_flush();
/* connect to the removed signal, so the buttons get updated */
gtk_signal_connect (GTK_OBJECT (gmask), "removed",
GTK_SIGNAL_FUNC (qmask_removed_callback), gdisp);
}
}
......@@ -301,8 +325,9 @@ edit_qmask_channel_query (GDisplay * gdisp)
gtk_widget_show (options->query_box);
}
static void edit_qmask_query_ok_callback (GtkWidget *widget,
gpointer client_data)
static void
edit_qmask_query_ok_callback (GtkWidget *widget,
gpointer client_data)
{
EditQmaskOptions *options;
Channel *channel;
......@@ -325,27 +350,27 @@ static void edit_qmask_query_ok_callback (GtkWidget *widget,
tmpcolp = channel_get_color(channel);
for (i = 0; i < 3; i++)
{ /* don't update if color hasn't changed */
tmpcol[