Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarco Pesenti Gritti <marco@localhost.localdomain>2008-06-10 08:39:45 (GMT)
committer Marco Pesenti Gritti <marco@localhost.localdomain>2008-06-10 08:39:45 (GMT)
commitcaa8b4ff5ae93b625cb1990cc6a62d6b3a18bb53 (patch)
tree51aa8e2a4ca9591d622680e3e28bc7f955fe8c71 /src
parent550aa20e5f2672c1f47f07fdd47ece9e1dcf1d16 (diff)
parentf91746f68e327660c6ec2ebc51608fe4eda3f60f (diff)
Merge branch 'master' of git://dev.laptop.org/users/marco/sugar
Diffstat (limited to 'src')
-rw-r--r--src/model/homemodel.py75
-rw-r--r--src/shellservice.py6
-rw-r--r--src/view/Shell.py49
-rw-r--r--src/view/frame/activitiestray.py6
-rw-r--r--src/view/frame/friendstray.py6
-rw-r--r--src/view/home/HomeWindow.py11
-rw-r--r--src/view/home/Makefile.am1
-rw-r--r--src/view/home/activitiesring.py12
-rw-r--r--src/view/home/launchbox.py94
9 files changed, 171 insertions, 89 deletions
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