Move the layouts to be box and subclass them.

This commit is contained in:
Marco Pesenti Gritti 2006-10-06 11:11:38 +02:00
parent f216f7bc0a
commit b33a1c141f
7 changed files with 190 additions and 178 deletions

View File

@ -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,

View File

@ -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)

View File

@ -8,7 +8,7 @@ sugar_PYTHON = \
menu.py \
menuicon.py \
menushell.py \
snowflakelayout.py \
spreadlayout.py \
snowflakebox.py \
spreadbox.py \
style.py \
timeline.py

View File

@ -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

View File

@ -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

101
sugar/graphics/spreadbox.py Normal file
View File

@ -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

View File

@ -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