Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksey Lim <alsroot@member.fsf.org>2009-05-26 11:16:01 (GMT)
committer Aleksey Lim <alsroot@member.fsf.org>2009-05-26 11:16:01 (GMT)
commit2302c3d2cf1688a5d8b44c4f927f96a0e4d58c04 (patch)
tree4b3bc949141a172415ffc8d2e767dc0a0667abca
parent584443c3db446e59d70778e37a2602fd58cb6c60 (diff)
Update sugar-port
-rw-r--r--port/AUTHORS1
-rw-r--r--port/NEWS8
-rw-r--r--port/README5
-rw-r--r--port/TODO0
-rw-r--r--port/activity.py34
-rw-r--r--port/chooser.py4
-rw-r--r--port/epydoc21
-rw-r--r--port/images/tempo1.svg8
-rw-r--r--port/images/tempo2.svg9
-rw-r--r--port/images/tempo3.svg8
-rw-r--r--port/images/tempo4.svg9
-rw-r--r--port/images/tempo5.svg9
-rw-r--r--port/images/tempo6.svg11
-rw-r--r--port/images/tempo7.svg9
-rw-r--r--port/images/tempo8.svg10
-rw-r--r--port/pixbuf.py179
l---------port/port1
-rw-r--r--port/tarball.py15
-rw-r--r--port/temposlider.py142
19 files changed, 358 insertions, 125 deletions
diff --git a/port/AUTHORS b/port/AUTHORS
deleted file mode 100644
index 47ead6c..0000000
--- a/port/AUTHORS
+++ /dev/null
@@ -1 +0,0 @@
-Aleksey Lim <alsroot@member.fsf.org>
diff --git a/port/NEWS b/port/NEWS
deleted file mode 100644
index 0dcfeb5..0000000
--- a/port/NEWS
+++ /dev/null
@@ -1,8 +0,0 @@
-1
-
-* Add tarball.py
-* Add json import wrapper
-* Add object chooser
-* Add activity classes
-* Add pixbuf methods
-* Add TempoSlider and ScrolledBox widgets
diff --git a/port/README b/port/README
index bd0dade..256200d 100644
--- a/port/README
+++ b/port/README
@@ -7,6 +7,11 @@ Cornerstone purposes for this project:
* Total backwards compatibility for sugar-port API
* Run on all sugar platforms beginning from 0.82
+In most cases sugar-port could be embedded to activity's directory tree.
+There is no need to include the whole sugar-port project only top level
+files/directories you are using directly - sugar-port's top level entities
+don't import each other.
+
Get it
------
diff --git a/port/TODO b/port/TODO
deleted file mode 100644
index e69de29..0000000
--- a/port/TODO
+++ /dev/null
diff --git a/port/activity.py b/port/activity.py
index dfe6a4a..e3b6fdd 100644
--- a/port/activity.py
+++ b/port/activity.py
@@ -17,6 +17,7 @@
import gtk
import logging
import telepathy
+import gobject
import sugar.activity.activity as toolkit
from sugar.presence.sugartubeconn import SugarTubeConnection
@@ -27,6 +28,18 @@ _NEW_INSTANCE = 1
_PRE_INSTANCE = 2
_POST_INSTANCE = 3
+class CursorFactory:
+ __shared_state = {"cursors": {}}
+
+ def __init__(self):
+ self.__dict__ = self.__shared_state
+
+ def get_cursor(self, cur_type):
+ if not self.cursors.has_key(cur_type):
+ cur = gtk.gdk.Cursor(cur_type)
+ self.cursors[cur_type] = cur
+ return self.cursors[cur_type]
+
class Activity(toolkit.Activity):
"""Basic activity class"""
@@ -57,6 +70,10 @@ class Activity(toolkit.Activity):
"""
raise NotImplementedError
+ def on_save_instance(self, cb, *args):
+ """ Register callback which will be invoked before save_instance """
+ self.__on_save_instance.append((cb, args))
+
def share_instance(self, connection, is_initiator):
"""
Activity was shared/joined.
@@ -98,6 +115,17 @@ class Activity(toolkit.Activity):
alert.show_all()
self.add_alert(alert)
+ def get_cursor(self):
+ return self._cursor
+
+ def set_cursor(self, cursor):
+ if not isinstance(cursor, gtk.gdk.Cursor):
+ cursor = CursorFactory().get_cursor(cursor)
+
+ if self._cursor != cursor:
+ self._cursor = cursor
+ self.window.set_cursor(self._cursor)
+
def __init__(self, canvas, handle):
"""
Initialise the Activity.
@@ -120,6 +148,10 @@ class Activity(toolkit.Activity):
self.__resume_filename = None
self.__postponed_share = []
+ self.__on_save_instance = []
+
+ self._cursor = None
+ self.set_cursor(gtk.gdk.LEFT_PTR)
# XXX do it after(possible) read_file() invoking
# have to rely on calling read_file() from map_cb in sugar-toolkit
@@ -153,6 +185,8 @@ class Activity(toolkit.Activity):
def write_file(self, filepath):
"""Subclass should not override this method"""
+ for cb, args in self.__on_save_instance:
+ cb(*args)
self.save_instance(filepath)
def __map_canvasactivity_cb(self, widget):
diff --git a/port/chooser.py b/port/chooser.py
index b7046be..e2df259 100644
--- a/port/chooser.py
+++ b/port/chooser.py
@@ -34,9 +34,9 @@ def pick(cb=None, default=None, parent=None, what=None):
* cb(jobject), if object was choosen and cb is not None
* jobject, if object was choosen and cb is None
- * None, otherwise
+ * default, otherwise
- NOTE: what make sense only for sugar >= 0.84
+ NOTE: 'what' makes sense only for sugar >= 0.84
"""
what = what and {'what_filter': what} or {}
chooser = ObjectChooser(parent=parent, **what)
diff --git a/port/epydoc b/port/epydoc
deleted file mode 100644
index 3e4852c..0000000
--- a/port/epydoc
+++ /dev/null
@@ -1,21 +0,0 @@
-[epydoc]
-
-modules: *.py
-output: html
-target: html/
-verbosity: 0
-debug: 0
-
-# Generation options
-docformat: epytext
-parse: yes
-introspect: no
-inheritance: listed
-private: no
-imports: no
-sourcecode: yes
-
-# Output options
-name: sugar-port
-url: http://wiki.sugarlabs.org/go/Development_Team/sugar-port
-frames: yes
diff --git a/port/images/tempo1.svg b/port/images/tempo1.svg
deleted file mode 100644
index bb9aeec..0000000
--- a/port/images/tempo1.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14576) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- width="50px" height="50px" viewBox="0 0 50 50" enable-background="new 0 0 50 50" xml:space="preserve">
-<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M23.5,6.5c3,3,7,7,9,11c-7,5-4,6-3,26c-1,1-8,1-9,0c0,0,2,1,2-1
- c0-3-2-7-2-11c0-2,1-4,1-6c0-3-2-1-2-3c0-3,3-8,3-11c0-2-1-1-2-2v-3H23.5z"/>
-</svg>
diff --git a/port/images/tempo2.svg b/port/images/tempo2.svg
deleted file mode 100644
index 4a98310..0000000
--- a/port/images/tempo2.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14576) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- width="50px" height="50px" viewBox="0 0 50 50" enable-background="new 0 0 50 50" xml:space="preserve">
-<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M27.5,44.5v-3C28.5,42.5,28.5,43.5,27.5,44.5z M26.5,10.5
- c2,2,2,6,2,8c0,4-3,11-3,13s4,7,7,10c-2,2-4,3-5,5h-6c1-1,2-3,2-5c0-3-2-9-3-14c0,0,0-1-1,0v-6c0-3,3-8,3-11c0-1-2-2-2-6h3
- C23.5,5.5,26.5,9.5,26.5,10.5z"/>
-</svg>
diff --git a/port/images/tempo3.svg b/port/images/tempo3.svg
deleted file mode 100644
index bd893bd..0000000
--- a/port/images/tempo3.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14576) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- width="50px" height="50px" viewBox="0 0 50 50" enable-background="new 0 0 50 50" xml:space="preserve">
-<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M30.5,17.5c0,3-2,2-2,4c0,3,4,14,7,21c-1,0-3,1-5,1c1-1,2,0,2-3
- c0-2-4-7-6-10c-3,3-5,8-7,13c-1,0-3-1-4-1c3-3,7-14,7-18s-1-3-4-4c3-2,4-8,4-14h3C23.5,9.5,30.5,14.5,30.5,17.5z"/>
-</svg>
diff --git a/port/images/tempo4.svg b/port/images/tempo4.svg
deleted file mode 100644
index 6fa5afa..0000000
--- a/port/images/tempo4.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14576) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- width="50px" height="50px" viewBox="0 0 50 50" enable-background="new 0 0 50 50" xml:space="preserve">
-<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M34.5,22.5c-1-1-2-4-5-6c-1,2,0,3,0,6c0,2-3,4-3,7c0,2,4,2,4,4
- c0,3-1,4-2,5c0-1,0-3-1-4c-1,3-2,7-3,10c-4-3,0-6,0-9s-3-11-4-17l-4,4c1-5,8.25-11.12,7.25-16.12c0.68,0.68,3.029,0,2.87,2.12
- C26.5,10.25,33.62,17.75,34.5,22.5z"/>
-</svg>
diff --git a/port/images/tempo5.svg b/port/images/tempo5.svg
deleted file mode 100644
index 9500e7e..0000000
--- a/port/images/tempo5.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14576) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- width="50px" height="50px" viewBox="0 0 50 50" enable-background="new 0 0 50 50" xml:space="preserve">
-<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M24.5,13.5c2,1,5,3,5,6c0,2-2,3-2,5c0,9,11,4,11,13c-1,0-3-2-4-3
- c-3-1-9,1-10-3c-2,3-5,7-7,11c-3,0-3-1-4-1c0-2,3-3,4-6s4-8,4-10c0-3-1-3-2-5c-1,0-2,1-3,2c0-1,2-3,2-4c1-2,3-5,2-8c0,0,1-1,4-2
- C25.5,9.5,25.5,11.5,24.5,13.5z"/>
-</svg>
diff --git a/port/images/tempo6.svg b/port/images/tempo6.svg
deleted file mode 100644
index 9844fd6..0000000
--- a/port/images/tempo6.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14576) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- width="50px" height="50px" viewBox="0 0 50 50" enable-background="new 0 0 50 50" xml:space="preserve">
-<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M22.5,10.5c3,2,7,5,7,7c0,3-4,8-4,10c0,3,1,3,1,5h5l2-2l2,2v4
- c-1,0-3-2-5-2c-3,0-5,1-8,1c-1,3-2,7-2,10h-5c1-1,3-3,3-4c1-5,1-11,1-18l-1-1c-1,1-1.75,2.88-2.75,2.88c0,0-0.25-0.63-0.25-1.63
- c4-4,2-8.25,2-13.25c0-1,0.25-2.5,0.38-5.38L22.5,5.5C23.12,6.5,22.5,8.5,22.5,10.5z"/>
-<polygon fill-rule="evenodd" clip-rule="evenodd" fill="#333333" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" points="
- 25,20 25.25,16.75 26.5,17.88 "/>
-</svg>
diff --git a/port/images/tempo7.svg b/port/images/tempo7.svg
deleted file mode 100644
index 54bed80..0000000
--- a/port/images/tempo7.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14576) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- width="50px" height="50px" viewBox="0 0 50 50" enable-background="new 0 0 50 50" xml:space="preserve">
-<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M20.5,7.5c1,1,1,3,1,4c10,4,8,6,8,14c0,2,6,9,10,13c-1,2-2,4-4,5
- c1.62-8.88-8.75-13.88-12-15c-1,1-1,0-1,2c0,3,2,5,3,7c-1,1-3,2-6,2c0-1,2-1,2-4c0-2-4-4-4-6c0-3,3-4,5-6c-3-8-8-2-11-6h6
- c0-1,1,0,1-3c0-2-1-1-2-2l1-5H20.5z"/>
-</svg>
diff --git a/port/images/tempo8.svg b/port/images/tempo8.svg
deleted file mode 100644
index 2c0154f..0000000
--- a/port/images/tempo8.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14576) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- width="50px" height="50px" viewBox="0 0 50 50" enable-background="new 0 0 50 50" xml:space="preserve">
-<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M20.5,12.5c0.67,0.4,0.4,1.9,1.75,2.25s1.05-0.38,1.5-0.37
- c4.971,0,10.95-0.88,11.75,7.12c-1-2-3-4-5-5l-4,1c1,2,4,4,5,7c1,1,1,4,1,6c3,3,8-1,11,6c-2.88-0.82-4.25-2.62-12.75-2.75
- c-1.561-0.02-2.34-1.561-3.75-1.87c-3.42-0.76-4.67-0.38-5.5-0.38c-3,0-8,7-11,7c-2,0-3-1-3-2c4,2,8-4,9-7c2-1,5-1,8-3c-2-4-6-5-8-3
- l-6-6l2-2c1,1,1,2,1,4c1,0,4.12,0.38,6.12-0.62L16.5,17.5v-5H20.5z"/>
-</svg>
diff --git a/port/pixbuf.py b/port/pixbuf.py
index 4390fef..ba6d0f5 100644
--- a/port/pixbuf.py
+++ b/port/pixbuf.py
@@ -14,10 +14,16 @@
"""gtk.gdk.Pixbuf extensions"""
+import re
import os
import cStringIO
-import tempfile
import gtk
+import rsvg
+import cairo
+import logging
+
+from sugar.graphics.xocolor import XoColor
+from sugar.util import LRU
def to_file(pixbuf):
"""Convert pixbuf object to file object"""
@@ -38,13 +44,170 @@ def to_str(pixbuf):
def from_str(str):
"""Convert string to pixbuf object"""
- file_d, path = tempfile.mkstemp()
+ loader = gtk.gdk.pixbuf_loader_new_with_mime_type('image/png')
+ loader.write(str)
+ loader.close()
+
+ return loader.get_pixbuf()
+
+def from_svg_at_size(filename=None, width=None, height=None, handle=None,
+ keep_ratio=True):
+ """Scale and load SVG into pixbuf"""
+
+ if not handle:
+ handle = rsvg.Handle(filename)
+
+ dimensions = handle.get_dimension_data()
+ icon_width = dimensions[0]
+ icon_height = dimensions[1]
+
+ if icon_width != width or icon_height != height:
+ ratio_width = float(width) / icon_width
+ ratio_height = float(height) / icon_height
+
+ if keep_ratio:
+ ratio = min(ratio_width, ratio_height)
+ if ratio_width != ratio:
+ ratio_width = ratio
+ width = int(icon_width * ratio)
+ elif ratio_height != ratio:
+ ratio_height = ratio
+ height = int(icon_height * ratio)
+ else:
+ ratio_width = 1
+ ratio_height = 1
+
+ surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
+ context = cairo.Context(surface)
+ context.scale(ratio_width, ratio_height)
+ handle.render_cairo(context)
+
+ loader = gtk.gdk.pixbuf_loader_new_with_mime_type('image/png')
+ surface.write_to_png(loader)
+ loader.close()
+
+ return loader.get_pixbuf()
+
+def sugar_icon(file_name=None, icon_name=None,
+ width=None, height=None,
+ color=None,
+ insensitive_widget=None):
+ """Load sugar icon into pixbuf
+
+ NOTE: Function can load all image formats but makes sense only for SVG
+ (due to color argument, see load_svg())
+
+ NOTE: Function caches results
+
+ Arguments:
+ file_name path to filename with image
+ (mutually exclusive for icon_name)
+ icon_name name of icon
+ (mutually exclusive for icon_name)
+ width width of final image
+ height height of final image
+ color defines stroke and fill colors for final SVG image
+ in string notion, could be:
+ * tuple of (stroke_color, fill_color)
+ * XoColor
+ * scalar value for stroke and fill colors
+ insensitive_widget render icon in insensitive mode
+ """
+ def load_svg():
+ entities = {}
+ if fill_color:
+ entities['fill_color'] = fill_color
+ if stroke_color:
+ entities['stroke_color'] = stroke_color
+
+ f = open(icon_filename, 'r')
+ icon = f.read()
+ f.close()
+
+ for entity, value in entities.items():
+ xml = '<!ENTITY %s "%s">' % (entity, value)
+ icon = re.sub('<!ENTITY %s .*>' % entity, xml, icon)
+
+ return rsvg.Handle(data=icon)
+
+ def get_insensitive_pixbuf():
+ if not (insensitive_widget and insensitive_widget.style):
+ return pixbuf
+
+ icon_source = gtk.IconSource()
+ # Special size meaning "don't touch"
+ icon_source.set_size(-1)
+ icon_source.set_pixbuf(pixbuf)
+ icon_source.set_state(gtk.STATE_INSENSITIVE)
+ icon_source.set_direction_wildcarded(False)
+ icon_source.set_size_wildcarded(False)
+
+ # Please note that the pixbuf returned by this function is leaked
+ # with current stable versions of pygtk. The relevant bug is
+ # http://bugzilla.gnome.org/show_bug.cgi?id=502871
+ # -- 2007-12-14 Benjamin Berg
+ pixbuf = insensitive_widget.style.render_icon(icon_source,
+ insensitive_widget.get_direction(), gtk.STATE_INSENSITIVE, -1,
+ insensitive_widget, "sugar-icon")
+
+ return pixbuf
+
+ def get_cache_key():
+ return (icon_filename, fill_color, stroke_color, width, height,
+ insensitive_widget is None)
+
+ if isinstance(color, XoColor):
+ stroke_color = color.get_stroke_color()
+ fill_color = color.get_fill_color()
+ elif isinstance(color, tuple):
+ stroke_color = color[0]
+ fill_color = color[1]
+ else:
+ stroke_color = color
+ fill_color = color
+
+ if file_name:
+ icon_filename = file_name
+ elif icon_name:
+ theme = gtk.icon_theme_get_default()
+ info = theme.lookup_icon(icon_name, width or 50, 0)
+ if info:
+ icon_filename = info.get_filename()
+ del info
+ else:
+ logging.warning('No icon with the name %s '
+ 'was found in the theme.' % icon_name)
+ else:
+ return None
+
+ cache_key = get_cache_key()
+ if cache_key in _sugar_icon_cache:
+ return _sugar_icon_cache[cache_key]
+
+ logging.debug('sugar_icon: file_name=%s icon_name=%s width=%s height=%s ' \
+ 'color=%s' % (file_name, icon_name, width, height, color))
+
+ is_svg = icon_filename.endswith('.svg')
+
+ if is_svg:
+ handle = load_svg()
+ if width and height:
+ pixbuf = from_svg_at_size(handle=handle, width=width, height=height,
+ keep_ratio=True)
+ else:
+ pixbuf = handle.get_pixbuf()
+ else:
+ if width and height:
+ pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(icon_filename,
+ width, height)
+ else:
+ pixbuf = gtk.gdk.pixbuf_new_from_file(icon_filename)
+
+ if insensitive_widget:
+ pixbuf = get_insensitive_pixbuf()
- file_o = os.fdopen(file_d, 'w')
- file_o.write(str)
- file_o.close()
+ _sugar_icon_cache[cache_key] = pixbuf
- out = gtk.gdk.pixbuf_new_from_file(path)
- os.unlink(path)
+ return pixbuf
- return out
+_sugar_icon_cache = LRU(50)
diff --git a/port/port b/port/port
deleted file mode 120000
index 945c9b4..0000000
--- a/port/port
+++ /dev/null
@@ -1 +0,0 @@
-. \ No newline at end of file
diff --git a/port/tarball.py b/port/tarball.py
index d07a3e1..9e842b9 100644
--- a/port/tarball.py
+++ b/port/tarball.py
@@ -23,8 +23,6 @@ import zipfile
import tempfile
import shutil
-import port.pixbuf as pixbuf
-
class TarballError(Exception):
"""Base Tarball exception."""
pass
@@ -124,7 +122,10 @@ class Tarball:
def read_pixbuf(self, arcname):
"""Returns pixbuf object of given file from tarball."""
- return pixbuf.from_str(self.read(arcname))
+ loader = gtk.gdk.pixbuf_loader_new_with_mime_type('image/png')
+ loader.write(self.read(arcname))
+ loader.close()
+ return loader.get_pixbuf()
def write(self, arcname, data, mode=0644):
"""
@@ -147,8 +148,12 @@ class Tarball:
self.__tar.addfile(info, cStringIO.StringIO(data))
def __write_pixbuf(self, info, data):
- buffer = pixbuf.to_file(data)
- buffer.seek(0, os.SEEK_END)
+ def push(pixbuf, buffer):
+ buffer.write(pixbuf)
+
+ buffer = cStringIO.StringIO()
+ data.save_to_callback(push, 'png', user_data=buffer)
+
info.size = buffer.tell()
buffer.seek(0)
self.__tar.addfile(info, buffer)
diff --git a/port/temposlider.py b/port/temposlider.py
index 9d14be8..6950453 100644
--- a/port/temposlider.py
+++ b/port/temposlider.py
@@ -12,8 +12,9 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-import os
import gtk
+import rsvg
+import cairo
from sugar.graphics import style
@@ -26,7 +27,7 @@ class TempoSlider(gtk.HBox):
self._image.show()
# used to store tempo updates while the slider is active
- self._delayed = 0
+ self._delayed = 0
self._active = False
self.adjustment = gtk.Adjustment(min_value, min_value, max_value,
@@ -68,10 +69,10 @@ class TempoSlider(gtk.HBox):
self.adjustment.upper, 0, 7)
if not self._pixbuf[img]:
- self._pixbuf[img] = gtk.gdk.pixbuf_new_from_file_at_size(
- os.path.join(os.path.dirname(__file__), 'images',
- 'tempo' + str(img+1) + '.svg'),
- style.STANDARD_ICON_SIZE, style.STANDARD_ICON_SIZE)
+ svg = rsvg.Handle(data=IMAGE[img])
+ self._pixbuf[img] = _from_svg_at_size(handle=svg,
+ width=style.STANDARD_ICON_SIZE,
+ height=style.STANDARD_ICON_SIZE)
self._image.set_from_pixbuf(self._pixbuf[img])
@@ -83,3 +84,132 @@ class TempoSlider(gtk.HBox):
if self._delayed != 0:
self.set_value(self._delayed, True)
self._delayed = 0
+
+def _from_svg_at_size(filename=None, width=None, height=None, handle=None,
+ keep_ratio=True):
+ """ import from pixbuf.py """
+
+ if not handle:
+ handle = rsvg.Handle(filename)
+
+ dimensions = handle.get_dimension_data()
+ icon_width = dimensions[0]
+ icon_height = dimensions[1]
+
+ if icon_width != width or icon_height != height:
+ ratio_width = float(width) / icon_width
+ ratio_height = float(height) / icon_height
+
+ if keep_ratio:
+ ratio = min(ratio_width, ratio_height)
+ if ratio_width != ratio:
+ ratio_width = ratio
+ width = int(icon_width * ratio)
+ elif ratio_height != ratio:
+ ratio_height = ratio
+ height = int(icon_height * ratio)
+ else:
+ ratio_width = 1
+ ratio_height = 1
+
+ surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
+ context = cairo.Context(surface)
+ context.scale(ratio_width, ratio_height)
+ handle.render_cairo(context)
+
+ loader = gtk.gdk.pixbuf_loader_new_with_mime_type('image/png')
+ surface.write_to_png(loader)
+ loader.close()
+
+ return loader.get_pixbuf()
+
+IMAGE = [None] * 8
+
+IMAGE[0] = """<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14576) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="50px" height="50px" viewBox="0 0 50 50" enable-background="new 0 0 50 50" xml:space="preserve">
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M23.5,6.5c3,3,7,7,9,11c-7,5-4,6-3,26c-1,1-8,1-9,0c0,0,2,1,2-1
+ c0-3-2-7-2-11c0-2,1-4,1-6c0-3-2-1-2-3c0-3,3-8,3-11c0-2-1-1-2-2v-3H23.5z"/>
+</svg>
+"""
+
+IMAGE[1] = """<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14576) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="50px" height="50px" viewBox="0 0 50 50" enable-background="new 0 0 50 50" xml:space="preserve">
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M27.5,44.5v-3C28.5,42.5,28.5,43.5,27.5,44.5z M26.5,10.5
+ c2,2,2,6,2,8c0,4-3,11-3,13s4,7,7,10c-2,2-4,3-5,5h-6c1-1,2-3,2-5c0-3-2-9-3-14c0,0,0-1-1,0v-6c0-3,3-8,3-11c0-1-2-2-2-6h3
+ C23.5,5.5,26.5,9.5,26.5,10.5z"/>
+</svg>
+"""
+
+IMAGE[2] = """<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14576) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="50px" height="50px" viewBox="0 0 50 50" enable-background="new 0 0 50 50" xml:space="preserve">
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M30.5,17.5c0,3-2,2-2,4c0,3,4,14,7,21c-1,0-3,1-5,1c1-1,2,0,2-3
+ c0-2-4-7-6-10c-3,3-5,8-7,13c-1,0-3-1-4-1c3-3,7-14,7-18s-1-3-4-4c3-2,4-8,4-14h3C23.5,9.5,30.5,14.5,30.5,17.5z"/>
+</svg>
+"""
+
+IMAGE[3] = """<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14576) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="50px" height="50px" viewBox="0 0 50 50" enable-background="new 0 0 50 50" xml:space="preserve">
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M34.5,22.5c-1-1-2-4-5-6c-1,2,0,3,0,6c0,2-3,4-3,7c0,2,4,2,4,4
+ c0,3-1,4-2,5c0-1,0-3-1-4c-1,3-2,7-3,10c-4-3,0-6,0-9s-3-11-4-17l-4,4c1-5,8.25-11.12,7.25-16.12c0.68,0.68,3.029,0,2.87,2.12
+ C26.5,10.25,33.62,17.75,34.5,22.5z"/>
+</svg>
+"""
+
+IMAGE[4] = """<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14576) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="50px" height="50px" viewBox="0 0 50 50" enable-background="new 0 0 50 50" xml:space="preserve">
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M24.5,13.5c2,1,5,3,5,6c0,2-2,3-2,5c0,9,11,4,11,13c-1,0-3-2-4-3
+ c-3-1-9,1-10-3c-2,3-5,7-7,11c-3,0-3-1-4-1c0-2,3-3,4-6s4-8,4-10c0-3-1-3-2-5c-1,0-2,1-3,2c0-1,2-3,2-4c1-2,3-5,2-8c0,0,1-1,4-2
+ C25.5,9.5,25.5,11.5,24.5,13.5z"/>
+</svg>
+"""
+
+IMAGE[5] = """<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14576) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="50px" height="50px" viewBox="0 0 50 50" enable-background="new 0 0 50 50" xml:space="preserve">
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M22.5,10.5c3,2,7,5,7,7c0,3-4,8-4,10c0,3,1,3,1,5h5l2-2l2,2v4
+ c-1,0-3-2-5-2c-3,0-5,1-8,1c-1,3-2,7-2,10h-5c1-1,3-3,3-4c1-5,1-11,1-18l-1-1c-1,1-1.75,2.88-2.75,2.88c0,0-0.25-0.63-0.25-1.63
+ c4-4,2-8.25,2-13.25c0-1,0.25-2.5,0.38-5.38L22.5,5.5C23.12,6.5,22.5,8.5,22.5,10.5z"/>
+<polygon fill-rule="evenodd" clip-rule="evenodd" fill="#333333" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" points="
+ 25,20 25.25,16.75 26.5,17.88 "/>
+</svg>
+"""
+
+IMAGE[6] = """<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14576) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="50px" height="50px" viewBox="0 0 50 50" enable-background="new 0 0 50 50" xml:space="preserve">
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M20.5,7.5c1,1,1,3,1,4c10,4,8,6,8,14c0,2,6,9,10,13c-1,2-2,4-4,5
+ c1.62-8.88-8.75-13.88-12-15c-1,1-1,0-1,2c0,3,2,5,3,7c-1,1-3,2-6,2c0-1,2-1,2-4c0-2-4-4-4-6c0-3,3-4,5-6c-3-8-8-2-11-6h6
+ c0-1,1,0,1-3c0-2-1-1-2-2l1-5H20.5z"/>
+</svg>
+"""
+
+IMAGE[7] = """<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14576) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="50px" height="50px" viewBox="0 0 50 50" enable-background="new 0 0 50 50" xml:space="preserve">
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF" d="M20.5,12.5c0.67,0.4,0.4,1.9,1.75,2.25s1.05-0.38,1.5-0.37
+ c4.971,0,10.95-0.88,11.75,7.12c-1-2-3-4-5-5l-4,1c1,2,4,4,5,7c1,1,1,4,1,6c3,3,8-1,11,6c-2.88-0.82-4.25-2.62-12.75-2.75
+ c-1.561-0.02-2.34-1.561-3.75-1.87c-3.42-0.76-4.67-0.38-5.5-0.38c-3,0-8,7-11,7c-2,0-3-1-3-2c4,2,8-4,9-7c2-1,5-1,8-3c-2-4-6-5-8-3
+ l-6-6l2-2c1,1,1,2,1,4c1,0,4.12,0.38,6.12-0.62L16.5,17.5v-5H20.5z"/>
+</svg>
+"""