added Revision and HeadURL properties to all files.
This commit is contained in:
parent
fb3c36767b
commit
cc60438a55
@ -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
|
||||
|
@ -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)
|
||||
|
3
demo.py
3
demo.py
@ -2,6 +2,9 @@
|
||||
A simple demo app.
|
||||
"""
|
||||
|
||||
__version__ = "$Revision$"
|
||||
# $HeadURL$
|
||||
|
||||
import pygtk
|
||||
pygtk.require('2.0')
|
||||
|
||||
|
@ -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
@ -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
|
||||
|
5
item.py
5
item.py
@ -1,3 +1,8 @@
|
||||
"""
|
||||
"""
|
||||
|
||||
__version__ = "$Revision$"
|
||||
# $HeadURL$
|
||||
|
||||
from geometry import Matrix, distance_line_point
|
||||
from solver import solvable, WEAK, NORMAL, STRONG
|
||||
|
477
painter.py
477
painter.py
@ -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:
|
||||
|
3
pylintrc
3
pylintrc
@ -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
|
||||
|
@ -1,3 +1,8 @@
|
||||
"""
|
||||
"""
|
||||
|
||||
__version__ = "$Revision$"
|
||||
# $HeadURL$
|
||||
|
||||
from __future__ import division
|
||||
|
||||
|
3
tool.py
3
tool.py
@ -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
|
||||
|
3
tree.py
3
tree.py
@ -3,6 +3,9 @@ Simple class containing the tree structure for the canvas items.
|
||||
|
||||
"""
|
||||
|
||||
__version__ = "$Revision$"
|
||||
# $HeadURL$
|
||||
|
||||
|
||||
class Tree(object):
|
||||
"""A Tree structure.
|
||||
|
Loading…
x
Reference in New Issue
Block a user