Merge branch 'master' of git://dev.laptop.org/sugar

This commit is contained in:
Ian Bicking 2006-10-03 11:59:40 -05:00
commit 48951dc1cb
12 changed files with 118 additions and 349 deletions

View File

@ -1,45 +1,33 @@
import goocanvas
import BuddyIcon
from sugar.canvas.IconItem import IconItem
from sugar.presence import PresenceService
import conf
import hippo
import gobject
import BuddyIcon
from sugar.graphics.canvasicon import CanvasIcon
from sugar.presence import PresenceService
import conf
class BuddyActivityView(goocanvas.Group):
class BuddyActivityView(hippo.CanvasBox):
def __init__(self, shell, menu_shell, buddy, **kwargs):
goocanvas.Group.__init__(self, **kwargs)
hippo.CanvasBox.__init__(self, **kwargs)
self._pservice = PresenceService.get_instance()
self._activity_registry = conf.get_activity_registry()
self._buddy = buddy
self._buddy_icon = BuddyIcon.BuddyIcon(shell, menu_shell, buddy)
self.add_child(self._buddy_icon)
self.append(self._buddy_icon)
buddy_size = self._buddy_icon.props.size
offset_y = buddy_size
offset_x = (buddy_size - 48) / 2
self._activity_icon = IconItem(x=offset_x, y=offset_y, size=48)
self._activity_icon = CanvasIcon(size=48)
self._activity_icon_visible = False
if self._buddy.is_present():
self.__buddy_appeared_cb(buddy)
self._buddy_appeared_cb(buddy)
self._buddy.connect('current-activity-changed', self.__buddy_activity_changed_cb)
self._buddy.connect('appeared', self.__buddy_appeared_cb)
self._buddy.connect('disappeared', self.__buddy_disappeared_cb)
self._buddy.connect('color-changed', self.__buddy_color_changed_cb)
def get_size_request(self):
bi_size = self._buddy_icon.props.size
acti_size = self._activity_icon.props.size
width = bi_size
height = bi_size + acti_size
return [width, height]
self._buddy.connect('current-activity-changed', self._buddy_activity_changed_cb)
self._buddy.connect('appeared', self._buddy_appeared_cb)
self._buddy.connect('disappeared', self._buddy_disappeared_cb)
self._buddy.connect('color-changed', self._buddy_color_changed_cb)
def _get_new_icon_name(self, activity):
# FIXME: do something better here; we probably need to use "flagship"
@ -51,14 +39,14 @@ class BuddyActivityView(goocanvas.Group):
return act.get_icon()
return None
def __remove_activity_icon(self):
def _remove_activity_icon(self):
if self._activity_icon_visible:
self.remove_child(self._activity_icon)
self.remove(self._activity_icon)
self._activity_icon_visible = False
def __buddy_activity_changed_cb(self, buddy, activity=None):
def _buddy_activity_changed_cb(self, buddy, activity=None):
if not activity:
self.__remove_activity_icon()
self._remove_activity_icon()
return
# FIXME: use some sort of "unknown activity" icon rather
@ -68,17 +56,17 @@ class BuddyActivityView(goocanvas.Group):
self._activity_icon.props.icon_name = name
self._activity_icon.props.color = buddy.get_color()
if not self._activity_icon_visible:
self.add_child(self._activity_icon)
self.append(self._activity_icon)
self._activity_icon_visible = True
else:
self.__remove_activity_icon()
self._remove_activity_icon()
def __buddy_appeared_cb(self, buddy):
def _buddy_appeared_cb(self, buddy):
activity = self._buddy.get_current_activity()
self.__buddy_activity_changed_cb(buddy, activity)
self._buddy_activity_changed_cb(buddy, activity)
def __buddy_disappeared_cb(self, buddy):
self.__buddy_activity_changed_cb(buddy, None)
def _buddy_disappeared_cb(self, buddy):
self._buddy_activity_changed_cb(buddy, None)
def __buddy_color_changed_cb(self, buddy, color):
def _buddy_color_changed_cb(self, buddy, color):
self._activity_icon.props.color = buddy.get_color()

View File

@ -1,4 +1,4 @@
from sugar.canvas.MenuIcon import MenuIcon
from sugar.graphics.menuicon import MenuIcon
from view.BuddyMenu import BuddyMenu
class BuddyIcon(MenuIcon):
@ -8,11 +8,11 @@ class BuddyIcon(MenuIcon):
self._shell = shell
self._buddy = buddy
self._buddy.connect('appeared', self.__buddy_presence_change_cb)
self._buddy.connect('disappeared', self.__buddy_presence_change_cb)
self._buddy.connect('color-changed', self.__buddy_presence_change_cb)
self._buddy.connect('appeared', self._buddy_presence_change_cb)
self._buddy.connect('disappeared', self._buddy_presence_change_cb)
self._buddy.connect('color-changed', self._buddy_presence_change_cb)
def __buddy_presence_change_cb(self, buddy, color=None):
def _buddy_presence_change_cb(self, buddy, color=None):
# Update the icon's color when the buddy comes and goes
self.set_property('color', buddy.get_color())

View File

@ -1,9 +1,11 @@
from sugar.canvas.Menu import Menu
from sugar.canvas.IconItem import IconItem
from sugar.presence import PresenceService
import gtk, gobject
import gtk
import gobject
import goocanvas
from sugar.graphics.menu import Menu
from sugar.graphics.canvasicon import CanvasIcon
from sugar.presence import PresenceService
_ICON_SIZE = 75
class BuddyMenu(Menu):
@ -12,12 +14,21 @@ class BuddyMenu(Menu):
ACTION_REMOVE_FRIEND = 2
def __init__(self, shell, buddy):
Menu.__init__(self, shell.get_grid(), buddy.get_name())
self._buddy = buddy
self._buddy.connect('icon-changed', self.__buddy_icon_changed_cb)
self._shell = shell
icon_item = None
pixbuf = self._get_buddy_icon_pixbuf()
if pixbuf:
scaled_pixbuf = pixbuf.scale_simple(_ICON_SIZE, _ICON_SIZE,
gtk.gdk.INTERP_BILINEAR)
del pixbuf
icon_item = hippo.Image(pixbuf=scaled_pixbuf)
Menu.__init__(self, buddy.get_name(), icon_item)
self._buddy.connect('icon-changed', self.__buddy_icon_changed_cb)
owner = shell.get_model().get_owner()
if buddy.get_name() != owner.get_name():
self._add_actions()
@ -48,20 +59,12 @@ class BuddyMenu(Menu):
shell_model = self._shell.get_model()
pservice = PresenceService.get_instance()
pixbuf = self._get_buddy_icon_pixbuf()
if pixbuf:
scaled_pixbuf = pixbuf.scale_simple(_ICON_SIZE, _ICON_SIZE, gtk.gdk.INTERP_BILINEAR)
del pixbuf
self._buddy_icon_item = goocanvas.Image()
self._buddy_icon_item.set_property('pixbuf', scaled_pixbuf)
self.add_image(self._buddy_icon_item, 5, 5)
friends = shell_model.get_friends()
if friends.has_buddy(self._buddy):
icon = IconItem(icon_name='stock-remove')
icon = CanvasIcon(icon_name='stock-remove')
self.add_action(icon, BuddyMenu.ACTION_REMOVE_FRIEND)
else:
icon = IconItem(icon_name='stock-add')
icon = CanvasIcon(icon_name='stock-add')
self.add_action(icon, BuddyMenu.ACTION_MAKE_FRIEND)
activity_id = shell_model.get_current_activity()

View File

@ -1,24 +1,25 @@
import random
import goocanvas
import hippo
from view.home.IconLayout import IconLayout
from sugar.graphics.spreadlayout import SpreadLayout
from view.home.MyIcon import MyIcon
from view.BuddyActivityView import BuddyActivityView
class FriendsGroup(goocanvas.Group):
class FriendsBox(hippo.CanvasBox, hippo.CanvasItem):
__gtype_name__ = 'SugarFriendsBox'
def __init__(self, shell, menu_shell):
goocanvas.Group.__init__(self)
hippo.CanvasBox.__init__(self, background_color=0xe2e2e2ff)
self._shell = shell
self._menu_shell = menu_shell
self._icon_layout = IconLayout(shell.get_grid())
self._layout = SpreadLayout()
self._friends = {}
me = MyIcon(112)
me.translate(600 - (me.get_property('size') / 2),
450 - (me.get_property('size') / 2))
self.add_child(me)
#me = MyIcon(112)
#me.translate(600 - (me.get_property('size') / 2),
# 450 - (me.get_property('size') / 2))
#self.add_child(me)
friends = self._shell.get_model().get_friends()
@ -30,8 +31,7 @@ class FriendsGroup(goocanvas.Group):
def add_friend(self, buddy_info):
icon = BuddyActivityView(self._shell, self._menu_shell, buddy_info)
self.add_child(icon)
self._icon_layout.add_icon(icon)
self.append(icon, hippo.PACK_FIXED)
self._friends[buddy_info.get_name()] = icon
@ -39,5 +39,9 @@ class FriendsGroup(goocanvas.Group):
self.add_friend(buddy_info)
def _friend_removed_cb(self, data_model, name):
self.remove_child(self._friends[name])
self.remove(self._friends[name])
del self._friends[name]
def do_allocate(self, width, height):
hippo.CanvasBox.do_allocate(self, width, height)
self._layout.layout(self)

View File

@ -1,12 +1,13 @@
import gtk
import goocanvas
import hippo
import cairo
from sugar.canvas.CanvasView import CanvasView
from sugar.canvas.MenuShell import MenuShell
from view.home.MeshGroup import MeshGroup
from view.home.MeshBox import MeshBox
from view.home.HomeGroup import HomeGroup
from view.home.FriendsGroup import FriendsGroup
from view.home.FriendsBox import FriendsBox
import sugar
class HomeWindow(gtk.Window):
@ -27,8 +28,18 @@ class HomeWindow(gtk.Window):
menu_shell = MenuShell(shell.get_grid())
self._add_page(HomeGroup(shell))
self._add_page(FriendsGroup(shell, menu_shell))
self._add_page(MeshGroup(shell, menu_shell))
canvas = hippo.Canvas()
box = FriendsBox(shell, menu_shell)
canvas.set_root(box)
self._nb.append_page(canvas)
canvas.show()
canvas = hippo.Canvas()
box = MeshBox(shell, menu_shell)
canvas.set_root(box)
self._nb.append_page(canvas)
canvas.show()
def _add_page(self, group):
view = CanvasView()

View File

@ -2,9 +2,8 @@ sugardir = $(pkgdatadir)/shell/view/home
sugar_PYTHON = \
__init__.py \
DonutItem.py \
FriendsGroup.py \
IconLayout.py \
FriendsBox.py \
HomeGroup.py \
HomeWindow.py \
MeshGroup.py \
MeshBox.py \
MyIcon.py

View File

@ -1,26 +1,26 @@
import random
import goocanvas
import hippo
import conf
from sugar.canvas.IconItem import IconItem
from view.home.IconLayout import IconLayout
from sugar.graphics.spreadlayout import SpreadLayout
from sugar.graphics.canvasicon import CanvasIcon
from view.BuddyIcon import BuddyIcon
from sugar.canvas.SnowflakeLayout import SnowflakeLayout
import conf
class ActivityView(goocanvas.Group):
class ActivityView(hippo.CanvasBox):
def __init__(self, shell, menu_shell, model):
goocanvas.Group.__init__(self)
hippo.CanvasBox.__init__(self)
self._shell = shell
self._model = model
self._layout = SnowflakeLayout()
self._icons = {}
icon = IconItem(icon_name=model.get_icon_name(),
icon = CanvasIcon(icon_name=model.get_icon_name(),
color=model.get_color(), size=80)
icon.connect('clicked', self._clicked_cb)
self.add_child(icon)
icon.connect('activated', self._clicked_cb)
self.append(icon, hippo.PACK_FIXED)
self._layout.set_root(icon)
def has_buddy_icon(self, name):
@ -28,13 +28,11 @@ class ActivityView(goocanvas.Group):
def add_buddy_icon(self, name, icon):
self._icons[name] = icon
self.add_child(icon)
self._layout.add_child(icon)
self.append(icon, hippo.PACK_FIXED)
def remove_buddy_icon(self, name):
icon = self._icons[name]
self._layout.remove_child(icon)
self.remove_child(icon)
self.remove(icon)
del self._icons[name]
def get_size_request(self):
@ -47,15 +45,15 @@ class ActivityView(goocanvas.Group):
bundle = registry.get_activity_from_type(default_type)
self._shell.join_activity(bundle.get_id(), self._model.get_id())
class MeshGroup(goocanvas.Group):
class MeshBox(hippo.CanvasBox, hippo.CanvasItem):
__gtype_name__ = 'SugarMeshBox'
def __init__(self, shell, menu_shell):
goocanvas.Group.__init__(self)
hippo.CanvasBox.__init__(self, background_color=0xe2e2e2ff)
self._shell = shell
self._menu_shell = menu_shell
self._model = shell.get_model().get_mesh()
self._layout = IconLayout(shell.get_grid())
self._layout = SpreadLayout()
self._buddies = {}
self._activities = {}
self._buddy_to_activity = {}
@ -91,15 +89,13 @@ class MeshGroup(goocanvas.Group):
def _add_alone_buddy(self, buddy_model):
icon = BuddyIcon(self._shell, self._menu_shell, buddy_model)
icon.props.size = 80
self.add_child(icon)
self.append(icon, hippo.PACK_FIXED)
self._buddies[buddy_model.get_name()] = icon
self._layout.add_icon(icon)
def _remove_alone_buddy(self, buddy_model):
icon = self._buddies[buddy_model.get_name()]
self.remove_child(icon)
self._layout.remove_icon(icon)
self.remove(icon)
del self._buddies[buddy_model.get_name()]
def _remove_buddy(self, buddy_model):
@ -110,7 +106,6 @@ class MeshGroup(goocanvas.Group):
for activity in self._activities.values():
if activity.has_buddy_icon(name):
activity.remove_buddy_icon(name)
self._layout.update()
def _move_buddy(self, buddy_model, activity_model):
name = buddy_model.get_name()
@ -126,17 +121,17 @@ class MeshGroup(goocanvas.Group):
icon.props.size = 60
activity.add_buddy_icon(buddy_model.get_name(), icon)
self._layout.update()
def _add_activity(self, activity_model):
icon = ActivityView(self._shell, self._menu_shell, activity_model)
self.add_child(icon)
self.append(icon, hippo.PACK_FIXED)
self._activities[activity_model.get_id()] = icon
self._layout.add_icon(icon)
def _remove_activity(self, activity_model):
icon = self._activities[activity_model.get_id()]
self.remove_child(icon)
self._layout.remove_icon(icon)
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,6 @@ sugar_PYTHON = \
IconItem.py \
IconColor.py \
Menu.py \
MenuIcon.py \
MenuShell.py \
SnowflakeLayout.py \
Timeline.py

View File

@ -1,95 +0,0 @@
import gtk
import goocanvas
import gobject
from sugar.canvas.CanvasView import CanvasView
from sugar.canvas.CanvasBox import CanvasBox
from sugar.canvas.IconItem import IconItem
class Menu(gtk.Window):
__gsignals__ = {
'action': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([int])),
}
def __init__(self, grid, title):
gtk.Window.__init__(self, gtk.WINDOW_POPUP)
self._width = 15
self._height = 3
self._grid = grid
self._action_box = None
self._canvas = CanvasView()
self.add(self._canvas)
self._canvas.show()
model = goocanvas.CanvasModelSimple()
self._root = model.get_root_item()
self._rect = goocanvas.Rect(fill_color='black', line_width=0)
self._root.add_child(self._rect)
text = goocanvas.Text(text=title, font="Sans bold 18",
fill_color='white', anchor=gtk.ANCHOR_SW)
self._grid.set_constraints(text, 1, self._height, self._width, 2)
self._root.add_child(text)
self._height += 1
self._update_constraints()
self._canvas.set_model(model)
def _create_action_box(self):
separator = goocanvas.Path(data='M 15 0 L 215 0', line_width=3,
stroke_color='white')
self._grid.set_constraints(separator, 0, self._height)
self._root.add_child(separator)
self._height += 1
box = CanvasBox(self._grid, CanvasBox.HORIZONTAL)
self._grid.set_constraints(box, 0, self._height)
self._height += 5
return box
def get_grid(self):
return self._grid
def add_image(self, image_item, width, height):
"""width & height in grid units"""
separator = goocanvas.Path(data='M 15 0 L 215 0', line_width=3,
stroke_color='white')
self._grid.set_constraints(separator, 0, self._height)
self._root.add_child(separator)
self._height += 1
self._grid.set_constraints(image_item, x=5, y=self._height, width=width, height=height)
self._root.add_child(image_item)
self._height += height + 1
self._update_constraints()
def add_action(self, icon, action_id):
if self._action_box == None:
self._action_box = self._create_action_box()
self._root.add_child(self._action_box)
self._update_constraints()
icon.connect('clicked', self._action_clicked_cb, action_id)
self._action_box.set_constraints(icon, 5, 5)
self._action_box.add_child(icon)
def _action_clicked_cb(self, icon, action):
self.emit('action', action)
def _update_constraints(self):
self._grid.set_constraints(self._canvas, 0, 0,
self._width, self._height)
self._grid.set_constraints(self._rect, 0, 0,
self._width, self._height)
def get_width(self):
return self._width
def get_height(self):
return self._height

View File

@ -1,121 +0,0 @@
import goocanvas
import gobject
from sugar.canvas.IconItem import IconItem
from sugar.canvas.Grid import Grid
class _MenuStrategy:
def get_menu_position(self, menu, grid_x1, grid_y1, grid_x2, grid_y2):
grid_x = grid_x2
if grid_x + menu.get_width() > Grid.COLS:
grid_x = grid_x1 - menu.get_width() + 1
grid_y = grid_y1
if grid_y < 0:
grid_y = 0
if grid_y + menu.get_width() > Grid.ROWS:
grid_y = Grid.ROWS - menu.get_width()
return [grid_x, grid_y]
class MenuIcon(IconItem, goocanvas.Item):
def __init__(self, menu_shell, **kwargs):
IconItem.__init__(self, **kwargs)
self._menu_shell = menu_shell
self._grid = menu_shell.get_grid()
self._menu = None
self._hover_menu = False
self._popdown_on_leave = False
self._popdown_sid = 0
self._menu_strategy = _MenuStrategy()
def popdown(self):
if self._menu:
self._menu.destroy()
self._menu = None
self._menu_shell.set_active(None)
def set_menu_strategy(self, strategy):
self._menu_strategy = strategy
def _popup(self, x1, y1, x2, y2):
self.popdown()
self._menu_shell.set_active(None)
grid = self._shell.get_grid()
self._menu = self.create_menu()
self._menu.connect('enter-notify-event',
self._menu_enter_notify_event_cb)
self._menu.connect('leave-notify-event',
self._menu_leave_notify_event_cb)
[grid_x1, grid_y1] = grid.convert_from_screen(x1, y1)
[grid_x2, grid_y2] = grid.convert_from_screen(x2, y2)
strategy = self._menu_strategy
[grid_x, grid_y] = strategy.get_menu_position(self._menu,
grid_x1, grid_y1,
grid_x2, grid_y2)
grid.set_constraints(self._menu, grid_x, grid_y,
self._menu.get_width(), self._menu.get_height())
self._menu.show()
self._menu_shell.set_active(self)
def _menu_enter_notify_event_cb(self, widget, event):
self._hover_menu = True
def _menu_leave_notify_event_cb(self, widget, event):
self._hover_menu = False
if self._popdown_on_leave:
self.popdown()
def do_create_view(self, canvas, parent_view):
view = IconItem.do_create_view(self, canvas, parent_view)
view.connect('enter-notify-event', self._enter_notify_event_cb, canvas)
view.connect('leave-notify-event', self._leave_notify_event_cb)
return view
def _start_popdown_timeout(self):
self._stop_popdown_timeout()
self._popdown_sid = gobject.timeout_add(1000, self._popdown_timeout_cb)
def _stop_popdown_timeout(self):
if self._popdown_sid > 0:
gobject.source_remove(self._popdown_sid)
self._popdown_sid = 0
def _enter_notify_event_cb(self, view, target, event, canvas):
self._stop_popdown_timeout()
[x1, y1] = canvas.convert_to_pixels(view.get_bounds().x1,
view.get_bounds().y1)
[x2, y2] = canvas.convert_to_pixels(view.get_bounds().x2,
view.get_bounds().y2)
[window_x, window_y] = canvas.window.get_origin()
x1 += window_x
y1 += window_y
x2 += window_x
y2 += window_y
self._popup(int(x1), int(y1), int(x2), int(y2))
def _popdown_timeout_cb(self):
self._popdown_sid = 0
if not self._hover_menu:
self.popdown()
else:
self._popdown_on_leave = True
return False
def _leave_notify_event_cb(self, view, target, event):
self._start_popdown_timeout()

View File

@ -5,4 +5,5 @@ sugar_PYTHON = \
grid.py \
menuicon.py \
menu.py \
spreadlayout.py \
style.py

View File

@ -3,26 +3,11 @@ import math
import cairo
class IconLayout:
class SpreadLayout:
DISTANCE_THRESHOLD = 120.0
def __init__(self, grid):
self._icons = []
self._constraints = {}
self._grid = grid
[self._x1, self._y1] = self._grid.convert_to_canvas(1, 1)
[self._x2, self._y2] = self._grid.convert_to_canvas(78, 59)
def add_icon(self, icon):
self._icons.append(icon)
self._layout_icon(icon)
self.update()
def remove_icon(self, icon):
self._icons.remove(icon)
del self._constraints[icon]
self.update()
def __init__(self):
pass
def _get_distance(self, icon1, icon2):
[icon1_x, icon1_y] = self._constraints[icon1]
@ -83,9 +68,9 @@ class IconLayout:
self._spread_icons()
tries -= 1
def _layout_icon(self, icon):
[width, height] = icon.get_size_request()
x = random.random() * (self._x2 - self._x1 - width)
y = random.random() * (self._y2 - self._y1 - height)
self._constraints[icon] = [x, y]
def layout(self, box):
[width, height] = box.get_allocation()
for item in box.get_children():
x = int(random.random() * width)
y = int(random.random() * height)
box.move(item, x, y)