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
|
1998-04-13 13:44:11 +08:00
|
|
|
* 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>
|
1999-02-21 07:20:54 +08:00
|
|
|
#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"
|
1999-07-07 11:18:54 +08:00
|
|
|
#include "draw_core.h"
|
1997-11-25 06:05:25 +08:00
|
|
|
#include "gdisplay.h"
|
|
|
|
#include "gdisplayP.h"
|
1999-08-26 03:18:41 +08:00
|
|
|
#include "gdisplay_color.h"
|
1997-11-25 06:05:25 +08:00
|
|
|
#include "gdisplay_ops.h"
|
|
|
|
#include "gimage_mask.h"
|
1999-06-20 21:53:15 +08:00
|
|
|
#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"
|
1999-06-07 01:26:51 +08:00
|
|
|
#include "lc_dialog.h"
|
1997-11-25 06:05:25 +08:00
|
|
|
#include "menus.h"
|
1999-08-13 06:21:04 +08:00
|
|
|
#include "nav_window.h"
|
1997-11-25 06:05:25 +08:00
|
|
|
#include "plug_in.h"
|
1999-07-07 11:18:54 +08:00
|
|
|
#include "qmask.h"
|
1997-11-25 06:05:25 +08:00
|
|
|
#include "scale.h"
|
|
|
|
#include "scroll.h"
|
|
|
|
#include "tools.h"
|
|
|
|
#include "undo.h"
|
1999-07-07 11:18:54 +08:00
|
|
|
|
|
|
|
#include "bezier_selectP.h"
|
|
|
|
#include "layer_pvt.h" /* ick. (not alone either) */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +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"
|
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
|
|
|
|
1999-02-07 23:16:45 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
#define OVERHEAD 25 /* in units of pixel area */
|
|
|
|
#define EPSILON 5
|
|
|
|
|
1998-08-03 04:36:34 +08:00
|
|
|
#define MAX_TITLE_BUF 256
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/* variable declarations */
|
1998-01-29 16:03:27 +08:00
|
|
|
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 */
|
1999-02-07 02:31:33 +08:00
|
|
|
static void gdisplay_format_title (GDisplay *, char *, int);
|
1997-11-25 06:05:25 +08:00
|
|
|
static void gdisplay_delete (GDisplay *);
|
1998-01-29 16:03:27 +08:00
|
|
|
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);
|
1998-06-06 11:49:01 +08:00
|
|
|
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 *);
|
1999-08-23 22:34:58 +08:00
|
|
|
static void gdisplay_cleandirty_handler (GimpImage *, void *);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1998-10-02 00:22:28 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
static GHashTable *display_ht = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
GDisplay*
|
1999-02-28 02:09:56 +08:00
|
|
|
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;
|
1998-12-06 05:48:37 +08:00
|
|
|
gdisp->dot_for_dot = TRUE;
|
1997-11-25 06:05:25 +08:00
|
|
|
gdisp->gimage = gimage;
|
|
|
|
gdisp->window_info_dialog = NULL;
|
1999-08-13 06:21:04 +08:00
|
|
|
gdisp->window_nav_dialog = NULL;
|
1999-09-02 06:39:44 +08:00
|
|
|
gdisp->nav_popup = NULL;
|
1997-11-25 06:05:25 +08:00
|
|
|
gdisp->depth = g_visual->depth;
|
|
|
|
gdisp->select = NULL;
|
|
|
|
gdisp->ID = display_num++;
|
1999-02-07 02:31:33 +08:00
|
|
|
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;
|
|
|
|
|
1998-06-06 11:49:01 +08:00
|
|
|
gdisp->draw_cursor = FALSE;
|
|
|
|
gdisp->proximity = FALSE;
|
|
|
|
gdisp->have_cursor = FALSE;
|
1999-01-11 07:36:29 +08:00
|
|
|
gdisp->using_override_cursor = FALSE;
|
1998-06-06 11:49:01 +08:00
|
|
|
|
1998-06-15 10:25:27 +08:00
|
|
|
gdisp->progressid = FALSE;
|
|
|
|
|
1998-10-02 00:22:28 +08:00
|
|
|
gdisp->idle_render.idleid = -1;
|
1998-10-04 04:14:00 +08:00
|
|
|
/*gdisp->idle_render.handlerid = -1;*/
|
1998-10-02 00:22:28 +08:00
|
|
|
gdisp->idle_render.update_areas = NULL;
|
|
|
|
gdisp->idle_render.active = FALSE;
|
|
|
|
|
1999-08-29 06:40:37 +08:00
|
|
|
gdisp->cd_list = NULL;
|
1999-08-26 03:18:41 +08:00
|
|
|
|
1999-02-07 02:31:33 +08:00
|
|
|
/* 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 */
|
1998-01-29 16:03:27 +08:00
|
|
|
display_list = g_slist_append (display_list, (void *) gdisp);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* create the shell for the image */
|
1998-06-30 23:31:32 +08:00
|
|
|
create_display_shell (gdisp, gimage->width, gimage->height,
|
1997-11-25 06:05:25 +08:00
|
|
|
title, gimage_base_type (gimage));
|
1999-03-06 10:07:54 +08:00
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
1999-07-07 11:18:54 +08:00
|
|
|
/* 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);
|
|
|
|
|
1999-02-07 02:31:33 +08:00
|
|
|
gimage->instance_count++;
|
|
|
|
gimage->ref_count++;
|
|
|
|
|
1999-06-24 07:01:14 +08:00
|
|
|
lc_dialog_preview_update(gimage);
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-02-07 02:31:33 +08:00
|
|
|
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
|
1999-02-07 02:31:33 +08:00
|
|
|
gdisplay_format_title (GDisplay *gdisp,
|
1999-02-28 02:09:56 +08:00
|
|
|
char *title,
|
|
|
|
int title_len)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-02-07 02:31:33 +08:00
|
|
|
GimpImage *gimage;
|
1997-11-25 06:05:25 +08:00
|
|
|
char *image_type_str;
|
|
|
|
int empty;
|
1999-02-07 02:31:33 +08:00
|
|
|
int i;
|
|
|
|
char *format;
|
|
|
|
|
|
|
|
gimage = gdisp->gimage;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
empty = gimage_is_empty (gimage);
|
|
|
|
|
1998-08-20 08:35:40 +08:00
|
|
|
switch (gimage_base_type (gimage))
|
|
|
|
{
|
|
|
|
case RGB:
|
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
|
|
|
image_type_str = (empty) ? _("RGB-empty") : _("RGB");
|
1998-08-20 08:35:40 +08:00
|
|
|
break;
|
|
|
|
case GRAY:
|
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
|
|
|
image_type_str = (empty) ? _("grayscale-empty") : _("grayscale");
|
1998-08-20 08:35:40 +08:00
|
|
|
break;
|
|
|
|
case INDEXED:
|
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
|
|
|
image_type_str = (empty) ? _("indexed-empty") : _("indexed");
|
1998-08-20 08:35:40 +08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
image_type_str = NULL;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-02-07 02:31:33 +08:00
|
|
|
i = 0;
|
|
|
|
format = image_title_format;
|
|
|
|
|
|
|
|
while (i < title_len && *format)
|
|
|
|
{
|
|
|
|
switch (*format) {
|
|
|
|
case '%':
|
|
|
|
format++;
|
|
|
|
switch (*format) {
|
|
|
|
case 0:
|
1999-05-30 00:35:47 +08:00
|
|
|
g_warning ("image-title-format string ended within %%-sequence");
|
1999-02-07 02:31:33 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case '%':
|
|
|
|
title[i++] = '%';
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'f': /* pruned filename */
|
|
|
|
i += print (title, title_len, i,
|
1999-02-07 18:45:56 +08:00
|
|
|
"%s", g_basename (gimage_filename (gimage)));
|
1999-02-07 02:31:33 +08:00
|
|
|
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;
|
|
|
|
|
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:
|
1999-02-07 02:31:33 +08:00
|
|
|
* %m = memory used by picture
|
|
|
|
* some kind of resolution / image size thing
|
|
|
|
* people seem to want to know the active layer name
|
|
|
|
*/
|
|
|
|
|
|
|
|
default:
|
1999-05-30 00:35:47 +08:00
|
|
|
g_warning ("image-title-format contains unknown format sequence '%%%c'", *format);
|
1999-02-07 02:31:33 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
title[i++] = *format;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
format++;
|
|
|
|
}
|
|
|
|
|
1999-02-14 09:53:23 +08:00
|
|
|
title[MIN(i, title_len-1)] = 0;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
gdisplay_delete (GDisplay *gdisp)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
|
1999-06-22 06:12:07 +08:00
|
|
|
/* clear out the pointer to this gdisp from the active tool */
|
1999-07-09 20:24:36 +08:00
|
|
|
if (active_tool &&
|
|
|
|
active_tool->gdisp_ptr == gdisp)
|
1999-06-22 06:12:07 +08:00
|
|
|
{
|
1999-07-09 20:24:36 +08:00
|
|
|
active_tool->drawable = NULL;
|
|
|
|
active_tool->gdisp_ptr = NULL;
|
1998-04-15 06:05:08 +08:00
|
|
|
}
|
1998-04-13 12:32:39 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/* free the selection structure */
|
|
|
|
selection_free (gdisp->select);
|
1998-10-02 00:22:28 +08:00
|
|
|
|
|
|
|
/* 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;
|
|
|
|
}
|
1999-08-23 22:34:58 +08:00
|
|
|
|
1999-10-05 03:26:07 +08:00
|
|
|
/* detach any color displays */
|
|
|
|
gdisplay_color_detach_all (gdisp);
|
|
|
|
|
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);
|
1999-10-31 01:49:50 +08:00
|
|
|
|
1997-12-18 14:30:11 +08:00
|
|
|
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);
|
|
|
|
|
1998-10-02 00:22:28 +08:00
|
|
|
gdisplay_free_area_list (gdisp->idle_render.update_areas);
|
|
|
|
|
1999-10-31 01:49:50 +08:00
|
|
|
/* remove dialogs before removing the image because they may want to
|
|
|
|
* disconnect from image signals
|
|
|
|
*/
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* insure that if a window information dialog exists, it is removed */
|
1999-11-30 08:11:08 +08:00
|
|
|
info_window_free (gdisp->window_info_dialog);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-11-20 08:46:58 +08:00
|
|
|
/* Remove navigation dialog */
|
|
|
|
nav_window_free(gdisp,gdisp->window_nav_dialog);
|
1999-08-13 06:21:04 +08:00
|
|
|
|
1999-10-31 01:49:50 +08:00
|
|
|
/* free the gimage */
|
|
|
|
gimage_delete (gdisp->gimage);
|
|
|
|
|
1999-10-14 07:07:45 +08:00
|
|
|
if (gdisp->nav_popup)
|
1999-09-02 06:39:44 +08:00
|
|
|
nav_popup_free(gdisp->nav_popup);
|
|
|
|
|
1998-02-14 23:30:31 +08:00
|
|
|
gtk_widget_unref (gdisp->shell);
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
g_free (gdisp);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-01-29 16:03:27 +08:00
|
|
|
static GSList *
|
|
|
|
gdisplay_free_area_list (GSList *list)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1998-01-29 16:03:27 +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);
|
|
|
|
|
1998-01-29 16:03:27 +08:00
|
|
|
l = g_slist_next (l);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (list)
|
1998-01-29 16:03:27 +08:00
|
|
|
g_slist_free (list);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-10-01 19:53:20 +08:00
|
|
|
/*
|
|
|
|
* 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]
|
|
|
|
*/
|
1998-01-29 16:03:27 +08:00
|
|
|
static GSList *
|
|
|
|
gdisplay_process_area_list (GSList *list,
|
|
|
|
GArea *ga1)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1998-01-29 16:03:27 +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 */
|
1998-01-29 16:03:27 +08:00
|
|
|
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)
|
1998-01-29 16:03:27 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
1998-01-29 16:03:27 +08:00
|
|
|
l = g_slist_next (l);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (list)
|
1998-01-29 16:03:27 +08:00
|
|
|
g_slist_free (list);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
return new_list;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-10-02 00:22:28 +08:00
|
|
|
static int
|
|
|
|
idle_render_next_area (GDisplay *gdisp)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1998-01-29 16:03:27 +08:00
|
|
|
GArea *ga;
|
|
|
|
GSList *list;
|
1998-10-02 00:22:28 +08:00
|
|
|
|
|
|
|
list = gdisp->idle_render.update_areas;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1998-10-02 00:22:28 +08:00
|
|
|
if (list == NULL)
|
|
|
|
{
|
|
|
|
return (-1);
|
|
|
|
}
|
1998-10-01 19:53:20 +08:00
|
|
|
|
1998-10-02 00:22:28 +08:00
|
|
|
ga = (GArea*) list->data;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1998-10-02 00:22:28 +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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-10-04 04:14:00 +08:00
|
|
|
/* 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 */
|
1998-10-02 00:22:28 +08:00
|
|
|
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;
|
1999-01-11 07:36:29 +08:00
|
|
|
|
1998-10-02 00:22:28 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Still work to do. */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
gdisplay_idlerender_init (GDisplay *gdisp)
|
|
|
|
{
|
|
|
|
GSList *list;
|
|
|
|
GArea *ga, *new_ga;
|
|
|
|
|
1999-01-11 07:36:29 +08:00
|
|
|
/* gdisplay_install_override_cursor(gdisp, GDK_CIRCLE); */
|
|
|
|
|
1998-10-02 00:22:28 +08:00
|
|
|
/* 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;
|
1998-10-02 00:22:28 +08:00
|
|
|
new_ga = g_malloc (sizeof(GArea));
|
|
|
|
memcpy (new_ga, ga, sizeof(GArea));
|
1998-10-01 19:53:20 +08:00
|
|
|
|
1998-10-02 00:22:28 +08:00
|
|
|
gdisp->idle_render.update_areas =
|
|
|
|
gdisplay_process_area_list (gdisp->idle_render.update_areas, new_ga);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1998-01-29 16:03:27 +08:00
|
|
|
list = g_slist_next (list);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
1998-10-02 00:22:28 +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)
|
|
|
|
{
|
1999-05-30 00:35:47 +08:00
|
|
|
g_warning ("Wanted to start idlerender thread with no update_areas. (+memleak)");
|
1998-10-02 00:22:28 +08:00
|
|
|
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 */
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-03-21 06:05:24 +08:00
|
|
|
void
|
1998-10-02 00:22:28 +08:00
|
|
|
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));
|
|
|
|
|
1998-01-29 16:03:27 +08:00
|
|
|
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);
|
|
|
|
|
1998-06-06 11:49:01 +08:00
|
|
|
/* 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);
|
1998-10-02 00:22:28 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
gdisplay_flush_whenever (GDisplay *gdisp, gboolean now)
|
|
|
|
{
|
1999-07-07 21:32:58 +08:00
|
|
|
GSList *list;
|
|
|
|
GArea *ga;
|
1998-10-02 00:22:28 +08:00
|
|
|
|
|
|
|
/* 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
|
|
|
}
|
1998-10-02 00:22:28 +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);
|
1997-11-27 03:30:17 +08:00
|
|
|
|
|
|
|
/* update the gdisplay's info dialog */
|
1999-11-30 08:11:08 +08:00
|
|
|
info_window_update (gdisp);
|
1999-07-07 11:18:54 +08:00
|
|
|
|
|
|
|
/* update the gdisplay's qmask buttons */
|
|
|
|
qmask_buttons_update (gdisp);
|
1999-07-07 21:32:58 +08:00
|
|
|
|
1999-06-21 07:29:34 +08:00
|
|
|
/* ensure the consistency of the tear-off menus */
|
1999-09-28 06:12:44 +08:00
|
|
|
if (!now && gimp_context_get_display (gimp_context_get_user ()) == gdisp)
|
1999-06-21 07:29:34 +08:00
|
|
|
gdisplay_set_menu_sensitivity (gdisp);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
1998-10-02 00:22:28 +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);
|
|
|
|
}
|
|
|
|
|
1999-01-18 06:50:14 +08:00
|
|
|
/* 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;
|
1998-12-26 02:22:01 +08:00
|
|
|
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;
|
1998-10-04 04:14:00 +08:00
|
|
|
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;
|
1998-10-04 04:14:00 +08:00
|
|
|
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);
|
1998-10-04 04:14:00 +08:00
|
|
|
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;
|
|
|
|
|
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);
|
|
|
|
}
|
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;
|
1998-12-06 05:48:37 +08:00
|
|
|
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;
|
1998-12-06 05:48:37 +08:00
|
|
|
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)
|
|
|
|
{
|
1999-07-29 07:00:08 +08:00
|
|
|
case ORIENTATION_HORIZONTAL:
|
1998-12-06 05:48:37 +08:00
|
|
|
pos = (int) (scaley * guide->position - offset_y);
|
1998-03-16 19:13:24 +08:00
|
|
|
if ((guide->position != -1) &&
|
|
|
|
(pos > (y - EPSILON)) &&
|
1997-11-25 06:05:25 +08:00
|
|
|
(pos < (y + EPSILON)))
|
|
|
|
return guide;
|
|
|
|
break;
|
1999-07-29 07:00:08 +08:00
|
|
|
case ORIENTATION_VERTICAL:
|
1998-12-06 05:48:37 +08:00
|
|
|
pos = (int) (scalex * guide->position - offset_x);
|
1998-03-16 19:13:24 +08:00
|
|
|
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,
|
1998-06-06 11:49:01 +08:00
|
|
|
gdouble x ,
|
|
|
|
gdouble y,
|
|
|
|
gdouble *tx,
|
|
|
|
gdouble *ty)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
GList *tmp_list;
|
|
|
|
Guide *guide;
|
1998-12-06 05:48:37 +08:00
|
|
|
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;
|
1998-12-06 05:48:37 +08:00
|
|
|
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)
|
|
|
|
{
|
1999-07-29 07:00:08 +08:00
|
|
|
case ORIENTATION_HORIZONTAL:
|
1998-12-06 05:48:37 +08:00
|
|
|
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;
|
1999-07-29 07:00:08 +08:00
|
|
|
case ORIENTATION_VERTICAL:
|
1998-12-06 05:48:37 +08:00
|
|
|
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)
|
|
|
|
{
|
1998-06-06 11:49:01 +08:00
|
|
|
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);
|
|
|
|
|
1998-06-06 11:49:01 +08:00
|
|
|
if (x1 != (int)nx1)
|
1997-11-25 06:05:25 +08:00
|
|
|
*tx1 = nx1;
|
1998-06-06 11:49:01 +08:00
|
|
|
else if (x2 != (int)nx2)
|
1997-11-25 06:05:25 +08:00
|
|
|
*tx1 = x1 + (nx2 - x2);
|
|
|
|
|
1998-06-06 11:49:01 +08:00
|
|
|
if (y1 != (int)ny1)
|
1997-11-25 06:05:25 +08:00
|
|
|
*ty1 = ny1;
|
1998-06-06 11:49:01 +08:00
|
|
|
else if (y2 != (int)ny2)
|
1997-11-25 06:05:25 +08:00
|
|
|
*ty1 = y1 + (ny2 - y2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-06-06 11:49:01 +08:00
|
|
|
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;
|
1998-07-25 01:14:26 +08:00
|
|
|
char buffer[CURSOR_STR_LENGTH];
|
1998-07-16 11:23:14 +08:00
|
|
|
int t_x, t_y;
|
1998-08-14 02:53:12 +08:00
|
|
|
GimpDrawable *active_drawable;
|
1998-06-06 11:49:01 +08:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
1998-07-16 11:23:14 +08:00
|
|
|
|
1999-08-13 06:21:04 +08:00
|
|
|
gdisplay_untransform_coords(gdisp, x, y, &t_x, &t_y, FALSE, FALSE);
|
1998-07-16 11:23:14 +08:00
|
|
|
|
1998-08-14 02:53:12 +08:00
|
|
|
active_drawable = gimp_image_active_drawable (gdisp->gimage);
|
|
|
|
|
1998-08-16 12:07:02 +08:00
|
|
|
if (active_drawable)
|
1998-07-16 11:23:14 +08:00
|
|
|
{
|
1998-08-16 12:07:02 +08:00
|
|
|
if (t_x < 0 ||
|
|
|
|
t_y < 0 ||
|
1998-08-16 21:12:57 +08:00
|
|
|
t_x >= active_drawable->width ||
|
|
|
|
t_y >= active_drawable->height)
|
1998-08-16 12:07:02 +08:00
|
|
|
{
|
1998-08-16 21:12:57 +08:00
|
|
|
gtk_label_set (GTK_LABEL (gdisp->cursor_label), "");
|
1999-11-30 08:11:08 +08:00
|
|
|
info_window_update_RGB (gdisp, -1, -1);
|
1998-08-16 12:07:02 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-02-28 02:09:56 +08:00
|
|
|
if (gdisp->dot_for_dot)
|
|
|
|
{
|
|
|
|
g_snprintf (buffer, CURSOR_STR_LENGTH,
|
1999-03-04 01:48:29 +08:00
|
|
|
gdisp->cursor_format_str, "", t_x, ", ", t_y);
|
1999-02-28 02:09:56 +08:00
|
|
|
}
|
|
|
|
else /* show real world units */
|
|
|
|
{
|
1999-05-23 01:56:35 +08:00
|
|
|
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);
|
1999-02-28 02:09:56 +08:00
|
|
|
}
|
1998-08-16 21:12:57 +08:00
|
|
|
gtk_label_set (GTK_LABEL (gdisp->cursor_label), buffer);
|
1999-11-30 08:11:08 +08:00
|
|
|
info_window_update_RGB (gdisp, t_x, t_y);
|
1998-08-16 12:07:02 +08:00
|
|
|
}
|
1998-07-16 11:23:14 +08:00
|
|
|
}
|
1998-08-16 21:12:57 +08:00
|
|
|
|
1998-06-06 11:49:01 +08:00
|
|
|
gdisp->have_cursor = new_cursor;
|
|
|
|
gdisp->cursor_x = x;
|
|
|
|
gdisp->cursor_y = y;
|
1998-08-16 12:07:02 +08:00
|
|
|
|
1998-06-06 11:49:01 +08:00
|
|
|
if (new_cursor)
|
|
|
|
gdisplay_flush (gdisp);
|
1999-08-13 06:21:04 +08:00
|
|
|
|
1998-06-06 11:49:01 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1998-12-06 05:48:37 +08:00
|
|
|
|
|
|
|
void
|
|
|
|
gdisplay_set_dot_for_dot (GDisplay *gdisp, int value)
|
|
|
|
{
|
|
|
|
if (value != gdisp->dot_for_dot)
|
|
|
|
{
|
|
|
|
gdisp->dot_for_dot = value;
|
|
|
|
|
1999-02-28 02:09:56 +08:00
|
|
|
gdisplay_resize_cursor_label (gdisp);
|
1998-12-06 05:48:37 +08:00
|
|
|
resize_display (gdisp, allow_resize_windows, TRUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-11-20 04:20:46 +08:00
|
|
|
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;
|
1999-02-28 02:09:56 +08:00
|
|
|
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),
|
1999-03-04 01:48:29 +08:00
|
|
|
"%%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,
|
1999-03-04 01:48:29 +08:00
|
|
|
"", gdisp->gimage->width, ", ", gdisp->gimage->height);
|
1999-02-28 02:09:56 +08:00
|
|
|
}
|
|
|
|
else /* show real world units */
|
|
|
|
{
|
1999-05-23 01:56:35 +08:00
|
|
|
gdouble unit_factor = gimp_unit_get_factor (gdisp->gimage->unit);
|
1999-02-28 02:09:56 +08:00
|
|
|
|
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),
|
1999-03-04 01:48:29 +08:00
|
|
|
"%%s%%.%df%%s%%.%df %s",
|
1999-02-28 02:09:56 +08:00
|
|
|
gimp_unit_get_digits (gdisp->gimage->unit),
|
1999-03-04 01:48:29 +08:00
|
|
|
gimp_unit_get_digits (gdisp->gimage->unit),
|
|
|
|
gimp_unit_get_symbol (gdisp->gimage->unit));
|
1999-02-28 02:09:56 +08:00
|
|
|
|
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,
|
1999-03-04 01:48:29 +08:00
|
|
|
"",
|
1999-05-23 01:56:35 +08:00
|
|
|
(gdouble) gdisp->gimage->width * unit_factor /
|
1999-02-28 02:09:56 +08:00
|
|
|
gdisp->gimage->xresolution,
|
1999-03-04 01:48:29 +08:00
|
|
|
", ",
|
1999-05-23 01:56:35 +08:00
|
|
|
(gdouble) gdisp->gimage->height * unit_factor /
|
1999-03-04 01:48:29 +08:00
|
|
|
gdisp->gimage->yresolution);
|
1999-02-28 02:09:56 +08:00
|
|
|
}
|
1998-11-20 04:20:46 +08:00
|
|
|
cursor_label_width =
|
1999-05-23 01:56:35 +08:00
|
|
|
gdk_string_width (gtk_widget_get_style (gdisp->cursor_label)->font, buffer);
|
1999-02-28 02:09:56 +08:00
|
|
|
|
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
|
|
|
|
*/
|
1999-02-28 02:09:56 +08:00
|
|
|
label_frame_size_difference =
|
|
|
|
gdisp->cursor_label->parent->allocation.width -
|
|
|
|
gdisp->cursor_label->allocation.width;
|
|
|
|
|
1998-11-20 04:20:46 +08:00
|
|
|
gtk_widget_set_usize (gdisp->cursor_label, cursor_label_width, -1);
|
1999-02-28 02:09:56 +08:00
|
|
|
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);
|
1999-05-05 01:20:05 +08:00
|
|
|
|
|
|
|
gdisplay_update_cursor (gdisp, gdisp->cursor_x, gdisp->cursor_y);
|
1998-11-20 04:20:46 +08:00
|
|
|
}
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
void
|
|
|
|
gdisplay_remove_and_delete (GDisplay *gdisp)
|
|
|
|
{
|
|
|
|
/* remove the display from the list */
|
1998-01-29 16:03:27 +08:00
|
|
|
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));
|
1998-04-12 06:07:00 +08:00
|
|
|
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));
|
|
|
|
|
1998-04-12 06:07:00 +08:00
|
|
|
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);
|
1998-04-12 06:07:00 +08:00
|
|
|
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);
|
|
|
|
|
1998-04-12 06:07:00 +08:00
|
|
|
gimage_invalidate (gdisp->gimage, x, y, w, h, x1, y1, x2, y2);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* display the area */
|
1998-04-12 06:07:00 +08:00
|
|
|
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;
|
1999-10-05 03:26:07 +08:00
|
|
|
GList *list;
|
|
|
|
guchar *buf;
|
1999-10-05 10:16:59 +08:00
|
|
|
int bpp, bpl;
|
1999-10-05 03:26:07 +08:00
|
|
|
|
|
|
|
buf = gximage_get_data ();
|
|
|
|
bpp = gximage_get_bpp ();
|
1999-10-05 10:16:59 +08:00
|
|
|
bpl = gximage_get_bpl ();
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1998-12-06 05:48:37 +08:00
|
|
|
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);
|
|
|
|
|
1998-10-04 04:14:00 +08:00
|
|
|
if (y1 < gdisp->disp_yoffset)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1998-10-04 04:14:00 +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
|
|
|
|
1998-10-04 04:14:00 +08:00
|
|
|
y1 = gdisp->disp_yoffset;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
1998-10-04 04:14:00 +08:00
|
|
|
if (x1 < gdisp->disp_xoffset)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1998-10-04 04:14:00 +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
|
|
|
|
1998-10-04 04:14:00 +08:00
|
|
|
x1 = gdisp->disp_xoffset;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (x2 > (gdisp->disp_xoffset + sx))
|
|
|
|
{
|
1998-10-04 04:14:00 +08:00
|
|
|
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))
|
|
|
|
{
|
1998-10-04 04:14:00 +08:00
|
|
|
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)
|
|
|
|
{
|
1998-10-04 04:14:00 +08:00
|
|
|
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);
|
1999-02-07 23:16:45 +08:00
|
|
|
#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
|
1999-10-05 03:26:07 +08:00
|
|
|
|
|
|
|
list = gdisp->cd_list;
|
|
|
|
while (list)
|
|
|
|
{
|
|
|
|
ColorDisplayNode *node = (ColorDisplayNode *) list->data;
|
1999-10-05 10:16:59 +08:00
|
|
|
node->cd_convert (node->cd_ID, buf, dx, dy, bpp, bpl);
|
1999-10-05 03:26:07 +08:00
|
|
|
list = list->next;
|
|
|
|
}
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
gximage_put (gdisp->canvas->window,
|
1998-09-01 06:22:23 +08:00
|
|
|
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;
|
1998-01-22 15:02:57 +08:00
|
|
|
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)))
|
|
|
|
{
|
1998-01-22 15:02:57 +08:00
|
|
|
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))
|
|
|
|
{
|
1998-01-22 15:02:57 +08:00
|
|
|
*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
|
|
|
|
{
|
1998-01-22 15:02:57 +08:00
|
|
|
*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)
|
|
|
|
{
|
1998-12-06 05:48:37 +08:00
|
|
|
double scalex;
|
|
|
|
double scaley;
|
1997-11-25 06:05:25 +08:00
|
|
|
int offset_x, offset_y;
|
|
|
|
|
|
|
|
/* transform from image coordinates to screen coordinates */
|
1998-12-06 05:48:37 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
1998-12-06 05:48:37 +08:00
|
|
|
*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)
|
|
|
|
{
|
1998-12-06 05:48:37 +08:00
|
|
|
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 */
|
1998-12-06 05:48:37 +08:00
|
|
|
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)
|
|
|
|
{
|
1998-12-06 05:48:37 +08:00
|
|
|
*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
|
|
|
|
{
|
1998-12-06 05:48:37 +08:00
|
|
|
*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)
|
|
|
|
{
|
1998-12-06 05:48:37 +08:00
|
|
|
double scalex;
|
|
|
|
double scaley;
|
1997-11-25 06:05:25 +08:00
|
|
|
int offset_x, offset_y;
|
|
|
|
|
|
|
|
/* transform from gimp coordinates to screen coordinates */
|
1998-12-06 05:48:37 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
1998-12-06 05:48:37 +08:00
|
|
|
*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)
|
|
|
|
{
|
1998-12-06 05:48:37 +08:00
|
|
|
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 */
|
1998-12-06 05:48:37 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
1998-12-06 05:48:37 +08:00
|
|
|
*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)
|
|
|
|
{
|
1999-05-13 19:12:32 +08:00
|
|
|
if (gdisp->current_cursor != (int)cursor_type)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-05-05 17:10:35 +08:00
|
|
|
gdisp->current_cursor = (int)cursor_type;
|
1999-01-11 07:36:29 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-01-11 07:36:29 +08:00
|
|
|
/* 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
|
|
|
|
{
|
1999-06-20 21:53:15 +08:00
|
|
|
/* g_warning ("Tried to remove override-cursor from un-overridden gdisp."); */
|
1999-01-11 07:36:29 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
1999-06-21 07:29:34 +08:00
|
|
|
Layer *layer = NULL;
|
|
|
|
gint fs = FALSE;
|
|
|
|
gint aux = FALSE;
|
|
|
|
gint lm = FALSE;
|
|
|
|
gint lp = FALSE;
|
1998-04-03 19:58:04 +08:00
|
|
|
gint alpha = FALSE;
|
1999-06-21 07:29:34 +08:00
|
|
|
GimpDrawable *drawable = NULL;
|
Actually use the enum types GimpImageType, GimpImageBaseType,
* app/*.[ch]: Actually use the enum types GimpImageType,
GimpImageBaseType, LayerModeEffects, PaintApplicationMode,
BrushApplicationMode, GimpFillType and ConvertPaletteType, instead
of just int or gint. Hopefully I catched most of the places
where these should be used.
Add an enum ConvolutionType, suffix the too general constants
NORMAL, ABSOLUTE and NEGATIVE with _CONVOL. Use NORMAL_MODE
instead of NORMAL in some places (this was what was intended). Fix
some minor gccisms.
* app/apptypes.h: New file. This file contains the above
enumeration types, and some opaque struct typedefs. It was
necessary to collect these in one header that doesn't include
other headers, because when we started using the above mentioned
types in the headers, all hell broke loose because of the
spaghetti-like cross-inclusion mess between headers.
(An example: Header A includes header B, which includes header C
which includes A. B uses a type defined in A. This is not defined,
because A hasn't defined it yet at the point where it includes B,
and A included from B of course is skipped as we already are
reading A.)
1999-08-19 07:41:39 +08:00
|
|
|
GimpImageBaseType base_type = 0;
|
|
|
|
GimpImageType type = -1;
|
1999-06-21 07:29:34 +08:00
|
|
|
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-11-24 03:11:29 +08:00
|
|
|
menus_set_sensitive ("<Image>/" menu, (condition) != 0)
|
1999-06-21 07:29:34 +08:00
|
|
|
#define SET_STATE(menu,condition) \
|
1999-11-24 03:11:29 +08:00
|
|
|
menus_set_state ("<Image>/" menu, (condition) != 0)
|
1999-06-21 07:29:34 +08:00
|
|
|
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("File/Save", gdisp);
|
|
|
|
SET_SENSITIVE ("File/Save as...", gdisp);
|
|
|
|
SET_SENSITIVE ("File/Revert", gdisp);
|
|
|
|
SET_SENSITIVE ("File/Close", gdisp);
|
1999-06-21 07:29:34 +08:00
|
|
|
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("Edit", gdisp);
|
|
|
|
SET_SENSITIVE ("Edit/Buffer", gdisp);
|
1999-07-10 19:53:42 +08:00
|
|
|
if (gdisp)
|
|
|
|
{
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("Edit/Undo", undo_get_undo_name (gdisp->gimage));
|
|
|
|
SET_SENSITIVE ("Edit/Redo", undo_get_redo_name (gdisp->gimage));
|
|
|
|
SET_SENSITIVE ("Edit/Cut", lp);
|
|
|
|
SET_SENSITIVE ("Edit/Copy", lp);
|
|
|
|
SET_SENSITIVE ("Edit/Paste", lp);
|
|
|
|
SET_SENSITIVE ("Edit/Paste Into", lp);
|
|
|
|
SET_SENSITIVE ("Edit/Paste As New", lp);
|
|
|
|
SET_SENSITIVE ("Edit/Buffer/Cut Named...", lp);
|
|
|
|
SET_SENSITIVE ("Edit/Buffer/Copy Named...", lp);
|
|
|
|
SET_SENSITIVE ("Edit/Buffer/Paste Named...", lp);
|
|
|
|
SET_SENSITIVE ("Edit/Clear", lp);
|
|
|
|
SET_SENSITIVE ("Edit/Fill", lp);
|
|
|
|
SET_SENSITIVE ("Edit/Stroke", lp);
|
1999-07-10 19:53:42 +08:00
|
|
|
}
|
1999-06-21 07:29:34 +08:00
|
|
|
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("Select", gdisp && lp);
|
|
|
|
SET_SENSITIVE ("Select/Save To Channel", !fs);
|
1999-06-21 07:29:34 +08:00
|
|
|
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("View", gdisp);
|
|
|
|
SET_SENSITIVE ("View/Zoom", gdisp);
|
1999-07-07 21:32:58 +08:00
|
|
|
if (gdisp)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_STATE ("View/Toggle Selection", !gdisp->select->hidden);
|
|
|
|
SET_STATE ("View/Toggle Rulers",
|
1999-06-21 07:29:34 +08:00
|
|
|
GTK_WIDGET_VISIBLE (gdisp->origin) ? 1 : 0);
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_STATE ("View/Toggle Guides", gdisp->draw_guides);
|
|
|
|
SET_STATE ("View/Snap To Guides", gdisp->snap_to_guides);
|
|
|
|
SET_STATE ("View/Toggle Statusbar",
|
1999-06-21 07:29:34 +08:00
|
|
|
GTK_WIDGET_VISIBLE (gdisp->statusarea) ? 1 : 0);
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_STATE ("View/Dot for dot", gdisp->dot_for_dot);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("Image", gdisp);
|
|
|
|
SET_SENSITIVE ("Image/Mode", gdisp);
|
|
|
|
SET_SENSITIVE ("Image/Colors", gdisp);
|
|
|
|
SET_SENSITIVE ("Image/Colors/Auto", gdisp);
|
|
|
|
SET_SENSITIVE ("Image/Alpha", gdisp);
|
|
|
|
SET_SENSITIVE ("Image/Transforms", gdisp);
|
|
|
|
SET_SENSITIVE ("Image/Transforms/Rotate", gdisp);
|
1999-07-07 21:32:58 +08:00
|
|
|
if (gdisp)
|
1999-06-21 07:29:34 +08:00
|
|
|
{
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("Image/Mode/RGB", (base_type != RGB));
|
|
|
|
SET_SENSITIVE ("Image/Mode/Grayscale", (base_type != GRAY));
|
|
|
|
SET_SENSITIVE ("Image/Mode/Indexed...", (base_type != INDEXED));
|
|
|
|
SET_SENSITIVE ("Image/Histogram...", lp);
|
|
|
|
|
|
|
|
SET_SENSITIVE ("Image/Colors", lp);
|
|
|
|
SET_SENSITIVE ("Image/Colors/Color Balance...", (base_type == RGB));
|
|
|
|
SET_SENSITIVE ("Image/Colors/Hue-Saturation...", (base_type == RGB));
|
|
|
|
SET_SENSITIVE ("Image/Colors/Brightness-Contrast...", (base_type != INDEXED));
|
|
|
|
SET_SENSITIVE ("Image/Colors/Threshold...", (base_type != INDEXED));
|
|
|
|
SET_SENSITIVE ("Image/Colors/Levels...", (base_type != INDEXED));
|
|
|
|
SET_SENSITIVE ("Image/Colors/Curves...", (base_type != INDEXED));
|
|
|
|
SET_SENSITIVE ("Image/Colors/Desaturate", (base_type == RGB));
|
|
|
|
SET_SENSITIVE ("Image/Colors/Posterize...", (base_type != INDEXED));
|
|
|
|
SET_SENSITIVE ("Image/Colors/Invert", (base_type != INDEXED));
|
|
|
|
SET_SENSITIVE ("Image/Colors/Auto/Equalize", (base_type != INDEXED));
|
|
|
|
|
|
|
|
SET_SENSITIVE ("Image/Alpha/Add Alpha Channel",
|
1999-06-21 07:29:34 +08:00
|
|
|
!fs && !aux && lp && !lm && !alpha);
|
1999-06-22 06:12:07 +08:00
|
|
|
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("Image/Transforms/Offset...", lp);
|
1999-06-21 07:29:34 +08:00
|
|
|
}
|
|
|
|
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("Layers/Stack", gdisp);
|
|
|
|
SET_SENSITIVE ("Layers/Rotate", gdisp);
|
1999-07-07 21:32:58 +08:00
|
|
|
if (gdisp)
|
1999-06-21 07:29:34 +08:00
|
|
|
{
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("Layers/Stack/Previous Layer",
|
1999-06-21 07:29:34 +08:00
|
|
|
!fs && !aux && lp && lind > 0);
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("Layers/Stack/Next Layer",
|
1999-06-21 07:29:34 +08:00
|
|
|
!fs && !aux && lp && lind < (lnum - 1));
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("Layers/Stack/Raise Layer",
|
1999-06-21 07:29:34 +08:00
|
|
|
!fs && !aux && lp && alpha && lind > 0);
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("Layers/Stack/Lower Layer",
|
1999-06-21 07:29:34 +08:00
|
|
|
!fs && !aux && lp && alpha && lind < (lnum - 1));
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("Layers/Stack/Layer to Top",
|
1999-06-21 07:29:34 +08:00
|
|
|
!fs && !aux && lp && alpha && lind > 0);
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("Layers/Stack/Layer to Bottom",
|
1999-06-21 07:29:34 +08:00
|
|
|
!fs && !aux && lp && alpha && lind < (lnum - 1));
|
|
|
|
}
|
|
|
|
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("Layers/Anchor Layer", gdisp && fs && !aux && lp);
|
|
|
|
SET_SENSITIVE ("Layers/Merge Visible Layers...", gdisp && !fs && !aux && lp);
|
|
|
|
SET_SENSITIVE ("Layers/Flatten Image", gdisp && !fs && !aux && lp);
|
|
|
|
SET_SENSITIVE ("Layers/Alpha To Selection", gdisp && !aux && lp && alpha);
|
|
|
|
SET_SENSITIVE ("Layers/Mask To Selection", gdisp && !aux && lm && lp);
|
|
|
|
SET_SENSITIVE ("Layers/Add Alpha Channel",
|
1999-06-21 07:29:34 +08:00
|
|
|
gdisp && !fs && !aux && lp && !lm && !alpha);
|
|
|
|
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("Filters", gdisp && lp);
|
1999-07-07 21:32:58 +08:00
|
|
|
|
1999-11-24 03:11:29 +08:00
|
|
|
SET_SENSITIVE ("Script-Fu", gdisp && lp);
|
1999-06-21 07:29:34 +08:00
|
|
|
|
|
|
|
#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;
|
|
|
|
|
1998-03-16 19:13:24 +08:00
|
|
|
gdisplay_transform_coords (gdisp, guide->position,
|
|
|
|
guide->position, &x, &y, FALSE);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
switch (guide->orientation)
|
|
|
|
{
|
1999-07-29 07:00:08 +08:00
|
|
|
case ORIENTATION_HORIZONTAL:
|
1998-03-16 19:13:24 +08:00
|
|
|
gdisplay_expose_area (gdisp, 0, y, gdisp->disp_width, 1);
|
1997-11-25 06:05:25 +08:00
|
|
|
break;
|
1999-07-29 07:00:08 +08:00
|
|
|
case ORIENTATION_VERTICAL:
|
1998-03-16 19:13:24 +08:00
|
|
|
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 ()
|
|
|
|
{
|
1999-06-26 19:16:47 +08:00
|
|
|
GdkEvent *event;
|
|
|
|
|
|
|
|
event = gtk_get_current_event ();
|
|
|
|
if (event != NULL)
|
|
|
|
{
|
|
|
|
gdk_event_free (event);
|
|
|
|
}
|
|
|
|
|
1999-06-21 07:29:34 +08:00
|
|
|
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;
|
1998-01-29 16:03:27 +08:00
|
|
|
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;
|
|
|
|
|
1998-01-29 16:03:27 +08:00
|
|
|
list = g_slist_next (list);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-02-07 02:31:33 +08:00
|
|
|
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 */
|
1999-06-21 07:29:34 +08:00
|
|
|
context_id =
|
|
|
|
gtk_statusbar_get_context_id (GTK_STATUSBAR (gdisp->statusbar), "title");
|
1999-02-07 02:31:33 +08:00
|
|
|
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
|
1998-06-29 08:24:44 +08:00
|
|
|
gdisplays_update_title (GimpImage *gimage)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
GDisplay *gdisp;
|
1998-01-29 16:03:27 +08:00
|
|
|
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;
|
1998-06-29 08:24:44 +08:00
|
|
|
if (gdisp->gimage == gimage)
|
1999-02-07 02:31:33 +08:00
|
|
|
gdisplay_update_title (gdisp);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1998-01-29 16:03:27 +08:00
|
|
|
list = g_slist_next (list);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-12-14 02:52:34 +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)
|
1999-05-05 01:20:05 +08:00
|
|
|
gdisplay_resize_cursor_label (gdisp);
|
1998-12-14 02:52:34 +08:00
|
|
|
|
|
|
|
list = g_slist_next (list);
|
|
|
|
}
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
void
|
1999-10-14 07:07:45 +08:00
|
|
|
gdisplays_update_area (GimpImage *gimage,
|
|
|
|
int x,
|
|
|
|
int y,
|
|
|
|
int w,
|
|
|
|
int h)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
GDisplay *gdisp;
|
1998-01-29 16:03:27 +08:00
|
|
|
GSList *list = display_list;
|
1998-07-05 08:03:06 +08:00
|
|
|
/* int x1, y1, x2, y2; */
|
1998-04-15 14:01:25 +08:00
|
|
|
/* int count = 0; */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* traverse the linked list of displays */
|
|
|
|
while (list)
|
|
|
|
{
|
|
|
|
gdisp = (GDisplay *) list->data;
|
1998-06-29 08:24:44 +08:00
|
|
|
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. */
|
1998-04-15 14:01:25 +08:00
|
|
|
|
|
|
|
/* 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));
|
|
|
|
}
|
1998-04-15 14:01:25 +08:00
|
|
|
*/
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1998-04-15 14:01:25 +08:00
|
|
|
gdisplay_add_update_area (gdisp, x, y, w, h);
|
1998-06-30 23:31:32 +08:00
|
|
|
/* Seems like this isn't needed, it's done in
|
|
|
|
gdisplay_flush. -la
|
1998-04-15 14:01:25 +08:00
|
|
|
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));
|
1998-06-30 23:31:32 +08:00
|
|
|
*/
|
1998-04-15 14:01:25 +08:00
|
|
|
}
|
1998-01-29 16:03:27 +08:00
|
|
|
list = g_slist_next (list);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
1999-10-14 07:07:45 +08:00
|
|
|
gdisplays_expose_guides (GimpImage *gimage)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
GDisplay *gdisp;
|
|
|
|
GList *tmp_list;
|
1998-01-29 16:03:27 +08:00
|
|
|
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;
|
1998-06-29 08:24:44 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-01-29 16:03:27 +08:00
|
|
|
list = g_slist_next (list);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
1999-10-14 07:07:45 +08:00
|
|
|
gdisplays_expose_guide (GimpImage *gimage,
|
|
|
|
Guide *guide)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
GDisplay *gdisp;
|
1998-01-29 16:03:27 +08:00
|
|
|
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;
|
1998-06-29 08:24:44 +08:00
|
|
|
if (gdisp->gimage == gimage)
|
1999-10-14 07:07:45 +08:00
|
|
|
{
|
|
|
|
gdisplay_expose_guide (gdisp, guide);
|
|
|
|
}
|
|
|
|
|
1998-01-29 16:03:27 +08:00
|
|
|
list = g_slist_next (list);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
1998-06-29 08:24:44 +08:00
|
|
|
gdisplays_update_full (GimpImage* gimage)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
GDisplay *gdisp;
|
1998-01-29 16:03:27 +08:00
|
|
|
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;
|
1998-06-29 08:24:44 +08:00
|
|
|
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++;
|
|
|
|
}
|
|
|
|
|
1998-01-29 16:03:27 +08:00
|
|
|
list = g_slist_next (list);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
1999-10-14 07:07:45 +08:00
|
|
|
gdisplays_shrink_wrap (GimpImage *gimage)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
GDisplay *gdisp;
|
1998-01-29 16:03:27 +08:00
|
|
|
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;
|
1998-06-29 08:24:44 +08:00
|
|
|
if (gdisp->gimage == gimage)
|
1997-11-25 06:05:25 +08:00
|
|
|
shrink_wrap_display (gdisp);
|
|
|
|
|
1998-01-29 16:03:27 +08:00
|
|
|
list = g_slist_next (list);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
comment typo fix, plus add %D* to default image-title-format string, so
Fri Oct 1 12:46:12 1999 Austin Donnelly <austin@gimp.org>
* gimprc.in: comment typo fix, plus add %D* to default
image-title-format string, so people get a '*' in the titlebar
if their image is dirty.
* app/fileops.c: initialise filename before using it.
* app/gdisplay.c: empty parameter list () is K&R - should be
stronger (void) in ANSI C.
* app/gimpdrawable.c: gimp_drawable_{dirty,clean} functions
removed - no one uses them anyway. Parasite undo type is
proper parasite undo type, not MISC_UNDO.
* app/gimpdrawableP.h: drawable dirty bit removed.
* app/gimpimage.c: don't change the resolution if there's no
difference from the old one. Call gdisplay_shrink_wrap() to
re-calculate scale factors and refresh the display on
resolution change. Layer undo doesn't have sub-types
anymore, uses main UndoType instead.
* app/layer.h: Remove LayerUndoType
* app/qmask.c: fix qmask undo so it actually works.
* app/undo.h: new types for undo_push_layer{,_mask} and
undo_push_qmask.
* app/undo.c: change way group boundaries are represented:
each Undo has a group_boundary boolean set to TRUE if this is
the start or the end of a group, and the type of the Undo is
the group's type. Within a group, each Undo keeps its own
type. This allows pop funcs and free funcs to do
type-specific things (eg needed by layer and channel stuff).
Don't maintain per-drawable dirty flags anymore. Floating
sel to layer and layer rename now uses meaningful undo types.
* app/undo_types.h: more specific undo types:
LAYER_{ADD,REMOVE}_UNDO, LAYER_MASK_{ADD,REMOVE}_UNDO,
LAYER_RENAME_UNDO, and PARASITE_{ATTACH,DETACH}_UNDO.
* app/undo_history.c: oops - undo stack was being placed into gtk
list in wrong order.
* app/edit_selection.c: push more descriptive LAYER_DISPLACE_UNDO
rather than MISC_UNDO.
* app/layers_dialog.c: better tagging of undo types
1999-10-02 02:43:24 +08:00
|
|
|
gdisplays_expose_full (void)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
GDisplay *gdisp;
|
1998-01-29 16:03:27 +08:00
|
|
|
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);
|
1998-01-29 16:03:27 +08:00
|
|
|
list = g_slist_next (list);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-09-05 06:27:20 +08:00
|
|
|
void
|
comment typo fix, plus add %D* to default image-title-format string, so
Fri Oct 1 12:46:12 1999 Austin Donnelly <austin@gimp.org>
* gimprc.in: comment typo fix, plus add %D* to default
image-title-format string, so people get a '*' in the titlebar
if their image is dirty.
* app/fileops.c: initialise filename before using it.
* app/gdisplay.c: empty parameter list () is K&R - should be
stronger (void) in ANSI C.
* app/gimpdrawable.c: gimp_drawable_{dirty,clean} functions
removed - no one uses them anyway. Parasite undo type is
proper parasite undo type, not MISC_UNDO.
* app/gimpdrawableP.h: drawable dirty bit removed.
* app/gimpimage.c: don't change the resolution if there's no
difference from the old one. Call gdisplay_shrink_wrap() to
re-calculate scale factors and refresh the display on
resolution change. Layer undo doesn't have sub-types
anymore, uses main UndoType instead.
* app/layer.h: Remove LayerUndoType
* app/qmask.c: fix qmask undo so it actually works.
* app/undo.h: new types for undo_push_layer{,_mask} and
undo_push_qmask.
* app/undo.c: change way group boundaries are represented:
each Undo has a group_boundary boolean set to TRUE if this is
the start or the end of a group, and the type of the Undo is
the group's type. Within a group, each Undo keeps its own
type. This allows pop funcs and free funcs to do
type-specific things (eg needed by layer and channel stuff).
Don't maintain per-drawable dirty flags anymore. Floating
sel to layer and layer rename now uses meaningful undo types.
* app/undo_types.h: more specific undo types:
LAYER_{ADD,REMOVE}_UNDO, LAYER_MASK_{ADD,REMOVE}_UNDO,
LAYER_RENAME_UNDO, and PARASITE_{ATTACH,DETACH}_UNDO.
* app/undo_history.c: oops - undo stack was being placed into gtk
list in wrong order.
* app/edit_selection.c: push more descriptive LAYER_DISPLACE_UNDO
rather than MISC_UNDO.
* app/layers_dialog.c: better tagging of undo types
1999-10-02 02:43:24 +08:00
|
|
|
gdisplays_nav_preview_resized (void)
|
1999-09-05 06:27:20 +08:00
|
|
|
{
|
|
|
|
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
|
1998-06-29 08:24:44 +08:00
|
|
|
gdisplays_selection_visibility (GimpImage* gimage,
|
1997-11-25 06:05:25 +08:00
|
|
|
SelectionControl function)
|
|
|
|
{
|
|
|
|
GDisplay *gdisp;
|
1998-01-29 16:03:27 +08:00
|
|
|
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;
|
1998-06-29 08:24:44 +08:00
|
|
|
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++;
|
|
|
|
}
|
|
|
|
|
1998-01-29 16:03:27 +08:00
|
|
|
list = g_slist_next (list);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
comment typo fix, plus add %D* to default image-title-format string, so
Fri Oct 1 12:46:12 1999 Austin Donnelly <austin@gimp.org>
* gimprc.in: comment typo fix, plus add %D* to default
image-title-format string, so people get a '*' in the titlebar
if their image is dirty.
* app/fileops.c: initialise filename before using it.
* app/gdisplay.c: empty parameter list () is K&R - should be
stronger (void) in ANSI C.
* app/gimpdrawable.c: gimp_drawable_{dirty,clean} functions
removed - no one uses them anyway. Parasite undo type is
proper parasite undo type, not MISC_UNDO.
* app/gimpdrawableP.h: drawable dirty bit removed.
* app/gimpimage.c: don't change the resolution if there's no
difference from the old one. Call gdisplay_shrink_wrap() to
re-calculate scale factors and refresh the display on
resolution change. Layer undo doesn't have sub-types
anymore, uses main UndoType instead.
* app/layer.h: Remove LayerUndoType
* app/qmask.c: fix qmask undo so it actually works.
* app/undo.h: new types for undo_push_layer{,_mask} and
undo_push_qmask.
* app/undo.c: change way group boundaries are represented:
each Undo has a group_boundary boolean set to TRUE if this is
the start or the end of a group, and the type of the Undo is
the group's type. Within a group, each Undo keeps its own
type. This allows pop funcs and free funcs to do
type-specific things (eg needed by layer and channel stuff).
Don't maintain per-drawable dirty flags anymore. Floating
sel to layer and layer rename now uses meaningful undo types.
* app/undo_types.h: more specific undo types:
LAYER_{ADD,REMOVE}_UNDO, LAYER_MASK_{ADD,REMOVE}_UNDO,
LAYER_RENAME_UNDO, and PARASITE_{ATTACH,DETACH}_UNDO.
* app/undo_history.c: oops - undo stack was being placed into gtk
list in wrong order.
* app/edit_selection.c: push more descriptive LAYER_DISPLACE_UNDO
rather than MISC_UNDO.
* app/layers_dialog.c: better tagging of undo types
1999-10-02 02:43:24 +08:00
|
|
|
gdisplays_dirty (void)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
int dirty = 0;
|
1998-01-29 16:03:27 +08:00
|
|
|
GSList *list = display_list;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* traverse the linked list of displays */
|
|
|
|
while (list)
|
|
|
|
{
|
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;
|
1998-01-29 16:03:27 +08:00
|
|
|
list = g_slist_next (list);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return dirty;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
comment typo fix, plus add %D* to default image-title-format string, so
Fri Oct 1 12:46:12 1999 Austin Donnelly <austin@gimp.org>
* gimprc.in: comment typo fix, plus add %D* to default
image-title-format string, so people get a '*' in the titlebar
if their image is dirty.
* app/fileops.c: initialise filename before using it.
* app/gdisplay.c: empty parameter list () is K&R - should be
stronger (void) in ANSI C.
* app/gimpdrawable.c: gimp_drawable_{dirty,clean} functions
removed - no one uses them anyway. Parasite undo type is
proper parasite undo type, not MISC_UNDO.
* app/gimpdrawableP.h: drawable dirty bit removed.
* app/gimpimage.c: don't change the resolution if there's no
difference from the old one. Call gdisplay_shrink_wrap() to
re-calculate scale factors and refresh the display on
resolution change. Layer undo doesn't have sub-types
anymore, uses main UndoType instead.
* app/layer.h: Remove LayerUndoType
* app/qmask.c: fix qmask undo so it actually works.
* app/undo.h: new types for undo_push_layer{,_mask} and
undo_push_qmask.
* app/undo.c: change way group boundaries are represented:
each Undo has a group_boundary boolean set to TRUE if this is
the start or the end of a group, and the type of the Undo is
the group's type. Within a group, each Undo keeps its own
type. This allows pop funcs and free funcs to do
type-specific things (eg needed by layer and channel stuff).
Don't maintain per-drawable dirty flags anymore. Floating
sel to layer and layer rename now uses meaningful undo types.
* app/undo_types.h: more specific undo types:
LAYER_{ADD,REMOVE}_UNDO, LAYER_MASK_{ADD,REMOVE}_UNDO,
LAYER_RENAME_UNDO, and PARASITE_{ATTACH,DETACH}_UNDO.
* app/undo_history.c: oops - undo stack was being placed into gtk
list in wrong order.
* app/edit_selection.c: push more descriptive LAYER_DISPLACE_UNDO
rather than MISC_UNDO.
* app/layers_dialog.c: better tagging of undo types
1999-10-02 02:43:24 +08:00
|
|
|
gdisplays_delete (void)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1998-01-29 16:03:27 +08:00
|
|
|
GSList *list = display_list;
|
1998-02-14 23:30:31 +08:00
|
|
|
GDisplay *gdisp;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* traverse the linked list of displays */
|
|
|
|
while (list)
|
|
|
|
{
|
1998-02-14 23:30:31 +08:00
|
|
|
gdisp = (GDisplay *) list->data;
|
1998-01-29 16:03:27 +08:00
|
|
|
list = g_slist_next (list);
|
1998-02-14 23:30:31 +08:00
|
|
|
gtk_widget_destroy (gdisp->shell);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* free up linked list data */
|
1998-01-29 16:03:27 +08:00
|
|
|
g_slist_free (display_list);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
1999-06-20 21:53:15 +08:00
|
|
|
|
1999-03-06 07:50:24 +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
|
|
|
|
1998-10-02 00:22:28 +08:00
|
|
|
static void
|
|
|
|
gdisplays_flush_whenever (gboolean now)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
static int flushing = FALSE;
|
1998-01-29 16:03:27 +08:00
|
|
|
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)
|
1998-10-01 19:53:20 +08:00
|
|
|
{
|
1999-09-23 19:49:16 +08:00
|
|
|
g_warning ("gdisplays_flush() called recursively.");
|
1998-10-01 19:53:20 +08:00
|
|
|
return;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
flushing = TRUE;
|
|
|
|
|
|
|
|
/* traverse the linked list of displays */
|
|
|
|
while (list)
|
|
|
|
{
|
1998-10-02 00:22:28 +08:00
|
|
|
gdisplay_flush_whenever ((GDisplay *) list->data, now);
|
1998-01-29 16:03:27 +08:00
|
|
|
list = g_slist_next (list);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
1999-06-07 01:26:51 +08:00
|
|
|
/* for convenience, we call the L&C flush here */
|
|
|
|
lc_dialog_flush ();
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
flushing = FALSE;
|
|
|
|
}
|
|
|
|
|
1998-09-27 04:07:46 +08:00
|
|
|
void
|
1998-10-02 00:22:28 +08:00
|
|
|
gdisplays_flush (void)
|
1998-09-27 04:07:46 +08:00
|
|
|
{
|
1998-10-02 00:22:28 +08:00
|
|
|
gdisplays_flush_whenever (FALSE);
|
1998-09-27 04:07:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
1998-10-02 00:22:28 +08:00
|
|
|
gdisplays_flush_now (void)
|
1998-09-27 04:07:46 +08:00
|
|
|
{
|
1998-10-02 00:22:28 +08:00
|
|
|
gdisplays_flush_whenever (TRUE);
|
1998-09-27 04:07:46 +08:00
|
|
|
}
|
|
|
|
|
1998-10-02 00:22:28 +08:00
|
|
|
static guint
|
|
|
|
gdisplay_hash (GDisplay *display)
|
1998-09-27 04:07:46 +08:00
|
|
|
{
|
1998-10-02 00:22:28 +08:00
|
|
|
return (gulong) display;
|
1998-09-27 04:07:46 +08:00
|
|
|
}
|
1998-10-01 19:53:20 +08:00
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
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);
|
|
|
|
|
1999-01-24 02:49:52 +08:00
|
|
|
gdisplays_update_title (gimage);
|
|
|
|
|
1999-01-12 09:31:49 +08:00
|
|
|
gdisplay_expose_full (gdisp);
|
|
|
|
gdisplay_flush (gdisp);
|
|
|
|
}
|
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);
|
|
|
|
}
|