Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManuel QuiƱones <manuq@laptop.org>2013-05-16 11:36:56 (GMT)
committer Agustin Zubiaga <aguz@localhost.localdomain>2013-06-03 19:07:01 (GMT)
commit8db37d787d4938d0f982c2676bfb4e52224afddd (patch)
treecd0e1e91c22ad1e49369c367feb7e6c0cb0a079b
parent7baddea12761f3c97095f4025f5999e07c366e14 (diff)
Add drag by touch
-rw-r--r--ImageView.py49
-rw-r--r--ImageViewerActivity.py24
2 files changed, 71 insertions, 2 deletions
diff --git a/ImageView.py b/ImageView.py
index 6219cd7..8b81ca9 100644
--- a/ImageView.py
+++ b/ImageView.py
@@ -70,6 +70,7 @@ class ImageViewer(Gtk.DrawingArea):
self._target_point = None
self._anchor_point = None
+ self._in_dragtouch = False
self._in_zoomtouch = False
self._zoomtouch_scale = 1
@@ -160,10 +161,56 @@ class ImageViewer(Gtk.DrawingArea):
self._do_set_zoom(1)
self._center_if_small()
+ def start_dragtouch(self, coords):
+ self._in_dragtouch = True
+
+ prev_target_point = self._target_point
+
+ # Set target point to the relative coordinates of this view.
+ alloc = self.get_parent().get_allocation()
+ self._target_point = (coords[1], coords[2])
+
+ # Calculate the new anchor point.
+
+ prev_anchor_scaled = (self._anchor_point[0] * self._zoom,
+ self._anchor_point[1] * self._zoom)
+
+ # This vector is the top left coordinate of the scaled image.
+ scaled_image_topleft = (prev_target_point[0] - prev_anchor_scaled[0],
+ prev_target_point[1] - prev_anchor_scaled[1])
+
+ anchor_scaled = (self._target_point[0] - scaled_image_topleft[0],
+ self._target_point[1] - scaled_image_topleft[1])
+
+ self._anchor_point = (int(anchor_scaled[0] * 1.0 / self._zoom),
+ int(anchor_scaled[1] * 1.0 / self._zoom))
+
+ self.queue_draw()
+
+ def update_dragtouch(self, coords):
+ # Drag touch will be replaced by zoom touch if another finger
+ # is placed over the display. When the user finishes zoom
+ # touch, it will probably remove one finger after the other,
+ # and this method will be called. In that probable case, we
+ # need to start drag touch again.
+ if not self._in_dragtouch:
+ self.start_dragtouch(coords)
+ return
+
+ self._target_point = (coords[1], coords[2])
+ self.queue_draw()
+
+ def finish_dragtouch(self, coords):
+ self._in_dragtouch = False
+ self._center_if_small()
+
def start_zoomtouch(self, center):
self._in_zoomtouch = True
self._zoomtouch_scale = 1
+ # Zoom touch replaces drag touch.
+ self._in_dragtouch = False
+
prev_target_point = self._target_point
# Set target point to the relative coordinates of this view.
@@ -266,7 +313,7 @@ class ImageViewer(Gtk.DrawingArea):
ctx.set_source_surface(self._surface, 0, 0)
- if self._in_zoomtouch:
+ if self._in_zoomtouch or self._in_dragtouch:
ctx.get_source().set_filter(cairo.FILTER_NEAREST)
ctx.paint()
diff --git a/ImageViewerActivity.py b/ImageViewerActivity.py
index 78e5679..a72642e 100644
--- a/ImageViewerActivity.py
+++ b/ImageViewerActivity.py
@@ -28,6 +28,7 @@ import time
import os
import math
from gi.repository import Gtk
+from gi.repository import Gdk
from gi.repository import GObject
from sugar3.graphics.alert import NotifyAlert
@@ -117,14 +118,21 @@ class ImageViewerActivity(activity.Activity):
Gtk.PolicyType.ALWAYS)
# Don't use the default kinetic scrolling, let the view do the
- # pinch to zoom logic.
+ # drag-by-touch and pinch-to-zoom logic.
self.scrolled_window.set_kinetic_scrolling(False)
self.view = ImageView.ImageViewer()
+
+ # Connect to the touch signal for performing drag-by-touch.
+ self.view.add_events(Gdk.EventMask.TOUCH_MASK)
+ self._touch_hid = self.view.connect('touch-event',
+ self.__touch_event_cb)
self.scrolled_window.add_with_viewport(self.view)
self.view.show()
if GESTURES_AVAILABLE:
+ # Connect to the zoom signals for performing
+ # pinch-to-zoom.
zoom_controller = SugarGestures.ZoomController()
zoom_controller.attach(self,
SugarGestures.EventControllerFlags.NONE)
@@ -203,14 +211,28 @@ class ImageViewerActivity(activity.Activity):
# Wait for a successful join before trying to get the document
self.connect("joined", self._joined_cb)
+ def __touch_event_cb(self, widget, event):
+ coords = event.get_coords()
+ if event.type == Gdk.EventType.TOUCH_BEGIN:
+ self.view.start_dragtouch(coords)
+ elif event.type == Gdk.EventType.TOUCH_UPDATE:
+ self.view.update_dragtouch(coords)
+ elif event.type == Gdk.EventType.TOUCH_END:
+ self.view.finish_dragtouch(coords)
+
def __zoomtouch_began_cb(self, controller):
self.view.start_zoomtouch(controller.get_center())
+ # Don't listen to touch signals until pinch-to-zoom ends.
+ self.view.disconnect(self._touch_hid)
+
def __zoomtouch_changed_cb(self, controller, scale):
self.view.update_zoomtouch(controller.get_center(), scale)
def __zoomtouch_ended_cb(self, controller):
self.view.finish_zoomtouch()
+ self._touch_hid = self.view.connect('touch-event',
+ self.__touch_event_cb)
def _add_toolbar_buttons(self, toolbar_box):
activity_button = ActivityToolbarButton(self)