Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/sugar/graphics
diff options
context:
space:
mode:
authorEduardo Silva <edsiper@monotop.(none)>2007-05-08 13:33:58 (GMT)
committer Eduardo Silva <edsiper@monotop.(none)>2007-05-08 13:33:58 (GMT)
commit6a685d38b4712a7efc031787780df4df171f1a46 (patch)
treef726720ac028cda71be2a8486d6e68f30e926759 /sugar/graphics
parent9180388a76e9de7742a9337a03458b98eb15747c (diff)
parent60d6dcd6188695add3c7b620c2a3eb61092fcf0a (diff)
Merge branch 'master' of git://dev.laptop.org/sugar
Diffstat (limited to 'sugar/graphics')
-rw-r--r--sugar/graphics/spreadbox.py146
1 files changed, 108 insertions, 38 deletions
diff --git a/sugar/graphics/spreadbox.py b/sugar/graphics/spreadbox.py
index ff50f71..8614cf6 100644
--- a/sugar/graphics/spreadbox.py
+++ b/sugar/graphics/spreadbox.py
@@ -15,67 +15,137 @@
# 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
-
-_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
+_X_TILES = 120
+_NUM_TRIALS = 20
+_MAX_WEIGHT = 255
+
+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 _place_item(self, item, x, y, w, h):
+ self._grid.add_weight_at(x, y, w, h)
+ self.set_position(item,
+ self._grid.cell_size * x,
+ self._grid.cell_size * y)
+
+ def _layout_item(self, item):
+ if not self._grid:
+ return
+
+ trials = _NUM_TRIALS
+ placed = False
+ best_weight = _MAX_WEIGHT
+
+ [width, height] = item.get_allocation()
+ w = int(width / self._grid.cell_size)
+ h = int(height / self._grid.cell_size)
+
+ while trials > 0 and not placed:
+ 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._place_item(item, x, y, w, h)
+ placed = True
+ elif weight < best_weight:
+ best_x = x
+ best_y = y
+
+ trials -= 1
+
+ if not placed:
+ self._place_item(item, best_x, best_y, w, h)
+
+ 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()