diff options
author | Tomeu Vizoso <tomeu@tomeuvizoso.net> | 2008-04-01 19:18:34 (GMT) |
---|---|---|
committer | Tomeu Vizoso <tomeu@tomeuvizoso.net> | 2008-04-01 19:18:34 (GMT) |
commit | 4094a96d0c52ce56c02e42d2524f5ae425e9c6e8 (patch) | |
tree | ae5a46cfcd6f1798c1ad4943ffe6b54b80a10183 /src | |
parent | 6f92d9077eefc81a4bffd5f451ea5c5cfe34b4f7 (diff) |
New activities tray
Diffstat (limited to 'src')
-rw-r--r-- | src/view/frame/activitiestray.py | 303 | ||||
-rw-r--r-- | src/view/frame/frame.py | 14 |
2 files changed, 187 insertions, 130 deletions
diff --git a/src/view/frame/activitiestray.py b/src/view/frame/activitiestray.py index 11e812c..2060783 100644 --- a/src/view/frame/activitiestray.py +++ b/src/view/frame/activitiestray.py @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. +# Copyright (C) 2008 One Laptop Per Child # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -15,145 +15,194 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import os +import statvfs import logging +from gettext import gettext as _ -import hippo +import gtk -from sugar.graphics.tray import TrayButton +from sugar import env +from sugar import profile +from sugar.graphics import style from sugar.graphics.tray import HTray +from sugar.graphics.radiotoolbutton import RadioToolButton from sugar.graphics.icon import Icon -from sugar.graphics import style -from sugar import profile -from sugar import activity -from sugar import env +from sugar.graphics.palette import Palette +from sugar.graphics.menuitem import MenuItem + +from view.frame.frameinvoker import FrameWidgetInvoker + +class _Palette(Palette): + def __init__(self, widget, home_activity): + Palette.__init__(self, '', menu_after_content=True) + + self.props.invoker = FrameWidgetInvoker(widget) + self.set_group_id('frame') + + if home_activity.props.launching: + home_activity.connect('notify::launching', self._launching_changed_cb) + self.set_primary_text(_('Starting...')) + else: + self.setup_palette() + + def _launching_changed_cb(self, home_activity, pspec): + if not home_activity.props.launching: + self.setup_palette() + + def setup_palette(self): + raise NotImplementedError + +class ActivityPalette(_Palette): + def __init__(self, widget, home_activity): + _Palette.__init__(self, widget, home_activity) + self._home_activity = home_activity + + def setup_palette(self): + self.set_primary_text(self._home_activity.get_title()) + + menu_item = MenuItem(_('Resume'), 'activity-start') + menu_item.connect('activate', self.__resume_activate_cb) + self.menu.append(menu_item) + menu_item.show() + + """ Not implemented yet + menu_item = MenuItem(_('Share with'), 'zoom-neighborhood') + #menu_item.connect('activate', self.__share_activate_cb) + self.menu.append(menu_item) + menu_item.show() + + menu_item = MenuItem(_('Keep')) + icon = Icon(icon_name='document-save', icon_size=gtk.ICON_SIZE_MENU, + xo_color=profile.get_color()) + menu_item.set_image(icon) + icon.show() + #menu_item.connect('activate', self.__keep_activate_cb) + self.menu.append(menu_item) + menu_item.show() + """ + + separator = gtk.SeparatorMenuItem() + self.menu.append(separator) + separator.show() + + menu_item = MenuItem(_('Stop'), 'activity-stop') + menu_item.connect('activate', self.__stop_activate_cb) + self.menu.append(menu_item) + menu_item.show() + + def __resume_activate_cb(self, menu_item): + self._home_activity.get_window().activate(1) + + def __stop_activate_cb(self, menu_item): + self._home_activity.get_window().close(1) + +class JournalPalette(_Palette): + def __init__(self, widget, home_activity): + _Palette.__init__(self, widget, home_activity) + self._home_activity = home_activity + self._progress_bar = None + self._free_space_label = None + + def setup_palette(self): + self.set_primary_text(self._home_activity.get_title()) + + vbox = gtk.VBox() + self.set_content(vbox) + vbox.show() + + self._progress_bar = gtk.ProgressBar() + vbox.add(self._progress_bar) + self._progress_bar.show() + + self._free_space_label = gtk.Label() + self._free_space_label.set_alignment(0.5, 0.5) + vbox.add(self._free_space_label) + self._free_space_label.show() + + self.connect('popup', self.__popup_cb) + + menu_item = MenuItem(_('Show contents')) + + icon = Icon(file=self._home_activity.get_icon_path(), + icon_size=gtk.ICON_SIZE_MENU, + xo_color=self._home_activity.get_icon_color()) + menu_item.set_image(icon) + icon.show() -from activitybutton import ActivityButton -import config + menu_item.connect('activate', self.__open_activate_cb) + self.menu.append(menu_item) + menu_item.show() -class InviteButton(TrayButton): - def __init__(self, activity_model, invite): - TrayButton.__init__(self) + def __open_activate_cb(self, menu_item): + self._home_activity.get_window().activate(1) - icon = Icon(file=activity_model.get_icon_name(), - xo_color=activity_model.get_color()) - self.set_icon_widget(icon) - icon.show() + def __popup_cb(self, palette): + # TODO: we should be able to ask the datastore this info, as that's the + # component that knows about mount points. + stat = os.statvfs(env.get_profile_path()) + free_space = stat[statvfs.F_BSIZE] * stat[statvfs.F_BAVAIL] + total_space = stat[statvfs.F_BSIZE] * stat[statvfs.F_BLOCKS] - self._invite = invite + fraction = (total_space - free_space) / float(total_space) + self._progress_bar.props.fraction = fraction + self._free_space_label.props.label = _('%(free_space)d MB Free') % \ + {'free_space': free_space / (1024 * 1024)} - def get_activity_id(self): - return self._invite.get_activity_id() +class ActivityButton(RadioToolButton): + def __init__(self, home_activity, group): + RadioToolButton.__init__(self, group=group) - def get_bundle_id(self): - return self._invite.get_bundle_id() + self._home_activity = home_activity - def get_invite(self): - return self._invite + icon = Icon(xo_color=home_activity.get_icon_color()) + if home_activity.get_icon_path(): + icon.props.file = home_activity.get_icon_path() + else: + icon.props.icon_name = 'image-missing' + self.set_icon_widget(icon) + icon.show() + + if self._home_activity.get_type() == "org.laptop.JournalActivity": + palette = JournalPalette(self, self._home_activity) + else: + palette = ActivityPalette(self, self._home_activity) + self.set_palette(palette) -class ActivitiesTray(hippo.CanvasBox): +class ActivitiesTray(HTray): def __init__(self, shell): - hippo.CanvasBox.__init__(self, orientation=hippo.ORIENTATION_HORIZONTAL) + HTray.__init__(self) + self._buttons = {} self._shell = shell - self._shell_model = self._shell.get_model() - self._invite_to_item = {} - self._invites = self._shell_model.get_invites() - self._config = self._load_config() - - self._tray = HTray() - self.append(hippo.CanvasWidget(widget=self._tray), hippo.PACK_EXPAND) - self._tray.show() - - registry = activity.get_registry() - registry.get_activities_async(reply_handler=self._get_activities_cb) - - registry.connect('activity-added', self._activity_added_cb) - registry.connect('activity-removed', self._activity_removed_cb) - - for invite in self._invites: - self.add_invite(invite) - self._invites.connect('invite-added', self._invite_added_cb) - self._invites.connect('invite-removed', self._invite_removed_cb) - - def _load_config(self): - cfg = [] - - f = open(os.path.join(config.data_path, 'activities.defaults'), 'r') - for line in f.readlines(): - line = line.strip() - if line and not line.startswith('#'): - cfg.append(line) - f.close() - - return cfg - - def _get_activities_cb(self, activity_list): - known_activities = [] - unknown_activities = [] - name_to_activity = {} - - while activity_list: - info = activity_list.pop() - name_to_activity[info.bundle_id] = info - - if info.bundle_id in self._config: - known_activities.append(info) - else: - unknown_activities.append(info) - - sorted_activities = [] - for name in self._config: - if name in name_to_activity: - sorted_activities.append(name_to_activity[name]) - - for info in sorted_activities + unknown_activities: - if info.show_launcher: - self.add_activity(info) - - def _activity_clicked_cb(self, icon): - self._shell.start_activity(icon.get_bundle_id()) - - def _invite_clicked_cb(self, icon): - self._invites.remove_invite(icon.get_invite()) - self._shell.join_activity(icon.get_bundle_id(), - icon.get_activity_id()) - - def _invite_added_cb(self, invites, invite): - self.add_invite(invite) - - def _invite_removed_cb(self, invites, invite): - self.remove_invite(invite) - - def _remove_activity_cb(self, item): - self._tray.remove_item(item) - - def _activity_added_cb(self, activity_registry, activity_info): - self.add_activity(activity_info) - - def _activity_removed_cb(self, activity_registry, activity_info): - for item in self._tray.get_children(): - if item.get_bundle_id() == activity_info.bundle_id: - self._tray.remove_item(item) - return - - def add_activity(self, activity_info): - item = ActivityButton(activity_info) - item.connect('clicked', self._activity_clicked_cb) - item.connect('remove_activity', self._remove_activity_cb) - self._tray.add_item(item, -1) - item.show() - - def add_invite(self, invite): - mesh = self._shell_model.get_mesh() - activity_model = mesh.get_activity(invite.get_activity_id()) - if activity: - item = InviteButton(activity_model, invite) - item.connect('clicked', self._invite_clicked_cb) - self._tray.add_item(item, 0) - item.show() - - self._invite_to_item[invite] = item - - def remove_invite(self, invite): - self._tray.remove_item(self._invite_to_item[invite]) - del self._invite_to_item[invite] + self._home_model = shell.get_model().get_home() + self._home_model.connect('activity-added', self.__activity_added_cb) + self._home_model.connect('activity-removed', self.__activity_removed_cb) + self._home_model.connect('pending-activity-changed', self.__activity_changed_cb) + + def __activity_added_cb(self, home_model, home_activity): + logging.debug('__activity_added_cb: %r' % home_activity) + if self.get_children(): + group = self.get_children()[0] + else: + group = None + + button = ActivityButton(home_activity, group) + self.add_item(button) + self._buttons[home_activity.get_activity_id()] = button + button.connect('toggled', self.__activity_toggled_cb, home_activity) + button.show() + + def __activity_removed_cb(self, home_model, home_activity): + logging.debug('__activity_removed_cb: %r' % home_activity) + button = self._buttons[home_activity.get_activity_id()] + self.remove_item(button) + del self._buttons[home_activity.get_activity_id()] + + def __activity_changed_cb(self, home_model, home_activity): + logging.debug('__activity_changed_cb: %r' % home_activity) + button = self._buttons[home_activity.get_activity_id()] + button.props.active = True + + def __activity_toggled_cb(self, button, home_activity): + home_activity.get_window().activate(1) + diff --git a/src/view/frame/frame.py b/src/view/frame/frame.py index e0230ee..5fea0d1 100644 --- a/src/view/frame/frame.py +++ b/src/view/frame/frame.py @@ -166,17 +166,25 @@ class Frame(object): def _create_top_panel(self): panel = self._create_panel(gtk.POS_TOP) + # TODO: setting box_width and hippo.PACK_EXPAND looks like a hack to me. + # Why hippo isn't respecting the request size of these controls? + zoom_toolbar = ZoomToolbar(self._shell) - panel.append(hippo.CanvasWidget(widget=zoom_toolbar), hippo.PACK_EXPAND) + panel.append(hippo.CanvasWidget(widget=zoom_toolbar, + box_width=4*style.GRID_CELL_SIZE)) zoom_toolbar.show() + activities_tray = ActivitiesTray(self._shell) + panel.append(hippo.CanvasWidget(widget=activities_tray), + hippo.PACK_EXPAND) + activities_tray.show() + return panel def _create_bottom_panel(self): panel = self._create_panel(gtk.POS_BOTTOM) - box = ActivitiesTray(self._shell) - panel.append(box, hippo.PACK_EXPAND) + # Append devices tray. return panel |