Merge demo4 branch

master
Marco Pesenti Gritti 18 years ago
commit 58ddb555c4

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

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

@ -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'))

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

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

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

@ -20,9 +20,15 @@ class ActivityHost:
self._gdk_window = gtk.gdk.window_foreign_new(self._xid)
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):
return self._id
def get_icon_name(self):
return self._icon_name
def share(self):
self._people_window.share()
self._activity.share()

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

@ -13,7 +13,8 @@ class ChatController:
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):
name = self._id_to_name[activity_id]
del self._name_to_chat[name]

@ -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())

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

@ -8,7 +8,8 @@ import gobject
import wnck
from ActivityRegistry import ActivityRegistry
from HomeWindow import HomeWindow
from home.HomeWindow import HomeWindow
from home.HomeModel import HomeModel
from sugar import env
from Owner import ShellOwner
from sugar.presence.PresenceService import PresenceService
@ -37,9 +38,25 @@ class ShellDbusService(dbus.service.Object):
def show_console(self):
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):
ZOOM_MESH = 0
ZOOM_FRIENDS = 1
ZOOM_HOME = 2
ZOOM_ACTIVITY = 3
__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):
@ -48,6 +65,7 @@ class Shell(gobject.GObject):
self._screen = wnck.screen_get_default()
self._registry = registry
self._hosts = {}
self._zoom_level = Shell.ZOOM_HOME
def start(self):
session_bus = dbus.SessionBus()
@ -60,7 +78,8 @@ class Shell(gobject.GObject):
self._chat_controller = ChatController(self)
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._screen.connect('window-opened', self.__window_opened_cb)
@ -71,14 +90,16 @@ class Shell(gobject.GObject):
def __window_opened_cb(self, screen, window):
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):
if window.get_window_type() == wnck.WINDOW_NORMAL:
xid = window.get_xid()
activity = self._hosts[xid]
self.emit('activity-closed', activity.get_id())
host = self._hosts[xid]
self.emit('activity-closed', host)
del self._hosts[xid]
@ -154,3 +175,28 @@ class Shell(gobject.GObject):
def get_chat_controller(self):
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)

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

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

@ -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)

@ -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

@ -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

@ -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()

@ -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)

@ -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

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

@ -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())

@ -30,7 +30,7 @@ def get_display_number():
class XephyrProcess(Process):
def __init__(self):
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)
def get_name(self):
@ -43,7 +43,7 @@ class XephyrProcess(Process):
class XnestProcess(Process):
def __init__(self):
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)
def get_name(self):

@ -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()

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

@ -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

@ -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)

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

@ -4,6 +4,20 @@ import random
import binascii
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):
"""Convert binary sha1 hash data into printable characters."""
print_sha = ""

Loading…
Cancel
Save