From 3cc77d917005e5c6ae8728bbc6eab38db45708ed Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Tue, 10 Jun 2008 14:55:37 +0000 Subject: Make the favorite activity icons draggable --- (limited to 'src') 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) -- cgit v0.9.1