gimp/app/core/gimpprojection.c

2247 lines
54 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
*/
app/appenv.h New file. Includes <math.h>. Move G_PI, RINT(), ROUND() etc 1999-09-01 Tor Lillqvist <tml@iki.fi> * app/appenv.h * libgimp/gimpmath.h: New file. Includes <math.h>. Move G_PI, RINT(), ROUND() etc from app/appenv.h here, so plug-ins can use them, too. Remove some commented-out old stuff in appenv.h. * libgimp/gimp.h: Include gimpmath.h. * libgimp/gimp.c (gimp_main): Win32: Don't install signal handlers, we can't do anything useful in the handler ourselves anyway (it would be nice to print out a backtrace, but that seems pretty hard to do, even if not impossible). Let Windows inform the user about the crash. If the plug-in was compiled with MSVC, and the user also has it, she is offered a chance to start the debugger automatically anyway. * app/*several*.c: Include gimpmath.h for G_PI etc. Don't include <math.h>, as gimpmath.h includes it. * plug-ins/*/*many*.c: Include config.h. Don't include <math.h>. Remove all the duplicated definitions of G_PI and rint(). Use RINT() instead of rint(). * app/app_procs.[ch]: app_exit() takes a gboolean. * app/batch.c * app/commands.c * app/interface.c: Call app_exit() with FALSE or TRUE. * app/main.c (on_error): Call gimp_fatal_error. (main): Don't install any signal handler on Win32 here, either. * app/errors.c (gimp_fatal_error, gimp_terminate): Win32: Format the message and call MessageBox with it. g_on_error_query doesn't do anything useful on Win32, and printf'ing a message to stdout or stderr doesn't do anything, either, in a windowing application.
1999-09-02 04:30:56 +08:00
#include "config.h"
1997-11-25 06:05:25 +08:00
#include <stdlib.h>
#include <string.h>
app/appenv.h New file. Includes <math.h>. Move G_PI, RINT(), ROUND() etc 1999-09-01 Tor Lillqvist <tml@iki.fi> * app/appenv.h * libgimp/gimpmath.h: New file. Includes <math.h>. Move G_PI, RINT(), ROUND() etc from app/appenv.h here, so plug-ins can use them, too. Remove some commented-out old stuff in appenv.h. * libgimp/gimp.h: Include gimpmath.h. * libgimp/gimp.c (gimp_main): Win32: Don't install signal handlers, we can't do anything useful in the handler ourselves anyway (it would be nice to print out a backtrace, but that seems pretty hard to do, even if not impossible). Let Windows inform the user about the crash. If the plug-in was compiled with MSVC, and the user also has it, she is offered a chance to start the debugger automatically anyway. * app/*several*.c: Include gimpmath.h for G_PI etc. Don't include <math.h>, as gimpmath.h includes it. * plug-ins/*/*many*.c: Include config.h. Don't include <math.h>. Remove all the duplicated definitions of G_PI and rint(). Use RINT() instead of rint(). * app/app_procs.[ch]: app_exit() takes a gboolean. * app/batch.c * app/commands.c * app/interface.c: Call app_exit() with FALSE or TRUE. * app/main.c (on_error): Call gimp_fatal_error. (main): Don't install any signal handler on Win32 here, either. * app/errors.c (gimp_fatal_error, gimp_terminate): Win32: Format the message and call MessageBox with it. g_on_error_query doesn't do anything useful on Win32, and printf'ing a message to stdout or stderr doesn't do anything, either, in a windowing application.
1999-09-02 04:30:56 +08:00
1997-11-25 06:05:25 +08:00
#include "appenv.h"
#include "colormaps.h"
#include "cursorutil.h"
#include "disp_callbacks.h"
#include "drawable.h"
#include "draw_core.h"
1997-11-25 06:05:25 +08:00
#include "gdisplay.h"
#include "gdisplayP.h"
#include "gdisplay_color.h"
1997-11-25 06:05:25 +08:00
#include "gdisplay_ops.h"
#include "gimage_mask.h"
#include "gimpcontext.h"
1997-11-25 06:05:25 +08:00
#include "gimprc.h"
#include "gximage.h"
#include "image_render.h"
#include "info_window.h"
#include "interface.h"
#include "lc_dialog.h"
1997-11-25 06:05:25 +08:00
#include "menus.h"
#include "nav_window.h"
1997-11-25 06:05:25 +08:00
#include "plug_in.h"
#include "qmask.h"
1997-11-25 06:05:25 +08:00
#include "scale.h"
#include "scroll.h"
#include "tools.h"
#include "undo.h"
#include "bezier_selectP.h"
#include "layer_pvt.h" /* ick. (not alone either) */
1997-11-25 06:05:25 +08:00
#include "libgimp/gimpintl.h"
app/appenv.h New file. Includes <math.h>. Move G_PI, RINT(), ROUND() etc 1999-09-01 Tor Lillqvist <tml@iki.fi> * app/appenv.h * libgimp/gimpmath.h: New file. Includes <math.h>. Move G_PI, RINT(), ROUND() etc from app/appenv.h here, so plug-ins can use them, too. Remove some commented-out old stuff in appenv.h. * libgimp/gimp.h: Include gimpmath.h. * libgimp/gimp.c (gimp_main): Win32: Don't install signal handlers, we can't do anything useful in the handler ourselves anyway (it would be nice to print out a backtrace, but that seems pretty hard to do, even if not impossible). Let Windows inform the user about the crash. If the plug-in was compiled with MSVC, and the user also has it, she is offered a chance to start the debugger automatically anyway. * app/*several*.c: Include gimpmath.h for G_PI etc. Don't include <math.h>, as gimpmath.h includes it. * plug-ins/*/*many*.c: Include config.h. Don't include <math.h>. Remove all the duplicated definitions of G_PI and rint(). Use RINT() instead of rint(). * app/app_procs.[ch]: app_exit() takes a gboolean. * app/batch.c * app/commands.c * app/interface.c: Call app_exit() with FALSE or TRUE. * app/main.c (on_error): Call gimp_fatal_error. (main): Don't install any signal handler on Win32 here, either. * app/errors.c (gimp_fatal_error, gimp_terminate): Win32: Format the message and call MessageBox with it. g_on_error_query doesn't do anything useful on Win32, and printf'ing a message to stdout or stderr doesn't do anything, either, in a windowing application.
1999-09-02 04:30:56 +08:00
#include "libgimp/gimpmath.h"
1997-11-25 06:05:25 +08:00
#define OVERHEAD 25 /* in units of pixel area */
#define EPSILON 5
#define MAX_TITLE_BUF 256
1997-11-25 06:05:25 +08:00
/* variable declarations */
GSList * display_list = NULL;
1997-11-25 06:05:25 +08:00
static int display_num = 1;
static GdkCursorType default_gdisplay_cursor = GDK_TOP_LEFT_ARROW;
/* Local functions */
static void gdisplay_format_title (GDisplay *, char *, int);
1997-11-25 06:05:25 +08:00
static void gdisplay_delete (GDisplay *);
static GSList * gdisplay_free_area_list (GSList *);
static GSList * gdisplay_process_area_list(GSList *, GArea *);
1997-11-25 06:05:25 +08:00
static void gdisplay_add_update_area (GDisplay *, int, int, int, int);
static void gdisplay_add_display_area (GDisplay *, int, int, int, int);
static void gdisplay_paint_area (GDisplay *, int, int, int, int);
static void gdisplay_draw_cursor (GDisplay *);
1997-11-25 06:05:25 +08:00
static void gdisplay_display_area (GDisplay *, int, int, int, int);
static guint gdisplay_hash (GDisplay *);
Dirty flag now correct in all cases. Can be displayed in image window Mon Aug 23 10:15:32 EDT 1999 Austin Donnelly <austin@gimp.org> Dirty flag now correct in all cases. Can be displayed in image window title too. See NOTE near gimp_image_dirty() for details. * app/fileops.c: gimp_image_clean_all() after reverting an image. * app/gdisplay.c: register handlers for gimage dirty and clean signals to update image title. New image-title-format expansion: %Dx expands to x if the image is dirty. * app/gdisplay_ops.c: gimage->dirty flags != 0 is the correct condition to test to see if an image is dirty. * app/gimpdrawable.c: gimp_image_dirty() should never be called except from an undo_push_* function. Call undo_push_cantundo() if you want to dirty the image but can't be bothered writing an undo handler (be ashamed of yourself!). * app/gimpimage.c: new gimage signal: clean. Emitted when an undo operation takes place. Gimage changes when either dirty or clean is emitted, so if you need to update previews etc, look for both! Move group_count into gimage structure, since leaving it as a static in undo.c is bad if two undo groups are started on different images at the same time. More changes of gimp_image_dirty() to undo_push_cantundo() (parasite-related, plus layer moves). See the NOTE on dirty counter near gimp_image_dirty() for the full story. gimp_image_dirty() and gimp_image_clean() simplified - counter can go negative. * app/gimpimageP.h: group_count moved from undo.c * app/layers_dialog.c: push undo for layer name change, rather than dirtying the image. * app/undo.c: layer rename undo functions added. undo_push_cantundo() convenience functions added. group_count made per-gimage since everything else is. When blowing away redo stack, make image infinitely dirty if redo info contained file save point. * app/undo.h: added undo_push_layer_rename() and undo_push_cantundo(). * TODO: added idea for undo history window.
1999-08-23 22:34:58 +08:00
static void gdisplay_cleandirty_handler (GimpImage *, void *);
1997-11-25 06:05:25 +08:00
1997-11-25 06:05:25 +08:00
static GHashTable *display_ht = NULL;
GDisplay*
gdisplay_new (GimpImage *gimage,
1997-11-25 06:05:25 +08:00
unsigned int scale)
{
GDisplay *gdisp;
char title [MAX_TITLE_BUF];
/* If there isn't an interface, never create a gdisplay */
if (no_interface)
return NULL;
/*
* Set all GDisplay parameters...
*/
gdisp = (GDisplay *) g_malloc (sizeof (GDisplay));
gdisp->offset_x = gdisp->offset_y = 0;
gdisp->scale = scale;
gdisp->dot_for_dot = TRUE;
1997-11-25 06:05:25 +08:00
gdisp->gimage = gimage;
gdisp->window_info_dialog = NULL;
gdisp->window_nav_dialog = NULL;
gdisp->nav_popup = NULL;
1997-11-25 06:05:25 +08:00
gdisp->depth = g_visual->depth;
gdisp->select = NULL;
gdisp->ID = display_num++;
gdisp->instance = gimage->instance_count;
1997-11-25 06:05:25 +08:00
gdisp->update_areas = NULL;
gdisp->display_areas = NULL;
gdisp->disp_xoffset = 0;
gdisp->disp_yoffset = 0;
gdisp->current_cursor = -1;
gdisp->draw_guides = TRUE;
gdisp->snap_to_guides = TRUE;
gdisp->draw_cursor = FALSE;
gdisp->proximity = FALSE;
gdisp->have_cursor = FALSE;
gdisp->using_override_cursor = FALSE;
gdisp->progressid = FALSE;
gdisp->idle_render.idleid = -1;
/*gdisp->idle_render.handlerid = -1;*/
gdisp->idle_render.update_areas = NULL;
gdisp->idle_render.active = FALSE;
gdisp->cd_list = NULL;
/* format the title */
gdisplay_format_title (gdisp, title, MAX_TITLE_BUF);
1997-11-25 06:05:25 +08:00
/* add the new display to the list so that it isn't lost */
display_list = g_slist_append (display_list, (void *) gdisp);
1997-11-25 06:05:25 +08:00
/* create the shell for the image */
create_display_shell (gdisp, gimage->width, gimage->height,
1997-11-25 06:05:25 +08:00
title, gimage_base_type (gimage));
/* update the title to correct the initially displayed scale */
gdisplay_update_title (gdisp);
1997-11-25 06:05:25 +08:00
/* 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);
1997-11-25 06:05:25 +08:00
/* set the user data */
if (!display_ht)
display_ht = g_hash_table_new ((GHashFunc) gdisplay_hash, NULL);
g_hash_table_insert (display_ht, gdisp->shell, gdisp);
g_hash_table_insert (display_ht, gdisp->canvas, gdisp);
/* set the current tool cursor */
gdisplay_install_tool_cursor (gdisp, default_gdisplay_cursor);
gimage->instance_count++;
gimage->ref_count++;
gimp/app/gimppreviewcache.c gimp/app/gimppreviewcache.h Wed Jun 23 23:52:54 BST 1999 Andy Thomas <alt@gimp.org> * gimp/app/gimppreviewcache.c * gimp/app/gimppreviewcache.h * gimp/app/drawable_cmds.c * gimp/app/gdisplay.c * gimp/app/gimpdrawableP.h * gimp/app/gimage_cmds.c * gimp/app/Makefile.am * gimp/app/layers_dialog.c * gimp/app/channel.c * gimp/app/lc_dialog.c * gimp/app/lc_dialog.h * gimp/app/lc_dialogP.h * gimp/app/layer.c * gimp/app/gimpdrawable.c * gimp/app/internal_procs.c * gimp/libgimp/gimp.h * gimp/libgimp/gimpimage.c * gimp/libgimp/gimpdrawable.c * gimp/libgimp/gimpmenu.c * gimp/tools/pdbgen/pdb/drawable.pdb * gimp/tools/pdbgen/pdb/gimage.pdb Added thumbnail image preview functions. Previews are visible on the L&C&P dialogs as well as in the drawables/channels/ menus generated for plugins (see the bumpmap & Mapobject plugins). PDB interface exists to simply extract a thumbnail preview of a given size. This is much quicker & more efficient than getting the image data tile-by-tile if you only need a small image since a "preview cache" has been implemented. This cache also reduces the number of times the tiles cached is scanned since smaller previews are always generated from large ones if they exists and are valid. Some possible usages (I don't intend to implement these ideas. Just suggestions). More plugins using the thumbnail preview (ie any that use multiple images). Indication of "active image" somewhere..... Actually almost anywhere a drawable/image name appears.
1999-06-24 07:01:14 +08:00
lc_dialog_preview_update(gimage);
Dirty flag now correct in all cases. Can be displayed in image window Mon Aug 23 10:15:32 EDT 1999 Austin Donnelly <austin@gimp.org> Dirty flag now correct in all cases. Can be displayed in image window title too. See NOTE near gimp_image_dirty() for details. * app/fileops.c: gimp_image_clean_all() after reverting an image. * app/gdisplay.c: register handlers for gimage dirty and clean signals to update image title. New image-title-format expansion: %Dx expands to x if the image is dirty. * app/gdisplay_ops.c: gimage->dirty flags != 0 is the correct condition to test to see if an image is dirty. * app/gimpdrawable.c: gimp_image_dirty() should never be called except from an undo_push_* function. Call undo_push_cantundo() if you want to dirty the image but can't be bothered writing an undo handler (be ashamed of yourself!). * app/gimpimage.c: new gimage signal: clean. Emitted when an undo operation takes place. Gimage changes when either dirty or clean is emitted, so if you need to update previews etc, look for both! Move group_count into gimage structure, since leaving it as a static in undo.c is bad if two undo groups are started on different images at the same time. More changes of gimp_image_dirty() to undo_push_cantundo() (parasite-related, plus layer moves). See the NOTE on dirty counter near gimp_image_dirty() for the full story. gimp_image_dirty() and gimp_image_clean() simplified - counter can go negative. * app/gimpimageP.h: group_count moved from undo.c * app/layers_dialog.c: push undo for layer name change, rather than dirtying the image. * app/undo.c: layer rename undo functions added. undo_push_cantundo() convenience functions added. group_count made per-gimage since everything else is. When blowing away redo stack, make image infinitely dirty if redo info contained file save point. * app/undo.h: added undo_push_layer_rename() and undo_push_cantundo(). * TODO: added idea for undo history window.
1999-08-23 22:34:58 +08:00
/* We're interested in clean and dirty signals so we can update the
* title if need be. */
gtk_signal_connect (GTK_OBJECT (gimage), "dirty",
GTK_SIGNAL_FUNC(gdisplay_cleandirty_handler), gdisp);
gtk_signal_connect (GTK_OBJECT (gimage), "clean",
GTK_SIGNAL_FUNC(gdisplay_cleandirty_handler), gdisp);
1997-11-25 06:05:25 +08:00
return gdisp;
}
static int print (char *, int, int, const char *, ...) G_GNUC_PRINTF (4, 5);
static int
print (char *buf, int len, int start, const char *fmt, ...)
{
va_list args;
int printed;
va_start (args, fmt);
printed = g_vsnprintf (buf + start, len - start, fmt, args);
if (printed < 0)
printed = len - start;
va_end (args);
return printed;
}
1997-11-25 06:05:25 +08:00
static void
gdisplay_format_title (GDisplay *gdisp,
char *title,
int title_len)
1997-11-25 06:05:25 +08:00
{
GimpImage *gimage;
1997-11-25 06:05:25 +08:00
char *image_type_str;
int empty;
int i;
char *format;
gimage = gdisp->gimage;
1997-11-25 06:05:25 +08:00
empty = gimage_is_empty (gimage);
switch (gimage_base_type (gimage))
{
case RGB:
image_type_str = (empty) ? _("RGB-empty") : _("RGB");
break;
case GRAY:
image_type_str = (empty) ? _("grayscale-empty") : _("grayscale");
break;
case INDEXED:
image_type_str = (empty) ? _("indexed-empty") : _("indexed");
break;
default:
image_type_str = NULL;
}
1997-11-25 06:05:25 +08:00
i = 0;
format = image_title_format;
while (i < title_len && *format)
{
switch (*format) {
case '%':
format++;
switch (*format) {
case 0:
configure.in removed tips files, AC_SUBST GIMP_PLUGINS and GIMP_MODULES so * configure.in * Makefile.am: removed tips files, AC_SUBST GIMP_PLUGINS and GIMP_MODULES so you can easily skip those parts of the build * acinclude.m4 * config.sub * config.guess * ltconfig * ltmain.sh: libtool 1.3.2 * app/fileops.c: shuffle #includes to avoid warning about MIN and MAX [ The following is a big i18n patch from David Monniaux <david.monniaux@ens.fr> ] * tips/gimp_conseils.fr.txt * tips/gimp_tips.txt * tips/Makefile.am * configure.in: moved tips to separate dir * po-plugins: new dir for plug-in translation files * configure.in: add po-plugins dir and POTFILES processing * app/boundary.c * app/brightness_contrast.c * app/by_color_select.c * app/color_balance.c * app/convert.c * app/curves.c * app/free_select.c * app/gdisplay.c * app/gimpimage.c * app/gimpunit.c * app/gradient.c * app/gradient_select.c * app/install.c * app/session.c: various i18n tweaks * app/tips_dialog.c: localize tips filename * libgimp/gimpunit.c * libgimp/gimpunitmenu.c: #include "config.h" * plug-ins/CEL * plug-ins/CML_explorer * plug-ins/Lighting * plug-ins/apply_lens * plug-ins/autostretch_hsv * plug-ins/blur * plug-ins/bmp * plug-ins/borderaverage * plug-ins/bumpmap * plug-ins/bz2 * plug-ins/checkerboard * plug-ins/colorify * plug-ins/compose * plug-ins/convmatrix * plug-ins/cubism * plug-ins/depthmerge * plug-ins/destripe * plug-ins/gif * plug-ins/gifload * plug-ins/jpeg * plug-ins/mail * plug-ins/oilify * plug-ins/png * plug-ins/print * plug-ins/ps * plug-ins/xbm * plug-ins/xpm * plug-ins/xwd: plug-in i18n stuff -Yosh
1999-05-30 00:35:47 +08:00
g_warning ("image-title-format string ended within %%-sequence");
break;
case '%':
title[i++] = '%';
break;
case 'f': /* pruned filename */
i += print (title, title_len, i,
"%s", g_basename (gimage_filename (gimage)));
break;
case 'F': /* full filename */
i += print (title, title_len, i, "%s", gimage_filename (gimage));
break;
case 'p': /* PDB id */
i += print (title, title_len, i, "%d", pdb_image_to_id (gimage));
break;
case 'i': /* instance */
i += print (title, title_len, i, "%d", gdisp->instance);
break;
case 't': /* type */
i += print (title, title_len, i, "%s", image_type_str);
break;
case 's': /* user source zoom factor */
i += print (title, title_len, i, "%d", SCALESRC (gdisp));
break;
case 'd': /* user destination zoom factor */
i += print (title, title_len, i, "%d", SCALEDEST (gdisp));
break;
case 'z': /* user zoom factor (percentage) */
i += print (title, title_len, i,
"%d", 100 * SCALEDEST (gdisp) / SCALESRC (gdisp));
break;
Dirty flag now correct in all cases. Can be displayed in image window Mon Aug 23 10:15:32 EDT 1999 Austin Donnelly <austin@gimp.org> Dirty flag now correct in all cases. Can be displayed in image window title too. See NOTE near gimp_image_dirty() for details. * app/fileops.c: gimp_image_clean_all() after reverting an image. * app/gdisplay.c: register handlers for gimage dirty and clean signals to update image title. New image-title-format expansion: %Dx expands to x if the image is dirty. * app/gdisplay_ops.c: gimage->dirty flags != 0 is the correct condition to test to see if an image is dirty. * app/gimpdrawable.c: gimp_image_dirty() should never be called except from an undo_push_* function. Call undo_push_cantundo() if you want to dirty the image but can't be bothered writing an undo handler (be ashamed of yourself!). * app/gimpimage.c: new gimage signal: clean. Emitted when an undo operation takes place. Gimage changes when either dirty or clean is emitted, so if you need to update previews etc, look for both! Move group_count into gimage structure, since leaving it as a static in undo.c is bad if two undo groups are started on different images at the same time. More changes of gimp_image_dirty() to undo_push_cantundo() (parasite-related, plus layer moves). See the NOTE on dirty counter near gimp_image_dirty() for the full story. gimp_image_dirty() and gimp_image_clean() simplified - counter can go negative. * app/gimpimageP.h: group_count moved from undo.c * app/layers_dialog.c: push undo for layer name change, rather than dirtying the image. * app/undo.c: layer rename undo functions added. undo_push_cantundo() convenience functions added. group_count made per-gimage since everything else is. When blowing away redo stack, make image infinitely dirty if redo info contained file save point. * app/undo.h: added undo_push_layer_rename() and undo_push_cantundo(). * TODO: added idea for undo history window.
1999-08-23 22:34:58 +08:00
case 'D': /* dirty flag */
if (format[1] == 0)
{
g_warning("image-title-format string ended within %%D-sequence");
break;
}
if (gimage->dirty)
title[i++] = format[1];
format++;
break;
/* Other cool things to be added:
* %m = memory used by picture
* some kind of resolution / image size thing
* people seem to want to know the active layer name
*/
default:
configure.in removed tips files, AC_SUBST GIMP_PLUGINS and GIMP_MODULES so * configure.in * Makefile.am: removed tips files, AC_SUBST GIMP_PLUGINS and GIMP_MODULES so you can easily skip those parts of the build * acinclude.m4 * config.sub * config.guess * ltconfig * ltmain.sh: libtool 1.3.2 * app/fileops.c: shuffle #includes to avoid warning about MIN and MAX [ The following is a big i18n patch from David Monniaux <david.monniaux@ens.fr> ] * tips/gimp_conseils.fr.txt * tips/gimp_tips.txt * tips/Makefile.am * configure.in: moved tips to separate dir * po-plugins: new dir for plug-in translation files * configure.in: add po-plugins dir and POTFILES processing * app/boundary.c * app/brightness_contrast.c * app/by_color_select.c * app/color_balance.c * app/convert.c * app/curves.c * app/free_select.c * app/gdisplay.c * app/gimpimage.c * app/gimpunit.c * app/gradient.c * app/gradient_select.c * app/install.c * app/session.c: various i18n tweaks * app/tips_dialog.c: localize tips filename * libgimp/gimpunit.c * libgimp/gimpunitmenu.c: #include "config.h" * plug-ins/CEL * plug-ins/CML_explorer * plug-ins/Lighting * plug-ins/apply_lens * plug-ins/autostretch_hsv * plug-ins/blur * plug-ins/bmp * plug-ins/borderaverage * plug-ins/bumpmap * plug-ins/bz2 * plug-ins/checkerboard * plug-ins/colorify * plug-ins/compose * plug-ins/convmatrix * plug-ins/cubism * plug-ins/depthmerge * plug-ins/destripe * plug-ins/gif * plug-ins/gifload * plug-ins/jpeg * plug-ins/mail * plug-ins/oilify * plug-ins/png * plug-ins/print * plug-ins/ps * plug-ins/xbm * plug-ins/xpm * plug-ins/xwd: plug-in i18n stuff -Yosh
1999-05-30 00:35:47 +08:00
g_warning ("image-title-format contains unknown format sequence '%%%c'", *format);
break;
}
break;
default:
title[i++] = *format;
break;
}
format++;
}
title[MIN(i, title_len-1)] = 0;
1997-11-25 06:05:25 +08:00
}
static void
gdisplay_delete (GDisplay *gdisp)
{
GimpContext *context;
1997-11-25 06:05:25 +08:00
g_hash_table_remove (display_ht, gdisp->shell);
g_hash_table_remove (display_ht, gdisp->canvas);
/* stop any active tool */
active_tool_control (HALT, (void *) 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
/* clear out the pointer to this gdisp from the active tool */
if (active_tool &&
active_tool->gdisp_ptr == 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
{
active_tool->drawable = NULL;
active_tool->gdisp_ptr = NULL;
}
1997-11-25 06:05:25 +08:00
/* free the selection structure */
selection_free (gdisp->select);
/* If this gdisplay was idlerendering at the time when it was deleted,
deactivate the idlerendering thread before deletion! */
if (gdisp->idle_render.active)
{
gtk_idle_remove (gdisp->idle_render.idleid);
gdisp->idle_render.active = FALSE;
}
Dirty flag now correct in all cases. Can be displayed in image window Mon Aug 23 10:15:32 EDT 1999 Austin Donnelly <austin@gimp.org> Dirty flag now correct in all cases. Can be displayed in image window title too. See NOTE near gimp_image_dirty() for details. * app/fileops.c: gimp_image_clean_all() after reverting an image. * app/gdisplay.c: register handlers for gimage dirty and clean signals to update image title. New image-title-format expansion: %Dx expands to x if the image is dirty. * app/gdisplay_ops.c: gimage->dirty flags != 0 is the correct condition to test to see if an image is dirty. * app/gimpdrawable.c: gimp_image_dirty() should never be called except from an undo_push_* function. Call undo_push_cantundo() if you want to dirty the image but can't be bothered writing an undo handler (be ashamed of yourself!). * app/gimpimage.c: new gimage signal: clean. Emitted when an undo operation takes place. Gimage changes when either dirty or clean is emitted, so if you need to update previews etc, look for both! Move group_count into gimage structure, since leaving it as a static in undo.c is bad if two undo groups are started on different images at the same time. More changes of gimp_image_dirty() to undo_push_cantundo() (parasite-related, plus layer moves). See the NOTE on dirty counter near gimp_image_dirty() for the full story. gimp_image_dirty() and gimp_image_clean() simplified - counter can go negative. * app/gimpimageP.h: group_count moved from undo.c * app/layers_dialog.c: push undo for layer name change, rather than dirtying the image. * app/undo.c: layer rename undo functions added. undo_push_cantundo() convenience functions added. group_count made per-gimage since everything else is. When blowing away redo stack, make image infinitely dirty if redo info contained file save point. * app/undo.h: added undo_push_layer_rename() and undo_push_cantundo(). * TODO: added idea for undo history window.
1999-08-23 22:34:58 +08:00
/* get rid of signals handled by this display */
gtk_signal_disconnect_by_data (GTK_OBJECT (gdisp->gimage), gdisp);
if (gdisp->scroll_gc)
gdk_gc_destroy (gdisp->scroll_gc);
1997-11-25 06:05:25 +08:00
/* free the area lists */
gdisplay_free_area_list (gdisp->update_areas);
gdisplay_free_area_list (gdisp->display_areas);
gdisplay_free_area_list (gdisp->idle_render.update_areas);
1997-11-25 06:05:25 +08:00
/* free the gimage */
gimage_delete (gdisp->gimage);
/* insure that if a window information dialog exists, it is removed */
if (gdisp->window_info_dialog)
info_window_free (gdisp->window_info_dialog);
/* Remove navigation dialog if we have one */
if(gdisp->window_nav_dialog)
nav_window_free(gdisp->window_nav_dialog);
if(gdisp->nav_popup)
nav_popup_free(gdisp->nav_popup);
/* set the active display to NULL if it was this display */
context = gimp_context_get_user ();
if (gimp_context_get_display (context) == gdisp)
gimp_context_set_display (context, NULL);
gtk_widget_unref (gdisp->shell);
1997-11-25 06:05:25 +08:00
g_free (gdisp);
}
static GSList *
gdisplay_free_area_list (GSList *list)
1997-11-25 06:05:25 +08:00
{
GSList *l = list;
1997-11-25 06:05:25 +08:00
GArea *ga;
while (l)
{
/* free the data */
ga = (GArea *) l->data;
g_free (ga);
l = g_slist_next (l);
1997-11-25 06:05:25 +08:00
}
if (list)
g_slist_free (list);
1997-11-25 06:05:25 +08:00
return NULL;
}
/*
* As far as I can tell, this function takes a GArea and unifies it with
* an existing list of GAreas, trying to avoid overdraw. [adam]
*/
static GSList *
gdisplay_process_area_list (GSList *list,
GArea *ga1)
1997-11-25 06:05:25 +08:00
{
GSList *new_list;
GSList *l = list;
1997-11-25 06:05:25 +08:00
int area1, area2, area3;
GArea *ga2;
/* start new list off */
new_list = g_slist_prepend (NULL, ga1);
1997-11-25 06:05:25 +08:00
while (l)
{
/* process the data */
ga2 = (GArea *) l->data;
area1 = (ga1->x2 - ga1->x1) * (ga1->y2 - ga1->y1) + OVERHEAD;
area2 = (ga2->x2 - ga2->x1) * (ga2->y2 - ga2->y1) + OVERHEAD;
area3 = (MAXIMUM (ga2->x2, ga1->x2) - MINIMUM (ga2->x1, ga1->x1)) *
(MAXIMUM (ga2->y2, ga1->y2) - MINIMUM (ga2->y1, ga1->y1)) + OVERHEAD;
if ((area1 + area2) < area3)
new_list = g_slist_prepend (new_list, ga2);
1997-11-25 06:05:25 +08:00
else
{
ga1->x1 = MINIMUM (ga1->x1, ga2->x1);
ga1->y1 = MINIMUM (ga1->y1, ga2->y1);
ga1->x2 = MAXIMUM (ga1->x2, ga2->x2);
ga1->y2 = MAXIMUM (ga1->y2, ga2->y2);
g_free (ga2);
}
l = g_slist_next (l);
1997-11-25 06:05:25 +08:00
}
if (list)
g_slist_free (list);
1997-11-25 06:05:25 +08:00
return new_list;
}
static int
idle_render_next_area (GDisplay *gdisp)
1997-11-25 06:05:25 +08:00
{
GArea *ga;
GSList *list;
list = gdisp->idle_render.update_areas;
1997-11-25 06:05:25 +08:00
if (list == NULL)
{
return (-1);
}
ga = (GArea*) list->data;
1997-11-25 06:05:25 +08:00
gdisp->idle_render.update_areas =
g_slist_remove (gdisp->idle_render.update_areas, ga);
gdisp->idle_render.x = gdisp->idle_render.basex = ga->x1;
gdisp->idle_render.y = gdisp->idle_render.basey = ga->y1;
gdisp->idle_render.width = ga->x2 - ga->x1;
gdisp->idle_render.height = ga->y2 - ga->y1;
g_free (ga);
return (0);
}
/* Unless specified otherwise, display re-rendering is organised
by IdleRender, which amalgamates areas to be re-rendered and
breaks them into bite-sized chunks which are chewed on in a low-
priority idle thread. This greatly improves responsiveness for
many GIMP operations. -- Adam */
static int
idlerender_callback (gpointer data)
{
const int CHUNK_WIDTH = 256;
const int CHUNK_HEIGHT = 128;
int workx, worky, workw, workh;
GDisplay* gdisp = data;
workw = CHUNK_WIDTH;
workh = CHUNK_HEIGHT;
workx = gdisp->idle_render.x;
worky = gdisp->idle_render.y;
if (workx+workw > gdisp->idle_render.basex+gdisp->idle_render.width)
{
workw = gdisp->idle_render.basex+gdisp->idle_render.width-workx;
}
if (worky+workh > gdisp->idle_render.basey+gdisp->idle_render.height)
{
workh = gdisp->idle_render.basey+gdisp->idle_render.height-worky;
}
gdisplay_paint_area (gdisp, workx, worky,
workw, workh);
gdisplay_flush_displays_only (gdisp);
gdisp->idle_render.x += CHUNK_WIDTH;
if (gdisp->idle_render.x >= gdisp->idle_render.basex+gdisp->idle_render.width)
{
gdisp->idle_render.x = gdisp->idle_render.basex;
gdisp->idle_render.y += CHUNK_HEIGHT;
if (gdisp->idle_render.y >=
gdisp->idle_render.basey + gdisp->idle_render.height)
{
if (idle_render_next_area(gdisp) != 0)
{
/* FINISHED */
gdisp->idle_render.active = FALSE;
return 0;
}
}
}
/* Still work to do. */
return 1;
}
static void
gdisplay_idlerender_init (GDisplay *gdisp)
{
GSList *list;
GArea *ga, *new_ga;
/* gdisplay_install_override_cursor(gdisp, GDK_CIRCLE); */
/* We need to merge the IdleRender's and the GDisplay's update_areas list
to keep track of which of the updates have been flushed and hence need
to be drawn. */
1997-11-25 06:05:25 +08:00
list = gdisp->update_areas;
while (list)
{
ga = (GArea *) list->data;
new_ga = g_malloc (sizeof(GArea));
memcpy (new_ga, ga, sizeof(GArea));
gdisp->idle_render.update_areas =
gdisplay_process_area_list (gdisp->idle_render.update_areas, new_ga);
1997-11-25 06:05:25 +08:00
list = g_slist_next (list);
1997-11-25 06:05:25 +08:00
}
/* If an idlerender was already running, merge the remainder of its
unrendered area with the update_areas list, and make it start work
on the next unrendered area in the list. */
if (gdisp->idle_render.active)
{
new_ga = g_malloc (sizeof(GArea));
new_ga->x1 = gdisp->idle_render.basex;
new_ga->y1 = gdisp->idle_render.y;
new_ga->x2 = gdisp->idle_render.basex + gdisp->idle_render.width;
new_ga->y2 = gdisp->idle_render.y +
(gdisp->idle_render.height -
(gdisp->idle_render.y - gdisp->idle_render.basey)
);
gdisp->idle_render.update_areas =
gdisplay_process_area_list (gdisp->idle_render.update_areas, new_ga);
idle_render_next_area(gdisp);
}
else
{
if (gdisp->idle_render.update_areas == NULL)
{
configure.in removed tips files, AC_SUBST GIMP_PLUGINS and GIMP_MODULES so * configure.in * Makefile.am: removed tips files, AC_SUBST GIMP_PLUGINS and GIMP_MODULES so you can easily skip those parts of the build * acinclude.m4 * config.sub * config.guess * ltconfig * ltmain.sh: libtool 1.3.2 * app/fileops.c: shuffle #includes to avoid warning about MIN and MAX [ The following is a big i18n patch from David Monniaux <david.monniaux@ens.fr> ] * tips/gimp_conseils.fr.txt * tips/gimp_tips.txt * tips/Makefile.am * configure.in: moved tips to separate dir * po-plugins: new dir for plug-in translation files * configure.in: add po-plugins dir and POTFILES processing * app/boundary.c * app/brightness_contrast.c * app/by_color_select.c * app/color_balance.c * app/convert.c * app/curves.c * app/free_select.c * app/gdisplay.c * app/gimpimage.c * app/gimpunit.c * app/gradient.c * app/gradient_select.c * app/install.c * app/session.c: various i18n tweaks * app/tips_dialog.c: localize tips filename * libgimp/gimpunit.c * libgimp/gimpunitmenu.c: #include "config.h" * plug-ins/CEL * plug-ins/CML_explorer * plug-ins/Lighting * plug-ins/apply_lens * plug-ins/autostretch_hsv * plug-ins/blur * plug-ins/bmp * plug-ins/borderaverage * plug-ins/bumpmap * plug-ins/bz2 * plug-ins/checkerboard * plug-ins/colorify * plug-ins/compose * plug-ins/convmatrix * plug-ins/cubism * plug-ins/depthmerge * plug-ins/destripe * plug-ins/gif * plug-ins/gifload * plug-ins/jpeg * plug-ins/mail * plug-ins/oilify * plug-ins/png * plug-ins/print * plug-ins/ps * plug-ins/xbm * plug-ins/xpm * plug-ins/xwd: plug-in i18n stuff -Yosh
1999-05-30 00:35:47 +08:00
g_warning ("Wanted to start idlerender thread with no update_areas. (+memleak)");
return;
}
idle_render_next_area(gdisp);
gdisp->idle_render.active = TRUE;
gdisp->idle_render.idleid =
gtk_idle_add_priority (GTK_PRIORITY_LOW,
idlerender_callback, gdisp);
}
/* Caller frees gdisp->update_areas */
}
void
gdisplay_flush_displays_only (GDisplay *gdisp)
{
GSList *list;
GArea *ga;
1997-11-25 06:05:25 +08:00
list = gdisp->display_areas;
if (list)
{
/* stop the currently active tool */
active_tool_control (PAUSE, (void *) gdisp);
while (list)
{
/* Paint the area specified by the GArea */
ga = (GArea *) list->data;
gdisplay_display_area (gdisp, ga->x1, ga->y1,
(ga->x2 - ga->x1), (ga->y2 - ga->y1));
list = g_slist_next (list);
1997-11-25 06:05:25 +08:00
}
/* Free the update lists */
gdisp->display_areas = gdisplay_free_area_list (gdisp->display_areas);
/* draw the guides */
gdisplay_draw_guides (gdisp);
/* and the cursor (if we have a software cursor */
if (gdisp->have_cursor)
gdisplay_draw_cursor (gdisp);
1997-11-25 06:05:25 +08:00
/* restart (and recalculate) the selection boundaries */
selection_start (gdisp->select, TRUE);
/* start the currently active tool */
active_tool_control (RESUME, (void *) gdisp);
}
}
static void
gdisplay_flush_whenever (GDisplay *gdisp, gboolean now)
{
GSList *list;
GArea *ga;
/* Flush the items in the displays and updates lists -
* but only if gdisplay has been mapped and exposed
*/
if (!gdisp->select)
return;
/* First the updates... */
if (now)
{ /* Synchronous */
list = gdisp->update_areas;
while (list)
{
/* Paint the area specified by the GArea */
ga = (GArea *) list->data;
if ((ga->x1 != ga->x2) && (ga->y1 != ga->y2))
{
gdisplay_paint_area (gdisp, ga->x1, ga->y1,
(ga->x2 - ga->x1), (ga->y2 - ga->y1));
}
list = g_slist_next (list);
}
1997-11-25 06:05:25 +08:00
}
else
{ /* Asynchronous */
if (gdisp->update_areas)
gdisplay_idlerender_init (gdisp);
}
/* Free the update lists */
gdisp->update_areas = gdisplay_free_area_list (gdisp->update_areas);
/* Next the displays... */
gdisplay_flush_displays_only (gdisp);
/* update the gdisplay's info dialog */
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 */
if (gimp_context_get_display (gimp_context_get_user ()) == gdisp)
gdisplay_set_menu_sensitivity (gdisp);
1997-11-25 06:05:25 +08:00
}
void
gdisplay_flush (GDisplay *gdisp)
{
/* Redraw on idle time */
gdisplay_flush_whenever (gdisp, FALSE);
}
void
gdisplay_flush_now (GDisplay *gdisp)
{
/* Redraw NOW */
gdisplay_flush_whenever (gdisp, TRUE);
}
/* Force all gdisplays to finish their idlerender projection */
void gdisplays_finish_draw (void)
{
GSList *list = display_list;
GDisplay* gdisp;
while (list)
{
gdisp = (GDisplay*) list->data;
if (gdisp->idle_render.active)
{
gtk_idle_remove (gdisp->idle_render.idleid);
while (idlerender_callback(gdisp));
}
list = g_slist_next (list);
}
}
1997-11-25 06:05:25 +08:00
void
gdisplay_draw_guides (GDisplay *gdisp)
{
GList *tmp_list;
Guide *guide;
if (gdisp->draw_guides)
{
tmp_list = gdisp->gimage->guides;
while (tmp_list)
{
guide = tmp_list->data;
tmp_list = tmp_list->next;
gdisplay_draw_guide (gdisp, guide, FALSE);
}
}
}
void
gdisplay_draw_guide (GDisplay *gdisp,
Guide *guide,
int active)
{
static GdkGC *normal_hgc = NULL;
static GdkGC *active_hgc = NULL;
static GdkGC *normal_vgc = NULL;
static GdkGC *active_vgc = NULL;
static int initialize = TRUE;
int x1, x2;
int y1, y2;
int w, h;
int x, y;
if (guide->position < 0)
return;
if (initialize)
{
GdkGCValues values;
const char stipple[] =
1997-11-25 06:05:25 +08:00
{
0xF0, /* ####---- */
0xE1, /* ###----# */
0xC3, /* ##----## */
0x87, /* #----### */
0x0F, /* ----#### */
0x1E, /* ---####- */
0x3C, /* --####-- */
0x78, /* -####--- */
};
initialize = FALSE;
values.foreground.pixel = gdisplay_black_pixel (gdisp);
values.background.pixel = g_normal_guide_pixel;
values.fill = GDK_OPAQUE_STIPPLED;
values.stipple = gdk_bitmap_create_from_data (gdisp->canvas->window,
(char*) stipple, 8, 1);
1997-11-25 06:05:25 +08:00
normal_hgc = gdk_gc_new_with_values (gdisp->canvas->window, &values,
GDK_GC_FOREGROUND |
GDK_GC_BACKGROUND |
GDK_GC_FILL |
GDK_GC_STIPPLE);
values.background.pixel = g_active_guide_pixel;
active_hgc = gdk_gc_new_with_values (gdisp->canvas->window, &values,
GDK_GC_FOREGROUND |
GDK_GC_BACKGROUND |
GDK_GC_FILL |
GDK_GC_STIPPLE);
values.foreground.pixel = gdisplay_black_pixel (gdisp);
values.background.pixel = g_normal_guide_pixel;
values.fill = GDK_OPAQUE_STIPPLED;
values.stipple = gdk_bitmap_create_from_data (gdisp->canvas->window,
(char*) stipple, 1, 8);
1997-11-25 06:05:25 +08:00
normal_vgc = gdk_gc_new_with_values (gdisp->canvas->window, &values,
GDK_GC_FOREGROUND |
GDK_GC_BACKGROUND |
GDK_GC_FILL |
GDK_GC_STIPPLE);
values.background.pixel = g_active_guide_pixel;
active_vgc = gdk_gc_new_with_values (gdisp->canvas->window, &values,
GDK_GC_FOREGROUND |
GDK_GC_BACKGROUND |
GDK_GC_FILL |
GDK_GC_STIPPLE);
}
gdisplay_transform_coords (gdisp, 0, 0, &x1, &y1, FALSE);
gdisplay_transform_coords (gdisp,
gdisp->gimage->width, gdisp->gimage->height,
&x2, &y2, FALSE);
1997-11-25 06:05:25 +08:00
gdk_window_get_size (gdisp->canvas->window, &w, &h);
if (x1 < 0) x1 = 0;
if (y1 < 0) y1 = 0;
if (x2 > w) x2 = w;
if (y2 > h) y2 = h;
add sample_colorize and curve_bend defs * plug-ins/common/plugin-defs.pl: add sample_colorize and curve_bend defs * libgimp/color_selector.h: minor consistency cleanup * libgimp/gimpchainbutton.[ch]: use new style gtk object helper macros * libgimp/gimpfileselection.c * libgimp/gimpmatrix.h: minor cleanup * libgimp/gimpintl.h: resync with gnome-i18n.h * libgimp/color_display.h * app/gimp.sym * app/gdisplay_color.[ch] * app/app_procs.c * app/gdisplay.h * app/image_render.c: color display transformation code. Still unfinished, so it's not activated yet. * app/buildmenu.h: remove unused defines (PULLDOWN, POPUP, OPTION) * app/colormaps.[ch] * app/image_render.c: remove vestigal dithering stuff * app/convolve.h * app/gimpdrawable.h * app/gimpimage.h * app/lut_funcs.h * app/paint_funcs.h * app/plug_in.h: enum nick changes from Marc * app/channel_ops.c * app/crop.c * app/gdisplay.c * app/gimpimage.[ch] * app/move.c: s/([A-Z]+)_GUIDE/ORIENTATION_$1/ * app/flip_tool.[ch] * app/shear_tool.[ch]: use ORIENTATION_* constants instead of our own * app/disp_callbacks.c: remove HORIZONTAL and VERTICAL #defines * app/general.h: enumified TOKEN_* symbols * app/lc_dialog.c * app/paint_funcs.c: remove unused variables * tools/pdbgen/lib.pl: autogen gimpenums.h (unfinished) * tools/pdbgen/stddefs.pdb: new std_orientation_enum, remove layer_mode shortcut since we've skipped it in app/ * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/drawable.pdb * tools/pdbgen/pdb/gimage.pdb * tools/pdbgen/pdb/guides.pdb * tools/pdbgen/pdb/layer.pdb * tools/pdbgen/pdb/tools.pdb: reflect above enum changes, whitespace cleanups * tools/pdbgen/enums.pl * app/brush_select_cmds.c * app/brushes_cmds.c * app/color_cmds.c * app/drawable_cmds.c * app/gimage_cmds.c * app/layer_cmds.c * app/procedural_db_cmds.c * app/tools_cmds.c: reflect pdb and enum nick changes above -Yosh
1999-07-29 07:00:08 +08:00
if (guide->orientation == ORIENTATION_HORIZONTAL)
1997-11-25 06:05:25 +08:00
{
gdisplay_transform_coords (gdisp, 0, guide->position, &x, &y, FALSE);
if (active)
gdk_draw_line (gdisp->canvas->window, active_hgc, x1, y, x2, y);
else
gdk_draw_line (gdisp->canvas->window, normal_hgc, x1, y, x2, y);
}
add sample_colorize and curve_bend defs * plug-ins/common/plugin-defs.pl: add sample_colorize and curve_bend defs * libgimp/color_selector.h: minor consistency cleanup * libgimp/gimpchainbutton.[ch]: use new style gtk object helper macros * libgimp/gimpfileselection.c * libgimp/gimpmatrix.h: minor cleanup * libgimp/gimpintl.h: resync with gnome-i18n.h * libgimp/color_display.h * app/gimp.sym * app/gdisplay_color.[ch] * app/app_procs.c * app/gdisplay.h * app/image_render.c: color display transformation code. Still unfinished, so it's not activated yet. * app/buildmenu.h: remove unused defines (PULLDOWN, POPUP, OPTION) * app/colormaps.[ch] * app/image_render.c: remove vestigal dithering stuff * app/convolve.h * app/gimpdrawable.h * app/gimpimage.h * app/lut_funcs.h * app/paint_funcs.h * app/plug_in.h: enum nick changes from Marc * app/channel_ops.c * app/crop.c * app/gdisplay.c * app/gimpimage.[ch] * app/move.c: s/([A-Z]+)_GUIDE/ORIENTATION_$1/ * app/flip_tool.[ch] * app/shear_tool.[ch]: use ORIENTATION_* constants instead of our own * app/disp_callbacks.c: remove HORIZONTAL and VERTICAL #defines * app/general.h: enumified TOKEN_* symbols * app/lc_dialog.c * app/paint_funcs.c: remove unused variables * tools/pdbgen/lib.pl: autogen gimpenums.h (unfinished) * tools/pdbgen/stddefs.pdb: new std_orientation_enum, remove layer_mode shortcut since we've skipped it in app/ * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/drawable.pdb * tools/pdbgen/pdb/gimage.pdb * tools/pdbgen/pdb/guides.pdb * tools/pdbgen/pdb/layer.pdb * tools/pdbgen/pdb/tools.pdb: reflect above enum changes, whitespace cleanups * tools/pdbgen/enums.pl * app/brush_select_cmds.c * app/brushes_cmds.c * app/color_cmds.c * app/drawable_cmds.c * app/gimage_cmds.c * app/layer_cmds.c * app/procedural_db_cmds.c * app/tools_cmds.c: reflect pdb and enum nick changes above -Yosh
1999-07-29 07:00:08 +08:00
else if (guide->orientation == ORIENTATION_VERTICAL)
1997-11-25 06:05:25 +08:00
{
gdisplay_transform_coords (gdisp, guide->position, 0, &x, &y, FALSE);
if (active)
gdk_draw_line (gdisp->canvas->window, active_vgc, x, y1, x, y2);
else
gdk_draw_line (gdisp->canvas->window, normal_vgc, x, y1, x, y2);
}
}
Guide*
gdisplay_find_guide (GDisplay *gdisp,
int x,
int y)
{
GList *tmp_list;
Guide *guide;
double scalex, scaley;
1997-11-25 06:05:25 +08:00
int offset_x, offset_y;
int pos;
if (gdisp->draw_guides)
{
offset_x = gdisp->offset_x - gdisp->disp_xoffset;
offset_y = gdisp->offset_y - gdisp->disp_yoffset;
scalex = SCALEFACTOR_X (gdisp);
scaley = SCALEFACTOR_Y (gdisp);
1997-11-25 06:05:25 +08:00
tmp_list = gdisp->gimage->guides;
while (tmp_list)
{
guide = tmp_list->data;
tmp_list = tmp_list->next;
switch (guide->orientation)
{
add sample_colorize and curve_bend defs * plug-ins/common/plugin-defs.pl: add sample_colorize and curve_bend defs * libgimp/color_selector.h: minor consistency cleanup * libgimp/gimpchainbutton.[ch]: use new style gtk object helper macros * libgimp/gimpfileselection.c * libgimp/gimpmatrix.h: minor cleanup * libgimp/gimpintl.h: resync with gnome-i18n.h * libgimp/color_display.h * app/gimp.sym * app/gdisplay_color.[ch] * app/app_procs.c * app/gdisplay.h * app/image_render.c: color display transformation code. Still unfinished, so it's not activated yet. * app/buildmenu.h: remove unused defines (PULLDOWN, POPUP, OPTION) * app/colormaps.[ch] * app/image_render.c: remove vestigal dithering stuff * app/convolve.h * app/gimpdrawable.h * app/gimpimage.h * app/lut_funcs.h * app/paint_funcs.h * app/plug_in.h: enum nick changes from Marc * app/channel_ops.c * app/crop.c * app/gdisplay.c * app/gimpimage.[ch] * app/move.c: s/([A-Z]+)_GUIDE/ORIENTATION_$1/ * app/flip_tool.[ch] * app/shear_tool.[ch]: use ORIENTATION_* constants instead of our own * app/disp_callbacks.c: remove HORIZONTAL and VERTICAL #defines * app/general.h: enumified TOKEN_* symbols * app/lc_dialog.c * app/paint_funcs.c: remove unused variables * tools/pdbgen/lib.pl: autogen gimpenums.h (unfinished) * tools/pdbgen/stddefs.pdb: new std_orientation_enum, remove layer_mode shortcut since we've skipped it in app/ * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/drawable.pdb * tools/pdbgen/pdb/gimage.pdb * tools/pdbgen/pdb/guides.pdb * tools/pdbgen/pdb/layer.pdb * tools/pdbgen/pdb/tools.pdb: reflect above enum changes, whitespace cleanups * tools/pdbgen/enums.pl * app/brush_select_cmds.c * app/brushes_cmds.c * app/color_cmds.c * app/drawable_cmds.c * app/gimage_cmds.c * app/layer_cmds.c * app/procedural_db_cmds.c * app/tools_cmds.c: reflect pdb and enum nick changes above -Yosh
1999-07-29 07:00:08 +08:00
case ORIENTATION_HORIZONTAL:
pos = (int) (scaley * guide->position - offset_y);
if ((guide->position != -1) &&
(pos > (y - EPSILON)) &&
1997-11-25 06:05:25 +08:00
(pos < (y + EPSILON)))
return guide;
break;
add sample_colorize and curve_bend defs * plug-ins/common/plugin-defs.pl: add sample_colorize and curve_bend defs * libgimp/color_selector.h: minor consistency cleanup * libgimp/gimpchainbutton.[ch]: use new style gtk object helper macros * libgimp/gimpfileselection.c * libgimp/gimpmatrix.h: minor cleanup * libgimp/gimpintl.h: resync with gnome-i18n.h * libgimp/color_display.h * app/gimp.sym * app/gdisplay_color.[ch] * app/app_procs.c * app/gdisplay.h * app/image_render.c: color display transformation code. Still unfinished, so it's not activated yet. * app/buildmenu.h: remove unused defines (PULLDOWN, POPUP, OPTION) * app/colormaps.[ch] * app/image_render.c: remove vestigal dithering stuff * app/convolve.h * app/gimpdrawable.h * app/gimpimage.h * app/lut_funcs.h * app/paint_funcs.h * app/plug_in.h: enum nick changes from Marc * app/channel_ops.c * app/crop.c * app/gdisplay.c * app/gimpimage.[ch] * app/move.c: s/([A-Z]+)_GUIDE/ORIENTATION_$1/ * app/flip_tool.[ch] * app/shear_tool.[ch]: use ORIENTATION_* constants instead of our own * app/disp_callbacks.c: remove HORIZONTAL and VERTICAL #defines * app/general.h: enumified TOKEN_* symbols * app/lc_dialog.c * app/paint_funcs.c: remove unused variables * tools/pdbgen/lib.pl: autogen gimpenums.h (unfinished) * tools/pdbgen/stddefs.pdb: new std_orientation_enum, remove layer_mode shortcut since we've skipped it in app/ * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/drawable.pdb * tools/pdbgen/pdb/gimage.pdb * tools/pdbgen/pdb/guides.pdb * tools/pdbgen/pdb/layer.pdb * tools/pdbgen/pdb/tools.pdb: reflect above enum changes, whitespace cleanups * tools/pdbgen/enums.pl * app/brush_select_cmds.c * app/brushes_cmds.c * app/color_cmds.c * app/drawable_cmds.c * app/gimage_cmds.c * app/layer_cmds.c * app/procedural_db_cmds.c * app/tools_cmds.c: reflect pdb and enum nick changes above -Yosh
1999-07-29 07:00:08 +08:00
case ORIENTATION_VERTICAL:
pos = (int) (scalex * guide->position - offset_x);
if ((guide->position != -1) &&
(pos > (x - EPSILON)) &&
1997-11-25 06:05:25 +08:00
(pos < (x + EPSILON)))
return guide;
break;
}
}
}
return NULL;
}
void
gdisplay_snap_point (GDisplay *gdisp,
gdouble x ,
gdouble y,
gdouble *tx,
gdouble *ty)
1997-11-25 06:05:25 +08:00
{
GList *tmp_list;
Guide *guide;
double scalex, scaley;
1997-11-25 06:05:25 +08:00
int offset_x, offset_y;
int minhdist, minvdist;
int pos, dist;
*tx = x;
*ty = y;
if (gdisp->draw_guides &&
gdisp->snap_to_guides &&
gdisp->gimage->guides)
{
offset_x = gdisp->offset_x - gdisp->disp_xoffset;
offset_y = gdisp->offset_y - gdisp->disp_yoffset;
scalex = SCALEFACTOR_X (gdisp);
scaley = SCALEFACTOR_Y (gdisp);
1997-11-25 06:05:25 +08:00
minhdist = G_MAXINT;
minvdist = G_MAXINT;
tmp_list = gdisp->gimage->guides;
while (tmp_list)
{
guide = tmp_list->data;
tmp_list = tmp_list->next;
switch (guide->orientation)
{
add sample_colorize and curve_bend defs * plug-ins/common/plugin-defs.pl: add sample_colorize and curve_bend defs * libgimp/color_selector.h: minor consistency cleanup * libgimp/gimpchainbutton.[ch]: use new style gtk object helper macros * libgimp/gimpfileselection.c * libgimp/gimpmatrix.h: minor cleanup * libgimp/gimpintl.h: resync with gnome-i18n.h * libgimp/color_display.h * app/gimp.sym * app/gdisplay_color.[ch] * app/app_procs.c * app/gdisplay.h * app/image_render.c: color display transformation code. Still unfinished, so it's not activated yet. * app/buildmenu.h: remove unused defines (PULLDOWN, POPUP, OPTION) * app/colormaps.[ch] * app/image_render.c: remove vestigal dithering stuff * app/convolve.h * app/gimpdrawable.h * app/gimpimage.h * app/lut_funcs.h * app/paint_funcs.h * app/plug_in.h: enum nick changes from Marc * app/channel_ops.c * app/crop.c * app/gdisplay.c * app/gimpimage.[ch] * app/move.c: s/([A-Z]+)_GUIDE/ORIENTATION_$1/ * app/flip_tool.[ch] * app/shear_tool.[ch]: use ORIENTATION_* constants instead of our own * app/disp_callbacks.c: remove HORIZONTAL and VERTICAL #defines * app/general.h: enumified TOKEN_* symbols * app/lc_dialog.c * app/paint_funcs.c: remove unused variables * tools/pdbgen/lib.pl: autogen gimpenums.h (unfinished) * tools/pdbgen/stddefs.pdb: new std_orientation_enum, remove layer_mode shortcut since we've skipped it in app/ * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/drawable.pdb * tools/pdbgen/pdb/gimage.pdb * tools/pdbgen/pdb/guides.pdb * tools/pdbgen/pdb/layer.pdb * tools/pdbgen/pdb/tools.pdb: reflect above enum changes, whitespace cleanups * tools/pdbgen/enums.pl * app/brush_select_cmds.c * app/brushes_cmds.c * app/color_cmds.c * app/drawable_cmds.c * app/gimage_cmds.c * app/layer_cmds.c * app/procedural_db_cmds.c * app/tools_cmds.c: reflect pdb and enum nick changes above -Yosh
1999-07-29 07:00:08 +08:00
case ORIENTATION_HORIZONTAL:
pos = (int) (scaley * guide->position - offset_y);
1997-11-25 06:05:25 +08:00
if ((pos > (y - EPSILON)) &&
(pos < (y + EPSILON)))
{
dist = pos - y;
dist = ABS (dist);
if (dist < minhdist)
{
minhdist = dist;
*ty = pos;
}
}
break;
add sample_colorize and curve_bend defs * plug-ins/common/plugin-defs.pl: add sample_colorize and curve_bend defs * libgimp/color_selector.h: minor consistency cleanup * libgimp/gimpchainbutton.[ch]: use new style gtk object helper macros * libgimp/gimpfileselection.c * libgimp/gimpmatrix.h: minor cleanup * libgimp/gimpintl.h: resync with gnome-i18n.h * libgimp/color_display.h * app/gimp.sym * app/gdisplay_color.[ch] * app/app_procs.c * app/gdisplay.h * app/image_render.c: color display transformation code. Still unfinished, so it's not activated yet. * app/buildmenu.h: remove unused defines (PULLDOWN, POPUP, OPTION) * app/colormaps.[ch] * app/image_render.c: remove vestigal dithering stuff * app/convolve.h * app/gimpdrawable.h * app/gimpimage.h * app/lut_funcs.h * app/paint_funcs.h * app/plug_in.h: enum nick changes from Marc * app/channel_ops.c * app/crop.c * app/gdisplay.c * app/gimpimage.[ch] * app/move.c: s/([A-Z]+)_GUIDE/ORIENTATION_$1/ * app/flip_tool.[ch] * app/shear_tool.[ch]: use ORIENTATION_* constants instead of our own * app/disp_callbacks.c: remove HORIZONTAL and VERTICAL #defines * app/general.h: enumified TOKEN_* symbols * app/lc_dialog.c * app/paint_funcs.c: remove unused variables * tools/pdbgen/lib.pl: autogen gimpenums.h (unfinished) * tools/pdbgen/stddefs.pdb: new std_orientation_enum, remove layer_mode shortcut since we've skipped it in app/ * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/drawable.pdb * tools/pdbgen/pdb/gimage.pdb * tools/pdbgen/pdb/guides.pdb * tools/pdbgen/pdb/layer.pdb * tools/pdbgen/pdb/tools.pdb: reflect above enum changes, whitespace cleanups * tools/pdbgen/enums.pl * app/brush_select_cmds.c * app/brushes_cmds.c * app/color_cmds.c * app/drawable_cmds.c * app/gimage_cmds.c * app/layer_cmds.c * app/procedural_db_cmds.c * app/tools_cmds.c: reflect pdb and enum nick changes above -Yosh
1999-07-29 07:00:08 +08:00
case ORIENTATION_VERTICAL:
pos = (int) (scalex * guide->position - offset_x);
1997-11-25 06:05:25 +08:00
if ((pos > (x - EPSILON)) &&
(pos < (x + EPSILON)))
{
dist = pos - x;
dist = ABS (dist);
if (dist < minvdist)
{
minvdist = dist;
*tx = pos;
}
}
break;
}
}
}
}
void
gdisplay_snap_rectangle (GDisplay *gdisp,
int x1,
int y1,
int x2,
int y2,
int *tx1,
int *ty1)
{
double nx1, ny1;
double nx2, ny2;
1997-11-25 06:05:25 +08:00
*tx1 = x1;
*ty1 = y1;
if (gdisp->draw_guides &&
gdisp->snap_to_guides &&
gdisp->gimage->guides)
{
gdisplay_snap_point (gdisp, x1, y1, &nx1, &ny1);
gdisplay_snap_point (gdisp, x2, y2, &nx2, &ny2);
if (x1 != (int)nx1)
1997-11-25 06:05:25 +08:00
*tx1 = nx1;
else if (x2 != (int)nx2)
1997-11-25 06:05:25 +08:00
*tx1 = x1 + (nx2 - x2);
if (y1 != (int)ny1)
1997-11-25 06:05:25 +08:00
*ty1 = ny1;
else if (y2 != (int)ny2)
1997-11-25 06:05:25 +08:00
*ty1 = y1 + (ny2 - y2);
}
}
void
gdisplay_draw_cursor (GDisplay *gdisp)
{
int x = gdisp->cursor_x;
int y = gdisp->cursor_y;
gdk_draw_line (gdisp->canvas->window,
gdisp->canvas->style->white_gc,
x - 7, y-1, x + 7, y-1);
gdk_draw_line (gdisp->canvas->window,
gdisp->canvas->style->black_gc,
x - 7, y, x + 7, y);
gdk_draw_line (gdisp->canvas->window,
gdisp->canvas->style->white_gc,
x - 7, y+1, x + 7, y+1);
gdk_draw_line (gdisp->canvas->window,
gdisp->canvas->style->white_gc,
x-1, y - 7, x-1, y + 7);
gdk_draw_line (gdisp->canvas->window,
gdisp->canvas->style->black_gc,
x, y - 7, x, y + 7);
gdk_draw_line (gdisp->canvas->window,
gdisp->canvas->style->white_gc,
x+1, y - 7, x+1, y + 7);
}
void
gdisplay_update_cursor (GDisplay *gdisp, int x, int y)
{
int new_cursor;
char buffer[CURSOR_STR_LENGTH];
int t_x, t_y;
1998-08-14 02:53:12 +08:00
GimpDrawable *active_drawable;
new_cursor = gdisp->draw_cursor && gdisp->proximity;
/* Erase old cursor, if necessary */
if (gdisp->have_cursor && (!new_cursor || x != gdisp->cursor_x ||
y != gdisp->cursor_y))
{
gdisplay_expose_area (gdisp, gdisp->cursor_x - 7,
gdisp->cursor_y - 7,
15, 15);
if (!new_cursor)
{
gdisp->have_cursor = FALSE;
gdisplay_flush (gdisp);
}
}
gdisplay_untransform_coords(gdisp, x, y, &t_x, &t_y, FALSE, FALSE);
1998-08-14 02:53:12 +08:00
active_drawable = gimp_image_active_drawable (gdisp->gimage);
if (active_drawable)
{
if (t_x < 0 ||
t_y < 0 ||
t_x >= active_drawable->width ||
t_y >= active_drawable->height)
{
gtk_label_set (GTK_LABEL (gdisp->cursor_label), "");
info_window_update_RGB(gdisp->window_info_dialog,
gdisp,
-1,
-1);
}
else
{
if (gdisp->dot_for_dot)
{
g_snprintf (buffer, CURSOR_STR_LENGTH,
gdisp->cursor_format_str, "", t_x, ", ", t_y);
}
else /* show real world units */
{
double unit_factor = gimp_unit_get_factor (gdisp->gimage->unit);
g_snprintf
(buffer, CURSOR_STR_LENGTH, gdisp->cursor_format_str,
"",
(double) t_x * unit_factor / gdisp->gimage->xresolution,
", ",
(double) t_y * unit_factor / gdisp->gimage->yresolution);
}
gtk_label_set (GTK_LABEL (gdisp->cursor_label), buffer);
info_window_update_RGB(gdisp->window_info_dialog,
gdisp,
t_x,
t_y);
}
}
gdisp->have_cursor = new_cursor;
gdisp->cursor_x = x;
gdisp->cursor_y = y;
if (new_cursor)
gdisplay_flush (gdisp);
}
1997-11-25 06:05:25 +08:00
void
gdisplay_set_dot_for_dot (GDisplay *gdisp, int value)
{
if (value != gdisp->dot_for_dot)
{
gdisp->dot_for_dot = value;
gdisplay_resize_cursor_label (gdisp);
resize_display (gdisp, allow_resize_windows, TRUE);
}
}
void
gdisplay_resize_cursor_label (GDisplay *gdisp)
{
/* Set a proper size for the coordinates display in the statusbar. */
char buffer[CURSOR_STR_LENGTH];
int cursor_label_width;
int label_frame_size_difference;
if (gdisp->dot_for_dot)
{
new ui for the "Layer Offset" dialog. 1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de> * app/channel_ops.[ch]: new ui for the "Layer Offset" dialog. * app/channels_dialog.c * app/layers_dialog.c: major code cleanup: Folded some callbacks into common ones, "widget" instead of "w", indentation, ... * app/commands.c * app/interface.[ch] * app/global_edit.c: the query boxes must be shown by the caller now. There's no need to split up the string for the message box manually as the Gtk 1.2 label widget handles newlines corectly. Added the "edge_lock" toggle to the "Shrink Selection" dialog. Nicer spacings for the query and message boxes. * app/ink.c: tried to grab the pointer in the blob preview but failed. Left the code there as a reminder (commented out). * app/menus.c: reordered <Image>/Select. I was bored and grep-ed the sources for ancient or deprecated stuff: * app/about_dialog.[ch] * app/actionarea.[ch] * app/app_procs.c * app/brush_edit.c * app/brush_select.c * app/color_select.c * app/convert.c * app/devices.c * app/gdisplay.c * app/gdisplay_ops.c * app/histogram_tool.[ch] * app/info_window.c * app/install.c * app/ops_buttons.c * app/palette.c * app/palette_select.c * app/paths_dialog.c * app/pattern_select.c * app/resize.c * app/scale_toolc.c * app/text_tool.c: s/container_border_width/container_set_border_width/g, s/sprintf/g_snprintf/g, replaced some constant string lengths with strlen(x). * app/bezier_select.c * app/blend.c * app/boundary.c * app/errors.[ch] * app/free_select.c * app/gimpbrushlist.c * app/gimprc.c * app/iscissors.c * app/main.c * app/patterns.[ch] * app/text_tool.c: namespace fanaticism: prefixed all gimp error functions with "gimp_" and formated the messages more uniformly. * app/gradient.c * app/gradient_select.c: same stuff as above for the ui code. There are still some sub-dialogs which need cleanup. Did some cleanup in most of these files: prototypes, removed tons of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
g_snprintf (gdisp->cursor_format_str, sizeof (gdisp->cursor_format_str),
"%%s%%d%%s%%d");
new ui for the "Layer Offset" dialog. 1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de> * app/channel_ops.[ch]: new ui for the "Layer Offset" dialog. * app/channels_dialog.c * app/layers_dialog.c: major code cleanup: Folded some callbacks into common ones, "widget" instead of "w", indentation, ... * app/commands.c * app/interface.[ch] * app/global_edit.c: the query boxes must be shown by the caller now. There's no need to split up the string for the message box manually as the Gtk 1.2 label widget handles newlines corectly. Added the "edge_lock" toggle to the "Shrink Selection" dialog. Nicer spacings for the query and message boxes. * app/ink.c: tried to grab the pointer in the blob preview but failed. Left the code there as a reminder (commented out). * app/menus.c: reordered <Image>/Select. I was bored and grep-ed the sources for ancient or deprecated stuff: * app/about_dialog.[ch] * app/actionarea.[ch] * app/app_procs.c * app/brush_edit.c * app/brush_select.c * app/color_select.c * app/convert.c * app/devices.c * app/gdisplay.c * app/gdisplay_ops.c * app/histogram_tool.[ch] * app/info_window.c * app/install.c * app/ops_buttons.c * app/palette.c * app/palette_select.c * app/paths_dialog.c * app/pattern_select.c * app/resize.c * app/scale_toolc.c * app/text_tool.c: s/container_border_width/container_set_border_width/g, s/sprintf/g_snprintf/g, replaced some constant string lengths with strlen(x). * app/bezier_select.c * app/blend.c * app/boundary.c * app/errors.[ch] * app/free_select.c * app/gimpbrushlist.c * app/gimprc.c * app/iscissors.c * app/main.c * app/patterns.[ch] * app/text_tool.c: namespace fanaticism: prefixed all gimp error functions with "gimp_" and formated the messages more uniformly. * app/gradient.c * app/gradient_select.c: same stuff as above for the ui code. There are still some sub-dialogs which need cleanup. Did some cleanup in most of these files: prototypes, removed tons of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
g_snprintf (buffer, sizeof (buffer), gdisp->cursor_format_str,
"", gdisp->gimage->width, ", ", gdisp->gimage->height);
}
else /* show real world units */
{
gdouble unit_factor = gimp_unit_get_factor (gdisp->gimage->unit);
new ui for the "Layer Offset" dialog. 1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de> * app/channel_ops.[ch]: new ui for the "Layer Offset" dialog. * app/channels_dialog.c * app/layers_dialog.c: major code cleanup: Folded some callbacks into common ones, "widget" instead of "w", indentation, ... * app/commands.c * app/interface.[ch] * app/global_edit.c: the query boxes must be shown by the caller now. There's no need to split up the string for the message box manually as the Gtk 1.2 label widget handles newlines corectly. Added the "edge_lock" toggle to the "Shrink Selection" dialog. Nicer spacings for the query and message boxes. * app/ink.c: tried to grab the pointer in the blob preview but failed. Left the code there as a reminder (commented out). * app/menus.c: reordered <Image>/Select. I was bored and grep-ed the sources for ancient or deprecated stuff: * app/about_dialog.[ch] * app/actionarea.[ch] * app/app_procs.c * app/brush_edit.c * app/brush_select.c * app/color_select.c * app/convert.c * app/devices.c * app/gdisplay.c * app/gdisplay_ops.c * app/histogram_tool.[ch] * app/info_window.c * app/install.c * app/ops_buttons.c * app/palette.c * app/palette_select.c * app/paths_dialog.c * app/pattern_select.c * app/resize.c * app/scale_toolc.c * app/text_tool.c: s/container_border_width/container_set_border_width/g, s/sprintf/g_snprintf/g, replaced some constant string lengths with strlen(x). * app/bezier_select.c * app/blend.c * app/boundary.c * app/errors.[ch] * app/free_select.c * app/gimpbrushlist.c * app/gimprc.c * app/iscissors.c * app/main.c * app/patterns.[ch] * app/text_tool.c: namespace fanaticism: prefixed all gimp error functions with "gimp_" and formated the messages more uniformly. * app/gradient.c * app/gradient_select.c: same stuff as above for the ui code. There are still some sub-dialogs which need cleanup. Did some cleanup in most of these files: prototypes, removed tons of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
g_snprintf (gdisp->cursor_format_str, sizeof (gdisp->cursor_format_str),
"%%s%%.%df%%s%%.%df %s",
gimp_unit_get_digits (gdisp->gimage->unit),
gimp_unit_get_digits (gdisp->gimage->unit),
gimp_unit_get_symbol (gdisp->gimage->unit));
new ui for the "Layer Offset" dialog. 1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de> * app/channel_ops.[ch]: new ui for the "Layer Offset" dialog. * app/channels_dialog.c * app/layers_dialog.c: major code cleanup: Folded some callbacks into common ones, "widget" instead of "w", indentation, ... * app/commands.c * app/interface.[ch] * app/global_edit.c: the query boxes must be shown by the caller now. There's no need to split up the string for the message box manually as the Gtk 1.2 label widget handles newlines corectly. Added the "edge_lock" toggle to the "Shrink Selection" dialog. Nicer spacings for the query and message boxes. * app/ink.c: tried to grab the pointer in the blob preview but failed. Left the code there as a reminder (commented out). * app/menus.c: reordered <Image>/Select. I was bored and grep-ed the sources for ancient or deprecated stuff: * app/about_dialog.[ch] * app/actionarea.[ch] * app/app_procs.c * app/brush_edit.c * app/brush_select.c * app/color_select.c * app/convert.c * app/devices.c * app/gdisplay.c * app/gdisplay_ops.c * app/histogram_tool.[ch] * app/info_window.c * app/install.c * app/ops_buttons.c * app/palette.c * app/palette_select.c * app/paths_dialog.c * app/pattern_select.c * app/resize.c * app/scale_toolc.c * app/text_tool.c: s/container_border_width/container_set_border_width/g, s/sprintf/g_snprintf/g, replaced some constant string lengths with strlen(x). * app/bezier_select.c * app/blend.c * app/boundary.c * app/errors.[ch] * app/free_select.c * app/gimpbrushlist.c * app/gimprc.c * app/iscissors.c * app/main.c * app/patterns.[ch] * app/text_tool.c: namespace fanaticism: prefixed all gimp error functions with "gimp_" and formated the messages more uniformly. * app/gradient.c * app/gradient_select.c: same stuff as above for the ui code. There are still some sub-dialogs which need cleanup. Did some cleanup in most of these files: prototypes, removed tons of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
g_snprintf (buffer, sizeof (buffer), gdisp->cursor_format_str,
"",
(gdouble) gdisp->gimage->width * unit_factor /
gdisp->gimage->xresolution,
", ",
(gdouble) gdisp->gimage->height * unit_factor /
gdisp->gimage->yresolution);
}
cursor_label_width =
gdk_string_width (gtk_widget_get_style (gdisp->cursor_label)->font, buffer);
new ui for the "Layer Offset" dialog. 1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de> * app/channel_ops.[ch]: new ui for the "Layer Offset" dialog. * app/channels_dialog.c * app/layers_dialog.c: major code cleanup: Folded some callbacks into common ones, "widget" instead of "w", indentation, ... * app/commands.c * app/interface.[ch] * app/global_edit.c: the query boxes must be shown by the caller now. There's no need to split up the string for the message box manually as the Gtk 1.2 label widget handles newlines corectly. Added the "edge_lock" toggle to the "Shrink Selection" dialog. Nicer spacings for the query and message boxes. * app/ink.c: tried to grab the pointer in the blob preview but failed. Left the code there as a reminder (commented out). * app/menus.c: reordered <Image>/Select. I was bored and grep-ed the sources for ancient or deprecated stuff: * app/about_dialog.[ch] * app/actionarea.[ch] * app/app_procs.c * app/brush_edit.c * app/brush_select.c * app/color_select.c * app/convert.c * app/devices.c * app/gdisplay.c * app/gdisplay_ops.c * app/histogram_tool.[ch] * app/info_window.c * app/install.c * app/ops_buttons.c * app/palette.c * app/palette_select.c * app/paths_dialog.c * app/pattern_select.c * app/resize.c * app/scale_toolc.c * app/text_tool.c: s/container_border_width/container_set_border_width/g, s/sprintf/g_snprintf/g, replaced some constant string lengths with strlen(x). * app/bezier_select.c * app/blend.c * app/boundary.c * app/errors.[ch] * app/free_select.c * app/gimpbrushlist.c * app/gimprc.c * app/iscissors.c * app/main.c * app/patterns.[ch] * app/text_tool.c: namespace fanaticism: prefixed all gimp error functions with "gimp_" and formated the messages more uniformly. * app/gradient.c * app/gradient_select.c: same stuff as above for the ui code. There are still some sub-dialogs which need cleanup. Did some cleanup in most of these files: prototypes, removed tons of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
/* find out how many pixels the label's parent frame is bigger than
* the label itself
*/
label_frame_size_difference =
gdisp->cursor_label->parent->allocation.width -
gdisp->cursor_label->allocation.width;
gtk_widget_set_usize (gdisp->cursor_label, cursor_label_width, -1);
if (label_frame_size_difference) /* don't resize if this is a new display */
gtk_widget_set_usize (gdisp->cursor_label->parent,
cursor_label_width + label_frame_size_difference, -1);
gdisplay_update_cursor (gdisp, gdisp->cursor_x, gdisp->cursor_y);
}
1997-11-25 06:05:25 +08:00
void
gdisplay_remove_and_delete (GDisplay *gdisp)
{
/* remove the display from the list */
display_list = g_slist_remove (display_list, (void *) gdisp);
1997-11-25 06:05:25 +08:00
gdisplay_delete (gdisp);
}
static void
gdisplay_add_update_area (GDisplay *gdisp,
int x,
int y,
int w,
int h)
{
GArea * ga;
ga = (GArea *) g_malloc (sizeof (GArea));
ga->x1 = BOUNDS (x, 0, gdisp->gimage->width);
ga->y1 = BOUNDS (y, 0, gdisp->gimage->height);
ga->x2 = BOUNDS (x + w, 0, gdisp->gimage->width);
ga->y2 = BOUNDS (y + h, 0, gdisp->gimage->height);
1997-11-25 06:05:25 +08:00
gdisp->update_areas = gdisplay_process_area_list (gdisp->update_areas, ga);
}
static void
gdisplay_add_display_area (GDisplay *gdisp,
int x,
int y,
int w,
int h)
{
GArea * ga;
ga = (GArea *) g_malloc (sizeof (GArea));
ga->x1 = BOUNDS (x, 0, gdisp->disp_width);
ga->y1 = BOUNDS (y, 0, gdisp->disp_height);
ga->x2 = BOUNDS (x + w, 0, gdisp->disp_width);
ga->y2 = BOUNDS (y + h, 0, gdisp->disp_height);
1997-11-25 06:05:25 +08:00
gdisp->display_areas = gdisplay_process_area_list (gdisp->display_areas, ga);
}
static void
gdisplay_paint_area (GDisplay *gdisp,
int x,
int y,
int w,
int h)
{
int x1, y1, x2, y2;
/* Bounds check */
x1 = BOUNDS (x, 0, gdisp->gimage->width);
y1 = BOUNDS (y, 0, gdisp->gimage->height);
x2 = BOUNDS (x + w, 0, gdisp->gimage->width);
y2 = BOUNDS (y + h, 0, gdisp->gimage->height);
x = x1;
y = y1;
w = (x2 - x1);
h = (y2 - y1);
1997-11-25 06:05:25 +08:00
/* calculate the extents of the update as limited by what's visible */
gdisplay_untransform_coords (gdisp, 0, 0, &x1, &y1, FALSE, FALSE);
gdisplay_untransform_coords (gdisp, gdisp->disp_width, gdisp->disp_height, &x2, &y2, FALSE, FALSE);
gimage_invalidate (gdisp->gimage, x, y, w, h, x1, y1, x2, y2);
1997-11-25 06:05:25 +08:00
/* display the area */
gdisplay_transform_coords (gdisp, x, y, &x1, &y1, FALSE);
gdisplay_transform_coords (gdisp, x + w, y + h, &x2, &y2, FALSE);
gdisplay_expose_area (gdisp, x1, y1, (x2 - x1), (y2 - y1));
1997-11-25 06:05:25 +08:00
}
static void
gdisplay_display_area (GDisplay *gdisp,
int x,
int y,
int w,
int h)
{
int sx, sy;
int x1, y1;
int x2, y2;
int dx, dy;
int i, j;
sx = SCALEX (gdisp, gdisp->gimage->width);
sy = SCALEY (gdisp, gdisp->gimage->height);
1997-11-25 06:05:25 +08:00
/* Bounds check */
x1 = BOUNDS (x, 0, gdisp->disp_width);
y1 = BOUNDS (y, 0, gdisp->disp_height);
x2 = BOUNDS (x + w, 0, gdisp->disp_width);
y2 = BOUNDS (y + h, 0, gdisp->disp_height);
if (y1 < gdisp->disp_yoffset)
1997-11-25 06:05:25 +08:00
{
gdk_draw_rectangle (gdisp->canvas->window,
gdisp->canvas->style->bg_gc[GTK_STATE_NORMAL], 1,
x, y, w, gdisp->disp_yoffset - y);
/* X X X
. # .
. . . */
1997-11-25 06:05:25 +08:00
y1 = gdisp->disp_yoffset;
1997-11-25 06:05:25 +08:00
}
if (x1 < gdisp->disp_xoffset)
1997-11-25 06:05:25 +08:00
{
gdk_draw_rectangle (gdisp->canvas->window,
gdisp->canvas->style->bg_gc[GTK_STATE_NORMAL], 1,
x, y1, gdisp->disp_xoffset - x, h);
/* . . .
X # .
X . . */
1997-11-25 06:05:25 +08:00
x1 = gdisp->disp_xoffset;
1997-11-25 06:05:25 +08:00
}
if (x2 > (gdisp->disp_xoffset + sx))
{
gdk_draw_rectangle (gdisp->canvas->window,
gdisp->canvas->style->bg_gc[GTK_STATE_NORMAL], 1,
gdisp->disp_xoffset + sx, y1,
x2 - (gdisp->disp_xoffset + sx), h - (y1-y));
/* . . .
. # X
. . X */
1997-11-25 06:05:25 +08:00
x2 = gdisp->disp_xoffset + sx;
}
if (y2 > (gdisp->disp_yoffset + sy))
{
gdk_draw_rectangle (gdisp->canvas->window,
gdisp->canvas->style->bg_gc[GTK_STATE_NORMAL], 1,
x1, gdisp->disp_yoffset + sy,
x2-x1,
y2 - (gdisp->disp_yoffset + sy));
/* . . .
. # .
. X . */
1997-11-25 06:05:25 +08:00
y2 = gdisp->disp_yoffset + sy;
}
/* display the image in GXIMAGE_WIDTH x GXIMAGE_HEIGHT sized chunks */
for (i = y1; i < y2; i += GXIMAGE_HEIGHT)
for (j = x1; j < x2; j += GXIMAGE_WIDTH)
{
dx = MIN (x2 - j, GXIMAGE_WIDTH);
dy = MIN (y2 - i, GXIMAGE_HEIGHT);
render_image (gdisp, j - gdisp->disp_xoffset, i - gdisp->disp_yoffset,
dx, dy);
#if 0
/* Invalidate the projection just after we render it! */
gimage_invalidate_without_render (gdisp->gimage,
j - gdisp->disp_xoffset,
i - gdisp->disp_yoffset,
dx, dy,
0, 0, 0, 0);
#endif
1997-11-25 06:05:25 +08:00
gximage_put (gdisp->canvas->window,
j, i, dx, dy,
gdisp->offset_x,
gdisp->offset_y);
1997-11-25 06:05:25 +08:00
}
}
int
gdisplay_mask_value (GDisplay *gdisp,
int x,
int y)
{
/* move the coordinates from screen space to image space */
gdisplay_untransform_coords (gdisp, x, y, &x, &y, FALSE, 0);
return gimage_mask_value (gdisp->gimage, x, y);
}
int
gdisplay_mask_bounds (GDisplay *gdisp,
int *x1,
int *y1,
int *x2,
int *y2)
{
Layer *layer;
int off_x, off_y;
1997-11-25 06:05:25 +08:00
/* If there is a floating selection, handle things differently */
if ((layer = gimage_floating_sel (gdisp->gimage)))
{
drawable_offsets (GIMP_DRAWABLE(layer), &off_x, &off_y);
1997-11-25 06:05:25 +08:00
if (! channel_bounds (gimage_get_mask (gdisp->gimage), x1, y1, x2, y2))
{
*x1 = off_x;
*y1 = off_y;
*x2 = off_x + drawable_width (GIMP_DRAWABLE(layer));
*y2 = off_y + drawable_height (GIMP_DRAWABLE(layer));
1997-11-25 06:05:25 +08:00
}
else
{
*x1 = MINIMUM (off_x, *x1);
*y1 = MINIMUM (off_y, *y1);
*x2 = MAXIMUM (off_x + drawable_width (GIMP_DRAWABLE(layer)), *x2);
*y2 = MAXIMUM (off_y + drawable_height (GIMP_DRAWABLE(layer)), *y2);
1997-11-25 06:05:25 +08:00
}
}
else if (! channel_bounds (gimage_get_mask (gdisp->gimage), x1, y1, x2, y2))
return FALSE;
gdisplay_transform_coords (gdisp, *x1, *y1, x1, y1, 0);
gdisplay_transform_coords (gdisp, *x2, *y2, x2, y2, 0);
/* Make sure the extents are within bounds */
*x1 = BOUNDS (*x1, 0, gdisp->disp_width);
*y1 = BOUNDS (*y1, 0, gdisp->disp_height);
*x2 = BOUNDS (*x2, 0, gdisp->disp_width);
*y2 = BOUNDS (*y2, 0, gdisp->disp_height);
return TRUE;
}
void
gdisplay_transform_coords (GDisplay *gdisp,
int x,
int y,
int *nx,
int *ny,
int use_offsets)
{
double scalex;
double scaley;
1997-11-25 06:05:25 +08:00
int offset_x, offset_y;
/* transform from image coordinates to screen coordinates */
scalex = SCALEFACTOR_X (gdisp);
scaley = SCALEFACTOR_Y (gdisp);
1997-11-25 06:05:25 +08:00
if (use_offsets)
drawable_offsets (gimage_active_drawable (gdisp->gimage), &offset_x, &offset_y);
else
{
offset_x = offset_y = 0;
}
*nx = (int) (scalex * (x + offset_x) - gdisp->offset_x);
*ny = (int) (scaley * (y + offset_y) - gdisp->offset_y);
1997-11-25 06:05:25 +08:00
*nx += gdisp->disp_xoffset;
*ny += gdisp->disp_yoffset;
}
void
gdisplay_untransform_coords (GDisplay *gdisp,
int x,
int y,
int *nx,
int *ny,
int round,
int use_offsets)
{
double scalex;
double scaley;
1997-11-25 06:05:25 +08:00
int offset_x, offset_y;
x -= gdisp->disp_xoffset;
y -= gdisp->disp_yoffset;
/* transform from screen coordinates to image coordinates */
scalex = SCALEFACTOR_X (gdisp);
scaley = SCALEFACTOR_Y (gdisp);
1997-11-25 06:05:25 +08:00
if (use_offsets)
drawable_offsets (gimage_active_drawable (gdisp->gimage), &offset_x, &offset_y);
else
{
offset_x = offset_y = 0;
}
if (round)
{
*nx = ROUND ((x + gdisp->offset_x) / scalex - offset_x);
*ny = ROUND ((y + gdisp->offset_y) / scaley - offset_y);
1997-11-25 06:05:25 +08:00
}
else
{
*nx = (int) ((x + gdisp->offset_x) / scalex - offset_x);
*ny = (int) ((y + gdisp->offset_y) / scaley - offset_y);
1997-11-25 06:05:25 +08:00
}
}
void
gdisplay_transform_coords_f (GDisplay *gdisp,
double x,
double y,
double *nx,
double *ny,
int use_offsets)
{
double scalex;
double scaley;
1997-11-25 06:05:25 +08:00
int offset_x, offset_y;
/* transform from gimp coordinates to screen coordinates */
scalex = SCALEFACTOR_X(gdisp);
scaley = SCALEFACTOR_Y(gdisp);
1997-11-25 06:05:25 +08:00
if (use_offsets)
drawable_offsets (gimage_active_drawable (gdisp->gimage), &offset_x, &offset_y);
else
{
offset_x = offset_y = 0;
}
*nx = scalex * (x + offset_x) - gdisp->offset_x;
*ny = scaley * (y + offset_y) - gdisp->offset_y;
1997-11-25 06:05:25 +08:00
*nx += gdisp->disp_xoffset;
*ny += gdisp->disp_yoffset;
}
void
gdisplay_untransform_coords_f (GDisplay *gdisp,
double x,
double y,
double *nx,
double *ny,
int use_offsets)
{
double scalex;
double scaley;
1997-11-25 06:05:25 +08:00
int offset_x, offset_y;
x -= gdisp->disp_xoffset;
y -= gdisp->disp_yoffset;
/* transform from screen coordinates to gimp coordinates */
scalex = SCALEFACTOR_X(gdisp);
scaley = SCALEFACTOR_Y(gdisp);
1997-11-25 06:05:25 +08:00
if (use_offsets)
drawable_offsets (gimage_active_drawable (gdisp->gimage), &offset_x, &offset_y);
else
{
offset_x = offset_y = 0;
}
*nx = (x + gdisp->offset_x) / scalex - offset_x;
*ny = (y + gdisp->offset_y) / scaley - offset_y;
1997-11-25 06:05:25 +08:00
}
/* install and remove tool cursor from gdisplay... */
void
gdisplay_install_tool_cursor (GDisplay *gdisp,
GdkCursorType cursor_type)
{
if (gdisp->current_cursor != (int)cursor_type)
1997-11-25 06:05:25 +08:00
{
gdisp->current_cursor = (int)cursor_type;
if (!gdisp->using_override_cursor)
{
change_win_cursor (gdisp->canvas->window, cursor_type);
}
}
}
/* install an override-cursor on gdisplay... */
void
gdisplay_install_override_cursor (GDisplay *gdisp,
GdkCursorType cursor_type)
{
if ((!gdisp->using_override_cursor) ||
(
(gdisp->using_override_cursor) &&
(gdisp->override_cursor != cursor_type)
)
)
{
gdisp->override_cursor = cursor_type;
gdisp->using_override_cursor = TRUE;
1997-11-25 06:05:25 +08:00
change_win_cursor (gdisp->canvas->window, cursor_type);
}
}
/* remove an override-cursor from gdisplay... */
void
gdisplay_remove_override_cursor (GDisplay *gdisp)
{
if (gdisp->using_override_cursor)
{
gdisp->using_override_cursor = FALSE;
change_win_cursor (gdisp->canvas->window, gdisp->current_cursor);
}
else
{
/* g_warning ("Tried to remove override-cursor from un-overridden gdisp."); */
}
}
1997-11-25 06:05:25 +08:00
void
gdisplay_remove_tool_cursor (GDisplay *gdisp)
{
unset_win_cursor (gdisp->canvas->window);
}
void
gdisplay_set_menu_sensitivity (GDisplay *gdisp)
{
Layer *layer = NULL;
gint fs = FALSE;
gint aux = FALSE;
gint lm = FALSE;
gint lp = FALSE;
gint alpha = FALSE;
GimpDrawable *drawable = NULL;
GimpImageBaseType base_type = 0;
GimpImageType type = -1;
gint lind = -1;
gint lnum = -1;
if (gdisp)
{
fs = (gimage_floating_sel (gdisp->gimage) != NULL);
aux = (gimage_get_active_channel (gdisp->gimage) != NULL);
if ((layer = gimage_get_active_layer (gdisp->gimage)) != NULL)
lm = (layer->mask) ? TRUE : FALSE;
base_type = gimage_base_type (gdisp->gimage);
lp = (gdisp->gimage->layers != NULL);
alpha = layer && layer_has_alpha (layer);
if (lp)
{
drawable = gimage_active_drawable (gdisp->gimage);
type = drawable_type (drawable);
lind = gimage_get_layer_index (gdisp->gimage,
gdisp->gimage->active_layer);
lnum = g_slist_length (gdisp->gimage->layers);
}
}
#define SET_SENSITIVE(menu,condition) \
1999-09-23 19:49:16 +08:00
menus_set_sensitive_glue ("<Image>", (menu), (condition) != 0)
#define SET_STATE(menu,condition) \
1999-09-23 19:49:16 +08:00
menus_set_state_glue ("<Image>", (menu), (condition) != 0)
SET_SENSITIVE (N_("/File/Save"), gdisp);
SET_SENSITIVE (N_("/File/Save as"), gdisp);
SET_SENSITIVE (N_("/File/Revert"), gdisp);
SET_SENSITIVE (N_("/File/Close"), gdisp);
SET_SENSITIVE (N_("/Edit"), gdisp);
if (gdisp)
{
SET_SENSITIVE (N_("/Edit/Cut"), lp);
SET_SENSITIVE (N_("/Edit/Copy"), lp);
SET_SENSITIVE (N_("/Edit/Paste"), lp);
SET_SENSITIVE (N_("/Edit/Paste Into"), lp);
SET_SENSITIVE (N_("/Edit/Paste As New"), lp);
SET_SENSITIVE (N_("/Edit/Clear"), lp);
SET_SENSITIVE (N_("/Edit/Fill"), lp);
SET_SENSITIVE (N_("/Edit/Stroke"), lp);
Honest, guv, it's not a feature - it's a tightly integrated package of Mon Sep 20 12:51:30 EDT 1999 Austin Donnelly <austin@gimp.org> Honest, guv, it's not a feature - it's a tightly integrated package of undo system cleanups and fixes. NEW FILES: * app/undo_history.c: window showing recent undo (and redo) steps available. * app/undo_types.h: broken out of undo.h to fix circular includes. MODIFIED FILES: * app/Makefile.am: compile undo_history.c * app/channel.h: use enum for channel undo type, not just magic numbers. * app/layer.h: same for layer undos. * app/commands.c: edit_show_undo_history_cmd_callback() function to pull up undo history window. * app/commands.h: prototype for above. * app/gdisplay.c: make undo / redo menu items sensitive according to whether they would do anything. Would be easy to change the text to say what would be undone/redone, but I don't know the GTK. * app/gimpimage.c: new signal emitted by gimage: UNDO_EVENT. gimp_image_undo_event() function to emit it. * app/gimpimage.h: prototype for above. * app/gimpimageP.h: pushing_undo_group member is now an undo_type, not an int. Keep undo history widget here too (if created). * app/menus.c: add "Edit/Undo history..." to image menu. * app/undo.c: new types: enums undo_type and undo_state rather than ints and magic numbers. All undo_pop_* and undo_free_* functions made static. New static function undo_type_to_name(). Issue undo event signals on various important events (eg undo pushed, undo popped etc). undo_push() now takes a "dirties_image" arg to say whether image should be dirtied. Layer moves now dirty the image. A couple of g_return_if_fails () on undo_pop and undo_redo to assert we're not in the middle of an undo group. undo_get_{undo,redo}_name() to peek at names of top items on undo and redo stacks resp. undo_map_over_{undo,redo}_stack() to run a function for each item or group on stack. Layer and channel undos use symbolic names rather than 0 or 1. Array mapping undo types to names. * app/undo.h: split out undo types to undo_types.h. Prototypes for functions described above. undo_event_t enum. undo_history_new() prototype lives here too. Random other fixes: * app/gimpdrawable.c * app/image_render.c: default labels in switches to keep egcs happy. * app/nav_window.c: some fixes to (sort of) cope with image res != screen res. Still needs work to handle non-square pixels properly. * app/paths_dialog.c: bad idea to call gimp_image_dirty() directly. Even though it's currently commented out.
1999-09-21 01:15:20 +08:00
SET_SENSITIVE (N_("/Edit/Undo"), undo_get_undo_name (gdisp->gimage));
SET_SENSITIVE (N_("/Edit/Redo"), undo_get_redo_name (gdisp->gimage));
SET_SENSITIVE (N_("/Edit/Cut Named"), lp);
SET_SENSITIVE (N_("/Edit/Copy Named"), lp);
SET_SENSITIVE (N_("/Edit/Paste Named"), lp);
}
SET_SENSITIVE (N_("/Select"), gdisp && lp);
SET_SENSITIVE (N_("/Select/Save To Channel"), !fs);
SET_SENSITIVE (N_("/View"), gdisp);
if (gdisp)
1997-11-25 06:05:25 +08:00
{
SET_STATE (N_("/View/Toggle Selection"), !gdisp->select->hidden);
SET_STATE (N_("/View/Toggle Rulers"),
GTK_WIDGET_VISIBLE (gdisp->origin) ? 1 : 0);
SET_STATE (N_("/View/Toggle Guides"), gdisp->draw_guides);
SET_STATE (N_("/View/Snap To Guides"), gdisp->snap_to_guides);
SET_STATE (N_("/View/Toggle Statusbar"),
GTK_WIDGET_VISIBLE (gdisp->statusarea) ? 1 : 0);
SET_STATE (N_("/View/Dot for dot"), gdisp->dot_for_dot);
1997-11-25 06:05:25 +08:00
}
SET_SENSITIVE (N_("/Image"), gdisp);
SET_SENSITIVE (N_("/Image/Colors"), gdisp);
SET_SENSITIVE (N_("/Image/Channel Ops"), gdisp);
SET_SENSITIVE (N_("/Image/Alpha"), gdisp);
if (gdisp)
{
SET_SENSITIVE (N_("/Image/RGB"), (base_type != RGB));
SET_SENSITIVE (N_("/Image/Grayscale"), (base_type != GRAY));
SET_SENSITIVE (N_("/Image/Indexed"), (base_type != INDEXED));
SET_SENSITIVE (N_("/Image/Histogram"), lp);
SET_SENSITIVE (N_("/Image/Colors"), lp);
SET_SENSITIVE (N_("/Image/Colors/Threshold"), (base_type != INDEXED));
SET_SENSITIVE (N_("/Image/Colors/Posterize"), (base_type != INDEXED));
SET_SENSITIVE (N_("/Image/Colors/Equalize"), (base_type != INDEXED));
SET_SENSITIVE (N_("/Image/Colors/Invert"), (base_type != INDEXED));
SET_SENSITIVE (N_("/Image/Colors/Color Balance"), (base_type == RGB));
SET_SENSITIVE (N_("/Image/Colors/Brightness-Contrast"),
(base_type != INDEXED));
SET_SENSITIVE (N_("/Image/Colors/Hue-Saturation"), (base_type == RGB));
SET_SENSITIVE (N_("/Image/Colors/Curves"), (base_type != INDEXED));
SET_SENSITIVE (N_("/Image/Colors/Levels"), (base_type != INDEXED));
SET_SENSITIVE (N_("/Image/Colors/Desaturate"), (base_type == RGB));
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
SET_SENSITIVE (N_("/Image/Alpha/Add Alpha Channel"),
!fs && !aux && lp && !lm && !alpha);
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
SET_SENSITIVE (N_("/Image/Channel Ops/Offset"), lp);
}
SET_SENSITIVE (N_("/Layers/Stack"), gdisp);
if (gdisp)
{
SET_SENSITIVE (N_("/Layers/Stack/Previous Layer"),
!fs && !aux && lp && lind > 0);
SET_SENSITIVE (N_("/Layers/Stack/Next Layer"),
!fs && !aux && lp && lind < (lnum - 1));
SET_SENSITIVE (N_("/Layers/Stack/Raise Layer"),
!fs && !aux && lp && alpha && lind > 0);
SET_SENSITIVE (N_("/Layers/Stack/Lower Layer"),
!fs && !aux && lp && alpha && lind < (lnum - 1));
SET_SENSITIVE (N_("/Layers/Stack/Layer to Top"),
!fs && !aux && lp && alpha && lind > 0);
SET_SENSITIVE (N_("/Layers/Stack/Layer to Bottom"),
!fs && !aux && lp && alpha && lind < (lnum - 1));
}
SET_SENSITIVE (N_("/Layers/Anchor Layer"), gdisp && fs && !aux && lp);
SET_SENSITIVE (N_("/Layers/Merge Visible Layers"), gdisp && !fs && !aux && lp);
SET_SENSITIVE (N_("/Layers/Flatten Image"), gdisp && !fs && !aux && lp);
SET_SENSITIVE (N_("/Layers/Alpha To Selection"), gdisp && !aux && lp && alpha);
SET_SENSITIVE (N_("/Layers/Mask To Selection"), gdisp && !aux && lm && lp);
SET_SENSITIVE (N_("/Layers/Add Alpha Channel"),
gdisp && !fs && !aux && lp && !lm && !alpha);
SET_SENSITIVE (N_("/Filters"), gdisp && lp);
SET_SENSITIVE (N_("/Script-Fu"), gdisp && lp);
#undef SET_STATE
#undef SET_SENSITIVE
1997-11-25 06:05:25 +08:00
plug_in_set_menu_sensitivity (type);
}
void
gdisplay_expose_area (GDisplay *gdisp,
int x,
int y,
int w,
int h)
{
gdisplay_add_display_area (gdisp, x, y, w, h);
}
void
gdisplay_expose_guide (GDisplay *gdisp,
Guide *guide)
{
int x, y;
if (guide->position < 0)
return;
gdisplay_transform_coords (gdisp, guide->position,
guide->position, &x, &y, FALSE);
1997-11-25 06:05:25 +08:00
switch (guide->orientation)
{
add sample_colorize and curve_bend defs * plug-ins/common/plugin-defs.pl: add sample_colorize and curve_bend defs * libgimp/color_selector.h: minor consistency cleanup * libgimp/gimpchainbutton.[ch]: use new style gtk object helper macros * libgimp/gimpfileselection.c * libgimp/gimpmatrix.h: minor cleanup * libgimp/gimpintl.h: resync with gnome-i18n.h * libgimp/color_display.h * app/gimp.sym * app/gdisplay_color.[ch] * app/app_procs.c * app/gdisplay.h * app/image_render.c: color display transformation code. Still unfinished, so it's not activated yet. * app/buildmenu.h: remove unused defines (PULLDOWN, POPUP, OPTION) * app/colormaps.[ch] * app/image_render.c: remove vestigal dithering stuff * app/convolve.h * app/gimpdrawable.h * app/gimpimage.h * app/lut_funcs.h * app/paint_funcs.h * app/plug_in.h: enum nick changes from Marc * app/channel_ops.c * app/crop.c * app/gdisplay.c * app/gimpimage.[ch] * app/move.c: s/([A-Z]+)_GUIDE/ORIENTATION_$1/ * app/flip_tool.[ch] * app/shear_tool.[ch]: use ORIENTATION_* constants instead of our own * app/disp_callbacks.c: remove HORIZONTAL and VERTICAL #defines * app/general.h: enumified TOKEN_* symbols * app/lc_dialog.c * app/paint_funcs.c: remove unused variables * tools/pdbgen/lib.pl: autogen gimpenums.h (unfinished) * tools/pdbgen/stddefs.pdb: new std_orientation_enum, remove layer_mode shortcut since we've skipped it in app/ * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/drawable.pdb * tools/pdbgen/pdb/gimage.pdb * tools/pdbgen/pdb/guides.pdb * tools/pdbgen/pdb/layer.pdb * tools/pdbgen/pdb/tools.pdb: reflect above enum changes, whitespace cleanups * tools/pdbgen/enums.pl * app/brush_select_cmds.c * app/brushes_cmds.c * app/color_cmds.c * app/drawable_cmds.c * app/gimage_cmds.c * app/layer_cmds.c * app/procedural_db_cmds.c * app/tools_cmds.c: reflect pdb and enum nick changes above -Yosh
1999-07-29 07:00:08 +08:00
case ORIENTATION_HORIZONTAL:
gdisplay_expose_area (gdisp, 0, y, gdisp->disp_width, 1);
1997-11-25 06:05:25 +08:00
break;
add sample_colorize and curve_bend defs * plug-ins/common/plugin-defs.pl: add sample_colorize and curve_bend defs * libgimp/color_selector.h: minor consistency cleanup * libgimp/gimpchainbutton.[ch]: use new style gtk object helper macros * libgimp/gimpfileselection.c * libgimp/gimpmatrix.h: minor cleanup * libgimp/gimpintl.h: resync with gnome-i18n.h * libgimp/color_display.h * app/gimp.sym * app/gdisplay_color.[ch] * app/app_procs.c * app/gdisplay.h * app/image_render.c: color display transformation code. Still unfinished, so it's not activated yet. * app/buildmenu.h: remove unused defines (PULLDOWN, POPUP, OPTION) * app/colormaps.[ch] * app/image_render.c: remove vestigal dithering stuff * app/convolve.h * app/gimpdrawable.h * app/gimpimage.h * app/lut_funcs.h * app/paint_funcs.h * app/plug_in.h: enum nick changes from Marc * app/channel_ops.c * app/crop.c * app/gdisplay.c * app/gimpimage.[ch] * app/move.c: s/([A-Z]+)_GUIDE/ORIENTATION_$1/ * app/flip_tool.[ch] * app/shear_tool.[ch]: use ORIENTATION_* constants instead of our own * app/disp_callbacks.c: remove HORIZONTAL and VERTICAL #defines * app/general.h: enumified TOKEN_* symbols * app/lc_dialog.c * app/paint_funcs.c: remove unused variables * tools/pdbgen/lib.pl: autogen gimpenums.h (unfinished) * tools/pdbgen/stddefs.pdb: new std_orientation_enum, remove layer_mode shortcut since we've skipped it in app/ * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/drawable.pdb * tools/pdbgen/pdb/gimage.pdb * tools/pdbgen/pdb/guides.pdb * tools/pdbgen/pdb/layer.pdb * tools/pdbgen/pdb/tools.pdb: reflect above enum changes, whitespace cleanups * tools/pdbgen/enums.pl * app/brush_select_cmds.c * app/brushes_cmds.c * app/color_cmds.c * app/drawable_cmds.c * app/gimage_cmds.c * app/layer_cmds.c * app/procedural_db_cmds.c * app/tools_cmds.c: reflect pdb and enum nick changes above -Yosh
1999-07-29 07:00:08 +08:00
case ORIENTATION_VERTICAL:
gdisplay_expose_area (gdisp, x, 0, 1, gdisp->disp_height);
1997-11-25 06:05:25 +08:00
break;
}
}
void
gdisplay_expose_full (GDisplay *gdisp)
{
gdisplay_add_display_area (gdisp, 0, 0,
gdisp->disp_width,
gdisp->disp_height);
}
/**************************************************/
/* Functions independent of a specific gdisplay */
/**************************************************/
GDisplay *
gdisplay_active ()
{
GdkEvent *event;
event = gtk_get_current_event ();
if (event != NULL)
{
gdk_event_free (event);
}
return gimp_context_get_display (gimp_context_get_user ());
1997-11-25 06:05:25 +08:00
}
GDisplay *
gdisplay_get_ID (int ID)
{
GDisplay *gdisp;
GSList *list = display_list;
1997-11-25 06:05:25 +08:00
/* Traverse the list of displays, returning the one that matches the ID */
/* If no display in the list is a match, return NULL. */
while (list)
{
gdisp = (GDisplay *) list->data;
if (gdisp->ID == ID)
return gdisp;
list = g_slist_next (list);
1997-11-25 06:05:25 +08:00
}
return NULL;
}
void
gdisplay_update_title (GDisplay *gdisp)
{
char title [MAX_TITLE_BUF];
guint context_id;
/* format the title */
gdisplay_format_title (gdisp, title, MAX_TITLE_BUF);
gdk_window_set_title (gdisp->shell->window, title);
/* update the statusbar */
context_id =
gtk_statusbar_get_context_id (GTK_STATUSBAR (gdisp->statusbar), "title");
gtk_statusbar_pop (GTK_STATUSBAR (gdisp->statusbar), context_id);
gtk_statusbar_push (GTK_STATUSBAR (gdisp->statusbar), context_id, title);
}
1997-11-25 06:05:25 +08:00
void
gdisplays_update_title (GimpImage *gimage)
1997-11-25 06:05:25 +08:00
{
GDisplay *gdisp;
GSList *list = display_list;
1997-11-25 06:05:25 +08:00
/* traverse the linked list of displays, handling each one */
while (list)
{
gdisp = (GDisplay *) list->data;
if (gdisp->gimage == gimage)
gdisplay_update_title (gdisp);
1997-11-25 06:05:25 +08:00
list = g_slist_next (list);
1997-11-25 06:05:25 +08:00
}
}
void
gdisplays_resize_cursor_label (GimpImage *gimage)
{
GDisplay *gdisp;
GSList *list = display_list;
/* traverse the linked list of displays, handling each one */
while (list)
{
gdisp = (GDisplay *) list->data;
if (gdisp->gimage == gimage)
gdisplay_resize_cursor_label (gdisp);
list = g_slist_next (list);
}
}
1997-11-25 06:05:25 +08:00
void
gdisplays_update_area (GimpImage* gimage,
1997-11-25 06:05:25 +08:00
int x,
int y,
int w,
int h)
{
GDisplay *gdisp;
GSList *list = display_list;
/* int x1, y1, x2, y2; */
/* int count = 0; */
1997-11-25 06:05:25 +08:00
/* traverse the linked list of displays */
while (list)
{
gdisp = (GDisplay *) list->data;
if (gdisp->gimage == gimage)
1997-11-25 06:05:25 +08:00
{
/* We only need to update the first instance that
we find of this gimage ID. Otherwise, we would
be reconverting the same region unnecessarily. */
/* Um.. I don't think so. If you only do this to the first
instance, you don't update other gdisplays pointing to this
gimage. I'm going to comment this out to show how it was in
case we need to change it back. msw 4/15/1998
*/
/*
1997-11-25 06:05:25 +08:00
if (! count)
gdisplay_add_update_area (gdisp, x, y, w, h);
else
{
gdisplay_transform_coords (gdisp, x, y, &x1, &y1, 0);
gdisplay_transform_coords (gdisp, x + w, y + h, &x2, &y2, 0);
gdisplay_add_display_area (gdisp, x1, y1, (x2 - x1), (y2 - y1));
}
*/
1997-11-25 06:05:25 +08:00
gdisplay_add_update_area (gdisp, x, y, w, h);
/* Seems like this isn't needed, it's done in
gdisplay_flush. -la
gdisplay_transform_coords (gdisp, x, y, &x1, &y1, 0);
gdisplay_transform_coords (gdisp, x + w, y + h, &x2, &y2, 0);
gdisplay_add_display_area (gdisp, x1, y1, (x2 - x1), (y2 - y1));
*/
}
list = g_slist_next (list);
1997-11-25 06:05:25 +08:00
}
}
void
gdisplays_expose_guides (GimpImage* gimage)
1997-11-25 06:05:25 +08:00
{
GDisplay *gdisp;
GList *tmp_list;
GSList *list;
1997-11-25 06:05:25 +08:00
/* traverse the linked list of displays, handling each one */
list = display_list;
while (list)
{
gdisp = (GDisplay *) list->data;
if (gdisp->gimage == gimage)
1997-11-25 06:05:25 +08:00
{
tmp_list = gdisp->gimage->guides;
while (tmp_list)
{
gdisplay_expose_guide (gdisp, tmp_list->data);
tmp_list = tmp_list->next;
}
}
list = g_slist_next (list);
1997-11-25 06:05:25 +08:00
}
}
void
gdisplays_expose_guide (GimpImage* gimage,
1997-11-25 06:05:25 +08:00
Guide *guide)
{
GDisplay *gdisp;
GSList *list;
1997-11-25 06:05:25 +08:00
/* traverse the linked list of displays, handling each one */
list = display_list;
while (list)
{
gdisp = (GDisplay *) list->data;
if (gdisp->gimage == gimage)
1997-11-25 06:05:25 +08:00
gdisplay_expose_guide (gdisp, guide);
list = g_slist_next (list);
1997-11-25 06:05:25 +08:00
}
}
void
gdisplays_update_full (GimpImage* gimage)
1997-11-25 06:05:25 +08:00
{
GDisplay *gdisp;
GSList *list = display_list;
1997-11-25 06:05:25 +08:00
int count = 0;
/* traverse the linked list of displays, handling each one */
while (list)
{
gdisp = (GDisplay *) list->data;
if (gdisp->gimage == gimage)
1997-11-25 06:05:25 +08:00
{
if (! count)
gdisplay_add_update_area (gdisp, 0, 0,
gdisp->gimage->width,
gdisp->gimage->height);
else
gdisplay_add_display_area (gdisp, 0, 0,
gdisp->disp_width,
gdisp->disp_height);
count++;
}
list = g_slist_next (list);
1997-11-25 06:05:25 +08:00
}
}
void
gdisplays_shrink_wrap (GimpImage* gimage)
1997-11-25 06:05:25 +08:00
{
GDisplay *gdisp;
GSList *list = display_list;
1997-11-25 06:05:25 +08:00
/* traverse the linked list of displays, handling each one */
while (list)
{
gdisp = (GDisplay *) list->data;
if (gdisp->gimage == gimage)
1997-11-25 06:05:25 +08:00
shrink_wrap_display (gdisp);
list = g_slist_next (list);
1997-11-25 06:05:25 +08:00
}
}
void
gdisplays_expose_full ()
{
GDisplay *gdisp;
GSList *list = display_list;
1997-11-25 06:05:25 +08:00
/* traverse the linked list of displays, handling each one */
while (list)
{
gdisp = (GDisplay *) list->data;
gdisplay_expose_full (gdisp);
list = g_slist_next (list);
1997-11-25 06:05:25 +08:00
}
}
void
gdisplays_nav_preview_resized ()
{
GDisplay *gdisp;
GSList *list = display_list;
/* traverse the linked list of displays, handling each one */
while (list)
{
gdisp = (GDisplay *) list->data;
if(gdisp->window_nav_dialog)
nav_window_preview_resized(gdisp->window_nav_dialog);
if(gdisp->nav_popup)
nav_window_popup_preview_resized(&gdisp->nav_popup);
list = g_slist_next (list);
}
}
1997-11-25 06:05:25 +08:00
void
gdisplays_selection_visibility (GimpImage* gimage,
1997-11-25 06:05:25 +08:00
SelectionControl function)
{
GDisplay *gdisp;
GSList *list = display_list;
1997-11-25 06:05:25 +08:00
int count = 0;
/* traverse the linked list of displays, handling each one */
while (list)
{
gdisp = (GDisplay *) list->data;
if (gdisp->gimage == gimage && gdisp->select)
1997-11-25 06:05:25 +08:00
{
switch (function)
{
case SelectionOff:
selection_invis (gdisp->select);
break;
case SelectionLayerOff:
selection_layer_invis (gdisp->select);
break;
case SelectionOn:
selection_start (gdisp->select, TRUE);
break;
case SelectionPause:
selection_pause (gdisp->select);
break;
case SelectionResume:
selection_resume (gdisp->select);
break;
}
count++;
}
list = g_slist_next (list);
1997-11-25 06:05:25 +08:00
}
}
int
gdisplays_dirty ()
{
int dirty = 0;
GSList *list = display_list;
1997-11-25 06:05:25 +08:00
/* traverse the linked list of displays */
while (list)
{
Dirty flag now correct in all cases. Can be displayed in image window Mon Aug 23 10:15:32 EDT 1999 Austin Donnelly <austin@gimp.org> Dirty flag now correct in all cases. Can be displayed in image window title too. See NOTE near gimp_image_dirty() for details. * app/fileops.c: gimp_image_clean_all() after reverting an image. * app/gdisplay.c: register handlers for gimage dirty and clean signals to update image title. New image-title-format expansion: %Dx expands to x if the image is dirty. * app/gdisplay_ops.c: gimage->dirty flags != 0 is the correct condition to test to see if an image is dirty. * app/gimpdrawable.c: gimp_image_dirty() should never be called except from an undo_push_* function. Call undo_push_cantundo() if you want to dirty the image but can't be bothered writing an undo handler (be ashamed of yourself!). * app/gimpimage.c: new gimage signal: clean. Emitted when an undo operation takes place. Gimage changes when either dirty or clean is emitted, so if you need to update previews etc, look for both! Move group_count into gimage structure, since leaving it as a static in undo.c is bad if two undo groups are started on different images at the same time. More changes of gimp_image_dirty() to undo_push_cantundo() (parasite-related, plus layer moves). See the NOTE on dirty counter near gimp_image_dirty() for the full story. gimp_image_dirty() and gimp_image_clean() simplified - counter can go negative. * app/gimpimageP.h: group_count moved from undo.c * app/layers_dialog.c: push undo for layer name change, rather than dirtying the image. * app/undo.c: layer rename undo functions added. undo_push_cantundo() convenience functions added. group_count made per-gimage since everything else is. When blowing away redo stack, make image infinitely dirty if redo info contained file save point. * app/undo.h: added undo_push_layer_rename() and undo_push_cantundo(). * TODO: added idea for undo history window.
1999-08-23 22:34:58 +08:00
if (((GDisplay *) list->data)->gimage->dirty != 0)
1997-11-25 06:05:25 +08:00
dirty = 1;
list = g_slist_next (list);
1997-11-25 06:05:25 +08:00
}
return dirty;
}
void
gdisplays_delete ()
{
GSList *list = display_list;
GDisplay *gdisp;
1997-11-25 06:05:25 +08:00
/* traverse the linked list of displays */
while (list)
{
gdisp = (GDisplay *) list->data;
list = g_slist_next (list);
gtk_widget_destroy (gdisp->shell);
1997-11-25 06:05:25 +08:00
}
/* free up linked list data */
g_slist_free (display_list);
1997-11-25 06:05:25 +08:00
}
GDisplay *
gdisplays_check_valid (GDisplay *gtest, GimpImage *gimage)
{
/* Give a gdisp check that it is still valid and points to the require
* GimpImage. If not return the first gDisplay that does point to the
* gimage. If none found return NULL;
*/
GSList *list = display_list;
GDisplay *gdisp;
GDisplay *gdisp_found = NULL;
/* traverse the linked list of displays */
while (list)
{
gdisp = (GDisplay *) list->data;
if(gdisp == gtest)
return (gtest);
if(!gdisp_found && gdisp->gimage == gimage)
gdisp_found = gdisp;
list = g_slist_next (list);
}
return (gdisp_found);
}
1997-11-25 06:05:25 +08:00
static void
gdisplays_flush_whenever (gboolean now)
1997-11-25 06:05:25 +08:00
{
static int flushing = FALSE;
GSList *list = display_list;
1997-11-25 06:05:25 +08:00
/* no flushing necessary without an interface */
if (no_interface)
return;
/* this prevents multiple recursive calls to this procedure */
if (flushing == TRUE)
{
1999-09-23 19:49:16 +08:00
g_warning ("gdisplays_flush() called recursively.");
return;
}
1997-11-25 06:05:25 +08:00
flushing = TRUE;
/* traverse the linked list of displays */
while (list)
{
gdisplay_flush_whenever ((GDisplay *) list->data, now);
list = g_slist_next (list);
1997-11-25 06:05:25 +08:00
}
/* for convenience, we call the L&C flush here */
lc_dialog_flush ();
1997-11-25 06:05:25 +08:00
flushing = FALSE;
}
void
gdisplays_flush (void)
{
gdisplays_flush_whenever (FALSE);
}
void
gdisplays_flush_now (void)
{
gdisplays_flush_whenever (TRUE);
}
static guint
gdisplay_hash (GDisplay *display)
{
return (gulong) display;
}
1999-01-12 09:31:49 +08:00
void
gdisplay_reconnect (GDisplay *gdisp, GimpImage *gimage)
{
int instance;
if (gdisp->idle_render.active)
{
gtk_idle_remove (gdisp->idle_render.idleid);
gdisp->idle_render.active = FALSE;
}
Dirty flag now correct in all cases. Can be displayed in image window Mon Aug 23 10:15:32 EDT 1999 Austin Donnelly <austin@gimp.org> Dirty flag now correct in all cases. Can be displayed in image window title too. See NOTE near gimp_image_dirty() for details. * app/fileops.c: gimp_image_clean_all() after reverting an image. * app/gdisplay.c: register handlers for gimage dirty and clean signals to update image title. New image-title-format expansion: %Dx expands to x if the image is dirty. * app/gdisplay_ops.c: gimage->dirty flags != 0 is the correct condition to test to see if an image is dirty. * app/gimpdrawable.c: gimp_image_dirty() should never be called except from an undo_push_* function. Call undo_push_cantundo() if you want to dirty the image but can't be bothered writing an undo handler (be ashamed of yourself!). * app/gimpimage.c: new gimage signal: clean. Emitted when an undo operation takes place. Gimage changes when either dirty or clean is emitted, so if you need to update previews etc, look for both! Move group_count into gimage structure, since leaving it as a static in undo.c is bad if two undo groups are started on different images at the same time. More changes of gimp_image_dirty() to undo_push_cantundo() (parasite-related, plus layer moves). See the NOTE on dirty counter near gimp_image_dirty() for the full story. gimp_image_dirty() and gimp_image_clean() simplified - counter can go negative. * app/gimpimageP.h: group_count moved from undo.c * app/layers_dialog.c: push undo for layer name change, rather than dirtying the image. * app/undo.c: layer rename undo functions added. undo_push_cantundo() convenience functions added. group_count made per-gimage since everything else is. When blowing away redo stack, make image infinitely dirty if redo info contained file save point. * app/undo.h: added undo_push_layer_rename() and undo_push_cantundo(). * TODO: added idea for undo history window.
1999-08-23 22:34:58 +08:00
gtk_signal_disconnect_by_data (GTK_OBJECT (gdisp->gimage), gdisp);
1999-01-12 09:31:49 +08:00
gimage_delete (gdisp->gimage);
instance = gimage->instance_count;
gimage->instance_count++;
gimage->ref_count++;
gdisp->gimage = gimage;
gdisp->instance = instance;
Dirty flag now correct in all cases. Can be displayed in image window Mon Aug 23 10:15:32 EDT 1999 Austin Donnelly <austin@gimp.org> Dirty flag now correct in all cases. Can be displayed in image window title too. See NOTE near gimp_image_dirty() for details. * app/fileops.c: gimp_image_clean_all() after reverting an image. * app/gdisplay.c: register handlers for gimage dirty and clean signals to update image title. New image-title-format expansion: %Dx expands to x if the image is dirty. * app/gdisplay_ops.c: gimage->dirty flags != 0 is the correct condition to test to see if an image is dirty. * app/gimpdrawable.c: gimp_image_dirty() should never be called except from an undo_push_* function. Call undo_push_cantundo() if you want to dirty the image but can't be bothered writing an undo handler (be ashamed of yourself!). * app/gimpimage.c: new gimage signal: clean. Emitted when an undo operation takes place. Gimage changes when either dirty or clean is emitted, so if you need to update previews etc, look for both! Move group_count into gimage structure, since leaving it as a static in undo.c is bad if two undo groups are started on different images at the same time. More changes of gimp_image_dirty() to undo_push_cantundo() (parasite-related, plus layer moves). See the NOTE on dirty counter near gimp_image_dirty() for the full story. gimp_image_dirty() and gimp_image_clean() simplified - counter can go negative. * app/gimpimageP.h: group_count moved from undo.c * app/layers_dialog.c: push undo for layer name change, rather than dirtying the image. * app/undo.c: layer rename undo functions added. undo_push_cantundo() convenience functions added. group_count made per-gimage since everything else is. When blowing away redo stack, make image infinitely dirty if redo info contained file save point. * app/undo.h: added undo_push_layer_rename() and undo_push_cantundo(). * TODO: added idea for undo history window.
1999-08-23 22:34:58 +08:00
/* reconnect our clean / dirty signals */
gtk_signal_connect (GTK_OBJECT (gimage), "dirty",
GTK_SIGNAL_FUNC(gdisplay_cleandirty_handler), gdisp);
gtk_signal_connect (GTK_OBJECT (gimage), "clean",
GTK_SIGNAL_FUNC(gdisplay_cleandirty_handler), gdisp);
gdisplays_update_title (gimage);
1999-01-12 09:31:49 +08:00
gdisplay_expose_full (gdisp);
gdisplay_flush (gdisp);
}
Dirty flag now correct in all cases. Can be displayed in image window Mon Aug 23 10:15:32 EDT 1999 Austin Donnelly <austin@gimp.org> Dirty flag now correct in all cases. Can be displayed in image window title too. See NOTE near gimp_image_dirty() for details. * app/fileops.c: gimp_image_clean_all() after reverting an image. * app/gdisplay.c: register handlers for gimage dirty and clean signals to update image title. New image-title-format expansion: %Dx expands to x if the image is dirty. * app/gdisplay_ops.c: gimage->dirty flags != 0 is the correct condition to test to see if an image is dirty. * app/gimpdrawable.c: gimp_image_dirty() should never be called except from an undo_push_* function. Call undo_push_cantundo() if you want to dirty the image but can't be bothered writing an undo handler (be ashamed of yourself!). * app/gimpimage.c: new gimage signal: clean. Emitted when an undo operation takes place. Gimage changes when either dirty or clean is emitted, so if you need to update previews etc, look for both! Move group_count into gimage structure, since leaving it as a static in undo.c is bad if two undo groups are started on different images at the same time. More changes of gimp_image_dirty() to undo_push_cantundo() (parasite-related, plus layer moves). See the NOTE on dirty counter near gimp_image_dirty() for the full story. gimp_image_dirty() and gimp_image_clean() simplified - counter can go negative. * app/gimpimageP.h: group_count moved from undo.c * app/layers_dialog.c: push undo for layer name change, rather than dirtying the image. * app/undo.c: layer rename undo functions added. undo_push_cantundo() convenience functions added. group_count made per-gimage since everything else is. When blowing away redo stack, make image infinitely dirty if redo info contained file save point. * app/undo.h: added undo_push_layer_rename() and undo_push_cantundo(). * TODO: added idea for undo history window.
1999-08-23 22:34:58 +08:00
/* Called whenever the underlying gimage is dirtied or cleaned */
static void
gdisplay_cleandirty_handler (GimpImage *gimage, void *data)
{
GDisplay *gdisp = data;
gdisplay_update_title (gdisp);
}