Merge demo4 branch

This commit is contained in:
Marco Pesenti Gritti 2006-08-19 11:56:49 +02:00
commit 58ddb555c4
34 changed files with 653 additions and 188 deletions

View File

@ -1 +1 @@
SUBDIRS = browser chat terminal SUBDIRS = browser chat groupchat terminal

View File

@ -1,6 +1,7 @@
[Activity] [Activity]
name = Web name = Web
id = com.redhat.Sugar.BrowserActivity id = com.redhat.Sugar.BrowserActivity
icon = activity-web
python_module = browser.BrowserActivity.BrowserActivity python_module = browser.BrowserActivity.BrowserActivity
default_type = _web_olpc._udp default_type = _web_olpc._udp
show_launcher = yes show_launcher = yes

View File

@ -0,0 +1,8 @@
from gettext import gettext as _
from sugar.activity.Activity import Activity
class GroupChatActivity(Activity):
def __init__(self):
Activity.__init__(self)
self.set_title(_('Group chat'))

View File

@ -0,0 +1,6 @@
sugardir = $(pkgdatadir)/activities/groupchat
sugar_PYTHON = \
__init__.py \
GroupChatActivity.py
EXTRA_DIST = groupchat.activity

View File

View File

@ -0,0 +1,6 @@
[Activity]
name = GroupChat
icon = activity-groupchat
id = com.redhat.Sugar.GroupChatActivity
python_module = groupchat.GroupChatActivity.GroupChatActivity
show_launcher = yes

View File

@ -27,14 +27,17 @@ dbus-installed.conf
activities/Makefile activities/Makefile
activities/browser/Makefile activities/browser/Makefile
activities/chat/Makefile activities/chat/Makefile
activities/groupchat/Makefile
activities/terminal/Makefile activities/terminal/Makefile
shell/Makefile shell/Makefile
shell/data/Makefile shell/data/Makefile
shell/home/Makefile
shell/session/Makefile shell/session/Makefile
shell/PresenceService/Makefile shell/PresenceService/Makefile
sugar/Makefile sugar/Makefile
sugar/__installed__.py sugar/__installed__.py
sugar/activity/Makefile sugar/activity/Makefile
sugar/canvas/Makefile
sugar/chat/Makefile sugar/chat/Makefile
sugar/chat/sketchpad/Makefile sugar/chat/sketchpad/Makefile
sugar/p2p/Makefile sugar/p2p/Makefile

View File

@ -20,9 +20,15 @@ class ActivityHost:
self._gdk_window = gtk.gdk.window_foreign_new(self._xid) self._gdk_window = gtk.gdk.window_foreign_new(self._xid)
self._people_window = PeopleWindow(shell, self) self._people_window = PeopleWindow(shell, self)
info = self._shell.get_registry().get_activity(self._default_type)
self._icon_name = info.get_icon()
def get_id(self): def get_id(self):
return self._id return self._id
def get_icon_name(self):
return self._icon_name
def share(self): def share(self):
self._people_window.share() self._people_window.share()
self._activity.share() self._activity.share()

View File

@ -8,6 +8,7 @@ class ActivityModule:
def __init__(self, name, activity_id, directory): def __init__(self, name, activity_id, directory):
self._name = name self._name = name
self._icon = None
self._id = activity_id self._id = activity_id
self._directory = directory self._directory = directory
self._show_launcher = False self._show_launcher = False
@ -20,6 +21,14 @@ class ActivityModule:
"""Get the activity identifier""" """Get the activity identifier"""
return self._id return self._id
def get_icon(self):
"""Get the activity icon name"""
return self._icon
def set_icon(self, icon):
"""Set the activity icon name"""
self._icon = icon
def get_directory(self): def get_directory(self):
"""Get the path to activity directory.""" """Get the path to activity directory."""
return self._directory return self._directory
@ -97,6 +106,9 @@ class ActivityRegistry:
if cp.has_option('Activity', 'show_launcher'): if cp.has_option('Activity', 'show_launcher'):
module.set_show_launcher(True) module.set_show_launcher(True)
if cp.has_option('Activity', 'icon'):
module.set_icon(cp.get('Activity', 'icon'))
module.set_default_type(default_type) module.set_default_type(default_type)
return True return True

View File

@ -13,7 +13,8 @@ class ChatController:
self._shell.connect('activity-closed', self.__activity_closed_cb) self._shell.connect('activity-closed', self.__activity_closed_cb)
def __activity_closed_cb(self, shell, activity_id): def __activity_closed_cb(self, shell, activity):
activity_id = activity.get_id()
if self._id_to_name.has_key(activity_id): if self._id_to_name.has_key(activity_id):
name = self._id_to_name[activity_id] name = self._id_to_name[activity_id]
del self._name_to_chat[name] del self._name_to_chat[name]

View File

@ -1,165 +0,0 @@
from gettext import gettext as _
import gtk
import wnck
from sugar.activity import ActivityFactory
from ActivitiesModel import ActivitiesModel
from sugar.presence.PresenceService import PresenceService
class NewActivityButton(gtk.MenuToolButton):
def __init__(self, home):
gtk.MenuToolButton.__init__(self, None, _('New Activity'))
self._home = home
self.set_menu(gtk.Menu())
self.connect("show-menu", self.__show_menu_cb)
def __show_menu_cb(self, button):
menu = gtk.Menu()
for module in self._home.list_activities():
if module.get_show_launcher():
item = gtk.MenuItem(module.get_name(), False)
activity_id = module.get_id()
item.connect('activate',
self.__menu_item_activate_cb, activity_id)
menu.append(item)
item.show()
self.set_menu(menu)
def __menu_item_activate_cb(self, item, activity_id):
self._home.create(activity_id)
class Toolbar(gtk.Toolbar):
def __init__(self, shell):
gtk.Toolbar.__init__(self)
new_activity_button = NewActivityButton(shell)
self.insert(new_activity_button, -1)
new_activity_button.show()
class ActivitiesGrid(gtk.VBox):
def __init__(self, shell, model):
gtk.VBox.__init__(self, shell)
self._shell = shell
self._buttons = {}
for activity in model:
self._add(activity)
model.connect('activity-added', self.__activity_added_cb)
model.connect('activity-removed', self.__activity_removed_cb)
def __activity_added_cb(self, model, activity):
self._add(activity)
def __activity_removed_cb(self, model, activity):
self._remove(window)
def _remove(self, activity):
button = self._buttons[activity.get_id()]
self.remove(button)
def _add(self, activity):
button = gtk.Button(activity.get_title())
button.connect('clicked', self.__button_clicked_cb, activity)
self.pack_start(button, False)
button.show()
self._buttons[activity.get_id()] = button
def __button_clicked_cb(self, button, info):
self._shell.join_activity(info.get_service())
class TasksGrid(gtk.VBox):
def __init__(self, home):
gtk.VBox.__init__(self)
self._home = home
self._buttons = {}
screen = wnck.screen_get_default()
for window in screen.get_windows():
if not window.is_skip_tasklist():
self._add(window)
screen.connect('window_opened', self.__window_opened_cb)
screen.connect('window_closed', self.__window_closed_cb)
def __window_opened_cb(self, screen, window):
if not window.is_skip_tasklist():
self._add(window)
def __window_closed_cb(self, screen, window):
if not window.is_skip_tasklist():
self._remove(window)
def _remove(self, window):
button = self._buttons[window.get_xid()]
self.remove(button)
def __window_name_changed_cb(self, window, button):
button.set_label(window.get_name())
def _add(self, window):
button = gtk.Button(window.get_name())
window.connect('name-changed', self.__window_name_changed_cb, button)
button.connect('clicked', self.__button_clicked_cb, window)
self.pack_start(button, False)
button.show()
self._buttons[window.get_xid()] = button
def __button_clicked_cb(self, button, window):
self._home.activate(window)
class HomeWindow(gtk.Window):
def __init__(self, shell):
gtk.Window.__init__(self)
self._shell = shell
self.connect('realize', self.__realize_cb)
vbox = gtk.VBox(False, 6)
vbox.set_border_width(24)
toolbar = Toolbar(self)
vbox.pack_start(toolbar, False)
toolbar.show()
label = gtk.Label('Open activities:')
label.set_alignment(0.0, 0.5)
vbox.pack_start(label, False)
label.show()
grid = TasksGrid(self)
vbox.pack_start(grid)
grid.show()
label = gtk.Label('Shared activities:')
label.set_alignment(0.0, 0.5)
vbox.pack_start(label, False)
label.show()
model = ActivitiesModel(shell.get_registry())
grid = ActivitiesGrid(shell, model)
vbox.pack_start(grid)
grid.show()
self.add(vbox)
vbox.show()
def __realize_cb(self, window):
self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DESKTOP)
def list_activities(self):
return self._shell.get_registry().list_activities()
def create(self, activity_name):
self._shell.start_activity(activity_name)
def activate(self, activity_window):
activity_window.activate(gtk.get_current_event_time())

View File

@ -1,4 +1,4 @@
SUBDIRS = data session PresenceService SUBDIRS = data session home PresenceService
bin_SCRIPTS = \ bin_SCRIPTS = \
sugar \ sugar \
@ -6,18 +6,17 @@ bin_SCRIPTS = \
sugar-activity-factory \ sugar-activity-factory \
sugar-console \ sugar-console \
sugar-people \ sugar-people \
sugar-zoom \
sugar-presence-service sugar-presence-service
sugardir = $(pkgdatadir)/shell sugardir = $(pkgdatadir)/shell
sugar_PYTHON = \ sugar_PYTHON = \
__init__.py \ __init__.py \
ActivitiesModel.py \
ActivityHost.py \ ActivityHost.py \
ActivityRegistry.py \ ActivityRegistry.py \
ChatController.py \ ChatController.py \
ConsoleWindow.py \ ConsoleWindow.py \
Owner.py \ Owner.py \
HomeWindow.py \
PeopleWindow.py \ PeopleWindow.py \
PresenceView.py \ PresenceView.py \
Shell.py Shell.py

View File

@ -8,7 +8,8 @@ import gobject
import wnck import wnck
from ActivityRegistry import ActivityRegistry from ActivityRegistry import ActivityRegistry
from HomeWindow import HomeWindow from home.HomeWindow import HomeWindow
from home.HomeModel import HomeModel
from sugar import env from sugar import env
from Owner import ShellOwner from Owner import ShellOwner
from sugar.presence.PresenceService import PresenceService from sugar.presence.PresenceService import PresenceService
@ -37,9 +38,25 @@ class ShellDbusService(dbus.service.Object):
def show_console(self): def show_console(self):
gobject.idle_add(self.__show_console_idle) gobject.idle_add(self.__show_console_idle)
@dbus.service.method('com.redhat.Sugar.Shell')
def zoom_in(self):
self._shell.zoom_in()
@dbus.service.method('com.redhat.Sugar.Shell')
def zoom_out(self):
self._shell.zoom_out()
class Shell(gobject.GObject): class Shell(gobject.GObject):
ZOOM_MESH = 0
ZOOM_FRIENDS = 1
ZOOM_HOME = 2
ZOOM_ACTIVITY = 3
__gsignals__ = { __gsignals__ = {
'activity-closed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([str])) 'activity-opened': (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, registry): def __init__(self, registry):
@ -48,6 +65,7 @@ class Shell(gobject.GObject):
self._screen = wnck.screen_get_default() self._screen = wnck.screen_get_default()
self._registry = registry self._registry = registry
self._hosts = {} self._hosts = {}
self._zoom_level = Shell.ZOOM_HOME
def start(self): def start(self):
session_bus = dbus.SessionBus() session_bus = dbus.SessionBus()
@ -60,7 +78,8 @@ class Shell(gobject.GObject):
self._chat_controller = ChatController(self) self._chat_controller = ChatController(self)
self._chat_controller.listen() self._chat_controller.listen()
self._home_window = HomeWindow(self) home_model = HomeModel(self._registry)
self._home_window = HomeWindow(self, home_model)
self._home_window.show() self._home_window.show()
self._screen.connect('window-opened', self.__window_opened_cb) self._screen.connect('window-opened', self.__window_opened_cb)
@ -71,14 +90,16 @@ class Shell(gobject.GObject):
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:
self._hosts[window.get_xid()] = ActivityHost(self, window) host = ActivityHost(self, window)
self._hosts[window.get_xid()] = host
self.emit('activity-opened', host)
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() xid = window.get_xid()
activity = self._hosts[xid] host = self._hosts[xid]
self.emit('activity-closed', activity.get_id()) self.emit('activity-closed', host)
del self._hosts[xid] del self._hosts[xid]
@ -154,3 +175,28 @@ class Shell(gobject.GObject):
def get_chat_controller(self): def get_chat_controller(self):
return self._chat_controller return self._chat_controller
def _set_zoom_level(self, level):
self._zoom_level = level
if level == Shell.ZOOM_ACTIVITY:
self._screen.toggle_showing_desktop(False)
else:
self._screen.toggle_showing_desktop(True)
if level == Shell.ZOOM_HOME:
self._home_window.set_view(HomeWindow.HOME_VIEW)
elif level == Shell.ZOOM_FRIENDS:
self._home_window.set_view(HomeWindow.FRIENDS_VIEW)
elif level == Shell.ZOOM_MESH:
self._home_window.set_view(HomeWindow.MESH_VIEW)
def zoom_in(self):
level = self._zoom_level + 1
if level <= Shell.ZOOM_ACTIVITY:
self._set_zoom_level(level)
def zoom_out(self):
level = self._zoom_level - 1
if level >= Shell.ZOOM_MESH:
self._set_zoom_level(level)

View File

@ -1,8 +1,4 @@
confdir = $(pkgdatadir) confdir = $(pkgdatadir)
conf_DATA = kbdconfig conf_DATA = kbdconfig
imagesdir = $(pkgdatadir) EXTRA_DIST = $(conf_DATA)
images_DATA = \
home-background.png
EXTRA_DIST = $(conf_DATA) $(images_DATA)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

View File

@ -5,7 +5,7 @@
<Alt>n=next <Alt>n=next
<Alt>p=prev <Alt>p=prev
<Alt>c=close <Alt>c=close
f1=desktop f1=!sugar-zoom out
f2=!sugar-people f2=!sugar-zoom in
f3=!sugar-console f3=!sugar-people
f4=!sugar-activity org.sugar.Terminal f4=!sugar-activity org.sugar.Terminal

View File

@ -0,0 +1,40 @@
import gobject
from sugar.presence.PresenceService import PresenceService
class Friend:
def __init__(self, buddy):
self._buddy = buddy
def get_name(self):
return self._buddy.get_name()
class FriendsModel(gobject.GObject):
__gsignals__ = {
'friend-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'friend-removed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT]))
}
def __init__(self):
gobject.GObject.__init__(self)
self._friends = []
self._pservice = PresenceService()
self._pservice.connect("buddy-appeared", self.__buddy_appeared_cb)
for buddy in self._pservice.get_buddies():
self.add_friend(buddy)
def add_friend(self, buddy):
friend = Friend(buddy)
self._friends.append(friend)
self.emit('friend-added', friend)
def __iter__(self):
return self._friends.__iter__()
def __buddy_appeared_cb(self, pservice, buddy):
self.add_friend(buddy)

45
shell/home/FriendsView.py Normal file
View File

@ -0,0 +1,45 @@
import random
import goocanvas
from sugar.canvas.IconItem import IconItem
class Model(goocanvas.CanvasModelSimple):
def __init__(self, data_model):
goocanvas.CanvasModelSimple.__init__(self)
root = self.get_root_item()
item = goocanvas.Rect(width=1200, height=900,
fill_color="#d8d8d8")
root.add_child(item)
for friend in data_model:
self.add_friend(friend)
data_model.connect('friend-added', self.__friend_added_cb)
def add_friend(self, friend):
root = self.get_root_item()
icon = IconItem('stock-buddy', 'green', 48)
icon.set_property('x', random.random() * 1100)
icon.set_property('y', random.random() * 800)
root.add_child(icon)
def __friend_added_cb(self, data_model, friend):
self.add_friend(friend)
class FriendsView(goocanvas.CanvasView):
def __init__(self, shell, data_model):
goocanvas.CanvasView.__init__(self)
self._shell = shell
self.connect("item_view_created", self.__item_view_created_cb)
canvas_model = Model(data_model)
self.set_model(canvas_model)
def __item_view_created_cb(self, view, item_view, item):
pass

13
shell/home/HomeModel.py Normal file
View File

@ -0,0 +1,13 @@
from home.FriendsModel import FriendsModel
from home.MeshModel import MeshModel
class HomeModel:
def __init__(self, registry):
self._friends = FriendsModel()
self._mesh = MeshModel(registry)
def get_friends(self):
return self._friends
def get_mesh(self):
return self._mesh

128
shell/home/HomeView.py Normal file
View File

@ -0,0 +1,128 @@
import gtk
import goocanvas
import wnck
from sugar.canvas.IconItem import IconItem
from sugar.canvas.DonutItem import DonutItem
from sugar.canvas.DonutItem import PieceItem
from sugar.canvas.DonutItem import PieceIcon
class TasksItem(DonutItem):
def __init__(self, shell):
DonutItem.__init__(self, 250)
self._items = {}
shell.connect('activity_opened', self.__activity_opened_cb)
shell.connect('activity_closed', self.__activity_closed_cb)
def __activity_opened_cb(self, shell, activity):
self._add(activity)
def __activity_closed_cb(self, shell, activity):
self._remove(activity)
def _remove(self, activity):
item = self._items[activity.get_id()]
self.remove_piece(item)
del self._items[activity.get_id()]
def _add(self, activity):
icon_name = activity.get_icon_name()
item = self.add_piece(100 / 8, icon_name, 'blue')
# FIXME This really sucks. Fix goocanvas event handling.
item.set_data('activity', activity)
item.get_icon().set_data('activity', activity)
self._items[activity.get_id()] = item
class ActivityItem(IconItem):
ICON_SIZE = 30
def __init__(self, activity):
IconItem.__init__(self, activity.get_icon(), 'white',
ActivityItem.ICON_SIZE)
self._activity = activity
def get_activity_id(self):
return self._activity.get_id()
class ActivityBar(goocanvas.Group):
def __init__(self, shell):
goocanvas.Group.__init__(self)
self._shell = shell
registry = shell.get_registry()
for activity in registry.list_activities():
if activity.get_show_launcher():
self.add_activity(activity)
def add_activity(self, activity):
item = ActivityItem(activity)
x = (ActivityItem.ICON_SIZE + 6) * self.get_n_children()
item.set_property('x', x)
self.add_child(item)
class Background(goocanvas.Group):
def __init__(self):
goocanvas.Group.__init__(self)
item = goocanvas.Rect(width=1200, height=900,
fill_color="#4f4f4f")
self.add_child(item)
item = goocanvas.Rect(x=50, y=50, width=1100, height=800,
line_width=0, fill_color="#d8d8d8",
radius_x=30, radius_y=30)
self.add_child(item)
item = goocanvas.Text(text="My Activities",
x=60, y=10, fill_color="white",
font="Sans 21")
self.add_child(item)
class Model(goocanvas.CanvasModelSimple):
def __init__(self, shell):
goocanvas.CanvasModelSimple.__init__(self)
root = self.get_root_item()
background = Background()
root.add_child(background)
activity_bar = ActivityBar(shell)
activity_bar.translate(50, 860)
root.add_child(activity_bar)
tasks = TasksItem(shell)
tasks.translate(600, 450)
root.add_child(tasks)
class HomeView(goocanvas.CanvasView):
def __init__(self, shell):
goocanvas.CanvasView.__init__(self)
self._shell = shell
self.connect("item_view_created", self.__item_view_created_cb)
canvas_model = Model(shell)
self.set_model(canvas_model)
def __item_view_created_cb(self, view, item_view, item):
if isinstance(item, ActivityItem):
item_view.connect("button_press_event",
self.__activity_button_press_cb,
item.get_activity_id())
elif isinstance(item, PieceItem) or \
isinstance(item, PieceIcon):
item_view.connect("button_press_event",
self.__task_button_press_cb)
def __activity_button_press_cb(self, view, target, event, activity_id):
self._shell.start_activity(activity_id)
def __task_button_press_cb(self, view, target, event):
activity = view.get_item().get_data('activity')
activity.present()

48
shell/home/HomeWindow.py Normal file
View File

@ -0,0 +1,48 @@
import gtk
from home.MeshView import MeshView
from home.HomeView import HomeView
from home.FriendsView import FriendsView
class HomeWindow(gtk.Window):
HOME_VIEW = 0
FRIENDS_VIEW = 1
MESH_VIEW = 2
def __init__(self, shell, model):
gtk.Window.__init__(self)
self.connect('realize', self.__realize_cb)
self._nb = gtk.Notebook()
self._nb.set_show_tabs(False)
self._nb.set_show_border(False)
home_view = HomeView(shell)
self._nb.append_page(home_view)
self._setup_canvas(home_view)
home_view.show()
friends_view = FriendsView(shell, model.get_friends())
self._nb.append_page(friends_view)
self._setup_canvas(friends_view)
friends_view.show()
mesh_view = MeshView(shell, model.get_mesh())
self._setup_canvas(mesh_view)
self._nb.append_page(mesh_view)
mesh_view.show()
self.add(self._nb)
self._nb.show()
def set_view(self, view):
self._nb.set_current_page(view)
def _setup_canvas(self, canvas):
canvas.set_bounds(0, 0, 1200, 900)
canvas.set_scale(float(800) / float(1200))
canvas.set_size_request(800, 600)
def __realize_cb(self, window):
self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DESKTOP)

10
shell/home/Makefile.am Normal file
View File

@ -0,0 +1,10 @@
sugardir = $(pkgdatadir)/shell/home
sugar_PYTHON = \
__init__.py \
FriendsModel.py \
FriendsView.py \
MeshModel.py \
MeshView.py \
HomeView.py \
HomeWindow.py \
HomeModel.py

View File

@ -19,7 +19,7 @@ class ActivityInfo:
def get_service(self): def get_service(self):
return self._service return self._service
class ActivitiesModel(gobject.GObject): class MeshModel(gobject.GObject):
__gsignals__ = { __gsignals__ = {
'activity-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, 'activity-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])), ([gobject.TYPE_PYOBJECT])),

63
shell/home/MeshView.py Normal file
View File

@ -0,0 +1,63 @@
import random
import goocanvas
from sugar.canvas.IconItem import IconItem
class ActivityItem(IconItem):
def __init__(self, activity, registry):
info = registry.get_activity(activity.get_type())
icon_name = info.get_icon()
IconItem.__init__(self, icon_name, 'green', 48)
self._activity = activity
def get_service(self):
return self._activity.get_service()
class Model(goocanvas.CanvasModelSimple):
def __init__(self, data_model, registry):
goocanvas.CanvasModelSimple.__init__(self)
self._registry = registry
root = self.get_root_item()
item = goocanvas.Rect(width=1200, height=900,
fill_color="#d8d8d8")
root.add_child(item)
for activity in data_model:
self.add_activity(activity)
data_model.connect('activity-added', self.__activity_added_cb)
def add_activity(self, activity):
root = self.get_root_item()
item = ActivityItem(activity, self._registry)
item.set_property('x', random.random() * 1100)
item.set_property('y', random.random() * 800)
root.add_child(item)
def __activity_added_cb(self, data_model, activity):
self.add_activity(activity)
class MeshView(goocanvas.CanvasView):
def __init__(self, shell, data_model):
goocanvas.CanvasView.__init__(self)
self._shell = shell
self.connect("item_view_created", self.__item_view_created_cb)
canvas_model = Model(data_model, shell.get_registry())
self.set_model(canvas_model)
def __activity_button_press_cb(self, view, target, event, service):
self._shell.join_activity(service)
def __item_view_created_cb(self, view, item_view, item):
if isinstance(item, ActivityItem):
item_view.connect("button_press_event",
self.__activity_button_press_cb,
item.get_service())

0
shell/home/__init__.py Normal file
View File

View File

@ -30,7 +30,7 @@ def get_display_number():
class XephyrProcess(Process): class XephyrProcess(Process):
def __init__(self): def __init__(self):
self._display = get_display_number() self._display = get_display_number()
cmd = 'Xephyr :%d -ac -screen 640x480' % (self._display) cmd = 'Xephyr :%d -ac -screen 800x600' % (self._display)
Process.__init__(self, cmd) Process.__init__(self, cmd)
def get_name(self): def get_name(self):
@ -43,7 +43,7 @@ class XephyrProcess(Process):
class XnestProcess(Process): class XnestProcess(Process):
def __init__(self): def __init__(self):
self._display = get_display_number() self._display = get_display_number()
cmd = 'Xnest :%d -ac -geometry 640x480' % (self._display) cmd = 'Xnest :%d -ac -geometry 800x600' % (self._display)
Process.__init__(self, cmd) Process.__init__(self, cmd)
def get_name(self): def get_name(self):

14
shell/sugar-zoom Normal file
View File

@ -0,0 +1,14 @@
#!/usr/bin/python
import sys
import dbus
import dbus.glib
bus = dbus.SessionBus()
proxy_obj = bus.get_object('com.redhat.Sugar.Shell', '/com/redhat/Sugar/Shell')
shell = dbus.Interface(proxy_obj, 'com.redhat.Sugar.Shell')
if sys.argv[1] == 'in':
shell.zoom_in()
elif sys.argv[1] == 'out':
shell.zoom_out()

View File

@ -1,4 +1,4 @@
SUBDIRS = activity chat p2p presence SUBDIRS = activity canvas chat p2p presence
sugardir = $(pythondir)/sugar sugardir = $(pythondir)/sugar
sugar_PYTHON = \ sugar_PYTHON = \

114
sugar/canvas/DonutItem.py Normal file
View File

@ -0,0 +1,114 @@
import math
import goocanvas
from sugar.canvas.IconItem import IconItem
class PieceIcon(IconItem):
def __init__(self, piece_item, icon_name, color, **kwargs):
IconItem.__init__(self, icon_name, color, 48, **kwargs)
self._piece_item = piece_item
def construct(self):
angle_start = self._piece_item.get_angle_start()
angle_end = self._piece_item.get_angle_end()
radius = self.get_parent().get_radius()
inner_radius = self.get_parent().get_inner_radius()
icon_radius = (radius + inner_radius) / 2
icon_angle = (angle_start + angle_end) / 2
x = icon_radius * math.cos(icon_angle)
y = - icon_radius * math.sin(icon_angle)
icon_width = self.get_property('width')
icon_height = self.get_property('height')
self.set_property('x', x - icon_width / 2)
self.set_property('y', y - icon_height / 2)
class PieceItem(goocanvas.Path):
def __init__(self, angle_start, angle_end, **kwargs):
goocanvas.Path.__init__(self, **kwargs)
self._angle_start = angle_start
self._angle_end = angle_end
self.set_property('fill-color', '#e8e8e8')
self.set_property('stroke-color', '#d8d8d8')
self.set_property('line-width', 4)
def get_icon(self):
return self._icon
def set_icon(self, icon_name, color):
self._icon = PieceIcon(self, icon_name, color)
self.get_parent().add_child(self._icon)
self._icon.construct()
def get_angle_start(self):
return self._angle_start
def get_angle_end(self):
return self._angle_end
def construct(self):
r = self.get_parent().get_radius()
data = 'M0,0 '
dx = r * math.cos(self._angle_start)
dy = - r * math.sin(self._angle_start)
data += 'l%f,%f ' % (dx, dy)
dx = r * math.cos(self._angle_end)
dy = - r * math.sin(self._angle_end)
data += 'A%f,%f 0 0,0 %f,%f ' % (r, r, dx, dy)
data += 'z'
self.set_property('data', data)
class DonutItem(goocanvas.Group):
def __init__(self, radius, **kwargs):
goocanvas.Group.__init__(self, **kwargs)
self._radius = radius
self._angle_start = 0
bg = goocanvas.Ellipse(radius_x=radius, radius_y=radius,
fill_color='#c2c3c5', line_width=0)
self.add_child(bg)
self._inner_radius = radius / 2
fg = goocanvas.Ellipse(radius_x=self._inner_radius,
radius_y=self._inner_radius,
fill_color='#d8d8d8', line_width=0)
self.add_child(fg)
def add_piece(self, perc, icon_name, color):
# FIXME can't override set_parent on the
# PieceItem and there is no signal. So we
# call a construct method on the childs for now.
angle_end = self._angle_start + perc * 2 * math.pi / 100
piece_item = PieceItem(self._angle_start, angle_end)
self._angle_start = angle_end
self.add_child(piece_item, 1)
piece_item.construct()
piece_item.set_icon(icon_name, color)
return piece_item
def remove_piece(self, piece_item):
index = self.find_child(piece_item)
self.remove_child(index)
icon = piece_item.get_icon()
index = self.find_child(icon)
self.remove_child(index)
def get_radius(self):
return self._radius
def get_inner_radius(self):
return self._inner_radius

52
sugar/canvas/IconItem.py Normal file
View File

@ -0,0 +1,52 @@
import re
import gobject
import gtk
import goocanvas
from sugar.util import GObjectSingletonMeta
class IconCache(gobject.GObject):
__metaclass__ = GObjectSingletonMeta
def __init__(self):
gobject.GObject.__init__(self)
self._icons = {}
def _create_icon(self, name, color, size):
theme = gtk.icon_theme_get_default()
info = theme.lookup_icon(name, size, 0)
icon_file = open(info.get_filename(), 'r')
data = icon_file.read()
icon_file.close()
if color != None:
style = '.fill-color {fill: %s;}' % (color)
data = re.sub('\.fill-color \{.*\}', style, data)
style = '.fill-and-stroke-color {fill: %s; stroke: %s;}' % (color, color)
data = re.sub('\.fill-and-stroke-color \{.*\}', style, data)
loader = gtk.gdk.pixbuf_loader_new_with_mime_type('image/svg-xml')
loader.set_size(size, size)
loader.write(data)
loader.close()
return loader.get_pixbuf()
def get_icon(self, name, color, size):
key = (name, color, size)
if self._icons.has_key(key):
return self._icons[key]
else:
icon = self._create_icon(name, color, size)
self._icons[key] = icon
return icon
class IconItem(goocanvas.Image):
def __init__(self, icon_name, color, size, **kwargs):
goocanvas.Image.__init__(self, **kwargs)
icon_cache = IconCache()
pixbuf = icon_cache.get_icon(icon_name, color, size)
self.set_property('pixbuf', pixbuf)

5
sugar/canvas/Makefile.am Normal file
View File

@ -0,0 +1,5 @@
sugardir = $(pythondir)/sugar/canvas
sugar_PYTHON = \
__init__.py \
DonutItem.py \
IconItem.py

0
sugar/canvas/__init__.py Normal file
View File

View File

@ -4,6 +4,20 @@ import random
import binascii import binascii
import string import string
import gobject
class GObjectSingletonMeta(gobject.GObjectMeta):
"""GObject Singleton Metaclass"""
def __init__(klass, name, bases, dict):
gobject.GObjectMeta.__init__(klass, name, bases, dict)
klass.__instance = None
def __call__(klass, *args, **kwargs):
if klass.__instance is None:
klass.__instance = gobject.GObjectMeta.__call__(klass, *args, **kwargs)
return klass.__instance
def _stringify_sha(sha_hash): def _stringify_sha(sha_hash):
"""Convert binary sha1 hash data into printable characters.""" """Convert binary sha1 hash data into printable characters."""
print_sha = "" print_sha = ""