Split shell in model/view, cleanup things a lot

This commit is contained in:
Marco Pesenti Gritti 2006-09-15 12:40:22 +02:00
parent 0232dc73b5
commit 645aa93e50
13 changed files with 63 additions and 166 deletions

View File

@ -31,6 +31,9 @@ class ActivityHost:
def get_id(self): def get_id(self):
return self._id return self._id
def get_xid(self):
return self._xid
def get_icon_name(self): def get_icon_name(self):
return self._icon_name return self._icon_name

View File

@ -14,11 +14,11 @@ class _PopupShell:
class FriendIcon(IconItem): class FriendIcon(IconItem):
_popup_shell = _PopupShell() _popup_shell = _PopupShell()
def __init__(self, shell, friend): def __init__(self, shell_model, friend):
IconItem.__init__(self, icon_name='stock-buddy', IconItem.__init__(self, icon_name='stock-buddy',
color=friend.get_color(), size=96) color=friend.get_color(), size=96)
self._shell = shell self._shell_model = shell_model
self._friend = friend self._friend = friend
self._popup = None self._popup = None
self._popup_distance = 0 self._popup_distance = 0
@ -83,10 +83,10 @@ class FriendIcon(IconItem):
return return
if action == FriendPopup.ACTION_INVITE: if action == FriendPopup.ACTION_INVITE:
activity = self._shell.get_current_activity() activity = self._shell_model.get_current_activity()
activity.invite(buddy) activity.invite(buddy)
elif action == FriendPopup.ACTION_MAKE_FRIEND: elif action == FriendPopup.ACTION_MAKE_FRIEND:
friends = self._shell.get_owner().get_friends() friends = self._shell_model.get_friends()
friends.add_buddy(buddy) friends.add_buddy(buddy)
def _popdown_cb(self, friend): def _popdown_cb(self, friend):

View File

@ -6,8 +6,6 @@ import conf
from sugar import env from sugar import env
from sugar.p2p import Stream from sugar.p2p import Stream
from sugar.presence import PresenceService from sugar.presence import PresenceService
from Friends import Friends
from Invites import Invites
PRESENCE_SERVICE_TYPE = "_presence_olpc._tcp" PRESENCE_SERVICE_TYPE = "_presence_olpc._tcp"
@ -31,14 +29,6 @@ class ShellOwner(object):
break break
self._pservice = PresenceService.get_instance() self._pservice = PresenceService.get_instance()
self._friends = Friends()
self._invites = Invites()
def get_friends(self):
return self._friends
def get_invites(self):
return self._invites
def announce(self): def announce(self):
# Create and announce our presence # Create and announce our presence

View File

@ -2,6 +2,7 @@ import os
import gtk import gtk
from Shell import Shell from Shell import Shell
from ShellModel import ShellModel
from ConsoleWindow import ConsoleWindow from ConsoleWindow import ConsoleWindow
from sugar import env from sugar import env
from sugar import logger from sugar import logger
@ -47,11 +48,8 @@ class Session:
dbm = DBusMonitorProcess() dbm = DBusMonitorProcess()
dbm.start() dbm.start()
console = ConsoleWindow() model = ShellModel()
logger.start('Shell', console) shell = Shell(model)
shell = Shell()
shell.set_console(console)
from sugar import TracebackUtils from sugar import TracebackUtils
tbh = TracebackUtils.TracebackHelper() tbh = TracebackUtils.TracebackHelper()

View File

@ -1,51 +1,19 @@
import os
import logging
import dbus
import dbus.glib
import gtk import gtk
import gobject import gobject
import wnck import wnck
from home.HomeWindow import HomeWindow from home.HomeWindow import HomeWindow
from Owner import ShellOwner
from sugar.presence import PresenceService
from ActivityHost import ActivityHost from ActivityHost import ActivityHost
from sugar.activity import ActivityFactory
from sugar.activity import Activity
from frame.Frame import Frame from frame.Frame import Frame
from globalkeys import KeyGrabber from globalkeys import KeyGrabber
import conf
import sugar 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): class Shell(gobject.GObject):
__gsignals__ = { def __init__(self, model):
'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) gobject.GObject.__init__(self)
self._model = model
self._screen = wnck.screen_get_default() self._screen = wnck.screen_get_default()
self._hosts = {}
self._current_window = None
self._key_grabber = KeyGrabber() self._key_grabber = KeyGrabber()
self._key_grabber.connect('key-pressed', self.__global_key_pressed_cb) self._key_grabber.connect('key-pressed', self.__global_key_pressed_cb)
@ -56,7 +24,7 @@ class Shell(gobject.GObject):
self._key_grabber.grab('F5') self._key_grabber.grab('F5')
self._key_grabber.grab('F6') self._key_grabber.grab('F6')
self._home_window = HomeWindow(self) self._home_window = HomeWindow(self.get_model())
self._home_window.show() self._home_window.show()
self.set_zoom_level(sugar.ZOOM_HOME) self.set_zoom_level(sugar.ZOOM_HOME)
@ -65,24 +33,9 @@ class Shell(gobject.GObject):
self._screen.connect('active-window-changed', self._screen.connect('active-window-changed',
self.__active_window_changed_cb) self.__active_window_changed_cb)
session_bus = dbus.SessionBus() self._frame = Frame(self)
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._owner.announce()
self._home_window.set_owner(self._owner)
self._frame = Frame(self, self._owner)
self._frame.show_and_hide(10) self._frame.show_and_hide(10)
def get_owner(self):
return self._owner
def __global_key_pressed_cb(self, grabber, key): def __global_key_pressed_cb(self, grabber, key):
if key == 'F1': if key == 'F1':
self.set_zoom_level(sugar.ZOOM_ACTIVITY) self.set_zoom_level(sugar.ZOOM_ACTIVITY)
@ -95,72 +48,23 @@ class Shell(gobject.GObject):
elif key == 'F5': elif key == 'F5':
self._frame.toggle_visibility() self._frame.toggle_visibility()
elif key == 'F6': elif key == 'F6':
ActivityFactory.create('org.sugar.Terminal') self._model.start_activity('org.sugar.Terminal')
def set_console(self, console):
self._console = console
def __window_opened_cb(self, screen, window): def __window_opened_cb(self, screen, window):
if window.get_window_type() == wnck.WINDOW_NORMAL: if window.get_window_type() == wnck.WINDOW_NORMAL:
host = ActivityHost(self, window) self._model.add_activity(ActivityHost(self, window))
self._hosts[window.get_xid()] = host
self.emit('activity-opened', host)
def __active_window_changed_cb(self, screen): def __active_window_changed_cb(self, screen):
window = screen.get_active_window() window = screen.get_active_window()
if window and window.get_window_type() == wnck.WINDOW_NORMAL: if window and window.get_window_type() == wnck.WINDOW_NORMAL:
if self._current_window != window: self._model.set_current_activity(window.get_xid())
self._current_window = window
self.emit('activity-changed', self.get_current_activity())
def __window_closed_cb(self, screen, window): def __window_closed_cb(self, screen, window):
if window.get_window_type() == wnck.WINDOW_NORMAL: if window.get_window_type() == wnck.WINDOW_NORMAL:
xid = window.get_xid() self._model.remove_activity(window.get_xid())
if self._hosts.has_key(xid):
host = self._hosts[xid]
self.emit('activity-closed', host)
del self._hosts[xid] def get_model(self):
return self._model
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 set_zoom_level(self, level): def set_zoom_level(self, level):
if level == sugar.ZOOM_ACTIVITY: if level == sugar.ZOOM_ACTIVITY:

View File

@ -33,30 +33,30 @@ class InviteItem(IconItem):
return self._invite return self._invite
class BottomPanel(CanvasBox): class BottomPanel(CanvasBox):
def __init__(self, grid, shell, invites): def __init__(self, grid, shell_model):
CanvasBox.__init__(self, grid, CanvasBox.HORIZONTAL, 1) CanvasBox.__init__(self, grid, CanvasBox.HORIZONTAL, 1)
self._shell = shell self._shell_model = shell_model
self._invite_to_item = {} self._invite_to_item = {}
self._invites = invites self._invites = shell_model.get_invites()
registry = conf.get_activity_registry() registry = conf.get_activity_registry()
for activity in registry.list_activities(): for activity in registry.list_activities():
if activity.get_show_launcher(): if activity.get_show_launcher():
self.add_activity(activity) self.add_activity(activity)
for invite in invites: for invite in self._invites:
self.add_invite(invite) self.add_invite(invite)
invites.connect('invite-added', self.__invite_added_cb) self._invites.connect('invite-added', self.__invite_added_cb)
invites.connect('invite-removed', self.__invite_removed_cb) self._invites.connect('invite-removed', self.__invite_removed_cb)
def __activity_clicked_cb(self, icon): def __activity_clicked_cb(self, icon):
self._shell.start_activity(icon.get_bundle_id()) self._shell_model.start_activity(icon.get_bundle_id())
def __invite_clicked_cb(self, icon): def __invite_clicked_cb(self, icon):
self._invites.remove_invite(icon.get_invite()) self._invites.remove_invite(icon.get_invite())
self._shell.join_activity(icon.get_bundle_id(), self._shell_model.join_activity(icon.get_bundle_id(),
icon.get_activity_id()) icon.get_activity_id())
def __invite_added_cb(self, invites, invite): def __invite_added_cb(self, invites, invite):
self.add_invite(invite) self.add_invite(invite)

View File

@ -9,9 +9,11 @@ from frame.PanelWindow import PanelWindow
from sugar.canvas.Grid import Grid from sugar.canvas.Grid import Grid
class Frame: class Frame:
def __init__(self, shell, owner): def __init__(self, shell):
self._windows = [] self._windows = []
shell_model = shell.get_model()
model = goocanvas.CanvasModelSimple() model = goocanvas.CanvasModelSimple()
root = model.get_root_item() root = model.get_root_item()
@ -21,7 +23,7 @@ class Frame:
grid.set_constraints(bg, 0, 0, 80, 60) grid.set_constraints(bg, 0, 0, 80, 60)
root.add_child(bg) root.add_child(bg)
panel = BottomPanel(grid, shell, owner.get_invites()) panel = BottomPanel(grid, shell_model)
grid.set_constraints(panel, 5, 55) grid.set_constraints(panel, 5, 55)
root.add_child(panel) root.add_child(panel)
@ -34,7 +36,7 @@ class Frame:
panel_window = PanelWindow(grid, model, 0, 0, 80, 5) panel_window = PanelWindow(grid, model, 0, 0, 80, 5)
self._windows.append(panel_window) self._windows.append(panel_window)
panel = RightPanel(grid, shell, owner.get_friends()) panel = RightPanel(grid, shell_model)
grid.set_constraints(panel, 75, 5) grid.set_constraints(panel, 75, 5)
root.add_child(panel) root.add_child(panel)

View File

@ -8,10 +8,10 @@ from FriendIcon import FriendIcon
from Friends import Friend from Friends import Friend
class RightPanel(CanvasBox): class RightPanel(CanvasBox):
def __init__(self, grid, shell, friends): def __init__(self, grid, shell_model):
CanvasBox.__init__(self, grid, CanvasBox.VERTICAL, 1) CanvasBox.__init__(self, grid, CanvasBox.VERTICAL, 1)
self._shell = shell self._shell_model = shell_model
self._friends = friends self._friends = shell_model.get_friends()
self._activity_ps = None self._activity_ps = None
self._joined_hid = -1 self._joined_hid = -1
self._left_hid = -1 self._left_hid = -1
@ -21,11 +21,11 @@ class RightPanel(CanvasBox):
self._pservice.connect('activity-appeared', self._pservice.connect('activity-appeared',
self.__activity_appeared_cb) self.__activity_appeared_cb)
shell.connect('activity-changed', self.__activity_changed_cb) shell_model.connect('activity-changed', self.__activity_changed_cb)
def add(self, buddy): def add(self, buddy):
friend = Friend(buddy.get_name(), buddy.get_color()) friend = Friend(buddy.get_name(), buddy.get_color())
icon = FriendIcon(self._shell, friend) icon = FriendIcon(self._shell_model, friend)
icon.set_popup_distance(1) icon.set_popup_distance(1)
self.set_constraints(icon, 3, 3) self.set_constraints(icon, 3, 3)
self.add_child(icon) self.add_child(icon)
@ -42,7 +42,7 @@ class RightPanel(CanvasBox):
self._buddies = {} self._buddies = {}
def __activity_appeared_cb(self, pservice, activity_ps): def __activity_appeared_cb(self, pservice, activity_ps):
activity = self._shell.get_current_activity() activity = self._shell_model.get_current_activity()
if activity and activity_ps.get_id() == activity.get_id(): if activity and activity_ps.get_id() == activity.get_id():
self._set_activity_ps(activity_ps) self._set_activity_ps(activity_ps)

View File

@ -58,7 +58,8 @@ class TopPanel(goocanvas.Group):
self._shell.set_zoom_level(level) self._shell.set_zoom_level(level)
def __share_clicked_cb(self, item): 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: if activity != None:
activity.share() activity.share()

View File

@ -7,12 +7,12 @@ from home.MyIcon import MyIcon
from FriendIcon import FriendIcon from FriendIcon import FriendIcon
class FriendsGroup(goocanvas.Group): class FriendsGroup(goocanvas.Group):
def __init__(self, shell, friends): def __init__(self, shell_model):
goocanvas.Group.__init__(self) goocanvas.Group.__init__(self)
self._shell = shell self._shell_model = shell_model
self._icon_layout = IconLayout(1200, 900) self._icon_layout = IconLayout(1200, 900)
self._friends = friends self._friends = shell_model.get_friends()
me = MyIcon(100) me = MyIcon(100)
me.translate(600 - (me.get_property('size') / 2), me.translate(600 - (me.get_property('size') / 2),
@ -22,10 +22,10 @@ class FriendsGroup(goocanvas.Group):
for friend in self._friends: for friend in self._friends:
self.add_friend(friend) self.add_friend(friend)
friends.connect('friend-added', self._friend_added_cb) self._friends.connect('friend-added', self._friend_added_cb)
def add_friend(self, friend): def add_friend(self, friend):
icon = FriendIcon(self._shell, friend) icon = FriendIcon(self._shell_model, friend)
self.add_child(icon) self.add_child(icon)
self._icon_layout.add_icon(icon) self._icon_layout.add_icon(icon)

View File

@ -4,19 +4,19 @@ from home.DonutItem import DonutItem
from home.MyIcon import MyIcon from home.MyIcon import MyIcon
class TasksItem(DonutItem): class TasksItem(DonutItem):
def __init__(self, shell): def __init__(self, shell_model):
DonutItem.__init__(self, 250) DonutItem.__init__(self, 250)
self._items = {} self._items = {}
self._shell = shell self._shell_model = shell_model
self._shell.connect('activity_opened', self.__activity_opened_cb) self._shell_model.connect('activity_opened', self.__activity_opened_cb)
self._shell.connect('activity_closed', self.__activity_closed_cb) self._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) self._add(activity)
def __activity_closed_cb(self, shell, activity): def __activity_closed_cb(self, model, activity):
self._remove(activity) self._remove(activity)
def _remove(self, activity): def _remove(self, activity):
@ -27,6 +27,7 @@ class TasksItem(DonutItem):
def _add(self, activity): def _add(self, activity):
icon_name = activity.get_icon_name() icon_name = activity.get_icon_name()
icon_color = activity.get_icon_color() icon_color = activity.get_icon_color()
print 'Add activity %s' % icon_color.to_string()
item = self.add_piece(100 / 8, icon_name, icon_color) item = self.add_piece(100 / 8, icon_name, icon_color)
item.get_icon().connect('clicked', item.get_icon().connect('clicked',
@ -39,10 +40,10 @@ class TasksItem(DonutItem):
activity.present() activity.present()
class HomeGroup(goocanvas.Group): class HomeGroup(goocanvas.Group):
def __init__(self, shell): def __init__(self, shell_model):
goocanvas.Group.__init__(self) goocanvas.Group.__init__(self)
tasks = TasksItem(shell) tasks = TasksItem(shell_model)
tasks.translate(600, 450) tasks.translate(600, 450)
self.add_child(tasks) self.add_child(tasks)

View File

@ -9,9 +9,9 @@ from home.FriendsGroup import FriendsGroup
import sugar import sugar
class HomeWindow(gtk.Window): class HomeWindow(gtk.Window):
def __init__(self, shell): def __init__(self, shell_model):
gtk.Window.__init__(self) gtk.Window.__init__(self)
self._shell = shell self._shell_model = shell_model
self.realize() self.realize()
self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DESKTOP) self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DESKTOP)
@ -23,6 +23,10 @@ class HomeWindow(gtk.Window):
self.add(self._nb) self.add(self._nb)
self._nb.show() self._nb.show()
self._add_page(HomeGroup(shell_model))
self._add_page(FriendsGroup(shell_model))
self._add_page(MeshGroup())
def _add_page(self, group): def _add_page(self, group):
view = CanvasView() view = CanvasView()
self._nb.append_page(view) self._nb.append_page(view)
@ -37,11 +41,6 @@ class HomeWindow(gtk.Window):
root.add_child(bg) root.add_child(bg)
root.add_child(group) 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): def set_zoom_level(self, level):
if level == sugar.ZOOM_HOME: if level == sugar.ZOOM_HOME:
self._nb.set_current_page(0) self._nb.set_current_page(0)

View File

@ -32,9 +32,8 @@ class ActivityItem(IconItem):
return self._service return self._service
class MeshGroup(goocanvas.Group): class MeshGroup(goocanvas.Group):
def __init__(self, shell): def __init__(self):
goocanvas.Group.__init__(self) goocanvas.Group.__init__(self)
self._shell = shell
self._icon_layout = IconLayout(1200, 900) self._icon_layout = IconLayout(1200, 900)
self._activities = {} self._activities = {}