Merge demo4 branch
This commit is contained in:
commit
58ddb555c4
@ -1 +1 @@
|
|||||||
SUBDIRS = browser chat terminal
|
SUBDIRS = browser chat groupchat terminal
|
||||||
|
@ -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
|
||||||
|
8
activities/groupchat/GroupChatActivity.py
Normal file
8
activities/groupchat/GroupChatActivity.py
Normal 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'))
|
6
activities/groupchat/Makefile.am
Normal file
6
activities/groupchat/Makefile.am
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
sugardir = $(pkgdatadir)/activities/groupchat
|
||||||
|
sugar_PYTHON = \
|
||||||
|
__init__.py \
|
||||||
|
GroupChatActivity.py
|
||||||
|
|
||||||
|
EXTRA_DIST = groupchat.activity
|
0
activities/groupchat/__init__.py
Normal file
0
activities/groupchat/__init__.py
Normal file
6
activities/groupchat/groupchat.activity
Normal file
6
activities/groupchat/groupchat.activity
Normal file
@ -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/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
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
|
@ -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]
|
||||||
|
@ -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 = \
|
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
|
||||||
|
@ -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)
|
||||||
|
@ -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 |
@ -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
|
||||||
|
40
shell/home/FriendsModel.py
Normal file
40
shell/home/FriendsModel.py
Normal 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
45
shell/home/FriendsView.py
Normal 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
13
shell/home/HomeModel.py
Normal 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
128
shell/home/HomeView.py
Normal 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
48
shell/home/HomeWindow.py
Normal 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
10
shell/home/Makefile.am
Normal 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
|
@ -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
63
shell/home/MeshView.py
Normal 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
0
shell/home/__init__.py
Normal 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
14
shell/sugar-zoom
Normal 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()
|
@ -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
114
sugar/canvas/DonutItem.py
Normal 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
52
sugar/canvas/IconItem.py
Normal 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
5
sugar/canvas/Makefile.am
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
sugardir = $(pythondir)/sugar/canvas
|
||||||
|
sugar_PYTHON = \
|
||||||
|
__init__.py \
|
||||||
|
DonutItem.py \
|
||||||
|
IconItem.py
|
0
sugar/canvas/__init__.py
Normal file
0
sugar/canvas/__init__.py
Normal 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 = ""
|
||||||
|
Loading…
Reference in New Issue
Block a user