Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGonzalo Odiard <godiard@gmail.com>2012-10-11 19:19:47 (GMT)
committer Agustin Zubiaga <aguz@sugarlabs.org>2012-10-12 23:08:34 (GMT)
commit812dcbe6027751ecae2c3078aa2f8cb6ee6e22a7 (patch)
tree8fe79b6aef516162b0de92c70b1fde2867d4d829
parentb845688ae92662153ccefcd2236ad75659c6a500 (diff)
Initial gesture support
Only zoom is implemented, but not rotate. Signed-off-by: Gonzalo Odiard <gonzalo@laptop.org> Signed-off-by: Agustin Zubiaga <aguz@sugarlabs.org>
-rw-r--r--ImageView.py51
-rw-r--r--ImageViewerActivity.py65
2 files changed, 81 insertions, 35 deletions
diff --git a/ImageView.py b/ImageView.py
index 2785337..7ec9a41 100644
--- a/ImageView.py
+++ b/ImageView.py
@@ -66,6 +66,10 @@ class ImageViewer(Gtk.DrawingArea):
self.connect('draw', self.__draw_cb)
self.angle = 0
+ self._zoom_ori = 1.0
+ self._angle_ori = 0.0
+ self._fast = True
+ self._redraw_id = None
def do_get_property(self, pspec):
if pspec.name == 'zoom':
@@ -97,12 +101,12 @@ class ImageViewer(Gtk.DrawingArea):
def __draw_cb(self, widget, ctx):
timeini = time.time()
- logging.debug('ImageViewer.draw start')
+ logging.error('ImageViewer.draw start')
if self.surface is None:
if self.file_location is None:
return
-
+ logging.error('init surface with image')
# http://cairographics.org/gdkpixbufpycairo/
pixbuf = GdkPixbuf.Pixbuf.new_from_file(self.file_location)
self.surface = ctx.get_target().create_similar(
@@ -116,17 +120,19 @@ class ImageViewer(Gtk.DrawingArea):
w = int(self.surface.get_width() * self.zoom)
h = int(self.surface.get_height() * self.zoom)
- logging.debug('W: %s, H: %s', w, h)
+ logging.error('W: %s, H: %s', w, h)
ctx.save()
+ if self._fast:
+ ctx.set_antialias(cairo.ANTIALIAS_NONE)
if self.angle != 0:
- logging.debug('Rotating: %s', -self.angle)
+ logging.error('Rotating: %s', self.angle)
ctx.translate(0.5 * w, 0.5 * h)
- ctx.rotate(-self.angle)
+ ctx.rotate(self.angle)
ctx.translate(-0.5 * w, -0.5 * h)
if self.zoom != 1:
- logging.debug('Scaling: %s', self.zoom)
+ logging.error('Scaling: %s', self.zoom)
ctx.scale(self.zoom, self.zoom)
rect = self.get_allocation()
@@ -140,13 +146,37 @@ class ImageViewer(Gtk.DrawingArea):
y = int((rect.height - h) / 2)
ctx.set_source_surface(self.surface, x, y)
+ if self._fast:
+ ctx.get_source().set_filter(cairo.FILTER_NEAREST)
ctx.paint()
- logging.debug('ImageViewer.draw end %f', (time.time() - timeini))
+ logging.error('ImageViewer.draw end %f', (time.time() - timeini))
+
+ if not self._fast:
+ if self._redraw_id is not None:
+ GObject.source_remove(self._redraw_id)
+ self._redraw_id = GObject.timeout_add(200,
+ self._redraw_high_quality)
+
+ def _redraw_high_quality(self):
+ self._fast = False
+ self._redraw_id = None
+ self.queue_draw()
+ return False
def set_zoom(self, zoom):
self._optimal_zoom_flag = False
self._set_zoom(zoom)
+ def set_zoom_relative(self, scale):
+ if scale == 1.0:
+ self._zoom_ori = self.zoom
+ self._set_zoom(self._zoom_ori * scale)
+
+ def set_angle_relative(self, diff):
+ if diff == 0.0:
+ self._angle_ori = self.angle
+ self.set_angle(self._angle_ori + diff)
+
def set_angle(self, angle):
self._optimal_zoom_flag = True
@@ -210,13 +240,12 @@ class ImageViewer(Gtk.DrawingArea):
def _set_zoom(self, zoom):
self.zoom = zoom
-
- # README: this is a hack to not raise the 'draw' event (again)
- # when we request more space to show the scroll bars
+# # README: this is a hack to not raise the 'draw' event (again)
+# # when we request more space to show the scroll bars
+ self._fast = True
w = int(self.surface.get_width() * self.zoom)
h = int(self.surface.get_height() * self.zoom)
self.set_size_request(w, h)
- # self.queue_draw()
self.emit('zoom-changed')
diff --git a/ImageViewerActivity.py b/ImageViewerActivity.py
index a4911a7..2cfe88b 100644
--- a/ImageViewerActivity.py
+++ b/ImageViewerActivity.py
@@ -42,6 +42,15 @@ from sugar3.graphics import style
from sugar3 import network
from sugar3.datastore import datastore
+
+try:
+ from gi.repository import SugarGestures
+ GESTURES_AVAILABLE = True
+except:
+ GESTURES_AVAILABLE = False
+
+ANGLE_THRESHOLD = 0.5 # 1.57 radians == 90 degrees
+
import telepathy
import dbus
@@ -98,8 +107,8 @@ IMAGEVIEWER_STREAM_SERVICE = 'imageviewer-activity-http'
class ImageViewerActivity(activity.Activity):
def __init__(self, handle):
+ logging.error('start activity')
activity.Activity.__init__(self, handle)
-
self.zoom = None
self._object_id = handle.object_id
@@ -109,6 +118,14 @@ class ImageViewerActivity(activity.Activity):
self._fileserver_tube_id = None
self.view = ImageView.ImageViewer()
+
+ if GESTURES_AVAILABLE:
+ zoom_controller = SugarGestures.ZoomController()
+ zoom_controller.connect('scale-changed',
+ self.__scale_changed_cb)
+ zoom_controller.attach(self,
+ SugarGestures.EventControllerFlags.NONE)
+
self.progressdialog = None
toolbar_box = ToolbarBox()
@@ -120,11 +137,16 @@ class ImageViewerActivity(activity.Activity):
hadj = Gtk.Adjustment()
self.sw = Gtk.ScrolledWindow(hadj, vadj)
self.view.parent = self.sw
+ # Avoid needless spacing
+ self.view.parent.props.shadow_type = Gtk.ShadowType.NONE
+ self.sw.set_policy(Gtk.PolicyType.AUTOMATIC,
+ Gtk.PolicyType.AUTOMATIC)
+ self.sw.add_with_viewport(self.view)
+ self.sw.show_all()
+ self._last_angle = 0.0
+ self._last_scale = 1.0
- notebook = Gtk.Notebook()
- notebook.set_show_tabs(False)
-
- if not handle.object_id:
+ if self._object_id is None:
empty_widgets = Gtk.EventBox()
empty_widgets.modify_bg(Gtk.StateType.NORMAL,
style.COLOR_WHITE.get_gdk_color())
@@ -147,7 +169,7 @@ class ImageViewerActivity(activity.Activity):
hbox = Gtk.Box()
open_image_btn = Gtk.Button()
- open_image_btn.connect('clicked', self._show_picker_cb, notebook)
+ open_image_btn.connect('clicked', self._show_picker_cb)
add_image = Gtk.Image.new_from_stock(Gtk.STOCK_ADD,
Gtk.IconSize.BUTTON)
buttonbox = Gtk.Box()
@@ -158,20 +180,11 @@ class ImageViewerActivity(activity.Activity):
mvbox.pack_start(hbox, False, False, style.DEFAULT_PADDING)
empty_widgets.add(vbox)
- vbox.show_all()
-
- notebook.append_page(empty_widgets, None)
empty_widgets.show_all()
-
- self.sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
- self.sw.add_with_viewport(self.view)
- # Avoid needless spacing
- self.view.parent.props.shadow_type = Gtk.ShadowType.NONE
-
- notebook.append_page(self.sw, None)
-
- self.set_canvas(notebook)
- notebook.show_all()
+ logging.error('show empty widgets')
+ self.set_canvas(empty_widgets)
+ else:
+ self.set_canvas(self.sw)
self.unused_download_tubes = set()
self._want_document = True
@@ -194,9 +207,13 @@ class ImageViewerActivity(activity.Activity):
else:
# Wait for a successful join before trying to get the document
self.connect("joined", self._joined_cb)
- elif self._object_id is None:
- self._show_object_picker = GObject.timeout_add(1000, \
- self._show_picker_cb, notebook)
+
+ def __scale_changed_cb(self, controller, scale):
+ if scale != self._last_scale:
+ self._last_scale = scale
+ logging.error('Scale changed %f', scale)
+
+ self.view.set_zoom_relative(scale)
def handle_view_source(self):
raise NotImplementedError
@@ -302,7 +319,7 @@ class ImageViewerActivity(activity.Activity):
def __fullscreen_cb(self, button):
self.fullscreen()
- def _show_picker_cb(self, *args):
+ def _show_picker_cb(self, button):
if not self._want_document:
return
@@ -315,7 +332,7 @@ class ImageViewerActivity(activity.Activity):
jobject = chooser.get_selected_object()
if jobject and jobject.file_path:
self.read_file(jobject.file_path)
- args[-1].set_current_page(-1)
+ self.set_canvas(self.sw)
finally:
chooser.destroy()
del chooser