Added Qmasks 7-6-99 <sjburges@gimp.org>

* pixmaps/qmasknosel.xpm
        * pixmaps/qmasksel.xpm: Ugly pixmaps that tigert promised to replace

        * app/channel.[ch]
        * app/channel_cmds.c : made some of the private structures accessible
          through exported functions to keep things a bit clean

        * app/interface.c
        * app/gdisplay.[ch]
        * app/gimpimageP.h
        * app/gimpimage.[ch]
        * app/undo.[ch]: added qmasks

        * app/Makefile.am
        * app/qmask.[ch]: added new files for qmask support

        * tools/pdbgen/pdb/channel.pdb: changed some channel stuff to keep
          things a bit more private
This commit is contained in:
Seth Burgess 1999-07-07 03:18:54 +00:00
parent 5a1c6e4383
commit 7058d4c631
53 changed files with 1966 additions and 43 deletions

View File

@ -1,3 +1,23 @@
Tue Jul 6 20:55 CST 1999 Seth Burgess <sjburges@gimp.org>
* pixmaps/qmasknosel.xpm
* pixmaps/qmasksel.xpm: Ugly pixmaps that tigert promised to replace
* app/channel.[ch]
* app/channel_cmds.c : made some of the private structures accessible
through exported functions to keep things a bit clean
* app/interface.c
* app/gdisplay.[ch]
* app/gimpimageP.h
* app/gimpimage.[ch]
* app/undo.[ch]: added qmasks
* app/Makefile.am
* app/qmask.[ch]: added new files for qmask support
* tools/pdbgen/pdb: changed some channel stuff to keep things a bit
more private
Wed Jul 7 03:54:54 MEST 1999 Sven Neumann <sven@gimp.org>
* plug-ins/script-fu/script-fu.c: Fixed typo.

View File

@ -329,6 +329,8 @@ gimp_SOURCES = \
procedural_db.c \
procedural_db.h \
procedural_db_cmds.c \
qmask.c \
qmask.h \
rect_select.c \
rect_select.h \
rect_selectP.h \

View File

@ -0,0 +1,152 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include "appenv.h"
#include "channel.h"
#include "gdisplayF.h"
#include "gimpcontext.h"
#include "gimage_mask.h"
#include "gimpimage.h"
#include "global_edit.h"
#include "qmask.h"
#include "undo.h"
/* Global variables */
/* Prototypes */
/* Static variables */
void
qmask_buttons_update (GDisplay *gdisp)
{
g_assert(gdisp);
g_assert(gdisp->gimage);
if (gdisp->gimage->qmask_state != GTK_TOGGLE_BUTTON(gdisp->qmaskon)->active)
{
/* Disable toggle from doing anything */
gtk_signal_handler_block_by_func(GTK_OBJECT(gdisp->qmaskoff),
(GtkSignalFunc) qmask_deactivate,
gdisp);
gtk_signal_handler_block_by_func(GTK_OBJECT(gdisp->qmaskon),
(GtkSignalFunc) qmask_activate,
gdisp);
/* Change the state of the buttons */
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gdisp->qmaskon),
gdisp->gimage->qmask_state);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gdisp->qmaskoff),
!gdisp->gimage->qmask_state);
/* Enable toggle again */
gtk_signal_handler_unblock_by_func(GTK_OBJECT(gdisp->qmaskoff),
(GtkSignalFunc) qmask_deactivate,
gdisp);
gtk_signal_handler_unblock_by_func(GTK_OBJECT(gdisp->qmaskon),
(GtkSignalFunc) qmask_activate,
gdisp);
/* Flush event queue */
/* while (g_main_iteration(FALSE)); */
}
}
void
qmask_deactivate(GtkWidget *w,
GDisplay *gdisp)
{
GimpImage *gimg;
GimpChannel *gmask;
if (gdisp)
{
gimg = gdisp->gimage;
if (!gimg) return;
if (!gdisp->gimage->qmask_state) {
return; /* if already set do nothing */
}
undo_push_group_start (gimg, QMASK_UNDO);
if ( (gmask = gimp_image_get_channel_by_name (gimg, "Qmask")) )
{
gimage_mask_load (gimg, gmask);
gimage_remove_channel(gimg, gmask);
undo_push_qmask(gimg,1);
gdisp->gimage->qmask_state = 0;
gdisplays_flush ();
}
undo_push_group_end (gimg);
}
}
void
qmask_activate(GtkWidget *w,
GDisplay *gdisp)
{
GimpImage *gimg;
GimpChannel *gmask;
unsigned char color[3] = {255,0,0};
double opacity = 50;
if (gdisp)
{
gimg = gdisp->gimage;
if (!gimg) return;
if (gdisp->gimage->qmask_state) {
return; /* If already set, do nothing */
}
if ( (gmask = gimp_image_get_channel_by_name (gimg, "Qmask")) )
return; /* do nothing if Qmask already exists */
undo_push_group_start (gimg, QMASK_UNDO);
if (gimage_mask_is_empty(gimg))
{ /* if no selection */
gmask = channel_new(gimg,
gimg->width,
gimg->height,
"Qmask",
(int)(255*opacity)/100,
color);
gimp_image_add_channel (gimg, gmask, 0);
edit_clear(gimg,GIMP_DRAWABLE(gmask));
undo_push_qmask(gimg,0);
gdisp->gimage->qmask_state = 1;
gdisplays_flush();
}
else
{ /* if selection */
gmask = channel_copy (gimage_get_mask (gimg));
gimp_image_add_channel (gimg, gmask, 0);
channel_set_color(gmask, color);
channel_set_name(gmask, "Qmask");
channel_set_opacity(gmask, opacity);
gimage_mask_none (gimg); /* Clear the selection */
undo_push_qmask(gimg,0);
gdisp->gimage->qmask_state = 1;
gdisplays_flush();
}
undo_push_group_end(gimg);
}
}

View File

@ -0,0 +1,152 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include "appenv.h"
#include "channel.h"
#include "gdisplayF.h"
#include "gimpcontext.h"
#include "gimage_mask.h"
#include "gimpimage.h"
#include "global_edit.h"
#include "qmask.h"
#include "undo.h"
/* Global variables */
/* Prototypes */
/* Static variables */
void
qmask_buttons_update (GDisplay *gdisp)
{
g_assert(gdisp);
g_assert(gdisp->gimage);
if (gdisp->gimage->qmask_state != GTK_TOGGLE_BUTTON(gdisp->qmaskon)->active)
{
/* Disable toggle from doing anything */
gtk_signal_handler_block_by_func(GTK_OBJECT(gdisp->qmaskoff),
(GtkSignalFunc) qmask_deactivate,
gdisp);
gtk_signal_handler_block_by_func(GTK_OBJECT(gdisp->qmaskon),
(GtkSignalFunc) qmask_activate,
gdisp);
/* Change the state of the buttons */
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gdisp->qmaskon),
gdisp->gimage->qmask_state);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gdisp->qmaskoff),
!gdisp->gimage->qmask_state);
/* Enable toggle again */
gtk_signal_handler_unblock_by_func(GTK_OBJECT(gdisp->qmaskoff),
(GtkSignalFunc) qmask_deactivate,
gdisp);
gtk_signal_handler_unblock_by_func(GTK_OBJECT(gdisp->qmaskon),
(GtkSignalFunc) qmask_activate,
gdisp);
/* Flush event queue */
/* while (g_main_iteration(FALSE)); */
}
}
void
qmask_deactivate(GtkWidget *w,
GDisplay *gdisp)
{
GimpImage *gimg;
GimpChannel *gmask;
if (gdisp)
{
gimg = gdisp->gimage;
if (!gimg) return;
if (!gdisp->gimage->qmask_state) {
return; /* if already set do nothing */
}
undo_push_group_start (gimg, QMASK_UNDO);
if ( (gmask = gimp_image_get_channel_by_name (gimg, "Qmask")) )
{
gimage_mask_load (gimg, gmask);
gimage_remove_channel(gimg, gmask);
undo_push_qmask(gimg,1);
gdisp->gimage->qmask_state = 0;
gdisplays_flush ();
}
undo_push_group_end (gimg);
}
}
void
qmask_activate(GtkWidget *w,
GDisplay *gdisp)
{
GimpImage *gimg;
GimpChannel *gmask;
unsigned char color[3] = {255,0,0};
double opacity = 50;
if (gdisp)
{
gimg = gdisp->gimage;
if (!gimg) return;
if (gdisp->gimage->qmask_state) {
return; /* If already set, do nothing */
}
if ( (gmask = gimp_image_get_channel_by_name (gimg, "Qmask")) )
return; /* do nothing if Qmask already exists */
undo_push_group_start (gimg, QMASK_UNDO);
if (gimage_mask_is_empty(gimg))
{ /* if no selection */
gmask = channel_new(gimg,
gimg->width,
gimg->height,
"Qmask",
(int)(255*opacity)/100,
color);
gimp_image_add_channel (gimg, gmask, 0);
edit_clear(gimg,GIMP_DRAWABLE(gmask));
undo_push_qmask(gimg,0);
gdisp->gimage->qmask_state = 1;
gdisplays_flush();
}
else
{ /* if selection */
gmask = channel_copy (gimage_get_mask (gimg));
gimp_image_add_channel (gimg, gmask, 0);
channel_set_color(gmask, color);
channel_set_name(gmask, "Qmask");
channel_set_opacity(gmask, opacity);
gimage_mask_none (gimg); /* Clear the selection */
undo_push_qmask(gimg,0);
gdisp->gimage->qmask_state = 1;
gdisplays_flush();
}
undo_push_group_end(gimg);
}
}

View File

@ -236,6 +236,24 @@ channel_get_name (Channel *channel)
return gimp_drawable_get_name(GIMP_DRAWABLE(channel));
}
void
channel_set_color (Channel *channel, gchar *color)
{
int i;
if (color)
{
for (i = 0; i < 3; i++)
channel->col[i] = color[i];
}
}
void
channel_set_opacity (Channel *channel, gint opacity)
{
if (opacity >=0 && opacity <= 100)
channel->opacity = (int) (opacity*255)/100;
}
Channel *
channel_get_ID (int ID)
{

View File

@ -86,6 +86,9 @@ void channel_unref (Channel *);
char * channel_get_name (Channel *);
void channel_set_name (Channel *, char *);
void channel_set_opacity (Channel *, int );
void channel_set_color (Channel *, gchar *);
Channel * channel_get_ID (int);
void channel_delete (Channel *);
void channel_scale (Channel *, int, int);

View File

@ -642,7 +642,7 @@ channel_set_opacity_invoker (Argument *args)
success = FALSE;
if (success)
channel->opacity = (int) ((opacity * 255) / 100);
channel_set_opacity (channel, opacity);
return procedural_db_return_args (&channel_set_opacity_proc, success);
}
@ -754,8 +754,7 @@ channel_set_color_invoker (Argument *args)
color = (guchar *) args[1].value.pdb_pointer;
if (success)
for (i = 0; i < 3; i++)
channel->col[i] = color[i];
channel_set_color(channel, color);
return procedural_db_return_args (&channel_set_color_proc, success);
}

View File

@ -236,6 +236,24 @@ channel_get_name (Channel *channel)
return gimp_drawable_get_name(GIMP_DRAWABLE(channel));
}
void
channel_set_color (Channel *channel, gchar *color)
{
int i;
if (color)
{
for (i = 0; i < 3; i++)
channel->col[i] = color[i];
}
}
void
channel_set_opacity (Channel *channel, gint opacity)
{
if (opacity >=0 && opacity <= 100)
channel->opacity = (int) (opacity*255)/100;
}
Channel *
channel_get_ID (int ID)
{

View File

@ -86,6 +86,9 @@ void channel_unref (Channel *);
char * channel_get_name (Channel *);
void channel_set_name (Channel *, char *);
void channel_set_opacity (Channel *, int );
void channel_set_color (Channel *, gchar *);
Channel * channel_get_ID (int);
void channel_delete (Channel *);
void channel_scale (Channel *, int, int);

View File

@ -236,6 +236,24 @@ channel_get_name (Channel *channel)
return gimp_drawable_get_name(GIMP_DRAWABLE(channel));
}
void
channel_set_color (Channel *channel, gchar *color)
{
int i;
if (color)
{
for (i = 0; i < 3; i++)
channel->col[i] = color[i];
}
}
void
channel_set_opacity (Channel *channel, gint opacity)
{
if (opacity >=0 && opacity <= 100)
channel->opacity = (int) (opacity*255)/100;
}
Channel *
channel_get_ID (int ID)
{

View File

@ -86,6 +86,9 @@ void channel_unref (Channel *);
char * channel_get_name (Channel *);
void channel_set_name (Channel *, char *);
void channel_set_opacity (Channel *, int );
void channel_set_color (Channel *, gchar *);
Channel * channel_get_ID (int);
void channel_delete (Channel *);
void channel_scale (Channel *, int, int);

View File

@ -1711,6 +1711,22 @@ gimp_image_get_channel_by_tattoo (GimpImage *gimage, Tattoo tattoo)
}
Channel *
gimp_image_get_channel_by_name (GimpImage *gimage, char *name)
{
Channel *channel;
GSList *channels = gimage->channels;
while (channels)
{
channel = (Channel *) channels->data;
if (! strcmp(channel_get_name(channel),name) )
return channel;
channels = g_slist_next (channels);
}
return NULL;
}
int
gimp_image_get_component_active (GimpImage *gimage, ChannelType type)
{

View File

@ -178,6 +178,7 @@ Layer * gimp_image_get_active_layer (GimpImage *);
Channel * gimp_image_get_active_channel (GimpImage *);
Layer * gimp_image_get_layer_by_tattoo (GimpImage *, Tattoo);
Channel * gimp_image_get_channel_by_tattoo (GimpImage *, Tattoo);
Channel * gimp_image_get_channel_by_name (GimpImage *, char *);
Channel * gimp_image_get_mask (GimpImage *);
int gimp_image_get_component_active (GimpImage *, ChannelType);
int gimp_image_get_component_visible (GimpImage *, ChannelType);

View File

@ -1711,6 +1711,22 @@ gimp_image_get_channel_by_tattoo (GimpImage *gimage, Tattoo tattoo)
}
Channel *
gimp_image_get_channel_by_name (GimpImage *gimage, char *name)
{
Channel *channel;
GSList *channels = gimage->channels;
while (channels)
{
channel = (Channel *) channels->data;
if (! strcmp(channel_get_name(channel),name) )
return channel;
channels = g_slist_next (channels);
}
return NULL;
}
int
gimp_image_get_component_active (GimpImage *gimage, ChannelType type)
{

View File

@ -178,6 +178,7 @@ Layer * gimp_image_get_active_layer (GimpImage *);
Channel * gimp_image_get_active_channel (GimpImage *);
Layer * gimp_image_get_layer_by_tattoo (GimpImage *, Tattoo);
Channel * gimp_image_get_channel_by_tattoo (GimpImage *, Tattoo);
Channel * gimp_image_get_channel_by_name (GimpImage *, char *);
Channel * gimp_image_get_mask (GimpImage *);
int gimp_image_get_component_active (GimpImage *, ChannelType);
int gimp_image_get_component_visible (GimpImage *, ChannelType);

View File

@ -1711,6 +1711,22 @@ gimp_image_get_channel_by_tattoo (GimpImage *gimage, Tattoo tattoo)
}
Channel *
gimp_image_get_channel_by_name (GimpImage *gimage, char *name)
{
Channel *channel;
GSList *channels = gimage->channels;
while (channels)
{
channel = (Channel *) channels->data;
if (! strcmp(channel_get_name(channel),name) )
return channel;
channels = g_slist_next (channels);
}
return NULL;
}
int
gimp_image_get_component_active (GimpImage *gimage, ChannelType type)
{

View File

@ -178,6 +178,7 @@ Layer * gimp_image_get_active_layer (GimpImage *);
Channel * gimp_image_get_active_channel (GimpImage *);
Layer * gimp_image_get_layer_by_tattoo (GimpImage *, Tattoo);
Channel * gimp_image_get_channel_by_tattoo (GimpImage *, Tattoo);
Channel * gimp_image_get_channel_by_name (GimpImage *, char *);
Channel * gimp_image_get_mask (GimpImage *);
int gimp_image_get_component_active (GimpImage *, ChannelType);
int gimp_image_get_component_visible (GimpImage *, ChannelType);

152
app/core/gimpimage-qmask.c Normal file
View File

@ -0,0 +1,152 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include "appenv.h"
#include "channel.h"
#include "gdisplayF.h"
#include "gimpcontext.h"
#include "gimage_mask.h"
#include "gimpimage.h"
#include "global_edit.h"
#include "qmask.h"
#include "undo.h"
/* Global variables */
/* Prototypes */
/* Static variables */
void
qmask_buttons_update (GDisplay *gdisp)
{
g_assert(gdisp);
g_assert(gdisp->gimage);
if (gdisp->gimage->qmask_state != GTK_TOGGLE_BUTTON(gdisp->qmaskon)->active)
{
/* Disable toggle from doing anything */
gtk_signal_handler_block_by_func(GTK_OBJECT(gdisp->qmaskoff),
(GtkSignalFunc) qmask_deactivate,
gdisp);
gtk_signal_handler_block_by_func(GTK_OBJECT(gdisp->qmaskon),
(GtkSignalFunc) qmask_activate,
gdisp);
/* Change the state of the buttons */
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gdisp->qmaskon),
gdisp->gimage->qmask_state);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gdisp->qmaskoff),
!gdisp->gimage->qmask_state);
/* Enable toggle again */
gtk_signal_handler_unblock_by_func(GTK_OBJECT(gdisp->qmaskoff),
(GtkSignalFunc) qmask_deactivate,
gdisp);
gtk_signal_handler_unblock_by_func(GTK_OBJECT(gdisp->qmaskon),
(GtkSignalFunc) qmask_activate,
gdisp);
/* Flush event queue */
/* while (g_main_iteration(FALSE)); */
}
}
void
qmask_deactivate(GtkWidget *w,
GDisplay *gdisp)
{
GimpImage *gimg;
GimpChannel *gmask;
if (gdisp)
{
gimg = gdisp->gimage;
if (!gimg) return;
if (!gdisp->gimage->qmask_state) {
return; /* if already set do nothing */
}
undo_push_group_start (gimg, QMASK_UNDO);
if ( (gmask = gimp_image_get_channel_by_name (gimg, "Qmask")) )
{
gimage_mask_load (gimg, gmask);
gimage_remove_channel(gimg, gmask);
undo_push_qmask(gimg,1);
gdisp->gimage->qmask_state = 0;
gdisplays_flush ();
}
undo_push_group_end (gimg);
}
}
void
qmask_activate(GtkWidget *w,
GDisplay *gdisp)
{
GimpImage *gimg;
GimpChannel *gmask;
unsigned char color[3] = {255,0,0};
double opacity = 50;
if (gdisp)
{
gimg = gdisp->gimage;
if (!gimg) return;
if (gdisp->gimage->qmask_state) {
return; /* If already set, do nothing */
}
if ( (gmask = gimp_image_get_channel_by_name (gimg, "Qmask")) )
return; /* do nothing if Qmask already exists */
undo_push_group_start (gimg, QMASK_UNDO);
if (gimage_mask_is_empty(gimg))
{ /* if no selection */
gmask = channel_new(gimg,
gimg->width,
gimg->height,
"Qmask",
(int)(255*opacity)/100,
color);
gimp_image_add_channel (gimg, gmask, 0);
edit_clear(gimg,GIMP_DRAWABLE(gmask));
undo_push_qmask(gimg,0);
gdisp->gimage->qmask_state = 1;
gdisplays_flush();
}
else
{ /* if selection */
gmask = channel_copy (gimage_get_mask (gimg));
gimp_image_add_channel (gimg, gmask, 0);
channel_set_color(gmask, color);
channel_set_name(gmask, "Qmask");
channel_set_opacity(gmask, opacity);
gimage_mask_none (gimg); /* Clear the selection */
undo_push_qmask(gimg,0);
gdisp->gimage->qmask_state = 1;
gdisplays_flush();
}
undo_push_group_end(gimg);
}
}

View File

@ -0,0 +1,152 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include "appenv.h"
#include "channel.h"
#include "gdisplayF.h"
#include "gimpcontext.h"
#include "gimage_mask.h"
#include "gimpimage.h"
#include "global_edit.h"
#include "qmask.h"
#include "undo.h"
/* Global variables */
/* Prototypes */
/* Static variables */
void
qmask_buttons_update (GDisplay *gdisp)
{
g_assert(gdisp);
g_assert(gdisp->gimage);
if (gdisp->gimage->qmask_state != GTK_TOGGLE_BUTTON(gdisp->qmaskon)->active)
{
/* Disable toggle from doing anything */
gtk_signal_handler_block_by_func(GTK_OBJECT(gdisp->qmaskoff),
(GtkSignalFunc) qmask_deactivate,
gdisp);
gtk_signal_handler_block_by_func(GTK_OBJECT(gdisp->qmaskon),
(GtkSignalFunc) qmask_activate,
gdisp);
/* Change the state of the buttons */
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gdisp->qmaskon),
gdisp->gimage->qmask_state);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gdisp->qmaskoff),
!gdisp->gimage->qmask_state);
/* Enable toggle again */
gtk_signal_handler_unblock_by_func(GTK_OBJECT(gdisp->qmaskoff),
(GtkSignalFunc) qmask_deactivate,
gdisp);
gtk_signal_handler_unblock_by_func(GTK_OBJECT(gdisp->qmaskon),
(GtkSignalFunc) qmask_activate,
gdisp);
/* Flush event queue */
/* while (g_main_iteration(FALSE)); */
}
}
void
qmask_deactivate(GtkWidget *w,
GDisplay *gdisp)
{
GimpImage *gimg;
GimpChannel *gmask;
if (gdisp)
{
gimg = gdisp->gimage;
if (!gimg) return;
if (!gdisp->gimage->qmask_state) {
return; /* if already set do nothing */
}
undo_push_group_start (gimg, QMASK_UNDO);
if ( (gmask = gimp_image_get_channel_by_name (gimg, "Qmask")) )
{
gimage_mask_load (gimg, gmask);
gimage_remove_channel(gimg, gmask);
undo_push_qmask(gimg,1);
gdisp->gimage->qmask_state = 0;
gdisplays_flush ();
}
undo_push_group_end (gimg);
}
}
void
qmask_activate(GtkWidget *w,
GDisplay *gdisp)
{
GimpImage *gimg;
GimpChannel *gmask;
unsigned char color[3] = {255,0,0};
double opacity = 50;
if (gdisp)
{
gimg = gdisp->gimage;
if (!gimg) return;
if (gdisp->gimage->qmask_state) {
return; /* If already set, do nothing */
}
if ( (gmask = gimp_image_get_channel_by_name (gimg, "Qmask")) )
return; /* do nothing if Qmask already exists */
undo_push_group_start (gimg, QMASK_UNDO);
if (gimage_mask_is_empty(gimg))
{ /* if no selection */
gmask = channel_new(gimg,
gimg->width,
gimg->height,
"Qmask",
(int)(255*opacity)/100,
color);
gimp_image_add_channel (gimg, gmask, 0);
edit_clear(gimg,GIMP_DRAWABLE(gmask));
undo_push_qmask(gimg,0);
gdisp->gimage->qmask_state = 1;
gdisplays_flush();
}
else
{ /* if selection */
gmask = channel_copy (gimage_get_mask (gimg));
gimp_image_add_channel (gimg, gmask, 0);
channel_set_color(gmask, color);
channel_set_name(gmask, "Qmask");
channel_set_opacity(gmask, opacity);
gimage_mask_none (gimg); /* Clear the selection */
undo_push_qmask(gimg,0);
gdisp->gimage->qmask_state = 1;
gdisplays_flush();
}
undo_push_group_end(gimg);
}
}

View File

@ -1711,6 +1711,22 @@ gimp_image_get_channel_by_tattoo (GimpImage *gimage, Tattoo tattoo)
}
Channel *
gimp_image_get_channel_by_name (GimpImage *gimage, char *name)
{
Channel *channel;
GSList *channels = gimage->channels;
while (channels)
{
channel = (Channel *) channels->data;
if (! strcmp(channel_get_name(channel),name) )
return channel;
channels = g_slist_next (channels);
}
return NULL;
}
int
gimp_image_get_component_active (GimpImage *gimage, ChannelType type)
{

View File

@ -178,6 +178,7 @@ Layer * gimp_image_get_active_layer (GimpImage *);
Channel * gimp_image_get_active_channel (GimpImage *);
Layer * gimp_image_get_layer_by_tattoo (GimpImage *, Tattoo);
Channel * gimp_image_get_channel_by_tattoo (GimpImage *, Tattoo);
Channel * gimp_image_get_channel_by_name (GimpImage *, char *);
Channel * gimp_image_get_mask (GimpImage *);
int gimp_image_get_component_active (GimpImage *, ChannelType);
int gimp_image_get_component_visible (GimpImage *, ChannelType);

View File

@ -1711,6 +1711,22 @@ gimp_image_get_channel_by_tattoo (GimpImage *gimage, Tattoo tattoo)
}
Channel *
gimp_image_get_channel_by_name (GimpImage *gimage, char *name)
{
Channel *channel;
GSList *channels = gimage->channels;
while (channels)
{
channel = (Channel *) channels->data;
if (! strcmp(channel_get_name(channel),name) )
return channel;
channels = g_slist_next (channels);
}
return NULL;
}
int
gimp_image_get_component_active (GimpImage *gimage, ChannelType type)
{

View File

@ -178,6 +178,7 @@ Layer * gimp_image_get_active_layer (GimpImage *);
Channel * gimp_image_get_active_channel (GimpImage *);
Layer * gimp_image_get_layer_by_tattoo (GimpImage *, Tattoo);
Channel * gimp_image_get_channel_by_tattoo (GimpImage *, Tattoo);
Channel * gimp_image_get_channel_by_name (GimpImage *, char *);
Channel * gimp_image_get_mask (GimpImage *);
int gimp_image_get_component_active (GimpImage *, ChannelType);
int gimp_image_get_component_visible (GimpImage *, ChannelType);

View File

@ -79,6 +79,7 @@ int undo_pop_fs_relax (GImage *, int, int, void *);
int undo_pop_gimage_mod (GImage *, int, int, void *);
int undo_pop_guide (GImage *, int, int, void *);
int undo_pop_parasite (GImage *, int, int, void *);
int undo_pop_qmask (GImage *, int, int, void *);
/* Free functions */
@ -98,7 +99,7 @@ void undo_free_fs_relax (int, void *);
void undo_free_gimage_mod (int, void *);
void undo_free_guide (int, void *);
void undo_free_parasite (int, void *);
void undo_free_qmask (int, void *);
/* Sizing functions */
@ -2011,6 +2012,87 @@ undo_free_gimage_mod (int state,
g_free (data_ptr);
}
/***********/
/* Qmask */
typedef struct _QmaskUndo QmaskUndo;
struct _QmaskUndo
{
GImage *gimage;
int qmask;
int orig;
};
int
undo_push_qmask (GImage *gimage,
int qmask)
{
Undo *new;
QmaskUndo *data;
long size;
/* increment the dirty flag for this gimage */
gimage_dirty (gimage);
size = sizeof (QmaskUndo);
if ((new = undo_push (gimage, size, GIMAGE_MOD)))
{
data = g_new (QmaskUndo, 1);
new->data = data;
new->pop_func = undo_pop_qmask;
new->free_func = undo_free_qmask;
data->gimage = gimage;
data->qmask = qmask;
data->orig = data->qmask;
return TRUE;
}
return FALSE;
}
int
undo_pop_qmask (GImage *gimage,
int state,
int type,
void *data_ptr)
{
QmaskUndo *data;
int tmp;
int tmp_ref;
data = data_ptr;
tmp = data->qmask;
data->qmask = data->orig;
data->orig = tmp;
gimage->qmask_state = data->qmask;
switch (state)
{
case UNDO:
gimage_clean (gimage);
break;
case REDO:
gimage_dirty (gimage);
break;
}
return TRUE;
}
void
undo_free_qmask (int state,
void *data_ptr)
{
g_free (data_ptr);
}
/***********/
/* Guide */
@ -2023,7 +2105,6 @@ struct _GuideUndo
Guide *guide;
Guide orig;
};
int
undo_push_guide (GImage *gimage,
void *guide)

View File

@ -55,6 +55,7 @@
#define CROP_UNDO 31
#define LAYER_SCALE_UNDO 32
#define LAYER_RESIZE_UNDO 33
#define QMASK_UNDO 34
#define MISC_UNDO 100
/* Undo interface functions */
@ -84,6 +85,7 @@ int undo_push_drawable_parasite (GImage *, GimpDrawable *, void *);
int undo_push_image_parasite_remove (GImage *, const char *);
int undo_push_drawable_parasite_remove (GImage *, GimpDrawable *,
const char *);
int undo_push_qmask (GImage *, int);
int undo_pop (GImage *);
int undo_redo (GImage *);

View File

@ -1711,6 +1711,22 @@ gimp_image_get_channel_by_tattoo (GimpImage *gimage, Tattoo tattoo)
}
Channel *
gimp_image_get_channel_by_name (GimpImage *gimage, char *name)
{
Channel *channel;
GSList *channels = gimage->channels;
while (channels)
{
channel = (Channel *) channels->data;
if (! strcmp(channel_get_name(channel),name) )
return channel;
channels = g_slist_next (channels);
}
return NULL;
}
int
gimp_image_get_component_active (GimpImage *gimage, ChannelType type)
{

View File

@ -178,6 +178,7 @@ Layer * gimp_image_get_active_layer (GimpImage *);
Channel * gimp_image_get_active_channel (GimpImage *);
Layer * gimp_image_get_layer_by_tattoo (GimpImage *, Tattoo);
Channel * gimp_image_get_channel_by_tattoo (GimpImage *, Tattoo);
Channel * gimp_image_get_channel_by_name (GimpImage *, char *);
Channel * gimp_image_get_mask (GimpImage *);
int gimp_image_get_component_active (GimpImage *, ChannelType);
int gimp_image_get_component_visible (GimpImage *, ChannelType);

View File

@ -1711,6 +1711,22 @@ gimp_image_get_channel_by_tattoo (GimpImage *gimage, Tattoo tattoo)
}
Channel *
gimp_image_get_channel_by_name (GimpImage *gimage, char *name)
{
Channel *channel;
GSList *channels = gimage->channels;
while (channels)
{
channel = (Channel *) channels->data;
if (! strcmp(channel_get_name(channel),name) )
return channel;
channels = g_slist_next (channels);
}
return NULL;
}
int
gimp_image_get_component_active (GimpImage *gimage, ChannelType type)
{

View File

@ -178,6 +178,7 @@ Layer * gimp_image_get_active_layer (GimpImage *);
Channel * gimp_image_get_active_channel (GimpImage *);
Layer * gimp_image_get_layer_by_tattoo (GimpImage *, Tattoo);
Channel * gimp_image_get_channel_by_tattoo (GimpImage *, Tattoo);
Channel * gimp_image_get_channel_by_name (GimpImage *, char *);
Channel * gimp_image_get_mask (GimpImage *);
int gimp_image_get_component_active (GimpImage *, ChannelType);
int gimp_image_get_component_visible (GimpImage *, ChannelType);

View File

@ -24,6 +24,7 @@
#include "cursorutil.h"
#include "disp_callbacks.h"
#include "drawable.h"
#include "draw_core.h"
#include "gdisplay.h"
#include "gdisplayP.h"
#include "gdisplay_ops.h"
@ -37,14 +38,15 @@
#include "interface.h"
#include "lc_dialog.h"
#include "menus.h"
#include "draw_core.h"
#include "bezier_selectP.h"
#include "plug_in.h"
#include "qmask.h"
#include "scale.h"
#include "scroll.h"
#include "tools.h"
#include "undo.h"
#include "layer_pvt.h" /* ick. */
#include "bezier_selectP.h"
#include "layer_pvt.h" /* ick. (not alone either) */
#include "libgimp/gimpintl.h"
@ -138,6 +140,9 @@ gdisplay_new (GimpImage *gimage,
/* set the gdisplay colormap type and install the appropriate colormap */
gdisp->color_type = (gimage_base_type (gimage) == GRAY) ? GRAY : RGB;
/* set the qmask buttons */
qmask_buttons_update(gdisp);
/* set the user data */
if (!display_ht)
display_ht = g_hash_table_new ((GHashFunc) gdisplay_hash, NULL);
@ -646,7 +651,9 @@ gdisplay_flush_whenever (GDisplay *gdisp, gboolean now)
if (gdisp->window_info_dialog)
info_window_update (gdisp->window_info_dialog,
(void *) gdisp);
/* update the gdisplay's qmask buttons */
qmask_buttons_update (gdisp);
/* ensure the consistency of the tear-off menus */
context = gimp_context_get_user ();
if (gimp_context_get_display (context) == gdisp)

View File

@ -93,6 +93,7 @@ struct _GDisplay
GtkWidget *shell; /* shell widget for this gdisplay */
GtkWidget *canvas; /* canvas widget for this gdisplay */
GtkWidget *hsb, *vsb; /* widgets for scroll bars */
GtkWidget *qmaskoff, *qmaskon; /* widgets for qmask buttons */
GtkWidget *hrule, *vrule; /* widgets for rulers */
GtkWidget *origin; /* widgets for rulers */
GtkWidget *popup; /* widget for popup menu */
@ -147,7 +148,7 @@ struct _GDisplay
int cursor_y; /* software cursor Y value */
short proximity; /* is a device in proximity of gdisplay ? */
short have_cursor; /* is cursor currently drawn ? */
IdleRenderStruct idle_render; /* state of this gdisplay's render thread */
};

View File

@ -24,6 +24,7 @@
#include "cursorutil.h"
#include "disp_callbacks.h"
#include "drawable.h"
#include "draw_core.h"
#include "gdisplay.h"
#include "gdisplayP.h"
#include "gdisplay_ops.h"
@ -37,14 +38,15 @@
#include "interface.h"
#include "lc_dialog.h"
#include "menus.h"
#include "draw_core.h"
#include "bezier_selectP.h"
#include "plug_in.h"
#include "qmask.h"
#include "scale.h"
#include "scroll.h"
#include "tools.h"
#include "undo.h"
#include "layer_pvt.h" /* ick. */
#include "bezier_selectP.h"
#include "layer_pvt.h" /* ick. (not alone either) */
#include "libgimp/gimpintl.h"
@ -138,6 +140,9 @@ gdisplay_new (GimpImage *gimage,
/* set the gdisplay colormap type and install the appropriate colormap */
gdisp->color_type = (gimage_base_type (gimage) == GRAY) ? GRAY : RGB;
/* set the qmask buttons */
qmask_buttons_update(gdisp);
/* set the user data */
if (!display_ht)
display_ht = g_hash_table_new ((GHashFunc) gdisplay_hash, NULL);
@ -646,7 +651,9 @@ gdisplay_flush_whenever (GDisplay *gdisp, gboolean now)
if (gdisp->window_info_dialog)
info_window_update (gdisp->window_info_dialog,
(void *) gdisp);
/* update the gdisplay's qmask buttons */
qmask_buttons_update (gdisp);
/* ensure the consistency of the tear-off menus */
context = gimp_context_get_user ();
if (gimp_context_get_display (context) == gdisp)

View File

@ -93,6 +93,7 @@ struct _GDisplay
GtkWidget *shell; /* shell widget for this gdisplay */
GtkWidget *canvas; /* canvas widget for this gdisplay */
GtkWidget *hsb, *vsb; /* widgets for scroll bars */
GtkWidget *qmaskoff, *qmaskon; /* widgets for qmask buttons */
GtkWidget *hrule, *vrule; /* widgets for rulers */
GtkWidget *origin; /* widgets for rulers */
GtkWidget *popup; /* widget for popup menu */
@ -147,7 +148,7 @@ struct _GDisplay
int cursor_y; /* software cursor Y value */
short proximity; /* is a device in proximity of gdisplay ? */
short have_cursor; /* is cursor currently drawn ? */
IdleRenderStruct idle_render; /* state of this gdisplay's render thread */
};

View File

@ -40,12 +40,14 @@
#include "indicator_area.h"
#include "interface.h"
#include "menus.h"
#include "dialog_handler.h"
#include "qmask.h"
#include "session.h"
#include "tools.h"
#include "libgimp/gimpsizeentry.h"
#include "pixmaps.h"
#include "pixmaps/qmasksel.xpm"
#include "pixmaps/qmasknosel.xpm"
#include "libgimp/gimpintl.h"
@ -226,6 +228,38 @@ allocate_colors (GtkWidget *parent)
gdk_color_alloc (colormap, &colors[11]);
}
#ifdef icky
static void
create_qmask_area (GtkWidget *parent)
{
GtkWidget *frame;
GtkWidget *alignment;
GdkPixmap *default_pixmap;
GdkPixmap *swap_pixmap;
gtk_widget_realize (parent);
default_pixmap = create_pixmap (parent->window, NULL, default_bits,
default_width, default_height);
swap_pixmap = create_pixmap (parent->window, NULL, swap_bits,
swap_width, swap_height);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
gtk_box_pack_start (GTK_BOX (parent), frame, FALSE, FALSE, 0);
gtk_widget_realize (frame);
alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_container_set_border_width (GTK_CONTAINER (alignment), 3);
gtk_container_add (GTK_CONTAINER (frame), alignment);
gtk_container_add (GTK_CONTAINER (alignment), qmask_area);
gtk_widget_show (qmask_off);
gtk_widget_show (qmask_on);
gtk_widget_show (alignment);
gtk_widget_show (frame);
}
#endif /* icky */
static void
create_indicator_area (GtkWidget *parent)
@ -572,9 +606,13 @@ create_toolbox ()
create_color_area (vbox);
if (show_indicators && (!no_data) )
create_indicator_area (vbox);
#ifdef icky
create_qmask_area (vbox);
#endif /*icky */
gtk_widget_show (window);
gimp_set_drop_open (window);
toolbox_shell = window;
}
@ -611,11 +649,17 @@ create_display_shell (GDisplay* gdisp,
{
static GtkWidget *image_popup_menu = NULL;
static GtkAccelGroup *image_accel_group = NULL;
GtkWidget *vbox;
GtkWidget *table;
GtkWidget *table_inner;
GtkWidget *table_lower;
GtkWidget *frame;
GtkWidget *arrow;
GtkWidget *pixmap;
GSList *group = NULL;
int n_width, n_height;
int s_width, s_height;
int scalesrc, scaledest;
@ -693,6 +737,9 @@ create_display_shell (GDisplay* gdisp,
gtk_table_set_col_spacing (GTK_TABLE (table_inner), 0, 1);
gtk_table_set_row_spacing (GTK_TABLE (table_inner), 0, 1);
table_lower = gtk_table_new (1,3,FALSE);
gtk_table_set_col_spacing (GTK_TABLE (table_lower), 0, 1);
/* gtk_table_set_row_spacing (GTK_TABLE (table_lower), 0, 1); */
/* hbox for statusbar area */
gdisp->statusarea = gtk_hbox_new (FALSE, 2);
@ -736,6 +783,51 @@ create_display_shell (GDisplay* gdisp,
gdisp->vsb = gtk_vscrollbar_new (gdisp->vsbdata);
GTK_WIDGET_UNSET_FLAGS (gdisp->vsb, GTK_CAN_FOCUS);
gdisp->qmaskoff = gtk_radio_button_new(group);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (gdisp->qmaskoff));
gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (gdisp->qmaskoff), FALSE);
gtk_signal_connect (GTK_OBJECT (gdisp->qmaskoff), "toggled",
(GtkSignalFunc) qmask_deactivate,
gdisp);
gdisp->qmaskon = gtk_radio_button_new(group);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (gdisp->qmaskon));
gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (gdisp->qmaskon), FALSE);
gtk_signal_connect (GTK_OBJECT (gdisp->qmaskon), "toggled",
(GtkSignalFunc) qmask_activate,
gdisp);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gdisp->qmaskoff), TRUE);
gtk_widget_set_usize(GTK_WIDGET(gdisp->qmaskon), 15, 15);
gtk_widget_set_usize(GTK_WIDGET(gdisp->qmaskoff), 15, 15);
/* Draw pixmaps - note: you must realize the parent prior to doing the
rest! */
{
GdkPixmap *pxmp;
GdkBitmap *mask;
GtkStyle *style;
style = gtk_widget_get_style(gdisp->shell);
gtk_widget_realize(gdisp->shell);
pxmp = gdk_pixmap_create_from_xpm_d(gdisp->shell->window, &mask,
&style->bg[GTK_STATE_NORMAL],
qmasksel_xpm);
pixmap = gtk_pixmap_new (pxmp, mask);
gtk_container_add (GTK_CONTAINER (gdisp->qmaskon), pixmap);
gtk_widget_show(pixmap);
pxmp = gdk_pixmap_create_from_xpm_d(gdisp->shell->window, &mask,
&style->bg[GTK_STATE_NORMAL],
qmasknosel_xpm);
pixmap = gtk_pixmap_new (pxmp, mask);
gtk_container_add (GTK_CONTAINER (gdisp->qmaskoff), pixmap);
gtk_widget_show(pixmap);
}
gdisp->canvas = gtk_drawing_area_new ();
gtk_drawing_area_size (GTK_DRAWING_AREA (gdisp->canvas), n_width, n_height);
gtk_widget_set_events (gdisp->canvas, CANVAS_EVENT_MASK);
@ -753,11 +845,22 @@ create_display_shell (GDisplay* gdisp,
gdisp);
/* pack all the widgets */
gtk_table_attach (GTK_TABLE (table), table_inner, 0, 1, 0, 1,
GTK_FILL | GTK_EXPAND | GTK_SHRINK,
GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0);
gtk_table_attach (GTK_TABLE (table), gdisp->hsb, 0, 1, 1, 2,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_FILL, 0, 0);
/* sneak in an extra table here */
gtk_table_attach (GTK_TABLE (table_lower), gdisp->hsb, 2, 3, 0, 1,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
gtk_table_attach (GTK_TABLE (table_lower), gdisp->qmaskoff, 0, 1, 0, 1,
GTK_SHRINK, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
gtk_table_attach (GTK_TABLE (table_lower), gdisp->qmaskon, 1, 2, 0, 1,
GTK_SHRINK, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
gtk_table_attach (GTK_TABLE (table), table_lower, 0, 1, 1, 2,
GTK_FILL | GTK_SHRINK | GTK_FILL, GTK_FILL, 0, 0);
gtk_table_attach (GTK_TABLE (table), gdisp->vsb, 1, 2, 0, 1,
GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
@ -809,13 +912,17 @@ create_display_shell (GDisplay* gdisp,
gtk_box_pack_start (GTK_BOX (gdisp->statusarea), gdisp->cancelbutton, FALSE, TRUE, 0);
gtk_widget_set_sensitive (gdisp->cancelbutton, FALSE);
/* the popup menu */
/* the popup menu */
gdisp->popup = image_popup_menu;
/* the accelerator table for images */
gtk_window_add_accel_group (GTK_WINDOW (gdisp->shell), image_accel_group);
gtk_widget_show (arrow);
gtk_widget_show (gdisp->qmaskon);
gtk_widget_show (gdisp->qmaskoff);
gtk_widget_show (gdisp->hsb);
gtk_widget_show (gdisp->vsb);
@ -832,6 +939,8 @@ create_display_shell (GDisplay* gdisp,
gtk_widget_show (gdisp->statusbar);
gtk_widget_show (gdisp->progressbar);
gtk_widget_show (gdisp->cancelbutton);
gtk_widget_show (table_lower);
gtk_widget_show (table_inner);
gtk_widget_show (table);
if (show_statusbar)
@ -839,16 +948,17 @@ create_display_shell (GDisplay* gdisp,
gtk_widget_show (gdisp->statusarea);
}
gtk_widget_show (vbox);
gtk_widget_show (gdisp->shell);
gtk_widget_show (gdisp->shell);
#ifdef __GNUC__
#warning DODGY?
#endif
#endif /*__GNUC__ */
gtk_widget_realize (gdisp->canvas);
gdk_window_set_back_pixmap(gdisp->canvas->window, NULL, 0);
/* set the focus to the canvas area */
gtk_widget_grab_focus (gdisp->canvas);
}

View File

@ -0,0 +1,152 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include "appenv.h"
#include "channel.h"
#include "gdisplayF.h"
#include "gimpcontext.h"
#include "gimage_mask.h"
#include "gimpimage.h"
#include "global_edit.h"
#include "qmask.h"
#include "undo.h"
/* Global variables */
/* Prototypes */
/* Static variables */
void
qmask_buttons_update (GDisplay *gdisp)
{
g_assert(gdisp);
g_assert(gdisp->gimage);
if (gdisp->gimage->qmask_state != GTK_TOGGLE_BUTTON(gdisp->qmaskon)->active)
{
/* Disable toggle from doing anything */
gtk_signal_handler_block_by_func(GTK_OBJECT(gdisp->qmaskoff),
(GtkSignalFunc) qmask_deactivate,
gdisp);
gtk_signal_handler_block_by_func(GTK_OBJECT(gdisp->qmaskon),
(GtkSignalFunc) qmask_activate,
gdisp);
/* Change the state of the buttons */
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gdisp->qmaskon),
gdisp->gimage->qmask_state);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gdisp->qmaskoff),
!gdisp->gimage->qmask_state);
/* Enable toggle again */
gtk_signal_handler_unblock_by_func(GTK_OBJECT(gdisp->qmaskoff),
(GtkSignalFunc) qmask_deactivate,
gdisp);
gtk_signal_handler_unblock_by_func(GTK_OBJECT(gdisp->qmaskon),
(GtkSignalFunc) qmask_activate,
gdisp);
/* Flush event queue */
/* while (g_main_iteration(FALSE)); */
}
}
void
qmask_deactivate(GtkWidget *w,
GDisplay *gdisp)
{
GimpImage *gimg;
GimpChannel *gmask;
if (gdisp)
{
gimg = gdisp->gimage;
if (!gimg) return;
if (!gdisp->gimage->qmask_state) {
return; /* if already set do nothing */
}
undo_push_group_start (gimg, QMASK_UNDO);
if ( (gmask = gimp_image_get_channel_by_name (gimg, "Qmask")) )
{
gimage_mask_load (gimg, gmask);
gimage_remove_channel(gimg, gmask);
undo_push_qmask(gimg,1);
gdisp->gimage->qmask_state = 0;
gdisplays_flush ();
}
undo_push_group_end (gimg);
}
}
void
qmask_activate(GtkWidget *w,
GDisplay *gdisp)
{
GimpImage *gimg;
GimpChannel *gmask;
unsigned char color[3] = {255,0,0};
double opacity = 50;
if (gdisp)
{
gimg = gdisp->gimage;
if (!gimg) return;
if (gdisp->gimage->qmask_state) {
return; /* If already set, do nothing */
}
if ( (gmask = gimp_image_get_channel_by_name (gimg, "Qmask")) )
return; /* do nothing if Qmask already exists */
undo_push_group_start (gimg, QMASK_UNDO);
if (gimage_mask_is_empty(gimg))
{ /* if no selection */
gmask = channel_new(gimg,
gimg->width,
gimg->height,
"Qmask",
(int)(255*opacity)/100,
color);
gimp_image_add_channel (gimg, gmask, 0);
edit_clear(gimg,GIMP_DRAWABLE(gmask));
undo_push_qmask(gimg,0);
gdisp->gimage->qmask_state = 1;
gdisplays_flush();
}
else
{ /* if selection */
gmask = channel_copy (gimage_get_mask (gimg));
gimp_image_add_channel (gimg, gmask, 0);
channel_set_color(gmask, color);
channel_set_name(gmask, "Qmask");
channel_set_opacity(gmask, opacity);
gimage_mask_none (gimg); /* Clear the selection */
undo_push_qmask(gimg,0);
gdisp->gimage->qmask_state = 1;
gdisplays_flush();
}
undo_push_group_end(gimg);
}
}

View File

@ -0,0 +1,30 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __QMASK_H__
#define __QMASK_H__
#include "pixmaps.h"
#ifdef icky
GtkWidget *
qmask_area_create (GDisplay *display);
#endif /* icky */
void qmask_activate(GtkWidget *w, GDisplay *gdisp);
void qmask_deactivate(GtkWidget *w, GDisplay *gdisp);
void qmask_buttons_update (GDisplay *gdisp);
#endif /* __QMASK_H__ */

View File

@ -40,12 +40,14 @@
#include "indicator_area.h"
#include "interface.h"
#include "menus.h"
#include "dialog_handler.h"
#include "qmask.h"
#include "session.h"
#include "tools.h"
#include "libgimp/gimpsizeentry.h"
#include "pixmaps.h"
#include "pixmaps/qmasksel.xpm"
#include "pixmaps/qmasknosel.xpm"
#include "libgimp/gimpintl.h"
@ -226,6 +228,38 @@ allocate_colors (GtkWidget *parent)
gdk_color_alloc (colormap, &colors[11]);
}
#ifdef icky
static void
create_qmask_area (GtkWidget *parent)
{
GtkWidget *frame;
GtkWidget *alignment;
GdkPixmap *default_pixmap;
GdkPixmap *swap_pixmap;
gtk_widget_realize (parent);
default_pixmap = create_pixmap (parent->window, NULL, default_bits,
default_width, default_height);
swap_pixmap = create_pixmap (parent->window, NULL, swap_bits,
swap_width, swap_height);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
gtk_box_pack_start (GTK_BOX (parent), frame, FALSE, FALSE, 0);
gtk_widget_realize (frame);
alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_container_set_border_width (GTK_CONTAINER (alignment), 3);
gtk_container_add (GTK_CONTAINER (frame), alignment);
gtk_container_add (GTK_CONTAINER (alignment), qmask_area);
gtk_widget_show (qmask_off);
gtk_widget_show (qmask_on);
gtk_widget_show (alignment);
gtk_widget_show (frame);
}
#endif /* icky */
static void
create_indicator_area (GtkWidget *parent)
@ -572,9 +606,13 @@ create_toolbox ()
create_color_area (vbox);
if (show_indicators && (!no_data) )
create_indicator_area (vbox);
#ifdef icky
create_qmask_area (vbox);
#endif /*icky */
gtk_widget_show (window);
gimp_set_drop_open (window);
toolbox_shell = window;
}
@ -611,11 +649,17 @@ create_display_shell (GDisplay* gdisp,
{
static GtkWidget *image_popup_menu = NULL;
static GtkAccelGroup *image_accel_group = NULL;
GtkWidget *vbox;
GtkWidget *table;
GtkWidget *table_inner;
GtkWidget *table_lower;
GtkWidget *frame;
GtkWidget *arrow;
GtkWidget *pixmap;
GSList *group = NULL;
int n_width, n_height;
int s_width, s_height;
int scalesrc, scaledest;
@ -693,6 +737,9 @@ create_display_shell (GDisplay* gdisp,
gtk_table_set_col_spacing (GTK_TABLE (table_inner), 0, 1);
gtk_table_set_row_spacing (GTK_TABLE (table_inner), 0, 1);
table_lower = gtk_table_new (1,3,FALSE);
gtk_table_set_col_spacing (GTK_TABLE (table_lower), 0, 1);
/* gtk_table_set_row_spacing (GTK_TABLE (table_lower), 0, 1); */
/* hbox for statusbar area */
gdisp->statusarea = gtk_hbox_new (FALSE, 2);
@ -736,6 +783,51 @@ create_display_shell (GDisplay* gdisp,
gdisp->vsb = gtk_vscrollbar_new (gdisp->vsbdata);
GTK_WIDGET_UNSET_FLAGS (gdisp->vsb, GTK_CAN_FOCUS);
gdisp->qmaskoff = gtk_radio_button_new(group);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (gdisp->qmaskoff));
gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (gdisp->qmaskoff), FALSE);
gtk_signal_connect (GTK_OBJECT (gdisp->qmaskoff), "toggled",
(GtkSignalFunc) qmask_deactivate,
gdisp);
gdisp->qmaskon = gtk_radio_button_new(group);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (gdisp->qmaskon));
gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (gdisp->qmaskon), FALSE);
gtk_signal_connect (GTK_OBJECT (gdisp->qmaskon), "toggled",
(GtkSignalFunc) qmask_activate,
gdisp);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gdisp->qmaskoff), TRUE);
gtk_widget_set_usize(GTK_WIDGET(gdisp->qmaskon), 15, 15);
gtk_widget_set_usize(GTK_WIDGET(gdisp->qmaskoff), 15, 15);
/* Draw pixmaps - note: you must realize the parent prior to doing the
rest! */
{
GdkPixmap *pxmp;
GdkBitmap *mask;
GtkStyle *style;
style = gtk_widget_get_style(gdisp->shell);
gtk_widget_realize(gdisp->shell);
pxmp = gdk_pixmap_create_from_xpm_d(gdisp->shell->window, &mask,
&style->bg[GTK_STATE_NORMAL],
qmasksel_xpm);
pixmap = gtk_pixmap_new (pxmp, mask);
gtk_container_add (GTK_CONTAINER (gdisp->qmaskon), pixmap);
gtk_widget_show(pixmap);
pxmp = gdk_pixmap_create_from_xpm_d(gdisp->shell->window, &mask,
&style->bg[GTK_STATE_NORMAL],
qmasknosel_xpm);
pixmap = gtk_pixmap_new (pxmp, mask);
gtk_container_add (GTK_CONTAINER (gdisp->qmaskoff), pixmap);
gtk_widget_show(pixmap);
}
gdisp->canvas = gtk_drawing_area_new ();
gtk_drawing_area_size (GTK_DRAWING_AREA (gdisp->canvas), n_width, n_height);
gtk_widget_set_events (gdisp->canvas, CANVAS_EVENT_MASK);
@ -753,11 +845,22 @@ create_display_shell (GDisplay* gdisp,
gdisp);
/* pack all the widgets */
gtk_table_attach (GTK_TABLE (table), table_inner, 0, 1, 0, 1,
GTK_FILL | GTK_EXPAND | GTK_SHRINK,
GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0);
gtk_table_attach (GTK_TABLE (table), gdisp->hsb, 0, 1, 1, 2,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_FILL, 0, 0);
/* sneak in an extra table here */
gtk_table_attach (GTK_TABLE (table_lower), gdisp->hsb, 2, 3, 0, 1,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
gtk_table_attach (GTK_TABLE (table_lower), gdisp->qmaskoff, 0, 1, 0, 1,
GTK_SHRINK, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
gtk_table_attach (GTK_TABLE (table_lower), gdisp->qmaskon, 1, 2, 0, 1,
GTK_SHRINK, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
gtk_table_attach (GTK_TABLE (table), table_lower, 0, 1, 1, 2,
GTK_FILL | GTK_SHRINK | GTK_FILL, GTK_FILL, 0, 0);
gtk_table_attach (GTK_TABLE (table), gdisp->vsb, 1, 2, 0, 1,
GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
@ -809,13 +912,17 @@ create_display_shell (GDisplay* gdisp,
gtk_box_pack_start (GTK_BOX (gdisp->statusarea), gdisp->cancelbutton, FALSE, TRUE, 0);
gtk_widget_set_sensitive (gdisp->cancelbutton, FALSE);
/* the popup menu */
/* the popup menu */
gdisp->popup = image_popup_menu;
/* the accelerator table for images */
gtk_window_add_accel_group (GTK_WINDOW (gdisp->shell), image_accel_group);
gtk_widget_show (arrow);
gtk_widget_show (gdisp->qmaskon);
gtk_widget_show (gdisp->qmaskoff);
gtk_widget_show (gdisp->hsb);
gtk_widget_show (gdisp->vsb);
@ -832,6 +939,8 @@ create_display_shell (GDisplay* gdisp,
gtk_widget_show (gdisp->statusbar);
gtk_widget_show (gdisp->progressbar);
gtk_widget_show (gdisp->cancelbutton);
gtk_widget_show (table_lower);
gtk_widget_show (table_inner);
gtk_widget_show (table);
if (show_statusbar)
@ -839,16 +948,17 @@ create_display_shell (GDisplay* gdisp,
gtk_widget_show (gdisp->statusarea);
}
gtk_widget_show (vbox);
gtk_widget_show (gdisp->shell);
gtk_widget_show (gdisp->shell);
#ifdef __GNUC__
#warning DODGY?
#endif
#endif /*__GNUC__ */
gtk_widget_realize (gdisp->canvas);
gdk_window_set_back_pixmap(gdisp->canvas->window, NULL, 0);
/* set the focus to the canvas area */
gtk_widget_grab_focus (gdisp->canvas);
}

View File

@ -24,6 +24,7 @@
#include "cursorutil.h"
#include "disp_callbacks.h"
#include "drawable.h"
#include "draw_core.h"
#include "gdisplay.h"
#include "gdisplayP.h"
#include "gdisplay_ops.h"
@ -37,14 +38,15 @@
#include "interface.h"
#include "lc_dialog.h"
#include "menus.h"
#include "draw_core.h"
#include "bezier_selectP.h"
#include "plug_in.h"
#include "qmask.h"
#include "scale.h"
#include "scroll.h"
#include "tools.h"
#include "undo.h"
#include "layer_pvt.h" /* ick. */
#include "bezier_selectP.h"
#include "layer_pvt.h" /* ick. (not alone either) */
#include "libgimp/gimpintl.h"
@ -138,6 +140,9 @@ gdisplay_new (GimpImage *gimage,
/* set the gdisplay colormap type and install the appropriate colormap */
gdisp->color_type = (gimage_base_type (gimage) == GRAY) ? GRAY : RGB;
/* set the qmask buttons */
qmask_buttons_update(gdisp);
/* set the user data */
if (!display_ht)
display_ht = g_hash_table_new ((GHashFunc) gdisplay_hash, NULL);
@ -646,7 +651,9 @@ gdisplay_flush_whenever (GDisplay *gdisp, gboolean now)
if (gdisp->window_info_dialog)
info_window_update (gdisp->window_info_dialog,
(void *) gdisp);
/* update the gdisplay's qmask buttons */
qmask_buttons_update (gdisp);
/* ensure the consistency of the tear-off menus */
context = gimp_context_get_user ();
if (gimp_context_get_display (context) == gdisp)

View File

@ -93,6 +93,7 @@ struct _GDisplay
GtkWidget *shell; /* shell widget for this gdisplay */
GtkWidget *canvas; /* canvas widget for this gdisplay */
GtkWidget *hsb, *vsb; /* widgets for scroll bars */
GtkWidget *qmaskoff, *qmaskon; /* widgets for qmask buttons */
GtkWidget *hrule, *vrule; /* widgets for rulers */
GtkWidget *origin; /* widgets for rulers */
GtkWidget *popup; /* widget for popup menu */
@ -147,7 +148,7 @@ struct _GDisplay
int cursor_y; /* software cursor Y value */
short proximity; /* is a device in proximity of gdisplay ? */
short have_cursor; /* is cursor currently drawn ? */
IdleRenderStruct idle_render; /* state of this gdisplay's render thread */
};

View File

@ -236,6 +236,24 @@ channel_get_name (Channel *channel)
return gimp_drawable_get_name(GIMP_DRAWABLE(channel));
}
void
channel_set_color (Channel *channel, gchar *color)
{
int i;
if (color)
{
for (i = 0; i < 3; i++)
channel->col[i] = color[i];
}
}
void
channel_set_opacity (Channel *channel, gint opacity)
{
if (opacity >=0 && opacity <= 100)
channel->opacity = (int) (opacity*255)/100;
}
Channel *
channel_get_ID (int ID)
{

View File

@ -86,6 +86,9 @@ void channel_unref (Channel *);
char * channel_get_name (Channel *);
void channel_set_name (Channel *, char *);
void channel_set_opacity (Channel *, int );
void channel_set_color (Channel *, gchar *);
Channel * channel_get_ID (int);
void channel_delete (Channel *);
void channel_scale (Channel *, int, int);

View File

@ -1711,6 +1711,22 @@ gimp_image_get_channel_by_tattoo (GimpImage *gimage, Tattoo tattoo)
}
Channel *
gimp_image_get_channel_by_name (GimpImage *gimage, char *name)
{
Channel *channel;
GSList *channels = gimage->channels;
while (channels)
{
channel = (Channel *) channels->data;
if (! strcmp(channel_get_name(channel),name) )
return channel;
channels = g_slist_next (channels);
}
return NULL;
}
int
gimp_image_get_component_active (GimpImage *gimage, ChannelType type)
{

View File

@ -178,6 +178,7 @@ Layer * gimp_image_get_active_layer (GimpImage *);
Channel * gimp_image_get_active_channel (GimpImage *);
Layer * gimp_image_get_layer_by_tattoo (GimpImage *, Tattoo);
Channel * gimp_image_get_channel_by_tattoo (GimpImage *, Tattoo);
Channel * gimp_image_get_channel_by_name (GimpImage *, char *);
Channel * gimp_image_get_mask (GimpImage *);
int gimp_image_get_component_active (GimpImage *, ChannelType);
int gimp_image_get_component_visible (GimpImage *, ChannelType);

View File

@ -70,6 +70,8 @@ struct _GimpImage
int by_color_select; /* TRUE if there's an active */
/* "by color" selection dialog */
int qmask_state; /* TRUE if qmask is on */
/* Undo apparatus */
GSList *undo_stack; /* stack for undo operations */
GSList *redo_stack; /* stack for redo operations */

152
app/gui/qmask-commands.c Normal file
View File

@ -0,0 +1,152 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include "appenv.h"
#include "channel.h"
#include "gdisplayF.h"
#include "gimpcontext.h"
#include "gimage_mask.h"
#include "gimpimage.h"
#include "global_edit.h"
#include "qmask.h"
#include "undo.h"
/* Global variables */
/* Prototypes */
/* Static variables */
void
qmask_buttons_update (GDisplay *gdisp)
{
g_assert(gdisp);
g_assert(gdisp->gimage);
if (gdisp->gimage->qmask_state != GTK_TOGGLE_BUTTON(gdisp->qmaskon)->active)
{
/* Disable toggle from doing anything */
gtk_signal_handler_block_by_func(GTK_OBJECT(gdisp->qmaskoff),
(GtkSignalFunc) qmask_deactivate,
gdisp);
gtk_signal_handler_block_by_func(GTK_OBJECT(gdisp->qmaskon),
(GtkSignalFunc) qmask_activate,
gdisp);
/* Change the state of the buttons */
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gdisp->qmaskon),
gdisp->gimage->qmask_state);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gdisp->qmaskoff),
!gdisp->gimage->qmask_state);
/* Enable toggle again */
gtk_signal_handler_unblock_by_func(GTK_OBJECT(gdisp->qmaskoff),
(GtkSignalFunc) qmask_deactivate,
gdisp);
gtk_signal_handler_unblock_by_func(GTK_OBJECT(gdisp->qmaskon),
(GtkSignalFunc) qmask_activate,
gdisp);
/* Flush event queue */
/* while (g_main_iteration(FALSE)); */
}
}
void
qmask_deactivate(GtkWidget *w,
GDisplay *gdisp)
{
GimpImage *gimg;
GimpChannel *gmask;
if (gdisp)
{
gimg = gdisp->gimage;
if (!gimg) return;
if (!gdisp->gimage->qmask_state) {
return; /* if already set do nothing */
}
undo_push_group_start (gimg, QMASK_UNDO);
if ( (gmask = gimp_image_get_channel_by_name (gimg, "Qmask")) )
{
gimage_mask_load (gimg, gmask);
gimage_remove_channel(gimg, gmask);
undo_push_qmask(gimg,1);
gdisp->gimage->qmask_state = 0;
gdisplays_flush ();
}
undo_push_group_end (gimg);
}
}
void
qmask_activate(GtkWidget *w,
GDisplay *gdisp)
{
GimpImage *gimg;
GimpChannel *gmask;
unsigned char color[3] = {255,0,0};
double opacity = 50;
if (gdisp)
{
gimg = gdisp->gimage;
if (!gimg) return;
if (gdisp->gimage->qmask_state) {
return; /* If already set, do nothing */
}
if ( (gmask = gimp_image_get_channel_by_name (gimg, "Qmask")) )
return; /* do nothing if Qmask already exists */
undo_push_group_start (gimg, QMASK_UNDO);
if (gimage_mask_is_empty(gimg))
{ /* if no selection */
gmask = channel_new(gimg,
gimg->width,
gimg->height,
"Qmask",
(int)(255*opacity)/100,
color);
gimp_image_add_channel (gimg, gmask, 0);
edit_clear(gimg,GIMP_DRAWABLE(gmask));
undo_push_qmask(gimg,0);
gdisp->gimage->qmask_state = 1;
gdisplays_flush();
}
else
{ /* if selection */
gmask = channel_copy (gimage_get_mask (gimg));
gimp_image_add_channel (gimg, gmask, 0);
channel_set_color(gmask, color);
channel_set_name(gmask, "Qmask");
channel_set_opacity(gmask, opacity);
gimage_mask_none (gimg); /* Clear the selection */
undo_push_qmask(gimg,0);
gdisp->gimage->qmask_state = 1;
gdisplays_flush();
}
undo_push_group_end(gimg);
}
}

View File

@ -40,12 +40,14 @@
#include "indicator_area.h"
#include "interface.h"
#include "menus.h"
#include "dialog_handler.h"
#include "qmask.h"
#include "session.h"
#include "tools.h"
#include "libgimp/gimpsizeentry.h"
#include "pixmaps.h"
#include "pixmaps/qmasksel.xpm"
#include "pixmaps/qmasknosel.xpm"
#include "libgimp/gimpintl.h"
@ -226,6 +228,38 @@ allocate_colors (GtkWidget *parent)
gdk_color_alloc (colormap, &colors[11]);
}
#ifdef icky
static void
create_qmask_area (GtkWidget *parent)
{
GtkWidget *frame;
GtkWidget *alignment;
GdkPixmap *default_pixmap;
GdkPixmap *swap_pixmap;
gtk_widget_realize (parent);
default_pixmap = create_pixmap (parent->window, NULL, default_bits,
default_width, default_height);
swap_pixmap = create_pixmap (parent->window, NULL, swap_bits,
swap_width, swap_height);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
gtk_box_pack_start (GTK_BOX (parent), frame, FALSE, FALSE, 0);
gtk_widget_realize (frame);
alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_container_set_border_width (GTK_CONTAINER (alignment), 3);
gtk_container_add (GTK_CONTAINER (frame), alignment);
gtk_container_add (GTK_CONTAINER (alignment), qmask_area);
gtk_widget_show (qmask_off);
gtk_widget_show (qmask_on);
gtk_widget_show (alignment);
gtk_widget_show (frame);
}
#endif /* icky */
static void
create_indicator_area (GtkWidget *parent)
@ -572,9 +606,13 @@ create_toolbox ()
create_color_area (vbox);
if (show_indicators && (!no_data) )
create_indicator_area (vbox);
#ifdef icky
create_qmask_area (vbox);
#endif /*icky */
gtk_widget_show (window);
gimp_set_drop_open (window);
toolbox_shell = window;
}
@ -611,11 +649,17 @@ create_display_shell (GDisplay* gdisp,
{
static GtkWidget *image_popup_menu = NULL;
static GtkAccelGroup *image_accel_group = NULL;
GtkWidget *vbox;
GtkWidget *table;
GtkWidget *table_inner;
GtkWidget *table_lower;
GtkWidget *frame;
GtkWidget *arrow;
GtkWidget *pixmap;
GSList *group = NULL;
int n_width, n_height;
int s_width, s_height;
int scalesrc, scaledest;
@ -693,6 +737,9 @@ create_display_shell (GDisplay* gdisp,
gtk_table_set_col_spacing (GTK_TABLE (table_inner), 0, 1);
gtk_table_set_row_spacing (GTK_TABLE (table_inner), 0, 1);
table_lower = gtk_table_new (1,3,FALSE);
gtk_table_set_col_spacing (GTK_TABLE (table_lower), 0, 1);
/* gtk_table_set_row_spacing (GTK_TABLE (table_lower), 0, 1); */
/* hbox for statusbar area */
gdisp->statusarea = gtk_hbox_new (FALSE, 2);
@ -736,6 +783,51 @@ create_display_shell (GDisplay* gdisp,
gdisp->vsb = gtk_vscrollbar_new (gdisp->vsbdata);
GTK_WIDGET_UNSET_FLAGS (gdisp->vsb, GTK_CAN_FOCUS);
gdisp->qmaskoff = gtk_radio_button_new(group);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (gdisp->qmaskoff));
gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (gdisp->qmaskoff), FALSE);
gtk_signal_connect (GTK_OBJECT (gdisp->qmaskoff), "toggled",
(GtkSignalFunc) qmask_deactivate,
gdisp);
gdisp->qmaskon = gtk_radio_button_new(group);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (gdisp->qmaskon));
gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (gdisp->qmaskon), FALSE);
gtk_signal_connect (GTK_OBJECT (gdisp->qmaskon), "toggled",
(GtkSignalFunc) qmask_activate,
gdisp);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gdisp->qmaskoff), TRUE);
gtk_widget_set_usize(GTK_WIDGET(gdisp->qmaskon), 15, 15);
gtk_widget_set_usize(GTK_WIDGET(gdisp->qmaskoff), 15, 15);
/* Draw pixmaps - note: you must realize the parent prior to doing the
rest! */
{
GdkPixmap *pxmp;
GdkBitmap *mask;
GtkStyle *style;
style = gtk_widget_get_style(gdisp->shell);
gtk_widget_realize(gdisp->shell);
pxmp = gdk_pixmap_create_from_xpm_d(gdisp->shell->window, &mask,
&style->bg[GTK_STATE_NORMAL],
qmasksel_xpm);
pixmap = gtk_pixmap_new (pxmp, mask);
gtk_container_add (GTK_CONTAINER (gdisp->qmaskon), pixmap);
gtk_widget_show(pixmap);
pxmp = gdk_pixmap_create_from_xpm_d(gdisp->shell->window, &mask,
&style->bg[GTK_STATE_NORMAL],
qmasknosel_xpm);
pixmap = gtk_pixmap_new (pxmp, mask);
gtk_container_add (GTK_CONTAINER (gdisp->qmaskoff), pixmap);
gtk_widget_show(pixmap);
}
gdisp->canvas = gtk_drawing_area_new ();
gtk_drawing_area_size (GTK_DRAWING_AREA (gdisp->canvas), n_width, n_height);
gtk_widget_set_events (gdisp->canvas, CANVAS_EVENT_MASK);
@ -753,11 +845,22 @@ create_display_shell (GDisplay* gdisp,
gdisp);
/* pack all the widgets */
gtk_table_attach (GTK_TABLE (table), table_inner, 0, 1, 0, 1,
GTK_FILL | GTK_EXPAND | GTK_SHRINK,
GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0);
gtk_table_attach (GTK_TABLE (table), gdisp->hsb, 0, 1, 1, 2,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_FILL, 0, 0);
/* sneak in an extra table here */
gtk_table_attach (GTK_TABLE (table_lower), gdisp->hsb, 2, 3, 0, 1,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
gtk_table_attach (GTK_TABLE (table_lower), gdisp->qmaskoff, 0, 1, 0, 1,
GTK_SHRINK, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
gtk_table_attach (GTK_TABLE (table_lower), gdisp->qmaskon, 1, 2, 0, 1,
GTK_SHRINK, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
gtk_table_attach (GTK_TABLE (table), table_lower, 0, 1, 1, 2,
GTK_FILL | GTK_SHRINK | GTK_FILL, GTK_FILL, 0, 0);
gtk_table_attach (GTK_TABLE (table), gdisp->vsb, 1, 2, 0, 1,
GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
@ -809,13 +912,17 @@ create_display_shell (GDisplay* gdisp,
gtk_box_pack_start (GTK_BOX (gdisp->statusarea), gdisp->cancelbutton, FALSE, TRUE, 0);
gtk_widget_set_sensitive (gdisp->cancelbutton, FALSE);
/* the popup menu */
/* the popup menu */
gdisp->popup = image_popup_menu;
/* the accelerator table for images */
gtk_window_add_accel_group (GTK_WINDOW (gdisp->shell), image_accel_group);
gtk_widget_show (arrow);
gtk_widget_show (gdisp->qmaskon);
gtk_widget_show (gdisp->qmaskoff);
gtk_widget_show (gdisp->hsb);
gtk_widget_show (gdisp->vsb);
@ -832,6 +939,8 @@ create_display_shell (GDisplay* gdisp,
gtk_widget_show (gdisp->statusbar);
gtk_widget_show (gdisp->progressbar);
gtk_widget_show (gdisp->cancelbutton);
gtk_widget_show (table_lower);
gtk_widget_show (table_inner);
gtk_widget_show (table);
if (show_statusbar)
@ -839,16 +948,17 @@ create_display_shell (GDisplay* gdisp,
gtk_widget_show (gdisp->statusarea);
}
gtk_widget_show (vbox);
gtk_widget_show (gdisp->shell);
gtk_widget_show (gdisp->shell);
#ifdef __GNUC__
#warning DODGY?
#endif
#endif /*__GNUC__ */
gtk_widget_realize (gdisp->canvas);
gdk_window_set_back_pixmap(gdisp->canvas->window, NULL, 0);
/* set the focus to the canvas area */
gtk_widget_grab_focus (gdisp->canvas);
}

152
app/qmask.c Normal file
View File

@ -0,0 +1,152 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include "appenv.h"
#include "channel.h"
#include "gdisplayF.h"
#include "gimpcontext.h"
#include "gimage_mask.h"
#include "gimpimage.h"
#include "global_edit.h"
#include "qmask.h"
#include "undo.h"
/* Global variables */
/* Prototypes */
/* Static variables */
void
qmask_buttons_update (GDisplay *gdisp)
{
g_assert(gdisp);
g_assert(gdisp->gimage);
if (gdisp->gimage->qmask_state != GTK_TOGGLE_BUTTON(gdisp->qmaskon)->active)
{
/* Disable toggle from doing anything */
gtk_signal_handler_block_by_func(GTK_OBJECT(gdisp->qmaskoff),
(GtkSignalFunc) qmask_deactivate,
gdisp);
gtk_signal_handler_block_by_func(GTK_OBJECT(gdisp->qmaskon),
(GtkSignalFunc) qmask_activate,
gdisp);
/* Change the state of the buttons */
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gdisp->qmaskon),
gdisp->gimage->qmask_state);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gdisp->qmaskoff),
!gdisp->gimage->qmask_state);
/* Enable toggle again */
gtk_signal_handler_unblock_by_func(GTK_OBJECT(gdisp->qmaskoff),
(GtkSignalFunc) qmask_deactivate,
gdisp);
gtk_signal_handler_unblock_by_func(GTK_OBJECT(gdisp->qmaskon),
(GtkSignalFunc) qmask_activate,
gdisp);
/* Flush event queue */
/* while (g_main_iteration(FALSE)); */
}
}
void
qmask_deactivate(GtkWidget *w,
GDisplay *gdisp)
{
GimpImage *gimg;
GimpChannel *gmask;
if (gdisp)
{
gimg = gdisp->gimage;
if (!gimg) return;
if (!gdisp->gimage->qmask_state) {
return; /* if already set do nothing */
}
undo_push_group_start (gimg, QMASK_UNDO);
if ( (gmask = gimp_image_get_channel_by_name (gimg, "Qmask")) )
{
gimage_mask_load (gimg, gmask);
gimage_remove_channel(gimg, gmask);
undo_push_qmask(gimg,1);
gdisp->gimage->qmask_state = 0;
gdisplays_flush ();
}
undo_push_group_end (gimg);
}
}
void
qmask_activate(GtkWidget *w,
GDisplay *gdisp)
{
GimpImage *gimg;
GimpChannel *gmask;
unsigned char color[3] = {255,0,0};
double opacity = 50;
if (gdisp)
{
gimg = gdisp->gimage;
if (!gimg) return;
if (gdisp->gimage->qmask_state) {
return; /* If already set, do nothing */
}
if ( (gmask = gimp_image_get_channel_by_name (gimg, "Qmask")) )
return; /* do nothing if Qmask already exists */
undo_push_group_start (gimg, QMASK_UNDO);
if (gimage_mask_is_empty(gimg))
{ /* if no selection */
gmask = channel_new(gimg,
gimg->width,
gimg->height,
"Qmask",
(int)(255*opacity)/100,
color);
gimp_image_add_channel (gimg, gmask, 0);
edit_clear(gimg,GIMP_DRAWABLE(gmask));
undo_push_qmask(gimg,0);
gdisp->gimage->qmask_state = 1;
gdisplays_flush();
}
else
{ /* if selection */
gmask = channel_copy (gimage_get_mask (gimg));
gimp_image_add_channel (gimg, gmask, 0);
channel_set_color(gmask, color);
channel_set_name(gmask, "Qmask");
channel_set_opacity(gmask, opacity);
gimage_mask_none (gimg); /* Clear the selection */
undo_push_qmask(gimg,0);
gdisp->gimage->qmask_state = 1;
gdisplays_flush();
}
undo_push_group_end(gimg);
}
}

30
app/qmask.h Normal file
View File

@ -0,0 +1,30 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __QMASK_H__
#define __QMASK_H__
#include "pixmaps.h"
#ifdef icky
GtkWidget *
qmask_area_create (GDisplay *display);
#endif /* icky */
void qmask_activate(GtkWidget *w, GDisplay *gdisp);
void qmask_deactivate(GtkWidget *w, GDisplay *gdisp);
void qmask_buttons_update (GDisplay *gdisp);
#endif /* __QMASK_H__ */

View File

@ -79,6 +79,7 @@ int undo_pop_fs_relax (GImage *, int, int, void *);
int undo_pop_gimage_mod (GImage *, int, int, void *);
int undo_pop_guide (GImage *, int, int, void *);
int undo_pop_parasite (GImage *, int, int, void *);
int undo_pop_qmask (GImage *, int, int, void *);
/* Free functions */
@ -98,7 +99,7 @@ void undo_free_fs_relax (int, void *);
void undo_free_gimage_mod (int, void *);
void undo_free_guide (int, void *);
void undo_free_parasite (int, void *);
void undo_free_qmask (int, void *);
/* Sizing functions */
@ -2011,6 +2012,87 @@ undo_free_gimage_mod (int state,
g_free (data_ptr);
}
/***********/
/* Qmask */
typedef struct _QmaskUndo QmaskUndo;
struct _QmaskUndo
{
GImage *gimage;
int qmask;
int orig;
};
int
undo_push_qmask (GImage *gimage,
int qmask)
{
Undo *new;
QmaskUndo *data;
long size;
/* increment the dirty flag for this gimage */
gimage_dirty (gimage);
size = sizeof (QmaskUndo);
if ((new = undo_push (gimage, size, GIMAGE_MOD)))
{
data = g_new (QmaskUndo, 1);
new->data = data;
new->pop_func = undo_pop_qmask;
new->free_func = undo_free_qmask;
data->gimage = gimage;
data->qmask = qmask;
data->orig = data->qmask;
return TRUE;
}
return FALSE;
}
int
undo_pop_qmask (GImage *gimage,
int state,
int type,
void *data_ptr)
{
QmaskUndo *data;
int tmp;
int tmp_ref;
data = data_ptr;
tmp = data->qmask;
data->qmask = data->orig;
data->orig = tmp;
gimage->qmask_state = data->qmask;
switch (state)
{
case UNDO:
gimage_clean (gimage);
break;
case REDO:
gimage_dirty (gimage);
break;
}
return TRUE;
}
void
undo_free_qmask (int state,
void *data_ptr)
{
g_free (data_ptr);
}
/***********/
/* Guide */
@ -2023,7 +2105,6 @@ struct _GuideUndo
Guide *guide;
Guide orig;
};
int
undo_push_guide (GImage *gimage,
void *guide)

View File

@ -55,6 +55,7 @@
#define CROP_UNDO 31
#define LAYER_SCALE_UNDO 32
#define LAYER_RESIZE_UNDO 33
#define QMASK_UNDO 34
#define MISC_UNDO 100
/* Undo interface functions */
@ -84,6 +85,7 @@ int undo_push_drawable_parasite (GImage *, GimpDrawable *, void *);
int undo_push_image_parasite_remove (GImage *, const char *);
int undo_push_drawable_parasite_remove (GImage *, GimpDrawable *,
const char *);
int undo_push_qmask (GImage *, int);
int undo_pop (GImage *);
int undo_redo (GImage *);

21
pixmaps/qmasknosel.xpm Normal file
View File

@ -0,0 +1,21 @@
/* XPM */
static char * qmasknosel_xpm[] = {
"15 15 3 1",
" c None",
". c #FFFFFF",
"+ c #000000",
" ",
" ",
" ",
" .+...+++. ",
" + . ",
" + . ",
" + + ",
" . + ",
" . + ",
" . . ",
" + . ",
" ++...+++. ",
" ",
" ",
" "};

16
pixmaps/qmasksel.xpm Normal file
View File

@ -0,0 +1,16 @@
/* XPM */
static char * qmasksel_xpm[] = {
"11 11 2 1",
" c None",
". c #FF0000",
"...........",
"...........",
".. ..",
".. ..",
".. ..",
".. ..",
".. ..",
".. ..",
".. ..",
"...........",
"..........."};

View File

@ -83,8 +83,7 @@ sub channel_set_prop_proc {
%invoke = (
vars => [ 'int i' ],
code => <<CODE
for (i = 0; i < 3; i++)
channel->col[i] = $prop\[i];
channel_set_color(channel, $prop);
CODE
);
}
@ -149,7 +148,7 @@ HELP
vars => [ 'int opacity' ],
code => <<'CODE'
{
opacity = (int) ((opacity_arg * 255) / 100);
channel_set_opacity (channel, opacity);
channel = channel_new (gimage, width, height, name, opacity, color);
success = channel != NULL;
}