Ticket #2143: 0001-adding-spirial-to-circle-view.patch

File 0001-adding-spirial-to-circle-view.patch, 5.9 KB (added by walter, 14 years ago)

adding spiral morph to ring view

  • src/jarabe/desktop/favoriteslayout.py

    From 4ad5ad7e003fdd9eeb703c1287bd9f5c8484e967 Mon Sep 17 00:00:00 2001
    From: Walter Bender <walter@sugarlabs.org>
    Date: Fri, 6 Aug 2010 08:53:10 -0400
    Subject: [PATCH] adding spirial to circle view
    
    ---
     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 b  
    11# Copyright (C) 2008 One Laptop Per Child
     2# Copyright (C) 2010 Sugar Labs
    23#
    34# This program is free software; you can redistribute it and/or modify
    45# it under the terms of the GNU General Public License as published by
    class RingLayout(FavoritesLayout): 
    201202    def __init__(self):
    202203        FavoritesLayout.__init__(self)
    203204        self._locked_children = {}
     205        self._spiral = False
     206        self._radius = _MINIMUM_RADIUS
     207        self._orientation = math.pi
     208        self._icon_size = style.STANDARD_ICON_SIZE
     209        self._count = -1
    204210
    205211    def append(self, icon, locked=False):
    206212        FavoritesLayout.append(self, icon, locked)
    class RingLayout(FavoritesLayout): 
    221227            self._locked_children[child] = (x, y)
    222228
    223229    def _calculate_radius_and_icon_size(self, children_count):
    224         # what's the radius required without downscaling?
     230        """ determine if we are drawing a circle or a spiral """
    225231        distance = style.STANDARD_ICON_SIZE + style.DEFAULT_SPACING
    226         icon_size = style.STANDARD_ICON_SIZE
    227         # circumference is 2*pi*r; we want this to be at least
    228         # 'children_count * distance'
     232
    229233        radius = children_count * distance / (2 * math.pi)
    230         # limit computed radius to reasonable bounds.
    231         radius = max(radius, _MINIMUM_RADIUS)
    232         radius = min(radius, _MAXIMUM_RADIUS)
    233         # recompute icon size from limited radius
    234         if children_count > 0:
    235             icon_size = (2 * math.pi * radius / children_count) \
    236                         - style.DEFAULT_SPACING
    237         # limit adjusted icon size.
    238         icon_size = max(icon_size, style.SMALL_ICON_SIZE)
    239         icon_size = min(icon_size, style.MEDIUM_ICON_SIZE)
    240         return radius, icon_size
     234        if radius < _MAXIMUM_RADIUS:
     235            self._spiral = False
     236            self._icon_size = style.STANDARD_ICON_SIZE
     237        else:
     238            self._spiral = True
     239            radius = _MINIMUM_RADIUS
     240
     241        # If there are fewer children, try increasing icon_size.
     242        if self._count > children_count:
     243            logging.debug('resetting count: %d > %d' % (self._count, children_count))
     244            if self._icon_size == style.MEDIUM_ICON_SIZE:
     245                self._icon_size = style.STANDARD_ICON_SIZE
     246            elif self._icon_size == style.SMALL_ICON_SIZE:
     247                self._icon_size = style.MEDIUM_ICON_SIZE
     248        self._count = children_count
     249
     250        return radius, self._icon_size
     251
     252    def _calculate_xy(self, icon_size, width, height):
     253        """ Convert r, o to x, y """
     254        x = -math.sin(self._orientation) * self._radius
     255        y = math.cos(self._orientation) * self._radius
     256        self._calculate_new_radius_orientation(icon_size +\
     257                                                   style.DEFAULT_SPACING)
     258
     259        x = int(x) + (width - icon_size) / 2
     260        y = int(y) + (height - icon_size - (style.GRID_CELL_SIZE / 2) ) / 2
     261        return x, y
     262
     263    def _calculate_new_radius_orientation(self, icon_size):
     264        """ Based upon current radius, calculate new increments """
     265        circumference = self._radius * 2 * math.pi
     266        n = circumference / icon_size
     267        self._orientation += 2 * math.pi / n
     268        self._radius += float(icon_size) / n
    241269
    242270    def _calculate_position(self, radius, icon_size, index, children_count,
    243271                            sin=math.sin, cos=math.cos):
     272        """ Try fitting a circle or a spiral """
     273
    244274        width, height = self.box.get_allocation()
    245         angle = index * (2 * math.pi / children_count) - math.pi / 2
    246         x = radius * cos(angle) + (width - icon_size) / 2
    247         y = radius * sin(angle) + (height - icon_size -
    248                                    (style.GRID_CELL_SIZE/2) ) / 2
     275        if not self._spiral:
     276            angle = index * (2 * math.pi / children_count) - math.pi / 2
     277            x = radius * cos(angle) + (width - icon_size) / 2
     278            y = radius * sin(angle) + (height - icon_size -
     279                                       (style.GRID_CELL_SIZE/2) ) / 2
     280        else:
     281            min_width_, box_width = self.box.get_width_request()
     282            min_height_, box_height = self.box.get_height_request(box_width)
     283            if index == 0:
     284                self._radius = _MINIMUM_RADIUS
     285                self._orientation = math.pi
     286            x, y = self._calculate_xy(icon_size, width, height)
     287            # If we run off the edge, keep spiralling until we return.
     288            while x < min_width_ or x > box_width - icon_size or \
     289                    y < min_height_ or y > box_height - icon_size:
     290                x, y = self._calculate_xy(icon_size, width, height)
     291                # If we run past a corner, we will never return, so time to
     292                # shrink the icons.
     293                if (x < min_height_ and \
     294                        (y < min_width_ or y > box_height - icon_size)) or \
     295                   (x > box_width - icon_size and \
     296                             (y < min_width_ or y > box_height - icon_size)):
     297                    if self._icon_size == style.STANDARD_ICON_SIZE:
     298                        self._icon_size = style.MEDIUM_ICON_SIZE
     299                    elif self._icon_size == style.MEDIUM_ICON_SIZE:
     300                        self._icon_size = style.SMALL_ICON_SIZE
     301                    else: # give up
     302                        return x, y
    249303        return x, y
    250304
    251305    def _get_children_in_ring(self):