[Sugar-devel] [PATCH ImageViewer] GTK3 Port

Agustin Zubiaga aguz at sugarlabs.org
Sun Jul 1 19:17:55 EDT 2012


Signed-off-by: Agustin Zubiaga <aguz at sugarlabs.org>
Signed-off-by: Flavio Danesse <fdanesse at gmail.com>
---
 ImageView.py           |  123 +++++++++++++++++++++++++-----------------------
 ImageViewerActivity.py |   75 ++++++++++++++---------------
 ProgressDialog.py      |   14 +++---
 3 files changed, 108 insertions(+), 104 deletions(-)

diff --git a/ImageView.py b/ImageView.py
index 538c5b5..39556d7 100644
--- a/ImageView.py
+++ b/ImageView.py
@@ -17,9 +17,11 @@
 
 from __future__ import division
 
-import gtk
-from gtk import gdk
-import gobject
+from gi.repository import Gtk
+from gi.repository import Gdk
+from gi.repository import GdkPixbuf
+from gi.repository import cairo
+from gi.repository import GObject
 
 import sys
 import logging
@@ -27,39 +29,42 @@ import logging
 import random
 
 
-class ImageViewer(gtk.DrawingArea):
+class ImageViewer(Gtk.DrawingArea):
     __gsignals__ = {
-        'expose-event': (
-            'override'),
+        #'expose-event': (
+        #    'override'),
         'zoom-changed': (
-            gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, []),
+            GObject.SignalFlags.RUN_FIRST, None, []),
         'angle-changed': (
-            gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, []),
+            GObject.SignalFlags.RUN_FIRST, None, []),
         }
 
     __gproperties__ = {
         'zoom': (
-            gobject.TYPE_FLOAT, 'Zoom Factor', 'Factor of zoom',
-            0, 4, 1, gobject.PARAM_READWRITE),
+            GObject.TYPE_FLOAT, 'Zoom Factor', 'Factor of zoom',
+            0, 4, 1, GObject.PARAM_READWRITE),
         'angle': (
-            gobject.TYPE_INT, 'Angle', 'Angle of rotation',
-            0, 360, 0, gobject.PARAM_READWRITE),
+            GObject.TYPE_INT, 'Angle', 'Angle of rotation',
+            0, 360, 0, GObject.PARAM_READWRITE),
         'file_location': (
-            gobject.TYPE_STRING, 'File Location', 'Location of the image file',
-            '', gobject.PARAM_READWRITE),
+            GObject.TYPE_STRING, 'File Location', 'Location of the image file',
+            '', GObject.PARAM_READWRITE),
         }
 
     def __init__(self):
-        gtk.DrawingArea.__init__(self)
+        GObject.GObject.__init__(self)
         self.set_app_paintable(True)
 
         self.pixbuf = None
         self.zoom = None
+        self.parent = None
         self.file_location = None
         self._temp_pixbuf = None
         self._image_changed_flag = True
         self._optimal_zoom_flag = True
 
+        self.connect('draw', self.draw)
+
         self.angle = 0
 
     def do_get_property(self, pspec):
@@ -90,19 +95,7 @@ class ImageViewer(gtk.DrawingArea):
         if self._optimal_zoom_flag:
             self._set_zoom(self._calc_optimal_zoom())
 
-    #def do_size_request(self, requisition):
-    #    requisition.width = self.pixbuf.get_width()
-    #    requisition.height = self.pixbuf.get_height()
-
-    def do_expose_event(self, event):
-        ctx = self.window.cairo_create()
-
-        ctx.rectangle(event.area.x, event.area.y,
-            event.area.width, event.area.height)
-        ctx.clip()
-        self.draw(ctx)
-
-    def draw(self, ctx):
+    def draw(self, widget, ctx):
         if not self.pixbuf:
             return
         if self.zoom is None:
@@ -130,7 +123,7 @@ class ImageViewer(gtk.DrawingArea):
         self.set_size_request(self._temp_pixbuf.get_width(),
                 self._temp_pixbuf.get_height())
 
-        ctx.set_source_pixbuf(self._temp_pixbuf, x, y)
+        Gdk.cairo_set_source_pixbuf(ctx, self._temp_pixbuf, x, y)
 
         ctx.paint()
 
@@ -144,12 +137,15 @@ class ImageViewer(gtk.DrawingArea):
 
         self.angle = angle
 
-        if self.window:
+        if self.props.window:
             alloc = self.get_allocation()
-            rect = gdk.Rectangle(alloc.x, alloc.y,
-                alloc.width, alloc.height)
-            self.window.invalidate_rect(rect, True)
-            self.window.process_updates(True)
+            rect = cairo.RectangleInt()
+            rect.x = alloc.x
+            rect.y = alloc.y
+            rect.width = alloc.width
+            rect.height = alloc.height
+            self.props.window.invalidate_rect(rect, True)
+            self.props.window.process_updates(True)
 
         self.emit('angle-changed')
 
@@ -168,24 +164,27 @@ class ImageViewer(gtk.DrawingArea):
             return True
 
     def set_file_location(self, file_location):
-        self.pixbuf = gtk.gdk.pixbuf_new_from_file(file_location)
+        self.pixbuf = GdkPixbuf.Pixbuf.new_from_file(file_location)
         self.file_location = file_location
         self.zoom = None
         self._image_changed_flag = True
 
-        if self.window:
+        if self.props.window:
             alloc = self.get_allocation()
-            rect = gdk.Rectangle(alloc.x, alloc.y,
-                alloc.width, alloc.height)
-            self.window.invalidate_rect(rect, True)
-            self.window.process_updates(True)
+            rect = cairo.RectangleInt()
+            rect.x = alloc.x
+            rect.y = alloc.y
+            rect.width = alloc.width
+            rect.height = alloc.height
+            self.props.window.invalidate_rect(rect, True)
+            self.props.window.process_updates(True)
 
     def _calc_optimal_zoom(self):
         # This tries to figure out a best fit model
         # If the image can fit in, we show it in 1:1,
         # in any other case we show it in a fit to screen way
 
-        if isinstance(self.parent, gtk.Viewport):
+        if isinstance(self.parent, Gtk.Viewport):
             rect = self.parent.parent.get_allocation()
         else:
             rect = self.parent.get_allocation()
@@ -206,37 +205,41 @@ class ImageViewer(gtk.DrawingArea):
         self._image_changed_flag = True
         self.zoom = zoom
 
-        if self.window:
+        if self.props.window:
             alloc = self.get_allocation()
-            rect = gdk.Rectangle(alloc.x, alloc.y,
-                alloc.width, alloc.height)
-            self.window.invalidate_rect(rect, True)
-            self.window.process_updates(True)
+            rect = cairo.RectangleInt()
+            rect.x = alloc.x
+            rect.y = alloc.y
+            rect.width = alloc.width
+            rect.height = alloc.height
+            self.props.window.invalidate_rect(rect, True)
+            self.props.window.process_updates(True)
 
         self.emit('zoom-changed')
 
     def _convert_pixbuf(self, pixbuf):
         if self.angle == 0:
-            rotate = gtk.gdk.PIXBUF_ROTATE_NONE
+            rotate = GdkPixbuf.PixbufRotation.NONE
         elif self.angle == 90:
-            rotate = gtk.gdk.PIXBUF_ROTATE_COUNTERCLOCKWISE
+            rotate = GdkPixbuf.PixbufRotation.COUNTERCLOCKWISE
         elif self.angle == 180:
-            rotate = gtk.gdk.PIXBUF_ROTATE_UPSIDEDOWN
+            rotate = GdkPixbuf.PixbufRotation.UPSIDEDOWN
         elif self.angle == 270:
-            rotate = gtk.gdk.PIXBUF_ROTATE_CLOCKWISE
+            rotate = GdkPixbuf.PixbufRotation.CLOCKWISE
         elif self.angle == 360:
             self.angle = 0
-            rotate = gtk.gdk.PIXBUF_ROTATE_NONE
+            rotate = GdkPixbuf.PixbufRotation.NONE
         else:
             logging.warning('Got unsupported rotate angle')
 
-        if rotate != gtk.gdk.PIXBUF_ROTATE_NONE:
+        if rotate != GdkPixbuf.PixbufRotation.NONE:
             pixbuf = pixbuf.rotate_simple(rotate)
 
         if self.zoom != 1:
             width = int(pixbuf.get_width() * self.zoom)
             height = int(pixbuf.get_height() * self.zoom)
-            pixbuf = pixbuf.scale_simple(width, height, gtk.gdk.INTERP_TILES)
+            pixbuf = pixbuf.scale_simple(width, height,
+                                         GdkPixbuf.InterpType.TILES)
 
         return pixbuf
 
@@ -250,18 +253,18 @@ def update(view_object):
 
 
 if __name__ == '__main__':
-    window = gtk.Window()
+    window = Gtk.Window()
 
-    vadj = gtk.Adjustment()
-    hadj = gtk.Adjustment()
-    sw = gtk.ScrolledWindow(hadj, vadj)
+    vadj = Gtk.Adjustment()
+    hadj = Gtk.Adjustment()
+    sw = Gtk.ScrolledWindow(hadj, vadj)
 
     view = ImageViewer()
 
     view.set_file_location(sys.argv[1])
 
 
-    sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+    sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
 
 
     sw.add_with_viewport(view)
@@ -271,6 +274,6 @@ if __name__ == '__main__':
 
     window.show_all()
 
-    gobject.timeout_add(1000, update, view)
+    GObject.timeout_add(1000, update, view)
 
-    gtk.main()
+    Gtk.main()
diff --git a/ImageViewerActivity.py b/ImageViewerActivity.py
index 2391dfd..c35829b 100644
--- a/ImageViewerActivity.py
+++ b/ImageViewerActivity.py
@@ -19,26 +19,26 @@
 
 from __future__ import division
 
-from sugar.activity import activity
+from sugar3.activity import activity
 import logging
 
 from gettext import gettext as _
 
 import time
 import os
-import gtk
-import gobject
-
-from sugar.graphics.alert import NotifyAlert
-from sugar.graphics.objectchooser import ObjectChooser
-from sugar import mime
-from sugar.graphics.toolbutton import ToolButton
-from sugar.graphics.toolbarbox import ToolbarBox
-from sugar.activity.widgets import ActivityToolbarButton
-from sugar.activity.widgets import StopButton
-
-from sugar import network
-from sugar.datastore import datastore
+from gi.repository import Gtk
+from gi.repository import GObject
+
+from sugar3.graphics.alert import NotifyAlert
+from sugar3.graphics.objectchooser import ObjectChooser
+from sugar3 import mime
+from sugar3.graphics.toolbutton import ToolButton
+from sugar3.graphics.toolbarbox import ToolbarBox
+from sugar3.activity.widgets import ActivityToolbarButton
+from sugar3.activity.widgets import StopButton
+
+from sugar3 import network
+from sugar3.datastore import datastore
 import telepathy
 import dbus
 
@@ -113,14 +113,15 @@ class ImageViewerActivity(activity.Activity):
         self.set_toolbar_box(toolbar_box)
         toolbar_box.show()
 
-        vadj = gtk.Adjustment()
-        hadj = gtk.Adjustment()
-        self.sw = gtk.ScrolledWindow(hadj, vadj)
+        vadj = Gtk.Adjustment()
+        hadj = Gtk.Adjustment()
+        self.sw = Gtk.ScrolledWindow(hadj, vadj)
+        self.view.parent = self.sw
 
-        self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        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.SHADOW_NONE
+        self.view.parent.props.shadow_type = Gtk.ShadowType.NONE
 
         self.set_canvas(self.sw)
         self.sw.show_all()
@@ -138,7 +139,7 @@ class ImageViewerActivity(activity.Activity):
 
         self.is_received_document = False
 
-        if self._shared_activity and handle.object_id == None:
+        if self.shared_activity and handle.object_id == None:
             # We're joining, and we don't already have the document.
             if self.get_shared():
                 # Already joined for some reason, just get the document
@@ -147,7 +148,7 @@ class ImageViewerActivity(activity.Activity):
                 # 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_object_picker = GObject.timeout_add(1000, \
                 self._show_picker_cb)
 
     def handle_view_source(self):
@@ -190,7 +191,7 @@ class ImageViewerActivity(activity.Activity):
         toolbar_box.toolbar.insert(zoom_original_button, -1)
         zoom_original_button.show()
 
-        spacer = gtk.SeparatorToolItem()
+        spacer = Gtk.SeparatorToolItem()
         spacer.props.draw = False
         toolbar_box.toolbar.insert(spacer, -1)
         spacer.show()
@@ -208,7 +209,7 @@ class ImageViewerActivity(activity.Activity):
         toolbar_box.toolbar.insert(rotate_clockwise_button, -1)
         rotate_clockwise_button.show()
 
-        spacer = gtk.SeparatorToolItem()
+        spacer = Gtk.SeparatorToolItem()
         spacer.props.draw = False
         toolbar_box.toolbar.insert(spacer, -1)
         spacer.show()
@@ -219,7 +220,7 @@ class ImageViewerActivity(activity.Activity):
         toolbar_box.toolbar.insert(fullscreen_button, -1)
         fullscreen_button.show()
 
-        separator = gtk.SeparatorToolItem()
+        separator = Gtk.SeparatorToolItem()
         separator.props.draw = False
         separator.set_expand(True)
         toolbar_box.toolbar.insert(separator, -1)
@@ -262,13 +263,13 @@ class ImageViewerActivity(activity.Activity):
             return
 
         chooser = ObjectChooser(_('Choose document'), self,
-            gtk.DIALOG_MODAL |
-            gtk.DIALOG_DESTROY_WITH_PARENT, \
+            Gtk.DialogFlags.MODAL |
+            Gtk.DialogFlags.DESTROY_WITH_PARENT, \
             what_filter=mime.GENERIC_TYPE_IMAGE)
 
         try:
             result = chooser.run()
-            if result == gtk.RESPONSE_ACCEPT:
+            if result == Gtk.ResponseType.ACCEPT:
                 jobject = chooser.get_selected_object()
                 if jobject and jobject.file_path:
                     self.read_file(jobject.file_path)
@@ -284,7 +285,7 @@ class ImageViewerActivity(activity.Activity):
 
         os.link(file_path, tempfile)
         self._tempfile = tempfile
-        gobject.idle_add(self.__set_file_idle_cb, tempfile)
+        GObject.idle_add(self.__set_file_idle_cb, tempfile)
 
     def __set_file_idle_cb(self, file_path):
         self.view.set_file_location(file_path)
@@ -335,7 +336,7 @@ class ImageViewerActivity(activity.Activity):
 
         self.progressdialog.destroy()
 
-        gobject.idle_add(self.__set_file_idle_cb, tempfile)
+        GObject.idle_add(self.__set_file_idle_cb, tempfile)
         self.save()
 
     def _download_progress_cb(self, getter, bytes_downloaded, tube_id):
@@ -351,7 +352,7 @@ class ImageViewerActivity(activity.Activity):
         fraction = bytes_downloaded / total
         self.progressdialog.set_fraction(fraction)
 
-        #gtk.main_iteration()
+        #Gtk.main_iteration()
 
     def _download_error_cb(self, getter, err, tube_id):
         _logger.debug("Error getting document from tube %u: %s",
@@ -360,12 +361,12 @@ class ImageViewerActivity(activity.Activity):
         self._want_document = True
         self._download_content_length = 0
         self._download_content_type = None
-        gobject.idle_add(self._get_document)
+        GObject.idle_add(self._get_document)
 
     def _download_document(self, tube_id, path):
         # FIXME: should ideally have the CM listen on a Unix socket
         # instead of IPv4 (might be more compatible with Rainbow)
-        chan = self._shared_activity.telepathy_tubes_chan
+        chan = self.shared_activity.telepathy_tubes_chan
         iface = chan[telepathy.CHANNEL_TYPE_TUBES]
         addr = iface.AcceptStreamTube(tube_id,
                 telepathy.SOCKET_ADDRESS_TYPE_IPV4,
@@ -413,7 +414,7 @@ class ImageViewerActivity(activity.Activity):
 
         # Avoid trying to download the document multiple times at once
         self._want_document = False
-        gobject.idle_add(self._download_document, tube_id, path)
+        GObject.idle_add(self._download_document, tube_id, path)
         return False
 
     def _joined_cb(self, also_self):
@@ -426,7 +427,7 @@ class ImageViewerActivity(activity.Activity):
         self.progressdialog = ProgressDialog.ProgressDialog(self)
         self.progressdialog.show_all()
 
-        gobject.idle_add(self._get_document)
+        GObject.idle_add(self._get_document)
 
     def _share_document(self):
         """Share the document."""
@@ -438,7 +439,7 @@ class ImageViewerActivity(activity.Activity):
             self._tempfile)
 
         # Make a tube for it
-        chan = self._shared_activity.telepathy_tubes_chan
+        chan = self.shared_activity.telepathy_tubes_chan
         iface = chan[telepathy.CHANNEL_TYPE_TUBES]
         self._fileserver_tube_id = \
                 iface.OfferStreamTube(IMAGEVIEWER_STREAM_SERVICE,
@@ -449,7 +450,7 @@ class ImageViewerActivity(activity.Activity):
 
     def watch_for_tubes(self):
         """Watch for new tubes."""
-        tubes_chan = self._shared_activity.telepathy_tubes_chan
+        tubes_chan = self.shared_activity.telepathy_tubes_chan
 
         tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal('NewTube',
             self._new_tube_cb)
@@ -468,7 +469,7 @@ class ImageViewerActivity(activity.Activity):
             self.unused_download_tubes.add(tube_id)
             # if no download is in progress, let's fetch the document
             if self._want_document:
-                gobject.idle_add(self._get_document)
+                GObject.idle_add(self._get_document)
 
     def _list_tubes_reply_cb(self, tubes):
         """Callback when new tubes are available."""
diff --git a/ProgressDialog.py b/ProgressDialog.py
index a46bae3..aa9cea8 100644
--- a/ProgressDialog.py
+++ b/ProgressDialog.py
@@ -1,24 +1,24 @@
-import gtk
+from gi.repository import Gtk
 from gettext import gettext as _
 
 
-class ProgressDialog(gtk.Dialog):
+class ProgressDialog(Gtk.Dialog):
 
     def __init__(self, parent):
-        gtk.Dialog.__init__(self, _('Downloading...'), parent, \
-                gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, \
-                (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT))
+        GObject.GObject.__init__(self, _('Downloading...'), parent, \
+                Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, \
+                (Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT))
 
         self._activity = parent
 
         self.connect('response', self._response_cb)
 
-        self._pb = gtk.ProgressBar()
+        self._pb = Gtk.ProgressBar()
         self._pb.set_text(_('Retrieving shared image, please wait...'))
         self.vbox.add(self._pb)
 
     def _response_cb(self, dialog, response_id):
-        if response_id == gtk.RESPONSE_REJECT:
+        if response_id == Gtk.ResponseType.REJECT:
             self._activity.close()
         else:
             pass
-- 
1.7.10.2



More information about the Sugar-devel mailing list