diff options
author | Federico Mena Quintero <federico@redhat.com> | 1999-09-28 23:08:06 +0000 |
---|---|---|
committer | Arturo Espinosa <unammx@src.gnome.org> | 1999-09-28 23:08:06 +0000 |
commit | aa9cf05bca2d5b998ee3b7c68f69e48a044207f1 (patch) | |
tree | 519e9c3360587ad858a815d8162b721c81aa9e84 /libeog | |
parent | a22f0aa50a4c691603de5186df2f5c91450082b9 (diff) | |
download | eog-aa9cf05bca2d5b998ee3b7c68f69e48a044207f1.tar.gz |
Set the cursor to a hand. (UIImagePrivate): Added fields for the anchor
1999-09-28 Federico Mena Quintero <federico@redhat.com>
* ui-image.c (canvas_realized): Set the cursor to a hand.
(UIImagePrivate): Added fields for the anchor point for dragging.
(drag_to): New function to allow dragging of the canvas. It will
perform badly for diagonal movement; see the comment in this
source file to see why.
* cursors.c (cursor_get): New file and new function to create
mouse cursors.
* Makefile.am: Added the cursors directory. Added cursors.[ch] to
the list of sources.
* cursors/Makefile.am: Added the cursor data files.
Diffstat (limited to 'libeog')
-rw-r--r-- | libeog/cursors.c | 103 | ||||
-rw-r--r-- | libeog/cursors.h | 39 | ||||
-rw-r--r-- | libeog/ui-image.c | 147 |
3 files changed, 284 insertions, 5 deletions
diff --git a/libeog/cursors.c b/libeog/cursors.c new file mode 100644 index 00000000..9896419d --- /dev/null +++ b/libeog/cursors.c @@ -0,0 +1,103 @@ +/* Eye of Gnome image viewer - mouse cursors + * + * Copyright (C) 1999 The Free Software Foundation + * + * Author: Federico Mena-Quintero <federico@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. + */ + +#include <config.h> +#include "cursors.h" + + + +/* Cursor definitions. Keep in sync with the CursorType enumeration in + * cursors.h. + */ + +#include "cursors/hand-open-data.xbm" +#include "cursors/hand-open-mask.xbm" +#include "cursors/hand-closed-data.xbm" +#include "cursors/hand-closed-mask.xbm" + +static struct { + char *data; + char *mask; + int data_width; + int data_height; + int mask_width; + int mask_height; + int hot_x, hot_y; +} cursors[] = { + { hand_open_data_bits, hand_open_mask_bits, + hand_open_data_width, hand_open_data_height, + hand_open_mask_width, hand_open_mask_height, + hand_open_data_width / 2, hand_open_data_height / 2 }, + { hand_closed_data_bits, hand_closed_mask_bits, + hand_closed_data_width, hand_closed_data_height, + hand_closed_mask_width, hand_closed_mask_height, + hand_closed_data_width / 2, hand_closed_data_height / 2 }, + { NULL, NULL, 0, 0, 0, 0 } +}; + + + +/** + * cursor_get: + * @window: Window whose screen and colormap determine the cursor's. + * @type: A cursor type. + * + * Creates a cursor. + * + * Return value: The newly-created cursor. + **/ +GdkCursor * +cursor_get (GdkWindow *window, CursorType type) +{ + GdkBitmap *data; + GdkBitmap *mask; + GdkColor black, white; + GdkCursor *cursor; + + g_return_val_if_fail (window != NULL, NULL); + g_return_val_if_fail (type >= 0 && type < CURSOR_NUM_CURSORS, NULL); + + g_assert (cursors[type].data_width == cursors[type].mask_width); + g_assert (cursors[type].data_height == cursors[type].mask_height); + + data = gdk_bitmap_create_from_data (window, + cursors[type].data, + cursors[type].data_width, + cursors[type].data_height); + mask = gdk_bitmap_create_from_data (window, + cursors[type].mask, + cursors[type].mask_width, + cursors[type].mask_height); + + g_assert (data != NULL && mask != NULL); + + gdk_color_black (gdk_window_get_colormap (window), &black); + gdk_color_white (gdk_window_get_colormap (window), &white); + + cursor = gdk_cursor_new_from_pixmap (data, mask, &white, &black, + cursors[type].hot_x, cursors[type].hot_y); + g_assert (cursor != NULL); + + gdk_bitmap_unref (data); + gdk_bitmap_unref (mask); + + return cursor; +} diff --git a/libeog/cursors.h b/libeog/cursors.h new file mode 100644 index 00000000..6e44b92a --- /dev/null +++ b/libeog/cursors.h @@ -0,0 +1,39 @@ +/* Eye of Gnome image viewer - mouse cursors + * + * Copyright (C) 1999 The Free Software Foundation + * + * Author: Federico Mena-Quintero <federico@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 CURSORS_H +#define CURSORS_H + +#include <gdk/gdk.h> + + + +typedef enum { + CURSOR_HAND_OPEN, + CURSOR_HAND_CLOSED, + CURSOR_NUM_CURSORS +} CursorType; + +GdkCursor *cursor_get (GdkWindow *window, CursorType type); + + + +#endif diff --git a/libeog/ui-image.c b/libeog/ui-image.c index 3553cab2..e744d348 100644 --- a/libeog/ui-image.c +++ b/libeog/ui-image.c @@ -21,6 +21,7 @@ #include <config.h> #include <gtk/gtksignal.h> +#include "cursors.h" #include "image-item.h" #include "ui-image.h" #include "zoom.h" @@ -41,6 +42,13 @@ typedef struct { /* Zoom factor */ double zoom; + + /* Anchor point for dragging */ + int drag_anchor_x, drag_anchor_y; + int drag_ofs_x, drag_ofs_y; + + /* Whether we are dragging or not */ + guint dragging : 1; } UIImagePrivate; @@ -158,15 +166,135 @@ ui_image_new (void) return GTK_WIDGET (ui); } + + +/* Signal handlers for the canvas */ + /* Called when the canvas in an image view is realized. We set its background * pixmap to NULL so that X won't clear exposed areas and thus be faster. */ static void canvas_realized (GtkWidget *widget, gpointer data) { + GdkCursor *cursor; + gdk_window_set_back_pixmap (GTK_LAYOUT (widget)->bin_window, NULL, FALSE); + + cursor = cursor_get (GTK_LAYOUT (widget)->bin_window, CURSOR_HAND_OPEN); + gdk_window_set_cursor (GTK_LAYOUT (widget)->bin_window, cursor); + gdk_cursor_destroy (cursor); +} + +/* Button press handler for the canvas. We simply start dragging. */ +static guint +canvas_button_press (GtkWidget *widget, GdkEventButton *event, gpointer data) +{ + UIImage *ui; + UIImagePrivate *priv; + GdkCursor *cursor; + + ui = UI_IMAGE (data); + priv = ui->priv; + + if (priv->dragging || event->button != 1) + return FALSE; + + priv->dragging = TRUE; + priv->drag_anchor_x = event->x; + priv->drag_anchor_y = event->y; + gnome_canvas_get_scroll_offsets (GNOME_CANVAS (priv->canvas), + &priv->drag_ofs_x, + &priv->drag_ofs_y); + + cursor = cursor_get (GTK_LAYOUT (priv->canvas)->bin_window, CURSOR_HAND_CLOSED); + gdk_pointer_grab (GTK_LAYOUT (priv->canvas)->bin_window, + FALSE, + (GDK_POINTER_MOTION_MASK + | GDK_POINTER_MOTION_HINT_MASK + | GDK_BUTTON_RELEASE_MASK), + NULL, + cursor, + event->time); + gdk_cursor_destroy (cursor); + + return TRUE; +} + +/* Drags the canvas to the specified position */ +static void +drag_to (UIImage *ui, int x, int y) +{ + UIImagePrivate *priv; + int dx, dy; + GtkAdjustment *adj; + + priv = ui->priv; + + dx = priv->drag_anchor_x - x; + dy = priv->drag_anchor_y - y; + + /* Right now this will suck for diagonal movement. GtkLayout does not + * have a way to scroll itself diagonally, i.e. you have to change the + * vertical and horizontal adjustments independently, leading to ugly + * visual results. The canvas freezes and thaws the layout in case of + * diagonal movement, forcing it to repaint everything. + * + * I will put in an ugly hack to circumvent this later. + */ + + gnome_canvas_scroll_to (GNOME_CANVAS (priv->canvas), + priv->drag_ofs_x + dx, + priv->drag_ofs_y + dy); +} + +/* Button release handler for the canvas. We terminate dragging. */ +static guint +canvas_button_release (GtkWidget *widget, GdkEventButton *event, gpointer data) +{ + UIImage *ui; + UIImagePrivate *priv; + + ui = UI_IMAGE (data); + priv = ui->priv; + + if (!priv->dragging || event->button != 1) + return FALSE; + + drag_to (ui, event->x, event->y); + priv->dragging = FALSE; + gdk_pointer_ungrab (event->time); + + return TRUE; } +/* Motion handler for the canvas. We update the drag offset. */ +static guint +canvas_motion (GtkWidget *widget, GdkEventMotion *event, gpointer data) +{ + UIImage *ui; + UIImagePrivate *priv; + gint x, y; + GdkModifierType mods; + + ui = UI_IMAGE (data); + priv = ui->priv; + + if (!priv->dragging) + return FALSE; + + if (event->is_hint) + gdk_window_get_pointer (GTK_LAYOUT (priv->canvas)->bin_window, &x, &y, &mods); + else { + x = event->x; + y = event->y; + } + + drag_to (ui, event->x, event->y); + return TRUE; +} + + + /** * ui_image_construct: * @ui: An image view. @@ -191,7 +319,16 @@ ui_image_construct (UIImage *ui) priv->canvas = gnome_canvas_new (); gtk_signal_connect (GTK_OBJECT (priv->canvas), "realize", GTK_SIGNAL_FUNC (canvas_realized), - NULL); + ui); + gtk_signal_connect (GTK_OBJECT (priv->canvas), "button_press_event", + GTK_SIGNAL_FUNC (canvas_button_press), + ui); + gtk_signal_connect (GTK_OBJECT (priv->canvas), "button_release_event", + GTK_SIGNAL_FUNC (canvas_button_release), + ui); + gtk_signal_connect (GTK_OBJECT (priv->canvas), "motion_notify_event", + GTK_SIGNAL_FUNC (canvas_motion), + ui); gtk_widget_pop_colormap (); gtk_widget_pop_visual (); @@ -265,7 +402,7 @@ ui_image_set_image (UIImage *ui, Image *image) * ui_image_set_zoom: * @ui: An image view. * @zoom: Desired zoom factor. - * + * * Sets the zoom factor of an image view. **/ void @@ -285,9 +422,9 @@ ui_image_set_zoom (UIImage *ui, double zoom) /** * ui_image_get_zoom: * @ui: An image view. - * + * * Gets the current zoom factor of an image view. - * + * * Return value: Current zoom factor. **/ double @@ -305,7 +442,7 @@ ui_image_get_zoom (UIImage *ui) /** * ui_image_zoom_fit: * @ui: An image view. - * + * * Sets the zoom factor to fit the size of an image view. **/ void |