Hi,
these two patches are the continuation of the work to implement a new
favorites screen in the home view.
Thanks,
Tomeu
From 40bdb87d43d0644edf62e1e727b6e936ccf7b00d Mon Sep 17 00:00:00 2001
From: Tomeu Vizoso <[EMAIL PROTECTED](none)>
Date: Wed, 11 Jun 2008 17:38:17 +0200
Subject: [PATCH] Persist position of favorite icons
---
service/activityregistryservice.py | 12 ++++-
service/bundleregistry.py | 106 ++++++++++++++++++++++++++----------
src/view/home/activitiesring.py | 36 ++++++++++---
3 files changed, 117 insertions(+), 37 deletions(-)
diff --git a/service/activityregistryservice.py b/service/activityregistryservice.py
index bf98ef9..a42eae0 100644
--- a/service/activityregistryservice.py
+++ b/service/activityregistryservice.py
@@ -109,6 +109,12 @@ class ActivityRegistry(dbus.service.Object):
registry = bundleregistry.get_registry()
registry.set_bundle_favorite(bundle_id, version, favorite)
+ @dbus.service.method(_ACTIVITY_REGISTRY_IFACE,
+ in_signature='siii', out_signature='')
+ def SetActivityPosition(self, bundle_id, version, x, y):
+ registry = bundleregistry.get_registry()
+ registry.set_bundle_position(bundle_id, version, x, y)
+
@dbus.service.signal(_ACTIVITY_REGISTRY_IFACE, signature='a{sv}')
def ActivityAdded(self, activity_info):
pass
@@ -125,6 +131,8 @@ class ActivityRegistry(dbus.service.Object):
registry = bundleregistry.get_registry()
favorite = registry.is_bundle_favorite(bundle.get_bundle_id(),
bundle.get_activity_version())
+ x, y = registry.get_bundle_position(bundle.get_bundle_id(),
+ bundle.get_activity_version())
return {'name': bundle.get_name(),
'icon': bundle.get_icon(),
'bundle_id': bundle.get_bundle_id(),
@@ -133,7 +141,9 @@ class ActivityRegistry(dbus.service.Object):
'command': bundle.get_command(),
'show_launcher': bundle.get_show_launcher(),
'favorite': favorite,
- 'installation_time': bundle.get_installation_time()}
+ 'installation_time': bundle.get_installation_time(),
+ 'position_x': x,
+ 'position_y': y}
def _bundle_added_cb(self, bundle_registry, bundle):
self.ActivityAdded(self._bundle_to_dict(bundle))
diff --git a/service/bundleregistry.py b/service/bundleregistry.py
index 8b7f09b..e7c30a8 100644
--- a/service/bundleregistry.py
+++ b/service/bundleregistry.py
@@ -16,6 +16,7 @@
import os
import logging
+import traceback
import gobject
import simplejson
@@ -48,7 +49,14 @@ class BundleRegistry(gobject.GObject):
self._scan_directory(activity_dir)
self._last_defaults_mtime = -1
- self._favorite_bundles = self._load_favorites()
+ self._favorite_bundles = {}
+
+ try:
+ self._load_favorites()
+ except Exception, e:
+ logging.error('Error while loading favorite_activities\n%s.' \
+ % traceback.format_exc())
+
self._merge_default_favorites()
def _get_activity_directories(self):
@@ -74,24 +82,34 @@ class BundleRegistry(gobject.GObject):
return defaults
+ def _get_favorite_key(self, bundle_id, version):
+ """We use a string as a composite key for the favorites dictionary
+ because JSON doesn't support tuples and python won't accept a list
+ as a dictionary key.
+ """
+ if ' ' in bundle_id:
+ raise ValueError('bundle_id cannot contain spaces')
+ return '%s %s' % (bundle_id, version)
+
def _load_favorites(self):
- favorite_bundles = []
favorites_path = env.get_profile_path('favorite_activities')
if os.path.exists(favorites_path):
- try:
- favorites_data = simplejson.load(open(favorites_path))
- except ValueError, e:
- logging.error('Error while loading favorite_activities: %r.' %
- e)
- else:
- # Old structure used to be a list, instead of a dictionary.
- if isinstance(favorites_data, list):
- favorite_bundles = favorites_data
- else:
- favorite_bundles = favorites_data['favorites']
- self._last_defaults_mtime = favorites_data['defaults-mtime']
+ favorites_data = simplejson.load(open(favorites_path))
+
+ favorite_bundles = favorites_data['favorites']
+ if not isinstance(favorite_bundles, dict):
+ raise ValueError('Invalid format in %s.' % favorites_path)
+ if favorite_bundles:
+ first_key = favorite_bundles.keys()[0]
+ if not isinstance(first_key, basestring):
+ raise ValueError('Invalid format in %s.' % favorites_path)
- return favorite_bundles
+ first_value = favorite_bundles.values()[0]
+ if first_value is not None and not isinstance(first_value, dict):
+ raise ValueError('Invalid format in %s.' % favorites_path)
+
+ self._last_defaults_mtime = float(favorites_data['defaults-mtime'])
+ self._favorite_bundles = favorite_bundles
def _merge_default_favorites(self):
default_activities = []
@@ -117,9 +135,9 @@ class BundleRegistry(gobject.GObject):
max_version < bundle.get_activity_version():
max_version = bundle.get_activity_version()
- if max_version > -1 and \
- [bundle_id, max_version] not in self._favorite_bundles:
- self._favorite_bundles.append([bundle_id, max_version])
+ key = self._get_favorite_key(bundle_id, max_version)
+ if max_version > -1 and key not in self._favorite_bundles:
+ self._favorite_bundles[key] = None
logging.debug('After merging: %r' % self._favorite_bundles)
@@ -205,24 +223,56 @@ class BundleRegistry(gobject.GObject):
(bundle_id, version))
def set_bundle_favorite(self, bundle_id, version, favorite):
+ key = self._get_favorite_key(bundle_id, version)
+ if favorite and not key in self._favorite_bundles:
+ self._favorite_bundles[key] = None
+ elif not favorite and key in self._favorite_bundles:
+ del self._favorite_bundles[key]
+ else:
+ return
+
+ self._write_favorites_file()
bundle = self._find_bundle(bundle_id, version)
- if favorite and not [bundle_id, version] in self._favorite_bundles:
- self._favorite_bundles.append([bundle_id, version])
- self.emit('bundle-changed', bundle)
- self._write_favorites_file()
- elif not favorite and [bundle_id, version] in self._favorite_bundles:
- self._favorite_bundles.remove([bundle_id, version])
- self.emit('bundle-changed', bundle)
- self._write_favorites_file()
+ self.emit('bundle-changed', bundle)
def is_bundle_favorite(self, bundle_id, version):
- return [bundle_id, version] in self._favorite_bundles
+ key = self._get_favorite_key(bundle_id, version)
+ return key in self._favorite_bundles
+
+ def set_bundle_position(self, bundle_id, version, x, y):
+ key = self._get_favorite_key(bundle_id, version)
+ if key not in self._favorite_bundles:
+ raise ValueError('Bundle %s %s not favorite' % (bundle_id, version))
+
+ if self._favorite_bundles[key] is None:
+ self._favorite_bundles[key] = {}
+ if 'position' not in self._favorite_bundles[key] or \
+ [x, y] != self._favorite_bundles[key]['position']:
+ self._favorite_bundles[key]['position'] = [x, y]
+ else:
+ return
+
+ self._write_favorites_file()
+ bundle = self._find_bundle(bundle_id, version)
+ self.emit('bundle-changed', bundle)
+
+ def get_bundle_position(self, bundle_id, version):
+ """Get the coordinates where the user wants the representation of this
+ bundle to be displayed. Coordinates are relative to a 1000x1000 area.
+ """
+ key = self._get_favorite_key(bundle_id, version)
+ if key not in self._favorite_bundles or \
+ self._favorite_bundles[key] is None or \
+ 'position' not in self._favorite_bundles[key]:
+ return (-1, -1)
+ else:
+ return tuple(self._favorite_bundles[key]['position'])
def _write_favorites_file(self):
path = env.get_profile_path('favorite_activities')
favorites_data = {'defaults-mtime': self._last_defaults_mtime,
'favorites': self._favorite_bundles}
- simplejson.dump(favorites_data, open(path, 'w'))
+ simplejson.dump(favorites_data, open(path, 'w'), indent=1)
_instance = None
diff --git a/src/view/home/activitiesring.py b/src/view/home/activitiesring.py
index 5d66ec3..a250c1d 100644
--- a/src/view/home/activitiesring.py
+++ b/src/view/home/activitiesring.py
@@ -203,7 +203,9 @@ class ActivitiesRing(hippo.Canvas):
icon_file_name = self._last_clicked_icon.props.file_name
# TODO: we should get the pixbuf from the widget, so it has colors, etc
pixbuf = gtk.gdk.pixbuf_new_from_file(icon_file_name)
- context.set_icon_pixbuf(pixbuf, 0, 0)
+
+ hot_spot = style.zoom(10)
+ context.set_icon_pixbuf(pixbuf, hot_spot, hot_spot)
def __drag_motion_cb(self, widget, context, x, y, time):
if self._last_clicked_icon is not None:
@@ -266,6 +268,10 @@ class ActivityIcon(CanvasIcon):
return self._activity_info.installation_time
installation_time = property(_get_installation_time, None)
+ def _get_fixed_position(self):
+ return self._activity_info.position
+ fixed_position = property(_get_fixed_position, None)
+
class CurrentActivityIcon(CanvasIcon, hippo.CanvasItem):
def __init__(self):
CanvasIcon.__init__(self, cache=True)
@@ -389,18 +395,32 @@ class RingLayout(gobject.GObject, hippo.CanvasLayout):
else:
return 0
- def append(self, child):
- self._box.insert_sorted(child, 0, self._compare_activities)
+ def append(self, icon):
+ self._box.insert_sorted(icon, 0, self._compare_activities)
+ relative_x, relative_y = icon.fixed_position
+ if relative_x >= 0 and relative_y >= 0:
+ width = gtk.gdk.screen_width()
+ height = gtk.gdk.screen_height() - style.GRID_CELL_SIZE
+ self._fixed_positions[icon] = (relative_x * 1000 / width,
+ relative_y * 1000 / height)
self._update_icon_sizes()
- def remove(self, child):
- self._box.remove(child)
+ def remove(self, icon):
+ del self._fixed_positions[icon]
+ self._box.remove(icon)
self._update_icon_sizes()
- def move_icon(self, child, x, y):
- if child not in self._box.get_children():
+ def move_icon(self, icon, x, y):
+ if icon not in self._box.get_children():
raise ValueError('Child not in box.')
- self._fixed_positions[child] = (x, y)
+
+ width = gtk.gdk.screen_width()
+ height = gtk.gdk.screen_height() - style.GRID_CELL_SIZE
+ registry = activity.get_registry()
+ registry.set_activity_position(icon.get_bundle_id(), icon.get_version(),
+ x * width / 1000, y * height / 1000)
+
+ self._fixed_positions[icon] = (x, y)
self._box.emit_request_changed()
def do_allocate(self, x, y, width, height, req_width, req_height,
--
1.5.4.3
From 2d9979ce907296ce2f13bfdfb064d4d9dd1c37df Mon Sep 17 00:00:00 2001
From: Tomeu Vizoso <[EMAIL PROTECTED](none)>
Date: Wed, 11 Jun 2008 17:41:58 +0200
Subject: [PATCH] Add a position attribute to registered activity bundles.
---
src/sugar/activity/registry.py | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/sugar/activity/registry.py b/src/sugar/activity/registry.py
index d5d0529..da2eb27 100644
--- a/src/sugar/activity/registry.py
+++ b/src/sugar/activity/registry.py
@@ -32,11 +32,12 @@ def _activity_info_from_dict(info_dict):
info_dict['bundle_id'], info_dict['version'],
info_dict['path'], info_dict['show_launcher'],
info_dict['command'], info_dict['favorite'],
- info_dict['installation_time'])
+ info_dict['installation_time'],
+ info_dict['position_x'], info_dict['position_y'])
class ActivityInfo(object):
def __init__(self, name, icon, bundle_id, version, path, show_launcher,
- command, favorite, installation_time):
+ command, favorite, installation_time, position_x, position_y):
self.name = name
self.icon = icon
self.bundle_id = bundle_id
@@ -46,6 +47,7 @@ class ActivityInfo(object):
self.show_launcher = show_launcher
self.favorite = favorite
self.installation_time = installation_time
+ self.position = (position_x, position_y)
class ActivityRegistry(gobject.GObject):
__gsignals__ = {
@@ -175,6 +177,9 @@ class ActivityRegistry(gobject.GObject):
def set_activity_favorite(self, bundle_id, version, favorite):
self._registry.SetActivityFavorite(bundle_id, version, favorite)
+ def set_activity_position(self, bundle_id, version, x, y):
+ self._registry.SetActivityPosition(bundle_id, version, x, y)
+
_registry = None
def get_registry():
--
1.5.4.3
_______________________________________________
Sugar mailing list
[email protected]
http://lists.laptop.org/listinfo/sugar