Changeset 2328

Show
Ignore:
Timestamp:
07/07/08 03:35:05 (5 months ago)
Author:
arj..@yirdis.nl
Message:

Moved index/sort code into tree.py, since the sort order is closely related to the way the tree is organized (depth-first). Canvas.sort can be used to order a set of nodes in traversal order.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • gaphas/trunk/gaphas/canvas.py

    r2327 r2328  
    1313from gaphas.decorators import nonrecursive, async, PRIORITY_HIGH_IDLE 
    1414from state import observed, reversible_method, reversible_pair 
    15 from gaphas.sorter import Sorter 
    1615 
    1716 
     
    4645        self._dirty_items = set() 
    4746        self._dirty_matrix_items = set() 
     47        self._dirty_index = False 
    4848 
    4949        self._registered_views = set() 
    50  
    51         self._sorter = Sorter(self._tree) 
    52  
    53     sorter = property(lambda s: s._sorter) 
    5450     
    5551    solver = property(lambda s: s._solver) 
     
    7369        self._tree.add(item, parent) 
    7470        item._set_canvas(self) 
    75         item._sort_key = self.sorter.get_key(item) 
     71        self._dirty_index = True 
    7672 
    7773        self.update_matrix(item, parent) 
     
    135131        self._tree.reparent(item, parent) 
    136132 
    137         for item in self._tree.get_children(parent): 
    138             item._sort_key = self.sorter.get_key(item) 
     133        self._dirty_index = True 
    139134 
    140135 
     
    260255        Return a set of items that are connected to ``item``. 
    261256        The list contains tuples (item, handle). As a result an item may be 
    262         in the list more than once (depending on the number of handles that 
    263         are connected). If ``item`` is connected to itself it will also appear 
    264         in the list. 
    265  
    266         >>> c = Canvas() 
    267         >>> from gaphas import item 
    268         >>> i = item.Line() 
    269         >>> c.add(i) 
     257            in the list more than once (depending on the number of handles that 
     258            are connected). If ``item`` is connected to itself it will also appear 
     259            in the list. 
     260 
     261            >>> c = Canvas() 
     262            >>> from gaphas import item 
     263            >>> i = item.Line() 
     264            >>> c.add(i) 
    270265        >>> ii = item.Line() 
    271266        >>> c.add(ii) 
     
    288283        return connected_items 
    289284 
     285     
     286    def sort(self, items, reverse=False): 
     287        """ 
     288        Sort a list of items in the order in which they are traversed in 
     289        the canvas (Depth first). 
     290 
     291        >>> c = Canvas() 
     292        >>> from gaphas import item 
     293        >>> i1 = item.Line() 
     294        >>> c.add(i1) 
     295        >>> i2 = item.Line() 
     296        >>> c.add(i2) 
     297        >>> i3 = item.Line() 
     298        >>> c.add (i3) 
     299        >>> c.update() # ensure items are indexed 
     300        >>> i1._canvas_index 
     301        0 
     302        >>> s = c.sort([i2, i3, i1]) 
     303        >>> s[0] is i1 and s[1] is i2 and s[2] is i3 
     304        True 
     305        """ 
     306        return self._tree.sort(items, index_key='_canvas_index', reverse=reverse) 
     307 
    290308 
    291309    #{ Matrices 
     
    316334            self.update_matrix(item) 
    317335        return item._matrix_c2i 
    318  
    319336 
    320337    #{ Update cycle 
     
    411428        """ 
    412429 
    413         sort = self._sorter.sort 
     430        if self._dirty_index: 
     431            self.update_index() 
     432            self._dirty_index = False 
     433 
     434        sort = self.sort 
    414435 
    415436        # perform update requests for parents of dirty items 
     
    578599 
    579600        return dirty_matrix_items 
     601 
     602 
     603    def update_index(self): 
     604        """ 
     605        Provide each item in the canvas with an index attribute. This makes 
     606        for fast searching of items. 
     607        """ 
     608        self._tree.index_nodes('_canvas_index') 
    580609 
    581610 
  • gaphas/trunk/gaphas/item.py

    r2321 r2328  
    159159        self._matrix_i2v = WeakKeyDictionary() 
    160160        self._matrix_v2i = WeakKeyDictionary() 
    161  
    162         # Used by gaphas.sorter.Sorter to order items fast. 
    163         self._sort_key = None 
    164161 
    165162 
  • gaphas/trunk/gaphas/painter.py

    r2326 r2328  
    312312        canvas = view.canvas 
    313313        cairo = context.cairo 
    314         for item in view.selected_items: 
     314        # Order matters here: 
     315        for item in canvas.sort(view.selected_items): 
    315316            self._draw_handles(item, view, cairo) 
     317        # Draw nice opaque handles when hovering an item: 
    316318        item = view.hovered_item 
    317319        if item and item not in view.selected_items: 
  • gaphas/trunk/gaphas/tree.py

    r2321 r2328  
    77# $HeadURL$ 
    88 
    9 import operato
     9from operator import attrgette
    1010from state import observed, reversible_method, \ 
    1111        reversible_pair, disable_dispatching 
     
    1414class Tree(object): 
    1515    """ 
    16     A Tree structure. 
    17     None is the root node. 
     16    A Tree structure. Nodes are stores in a depth-first order. 
     17     
     18    ``None`` is the root node. 
    1819 
    1920    @invariant: len(self._children) == len(self._nodes) + 1 
     
    157158            yield parent 
    158159            parent = self.get_parent(parent) 
     160 
     161    def index_nodes(self, index_key): 
     162        """ 
     163        Provide each item in the tree with an index attribute. This makes 
     164        for fast sorting of items. 
     165 
     166        >>> class A(object): 
     167        ...     def __init__(self, n): 
     168        ...         self.n = n 
     169        ...     def __repr__(self): 
     170        ...         return self.n 
     171        >>> t = Tree() 
     172        >>> a = A('a') 
     173        >>> t.add(a) 
     174        >>> t.add(A('b')) 
     175        >>> t.add(A('c'), parent=a) 
     176        >>> t.nodes 
     177        [a, c, b] 
     178        >>> t.index_nodes('my_key') 
     179        >>> t.nodes[0].my_key, t.nodes[1].my_key, t.nodes[2].my_key 
     180        (0, 1, 2) 
     181 
     182        For sorting, see ``sort()``. 
     183        """ 
     184        nodes = self.nodes 
     185        lnodes = len(nodes) 
     186        map(setattr, nodes, [index_key] * lnodes, xrange(lnodes)) 
     187 
     188    def sort(self, nodes, index_key, reverse=False): 
     189        """ 
     190        Sort a set (or list) of nodes. 
     191         
     192        >>> class A(object): 
     193        ...     def __init__(self, n): 
     194        ...         self.n = n 
     195        ...     def __repr__(self): 
     196        ...         return self.n 
     197        >>> t = Tree() 
     198        >>> a = A('a') 
     199        >>> t.add(a) 
     200        >>> t.add(A('b')) 
     201        >>> t.add(A('c'), parent=a) 
     202        >>> t.nodes    # the series from Tree.index_nodes 
     203        [a, c, b] 
     204        >>> t.index_nodes('my_key') 
     205        >>> selection = (t.nodes[2], t.nodes[1]) 
     206        >>> t.sort(selection, index_key='my_key') 
     207        [c, b] 
     208        """ 
     209        if index_key: 
     210            return sorted(nodes, key=attrgetter(index_key), reverse=reverse) 
     211        else: 
     212            raise NotImplemented('index_key should be provided.') 
    159213 
    160214    def _add_to_nodes(self, node, parent): 
  • gaphas/trunk/gaphas/view.py

    r2321 r2328  
    1616from decorators import async, PRIORITY_HIGH_IDLE 
    1717from decorators import nonrecursive 
    18 from gaphas.sorter import Sorted 
    1918 
    2019# Handy debug flag for drawing bounding boxes around the items. 
     
    3635 
    3736        # Handling selections. 
    38         self._selected_items = Sorted(canvas
     37        self._selected_items = set(
    3938        self._focused_item = None 
    4039        self._hovered_item = None 
     
    6160 
    6261        self._canvas = canvas 
    63         self._selected_items.canvas = canvas 
    64          
    6562 
    6663    canvas = property(lambda s: s._canvas, _set_canvas) 
     
    127124 
    128125        if item: 
    129             self.selected_items = item #.add(item) 
     126            self.select_item(item) 
    130127        if item is not self._focused_item: 
    131128            self._focused_item = item 
     
    210207        point = (x, y) 
    211208        items = self._qtree.find_intersect((x, y, 1, 1)) 
    212         for item in self._canvas.sorter.sort(items, reverse=True): 
     209        for item in self._canvas.sort(items, reverse=True): 
    213210            if not selected and item in self.selected_items: 
    214211                continue  # skip selected items 
     
    230227        else: 
    231228            items = self._qtree.find_inside(rect) 
    232         return self._canvas.sorter.sort(items, reverse=reverse) 
     229        return self._canvas.sort(items, reverse=reverse) 
    233230 
    234231 
     
    526523        item as update areas. Of course with a pythonic flavor: update 
    527524        any number of items at once. 
     525 
     526        TODO: Should we also create a (sorted) list of items that need redrawal? 
    528527        """ 
    529528        queue_draw_area = self.queue_draw_area