[Xfce4-commits] <ristretto:master> Implement box-zoom (zoom to selection)
Stephan Arts
noreply at xfce.org
Mon Aug 8 15:04:24 CEST 2011
Updating branch refs/heads/master
to 0a18c04760f358f279a63b55de1ee46af69c0ccd (commit)
from 1deeb369388f473bc651e43baf14985f480fbeae (commit)
commit 0a18c04760f358f279a63b55de1ee46af69c0ccd
Author: Stephan Arts <stephan at xfce.org>
Date: Fri Aug 5 00:04:49 2011 +0200
Implement box-zoom (zoom to selection)
src/image_viewer.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 155 insertions(+), 2 deletions(-)
diff --git a/src/image_viewer.c b/src/image_viewer.c
index 523ba7f..bb6b208 100644
--- a/src/image_viewer.c
+++ b/src/image_viewer.c
@@ -544,6 +544,13 @@ rstto_image_viewer_paint (GtkWidget *widget)
if(viewer->priv->motion.state == RSTTO_IMAGE_VIEWER_MOTION_STATE_BOX_ZOOM)
{
+ /*
+ * The user can create a selection-box when dragging from four corners.
+ * Check if the endpoint is before or after the starting-point,
+ * calculate the offset and box-size accordingly.
+ *
+ * Perform the calculations for the vertical movement.
+ */
if (viewer->priv->motion.y < viewer->priv->motion.current_y)
{
box_y = viewer->priv->motion.y;
@@ -555,6 +562,9 @@ rstto_image_viewer_paint (GtkWidget *widget)
box_height = viewer->priv->motion.y - box_y;
}
+ /*
+ * Above comment applies here aswell, for the horizontal movement.
+ */
if (viewer->priv->motion.x < viewer->priv->motion.current_x)
{
box_x = viewer->priv->motion.x;
@@ -566,6 +576,9 @@ rstto_image_viewer_paint (GtkWidget *widget)
box_width = viewer->priv->motion.x - box_x;
}
+ /*
+ * Finally, paint the selection-box.
+ */
rstto_image_viewer_paint_selection (viewer, GDK_DRAWABLE(buffer), gc, box_width, box_height, box_x, box_y);
}
}
@@ -1452,12 +1465,27 @@ cb_rstto_image_viewer_scroll_event (RsttoImageViewer *viewer, GdkEventScroll *ev
{
gdouble tmp_x, tmp_y;
gdouble scale;
+ GtkWidget *widget = GTK_WIDGET(viewer);
+
+ gint pixbuf_width;
+ gint pixbuf_height;
+ gint pixbuf_x_offset;
+ gint pixbuf_y_offset;
+
+
+ if (viewer->priv->dst_pixbuf)
+ {
+ pixbuf_width = gdk_pixbuf_get_width(viewer->priv->dst_pixbuf);
+ pixbuf_height = gdk_pixbuf_get_height(viewer->priv->dst_pixbuf);
+ pixbuf_x_offset = ((widget->allocation.width - pixbuf_width)/2);
+ pixbuf_y_offset = ((widget->allocation.height - pixbuf_height)/2);
+ }
if ((event->state & (GDK_CONTROL_MASK)))
{
viewer->priv->auto_scale = FALSE;
- tmp_x = (gtk_adjustment_get_value(viewer->hadjustment) + event->x) / viewer->priv->scale;
- tmp_y = (gtk_adjustment_get_value(viewer->vadjustment) + event->y) / viewer->priv->scale;
+ tmp_x = (gtk_adjustment_get_value(viewer->hadjustment) + event->x) / viewer->priv->scale + pixbuf_x_offset;
+ tmp_y = (gtk_adjustment_get_value(viewer->vadjustment) + event->y) / viewer->priv->scale + pixbuf_y_offset;
switch(event->direction)
{
@@ -1654,6 +1682,49 @@ static void
cb_rstto_image_viewer_button_release_event (RsttoImageViewer *viewer, GdkEventButton *event)
{
GtkWidget *widget = GTK_WIDGET(viewer);
+ gint box_x;
+ gint box_y;
+ gint box_width;
+ gint box_height;
+ gint pixbuf_width;
+ gint pixbuf_height;
+ gint pixbuf_x_offset;
+ gint pixbuf_y_offset;
+ gint width;
+ gint height;
+
+
+ pixbuf_width = gdk_pixbuf_get_width(viewer->priv->dst_pixbuf);
+ pixbuf_height = gdk_pixbuf_get_height(viewer->priv->dst_pixbuf);
+ pixbuf_x_offset = ((widget->allocation.width - pixbuf_width)/2);
+ pixbuf_y_offset = ((widget->allocation.height - pixbuf_height)/2);
+
+ width = gdk_pixbuf_get_width (viewer->priv->pixbuf);
+ height = gdk_pixbuf_get_height (viewer->priv->pixbuf);
+
+ if (viewer->priv->motion.y < viewer->priv->motion.current_y)
+ {
+ box_y = viewer->priv->motion.y;
+ box_height = viewer->priv->motion.current_y - box_y;
+ }
+ else
+ {
+ box_y = viewer->priv->motion.current_y;
+ box_height = viewer->priv->motion.y - box_y;
+ }
+
+ if (viewer->priv->motion.x < viewer->priv->motion.current_x)
+ {
+ box_x = viewer->priv->motion.x;
+ box_width = viewer->priv->motion.current_x - box_x;
+ }
+ else
+ {
+ box_x = viewer->priv->motion.current_x;
+ box_width = viewer->priv->motion.x - box_x;
+ }
+
+
switch (event->button)
{
case 1:
@@ -1661,6 +1732,88 @@ cb_rstto_image_viewer_button_release_event (RsttoImageViewer *viewer, GdkEventBu
switch (viewer->priv->motion.state)
{
case RSTTO_IMAGE_VIEWER_MOTION_STATE_BOX_ZOOM:
+ /*
+ * Constrain the selection-box to the left
+ * and top sides of the image.
+ */
+ if (box_x < pixbuf_x_offset)
+ {
+ box_width -= (pixbuf_x_offset - box_x);
+ box_x = pixbuf_x_offset;
+ }
+ if (box_y < pixbuf_y_offset)
+ {
+ box_height -= (pixbuf_y_offset - box_y);
+ box_y = pixbuf_y_offset;
+ }
+
+ /*
+ * Constrain the selection-box to the right
+ * and bottom sides of the image.
+ */
+ if ((box_x + box_width) > (pixbuf_x_offset+pixbuf_width))
+ {
+ box_width = (pixbuf_x_offset+pixbuf_width)-box_x;
+ }
+ if ((box_y + box_height) > (pixbuf_y_offset+pixbuf_height))
+ {
+ box_height = (pixbuf_y_offset+pixbuf_height)-box_y;
+ }
+
+ if ((box_width > 0) && (box_height > 0))
+ {
+ /*
+ * Using BOX_ZOOM disables auto-scale (zoom-to-fit-widget)
+ */
+ viewer->priv->auto_scale = FALSE;
+
+ /*
+ * Calculate the center of the selection-box.
+ */
+
+ gdouble tmp_y = (gtk_adjustment_get_value(viewer->vadjustment) + (gdouble)box_y + ((gdouble)box_height/ 2)) / viewer->priv->scale + pixbuf_y_offset;
+
+ gdouble tmp_x = (gtk_adjustment_get_value(viewer->hadjustment) + (gdouble)box_x + ((gdouble)box_width / 2)) / viewer->priv->scale + pixbuf_x_offset;
+
+ /*
+ * Calculate the new scale
+ */
+ gdouble scale;
+ if ((gtk_adjustment_get_page_size(viewer->hadjustment) / box_width) >
+ (gtk_adjustment_get_page_size(viewer->vadjustment) / box_height))
+ {
+ scale = viewer->priv->scale * (gtk_adjustment_get_page_size(viewer->hadjustment) / box_width);
+ }
+ else
+ {
+ scale = viewer->priv->scale * (gtk_adjustment_get_page_size(viewer->vadjustment) / box_height);
+ }
+
+ /*
+ * Prevent the widget from zooming in beyond the MAX_SCALE.
+ */
+ if (scale > RSTTO_MAX_SCALE)
+ {
+ scale = RSTTO_MAX_SCALE;
+ }
+
+ viewer->priv->scale = scale;
+
+
+ g_object_freeze_notify(G_OBJECT(viewer->hadjustment));
+ gtk_adjustment_set_upper (viewer->hadjustment, (gdouble)width*(viewer->priv->scale/viewer->priv->image_scale));
+ gtk_adjustment_set_value (viewer->hadjustment, (tmp_x * scale - ((gdouble)gtk_adjustment_get_page_size(viewer->hadjustment)/2)));
+ g_object_thaw_notify(G_OBJECT(viewer->hadjustment));
+
+ g_object_freeze_notify(G_OBJECT(viewer->vadjustment));
+ gtk_adjustment_set_upper (viewer->vadjustment, (gdouble)height*(viewer->priv->scale/viewer->priv->image_scale));
+ gtk_adjustment_set_value (viewer->vadjustment, (tmp_y * scale - ((gdouble)gtk_adjustment_get_page_size(viewer->vadjustment)/2)));
+ g_object_thaw_notify(G_OBJECT(viewer->vadjustment));
+
+ gtk_adjustment_changed(viewer->hadjustment);
+ gtk_adjustment_changed(viewer->vadjustment);
+
+ }
break;
default:
break;
More information about the Xfce4-commits
mailing list