From caa8b4ff5ae93b625cb1990cc6a62d6b3a18bb53 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 10 Jun 2008 08:39:45 +0000 Subject: Merge branch 'master' of git://dev.laptop.org/users/marco/sugar --- (limited to 'src') diff --git a/src/model/homemodel.py b/src/model/homemodel.py index 5538f84..a75adcf 100644 --- a/src/model/homemodel.py +++ b/src/model/homemodel.py @@ -42,18 +42,21 @@ class HomeModel(gobject.GObject): 'activity-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])), - 'activity-started': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])), 'activity-removed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])), 'active-activity-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])), - 'pending-activity-changed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])) + 'launch-started': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, + ([gobject.TYPE_PYOBJECT])), + 'launch-completed': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, + ([gobject.TYPE_PYOBJECT])), + 'launch-failed': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, + ([gobject.TYPE_PYOBJECT])) } def __init__(self): @@ -61,7 +64,6 @@ class HomeModel(gobject.GObject): self._activities = [] self._active_activity = None - self._pending_activity = None screen = wnck.screen_get_default() screen.connect('window-opened', self._window_opened_cb) @@ -78,7 +80,7 @@ class HomeModel(gobject.GObject): def get_previous_activity(self): activities = self._get_activities_with_window() - i = activities.index(self._pending_activity) + i = activities.index(self._active_activity) if len(activities) == 0: return None elif i - 1 >= 0: @@ -88,7 +90,7 @@ class HomeModel(gobject.GObject): def get_next_activity(self): activities = self._get_activities_with_window() - i = activities.index(self._pending_activity) + i = activities.index(self._active_activity) if len(activities) == 0: return None elif i + 1 < len(activities): @@ -96,34 +98,8 @@ class HomeModel(gobject.GObject): else: return activities[0] - def get_pending_activity(self): - """Returns the activity that would be seen in the Activity zoom level - - In the Home (or Neighborhood or Groups) zoom level, this - indicates the activity that would become active if the user - switched to the Activity zoom level. (In the Activity zoom - level, this just returns the currently-active activity.) - Unlike get_active_activity(), this never returns None as long - as there is any activity running. - """ - return self._pending_activity - - def _set_pending_activity(self, home_activity): - if self._pending_activity == home_activity: - return - - self._pending_activity = home_activity - self.emit('pending-activity-changed', self._pending_activity) - def get_active_activity(self): - """Returns the activity that the user is currently working in - - In the Activity zoom level, this returns the currently-active - activity. In the other zoom levels, it returns the activity - that was most-recently active in the Activity zoom level, or - None if the most-recently-active activity is no longer - running. - """ + """Returns the activity that the user is currently working in""" return self._active_activity def _set_active_activity(self, home_activity): @@ -181,10 +157,10 @@ class HomeModel(gobject.GObject): home_activity.set_window(window) home_activity.props.launching = False - self.emit('activity-started', home_activity) + self.emit('launch-completed', home_activity) - if self._pending_activity is None: - self._set_pending_activity(home_activity) + if self._active_activity is None: + self._set_active_activity(home_activity) def _window_closed_cb(self, screen, window): if window.get_window_type() == wnck.WINDOW_NORMAL: @@ -219,7 +195,6 @@ class HomeModel(gobject.GObject): act = self._get_activity_by_xid(window.get_xid()) if act is not None: - self._set_pending_activity(act) self._set_active_activity(act) def _add_activity(self, home_activity): @@ -228,20 +203,16 @@ class HomeModel(gobject.GObject): def _remove_activity(self, home_activity): if home_activity == self._active_activity: - self._set_active_activity(None) - - if home_activity == self._pending_activity: - # Figure out the new _pending_activity windows = wnck.screen_get_default().get_windows_stacked() windows.reverse() for window in windows: new_activity = self._get_activity_by_xid(window.get_xid()) if new_activity is not None: - self._set_pending_activity(new_activity) + self._set_active_activity(new_activity) break else: logging.error('No activities are running') - self._set_pending_activity(None) + self._set_active_activity(None) self.emit('activity-removed', home_activity) self._activities.remove(home_activity) @@ -253,7 +224,7 @@ class HomeModel(gobject.GObject): else: logging.error('Model for window %d does not exist.' % xid) - def notify_activity_launch(self, activity_id, service_name): + def notify_launch(self, activity_id, service_name): registry = activity.get_registry() activity_info = registry.get_activity(service_name) if not activity_info: @@ -264,11 +235,15 @@ class HomeModel(gobject.GObject): home_activity.props.launching = True self._add_activity(home_activity) + self._set_active_activity(home_activity) + + self.emit('launch-started', home_activity) + # FIXME: better learn about finishing processes by receiving a signal. # Now just check whether an activity has a window after ~90sec gobject.timeout_add(90000, self._check_activity_launched, activity_id) - def notify_activity_launch_failed(self, activity_id): + def notify_launch_failed(self, activity_id): home_activity = self._get_activity_by_id(activity_id) if home_activity: logging.debug("Activity %s (%s) launch failed" % \ @@ -279,10 +254,12 @@ class HomeModel(gobject.GObject): logging.error('Model for activity id %s does not exist.' % activity_id) + self.emit('launch-failed', home_activity) + def _check_activity_launched(self, activity_id): home_activity = self._get_activity_by_id(activity_id) if home_activity and home_activity.props.launching: logging.debug('Activity %s still launching, assuming it failed...' % activity_id) - self.notify_activity_launch_failed(activity_id) + self.notify_launch_failed(activity_id) return False diff --git a/src/shellservice.py b/src/shellservice.py index 3d90779..706f2f2 100644 --- a/src/shellservice.py +++ b/src/shellservice.py @@ -79,12 +79,14 @@ class ShellService(dbus.service.Object): @dbus.service.method(_DBUS_SHELL_IFACE, in_signature="ss", out_signature="") def NotifyLaunch(self, bundle_id, activity_id): - self._shell.notify_launch(bundle_id, activity_id) + home = self._shell.get_model().get_home() + home.notify_launch(activity_id, bundle_id) @dbus.service.method(_DBUS_SHELL_IFACE, in_signature="s", out_signature="") def NotifyLaunchFailure(self, activity_id): - self._shell.notify_launch_failure(activity_id) + home = self._shell.get_model().get_home() + home.notify_launch_failed(activity_id) @dbus.service.signal(_DBUS_OWNER_IFACE, signature="s") def ColorChanged(self, color): diff --git a/src/view/Shell.py b/src/view/Shell.py index 875e9a5..1095878 100644 --- a/src/view/Shell.py +++ b/src/view/Shell.py @@ -56,7 +56,6 @@ class Shell(gobject.GObject): self._hosts = {} self._screen = wnck.screen_get_default() self._current_host = None - self._pending_host = None self._screen_rotation = 0 self._key_handler = KeyHandler() @@ -67,12 +66,12 @@ class Shell(gobject.GObject): self._home_window.show() home_model = self._model.get_home() - home_model.connect('activity-started', self._activity_started_cb) + home_model.connect('launch-started', self.__launch_started_cb) + home_model.connect('launch-failed', self.__launch_failed_cb) + home_model.connect('launch-completed', self.__launch_completed_cb) home_model.connect('activity-removed', self._activity_removed_cb) home_model.connect('active-activity-changed', self._active_activity_changed_cb) - home_model.connect('pending-activity-changed', - self._pending_activity_changed_cb) gobject.idle_add(self._start_journal_idle) @@ -95,7 +94,19 @@ class Shell(gobject.GObject): if registry.get_activity('org.laptop.JournalActivity'): self.start_activity('org.laptop.JournalActivity') - def _activity_started_cb(self, home_model, home_activity): + def __launch_started_cb(self, home_model, home_activity): + if home_activity.get_type() == 'org.laptop.JournalActivity': + return + + self._screen.toggle_showing_desktop(True) + self._home_window.set_zoom_level(shellmodel.ShellModel.ZOOM_ACTIVITY) + self._home_window.launch_box.zoom_in() + + def __launch_failed_cb(self, home_model, home_activity): + if self._screen.get_showing_desktop(): + self._home_window.set_zoom_level(shellmodel.ShellModel.ZOOM_HOME) + + def __launch_completed_cb(self, home_model, home_activity): activity_host = ActivityHost(home_activity) self._hosts[activity_host.get_xid()] = activity_host if home_activity.get_type() in self._activities_starting: @@ -110,22 +121,17 @@ class Shell(gobject.GObject): del self._hosts[xid] def _active_activity_changed_cb(self, home_model, home_activity): + host = None if home_activity: - host = self._hosts[home_activity.get_xid()] - else: - host = None + xid = home_activity.get_xid() + if xid: + host = self._hosts[home_activity.get_xid()] if self._current_host: self._current_host.set_active(False) self._current_host = host - def _pending_activity_changed_cb(self, home_model, home_activity): - if home_activity: - self._pending_host = self._hosts[home_activity.get_xid()] - else: - self._pending_host = None - def get_model(self): return self._model @@ -150,17 +156,6 @@ class Shell(gobject.GObject): handle = ActivityHandle(activity_id) activityfactory.create(bundle_id, handle) - def notify_launch(self, bundle_id, activity_id): - # Zoom to Home for launch feedback - self.set_zoom_level(shellmodel.ShellModel.ZOOM_HOME) - - home_model = self._model.get_home() - home_model.notify_activity_launch(activity_id, bundle_id) - - def notify_launch_failure(self, activity_id): - home_model = self._model.get_home() - home_model.notify_activity_launch_failed(activity_id) - def start_activity(self, activity_type): if activity_type in self._activities_starting: logging.debug("This activity is still launching.") @@ -192,8 +187,8 @@ class Shell(gobject.GObject): self.take_activity_screenshot() if level == shellmodel.ShellModel.ZOOM_ACTIVITY: - if self._pending_host is not None: - self._pending_host.present() + if self._current_host is not None: + self._current_host.present() self._screen.toggle_showing_desktop(False) else: self._model.set_zoom_level(level) diff --git a/src/view/frame/activitiestray.py b/src/view/frame/activitiestray.py index 020cb68..90be6e9 100644 --- a/src/view/frame/activitiestray.py +++ b/src/view/frame/activitiestray.py @@ -191,7 +191,7 @@ class ActivitiesTray(HTray): self._home_model = shellmodel.get_instance().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._home_model.connect('active-activity-changed', self.__activity_changed_cb) self._invites = shellmodel.get_instance().get_invites() @@ -227,7 +227,9 @@ class ActivitiesTray(HTray): def __activity_clicked_cb(self, button, home_activity): if button.props.active: logging.debug('ActivitiesTray.__activity_clicked_cb') - home_activity.get_window().activate(gtk.get_current_event_time()) + window = home_activity.get_window() + if window: + window.activate(gtk.get_current_event_time()) def __invite_clicked_cb(self, icon, invite): self._invites.remove_invite(invite) diff --git a/src/view/frame/friendstray.py b/src/view/frame/friendstray.py index 86decaa..b9d8c07 100644 --- a/src/view/frame/friendstray.py +++ b/src/view/frame/friendstray.py @@ -54,8 +54,8 @@ class FriendsTray(VTray): reply_handler=self._get_activities_cb) home_model = shellmodel.get_instance().get_home() - home_model.connect('pending-activity-changed', - self._pending_activity_changed_cb) + home_model.connect('active-activity-changed', + self._active_activity_changed_cb) def _get_activities_cb(self, activities_list): for act in activities_list: @@ -117,7 +117,7 @@ class FriendsTray(VTray): self._left_hid = activity_ps.connect( 'buddy-left', self.__buddy_left_cb) - def _pending_activity_changed_cb(self, home_model, home_activity): + def _active_activity_changed_cb(self, home_model, home_activity): if home_activity is None: return diff --git a/src/view/home/HomeWindow.py b/src/view/home/HomeWindow.py index 7e0a0c5..9151d46 100644 --- a/src/view/home/HomeWindow.py +++ b/src/view/home/HomeWindow.py @@ -24,12 +24,14 @@ from view.home.MeshBox import MeshBox from view.home.HomeBox import HomeBox from view.home.FriendsBox import FriendsBox from view.home.transitionbox import TransitionBox +from view.home.launchbox import LaunchBox from model.shellmodel import ShellModel _HOME_PAGE = 0 _FRIENDS_PAGE = 1 _MESH_PAGE = 2 _TRANSITION_PAGE = 3 +_LAUNCH_PAGE = 4 class HomeWindow(gtk.Window): def __init__(self): @@ -65,6 +67,7 @@ class HomeWindow(gtk.Window): self._friends_box = FriendsBox() self._mesh_box = MeshBox() self._transition_box = TransitionBox() + self.launch_box = LaunchBox() self._activate_view() self._canvas.set_root(self._home_box) @@ -98,12 +101,16 @@ class HomeWindow(gtk.Window): self._home_box.suspend() elif self._level == ShellModel.ZOOM_MESH: self._mesh_box.suspend() + elif self._level == ShellModel.ZOOM_ACTIVITY: + self.launch_box.suspend() def _activate_view(self): if self._level == ShellModel.ZOOM_HOME: self._home_box.resume() elif self._level == ShellModel.ZOOM_MESH: self._mesh_box.resume() + elif self._level == ShellModel.ZOOM_ACTIVITY: + self.launch_box.resume() def _visibility_notify_event_cb(self, window, event): if event.state == gtk.gdk.VISIBILITY_FULLY_OBSCURED: @@ -124,6 +131,8 @@ class HomeWindow(gtk.Window): size = style.LARGE_ICON_SIZE elif level == ShellModel.ZOOM_MESH: size = style.STANDARD_ICON_SIZE + elif level == ShellModel.ZOOM_ACTIVITY: + size = style.XLARGE_ICON_SIZE self._transition_box.set_size(size) @@ -135,6 +144,8 @@ class HomeWindow(gtk.Window): elif self._level == ShellModel.ZOOM_MESH: self._canvas.set_root(self._mesh_box) self._mesh_box.focus_search_entry() + elif self._level == ShellModel.ZOOM_ACTIVITY: + self._canvas.set_root(self.launch_box) def get_home_box(self): return self._home_box diff --git a/src/view/home/Makefile.am b/src/view/home/Makefile.am index 4ae3410..5306e2b 100644 --- a/src/view/home/Makefile.am +++ b/src/view/home/Makefile.am @@ -5,6 +5,7 @@ sugar_PYTHON = \ activitiesring.py \ FriendView.py \ FriendsBox.py \ + launchbox.py \ HomeBox.py \ HomeWindow.py \ MeshBox.py \ diff --git a/src/view/home/activitiesring.py b/src/view/home/activitiesring.py index 1d3c9d3..dccb066 100644 --- a/src/view/home/activitiesring.py +++ b/src/view/home/activitiesring.py @@ -172,16 +172,16 @@ class CurrentActivityIcon(CanvasIcon, hippo.CanvasItem): CanvasIcon.__init__(self, cache=True) self._home_model = shellmodel.get_instance().get_home() - if self._home_model.get_pending_activity() is not None: - self._update(self._home_model.get_pending_activity()) + if self._home_model.get_active_activity() is not None: + self._update(self._home_model.get_active_activity()) - self._home_model.connect('pending-activity-changed', - self.__pending_activity_changed_cb) + self._home_model.connect('active-activity-changed', + self.__active_activity_changed_cb) self.connect('button-release-event', self.__button_release_event_cb) def __button_release_event_cb(self, icon, event): - self._home_model.get_pending_activity().get_window().activate(1) + self._home_model.get_active_activity().get_window().activate(1) def _update(self, home_activity): _logger.debug('CurrentActivityIcon._update') @@ -195,7 +195,7 @@ class CurrentActivityIcon(CanvasIcon, hippo.CanvasItem): palette = CurrentActivityPalette(home_activity) self.set_palette(palette) - def __pending_activity_changed_cb(self, home_model, home_activity): + def __active_activity_changed_cb(self, home_model, home_activity): self._update(home_activity) class RingLayout(gobject.GObject, hippo.CanvasLayout): diff --git a/src/view/home/launchbox.py b/src/view/home/launchbox.py new file mode 100644 index 0000000..a70cb61 --- /dev/null +++ b/src/view/home/launchbox.py @@ -0,0 +1,94 @@ +# Copyright (C) 2008, Red Hat, Inc. +# +# 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 +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import hippo +import gobject +import logging + +from sugar.graphics import style +from sugar.graphics import animator +from sugar.graphics.xocolor import XoColor + +from model import shellmodel +from view.pulsingicon import CanvasPulsingIcon + +class LaunchBox(hippo.CanvasBox): + def __init__(self): + gobject.GObject.__init__( + self, background_color=style.COLOR_WHITE.get_int()) + + self._activity_icon = CanvasPulsingIcon() + + # FIXME support non-xo colors in CanvasPulsingIcon + self._activity_icon.props.base_color = \ + XoColor('%s,%s' % (style.COLOR_BUTTON_GREY.get_svg(), + style.COLOR_TRANSPARENT.get_svg())) + + vbox = hippo.CanvasBox(orientation=hippo.ORIENTATION_VERTICAL) + vbox.append(self._activity_icon, hippo.PACK_EXPAND) + self.append(vbox, hippo.PACK_EXPAND) + + self._animator = animator.Animator(1.0) + + self._home = shellmodel.get_instance().get_home() + self._home.connect('active-activity-changed', + self.__active_activity_changed_cb) + + self._update_icon() + + def zoom_in(self): + logging.debug('zooming in to activity') + + self._activity_icon.props.size = style.STANDARD_ICON_SIZE + + self._animator.remove_all() + self._animator.add(_Animation(self._activity_icon, + style.STANDARD_ICON_SIZE, + style.XLARGE_ICON_SIZE)) + self._animator.start() + + logging.debug('starting pulse') + + self._activity_icon.props.pulsing = True + + def suspend(self): + self._activity_icon.props.paused = True + + def resume(self): + self._activity_icon.props.paused = False + + def _update_icon(self): + activity = self._home.get_active_activity() + if activity: + self._activity_icon.props.file_name = activity.get_icon_path() + self._activity_icon.props.pulse_color = activity.get_icon_color() + else: + self._activity_icon.props.file_name = None + + def __active_activity_changed_cb(self, model, activity): + self._update_icon() + +class _Animation(animator.Animation): + def __init__(self, icon, start_size, end_size): + animator.Animation.__init__(self, 0.0, 1.0) + + self._icon = icon + self.start_size = start_size + self.end_size = end_size + + def next_frame(self, current): + d = (self.end_size - self.start_size) * current + self._icon.props.size = self.start_size + d -- cgit v0.9.1