diff --git a/sugar/canvas/Makefile.am b/sugar/canvas/Makefile.am index fbd241e7..85991775 100644 --- a/sugar/canvas/Makefile.am +++ b/sugar/canvas/Makefile.am @@ -10,4 +10,5 @@ sugar_PYTHON = \ Menu.py \ MenuIcon.py \ MenuShell.py \ + SnowflakeLayout.py \ Timeline.py diff --git a/sugar/canvas/SnowflakeLayout.py b/sugar/canvas/SnowflakeLayout.py new file mode 100644 index 00000000..aae7d078 --- /dev/null +++ b/sugar/canvas/SnowflakeLayout.py @@ -0,0 +1,62 @@ +import math + +import cairo + +class SnowflakeLayout: + _BASE_RADIUS = 65 + _CHILDREN_FACTOR = 1 + _FLAKE_DISTANCE = 6 + _BORDER = 20 + + def __init__(self): + self._root = None + self._children = [] + + def set_root(self, icon): + self._root = icon + + def add_child(self, icon): + self._children.append(icon) + self._layout() + + def remove_child(self, icon): + self._children.remove(icon) + self._layout() + + def _layout_root(self): + [width, height] = self._root.get_size_request() + + matrix = cairo.Matrix(1, 0, 0, 1, 0, 0) + matrix.translate(self._cx, self._cy) + self._root.set_transform(matrix) + + def _layout_child(self, child, index): + r = self._r + if (len(self._children) > 10): + r += SnowflakeLayout._FLAKE_DISTANCE * (index % 3) + + angle = 2 * math.pi / len(self._children) * index + + x = self._cx + math.cos(angle) * r + y = self._cy + math.sin(angle) * r + + matrix = cairo.Matrix(1, 0, 0, 1, 0, 0) + matrix.translate(x, y) + child.set_transform(matrix) + + def _layout(self): + self._r = SnowflakeLayout._BASE_RADIUS + \ + SnowflakeLayout._CHILDREN_FACTOR * len(self._children) + + c = self._r + SnowflakeLayout._BORDER + \ + SnowflakeLayout._FLAKE_DISTANCE * 2 + + self._cx = c + self._cy = c + + self._layout_root() + + index = 0 + for child in self._children: + self._layout_child(child, index) + index += 1 diff --git a/tests/test-snowflake.py b/tests/test-snowflake.py new file mode 100755 index 00000000..bba90f5e --- /dev/null +++ b/tests/test-snowflake.py @@ -0,0 +1,66 @@ +#!/usr/bin/python +import pygtk +pygtk.require('2.0') +import gobject + +from sugar.session.UITestSession import UITestSession + +session = UITestSession() +session.start() + +import sys +import random + +import gtk +import goocanvas + +from sugar.canvas.SnowflakeLayout import SnowflakeLayout +from sugar.canvas import IconColor +from sugar.canvas.IconItem import IconItem +from sugar.canvas.CanvasView import CanvasView +from sugar.canvas.Grid import Grid + +def _create_snowflake(group, children): + color = IconColor.IconColor() + icon = IconItem(size=60, color=color, + icon_name='activity-groupchat') + group.add_child(icon) + layout.set_root(icon) + + for i in range(0, children): + color = IconColor.IconColor() + icon = IconItem(size=60, color=color, + icon_name='stock-buddy') + group.add_child(icon) + layout.add_child(icon) + +window = gtk.Window() +window.connect("destroy", lambda w: gtk.main_quit()) +window.show() + +canvas = CanvasView() +canvas.show() +window.add(canvas) + +canvas_model = goocanvas.CanvasModelSimple() +root = canvas_model.get_root_item() + +item = goocanvas.Rect(x=0, y=0, width=1200, height=900, + line_width=0.0, fill_color='#e2e2e2') +root.add_child(item) + +layout = SnowflakeLayout() +group = goocanvas.Group() +snow_flake = _create_snowflake(group, 30) +root.add_child(group) + +layout = SnowflakeLayout() +group = goocanvas.Group() +group.translate(500, 500) +_create_snowflake(group, 8) +root.add_child(group) + + +canvas.set_model(canvas_model) + +gtk.main()