Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dcbw@localhost.localdomain>2006-09-15 20:50:06 (GMT)
committer Dan Williams <dcbw@localhost.localdomain>2006-09-15 20:50:06 (GMT)
commit922b7238b9db8307f6b9df9b3a4e36f9a46e81a0 (patch)
tree90aa62656494be7b5740c43549adbbcfaab49ac8
parentb39eff33655590565aaac3d514df640f1ad3f2a8 (diff)
parente79a5f5e989fa062366295c3f236692fc3c889e5 (diff)
Merge
-rw-r--r--.gitignore2
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac9
-rw-r--r--services/Makefile.am1
-rw-r--r--services/presence/Activity.py (renamed from shell/PresenceService/Activity.py)0
-rw-r--r--services/presence/Buddy.py (renamed from shell/PresenceService/Buddy.py)0
-rw-r--r--services/presence/Makefile.am (renamed from shell/PresenceService/Makefile.am)6
-rw-r--r--services/presence/PresenceService.py (renamed from shell/PresenceService/PresenceService.py)0
-rw-r--r--services/presence/Service.py (renamed from shell/PresenceService/Service.py)0
-rw-r--r--services/presence/__init__.py (copied from shell/PresenceService/__init__.py)0
-rw-r--r--services/presence/org.laptop.Presence.service.in (renamed from shell/PresenceService/org.laptop.Presence.service.in)0
-rwxr-xr-xservices/presence/sugar-presence-service (renamed from shell/sugar-presence-service)2
-rw-r--r--shell/ChatController.py54
-rw-r--r--shell/Makefile.am14
-rw-r--r--shell/Session.py13
-rwxr-xr-xshell/Shell.py174
-rw-r--r--shell/home/FriendsGroup.py84
-rw-r--r--shell/model/BuddyInfo.py24
-rw-r--r--shell/model/Friends.py (renamed from shell/Friends.py)51
-rw-r--r--shell/model/Invites.py (renamed from shell/Invites.py)0
-rw-r--r--shell/model/Makefile.am8
-rw-r--r--shell/model/Owner.py (renamed from shell/Owner.py)8
-rw-r--r--shell/model/ShellModel.py64
-rw-r--r--shell/model/__init__.py (renamed from shell/frame/__init__.py)0
-rw-r--r--shell/view/ActivityHost.py (renamed from shell/ActivityHost.py)3
-rw-r--r--shell/view/BuddyIcon.py108
-rw-r--r--shell/view/BuddyPopup.py (renamed from shell/FriendPopup.py)67
-rw-r--r--shell/view/ConsoleWindow.py (renamed from shell/ConsoleWindow.py)0
-rw-r--r--shell/view/FirstTimeDialog.py (renamed from shell/FirstTimeDialog.py)0
-rw-r--r--shell/view/Makefile.am11
-rw-r--r--shell/view/Shell.py102
-rw-r--r--shell/view/__init__.py (renamed from shell/home/__init__.py)0
-rw-r--r--shell/view/frame/BottomPanel.py (renamed from shell/frame/BottomPanel.py)12
-rw-r--r--shell/view/frame/Frame.py (renamed from shell/frame/Frame.py)18
-rw-r--r--shell/view/frame/Makefile.am (renamed from shell/frame/Makefile.am)2
-rw-r--r--shell/view/frame/PanelWindow.py (renamed from shell/frame/PanelWindow.py)0
-rw-r--r--shell/view/frame/RightPanel.py (renamed from shell/frame/RightPanel.py)21
-rw-r--r--shell/view/frame/TopPanel.py (renamed from shell/frame/TopPanel.py)12
-rw-r--r--shell/view/frame/__init__.py (copied from shell/PresenceService/__init__.py)0
-rw-r--r--shell/view/home/DonutItem.py (renamed from shell/home/DonutItem.py)0
-rw-r--r--shell/view/home/FriendsGroup.py42
-rw-r--r--shell/view/home/HomeGroup.py (renamed from shell/home/HomeGroup.py)14
-rw-r--r--shell/view/home/HomeWindow.py (renamed from shell/home/HomeWindow.py)15
-rw-r--r--shell/view/home/IconLayout.py (renamed from shell/home/IconLayout.py)0
-rw-r--r--shell/view/home/Makefile.am (renamed from shell/home/Makefile.am)2
-rw-r--r--shell/view/home/MeshGroup.py (renamed from shell/home/MeshGroup.py)4
-rw-r--r--shell/view/home/MyIcon.py (renamed from shell/home/MyIcon.py)0
-rw-r--r--shell/view/home/__init__.py (renamed from shell/PresenceService/__init__.py)0
-rw-r--r--sugar/__installed__.py.in3
-rw-r--r--sugar/__uninstalled__.py.in2
-rw-r--r--sugar/canvas/Grid.py6
-rw-r--r--sugar/canvas/IconColor.py8
-rw-r--r--sugar/canvas/IconItem.py31
-rw-r--r--sugar/env.py3
54 files changed, 519 insertions, 483 deletions
diff --git a/.gitignore b/.gitignore
index d0ca239..ffd6362 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,7 +38,7 @@ po/*.gmo
sugar/__installed__.py
sugar/__uninstalled__.py
tools/sugar-setup-activity
-shell/PresenceService/org.laptop.Presence.service
+services/presence/org.laptop.Presence.service
threadframe
config.guess
config.sub
diff --git a/Makefile.am b/Makefile.am
index 72ff820..323f1f4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = activities bindings po shell sugar tools
+SUBDIRS = activities bindings po shell sugar services tools
ACLOCAL_AMFLAGS = -I m4
diff --git a/configure.ac b/configure.ac
index 842a113..a81c6d5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -45,12 +45,15 @@ activities/terminal/Makefile
bindings/Makefile
bindings/globalkeys/Makefile
bindings/threadframe/Makefile
+services/Makefile
+services/presence/Makefile
shell/Makefile
shell/conf/Makefile
shell/data/Makefile
-shell/home/Makefile
-shell/frame/Makefile
-shell/PresenceService/Makefile
+shell/view/Makefile
+shell/view/home/Makefile
+shell/view/frame/Makefile
+shell/model/Makefile
sugar/Makefile
sugar/__installed__.py
sugar/__uninstalled__.py
diff --git a/services/Makefile.am b/services/Makefile.am
new file mode 100644
index 0000000..da40441
--- /dev/null
+++ b/services/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = presence
diff --git a/shell/PresenceService/Activity.py b/services/presence/Activity.py
index 6dc9497..6dc9497 100644
--- a/shell/PresenceService/Activity.py
+++ b/services/presence/Activity.py
diff --git a/shell/PresenceService/Buddy.py b/services/presence/Buddy.py
index 5d13c29..5d13c29 100644
--- a/shell/PresenceService/Buddy.py
+++ b/services/presence/Buddy.py
diff --git a/shell/PresenceService/Makefile.am b/services/presence/Makefile.am
index 1710d54..c095cb6 100644
--- a/shell/PresenceService/Makefile.am
+++ b/services/presence/Makefile.am
@@ -5,7 +5,7 @@ service_DATA = $(service_in_files:.service.in=.service)
$(service_DATA): $(service_in_files) Makefile
@sed -e "s|\@bindir\@|$(bindir)|" $< > $@
-sugardir = $(pkgdatadir)/shell/PresenceService
+sugardir = $(pkgdatadir)/services/presence
sugar_PYTHON = \
__init__.py \
Activity.py \
@@ -13,6 +13,8 @@ sugar_PYTHON = \
PresenceService.py \
Service.py
+bin_SCRIPTS = sugar-presence-service
+
DISTCLEANFILES = $(service_DATA)
-EXTRA_DIST = $(service_in_files)
+EXTRA_DIST = $(service_in_files) $(bin_SCRIPTS)
diff --git a/shell/PresenceService/PresenceService.py b/services/presence/PresenceService.py
index c04084c..c04084c 100644
--- a/shell/PresenceService/PresenceService.py
+++ b/services/presence/PresenceService.py
diff --git a/shell/PresenceService/Service.py b/services/presence/Service.py
index 0c23600..0c23600 100644
--- a/shell/PresenceService/Service.py
+++ b/services/presence/Service.py
diff --git a/shell/PresenceService/__init__.py b/services/presence/__init__.py
index e69de29..e69de29 100644
--- a/shell/PresenceService/__init__.py
+++ b/services/presence/__init__.py
diff --git a/shell/PresenceService/org.laptop.Presence.service.in b/services/presence/org.laptop.Presence.service.in
index 3739d9e..3739d9e 100644
--- a/shell/PresenceService/org.laptop.Presence.service.in
+++ b/services/presence/org.laptop.Presence.service.in
diff --git a/shell/sugar-presence-service b/services/presence/sugar-presence-service
index fda0d12..88fd2e7 100755
--- a/shell/sugar-presence-service
+++ b/services/presence/sugar-presence-service
@@ -1,7 +1,7 @@
#!/usr/bin/python
import logging
-from PresenceService import PresenceService
+from presence import PresenceService
import sugar.logger
sugar.logger.start('PresenceService')
diff --git a/shell/ChatController.py b/shell/ChatController.py
deleted file mode 100644
index 022d608..0000000
--- a/shell/ChatController.py
+++ /dev/null
@@ -1,54 +0,0 @@
-import conf
-from sugar.chat.BuddyChat import BuddyChat
-from sugar.activity import ActivityFactory
-from sugar.presence import PresenceService
-from sugar.p2p.Stream import Stream
-from sugar.chat.Chat import Chat
-
-class ChatController:
- def __init__(self, shell):
- self._shell = shell
- self._id_to_name = {}
- self._name_to_chat = {}
-
- self._shell.connect('activity-closed', self.__activity_closed_cb)
-
- def __activity_closed_cb(self, shell, activity):
- activity_id = activity.get_id()
- if self._id_to_name.has_key(activity_id):
- name = self._id_to_name[activity_id]
- del self._name_to_chat[name]
- del self._id_to_name[activity_id]
-
- def listen(self):
- self._pservice = PresenceService.get_instance()
-
- self._pservice.register_service_type(BuddyChat.SERVICE_TYPE)
- profile = conf.get_profile()
- self._service = self._pservice.register_service(profile.get_nick_name(),
- BuddyChat.SERVICE_TYPE)
-
- self._buddy_stream = Stream.new_from_service(self._service)
- self._buddy_stream.set_data_listener(self._recv_message)
-
- def open_chat_activity(self, buddy):
- service = buddy.get_service_of_type(BuddyChat.SERVICE_TYPE)
- if service:
- activity = self._shell.start_activity('com.redhat.Sugar.ChatActivity')
- activity.execute('connect', [service.object_path()])
- self._name_to_chat[buddy.get_name()] = activity
- self._id_to_name[activity.get_id()] = buddy.get_name()
-
- def _get_chat_activity(self, buddy):
- nick = buddy.get_name()
- if not self._name_to_chat.has_key(nick):
- self.open_chat_activity(buddy)
- return self._name_to_chat[nick]
-
- def _recv_message(self, address, message):
- [nick, msg] = Chat.deserialize_message(message)
- buddy = self._pservice.get_buddy_by_name(nick)
- if buddy:
- activity = self._get_chat_activity(buddy)
- if activity:
- activity.execute('message', [message])
diff --git a/shell/Makefile.am b/shell/Makefile.am
index 4a1d49b..a4fd719 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -1,24 +1,14 @@
-SUBDIRS = conf data frame home PresenceService
+SUBDIRS = conf data model view
bin_SCRIPTS = \
sugar \
sugar-activity \
sugar-activity-factory \
- sugar-console \
- sugar-presence-service
+ sugar-console
sugardir = $(pkgdatadir)/shell
sugar_PYTHON = \
__init__.py \
- ActivityHost.py \
- ChatController.py \
- ConsoleWindow.py \
- FirstTimeDialog.py \
- FriendPopup.py \
- Friends.py \
- Invites.py \
- Owner.py \
- Shell.py \
Session.py
EXTRA_DIST = $(bin_SCRIPTS)
diff --git a/shell/Session.py b/shell/Session.py
index 07337d6..da17cd7 100644
--- a/shell/Session.py
+++ b/shell/Session.py
@@ -1,8 +1,8 @@
import os
import gtk
-from Shell import Shell
-from ConsoleWindow import ConsoleWindow
+from view.Shell import Shell
+from model.ShellModel import ShellModel
from sugar import env
from sugar import logger
@@ -10,7 +10,7 @@ from sugar.session.Process import Process
from sugar.session.DbusProcess import DbusProcess
from sugar.session.MatchboxProcess import MatchboxProcess
-from FirstTimeDialog import FirstTimeDialog
+from view.FirstTimeDialog import FirstTimeDialog
import conf
class DBusMonitorProcess(Process):
@@ -47,11 +47,8 @@ class Session:
dbm = DBusMonitorProcess()
dbm.start()
- console = ConsoleWindow()
- logger.start('Shell', console)
-
- shell = Shell()
- shell.set_console(console)
+ model = ShellModel()
+ shell = Shell(model)
from sugar import TracebackUtils
tbh = TracebackUtils.TracebackHelper()
diff --git a/shell/Shell.py b/shell/Shell.py
deleted file mode 100755
index 277e2f9..0000000
--- a/shell/Shell.py
+++ /dev/null
@@ -1,174 +0,0 @@
-import os
-import logging
-
-import dbus
-import dbus.glib
-import gtk
-import gobject
-import wnck
-
-from home.HomeWindow import HomeWindow
-from Owner import ShellOwner
-from sugar.presence import PresenceService
-from ActivityHost import ActivityHost
-from ChatController import ChatController
-from sugar.activity import ActivityFactory
-from sugar.activity import Activity
-from frame.Frame import Frame
-from globalkeys import KeyGrabber
-import conf
-import sugar
-
-class ShellDbusService(dbus.service.Object):
- def __init__(self, shell, bus_name):
- dbus.service.Object.__init__(self, bus_name, '/com/redhat/Sugar/Shell')
- self._shell = shell
-
- def __show_console_idle(self):
- self._shell.show_console()
-
- @dbus.service.method('com.redhat.Sugar.Shell')
- def show_console(self):
- gobject.idle_add(self.__show_console_idle)
-
-class Shell(gobject.GObject):
- __gsignals__ = {
- 'activity-opened': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])),
- 'activity-changed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])),
- 'activity-closed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT]))
- }
-
- def __init__(self):
- gobject.GObject.__init__(self)
-
- self._screen = wnck.screen_get_default()
- self._hosts = {}
- self._current_window = None
-
- 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)
- 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)
-
- session_bus = dbus.SessionBus()
- bus_name = dbus.service.BusName('com.redhat.Sugar.Shell', bus=session_bus)
- ShellDbusService(self, bus_name)
-
- PresenceService.start()
- self._pservice = PresenceService.get_instance()
-
- self._owner = ShellOwner(self)
- self._owner.announce()
-
- self._home_window.set_owner(self._owner)
-
- self._chat_controller = ChatController(self)
- self._chat_controller.listen()
-
- self._frame = Frame(self, self._owner)
- 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':
- ActivityFactory.create('org.sugar.Terminal')
-
- def set_console(self, console):
- self._console = console
-
- def __window_opened_cb(self, screen, window):
- if window.get_window_type() == wnck.WINDOW_NORMAL:
- host = ActivityHost(self, window)
- self._hosts[window.get_xid()] = host
- self.emit('activity-opened', host)
-
- def __active_window_changed_cb(self, screen):
- window = screen.get_active_window()
- if window and window.get_window_type() == wnck.WINDOW_NORMAL:
- if self._current_window != window:
- self._current_window = window
- self.emit('activity-changed', self.get_current_activity())
-
- def __window_closed_cb(self, screen, window):
- if window.get_window_type() == wnck.WINDOW_NORMAL:
- xid = window.get_xid()
- if self._hosts.has_key(xid):
- host = self._hosts[xid]
- self.emit('activity-closed', host)
-
- del self._hosts[xid]
-
- def get_activity(self, activity_id):
- for host in self._hosts.values():
- if host.get_id() == activity_id:
- return host
- return None
-
- def get_current_activity(self):
- if self._current_window != None:
- xid = self._current_window.get_xid()
- return self._hosts[xid]
- else:
- return None
-
- def show_console(self):
- self._console.show()
-
- activity = self.get_current_activity()
- if activity:
- registry = conf.get_activity_registry()
- module = registry.get_activity(activity.get_type())
- self._console.set_page(module.get_id())
-
- def join_activity(self, bundle_id, activity_id):
- activity = self.get_activity(activity_id)
- if activity:
- activity.present()
- else:
- activity_ps = self._pservice.get_activity(activity_id)
-
- if activity_ps:
- activity = ActivityFactory.create(bundle_id)
- activity.join(activity_ps.object_path())
- else:
- logging.error('Cannot start activity.')
-
- def start_activity(self, activity_type):
- activity = ActivityFactory.create(activity_type)
- activity.execute('test', [])
- return activity
-
- def get_chat_controller(self):
- return self._chat_controller
-
- 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)
diff --git a/shell/home/FriendsGroup.py b/shell/home/FriendsGroup.py
deleted file mode 100644
index 605070b..0000000
--- a/shell/home/FriendsGroup.py
+++ /dev/null
@@ -1,84 +0,0 @@
-import random
-
-import goocanvas
-
-from sugar.canvas.IconItem import IconItem
-from home.IconLayout import IconLayout
-from home.MyIcon import MyIcon
-from FriendPopup import FriendPopup
-from sugar.canvas.Grid import Grid
-
-class FriendIcon(IconItem):
- def __init__(self, shell, friend):
- IconItem.__init__(self, icon_name='stock-buddy',
- color=friend.get_color(), size=96)
-
- self._shell = shell
- self._friend = friend
- self._popup = None
-
- self.connect('popup', self._popup_cb)
- self.connect('popdown', self._popdown_cb)
-
- def get_friend(self):
- return self._friend
-
- def _popup_cb(self, icon, x1, y1, x2, y2):
- grid = Grid()
-
- if not self._popup:
- self._popup = FriendPopup(self._shell, grid, icon.get_friend())
-
- [grid_x1, grid_y1] = grid.convert_from_screen(x1, y1)
- [grid_x2, grid_y2] = grid.convert_from_screen(x2, y2)
-
- if grid_x2 + self._popup.get_width() + 1 > Grid.ROWS:
- grid_x = grid_x1 - self._popup.get_width() + 1
- else:
- grid_x = grid_x2 - 1
-
- 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()
-
- def _popup_destroy_cb(self, popup):
- self._popup = None
-
- def _popdown_cb(self, friend):
- if self._popup:
- self._popup.connect('destroy', self._popup_destroy_cb)
- self._popup.popdown()
-
-class FriendsGroup(goocanvas.Group):
- def __init__(self, shell, friends):
- goocanvas.Group.__init__(self)
-
- self._shell = shell
- self._icon_layout = IconLayout(1200, 900)
- self._friends = 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)
-
- friends.connect('friend-added', self._friend_added_cb)
-
- def add_friend(self, friend):
- icon = FriendIcon(self._shell, friend)
- self.add_child(icon)
- self._icon_layout.add_icon(icon)
-
- def _friend_added_cb(self, data_model, friend):
- self.add_friend(friend)
diff --git a/shell/model/BuddyInfo.py b/shell/model/BuddyInfo.py
new file mode 100644
index 0000000..68f0a44
--- /dev/null
+++ b/shell/model/BuddyInfo.py
@@ -0,0 +1,24 @@
+from sugar.presence import PresenceService
+from sugar.canvas.IconColor import IconColor
+
+class BuddyInfo:
+ def __init__(self, buddy=None):
+ if buddy:
+ self.set_name(buddy.get_name())
+ self.set_color(buddy.get_color())
+
+ def set_name(self, name):
+ self._name = name
+
+ def set_color(self, color_string):
+ self._color = IconColor(color_string)
+
+ def get_name(self):
+ return self._name
+
+ def get_color(self):
+ return self._color
+
+ def get_buddy(self):
+ pservice = PresenceService.get_instance()
+ return pservice.get_buddy_by_name(self._name)
diff --git a/shell/Friends.py b/shell/model/Friends.py
index 6beca66..a11acc0 100644
--- a/shell/Friends.py
+++ b/shell/model/Friends.py
@@ -3,67 +3,54 @@ from ConfigParser import ConfigParser
import gobject
-from sugar.canvas.IconColor import IconColor
-from sugar.presence import PresenceService
+from model.BuddyInfo import BuddyInfo
from sugar import env
-class Friend:
- def __init__(self, name, color):
- self._name = name
- self._color = color
-
- def get_name(self):
- return self._name
-
- def get_color(self):
- return IconColor(self._color)
-
- def get_buddy(self):
- pservice = PresenceService.get_instance()
- return pservice.get_buddy_by_name(self._name)
-
class Friends(gobject.GObject):
__gsignals__ = {
'friend-added': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([object])),
'friend-removed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE, ([object])),
+ gobject.TYPE_NONE, ([str])),
}
def __init__(self):
gobject.GObject.__init__(self)
- self._list = []
+ self._friends = {}
self._path = os.path.join(env.get_profile_path(), 'friends')
self.load()
def has_buddy(self, buddy):
- for friend in self:
- if friend.get_name() == buddy.get_name():
- return True
- return False
+ return self._friends.has_key(buddy.get_name())
- def add_friend(self, name, color):
- friend = Friend(name, color)
- self._list.append(friend)
+ def add_friend(self, buddy_info):
+ self._friends[buddy_info.get_name()] = buddy_info
+ self.emit('friend-added', buddy_info)
- self.emit('friend-added', friend)
-
- def add_buddy(self, buddy):
+ def make_friend(self, buddy):
if not self.has_buddy(buddy):
- self.add_friend(buddy.get_name(), buddy.get_color())
+ self.add_friend(BuddyInfo(buddy))
self.save()
+ def remove(self, buddy_info):
+ del self._friends[buddy_info.get_name()]
+ self.save()
+ self.emit('friend-removed', buddy_info.get_name())
+
def __iter__(self):
- return self._list.__iter__()
+ return self._friends.values().__iter__()
def load(self):
cp = ConfigParser()
if cp.read([self._path]):
for name in cp.sections():
- self.add_friend(name, cp.get(name, 'color'))
+ buddy = BuddyInfo()
+ buddy.set_name(name)
+ buddy.set_color(cp.get(name, 'color'))
+ self.add_friend(buddy)
def save(self):
cp = ConfigParser()
diff --git a/shell/Invites.py b/shell/model/Invites.py
index 24f9913..24f9913 100644
--- a/shell/Invites.py
+++ b/shell/model/Invites.py
diff --git a/shell/model/Makefile.am b/shell/model/Makefile.am
new file mode 100644
index 0000000..ce24668
--- /dev/null
+++ b/shell/model/Makefile.am
@@ -0,0 +1,8 @@
+sugardir = $(pkgdatadir)/shell/model
+sugar_PYTHON = \
+ __init__.py \
+ BuddyInfo.py \
+ Friends.py \
+ Invites.py \
+ Owner.py \
+ ShellModel.py
diff --git a/shell/Owner.py b/shell/model/Owner.py
index b4781f9..24004f0 100644
--- a/shell/Owner.py
+++ b/shell/model/Owner.py
@@ -8,8 +8,7 @@ from sugar import env
import logging
from sugar.p2p import Stream
from sugar.presence import PresenceService
-from Friends import Friends
-from Invites import Invites
+from model.Invites import Invites
PRESENCE_SERVICE_TYPE = "_presence_olpc._tcp"
@@ -33,7 +32,7 @@ class ShellOwner(object):
break
self._pservice = PresenceService.get_instance()
- self._friends = Friends()
+
self._invites = Invites()
self._shell = shell
@@ -42,9 +41,6 @@ class ShellOwner(object):
self._pending_activity_update_timer = None
self._pending_activity_update = None
- def get_friends(self):
- return self._friends
-
def get_invites(self):
return self._invites
diff --git a/shell/model/ShellModel.py b/shell/model/ShellModel.py
new file mode 100644
index 0000000..0820b44
--- /dev/null
+++ b/shell/model/ShellModel.py
@@ -0,0 +1,64 @@
+import gobject
+
+from sugar.presence import PresenceService
+from model.Friends import Friends
+from model.Owner import ShellOwner
+
+class ShellModel(gobject.GObject):
+ __gsignals__ = {
+ 'activity-opened': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])),
+ 'activity-changed': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])),
+ 'activity-closed': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT]))
+ }
+
+ def __init__(self):
+ gobject.GObject.__init__(self)
+
+ self._hosts = {}
+ self._current_activity = None
+
+ PresenceService.start()
+ self._pservice = PresenceService.get_instance()
+
+ self._owner = ShellOwner(self)
+ self._owner.announce()
+ self._friends = Friends()
+
+ def get_friends(self):
+ return self._friends
+
+ def get_invites(self):
+ return self._owner.get_invites()
+
+ def get_owner(self):
+ return self._owner
+
+ def add_activity(self, activity_host):
+ self._hosts[activity_host.get_xid()] = activity_host
+ self.emit('activity-opened', activity_host)
+
+ def set_current_activity(self, activity_xid):
+ activity_host = self._hosts[activity_xid]
+ if self._current_activity == activity_host:
+ return
+
+ self._current_activity = activity_host
+ self.emit('activity-changed', activity_host)
+
+ def remove_activity(self, activity_xid):
+ if self._hosts.has_key(activity_xid):
+ host = self._hosts[activity_xid]
+ self.emit('activity-closed', host)
+ del self._hosts[activity_xid]
+
+ def get_activity(self, activity_id):
+ for host in self._hosts.values():
+ if host.get_id() == activity_id:
+ return host
+ return None
+
+ def get_current_activity(self):
+ return self._current_activity
diff --git a/shell/frame/__init__.py b/shell/model/__init__.py
index e69de29..e69de29 100644
--- a/shell/frame/__init__.py
+++ b/shell/model/__init__.py
diff --git a/shell/ActivityHost.py b/shell/view/ActivityHost.py
index b3703e7..456406b 100644
--- a/shell/ActivityHost.py
+++ b/shell/view/ActivityHost.py
@@ -31,6 +31,9 @@ class ActivityHost:
def get_id(self):
return self._id
+ def get_xid(self):
+ return self._xid
+
def get_icon_name(self):
return self._icon_name
diff --git a/shell/view/BuddyIcon.py b/shell/view/BuddyIcon.py
new file mode 100644
index 0000000..3e26b08
--- /dev/null
+++ b/shell/view/BuddyIcon.py
@@ -0,0 +1,108 @@
+from sugar.canvas.IconItem import IconItem
+from sugar.canvas.Grid import Grid
+from view.BuddyPopup import BuddyPopup
+
+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 BuddyIcon(IconItem):
+ _popup_shell = _PopupShell()
+
+ def __init__(self, shell, friend):
+ IconItem.__init__(self, icon_name='stock-buddy',
+ color=friend.get_color(), size=96)
+
+ self._shell = shell
+ 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()
+
+ BuddyIcon._popup_shell.set_active(None)
+
+ grid = self._shell.get_grid()
+ self._popup = BuddyPopup(self._shell, 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()
+
+ BuddyIcon._popup_shell.set_active(self)
+
+ def _popup_action_cb(self, popup, action):
+ self._popdown()
+
+ buddy = self._friend.get_buddy()
+ if buddy == None:
+ return
+
+ model = self._shell.get_model()
+ if action == BuddyPopup.ACTION_INVITE:
+ activity = model.get_current_activity()
+ activity.invite(buddy)
+ elif action == BuddyPopup.ACTION_MAKE_FRIEND:
+ friends = model.get_friends()
+ friends.make_friend(buddy)
+ elif action == BuddyPopup.ACTION_REMOVE_FRIEND:
+ friends = model.get_friends()
+ friends.remove(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()
diff --git a/shell/FriendPopup.py b/shell/view/BuddyPopup.py
index 1d309a6..4aab3f6 100644
--- a/shell/FriendPopup.py
+++ b/shell/view/BuddyPopup.py
@@ -1,21 +1,32 @@
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):
- def __init__(self, shell, grid, friend):
+class BuddyPopup(gtk.Window):
+ ACTION_MAKE_FRIEND = 0
+ ACTION_INVITE = 1
+ ACTION_REMOVE_FRIEND = 2
+
+ __gsignals__ = {
+ 'action': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, ([int])),
+ }
+
+ def __init__(self, shell, buddy):
gtk.Window.__init__(self, gtk.WINDOW_POPUP)
- self._shell = shell
- self._friend = friend
+ self._buddy = buddy
self._hover = False
self._popdown_on_leave = False
self._width = 13
self._height = 10
+ grid = shell.get_grid()
+
canvas = CanvasView()
self.add(canvas)
canvas.show()
@@ -25,14 +36,14 @@ class FriendPopup(gtk.Window):
model = goocanvas.CanvasModelSimple()
root = model.get_root_item()
- color = friend.get_color()
+ color = buddy.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",
+ text = goocanvas.Text(text=buddy.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)
@@ -45,8 +56,16 @@ class FriendPopup(gtk.Window):
box = CanvasBox(grid, CanvasBox.HORIZONTAL, 1)
grid.set_constraints(box, 0, 5)
- icon = IconItem(icon_name='stock-make-friend')
- icon.connect('clicked', self._make_friend_clicked_cb)
+ friends = shell.get_model().get_friends()
+ if friends.has_buddy(buddy):
+ icon = IconItem(icon_name='stock-remove-friend')
+ icon.connect('clicked', self._action_clicked_cb,
+ BuddyPopup.ACTION_REMOVE_FRIEND)
+ else:
+ icon = IconItem(icon_name='stock-make-friend')
+ icon.connect('clicked', self._action_clicked_cb,
+ BuddyPopup.ACTION_MAKE_FRIEND)
+
box.set_constraints(icon, 3, 3)
box.add_child(icon)
@@ -55,7 +74,8 @@ class FriendPopup(gtk.Window):
box.add_child(icon)
icon = IconItem(icon_name='stock-invite')
- icon.connect('clicked', self._invite_clicked_cb)
+ icon.connect('clicked', self._action_clicked_cb,
+ BuddyPopup.ACTION_INVITE)
box.set_constraints(icon, 3, 3)
box.add_child(icon)
@@ -63,33 +83,8 @@ class FriendPopup(gtk.Window):
canvas.set_model(model)
- self.connect('enter-notify-event', self._enter_notify_event_cb)
- self.connect('leave-notify-event', self._leave_notify_event_cb)
-
- def _invite_clicked_cb(self, icon):
- activity = self._shell.get_current_activity()
- buddy = self._friend.get_buddy()
- if buddy != None:
- activity.invite(buddy)
- else:
- print 'Friend not online'
-
- def _make_friend_clicked_cb(self, icon):
- pass
-
- def _enter_notify_event_cb(self, widget, event):
- self._hover = True
-
- def _leave_notify_event_cb(self, widget, event):
- self._hover = False
- if self._popdown_on_leave:
- self.popdown()
-
- def popdown(self):
- if not self._hover:
- self.destroy()
- else:
- self._popdown_on_leave = True
+ def _action_clicked_cb(self, icon, action):
+ self.emit('action', action)
def get_width(self):
return self._width
diff --git a/shell/ConsoleWindow.py b/shell/view/ConsoleWindow.py
index 4cdbbb1..4cdbbb1 100644
--- a/shell/ConsoleWindow.py
+++ b/shell/view/ConsoleWindow.py
diff --git a/shell/FirstTimeDialog.py b/shell/view/FirstTimeDialog.py
index abf6bd8..abf6bd8 100644
--- a/shell/FirstTimeDialog.py
+++ b/shell/view/FirstTimeDialog.py
diff --git a/shell/view/Makefile.am b/shell/view/Makefile.am
new file mode 100644
index 0000000..4b1c901
--- /dev/null
+++ b/shell/view/Makefile.am
@@ -0,0 +1,11 @@
+SUBDIRS = frame home
+
+sugardir = $(pkgdatadir)/shell/view
+sugar_PYTHON = \
+ __init__.py \
+ ActivityHost.py \
+ ConsoleWindow.py \
+ FirstTimeDialog.py \
+ BuddyIcon.py \
+ BuddyPopup.py \
+ Shell.py
diff --git a/shell/view/Shell.py b/shell/view/Shell.py
new file mode 100644
index 0000000..76d3f26
--- /dev/null
+++ b/shell/view/Shell.py
@@ -0,0 +1,102 @@
+import gtk
+import gobject
+import wnck
+
+from sugar.canvas.Grid import Grid
+from view.home.HomeWindow import HomeWindow
+from sugar.presence import PresenceService
+from view.ActivityHost import ActivityHost
+from sugar.activity import ActivityFactory
+from sugar.activity import Activity
+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._grid = Grid()
+
+ 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)
+ 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 get_grid(self):
+ return self._grid
+
+ def join_activity(self, bundle_id, activity_id):
+ pservice = PresenceService.get_instance()
+
+ activity = self._model.get_activity(activity_id)
+ if activity:
+ activity.present()
+ else:
+ activity_ps = pservice.get_activity(activity_id)
+
+ if activity_ps:
+ activity = ActivityFactory.create(bundle_id)
+ activity.join(activity_ps.object_path())
+ else:
+ logging.error('Cannot start activity.')
+
+ def start_activity(self, activity_type):
+ activity = ActivityFactory.create(activity_type)
+ activity.execute('test', [])
+ return activity
+
+ 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)
diff --git a/shell/home/__init__.py b/shell/view/__init__.py
index e69de29..e69de29 100644
--- a/shell/home/__init__.py
+++ b/shell/view/__init__.py
diff --git a/shell/frame/BottomPanel.py b/shell/view/frame/BottomPanel.py
index 2da51e7..5f98f01 100644
--- a/shell/frame/BottomPanel.py
+++ b/shell/view/frame/BottomPanel.py
@@ -33,22 +33,22 @@ class InviteItem(IconItem):
return self._invite
class BottomPanel(CanvasBox):
- def __init__(self, grid, shell, invites):
- CanvasBox.__init__(self, grid, CanvasBox.HORIZONTAL, 1)
+ def __init__(self, shell):
+ CanvasBox.__init__(self, shell.get_grid(), CanvasBox.HORIZONTAL, 1)
self._shell = shell
self._invite_to_item = {}
- self._invites = invites
+ self._invites = self._shell.get_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 invites:
+ for invite in self._invites:
self.add_invite(invite)
- invites.connect('invite-added', self.__invite_added_cb)
- invites.connect('invite-removed', self.__invite_removed_cb)
+ 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.start_activity(icon.get_bundle_id())
diff --git a/shell/frame/Frame.py b/shell/view/frame/Frame.py
index 1da50f0..9967a50 100644
--- a/shell/frame/Frame.py
+++ b/shell/view/frame/Frame.py
@@ -2,39 +2,39 @@ import gtk
import gobject
import goocanvas
-from frame.BottomPanel import BottomPanel
-from frame.RightPanel import RightPanel
-from frame.TopPanel import TopPanel
-from frame.PanelWindow import PanelWindow
+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, owner):
+ def __init__(self, shell):
self._windows = []
model = goocanvas.CanvasModelSimple()
root = model.get_root_item()
- grid = Grid()
+ grid = shell.get_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, owner.get_invites())
+ panel = BottomPanel(shell)
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)
+ panel = TopPanel(shell)
root.add_child(panel)
panel_window = PanelWindow(grid, model, 0, 0, 80, 5)
self._windows.append(panel_window)
- panel = RightPanel(grid, shell, owner.get_friends())
+ panel = RightPanel(shell)
grid.set_constraints(panel, 75, 5)
root.add_child(panel)
diff --git a/shell/frame/Makefile.am b/shell/view/frame/Makefile.am
index 9f45543..a737e01 100644
--- a/shell/frame/Makefile.am
+++ b/shell/view/frame/Makefile.am
@@ -1,4 +1,4 @@
-sugardir = $(pkgdatadir)/shell/frame
+sugardir = $(pkgdatadir)/shell/view/frame
sugar_PYTHON = \
__init__.py \
RightPanel.py \
diff --git a/shell/frame/PanelWindow.py b/shell/view/frame/PanelWindow.py
index 549776f..549776f 100644
--- a/shell/frame/PanelWindow.py
+++ b/shell/view/frame/PanelWindow.py
diff --git a/shell/frame/RightPanel.py b/shell/view/frame/RightPanel.py
index 80729fd..6ed4a0d 100644
--- a/shell/frame/RightPanel.py
+++ b/shell/view/frame/RightPanel.py
@@ -4,12 +4,13 @@ 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.BuddyIcon import BuddyIcon
+from model.BuddyInfo import BuddyInfo
class RightPanel(CanvasBox):
- def __init__(self, grid, shell, friends):
- CanvasBox.__init__(self, grid, CanvasBox.VERTICAL, 1)
+ def __init__(self, shell):
+ CanvasBox.__init__(self, shell.get_grid(), CanvasBox.VERTICAL, 1)
self._shell = shell
- self._friends = friends
self._activity_ps = None
self._joined_hid = -1
self._left_hid = -1
@@ -19,14 +20,13 @@ class RightPanel(CanvasBox):
self._pservice.connect('activity-appeared',
self.__activity_appeared_cb)
- shell.connect('activity-changed', self.__activity_changed_cb)
+ shell.get_model().connect('activity-changed',
+ self.__activity_changed_cb)
def add(self, buddy):
- icon = IconItem(icon_name='stock-buddy',
- color=IconColor(buddy.get_color()))
+ icon = BuddyIcon(self._shell, BuddyInfo(buddy))
+ icon.set_popup_distance(1)
self.set_constraints(icon, 3, 3)
- icon.connect('clicked', self.__buddy_clicked_cb, buddy)
-
self.add_child(icon)
self._buddies[buddy.get_name()] = icon
@@ -41,7 +41,7 @@ class RightPanel(CanvasBox):
self._buddies = {}
def __activity_appeared_cb(self, pservice, activity_ps):
- activity = self._shell.get_current_activity()
+ activity = self._shell.get_model().get_current_activity()
if activity and activity_ps.get_id() == activity.get_id():
self._set_activity_ps(activity_ps)
@@ -78,6 +78,3 @@ class RightPanel(CanvasBox):
def __buddy_left_cb(self, activity, buddy):
self.remove(buddy)
-
- def __buddy_clicked_cb(self, icon, buddy):
- self._friends.add_buddy(buddy)
diff --git a/shell/frame/TopPanel.py b/shell/view/frame/TopPanel.py
index 14c0fb7..b1611d7 100644
--- a/shell/frame/TopPanel.py
+++ b/shell/view/frame/TopPanel.py
@@ -5,14 +5,15 @@ from sugar.canvas.IconItem import IconItem
import sugar
class TopPanel(goocanvas.Group):
- def __init__(self, grid, shell):
+ def __init__(self, shell):
goocanvas.Group.__init__(self)
- self._grid = grid
self._shell = shell
+ grid = shell.get_grid()
+
box = CanvasBox(grid, CanvasBox.HORIZONTAL, 1)
- self._grid.set_constraints(box, 5, 0)
+ grid.set_constraints(box, 5, 0)
self.add_child(box)
icon = IconItem(icon_name='stock-zoom-activity')
@@ -36,7 +37,7 @@ class TopPanel(goocanvas.Group):
box.add_child(icon)
box = CanvasBox(grid, CanvasBox.HORIZONTAL, 1)
- self._grid.set_constraints(box, 60, 0)
+ grid.set_constraints(box, 60, 0)
self.add_child(box)
icon = IconItem(icon_name='stock-share')
@@ -58,7 +59,8 @@ class TopPanel(goocanvas.Group):
self._shell.set_zoom_level(level)
def __share_clicked_cb(self, item):
- activity = self._shell.get_current_activity()
+ shell_model = self._shell.get_model()
+ activity = shell_model.get_current_activity()
if activity != None:
activity.share()
diff --git a/shell/PresenceService/__init__.py b/shell/view/frame/__init__.py
index e69de29..e69de29 100644
--- a/shell/PresenceService/__init__.py
+++ b/shell/view/frame/__init__.py
diff --git a/shell/home/DonutItem.py b/shell/view/home/DonutItem.py
index 9038523..9038523 100644
--- a/shell/home/DonutItem.py
+++ b/shell/view/home/DonutItem.py
diff --git a/shell/view/home/FriendsGroup.py b/shell/view/home/FriendsGroup.py
new file mode 100644
index 0000000..1749738
--- /dev/null
+++ b/shell/view/home/FriendsGroup.py
@@ -0,0 +1,42 @@
+import random
+
+import goocanvas
+
+from view.home.IconLayout import IconLayout
+from view.home.MyIcon import MyIcon
+from view.BuddyIcon import BuddyIcon
+
+class FriendsGroup(goocanvas.Group):
+ def __init__(self, shell):
+ goocanvas.Group.__init__(self)
+
+ self._shell = shell
+ self._icon_layout = IconLayout(1200, 900)
+ self._friends = {}
+
+ me = MyIcon(100)
+ 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()
+
+ for friend in friends:
+ self.add_friend(friend)
+
+ friends.connect('friend-added', self._friend_added_cb)
+ friends.connect('friend-removed', self._friend_removed_cb)
+
+ def add_friend(self, buddy_info):
+ icon = BuddyIcon(self._shell, buddy_info)
+ self.add_child(icon)
+ self._icon_layout.add_icon(icon)
+
+ self._friends[buddy_info.get_name()] = icon
+
+ def _friend_added_cb(self, data_model, buddy_info):
+ self.add_friend(buddy_info)
+
+ def _friend_removed_cb(self, data_model, name):
+ self.remove_child(self._friends[name])
+ del self._friends[name]
diff --git a/shell/home/HomeGroup.py b/shell/view/home/HomeGroup.py
index 0f08813..d01ba16 100644
--- a/shell/home/HomeGroup.py
+++ b/shell/view/home/HomeGroup.py
@@ -1,7 +1,7 @@
import goocanvas
-from home.DonutItem import DonutItem
-from home.MyIcon import MyIcon
+from view.home.DonutItem import DonutItem
+from view.home.MyIcon import MyIcon
class TasksItem(DonutItem):
def __init__(self, shell):
@@ -9,14 +9,14 @@ class TasksItem(DonutItem):
self._items = {}
- self._shell = shell
- self._shell.connect('activity_opened', self.__activity_opened_cb)
- self._shell.connect('activity_closed', self.__activity_closed_cb)
+ shell_model = shell.get_model()
+ shell_model.connect('activity_opened', self.__activity_opened_cb)
+ shell_model.connect('activity_closed', self.__activity_closed_cb)
- def __activity_opened_cb(self, shell, activity):
+ def __activity_opened_cb(self, model, activity):
self._add(activity)
- def __activity_closed_cb(self, shell, activity):
+ def __activity_closed_cb(self, model, activity):
self._remove(activity)
def _remove(self, activity):
diff --git a/shell/home/HomeWindow.py b/shell/view/home/HomeWindow.py
index 259ddc4..ba1129e 100644
--- a/shell/home/HomeWindow.py
+++ b/shell/view/home/HomeWindow.py
@@ -3,9 +3,9 @@ import goocanvas
import cairo
from sugar.canvas.CanvasView import CanvasView
-from home.MeshGroup import MeshGroup
-from home.HomeGroup import HomeGroup
-from home.FriendsGroup import FriendsGroup
+from view.home.MeshGroup import MeshGroup
+from view.home.HomeGroup import HomeGroup
+from view.home.FriendsGroup import FriendsGroup
import sugar
class HomeWindow(gtk.Window):
@@ -23,6 +23,10 @@ class HomeWindow(gtk.Window):
self.add(self._nb)
self._nb.show()
+ self._add_page(HomeGroup(shell))
+ self._add_page(FriendsGroup(shell))
+ self._add_page(MeshGroup(shell))
+
def _add_page(self, group):
view = CanvasView()
self._nb.append_page(view)
@@ -37,11 +41,6 @@ class HomeWindow(gtk.Window):
root.add_child(bg)
root.add_child(group)
- def set_owner(self, owner):
- self._add_page(HomeGroup(self._shell))
- self._add_page(FriendsGroup(self._shell, owner.get_friends()))
- self._add_page(MeshGroup(self._shell))
-
def set_zoom_level(self, level):
if level == sugar.ZOOM_HOME:
self._nb.set_current_page(0)
diff --git a/shell/home/IconLayout.py b/shell/view/home/IconLayout.py
index eedced8..eedced8 100644
--- a/shell/home/IconLayout.py
+++ b/shell/view/home/IconLayout.py
diff --git a/shell/home/Makefile.am b/shell/view/home/Makefile.am
index 5d5436e..ddf9653 100644
--- a/shell/home/Makefile.am
+++ b/shell/view/home/Makefile.am
@@ -1,4 +1,4 @@
-sugardir = $(pkgdatadir)/shell/home
+sugardir = $(pkgdatadir)/shell/view/home
sugar_PYTHON = \
__init__.py \
DonutItem.py \
diff --git a/shell/home/MeshGroup.py b/shell/view/home/MeshGroup.py
index f7bc1c9..6111823 100644
--- a/shell/home/MeshGroup.py
+++ b/shell/view/home/MeshGroup.py
@@ -6,7 +6,7 @@ import conf
from sugar.canvas.IconItem import IconItem
from sugar.canvas.IconItem import IconColor
from sugar.presence import PresenceService
-from home.IconLayout import IconLayout
+from view.home.IconLayout import IconLayout
class ActivityItem(IconItem):
def __init__(self, activity, service):
@@ -34,7 +34,9 @@ class ActivityItem(IconItem):
class MeshGroup(goocanvas.Group):
def __init__(self, shell):
goocanvas.Group.__init__(self)
+
self._shell = shell
+
self._icon_layout = IconLayout(1200, 900)
self._activities = {}
diff --git a/shell/home/MyIcon.py b/shell/view/home/MyIcon.py
index 226520d..226520d 100644
--- a/shell/home/MyIcon.py
+++ b/shell/view/home/MyIcon.py
diff --git a/shell/PresenceService/__init__.py b/shell/view/home/__init__.py
index e69de29..e69de29 100644
--- a/shell/PresenceService/__init__.py
+++ b/shell/view/home/__init__.py
diff --git a/sugar/__installed__.py.in b/sugar/__installed__.py.in
index 5ebed29..fd1b855 100644
--- a/sugar/__installed__.py.in
+++ b/sugar/__installed__.py.in
@@ -6,5 +6,6 @@ sugar_dbus_config = '@prefix@/share/sugar/dbus-installed.conf'
sugar_python_path = ['@prefix@/share/sugar/shell',
'@prefix@/share/sugar/bindings',
- '@prefix@/share/sugar/activities']
+ '@prefix@/share/sugar/activities',
+ '@prefix@/share/sugar/services']
sugar_bin_path = []
diff --git a/sugar/__uninstalled__.py.in b/sugar/__uninstalled__.py.in
index 860cb21..02b43f1 100644
--- a/sugar/__uninstalled__.py.in
+++ b/sugar/__uninstalled__.py.in
@@ -14,6 +14,8 @@ sugar_python_path = ['@prefix@/share/sugar/bindings']
sugar_python_path.append(sugar_source_dir)
sugar_python_path.append(os.path.join(sugar_source_dir, 'shell'))
sugar_python_path.append(os.path.join(sugar_source_dir, 'activities'))
+sugar_python_path.append(os.path.join(sugar_source_dir, 'services'))
sugar_bin_path = []
sugar_bin_path.append(os.path.join(sugar_source_dir, 'shell'))
+sugar_bin_path.append(os.path.join(sugar_source_dir, 'services/presence'))
diff --git a/sugar/canvas/Grid.py b/sugar/canvas/Grid.py
index e4c377a..50b5dbe 100644
--- a/sugar/canvas/Grid.py
+++ b/sugar/canvas/Grid.py
@@ -10,7 +10,11 @@ class Grid:
def convert_from_screen(self, x, y):
factor = Grid.COLS / gtk.gdk.screen_width()
- return [int(x * factor), int(y * factor)]
+
+ grid_x = round(x * factor) - 1
+ grid_y = round(y * factor) - 1
+
+ return [grid_x, grid_y]
def set_constraints(self, component, x, y, width=-1, height=-1):
if isinstance(component, gtk.Window):
diff --git a/sugar/canvas/IconColor.py b/sugar/canvas/IconColor.py
index 8babea0..84ca409 100644
--- a/sugar/canvas/IconColor.py
+++ b/sugar/canvas/IconColor.py
@@ -4,7 +4,7 @@ from sugar.canvas import Colors
def _parse_string(color_string):
if color_string == 'white':
- return ['#4f4f4f', 'white']
+ return ['white', '#4f4f4f']
splitted = color_string.split(',')
if len(splitted) == 2:
@@ -19,9 +19,9 @@ class IconColor:
def __init__(self, color_string=None):
if color_string == None or not is_valid(color_string):
n = int(random.random() * (len(Colors.colors) - 1))
- [self._fill, self._stroke] = Colors.colors[n]
+ [self._stroke, self._fill] = Colors.colors[n]
else:
- [self._fill, self._stroke] = _parse_string(color_string)
+ [self._stroke, self._fill] = _parse_string(color_string)
def get_stroke_color(self):
return self._stroke
@@ -30,5 +30,5 @@ class IconColor:
return self._fill
def to_string(self):
- return '%s,%s' % (self._fill, self._stroke)
+ return '%s,%s' % (self._stroke, self._fill)
diff --git a/sugar/canvas/IconItem.py b/sugar/canvas/IconItem.py
index 38850f1..d4be1e5 100644
--- a/sugar/canvas/IconItem.py
+++ b/sugar/canvas/IconItem.py
@@ -195,7 +195,7 @@ class IconItem(goocanvas.ItemSimple, goocanvas.Item):
self.size = 24
self.color = None
self.icon_name = None
- self._popdown_timeout = 0
+ self._popdown_sid = 0
goocanvas.ItemSimple.__init__(self, **kwargs)
@@ -240,29 +240,36 @@ class IconItem(goocanvas.ItemSimple, goocanvas.Item):
def _button_press_cb(self, view, target, event):
self.emit('clicked')
- def _start_popup_timeout(self):
- self._stop_popup_timeout()
- self._popdown_timeout = gobject.timeout_add(1000, self._popdown)
+ def _start_popdown_timeout(self):
+ self._stop_popdown_timeout()
+ self._popdown_sid = gobject.timeout_add(1000, self._popdown_timeout_cb)
- def _stop_popup_timeout(self):
- if self._popdown_timeout > 0:
- gobject.source_remove(self._popdown_timeout)
- self._popdown_timeout = 0
+ 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_popup_timeout()
+ 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.emit('popup', int(x1), int(y1), int(x2), int(y2))
- def _popdown(self):
- self._popdown_timeout = 0
+ def _popdown_timeout_cb(self):
+ self._popdown_sid = 0
self.emit('popdown')
return False
def _leave_notify_event_cb(self, view, target, event):
- self._start_popup_timeout()
+ self._start_popdown_timeout()
diff --git a/sugar/env.py b/sugar/env.py
index 8fc131a..b0c5443 100644
--- a/sugar/env.py
+++ b/sugar/env.py
@@ -43,7 +43,8 @@ def setup_system():
runner = os.path.join(sugar_source_dir, 'shell/sugar-activity-factory')
sugar.setup.setup_activities(source, sugar_activities_dir, runner)
- bin = os.path.join(sugar_source_dir, 'shell/sugar-presence-service')
+ bin = os.path.join(sugar_source_dir,
+ 'services/presence/sugar-presence-service')
sugar.setup.write_service('org.laptop.Presence', bin,
sugar_activities_dir)