From b33a1c141f8e47b7d57a033baa9f0a44ea8d8834 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Fri, 06 Oct 2006 09:11:38 +0000 Subject: Move the layouts to be box and subclass them. --- diff --git a/shell/view/home/FriendsBox.py b/shell/view/home/FriendsBox.py index cb8b3f6..ed722f4 100644 --- a/shell/view/home/FriendsBox.py +++ b/shell/view/home/FriendsBox.py @@ -1,20 +1,20 @@ import random import hippo +import gobject -from sugar.graphics.spreadlayout import SpreadLayout +from sugar.graphics.spreadbox import SpreadBox from sugar.graphics import style from view.home.MyIcon import MyIcon from view.home.FriendView import FriendView -class FriendsBox(hippo.CanvasBox, hippo.CanvasItem): +class FriendsBox(SpreadBox, hippo.CanvasItem): __gtype_name__ = 'SugarFriendsBox' def __init__(self, shell, menu_shell): - hippo.CanvasBox.__init__(self, background_color=0xe2e2e2ff) + SpreadBox.__init__(self, background_color=0xe2e2e2ff) self._shell = shell self._menu_shell = menu_shell - self._layout = SpreadLayout() self._friends = {} self._my_icon = MyIcon() @@ -29,9 +29,11 @@ class FriendsBox(hippo.CanvasBox, hippo.CanvasItem): friends.connect('friend-added', self._friend_added_cb) friends.connect('friend-removed', self._friend_removed_cb) + gobject.idle_add(self.spread) + def add_friend(self, buddy_info): icon = FriendView(self._shell, self._menu_shell, buddy_info) - self.append(icon, hippo.PACK_FIXED) + self.add(icon) self._friends[buddy_info.get_name()] = icon @@ -43,9 +45,7 @@ class FriendsBox(hippo.CanvasBox, hippo.CanvasItem): del self._friends[name] def do_allocate(self, width, height): - hippo.CanvasBox.do_allocate(self, width, height) - - self._layout.layout(self) + SpreadBox.do_allocate(self, width, height) [icon_width, icon_height] = self._my_icon.get_allocation() self.move(self._my_icon, (width - icon_width) / 2, diff --git a/shell/view/home/MeshBox.py b/shell/view/home/MeshBox.py index 9b3ce3c..be47f7e 100644 --- a/shell/view/home/MeshBox.py +++ b/shell/view/home/MeshBox.py @@ -1,28 +1,27 @@ import random import hippo +import gobject -from sugar.graphics.spreadlayout import SpreadLayout +from sugar.graphics.spreadbox import SpreadBox +from sugar.graphics.snowflakebox import SnowflakeBox from sugar.graphics.canvasicon import CanvasIcon from view.BuddyIcon import BuddyIcon -from sugar.graphics.snowflakelayout import SnowflakeLayout import conf -class ActivityView(hippo.CanvasBox, hippo.CanvasItem): - __gtype_name__ = 'SugarActivityView' +class ActivityView(SnowflakeBox): def __init__(self, shell, menu_shell, model): - hippo.CanvasBox.__init__(self) + SnowflakeBox.__init__(self) self._shell = shell self._model = model - self._layout = SnowflakeLayout() self._icons = {} icon = CanvasIcon(icon_name=model.get_icon_name(), color=model.get_color(), size=80) icon.connect('activated', self._clicked_cb) self.append(icon, hippo.PACK_FIXED) - self._layout.set_root(icon) + self.set_root(icon) def has_buddy_icon(self, name): return self._icons.has_key(name) @@ -42,19 +41,13 @@ class ActivityView(hippo.CanvasBox, hippo.CanvasItem): bundle = registry.get_activity_from_type(default_type) self._shell.join_activity(bundle.get_id(), self._model.get_id()) - def do_allocate(self, width, height): - hippo.CanvasBox.do_allocate(self, width, height) - self._layout.layout(self) - -class MeshBox(hippo.CanvasBox, hippo.CanvasItem): - __gtype_name__ = 'SugarMeshBox' +class MeshBox(SpreadBox): def __init__(self, shell, menu_shell): - hippo.CanvasBox.__init__(self, background_color=0xe2e2e2ff) + SpreadBox.__init__(self, background_color=0xe2e2e2ff) self._shell = shell self._menu_shell = menu_shell self._model = shell.get_model().get_mesh() - self._layout = SpreadLayout() self._buddies = {} self._activities = {} self._buddy_to_activity = {} @@ -72,6 +65,8 @@ class MeshBox(hippo.CanvasBox, hippo.CanvasItem): self._model.connect('activity-added', self._activity_added_cb) self._model.connect('activity-removed', self._activity_removed_cb) + gobject.idle_add(self.spread) + def _buddy_added_cb(self, model, buddy_model): self._add_alone_buddy(buddy_model) @@ -90,7 +85,7 @@ class MeshBox(hippo.CanvasBox, hippo.CanvasItem): def _add_alone_buddy(self, buddy_model): icon = BuddyIcon(self._shell, self._menu_shell, buddy_model) icon.props.size = 80 - self.append(icon, hippo.PACK_FIXED) + self.add(icon) self._buddies[buddy_model.get_name()] = icon @@ -124,7 +119,7 @@ class MeshBox(hippo.CanvasBox, hippo.CanvasItem): def _add_activity(self, activity_model): icon = ActivityView(self._shell, self._menu_shell, activity_model) - self.append(icon, hippo.PACK_FIXED) + self.add(icon) self._activities[activity_model.get_id()] = icon @@ -132,7 +127,3 @@ class MeshBox(hippo.CanvasBox, hippo.CanvasItem): icon = self._activities[activity_model.get_id()] self.remove(icon) del self._activities[activity_model.get_id()] - - def do_allocate(self, width, height): - hippo.CanvasBox.do_allocate(self, width, height) - self._layout.layout(self) 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 -- cgit v0.9.1