home *** CD-ROM | disk | FTP | other *** search
- /* The GIMP -- an image manipulation program
- * Copyright (C) 1995 Spencer Kimball and Peter Mattis
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
- #include "config.h"
-
- #include <stdlib.h>
-
- #include <gtk/gtk.h>
- #include <gdk/gdkkeysyms.h>
-
- #include "apptypes.h"
-
- #include "appenv.h"
- #include "cursorutil.h"
- #include "dialog_handler.h"
- #include "info_dialog.h"
- #include "info_window.h"
- #include "gdisplay.h"
- #include "gimpcontext.h"
- #include "gimppreviewcache.h"
- #include "gimpset.h"
- #include "gimprc.h"
- #include "gimpui.h"
- #include "gximage.h"
- #include "nav_window.h"
- #include "scroll.h"
- #include "scale.h"
-
- #include "libgimp/gimpunit.h"
-
- #include "libgimp/gimpintl.h"
-
- #include "pixmaps/zoom_in.xpm"
- #include "pixmaps/zoom_out.xpm"
-
-
- #define MAX_BUF 256
-
- #define PREVIEW_MASK GDK_EXPOSURE_MASK | \
- GDK_BUTTON_PRESS_MASK | \
- GDK_KEY_PRESS_MASK | \
- GDK_KEY_RELEASE_MASK | \
- GDK_POINTER_MOTION_MASK
-
-
- /* Navigation preview sizes */
- #define NAV_PREVIEW_WIDTH 112
- #define NAV_PREVIEW_HEIGHT 112
- #define BORDER_PEN_WIDTH 3
-
- #define MAX_SCALE_BUF 20
-
- typedef enum
- {
- NAV_WINDOW,
- NAV_POPUP
- } NavWinType;
-
- /* Timeout before preview is updated */
- #define PREVIEW_UPDATE_TIMEOUT 1100
-
- typedef struct _NavWinData NavWinData;
- struct _NavWinData
- {
- NavWinType ptype;
- gboolean showingPreview;
- gboolean installedDirtyTimer;
- InfoDialog *info_win;
- GtkWidget *previewBox;
- GtkWidget *previewAlign;
- GtkWidget *zoom_label;
- GtkObject *zoom_adjustment;
- GtkWidget *preview;
- void *gdisp_ptr; /* I'm not happy 'bout this one */
- GdkGC *gc;
- gint dispx; /* x pos of top left corner of display area */
- gint dispy; /* y pos of top left corner of display area */
- gint dispwidth; /* width of display area */
- gint dispheight; /* height of display area */
- gint sig_hand_id;
- gboolean sq_grabbed; /* In the process of moving the preview square */
- gint motion_offsetx;
- gint motion_offsety;
- gint pwidth; /* real preview width */
- gint pheight; /* real preview height */
- gint imagewidth; /* width of the real image */
- gint imageheight; /* height of real image */
- gdouble ratio;
- gboolean block_window_marker; /* Block redraws of window marker */
- gint nav_preview_width;
- gint nav_preview_height;
- gboolean block_adj_sig;
- gboolean frozen; /* Has the dialog been frozen ? */
- guint timer_id;
- };
-
-
- static gint nav_window_preview_events (GtkWidget *widget,
- GdkEvent *event,
- gpointer data);
- static gint nav_window_expose_events (GtkWidget *widget,
- GdkEvent *event,
- gpointer data);
- static void nav_window_update_preview (NavWinData *iwd);
- static void nav_window_update_preview_blank (NavWinData *iwd);
- static void destroy_preview_widget (NavWinData *iwd);
- static void create_preview_widget (NavWinData *iwd);
- static void nav_window_draw_sqr (NavWinData *iwd,
- gboolean undraw,
- gint x,
- gint y,
- gint w,
- gint h);
- static void set_size_data (NavWinData *iwd);
- static gint nav_preview_update_do_timer (NavWinData *iwd);
-
-
- static void
- nav_window_destroy_callback (GtkWidget *widget,
- gpointer client_data)
- {
- InfoDialog *info_win;
-
- info_win = (InfoDialog *)client_data;
- dialog_unregister(info_win->shell);
- }
-
- static void
- nav_window_close_callback (GtkWidget *widget,
- gpointer client_data)
- {
- InfoDialog *info_win;
- NavWinData *iwd;
-
- info_win = (InfoDialog *)client_data;
- iwd = (NavWinData *)info_win->user_data;
-
- iwd->showingPreview = FALSE;
- info_dialog_popdown ((InfoDialog *) client_data);
- }
-
- static void
- nav_window_disp_area (NavWinData *iwd,
- GDisplay *gdisp)
- {
- GimpImage *gimage;
- gint newwidth;
- gint newheight;
- gdouble xratio;
- gdouble yratio; /* Screen res ratio */
- gboolean need_update = FALSE;
-
- /* Calculate preview size */
- gimage = gdisp->gimage;
-
- xratio = SCALEFACTOR_X (gdisp);
- yratio = SCALEFACTOR_Y (gdisp);
-
- iwd->dispx = gdisp->offset_x * iwd->ratio / xratio + 0.5;
- iwd->dispy = gdisp->offset_y * iwd->ratio/yratio + 0.5;
- iwd->dispwidth = (gdisp->disp_width * iwd->ratio) / xratio + 0.5;
- iwd->dispheight = (gdisp->disp_height * iwd->ratio) / yratio + 0.5;
-
- newwidth = gimage->width;
- newheight = gimage->height;
-
- if (!gdisp->dot_for_dot)
- {
- newwidth = (newwidth *
- gdisp->gimage->yresolution) / gdisp->gimage->xresolution;
- iwd->dispx = ((gdisp->offset_x *
- gdisp->gimage->yresolution * iwd->ratio) /
- (gdisp->gimage->xresolution * xratio)) + 0.5; /*here*/
- iwd->dispwidth = ((gdisp->disp_width *
- gdisp->gimage->yresolution * iwd->ratio) /
- (gdisp->gimage->xresolution * xratio)) + 0.5; /*here*/
- }
-
- if ((iwd->imagewidth > 0 && newwidth != iwd->imagewidth) ||
- (iwd->imageheight > 0 && newheight != iwd->imageheight))
- {
- /* Must change the preview size */
- if (iwd->ptype != NAV_POPUP)
- {
- gtk_window_set_focus (GTK_WINDOW (iwd->info_win->shell), NULL);
- }
- destroy_preview_widget (iwd);
- create_preview_widget (iwd);
- need_update = TRUE;
- }
-
- iwd->imagewidth = newwidth;
- iwd->imageheight = newheight;
-
- /* Normalise */
- iwd->dispwidth = MAX (iwd->dispwidth, 2);
- iwd->dispheight = MAX (iwd->dispheight, 2);
-
- iwd->dispwidth = MIN (iwd->dispwidth, iwd->pwidth /* - BORDER_PEN_WIDTH */);
- iwd->dispheight = MIN (iwd->dispheight, iwd->pheight /* - BORDER_PEN_WIDTH */);
-
- if (need_update)
- {
- gtk_widget_hide (iwd->previewAlign);
- nav_window_update_preview_blank (iwd);
- gtk_widget_show (iwd->preview);
- gtk_widget_draw (iwd->preview, NULL);
- gtk_widget_show (iwd->previewAlign);
- nav_window_draw_sqr (iwd, FALSE,
- iwd->dispx, iwd->dispy,
- iwd->dispwidth, iwd->dispheight);
- if (iwd->ptype != NAV_POPUP)
- {
- gtk_window_set_focus (GTK_WINDOW (iwd->info_win->shell),
- iwd->preview);
- iwd->timer_id =
- gtk_timeout_add (PREVIEW_UPDATE_TIMEOUT,
- (GtkFunction) nav_preview_update_do_timer,
- (gpointer) iwd);
- }
- else
- {
- nav_window_update_preview (iwd);
- gtk_widget_draw (iwd->preview, NULL);
- }
- }
- }
-
- static void
- nav_window_draw_sqr (NavWinData *iwd,
- gboolean undraw,
- gint x,
- gint y,
- gint w,
- gint h)
- {
- GDisplay *gdisp;
-
- gdisp = (GDisplay *) iwd->gdisp_ptr;
-
- gdk_gc_set_function (iwd->gc, GDK_INVERT);
-
- if (undraw)
- {
- if (iwd->dispx != 0 || iwd->dispy != 0 ||
- iwd->pwidth != iwd->dispwidth || iwd->pheight != iwd->dispheight)
- {
- /* first undraw from last co-ords */
- gdk_draw_rectangle (iwd->preview->window, iwd->gc, FALSE,
- iwd->dispx, iwd->dispy,
- iwd->dispwidth - BORDER_PEN_WIDTH + 1,
- iwd->dispheight - BORDER_PEN_WIDTH + 1);
- }
- }
-
- if (x != 0 || y != 0 ||
- w != iwd->pwidth || h != iwd->pheight)
- {
- gdk_draw_rectangle (iwd->preview->window, iwd->gc, FALSE,
- x, y,
- w - BORDER_PEN_WIDTH + 1,
- h - BORDER_PEN_WIDTH + 1);
- }
-
- iwd->dispx = x;
- iwd->dispy = y;
- iwd->dispwidth = w;
- iwd->dispheight = h;
- }
-
- static void
- destroy_preview_widget (NavWinData *iwd)
- {
- if(!iwd->preview)
- return;
-
- gtk_widget_hide(iwd->previewBox);
- gtk_widget_destroy(iwd->previewBox);
- iwd->previewBox = NULL;
- iwd->preview = NULL;
- }
-
- static void
- set_size_data (NavWinData *iwd)
- {
- gint sel_width;
- gint sel_height;
- gint pwidth;
- gint pheight;
- GDisplay *gdisp;
- GimpImage *gimage;
-
- gdisp = (GDisplay *)(iwd->gdisp_ptr);
- gimage = gdisp->gimage;
-
- sel_width = gimage->width;
- sel_height = gimage->height;
-
- if (!gdisp->dot_for_dot)
- sel_width =
- (sel_width * gdisp->gimage->yresolution) / gdisp->gimage->xresolution;
-
- if (sel_width > sel_height)
- {
- pwidth = iwd->nav_preview_width;
- /* pheight = sel_height * pwidth / sel_width; */
- /*iwd->ratio = MIN (1.0, (gdouble) pwidth / (gdouble) sel_width);*/
- iwd->ratio = (gdouble) pwidth / (gdouble) sel_width;
- }
- else
- {
- pheight = iwd->nav_preview_height;
- /* pwidth = sel_width * pheight / sel_height; */
- /*iwd->ratio = MIN (1.0, (gdouble) pheight / (gdouble) sel_height);*/
- iwd->ratio = (gdouble) pheight / (gdouble) sel_height;
- }
-
- pwidth = sel_width * iwd->ratio + 0.5;
- pheight = sel_height * iwd->ratio + 0.5;
-
- iwd->pwidth = pwidth;
- iwd->pheight = pheight;
- }
-
- static void
- create_preview_widget (NavWinData *iwd)
- {
- GtkWidget *hbox;
- GtkWidget *image;
- GtkWidget *frame;
- GDisplay *gdisp;
-
- gdisp = (GDisplay *)(iwd->gdisp_ptr);
-
- hbox = gtk_hbox_new (FALSE,0);
- iwd->previewBox = hbox;
- gtk_widget_show (hbox);
- gtk_container_add (GTK_CONTAINER (iwd->previewAlign), hbox);
-
- image = gtk_preview_new (GTK_PREVIEW_COLOR);
- gtk_widget_set_events (GTK_WIDGET(image), PREVIEW_MASK);
- iwd->preview = image;
- gtk_widget_show (image);
-
- gtk_preview_set_dither (GTK_PREVIEW (image), GDK_RGB_DITHER_MAX);
-
- set_size_data (iwd);
-
- gtk_preview_size (GTK_PREVIEW (iwd->preview),
- iwd->pwidth,
- iwd->pheight);
-
- gtk_widget_set_usize (iwd->preview,
- iwd->pwidth,
- iwd->pheight);
-
- frame = gtk_frame_new(NULL);
- gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
- gtk_container_add (GTK_CONTAINER (iwd->previewBox), frame);
- gtk_container_add (GTK_CONTAINER (frame), iwd->preview);
- gtk_widget_show (frame);
-
- iwd->sig_hand_id =
- gtk_signal_connect_after (GTK_OBJECT (image), "expose_event",
- (GtkSignalFunc) nav_window_expose_events,
- iwd);
-
- gtk_signal_connect (GTK_OBJECT (image), "event",
- (GtkSignalFunc) nav_window_preview_events,
- iwd);
-
- /* gtk_signal_connect (GTK_OBJECT (image), "size_allocate", */
- /* (GtkSignalFunc) nav_window_preview_resized, */
- /* iwd); */
-
- GTK_WIDGET_SET_FLAGS (image, GTK_CAN_FOCUS);
- }
-
- static void
- update_real_view (NavWinData *iwd,
- gint tx,
- gint ty)
- {
- GDisplay *gdisp;
- gdouble xratio;
- gdouble yratio;
- gint xoffset;
- gint yoffset;
- gint xpnt;
- gint ypnt;
-
- gdisp = (GDisplay *) iwd->gdisp_ptr;
-
- xratio = SCALEFACTOR_X (gdisp);
- yratio = SCALEFACTOR_Y (gdisp);
-
- if ((tx + iwd->dispwidth) >= iwd->pwidth)
- {
- tx = iwd->pwidth; /* Actually should be less...
- * but bound check will save us.
- */
- }
-
- xpnt = (gint) (((gdouble) (tx) * xratio) / iwd->ratio + 0.5);
-
- if ((ty + iwd->dispheight) >= iwd->pheight)
- ty = iwd->pheight; /* Same comment as for xpnt above. */
-
- ypnt = (gint) (((gdouble) (ty) * yratio) / iwd->ratio + 0.5);
-
- if (!gdisp->dot_for_dot) /* here */
- xpnt = ((gdouble) xpnt *
- gdisp->gimage->xresolution) / gdisp->gimage->yresolution + 0.5;
-
- xoffset = xpnt - gdisp->offset_x;
- yoffset = ypnt - gdisp->offset_y;
-
- iwd->block_window_marker = TRUE;
- scroll_display (iwd->gdisp_ptr, xoffset, yoffset);
- iwd->block_window_marker = FALSE;
- }
-
- static void
- nav_window_update_preview (NavWinData *iwd)
- {
- GDisplay *gdisp;
- TempBuf *preview_buf;
- TempBuf *preview_buf_ptr;
- TempBuf *preview_buf_notdot = NULL;
- guchar *src, *buf, *dest;
- gint x, y;
- gint pwidth, pheight;
- GimpImage *gimage;
- gdouble r, g, b, a, chk;
- gint xoff = 0;
- gint yoff = 0;
-
- gimp_add_busy_cursors ();
-
- gdisp = (GDisplay *) iwd->gdisp_ptr;
-
- /* Calculate preview size */
- gimage = ((GDisplay *) (iwd->gdisp_ptr))->gimage;
-
- /* Min size is 2 */
- pwidth = iwd->pwidth;
- pheight = iwd->pheight;
-
- /* we need a large normal preview which we will cut down later.
- * gimp_image_construct_composite_preview() can't cope with
- * dot_for_dot not been set.
- */
- if (!gdisp->dot_for_dot) /* ALT */
- {
- gint sel_width = gimage->width;
- gint sel_height = gimage->height;
- gdouble tratio;
-
- if (sel_width > sel_height)
- tratio = (gdouble) iwd->nav_preview_width / ((gdouble) sel_width);
- else
- tratio = (gdouble) iwd->nav_preview_height / ((gdouble) sel_height);
-
- pwidth = sel_width * tratio + 0.5;
- pheight = sel_height * tratio + 0.5;
- }
-
- if (iwd->ratio > 1.0) /* Preview is scaling up! */
- {
- TempBuf *tmp;
-
- tmp = gimp_image_construct_composite_preview (gimage,
- gimage->width,
- gimage->height);
- preview_buf = gimp_preview_scale (tmp,
- pwidth,
- pheight);
- temp_buf_free (tmp);
- }
- else
- {
- preview_buf = gimp_image_construct_composite_preview (gimage,
- MAX (pwidth, 2),
- MAX (pheight, 2));
- }
-
- /* reset & get new preview */
- /* FIXME: should use gimp_preview_scale() */
- if (!gdisp->dot_for_dot)
- {
- gint loop1, loop2;
- gdouble x_ratio, y_ratio;
- guchar *src_data;
- guchar *dest_data;
-
- preview_buf_notdot = temp_buf_new (iwd->pwidth,
- iwd->pheight,
- preview_buf->bytes,
- 0, 0, NULL);
-
- x_ratio = (gdouble) pwidth / (gdouble) iwd->pwidth;
- y_ratio = (gdouble) pheight / (gdouble) iwd->pheight;
-
- src_data = temp_buf_data (preview_buf);
- dest_data = temp_buf_data (preview_buf_notdot);
-
- for (loop1 = 0 ; loop1 < iwd->pheight ; loop1++)
- for (loop2 = 0 ; loop2 < iwd->pwidth ; loop2++)
- {
- gint i;
- guchar *src_pixel;
- guchar *dest_pixel;
-
- src_pixel = src_data +
- ((gint) (loop2 * x_ratio)) * preview_buf->bytes +
- ((gint) (loop1 * y_ratio)) * pwidth * preview_buf->bytes;
- dest_pixel = dest_data +
- (loop2 + loop1 * iwd->pwidth) * preview_buf->bytes;
-
- for (i = 0 ; i < preview_buf->bytes; i++)
- *dest_pixel++ = *src_pixel++;
- }
-
- pwidth = iwd->pwidth;
- pheight = iwd->pheight;
-
- src = temp_buf_data (preview_buf_notdot);
- preview_buf_ptr = preview_buf_notdot;
- }
- else
- {
- src = temp_buf_data (preview_buf);
- preview_buf_ptr = preview_buf;
- }
-
- buf = g_new (gchar, preview_buf_ptr->width * 3);
-
- for (y = 0; y < preview_buf_ptr->height ; y++)
- {
- dest = buf;
- switch (preview_buf_ptr->bytes)
- {
- case 4:
- for (x = 0; x < preview_buf_ptr->width; x++)
- {
- r = ((gdouble) (*(src++))) / 255.0;
- g = ((gdouble) (*(src++))) / 255.0;
- b = ((gdouble) (*(src++))) / 255.0;
- a = ((gdouble) (*(src++))) / 255.0;
- chk = ((gdouble) ((( (x^y) & 4 ) << 4) | 128)) / 255.0;
- *(dest++) = (guchar) ((chk + (r - chk) * a) * 255.0);
- *(dest++) = (guchar) ((chk + (g - chk) * a) * 255.0);
- *(dest++) = (guchar) ((chk + (b - chk) * a) * 255.0);
- }
- break;
-
- case 2:
- for (x = 0; x < preview_buf_ptr->width; x++)
- {
- r = ((gdouble) (*(src++))) / 255.0;
- a = ((gdouble) (*(src++))) / 255.0;
- chk = ((gdouble) ((( (x^y) & 4 ) << 4) | 128)) / 255.0;
- *(dest++) = (guchar) ((chk + (r - chk) * a) * 255.0);
- *(dest++) = (guchar) ((chk + (r - chk) * a) * 255.0);
- *(dest++) = (guchar) ((chk + (r - chk) * a) * 255.0);
- }
- break;
-
- default:
- g_warning ("UNKNOWN TempBuf bpp in nav_window_update_preview()");
- }
-
- gtk_preview_draw_row (GTK_PREVIEW (iwd->preview),
- (guchar *) buf,
- xoff, yoff + y,
- preview_buf_ptr->width);
- }
-
- g_free (buf);
-
- temp_buf_free (preview_buf);
- if (preview_buf_notdot)
- temp_buf_free (preview_buf_notdot);
-
- gimp_remove_busy_cursors (NULL);
- }
-
- static void
- nav_window_update_preview_blank (NavWinData *iwd)
- {
-
- guchar *buf;
- guchar *dest;
- gint x, y;
- gdouble chk;
-
- #if 0
- GimpImage *gimage;
- GDisplay *gdisp;
-
- gdisp = (GDisplay *) iwd->gdisp_ptr;
-
- /* Calculate preview size */
- gimage = ((GDisplay *) (iwd->gdisp_ptr))->gimage;
-
- #endif /* 0 */
-
- buf = g_new (gchar, iwd->pwidth * 3);
-
- for (y = 0; y < iwd->pheight ; y++)
- {
- dest = buf;
- for (x = 0; x < iwd->pwidth; x++)
- {
- chk = ((gdouble) ((( (x^y) & 4 ) << 4) | 128))/255.0;
- chk *= 128.0;
- *(dest++) = (guchar) chk;
- *(dest++) = (guchar) chk;
- *(dest++) = (guchar) chk;
- }
-
- gtk_preview_draw_row (GTK_PREVIEW (iwd->preview),
- (guchar *) buf,
- 0, y, iwd->pwidth);
- }
-
- g_free (buf);
-
- gdk_flush ();
- }
-
- static gint
- inside_preview_square (NavWinData *iwd,
- gint x,
- gint y)
- {
- if (x > iwd->dispx &&
- x < (iwd->dispx + iwd->dispwidth) &&
- y > iwd->dispy &&
- y < iwd->dispy + iwd->dispheight)
- return TRUE;
-
- return FALSE;
- }
-
- static void
- update_zoom_label (NavWinData *iwd)
- {
- gchar scale_str[MAX_SCALE_BUF];
-
- if(!iwd->zoom_label)
- return;
-
- /* Update the zoom scale string */
- g_snprintf (scale_str, MAX_SCALE_BUF, "%d:%d",
- SCALEDEST (((GDisplay *)iwd->gdisp_ptr)),
- SCALESRC (((GDisplay *)iwd->gdisp_ptr)));
-
- gtk_label_set_text (GTK_LABEL (iwd->zoom_label), scale_str);
- }
-
- static void
- update_zoom_adjustment (NavWinData *iwd)
- {
- GtkAdjustment *adj;
- gdouble f;
- gdouble val;
-
- if (! iwd->zoom_adjustment)
- return;
-
- adj = GTK_ADJUSTMENT (iwd->zoom_adjustment);
-
- f =
- ((gdouble) SCALEDEST (((GDisplay *) iwd->gdisp_ptr))) /
- ((gdouble) SCALESRC (((GDisplay *) iwd->gdisp_ptr)));
-
- if (f < 1.0)
- {
- val = -1.0 / f;
- }
- else
- {
- val = f;
- }
-
- if (abs ((gint) adj->value) != (gint)(val - 1) && iwd->block_adj_sig != TRUE)
- {
- adj->value = val;
- gtk_signal_emit_by_name (GTK_OBJECT (iwd->zoom_adjustment), "changed");
- }
- }
-
- static void
- move_to_point (NavWinData *iwd,
- gint tx,
- gint ty)
- {
- tx = CLAMP (tx, 0, iwd->pwidth);
- ty = CLAMP (ty, 0, iwd->pheight);
-
- if ((tx + iwd->dispwidth) >= iwd->pwidth)
- {
- tx = iwd->pwidth - iwd->dispwidth;
- }
-
- if ((ty + iwd->dispheight) >= iwd->pheight)
- {
- ty = iwd->pheight - iwd->dispheight;
- }
-
- if (iwd->dispx == tx && iwd->dispy == ty)
- return;
-
- /* Update the real display */
- update_real_view (iwd, tx, ty);
-
- nav_window_draw_sqr (iwd,
- TRUE,
- tx, ty,
- iwd->dispwidth, iwd->dispheight);
-
- }
-
- static void
- nav_window_grab_pointer (NavWinData *iwd,
- GtkWidget *widget)
- {
- GdkCursor *cursor;
-
- iwd->sq_grabbed = TRUE;
- gtk_grab_add (widget);
-
- cursor = gdk_cursor_new (GDK_CROSSHAIR);
-
- gdk_pointer_grab (widget->window, TRUE,
- GDK_BUTTON_RELEASE_MASK |
- GDK_POINTER_MOTION_HINT_MASK |
- GDK_BUTTON_MOTION_MASK |
- GDK_EXTENSION_EVENTS_ALL,
- widget->window, cursor, 0);
-
- gdk_cursor_destroy (cursor);
- }
-
- static gint
- nav_window_preview_events (GtkWidget *widget,
- GdkEvent *event,
- gpointer data)
- {
- NavWinData *iwd;
- GDisplay *gdisp;
- GdkEventButton *bevent;
- GdkEventMotion *mevent;
- GdkEventKey *kevent;
- GdkModifierType mask;
- gint tx = 0;
- gint ty = 0;
- gint mx;
- gint my;
- gboolean arrowKey = FALSE;
-
- iwd = (NavWinData *)data;
-
- if(!iwd || iwd->frozen == TRUE)
- return FALSE;
-
- gdisp = (GDisplay *) iwd->gdisp_ptr;
-
- switch (event->type)
- {
- case GDK_EXPOSE:
- break;
-
- case GDK_MAP:
- if (iwd->ptype == NAV_POPUP)
- {
- nav_window_update_preview (iwd);
- /* First time displayed.... get the pointer! */
- nav_window_grab_pointer (iwd, iwd->preview);
- }
- else
- {
- nav_window_update_preview_blank (iwd);
- iwd->timer_id =
- gtk_timeout_add (PREVIEW_UPDATE_TIMEOUT,
- (GtkFunction) nav_preview_update_do_timer,
- (gpointer) iwd);
- }
- break;
-
- case GDK_BUTTON_PRESS:
- bevent = (GdkEventButton *) event;
- tx = bevent->x;
- ty = bevent->y;
-
- /* Must start the move */
- switch (bevent->button)
- {
- case 1:
- if (! inside_preview_square (iwd, tx, ty))
- {
- /* Direct scroll to the location */
- /* view scrolled to the center or nearest possible point */
-
- tx -= iwd->dispwidth / 2;
- ty -= iwd->dispheight / 2;
-
- if(tx < 0)
- tx = 0;
-
- if((tx + iwd->dispwidth) > iwd->pwidth)
- tx = iwd->pwidth - iwd->dispwidth;
-
- if(ty < 0)
- ty = 0;
-
- if((ty + iwd->dispheight) > iwd->pheight)
- ty = iwd->pheight - iwd->dispheight;
-
- update_real_view(iwd,tx,ty);
-
- nav_window_draw_sqr (iwd,
- TRUE,
- tx, ty,
- iwd->dispwidth, iwd->dispheight);
- iwd->motion_offsetx = iwd->dispwidth / 2;
- iwd->motion_offsety = iwd->dispheight / 2;
- }
- else
- {
- iwd->motion_offsetx = tx - iwd->dispx;
- iwd->motion_offsety = ty - iwd->dispy;
- }
-
- nav_window_grab_pointer (iwd, widget);
-
- break;
-
- /* wheelmouse support */
- case 4:
- if (bevent->state & GDK_SHIFT_MASK)
- {
- change_scale (gdisp, ZOOMIN);
- }
- else
- {
- GtkAdjustment *adj =
- (bevent->state & GDK_CONTROL_MASK) ?
- gdisp->hsbdata : gdisp->vsbdata;
- gfloat new_value = adj->value - adj->page_increment / 2;
- new_value =
- CLAMP (new_value, adj->lower, adj->upper - adj->page_size);
- gtk_adjustment_set_value (adj, new_value);
- }
- break;
-
- case 5:
- if (bevent->state & GDK_SHIFT_MASK)
- {
- change_scale (gdisp, ZOOMOUT);
- }
- else
- {
- GtkAdjustment *adj =
- (bevent->state & GDK_CONTROL_MASK) ?
- gdisp->hsbdata : gdisp->vsbdata;
- gfloat new_value = adj->value + adj->page_increment / 2;
- new_value = CLAMP (new_value,
- adj->lower, adj->upper - adj->page_size);
- gtk_adjustment_set_value (adj, new_value);
- }
- break;
-
- default:
- break;
- }
- break;
-
- case GDK_BUTTON_RELEASE:
- bevent = (GdkEventButton *) event;
- tx = bevent->x;
- ty = bevent->y;
-
- switch (bevent->button)
- {
- case 1:
- iwd->sq_grabbed = FALSE;
- gtk_grab_remove (widget);
- gdk_pointer_ungrab (0);
- if(iwd->ptype == NAV_POPUP)
- {
- gtk_widget_hide (gdisp->nav_popup);
- }
- gdk_flush ();
- break;
- default:
- break;
- }
- break;
-
- case GDK_KEY_PRESS:
- /* hack for the update preview... needs to be fixed */
- kevent = (GdkEventKey *) event;
-
- switch (kevent->keyval)
- {
- case GDK_space:
- gdk_window_raise(gdisp->shell->window);
- break;
- case GDK_Up:
- arrowKey = TRUE;
- tx = iwd->dispx;
- ty = iwd->dispy - 1;
- break;
- case GDK_Left:
- arrowKey = TRUE;
- tx = iwd->dispx - 1;
- ty = iwd->dispy;
- break;
- case GDK_Right:
- arrowKey = TRUE;
- tx = iwd->dispx + 1;
- ty = iwd->dispy;
- break;
- case GDK_Down:
- arrowKey = TRUE;
- tx = iwd->dispx;
- ty = iwd->dispy + 1;
- break;
- case GDK_equal:
- change_scale (gdisp, ZOOMIN);
- break;
- case GDK_minus:
- change_scale (gdisp, ZOOMOUT);
- break;
- default:
- break;
- }
-
- if (arrowKey)
- {
- move_to_point (iwd, tx, ty);
- return TRUE;
- }
- break;
-
- case GDK_MOTION_NOTIFY:
- mevent = (GdkEventMotion *) event;
-
- if (!iwd->sq_grabbed)
- break;
-
- gdk_window_get_pointer (widget->window, &mx, &my, &mask);
- tx = mx;
- ty = my;
-
- tx = tx - iwd->motion_offsetx;
- ty = ty - iwd->motion_offsety;
-
- move_to_point (iwd, tx, ty);
- break;
-
- default:
- break;
- }
-
- return FALSE;
- }
-
- static gint
- nav_window_expose_events (GtkWidget *widget,
- GdkEvent *event,
- gpointer data)
- {
- NavWinData *iwd;
- GDisplay *gdisp;
-
- iwd = (NavWinData *) data;
-
- if(!iwd || iwd->frozen == TRUE)
- return FALSE;
-
- gdisp = (GDisplay *) iwd->gdisp_ptr;
-
- switch (event->type)
- {
- case GDK_EXPOSE:
- /* we must have the grab if in nav_popup*/
- gtk_signal_handler_block (GTK_OBJECT(widget), iwd->sig_hand_id);
- gtk_widget_draw (iwd->preview, NULL);
- gtk_signal_handler_unblock (GTK_OBJECT(widget), iwd->sig_hand_id);
-
- nav_window_draw_sqr (iwd,FALSE,
- iwd->dispx, iwd->dispy,
- iwd->dispwidth, iwd->dispheight);
- if (! gtk_grab_get_current() && iwd->ptype == NAV_POPUP)
- nav_window_grab_pointer (iwd, iwd->preview);
- break;
-
- default:
- break;
- }
-
- return FALSE;
- }
-
- static gint
- nav_preview_update_do (NavWinData *iwd)
- {
- /* If the gdisp_ptr has gone then don't do anything in this timer */
- if (!iwd->gdisp_ptr)
- return FALSE;
-
- nav_window_update_preview (iwd);
- nav_window_disp_area (iwd, iwd->gdisp_ptr);
- gtk_widget_queue_draw (iwd->preview);
-
- iwd->installedDirtyTimer = FALSE;
-
- return FALSE;
- }
-
- static gint
- nav_preview_update_do_timer (NavWinData *iwd)
- {
- iwd->timer_id = 0;
- gtk_idle_add ((GtkFunction) nav_preview_update_do, (gpointer) iwd);
-
- return FALSE;
- }
-
- static void
- nav_image_need_update (GtkObject *obj,
- gpointer client_data)
- {
- NavWinData *iwd;
-
- iwd = (NavWinData *)client_data;
-
- if(!iwd ||
- !iwd->showingPreview ||
- iwd->installedDirtyTimer == TRUE ||
- iwd->frozen == TRUE)
- return;
-
- iwd->installedDirtyTimer = TRUE;
-
- /* Update preview at a less busy time */
- nav_window_update_preview_blank (iwd);
- gtk_widget_draw (iwd->preview, NULL);
- iwd->timer_id = gtk_timeout_add (PREVIEW_UPDATE_TIMEOUT,
- (GtkFunction) nav_preview_update_do_timer,
- (gpointer) iwd);
- }
-
- static void
- navwindow_zoomin (GtkWidget *widget,
- gpointer data)
- {
- NavWinData *iwd;
- GDisplay *gdisp;
-
- iwd = (NavWinData *)data;
-
- if(!iwd || iwd->frozen == TRUE)
- return;
-
- gdisp = (GDisplay *) iwd->gdisp_ptr;
-
- change_scale (gdisp, ZOOMIN);
- }
-
- static void
- navwindow_zoomout (GtkWidget *widget,
- gpointer data)
- {
- NavWinData *iwd;
- GDisplay *gdisp;
-
- iwd = (NavWinData *)data;
-
- if (!iwd || iwd->frozen == TRUE)
- return;
-
- gdisp = (GDisplay *) iwd->gdisp_ptr;
-
- change_scale (gdisp, ZOOMOUT);
- }
-
- static void
- zoom_adj_changed (GtkAdjustment *adj,
- gpointer data)
- {
- NavWinData *iwd;
- GDisplay *gdisp;
- gint scalesrc;
- gint scaledest;
-
- iwd = (NavWinData *)data;
-
- if (!iwd || iwd->frozen == TRUE)
- return;
-
- gdisp = (GDisplay *) iwd->gdisp_ptr;
-
- if (adj->value < 0.0)
- {
- scalesrc = abs ((gint) adj->value - 1);
- scaledest = 1;
- }
- else
- {
- scaledest = abs ((gint) adj->value + 1);
- scalesrc = 1;
- }
-
- iwd->block_adj_sig = TRUE;
- change_scale (gdisp, (scaledest * 100) + scalesrc);
- iwd->block_adj_sig = FALSE;
- }
-
- static GtkWidget *
- nav_create_button_area (InfoDialog *info_win)
- {
- GtkWidget *hbox1;
- GtkWidget *vbox1;
- GtkWidget *button;
- GtkWidget *hscale1;
- GtkWidget *label1;
- GtkObject *adjustment;
- NavWinData *iwd;
- gchar scale_str[MAX_SCALE_BUF];
-
- iwd = (NavWinData *) info_win->user_data;
-
- hbox1 = gtk_hbox_new (FALSE, 0);
- gtk_widget_show (hbox1);
-
- button = gimp_pixmap_button_new (zoom_out_xpm, NULL);
- GTK_WIDGET_UNSET_FLAGS (button, GTK_RECEIVES_DEFAULT);
- gtk_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (navwindow_zoomout),
- (gpointer) info_win->user_data);
- gtk_box_pack_start (GTK_BOX (hbox1), button, FALSE, FALSE, 0);
- gtk_widget_show (button);
-
- vbox1 = gtk_vbox_new (FALSE, 0);
- gtk_widget_show (vbox1);
- gtk_box_pack_start (GTK_BOX (vbox1), hbox1, TRUE, TRUE, 0);
-
- /* user zoom ratio */
- g_snprintf (scale_str, MAX_SCALE_BUF, "%d:%d",
- SCALEDEST (((GDisplay *)iwd->gdisp_ptr)),
- SCALESRC (((GDisplay *)iwd->gdisp_ptr)));
-
- label1 = gtk_label_new (scale_str);
- gtk_widget_show (label1);
- iwd->zoom_label = label1;
- gtk_box_pack_start (GTK_BOX (hbox1), label1, TRUE, TRUE, 0);
-
- adjustment = gtk_adjustment_new (0.0, -15.0, 16.0, 1.0, 1.0, 1.0);
- hscale1 = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
- gtk_scale_set_digits (GTK_SCALE (hscale1), 0);
- iwd->zoom_adjustment = adjustment;
- gtk_widget_show (hscale1);
-
- gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
- GTK_SIGNAL_FUNC (zoom_adj_changed),
- iwd);
-
- gtk_box_pack_start (GTK_BOX (vbox1), hscale1, TRUE, TRUE, 0);
- gtk_scale_set_draw_value (GTK_SCALE (hscale1), FALSE);
-
- button = gimp_pixmap_button_new (zoom_in_xpm, NULL);
- GTK_WIDGET_UNSET_FLAGS (button, GTK_RECEIVES_DEFAULT);
- gtk_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (navwindow_zoomin),
- (gpointer) info_win->user_data);
- gtk_box_pack_start (GTK_BOX (hbox1), button, FALSE, FALSE, 0);
- gtk_widget_show (button);
-
- return vbox1;
- }
-
- static GtkWidget *
- create_preview_containers (NavWinData *iwd,
- GtkWidget *shell)
- {
- GtkWidget *hbox1;
- GtkWidget *vbox1;
- GtkWidget *alignment;
-
- hbox1 = gtk_hbox_new (FALSE, 0);
- gtk_widget_show (hbox1);
-
- vbox1 = gtk_vbox_new (FALSE, 0);
- gtk_widget_show (vbox1);
-
- gtk_widget_realize (shell);
-
- /* need gc to draw the preview sqr with */
- iwd->gc = gdk_gc_new (shell->window);
- gdk_gc_set_function (iwd->gc, GDK_INVERT);
- gdk_gc_set_line_attributes (iwd->gc, BORDER_PEN_WIDTH,
- GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_ROUND);
-
- alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
- iwd->previewAlign = alignment;
- gtk_widget_show (alignment);
-
- /* Create the preview in which to draw the thumbnail image */
-
- create_preview_widget (iwd);
-
- gtk_box_pack_start (GTK_BOX (hbox1), alignment, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (vbox1), hbox1, TRUE, TRUE, 0);
-
- return vbox1;
- }
-
- static GtkWidget *
- info_window_image_preview_new (InfoDialog *info_win)
- {
- GtkWidget *button_area;
- GtkWidget *vbox1;
-
- NavWinData *iwd;
-
- iwd = (NavWinData *) info_win->user_data;
-
- vbox1 = create_preview_containers (iwd, info_win->shell);
-
- /* This one has (may) have the buttons in */
- button_area = nav_create_button_area (info_win);
- gtk_box_pack_start (GTK_BOX (vbox1), button_area, TRUE, TRUE, 0);
-
- return vbox1;
- }
-
- NavWinData *
- create_dummy_iwd (void *gdisp_ptr,
- NavWinType ptype)
- {
- NavWinData *iwd;
-
- iwd = (NavWinData *) g_malloc (sizeof (NavWinData));
- iwd->ptype = ptype;
- iwd->info_win = NULL;
- iwd->showingPreview = TRUE;
- iwd->installedDirtyTimer = FALSE;
- iwd->preview = NULL;
- iwd->zoom_label = NULL;
- iwd->zoom_adjustment = NULL;
- iwd->gdisp_ptr = gdisp_ptr;
- iwd->dispx = -1;
- iwd->dispy = -1;
- iwd->dispwidth = -1;
- iwd->dispheight = -1;
- iwd->imagewidth = -1;
- iwd->imageheight = -1;
- iwd->sq_grabbed = FALSE;
- iwd->ratio = 1.0;
- iwd->block_window_marker = FALSE;
- iwd->nav_preview_width =
- (nav_preview_size < 0 || nav_preview_size > 256) ?
- NAV_PREVIEW_WIDTH : nav_preview_size;
- iwd->nav_preview_height =
- (nav_preview_size < 0 || nav_preview_size > 256) ?
- NAV_PREVIEW_HEIGHT : nav_preview_size;
- iwd->block_adj_sig = FALSE;
- iwd->frozen = FALSE;
- iwd->timer_id = 0;
-
- return(iwd);
- }
-
- /* Create a version of the nav window that follows the active
- * image.
- */
-
- static InfoDialog *nav_window_auto = NULL;
-
- static gchar *
- nav_window_title(GDisplay *gdisp)
- {
- gchar *title;
- gchar *title_buf;
-
- title = g_basename (gimage_filename (gdisp->gimage));
-
- /* create the info dialog */
- title_buf = g_strdup_printf (_("Navigation: %s-%d.%d"),
- title,
- pdb_image_to_id (gdisp->gimage),
- gdisp->instance);
-
- return title_buf;
- }
-
- static void
- nav_window_change_display (GimpContext *context, /* NOT USED */
- GDisplay *newdisp,
- gpointer data /* Not used */)
- {
- GDisplay *gdisp = newdisp;
- GDisplay *old_gdisp;
- GimpImage *gimage;
- NavWinData *iwd;
- gchar *title_buf;
-
- iwd = (NavWinData *)nav_window_auto->user_data;
- old_gdisp = (GDisplay *) iwd->gdisp_ptr;
-
- if (!nav_window_auto || gdisp == old_gdisp || !gdisp)
- {
- return;
- }
-
- gtk_widget_set_sensitive (nav_window_auto->vbox, TRUE);
- iwd->frozen = FALSE;
-
- title_buf = nav_window_title (gdisp);
-
- gtk_window_set_title (GTK_WINDOW (nav_window_auto->shell), title_buf);
-
- g_free (title_buf);
-
- gimage = gdisp->gimage;
-
- if (gimage && gimp_set_have (image_context, gimage))
- {
- iwd->gdisp_ptr = gdisp;
-
- /* Update preview to new display */
- nav_window_preview_resized (nav_window_auto);
-
- /* Tie into the dirty signal so we can update the preview */
- /* provided we haven't already */
- if (!gtk_object_get_data (GTK_OBJECT (gdisp->gimage),
- "nav_handlers_installed"))
- {
- gtk_signal_connect_after (GTK_OBJECT (gdisp->gimage), "dirty",
- GTK_SIGNAL_FUNC (nav_image_need_update),
- iwd);
-
- /* Also clean signal so undos get caught as well..*/
- gtk_signal_connect_after (GTK_OBJECT (gdisp->gimage), "clean",
- GTK_SIGNAL_FUNC (nav_image_need_update),
- iwd);
- gtk_object_set_data (GTK_OBJECT (gdisp->gimage),
- "nav_handlers_installed",iwd);
- }
- }
- }
-
- void
- nav_window_follow_auto (void)
- {
- GDisplay *gdisp;
- NavWinData *iwd;
-
- gdisp = gdisplay_active ();
-
- if (!gdisp)
- return;
-
- if(!nav_window_auto)
- {
- nav_window_auto = nav_window_create ((void *) gdisp);
- gtk_signal_connect (GTK_OBJECT (gimp_context_get_user ()),
- "display_changed",
- GTK_SIGNAL_FUNC (nav_window_change_display),
- NULL);
- }
-
- nav_dialog_popup (nav_window_auto);
-
- iwd = (NavWinData *) nav_window_auto->user_data;
- gtk_widget_set_sensitive (nav_window_auto->vbox, TRUE);
- iwd->frozen = FALSE;
- }
-
-
- InfoDialog *
- nav_window_create (void *gdisp_ptr)
- {
- InfoDialog *info_win;
- GDisplay *gdisp;
- NavWinData *iwd;
- GtkWidget *container;
- gchar *title_buf;
- GimpImageBaseType type;
-
- gdisp = (GDisplay *) gdisp_ptr;
-
- type = gimage_base_type (gdisp->gimage);
-
- title_buf = nav_window_title(gdisp);
-
- info_win = info_dialog_new (title_buf,
- gimp_standard_help_func,
- "dialogs/navigation_window.html");
- g_free (title_buf);
-
- dialog_register (info_win->shell);
-
- /* create the action area */
- gimp_dialog_create_action_area (GTK_DIALOG (info_win->shell),
-
- _("Close"), nav_window_close_callback,
- info_win, NULL, NULL, TRUE, FALSE,
-
- NULL);
-
- gtk_signal_connect (GTK_OBJECT (info_win->shell), "destroy",
- (GtkSignalFunc) nav_window_destroy_callback,
- info_win);
-
- iwd = create_dummy_iwd (gdisp_ptr, NAV_WINDOW);
- info_win->user_data = iwd;
- iwd->info_win = info_win;
-
- /* Add preview */
- container = info_window_image_preview_new (info_win);
- gtk_table_attach_defaults (GTK_TABLE (info_win->info_table), container,
- 0, 2, 0, 1);
-
- /* Tie into the dirty signal so we can update the preview */
- gtk_signal_connect_after (GTK_OBJECT (gdisp->gimage), "dirty",
- GTK_SIGNAL_FUNC(nav_image_need_update),iwd);
-
- /* Also clean signal so undos get caught as well..*/
- gtk_signal_connect_after (GTK_OBJECT (gdisp->gimage), "clean",
- GTK_SIGNAL_FUNC(nav_image_need_update),iwd);
-
-
- /* Mark the image as having the handlers installed...
- */
- gtk_object_set_data (GTK_OBJECT (gdisp->gimage),
- "nav_handlers_installed", iwd);
-
- return info_win;
- }
-
- void
- nav_window_update_window_marker (InfoDialog *info_win)
- {
- NavWinData *iwd;
-
- /* So this functions works both ways..
- * it will come in here with info_win == null
- * if the auto mode is on...
- */
-
- if (!info_win && nav_window_auto)
- {
- iwd = (NavWinData *) nav_window_auto->user_data;
- if(iwd->frozen)
- return;
-
- nav_window_update_window_marker (nav_window_auto);
-
- return;
- }
-
- if (!info_win)
- return;
-
- iwd = (NavWinData *) info_win->user_data;
-
- if (!iwd ||
- iwd->showingPreview == FALSE ||
- iwd->block_window_marker == TRUE)
- return;
-
- update_zoom_label (iwd);
- update_zoom_adjustment (iwd);
-
- /* Undraw old size */
- nav_window_draw_sqr (iwd,
- FALSE,
- iwd->dispx, iwd->dispy,
- iwd->dispwidth, iwd->dispheight);
-
- /* Update to new size */
- nav_window_disp_area (iwd, iwd->gdisp_ptr);
-
- /* and redraw */
- nav_window_draw_sqr (iwd,
- FALSE,
- iwd->dispx, iwd->dispy,
- iwd->dispwidth, iwd->dispheight);
- }
-
- void
- nav_dialog_popup (InfoDialog *idialog)
- {
- NavWinData *iwd;
-
- if (!idialog)
- return;
-
- iwd = (NavWinData *) idialog->user_data;
- iwd->showingPreview = TRUE;
-
- if (! GTK_WIDGET_VISIBLE (idialog->shell))
- {
- gtk_widget_show (idialog->shell);
- nav_window_update_preview_blank (iwd);
- nav_window_update_window_marker (idialog);
- iwd->timer_id =
- gtk_timeout_add (PREVIEW_UPDATE_TIMEOUT,
- (GtkFunction) nav_preview_update_do_timer,
- (gpointer) iwd);
- }
-
- gdk_window_raise (GTK_WIDGET (idialog->shell)->window);
- }
-
- /* Chose the first image.. */
- static void
- gimlist_cb (gpointer im,
- gpointer data)
- {
- GSList **list_ptr;
-
- list_ptr = (GSList **) data;
- *list_ptr = g_slist_prepend (*list_ptr, im);
- }
-
- static GDisplay *
- nav_window_get_gdisp (void)
- {
- GSList *list = NULL;
- GSList *listPtr = NULL;
- GDisplay *gdisp = NULL;
- GimpImage *gimage;
-
- gimage_foreach (gimlist_cb, &list);
-
- if (!list)
- return NULL;
-
- /* Find first valid image */
- for (listPtr = list; listPtr; listPtr = g_slist_next (listPtr))
- {
- gimage = GIMP_IMAGE (listPtr->data);
- gdisp = gdisplays_check_valid (NULL,gimage);
- if (gdisp)
- break;
- }
-
- g_slist_free (list);
-
- return (gdisp);
- }
-
-
- void
- nav_window_free (GDisplay *del_gdisp,
- InfoDialog *info_win)
- {
- NavWinData *iwd;
-
- /* So this functions works both ways..
- * it will come in here with info_win == null
- * if the auto mode is on...
- */
-
- if (!info_win)
- {
- if (nav_window_auto != NULL)
- {
- GDisplay * gdisp;
-
- iwd = (NavWinData *) nav_window_auto->user_data;
-
- /* Only freeze if we are displaying the image we have deleted */
- if ((GDisplay *) iwd->gdisp_ptr != del_gdisp)
- return;
-
- if (iwd->timer_id)
- gtk_timeout_remove (iwd->timer_id);
-
- iwd->timer_id = 0;
-
- gdisp = nav_window_get_gdisp ();
-
- if (gdisp)
- nav_window_change_display (NULL, gdisp, NULL);
- else
- {
- /* Clear window and freeze */
- iwd->frozen = TRUE;
- nav_window_update_preview_blank (iwd);
- gtk_window_set_title (GTK_WINDOW (nav_window_auto->shell),
- _("Navigation: No Image"));
-
- gtk_widget_set_sensitive (nav_window_auto->vbox, FALSE);
- iwd->gdisp_ptr = NULL;
- gtk_widget_hide (GTK_WIDGET (nav_window_auto->shell));
- }
- }
- return;
- }
-
- /* We are actually freeing a window here so remove any timers left. */
- iwd = (NavWinData *)info_win->user_data;
- if (iwd->timer_id)
- gtk_timeout_remove (iwd->timer_id);
-
- g_free (info_win->user_data);
- info_dialog_free (info_win);
- }
-
-
- /* nav popup ...
- * should share code with the nav_window dialog since they are
- * essentially the same.
- */
-
- void
- nav_popup_click_handler (GtkWidget *widget,
- GdkEventButton *event,
- gpointer data)
- {
- GdkEventButton *bevent;
- GDisplay *gdisp = data;
- NavWinData *iwp; /* dummy shorter version for the popups */
- gint x, y;
- gint x_org, y_org;
- gint scr_w, scr_h;
-
- bevent = (GdkEventButton *)event;
-
- if(!gdisp->nav_popup)
- {
- /* popup a simplfied window with the nav box in it */
- GtkWidget *frame;
- GtkWidget *vbox;
-
- iwp = create_dummy_iwd (gdisp, NAV_POPUP);
- gdisp->nav_popup = gtk_window_new (GTK_WINDOW_POPUP);
- gtk_widget_set_events (gdisp->nav_popup, PREVIEW_MASK);
-
- gtk_window_set_policy (GTK_WINDOW (gdisp->nav_popup),
- FALSE, FALSE, TRUE);
- frame = gtk_frame_new (NULL);
- gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
- gtk_container_add (GTK_CONTAINER (gdisp->nav_popup), frame);
- gtk_widget_show (frame);
-
- vbox = create_preview_containers (iwp,gdisp->nav_popup);
- gtk_widget_set_extension_events (iwp->preview, GDK_EXTENSION_EVENTS_ALL);
-
- gtk_container_add (GTK_CONTAINER (frame), vbox);
- gtk_object_set_data (GTK_OBJECT (gdisp->nav_popup),"navpop_prt",
- (gpointer) iwp);
- nav_window_disp_area (iwp, iwp->gdisp_ptr);
- }
- else
- {
- gtk_widget_hide (gdisp->nav_popup);
- iwp = (NavWinData *) gtk_object_get_data (GTK_OBJECT (gdisp->nav_popup),
- "navpop_prt");
- nav_window_disp_area (iwp, iwp->gdisp_ptr);
- nav_window_update_preview (iwp);
- }
-
- /* decide where to put the popup */
- gdk_window_get_origin (widget->window, &x_org, &y_org);
-
- scr_w = gdk_screen_width ();
- scr_h = gdk_screen_height ();
-
- x = x_org + bevent->x - iwp->dispx -
- ((iwp->dispwidth - BORDER_PEN_WIDTH + 1) * 0.5) - 2;
- y = y_org + bevent->y - iwp->dispy -
- ((iwp->dispheight - BORDER_PEN_WIDTH + 1)* 0.5) - 2;
-
- /* If the popup doesn't fit into the screen, we have a problem.
- * We move the popup onscreen and risk that the pointer is not
- * in the square representing the viewable area anymore. Moving
- * the pointer will make the image scroll by a large amount,
- * but then it works as usual. Probably better than a popup that
- * is completely unusable in the lower right of the screen.
- *
- * Warping the pointer would be another solution ...
- */
- x = (x < 0) ? 0 : x;
- y = (y < 0) ? 0 : y;
- x = (x + iwp->pwidth > scr_w) ? scr_w - iwp->pwidth - 2: x;
- y = (y + iwp->pheight > scr_h) ? scr_h - iwp->pheight - 2: y;
-
- gtk_widget_popup (gdisp->nav_popup, x, y);
- gdk_flush();
-
- /* fill in then set up handlers for mouse motion etc */
- iwp->motion_offsetx = (iwp->dispwidth - BORDER_PEN_WIDTH + 1) * 0.5;
- iwp->motion_offsety = (iwp->dispheight - BORDER_PEN_WIDTH + 1) * 0.5;
-
- if(GTK_WIDGET_VISIBLE(iwp->preview))
- nav_window_grab_pointer (iwp, iwp->preview);
- }
-
- void
- nav_popup_free (GtkWidget *nav_popup)
- {
- gtk_widget_destroy (nav_popup);
- }
-
- void
- nav_window_preview_resized (InfoDialog *idialog)
- {
- NavWinData *iwd;
-
- if (!idialog)
- return;
-
- iwd = (NavWinData *)idialog->user_data;
-
- /* force regeneration of the widgets */
- /* bit of a fiddle... could cause if the image really is 1x1
- * but the preview would not really matter in that case.
- */
- iwd->imagewidth = 1;
- iwd->imageheight = 1;
-
- iwd->nav_preview_width =
- (nav_preview_size < 0 || nav_preview_size > 256) ?
- NAV_PREVIEW_WIDTH : nav_preview_size;
- iwd->nav_preview_height =
- (nav_preview_size < 0 || nav_preview_size > 256) ?
- NAV_PREVIEW_HEIGHT : nav_preview_size;
-
- nav_window_update_window_marker (idialog);
- }
-
- void
- nav_window_popup_preview_resized (GtkWidget **widget)
- {
- NavWinData *iwp; /* dummy shorter version for the popups */
-
- iwp = (NavWinData *) gtk_object_get_data (GTK_OBJECT (*widget),
- "navpop_prt");
-
- g_free (iwp);
-
- gtk_widget_destroy (*widget);
-
- *widget = NULL;
- }
-