Added matrix updating to canvas.

This commit is contained in:
Arjan Molenaar 2006-03-24 20:22:23 +00:00
parent 8cfefe8a80
commit f488ee28b2
4 changed files with 93 additions and 9 deletions

View File

@ -5,6 +5,7 @@ and a constraint solver.
import tree
import solver
from geometry import matrix_multiply
class Canvas(object):
"""Container class for Items.
@ -14,6 +15,7 @@ class Canvas(object):
self._tree = tree.Tree()
self._solver = solver.Solver()
self._dirty_items = set()
self._dirty_matrix_items = set()
self._in_update = False
def add(self, item, parent=None):
@ -30,6 +32,7 @@ class Canvas(object):
item.canvas = self
self._tree.add(item, parent)
self._dirty_items.add(item)
self._dirty_matrix_items.add(item)
def remove(self, item):
"""Remove item from the canvas
@ -45,13 +48,26 @@ class Canvas(object):
self._tree.remove(item)
item.canvas = None
self._dirty_items.discard(item)
self._dirty_matrix_items.discard(item)
def request_update(self, item):
"""Set an update request for the item.
>>> c = Canvas()
>>> import item
>>> i = item.Item()
>>> ii = item.Item()
>>> c.add(i)
>>> c.add(ii, i)
>>> len(c._dirty_items)
2
>>> c.update_now()
>>> len(c._dirty_items)
0
"""
if not self._in_update:
self._dirty_items.add(item)
self._dirty_matrix_items.add(item)
# Also add update requests for parents of item
parent = self._tree.get_parent(item)
@ -61,6 +77,11 @@ class Canvas(object):
# TODO: Schedule update, directly or through a view.
def request_matrix_update(self, item):
"""Schedule only the matrix to be updated.
"""
self._dirty_matrix_items.add(item)
def update_needed(self):
"""Returns True or False depending on if an update is needed.
>>> c=Canvas()
@ -81,21 +102,67 @@ class Canvas(object):
try:
dirty_items = [ item for item in reversed(self._tree.nodes) \
if item in self._dirty_items ]
context = {}
for item in dirty_items:
# TODO: calculate context.matrix_i2w
item.pre_update(context)
self.update_matrices()
self._solver.solve()
self.update_matrices()
for item in dirty_items:
item.update(context)
finally:
self._dirty_items.clear()
self._in_update = False
def get_matrix_i2w(self, item):
matrix = item.matrix
def update_matrices(self):
"""Update the matrix of the items scheduled to be updated
*and* their sub-items.
>>> c = Canvas()
>>> import item
>>> i = item.Item()
>>> ii = item.Item()
>>> c.add(i)
>>> i.matrix = (1.0, 0.0, 0.0, 1.0, 5.0, 0.0)
>>> c.add(ii, i)
>>> ii.matrix = (1.0, 0.0, 0.0, 1.0, 0.0, 8.0)
>>> c.update_matrices()
>>> i._matrix_w2i
(1.0, 0.0, 0.0, 1.0, 5.0, 0.0)
>>> ii._matrix_w2i
(1.0, 0.0, 0.0, 1.0, 5.0, 8.0)
>>> len(c._dirty_items)
2
"""
dirty_items = self._dirty_matrix_items
while dirty_items:
item = dirty_items.pop()
self.update_matrix_w2i(item)
def update_matrix_w2i(self, item, recursive=True):
"""Update the World-to-Item (w2i) matrix for @item.
This is stored as @item._matrix_w2i.
@recursive == True will also update child objects.
"""
parent = self._tree.get_parent(item)
# First remove from the to-be-updated set.
self._dirty_matrix_items.discard(item)
if parent:
if parent in self._dirty_matrix_items:
self.update_matrix_w2i(parent)
item._matrix_w2i = matrix_multiply(parent._matrix_w2i, item.matrix)
else:
item._matrix_w2i = tuple(item.matrix)
if recursive:
for child in self._tree.get_children(item):
self.update_matrix_w2i(child, recursive)
if __name__ == '__main__':
import doctest
doctest.testmod()

View File

@ -1,8 +1,13 @@
""" Item and Handle.
"""
from geometry import matrix_identity
class Handle(object):
"""Handles are used to support modifications of Items.
"""
def __init__(self, pos=(0,0)):
self._pos = pos
@ -20,7 +25,7 @@ class Item(object):
def __init__(self, canvas=None):
self._canvas = canvas
self.dirty = True
self.matrix = matrix_identity()
def _set_canvas(self, canvas):
assert not canvas or not self._canvas or self._canvas is canvas

View File

@ -28,6 +28,9 @@ class Tree(object):
if node in children:
return item
def get_children(self, node):
return self._children[node]
def get_siblings(self, node):
parent = self.get_parent(node)
return self._children[parent]

15
view.py
View File

@ -6,8 +6,14 @@ import gtk
class View(gtk.Widget):
def __init__(self):
pass
def __init__(self, canvas=None):
self._canvas = canvas
self._tool = None
def _set_canvas(self, canvas):
self._canvas = canvas
canvas = property(lambda s: s._canvas, _set_canvas)
def do_expose(self, event):
print 'expose', event
@ -17,5 +23,8 @@ class View(gtk.Widget):
"""
def do_realize(self):
"""Realize the window (GDK) and some other stuff, used from
the GTK+ framework.
"""
# create gdk.Window() for this widget.