From 20ea0d7bccd9aecdd394d1570cbb87e63f3b3f18 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Thu, 05 Jul 2007 11:33:29 +0000 Subject: Add a spread layout manager. Work in progress. --- diff --git a/shell/view/home/snowflakelayout.py b/shell/view/home/snowflakelayout.py index 4aef6b6..8f04846 100644 --- a/shell/view/home/snowflakelayout.py +++ b/shell/view/home/snowflakelayout.py @@ -28,7 +28,7 @@ _CHILDREN_FACTOR = 1 class SnowflakeLayout(gobject.GObject,hippo.CanvasLayout): __gtype_name__ = 'SugarSnowflakeLayout' def __init__(self): - hippo.CanvasBox.__init__(self) + gobject.GObject.__init__(self) self._nflakes = 0 def add(self, child): diff --git a/sugar/graphics/spreadlayout.py b/sugar/graphics/spreadlayout.py new file mode 100644 index 0000000..3daf20a --- /dev/null +++ b/sugar/graphics/spreadlayout.py @@ -0,0 +1,131 @@ +# Copyright (C) 2007 Red Hat, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +from array import array +from random import random + +import hippo +import gobject +import gtk + +_PLACE_TRIALS = 20 +_MAX_WEIGHT = 255 +_CELL_SIZE = 4 + +class _Grid(object): + def __init__(self, width, height): + self.width = width + self.height = height + + self._array = array('B') + for i in range(width * height): + self._array.append(0) + + def add(self, child, width, height): + trials = _PLACE_TRIALS + weight = _MAX_WEIGHT + while trials > 0 and weight: + x = int(random() * (self.width - width)) + y = int(random() * (self.height - height)) + + rect = gtk.gdk.Rectangle(x, y, width, height) + new_weight = self._compute_weight(rect) + if weight > new_weight: + weight = new_weight + + trials -= 1 + + child.grid_rect = rect + self._add_weight(rect) + + def remove(self, child): + self._remove_weight(box_child.grid_rect) + child.grid_rect = None + + def _add_weight(self, rect): + for i in range(rect.x, rect.x + rect.width): + for j in range(rect.y, rect.y + rect.height): + self[j, i] += 1 + + def _remove_weight(self, rect): + for i in range(rect.x, rect.x + rect.width): + for j in range(rect.y, rect.y + rect.height): + self[j, i] -= 1 + + def _compute_weight(self, rect): + weight = 0 + + for i in range(rect.x, rect.x + rect.width): + for j in range(rect.y, rect.y + rect.height): + weight += self[j, i] + + return weight + + def __getitem__(self, (row, col)): + return self._array[col + row * self.width] + + def __setitem__(self, (row, col), value): + self._array[col + row * self.width] = value + + +class SpreadLayout(gobject.GObject,hippo.CanvasLayout): + __gtype_name__ = 'SugarSpreadLayout' + def __init__(self): + gobject.GObject.__init__(self) + + min_width, width = self.do_get_width_request() + min_height, height = self.do_get_height_request(width) + + self._grid = _Grid(width / _CELL_SIZE, height / _CELL_SIZE) + + def add(self, child): + self._box.append(child) + + width, height = self._get_child_grid_size(child) + box_child = self._box.find_box_child(child) + self._grid.add(box_child, width, height) + + def remove(self, child): + box_child = self._box.find_box_child(child) + self._grid.remove(box_child) + + self._box.remove(child) + + def do_set_box(self, box): + self._box = box + + def do_get_height_request(self, for_width): + return 0, gtk.gdk.screen_height() + + def do_get_width_request(self): + return 0, gtk.gdk.screen_width() + + def do_allocate(self, x, y, width, height, + req_width, req_height, origin_changed): + for child in self._box.get_layout_children(): + rect = child.grid_rect + child.allocate(rect.x * _CELL_SIZE, + rect.y * _CELL_SIZE, + rect.width * _CELL_SIZE, + rect.height * _CELL_SIZE, + origin_changed) + + def _get_child_grid_size(self, child): + min_width, width = child.get_width_request() + min_height, height = child.get_height_request(width) + + return int(width / _CELL_SIZE), int(height / _CELL_SIZE) diff --git a/tests/test-spread-box.py b/tests/test-spread-box.py index 02aa59c..84a3ae1 100755 --- a/tests/test-spread-box.py +++ b/tests/test-spread-box.py @@ -26,7 +26,7 @@ import gobject import gtk import hippo -from sugar.graphics.spreadbox import SpreadBox +from sugar.graphics.spreadlayout import SpreadLayout from sugar.graphics.xocolor import XoColor from sugar.graphics.canvasicon import CanvasIcon @@ -35,7 +35,7 @@ def _create_icon(): icon = CanvasIcon(scale=1.0, xo_color=color, icon_name='theme:stock-buddy') - box.add_item(icon) + layout.add(icon) return (len(box.get_children()) < 20) @@ -45,7 +45,11 @@ window.show() canvas = hippo.Canvas() -box = SpreadBox(background_color=0xe2e2e2ff) +box = hippo.CanvasBox(background_color=0xe2e2e2ff) + +layout = SpreadLayout() +box.set_layout(layout) + canvas.set_root(box) window.add(canvas) -- cgit v0.9.1