gimp/app/commands.c

1371 lines
29 KiB
C
Raw Normal View History

1997-11-25 06:05:25 +08:00
/* 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.
1997-11-25 06:05:25 +08:00
*/
#include <stdlib.h>
#include <stdio.h>
#include "appenv.h"
#include "about_dialog.h"
#include "app_procs.h"
#include "brightness_contrast.h"
#include "gimpbrushlist.h"
1997-11-25 06:05:25 +08:00
#include "by_color_select.h"
#include "colormaps.h"
#include "colormap_dialog.i.h"
#include "color_area.h"
1997-11-25 06:05:25 +08:00
#include "color_balance.h"
#include "commands.h"
#include "convert.h"
#include "curves.h"
#include "desaturate.h"
#include "devices.h"
1997-11-25 06:05:25 +08:00
#include "channel_ops.h"
#include "drawable.h"
#include "equalize.h"
1998-08-13 23:25:41 +08:00
#include "errorconsole.h"
1997-11-25 06:05:25 +08:00
#include "fileops.h"
#include "floating_sel.h"
#include "gdisplay_ops.h"
#include "general.h"
#include "gimage_mask.h"
#include "gimprc.h"
#include "global_edit.h"
#include "gradient.h"
#include "histogram_tool.h"
#include "hue_saturation.h"
#include "image_render.h"
#include "info_window.h"
#include "interface.h"
#include "invert.h"
#include "lc_dialog.h"
1997-11-25 06:05:25 +08:00
#include "layer_select.h"
#include "levels.h"
#include "module_db.h"
1997-11-25 06:05:25 +08:00
#include "palette.h"
#include "patterns.h"
#include "plug_in.h"
#include "posterize.h"
#include "resize.h"
#include "scale.h"
#include "threshold.h"
#include "tips_dialog.h"
#include "tools.h"
#include "undo.h"
#include "libgimp/gimpintl.h"
#define return_if_no_display(gdisp) \
gdisp = gdisplay_active (); \
if (!gdisp) return
1997-11-25 06:05:25 +08:00
typedef struct
{
namespace cleanups. 1999-06-21 Michael Natterer <mitschel@cs.tu-berlin.de> * app/context_manager.c: namespace cleanups. * app/commands.[ch] * app/menus.c: moved the "Toggle Selection" menu entry to "View", sprinkled some separators and made the layers/channels/paths popup menus consistent with Tigert's last ops buttons change. * app/fileops.c * app/plug_in.c: check for gdisplay_active() returning NULL in some more places. * app/[all tool related files]: - Turned the ToolAction and ToolState #define's into typedef'ed enums, so the compiler can do some more sanity checking. - Removed one more unused global variable "active_tool_layer". - Removed some #include's from tools.c. - Standardized the individual tools' structure names. - Moved showing/hiding the tool options to separate functions. - Stuff... * app/commands.c * app/disp_callbacks.c * app/gdisplay.c * app/tools.c: fixed the segfaults which happened when the image of one of the tools which have dialogs (levels/posterize/...) was deleted. My approach was to do stricter sanity checking and to set some gdisplay pointers correctly where appropriate, so I can't tell exactly where the bug was. The curves tool now(??) updates on every _second_ display change only, which is really obscure. Finding/changing the display to operate on should definitely be done by connecting to the user context's "display_changed" signal. * app/gimpset.c: emit the "remove" signal _after_ removing the pointer from the set. If this was not a bug but a feature, please let me know, we'll need two signals then.
1999-06-22 06:12:07 +08:00
Resize *resize;
GimpImage *gimage;
1997-11-25 06:05:25 +08:00
} ImageResize;
/* external functions */
extern void layers_dialog_layer_merge_query (GImage *, int);
1997-11-25 06:05:25 +08:00
/* local functions */
static void image_resize_callback (GtkWidget *, gpointer);
static void image_scale_callback (GtkWidget *, gpointer);
static void image_cancel_callback (GtkWidget *, gpointer);
static gint image_delete_callback (GtkWidget *, GdkEvent *, gpointer);
1997-11-25 06:05:25 +08:00
static void gimage_mask_feather_callback (GtkWidget *, gpointer, gpointer);
static void gimage_mask_border_callback (GtkWidget *, gpointer, gpointer);
static void gimage_mask_grow_callback (GtkWidget *, gpointer, gpointer);
static void gimage_mask_shrink_callback (GtkWidget *, gpointer, gpointer);
1997-11-25 06:05:25 +08:00
/* local variables */
static gdouble selection_feather_radius = 5.0;
static gint selection_border_radius = 5;
static gint selection_grow_pixels = 1;
static gint selection_shrink_pixels = 1;
1997-11-25 06:05:25 +08:00
void
file_open_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
file_open_callback (widget, client_data);
}
void
file_save_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
file_save_callback (widget, client_data);
}
void
file_save_as_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
file_save_as_callback (widget, client_data);
}
1999-01-12 09:31:49 +08:00
void
file_revert_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
file_revert_callback (widget, client_data);
}
1997-11-25 06:05:25 +08:00
void
file_close_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay *gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
gdisplay_close_window (gdisp, FALSE);
}
void
file_quit_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
app_exit (0);
}
void
edit_cut_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
global_edit_cut (gdisp);
}
void
edit_copy_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
global_edit_copy (gdisp);
}
void
edit_paste_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
global_edit_paste (gdisp, 0);
}
void
edit_paste_into_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
global_edit_paste (gdisp, 1);
}
void
edit_clear_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
edit_clear (gdisp->gimage, gimage_active_drawable (gdisp->gimage));
gdisplays_flush ();
}
void
edit_fill_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
edit_fill (gdisp->gimage, gimage_active_drawable (gdisp->gimage));
gdisplays_flush ();
}
void
edit_stroke_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
gimage_mask_stroke (gdisp->gimage, gimage_active_drawable (gdisp->gimage));
gdisplays_flush ();
}
void
edit_undo_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
undo_pop (gdisp->gimage);
}
void
edit_redo_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
undo_redo (gdisp->gimage);
}
void
edit_named_cut_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
named_edit_cut (gdisp);
}
void
edit_named_copy_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
named_edit_copy (gdisp);
}
void
edit_named_paste_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
named_edit_paste (gdisp);
}
void
select_invert_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
gimage_mask_invert (gdisp->gimage);
gdisplays_flush ();
}
void
select_all_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
gimage_mask_all (gdisp->gimage);
gdisplays_flush ();
}
void
select_none_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
gimage_mask_none (gdisp->gimage);
gdisplays_flush ();
}
void
select_float_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
gimage_mask_float (gdisp->gimage, gimage_active_drawable (gdisp->gimage),
0, 0);
1997-11-25 06:05:25 +08:00
gdisplays_flush ();
}
void
select_sharpen_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
gimage_mask_sharpen (gdisp->gimage);
gdisplays_flush ();
}
void
select_border_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
query_size_box (N_("Border Selection"),
N_("Border selection by:"),
selection_border_radius, 1, 32767, 0,
gdisp->gimage->unit,
MIN (gdisp->gimage->xresolution,
gdisp->gimage->yresolution),
gdisp->dot_for_dot,
GTK_OBJECT (gdisp->gimage), "destroy",
gimage_mask_border_callback, gdisp->gimage);
1997-11-25 06:05:25 +08:00
}
void
select_feather_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
query_size_box (N_("Feather Selection"),
N_("Feather selection by:"),
selection_feather_radius, 0, 32767, 3,
gdisp->gimage->unit,
MIN (gdisp->gimage->xresolution,
gdisp->gimage->yresolution),
gdisp->dot_for_dot,
GTK_OBJECT (gdisp->gimage), "destroy",
gimage_mask_feather_callback, gdisp->gimage);
1997-11-25 06:05:25 +08:00
}
void
select_grow_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
query_size_box (N_("Grow Selection"),
N_("Grow selection by:"),
selection_grow_pixels, 1, 32767, 0,
gdisp->gimage->unit,
MIN (gdisp->gimage->xresolution,
gdisp->gimage->yresolution),
gdisp->dot_for_dot,
GTK_OBJECT (gdisp->gimage), "destroy",
gimage_mask_grow_callback, gdisp->gimage);
1997-11-25 06:05:25 +08:00
}
void
select_shrink_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
query_size_box (N_("Shrink Selection"),
N_("Shrink selection by:"),
selection_shrink_pixels, 1, 32767, 0,
gdisp->gimage->unit,
MIN (gdisp->gimage->xresolution,
gdisp->gimage->yresolution),
gdisp->dot_for_dot,
GTK_OBJECT (gdisp->gimage), "destroy",
gimage_mask_shrink_callback, gdisp->gimage);
1997-11-25 06:05:25 +08:00
}
void
select_save_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
gimage_mask_save (gdisp->gimage);
gdisplays_flush ();
}
void
view_dot_for_dot_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay *gdisp;
return_if_no_display (gdisp);
gdisplay_set_dot_for_dot (gdisp, GTK_CHECK_MENU_ITEM (widget)->active);
}
1997-11-25 06:05:25 +08:00
void
view_zoomin_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay *gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
change_scale (gdisp, ZOOMIN);
}
void
view_zoomout_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay *gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
change_scale (gdisp, ZOOMOUT);
}
static void
view_zoom_val (GtkWidget *widget,
gpointer client_data,
int val)
{
GDisplay *gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
change_scale (gdisp, val);
}
void
view_zoom_16_1_callback (GtkWidget *widget,
gpointer client_data)
{
view_zoom_val (widget, client_data, 1601);
}
void
view_zoom_8_1_callback (GtkWidget *widget,
gpointer client_data)
{
view_zoom_val (widget, client_data, 801);
}
void
view_zoom_4_1_callback (GtkWidget *widget,
gpointer client_data)
{
view_zoom_val (widget, client_data, 401);
}
void
view_zoom_2_1_callback (GtkWidget *widget,
gpointer client_data)
{
view_zoom_val (widget, client_data, 201);
}
void
view_zoom_1_1_callback (GtkWidget *widget,
gpointer client_data)
{
view_zoom_val (widget, client_data, 101);
}
void
view_zoom_1_2_callback (GtkWidget *widget,
gpointer client_data)
{
view_zoom_val (widget, client_data, 102);
}
void
view_zoom_1_4_callback (GtkWidget *widget,
gpointer client_data)
{
view_zoom_val (widget, client_data, 104);
}
void
view_zoom_1_8_callback (GtkWidget *widget,
gpointer client_data)
{
view_zoom_val (widget, client_data, 108);
}
void
view_zoom_1_16_callback (GtkWidget *widget,
gpointer client_data)
{
view_zoom_val (widget, client_data, 116);
}
void
view_window_info_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
if (! gdisp->window_info_dialog)
gdisp->window_info_dialog = info_window_create ((void *) gdisp);
info_dialog_popup (gdisp->window_info_dialog);
}
namespace cleanups. 1999-06-21 Michael Natterer <mitschel@cs.tu-berlin.de> * app/context_manager.c: namespace cleanups. * app/commands.[ch] * app/menus.c: moved the "Toggle Selection" menu entry to "View", sprinkled some separators and made the layers/channels/paths popup menus consistent with Tigert's last ops buttons change. * app/fileops.c * app/plug_in.c: check for gdisplay_active() returning NULL in some more places. * app/[all tool related files]: - Turned the ToolAction and ToolState #define's into typedef'ed enums, so the compiler can do some more sanity checking. - Removed one more unused global variable "active_tool_layer". - Removed some #include's from tools.c. - Standardized the individual tools' structure names. - Moved showing/hiding the tool options to separate functions. - Stuff... * app/commands.c * app/disp_callbacks.c * app/gdisplay.c * app/tools.c: fixed the segfaults which happened when the image of one of the tools which have dialogs (levels/posterize/...) was deleted. My approach was to do stricter sanity checking and to set some gdisplay pointers correctly where appropriate, so I can't tell exactly where the bug was. The curves tool now(??) updates on every _second_ display change only, which is really obscure. Finding/changing the display to operate on should definitely be done by connecting to the user context's "display_changed" signal. * app/gimpset.c: emit the "remove" signal _after_ removing the pointer from the set. If this was not a bug but a feature, please let me know, we'll need two signals then.
1999-06-22 06:12:07 +08:00
void
view_toggle_selection_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
selection_hide (gdisp->select, (void *) gdisp);
gdisplays_flush ();
}
1997-11-25 06:05:25 +08:00
void
view_toggle_rulers_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
/* This routine use promiscuous knowledge of gtk internals
* in order to hide and show the rulers "smoothly". This
* is kludgy and a hack and may break if gtk is changed
* internally.
*/
if (!GTK_CHECK_MENU_ITEM (widget)->active)
{
if (GTK_WIDGET_VISIBLE (gdisp->origin))
{
gtk_widget_unmap (gdisp->origin);
gtk_widget_unmap (gdisp->hrule);
gtk_widget_unmap (gdisp->vrule);
GTK_WIDGET_UNSET_FLAGS (gdisp->origin, GTK_VISIBLE);
GTK_WIDGET_UNSET_FLAGS (gdisp->hrule, GTK_VISIBLE);
GTK_WIDGET_UNSET_FLAGS (gdisp->vrule, GTK_VISIBLE);
gtk_widget_queue_resize (GTK_WIDGET (gdisp->origin->parent));
}
}
else
{
if (!GTK_WIDGET_VISIBLE (gdisp->origin))
{
gtk_widget_map (gdisp->origin);
gtk_widget_map (gdisp->hrule);
gtk_widget_map (gdisp->vrule);
GTK_WIDGET_SET_FLAGS (gdisp->origin, GTK_VISIBLE);
GTK_WIDGET_SET_FLAGS (gdisp->hrule, GTK_VISIBLE);
GTK_WIDGET_SET_FLAGS (gdisp->vrule, GTK_VISIBLE);
gtk_widget_queue_resize (GTK_WIDGET (gdisp->origin->parent));
}
}
}
void
view_toggle_guides_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
int old_val;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
old_val = gdisp->draw_guides;
gdisp->draw_guides = GTK_CHECK_MENU_ITEM (widget)->active;
if ((old_val != gdisp->draw_guides) && gdisp->gimage->guides)
{
gdisplay_expose_full (gdisp);
gdisplays_flush ();
}
}
void
view_snap_to_guides_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
gdisp->snap_to_guides = GTK_CHECK_MENU_ITEM (widget)->active;
}
void
view_toggle_statusbar_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
if (!GTK_CHECK_MENU_ITEM (widget)->active)
{
if (GTK_WIDGET_VISIBLE (gdisp->statusarea))
gtk_widget_hide (gdisp->statusarea);
}
else
{
if (!GTK_WIDGET_VISIBLE (gdisp->statusarea))
gtk_widget_show (gdisp->statusarea);
}
}
1997-11-25 06:05:25 +08:00
void
view_new_view_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay *gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
gdisplay_new_view (gdisp);
}
void
view_shrink_wrap_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay *gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
shrink_wrap_display (gdisp);
1997-11-25 06:05:25 +08:00
}
void
image_equalize_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
image_equalize ((void *) gdisp->gimage);
gdisplays_flush ();
}
void
image_invert_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
image_invert ((void *) gdisp->gimage);
gdisplays_flush ();
}
void
image_desaturate_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
image_desaturate ((void *) gdisp->gimage);
gdisplays_flush ();
}
void
channel_ops_duplicate_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
channel_ops_duplicate ((void *) gdisp->gimage);
}
void
channel_ops_offset_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
channel_ops_offset ((void *) gdisp->gimage);
}
void
image_convert_rgb_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
convert_to_rgb ((void *) gdisp->gimage);
}
void
image_convert_grayscale_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
convert_to_grayscale ((void *) gdisp->gimage);
}
void
image_convert_indexed_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
convert_to_indexed ((void *) gdisp->gimage);
}
void
image_resize_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
GimpImage * gimage;
ImageResize * image_resize;
1997-11-25 06:05:25 +08:00
return_if_no_display (gdisp);
gimage = gdisp->gimage;
1997-11-25 06:05:25 +08:00
/* the ImageResize structure */
image_resize = (ImageResize *) g_malloc (sizeof (ImageResize));
image_resize->gimage = gimage;
image_resize->resize = resize_widget_new (ResizeWidget,
ResizeImage,
GTK_OBJECT (gimage),
gimage->width,
gimage->height,
gimage->xresolution,
gimage->yresolution,
gimage->unit,
gdisp->dot_for_dot,
image_resize_callback,
image_cancel_callback,
image_delete_callback,
image_resize);
gtk_widget_show (image_resize->resize->resize_shell);
1997-11-25 06:05:25 +08:00
}
void
image_scale_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
GimpImage * gimage;
ImageResize * image_scale;
1997-11-25 06:05:25 +08:00
return_if_no_display (gdisp);
gimage = gdisp->gimage;
1997-11-25 06:05:25 +08:00
/* the ImageResize structure */
image_scale = (ImageResize *) g_malloc (sizeof (ImageResize));
image_scale->gimage = gimage;
image_scale->resize = resize_widget_new (ScaleWidget,
ResizeImage,
GTK_OBJECT (gimage),
gimage->width,
gimage->height,
gimage->xresolution,
gimage->yresolution,
gimage->unit,
gdisp->dot_for_dot,
image_scale_callback,
image_cancel_callback,
image_delete_callback,
image_scale);
1997-11-25 06:05:25 +08:00
gtk_widget_show (image_scale->resize->resize_shell);
1997-11-25 06:05:25 +08:00
}
void
layers_previous_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
int current_layer;
Layer * new_layer;
return_if_no_display (gdisp);
current_layer =
gimage_get_layer_index (gdisp->gimage, gdisp->gimage->active_layer);
/* FIXME: don't use internal knowledge about layer lists
* TODO : implement gimage_get_layer_by_index()
*/
new_layer =
(Layer *) g_slist_nth_data (gdisp->gimage->layers, current_layer - 1);
if (new_layer)
{
gimage_set_active_layer (gdisp->gimage, new_layer);
gdisplays_flush ();
}
}
void
layers_next_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
int current_layer;
Layer * new_layer;
return_if_no_display (gdisp);
current_layer =
gimage_get_layer_index (gdisp->gimage, gdisp->gimage->active_layer);
/* FIXME: don't use internal knowledge about layer lists
* TODO : implement gimage_get_layer_by_index()
*/
new_layer =
(Layer *) g_slist_nth_data (gdisp->gimage->layers, current_layer + 1);
if (new_layer)
{
gimage_set_active_layer (gdisp->gimage, new_layer);
gdisplays_flush ();
}
}
1997-11-25 06:05:25 +08:00
void
layers_raise_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
gimage_raise_layer (gdisp->gimage, gdisp->gimage->active_layer);
gdisplays_flush ();
}
void
layers_lower_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
gimage_lower_layer (gdisp->gimage, gdisp->gimage->active_layer);
gdisplays_flush ();
}
void
layers_raise_to_top_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
gimage_raise_layer_to_top (gdisp->gimage, gdisp->gimage->active_layer);
gdisplays_flush ();
}
void
layers_lower_to_bottom_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
gimage_lower_layer_to_bottom (gdisp->gimage, gdisp->gimage->active_layer);
gdisplays_flush ();
}
1997-11-25 06:05:25 +08:00
void
layers_anchor_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
floating_sel_anchor (gimage_get_active_layer (gdisp->gimage));
gdisplays_flush ();
}
void
layers_merge_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
layers_dialog_layer_merge_query (gdisp->gimage, TRUE);
}
void
layers_flatten_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
gimage_flatten (gdisp->gimage);
gdisplays_flush ();
}
void
layers_alpha_select_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
gimage_mask_layer_alpha (gdisp->gimage, gdisp->gimage->active_layer);
gdisplays_flush ();
}
void
layers_mask_select_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
1997-11-25 06:05:25 +08:00
gimage_mask_layer_mask (gdisp->gimage, gdisp->gimage->active_layer);
gdisplays_flush ();
}
void
layers_add_alpha_channel_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
layer_add_alpha ( gdisp->gimage->active_layer);
gdisplays_flush ();
}
void
tools_default_colors_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
palette_set_default_colors ();
}
void
tools_swap_colors_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
palette_swap_colors ();
}
1997-11-25 06:05:25 +08:00
void
tools_select_cmd_callback (GtkWidget *widget,
gpointer callback_data,
guint callback_action)
1997-11-25 06:05:25 +08:00
{
GDisplay * gdisp;
gdisp = gdisplay_active ();
namespace cleanups. 1999-06-21 Michael Natterer <mitschel@cs.tu-berlin.de> * app/context_manager.c: namespace cleanups. * app/commands.[ch] * app/menus.c: moved the "Toggle Selection" menu entry to "View", sprinkled some separators and made the layers/channels/paths popup menus consistent with Tigert's last ops buttons change. * app/fileops.c * app/plug_in.c: check for gdisplay_active() returning NULL in some more places. * app/[all tool related files]: - Turned the ToolAction and ToolState #define's into typedef'ed enums, so the compiler can do some more sanity checking. - Removed one more unused global variable "active_tool_layer". - Removed some #include's from tools.c. - Standardized the individual tools' structure names. - Moved showing/hiding the tool options to separate functions. - Stuff... * app/commands.c * app/disp_callbacks.c * app/gdisplay.c * app/tools.c: fixed the segfaults which happened when the image of one of the tools which have dialogs (levels/posterize/...) was deleted. My approach was to do stricter sanity checking and to set some gdisplay pointers correctly where appropriate, so I can't tell exactly where the bug was. The curves tool now(??) updates on every _second_ display change only, which is really obscure. Finding/changing the display to operate on should definitely be done by connecting to the user context's "display_changed" signal. * app/gimpset.c: emit the "remove" signal _after_ removing the pointer from the set. If this was not a bug but a feature, please let me know, we'll need two signals then.
1999-06-22 06:12:07 +08:00
/* Activate the approriate widget.
* Implicitly calls tools_select()
*/
gtk_widget_activate (tool_info[callback_action].tool_widget);
/* Complete the initialisation by doing the same stuff
* tools_initialize() does after it did what tools_select() does
*/
if (tool_info[callback_action].init_func && gdisp)
{
namespace cleanups. 1999-06-21 Michael Natterer <mitschel@cs.tu-berlin.de> * app/context_manager.c: namespace cleanups. * app/commands.[ch] * app/menus.c: moved the "Toggle Selection" menu entry to "View", sprinkled some separators and made the layers/channels/paths popup menus consistent with Tigert's last ops buttons change. * app/fileops.c * app/plug_in.c: check for gdisplay_active() returning NULL in some more places. * app/[all tool related files]: - Turned the ToolAction and ToolState #define's into typedef'ed enums, so the compiler can do some more sanity checking. - Removed one more unused global variable "active_tool_layer". - Removed some #include's from tools.c. - Standardized the individual tools' structure names. - Moved showing/hiding the tool options to separate functions. - Stuff... * app/commands.c * app/disp_callbacks.c * app/gdisplay.c * app/tools.c: fixed the segfaults which happened when the image of one of the tools which have dialogs (levels/posterize/...) was deleted. My approach was to do stricter sanity checking and to set some gdisplay pointers correctly where appropriate, so I can't tell exactly where the bug was. The curves tool now(??) updates on every _second_ display change only, which is really obscure. Finding/changing the display to operate on should definitely be done by connecting to the user context's "display_changed" signal. * app/gimpset.c: emit the "remove" signal _after_ removing the pointer from the set. If this was not a bug but a feature, please let me know, we'll need two signals then.
1999-06-22 06:12:07 +08:00
(* tool_info[callback_action].init_func) (gdisp);
active_tool->gdisp_ptr = gdisp;
active_tool->drawable = gimage_active_drawable (gdisp->gimage);
}
1997-11-25 06:05:25 +08:00
}
void
filters_repeat_cmd_callback (GtkWidget *widget,
gpointer callback_data,
guint callback_action)
1997-11-25 06:05:25 +08:00
{
plug_in_repeat (callback_action);
1997-11-25 06:05:25 +08:00
}
void
dialogs_brushes_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
create_brush_dialog ();
}
void
dialogs_patterns_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
create_pattern_dialog ();
}
void
dialogs_palette_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
palette_create ();
}
void
dialogs_gradient_editor_cmd_callback (GtkWidget *widget,
gpointer client_data)
1997-11-25 06:05:25 +08:00
{
grad_create_gradient_editor ();
}
1997-11-25 06:05:25 +08:00
void
dialogs_lc_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
1997-11-25 06:05:25 +08:00
gdisp = gdisplay_active ();
namespace cleanups. 1999-06-21 Michael Natterer <mitschel@cs.tu-berlin.de> * app/context_manager.c: namespace cleanups. * app/commands.[ch] * app/menus.c: moved the "Toggle Selection" menu entry to "View", sprinkled some separators and made the layers/channels/paths popup menus consistent with Tigert's last ops buttons change. * app/fileops.c * app/plug_in.c: check for gdisplay_active() returning NULL in some more places. * app/[all tool related files]: - Turned the ToolAction and ToolState #define's into typedef'ed enums, so the compiler can do some more sanity checking. - Removed one more unused global variable "active_tool_layer". - Removed some #include's from tools.c. - Standardized the individual tools' structure names. - Moved showing/hiding the tool options to separate functions. - Stuff... * app/commands.c * app/disp_callbacks.c * app/gdisplay.c * app/tools.c: fixed the segfaults which happened when the image of one of the tools which have dialogs (levels/posterize/...) was deleted. My approach was to do stricter sanity checking and to set some gdisplay pointers correctly where appropriate, so I can't tell exactly where the bug was. The curves tool now(??) updates on every _second_ display change only, which is really obscure. Finding/changing the display to operate on should definitely be done by connecting to the user context's "display_changed" signal. * app/gimpset.c: emit the "remove" signal _after_ removing the pointer from the set. If this was not a bug but a feature, please let me know, we'll need two signals then.
1999-06-22 06:12:07 +08:00
lc_dialog_create (gdisp ? gdisp->gimage : NULL);
1997-11-25 06:05:25 +08:00
}
static void
cmap_dlg_sel_cb (ColormapDialog *dlg,
gpointer user_data)
{
guchar * c;
GimpImage * img = colormap_dialog_image(dlg);
c = &img->cmap[colormap_dialog_col_index(dlg) * 3];
if(active_color == FOREGROUND)
palette_set_foreground (c[0], c[1], c[2]);
else if(active_color == BACKGROUND)
palette_set_background (c[0], c[1], c[2]);
}
1997-11-25 06:05:25 +08:00
void
dialogs_indexed_palette_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
static ColormapDialog * cmap_dlg;
if(!cmap_dlg)
{
cmap_dlg = colormap_dialog_create (image_context);
colormap_dialog_connect_selected (cmap_dlg_sel_cb, NULL, cmap_dlg);
}
gtk_widget_show (GTK_WIDGET (cmap_dlg));
1997-11-25 06:05:25 +08:00
}
void
dialogs_tools_options_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
tools_options_dialog_show ();
}
void
dialogs_input_devices_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
create_input_dialog ();
}
void
dialogs_device_status_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
create_device_status ();
}
void
dialogs_error_console_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
error_console_add (NULL);
}
1997-11-25 06:05:25 +08:00
void
about_dialog_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
about_dialog_create (FALSE);
}
void
tips_dialog_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
tips_dialog_create ();
}
void
dialogs_module_browser_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GtkWidget *w;
w = module_db_browser_new ();
gtk_widget_show (w);
}
1997-11-25 06:05:25 +08:00
/*********************/
/* Local functions */
/*********************/
static void
image_resize_callback (GtkWidget *w,
gpointer client_data)
{
ImageResize * image_resize;
GImage * gimage;
1997-11-25 06:05:25 +08:00
image_resize = (ImageResize *) client_data;
if ((gimage = image_resize->gimage) != NULL)
1997-11-25 06:05:25 +08:00
{
if (image_resize->resize->width > 0 &&
image_resize->resize->height > 0)
{
gimage_resize (gimage,
image_resize->resize->width,
image_resize->resize->height,
image_resize->resize->offset_x,
image_resize->resize->offset_y);
1997-11-25 06:05:25 +08:00
gdisplays_flush ();
}
else
{
g_message (_("Resize Error: Both width and height must be greater than zero."));
1997-11-25 06:05:25 +08:00
return;
}
}
resize_widget_free (image_resize->resize);
g_free (image_resize);
}
static void
image_scale_callback (GtkWidget *w,
gpointer client_data)
{
ImageResize * image_scale;
GImage * gimage;
gboolean flush = FALSE;
1997-11-25 06:05:25 +08:00
image_scale = (ImageResize *) client_data;
if ((gimage = image_scale->gimage) != NULL)
1997-11-25 06:05:25 +08:00
{
if (image_scale->resize->resolution_x != gimage->xresolution ||
image_scale->resize->resolution_y != gimage->yresolution)
1997-11-25 06:05:25 +08:00
{
gimage_set_resolution (gimage,
image_scale->resize->resolution_x,
image_scale->resize->resolution_y);
flush = TRUE;
1997-11-25 06:05:25 +08:00
}
if (image_scale->resize->unit != gimage->unit)
{
gimage_set_unit (gimage, image_scale->resize->unit);
gdisplays_resize_cursor_label (gimage);
}
if (image_scale->resize->width != gimage->width ||
image_scale->resize->height != gimage->height)
1997-11-25 06:05:25 +08:00
{
if (image_scale->resize->width > 0 &&
image_scale->resize->height > 0)
{
gimage_scale (gimage,
image_scale->resize->width,
image_scale->resize->height);
flush = TRUE;
}
else
{
g_message (_("Scale Error: Both width and height must be "
"greater than zero."));
return;
}
1997-11-25 06:05:25 +08:00
}
if (flush)
gdisplays_flush ();
1997-11-25 06:05:25 +08:00
}
resize_widget_free (image_scale->resize);
g_free (image_scale);
}
static gint
image_delete_callback (GtkWidget *w,
GdkEvent *e,
gpointer client_data)
1997-11-25 06:05:25 +08:00
{
image_cancel_callback (w, client_data);
return TRUE;
1997-11-25 06:05:25 +08:00
}
static void
image_cancel_callback (GtkWidget *w,
gpointer client_data)
{
ImageResize *image_resize;
1997-11-25 06:05:25 +08:00
image_resize = (ImageResize *) client_data;
resize_widget_free (image_resize->resize);
g_free (image_resize);
}
static void
gimage_mask_feather_callback (GtkWidget *w,
gpointer client_data,
gpointer call_data)
{
GImage *gimage = GIMP_IMAGE (client_data);
GUnit unit;
gdouble radius_x;
gdouble radius_y;
1997-11-25 06:05:25 +08:00
selection_feather_radius = *(double*) call_data;
g_free (call_data);
unit = (GUnit) gtk_object_get_data (GTK_OBJECT (w), "size_query_unit");
radius_x = radius_y = selection_feather_radius;
if (unit != UNIT_PIXEL)
{
double factor;
factor = (MAX (gimage->xresolution, gimage->yresolution) /
MIN (gimage->xresolution, gimage->yresolution));
if (gimage->xresolution == MIN (gimage->xresolution, gimage->yresolution))
radius_y *= factor;
else
radius_x *= factor;
}
gimage_mask_feather (gimage, radius_x, radius_y);
1997-11-25 06:05:25 +08:00
gdisplays_flush ();
}
static void
gimage_mask_border_callback (GtkWidget *w,
gpointer client_data,
gpointer call_data)
{
GImage *gimage = GIMP_IMAGE (client_data);
GUnit unit;
gdouble radius_x;
gdouble radius_y;
selection_border_radius = (int) (*(double*) call_data + 0.5);
g_free (call_data);
unit = (GUnit) gtk_object_get_data (GTK_OBJECT (w), "size_query_unit");
radius_x = radius_y = selection_feather_radius;
if (unit != UNIT_PIXEL)
{
double factor;
factor = (MAX (gimage->xresolution, gimage->yresolution) /
MIN (gimage->xresolution, gimage->yresolution));
if (gimage->xresolution == MIN (gimage->xresolution, gimage->yresolution))
radius_y *= factor;
else
radius_x *= factor;
}
gimage_mask_border (gimage, radius_x, radius_y);
1997-11-25 06:05:25 +08:00
gdisplays_flush ();
}
static void
gimage_mask_grow_callback (GtkWidget *w,
gpointer client_data,
gpointer call_data)
{
GImage *gimage = GIMP_IMAGE (client_data);
GUnit unit;
gdouble radius_x;
gdouble radius_y;
1997-11-25 06:05:25 +08:00
selection_grow_pixels = (int) (*(double*) call_data + 0.5);
g_free (call_data);
unit = (GUnit) gtk_object_get_data (GTK_OBJECT (w), "size_query_unit");
radius_x = radius_y = selection_grow_pixels;
if (unit != UNIT_PIXEL)
{
double factor;
factor = (MAX (gimage->xresolution, gimage->yresolution) /
MIN (gimage->xresolution, gimage->yresolution));
if (gimage->xresolution == MIN (gimage->xresolution, gimage->yresolution))
radius_y *= factor;
else
radius_x *= factor;
}
gimage_mask_grow (gimage, radius_x, radius_y);
1997-11-25 06:05:25 +08:00
gdisplays_flush ();
}
static void
gimage_mask_shrink_callback (GtkWidget *w,
gpointer client_data,
gpointer call_data)
{
GImage *gimage = GIMP_IMAGE (client_data);
GUnit unit;
gint radius_x;
gint radius_y;
1997-11-25 06:05:25 +08:00
selection_shrink_pixels = (int) (*(double*) call_data + 0.5);
g_free (call_data);
unit = (GUnit) gtk_object_get_data (GTK_OBJECT (w), "size_query_unit");
radius_x = radius_y = selection_shrink_pixels;
if (unit != UNIT_PIXEL)
{
double factor;
factor = (MAX (gimage->xresolution, gimage->yresolution) /
MIN (gimage->xresolution, gimage->yresolution));
if (gimage->xresolution == MIN (gimage->xresolution, gimage->yresolution))
radius_y *= factor;
else
radius_x *= factor;
}
gimage_mask_shrink (gimage, radius_x, radius_y, FALSE);
1997-11-25 06:05:25 +08:00
gdisplays_flush ();
}