diff options
author | Walter Bender <walter.bender@gmail.com> | 2012-10-29 14:24:44 (GMT) |
---|---|---|
committer | Walter Bender <walter.bender@gmail.com> | 2012-10-29 14:24:44 (GMT) |
commit | 72f6733bde67ccb3aef4b027dd922ff69b89125b (patch) | |
tree | 05ebc5eb3792f22e993db1873937c01e2368b6bc | |
parent | b3a16438ef52f1c0f8b5e375668a946da8e38551 (diff) |
gtk3 port
-rw-r--r-- | YupanaActivity.py | 88 | ||||
-rw-r--r-- | setup.py | 3 | ||||
-rw-r--r-- | sprites.py | 393 | ||||
-rw-r--r-- | toolbar_utils.py | 4 | ||||
-rw-r--r-- | utils.py | 49 | ||||
-rw-r--r-- | yupana.py | 77 |
6 files changed, 89 insertions, 525 deletions
diff --git a/YupanaActivity.py b/YupanaActivity.py index 5df63d9..9718230 100644 --- a/YupanaActivity.py +++ b/YupanaActivity.py @@ -1,4 +1,4 @@ -#Copyright (c) 2011 Walter Bender +#Copyright (c) 2011,12 Walter Bender #Copyright (c) 2012 Ignacio Rodriguez # This program is free software; you can redistribute it and/or modify @@ -14,16 +14,10 @@ from gi.repository import Gtk, Gdk, GObject from sugar3.activity import activity from sugar3 import profile -try: - from sugar3.graphics.toolbarbox import ToolbarBox - _have_toolbox = True -except ImportError: - _have_toolbox = False - -if _have_toolbox: - from sugar3.activity.widgets import ActivityToolbarButton - from sugar3.activity.widgets import StopButton - from sugar3.graphics.toolbarbox import ToolbarButton +from sugar3.graphics.toolbarbox import ToolbarBox +from sugar3.activity.widgets import ActivityToolbarButton +from sugar3.activity.widgets import StopButton +from sugar3.graphics.toolbarbox import ToolbarButton from toolbar_utils import button_factory, label_factory, separator_factory, \ radio_factory, entry_factory @@ -66,7 +60,7 @@ class YupanaActivity(activity.Activity): else: self.colors = ['#A0FFA0', '#FF8080'] - self._setup_toolbars(_have_toolbox) + self._setup_toolbars() self._setup_dispatch_table() # Create a canvas @@ -89,56 +83,44 @@ class YupanaActivity(activity.Activity): if self._reload_custom: self._custom_cb() - def _setup_toolbars(self, have_toolbox): + def _setup_toolbars(self): """ Setup the toolbars. """ self.max_participants = 4 yupana_toolbar = Gtk.Toolbar() self.custom_toolbar = Gtk.Toolbar() - if have_toolbox: - toolbox = ToolbarBox() - - # Activity toolbar - activity_button = ActivityToolbarButton(self) + toolbox = ToolbarBox() - toolbox.toolbar.insert(activity_button, 0) - activity_button.show() + # Activity toolbar + activity_button = ActivityToolbarButton(self) - yupana_toolbar_button = ToolbarButton( - label=_("Mode"), page=yupana_toolbar, - icon_name='preferences-system') - yupana_toolbar.show() - toolbox.toolbar.insert(yupana_toolbar_button, -1) - yupana_toolbar_button.show() + toolbox.toolbar.insert(activity_button, 0) + activity_button.show() - custom_toolbar_button = ToolbarButton( - label=_("Custom"), page=self.custom_toolbar, - icon_name='view-source') - self.custom_toolbar.show() - toolbox.toolbar.insert(custom_toolbar_button, -1) - custom_toolbar_button.show() + yupana_toolbar_button = ToolbarButton( + label=_("Mode"), page=yupana_toolbar, + icon_name='preferences-system') + yupana_toolbar.show() + toolbox.toolbar.insert(yupana_toolbar_button, -1) + yupana_toolbar_button.show() - self.set_toolbar_box(toolbox) - toolbox.show() - self.toolbar = toolbox.toolbar + custom_toolbar_button = ToolbarButton( + label=_("Custom"), page=self.custom_toolbar, + icon_name='view-source') + self.custom_toolbar.show() + toolbox.toolbar.insert(custom_toolbar_button, -1) + custom_toolbar_button.show() - else: - # Use pre-0.86 toolbar design - toolbox = activity.ActivityToolbox(self) - self.set_toolbox(toolbox) - toolbox.add_toolbar(_('Yupana'), yupana_toolbar) - toolbox.add_toolbar(_('Custom'), self.custom_toolbar) - toolbox.show() - toolbox.set_current_toolbar(1) - self.toolbar = yupana_toolbar + self.set_toolbar_box(toolbox) + toolbox.show() + self.toolbar = toolbox.toolbar self._new_yupana_button = button_factory( 'edit-delete', self.toolbar, self._new_yupana_cb, tooltip=_('Clear the yupana.')) - if not _have_toolbox: - separator_factory(yupana_toolbar, False, True) + separator_factory(yupana_toolbar, False, True) self.ten_button = radio_factory( 'ten', yupana_toolbar, self._ten_cb, tooltip=_('decimal mode'), @@ -161,17 +143,15 @@ class YupanaActivity(activity.Activity): group=self.ten_button) separator_factory(self.toolbar, False, False) - self.status = label_factory(self.toolbar, '') + self.status = label_factory(self.toolbar, '', width=200) self.status.set_label(_('decimal mode')) - if _have_toolbox: - separator_factory(toolbox.toolbar, True, False) + separator_factory(toolbox.toolbar, True, False) - if _have_toolbox: - stop_button = StopButton(self) - stop_button.props.accelerator = '<Ctrl>q' - toolbox.toolbar.insert(stop_button, -1) - stop_button.show() + stop_button = StopButton(self) + stop_button.props.accelerator = '<Ctrl>q' + toolbox.toolbar.insert(stop_button, -1) + stop_button.show() def _make_custom_toolbar(self): self._ones = entry_factory(str(self._yupana.custom[0]), @@ -1,4 +1,5 @@ #!/usr/bin/env python from sugar3.activity import bundlebuilder if __name__ == "__main__": - bundlebuilder.start() + bundlebuilder.start() + @@ -24,7 +24,7 @@ ''' sprites.py is a simple sprites library for managing graphics objects, -'sprites', on a gtk.DrawingArea. It manages multiple sprites with +'sprites', on a Gtk.DrawingArea. It manages multiple sprites with methods such as move, hide, set_layer, etc. There are two classes: @@ -68,401 +68,14 @@ Example usage: # method for converting SVG to a gtk pixbuf def svg_str_to_pixbuf(svg_string): - pl = gtk.gdk.PixbufLoader('svg') + pl = GdkPixbuf.PixbufLoader('svg') pl.write(svg_string) pl.close() pixbuf = pl.get_pixbuf() return pixbuf -''' -## <-----------GTK2---------------->## - -''' - - -import pygtk -pygtk.require('2.0') -import gtk -import pango -import pangocairo -import cairo - -class Sprites: - # A class for the list of sprites and everything they share in common # - - def __init__(self, widget): - # Initialize an empty array of sprites # - self.widget = widget - self.list = [] - self.cr = None - - def set_cairo_context(self, cr): - # Cairo context may be set or reset after __init__ # - self.cr = cr - - def get_sprite(self, i): - # Return a sprint from the array # - if i < 0 or i > len(self.list) - 1: - return(None) - else: - return(self.list[i]) - - def length_of_list(self): - # How many sprites are there? # - return(len(self.list)) - - def append_to_list(self, spr): - # Append a new sprite to the end of the list. # - self.list.append(spr) - - def insert_in_list(self, spr, i): - # Insert a sprite at position i. # - if i < 0: - self.list.insert(0, spr) - elif i > len(self.list) - 1: - self.list.append(spr) - else: - self.list.insert(i, spr) - - def remove_from_list(self, spr): - # Remove a sprite from the list. # - if spr in self.list: - self.list.remove(spr) - - def find_sprite(self, pos, inverse=False): - # Search based on (x, y) position. Return the 'top/first' one. # - list = self.list[:] - if not inverse: - list.reverse() - for spr in list: - if spr.hit(pos): - return spr - return None - - def redraw_sprites(self, area=None, cr=None): - # Redraw the sprites that intersect area. # - # I think I need to do this to save Cairo some work - if cr is None: - cr = self.cr - else: - self.cr = cr - if cr is None: - print 'sprites.redraw_sprites: no Cairo context' - return - for spr in self.list: - if area == None: - spr.draw(cr=cr) - else: - intersection = spr.rect.intersect(area) - if intersection.width > 0 or intersection.height > 0: - spr.draw(cr=cr) - - -class Sprite: - # A class for the individual sprites # - - def __init__(self, sprites, x, y, image): - # Initialize an individual sprite # - self._sprites = sprites - self.save_xy = (x, y) # remember initial (x, y) position - self.rect = gtk.gdk.Rectangle(int(x), int(y), 0, 0) - self._scale = [12] - self._rescale = [True] - self._horiz_align = ["center"] - self._vert_align = ["middle"] - self._fd = None - self._bold = False - self._italic = False - self._color = None - self._margins = [0, 0, 0, 0] - self.layer = 100 - self.labels = [] - self.cached_surfaces = [] - self._dx = [] # image offsets - self._dy = [] - self.type = None - self.set_image(image) - self._sprites.append_to_list(self) - - def set_image(self, image, i=0, dx=0, dy=0): - # Add an image to the sprite. # - while len(self.cached_surfaces) < i + 1: - self.cached_surfaces.append(None) - self._dx.append(0) - self._dy.append(0) - self._dx[i] = dx - self._dy[i] = dy - if isinstance(image, gtk.gdk.Pixbuf) or \ - isinstance(image, cairo.ImageSurface): - w = image.get_width() - h = image.get_height() - else: - w, h = image.get_size() - if i == 0: # Always reset width and height when base image changes. - self.rect.width = w + dx - self.rect.height = h + dy - else: - if w + dx > self.rect.width: - self.rect.width = w + dx - if h + dy > self.rect.height: - self.rect.height = h + dy - if isinstance(image, cairo.ImageSurface): - self.cached_surfaces[i] = image - else: # Convert to Cairo surface - surface = cairo.ImageSurface( - cairo.FORMAT_ARGB32, self.rect.width, self.rect.height) - context = cairo.Context(surface) - context = gtk.gdk.CairoContext(context) - context.set_source_pixbuf(image, 0, 0) - context.rectangle(0, 0, self.rect.width, self.rect.height) - context.fill() - self.cached_surfaces[i] = surface - - def move(self, pos): - # Move to new (x, y) position # - self.inval() - self.rect.x, self.rect.y = int(pos[0]), int(pos[1]) - self.inval() - - def move_relative(self, pos): - # Move to new (x+dx, y+dy) position # - self.inval() - self.rect.x += int(pos[0]) - self.rect.y += int(pos[1]) - self.inval() - - def get_xy(self): - # Return current (x, y) position # - return (self.rect.x, self.rect.y) - - def get_dimensions(self): - # Return current size # - return (self.rect.width, self.rect.height) - - def get_layer(self): - # Return current layer # - return self.layer - - def set_shape(self, image, i=0): - # Set the current image associated with the sprite # - self.inval() - self.set_image(image, i) - self.inval() - - def set_layer(self, layer=None): - # Set the layer for a sprite # - self._sprites.remove_from_list(self) - if layer is not None: - self.layer = layer - for i in range(self._sprites.length_of_list()): - if layer < self._sprites.get_sprite(i).layer: - self._sprites.insert_in_list(self, i) - self.inval() - return - self._sprites.append_to_list(self) - self.inval() - - def set_label(self, new_label, i=0): - # Set the label drawn on the sprite # - self._extend_labels_array(i) - if type(new_label) is str or type(new_label) is unicode: - # pango doesn't like nulls - self.labels[i] = new_label.replace("\0", " ") - else: - self.labels[i] = str(new_label) - self.inval() - - def set_margins(self, l=0, t=0, r=0, b=0): - # Set the margins for drawing the label # - self._margins = [l, t, r, b] - - def _extend_labels_array(self, i): - # Append to the labels attribute list # - if self._fd is None: - self.set_font('Sans') - if self._color is None: - self._color = (0., 0., 0.) - while len(self.labels) < i + 1: - self.labels.append(" ") - self._scale.append(self._scale[0]) - self._rescale.append(self._rescale[0]) - self._horiz_align.append(self._horiz_align[0]) - self._vert_align.append(self._vert_align[0]) - - def set_font(self, font): - # Set the font for a label # - self._fd = pango.FontDescription(font) - - def set_label_color(self, rgb): - # Set the font color for a label # - COLORTABLE = {'black': '#000000', 'white': '#FFFFFF', - 'red': '#FF0000', 'yellow': '#FFFF00', - 'green': '#00FF00', 'cyan': '#00FFFF', - 'blue': '#0000FF', 'purple': '#FF00FF', - 'gray': '#808080'} - if rgb.lower() in COLORTABLE: - rgb = COLORTABLE[rgb.lower()] - # Convert from '#RRGGBB' to floats - self._color = (int('0x' + rgb[1:3], 16) / 256., - int('0x' + rgb[3:5], 16) / 256., - int('0x' + rgb[5:7], 16) / 256.) - return - - def set_label_attributes(self, scale, rescale=True, horiz_align="center", - vert_align="middle", i=0): - # Set the various label attributes # - self._extend_labels_array(i) - self._scale[i] = scale - self._rescale[i] = rescale - self._horiz_align[i] = horiz_align - self._vert_align[i] = vert_align - - def hide(self): - # Hide a sprite # - self.inval() - self._sprites.remove_from_list(self) - - def restore(self): - # Restore a hidden sprite # - self.set_layer() - - def inval(self): - # Invalidate a region for gtk # - self._sprites.widget.queue_draw_area(self.rect.x, - self.rect.y, - self.rect.width, - self.rect.height) - - def draw(self, cr=None): - # Draw the sprite (and label) # - if cr is None: - print 'sprite.draw: no Cairo context.' - return - for i, surface in enumerate(self.cached_surfaces): - cr.set_source_surface(surface, - self.rect.x + self._dx[i], - self.rect.y + self._dy[i]) - cr.rectangle(self.rect.x + self._dx[i], - self.rect.y + self._dy[i], - self.rect.width, - self.rect.height) - cr.fill() - if len(self.labels) > 0: - self.draw_label(cr) - - def hit(self, pos): - # Is (x, y) on top of the sprite? # - x, y = pos - if x < self.rect.x: - return False - if x > self.rect.x + self.rect.width: - return False - if y < self.rect.y: - return False - if y > self.rect.y + self.rect.height: - return False - return True - - def draw_label(self, cr): - # Draw the label based on its attributes # - # Create a pangocairo context - cr = pangocairo.CairoContext(cr) - my_width = self.rect.width - self._margins[0] - self._margins[2] - if my_width < 0: - my_width = 0 - my_height = self.rect.height - self._margins[1] - self._margins[3] - for i in range(len(self.labels)): - pl = cr.create_layout() - pl.set_text(str(self.labels[i])) - self._fd.set_size(int(self._scale[i] * pango.SCALE)) - pl.set_font_description(self._fd) - w = pl.get_size()[0] / pango.SCALE - if w > my_width: - if self._rescale[i]: - self._fd.set_size( - int(self._scale[i] * pango.SCALE * my_width / w)) - pl.set_font_description(self._fd) - w = pl.get_size()[0] / pango.SCALE - else: - j = len(self.labels[i]) - 1 - while(w > my_width and j > 0): - pl.set_text( - "…" + self.labels[i][len(self.labels[i]) - j:]) - self._fd.set_size(int(self._scale[i] * pango.SCALE)) - pl.set_font_description(self._fd) - w = pl.get_size()[0] / pango.SCALE - j -= 1 - if self._horiz_align[i] == "center": - x = int(self.rect.x + self._margins[0] + (my_width - w) / 2) - elif self._horiz_align[i] == 'left': - x = int(self.rect.x + self._margins[0]) - else: # right - x = int(self.rect.x + self.rect.width - w - self._margins[2]) - h = pl.get_size()[1] / pango.SCALE - if self._vert_align[i] == "middle": - y = int(self.rect.y + self._margins[1] + (my_height - h) / 2) - elif self._vert_align[i] == "top": - y = int(self.rect.y + self._margins[1]) - else: # bottom - y = int(self.rect.y + self.rect.height - h - self._margins[3]) - cr.save() - cr.translate(x, y) - cr.set_source_rgb(self._color[0], self._color[1], self._color[2]) - cr.update_layout(pl) - cr.show_layout(pl) - cr.restore() - - def label_width(self): - # Calculate the width of a label # - cr = pangocairo.CairoContext(self._sprites.cr) - if cr is not None: - max = 0 - for i in range(len(self.labels)): - pl = cr.create_layout() - pl.set_text(self.labels[i]) - self._fd.set_size(int(self._scale[i] * pango.SCALE)) - pl.set_font_description(self._fd) - w = pl.get_size()[0] / pango.SCALE - if w > max: - max = w - return max - else: - return self.rect.width - - def label_safe_width(self): - # Return maximum width for a label # - return self.rect.width - self._margins[0] - self._margins[2] - - def label_safe_height(self): - # Return maximum height for a label # - return self.rect.height - self._margins[1] - self._margins[3] - - def label_left_top(self): - # Return the upper-left corner of the label safe zone # - return(self._margins[0], self._margins[1]) - - def get_pixel(self, pos, i=0): - # Return the pixel at (x, y) # - x = int(pos[0] - self.rect.x) - y = int(pos[1] - self.rect.y) - if x < 0 or x > (self.rect.width - 1) or \ - y < 0 or y > (self.rect.height - 1): - return(-1, -1, -1, -1) - - # create a new 1x1 cairo surface - cs = cairo.ImageSurface(cairo.FORMAT_RGB24, 1, 1); - cr = cairo.Context(cs) - cr.set_source_surface(self.cached_surfaces[i], -x, -y) - cr.rectangle(0,0,1,1) - cr.set_operator(cairo.OPERATOR_SOURCE) - cr.fill() - cs.flush() # ensure all writing is done - # Read the pixel - pixels = cs.get_data() - return (ord(pixels[2]), ord(pixels[1]), ord(pixels[0]), 0) ''' -#<-----------------------GTK3-----------># import gi from gi.repository import Gtk, GdkPixbuf, Gdk from gi.repository import Pango, PangoCairo @@ -528,7 +141,6 @@ class Sprites: else: self.cr = cr if cr is None: - print 'sprites.redraw_sprites: no Cairo context' return for spr in self.list: if area == None: @@ -715,7 +327,6 @@ class Sprite: if cr is None: cr = self._sprites.cr if cr is None: - print 'sprite.draw: no Cairo context.' return for i, img in enumerate(self.images): if isinstance(img, GdkPixbuf.Pixbuf): diff --git a/toolbar_utils.py b/toolbar_utils.py index 03f5461..72f7100 100644 --- a/toolbar_utils.py +++ b/toolbar_utils.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # Copyright (c) 2011, Walter Bender -# Copyright (c) 2012, Ignacio Rodriguez +# Port To GTK3: +# Ignacio Rodriguez <ignaciorodriguez@sugarlabs.org> # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or @@ -10,6 +11,7 @@ # along with this library; if not, write to the Free Software # Foundation, 51 Franklin Street, Suite 500 Boston, MA 02110-1335 USA + from gi.repository import Gtk from sugar3.graphics.radiotoolbutton import RadioToolButton @@ -1,4 +1,4 @@ -#Copyright (c) 2011 Walter Bender +#Copyright (c) 2011,12 Walter Bender # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -11,43 +11,28 @@ from StringIO import StringIO -try: - OLD_SUGAR_SYSTEM = False - import json - json.dumps - from json import load as jload - from json import dump as jdump -except (ImportError, AttributeError): - try: - import simplejson as json - from simplejson import load as jload - from simplejson import dump as jdump - except: - OLD_SUGAR_SYSTEM = True +import json +json.dumps +from json import load as jload +from json import dump as jdump def json_load(text): """ Load JSON data using what ever resources are available. """ - if OLD_SUGAR_SYSTEM is True: - listdata = json.read(text) - else: - # strip out leading and trailing whitespace, nulls, and newlines - io = StringIO(text) - try: - listdata = jload(io) - except ValueError: - # assume that text is ascii list - listdata = text.split() - for i, value in enumerate(listdata): - listdata[i] = int(value) + # strip out leading and trailing whitespace, nulls, and newlines + io = StringIO(text) + try: + listdata = jload(io) + except ValueError: + # assume that text is ascii list + listdata = text.split() + for i, value in enumerate(listdata): + listdata[i] = int(value) return listdata def json_dump(data): """ Save data using available JSON tools. """ - if OLD_SUGAR_SYSTEM is True: - return json.write(data) - else: - _io = StringIO() - jdump(data, _io) - return _io.getvalue() + _io = StringIO() + jdump(data, _io) + return _io.getvalue() @@ -80,7 +80,7 @@ class Yupana(): Sprite(self._sprites, x, y, self._new_dot(self._colors[0]))) self._dots[-1].type = 0 # not set - self._dots[-1].set_label_color('black') + self._dots[-1].set_label_color('white') x += self._dot_size + self._space x = int((p * self._width / 6.) + self._dot_size / 2.) + self._space y -= self._dot_size + self._space @@ -89,7 +89,7 @@ class Yupana(): Sprite(self._sprites, x, y, self._new_dot(self._colors[0]))) self._dots[-1].type = 0 # not set - self._dots[-1].set_label_color('black') + self._dots[-1].set_label_color('white') x += self._dot_size + self._space y -= self._dot_size @@ -102,7 +102,7 @@ class Yupana(): Sprite(self._sprites, x, y, self._new_dot(self._colors[0]))) self._dots[-1].type = 0 # not set - self._dots[-1].set_label_color('black') + self._dots[-1].set_label_color('white') x += self._dot_size + self._space x = int((p * self._width / 6.) + self._dot_size) + self._space y -= self._dot_size + self._space @@ -111,7 +111,7 @@ class Yupana(): Sprite(self._sprites, x, y, self._new_dot(self._colors[0]))) self._dots[-1].type = 0 # not set - self._dots[-1].set_label_color('black') + self._dots[-1].set_label_color('white') x += self._dot_size + self._space y -= self._dot_size @@ -124,7 +124,7 @@ class Yupana(): Sprite(self._sprites, x, y, self._new_dot(self._colors[0]))) self._dots[-1].type = 0 # not set - self._dots[-1].set_label_color('black') + self._dots[-1].set_label_color('white') x += self._dot_size + self._space y -= self._dot_size @@ -137,7 +137,7 @@ class Yupana(): Sprite(self._sprites, x, y, self._new_dot(self._colors[0]))) self._dots[-1].type = 0 # not set - self._dots[-1].set_label_color('black') + self._dots[-1].set_label_color('white') x += self._dot_size + self._space y -= self._dot_size @@ -174,7 +174,7 @@ class Yupana(): if mode is not None: self._mode = mode - o = (SIX - 1) * (TEN + 1) # only label units + o = (SIX - 1) * (TEN + 1) # only label units if mode == 'ten': for i in range(TEN + 1): self._dots[o + i].set_label('1') @@ -311,6 +311,7 @@ class Yupana(): else: return (self.custom[4] ** e) * self.custom[3] + def remote_button_press(self, dot, color): ''' Receive a button press from a sharer ''' self._dots[dot].type = color @@ -371,6 +372,7 @@ class Yupana(): else: pixbuf = svg_str_to_pixbuf( self._header() + \ + self._def(self._dot_size) + \ self._gradient(self._dot_size / 2., self._dot_size / 2., self._dot_size / 2.) + \ self._footer()) @@ -402,7 +404,7 @@ class Yupana(): self._rect(self._width, 3, 0, 0) + \ self._footer()) - def _box(self, w, h, color='black'): + def _box(self, w, h, color='white'): ''' Generate a box ''' self._svg_width = w self._svg_height = h @@ -436,56 +438,39 @@ class Yupana(): return svg_string def _circle(self, r, cx, cy): - scale = (DOT_SIZE * self._scale) / 55. - return '\ - <g transform="matrix(%f,0,0,%f,0,0)">\ - <path\ - d="m 35.798426,4.2187227 c -2.210658,0.9528967 -4.993612,-0.9110169 -7.221856,0 C 23.805784,6.1692574 20.658687,10.945585 17.543179,15.051507 13.020442,21.012013 7.910957,27.325787 6.7103942,34.711004 6.0558895,38.737163 6.434461,43.510925 8.917073,46.747431 c 3.604523,4.699107 15.24614,7.62307 16.048569,7.62307 0.802429,0 8.366957,0.46766 12.036427,-1.203642 2.841316,-1.294111 5.173945,-3.766846 6.820641,-6.419428 2.543728,-4.097563 3.563068,-9.062928 4.21275,-13.841891 C 49.107723,25.018147 48.401726,15.967648 47.433639,9.0332932 47.09109,6.5796321 43.508442,7.2266282 42.329009,5.7211058 41.256823,4.3524824 42.197481,1.860825 40.813604,0.80840168 40.384481,0.48205899 39.716131,0.42556727 39.208747,0.60779459 37.650593,1.1674066 37.318797,3.5633724 35.798426,4.2187227 z"\ - style="fill:none;fill-opacity:1;stroke:%s;stroke-width:3.0" />\ -</g>' % ( - scale, scale, self._colors[1]) + return '<circle style="fill:' + str(self._fill) + ';stroke:' + \ + str(self._stroke) + ';" r="' + str(r - 0.5) + '" cx="' + \ + str(cx) + '" cy="' + str(cy) + '" />\n' def _gradient(self, r, cx, cy): - ''' return '<circle style="fill:url(#radialGradient3761);' + \ 'fill-opacity:1;stroke:none;" r="' + str(r - 0.5) + '" cx="' + \ str(cx) + '" cy="' + str(cy) + '" />\n' - ''' - scale = (DOT_SIZE * self._scale) / 55. - return '\ - <defs>\ + + def _def(self, r): + return ' <defs>\ <linearGradient\ - id="linearGradient3769">\ + id="linearGradient3755">\ <stop\ - id="stop3771"\ - style="stop-color:#ffff00;stop-opacity:1"\ + id="stop3757"\ + style="stop-color:%s;stop-opacity:1"\ offset="0" />\ <stop\ - id="stop3773"\ - style="stop-color:#ffff00;stop-opacity:0"\ + id="stop3759"\ + style="stop-color:%s;stop-opacity:1"\ offset="1" />\ </linearGradient>\ - <linearGradient\ - x1="10.761448"\ - y1="41.003559"\ - x2="56.70686"\ - y2="41.003559"\ - id="linearGradient2999"\ - xlink:href="#linearGradient3769"\ - gradientUnits="userSpaceOnUse"\ - gradientTransform="matrix(0.93094239,0,0,0.93094239,-3.9217825,-2.4013121)" />\ + <radialGradient\ + cx="0"\ + cy="0"\ + r="%f"\ + fx="%f"\ + fy="%f"\ + id="radialGradient3761"\ + xlink:href="#linearGradient3755"\ + gradientUnits="userSpaceOnUse" />\ </defs>\ - <g transform="matrix(%f,0,0,%f,0,0)">\ - <path\ - d="m 35.798426,4.2187227 c -2.210658,0.9528967 -4.993612,-0.9110169 -7.221856,0 C 23.805784,6.1692574 20.658687,10.945585 17.543179,15.051507 13.020442,21.012013 7.910957,27.325787 6.7103942,34.711004 6.0558895,38.737163 6.434461,43.510925 8.917073,46.747431 c 3.604523,4.699107 15.24614,7.62307 16.048569,7.62307 0.802429,0 8.366957,0.46766 12.036427,-1.203642 2.841316,-1.294111 5.173945,-3.766846 6.820641,-6.419428 2.543728,-4.097563 3.563068,-9.062928 4.21275,-13.841891 C 49.107723,25.018147 48.401726,15.967648 47.433639,9.0332932 47.09109,6.5796321 43.508442,7.2266282 42.329009,5.7211058 41.256823,4.3524824 42.197481,1.860825 40.813604,0.80840168 40.384481,0.48205899 39.716131,0.42556727 39.208747,0.60779459 37.650593,1.1674066 37.318797,3.5633724 35.798426,4.2187227 z"\ - style="fill:#fffec2;fill-opacity:1;stroke:#878600;stroke-width:2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />\ - <path\ - d="m 15.11608,18.808876 c 1.271657,-1.444003 4.153991,-3.145785 5.495465,-1.7664 2.950062,3.033434 -6.07961,8.17155 -4.219732,11.972265 0.545606,1.114961 2.322391,1.452799 3.532799,1.177599 5.458966,-1.241154 6.490591,-12.132334 12.070397,-11.677864 1.584527,0.129058 2.526156,2.269906 2.845867,3.827199 0.453143,2.207236 -1.962667,6.182399 -1.570133,6.574932 0.392533,0.392533 2.371401,0.909584 3.140266,0.196266 1.91857,-1.779962 -0.490667,-7.752531 0.09813,-7.850664 0.5888,-0.09813 4.421663,2.851694 5.789865,5.004799 0.583188,0.917747 -0.188581,2.956817 0.8832,3.140266 2.128963,0.364398 1.601562,-5.672021 3.729066,-5.299199 1.836829,0.321884 1.450925,3.532631 1.471999,5.397332 0.06743,5.965698 -0.565586,12.731224 -4.317865,17.369596 -3.846028,4.75426 -10.320976,8.31978 -16.388263,7.556266 C 22.030921,53.720741 16.615679,52.58734 11.485147,49.131043 7.9833717,46.771994 6.8028191,42.063042 6.5784815,37.846738 6.3607378,33.754359 8.3381535,29.765466 10.111281,26.070741 c 1.271951,-2.650408 2.940517,-4.917813 5.004799,-7.261865 z"\ - style="fill:url(#linearGradient2999);fill-opacity:1;stroke:none" />\ - <path\ - d="m 32.382709,4.7758124 c -0.123616,1.0811396 1.753928,2.8458658 2.728329,2.9439992 0.974405,0.098134 6.718874,0.7298319 9.159392,-0.1962668 0.820281,-0.3112699 0.968884,-0.9547989 0.974407,-1.4719993 0.02053,-1.9240971 0.03247,-4.7715376 -3.507853,-5.49546551 C 39.556079,0.11012647 37.217081,1.4131653 35.500801,2.2243463 34.054814,2.9077752 32.496703,3.7788369 32.382709,4.7758124 z"\ - style="fill:#b69556;fill-opacity:1;stroke:#b69556;stroke-width:1.31189477px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /></g>' % ( - scale, scale) +' % (self._fill, self._fill_dark, r, r / 3, r / 3) def _footer(self): return '</svg>\n' |