Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTomeu Vizoso <tomeu@tomeu-asus.(none)>2008-06-11 19:00:15 (GMT)
committer Tomeu Vizoso <tomeu@tomeu-laptop.(none)>2008-06-20 10:25:09 (GMT)
commit76d353a120463fa5ca5af2cddd5705555b23c0e3 (patch)
tree42ddfba4c26662b5e4cf087dca743e632f3256d8 /src
parent8653d936ef59916a6c3f4b56f17161e5a61afdfc (diff)
Add RandomLayout and make it the default.
Diffstat (limited to 'src')
-rw-r--r--src/view/home/HomeBox.py54
-rw-r--r--src/view/home/Makefile.am3
-rw-r--r--src/view/home/favoriteslayout.py225
-rw-r--r--src/view/home/favoritesview.py (renamed from src/view/home/activitiesring.py)162
-rw-r--r--src/view/palettes.py4
5 files changed, 254 insertions, 194 deletions
diff --git a/src/view/home/HomeBox.py b/src/view/home/HomeBox.py
index 429b903..14c0911 100644
--- a/src/view/home/HomeBox.py
+++ b/src/view/home/HomeBox.py
@@ -23,10 +23,10 @@ from sugar.graphics import style
from sugar.graphics import iconentry
from sugar.graphics.radiotoolbutton import RadioToolButton
-from view.home.activitiesring import ActivitiesRing
+from view.home.favoritesview import FavoritesView
from view.home.activitieslist import ActivitiesList
-_RING_VIEW = 0
+_FAVORITES_VIEW = 0
_LIST_VIEW = 1
_AUTOSEARCH_TIMEOUT = 1000
@@ -37,7 +37,7 @@ class HomeBox(gtk.VBox):
def __init__(self):
gobject.GObject.__init__(self)
- self._ring_view = ActivitiesRing()
+ self._favorites_view = FavoritesView()
self._list_view = ActivitiesList()
self._enable_xo_palette = False
@@ -47,7 +47,7 @@ class HomeBox(gtk.VBox):
self.pack_start(self._toolbar, expand=False)
self._toolbar.show()
- self._set_view(_RING_VIEW)
+ self._set_view(_FAVORITES_VIEW)
def __toolbar_query_changed_cb(self, toolbar, query):
if self._list_view is None:
@@ -59,18 +59,18 @@ class HomeBox(gtk.VBox):
self._set_view(view)
def _set_view(self, view):
- if view == _RING_VIEW:
+ if view == _FAVORITES_VIEW:
if self._list_view in self.get_children():
self.remove(self._list_view)
if self._enable_xo_palette:
- self._ring_view.enable_xo_palette()
+ self._favorites_view.enable_xo_palette()
- self.add(self._ring_view)
- self._ring_view.show()
+ self.add(self._favorites_view)
+ self._favorites_view.show()
elif view == _LIST_VIEW:
- if self._ring_view in self.get_children():
- self.remove(self._ring_view)
+ if self._favorites_view in self.get_children():
+ self.remove(self._favorites_view)
self.add(self._list_view)
self._list_view.show()
@@ -80,25 +80,11 @@ class HomeBox(gtk.VBox):
_REDRAW_TIMEOUT = 5 * 60 * 1000 # 5 minutes
def resume(self):
- # TODO: Do we need this?
- #if self._redraw_id is None:
- # self._redraw_id = gobject.timeout_add(self._REDRAW_TIMEOUT,
- # self._redraw_activity_ring)
- # self._redraw_activity_ring()
pass
def suspend(self):
- # TODO: Do we need this?
- #if self._redraw_id is not None:
- # gobject.source_remove(self._redraw_id)
- # self._redraw_id = None
pass
- def _redraw_activity_ring(self):
- # TODO: Do we need this?
- #self._donut.redraw()
- return True
-
def has_activities(self):
# TODO: Do we need this?
#return self._donut.has_activities()
@@ -106,8 +92,8 @@ class HomeBox(gtk.VBox):
def enable_xo_palette(self):
self._enable_xo_palette = True
- if self._ring_view is not None:
- self._ring_view.enable_xo_palette()
+ if self._favorites_view is not None:
+ self._favorites_view.enable_xo_palette()
class HomeToolbar(gtk.Toolbar):
__gtype_name__ = 'SugarHomeToolbar'
@@ -145,16 +131,16 @@ class HomeToolbar(gtk.Toolbar):
self._add_separator(expand=True)
- ring_button = RadioToolButton(named_icon='view-radial', group=None)
- ring_button.props.tooltip = _('Ring view')
- ring_button.props.accelerator = _('<Ctrl>R')
- ring_button.connect('toggled', self.__view_button_toggled_cb,
- _RING_VIEW)
- self.insert(ring_button, -1)
- ring_button.show()
+ favorites_button = RadioToolButton(named_icon='view-radial', group=None)
+ favorites_button.props.tooltip = _('Favorites view')
+ favorites_button.props.accelerator = _('<Ctrl>R')
+ favorites_button.connect('toggled', self.__view_button_toggled_cb,
+ _FAVORITES_VIEW)
+ self.insert(favorites_button, -1)
+ favorites_button.show()
list_button = RadioToolButton(named_icon='view-list')
- list_button.props.group = ring_button
+ list_button.props.group = favorites_button
list_button.props.tooltip = _('List view')
list_button.props.accelerator = _('<Ctrl>L')
list_button.connect('toggled', self.__view_button_toggled_cb,
diff --git a/src/view/home/Makefile.am b/src/view/home/Makefile.am
index 5306e2b..0983077 100644
--- a/src/view/home/Makefile.am
+++ b/src/view/home/Makefile.am
@@ -2,7 +2,8 @@ sugardir = $(pkgdatadir)/shell/view/home
sugar_PYTHON = \
__init__.py \
activitieslist.py \
- activitiesring.py \
+ favoritesview.py \
+ favoriteslayout.py \
FriendView.py \
FriendsBox.py \
launchbox.py \
diff --git a/src/view/home/favoriteslayout.py b/src/view/home/favoriteslayout.py
new file mode 100644
index 0000000..9ab4eff
--- /dev/null
+++ b/src/view/home/favoriteslayout.py
@@ -0,0 +1,225 @@
+# Copyright (C) 2008 One Laptop Per Child
+#
+# 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 logging
+import math
+import hashlib
+
+import gobject
+import gtk
+import hippo
+
+from sugar.graphics import style
+from sugar import activity
+
+_logger = logging.getLogger('FavoritesLayout')
+
+class FavoritesLayout(gobject.GObject, hippo.CanvasLayout):
+ __gtype_name__ = 'FavoritesLayout'
+
+ def __init__(self):
+ gobject.GObject.__init__(self)
+ self.box = None
+ self.fixed_positions = {}
+
+ def do_set_box(self, box):
+ self.box = box
+
+ def do_get_height_request(self, for_width):
+ return 0, gtk.gdk.screen_height() - style.GRID_CELL_SIZE
+
+ def do_get_width_request(self):
+ return 0, gtk.gdk.screen_width()
+
+ 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, 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, icon):
+ del self.fixed_positions[icon]
+ self.box.remove(icon)
+ self.update_icon_sizes()
+
+ def move_icon(self, icon, x, y):
+ if icon not in self.box.get_children():
+ raise ValueError('Child not in box.')
+
+ 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 update_icon_sizes(self):
+ pass
+
+ def do_allocate(self, x, y, width, height, req_width, req_height,
+ origin_changed):
+ raise NotImplementedError()
+
+class RandomLayout(FavoritesLayout):
+ __gtype_name__ = 'RandomLayout'
+
+ def __init__(self):
+ FavoritesLayout.__init__(self)
+
+ def append(self, icon):
+ FavoritesLayout.append(self, icon)
+ icon.props.size = style.STANDARD_ICON_SIZE
+
+ def do_allocate(self, x, y, width, height, req_width, req_height,
+ origin_changed):
+ for child in self.box.get_layout_children():
+ # 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)
+
+ if child.item in self.fixed_positions:
+ x, y = self.fixed_positions[child.item]
+ else:
+ name_hash = hashlib.md5(child.item.get_bundle_id())
+
+ x = int(name_hash.hexdigest()[:5], 16) % (width - child_width)
+ y = int(name_hash.hexdigest()[-5:], 16) % (height - child_height)
+
+ # TODO Handle collisions
+
+ child.allocate(int(x), int(y), child_width, child_height,
+ origin_changed)
+
+_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(FavoritesLayout):
+ __gtype_name__ = 'RingLayout'
+
+ def __init__(self):
+ FavoritesLayout.__init__(self)
+
+ def _calculate_radius_and_icon_size(self, children_count):
+ angle = 2 * math.pi / children_count
+
+ # what's the radius required without downscaling?
+ distance = style.STANDARD_ICON_SIZE + style.DEFAULT_SPACING
+ icon_size = style.STANDARD_ICON_SIZE
+
+ if children_count == 1:
+ radius = 0
+ else:
+ radius = math.sqrt(distance ** 2 /
+ (math.sin(angle) ** 2 + (math.cos(angle) - 1) ** 2))
+
+ 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
+ # 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
+
+ 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
+ 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 do_allocate(self, 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))
+
+ for n in range(len(children_in_ring)):
+ child = children_in_ring[n]
+
+ x, y = self._calculate_position(radius, icon_size, n,
+ len(children_in_ring))
+
+ # 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)
+
+ 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)
+
+ x, y = self.fixed_positions[child.item]
+
+ child.allocate(int(x), int(y), child_width, child_height,
+ origin_changed)
+
diff --git a/src/view/home/activitiesring.py b/src/view/home/favoritesview.py
index a250c1d..bf8ab38 100644
--- a/src/view/home/activitiesring.py
+++ b/src/view/home/favoritesview.py
@@ -34,18 +34,19 @@ import view.Shell
from view.palettes import JournalPalette
from view.palettes import CurrentActivityPalette, ActivityPalette
from view.home.MyIcon import MyIcon
+from view.home.favoriteslayout import RandomLayout
from model import shellmodel
from model.shellmodel import ShellModel
from hardware import schoolserver
from controlpanel.gui import ControlPanel
from session import get_session_manager
-_logger = logging.getLogger('ActivitiesRing')
+_logger = logging.getLogger('FavoritesView')
_ICON_DND_TARGET = ('activity-icon', gtk.TARGET_SAME_WIDGET, 0)
-class ActivitiesRing(hippo.Canvas):
- __gtype_name__ = 'SugarActivitiesRing'
+class FavoritesView(hippo.Canvas):
+ __gtype_name__ = 'SugarFavoritesView'
def __init__(self, **kwargs):
gobject.GObject.__init__(self, **kwargs)
@@ -63,7 +64,7 @@ class ActivitiesRing(hippo.Canvas):
self._current_activity = CurrentActivityIcon()
self._box.append(self._current_activity, hippo.PACK_FIXED)
- self._layout = RingLayout()
+ self._layout = RandomLayout()
self._box.set_layout(self._layout)
registry = activity.get_registry()
@@ -303,159 +304,6 @@ 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
-
- def do_get_height_request(self, for_width):
- return 0, gtk.gdk.screen_height() - style.GRID_CELL_SIZE
-
- def do_get_width_request(self):
- return 0, gtk.gdk.screen_width()
-
- def _calculate_radius_and_icon_size(self, children_count):
- angle = 2 * math.pi / children_count
-
- # what's the radius required without downscaling?
- distance = style.STANDARD_ICON_SIZE + style.DEFAULT_SPACING
- icon_size = style.STANDARD_ICON_SIZE
-
- if children_count == 1:
- radius = 0
- else:
- radius = math.sqrt(distance ** 2 /
- (math.sin(angle) ** 2 + (math.cos(angle) - 1) ** 2))
-
- 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
- # 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
-
- 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
- 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, 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, icon):
- del self._fixed_positions[icon]
- self._box.remove(icon)
- self._update_icon_sizes()
-
- def move_icon(self, icon, x, y):
- if icon not in self._box.get_children():
- raise ValueError('Child not in box.')
-
- 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,
- 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))
-
- for n in range(len(children_in_ring)):
- child = children_in_ring[n]
-
- x, y = self._calculate_position(radius, icon_size, n,
- len(children_in_ring))
-
- # 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)
-
- 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)
-
- 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):
MyIcon.__init__(self, scale)
diff --git a/src/view/palettes.py b/src/view/palettes.py
index bda7f95..8406fd0 100644
--- a/src/view/palettes.py
+++ b/src/view/palettes.py
@@ -116,11 +116,11 @@ class ActivityPalette(Palette):
def _update_favorite_item(self):
label = self._favorite_item.child
if self._favorite:
- label.set_text(_('Remove from ring'))
+ label.set_text(_('Remove favorite'))
xo_color = XoColor('%s,%s' % (style.COLOR_WHITE.get_svg(),
style.COLOR_TRANSPARENT.get_svg()))
else:
- label.set_text(_('Add to ring'))
+ label.set_text(_('Make favorite'))
xo_color = profile.get_color()
self._favorite_icon.props.xo_color = xo_color