added Revision and HeadURL properties to all files.

This commit is contained in:
Arjan Molenaar 2006-04-27 09:56:34 +00:00
parent fb3c36767b
commit cc60438a55
13 changed files with 288 additions and 248 deletions

View File

@ -3,6 +3,9 @@ A Canvas owns a set of Items and acts as a container for both the items
and a constraint solver.
"""
__version__ = "$Revision$"
# $HeadURL$
import tree
import solver
from geometry import Matrix

View File

@ -1,8 +1,11 @@
'''equation solver using attributes and introspection.
"""equation solver using attributes and introspection.
Class Constraint from
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/303396
'''
"""
__version__ = "$Revision$"
# $HeadURL$
from __future__ import division
@ -10,8 +13,8 @@ TOL = 0.0000001 # tolerance
ITERLIMIT = 1000 # iteration limit
class Constraint(object):
'''takes a function, named arg value (opt.) and returns a Constraint object
'''
"""takes a function, named arg value (opt.) and returns a Constraint object
"""
def __init__(self, f, **args):
self._f = f
@ -30,13 +33,13 @@ class Constraint(object):
return 'Constraint(%s)' % self._f.func_code.co_name
def __getattr__(self, name):
'''used to extract function argument values
'''
"""used to extract function argument values
"""
self._args[name]
return self.solve_for(name)
def __setattr__(self, name, value):
'''sets function argument values'''
"""sets function argument values"""
# Note - once self._args is created, no new attributes can
# be added to self.__dict__. This is a good thing as it throws
# an exception if you try to assign to an arg which is inappropriate
@ -50,13 +53,13 @@ class Constraint(object):
object.__setattr__(self, name, value)
def set(self, **args):
'''sets values of function arguments'''
"""sets values of function arguments"""
for arg in args:
self._args[arg] # raise exception if arg not in _args
setattr(self, arg, args[arg])
def solve_for(self, arg):
'''Newton's method solver'''
"""Newton's method solver"""
args = self._args
close_runs = 10 # after getting close, do more passes
if self._args[arg]:
@ -68,7 +71,7 @@ class Constraint(object):
else:
x1 = x0*1.1
def f(x):
'''function to solve'''
"""function to solve"""
args[arg] = x
return self._f(**args)
fx0 = f(x0)

View File

@ -2,6 +2,9 @@
A simple demo app.
"""
__version__ = "$Revision$"
# $HeadURL$
import pygtk
pygtk.require('2.0')

View File

@ -2,6 +2,9 @@
These items are used in various tests.
"""
__version__ = "$Revision$"
# $HeadURL$
from item import Handle, Element, Item
from item import NW, NE,SW, SE
from solver import solvable

File diff suppressed because one or more lines are too long

View File

@ -11,6 +11,9 @@ A point is represented as a tuple (x, y).
"""
__version__ = "$Revision$"
# $HeadURL$
from math import sqrt
# This saves me a lot of coding:
from cairo import Matrix

View File

@ -1,3 +1,8 @@
"""
"""
__version__ = "$Revision$"
# $HeadURL$
from geometry import Matrix, distance_line_point
from solver import solvable, WEAK, NORMAL, STRONG

View File

@ -1,237 +1,240 @@
"""
The painter module provides different painters for parts of the canvas.
Painters can be swapped in and out.
Each painter takes are of a layer in the canvas (such as grid, items
and handles).
"""
from cairo import Matrix, ANTIALIAS_NONE
from canvas import Context
from geometry import Rectangle
DEBUG_DRAW_BOUNDING_BOX = False
class Painter(object):
"""Painter interface.
"""
def paint(self, context):
pass
class PainterChain(Painter):
"""Chain up a set of painters.
like ToolChain.
"""
def __init__(self):
self._painters = []
def append(self, painter):
self._painters.append(painter)
def prepend(self, painter):
self._painters.insert(0, painter)
def paint(self, context):
for painter in self._painters:
painter.paint(context)
class DrawContext(Context):
"""Special context for draw()'ing the item. The draw-context contains
stuff like the view, the cairo context and properties like selected and
focused.
"""
painter = None
cairo = None
def __init__(self, **kwargs):
super(DrawContext, self).__init__(**kwargs)
def draw_children(self):
"""Extra helper method for drawing child items from within
the Item.draw() method.
"""
self.painter._draw_items(self.children,
self.view,
self.cairo,
self.update_bounds)
class CairoContextWrapper(object):
"""Delegate all calls to the wrapped CairoContext, intercept
stroke(), fill() and a few others so the bounding box of the
item involved can be calculated.
"""
def __init__(self, cairo):
self._cairo = cairo
self._bounds = None # a Rectangle object
def __getattr__(self, key):
return getattr(self._cairo, key)
def _update_bounds(self, bounds):
if not self._bounds:
self._bounds = Rectangle(*bounds)
else:
self._bounds += bounds
def _extents(self, funcname):
ctx = self._cairo
ctx.save()
ctx.identity_matrix()
self._update_bounds(getattr(ctx, funcname)())
ctx.restore()
def fill(self):
self._extents('fill_extents')
return self._cairo.fill()
def fill_preserve(self):
self._extents('fill_extents')
return self._cairo.fill_preserve()
def stroke(self):
self._extents('stroke_extents')
return self._cairo.stroke()
def stroke_preserve(self):
self._extents('stroke_extents')
return self._cairo.stroke_preserve()
def show_text(self, utf8):
cairo = self._cairo
e = cairo.text_extents(utf8)
x0, y0 = cairo.user_to_device(e[0], e[1])
x1, y1 = cairo.user_to_device(e[0]+e[2], e[1]+e[3])
self._update_bounds((x0, y0, x1, y1))
return cairo.show_text(utf8)
class ItemPainter(Painter):
def _draw_items(self, items, view, cairo, update_bounds):
"""Draw the items. This method can also be called from DrawContext
to draw sub-items.
"""
for item in items:
cairo.save()
try:
cairo.set_matrix(view.matrix)
cairo.transform(view.canvas.get_matrix_i2w(item))
if update_bounds:
the_context = CairoContextWrapper(cairo)
else:
# No wrapper:
the_context = cairo
item.draw(DrawContext(painter=self,
update_bounds=update_bounds,
view=view,
cairo=the_context,
parent=view.canvas.get_parent(item),
children=view.canvas.get_children(item),
selected=(item in view.selected_items),
focused=(item is view.focused_item),
hovered=(item is view.hovered_item)))
if update_bounds:
view.set_item_bounding_box(item, the_context._bounds)
if DEBUG_DRAW_BOUNDING_BOX:
b = view.get_item_bounding_box(item)
cairo.save()
cairo.identity_matrix()
cairo.set_source_rgb(.8, 0, 0)
cairo.set_line_width(1.0)
cairo.rectangle(b[0], b[1], b[2] - b[0], b[3] - b[1])
cairo.stroke()
cairo.restore()
finally:
cairo.restore()
def paint(self, context):
cairo = context.cairo
view = context.view
items = view.canvas.get_root_items()
update_bounds = context.update_bounds
self._draw_items(items, view, cairo, update_bounds)
class HandlePainter(Painter):
"""Draw handles of items that are marked as selected in the view.
"""
def _draw_handles(self, item, view, cairo):
"""Draw handles for an item.
The handles are drawn in non-antialiased mode for clearity.
"""
cairo.save()
cairo.identity_matrix()
#cairo.set_matrix(self._matrix)
m = Matrix(*view.canvas.get_matrix_i2w(item))
m *= view._matrix
opacity = (item is view.focused_item) and .7 or .4
for h in item.handles():
cairo.save()
cairo.set_antialias(ANTIALIAS_NONE)
cairo.translate(*m.transform_point(h.x, h.y))
cairo.rectangle(-4, -4, 8, 8)
cairo.set_source_rgba(0, 1, 0, opacity)
cairo.fill_preserve()
cairo.move_to(-2, -2)
cairo.line_to(2, 3)
cairo.move_to(2, -2)
cairo.line_to(-2, 3)
cairo.set_source_rgba(0, .2, 0, 0.9)
cairo.set_line_width(1)
cairo.stroke()
cairo.restore()
cairo.restore()
def paint(self, context):
view = context.view
cairo = context.cairo
items = view.canvas.get_all_items()
# Draw handles of selected items on top of the items.
# Conpare with canvas.get_all_items() to determine drawing order.
for item in (i for i in items if i in view.selected_items):
self._draw_handles(item, view, cairo)
class ToolPainter(Painter):
"""ToolPainter allows the Tool defined on a view to do some special
drawing.
"""
def paint(self, context):
view = context.view
cairo = context.cairo
if view.tool:
cairo.save()
cairo.identity_matrix()
view.tool.draw(Context(view=view, cairo=cairo))
cairo.restore()
def DefaultPainter():
"""Default painter, containing item, handle and tool painters.
"""
chain = PainterChain()
chain.append(ItemPainter())
chain.append(HandlePainter())
chain.append(ToolPainter())
return chain
if __name__ == '__main__':
import doctest
doctest.testmod()
# vim: sw=4:et:
"""
The painter module provides different painters for parts of the canvas.
Painters can be swapped in and out.
Each painter takes are of a layer in the canvas (such as grid, items
and handles).
"""
__version__ = "$Revision$"
# $HeadURL$
from cairo import Matrix, ANTIALIAS_NONE
from canvas import Context
from geometry import Rectangle
DEBUG_DRAW_BOUNDING_BOX = False
class Painter(object):
"""Painter interface.
"""
def paint(self, context):
pass
class PainterChain(Painter):
"""Chain up a set of painters.
like ToolChain.
"""
def __init__(self):
self._painters = []
def append(self, painter):
self._painters.append(painter)
def prepend(self, painter):
self._painters.insert(0, painter)
def paint(self, context):
for painter in self._painters:
painter.paint(context)
class DrawContext(Context):
"""Special context for draw()'ing the item. The draw-context contains
stuff like the view, the cairo context and properties like selected and
focused.
"""
painter = None
cairo = None
def __init__(self, **kwargs):
super(DrawContext, self).__init__(**kwargs)
def draw_children(self):
"""Extra helper method for drawing child items from within
the Item.draw() method.
"""
self.painter._draw_items(self.children,
self.view,
self.cairo,
self.update_bounds)
class CairoContextWrapper(object):
"""Delegate all calls to the wrapped CairoContext, intercept
stroke(), fill() and a few others so the bounding box of the
item involved can be calculated.
"""
def __init__(self, cairo):
self._cairo = cairo
self._bounds = None # a Rectangle object
def __getattr__(self, key):
return getattr(self._cairo, key)
def _update_bounds(self, bounds):
if not self._bounds:
self._bounds = Rectangle(*bounds)
else:
self._bounds += bounds
def _extents(self, funcname):
ctx = self._cairo
ctx.save()
ctx.identity_matrix()
self._update_bounds(getattr(ctx, funcname)())
ctx.restore()
def fill(self):
self._extents('fill_extents')
return self._cairo.fill()
def fill_preserve(self):
self._extents('fill_extents')
return self._cairo.fill_preserve()
def stroke(self):
self._extents('stroke_extents')
return self._cairo.stroke()
def stroke_preserve(self):
self._extents('stroke_extents')
return self._cairo.stroke_preserve()
def show_text(self, utf8):
cairo = self._cairo
e = cairo.text_extents(utf8)
x0, y0 = cairo.user_to_device(e[0], e[1])
x1, y1 = cairo.user_to_device(e[0]+e[2], e[1]+e[3])
self._update_bounds((x0, y0, x1, y1))
return cairo.show_text(utf8)
class ItemPainter(Painter):
def _draw_items(self, items, view, cairo, update_bounds):
"""Draw the items. This method can also be called from DrawContext
to draw sub-items.
"""
for item in items:
cairo.save()
try:
cairo.set_matrix(view.matrix)
cairo.transform(view.canvas.get_matrix_i2w(item))
if update_bounds:
the_context = CairoContextWrapper(cairo)
else:
# No wrapper:
the_context = cairo
item.draw(DrawContext(painter=self,
update_bounds=update_bounds,
view=view,
cairo=the_context,
parent=view.canvas.get_parent(item),
children=view.canvas.get_children(item),
selected=(item in view.selected_items),
focused=(item is view.focused_item),
hovered=(item is view.hovered_item)))
if update_bounds:
view.set_item_bounding_box(item, the_context._bounds)
if DEBUG_DRAW_BOUNDING_BOX:
b = view.get_item_bounding_box(item)
cairo.save()
cairo.identity_matrix()
cairo.set_source_rgb(.8, 0, 0)
cairo.set_line_width(1.0)
cairo.rectangle(b[0], b[1], b[2] - b[0], b[3] - b[1])
cairo.stroke()
cairo.restore()
finally:
cairo.restore()
def paint(self, context):
cairo = context.cairo
view = context.view
items = view.canvas.get_root_items()
update_bounds = context.update_bounds
self._draw_items(items, view, cairo, update_bounds)
class HandlePainter(Painter):
"""Draw handles of items that are marked as selected in the view.
"""
def _draw_handles(self, item, view, cairo):
"""Draw handles for an item.
The handles are drawn in non-antialiased mode for clearity.
"""
cairo.save()
cairo.identity_matrix()
#cairo.set_matrix(self._matrix)
m = Matrix(*view.canvas.get_matrix_i2w(item))
m *= view._matrix
opacity = (item is view.focused_item) and .7 or .4
for h in item.handles():
cairo.save()
cairo.set_antialias(ANTIALIAS_NONE)
cairo.translate(*m.transform_point(h.x, h.y))
cairo.rectangle(-4, -4, 8, 8)
cairo.set_source_rgba(0, 1, 0, opacity)
cairo.fill_preserve()
cairo.move_to(-2, -2)
cairo.line_to(2, 3)
cairo.move_to(2, -2)
cairo.line_to(-2, 3)
cairo.set_source_rgba(0, .2, 0, 0.9)
cairo.set_line_width(1)
cairo.stroke()
cairo.restore()
cairo.restore()
def paint(self, context):
view = context.view
cairo = context.cairo
items = view.canvas.get_all_items()
# Draw handles of selected items on top of the items.
# Conpare with canvas.get_all_items() to determine drawing order.
for item in (i for i in items if i in view.selected_items):
self._draw_handles(item, view, cairo)
class ToolPainter(Painter):
"""ToolPainter allows the Tool defined on a view to do some special
drawing.
"""
def paint(self, context):
view = context.view
cairo = context.cairo
if view.tool:
cairo.save()
cairo.identity_matrix()
view.tool.draw(Context(view=view, cairo=cairo))
cairo.restore()
def DefaultPainter():
"""Default painter, containing item, handle and tool painters.
"""
chain = PainterChain()
chain.append(ItemPainter())
chain.append(HandlePainter())
chain.append(ToolPainter())
return chain
if __name__ == '__main__':
import doctest
doctest.testmod()
# vim: sw=4:et:

View File

@ -1,4 +1,7 @@
# lint Python modules using external checkers.
#
# $Revision$
# $HeadURL$
#
# This is the main checker controling the other ones and the reports
# generation. It is itself both a raw checker and an astng checker in order

View File

@ -1,3 +1,8 @@
"""
"""
__version__ = "$Revision$"
# $HeadURL$
from __future__ import division

View File

@ -22,6 +22,9 @@ Maybe even:
(context.view = view; context.grab() to grab, context.ungrab() to ungrab)
"""
__version__ = "$Revision$"
# $HeadURL$
import cairo
import gtk
from canvas import Context

View File

@ -3,6 +3,9 @@ Simple class containing the tree structure for the canvas items.
"""
__version__ = "$Revision$"
# $HeadURL$
class Tree(object):
"""A Tree structure.

View File

@ -2,6 +2,9 @@
This module contains everything to display a Canvas on a screen.
"""
__version__ = "$Revision$"
# $HeadURL$
# for doctesting:
if __name__ == '__main__':
import pygtk