diff options
author | Marco Pesenti Gritti <marco@localhost.localdomain> | 2006-10-06 09:11:38 (GMT) |
---|---|---|
committer | Marco Pesenti Gritti <marco@localhost.localdomain> | 2006-10-06 09:11:38 (GMT) |
commit | b33a1c141f8e47b7d57a033baa9f0a44ea8d8834 (patch) | |
tree | 2bdb87dc43fdecf9c90dad58f359b733fb339b03 /sugar/graphics | |
parent | f216f7bc0a20b446bc9723e7a1e50486931ebbac (diff) |
Move the layouts to be box and subclass them.
Diffstat (limited to 'sugar/graphics')
-rw-r--r-- | sugar/graphics/Makefile.am | 4 | ||||
-rw-r--r-- | sugar/graphics/snowflakebox.py | 67 | ||||
-rw-r--r-- | sugar/graphics/snowflakelayout.py | 61 | ||||
-rw-r--r-- | sugar/graphics/spreadbox.py | 101 | ||||
-rw-r--r-- | sugar/graphics/spreadlayout.py | 86 |
5 files changed, 170 insertions, 149 deletions
diff --git a/sugar/graphics/Makefile.am b/sugar/graphics/Makefile.am index fd32797..aa1f51f 100644 --- a/sugar/graphics/Makefile.am +++ b/sugar/graphics/Makefile.am @@ -8,7 +8,7 @@ sugar_PYTHON = \ menu.py \ menuicon.py \ menushell.py \ - snowflakelayout.py \ - spreadlayout.py \ + snowflakebox.py \ + spreadbox.py \ style.py \ timeline.py diff --git a/sugar/graphics/snowflakebox.py b/sugar/graphics/snowflakebox.py new file mode 100644 index 0000000..4ee22c5 --- /dev/null +++ b/sugar/graphics/snowflakebox.py @@ -0,0 +1,67 @@ +import math + +import cairo +import hippo + +_BASE_RADIUS = 65 +_CHILDREN_FACTOR = 1 +_FLAKE_DISTANCE = 6 + +class SnowflakeBox(hippo.CanvasBox, hippo.CanvasItem): + __gtype_name__ = 'SugarSnowflakeBox' + def __init__(self, **kwargs): + CanvasBox.__init__(self, **kwargs) + + self._root = None + self._r = 0 + + def set_root(self, icon): + self._root = icon + + def _layout_root(self): + [width, height] = self._root.get_allocation() + + x = self._cx - (width / 2) + y = self._cy - (height / 2) + + self.move(self._root, int(x), int(y)) + + def _layout_child(self, child, index): + r = self._r + if (len(box.get_children()) > 10): + r += _FLAKE_DISTANCE * (index % 3) + + angle = 2 * math.pi / len(box.get_children()) * index + + [width, height] = child.get_allocation() + x = self._cx + math.cos(angle) * r - (width / 2) + y = self._cy + math.sin(angle) * r - (height / 2) + + self.move(child, int(x), int(y)) + + def do_get_width_request(self): + max_child_size = 0 + for child in box.get_children(): + [width, height] = child.get_allocation() + max_child_size = max (max_child_size, width) + max_child_size = max (max_child_size, height) + + return self._r * 2 + max_child_size + _FLAKE_DISTANCE * 2 + + def do_get_height_request(self, width): + return width + + def do_allocate(self, width, height): + self._r = _BASE_RADIUS + _CHILDREN_FACTOR * len(box.get_children()) + + hippo.CanvasBox.do_allocate(self, width, height) + + self._cx = self.get_width_request() / 2 + self._cy = self.get_height_request() / 2 + + self._layout_root(box) + + index = 0 + for child in box.get_children(): + self._layout_child(child, index) + index += 1 diff --git a/sugar/graphics/snowflakelayout.py b/sugar/graphics/snowflakelayout.py deleted file mode 100644 index afce0c8..0000000 --- a/sugar/graphics/snowflakelayout.py +++ /dev/null @@ -1,61 +0,0 @@ -import math - -import cairo - -class SnowflakeLayout: - _BASE_RADIUS = 65 - _CHILDREN_FACTOR = 1 - _FLAKE_DISTANCE = 6 - - def __init__(self): - self._root = None - self._r = 0 - - def set_root(self, icon): - self._root = icon - - def _layout_root(self, box): - [width, height] = self._root.get_allocation() - - x = self._cx - (width / 2) - y = self._cy - (height / 2) - - box.move(self._root, int(x), int(y)) - - def _layout_child(self, box, child, index): - r = self._r - if (len(box.get_children()) > 10): - r += SnowflakeLayout._FLAKE_DISTANCE * (index % 3) - - angle = 2 * math.pi / len(box.get_children()) * index - - [width, height] = child.get_allocation() - x = self._cx + math.cos(angle) * r - (width / 2) - y = self._cy + math.sin(angle) * r - (height / 2) - - box.move(child, int(x), int(y)) - - def get_size(self, box): - max_child_size = 0 - for child in box.get_children(): - [width, height] = child.get_allocation() - max_child_size = max (max_child_size, width) - max_child_size = max (max_child_size, height) - - return self._r * 2 + max_child_size + \ - SnowflakeLayout._FLAKE_DISTANCE * 2 - - def layout(self, box): - self._r = SnowflakeLayout._BASE_RADIUS + \ - SnowflakeLayout._CHILDREN_FACTOR * len(box.get_children()) - - size = self.get_size(box) - self._cx = size / 2 - self._cy = size / 2 - - self._layout_root(box) - - index = 0 - for child in box.get_children(): - self._layout_child(box, child, index) - index += 1 diff --git a/sugar/graphics/spreadbox.py b/sugar/graphics/spreadbox.py new file mode 100644 index 0000000..456aeca --- /dev/null +++ b/sugar/graphics/spreadbox.py @@ -0,0 +1,101 @@ +import random +import math + +import cairo +import hippo + +_DISTANCE_THRESHOLD = 120.0 + +class SpreadBox(hippo.CanvasBox, hippo.CanvasItem): + __gtype_name__ = 'SugarSpreadBox' + + def __init__(self, **kwargs): + hippo.CanvasBox.__init__(self, **kwargs) + + self._items_to_position = [] + self._spread_on_add = False + + def add(self, item): + self._items_to_position.append(item) + self.append(item, hippo.PACK_FIXED) + if self._spread_on_add: + self.spread() + + def spread(self): + self._spread_on_add = True + + [width, height] = self.get_allocation() + for item in self._items_to_position: + x = int(random.random() * width) + y = int(random.random() * height) + + [x, y] = self._clamp_position(item, x, y) + self.move(item, x, y) + + self._items_to_position = [] + + def _get_distance(self, icon1, icon2): + [icon1_x, icon1_y] = self.get_position(icon1) + [icon2_x, icon2_y] = self.get_position(icon2) + + a = icon1_x - icon2_x + b = icon1_y - icon2_y + + return math.sqrt(a * a + b * b) + + def _get_repulsion(self, icon1, icon2): + [icon1_x, icon1_y] = self.get_position(icon1) + [icon2_x, icon2_y] = self.get_position(icon2) + + f_x = icon1_x - icon2_x + f_y = icon1_y - icon2_y + + return [f_x, f_y] + + def _clamp_position(self, icon, x, y): + x = max(0, x) + y = max(0, y) + + [item_w, item_h] = icon.get_allocation() + [box_w, box_h] = self.get_allocation() + + x = min(box_w - item_w, x) + y = min(box_h - item_h, y) + + return [x, y] + + def _spread_icons(self): + stable = True + + for icon1 in self.get_children(): + vx = 0 + vy = 0 + + [x, y] = self.get_position(icon1) + + for icon2 in self.get_children(): + if icon1 != icon2: + distance = self._get_distance(icon1, icon2) + if distance <= _DISTANCE_THRESHOLD: + stable = False + [f_x, f_y] = self._get_repulsion(icon1, icon2) + vx += f_x + vy += f_y + + new_x = x + vx + new_y = y + vy + + [new_x, new_y] = self._clamp_position(icon1, new_x, new_y) + + self.move(icon1, new_x, new_y) + + return stable + + def do_allocate(self, width, height): + hippo.CanvasBox.do_allocate(self, width, height) + + tries = 10 + stable = self._spread_icons() + while not stable and tries > 0: + stable = self._spread_icons() + tries -= 1 diff --git a/sugar/graphics/spreadlayout.py b/sugar/graphics/spreadlayout.py deleted file mode 100644 index 0ce70ff..0000000 --- a/sugar/graphics/spreadlayout.py +++ /dev/null @@ -1,86 +0,0 @@ -import random -import math - -import cairo - -_DISTANCE_THRESHOLD = 120.0 - -class SpreadLayout: - def __init__(self): - pass - - def _get_distance(self, box, icon1, icon2): - [icon1_x, icon1_y] = box.get_position(icon1) - [icon2_x, icon2_y] = box.get_position(icon2) - - a = icon1_x - icon2_x - b = icon1_y - icon2_y - - return math.sqrt(a * a + b * b) - - def _get_repulsion(self, box, icon1, icon2): - [icon1_x, icon1_y] = box.get_position(icon1) - [icon2_x, icon2_y] = box.get_position(icon2) - - f_x = icon1_x - icon2_x - f_y = icon1_y - icon2_y - - return [f_x, f_y] - - def _clamp_position(self, box, icon, x, y): - x = max(0, x) - y = max(0, y) - - [item_w, item_h] = icon.get_allocation() - [box_w, box_h] = box.get_allocation() - - x = min(box_w - item_w, x) - y = min(box_h - item_h, y) - - return [x, y] - - def _spread_icons(self, box): - stable = True - - for icon1 in box.get_children(): - vx = 0 - vy = 0 - - [x, y] = box.get_position(icon1) - - for icon2 in box.get_children(): - if icon1 != icon2: - distance = self._get_distance(box, icon1, icon2) - if distance <= _DISTANCE_THRESHOLD: - stable = False - [f_x, f_y] = self._get_repulsion(box, icon1, icon2) - vx += f_x - vy += f_y - - new_x = x + vx - new_y = y + vy - - [new_x, new_y] = self._clamp_position(box, icon1, new_x, new_y) - - box.move(icon1, new_x, new_y) - - return stable - - def layout(self, box): - [width, height] = box.get_allocation() - - for item in box.get_children(): - [item_w, item_h] = item.get_allocation() - - x = int(random.random() * width) - y = int(random.random() * height) - - [x, y] = self._clamp_position(box, item, x, y) - - box.move(item, x, y) - - tries = 10 - stable = self._spread_icons(box) - while not stable and tries > 0: - stable = self._spread_icons(box) - tries -= 1 |