gimp/app/nav_window.c
GMT 1999 Andy Thomas 48fb5c0959 2nd Try.. First failed due to problems at my end....
2nd Try.. First failed due to problems at my end....

Sat Nov 20 00:27:26 GMT 1999 Andy Thomas <alt@gimp.org>

	* app/commands.c
	* app/gdisplay.c
	* app/gimprc.c
	* app/gimprc.h
	* app/nav_window.c
	* app/nav_window.h
	* app/preferences_dialog.c
	* app/scale.c
	* app/scroll.c

	Nav dialog now follows auto. There is an option in the
	preferences dialog (interface) that allow you to switch
	between this behaviour and the "original" way of having
	one nav dialog per display.
1999-11-20 00:46:58 +00:00

1674 lines
41 KiB
C

/* 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 "gdk/gdkkeysyms.h"
#include "appenv.h"
#include "colormaps.h"
#include "cursorutil.h"
#include "dialog_handler.h"
#include "info_dialog.h"
#include "info_window.h"
#include "gdisplay.h"
#include "gimpcontext.h"
#include "gimpset.h"
#include "gimprc.h"
#include "gimpui.h"
#include "gximage.h"
#include "interface.h"
#include "nav_window.h"
#include "scroll.h"
#include "scale.h"
#include "libgimp/gimpintl.h"
#include "libgimp/gimpunit.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 ? */
};
static gint nav_window_preview_events (GtkWidget *, GdkEvent *, gpointer *);
static gint nav_window_expose_events (GtkWidget *, GdkEvent *, gpointer *);
static void nav_window_update_preview (NavWinData *);
static void nav_window_update_preview_blank (NavWinData *iwd);
static void destroy_preview_widget (NavWinData *);
static void create_preview_widget (NavWinData *);
static void nav_window_draw_sqr (NavWinData *, gboolean,
gint, gint, gint, gint );
static void set_size_data (NavWinData *);
static gint nav_preview_update_do_timer (NavWinData *);
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 == TRUE)
{
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);
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)
{
/* 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);
}
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, sel_height;
gint pwidth, 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 = (gdouble)pwidth / ((gdouble)sel_width);
pheight = sel_height * iwd->ratio + 0.5;
iwd->ratio = (gdouble)pheight/(gdouble)sel_height;
pwidth = sel_width * iwd->ratio + 0.5;
} else {
pheight = iwd->nav_preview_height;
/* pwidth = sel_width * pheight / sel_height; */
iwd->ratio = (gdouble)pheight / ((gdouble)sel_height);
pwidth = sel_width * iwd->ratio + 0.5;
iwd->ratio = (gdouble)pwidth/(gdouble)sel_width;
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 */
{
gdouble unit_factor = gimp_unit_get_factor (gdisp->gimage->unit);
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,has_alpha;
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) {
pwidth = iwd->nav_preview_width;
tratio = (gdouble)pwidth / ((gdouble)sel_width);
pheight = sel_height * tratio + 0.5;
tratio = (gdouble)pheight/(gdouble)sel_height;
pwidth = sel_width * tratio + 0.5;
} else {
pheight = iwd->nav_preview_height;
tratio = (gdouble)pheight / ((gdouble)sel_height);
pwidth = sel_width * tratio + 0.5;
tratio = (gdouble)pwidth/(gdouble)sel_width;
pheight = sel_height * tratio + 0.5;
}
}
preview_buf = gimp_image_construct_composite_preview (gimage,
MAX (pwidth, 2),
MAX (pheight, 2));
/* reset & get new preview */
if (!gdisp->dot_for_dot)
{
int 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++)
{
int i;
guchar *src_pixel = src_data +
((gint)(loop2*x_ratio))*preview_buf->bytes +
((gint)(loop1*y_ratio))*pwidth*preview_buf->bytes;
guchar *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 = (gchar *) temp_buf_data (preview_buf_notdot);
preview_buf_ptr = preview_buf_notdot;
}
else
{
src = (gchar *) temp_buf_data (preview_buf);
preview_buf_ptr = preview_buf;
}
buf = g_new (gchar, iwd->nav_preview_width * 3);
has_alpha = (preview_buf_ptr->bytes == 2 || preview_buf_ptr->bytes == 4);
for (y = 0; y <pheight ; y++)
{
dest = buf;
switch (preview_buf_ptr->bytes)
{
case 4:
for (x = 0; x < pwidth; 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 < pwidth; 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, *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/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;
int ret;
iwd->sq_grabbed = TRUE;
gtk_grab_add (widget);
cursor = gdk_cursor_new (GDK_CROSSHAIR);
ret = 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,ty = 0; /* So compiler complaints */
gint mx,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);
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)
{
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)
{
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);
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, 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;
GdkPixmap *pixmap;
GtkWidget *pixmapwid;
GdkBitmap *mask;
GtkStyle *style;
NavWinData *iwd;
gchar scale_str[MAX_SCALE_BUF];
iwd = (NavWinData *)info_win->user_data;
hbox1 = gtk_hbox_new (FALSE, 0);
gtk_widget_show (hbox1);
style = gtk_widget_get_style (info_win->shell);
button = gtk_button_new ();
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);
pixmap = gdk_pixmap_create_from_xpm_d (info_win->shell->window, &mask,
&style->bg[GTK_STATE_NORMAL],
zoom_out_xpm);
pixmapwid = gtk_pixmap_new (pixmap, mask);
gtk_container_add (GTK_CONTAINER (button), pixmapwid);
gtk_widget_show (pixmapwid);
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 = gtk_button_new ();
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);
pixmap = gdk_pixmap_create_from_xpm_d (info_win->shell->window, &mask,
&style->bg[GTK_STATE_NORMAL],
zoom_in_xpm);
pixmapwid = gtk_pixmap_new (pixmap, mask);
gtk_container_add (GTK_CONTAINER (button), pixmapwid);
gtk_widget_show (pixmapwid);
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;
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)
{
char *title;
gchar *title_buf;
title = g_basename (gimage_filename (gdisp->gimage));
/* create the info dialog */
title_buf = g_strdup_printf (_("Window 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()
{
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;
char *title_buf;
int 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, 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);
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** l;
l = (GSList**) data;
*l = g_slist_prepend (*l, im);
}
static GDisplay *
nav_window_get_gdisp (void)
{
GSList *list=NULL;
GSList *listPtr=NULL;
GimpImage *gimage ;
GDisplay * gdisp;
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)
{
/* 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)
{
NavWinData *iwd;
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;
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),
_("No image: Window Navigation"));
gtk_widget_set_sensitive(nav_window_auto->vbox,FALSE);
iwd->gdisp_ptr = NULL;
}
}
return;
}
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 we leave this in we need to warp the pointer so it still fits in
* in the square representing the viewable area.
* However warping is probably frowned upon.
*/
#if 0
x = (x < 0) ? 0 : x;
y = (y < 0) ? 0 : y;
x = (x + NAV_PREVIEW_WIDTH > scr_w) ? scr_w - NAV_PREVIEW_WIDTH : x;
y = (y + NAV_PREVIEW_HEIGHT > scr_h) ? scr_h - NAV_PREVIEW_HEIGHT : y;
#endif /* 0 */
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;
}