Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sugar/graphics/spreadbox.py131
-rwxr-xr-x[-rw-r--r--]tests/test-notebook.py0
-rwxr-xr-xtests/test-snowflake-box.py4
3 files changed, 98 insertions, 37 deletions
diff --git a/sugar/graphics/spreadbox.py b/sugar/graphics/spreadbox.py
index ff50f71..f4cf5ea 100644
--- a/sugar/graphics/spreadbox.py
+++ b/sugar/graphics/spreadbox.py
@@ -15,67 +15,124 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
-import random
+from array import array
+from random import random
import hippo
-import gtk
-from sugar.graphics import units
+_X_TILES = 120
+_NUM_TRIALS = 100
-_WIDTH = gtk.gdk.screen_width()
-_HEIGHT = gtk.gdk.screen_height()
-_CELL_WIDTH = units.grid_to_pixels(1)
-_CELL_HEIGHT = units.grid_to_pixels(1)
-_GRID_WIDTH = _WIDTH / _CELL_WIDTH
-_GRID_HEIGHT = _HEIGHT / _CELL_HEIGHT
+class _Grid(object):
+ def __init__(self, x_tiles, y_tiles, cell_size):
+ self._array = array('B')
+ self.x_tiles = x_tiles
+ self.y_tiles = y_tiles
+ self.cell_size = cell_size
+
+ for i in range(self.y_tiles * self.x_tiles):
+ self._array.append(0)
+
+ def __getitem__(self, (row, col)):
+ return self._array[col + row * self.x_tiles]
+
+ def __setitem__(self, (row, col), value):
+ self._array[col + row * self.x_tiles] = value
+
+ def compute_weight_at(self, x, y, width, height):
+ weight = 0
+
+ for i in range(x, x + width):
+ for j in range(y, y + height):
+ weight += self[j, i]
+
+ return weight
+
+ def add_weight_at(self, x, y, width, height):
+ for i in range(x, x + width):
+ for j in range(y, y + height):
+ self[j, i] += 1
+
+ def remove_weight_at(self, x, y, width, height):
+ for i in range(x, x + width):
+ for j in range(y, y + height):
+ self[j, i] -= 1
class SpreadBox(hippo.CanvasBox, hippo.CanvasItem):
__gtype_name__ = 'SugarSpreadBox'
def __init__(self, **kwargs):
hippo.CanvasBox.__init__(self, **kwargs)
- self._grid = []
+ self._grid = None
self._center = None
-
- for i in range(0, _GRID_WIDTH * _GRID_HEIGHT):
- self._grid.append(None)
+ self._width = -1
+ self._height = -1
def set_center_item(self, item):
if self._center:
self.remove(self._center)
- self._center = item
self.append(item, hippo.PACK_FIXED)
+ self._center = item
- def add_item(self, item):
- start_pos = int(random.random() * len(self._grid))
-
- pos = start_pos
- while self._grid[pos] != None:
- pos = pos + 1
- if pos == len(self._grid):
- pos = 0
- elif pos == start_pos:
- break
-
- self._grid[pos] = item
+ self._layout_center()
+ def add_item(self, item):
self.append(item, hippo.PACK_FIXED)
-
- cell_y = int(pos / _GRID_WIDTH)
- cell_x = pos - cell_y * _GRID_WIDTH
- self.set_position(item, cell_x * _CELL_WIDTH, cell_y * _CELL_HEIGHT)
+ self._layout_item(item)
def remove_item(self, item):
- for i in range(0, len(self._grid)):
- if self._grid[i] == item:
- self._grid[i] = None
self.remove(item)
+
+ def _layout_item(self, item):
+ if not self._grid:
+ return
+
+ trials = _NUM_TRIALS
+ placed = False
+
+ while trials > 0 and not placed:
+ [width, height] = item.get_allocation()
+ cell_size = self._grid.cell_size
+
+ w = int(width / cell_size)
+ h = int(height / cell_size)
+ x = int(random() * (self._grid.x_tiles - w))
+ y = int(random() * (self._grid.y_tiles - h))
+
+ weight = self._grid.compute_weight_at(x, y, w, h)
+ if weight == 0:
+ self._grid.add_weight_at(x, y, w, h)
+ self.set_position(item, cell_size * x, cell_size * y)
+ placed = True
+
+ trials -= 1
+
+ def _layout(self):
+ for item in self.get_children():
+ if item != self._center:
+ self._layout_item(item)
+
+ def _layout_center(self):
+ if not self._center or not self._grid:
+ return
+ [width, height] = self._center.get_allocation()
+ x = (self._width - width) / 2
+ y = (self._height - height) / 2
+ self.set_position(self._center, x, y)
+
def do_allocate(self, width, height, origin_changed):
hippo.CanvasBox.do_allocate(self, width, height, origin_changed)
- if self._center:
- [icon_width, icon_height] = self._center.get_allocation()
- self.set_position(self._center, (width - icon_width) / 2,
- (height - icon_height) / 2)
+ if width != self._width or height != self._height:
+ cell_size = width / _X_TILES
+ y_tiles = height / cell_size
+
+ self._grid = _Grid(_X_TILES, y_tiles, cell_size)
+ self._width = width
+ self._height = height
+
+ self._layout()
+
+ self._layout_center()
diff --git a/tests/test-notebook.py b/tests/test-notebook.py
index 685bedd..685bedd 100644..100755
--- a/tests/test-notebook.py
+++ b/tests/test-notebook.py
diff --git a/tests/test-snowflake-box.py b/tests/test-snowflake-box.py
index 4164af4..eb7efb9 100755
--- a/tests/test-snowflake-box.py
+++ b/tests/test-snowflake-box.py
@@ -55,6 +55,10 @@ root_box = SpreadBox(background_color=0xe2e2e2ff)
canvas.set_root(root_box)
box = SnowflakeBox()
+snow_flake = _create_snowflake(box, 0)
+root_box.set_center_item(box)
+
+box = SnowflakeBox()
snow_flake = _create_snowflake(box, 30)
root_box.add_item(box)