Hi,

this patch adds the ability to drag activity icons out from the ring.

Thanks,

Tomeu
From 5b44c112e59ed581001bdcadb962ff7f2bb9f9d7 Mon Sep 17 00:00:00 2001
From: Tomeu Vizoso <[EMAIL PROTECTED](none)>
Date: Tue, 10 Jun 2008 16:55:37 +0200
Subject: [PATCH] Make the favorite activity icons draggable

---
 src/view/home/FriendsBox.py     |   12 ++-
 src/view/home/HomeBox.py        |   15 ++-
 src/view/home/HomeWindow.py     |   31 +++--
 src/view/home/MeshBox.py        |   12 ++-
 src/view/home/activitieslist.py |   22 ++--
 src/view/home/activitiesring.py |  263 ++++++++++++++++++++++++++++++---------
 src/view/home/launchbox.py      |    8 +-
 src/view/home/transitionbox.py  |   13 ++-
 8 files changed, 274 insertions(+), 102 deletions(-)

diff --git a/src/view/home/FriendsBox.py b/src/view/home/FriendsBox.py
index 7c6648a..8c6ddcf 100644
--- a/src/view/home/FriendsBox.py
+++ b/src/view/home/FriendsBox.py
@@ -14,6 +14,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
+import gobject
 import gtk
 import hippo
 
@@ -26,16 +27,19 @@ from model import shellmodel
 from view.home.FriendView import FriendView
 from view.home.spreadlayout import SpreadLayout
 
-class FriendsBox(hippo.CanvasBox):
+class FriendsBox(hippo.Canvas):
     __gtype_name__ = 'SugarFriendsBox'
     def __init__(self):
-        hippo.CanvasBox.__init__(self,
-                                 background_color=style.COLOR_WHITE.get_int())
+        gobject.GObject.__init__(self)
+
+        self._box = hippo.CanvasBox()
+        self._box.props.background_color = style.COLOR_WHITE.get_int()
+        self.set_root(self._box)
 
         self._friends = {}
 
         self._layout = SpreadLayout()
-        self.set_layout(self._layout)
+        self._box.set_layout(self._layout)
 
         self._owner_icon = CanvasIcon(icon_name='computer-xo', cache=True,
                                       xo_color=profile.get_color())
diff --git a/src/view/home/HomeBox.py b/src/view/home/HomeBox.py
index fa22a11..429b903 100644
--- a/src/view/home/HomeBox.py
+++ b/src/view/home/HomeBox.py
@@ -18,7 +18,6 @@ from gettext import gettext as _
 
 import gobject
 import gtk
-import hippo
 
 from sugar.graphics import style
 from sugar.graphics import iconentry
@@ -32,11 +31,11 @@ _LIST_VIEW = 1
 
 _AUTOSEARCH_TIMEOUT = 1000
 
-class HomeBox(hippo.CanvasBox, hippo.CanvasItem):
+class HomeBox(gtk.VBox):
     __gtype_name__ = 'SugarHomeBox'
 
     def __init__(self):
-        hippo.CanvasBox.__init__(self)
+        gobject.GObject.__init__(self)
 
         self._ring_view = ActivitiesRing()
         self._list_view = ActivitiesList()
@@ -45,7 +44,8 @@ class HomeBox(hippo.CanvasBox, hippo.CanvasItem):
         self._toolbar = HomeToolbar()
         self._toolbar.connect('query-changed', self.__toolbar_query_changed_cb)
         self._toolbar.connect('view-changed', self.__toolbar_view_changed_cb)
-        self.append(hippo.CanvasWidget(widget=self._toolbar))
+        self.pack_start(self._toolbar, expand=False)
+        self._toolbar.show()
 
         self._set_view(_RING_VIEW)
 
@@ -66,13 +66,14 @@ class HomeBox(hippo.CanvasBox, hippo.CanvasItem):
             if self._enable_xo_palette:
                 self._ring_view.enable_xo_palette()
 
-            self.append(self._ring_view, hippo.PACK_EXPAND)
-
+            self.add(self._ring_view)
+            self._ring_view.show()
         elif view == _LIST_VIEW:
             if self._ring_view in self.get_children():
                 self.remove(self._ring_view)
 
-            self.append(self._list_view, hippo.PACK_EXPAND)
+            self.add(self._list_view)
+            self._list_view.show()
         else:
             raise ValueError('Invalid view: %r' % view)
 
diff --git a/src/view/home/HomeWindow.py b/src/view/home/HomeWindow.py
index 9151d46..03a571e 100644
--- a/src/view/home/HomeWindow.py
+++ b/src/view/home/HomeWindow.py
@@ -15,7 +15,6 @@
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 import gtk
-import hippo
 
 from sugar.graphics import style
 from sugar.graphics import palettegroup
@@ -44,10 +43,6 @@ class HomeWindow(gtk.Window):
         self._active = False
         self._level = ShellModel.ZOOM_HOME
 
-        self._canvas = hippo.Canvas()
-        self.add(self._canvas)
-        self._canvas.show()
-
         self.set_default_size(gtk.gdk.screen_width(),
                               gtk.gdk.screen_height())
 
@@ -70,8 +65,9 @@ class HomeWindow(gtk.Window):
         self.launch_box = LaunchBox()
 
         self._activate_view()
-        self._canvas.set_root(self._home_box)
-        
+        self.add(self._home_box)
+        self._home_box.show()
+
         self._transition_box.connect('completed',
                                      self._transition_completed_cb)
 
@@ -122,8 +118,9 @@ class HomeWindow(gtk.Window):
         self._deactivate_view()
         self._level = level
         self._activate_view()
-    
-        self._canvas.set_root(self._transition_box)
+
+        self.remove(self.get_child())    
+        self.add(self._transition_box)
 
         if level == ShellModel.ZOOM_HOME:
             size = style.XLARGE_ICON_SIZE
@@ -138,14 +135,22 @@ class HomeWindow(gtk.Window):
     
     def _transition_completed_cb(self, transition_box):
         if self._level == ShellModel.ZOOM_HOME:
-            self._canvas.set_root(self._home_box)
+            self.remove(self.get_child())    
+            self.add(self._home_box)
+            self._home_box.show()
         elif self._level == ShellModel.ZOOM_FRIENDS:
-            self._canvas.set_root(self._friends_box)
+            self.remove(self.get_child())    
+            self.add(self._friends_box)
+            self._friends_box.show()
         elif self._level == ShellModel.ZOOM_MESH:
-            self._canvas.set_root(self._mesh_box)
+            self.remove(self.get_child())    
+            self.add(self._mesh_box)
+            self._mesh_box.show()
             self._mesh_box.focus_search_entry()
         elif self._level == ShellModel.ZOOM_ACTIVITY:
-            self._canvas.set_root(self.launch_box)
+            self.remove(self.get_child())    
+            self.add(self.launch_box)
+            self.launch_box.show()
 
     def get_home_box(self):
         return self._home_box   
diff --git a/src/view/home/MeshBox.py b/src/view/home/MeshBox.py
index db2f80e..cf447d4 100644
--- a/src/view/home/MeshBox.py
+++ b/src/view/home/MeshBox.py
@@ -429,9 +429,9 @@ class MeshToolbar(gtk.Toolbar):
         self.search_entry.activate()
         return False
 
-class MeshBox(hippo.CanvasBox):
+class MeshBox(gtk.VBox):
     def __init__(self):
-        hippo.CanvasBox.__init__(self)
+        gobject.GObject.__init__(self)
 
         self._model = shellmodel.get_instance().get_mesh()
         self._buddies = {}
@@ -444,11 +444,15 @@ class MeshBox(hippo.CanvasBox):
 
         self._toolbar = MeshToolbar()
         self._toolbar.connect('query-changed', self._toolbar_query_changed_cb)
-        self.append(hippo.CanvasWidget(widget=self._toolbar))
+        self.add(self._toolbar)
+        
+        canvas = hippo.Canvas()
+        self.add(canvas)
+        canvas.show()
 
         self._layout_box = hippo.CanvasBox( \
                 background_color=style.COLOR_WHITE.get_int())
-        self.append(self._layout_box, hippo.PACK_EXPAND)
+        canvas.set_root(self._layout_box)
 
         self._layout = SpreadLayout()
         self._layout_box.set_layout(self._layout)
diff --git a/src/view/home/activitieslist.py b/src/view/home/activitieslist.py
index 8a824fd..5dab09d 100644
--- a/src/view/home/activitieslist.py
+++ b/src/view/home/activitieslist.py
@@ -27,19 +27,25 @@ from sugar.graphics.icon import CanvasIcon
 import view.Shell
 from view.palettes import ActivityPalette
 
-class ActivitiesList(hippo.CanvasScrollbars):
+class ActivitiesList(gtk.ScrolledWindow):
     __gtype_name__ = 'SugarActivitiesList'
 
     def __init__(self):
-        hippo.CanvasScrollbars.__init__(self)
+        gobject.GObject.__init__(self)
 
-        self.set_policy(hippo.ORIENTATION_HORIZONTAL, hippo.SCROLLBAR_NEVER)
-        self.props.widget.connect('key-press-event', self.__key_press_event_cb)
+        self.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+        self.set_shadow_type(gtk.SHADOW_NONE)
+        self.connect('key-press-event', self.__key_press_event_cb)
+
+        canvas = hippo.Canvas()
+        self.add_with_viewport(canvas)
+        self.child.set_shadow_type(gtk.SHADOW_NONE)
+        canvas.show()
 
         self._query = ''
-        self._box = hippo.CanvasBox( \
-                background_color=style.COLOR_WHITE.get_int())
-        self.set_root(self._box)
+        self._box = hippo.CanvasBox()
+        self._box.props.background_color = style.COLOR_WHITE.get_int()
+        canvas.set_root(self._box)
 
         registry = activity.get_registry()
         registry.get_activities_async(reply_handler=self._get_activities_cb)
@@ -81,7 +87,7 @@ class ActivitiesList(hippo.CanvasScrollbars):
     def __key_press_event_cb(self, widget, event):
         keyname = gtk.gdk.keyval_name(event.keyval)
 
-        vadjustment = self.props.widget.props.vadjustment
+        vadjustment = self.props.vadjustment
         if keyname == 'Up':
             if vadjustment.props.value > vadjustment.props.lower:
                 vadjustment.props.value -= vadjustment.props.step_increment
diff --git a/src/view/home/activitiesring.py b/src/view/home/activitiesring.py
index dccb066..5d66ec3 100644
--- a/src/view/home/activitiesring.py
+++ b/src/view/home/activitiesring.py
@@ -42,23 +42,29 @@ from session import get_session_manager
 
 _logger = logging.getLogger('ActivitiesRing')
 
-class ActivitiesRing(hippo.CanvasBox, hippo.CanvasItem):
+_ICON_DND_TARGET = ('activity-icon', gtk.TARGET_SAME_WIDGET, 0)
+
+class ActivitiesRing(hippo.Canvas):
     __gtype_name__ = 'SugarActivitiesRing'
 
-    def __init__(self):
-        hippo.CanvasBox.__init__(self, 
-                                 background_color=style.COLOR_WHITE.get_int())
+    def __init__(self, **kwargs):
+        gobject.GObject.__init__(self, **kwargs)
+
+        self._box = hippo.CanvasBox()
+        self._box.props.background_color = style.COLOR_WHITE.get_int()
+        self.set_root(self._box)
 
         shell_model = shellmodel.get_instance()
         shell_model.connect('notify::state', self._shell_state_changed_cb)
 
         self._my_icon = _MyIcon(style.XLARGE_ICON_SIZE)
-        self.append(self._my_icon, hippo.PACK_FIXED)
+        self._box.append(self._my_icon, hippo.PACK_FIXED)
 
         self._current_activity = CurrentActivityIcon()
-        self.append(self._current_activity, hippo.PACK_FIXED)
+        self._box.append(self._current_activity, hippo.PACK_FIXED)
 
-        self.set_layout(RingLayout())
+        self._layout = RingLayout()
+        self._box.set_layout(self._layout)
 
         registry = activity.get_registry()
         registry.get_activities_async(reply_handler=self._get_activities_cb)
@@ -66,16 +72,27 @@ class ActivitiesRing(hippo.CanvasBox, hippo.CanvasItem):
         registry.connect('activity-removed', self.__activity_removed_cb)
         registry.connect('activity-changed', self.__activity_changed_cb)
 
-    def _compare_activities(self, icon_a, icon_b):
-        if hasattr(icon_a, 'installation_time') and \
-                hasattr(icon_b, 'installation_time'):
-            return icon_b.installation_time - icon_a.installation_time
-        else:
-            return 0
+        # DND stuff
+        self._pressed_button = None
+        self._press_start_x = None
+        self._press_start_y = None
+        self._last_clicked_icon = None
+
+        self.drag_source_set(0, [], 0)
+        self.add_events(gtk.gdk.BUTTON_PRESS_MASK |
+                        gtk.gdk.POINTER_MOTION_HINT_MASK)
+        self.connect('motion-notify-event', self.__motion_notify_event_cb)
+        self.connect('button-press-event', self.__button_press_event_cb)
+        self.connect('drag-begin', self.__drag_begin_cb)
+
+        self.drag_dest_set(0, [], 0)
+        self.connect('drag-motion', self.__drag_motion_cb)
+        self.connect('drag-drop', self.__drag_drop_cb)
+        self.connect('drag-data-received', self.__drag_data_received_cb)
 
     def _add_activity(self, activity_info):
         icon = ActivityIcon(activity_info)
-        self.insert_sorted(icon, 0, self._compare_activities)
+        self._layout.append(icon)
 
     def _get_activities_cb(self, activity_list):
         for info in activity_list:
@@ -88,7 +105,7 @@ class ActivitiesRing(hippo.CanvasBox, hippo.CanvasItem):
             self._add_activity(activity_info)
 
     def _find_activity_icon(self, bundle_id, version):
-        for icon in self.get_children():
+        for icon in self._box.get_children():
             if isinstance(icon, ActivityIcon) and \
                     icon.bundle_id == bundle_id and icon.version == version:
                 return icon
@@ -98,7 +115,7 @@ class ActivitiesRing(hippo.CanvasBox, hippo.CanvasItem):
         icon = self._find_activity_icon(activity_info.bundle_id,
                 activity_info.version)
         if icon is not None:
-            self.remove(icon)
+            self._layout.remove(icon)
 
     def __activity_changed_cb(self, activity_registry, activity_info):
         if activity_info.bundle_id == "org.laptop.JournalActivity":
@@ -106,7 +123,7 @@ class ActivitiesRing(hippo.CanvasBox, hippo.CanvasItem):
         icon = self._find_activity_icon(activity_info.bundle_id,
                 activity_info.version)
         if icon is not None and not activity_info.favorite:
-            self.remove(icon)
+            self._box.remove(icon)
         elif icon is None and activity_info.favorite:
             self._add_activity(activity_info)
 
@@ -115,23 +132,105 @@ class ActivitiesRing(hippo.CanvasBox, hippo.CanvasItem):
         if model.props.state == ShellModel.STATE_SHUTDOWN:
             pass
 
-    def do_allocate(self, width, height, origin_changed):
-        hippo.CanvasBox.do_allocate(self, width, height, origin_changed)
+    def do_size_allocate(self, allocation):
+        hippo.Canvas.do_size_allocate(self, allocation)
+        
+        width = allocation.width        
+        height = allocation.height
 
         [my_icon_width, my_icon_height] = self._my_icon.get_allocation()
         x = (width - my_icon_width) / 2
         y = (height - my_icon_height - style.GRID_CELL_SIZE) / 2
-        self.set_position(self._my_icon, x, y)
+        self._box.set_position(self._my_icon, x, y)
 
         [icon_width, icon_height] = self._current_activity.get_allocation()
         x = (width - icon_width) / 2
         y = (height + my_icon_height + style.DEFAULT_PADDING \
                  - style.GRID_CELL_SIZE) / 2
-        self.set_position(self._current_activity, x, y)
+        self._box.set_position(self._current_activity, x, y)
 
     def enable_xo_palette(self):
         self._my_icon.enable_palette()
 
+    # TODO: Dnd methods. This should be merged somehow inside hippo-canvas.
+    def __button_press_event_cb(self, widget, event):
+        if event.button == 1 and event.type == gtk.gdk.BUTTON_PRESS:
+            self._last_clicked_icon = self._get_icon_at_coords(event.x, event.y)
+            if self._last_clicked_icon is not None:
+                self._pressed_button = event.button
+                self._press_start_x = event.x
+                self._press_start_y = event.y
+
+        return False
+
+    def _get_icon_at_coords(self, x, y):
+        for icon in self._box.get_children():
+            icon_x, icon_y = icon.get_context().translate_to_widget(icon)
+            icon_width, icon_height = icon.get_allocation()
+
+            if (x >= icon_x ) and (x <= icon_x + icon_width) and \
+                    (y >= icon_y ) and (y <= icon_y + icon_height) and \
+                    isinstance(icon, ActivityIcon):
+                return icon
+        return None
+
+    def __motion_notify_event_cb(self, widget, event):
+        if not self._pressed_button:
+            return False
+        
+        # if the mouse button is not pressed, no drag should occurr
+        if not event.state & gtk.gdk.BUTTON1_MASK:
+            self._pressed_button = None
+            return False
+
+        if event.is_hint:
+            x, y, state_ = event.window.get_pointer()
+        else:
+            x = event.x
+            y = event.y
+
+        if widget.drag_check_threshold(int(self._press_start_x),
+                                       int(self._press_start_y),
+                                       int(x),
+                                       int(y)):
+            context_ = widget.drag_begin([_ICON_DND_TARGET],
+                                         gtk.gdk.ACTION_MOVE,
+                                         1,
+                                         event)
+        return False
+
+    def __drag_begin_cb(self, widget, context):
+        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)        
+
+    def __drag_motion_cb(self, widget, context, x, y, time):
+        if self._last_clicked_icon is not None:
+            context.drag_status(context.suggested_action, time)
+            return True
+        else:
+            return False
+
+    def __drag_drop_cb(self, widget, context, x, y, time):
+        if self._last_clicked_icon is not None:
+            self.drag_get_data(context, _ICON_DND_TARGET[0])
+
+            self._layout.move_icon(self._last_clicked_icon, x, y)
+
+            self._pressed_button = None
+            self._press_start_x = None
+            self._press_start_y = None
+            self._last_clicked_icon = None
+
+            return True
+        else:
+            return False
+
+    def __drag_data_received_cb(self, widget, context, x, y, selection_data,
+                                info, time):
+        context.drop_finish(success=True, time=time)
+
 class ActivityIcon(CanvasIcon):
     def __init__(self, activity_info):
         CanvasIcon.__init__(self, cache=True, file_name=activity_info.icon)
@@ -198,11 +297,18 @@ class CurrentActivityIcon(CanvasIcon, hippo.CanvasItem):
     def __active_activity_changed_cb(self, home_model, home_activity):
         self._update(home_activity)
 
+_MINIMUM_RADIUS = style.XLARGE_ICON_SIZE / 2 + style.DEFAULT_SPACING + \
+        style.STANDARD_ICON_SIZE * 2
+_MAXIMUM_RADIUS = (gtk.gdk.screen_height() - style.GRID_CELL_SIZE) / 2 - \
+        style.STANDARD_ICON_SIZE - style.DEFAULT_SPACING
+
 class RingLayout(gobject.GObject, hippo.CanvasLayout):
     __gtype_name__ = 'SugarRingLayout'
+
     def __init__(self):
         gobject.GObject.__init__(self)
         self._box = None
+        self._fixed_positions = {}
 
     def do_set_box(self, box):
         self._box = box
@@ -214,15 +320,8 @@ class RingLayout(gobject.GObject, hippo.CanvasLayout):
         return 0, gtk.gdk.screen_width()
 
     def _calculate_radius_and_icon_size(self, children_count):
-        minimum_radius = style.XLARGE_ICON_SIZE / 2 + style.DEFAULT_SPACING + \
-                style.STANDARD_ICON_SIZE * 2
-        maximum_radius = (gtk.gdk.screen_height() - style.GRID_CELL_SIZE) \
-                / 2 - style.STANDARD_ICON_SIZE - style.DEFAULT_SPACING
         angle = 2 * math.pi / children_count
 
-        _logger.debug('minimum_radius %r maximum_radius %r angle %r' % \
-                (minimum_radius, maximum_radius, angle))
-
         # what's the radius required without downscaling?
         distance = style.STANDARD_ICON_SIZE + style.DEFAULT_SPACING
         icon_size = style.STANDARD_ICON_SIZE
@@ -232,60 +331,110 @@ class RingLayout(gobject.GObject, hippo.CanvasLayout):
         else:
             radius = math.sqrt(distance ** 2 /
                     (math.sin(angle) ** 2 + (math.cos(angle) - 1) ** 2))
-
-        _logger.debug('radius 1 %r' % radius)
         
-        if radius < minimum_radius:
+        if radius < _MINIMUM_RADIUS:
             # we can upscale, if we want
             icon_size += style.STANDARD_ICON_SIZE * \
-                    (0.5 * (minimum_radius - radius)/minimum_radius)
-            radius = minimum_radius
-        elif radius > maximum_radius:
-            radius = maximum_radius
+                    (0.5 * (_MINIMUM_RADIUS - radius) / _MINIMUM_RADIUS)
+            radius = _MINIMUM_RADIUS
+        elif radius > _MAXIMUM_RADIUS:
+            radius = _MAXIMUM_RADIUS
             # need to downscale. what's the icon size required?
             distance = math.sqrt((radius * math.sin(angle)) ** 2 + \
                     (radius * (math.cos(angle) - 1)) ** 2)
             icon_size = distance - style.DEFAULT_SPACING
-
-        _logger.debug('radius 2 %r icon_size %r' % (radius, icon_size))
         
         return radius, icon_size
 
     def _calculate_position(self, radius, icon_size, index, children_count):
         width, height = self._box.get_allocation()
-        angle = index * (2 * math.pi / children_count) - math.pi/2
+        angle = index * (2 * math.pi / children_count) - math.pi / 2
         x = radius * math.cos(angle) + (width - icon_size) / 2
         y = radius * math.sin(angle) + (height - icon_size -
                                         style.GRID_CELL_SIZE) / 2
         return x, y
 
+    def _get_children_in_ring(self):
+        children = self._box.get_layout_children()
+        width, height = self._box.get_allocation()
+        children_in_ring = []
+        for child in children:
+            if child.item in self._fixed_positions:
+                x, y = self._fixed_positions[child.item]
+                distance_to_center = math.hypot(x - width / 2, y - height / 2)
+                # TODO at what distance should we consider a child inside the ring?
+            else:
+                children_in_ring.append(child)
+
+        return children_in_ring
+
+    def _update_icon_sizes(self):
+        children_in_ring = self._get_children_in_ring()
+        if children_in_ring:
+            radius_, icon_size = \
+                    self._calculate_radius_and_icon_size(len(children_in_ring))
+
+            for n in range(len(children_in_ring)):
+                child = children_in_ring[n]
+                child.item.props.size = icon_size
+
+        for child in self._box.get_layout_children():
+            if child not in children_in_ring:
+                child.item.props.size = style.STANDARD_ICON_SIZE
+
+    def _compare_activities(self, icon_a, icon_b):
+        if hasattr(icon_a, 'installation_time') and \
+                hasattr(icon_b, 'installation_time'):
+            return icon_b.installation_time - icon_a.installation_time
+        else:
+            return 0
+
+    def append(self, child):
+        self._box.insert_sorted(child, 0, self._compare_activities)
+        self._update_icon_sizes()
+
+    def remove(self, child):
+        self._box.remove(child)
+        self._update_icon_sizes()
+
+    def move_icon(self, child, x, y):
+        if child not in self._box.get_children():
+            raise ValueError('Child not in box.')
+        self._fixed_positions[child] = (x, y)
+        self._box.emit_request_changed()
+
     def do_allocate(self, x, y, width, height, req_width, req_height,
                     origin_changed):
-        _logger.debug('RingLayout.do_allocate: %r %r %r %r %r %r %r' % (x, y,
-                width, height, req_width, req_height, origin_changed))
+        children_in_ring = self._get_children_in_ring()
+        if children_in_ring:
+            radius, icon_size = \
+                    self._calculate_radius_and_icon_size(len(children_in_ring))
 
-        children = self._box.get_layout_children()
-        if not children:
-            return
+            for n in range(len(children_in_ring)):
+                child = children_in_ring[n]
 
-        radius, icon_size = self._calculate_radius_and_icon_size(len(children))
+                x, y = self._calculate_position(radius, icon_size, n,
+                                                len(children_in_ring))
 
-        for n in range(len(children)):
-            child = children[n]
-            # TODO: We get here a glib warning and I don't know why.
-            child.item.props.size = icon_size
+                # We need to always get requests to not confuse hippo
+                min_w_, child_width = child.get_width_request()
+                min_h_, child_height = child.get_height_request(child_width)
 
-            x, y = self._calculate_position(radius, icon_size, n, len(children))
+                child.allocate(int(x), int(y), child_width, child_height,
+                               origin_changed)
+
+        for child in self._box.get_layout_children():
+            if child in children_in_ring:
+                continue
 
             # We need to always get requests to not confuse hippo
-            min_w, child_width = child.get_width_request()
-            min_h, child_height = child.get_height_request(child_width)
-
-            child.allocate(int(x),
-                           int(y),
-                           child_width,
-                           child_height,
-                           origin_changed)
+            min_w_, child_width = child.get_width_request()
+            min_h_, child_height = child.get_height_request(child_width)
+
+            x, y = self._fixed_positions[child.item]
+
+            child.allocate(int(x), int(y), child_width, child_height,
+                            origin_changed)
 
 class _MyIcon(MyIcon):
     def __init__(self, scale):
diff --git a/src/view/home/launchbox.py b/src/view/home/launchbox.py
index a70cb61..dfbec40 100644
--- a/src/view/home/launchbox.py
+++ b/src/view/home/launchbox.py
@@ -25,10 +25,9 @@ from sugar.graphics.xocolor import XoColor
 from model import shellmodel
 from view.pulsingicon import CanvasPulsingIcon
 
-class LaunchBox(hippo.CanvasBox):
+class LaunchBox(hippo.Canvas):
     def __init__(self):
-        gobject.GObject.__init__(
-                self, background_color=style.COLOR_WHITE.get_int())
+        gobject.GObject.__init__(self)
 
         self._activity_icon = CanvasPulsingIcon()
 
@@ -38,8 +37,9 @@ class LaunchBox(hippo.CanvasBox):
                                style.COLOR_TRANSPARENT.get_svg()))
 
         vbox = hippo.CanvasBox(orientation=hippo.ORIENTATION_VERTICAL)
+        vbox.props.background_color = style.COLOR_WHITE.get_int()
         vbox.append(self._activity_icon, hippo.PACK_EXPAND)
-        self.append(vbox, hippo.PACK_EXPAND)
+        self.set_root(vbox)
 
         self._animator = animator.Animator(1.0)
 
diff --git a/src/view/home/transitionbox.py b/src/view/home/transitionbox.py
index c4ef6ca..fb351f8 100644
--- a/src/view/home/transitionbox.py
+++ b/src/view/home/transitionbox.py
@@ -59,7 +59,7 @@ class _Layout(gobject.GObject, hippo.CanvasLayout):
                            y + (height - child_height) / 2,
                            child_width, child_height, origin_changed)
 
-class TransitionBox(hippo.CanvasBox):
+class TransitionBox(hippo.Canvas):
     __gtype_name__ = 'SugarTransitionBox'
     
     __gsignals__ = {
@@ -68,16 +68,19 @@ class TransitionBox(hippo.CanvasBox):
     }
     
     def __init__(self):
-        hippo.CanvasBox.__init__(self, 
-                                 background_color=style.COLOR_WHITE.get_int())
+        gobject.GObject.__init__(self)
+
+        self._box = hippo.CanvasBox()
+        self._box.props.background_color = style.COLOR_WHITE.get_int()
+        self.set_root(self._box)
 
         self._size = style.XLARGE_ICON_SIZE
 
         self._layout = _Layout()
-        self.set_layout(self._layout)
+        self._box.set_layout(self._layout)
 
         self._my_icon = MyIcon(self._size)
-        self.append(self._my_icon)
+        self._box.append(self._my_icon)
 
         self._animator = animator.Animator(0.3)
         self._animator.connect('completed', self._animation_completed_cb)
-- 
1.5.4.3

_______________________________________________
Sugar mailing list
[email protected]
http://lists.laptop.org/listinfo/sugar

Reply via email to