[PATCH] adding spiral to circle view
Walter Bender
walter at sugarlabs.org
Fri Aug 6 08:53:10 EDT 2010
---
src/jarabe/desktop/favoriteslayout.py | 92 ++++++++++++++++++++++++++-------
1 files changed, 73 insertions(+), 19 deletions(-)
diff --git a/src/jarabe/desktop/favoriteslayout.py
b/src/jarabe/desktop/favoriteslayout.py
index 85e1b59..a945c49 100644
--- a/src/jarabe/desktop/favoriteslayout.py
+++ b/src/jarabe/desktop/favoriteslayout.py
@@ -1,4 +1,5 @@
# Copyright (C) 2008 One Laptop Per Child
+# Copyright (C) 2010 Sugar Labs
#
# 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
@@ -201,6 +202,11 @@ class RingLayout(FavoritesLayout):
def __init__(self):
FavoritesLayout.__init__(self)
self._locked_children = {}
+ self._spiral = False
+ self._radius = _MINIMUM_RADIUS
+ self._orientation = math.pi
+ self._icon_size = style.STANDARD_ICON_SIZE
+ self._count = -1
def append(self, icon, locked=False):
FavoritesLayout.append(self, icon, locked)
@@ -221,31 +227,79 @@ class RingLayout(FavoritesLayout):
self._locked_children[child] = (x, y)
def _calculate_radius_and_icon_size(self, children_count):
- # what's the radius required without downscaling?
+ """ determine if we are drawing a circle or a spiral """
distance = style.STANDARD_ICON_SIZE + style.DEFAULT_SPACING
- icon_size = style.STANDARD_ICON_SIZE
- # circumference is 2*pi*r; we want this to be at least
- # 'children_count * distance'
+
radius = children_count * distance / (2 * math.pi)
- # limit computed radius to reasonable bounds.
- radius = max(radius, _MINIMUM_RADIUS)
- radius = min(radius, _MAXIMUM_RADIUS)
- # recompute icon size from limited radius
- if children_count > 0:
- icon_size = (2 * math.pi * radius / children_count) \
- - style.DEFAULT_SPACING
- # limit adjusted icon size.
- icon_size = max(icon_size, style.SMALL_ICON_SIZE)
- icon_size = min(icon_size, style.MEDIUM_ICON_SIZE)
- return radius, icon_size
+ if radius < _MAXIMUM_RADIUS:
+ self._spiral = False
+ self._icon_size = style.STANDARD_ICON_SIZE
+ else:
+ self._spiral = True
+ radius = _MINIMUM_RADIUS
+
+ # If there are fewer children, try increasing icon_size.
+ if self._count > children_count:
+ logging.debug('resetting count: %d > %d' % (self._count,
children_count))
+ if self._icon_size == style.MEDIUM_ICON_SIZE:
+ self._icon_size = style.STANDARD_ICON_SIZE
+ elif self._icon_size == style.SMALL_ICON_SIZE:
+ self._icon_size = style.MEDIUM_ICON_SIZE
+ self._count = children_count
+
+ return radius, self._icon_size
+
+ def _calculate_xy(self, icon_size, width, height):
+ """ Convert r, o to x, y """
+ x = -math.sin(self._orientation) * self._radius
+ y = math.cos(self._orientation) * self._radius
+ self._calculate_new_radius_orientation(icon_size +\
+ style.DEFAULT_SPACING)
+
+ x = int(x) + (width - icon_size) / 2
+ y = int(y) + (height - icon_size - (style.GRID_CELL_SIZE / 2) ) / 2
+ return x, y
+
+ def _calculate_new_radius_orientation(self, icon_size):
+ """ Based upon current radius, calculate new increments """
+ circumference = self._radius * 2 * math.pi
+ n = circumference / icon_size
+ self._orientation += 2 * math.pi / n
+ self._radius += float(icon_size) / n
def _calculate_position(self, radius, icon_size, index, children_count,
sin=math.sin, cos=math.cos):
+ """ Try fitting a circle or a spiral """
+
width, height = self.box.get_allocation()
- angle = index * (2 * math.pi / children_count) - math.pi / 2
- x = radius * cos(angle) + (width - icon_size) / 2
- y = radius * sin(angle) + (height - icon_size -
- (style.GRID_CELL_SIZE/2) ) / 2
+ if not self._spiral:
+ angle = index * (2 * math.pi / children_count) - math.pi / 2
+ x = radius * cos(angle) + (width - icon_size) / 2
+ y = radius * sin(angle) + (height - icon_size -
+ (style.GRID_CELL_SIZE/2) ) / 2
+ else:
+ min_width_, box_width = self.box.get_width_request()
+ min_height_, box_height = self.box.get_height_request(box_width)
+ if index == 0:
+ self._radius = _MINIMUM_RADIUS
+ self._orientation = math.pi
+ x, y = self._calculate_xy(icon_size, width, height)
+ # If we run off the edge, keep spiraling until we return.
+ while x < min_width_ or x > box_width - icon_size or \
+ y < min_height_ or y > box_height - icon_size:
+ x, y = self._calculate_xy(icon_size, width, height)
+ # If we run past a corner, we will never return, so time to
+ # shrink the icons.
+ if (x < min_height_ and \
+ (y < min_width_ or y > box_height - icon_size)) or \
+ (x > box_width - icon_size and \
+ (y < min_width_ or y > box_height - icon_size)):
+ if self._icon_size == style.STANDARD_ICON_SIZE:
+ self._icon_size = style.MEDIUM_ICON_SIZE
+ elif self._icon_size == style.MEDIUM_ICON_SIZE:
+ self._icon_size = style.SMALL_ICON_SIZE
+ else: # give up
+ return x, y
return x, y
def _get_children_in_ring(self):
--
1.7.0.4
-walter
--
Walter Bender
Sugar Labs
http://www.sugarlabs.org
More information about the Sugar-devel
mailing list