Merge
This commit is contained in:
commit
922b7238b9
2
.gitignore
vendored
2
.gitignore
vendored
@ -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
|
||||
|
@ -1,4 +1,4 @@
|
||||
SUBDIRS = activities bindings po shell sugar tools
|
||||
SUBDIRS = activities bindings po shell sugar services tools
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
|
@ -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
|
||||
|
1
services/Makefile.am
Normal file
1
services/Makefile.am
Normal file
@ -0,0 +1 @@
|
||||
SUBDIRS = presence
|
@ -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)
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import logging
|
||||
from PresenceService import PresenceService
|
||||
from presence import PresenceService
|
||||
import sugar.logger
|
||||
|
||||
sugar.logger.start('PresenceService')
|
@ -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])
|
@ -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)
|
||||
|
@ -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()
|
||||
|
174
shell/Shell.py
174
shell/Shell.py
@ -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)
|
@ -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)
|
24
shell/model/BuddyInfo.py
Normal file
24
shell/model/BuddyInfo.py
Normal file
@ -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)
|
@ -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()
|
8
shell/model/Makefile.am
Normal file
8
shell/model/Makefile.am
Normal file
@ -0,0 +1,8 @@
|
||||
sugardir = $(pkgdatadir)/shell/model
|
||||
sugar_PYTHON = \
|
||||
__init__.py \
|
||||
BuddyInfo.py \
|
||||
Friends.py \
|
||||
Invites.py \
|
||||
Owner.py \
|
||||
ShellModel.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
|
||||
|
64
shell/model/ShellModel.py
Normal file
64
shell/model/ShellModel.py
Normal file
@ -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
|
@ -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
|
||||
|
108
shell/view/BuddyIcon.py
Normal file
108
shell/view/BuddyIcon.py
Normal file
@ -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()
|
@ -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
|
11
shell/view/Makefile.am
Normal file
11
shell/view/Makefile.am
Normal file
@ -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
|
102
shell/view/Shell.py
Normal file
102
shell/view/Shell.py
Normal file
@ -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)
|
@ -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())
|
@ -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)
|
||||
|
@ -1,4 +1,4 @@
|
||||
sugardir = $(pkgdatadir)/shell/frame
|
||||
sugardir = $(pkgdatadir)/shell/view/frame
|
||||
sugar_PYTHON = \
|
||||
__init__.py \
|
||||
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)
|
@ -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()
|
||||
|
0
shell/view/frame/__init__.py
Normal file
0
shell/view/frame/__init__.py
Normal file
42
shell/view/home/FriendsGroup.py
Normal file
42
shell/view/home/FriendsGroup.py
Normal file
@ -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]
|
@ -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):
|
@ -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)
|
@ -1,4 +1,4 @@
|
||||
sugardir = $(pkgdatadir)/shell/home
|
||||
sugardir = $(pkgdatadir)/shell/view/home
|
||||
sugar_PYTHON = \
|
||||
__init__.py \
|
||||
DonutItem.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 = {}
|
||||
|
0
shell/view/home/__init__.py
Normal file
0
shell/view/home/__init__.py
Normal file
@ -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 = []
|
||||
|
@ -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'))
|
||||
|
@ -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):
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user