diff --git a/shell/model/BuddyModel.py b/shell/model/BuddyModel.py index a06a728a..2339832f 100644 --- a/shell/model/BuddyModel.py +++ b/shell/model/BuddyModel.py @@ -84,6 +84,11 @@ class BuddyModel(gobject.GObject): def get_buddy(self): return self._buddy + def is_owner(self): + if not self._buddy: + return False + return self._buddy.props.owner + def is_present(self): if self._buddy: return True diff --git a/shell/view/frame/frame.py b/shell/view/frame/frame.py index bd598aa2..472cb5fb 100644 --- a/shell/view/frame/frame.py +++ b/shell/view/frame/frame.py @@ -169,7 +169,7 @@ class Frame(object): if self._animator: self._animator.stop() - self._animator = animator.Animator(0.5, 30, animator.EASE_OUT_EXPO) + self._animator = animator.Animator(0.5) self._animator.add(_Animation(self, 0.0)) self._animator.start() @@ -188,7 +188,7 @@ class Frame(object): if self._animator: self._animator.stop() - self._animator = animator.Animator(0.5, 30, animator.EASE_OUT_EXPO) + self._animator = animator.Animator(0.5) self._animator.add(_Animation(self, 1.0)) self._animator.start() diff --git a/shell/view/home/FriendsBox.py b/shell/view/home/FriendsBox.py index 6f1cdb7d..71b90263 100644 --- a/shell/view/home/FriendsBox.py +++ b/shell/view/home/FriendsBox.py @@ -24,7 +24,7 @@ from sugar.graphics import units from view.home.MyIcon import MyIcon from view.home.FriendView import FriendView -class FriendsBox(SpreadBox, hippo.CanvasItem): +class FriendsBox(SpreadBox): __gtype_name__ = 'SugarFriendsBox' def __init__(self, shell, menu_shell): SpreadBox.__init__(self, background_color=0xe2e2e2ff) @@ -34,7 +34,7 @@ class FriendsBox(SpreadBox, hippo.CanvasItem): self._friends = {} self._my_icon = MyIcon(units.LARGE_ICON_SCALE) - self.append(self._my_icon, hippo.PACK_FIXED) + self.set_center_item(self._my_icon) friends = self._shell.get_model().get_friends() @@ -56,10 +56,3 @@ class FriendsBox(SpreadBox, hippo.CanvasItem): def _friend_removed_cb(self, data_model, key): self.remove_item(self._friends[key]) del self._friends[key] - - def do_allocate(self, width, height, origin_changed): - SpreadBox.do_allocate(self, width, height, origin_changed) - - [icon_width, icon_height] = self._my_icon.get_allocation() - self.set_position(self._my_icon, (width - icon_width) / 2, - (height - icon_height) / 2) diff --git a/shell/view/home/HomeWindow.py b/shell/view/home/HomeWindow.py index a37aeaea..3f339190 100644 --- a/shell/view/home/HomeWindow.py +++ b/shell/view/home/HomeWindow.py @@ -19,20 +19,26 @@ import hippo import cairo from sugar.graphics.menushell import MenuShell +from sugar.graphics.window import Window +from sugar.graphics import units import sugar + from view.home.MeshBox import MeshBox from view.home.HomeBox import HomeBox from view.home.FriendsBox import FriendsBox +from view.home.transitionbox import TransitionBox -_HOME_PAGE = 0 -_FRIENDS_PAGE = 1 -_MESH_PAGE = 2 +_HOME_PAGE = 0 +_FRIENDS_PAGE = 1 +_MESH_PAGE = 2 +_TRANSITION_PAGE = 3 -class HomeWindow(gtk.Window): +class HomeWindow(Window): def __init__(self, shell): - gtk.Window.__init__(self) + Window.__init__(self) self._shell = shell self._active = False + self._level = sugar.ZOOM_HOME self.set_default_size(gtk.gdk.screen_width(), gtk.gdk.screen_height()) @@ -43,30 +49,15 @@ class HomeWindow(gtk.Window): self.connect('focus-in-event', self._focus_in_cb) self.connect('focus-out-event', self._focus_out_cb) - self._nb = gtk.Notebook() - self._nb.set_show_border(False) - self._nb.set_show_tabs(False) - - self.add(self._nb) - self._nb.show() - - canvas = hippo.Canvas() self._home_box = HomeBox(shell) - canvas.set_root(self._home_box) - self._nb.append_page(canvas) - canvas.show() + self._friends_box = FriendsBox(shell, MenuShell(self)) + self._mesh_box = MeshBox(shell, MenuShell(self)) + self._transition_box = TransitionBox() - canvas = hippo.Canvas() - box = FriendsBox(shell, MenuShell(canvas)) - canvas.set_root(box) - self._nb.append_page(canvas) - canvas.show() - - canvas = hippo.Canvas() - self._mesh_box = MeshBox(shell, MenuShell(canvas)) - canvas.set_root(self._mesh_box) - self._nb.append_page(canvas) - canvas.show() + self.set_root(self._home_box) + + self._transition_box.connect('completed', + self._transition_completed_cb) def _key_release_cb(self, widget, event): keyname = gtk.gdk.keyval_name(event.keyval) @@ -74,7 +65,7 @@ class HomeWindow(gtk.Window): self._home_box.release() def _update_mesh_state(self): - if self._active and self._nb.get_current_page() == _MESH_PAGE: + if self._active and self._level == sugar.ZOOM_MESH: self._mesh_box.resume() else: self._mesh_box.suspend() @@ -88,12 +79,26 @@ class HomeWindow(gtk.Window): self._update_mesh_state() def set_zoom_level(self, level): + self._level = level + + self.set_root(self._transition_box) + if level == sugar.ZOOM_HOME: - self._nb.set_current_page(_HOME_PAGE) + scale = units.XLARGE_ICON_SCALE elif level == sugar.ZOOM_FRIENDS: - self._nb.set_current_page(_FRIENDS_PAGE) + scale = units.LARGE_ICON_SCALE elif level == sugar.ZOOM_MESH: - self._nb.set_current_page(_MESH_PAGE) + scale = units.STANDARD_ICON_SCALE + + self._transition_box.set_scale(scale) + + def _transition_completed_cb(self, transition_box): + if self._level == sugar.ZOOM_HOME: + self.set_root(self._home_box) + elif self._level == sugar.ZOOM_FRIENDS: + self.set_root(self._friends_box) + elif self._level == sugar.ZOOM_MESH: + self.set_root(self._mesh_box) self._update_mesh_state() diff --git a/shell/view/home/Makefile.am b/shell/view/home/Makefile.am index 11e221c3..466187be 100644 --- a/shell/view/home/Makefile.am +++ b/shell/view/home/Makefile.am @@ -7,4 +7,5 @@ sugar_PYTHON = \ HomeBox.py \ HomeWindow.py \ MeshBox.py \ - MyIcon.py + MyIcon.py \ + transitionbox.py diff --git a/shell/view/home/MeshBox.py b/shell/view/home/MeshBox.py index 218a44d8..fa85b033 100644 --- a/shell/view/home/MeshBox.py +++ b/shell/view/home/MeshBox.py @@ -278,7 +278,10 @@ class MeshBox(SpreadBox): def _add_alone_buddy(self, buddy_model): icon = BuddyIcon(self._shell, self._menu_shell, buddy_model) - self.add_item(icon) + if buddy_model.is_owner(): + self.set_center_item(icon) + else: + self.add_item(icon) self._buddies[buddy_model.get_key()] = icon diff --git a/shell/view/home/transitionbox.py b/shell/view/home/transitionbox.py new file mode 100644 index 00000000..3d83347e --- /dev/null +++ b/shell/view/home/transitionbox.py @@ -0,0 +1,66 @@ +# Copyright (C) 2007, 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 + +from sugar.graphics import units +from sugar.graphics import animator +from sugar.graphics.spreadbox import SpreadBox + +from view.home.MyIcon import MyIcon + +class _Animation(animator.Animation): + def __init__(self, icon, start_scale, end_scale): + animator.Animation.__init__(self, 0.0, 1.0) + + self._icon = icon + self.start_scale = start_scale + self.end_scale = end_scale + + def next_frame(self, current): + d = (self.end_scale - self.start_scale) * current + self._icon.props.scale = self.start_scale + d + +class TransitionBox(SpreadBox): + __gtype_name__ = 'SugarTransitionBox' + + __gsignals__ = { + 'completed': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, ([])) + } + + def __init__(self): + SpreadBox.__init__(self, background_color=0xe2e2e2ff) + + self._scale = units.XLARGE_ICON_SCALE + + self._my_icon = MyIcon(self._scale) + self.set_center_item(self._my_icon) + + self._animator = animator.Animator(0.3) + self._animator.connect('completed', self._animation_completed_cb) + + def _animation_completed_cb(self, anim): + self.emit('completed') + + def set_scale(self, scale): + self._animator.remove_all() + self._animator.add(_Animation(self._my_icon, self._scale, scale)) + self._animator.start() + + self._scale = scale + diff --git a/sugar/graphics/animator.py b/sugar/graphics/animator.py index 60ff9f39..459851b7 100644 --- a/sugar/graphics/animator.py +++ b/sugar/graphics/animator.py @@ -28,7 +28,7 @@ class Animator(gobject.GObject): gobject.TYPE_NONE, ([])), } - def __init__(self, time, fps, easing=EASE_OUT_EXPO): + def __init__(self, time, fps=20, easing=EASE_OUT_EXPO): gobject.GObject.__init__(self) self._animations = [] self._time = time @@ -39,6 +39,10 @@ class Animator(gobject.GObject): def add(self, animation): self._animations.append(animation) + def remove_all(self): + self.stop() + self._animations = [] + def start(self): if self._timeout_sid: self.stop() @@ -51,7 +55,7 @@ class Animator(gobject.GObject): if self._timeout_sid: gobject.source_remove(self._timeout_sid) self._timeout_sid = 0 - self.emit('completed') + self.emit('completed') def _next_frame_cb(self): current_time = min(self._time, time.time() - self._start_time) diff --git a/sugar/graphics/spreadbox.py b/sugar/graphics/spreadbox.py index 24e12f39..ff50f71e 100644 --- a/sugar/graphics/spreadbox.py +++ b/sugar/graphics/spreadbox.py @@ -22,20 +22,31 @@ import gtk from sugar.graphics import units +_WIDTH = gtk.gdk.screen_width() +_HEIGHT = gtk.gdk.screen_height() _CELL_WIDTH = units.grid_to_pixels(1) _CELL_HEIGHT = units.grid_to_pixels(1) -_GRID_WIDTH = gtk.gdk.screen_width() / _CELL_WIDTH -_GRID_HEIGHT = gtk.gdk.screen_height() / _CELL_HEIGHT +_GRID_WIDTH = _WIDTH / _CELL_WIDTH +_GRID_HEIGHT = _HEIGHT / _CELL_HEIGHT -class SpreadBox(hippo.CanvasBox): +class SpreadBox(hippo.CanvasBox, hippo.CanvasItem): + __gtype_name__ = 'SugarSpreadBox' def __init__(self, **kwargs): hippo.CanvasBox.__init__(self, **kwargs) self._grid = [] + self._center = None for i in range(0, _GRID_WIDTH * _GRID_HEIGHT): self._grid.append(None) + def set_center_item(self, item): + if self._center: + self.remove(self._center) + + self._center = item + self.append(item, hippo.PACK_FIXED) + def add_item(self, item): start_pos = int(random.random() * len(self._grid)) @@ -60,3 +71,11 @@ class SpreadBox(hippo.CanvasBox): if self._grid[i] == item: self._grid[i] = None self.remove(item) + + def do_allocate(self, width, height, origin_changed): + hippo.CanvasBox.do_allocate(self, width, height, origin_changed) + + if self._center: + [icon_width, icon_height] = self._center.get_allocation() + self.set_position(self._center, (width - icon_width) / 2, + (height - icon_height) / 2)