From 2db2ae531208cdb58c448f4bd4a91f8ea947066a Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Sun, 24 Dec 2006 11:19:24 +0000 Subject: Split model/view in the activities donut. Provide some infrastructure for Alt+Tab implementation. --- diff --git a/shell/model/Makefile.am b/shell/model/Makefile.am index 50fe145..010f000 100644 --- a/shell/model/Makefile.am +++ b/shell/model/Makefile.am @@ -6,4 +6,6 @@ sugar_PYTHON = \ Invites.py \ Owner.py \ MeshModel.py \ - ShellModel.py + ShellModel.py \ + homeactivity.py \ + homemodel.py diff --git a/shell/model/homeactivity.py b/shell/model/homeactivity.py new file mode 100644 index 0000000..8c4d232 --- /dev/null +++ b/shell/model/homeactivity.py @@ -0,0 +1,32 @@ +# Copyright (C) 2006, Owen Williams. +# +# 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 + +from sugar.graphics.canvasicon import CanvasIcon + +class HomeActivity: + def __init__(self, activity): + self._icon_name = activity.get_icon_name() + self._icon_color = activity.get_icon_color() + self._id = activity.get_id() + + def get_icon_name(self): + return self._icon_name + + def get_icon_color(self): + return self._icon_color + + def get_id(self): + return self._id diff --git a/shell/model/homemodel.py b/shell/model/homemodel.py new file mode 100644 index 0000000..a5e2634 --- /dev/null +++ b/shell/model/homemodel.py @@ -0,0 +1,69 @@ +# Copyright (C) 2006, Owen Williams. +# +# 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 gobject + +from sugar.graphics.canvasicon import CanvasIcon +from sugar.graphics import style +from model.homeactivity import HomeActivity + +class HomeModel(gobject.GObject): + + __gsignals__ = { + 'activity-added': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, + ([gobject.TYPE_PYOBJECT])), + 'activity-removed': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, + ([gobject.TYPE_PYOBJECT])) + } + + def __init__(self, shell): + gobject.GObject.__init__(self) + self._activities = [] + self._shell = shell + + shell.connect('activity-opened', self.__activity_opened_cb) + shell.connect('activity-closed', self.__activity_closed_cb) + + def __iter__(self): + return iter(self._activities) + + def __len__(self): + return len(self._activities) + + def __getitem__(self, i): + return self._activities[i] + + def __activity_opened_cb(self, model, activity): + self._add_activity(activity) + + def __activity_closed_cb(self, model, activity): + self._remove_activity(activity) + + def _add_activity(self, activity): + h_activity = HomeActivity(activity) + self._activities.append(h_activity) + self.emit('activity-added', h_activity) + + def _remove_activity(self, activity): + i = 0 + for h_activity in self._activities: + if h_activity.get_id() == activity.get_id(): + self.emit('activity-removed', self._activities[i]) + del self._activities[i] + return + i += 1 diff --git a/shell/view/Shell.py b/shell/view/Shell.py index dcdc5d4..8b0dee8 100644 --- a/shell/view/Shell.py +++ b/shell/view/Shell.py @@ -95,6 +95,7 @@ class Shell(gobject.GObject): self._key_grabber.grab('0xDC') # Camera key self._key_grabber.grab('0xE0') # Overlay key self._key_grabber.grab('0x93') # Frame key + self._key_grabber.grab('Tab') # For non-OLPC machines self._key_grabber.grab('F9') @@ -127,6 +128,10 @@ class Shell(gobject.GObject): self.toggle_chat_visibility() elif key == '0x93': # Frame key self._frame.notify_key_press() + elif key == 'Tab': + self.set_zoom_level(sugar.ZOOM_HOME) + box = self._home_window.get_home_box() + box.grab_and_rotate() def _key_released_cb(self, grabber, key): if key == 'F9': @@ -202,7 +207,7 @@ class Shell(gobject.GObject): def join_activity(self, bundle_id, activity_id): pservice = PresenceService.get_instance() - activity = self._get_activity(activity_id) + activity = self.get_activity(activity_id) if activity: activity.present() else: @@ -244,11 +249,11 @@ class Shell(gobject.GObject): def get_current_activity(self): activity_id = self._model.get_current_activity() if activity_id: - return self._get_activity(activity_id) + return self.get_activity(activity_id) else: return None - def _get_activity(self, activity_id): + def get_activity(self, activity_id): for host in self._hosts.values(): if host.get_id() == activity_id: return host diff --git a/shell/view/home/HomeBox.py b/shell/view/home/HomeBox.py index a24402d..48069ea 100644 --- a/shell/view/home/HomeBox.py +++ b/shell/view/home/HomeBox.py @@ -25,13 +25,12 @@ class HomeBox(hippo.CanvasBox, hippo.CanvasItem): __gtype_name__ = 'SugarHomeBox' def __init__(self, shell): - hippo.CanvasBox.__init__(self, background_color=0xe2e2e2ff, - yalign=2) + hippo.CanvasBox.__init__(self, background_color=0xe2e2e2ff, yalign=2) grid = Grid() - donut = ActivitiesDonut(shell, box_width=grid.dimension(7), - box_height=grid.dimension(7)) - self.append(donut) + self._donut = ActivitiesDonut(shell, box_width=grid.dimension(7), + box_height=grid.dimension(7)) + self.append(self._donut) self._my_icon = MyIcon() style.apply_stylesheet(self._my_icon, 'home.MyIcon') @@ -43,3 +42,15 @@ class HomeBox(hippo.CanvasBox, hippo.CanvasItem): [icon_width, icon_height] = self._my_icon.get_allocation() self.move(self._my_icon, (width - icon_width) / 2, (height - icon_height) / 2) + + def has_activities(self): + return self._donut.has_activities() + + def grab_and_rotate(self): + pass + + def rotate(self): + pass + + def release(self): + pass diff --git a/shell/view/home/HomeWindow.py b/shell/view/home/HomeWindow.py index b450b8c..73d29c5 100644 --- a/shell/view/home/HomeWindow.py +++ b/shell/view/home/HomeWindow.py @@ -34,6 +34,7 @@ class HomeWindow(gtk.Window): self.realize() self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DESKTOP) + self.connect("key-release-event", self._key_release_cb) self._nb = gtk.Notebook() self._nb.set_show_border(False) @@ -43,8 +44,8 @@ class HomeWindow(gtk.Window): self._nb.show() canvas = hippo.Canvas() - box = HomeBox(shell) - canvas.set_root(box) + self._home_box = HomeBox(shell) + canvas.set_root(self._home_box) self._nb.append_page(canvas) canvas.show() @@ -60,6 +61,11 @@ class HomeWindow(gtk.Window): self._nb.append_page(canvas) canvas.show() + def _key_release_cb(self, widget, event): + keyname = gtk.gdk.keyval_name(event.keyval) + if keyname == "Alt_L": + self._home_box.release() + def set_zoom_level(self, level): if level == sugar.ZOOM_HOME: self._nb.set_current_page(0) @@ -67,3 +73,6 @@ class HomeWindow(gtk.Window): self._nb.set_current_page(1) elif level == sugar.ZOOM_MESH: self._nb.set_current_page(2) + + def get_home_box(self): + return self._home_box diff --git a/shell/view/home/activitiesdonut.py b/shell/view/home/activitiesdonut.py index 74f3bbb..7d1c3e5 100644 --- a/shell/view/home/activitiesdonut.py +++ b/shell/view/home/activitiesdonut.py @@ -19,6 +19,7 @@ import math from sugar.graphics.canvasicon import CanvasIcon from sugar.graphics import style +from model.homemodel import HomeModel class ActivitiesDonut(hippo.CanvasBox, hippo.CanvasItem): __gtype_name__ = 'SugarActivitiesDonut' @@ -26,14 +27,16 @@ class ActivitiesDonut(hippo.CanvasBox, hippo.CanvasItem): hippo.CanvasBox.__init__(self, **kwargs) self._activities = {} + self._shell = shell - shell.connect('activity_opened', self.__activity_opened_cb) - shell.connect('activity_closed', self.__activity_closed_cb) + self._model = HomeModel(shell) + self._model.connect('activity-added', self._activity_added_cb) + self._model.connect('activity-removed', self._activity_removed_cb) - def __activity_opened_cb(self, model, activity): + def _activity_added_cb(self, model, activity): self._add_activity(activity) - def __activity_closed_cb(self, model, activity): + def _activity_removed_cb(self, model, activity): self._remove_activity(activity) def _remove_activity(self, activity): @@ -47,15 +50,17 @@ class ActivitiesDonut(hippo.CanvasBox, hippo.CanvasItem): icon = CanvasIcon(icon_name=icon_name, color=icon_color) style.apply_stylesheet(icon, 'ring.ActivityIcon') - icon.connect('activated', self.__activity_icon_clicked_cb, activity) + icon.connect('activated', self._activity_icon_clicked_cb, activity) self.append(icon, hippo.PACK_FIXED) self._activities[activity.get_id()] = icon self.emit_paint_needed(0, 0, -1, -1) - def __activity_icon_clicked_cb(self, item, activity): - activity.present() + def _activity_icon_clicked_cb(self, item, activity): + activity_host = self._shell.get_activity(activity.get_id()) + if activity_host: + activity_host.present() def _get_angles(self, index): angle = 2 * math.pi / 8 diff --git a/sugar/graphics/timeline.py b/sugar/graphics/timeline.py index 3944771..013687d 100644 --- a/sugar/graphics/timeline.py +++ b/sugar/graphics/timeline.py @@ -56,7 +56,7 @@ class Timeline: del self._tags[name] def _next_frame(self, tag, frame): - n_frames = tag.start_frame - tag.end_frame + n_frames = tag.end_frame - tag.start_frame + 1 self._observer.next_frame(tag.name, frame, n_frames) def goto(self, tag_name, end_frame=False): -- cgit v0.9.1