Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManuel Kaufmann <humitos@gmail.com>2012-10-29 20:13:15 (GMT)
committer Agustin Zubiaga <aguz@sugarlabs.org>2012-11-06 01:05:28 (GMT)
commit290189d892861a30fb97cefe9197cd2194e89594 (patch)
tree9b0316785ed8811bb25dcd178033316f43a466e9
parentdeeff1aadcde25b0d3ccbe609f885ec4943fc5a0 (diff)
Zoom Gesture zooms through the gesture's center
When two fingers are used to zoom in/out the image, the center of the gesture is used to zoom the image through it. Signed-off-by: Manuel Kaufmann <humitos@gmail.com> Signed-off-by: Agustin Zubiaga <aguz@sugarlabs.org>
-rw-r--r--ImageView.py86
-rw-r--r--ImageViewerActivity.py6
2 files changed, 77 insertions, 15 deletions
diff --git a/ImageView.py b/ImageView.py
index cbc5516..f20910c 100644
--- a/ImageView.py
+++ b/ImageView.py
@@ -71,9 +71,15 @@ class ImageViewer(Gtk.DrawingArea):
self._angle_ori = 0.0
self._fast = True
self._redraw_id = None
- self._is_touching = False
self._switched = False
+ # zoom with fixed point
+ self._is_touching = False
+ self._touch_center = False
+ self._old_zoom = None
+ self._xofs = 0
+ self._yofs = 0
+
def do_get_property(self, pspec):
if pspec.name == 'zoom':
return self.zoom
@@ -167,20 +173,6 @@ class ImageViewer(Gtk.DrawingArea):
y = int((rect.height - h) / 2)
ctx.translate(x, y)
- if self._is_touching:
- if self._switched:
- w, h = h, w
-
- if rect.height < h:
- vadj = int((h - rect.height) / 2)
- vadjustment = scrolled_window.get_vadjustment()
- vadjustment.set_value(vadj)
-
- if rect.width < w:
- hadj = int((w - rect.width) / 2)
- hadjustment = scrolled_window.get_hadjustment()
- hadjustment.set_value(hadj)
-
if self.zoom != 1:
logging.error('Scaling: %s', self.zoom)
ctx.scale(self.zoom, self.zoom)
@@ -218,6 +210,69 @@ class ImageViewer(Gtk.DrawingArea):
self._switched = True
self.set_size_request(w, h)
+ self._scroll_image()
+
+ def _scroll_image(self):
+ # based on Eye Of GNOME code
+
+ w = int(self.surface.get_width() * self.zoom)
+ h = int(self.surface.get_height() * self.zoom)
+
+ old_width = int(self.surface.get_width() * self._old_zoom)
+ old_height = int(self.surface.get_height() * self._old_zoom)
+
+ scrolled_window = self.get_parent()
+ rect = scrolled_window.get_allocation()
+
+ if self._switched:
+ # TODO: zoom with fixed point does not work properly when
+ # the image is rotated
+ return
+
+ if self._is_touching:
+ zoom_x_anchor = self._touch_center[1] / rect.width
+ zoom_y_anchor = self._touch_center[2] / rect.height
+ else:
+ zoom_x_anchor = 0.5
+ zoom_y_anchor = 0.5
+
+ vadjustment = scrolled_window.get_vadjustment()
+ step_inc = vadjustment.get_step_increment()
+ page_inc = vadjustment.get_page_increment()
+
+ if old_height < rect.height:
+ cy = zoom_y_anchor * old_height / self._old_zoom
+ else:
+ cy = (self._yofs + zoom_y_anchor * rect.height) / self._old_zoom
+
+ if h < rect.height:
+ self._yofs = 0
+ else:
+ self._yofs = math.floor(cy * self.zoom - \
+ zoom_y_anchor * rect.height + 0.5)
+
+ vadj = max(0, min(self._yofs, h - rect.height))
+ vadjustment.configure(vadj, 0, h, step_inc, page_inc,
+ rect.height)
+
+ hadjustment = scrolled_window.get_hadjustment()
+ step_inc = hadjustment.get_step_increment()
+ page_inc = hadjustment.get_page_increment()
+
+ if old_width < rect.width:
+ cx = zoom_x_anchor * old_width / self._old_zoom
+ else:
+ cx = (self._xofs + zoom_x_anchor * rect.width) / self._old_zoom
+
+ if w < rect.width:
+ self._xofs = 0
+ else:
+ self._xofs = math.floor(cx * self.zoom - \
+ zoom_x_anchor * rect.width + 0.5)
+
+ hadj = max(0, min(self._xofs, w - rect.width))
+ hadjustment.configure(hadj, 0, w, step_inc, page_inc,
+ rect.width)
def set_zoom(self, zoom):
self._optimal_zoom_flag = False
@@ -302,6 +357,7 @@ class ImageViewer(Gtk.DrawingArea):
return zoom
def _set_zoom(self, zoom):
+ self._old_zoom = self.zoom
self.zoom = zoom
self._redraw()
self.emit('zoom-changed')
diff --git a/ImageViewerActivity.py b/ImageViewerActivity.py
index 0c51699..4850116 100644
--- a/ImageViewerActivity.py
+++ b/ImageViewerActivity.py
@@ -123,6 +123,8 @@ class ImageViewerActivity(activity.Activity):
zoom_controller = SugarGestures.ZoomController()
zoom_controller.connect('scale-changed',
self.__scale_changed_cb)
+ zoom_controller.connect('began',
+ self.__scale_began_cb)
zoom_controller.attach(self,
SugarGestures.EventControllerFlags.NONE)
@@ -208,12 +210,16 @@ class ImageViewerActivity(activity.Activity):
# Wait for a successful join before trying to get the document
self.connect("joined", self._joined_cb)
+ def __scale_began_cb(self, controller):
+ self.view._zoom_ori = self.view.zoom
+
def __scale_changed_cb(self, controller, scale):
if scale != self._last_scale:
self._last_scale = scale
logging.error('Scale changed %f', scale)
self.view._is_touching = True
+ self.view._touch_center = controller.get_center()
self.view.set_zoom_relative(scale)
def handle_view_source(self):