view src/pixbuf-renderer.h @ 1743:d8e9d0cc640e

Allow to switch to fullscreen mode using LIRC. Imagine the following situation (which happened to me several times) : you want to see photos from your bed or your sofa so you launch geeqie and go to the right directory, then you take your remote control and sit comfortably far from your keyboard and mouse. And when you want to begin to watch photos, you realize you forgot to enable full screen! You have to stand up and to go until your computer and come back, whereas you could have done it with your remote control. Patch by Bernard Massot.
author zas_
date Tue, 05 Jan 2010 17:49:50 +0000
parents 24a12aa0cb54
children
line wrap: on
line source

/*
 * Geeqie
 * (C) 2006 John Ellis
 * Copyright (C) 2008 - 2009 The Geeqie Team
 *
 * Author: John Ellis
 *
 * This software is released under the GNU General Public License (GNU GPL).
 * Please read the included file COPYING for more information.
 * This software comes with no warranty of any kind, use at your own risk!
 */

#ifndef PIXBUF_RENDERER_H
#define PIXBUF_RENDERER_H

#include <gtk/gtkeventbox.h>
#include <gtk/gtkwindow.h>


#define TYPE_PIXBUF_RENDERER		(pixbuf_renderer_get_type())
#define PIXBUF_RENDERER(obj)		(G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_PIXBUF_RENDERER, PixbufRenderer))
#define PIXBUF_RENDERER_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST((klass), TYPE_PIXBUF_RENDERER, PixbufRendererClass))
#define IS_PIXBUF_RENDERER(obj)		(G_TYPE_CHECK_INSTANCE_TYPE((obj), TYPE_PIXBUF_RENDERER))
#define IS_PIXBUF_RENDERER_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), TYPE_PIXBUF_RENDERER))
#define PIXBUF_RENDERER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), TYPE_PIXBUF_RENDERER, PixbufRendererClass))


typedef struct _PixbufRenderer PixbufRenderer;
typedef struct _PixbufRendererClass PixbufRendererClass;


typedef gint (* PixbufRendererTileRequestFunc)(PixbufRenderer *pr, gint x, gint y,
					       gint width, gint height, GdkPixbuf *pixbuf, gpointer user_data);
typedef void (* PixbufRendererTileDisposeFunc)(PixbufRenderer *pr, gint x, gint y,
					       gint width, gint height, GdkPixbuf *pixbuf, gpointer user_data);

typedef void (* PixbufRendererPostProcessFunc)(PixbufRenderer *pr, GdkPixbuf **pixbuf, gint x, gint y,
					       gint width, gint height, gpointer user_data);

typedef enum {
	PR_SCROLL_RESET_TOPLEFT = 0,
	PR_SCROLL_RESET_CENTER,
	PR_SCROLL_RESET_NOCHANGE,
	PR_SCROLL_RESET_COUNT,
} PixbufRendererScrollResetType;

struct _PixbufRenderer
{
	GtkEventBox eventbox;

	gint image_width;	/* image actual dimensions (pixels) */
	gint image_height;

	GdkPixbuf *pixbuf;

	gint window_width;	/* allocated size of window (drawing area) */
	gint window_height;

	gint x_offset;		/* offset of image start (non-zero when image < window) */
	gint y_offset;
	
	gint x_mouse; /* coordinates of the mouse taken from GtkEvent */
	gint y_mouse;

	gint vis_width;		/* dimensions of visible part of image */
	gint vis_height;

	gint width;		/* size of scaled image (result) */
	gint height;

	gint x_scroll;		/* scroll offset of image (into width, height to start drawing) */
	gint y_scroll;

	gdouble norm_center_x;	/* coordinates of viewport center in the image, in range 0.0 - 1.0 */
	gdouble norm_center_y;  /* these coordinates are used for PR_SCROLL_RESET_NOCHANGE and should be preserved over periods with NULL pixbuf */
	
	gdouble subpixel_x_scroll; /* subpixel scroll alignment, used to prevent acumulation of rounding errors */
	gdouble subpixel_y_scroll;

	gdouble zoom_min;
	gdouble zoom_max;
	gdouble zoom;		/* zoom we want (0 is auto) */
	gdouble scale;		/* zoom we got (should never be 0) */

	GdkInterpType zoom_quality;
	gboolean zoom_2pass;
	gboolean zoom_expand;

	GdkRgbDither dither_quality;

	PixbufRendererScrollResetType scroll_reset;

	gboolean has_frame;

	GtkWidget *parent_window;	/* resize parent_window when image dimensions change */

	gboolean window_fit;
	gboolean window_limit;
	gint window_limit_size;

	gboolean autofit_limit;
	gint autofit_limit_size;


	gint tile_cache_max;		/* max mb to use for offscreen buffer */

	/*< private >*/

	gint tile_width;
	gint tile_height;
	gint tile_cols;		/* count of tile columns */
	GList *tiles;		/* list of buffer tiles */
	gint tile_cache_size;	/* allocated size of pixmaps/pixbufs */
	GList *draw_queue;	/* list of areas to redraw */
	GList *draw_queue_2pass;/* list when 2 pass is enabled */

	guint draw_idle_id; /* event source id */

	gboolean in_drag;
	gint drag_last_x;
	gint drag_last_y;
	gint drag_moved;

	gboolean source_tiles_enabled;
	gint source_tiles_cache_size;

	GList *source_tiles;	/* list of active source tiles */
	gint source_tile_width;
	gint source_tile_height;

	PixbufRendererTileRequestFunc func_tile_request;
	PixbufRendererTileDisposeFunc func_tile_dispose;

	gpointer func_tile_data;

	PixbufRendererPostProcessFunc func_post_process;
	gpointer post_process_user_data;
	gint post_process_slow;

	gboolean delay_flip;
	gboolean loading;
	gboolean complete;
	gboolean debug_updated; /* debug only */

	guint scroller_id; /* event source id */
	gint scroller_overlay;
	gint scroller_x;
	gint scroller_y;
	gint scroller_xpos;
	gint scroller_ypos;
	gint scroller_xinc;
	gint scroller_yinc;

	GList *overlay_list;
	GdkPixmap *overlay_buffer;

	GdkPixbuf *spare_tile;

	gint orientation;
};

struct _PixbufRendererClass
{
	GtkEventBoxClass parent_class;

	void (*zoom)(PixbufRenderer *pr, gdouble zoom);
	void (*clicked)(PixbufRenderer *pr, GdkEventButton *event);
	void (*scroll_notify)(PixbufRenderer *pr);
	void (*update_pixel)(PixbufRenderer *pr);

	void (*render_complete)(PixbufRenderer *pr);
	void (*drag)(PixbufRenderer *pr, GdkEventButton *event);
};


GType pixbuf_renderer_get_type(void);

PixbufRenderer *pixbuf_renderer_new(void);

void pixbuf_renderer_set_parent(PixbufRenderer *pr, GtkWindow *window);
GtkWindow *pixbuf_renderer_get_parent(PixbufRenderer *pr);

/* display a pixbuf */

void pixbuf_renderer_set_pixbuf(PixbufRenderer *pr, GdkPixbuf *pixbuf, gdouble zoom);

/* same as pixbuf_renderer_set_pixbuf but waits with redrawing for pixbuf_renderer_area_changed */
void pixbuf_renderer_set_pixbuf_lazy(PixbufRenderer *pr, GdkPixbuf *pixbuf, gdouble zoom, gint orientation);


GdkPixbuf *pixbuf_renderer_get_pixbuf(PixbufRenderer *pr);

void pixbuf_renderer_set_orientation(PixbufRenderer *pr, gint orientation);
gint pixbuf_renderer_get_orientation(PixbufRenderer *pr);

void pixbuf_renderer_set_post_process_func(PixbufRenderer *pr, PixbufRendererPostProcessFunc func, gpointer user_data, gboolean slow);

/* display an on-request array of pixbuf tiles */

void pixbuf_renderer_set_tiles(PixbufRenderer *pr, gint width, gint height,
			       gint tile_width, gint tile_height, gint cache_size,
			       PixbufRendererTileRequestFunc func_request,
			       PixbufRendererTileDisposeFunc func_dispose,
			       gpointer user_data,
			       gdouble zoom);
void pixbuf_renderer_set_tiles_size(PixbufRenderer *pr, gint width, gint height);
gint pixbuf_renderer_get_tiles(PixbufRenderer *pr);

/* move image data from source to pr, source is then set to NULL image */

void pixbuf_renderer_move(PixbufRenderer *pr, PixbufRenderer *source);

/* update region of existing image */

void pixbuf_renderer_area_changed(PixbufRenderer *pr, gint x, gint y, gint width, gint height);

/* scrolling */

void pixbuf_renderer_scroll(PixbufRenderer *pr, gint x, gint y);
void pixbuf_renderer_scroll_to_point(PixbufRenderer *pr, gint x, gint y,
				     gdouble x_align, gdouble y_align);

void pixbuf_renderer_get_scroll_center(PixbufRenderer *pr, gdouble *x, gdouble *y);
void pixbuf_renderer_set_scroll_center(PixbufRenderer *pr, gdouble x, gdouble y);
/* zoom */

void pixbuf_renderer_zoom_adjust(PixbufRenderer *pr, gdouble increment);
void pixbuf_renderer_zoom_adjust_at_point(PixbufRenderer *pr, gdouble increment, gint x, gint y);

void pixbuf_renderer_zoom_set(PixbufRenderer *pr, gdouble zoom);
gdouble pixbuf_renderer_zoom_get(PixbufRenderer *pr);
gdouble pixbuf_renderer_zoom_get_scale(PixbufRenderer *pr);

void pixbuf_renderer_zoom_set_limits(PixbufRenderer *pr, gdouble min, gdouble max);

/* sizes */

gboolean pixbuf_renderer_get_image_size(PixbufRenderer *pr, gint *width, gint *height);
gboolean pixbuf_renderer_get_scaled_size(PixbufRenderer *pr, gint *width, gint *height);

/* region of image in pixel coordinates */
gboolean pixbuf_renderer_get_visible_rect(PixbufRenderer *pr, GdkRectangle *rect);

/* actual size of the PixbufRenderer window minus borders,
 * x and y are the scroll offset and include zoom factor.
 */
gboolean pixbuf_renderer_get_virtual_rect(PixbufRenderer *pr, GdkRectangle *rect);

/* background color */
void pixbuf_renderer_set_color(PixbufRenderer *pr, GdkColor *color);

/* overlay */
typedef enum {
	OVL_NORMAL 	= 0,
	OVL_RELATIVE 	= 1 << 0, /* x,y coordinates are relative, negative values start bottom right */
	/* OVL_HIDE_ON_SCROLL = 1 << 1*/ /* hide temporarily when scrolling (not yet implemented) */
} OverlayRendererFlags;

gint pixbuf_renderer_overlay_add(PixbufRenderer *pr, GdkPixbuf *pixbuf, gint x, gint y,
				 OverlayRendererFlags flags);
void pixbuf_renderer_overlay_set(PixbufRenderer *pr, gint id, GdkPixbuf *pixbuf, gint x, gint y);
gboolean pixbuf_renderer_overlay_get(PixbufRenderer *pr, gint id, GdkPixbuf **pixbuf, gint *x, gint *y);
void pixbuf_renderer_overlay_remove(PixbufRenderer *pr, gint id);

gboolean pixbuf_renderer_get_mouse_position(PixbufRenderer *pr, gint *x_pixel, gint *y_pixel);
/* x_pixel and y_pixel are the pixel coordinates \see pixbuf_renderer_get_mouse_position */
gboolean pixbuf_renderer_get_pixel_colors(PixbufRenderer *pr, gint x_pixel, gint y_pixel,
															 				gint *r_mouse, gint *g_mouse, gint *b_mouse);

#endif
/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */