app/commands.c app/commands.h app/disp_callbacks.c app/gdisplay.c

Thu Aug 12 21:38:53 BST 1999 Andy Thomas <alt@gimp.org>

	* app/commands.c
	* app/commands.h
	* app/disp_callbacks.c
	* app/gdisplay.c
	* app/gdisplay.h
	* app/info_dialog.c
	* app/info_dialog.h
	* app/info_window.c
	* app/info_window.h
	* app/menus.c
	* app/scale.c
	* app/scroll.c
	* app/scroll.h
	* app/nav_window.c (new)
	* app/nav_window.h (new)
	* pixmap/dropper.xpm (new)

	New "navigator" image (accessed via <Image>/Window Nav..). This gives
	an outline of the location of the current view on an image. Eg if your
	image window is only showing part of an image then the Window Navigation	window will outline the area viewed. You can "drag" the outlined
	square around the viewport and the main image will scroll. Additional
	a single click outside the square will center the image at that
	location.

	Also started to add additional information to a new page inside the
	Window information dialog (currently only pixel value is shown).

	Both these features are currently work in progress and unfinished.
	In particular the Navigator does not keep in step with changes
	to the basic image (however it does keep in step with image size changes	and if you modify the size of the image viewing window). It also
	does not display the transparent areas of images very nicely.
This commit is contained in:
BST 1999 Andy Thomas 1999-08-12 22:21:04 +00:00 committed by Andy Thomas
parent cac72d12f8
commit 2557c517b1
49 changed files with 3402 additions and 45 deletions

View File

@ -1,3 +1,37 @@
Thu Aug 12 23:15:53 BST 1999 Andy Thomas <alt@gimp.org>
* app/commands.c
* app/commands.h
* app/disp_callbacks.c
* app/gdisplay.c
* app/gdisplay.h
* app/info_dialog.c
* app/info_dialog.h
* app/info_window.c
* app/info_window.h
* app/menus.c
* app/scale.c
* app/scroll.c
* app/scroll.h
* app/nav_window.c (new)
* app/nav_window.h (new)
* pixmap/dropper.xpm (new)
New "navigator" image (accessed via <Image>/Window Nav..). This gives
an outline of the location of the current view on an image. Eg if your
image window is only showing part of an image then the Window Navigation window will outline the area viewed. You can "drag" the outlined
square around the viewport and the main image will scroll. Additional
a single click outside the square will center the image at that
location.
Also started to add additional information to a new page inside the
Window information dialog (currently only pixel value is shown).
Both these features are currently work in progress and unfinished.
In particular the Navigator does not keep in step with changes
to the basic image (however it does keep in step with image size changes and if you modify the size of the image viewing window). It also
does not display the transparent areas of images very nicely.
1999-08-13 Tor Lillqvist <tml@iki.fi>
* app/makefile.{cygwin,msc} (gimp_OBJECTS): Add newest files.

View File

@ -283,6 +283,8 @@ gimp_SOURCES = \
module_db.h \
move.c \
move.h \
nav_window.c \
nav_window.h \
ops_buttons.c \
ops_buttons.h \
palette.c \

View File

@ -39,6 +39,7 @@
#include "gradient.h"
#include "image_render.h"
#include "info_window.h"
#include "nav_window.h"
#include "interface.h"
#include "invert.h"
#include "lc_dialog.h"
@ -535,6 +536,19 @@ view_window_info_cmd_callback (GtkWidget *widget,
info_dialog_popup (gdisp->window_info_dialog);
}
void
view_window_nav_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
if (! gdisp->window_nav_dialog)
gdisp->window_nav_dialog = nav_window_create ((void *) gdisp);
info_dialog_popup (gdisp->window_nav_dialog);
}
void
view_toggle_selection_cmd_callback (GtkWidget *widget,
gpointer client_data)

View File

@ -51,6 +51,7 @@ void view_zoom_1_4_callback (GtkWidget *, gpointer);
void view_zoom_1_8_callback (GtkWidget *, gpointer);
void view_zoom_1_16_callback (GtkWidget *, gpointer);
void view_window_info_cmd_callback (GtkWidget *, gpointer);
void view_window_nav_cmd_callback (GtkWidget *, gpointer);
void view_toggle_selection_cmd_callback (GtkWidget *, gpointer);
void view_toggle_rulers_cmd_callback (GtkWidget *, gpointer);
void view_toggle_guides_cmd_callback (GtkWidget *, gpointer);

View File

@ -39,6 +39,7 @@
#include "gradient.h"
#include "image_render.h"
#include "info_window.h"
#include "nav_window.h"
#include "interface.h"
#include "invert.h"
#include "lc_dialog.h"
@ -535,6 +536,19 @@ view_window_info_cmd_callback (GtkWidget *widget,
info_dialog_popup (gdisp->window_info_dialog);
}
void
view_window_nav_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
if (! gdisp->window_nav_dialog)
gdisp->window_nav_dialog = nav_window_create ((void *) gdisp);
info_dialog_popup (gdisp->window_nav_dialog);
}
void
view_toggle_selection_cmd_callback (GtkWidget *widget,
gpointer client_data)

View File

@ -51,6 +51,7 @@ void view_zoom_1_4_callback (GtkWidget *, gpointer);
void view_zoom_1_8_callback (GtkWidget *, gpointer);
void view_zoom_1_16_callback (GtkWidget *, gpointer);
void view_window_info_cmd_callback (GtkWidget *, gpointer);
void view_window_nav_cmd_callback (GtkWidget *, gpointer);
void view_toggle_selection_cmd_callback (GtkWidget *, gpointer);
void view_toggle_rulers_cmd_callback (GtkWidget *, gpointer);
void view_toggle_guides_cmd_callback (GtkWidget *, gpointer);

View File

@ -35,6 +35,7 @@
#include "interface.h"
#include "lc_dialog.h"
#include "menus.h"
#include "nav_window.h"
#include "plug_in.h"
#include "qmask.h"
#include "scale.h"
@ -97,6 +98,7 @@ gdisplay_new (GimpImage *gimage,
gdisp->dot_for_dot = TRUE;
gdisp->gimage = gimage;
gdisp->window_info_dialog = NULL;
gdisp->window_nav_dialog = NULL;
gdisp->depth = g_visual->depth;
gdisp->select = NULL;
gdisp->ID = display_num++;
@ -329,6 +331,10 @@ gdisplay_delete (GDisplay *gdisp)
if (gdisp->window_info_dialog)
info_window_free (gdisp->window_info_dialog);
/* Remove navigation dialog if we have one */
if(gdisp->window_nav_dialog)
nav_window_free(gdisp->window_nav_dialog);
/* set the active display to NULL if it was this display */
context = gimp_context_get_user ();
if (gimp_context_get_display (context) == gdisp)
@ -1010,7 +1016,7 @@ gdisplay_update_cursor (GDisplay *gdisp, int x, int y)
}
}
gdisplay_untransform_coords(gdisp, x, y, &t_x, &t_y, TRUE, TRUE);
gdisplay_untransform_coords(gdisp, x, y, &t_x, &t_y, FALSE, FALSE);
active_drawable = gimp_image_active_drawable (gdisp->gimage);
@ -1022,6 +1028,10 @@ gdisplay_update_cursor (GDisplay *gdisp, int x, int y)
t_y >= active_drawable->height)
{
gtk_label_set (GTK_LABEL (gdisp->cursor_label), "");
info_window_update_RGB(gdisp->window_info_dialog,
gdisp,
-1,
-1);
}
else
{
@ -1042,6 +1052,10 @@ gdisplay_update_cursor (GDisplay *gdisp, int x, int y)
(double) t_y * unit_factor / gdisp->gimage->yresolution);
}
gtk_label_set (GTK_LABEL (gdisp->cursor_label), buffer);
info_window_update_RGB(gdisp->window_info_dialog,
gdisp,
t_x,
t_y);
}
}
@ -1051,6 +1065,7 @@ gdisplay_update_cursor (GDisplay *gdisp, int x, int y)
if (new_cursor)
gdisplay_flush (gdisp);
}

View File

@ -111,6 +111,7 @@ struct _GDisplay
guint progressid; /* id of statusbar message for progress */
InfoDialog *window_info_dialog; /* dialog box for image information */
InfoDialog *window_nav_dialog; /* dialog box for image navigation */
int color_type; /* is this an RGB or GRAY colormap */

View File

@ -139,15 +139,14 @@ info_dialog_delete_callback (GtkWidget *w,
return TRUE;
}
/* public functions */
InfoDialog *
info_dialog_new (char *title)
static InfoDialog *
info_dialog_new_extended (char *title,gboolean inNotebook)
{
InfoDialog *idialog;
GtkWidget *shell;
GtkWidget *vbox;
GtkWidget *info_table;
GtkWidget *info_notebook;
idialog = g_new (InfoDialog, 1);
idialog->field_list = NULL;
@ -167,11 +166,28 @@ info_dialog_new (char *title)
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (shell)->vbox), vbox, TRUE, TRUE, 0);
info_table = gtk_table_new (2, 0, FALSE);
gtk_box_pack_start (GTK_BOX (vbox), info_table, TRUE, TRUE, 0);
if(inNotebook)
{
info_notebook = gtk_notebook_new();
gtk_notebook_append_page(GTK_NOTEBOOK(info_notebook),
info_table,
gtk_label_new (_("General")));
gtk_box_pack_start (GTK_BOX (vbox), info_notebook, TRUE, TRUE, 0);
}
else
{
info_notebook = NULL;
gtk_box_pack_start (GTK_BOX (vbox), info_table, TRUE, TRUE, 0);
}
idialog->shell = shell;
idialog->vbox = vbox;
idialog->info_table = info_table;
idialog->info_notebook = info_notebook;
if(inNotebook)
gtk_widget_show (idialog->info_notebook);
gtk_widget_show (idialog->info_table);
gtk_widget_show (idialog->vbox);
@ -179,6 +195,20 @@ info_dialog_new (char *title)
return idialog;
}
/* public functions */
InfoDialog *
info_dialog_notebook_new (char *title)
{
return info_dialog_new_extended(title,TRUE);
}
InfoDialog *
info_dialog_new (char *title)
{
return info_dialog_new_extended(title,FALSE);
}
void
info_dialog_free (InfoDialog *idialog)
{

View File

@ -50,6 +50,7 @@ struct _InfoDialog
GtkWidget *shell;
GtkWidget *vbox;
GtkWidget *info_table;
GtkWidget *info_notebook;
GSList *field_list;
int nfields;
@ -60,6 +61,7 @@ struct _InfoDialog
/* Info Dialog functions */
InfoDialog *info_dialog_new (gchar *title);
InfoDialog *info_dialog_notebook_new (gchar *title);
void info_dialog_free (InfoDialog *idialog);
void info_dialog_popup (InfoDialog *idialog);

View File

@ -15,6 +15,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "appenv.h"
#include "actionarea.h"
#include "colormaps.h"
@ -23,9 +24,12 @@
#include "gdisplay.h"
#include "gximage.h"
#include "interface.h"
#include "scroll.h"
#include "libgimp/gimpintl.h"
#include "libgimp/gimpunit.h"
#include "pixmaps/dropper.xpm"
#define MAX_BUF 256
@ -40,6 +44,12 @@ struct _InfoWinData
char shades_str[MAX_BUF];
char resolution_str[MAX_BUF];
char unit_str[MAX_BUF];
void *gdisp_ptr; /* I'a not happy 'bout this one */
GtkWidget *labelBvalue;
GtkWidget *labelGvalue;
GtkWidget *labelRvalue;
GtkWidget *labelAvalue;
gboolean showingPreview;
};
/* The different classes of visuals */
@ -104,6 +114,142 @@ info_window_close_callback (GtkWidget *widget,
info_dialog_popdown ((InfoDialog *) client_data);
}
static void
info_window_page_switch (GtkWidget *widget,
GtkNotebookPage *page,
gint page_num)
{
InfoDialog *info_win;
InfoWinData *iwd;
info_win = (InfoDialog *)gtk_object_get_user_data(GTK_OBJECT (widget));
iwd = (InfoWinData *)info_win->user_data;
/* Only deal with the second page */
if(page_num != 1)
{
iwd->showingPreview = FALSE;
return;
}
iwd->showingPreview = TRUE;
}
static void
info_window_image_preview_book(InfoDialog *info_win)
{
GtkWidget *hbox1;
GtkWidget *frame;
GtkWidget *alignment;
GtkWidget *table2;
GtkWidget *labelBvalue;
GtkWidget *labelGvalue;
GtkWidget *labelRvalue;
GtkWidget *labelAvalue;
GtkWidget *labelB;
GtkWidget *labelG;
GtkWidget *labelR;
GtkWidget *labelA;
GtkWidget *pixmapwid;
GdkPixmap *pixmap;
GdkBitmap *mask;
GtkStyle *style;
InfoWinData *iwd;
iwd = (InfoWinData *)info_win->user_data;
hbox1 = gtk_hbox_new (FALSE, 0);
gtk_widget_show (hbox1);
alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_widget_show (alignment);
frame = gtk_frame_new(NULL);
gtk_widget_show (frame);
gtk_box_pack_start (GTK_BOX (hbox1), alignment, TRUE, TRUE, 0);
table2 = gtk_table_new (5, 2, TRUE);
gtk_container_border_width (GTK_CONTAINER (table2), 2);
gtk_widget_show (table2);
gtk_container_add (GTK_CONTAINER (frame), table2);
gtk_container_add (GTK_CONTAINER (alignment), frame);
labelAvalue = gtk_label_new ("N/A");
gtk_widget_show (labelAvalue);
gtk_table_attach (GTK_TABLE (table2), labelAvalue, 1, 2, 4, 5,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
labelBvalue = gtk_label_new ("N/A");
gtk_widget_show (labelBvalue);
gtk_table_attach (GTK_TABLE (table2), labelBvalue, 1, 2, 3, 4,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
labelGvalue = gtk_label_new ("N/A");
gtk_widget_show (labelGvalue);
gtk_table_attach (GTK_TABLE (table2), labelGvalue, 1, 2, 2, 3,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
labelRvalue = gtk_label_new ("N/A");
gtk_widget_show (labelRvalue);
gtk_table_attach (GTK_TABLE (table2), labelRvalue, 1, 2, 1, 2,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
labelA = gtk_label_new ("A:");
gtk_widget_show (labelA);
gtk_table_attach (GTK_TABLE (table2), labelA, 0, 1, 4, 5,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
labelB = gtk_label_new ("B:");
gtk_widget_show (labelB);
gtk_table_attach (GTK_TABLE (table2), labelB, 0, 1, 3, 4,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
labelG = gtk_label_new ("G:");
gtk_widget_show (labelG);
gtk_table_attach (GTK_TABLE (table2), labelG, 0, 1, 2, 3,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
labelR = gtk_label_new ("R:");
gtk_widget_show (labelR);
gtk_table_attach (GTK_TABLE (table2), labelR, 0, 1, 1, 2,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
gtk_widget_realize(info_win->shell);
style = gtk_widget_get_style (info_win->shell);
pixmap = gdk_pixmap_create_from_xpm_d (info_win->shell->window, &mask,
&style->bg[GTK_STATE_NORMAL],
dropper_xpm);
pixmapwid = gtk_pixmap_new (pixmap, mask);
gtk_misc_set_alignment (GTK_MISC (pixmapwid), 0.2, 0.2);
gtk_table_attach (GTK_TABLE (table2), pixmapwid, 0, 2, 0, 1,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
gtk_widget_show (pixmapwid);
gtk_notebook_append_page(GTK_NOTEBOOK(info_win->info_notebook),
hbox1,
gtk_label_new (_("Extended")));
/* Set back to first page */
gtk_notebook_set_page(GTK_NOTEBOOK(info_win->info_notebook),0);
gtk_object_set_user_data(GTK_OBJECT (info_win->info_notebook),
(gpointer)info_win);
gtk_signal_connect (GTK_OBJECT (info_win->info_notebook), "switch_page",
GTK_SIGNAL_FUNC (info_window_page_switch), NULL);
iwd->labelBvalue = labelBvalue;
iwd->labelGvalue = labelGvalue;
iwd->labelRvalue = labelRvalue;
iwd->labelAvalue = labelAvalue;
}
/* displays information:
* image name
* image width, height
@ -136,7 +282,7 @@ info_window_create (void *gdisp_ptr)
/* create the info dialog */
title_buf = g_strdup_printf (_("%s: Window Info"), title);
info_win = info_dialog_new (title_buf);
info_win = info_dialog_notebook_new (title_buf);
g_free (title_buf);
iwd = (InfoWinData *) g_malloc (sizeof (InfoWinData));
@ -149,6 +295,7 @@ info_window_create (void *gdisp_ptr)
iwd->visual_class_str[0] = '\0';
iwd->visual_depth_str[0] = '\0';
iwd->shades_str[0] = '\0';
iwd->showingPreview = FALSE;
/* add the information fields */
info_dialog_add_label (info_win, _("Dimensions (w x h):"),
@ -178,6 +325,9 @@ info_window_create (void *gdisp_ptr)
/* update the fields */
info_window_update (info_win, gdisp_ptr);
/* Add extra tabs */
info_window_image_preview_book(info_win);
/* Create the action area */
action_items[0].user_data = info_win;
build_action_area (GTK_DIALOG (info_win->shell), action_items, 1, 0);
@ -185,6 +335,61 @@ info_window_create (void *gdisp_ptr)
return info_win;
}
void
info_window_update_RGB (InfoDialog *info_win,
void *gdisp_ptr,
gdouble tx,
gdouble ty)
{
GDisplay *gdisp;
InfoWinData *iwd;
char buff[5];
guchar *color;
gint has_alpha;
gint sample_type;
if(!info_win)
return;
gdisp = (GDisplay *) gdisp_ptr;
iwd = (InfoWinData *) info_win->user_data;
if(!iwd || iwd->showingPreview == FALSE)
return;
/* gimage_active_drawable (gdisp->gimage) */
if (!(color = gimp_image_get_color_at(gdisp->gimage, tx, ty))
|| (tx < 0.0 && ty < 0.0))
{
g_snprintf(buff,5,"%4s","N/A");
gtk_label_set_text(GTK_LABEL(iwd->labelBvalue),buff);
gtk_label_set_text(GTK_LABEL(iwd->labelGvalue),buff);
gtk_label_set_text(GTK_LABEL(iwd->labelRvalue),buff);
gtk_label_set_text(GTK_LABEL(iwd->labelAvalue),buff);
return;
}
g_snprintf(buff,5,"%4d",(gint)color[BLUE_PIX]);
gtk_label_set_text(GTK_LABEL(iwd->labelBvalue),buff);
g_snprintf(buff,5,"%4d",(gint)color[GREEN_PIX]);
gtk_label_set_text(GTK_LABEL(iwd->labelGvalue),buff);
g_snprintf(buff,5,"%4d",(gint)color[RED_PIX]);
gtk_label_set_text(GTK_LABEL(iwd->labelRvalue),buff);
sample_type = gimp_image_composite_type (gdisp->gimage);
has_alpha = TYPE_HAS_ALPHA (sample_type);
if(has_alpha)
g_snprintf(buff,5,"%4d",(gint)color[ALPHA_PIX]);
else
g_snprintf(buff,5,"%4s","N/A");
gtk_label_set_text(GTK_LABEL(iwd->labelAvalue),buff);
g_free(color);
}
void
info_window_free (InfoDialog *info_win)
{

View File

@ -23,6 +23,9 @@
InfoDialog *info_window_create (void *);
void info_window_free (InfoDialog *);
void info_window_update (InfoDialog *, void *);
void info_window_update_RGB (InfoDialog *,
void *,
gdouble,
gdouble);
#endif /* __INFO_WINDOW_H__ */

View File

@ -26,6 +26,7 @@
#include "general.h"
#include "gimpcontext.h"
#include "gimprc.h"
#include "info_window.h"
#include "interface.h"
#include "layer_select.h"
#include "move.h"
@ -199,6 +200,10 @@ gdisplay_canvas_events (GtkWidget *canvas,
case GDK_LEAVE_NOTIFY:
gdisplay_update_cursor (gdisp, 0, 0);
gtk_label_set_text (GTK_LABEL (gdisp->cursor_label), "");
info_window_update_RGB(gdisp->window_info_dialog,
gdisp,
-1,
-1);
case GDK_PROXIMITY_OUT:
gdisp->proximity = FALSE;

View File

@ -26,6 +26,7 @@
#include "general.h"
#include "gimpcontext.h"
#include "gimprc.h"
#include "info_window.h"
#include "interface.h"
#include "layer_select.h"
#include "move.h"
@ -199,6 +200,10 @@ gdisplay_canvas_events (GtkWidget *canvas,
case GDK_LEAVE_NOTIFY:
gdisplay_update_cursor (gdisp, 0, 0);
gtk_label_set_text (GTK_LABEL (gdisp->cursor_label), "");
info_window_update_RGB(gdisp->window_info_dialog,
gdisp,
-1,
-1);
case GDK_PROXIMITY_OUT:
gdisp->proximity = FALSE;

View File

@ -21,7 +21,7 @@
#include "gdisplay.h"
#include "gdisplay_ops.h"
#include "gimprc.h"
#include "info_window.h"
#include "nav_window.h"
#include "scale.h"
#include "tools.h"
@ -257,4 +257,7 @@ setup_scale (GDisplay *gdisp)
gtk_widget_draw (GTK_WIDGET (hruler), NULL);
gtk_widget_draw (GTK_WIDGET (vruler), NULL);
if (gdisp->window_nav_dialog)
nav_window_update_window_marker(gdisp->window_nav_dialog);
}

View File

@ -21,6 +21,7 @@
#include "scroll.h"
#include "cursorutil.h"
#include "tools.h"
#include "nav_window.h"
/* This is the delay before dithering begins
@ -28,9 +29,6 @@
*/
#define DITHER_DELAY 250 /* milliseconds */
/* Locally defined functions */
static int scroll_display (GDisplay *, int, int);
/* STATIC variables */
/* These are the values of the initial pointer grab */
static int startx, starty;
@ -127,10 +125,10 @@ scroll_to_pointer_position (GDisplay *gdisp,
}
static int
int
scroll_display (GDisplay *gdisp,
int x_offset,
int y_offset)
gint x_offset,
gint y_offset)
{
int old_x, old_y;
int src_x, src_y;
@ -201,6 +199,8 @@ scroll_display (GDisplay *gdisp,
if (x_offset || y_offset)
gdisplays_flush ();
if (gdisp->window_nav_dialog)
nav_window_update_window_marker(gdisp->window_nav_dialog);
/* Make sure graphics expose events are processed before scrolling
* again */

View File

@ -35,4 +35,8 @@ void end_grab_and_scroll (GDisplay *, GdkEventButton *);
void grab_and_scroll (GDisplay *, GdkEventMotion *);
void scroll_to_pointer_position (GDisplay *, GdkEventMotion *);
/* generic scroll-by-offset function */
gint scroll_display (GDisplay *, gint, gint);
#endif /* __SCROLL_H__ */

View File

@ -35,6 +35,7 @@
#include "interface.h"
#include "lc_dialog.h"
#include "menus.h"
#include "nav_window.h"
#include "plug_in.h"
#include "qmask.h"
#include "scale.h"
@ -97,6 +98,7 @@ gdisplay_new (GimpImage *gimage,
gdisp->dot_for_dot = TRUE;
gdisp->gimage = gimage;
gdisp->window_info_dialog = NULL;
gdisp->window_nav_dialog = NULL;
gdisp->depth = g_visual->depth;
gdisp->select = NULL;
gdisp->ID = display_num++;
@ -329,6 +331,10 @@ gdisplay_delete (GDisplay *gdisp)
if (gdisp->window_info_dialog)
info_window_free (gdisp->window_info_dialog);
/* Remove navigation dialog if we have one */
if(gdisp->window_nav_dialog)
nav_window_free(gdisp->window_nav_dialog);
/* set the active display to NULL if it was this display */
context = gimp_context_get_user ();
if (gimp_context_get_display (context) == gdisp)
@ -1010,7 +1016,7 @@ gdisplay_update_cursor (GDisplay *gdisp, int x, int y)
}
}
gdisplay_untransform_coords(gdisp, x, y, &t_x, &t_y, TRUE, TRUE);
gdisplay_untransform_coords(gdisp, x, y, &t_x, &t_y, FALSE, FALSE);
active_drawable = gimp_image_active_drawable (gdisp->gimage);
@ -1022,6 +1028,10 @@ gdisplay_update_cursor (GDisplay *gdisp, int x, int y)
t_y >= active_drawable->height)
{
gtk_label_set (GTK_LABEL (gdisp->cursor_label), "");
info_window_update_RGB(gdisp->window_info_dialog,
gdisp,
-1,
-1);
}
else
{
@ -1042,6 +1052,10 @@ gdisplay_update_cursor (GDisplay *gdisp, int x, int y)
(double) t_y * unit_factor / gdisp->gimage->yresolution);
}
gtk_label_set (GTK_LABEL (gdisp->cursor_label), buffer);
info_window_update_RGB(gdisp->window_info_dialog,
gdisp,
t_x,
t_y);
}
}
@ -1051,6 +1065,7 @@ gdisplay_update_cursor (GDisplay *gdisp, int x, int y)
if (new_cursor)
gdisplay_flush (gdisp);
}

View File

@ -111,6 +111,7 @@ struct _GDisplay
guint progressid; /* id of statusbar message for progress */
InfoDialog *window_info_dialog; /* dialog box for image information */
InfoDialog *window_nav_dialog; /* dialog box for image navigation */
int color_type; /* is this an RGB or GRAY colormap */

View File

@ -26,6 +26,7 @@
#include "general.h"
#include "gimpcontext.h"
#include "gimprc.h"
#include "info_window.h"
#include "interface.h"
#include "layer_select.h"
#include "move.h"
@ -199,6 +200,10 @@ gdisplay_canvas_events (GtkWidget *canvas,
case GDK_LEAVE_NOTIFY:
gdisplay_update_cursor (gdisp, 0, 0);
gtk_label_set_text (GTK_LABEL (gdisp->cursor_label), "");
info_window_update_RGB(gdisp->window_info_dialog,
gdisp,
-1,
-1);
case GDK_PROXIMITY_OUT:
gdisp->proximity = FALSE;

View File

@ -21,7 +21,7 @@
#include "gdisplay.h"
#include "gdisplay_ops.h"
#include "gimprc.h"
#include "info_window.h"
#include "nav_window.h"
#include "scale.h"
#include "tools.h"
@ -257,4 +257,7 @@ setup_scale (GDisplay *gdisp)
gtk_widget_draw (GTK_WIDGET (hruler), NULL);
gtk_widget_draw (GTK_WIDGET (vruler), NULL);
if (gdisp->window_nav_dialog)
nav_window_update_window_marker(gdisp->window_nav_dialog);
}

View File

@ -21,6 +21,7 @@
#include "scroll.h"
#include "cursorutil.h"
#include "tools.h"
#include "nav_window.h"
/* This is the delay before dithering begins
@ -28,9 +29,6 @@
*/
#define DITHER_DELAY 250 /* milliseconds */
/* Locally defined functions */
static int scroll_display (GDisplay *, int, int);
/* STATIC variables */
/* These are the values of the initial pointer grab */
static int startx, starty;
@ -127,10 +125,10 @@ scroll_to_pointer_position (GDisplay *gdisp,
}
static int
int
scroll_display (GDisplay *gdisp,
int x_offset,
int y_offset)
gint x_offset,
gint y_offset)
{
int old_x, old_y;
int src_x, src_y;
@ -201,6 +199,8 @@ scroll_display (GDisplay *gdisp,
if (x_offset || y_offset)
gdisplays_flush ();
if (gdisp->window_nav_dialog)
nav_window_update_window_marker(gdisp->window_nav_dialog);
/* Make sure graphics expose events are processed before scrolling
* again */

View File

@ -35,4 +35,8 @@ void end_grab_and_scroll (GDisplay *, GdkEventButton *);
void grab_and_scroll (GDisplay *, GdkEventMotion *);
void scroll_to_pointer_position (GDisplay *, GdkEventMotion *);
/* generic scroll-by-offset function */
gint scroll_display (GDisplay *, gint, gint);
#endif /* __SCROLL_H__ */

View File

@ -0,0 +1,799 @@
/* 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 "appenv.h"
#include "actionarea.h"
#include "colormaps.h"
#include "info_dialog.h"
#include "info_window.h"
#include "gdisplay.h"
#include "gximage.h"
#include "interface.h"
#include "scroll.h"
#include "libgimp/gimpintl.h"
#include "libgimp/gimpunit.h"
#define MAX_BUF 256
#define PREVIEW_MASK GDK_EXPOSURE_MASK | \
GDK_MOTION_NOTIFY | \
GDK_POINTER_MOTION_MASK | \
GDK_BUTTON_PRESS_MASK | \
GDK_BUTTON_RELEASE_MASK | \
GDK_BUTTON_MOTION_MASK | \
GDK_KEY_PRESS_MASK | \
GDK_KEY_RELEASE_MASK
/* Navigation preview sizes */
#define NAV_PREVIEW_WIDTH 112
#define NAV_PREVIEW_HEIGHT 112
#define BORDER_PEN_WIDTH 3
typedef struct _NavWinData NavWinData;
struct _NavWinData
{
gboolean showingPreview;
GtkWidget *preview;
void *gdisp_ptr; /* I'a not happy 'bout this one */
GtkWidget *previewBox;
GtkWidget *previewAlign;
gdouble ratio;
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 left corner 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 */
gboolean block_window_marker; /* Block redraws of window marker */
gint nav_preview_width;
gint nav_preview_height;
};
static gint
nav_window_preview_events (GtkWidget *,
GdkEvent *,
gpointer *);
static gint
nav_window_expose_events (GtkWidget *,
GdkEvent *,
gpointer *);
#if 0
static gint
nav_window_preview_resized (GtkWidget *,
GtkAllocation *,
gpointer *);
#endif /* 0 */
static void
nav_window_update_preview (NavWinData *);
static void
destroy_preview_widget (NavWinData *);
static void
create_preview_widget (NavWinData *);
void
nav_window_update_window_marker(InfoDialog *);
static void
nav_window_draw_sqr(NavWinData *,
gboolean,
gint ,
gint ,
gint ,
gint );
static void
set_size_data(NavWinData *);
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; ALT. Needs to be sorted out */
info_dialog_popdown ((InfoDialog *) client_data);
}
static void
nav_window_disp_area(NavWinData *iwd,GDisplay *gdisp)
{
GimpImage *gimage;
gint newwidth;
gint newheight;
gdouble ratio; /* Screen res ratio */
gboolean need_update = FALSE;
/* Calculate preview size */
gimage = gdisp->gimage;
ratio = ((gdouble)SCALEDEST(gdisp))/((gdouble)SCALESRC(gdisp));
iwd->dispx = gdisp->offset_x*iwd->ratio/ratio;
iwd->dispy = gdisp->offset_y*iwd->ratio/ratio;
iwd->dispwidth = (gdisp->disp_width*iwd->ratio)/ratio;
iwd->dispheight = (gdisp->disp_height*iwd->ratio)/ratio;
newwidth = gimage->width;
newheight = gimage->height;
if((iwd->imagewidth > 0 && newwidth != iwd->imagewidth) ||
(iwd->imageheight > 0 && newheight != iwd->imageheight))
{
/* Must change the preview size */
destroy_preview_widget(iwd);
create_preview_widget(iwd);
need_update = TRUE;
}
iwd->imagewidth = newwidth;
iwd->imageheight = newheight;
/* Normalise */
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(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);
}
}
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,
iwd->dispheight);
}
/* gdk_draw_rectangle (iwd->preview->window, iwd->gc, FALSE, */
/* 10,20, */
/* 40,50); */
gdk_draw_rectangle (iwd->preview->window, iwd->gc, FALSE,
x,y,
w,
h);
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 (sel_width > sel_height) {
pwidth = MIN(sel_width, iwd->nav_preview_width);
pheight = sel_height * pwidth / sel_width;
iwd->ratio = (gdouble)pwidth / ((gdouble)sel_width);
} else {
pheight = MIN(sel_height, iwd->nav_preview_height);
pwidth = sel_width * pheight / sel_height;
iwd->ratio = (gdouble)pheight / ((gdouble)sel_height);
}
iwd->pwidth = pwidth;
iwd->pheight = pheight;
}
static void
create_preview_widget(NavWinData *iwd)
{
GtkWidget *hbox;
GtkWidget *image;
GtkWidget *frame;
gdouble ratio;
GDisplay *gdisp;
gdisp = (GDisplay *)(iwd->gdisp_ptr);
ratio = ((gdouble)SCALEDEST(gdisp))/((gdouble)SCALESRC(gdisp));
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);
iwd->preview = image;
gtk_widget_show (image);
gtk_preview_set_dither (GTK_PREVIEW (image), GDK_RGB_DITHER_MAX);
gtk_widget_set_events( GTK_WIDGET(image), PREVIEW_MASK );
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_grab_focus(image);
}
#if 0
static void
info_window_page_switch (GtkWidget *widget,
GtkNotebookPage *page,
gint page_num)
{
InfoDialog *info_win;
InfoWinData *iwd;
info_win = (InfoDialog *)gtk_object_get_user_data(GTK_OBJECT (widget));
iwd = (InfoWinData *)info_win->user_data;
/* Only deal with the second page */
if(page_num != 1)
{
iwd->showingPreview = FALSE;
return;
}
iwd->showingPreview = TRUE;
}
#endif /* 0 */
static void
update_real_view(NavWinData *iwd,gint tx,gint ty)
{
GDisplay *gdisp;
gdouble ratio;
gint xoffset;
gint yoffset;
gdisp = (GDisplay *) iwd->gdisp_ptr;
ratio = ((gdouble)SCALEDEST(gdisp))/((gdouble)SCALESRC(gdisp));
xoffset = tx - iwd->dispx;
yoffset = ty - iwd->dispy;
xoffset = (gint)(((gdouble)xoffset*ratio)/iwd->ratio);
yoffset = (gint)(((gdouble)yoffset*ratio)/iwd->ratio);
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;
gchar *src, *buf;
gint x,y,has_alpha;
gint pwidth, pheight;
GimpImage *gimage;
gdisp = (GDisplay *) iwd->gdisp_ptr;
/* Calculate preview size */
gimage = ((GDisplay *)(iwd->gdisp_ptr))->gimage;
/* Min size is 2 */
pwidth = iwd->pwidth;
pheight = iwd->pheight;
preview_buf = gimp_image_construct_composite_preview (gimage,
MAX (pwidth, 2),
MAX (pheight, 2));
buf = g_new (gchar, iwd->nav_preview_width * 3);
src = (gchar *) temp_buf_data (preview_buf);
has_alpha = (preview_buf->bytes == 2 || preview_buf->bytes == 4);
for (y = 0; y <preview_buf->height ; y++)
{
if (preview_buf->bytes == (1+has_alpha))
for (x = 0; x < preview_buf->width; x++)
{
buf[x*3+0] = src[x];
buf[x*3+1] = src[x];
buf[x*3+2] = src[x];
}
else
for (x = 0; x < preview_buf->width; x++)
{
gint stride = 3 + has_alpha;
buf[x*3+0] = src[x*stride+0];
buf[x*3+1] = src[x*stride+1];
buf[x*3+2] = src[x*stride+2];
}
gtk_preview_draw_row (GTK_PREVIEW (iwd->preview),
(guchar *)buf, 0, y, preview_buf->width);
src += preview_buf->width * preview_buf->bytes;
}
g_free (buf);
temp_buf_free (preview_buf);
nav_window_disp_area(iwd,gdisp);
}
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;
}
#if 0
static gint
nav_window_preview_resized (GtkWidget *widget,
GtkAllocation *alloc,
gpointer *data)
{
NavWinData *iwd;
iwd = (NavWinData *)data;
if(!iwd || !iwd->preview)
return FALSE;
printf("Now at [x,y] = [%d,%d] [w,h] = [%d,%d]\n",
alloc->x,alloc->y,
alloc->width,alloc->height);
if(iwd->nav_preview_width == alloc->width &&
iwd->nav_preview_height == alloc->height)
return FALSE;
iwd->nav_preview_width = alloc->width;
iwd->nav_preview_height = alloc->height;
set_size_data(iwd);
gtk_preview_size(GTK_PREVIEW(iwd->preview),alloc->width,alloc->height);
nav_window_update_preview(iwd);
nav_window_draw_sqr(iwd,FALSE,
iwd->dispx,iwd->dispy,
iwd->dispwidth,iwd->dispheight);
#if 0
destroy_preview_widget(iwd);
create_preview_widget(iwd);
nav_window_update_preview(iwd);
nav_window_update_preview(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);
#endif /* 0 */
return FALSE;
}
#endif /* 0 */
static gint
nav_window_preview_events (GtkWidget *widget,
GdkEvent *event,
gpointer *data)
{
NavWinData *iwd;
GDisplay *gdisp;
GdkEventButton *bevent;
GdkEventMotion *mevent;
gint tx,ty;
iwd = (NavWinData *)data;
if(!iwd)
return FALSE;
gdisp = (GDisplay *) iwd->gdisp_ptr;
switch (event->type)
{
case GDK_EXPOSE:
break;
case GDK_MAP:
nav_window_update_preview(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))
{
iwd->motion_offsetx = tx - iwd->dispx;
iwd->motion_offsety = ty - iwd->dispy;
iwd->sq_grabbed = TRUE;
gtk_grab_add(widget);
}
else
{
/* 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);
}
break;
default:
}
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);
break;
default:
}
break;
case GDK_MOTION_NOTIFY:
mevent = (GdkEventMotion *) event;
if(!iwd->sq_grabbed)
break;
tx = mevent->x;
ty = mevent->y;
if(tx < 0)
{
tx = 0;
}
if(tx > iwd->pwidth)
{
tx = iwd->pwidth;
}
if(ty < 0)
{
ty = 0;
}
if(ty > iwd->pheight)
{
ty = iwd->pwidth;
}
tx = tx - iwd->motion_offsetx;
ty = ty - iwd->motion_offsety;
if(tx < 0 || (tx + iwd->dispwidth) >= iwd->pwidth)
{
iwd->motion_offsetx = mevent->x - iwd->dispx;
tx = iwd->dispx;
}
if(ty < 0 || (ty + iwd->dispheight) >= iwd->pheight)
{
iwd->motion_offsety = mevent->y - iwd->dispy;
ty = iwd->dispy;
}
/* Update the real display */
update_real_view(iwd,tx,ty);
nav_window_draw_sqr(iwd,
TRUE,
tx,ty,
iwd->dispwidth,iwd->dispheight);
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)
return FALSE;
gdisp = (GDisplay *) iwd->gdisp_ptr;
switch (event->type)
{
case GDK_EXPOSE:
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);
break;
case GDK_KEY_PRESS:
/* hack for the update preview... needs to be fixed */
nav_window_update_preview(iwd);
gtk_widget_draw(iwd->preview, NULL);
break;
default:
break;
}
return FALSE;
}
static GtkWidget *
info_window_image_preview_new(InfoDialog *info_win)
{
GtkWidget *hbox1;
GtkWidget *alignment;
NavWinData *iwd;
iwd = (NavWinData *)info_win->user_data;
hbox1 = gtk_hbox_new (FALSE, 0);
gtk_widget_show (hbox1);
gtk_widget_realize(info_win->shell);
/* need gc to draw the preview sqr with */
iwd->gc = gdk_gc_new(info_win->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);
return hbox1;
}
static ActionAreaItem action_items[] =
{
{ N_("Close"), nav_window_close_callback, NULL, NULL },
};
InfoDialog *
nav_window_create (void *gdisp_ptr)
{
InfoDialog *info_win;
GDisplay *gdisp;
NavWinData *iwd;
GtkWidget *container;
char *title;
char *title_buf;
int type;
gdisp = (GDisplay *) gdisp_ptr;
title = g_basename (gimage_filename (gdisp->gimage));
type = gimage_base_type (gdisp->gimage);
/* create the info dialog */
title_buf = g_strdup_printf (_("%s: Window Navigation"), title);
info_win = info_dialog_new (title_buf);
g_free (title_buf);
/* gtk_window_set_policy (GTK_WINDOW (info_win->shell), */
/* FALSE,FALSE,FALSE); */
iwd = (NavWinData *) g_malloc (sizeof (NavWinData));
info_win->user_data = iwd;
iwd->showingPreview = TRUE;
iwd->preview = 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_WIDTH;
iwd->nav_preview_height = NAV_PREVIEW_HEIGHT;
/* 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);
/* Create the action area */
action_items[0].user_data = info_win;
build_action_area (GTK_DIALOG (info_win->shell), action_items, 1, 0);
return info_win;
}
void
nav_window_update_window_marker(InfoDialog *info_win)
{
NavWinData *iwd;
if(!info_win)
return;
iwd = (NavWinData *)info_win->user_data;
if(!iwd ||
iwd->showingPreview == FALSE ||
iwd->block_window_marker == TRUE)
return;
/* 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_window_free (InfoDialog *info_win)
{
g_free (info_win->user_data);
info_dialog_free (info_win);
}

View File

@ -0,0 +1,799 @@
/* 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 "appenv.h"
#include "actionarea.h"
#include "colormaps.h"
#include "info_dialog.h"
#include "info_window.h"
#include "gdisplay.h"
#include "gximage.h"
#include "interface.h"
#include "scroll.h"
#include "libgimp/gimpintl.h"
#include "libgimp/gimpunit.h"
#define MAX_BUF 256
#define PREVIEW_MASK GDK_EXPOSURE_MASK | \
GDK_MOTION_NOTIFY | \
GDK_POINTER_MOTION_MASK | \
GDK_BUTTON_PRESS_MASK | \
GDK_BUTTON_RELEASE_MASK | \
GDK_BUTTON_MOTION_MASK | \
GDK_KEY_PRESS_MASK | \
GDK_KEY_RELEASE_MASK
/* Navigation preview sizes */
#define NAV_PREVIEW_WIDTH 112
#define NAV_PREVIEW_HEIGHT 112
#define BORDER_PEN_WIDTH 3
typedef struct _NavWinData NavWinData;
struct _NavWinData
{
gboolean showingPreview;
GtkWidget *preview;
void *gdisp_ptr; /* I'a not happy 'bout this one */
GtkWidget *previewBox;
GtkWidget *previewAlign;
gdouble ratio;
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 left corner 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 */
gboolean block_window_marker; /* Block redraws of window marker */
gint nav_preview_width;
gint nav_preview_height;
};
static gint
nav_window_preview_events (GtkWidget *,
GdkEvent *,
gpointer *);
static gint
nav_window_expose_events (GtkWidget *,
GdkEvent *,
gpointer *);
#if 0
static gint
nav_window_preview_resized (GtkWidget *,
GtkAllocation *,
gpointer *);
#endif /* 0 */
static void
nav_window_update_preview (NavWinData *);
static void
destroy_preview_widget (NavWinData *);
static void
create_preview_widget (NavWinData *);
void
nav_window_update_window_marker(InfoDialog *);
static void
nav_window_draw_sqr(NavWinData *,
gboolean,
gint ,
gint ,
gint ,
gint );
static void
set_size_data(NavWinData *);
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; ALT. Needs to be sorted out */
info_dialog_popdown ((InfoDialog *) client_data);
}
static void
nav_window_disp_area(NavWinData *iwd,GDisplay *gdisp)
{
GimpImage *gimage;
gint newwidth;
gint newheight;
gdouble ratio; /* Screen res ratio */
gboolean need_update = FALSE;
/* Calculate preview size */
gimage = gdisp->gimage;
ratio = ((gdouble)SCALEDEST(gdisp))/((gdouble)SCALESRC(gdisp));
iwd->dispx = gdisp->offset_x*iwd->ratio/ratio;
iwd->dispy = gdisp->offset_y*iwd->ratio/ratio;
iwd->dispwidth = (gdisp->disp_width*iwd->ratio)/ratio;
iwd->dispheight = (gdisp->disp_height*iwd->ratio)/ratio;
newwidth = gimage->width;
newheight = gimage->height;
if((iwd->imagewidth > 0 && newwidth != iwd->imagewidth) ||
(iwd->imageheight > 0 && newheight != iwd->imageheight))
{
/* Must change the preview size */
destroy_preview_widget(iwd);
create_preview_widget(iwd);
need_update = TRUE;
}
iwd->imagewidth = newwidth;
iwd->imageheight = newheight;
/* Normalise */
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(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);
}
}
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,
iwd->dispheight);
}
/* gdk_draw_rectangle (iwd->preview->window, iwd->gc, FALSE, */
/* 10,20, */
/* 40,50); */
gdk_draw_rectangle (iwd->preview->window, iwd->gc, FALSE,
x,y,
w,
h);
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 (sel_width > sel_height) {
pwidth = MIN(sel_width, iwd->nav_preview_width);
pheight = sel_height * pwidth / sel_width;
iwd->ratio = (gdouble)pwidth / ((gdouble)sel_width);
} else {
pheight = MIN(sel_height, iwd->nav_preview_height);
pwidth = sel_width * pheight / sel_height;
iwd->ratio = (gdouble)pheight / ((gdouble)sel_height);
}
iwd->pwidth = pwidth;
iwd->pheight = pheight;
}
static void
create_preview_widget(NavWinData *iwd)
{
GtkWidget *hbox;
GtkWidget *image;
GtkWidget *frame;
gdouble ratio;
GDisplay *gdisp;
gdisp = (GDisplay *)(iwd->gdisp_ptr);
ratio = ((gdouble)SCALEDEST(gdisp))/((gdouble)SCALESRC(gdisp));
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);
iwd->preview = image;
gtk_widget_show (image);
gtk_preview_set_dither (GTK_PREVIEW (image), GDK_RGB_DITHER_MAX);
gtk_widget_set_events( GTK_WIDGET(image), PREVIEW_MASK );
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_grab_focus(image);
}
#if 0
static void
info_window_page_switch (GtkWidget *widget,
GtkNotebookPage *page,
gint page_num)
{
InfoDialog *info_win;
InfoWinData *iwd;
info_win = (InfoDialog *)gtk_object_get_user_data(GTK_OBJECT (widget));
iwd = (InfoWinData *)info_win->user_data;
/* Only deal with the second page */
if(page_num != 1)
{
iwd->showingPreview = FALSE;
return;
}
iwd->showingPreview = TRUE;
}
#endif /* 0 */
static void
update_real_view(NavWinData *iwd,gint tx,gint ty)
{
GDisplay *gdisp;
gdouble ratio;
gint xoffset;
gint yoffset;
gdisp = (GDisplay *) iwd->gdisp_ptr;
ratio = ((gdouble)SCALEDEST(gdisp))/((gdouble)SCALESRC(gdisp));
xoffset = tx - iwd->dispx;
yoffset = ty - iwd->dispy;
xoffset = (gint)(((gdouble)xoffset*ratio)/iwd->ratio);
yoffset = (gint)(((gdouble)yoffset*ratio)/iwd->ratio);
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;
gchar *src, *buf;
gint x,y,has_alpha;
gint pwidth, pheight;
GimpImage *gimage;
gdisp = (GDisplay *) iwd->gdisp_ptr;
/* Calculate preview size */
gimage = ((GDisplay *)(iwd->gdisp_ptr))->gimage;
/* Min size is 2 */
pwidth = iwd->pwidth;
pheight = iwd->pheight;
preview_buf = gimp_image_construct_composite_preview (gimage,
MAX (pwidth, 2),
MAX (pheight, 2));
buf = g_new (gchar, iwd->nav_preview_width * 3);
src = (gchar *) temp_buf_data (preview_buf);
has_alpha = (preview_buf->bytes == 2 || preview_buf->bytes == 4);
for (y = 0; y <preview_buf->height ; y++)
{
if (preview_buf->bytes == (1+has_alpha))
for (x = 0; x < preview_buf->width; x++)
{
buf[x*3+0] = src[x];
buf[x*3+1] = src[x];
buf[x*3+2] = src[x];
}
else
for (x = 0; x < preview_buf->width; x++)
{
gint stride = 3 + has_alpha;
buf[x*3+0] = src[x*stride+0];
buf[x*3+1] = src[x*stride+1];
buf[x*3+2] = src[x*stride+2];
}
gtk_preview_draw_row (GTK_PREVIEW (iwd->preview),
(guchar *)buf, 0, y, preview_buf->width);
src += preview_buf->width * preview_buf->bytes;
}
g_free (buf);
temp_buf_free (preview_buf);
nav_window_disp_area(iwd,gdisp);
}
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;
}
#if 0
static gint
nav_window_preview_resized (GtkWidget *widget,
GtkAllocation *alloc,
gpointer *data)
{
NavWinData *iwd;
iwd = (NavWinData *)data;
if(!iwd || !iwd->preview)
return FALSE;
printf("Now at [x,y] = [%d,%d] [w,h] = [%d,%d]\n",
alloc->x,alloc->y,
alloc->width,alloc->height);
if(iwd->nav_preview_width == alloc->width &&
iwd->nav_preview_height == alloc->height)
return FALSE;
iwd->nav_preview_width = alloc->width;
iwd->nav_preview_height = alloc->height;
set_size_data(iwd);
gtk_preview_size(GTK_PREVIEW(iwd->preview),alloc->width,alloc->height);
nav_window_update_preview(iwd);
nav_window_draw_sqr(iwd,FALSE,
iwd->dispx,iwd->dispy,
iwd->dispwidth,iwd->dispheight);
#if 0
destroy_preview_widget(iwd);
create_preview_widget(iwd);
nav_window_update_preview(iwd);
nav_window_update_preview(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);
#endif /* 0 */
return FALSE;
}
#endif /* 0 */
static gint
nav_window_preview_events (GtkWidget *widget,
GdkEvent *event,
gpointer *data)
{
NavWinData *iwd;
GDisplay *gdisp;
GdkEventButton *bevent;
GdkEventMotion *mevent;
gint tx,ty;
iwd = (NavWinData *)data;
if(!iwd)
return FALSE;
gdisp = (GDisplay *) iwd->gdisp_ptr;
switch (event->type)
{
case GDK_EXPOSE:
break;
case GDK_MAP:
nav_window_update_preview(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))
{
iwd->motion_offsetx = tx - iwd->dispx;
iwd->motion_offsety = ty - iwd->dispy;
iwd->sq_grabbed = TRUE;
gtk_grab_add(widget);
}
else
{
/* 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);
}
break;
default:
}
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);
break;
default:
}
break;
case GDK_MOTION_NOTIFY:
mevent = (GdkEventMotion *) event;
if(!iwd->sq_grabbed)
break;
tx = mevent->x;
ty = mevent->y;
if(tx < 0)
{
tx = 0;
}
if(tx > iwd->pwidth)
{
tx = iwd->pwidth;
}
if(ty < 0)
{
ty = 0;
}
if(ty > iwd->pheight)
{
ty = iwd->pwidth;
}
tx = tx - iwd->motion_offsetx;
ty = ty - iwd->motion_offsety;
if(tx < 0 || (tx + iwd->dispwidth) >= iwd->pwidth)
{
iwd->motion_offsetx = mevent->x - iwd->dispx;
tx = iwd->dispx;
}
if(ty < 0 || (ty + iwd->dispheight) >= iwd->pheight)
{
iwd->motion_offsety = mevent->y - iwd->dispy;
ty = iwd->dispy;
}
/* Update the real display */
update_real_view(iwd,tx,ty);
nav_window_draw_sqr(iwd,
TRUE,
tx,ty,
iwd->dispwidth,iwd->dispheight);
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)
return FALSE;
gdisp = (GDisplay *) iwd->gdisp_ptr;
switch (event->type)
{
case GDK_EXPOSE:
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);
break;
case GDK_KEY_PRESS:
/* hack for the update preview... needs to be fixed */
nav_window_update_preview(iwd);
gtk_widget_draw(iwd->preview, NULL);
break;
default:
break;
}
return FALSE;
}
static GtkWidget *
info_window_image_preview_new(InfoDialog *info_win)
{
GtkWidget *hbox1;
GtkWidget *alignment;
NavWinData *iwd;
iwd = (NavWinData *)info_win->user_data;
hbox1 = gtk_hbox_new (FALSE, 0);
gtk_widget_show (hbox1);
gtk_widget_realize(info_win->shell);
/* need gc to draw the preview sqr with */
iwd->gc = gdk_gc_new(info_win->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);
return hbox1;
}
static ActionAreaItem action_items[] =
{
{ N_("Close"), nav_window_close_callback, NULL, NULL },
};
InfoDialog *
nav_window_create (void *gdisp_ptr)
{
InfoDialog *info_win;
GDisplay *gdisp;
NavWinData *iwd;
GtkWidget *container;
char *title;
char *title_buf;
int type;
gdisp = (GDisplay *) gdisp_ptr;
title = g_basename (gimage_filename (gdisp->gimage));
type = gimage_base_type (gdisp->gimage);
/* create the info dialog */
title_buf = g_strdup_printf (_("%s: Window Navigation"), title);
info_win = info_dialog_new (title_buf);
g_free (title_buf);
/* gtk_window_set_policy (GTK_WINDOW (info_win->shell), */
/* FALSE,FALSE,FALSE); */
iwd = (NavWinData *) g_malloc (sizeof (NavWinData));
info_win->user_data = iwd;
iwd->showingPreview = TRUE;
iwd->preview = 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_WIDTH;
iwd->nav_preview_height = NAV_PREVIEW_HEIGHT;
/* 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);
/* Create the action area */
action_items[0].user_data = info_win;
build_action_area (GTK_DIALOG (info_win->shell), action_items, 1, 0);
return info_win;
}
void
nav_window_update_window_marker(InfoDialog *info_win)
{
NavWinData *iwd;
if(!info_win)
return;
iwd = (NavWinData *)info_win->user_data;
if(!iwd ||
iwd->showingPreview == FALSE ||
iwd->block_window_marker == TRUE)
return;
/* 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_window_free (InfoDialog *info_win)
{
g_free (info_win->user_data);
info_dialog_free (info_win);
}

View File

@ -35,6 +35,7 @@
#include "interface.h"
#include "lc_dialog.h"
#include "menus.h"
#include "nav_window.h"
#include "plug_in.h"
#include "qmask.h"
#include "scale.h"
@ -97,6 +98,7 @@ gdisplay_new (GimpImage *gimage,
gdisp->dot_for_dot = TRUE;
gdisp->gimage = gimage;
gdisp->window_info_dialog = NULL;
gdisp->window_nav_dialog = NULL;
gdisp->depth = g_visual->depth;
gdisp->select = NULL;
gdisp->ID = display_num++;
@ -329,6 +331,10 @@ gdisplay_delete (GDisplay *gdisp)
if (gdisp->window_info_dialog)
info_window_free (gdisp->window_info_dialog);
/* Remove navigation dialog if we have one */
if(gdisp->window_nav_dialog)
nav_window_free(gdisp->window_nav_dialog);
/* set the active display to NULL if it was this display */
context = gimp_context_get_user ();
if (gimp_context_get_display (context) == gdisp)
@ -1010,7 +1016,7 @@ gdisplay_update_cursor (GDisplay *gdisp, int x, int y)
}
}
gdisplay_untransform_coords(gdisp, x, y, &t_x, &t_y, TRUE, TRUE);
gdisplay_untransform_coords(gdisp, x, y, &t_x, &t_y, FALSE, FALSE);
active_drawable = gimp_image_active_drawable (gdisp->gimage);
@ -1022,6 +1028,10 @@ gdisplay_update_cursor (GDisplay *gdisp, int x, int y)
t_y >= active_drawable->height)
{
gtk_label_set (GTK_LABEL (gdisp->cursor_label), "");
info_window_update_RGB(gdisp->window_info_dialog,
gdisp,
-1,
-1);
}
else
{
@ -1042,6 +1052,10 @@ gdisplay_update_cursor (GDisplay *gdisp, int x, int y)
(double) t_y * unit_factor / gdisp->gimage->yresolution);
}
gtk_label_set (GTK_LABEL (gdisp->cursor_label), buffer);
info_window_update_RGB(gdisp->window_info_dialog,
gdisp,
t_x,
t_y);
}
}
@ -1051,6 +1065,7 @@ gdisplay_update_cursor (GDisplay *gdisp, int x, int y)
if (new_cursor)
gdisplay_flush (gdisp);
}

View File

@ -111,6 +111,7 @@ struct _GDisplay
guint progressid; /* id of statusbar message for progress */
InfoDialog *window_info_dialog; /* dialog box for image information */
InfoDialog *window_nav_dialog; /* dialog box for image navigation */
int color_type; /* is this an RGB or GRAY colormap */

View File

@ -39,6 +39,7 @@
#include "gradient.h"
#include "image_render.h"
#include "info_window.h"
#include "nav_window.h"
#include "interface.h"
#include "invert.h"
#include "lc_dialog.h"
@ -535,6 +536,19 @@ view_window_info_cmd_callback (GtkWidget *widget,
info_dialog_popup (gdisp->window_info_dialog);
}
void
view_window_nav_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
if (! gdisp->window_nav_dialog)
gdisp->window_nav_dialog = nav_window_create ((void *) gdisp);
info_dialog_popup (gdisp->window_nav_dialog);
}
void
view_toggle_selection_cmd_callback (GtkWidget *widget,
gpointer client_data)

View File

@ -51,6 +51,7 @@ void view_zoom_1_4_callback (GtkWidget *, gpointer);
void view_zoom_1_8_callback (GtkWidget *, gpointer);
void view_zoom_1_16_callback (GtkWidget *, gpointer);
void view_window_info_cmd_callback (GtkWidget *, gpointer);
void view_window_nav_cmd_callback (GtkWidget *, gpointer);
void view_toggle_selection_cmd_callback (GtkWidget *, gpointer);
void view_toggle_rulers_cmd_callback (GtkWidget *, gpointer);
void view_toggle_guides_cmd_callback (GtkWidget *, gpointer);

View File

@ -39,6 +39,7 @@
#include "gradient.h"
#include "image_render.h"
#include "info_window.h"
#include "nav_window.h"
#include "interface.h"
#include "invert.h"
#include "lc_dialog.h"
@ -535,6 +536,19 @@ view_window_info_cmd_callback (GtkWidget *widget,
info_dialog_popup (gdisp->window_info_dialog);
}
void
view_window_nav_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GDisplay * gdisp;
return_if_no_display (gdisp);
if (! gdisp->window_nav_dialog)
gdisp->window_nav_dialog = nav_window_create ((void *) gdisp);
info_dialog_popup (gdisp->window_nav_dialog);
}
void
view_toggle_selection_cmd_callback (GtkWidget *widget,
gpointer client_data)

View File

@ -51,6 +51,7 @@ void view_zoom_1_4_callback (GtkWidget *, gpointer);
void view_zoom_1_8_callback (GtkWidget *, gpointer);
void view_zoom_1_16_callback (GtkWidget *, gpointer);
void view_window_info_cmd_callback (GtkWidget *, gpointer);
void view_window_nav_cmd_callback (GtkWidget *, gpointer);
void view_toggle_selection_cmd_callback (GtkWidget *, gpointer);
void view_toggle_rulers_cmd_callback (GtkWidget *, gpointer);
void view_toggle_guides_cmd_callback (GtkWidget *, gpointer);

View File

@ -139,15 +139,14 @@ info_dialog_delete_callback (GtkWidget *w,
return TRUE;
}
/* public functions */
InfoDialog *
info_dialog_new (char *title)
static InfoDialog *
info_dialog_new_extended (char *title,gboolean inNotebook)
{
InfoDialog *idialog;
GtkWidget *shell;
GtkWidget *vbox;
GtkWidget *info_table;
GtkWidget *info_notebook;
idialog = g_new (InfoDialog, 1);
idialog->field_list = NULL;
@ -167,11 +166,28 @@ info_dialog_new (char *title)
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (shell)->vbox), vbox, TRUE, TRUE, 0);
info_table = gtk_table_new (2, 0, FALSE);
gtk_box_pack_start (GTK_BOX (vbox), info_table, TRUE, TRUE, 0);
if(inNotebook)
{
info_notebook = gtk_notebook_new();
gtk_notebook_append_page(GTK_NOTEBOOK(info_notebook),
info_table,
gtk_label_new (_("General")));
gtk_box_pack_start (GTK_BOX (vbox), info_notebook, TRUE, TRUE, 0);
}
else
{
info_notebook = NULL;
gtk_box_pack_start (GTK_BOX (vbox), info_table, TRUE, TRUE, 0);
}
idialog->shell = shell;
idialog->vbox = vbox;
idialog->info_table = info_table;
idialog->info_notebook = info_notebook;
if(inNotebook)
gtk_widget_show (idialog->info_notebook);
gtk_widget_show (idialog->info_table);
gtk_widget_show (idialog->vbox);
@ -179,6 +195,20 @@ info_dialog_new (char *title)
return idialog;
}
/* public functions */
InfoDialog *
info_dialog_notebook_new (char *title)
{
return info_dialog_new_extended(title,TRUE);
}
InfoDialog *
info_dialog_new (char *title)
{
return info_dialog_new_extended(title,FALSE);
}
void
info_dialog_free (InfoDialog *idialog)
{

View File

@ -50,6 +50,7 @@ struct _InfoDialog
GtkWidget *shell;
GtkWidget *vbox;
GtkWidget *info_table;
GtkWidget *info_notebook;
GSList *field_list;
int nfields;
@ -60,6 +61,7 @@ struct _InfoDialog
/* Info Dialog functions */
InfoDialog *info_dialog_new (gchar *title);
InfoDialog *info_dialog_notebook_new (gchar *title);
void info_dialog_free (InfoDialog *idialog);
void info_dialog_popup (InfoDialog *idialog);

View File

@ -15,6 +15,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "appenv.h"
#include "actionarea.h"
#include "colormaps.h"
@ -23,9 +24,12 @@
#include "gdisplay.h"
#include "gximage.h"
#include "interface.h"
#include "scroll.h"
#include "libgimp/gimpintl.h"
#include "libgimp/gimpunit.h"
#include "pixmaps/dropper.xpm"
#define MAX_BUF 256
@ -40,6 +44,12 @@ struct _InfoWinData
char shades_str[MAX_BUF];
char resolution_str[MAX_BUF];
char unit_str[MAX_BUF];
void *gdisp_ptr; /* I'a not happy 'bout this one */
GtkWidget *labelBvalue;
GtkWidget *labelGvalue;
GtkWidget *labelRvalue;
GtkWidget *labelAvalue;
gboolean showingPreview;
};
/* The different classes of visuals */
@ -104,6 +114,142 @@ info_window_close_callback (GtkWidget *widget,
info_dialog_popdown ((InfoDialog *) client_data);
}
static void
info_window_page_switch (GtkWidget *widget,
GtkNotebookPage *page,
gint page_num)
{
InfoDialog *info_win;
InfoWinData *iwd;
info_win = (InfoDialog *)gtk_object_get_user_data(GTK_OBJECT (widget));
iwd = (InfoWinData *)info_win->user_data;
/* Only deal with the second page */
if(page_num != 1)
{
iwd->showingPreview = FALSE;
return;
}
iwd->showingPreview = TRUE;
}
static void
info_window_image_preview_book(InfoDialog *info_win)
{
GtkWidget *hbox1;
GtkWidget *frame;
GtkWidget *alignment;
GtkWidget *table2;
GtkWidget *labelBvalue;
GtkWidget *labelGvalue;
GtkWidget *labelRvalue;
GtkWidget *labelAvalue;
GtkWidget *labelB;
GtkWidget *labelG;
GtkWidget *labelR;
GtkWidget *labelA;
GtkWidget *pixmapwid;
GdkPixmap *pixmap;
GdkBitmap *mask;
GtkStyle *style;
InfoWinData *iwd;
iwd = (InfoWinData *)info_win->user_data;
hbox1 = gtk_hbox_new (FALSE, 0);
gtk_widget_show (hbox1);
alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_widget_show (alignment);
frame = gtk_frame_new(NULL);
gtk_widget_show (frame);
gtk_box_pack_start (GTK_BOX (hbox1), alignment, TRUE, TRUE, 0);
table2 = gtk_table_new (5, 2, TRUE);
gtk_container_border_width (GTK_CONTAINER (table2), 2);
gtk_widget_show (table2);
gtk_container_add (GTK_CONTAINER (frame), table2);
gtk_container_add (GTK_CONTAINER (alignment), frame);
labelAvalue = gtk_label_new ("N/A");
gtk_widget_show (labelAvalue);
gtk_table_attach (GTK_TABLE (table2), labelAvalue, 1, 2, 4, 5,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
labelBvalue = gtk_label_new ("N/A");
gtk_widget_show (labelBvalue);
gtk_table_attach (GTK_TABLE (table2), labelBvalue, 1, 2, 3, 4,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
labelGvalue = gtk_label_new ("N/A");
gtk_widget_show (labelGvalue);
gtk_table_attach (GTK_TABLE (table2), labelGvalue, 1, 2, 2, 3,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
labelRvalue = gtk_label_new ("N/A");
gtk_widget_show (labelRvalue);
gtk_table_attach (GTK_TABLE (table2), labelRvalue, 1, 2, 1, 2,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
labelA = gtk_label_new ("A:");
gtk_widget_show (labelA);
gtk_table_attach (GTK_TABLE (table2), labelA, 0, 1, 4, 5,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
labelB = gtk_label_new ("B:");
gtk_widget_show (labelB);
gtk_table_attach (GTK_TABLE (table2), labelB, 0, 1, 3, 4,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
labelG = gtk_label_new ("G:");
gtk_widget_show (labelG);
gtk_table_attach (GTK_TABLE (table2), labelG, 0, 1, 2, 3,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
labelR = gtk_label_new ("R:");
gtk_widget_show (labelR);
gtk_table_attach (GTK_TABLE (table2), labelR, 0, 1, 1, 2,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
gtk_widget_realize(info_win->shell);
style = gtk_widget_get_style (info_win->shell);
pixmap = gdk_pixmap_create_from_xpm_d (info_win->shell->window, &mask,
&style->bg[GTK_STATE_NORMAL],
dropper_xpm);
pixmapwid = gtk_pixmap_new (pixmap, mask);
gtk_misc_set_alignment (GTK_MISC (pixmapwid), 0.2, 0.2);
gtk_table_attach (GTK_TABLE (table2), pixmapwid, 0, 2, 0, 1,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
gtk_widget_show (pixmapwid);
gtk_notebook_append_page(GTK_NOTEBOOK(info_win->info_notebook),
hbox1,
gtk_label_new (_("Extended")));
/* Set back to first page */
gtk_notebook_set_page(GTK_NOTEBOOK(info_win->info_notebook),0);
gtk_object_set_user_data(GTK_OBJECT (info_win->info_notebook),
(gpointer)info_win);
gtk_signal_connect (GTK_OBJECT (info_win->info_notebook), "switch_page",
GTK_SIGNAL_FUNC (info_window_page_switch), NULL);
iwd->labelBvalue = labelBvalue;
iwd->labelGvalue = labelGvalue;
iwd->labelRvalue = labelRvalue;
iwd->labelAvalue = labelAvalue;
}
/* displays information:
* image name
* image width, height
@ -136,7 +282,7 @@ info_window_create (void *gdisp_ptr)
/* create the info dialog */
title_buf = g_strdup_printf (_("%s: Window Info"), title);
info_win = info_dialog_new (title_buf);
info_win = info_dialog_notebook_new (title_buf);
g_free (title_buf);
iwd = (InfoWinData *) g_malloc (sizeof (InfoWinData));
@ -149,6 +295,7 @@ info_window_create (void *gdisp_ptr)
iwd->visual_class_str[0] = '\0';
iwd->visual_depth_str[0] = '\0';
iwd->shades_str[0] = '\0';
iwd->showingPreview = FALSE;
/* add the information fields */
info_dialog_add_label (info_win, _("Dimensions (w x h):"),
@ -178,6 +325,9 @@ info_window_create (void *gdisp_ptr)
/* update the fields */
info_window_update (info_win, gdisp_ptr);
/* Add extra tabs */
info_window_image_preview_book(info_win);
/* Create the action area */
action_items[0].user_data = info_win;
build_action_area (GTK_DIALOG (info_win->shell), action_items, 1, 0);
@ -185,6 +335,61 @@ info_window_create (void *gdisp_ptr)
return info_win;
}
void
info_window_update_RGB (InfoDialog *info_win,
void *gdisp_ptr,
gdouble tx,
gdouble ty)
{
GDisplay *gdisp;
InfoWinData *iwd;
char buff[5];
guchar *color;
gint has_alpha;
gint sample_type;
if(!info_win)
return;
gdisp = (GDisplay *) gdisp_ptr;
iwd = (InfoWinData *) info_win->user_data;
if(!iwd || iwd->showingPreview == FALSE)
return;
/* gimage_active_drawable (gdisp->gimage) */
if (!(color = gimp_image_get_color_at(gdisp->gimage, tx, ty))
|| (tx < 0.0 && ty < 0.0))
{
g_snprintf(buff,5,"%4s","N/A");
gtk_label_set_text(GTK_LABEL(iwd->labelBvalue),buff);
gtk_label_set_text(GTK_LABEL(iwd->labelGvalue),buff);
gtk_label_set_text(GTK_LABEL(iwd->labelRvalue),buff);
gtk_label_set_text(GTK_LABEL(iwd->labelAvalue),buff);
return;
}
g_snprintf(buff,5,"%4d",(gint)color[BLUE_PIX]);
gtk_label_set_text(GTK_LABEL(iwd->labelBvalue),buff);
g_snprintf(buff,5,"%4d",(gint)color[GREEN_PIX]);
gtk_label_set_text(GTK_LABEL(iwd->labelGvalue),buff);
g_snprintf(buff,5,"%4d",(gint)color[RED_PIX]);
gtk_label_set_text(GTK_LABEL(iwd->labelRvalue),buff);
sample_type = gimp_image_composite_type (gdisp->gimage);
has_alpha = TYPE_HAS_ALPHA (sample_type);
if(has_alpha)
g_snprintf(buff,5,"%4d",(gint)color[ALPHA_PIX]);
else
g_snprintf(buff,5,"%4s","N/A");
gtk_label_set_text(GTK_LABEL(iwd->labelAvalue),buff);
g_free(color);
}
void
info_window_free (InfoDialog *info_win)
{

View File

@ -23,6 +23,9 @@
InfoDialog *info_window_create (void *);
void info_window_free (InfoDialog *);
void info_window_update (InfoDialog *, void *);
void info_window_update_RGB (InfoDialog *,
void *,
gdouble,
gdouble);
#endif /* __INFO_WINDOW_H__ */

View File

@ -143,6 +143,7 @@ static GtkItemFactoryEntry image_entries[] =
{ N_("/View/Zoom/1:16"), NULL, view_zoom_1_16_callback, 0 },
{ N_("/View/Dot for dot"), NULL, view_dot_for_dot_callback, 0, "<ToggleItem>"},
{ N_("/View/Window Info..."), "<control><shift>I", view_window_info_cmd_callback, 0 },
{ N_("/View/Window Nav..."), NULL, view_window_nav_cmd_callback, 0 },
{ N_("/View/---"), NULL, NULL, 0, "<Separator>" },
{ N_("/View/Toggle Selection"), "<control>T", view_toggle_selection_cmd_callback, 0, "<ToggleItem>" },

View File

@ -139,15 +139,14 @@ info_dialog_delete_callback (GtkWidget *w,
return TRUE;
}
/* public functions */
InfoDialog *
info_dialog_new (char *title)
static InfoDialog *
info_dialog_new_extended (char *title,gboolean inNotebook)
{
InfoDialog *idialog;
GtkWidget *shell;
GtkWidget *vbox;
GtkWidget *info_table;
GtkWidget *info_notebook;
idialog = g_new (InfoDialog, 1);
idialog->field_list = NULL;
@ -167,11 +166,28 @@ info_dialog_new (char *title)
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (shell)->vbox), vbox, TRUE, TRUE, 0);
info_table = gtk_table_new (2, 0, FALSE);
gtk_box_pack_start (GTK_BOX (vbox), info_table, TRUE, TRUE, 0);
if(inNotebook)
{
info_notebook = gtk_notebook_new();
gtk_notebook_append_page(GTK_NOTEBOOK(info_notebook),
info_table,
gtk_label_new (_("General")));
gtk_box_pack_start (GTK_BOX (vbox), info_notebook, TRUE, TRUE, 0);
}
else
{
info_notebook = NULL;
gtk_box_pack_start (GTK_BOX (vbox), info_table, TRUE, TRUE, 0);
}
idialog->shell = shell;
idialog->vbox = vbox;
idialog->info_table = info_table;
idialog->info_notebook = info_notebook;
if(inNotebook)
gtk_widget_show (idialog->info_notebook);
gtk_widget_show (idialog->info_table);
gtk_widget_show (idialog->vbox);
@ -179,6 +195,20 @@ info_dialog_new (char *title)
return idialog;
}
/* public functions */
InfoDialog *
info_dialog_notebook_new (char *title)
{
return info_dialog_new_extended(title,TRUE);
}
InfoDialog *
info_dialog_new (char *title)
{
return info_dialog_new_extended(title,FALSE);
}
void
info_dialog_free (InfoDialog *idialog)
{

View File

@ -50,6 +50,7 @@ struct _InfoDialog
GtkWidget *shell;
GtkWidget *vbox;
GtkWidget *info_table;
GtkWidget *info_notebook;
GSList *field_list;
int nfields;
@ -60,6 +61,7 @@ struct _InfoDialog
/* Info Dialog functions */
InfoDialog *info_dialog_new (gchar *title);
InfoDialog *info_dialog_notebook_new (gchar *title);
void info_dialog_free (InfoDialog *idialog);
void info_dialog_popup (InfoDialog *idialog);

View File

@ -15,6 +15,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "appenv.h"
#include "actionarea.h"
#include "colormaps.h"
@ -23,9 +24,12 @@
#include "gdisplay.h"
#include "gximage.h"
#include "interface.h"
#include "scroll.h"
#include "libgimp/gimpintl.h"
#include "libgimp/gimpunit.h"
#include "pixmaps/dropper.xpm"
#define MAX_BUF 256
@ -40,6 +44,12 @@ struct _InfoWinData
char shades_str[MAX_BUF];
char resolution_str[MAX_BUF];
char unit_str[MAX_BUF];
void *gdisp_ptr; /* I'a not happy 'bout this one */
GtkWidget *labelBvalue;
GtkWidget *labelGvalue;
GtkWidget *labelRvalue;
GtkWidget *labelAvalue;
gboolean showingPreview;
};
/* The different classes of visuals */
@ -104,6 +114,142 @@ info_window_close_callback (GtkWidget *widget,
info_dialog_popdown ((InfoDialog *) client_data);
}
static void
info_window_page_switch (GtkWidget *widget,
GtkNotebookPage *page,
gint page_num)
{
InfoDialog *info_win;
InfoWinData *iwd;
info_win = (InfoDialog *)gtk_object_get_user_data(GTK_OBJECT (widget));
iwd = (InfoWinData *)info_win->user_data;
/* Only deal with the second page */
if(page_num != 1)
{
iwd->showingPreview = FALSE;
return;
}
iwd->showingPreview = TRUE;
}
static void
info_window_image_preview_book(InfoDialog *info_win)
{
GtkWidget *hbox1;
GtkWidget *frame;
GtkWidget *alignment;
GtkWidget *table2;
GtkWidget *labelBvalue;
GtkWidget *labelGvalue;
GtkWidget *labelRvalue;
GtkWidget *labelAvalue;
GtkWidget *labelB;
GtkWidget *labelG;
GtkWidget *labelR;
GtkWidget *labelA;
GtkWidget *pixmapwid;
GdkPixmap *pixmap;
GdkBitmap *mask;
GtkStyle *style;
InfoWinData *iwd;
iwd = (InfoWinData *)info_win->user_data;
hbox1 = gtk_hbox_new (FALSE, 0);
gtk_widget_show (hbox1);
alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_widget_show (alignment);
frame = gtk_frame_new(NULL);
gtk_widget_show (frame);
gtk_box_pack_start (GTK_BOX (hbox1), alignment, TRUE, TRUE, 0);
table2 = gtk_table_new (5, 2, TRUE);
gtk_container_border_width (GTK_CONTAINER (table2), 2);
gtk_widget_show (table2);
gtk_container_add (GTK_CONTAINER (frame), table2);
gtk_container_add (GTK_CONTAINER (alignment), frame);
labelAvalue = gtk_label_new ("N/A");
gtk_widget_show (labelAvalue);
gtk_table_attach (GTK_TABLE (table2), labelAvalue, 1, 2, 4, 5,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
labelBvalue = gtk_label_new ("N/A");
gtk_widget_show (labelBvalue);
gtk_table_attach (GTK_TABLE (table2), labelBvalue, 1, 2, 3, 4,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
labelGvalue = gtk_label_new ("N/A");
gtk_widget_show (labelGvalue);
gtk_table_attach (GTK_TABLE (table2), labelGvalue, 1, 2, 2, 3,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
labelRvalue = gtk_label_new ("N/A");
gtk_widget_show (labelRvalue);
gtk_table_attach (GTK_TABLE (table2), labelRvalue, 1, 2, 1, 2,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
labelA = gtk_label_new ("A:");
gtk_widget_show (labelA);
gtk_table_attach (GTK_TABLE (table2), labelA, 0, 1, 4, 5,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
labelB = gtk_label_new ("B:");
gtk_widget_show (labelB);
gtk_table_attach (GTK_TABLE (table2), labelB, 0, 1, 3, 4,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
labelG = gtk_label_new ("G:");
gtk_widget_show (labelG);
gtk_table_attach (GTK_TABLE (table2), labelG, 0, 1, 2, 3,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
labelR = gtk_label_new ("R:");
gtk_widget_show (labelR);
gtk_table_attach (GTK_TABLE (table2), labelR, 0, 1, 1, 2,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
gtk_widget_realize(info_win->shell);
style = gtk_widget_get_style (info_win->shell);
pixmap = gdk_pixmap_create_from_xpm_d (info_win->shell->window, &mask,
&style->bg[GTK_STATE_NORMAL],
dropper_xpm);
pixmapwid = gtk_pixmap_new (pixmap, mask);
gtk_misc_set_alignment (GTK_MISC (pixmapwid), 0.2, 0.2);
gtk_table_attach (GTK_TABLE (table2), pixmapwid, 0, 2, 0, 1,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
gtk_widget_show (pixmapwid);
gtk_notebook_append_page(GTK_NOTEBOOK(info_win->info_notebook),
hbox1,
gtk_label_new (_("Extended")));
/* Set back to first page */
gtk_notebook_set_page(GTK_NOTEBOOK(info_win->info_notebook),0);
gtk_object_set_user_data(GTK_OBJECT (info_win->info_notebook),
(gpointer)info_win);
gtk_signal_connect (GTK_OBJECT (info_win->info_notebook), "switch_page",
GTK_SIGNAL_FUNC (info_window_page_switch), NULL);
iwd->labelBvalue = labelBvalue;
iwd->labelGvalue = labelGvalue;
iwd->labelRvalue = labelRvalue;
iwd->labelAvalue = labelAvalue;
}
/* displays information:
* image name
* image width, height
@ -136,7 +282,7 @@ info_window_create (void *gdisp_ptr)
/* create the info dialog */
title_buf = g_strdup_printf (_("%s: Window Info"), title);
info_win = info_dialog_new (title_buf);
info_win = info_dialog_notebook_new (title_buf);
g_free (title_buf);
iwd = (InfoWinData *) g_malloc (sizeof (InfoWinData));
@ -149,6 +295,7 @@ info_window_create (void *gdisp_ptr)
iwd->visual_class_str[0] = '\0';
iwd->visual_depth_str[0] = '\0';
iwd->shades_str[0] = '\0';
iwd->showingPreview = FALSE;
/* add the information fields */
info_dialog_add_label (info_win, _("Dimensions (w x h):"),
@ -178,6 +325,9 @@ info_window_create (void *gdisp_ptr)
/* update the fields */
info_window_update (info_win, gdisp_ptr);
/* Add extra tabs */
info_window_image_preview_book(info_win);
/* Create the action area */
action_items[0].user_data = info_win;
build_action_area (GTK_DIALOG (info_win->shell), action_items, 1, 0);
@ -185,6 +335,61 @@ info_window_create (void *gdisp_ptr)
return info_win;
}
void
info_window_update_RGB (InfoDialog *info_win,
void *gdisp_ptr,
gdouble tx,
gdouble ty)
{
GDisplay *gdisp;
InfoWinData *iwd;
char buff[5];
guchar *color;
gint has_alpha;
gint sample_type;
if(!info_win)
return;
gdisp = (GDisplay *) gdisp_ptr;
iwd = (InfoWinData *) info_win->user_data;
if(!iwd || iwd->showingPreview == FALSE)
return;
/* gimage_active_drawable (gdisp->gimage) */
if (!(color = gimp_image_get_color_at(gdisp->gimage, tx, ty))
|| (tx < 0.0 && ty < 0.0))
{
g_snprintf(buff,5,"%4s","N/A");
gtk_label_set_text(GTK_LABEL(iwd->labelBvalue),buff);
gtk_label_set_text(GTK_LABEL(iwd->labelGvalue),buff);
gtk_label_set_text(GTK_LABEL(iwd->labelRvalue),buff);
gtk_label_set_text(GTK_LABEL(iwd->labelAvalue),buff);
return;
}
g_snprintf(buff,5,"%4d",(gint)color[BLUE_PIX]);
gtk_label_set_text(GTK_LABEL(iwd->labelBvalue),buff);
g_snprintf(buff,5,"%4d",(gint)color[GREEN_PIX]);
gtk_label_set_text(GTK_LABEL(iwd->labelGvalue),buff);
g_snprintf(buff,5,"%4d",(gint)color[RED_PIX]);
gtk_label_set_text(GTK_LABEL(iwd->labelRvalue),buff);
sample_type = gimp_image_composite_type (gdisp->gimage);
has_alpha = TYPE_HAS_ALPHA (sample_type);
if(has_alpha)
g_snprintf(buff,5,"%4d",(gint)color[ALPHA_PIX]);
else
g_snprintf(buff,5,"%4s","N/A");
gtk_label_set_text(GTK_LABEL(iwd->labelAvalue),buff);
g_free(color);
}
void
info_window_free (InfoDialog *info_win)
{

View File

@ -23,6 +23,9 @@
InfoDialog *info_window_create (void *);
void info_window_free (InfoDialog *);
void info_window_update (InfoDialog *, void *);
void info_window_update_RGB (InfoDialog *,
void *,
gdouble,
gdouble);
#endif /* __INFO_WINDOW_H__ */

View File

@ -143,6 +143,7 @@ static GtkItemFactoryEntry image_entries[] =
{ N_("/View/Zoom/1:16"), NULL, view_zoom_1_16_callback, 0 },
{ N_("/View/Dot for dot"), NULL, view_dot_for_dot_callback, 0, "<ToggleItem>"},
{ N_("/View/Window Info..."), "<control><shift>I", view_window_info_cmd_callback, 0 },
{ N_("/View/Window Nav..."), NULL, view_window_nav_cmd_callback, 0 },
{ N_("/View/---"), NULL, NULL, 0, "<Separator>" },
{ N_("/View/Toggle Selection"), "<control>T", view_toggle_selection_cmd_callback, 0, "<ToggleItem>" },

View File

@ -143,6 +143,7 @@ static GtkItemFactoryEntry image_entries[] =
{ N_("/View/Zoom/1:16"), NULL, view_zoom_1_16_callback, 0 },
{ N_("/View/Dot for dot"), NULL, view_dot_for_dot_callback, 0, "<ToggleItem>"},
{ N_("/View/Window Info..."), "<control><shift>I", view_window_info_cmd_callback, 0 },
{ N_("/View/Window Nav..."), NULL, view_window_nav_cmd_callback, 0 },
{ N_("/View/---"), NULL, NULL, 0, "<Separator>" },
{ N_("/View/Toggle Selection"), "<control>T", view_toggle_selection_cmd_callback, 0, "<ToggleItem>" },

799
app/nav_window.c Normal file
View File

@ -0,0 +1,799 @@
/* 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 "appenv.h"
#include "actionarea.h"
#include "colormaps.h"
#include "info_dialog.h"
#include "info_window.h"
#include "gdisplay.h"
#include "gximage.h"
#include "interface.h"
#include "scroll.h"
#include "libgimp/gimpintl.h"
#include "libgimp/gimpunit.h"
#define MAX_BUF 256
#define PREVIEW_MASK GDK_EXPOSURE_MASK | \
GDK_MOTION_NOTIFY | \
GDK_POINTER_MOTION_MASK | \
GDK_BUTTON_PRESS_MASK | \
GDK_BUTTON_RELEASE_MASK | \
GDK_BUTTON_MOTION_MASK | \
GDK_KEY_PRESS_MASK | \
GDK_KEY_RELEASE_MASK
/* Navigation preview sizes */
#define NAV_PREVIEW_WIDTH 112
#define NAV_PREVIEW_HEIGHT 112
#define BORDER_PEN_WIDTH 3
typedef struct _NavWinData NavWinData;
struct _NavWinData
{
gboolean showingPreview;
GtkWidget *preview;
void *gdisp_ptr; /* I'a not happy 'bout this one */
GtkWidget *previewBox;
GtkWidget *previewAlign;
gdouble ratio;
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 left corner 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 */
gboolean block_window_marker; /* Block redraws of window marker */
gint nav_preview_width;
gint nav_preview_height;
};
static gint
nav_window_preview_events (GtkWidget *,
GdkEvent *,
gpointer *);
static gint
nav_window_expose_events (GtkWidget *,
GdkEvent *,
gpointer *);
#if 0
static gint
nav_window_preview_resized (GtkWidget *,
GtkAllocation *,
gpointer *);
#endif /* 0 */
static void
nav_window_update_preview (NavWinData *);
static void
destroy_preview_widget (NavWinData *);
static void
create_preview_widget (NavWinData *);
void
nav_window_update_window_marker(InfoDialog *);
static void
nav_window_draw_sqr(NavWinData *,
gboolean,
gint ,
gint ,
gint ,
gint );
static void
set_size_data(NavWinData *);
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; ALT. Needs to be sorted out */
info_dialog_popdown ((InfoDialog *) client_data);
}
static void
nav_window_disp_area(NavWinData *iwd,GDisplay *gdisp)
{
GimpImage *gimage;
gint newwidth;
gint newheight;
gdouble ratio; /* Screen res ratio */
gboolean need_update = FALSE;
/* Calculate preview size */
gimage = gdisp->gimage;
ratio = ((gdouble)SCALEDEST(gdisp))/((gdouble)SCALESRC(gdisp));
iwd->dispx = gdisp->offset_x*iwd->ratio/ratio;
iwd->dispy = gdisp->offset_y*iwd->ratio/ratio;
iwd->dispwidth = (gdisp->disp_width*iwd->ratio)/ratio;
iwd->dispheight = (gdisp->disp_height*iwd->ratio)/ratio;
newwidth = gimage->width;
newheight = gimage->height;
if((iwd->imagewidth > 0 && newwidth != iwd->imagewidth) ||
(iwd->imageheight > 0 && newheight != iwd->imageheight))
{
/* Must change the preview size */
destroy_preview_widget(iwd);
create_preview_widget(iwd);
need_update = TRUE;
}
iwd->imagewidth = newwidth;
iwd->imageheight = newheight;
/* Normalise */
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(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);
}
}
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,
iwd->dispheight);
}
/* gdk_draw_rectangle (iwd->preview->window, iwd->gc, FALSE, */
/* 10,20, */
/* 40,50); */
gdk_draw_rectangle (iwd->preview->window, iwd->gc, FALSE,
x,y,
w,
h);
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 (sel_width > sel_height) {
pwidth = MIN(sel_width, iwd->nav_preview_width);
pheight = sel_height * pwidth / sel_width;
iwd->ratio = (gdouble)pwidth / ((gdouble)sel_width);
} else {
pheight = MIN(sel_height, iwd->nav_preview_height);
pwidth = sel_width * pheight / sel_height;
iwd->ratio = (gdouble)pheight / ((gdouble)sel_height);
}
iwd->pwidth = pwidth;
iwd->pheight = pheight;
}
static void
create_preview_widget(NavWinData *iwd)
{
GtkWidget *hbox;
GtkWidget *image;
GtkWidget *frame;
gdouble ratio;
GDisplay *gdisp;
gdisp = (GDisplay *)(iwd->gdisp_ptr);
ratio = ((gdouble)SCALEDEST(gdisp))/((gdouble)SCALESRC(gdisp));
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);
iwd->preview = image;
gtk_widget_show (image);
gtk_preview_set_dither (GTK_PREVIEW (image), GDK_RGB_DITHER_MAX);
gtk_widget_set_events( GTK_WIDGET(image), PREVIEW_MASK );
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_grab_focus(image);
}
#if 0
static void
info_window_page_switch (GtkWidget *widget,
GtkNotebookPage *page,
gint page_num)
{
InfoDialog *info_win;
InfoWinData *iwd;
info_win = (InfoDialog *)gtk_object_get_user_data(GTK_OBJECT (widget));
iwd = (InfoWinData *)info_win->user_data;
/* Only deal with the second page */
if(page_num != 1)
{
iwd->showingPreview = FALSE;
return;
}
iwd->showingPreview = TRUE;
}
#endif /* 0 */
static void
update_real_view(NavWinData *iwd,gint tx,gint ty)
{
GDisplay *gdisp;
gdouble ratio;
gint xoffset;
gint yoffset;
gdisp = (GDisplay *) iwd->gdisp_ptr;
ratio = ((gdouble)SCALEDEST(gdisp))/((gdouble)SCALESRC(gdisp));
xoffset = tx - iwd->dispx;
yoffset = ty - iwd->dispy;
xoffset = (gint)(((gdouble)xoffset*ratio)/iwd->ratio);
yoffset = (gint)(((gdouble)yoffset*ratio)/iwd->ratio);
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;
gchar *src, *buf;
gint x,y,has_alpha;
gint pwidth, pheight;
GimpImage *gimage;
gdisp = (GDisplay *) iwd->gdisp_ptr;
/* Calculate preview size */
gimage = ((GDisplay *)(iwd->gdisp_ptr))->gimage;
/* Min size is 2 */
pwidth = iwd->pwidth;
pheight = iwd->pheight;
preview_buf = gimp_image_construct_composite_preview (gimage,
MAX (pwidth, 2),
MAX (pheight, 2));
buf = g_new (gchar, iwd->nav_preview_width * 3);
src = (gchar *) temp_buf_data (preview_buf);
has_alpha = (preview_buf->bytes == 2 || preview_buf->bytes == 4);
for (y = 0; y <preview_buf->height ; y++)
{
if (preview_buf->bytes == (1+has_alpha))
for (x = 0; x < preview_buf->width; x++)
{
buf[x*3+0] = src[x];
buf[x*3+1] = src[x];
buf[x*3+2] = src[x];
}
else
for (x = 0; x < preview_buf->width; x++)
{
gint stride = 3 + has_alpha;
buf[x*3+0] = src[x*stride+0];
buf[x*3+1] = src[x*stride+1];
buf[x*3+2] = src[x*stride+2];
}
gtk_preview_draw_row (GTK_PREVIEW (iwd->preview),
(guchar *)buf, 0, y, preview_buf->width);
src += preview_buf->width * preview_buf->bytes;
}
g_free (buf);
temp_buf_free (preview_buf);
nav_window_disp_area(iwd,gdisp);
}
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;
}
#if 0
static gint
nav_window_preview_resized (GtkWidget *widget,
GtkAllocation *alloc,
gpointer *data)
{
NavWinData *iwd;
iwd = (NavWinData *)data;
if(!iwd || !iwd->preview)
return FALSE;
printf("Now at [x,y] = [%d,%d] [w,h] = [%d,%d]\n",
alloc->x,alloc->y,
alloc->width,alloc->height);
if(iwd->nav_preview_width == alloc->width &&
iwd->nav_preview_height == alloc->height)
return FALSE;
iwd->nav_preview_width = alloc->width;
iwd->nav_preview_height = alloc->height;
set_size_data(iwd);
gtk_preview_size(GTK_PREVIEW(iwd->preview),alloc->width,alloc->height);
nav_window_update_preview(iwd);
nav_window_draw_sqr(iwd,FALSE,
iwd->dispx,iwd->dispy,
iwd->dispwidth,iwd->dispheight);
#if 0
destroy_preview_widget(iwd);
create_preview_widget(iwd);
nav_window_update_preview(iwd);
nav_window_update_preview(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);
#endif /* 0 */
return FALSE;
}
#endif /* 0 */
static gint
nav_window_preview_events (GtkWidget *widget,
GdkEvent *event,
gpointer *data)
{
NavWinData *iwd;
GDisplay *gdisp;
GdkEventButton *bevent;
GdkEventMotion *mevent;
gint tx,ty;
iwd = (NavWinData *)data;
if(!iwd)
return FALSE;
gdisp = (GDisplay *) iwd->gdisp_ptr;
switch (event->type)
{
case GDK_EXPOSE:
break;
case GDK_MAP:
nav_window_update_preview(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))
{
iwd->motion_offsetx = tx - iwd->dispx;
iwd->motion_offsety = ty - iwd->dispy;
iwd->sq_grabbed = TRUE;
gtk_grab_add(widget);
}
else
{
/* 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);
}
break;
default:
}
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);
break;
default:
}
break;
case GDK_MOTION_NOTIFY:
mevent = (GdkEventMotion *) event;
if(!iwd->sq_grabbed)
break;
tx = mevent->x;
ty = mevent->y;
if(tx < 0)
{
tx = 0;
}
if(tx > iwd->pwidth)
{
tx = iwd->pwidth;
}
if(ty < 0)
{
ty = 0;
}
if(ty > iwd->pheight)
{
ty = iwd->pwidth;
}
tx = tx - iwd->motion_offsetx;
ty = ty - iwd->motion_offsety;
if(tx < 0 || (tx + iwd->dispwidth) >= iwd->pwidth)
{
iwd->motion_offsetx = mevent->x - iwd->dispx;
tx = iwd->dispx;
}
if(ty < 0 || (ty + iwd->dispheight) >= iwd->pheight)
{
iwd->motion_offsety = mevent->y - iwd->dispy;
ty = iwd->dispy;
}
/* Update the real display */
update_real_view(iwd,tx,ty);
nav_window_draw_sqr(iwd,
TRUE,
tx,ty,
iwd->dispwidth,iwd->dispheight);
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)
return FALSE;
gdisp = (GDisplay *) iwd->gdisp_ptr;
switch (event->type)
{
case GDK_EXPOSE:
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);
break;
case GDK_KEY_PRESS:
/* hack for the update preview... needs to be fixed */
nav_window_update_preview(iwd);
gtk_widget_draw(iwd->preview, NULL);
break;
default:
break;
}
return FALSE;
}
static GtkWidget *
info_window_image_preview_new(InfoDialog *info_win)
{
GtkWidget *hbox1;
GtkWidget *alignment;
NavWinData *iwd;
iwd = (NavWinData *)info_win->user_data;
hbox1 = gtk_hbox_new (FALSE, 0);
gtk_widget_show (hbox1);
gtk_widget_realize(info_win->shell);
/* need gc to draw the preview sqr with */
iwd->gc = gdk_gc_new(info_win->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);
return hbox1;
}
static ActionAreaItem action_items[] =
{
{ N_("Close"), nav_window_close_callback, NULL, NULL },
};
InfoDialog *
nav_window_create (void *gdisp_ptr)
{
InfoDialog *info_win;
GDisplay *gdisp;
NavWinData *iwd;
GtkWidget *container;
char *title;
char *title_buf;
int type;
gdisp = (GDisplay *) gdisp_ptr;
title = g_basename (gimage_filename (gdisp->gimage));
type = gimage_base_type (gdisp->gimage);
/* create the info dialog */
title_buf = g_strdup_printf (_("%s: Window Navigation"), title);
info_win = info_dialog_new (title_buf);
g_free (title_buf);
/* gtk_window_set_policy (GTK_WINDOW (info_win->shell), */
/* FALSE,FALSE,FALSE); */
iwd = (NavWinData *) g_malloc (sizeof (NavWinData));
info_win->user_data = iwd;
iwd->showingPreview = TRUE;
iwd->preview = 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_WIDTH;
iwd->nav_preview_height = NAV_PREVIEW_HEIGHT;
/* 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);
/* Create the action area */
action_items[0].user_data = info_win;
build_action_area (GTK_DIALOG (info_win->shell), action_items, 1, 0);
return info_win;
}
void
nav_window_update_window_marker(InfoDialog *info_win)
{
NavWinData *iwd;
if(!info_win)
return;
iwd = (NavWinData *)info_win->user_data;
if(!iwd ||
iwd->showingPreview == FALSE ||
iwd->block_window_marker == TRUE)
return;
/* 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_window_free (InfoDialog *info_win)
{
g_free (info_win->user_data);
info_dialog_free (info_win);
}

28
app/nav_window.h Normal file
View File

@ -0,0 +1,28 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
* Copyright (C) 1999 Andy Thomas alt@gimp.org
*
* 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.
*/
#ifndef __NAV_WINDOW_H__
#define __NAV_WINDOW_H__
#include "info_dialog.h"
InfoDialog *nav_window_create (void *);
void nav_window_free (InfoDialog *);
void nav_window_update_window_marker(InfoDialog *);
#endif /* __NAV_WINDOW_H__ */

View File

@ -21,7 +21,7 @@
#include "gdisplay.h"
#include "gdisplay_ops.h"
#include "gimprc.h"
#include "info_window.h"
#include "nav_window.h"
#include "scale.h"
#include "tools.h"
@ -257,4 +257,7 @@ setup_scale (GDisplay *gdisp)
gtk_widget_draw (GTK_WIDGET (hruler), NULL);
gtk_widget_draw (GTK_WIDGET (vruler), NULL);
if (gdisp->window_nav_dialog)
nav_window_update_window_marker(gdisp->window_nav_dialog);
}

View File

@ -21,6 +21,7 @@
#include "scroll.h"
#include "cursorutil.h"
#include "tools.h"
#include "nav_window.h"
/* This is the delay before dithering begins
@ -28,9 +29,6 @@
*/
#define DITHER_DELAY 250 /* milliseconds */
/* Locally defined functions */
static int scroll_display (GDisplay *, int, int);
/* STATIC variables */
/* These are the values of the initial pointer grab */
static int startx, starty;
@ -127,10 +125,10 @@ scroll_to_pointer_position (GDisplay *gdisp,
}
static int
int
scroll_display (GDisplay *gdisp,
int x_offset,
int y_offset)
gint x_offset,
gint y_offset)
{
int old_x, old_y;
int src_x, src_y;
@ -201,6 +199,8 @@ scroll_display (GDisplay *gdisp,
if (x_offset || y_offset)
gdisplays_flush ();
if (gdisp->window_nav_dialog)
nav_window_update_window_marker(gdisp->window_nav_dialog);
/* Make sure graphics expose events are processed before scrolling
* again */

View File

@ -35,4 +35,8 @@ void end_grab_and_scroll (GDisplay *, GdkEventButton *);
void grab_and_scroll (GDisplay *, GdkEventMotion *);
void scroll_to_pointer_position (GDisplay *, GdkEventMotion *);
/* generic scroll-by-offset function */
gint scroll_display (GDisplay *, gint, gint);
#endif /* __SCROLL_H__ */

View File

@ -143,6 +143,7 @@ static GtkItemFactoryEntry image_entries[] =
{ N_("/View/Zoom/1:16"), NULL, view_zoom_1_16_callback, 0 },
{ N_("/View/Dot for dot"), NULL, view_dot_for_dot_callback, 0, "<ToggleItem>"},
{ N_("/View/Window Info..."), "<control><shift>I", view_window_info_cmd_callback, 0 },
{ N_("/View/Window Nav..."), NULL, view_window_nav_cmd_callback, 0 },
{ N_("/View/---"), NULL, NULL, 0, "<Separator>" },
{ N_("/View/Toggle Selection"), "<control>T", view_toggle_selection_cmd_callback, 0, "<ToggleItem>" },

28
pixmaps/dropper.xpm Normal file
View File

@ -0,0 +1,28 @@
/* XPM */
static char * dropper_xpm[] = {
"22 22 3 1",
" c None",
". c #FFFFFF",
"+ c #000000",
" ",
" ",
" ",
" ... ",
" ..... ",
" .+.... ",
" .++++.... ",
" .+++.++. ",
" ...+..+. ",
" .+...+. ",
" ..++..+. ",
" . .++..+. ",
" .++..+. ",
" .++..+. ",
" .++..+. ",
" .++..+. ",
" .++..+. ",
" .++..+. ",
" .++.+. ",
" .++++. ",
" ... ",
" . "};