Move the view to his own module

This commit is contained in:
Marco Pesenti Gritti
2006-09-15 13:23:21 +02:00
parent ca19f0f251
commit bcc1740f7f
27 changed files with 37 additions and 32 deletions
+72
View File
@@ -0,0 +1,72 @@
import gtk
import dbus
import conf
from sugar.activity import Activity
from sugar.presence import PresenceService
from sugar.canvas.IconColor import IconColor
from sugar.p2p import Stream
from sugar.p2p import network
class ActivityHost:
def __init__(self, shell, window):
self._shell = shell
self._window = window
self._xid = window.get_xid()
self._pservice = PresenceService.get_instance()
bus = dbus.SessionBus()
proxy_obj = bus.get_object(Activity.get_service_name(self._xid),
Activity.get_object_path(self._xid))
self._activity = dbus.Interface(proxy_obj, Activity.ACTIVITY_INTERFACE)
self._id = self._activity.get_id()
self._type = self._activity.get_type()
self._gdk_window = gtk.gdk.window_foreign_new(self._xid)
registry = conf.get_activity_registry()
info = registry.get_activity(self._type)
self._icon_name = info.get_icon()
def get_id(self):
return self._id
def get_xid(self):
return self._xid
def get_icon_name(self):
return self._icon_name
def get_icon_color(self):
activity = self._pservice.get_activity(self._id)
if activity != None:
return IconColor(activity.get_color())
else:
return conf.get_profile().get_color()
def share(self):
self._activity.share()
def invite(self, buddy):
if not self.get_shared():
self.share()
issuer = self._pservice.get_owner().get_name()
service = buddy.get_service_of_type("_presence_olpc._tcp")
stream = Stream.Stream.new_from_service(service, start_reader=False)
writer = stream.new_writer(service)
writer.custom_request("invite", None, None, issuer,
self._type, self._id)
def get_shared(self):
return self._activity.get_shared()
def get_type(self):
return self._type
def present(self):
self._window.activate(gtk.get_current_event_time())
def show_dialog(self, dialog):
dialog.show()
dialog.window.set_transient_for(self._gdk_window)
+128
View File
@@ -0,0 +1,128 @@
import logging
import gtk
import dbus
import dbus.service
class Console(gtk.ScrolledWindow):
def __init__(self):
gtk.ScrolledWindow.__init__(self)
self._show_debug = False
self.set_policy(gtk.POLICY_AUTOMATIC,
gtk.POLICY_AUTOMATIC)
self._textview = gtk.TextView()
self._textview.set_wrap_mode(gtk.WRAP_WORD)
self.add(self._textview)
self._textview.show()
buf = self._textview.get_buffer()
self._debug_tag = buf.create_tag("debug")
self._debug_tag.set_property("invisible", True)
def get_show_debug(self):
return self._show_debug
def set_show_debug(self, show_debug):
self._show_debug = show_debug
self._debug_tag.set_property("invisible", not show_debug)
def log(self, level, message):
msg = message + '\n'
buf = self._textview.get_buffer()
it = buf.get_end_iter()
if level == logging.DEBUG:
buf.insert_with_tags(it, msg, self._debug_tag)
else:
buf.insert(it, msg)
class ConsoleDbusService(dbus.service.Object):
def __init__(self, console, bus_name):
dbus.service.Object.__init__(self, bus_name, '/org/laptop/Sugar/Console')
self._console = console
@dbus.service.method('org.laptop.Sugar.Console',
in_signature="saias", out_signature="")
def log(self, module_id, levels, messages):
self._console.log(module_id, levels, messages)
class ConsoleWindow(gtk.Window):
def __init__(self):
gtk.Window.__init__(self)
self.set_default_size(620, 440)
self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
self.set_title("Console")
self.connect("delete_event", lambda w, e: w.hide_on_delete())
vbox = gtk.VBox()
toolbar = gtk.Toolbar()
self._debug_toggle = gtk.ToggleToolButton()
self._debug_toggle.connect('toggled', self.__debug_toggled_cb)
self._debug_toggle.set_label('Debug')
toolbar.insert(self._debug_toggle, -1)
self._debug_toggle.show()
self._ignore_toggle = False
vbox.pack_start(toolbar, False)
toolbar.show()
self._nb = gtk.Notebook()
self._nb.connect('switch-page', self.__page_changed_cb)
vbox.pack_start(self._nb)
self._nb.show()
self.add(vbox)
vbox.show()
self._consoles = {}
session_bus = dbus.SessionBus()
bus_name = dbus.service.BusName('org.laptop.Sugar.Console', bus=session_bus)
ConsoleDbusService(self, bus_name)
def _add_console(self, page_id):
console = Console()
page = self._nb.append_page(console, gtk.Label(page_id))
console.show()
self._consoles[page_id] = console
return console
def _get_console(self, page_id):
if not self._consoles.has_key(page_id):
console = self._add_console(page_id)
else:
console = self._consoles[page_id]
return console
def __debug_toggled_cb(self, button):
if not self._ignore_toggle:
console = self._nb.get_nth_page(self._nb.get_current_page())
if console:
console.set_show_debug(button.get_active())
def __page_changed_cb(self, notebook, page, page_num):
console = self._nb.get_nth_page(page_num)
self._ignore_toggle = True
self._debug_toggle.set_active(console.get_show_debug())
self._ignore_toggle = False
def set_page(self, page_id):
page = self._nb.page_num(self._consoles[page_id])
self._nb.set_current_page(page)
def log(self, page_id, levels, messages):
console = self._get_console(page_id)
i = 0
while i < len(levels):
console.log(levels[i], messages[i])
i += 1
+36
View File
@@ -0,0 +1,36 @@
import gtk
from gettext import gettext as _
import conf
class FirstTimeDialog(gtk.Dialog):
def __init__(self):
gtk.Dialog.__init__(self)
label = gtk.Label(_('Nick Name:'))
label.set_alignment(0.0, 0.5)
self.vbox.pack_start(label)
label.show()
self._entry = gtk.Entry()
self.vbox.pack_start(self._entry)
self._entry.show()
button = gtk.Button(None, gtk.STOCK_OK)
self.vbox.pack_start(button)
button.connect('clicked', self.__ok_button_clicked_cb)
button.show()
def __ok_button_clicked_cb(self, button):
profile = conf.get_profile()
profile.set_nick_name(self._entry.get_text())
self.destroy()
def get_profile():
profile = conf.get_profile()
if profile.get_nick_name() == None:
dialog = FirstTimeDialog()
dialog.connect('destroy', self.__first_time_dialog_destroy_cb)
dialog.show()
return profile
+104
View File
@@ -0,0 +1,104 @@
from sugar.canvas.IconItem import IconItem
from sugar.canvas.Grid import Grid
from view.FriendPopup import FriendPopup
class _PopupShell:
def __init__(self):
self._popup_controller = None
def set_active(self, controller):
if self._popup_controller:
self._popup_controller._popdown()
self._popup_controller = controller
class FriendIcon(IconItem):
_popup_shell = _PopupShell()
def __init__(self, shell_model, friend):
IconItem.__init__(self, icon_name='stock-buddy',
color=friend.get_color(), size=96)
self._shell_model = shell_model
self._friend = friend
self._popup = None
self._popup_distance = 0
self._hover_popup = False
self._popdown_on_leave = False
self.connect('popup', self._popup_cb)
self.connect('popdown', self._popdown_cb)
def set_popup_distance(self, distance):
self._popup_distance = distance
def get_friend(self):
return self._friend
def _popdown(self):
if self._popup:
self._popup.destroy()
self._popup = None
def _popup_cb(self, icon, x1, y1, x2, y2):
self._popdown()
FriendIcon._popup_shell.set_active(None)
grid = Grid()
self._popup = FriendPopup(grid, icon.get_friend())
self._popup.connect('action', self._popup_action_cb)
self._popup.connect('enter-notify-event',
self._popup_enter_notify_event_cb)
self._popup.connect('leave-notify-event',
self._popup_leave_notify_event_cb)
distance = self._popup_distance
[grid_x1, grid_y1] = grid.convert_from_screen(x1, y1)
[grid_x2, grid_y2] = grid.convert_from_screen(x2, y2)
grid_x = grid_x2 + distance
if grid_x + self._popup.get_width() > Grid.ROWS:
grid_x = grid_x1 - self._popup.get_width() + 1 - distance
grid_y = grid_y1
if grid_y < 0:
grid_y = 0
if grid_y + self._popup.get_width() > Grid.ROWS:
grid_y = Grid.ROWS - self._popup.get_width()
grid.set_constraints(self._popup, grid_x, grid_y,
self._popup.get_width(), self._popup.get_height())
self._popup.show()
FriendIcon._popup_shell.set_active(self)
def _popup_action_cb(self, popup, action):
self._popdown()
buddy = self._friend.get_buddy()
if buddy == None:
return
if action == FriendPopup.ACTION_INVITE:
activity = self._shell_model.get_current_activity()
activity.invite(buddy)
elif action == FriendPopup.ACTION_MAKE_FRIEND:
friends = self._shell_model.get_friends()
friends.add_buddy(buddy)
def _popdown_cb(self, friend):
if not self._hover_popup:
self._popdown()
else:
self._popdown_on_leave = True
def _popup_enter_notify_event_cb(self, widget, event):
self._hover_popup = True
def _popup_leave_notify_event_cb(self, widget, event):
self._hover_popup = False
if self._popdown_on_leave:
self._popdown()
+83
View File
@@ -0,0 +1,83 @@
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 FriendPopup(gtk.Window):
ACTION_MAKE_FRIEND = 0
ACTION_INVITE = 1
__gsignals__ = {
'action': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([int])),
}
def __init__(self, grid, friend):
gtk.Window.__init__(self, gtk.WINDOW_POPUP)
self._friend = friend
self._hover = False
self._popdown_on_leave = False
self._width = 13
self._height = 10
canvas = CanvasView()
self.add(canvas)
canvas.show()
grid.set_constraints(canvas, 0, 0, self._width, self._height)
model = goocanvas.CanvasModelSimple()
root = model.get_root_item()
color = friend.get_color()
rect = goocanvas.Rect(fill_color=color.get_fill_color(),
stroke_color=color.get_stroke_color(),
line_width=3)
grid.set_constraints(rect, 0, 0, self._width, self._height)
root.add_child(rect)
text = goocanvas.Text(text=friend.get_name(), font="Sans bold 18",
fill_color='black', anchor=gtk.ANCHOR_SW)
grid.set_constraints(text, 1, 3, self._width, self._height)
root.add_child(text)
separator = goocanvas.Path(data='M 15 0 L 185 0', line_width=3,
fill_color='black')
grid.set_constraints(separator, 0, 4)
root.add_child(separator)
box = CanvasBox(grid, CanvasBox.HORIZONTAL, 1)
grid.set_constraints(box, 0, 5)
icon = IconItem(icon_name='stock-make-friend')
icon.connect('clicked', self._action_clicked_cb,
FriendPopup.ACTION_MAKE_FRIEND)
box.set_constraints(icon, 3, 3)
box.add_child(icon)
icon = IconItem(icon_name='stock-chat')
box.set_constraints(icon, 3, 3)
box.add_child(icon)
icon = IconItem(icon_name='stock-invite')
icon.connect('clicked', self._action_clicked_cb,
FriendPopup.ACTION_INVITE)
box.set_constraints(icon, 3, 3)
box.add_child(icon)
root.add_child(box)
canvas.set_model(model)
def _action_clicked_cb(self, icon, action):
self.emit('action', action)
def get_width(self):
return self._width
def get_height(self):
return self._height
+11
View File
@@ -0,0 +1,11 @@
SUBDIRS = frame home
sugardir = $(pkgdatadir)/shell/view
sugar_PYTHON = \
__init__.py \
ActivityHost.py \
ConsoleWindow.py \
FirstTimeDialog.py \
FriendIcon.py \
FriendPopup.py \
Shell.py
+74
View File
@@ -0,0 +1,74 @@
import gtk
import gobject
import wnck
from view.home.HomeWindow import HomeWindow
from view.ActivityHost import ActivityHost
from view.frame.Frame import Frame
from globalkeys import KeyGrabber
import sugar
class Shell(gobject.GObject):
def __init__(self, model):
gobject.GObject.__init__(self)
self._model = model
self._screen = wnck.screen_get_default()
self._key_grabber = KeyGrabber()
self._key_grabber.connect('key-pressed', self.__global_key_pressed_cb)
self._key_grabber.grab('F1')
self._key_grabber.grab('F2')
self._key_grabber.grab('F3')
self._key_grabber.grab('F4')
self._key_grabber.grab('F5')
self._key_grabber.grab('F6')
self._home_window = HomeWindow(self.get_model())
self._home_window.show()
self.set_zoom_level(sugar.ZOOM_HOME)
self._screen.connect('window-opened', self.__window_opened_cb)
self._screen.connect('window-closed', self.__window_closed_cb)
self._screen.connect('active-window-changed',
self.__active_window_changed_cb)
self._frame = Frame(self)
self._frame.show_and_hide(10)
def __global_key_pressed_cb(self, grabber, key):
if key == 'F1':
self.set_zoom_level(sugar.ZOOM_ACTIVITY)
elif key == 'F2':
self.set_zoom_level(sugar.ZOOM_HOME)
elif key == 'F3':
self.set_zoom_level(sugar.ZOOM_FRIENDS)
elif key == 'F4':
self.set_zoom_level(sugar.ZOOM_MESH)
elif key == 'F5':
self._frame.toggle_visibility()
elif key == 'F6':
self._model.start_activity('org.sugar.Terminal')
def __window_opened_cb(self, screen, window):
if window.get_window_type() == wnck.WINDOW_NORMAL:
self._model.add_activity(ActivityHost(self, window))
def __active_window_changed_cb(self, screen):
window = screen.get_active_window()
if window and window.get_window_type() == wnck.WINDOW_NORMAL:
self._model.set_current_activity(window.get_xid())
def __window_closed_cb(self, screen, window):
if window.get_window_type() == wnck.WINDOW_NORMAL:
self._model.remove_activity(window.get_xid())
def get_model(self):
return self._model
def set_zoom_level(self, level):
if level == sugar.ZOOM_ACTIVITY:
self._screen.toggle_showing_desktop(False)
else:
self._screen.toggle_showing_desktop(True)
self._home_window.set_zoom_level(level)
View File
+83
View File
@@ -0,0 +1,83 @@
import gtk
import goocanvas
import logging
import conf
from sugar.canvas.IconItem import IconItem
from sugar.canvas.IconColor import IconColor
from sugar.presence import PresenceService
from sugar.canvas.CanvasBox import CanvasBox
class ActivityItem(IconItem):
def __init__(self, activity):
icon_name = activity.get_icon()
IconItem.__init__(self, icon_name=icon_name, color=IconColor('white'))
self._activity = activity
def get_bundle_id(self):
return self._activity.get_id()
class InviteItem(IconItem):
def __init__(self, invite):
IconItem.__init__(self, icon_name=invite.get_icon(),
color=invite.get_color())
self._invite = invite
def get_activity_id(self):
return self._invite.get_activity_id()
def get_bundle_id(self):
return self._invite.get_bundle_id()
def get_invite(self):
return self._invite
class BottomPanel(CanvasBox):
def __init__(self, grid, shell_model):
CanvasBox.__init__(self, grid, CanvasBox.HORIZONTAL, 1)
self._shell_model = shell_model
self._invite_to_item = {}
self._invites = shell_model.get_invites()
registry = conf.get_activity_registry()
for activity in registry.list_activities():
if activity.get_show_launcher():
self.add_activity(activity)
for invite in self._invites:
self.add_invite(invite)
self._invites.connect('invite-added', self.__invite_added_cb)
self._invites.connect('invite-removed', self.__invite_removed_cb)
def __activity_clicked_cb(self, icon):
self._shell_model.start_activity(icon.get_bundle_id())
def __invite_clicked_cb(self, icon):
self._invites.remove_invite(icon.get_invite())
self._shell_model.join_activity(icon.get_bundle_id(),
icon.get_activity_id())
def __invite_added_cb(self, invites, invite):
self.add_invite(invite)
def __invite_removed_cb(self, invites, invite):
self.remove_invite(invite)
def add_activity(self, activity):
item = ActivityItem(activity)
item.connect('clicked', self.__activity_clicked_cb)
self.set_constraints(item, 3, 3)
self.add_child(item)
def add_invite(self, invite):
item = InviteItem(invite)
item.connect('clicked', self.__invite_clicked_cb)
self.set_constraints(item, 3, 3)
self.add_child(item, 0)
self._invite_to_item[invite] = item
def remove_invite(self, invite):
self.remove_child(self._invite_to_item[invite])
del self._invite_to_item[invite]
+70
View File
@@ -0,0 +1,70 @@
import gtk
import gobject
import goocanvas
from view.frame.BottomPanel import BottomPanel
from view.frame.RightPanel import RightPanel
from view.frame.TopPanel import TopPanel
from view.frame.PanelWindow import PanelWindow
from sugar.canvas.Grid import Grid
class Frame:
def __init__(self, shell):
self._windows = []
shell_model = shell.get_model()
model = goocanvas.CanvasModelSimple()
root = model.get_root_item()
grid = Grid()
bg = goocanvas.Rect(fill_color="#4f4f4f", line_width=0)
grid.set_constraints(bg, 0, 0, 80, 60)
root.add_child(bg)
panel = BottomPanel(grid, shell_model)
grid.set_constraints(panel, 5, 55)
root.add_child(panel)
panel_window = PanelWindow(grid, model, 0, 55, 80, 5)
self._windows.append(panel_window)
panel = TopPanel(grid, shell)
root.add_child(panel)
panel_window = PanelWindow(grid, model, 0, 0, 80, 5)
self._windows.append(panel_window)
panel = RightPanel(grid, shell_model)
grid.set_constraints(panel, 75, 5)
root.add_child(panel)
panel_window = PanelWindow(grid, model, 75, 5, 5, 50)
self._windows.append(panel_window)
panel_window = PanelWindow(grid, model, 0, 5, 5, 50)
self._windows.append(panel_window)
def __hide_timeout_cb(self):
self.hide()
return False
def show_and_hide(self, seconds):
self.show()
gobject.timeout_add(seconds * 1000, self.__hide_timeout_cb)
def show(self):
for panel in self._windows:
panel.show()
def hide(self):
for panel in self._windows:
panel.hide()
def toggle_visibility(self):
for panel in self._windows:
if panel.props.visible:
panel.hide()
else:
panel.show()
+8
View File
@@ -0,0 +1,8 @@
sugardir = $(pkgdatadir)/shell/view/frame
sugar_PYTHON = \
__init__.py \
RightPanel.py \
PanelWindow.py \
Frame.py \
TopPanel.py \
BottomPanel.py
+27
View File
@@ -0,0 +1,27 @@
import gtk
import goocanvas
from sugar.canvas.CanvasView import CanvasView
class PanelWindow(gtk.Window):
def __init__(self, grid, model, x, y, width, height):
gtk.Window.__init__(self)
self._grid = grid
self.set_decorated(False)
self.realize()
self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
self.window.set_accept_focus(False)
screen = gtk.gdk.screen_get_default()
self.window.set_transient_for(screen.get_root_window())
view = CanvasView()
view.show()
self.add(view)
view.set_model(model)
self._grid.set_constraints(self, x, y, width, height)
self._grid.set_constraints(view, x, y, width, height)
+81
View File
@@ -0,0 +1,81 @@
import goocanvas
from sugar.canvas.IconItem import IconItem
from sugar.canvas.IconColor import IconColor
from sugar.canvas.CanvasBox import CanvasBox
from sugar.presence import PresenceService
from view.FriendIcon import FriendIcon
from model.Friends import Friend
class RightPanel(CanvasBox):
def __init__(self, grid, shell_model):
CanvasBox.__init__(self, grid, CanvasBox.VERTICAL, 1)
self._shell_model = shell_model
self._friends = shell_model.get_friends()
self._activity_ps = None
self._joined_hid = -1
self._left_hid = -1
self._buddies = {}
self._pservice = PresenceService.get_instance()
self._pservice.connect('activity-appeared',
self.__activity_appeared_cb)
shell_model.connect('activity-changed', self.__activity_changed_cb)
def add(self, buddy):
friend = Friend(buddy.get_name(), buddy.get_color())
icon = FriendIcon(self._shell_model, friend)
icon.set_popup_distance(1)
self.set_constraints(icon, 3, 3)
self.add_child(icon)
self._buddies[buddy.get_name()] = icon
def remove(self, buddy):
i = self.find_child(self._buddies[buddy.get_name()])
self.remove_child(i)
def clear(self):
while (self.get_n_children() > 0):
self.remove_child(0)
self._buddies = {}
def __activity_appeared_cb(self, pservice, activity_ps):
activity = self._shell_model.get_current_activity()
if activity and activity_ps.get_id() == activity.get_id():
self._set_activity_ps(activity_ps)
def _set_activity_ps(self, activity_ps):
if self._activity_ps == activity_ps:
return
if self._joined_hid > 0:
self._activity_ps.disconnect(self._joined_hid)
self._joined_hid = -1
if self._left_hid > 0:
self._activity_ps.disconnect(self._left_hid)
self._left_hid = -1
self._activity_ps = activity_ps
self.clear()
if activity_ps != None:
for buddy in activity_ps.get_joined_buddies():
self.add(buddy)
self._joined_hid = activity_ps.connect(
'buddy-joined', self.__buddy_joined_cb)
self._left_hid = activity_ps.connect(
'buddy-left', self.__buddy_left_cb)
def __activity_changed_cb(self, group, activity):
activity_ps = self._pservice.get_activity(activity.get_id())
self._set_activity_ps(activity_ps)
def __buddy_joined_cb(self, activity, buddy):
self.add(buddy)
def __buddy_left_cb(self, activity, buddy):
self.remove(buddy)
+70
View File
@@ -0,0 +1,70 @@
import goocanvas
from sugar.canvas.CanvasBox import CanvasBox
from sugar.canvas.IconItem import IconItem
import sugar
class TopPanel(goocanvas.Group):
def __init__(self, grid, shell):
goocanvas.Group.__init__(self)
self._grid = grid
self._shell = shell
box = CanvasBox(grid, CanvasBox.HORIZONTAL, 1)
self._grid.set_constraints(box, 5, 0)
self.add_child(box)
icon = IconItem(icon_name='stock-zoom-activity')
icon.connect('clicked', self.__level_clicked_cb, sugar.ZOOM_ACTIVITY)
box.set_constraints(icon, 3, 3)
box.add_child(icon)
icon = IconItem(icon_name='stock-zoom-home')
icon.connect('clicked', self.__level_clicked_cb, sugar.ZOOM_HOME)
box.set_constraints(icon, 3, 3)
box.add_child(icon)
icon = IconItem(icon_name='stock-zoom-friends')
icon.connect('clicked', self.__level_clicked_cb, sugar.ZOOM_FRIENDS)
box.set_constraints(icon, 3, 3)
box.add_child(icon)
icon = IconItem(icon_name='stock-zoom-mesh')
icon.connect('clicked', self.__level_clicked_cb, sugar.ZOOM_MESH)
box.set_constraints(icon, 3, 3)
box.add_child(icon)
box = CanvasBox(grid, CanvasBox.HORIZONTAL, 1)
self._grid.set_constraints(box, 60, 0)
self.add_child(box)
icon = IconItem(icon_name='stock-share')
icon.connect('clicked', self.__share_clicked_cb)
box.set_constraints(icon, 3, 3)
box.add_child(icon)
icon = IconItem(icon_name='stock-invite')
icon.connect('clicked', self.__invite_clicked_cb)
box.set_constraints(icon, 3, 3)
box.add_child(icon)
icon = IconItem(icon_name='stock-chat')
icon.connect('clicked', self.__chat_clicked_cb)
box.set_constraints(icon, 3, 3)
box.add_child(icon)
def __level_clicked_cb(self, item, level):
self._shell.set_zoom_level(level)
def __share_clicked_cb(self, item):
shell_model = self._shell.get_model()
activity = shell_model.get_current_activity()
if activity != None:
activity.share()
def __invite_clicked_cb(self, item):
pass
def __chat_clicked_cb(self, item):
pass
View File
+114
View File
@@ -0,0 +1,114 @@
import math
import goocanvas
from sugar.canvas.IconItem import IconItem
class PieceIcon(IconItem):
def __init__(self, piece_item, **kwargs):
IconItem.__init__(self, size=48, **kwargs)
self._piece_item = piece_item
def construct(self):
angle_start = self._piece_item.get_angle_start()
angle_end = self._piece_item.get_angle_end()
radius = self.get_parent().get_radius()
inner_radius = self.get_parent().get_inner_radius()
icon_radius = (radius + inner_radius) / 2
icon_angle = (angle_start + angle_end) / 2
x = icon_radius * math.cos(icon_angle)
y = - icon_radius * math.sin(icon_angle)
icon_width = self.get_property('size')
icon_height = self.get_property('size')
self.set_property('x', x - icon_width / 2)
self.set_property('y', y - icon_height / 2)
class PieceItem(goocanvas.Path):
def __init__(self, angle_start, angle_end, **kwargs):
goocanvas.Path.__init__(self, **kwargs)
self._angle_start = angle_start
self._angle_end = angle_end
self.set_property('fill-color', '#ffffff')
self.set_property('stroke-color', '#e2e2e2')
self.set_property('line-width', 4)
def get_icon(self):
return self._icon
def set_icon(self, icon_name, color):
self._icon = PieceIcon(self, icon_name=icon_name, color=color)
self.get_parent().add_child(self._icon)
self._icon.construct()
def get_angle_start(self):
return self._angle_start
def get_angle_end(self):
return self._angle_end
def construct(self):
r = self.get_parent().get_radius()
data = 'M0,0 '
dx = r * math.cos(self._angle_start)
dy = - r * math.sin(self._angle_start)
data += 'l%f,%f ' % (dx, dy)
dx = r * math.cos(self._angle_end)
dy = - r * math.sin(self._angle_end)
data += 'A%f,%f 0 0,0 %f,%f ' % (r, r, dx, dy)
data += 'z'
self.set_property('data', data)
class DonutItem(goocanvas.Group):
def __init__(self, radius, **kwargs):
goocanvas.Group.__init__(self, **kwargs)
self._radius = radius
self._angle_start = 0
bg = goocanvas.Ellipse(radius_x=radius, radius_y=radius,
fill_color='#f1f1f1', line_width=0)
self.add_child(bg)
self._inner_radius = radius / 2
fg = goocanvas.Ellipse(radius_x=self._inner_radius,
radius_y=self._inner_radius,
fill_color='#e2e2e2', line_width=0)
self.add_child(fg)
def add_piece(self, perc, icon_name, color):
# FIXME can't override set_parent on the
# PieceItem and there is no signal. So we
# call a construct method on the childs for now.
angle_end = self._angle_start + perc * 2 * math.pi / 100
piece_item = PieceItem(self._angle_start, angle_end)
self._angle_start = angle_end
self.add_child(piece_item, 1)
piece_item.construct()
piece_item.set_icon(icon_name, color)
return piece_item
def remove_piece(self, piece_item):
index = self.find_child(piece_item)
self.remove_child(index)
icon = piece_item.get_icon()
index = self.find_child(icon)
self.remove_child(index)
def get_radius(self):
return self._radius
def get_inner_radius(self):
return self._inner_radius
+33
View File
@@ -0,0 +1,33 @@
import random
import goocanvas
from view.home.IconLayout import IconLayout
from view.home.MyIcon import MyIcon
from view.FriendIcon import FriendIcon
class FriendsGroup(goocanvas.Group):
def __init__(self, shell_model):
goocanvas.Group.__init__(self)
self._shell_model = shell_model
self._icon_layout = IconLayout(1200, 900)
self._friends = shell_model.get_friends()
me = MyIcon(100)
me.translate(600 - (me.get_property('size') / 2),
450 - (me.get_property('size') / 2))
self.add_child(me)
for friend in self._friends:
self.add_friend(friend)
self._friends.connect('friend-added', self._friend_added_cb)
def add_friend(self, friend):
icon = FriendIcon(self._shell_model, friend)
self.add_child(icon)
self._icon_layout.add_icon(icon)
def _friend_added_cb(self, data_model, friend):
self.add_friend(friend)
+52
View File
@@ -0,0 +1,52 @@
import goocanvas
from view.home.DonutItem import DonutItem
from view.home.MyIcon import MyIcon
class TasksItem(DonutItem):
def __init__(self, shell_model):
DonutItem.__init__(self, 250)
self._items = {}
self._shell_model = shell_model
self._shell_model.connect('activity_opened', self.__activity_opened_cb)
self._shell_model.connect('activity_closed', self.__activity_closed_cb)
def __activity_opened_cb(self, model, activity):
self._add(activity)
def __activity_closed_cb(self, model, activity):
self._remove(activity)
def _remove(self, activity):
item = self._items[activity.get_id()]
self.remove_piece(item)
del self._items[activity.get_id()]
def _add(self, activity):
icon_name = activity.get_icon_name()
icon_color = activity.get_icon_color()
item = self.add_piece(100 / 8, icon_name, icon_color)
item.get_icon().connect('clicked',
self.__activity_icon_clicked_cb,
activity)
self._items[activity.get_id()] = item
def __activity_icon_clicked_cb(self, item, activity):
activity.present()
class HomeGroup(goocanvas.Group):
def __init__(self, shell_model):
goocanvas.Group.__init__(self)
tasks = TasksItem(shell_model)
tasks.translate(600, 450)
self.add_child(tasks)
me = MyIcon(150)
me.translate(600 - (me.get_property('size') / 2),
450 - (me.get_property('size') / 2))
self.add_child(me)
+50
View File
@@ -0,0 +1,50 @@
import gtk
import goocanvas
import cairo
from sugar.canvas.CanvasView import CanvasView
from view.home.MeshGroup import MeshGroup
from view.home.HomeGroup import HomeGroup
from view.home.FriendsGroup import FriendsGroup
import sugar
class HomeWindow(gtk.Window):
def __init__(self, shell_model):
gtk.Window.__init__(self)
self._shell_model = shell_model
self.realize()
self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DESKTOP)
self._nb = gtk.Notebook()
self._nb.set_show_border(False)
self._nb.set_show_tabs(False)
self.add(self._nb)
self._nb.show()
self._add_page(HomeGroup(shell_model))
self._add_page(FriendsGroup(shell_model))
self._add_page(MeshGroup())
def _add_page(self, group):
view = CanvasView()
self._nb.append_page(view)
view.show()
model = goocanvas.CanvasModelSimple()
root = model.get_root_item()
view.set_model(model)
bg = goocanvas.Rect(width=1900, height=1200,
line_width=0, fill_color='#e2e2e2')
root.add_child(bg)
root.add_child(group)
def set_zoom_level(self, level):
if level == sugar.ZOOM_HOME:
self._nb.set_current_page(0)
elif level == sugar.ZOOM_FRIENDS:
self._nb.set_current_page(1)
elif level == sugar.ZOOM_MESH:
self._nb.set_current_page(2)
+34
View File
@@ -0,0 +1,34 @@
import random
class IconLayout:
def __init__(self, width, height):
self._icons = []
self._width = width
self._height = height
def add_icon(self, icon):
self._icons.append(icon)
self._layout_icon(icon)
def remove_icon(self, icon):
self._icons.remove(icon)
def _is_valid_position(self, icon, x, y):
icon_size = icon.props.size
border = 20
if not (border < x < self._width - icon_size - border and \
border < y < self._height - icon_size - border):
return False
return True
def _layout_icon(self, icon):
while True:
x = random.random() * self._width
y = random.random() * self._height
if self._is_valid_position(icon, x, y):
break
icon.props.x = x
icon.props.y = y
+10
View File
@@ -0,0 +1,10 @@
sugardir = $(pkgdatadir)/shell/view/home
sugar_PYTHON = \
__init__.py \
DonutItem.py \
FriendsGroup.py \
IconLayout.py \
HomeGroup.py \
HomeWindow.py \
MeshGroup.py \
MyIcon.py
+82
View File
@@ -0,0 +1,82 @@
import random
import goocanvas
import conf
from sugar.canvas.IconItem import IconItem
from sugar.canvas.IconItem import IconColor
from sugar.presence import PresenceService
from view.home.IconLayout import IconLayout
class ActivityItem(IconItem):
def __init__(self, activity, service):
self._service = service
self._activity = activity
IconItem.__init__(self, icon_name=self.get_icon_name(),
color=self.get_color(), size=96)
def get_id(self):
return self._activity.get_id()
def get_icon_name(self):
registry = conf.get_activity_registry()
info = registry.get_activity_from_type(self._service.get_type())
return info.get_icon()
def get_color(self):
return IconColor(self._activity.get_color())
def get_service(self):
return self._service
class MeshGroup(goocanvas.Group):
def __init__(self):
goocanvas.Group.__init__(self)
self._icon_layout = IconLayout(1200, 900)
self._activities = {}
self._pservice = PresenceService.get_instance()
self._pservice.connect("service-appeared", self._service_appeared_cb)
self._pservice.connect('activity-disappeared', self._activity_disappeared_cb)
for service in self._pservice.get_services():
self._check_service(service)
def _service_appeared_cb(self, pservice, service):
self._check_service(service)
def _check_service(self, service):
registry = conf.get_activity_registry()
if registry.get_activity_from_type(service.get_type()) != None:
activity_id = service.get_activity_id()
if not self.has_activity(activity_id):
activity = self._pservice.get_activity(activity_id)
if activity != None:
self.add_activity(activity, service)
def has_activity(self, activity_id):
return self._activities.has_key(activity_id)
def add_activity(self, activity, service):
item = ActivityItem(activity, service)
item.connect('clicked', self._activity_clicked_cb)
self._icon_layout.add_icon(item)
self.add_child(item)
self._activities[item.get_id()] = item
def _activity_disappeared_cb(self, pservice, activity):
if self._activities.has_key(activity.get_id()):
self.remove_child(self._activities[activity.get_id()])
del self._activities[activity.get_id()]
def _activity_clicked_cb(self, item):
default_type = item.get_service().get_type()
registry = conf.get_activity_registry()
bundle_id = registry.get_activity_from_type(default_type).get_id()
activity_id = item.get_id()
self._shell.join_activity(bundle_id, activity_id)
+10
View File
@@ -0,0 +1,10 @@
import conf
from sugar.canvas.IconItem import IconItem
from sugar.canvas.IconColor import IconColor
class MyIcon(IconItem):
def __init__(self, size):
profile = conf.get_profile()
IconItem.__init__(self, icon_name='stock-buddy',
color=profile.get_color(), size=size)
View File