From 812dcbe6027751ecae2c3078aa2f8cb6ee6e22a7 Mon Sep 17 00:00:00 2001 From: Gonzalo Odiard Date: Thu, 11 Oct 2012 19:19:47 +0000 Subject: Initial gesture support Only zoom is implemented, but not rotate. Signed-off-by: Gonzalo Odiard Signed-off-by: Agustin Zubiaga --- 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 -- cgit v0.9.1