[Skencil-commits] r727 - skencil/branches/skencil-0.6/src/Sketch/Graphics
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Wed Sep 22 23:52:33 CEST 2010
Author: igor_n
Date: 2010-09-22 23:52:28 +0200 (Wed, 22 Sep 2010)
New Revision: 727
Modified:
skencil/branches/skencil-0.6/src/Sketch/Graphics/arrow.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/base.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/bezier.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/blend.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/blendgroup.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/clone.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/color.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/compound.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/dashes.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/document.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/ellipse.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/eps.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/external.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/font.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/gradient.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/graphics.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/group.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/guide.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/handle.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/image.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/layer.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/maskgroup.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/pagelayout.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/papersize.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/pattern.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/plugobj.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/properties.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/psdevice.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/rectangle.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/selection.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/selinfo.py
skencil/branches/skencil-0.6/src/Sketch/Graphics/text.py
Log:
mixed indents are removed
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/arrow.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/arrow.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/arrow.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -33,7 +33,7 @@
class Arrow:
def __init__(self, path, closed = 0):
- self.path = CreatePath()
+ self.path = CreatePath()
if type(path) in (ListType, TupleType):
for segment in path:
if len(segment) == 2:
@@ -42,26 +42,26 @@
apply(self.path.AppendBezier, segment)
else:
self.path = path
- if closed:
- self.path.load_close()
+ if closed:
+ self.path.load_close()
def BoundingRect(self, pos, dir, width):
try:
angle = atan2(dir.y, dir.x)
except ValueError:
angle = 0
- if width < 1.0:
- width = 1.0
- s = width * sin(angle)
- c = width * cos(angle)
- trafo = Trafo(c, s, -s, c, pos.x, pos.y)
- return self.path.accurate_rect(trafo)
+ if width < 1.0:
+ width = 1.0
+ s = width * sin(angle)
+ c = width * cos(angle)
+ trafo = Trafo(c, s, -s, c, pos.x, pos.y)
+ return self.path.accurate_rect(trafo)
def Draw(self, device, rect = None):
- if self.path.closed:
- device.FillBezierPath(self.path, rect)
- else:
- device.DrawBezierPath(self.path, rect)
+ if self.path.closed:
+ device.FillBezierPath(self.path, rect)
+ else:
+ device.DrawBezierPath(self.path, rect)
def Paths(self):
return (self.path,)
@@ -70,28 +70,28 @@
return self.path.closed
def SaveRepr(self):
- path = map(lambda t: t[:-1], self.path.get_save())
- return (path, self.path.closed)
+ path = map(lambda t: t[:-1], self.path.get_save())
+ return (path, self.path.closed)
def __hash__(self):
- return hash(id(self.path))
+ return hash(id(self.path))
def __cmp__(self, other):
- if __debug__:
- pdebug(None, 'Arrow.__cmp__, %s', other)
- if isinstance(other, self.__class__):
- return cmp(self.path, other.path)
- return cmp(id(self), id(other))
+ if __debug__:
+ pdebug(None, 'Arrow.__cmp__, %s', other)
+ if isinstance(other, self.__class__):
+ return cmp(self.path, other.path)
+ return cmp(id(self), id(other))
def read_arrows(filename):
arrows = []
def arrow(path, closed, list = arrows):
- list.append(Arrow(path, closed))
+ list.append(Arrow(path, closed))
dict = {'arrow': arrow}
read_resource_file(filename, '##Sketch Arrow 0',
- _("%s is not an arrow definition file"), dict)
+ _("%s is not an arrow definition file"), dict)
return arrows
@@ -100,11 +100,11 @@
def StandardArrows():
global std_arrows
if std_arrows is None:
- filename = os.path.join(config.std_res_dir, config.preferences.arrows)
- try:
- std_arrows = read_arrows(filename)
- except:
- warn_tb(USER, _("Error trying to read arrows from %s\n"
+ filename = os.path.join(config.std_res_dir, config.preferences.arrows)
+ try:
+ std_arrows = read_arrows(filename)
+ except:
+ warn_tb(USER, _("Error trying to read arrows from %s\n"
"Using builtin defaults"), filename)
- std_arrows = []
+ std_arrows = []
return std_arrows
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/base.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/base.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/base.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -100,42 +100,42 @@
def __init__(self):
- # not needed here, but if some derived class wants to call the
- # base class constructor...
- pass
+ # not needed here, but if some derived class wants to call the
+ # base class constructor...
+ pass
def DragStart(self, p):
- # Start the drag at P. Initialize the instance variables. Set
- # dragging to true.
- # XXX: document the meaning of the return value
- self.drawn = 0 # the object is not visible yet
- self.dragging = 1
- self.drag_start = p
- self.drag_cur = p
- self.off = NullPoint
- return self.off
+ # Start the drag at P. Initialize the instance variables. Set
+ # dragging to true.
+ # XXX: document the meaning of the return value
+ self.drawn = 0 # the object is not visible yet
+ self.dragging = 1
+ self.drag_start = p
+ self.drag_cur = p
+ self.off = NullPoint
+ return self.off
def DragMove(self, p):
- # The pointer has moved to p. Compute the new offset.
- self.off = p - self.drag_start
- self.drag_cur = p
+ # The pointer has moved to p. Compute the new offset.
+ self.off = p - self.drag_start
+ self.drag_cur = p
def MouseMove(self, p, state):
- # XXX add documentation for this
- if state & self.drag_mask:
- self.off = p - self.drag_start
- self.drag_cur = p
+ # XXX add documentation for this
+ if state & self.drag_mask:
+ self.off = p - self.drag_start
+ self.drag_cur = p
def DragStop(self, p):
- # The drag stopped at p. Update drag_cur and off for the last
- # time, and set dragging to false.
- self.dragging = 0
- self.off = p - self.drag_start
- self.drag_cur = p
+ # The drag stopped at p. Update drag_cur and off for the last
+ # time, and set dragging to false.
+ self.dragging = 0
+ self.off = p - self.drag_start
+ self.drag_cur = p
def DragCancel(self):
- self.dragging = 0
+ self.dragging = 0
# The rest of Draggable's methods deal with drawing the object in
# `dragged' form (usually an outline) on the screen. The output
@@ -173,17 +173,17 @@
# DrawDragged is called directly.
def DrawDragged(self, device, partially):
- pass
+ pass
def Show(self, device, partially = 0):
- if not self.drawn:
- self.DrawDragged(device, partially)
- self.drawn = 1
+ if not self.drawn:
+ self.DrawDragged(device, partially)
+ self.drawn = 1
def Hide(self, device, partially = 0):
- if self.drawn:
- self.DrawDragged(device, partially)
- self.drawn = 0
+ if self.drawn:
+ self.DrawDragged(device, partially)
+ self.drawn = 0
#
# Class Selectable
@@ -195,56 +195,56 @@
class Selectable:
def __init__(self):
- # only needed for derived classes.
- pass
+ # only needed for derived classes.
+ pass
def Hit(self, p, rect, device):
- return None
+ return None
def SelectSubobject(self, p, rect, device, path = None, *rest):
- return self
+ return self
def GetObjectHandle(self, multiple):
- # Return a single point marking an important point of the
- # object. This point is highlighted by a small rectangle in the
- # canvas to indicate that the object is selected. Alternatively,
- # a list of such points can be returned to mark several points,
- # but that feature should only be used by compound objects.
- #
- # If multiple is false, self is the only object selected. If
- # it's true, there may be more than one selected object.
- return []
+ # Return a single point marking an important point of the
+ # object. This point is highlighted by a small rectangle in the
+ # canvas to indicate that the object is selected. Alternatively,
+ # a list of such points can be returned to mark several points,
+ # but that feature should only be used by compound objects.
+ #
+ # If multiple is false, self is the only object selected. If
+ # it's true, there may be more than one selected object.
+ return []
class EditSelect(Selectable):
def SelectPoint(self, p, rect, device, mode = SelectSet):
- # Select (sub)object at P. If something is selected, return
- # true, false otherwise.
- return 0
+ # Select (sub)object at P. If something is selected, return
+ # true, false otherwise.
+ return 0
def SelectHandle(self, handle, mode = SelectSet):
- pass
+ pass
def SelectRect(self, rect, mode = SelectSet):
- # select (sub-)object(s) in RECT
- pass
+ # select (sub-)object(s) in RECT
+ pass
def GetHandles(self):
- # In edit mode, this method will be called to get a list of
- # handles. A handle should be shown at every `hot' spot of the
- # object (e.g. the nodes of a PolyBezier). Handles are described
- # by tuples which can be easily created by the functions in
- # handle.py
- return []
+ # In edit mode, this method will be called to get a list of
+ # handles. A handle should be shown at every `hot' spot of the
+ # object (e.g. the nodes of a PolyBezier). Handles are described
+ # by tuples which can be easily created by the functions in
+ # handle.py
+ return []
class SelectAndDrag(Draggable, EditSelect):
def __init__(self):
- Draggable.__init__(self)
- Selectable.__init__(self)
+ Draggable.__init__(self)
+ Selectable.__init__(self)
def CurrentInfoText(self):
# return a string describing the current state of the object
@@ -266,12 +266,12 @@
is_Creator = 0
has_edit_mode = 0 # true if object has an edit mode. If true, the
- # Editor() method must be implemented
+ # Editor() method must be implemented
is_curve = 0 # true, if object can be represented by and
- # converted to a PolyBezier object. If true, the
- # AsBezier() and Paths() methods must be
- # implemented
+ # converted to a PolyBezier object. If true, the
+ # AsBezier() and Paths() methods must be
+ # implemented
is_clip = 0
has_fill = 0 # True, iff object can have fill properties
@@ -283,7 +283,7 @@
is_Rectangle = 0
is_Ellipse = 0
is_Text = 0 # Text objects must have a Font() method
- # returning a font.
+ # returning a font.
is_SimpleText = 0
is_PathTextGroup = 0
is_PathTextText = 0 # The text part of a path text group
@@ -335,51 +335,51 @@
class Bounded:
_lazy_attrs = {'coord_rect' : 'update_rects',
- 'bounding_rect' : 'update_rects'}
+ 'bounding_rect' : 'update_rects'}
def __init__(self):
- pass
+ pass
def del_lazy_attrs(self):
- for key in self._lazy_attrs.keys():
- try:
- delattr(self, key)
- except:
- pass
+ for key in self._lazy_attrs.keys():
+ try:
+ delattr(self, key)
+ except:
+ pass
def update_rects(self):
- # compute the various bounding rects and other attributes that
- # use `lazy evaluation'. This method MUST be implemented by
- # derived classes. It MUST set self.bounding_rect and
- # self.coord_rect and other attributes where appropriate.
- pass
+ # compute the various bounding rects and other attributes that
+ # use `lazy evaluation'. This method MUST be implemented by
+ # derived classes. It MUST set self.bounding_rect and
+ # self.coord_rect and other attributes where appropriate.
+ pass
def __getattr__(self, attr):
- # if a lazy attribute is accessed, compute it.
- method = self._lazy_attrs.get(attr)
- if method:
- getattr(self, method)()
- # now it should work... use self.__dict__ directly to avoid
- # recursion if the method is buggy
- try:
- return self.__dict__[attr]
- except KeyError, msg:
- warn(INTERNAL, '%s did not compute %s for %s.',
- method, attr, self)
- if attr[:2] == attr[-2:] == '__':
- #if attr in ('__nonzero__', '__len__'):
- # print_stack()
- pass
- else:
- warn(INTERNAL, "%s instance doesn't have an attribute %s",
- self.__class__, attr)
- raise AttributeError, attr
+ # if a lazy attribute is accessed, compute it.
+ method = self._lazy_attrs.get(attr)
+ if method:
+ getattr(self, method)()
+ # now it should work... use self.__dict__ directly to avoid
+ # recursion if the method is buggy
+ try:
+ return self.__dict__[attr]
+ except KeyError, msg:
+ warn(INTERNAL, '%s did not compute %s for %s.',
+ method, attr, self)
+ if attr[:2] == attr[-2:] == '__':
+ #if attr in ('__nonzero__', '__len__'):
+ # print_stack()
+ pass
+ else:
+ warn(INTERNAL, "%s instance doesn't have an attribute %s",
+ self.__class__, attr)
+ raise AttributeError, attr
def LayoutPoint(self):
- return Point(self.coord_rect.left, self.coord_rect.bottom)
+ return Point(self.coord_rect.left, self.coord_rect.bottom)
def GetSnapPoints(self):
- return []
+ return []
#
# Class HierarchyNode
@@ -394,84 +394,84 @@
class HierarchyNode:
def __init__(self, duplicate = None):
- if duplicate is not None:
- self.document = duplicate.document
- if duplicate.was_untied:
- self.was_untied = duplicate.was_untied
+ if duplicate is not None:
+ self.document = duplicate.document
+ if duplicate.was_untied:
+ self.was_untied = duplicate.was_untied
def __del__(self):
- if self.document:
- self.document.connector.RemovePublisher(self)
+ if self.document:
+ self.document.connector.RemovePublisher(self)
def Destroy(self):
- # remove all circular references here...
- # May be extended by derived classes.
- self.parent = None
+ # remove all circular references here...
+ # May be extended by derived classes.
+ self.parent = None
parent = None
def SetParent(self, parent):
- self.parent = parent
+ self.parent = parent
def depth(self):
- if self.parent is not None:
- return self.parent.depth() + 1
- return 1
+ if self.parent is not None:
+ return self.parent.depth() + 1
+ return 1
def SelectionInfo(self):
- if self.parent is not None:
- return self.parent.SelectionInfo(self)
+ if self.parent is not None:
+ return self.parent.SelectionInfo(self)
document = None # the document self belongs to
def SetDocument(self, doc):
- self.document = doc
- if doc is not None and self.was_untied:
- self.TieToDocument()
- del self.was_untied
+ self.document = doc
+ if doc is not None and self.was_untied:
+ self.TieToDocument()
+ del self.was_untied
def UntieFromDocument(self):
- # this will be called when self is being stored in the clipboard
- # (CopyForClipboard/CutForClipboard), but before self.document
- # becomes None. Disconnect will not be called in this case.
- # May be extended by derived classes.
- self.was_untied = 1
+ # this will be called when self is being stored in the clipboard
+ # (CopyForClipboard/CutForClipboard), but before self.document
+ # becomes None. Disconnect will not be called in this case.
+ # May be extended by derived classes.
+ self.was_untied = 1
def TieToDocument(self):
- # this will be called when self is being inserted into the
- # document from the clipboard, after self.document has been set.
- # Connect will not be called in this case.
- # May be extended by derived classes.
- pass
+ # this will be called when self is being inserted into the
+ # document from the clipboard, after self.document has been set.
+ # Connect will not be called in this case.
+ # May be extended by derived classes.
+ pass
def Subscribe(self, channel, func, *args):
- # XXX: what do we do if document has not been set (yet)
- if self.document is not None:
- self.document.connector.Connect(self, channel, func, args)
+ # XXX: what do we do if document has not been set (yet)
+ if self.document is not None:
+ self.document.connector.Connect(self, channel, func, args)
def Unsubscribe(self, channel, func, *args):
- if self.document is not None:
- self.document.connector.Disconnect(self, channel, func, args)
+ if self.document is not None:
+ self.document.connector.Disconnect(self, channel, func, args)
def Issue(self, channel, *args):
- if self.document is not None:
- apply(self.document.connector.Issue, (self, channel,) + args)
+ if self.document is not None:
+ apply(self.document.connector.Issue, (self, channel,) + args)
def issue_changed(self):
- self.Issue(CHANGED, self)
- if self.parent is not None:
- self.parent.ChildChanged(self)
+ self.Issue(CHANGED, self)
+ if self.parent is not None:
+ self.parent.ChildChanged(self)
def Connect(self):
- # May be extended by derived classes.
- pass
+ # May be extended by derived classes.
+ pass
def Disconnect(self):
- # May be extended by derived classes.
- pass
+ # May be extended by derived classes.
+ pass
def Duplicate(self):
- # return a duplicate of self
- return self.__class__(duplicate = self)
+ # return a duplicate of self
+ return self.__class__(duplicate = self)
@@ -495,72 +495,72 @@
script_access = {}
def __init__(self, duplicate = None):
- Selectable.__init__(self)
- HierarchyNode.__init__(self, duplicate = duplicate)
+ Selectable.__init__(self)
+ HierarchyNode.__init__(self, duplicate = duplicate)
def ChildChanged(self, child):
- # in compound objects, this method is called by the child
- # whenever it changes (normally via the issue_changed method)
- pass
+ # in compound objects, this method is called by the child
+ # whenever it changes (normally via the issue_changed method)
+ pass
def __cmp__(self, other):
- return cmp(id(self), id(other))
+ return cmp(id(self), id(other))
def _changed(self):
- self.del_lazy_attrs()
- self.issue_changed()
- return (self._changed,)
+ self.del_lazy_attrs()
+ self.issue_changed()
+ return (self._changed,)
def SetLowerLeftCorner(self, corner):
- # move self so that self's lower left corner is at CORNER. This
- # used when interactively placing an object
- rect = self.coord_rect
- ll = Point(rect.left, rect.bottom)
- return self.Translate(corner - ll)
+ # move self so that self's lower left corner is at CORNER. This
+ # used when interactively placing an object
+ rect = self.coord_rect
+ ll = Point(rect.left, rect.bottom)
+ return self.Translate(corner - ll)
def RemoveTransformation(self):
- # Some objects accumulate the transformation applied by
- # Transform() and apply them every time the object is displayed
- # Restore this transformation to Identity.
- return NullUndo
+ # Some objects accumulate the transformation applied by
+ # Transform() and apply them every time the object is displayed
+ # Restore this transformation to Identity.
+ return NullUndo
script_access['RemoveTransformation'] = SCRIPT_UNDO
def AsBezier(self):
- # Return self as bezier if possible. See is_curve above.
- return None
+ # Return self as bezier if possible. See is_curve above.
+ return None
script_access['AsBezier'] = SCRIPT_OBJECT
def Paths(self):
- # Return a tuple of curve objects describing the outline of self
- # if possible. The curve objects can be the ones used internally
- # by self. The calling code is expected not to modify the curve
- # objects in place.
+ # Return a tuple of curve objects describing the outline of self
+ # if possible. The curve objects can be the ones used internally
+ # by self. The calling code is expected not to modify the curve
+ # objects in place.
# See is_curve above.
- return None
+ return None
script_access['Paths'] = SCRIPT_GET
def Blend(self, other, frac1, frac2):
- # Return the weighted average of SELF and OTHER. FRAC1 and FRAC2
- # are the weights (if SELF and OTHER were numbers this should be
- # FRAC1 * SELF + FRAC2 * OTHER).
- #
- # This method is used by the function Blend() in blend.py. If
- # SELF and OTHER can't be blended, raise the blend.MismatchError
- # exception. This is also the default behaviour.
- raise MismatchError
+ # Return the weighted average of SELF and OTHER. FRAC1 and FRAC2
+ # are the weights (if SELF and OTHER were numbers this should be
+ # FRAC1 * SELF + FRAC2 * OTHER).
+ #
+ # This method is used by the function Blend() in blend.py. If
+ # SELF and OTHER can't be blended, raise the blend.MismatchError
+ # exception. This is also the default behaviour.
+ raise MismatchError
script_access['Blend'] = SCRIPT_OBJECT
def Snap(self, p):
- # Determine the point Q on self's outline closest to P and
- # return a tuple (abs(Q - P), Q)
- return (1e100, p)
+ # Determine the point Q on self's outline closest to P and
+ # return a tuple (abs(Q - P), Q)
+ return (1e100, p)
script_access['Snap'] = SCRIPT_GET
def ObjectChanged(self, obj):
- return 0
+ return 0
def ObjectRemoved(self, obj):
- return NullUndo
+ return NullUndo
# Add some inherited method's script access flags
script_access['coord_rect'] = SCRIPT_GET
@@ -582,33 +582,33 @@
creation_text = 'Create Object'
def __init__(self, start):
- self.start = start
+ self.start = start
def EndCreation(self):
- # This method will be called when the object was being created
- # interactively using more than one click-drag-release cycle,
- # and the user has finished. This method is needed by the
- # PolyBezier primitive for instance.
- #
- # Return true if creation was successful, false otherwise.
- return 1
+ # This method will be called when the object was being created
+ # interactively using more than one click-drag-release cycle,
+ # and the user has finished. This method is needed by the
+ # PolyBezier primitive for instance.
+ #
+ # Return true if creation was successful, false otherwise.
+ return 1
def ContinueCreation(self):
- # called during interactive creation when the user releases the
- # mouse button. Return true, if the object may need another
- # click-drag-release cycle, false for objects that are always
- # complete after one cycle. (XXX the `true' return value is
- # interpreted in a special way, see the PolyBezier primitive)
- #
- # XXX: Should we distinguish more cases? A rectangle for example
- # is always complete after one click-drag-release cycle. A
- # PolyBezier object needs at least two cycles but accepts any
- # number of additional cycles. A polygon (with straight lines)
- # needs at least one. We might return a value that indicates
- # whether the user *must* supply additional points, whether it's
- # optional or whether the object is complete and the user
- # *cannot* add points.
- return None
+ # called during interactive creation when the user releases the
+ # mouse button. Return true, if the object may need another
+ # click-drag-release cycle, false for objects that are always
+ # complete after one cycle. (XXX the `true' return value is
+ # interpreted in a special way, see the PolyBezier primitive)
+ #
+ # XXX: Should we distinguish more cases? A rectangle for example
+ # is always complete after one click-drag-release cycle. A
+ # PolyBezier object needs at least two cycles but accepts any
+ # number of additional cycles. A polygon (with straight lines)
+ # needs at least one. We might return a value that indicates
+ # whether the user *must* supply additional points, whether it's
+ # optional or whether the object is complete and the user
+ # *cannot* add points.
+ return None
class Editor(SelectAndDrag):
@@ -618,22 +618,22 @@
context_commands = ()
def __init__(self, object):
- self.object = object
+ self.object = object
def __getattr__(self, attr):
- return getattr(self.object, attr)
+ return getattr(self.object, attr)
def Destroy(self):
- # called by the edit mode selection when the editor it not
- # needed anymore.
- pass
+ # called by the edit mode selection when the editor it not
+ # needed anymore.
+ pass
def ChangeRect(self):
- # ChangeRect indicates the area that is going to change during
- # the current click-drag-release cycle. It is safe to make this
- # equal to bounding_rect. This rectangle is used to determine
- # which parts of the window have to be redrawn.
- return self.bounding_rect
+ # ChangeRect indicates the area that is going to change during
+ # the current click-drag-release cycle. It is safe to make this
+ # equal to bounding_rect. This rectangle is used to determine
+ # which parts of the window have to be redrawn.
+ return self.bounding_rect
#
@@ -655,123 +655,123 @@
script_access = GraphicsObject.script_access.copy()
def __init__(self, properties = None, duplicate = None):
- GraphicsObject.__init__(self, duplicate = duplicate)
- if duplicate is not None:
- self.properties = duplicate.properties.Duplicate()
- if duplicate.tie_info:
- self.tie_info = duplicate.tie_info
- else:
- if properties is not None:
- self.properties = properties
- else:
- self.properties = PropertyStack()
+ GraphicsObject.__init__(self, duplicate = duplicate)
+ if duplicate is not None:
+ self.properties = duplicate.properties.Duplicate()
+ if duplicate.tie_info:
+ self.tie_info = duplicate.tie_info
+ else:
+ if properties is not None:
+ self.properties = properties
+ else:
+ self.properties = PropertyStack()
def Destroy(self):
- GraphicsObject.Destroy(self)
+ GraphicsObject.Destroy(self)
def UntieFromDocument(self):
- info = self.properties.Untie()
- if info:
- self.tie_info = info
- GraphicsObject.UntieFromDocument(self)
+ info = self.properties.Untie()
+ if info:
+ self.tie_info = info
+ GraphicsObject.UntieFromDocument(self)
def TieToDocument(self):
- if self.tie_info:
- self.properties.Tie(self.document, self.tie_info)
- del self.tie_info
+ if self.tie_info:
+ self.properties.Tie(self.document, self.tie_info)
+ del self.tie_info
def Transform(self, trafo, rects = None):
- # Apply the affine transformation trafo to all coordinates and
- # the properties.
- undo = self.properties.Transform(trafo, rects)
- if undo is not NullUndo:
- return self.properties_changed(undo)
- return undo
+ # Apply the affine transformation trafo to all coordinates and
+ # the properties.
+ undo = self.properties.Transform(trafo, rects)
+ if undo is not NullUndo:
+ return self.properties_changed(undo)
+ return undo
def Translate(self, offset):
- # Move all points by OFFSET. OFFSET is an SKPoint instance.
- return NullUndo
+ # Move all points by OFFSET. OFFSET is an SKPoint instance.
+ return NullUndo
def DrawShape(self, device):
- # Draw the object on device. Here we just set the properties.
- device.SetProperties(self.properties, self.bounding_rect)
+ # Draw the object on device. Here we just set the properties.
+ device.SetProperties(self.properties, self.bounding_rect)
# The following functions manage the properties
def set_property_stack(self, properties):
- self.properties = properties
+ self.properties = properties
load_SetProperties = set_property_stack
def properties_changed(self, undo):
- if undo is not NullUndo:
- return (UndoAfter, undo, self._changed())
- return undo
+ if undo is not NullUndo:
+ return (UndoAfter, undo, self._changed())
+ return undo
def AddStyle(self, style):
- return self.properties_changed(self.properties.AddStyle(style))
+ return self.properties_changed(self.properties.AddStyle(style))
script_access['AddStyle'] = SCRIPT_UNDO
def Filled(self):
- return self.properties.HasFill()
+ return self.properties.HasFill()
script_access['Filled'] = SCRIPT_GET
def Properties(self):
- return self.properties
+ return self.properties
script_access['Properties'] = SCRIPT_OBJECT
def SetProperties(self, if_type_present = 0, **kw):
- if if_type_present:
- # change properties of that type if properties of that are
- # already present.
- prop_types = properties.property_types
- LineProperty = properties.LineProperty
- FillProperty = properties.FillProperty
- FontProperty = properties.FontProperty
- types = map(prop_types.get, kw.keys())
- if LineProperty in types and not self.properties.HasLine():
- for key in kw.keys():
- if prop_types[key] == LineProperty:
- del kw[key]
- if FillProperty in types and not self.properties.HasFill():
- for key in kw.keys():
- if prop_types[key] == FillProperty:
- del kw[key]
- if FontProperty in types and not self.properties.HasFont():
- for key in kw.keys():
- if prop_types[key] == FontProperty:
- del kw[key]
- return self.properties_changed(apply(self.properties.SetProperty, (),
- kw))
+ if if_type_present:
+ # change properties of that type if properties of that are
+ # already present.
+ prop_types = properties.property_types
+ LineProperty = properties.LineProperty
+ FillProperty = properties.FillProperty
+ FontProperty = properties.FontProperty
+ types = map(prop_types.get, kw.keys())
+ if LineProperty in types and not self.properties.HasLine():
+ for key in kw.keys():
+ if prop_types[key] == LineProperty:
+ del kw[key]
+ if FillProperty in types and not self.properties.HasFill():
+ for key in kw.keys():
+ if prop_types[key] == FillProperty:
+ del kw[key]
+ if FontProperty in types and not self.properties.HasFont():
+ for key in kw.keys():
+ if prop_types[key] == FontProperty:
+ del kw[key]
+ return self.properties_changed(apply(self.properties.SetProperty, (),
+ kw))
script_access['SetProperties'] = SCRIPT_UNDO
def LineWidth(self):
- if self.properties.HasLine:
- return self.properties.line_width
- return 0
+ if self.properties.HasLine:
+ return self.properties.line_width
+ return 0
script_access['LineWidth'] = SCRIPT_GET
def ObjectChanged(self, obj):
- if self.properties.ObjectChanged(obj):
- rect = self.bounding_rect
- self.del_lazy_attrs()
- self.document.AddClearRect(UnionRects(rect, self.bounding_rect))
- self.issue_changed()
- return 1
- return 0
+ if self.properties.ObjectChanged(obj):
+ rect = self.bounding_rect
+ self.del_lazy_attrs()
+ self.document.AddClearRect(UnionRects(rect, self.bounding_rect))
+ self.issue_changed()
+ return 1
+ return 0
def ObjectRemoved(self, obj):
- return self.properties.ObjectRemoved(obj)
+ return self.properties.ObjectRemoved(obj)
def set_blended_properties(self, blended, other, frac1, frac2):
- blended.set_property_stack(Blend(self.properties, other.properties,
- frac1, frac2))
+ blended.set_property_stack(Blend(self.properties, other.properties,
+ frac1, frac2))
def SaveToFile(self, file):
- # save object to file. Must be extended by the subclasses. Here,
- # we just save the properties.
- self.properties.SaveToFile(file)
+ # save object to file. Must be extended by the subclasses. Here,
+ # we just save the properties.
+ self.properties.SaveToFile(file)
#
@@ -783,102 +783,102 @@
class RectangularObject:
def __init__(self, trafo = None, duplicate = None):
- if duplicate is not None:
- self.trafo = duplicate.trafo
- else:
- if not trafo:
- self.trafo = Identity
- else:
- self.trafo = trafo
+ if duplicate is not None:
+ self.trafo = duplicate.trafo
+ else:
+ if not trafo:
+ self.trafo = Identity
+ else:
+ self.trafo = trafo
def Trafo(self):
return self.trafo
def LayoutPoint(self, *rest):
- # accept arguments to use this function as GetObjectHandle
- return self.trafo.offset()
+ # accept arguments to use this function as GetObjectHandle
+ return self.trafo.offset()
GetObjectHandle = LayoutPoint
def Translate(self, offset):
- return self.Transform(Translation(offset))
+ return self.Transform(Translation(offset))
def set_transformation(self, trafo):
- undo = (self.set_transformation, self.trafo)
- self.trafo = trafo
- self._changed()
- return undo
+ undo = (self.set_transformation, self.trafo)
+ self.trafo = trafo
+ self._changed()
+ return undo
def Transform(self, trafo):
- trafo = trafo(self.trafo)
- return self.set_transformation(trafo)
+ trafo = trafo(self.trafo)
+ return self.set_transformation(trafo)
def Blend(self, other, p, q):
- if other.__class__ == self.__class__:
- blended = self.__class__(BlendTrafo(self.trafo, other.trafo, p, q))
- self.set_blended_properties(blended, other, p, q)
- return blended
- raise MismatchError
+ if other.__class__ == self.__class__:
+ blended = self.__class__(BlendTrafo(self.trafo, other.trafo, p, q))
+ self.set_blended_properties(blended, other, p, q)
+ return blended
+ raise MismatchError
class RectangularPrimitive(RectangularObject, Primitive):
def __init__(self, trafo = None, properties = None, duplicate = None):
- RectangularObject.__init__(self, trafo, duplicate = duplicate)
- Primitive.__init__(self, properties = properties,
- duplicate = duplicate)
+ RectangularObject.__init__(self, trafo, duplicate = duplicate)
+ Primitive.__init__(self, properties = properties,
+ duplicate = duplicate)
def Transform(self, trafo, transform_properties = 1):
- undostyle = undo = NullUndo
- try:
- rect = self.bounding_rect
- undo = RectangularObject.Transform(self, trafo)
- if transform_properties:
- rects = (rect, self.bounding_rect)
- undostyle = Primitive.Transform(self, trafo, rects = rects)
- return CreateMultiUndo(undostyle, undo)
- except:
- Undo(undo)
- Undo(undostyle)
- raise
+ undostyle = undo = NullUndo
+ try:
+ rect = self.bounding_rect
+ undo = RectangularObject.Transform(self, trafo)
+ if transform_properties:
+ rects = (rect, self.bounding_rect)
+ undostyle = Primitive.Transform(self, trafo, rects = rects)
+ return CreateMultiUndo(undostyle, undo)
+ except:
+ Undo(undo)
+ Undo(undostyle)
+ raise
def Translate(self, offset):
- return self.Transform(Translation(offset), transform_properties = 0)
+ return self.Transform(Translation(offset), transform_properties = 0)
class RectangularCreator(Creator):
def __init__(self, start):
- Creator.__init__(self, start)
- self.trafo = Trafo(1, 0, 0, 1, start.x, start.y)
+ Creator.__init__(self, start)
+ self.trafo = Trafo(1, 0, 0, 1, start.x, start.y)
def ButtonDown(self, p, button, state):
- Creator.DragStart(self, p)
+ Creator.DragStart(self, p)
def apply_constraint(self, p, state):
- if state & ConstraintMask:
- trafo = self.trafo
+ if state & ConstraintMask:
+ trafo = self.trafo
w, h = p - self.drag_start
- if w == 0:
- w = 0.00001
- a = h / w
- if a > 0:
- sign = 1
- else:
- sign = -1
- if abs(a) > 1.0:
- h = sign * w
- else:
- w = sign * h
- p = self.drag_start + Point(w, h)
- return p
+ if w == 0:
+ w = 0.00001
+ a = h / w
+ if a > 0:
+ sign = 1
+ else:
+ sign = -1
+ if abs(a) > 1.0:
+ h = sign * w
+ else:
+ w = sign * h
+ p = self.drag_start + Point(w, h)
+ return p
def MouseMove(self, p, state):
- p = self.apply_constraint(p, state)
- Creator.MouseMove(self, p, state)
+ p = self.apply_constraint(p, state)
+ Creator.MouseMove(self, p, state)
def ButtonUp(self, p, button, state):
- p = self.apply_constraint(p, state)
- Creator.DragStop(self, p)
- x, y = self.off
- self.trafo = Trafo(x, 0, 0, y, self.trafo.v1, self.trafo.v2)
+ p = self.apply_constraint(p, state)
+ Creator.DragStop(self, p)
+ x, y = self.off
+ self.trafo = Trafo(x, 0, 0, y, self.trafo.v1, self.trafo.v2)
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/bezier.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/bezier.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/bezier.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -49,9 +49,9 @@
def undo_path(undo, path):
if undo is not None:
- return apply(getattr(path, undo[0]), undo[1:])
+ return apply(getattr(path, undo[0]), undo[1:])
else:
- return undo
+ return undo
class PolyBezier(Primitive):
@@ -63,214 +63,214 @@
script_access = Primitive.script_access.copy()
def __init__(self, paths = None, properties = None, duplicate = None):
- if duplicate is not None:
- if paths is None:
- paths = []
- for path in duplicate.paths:
- paths.append(path.Duplicate())
- self.paths = tuple(paths)
- else:
- # This special case uses the properties kwarg now, I
- # hope.
- warn(INTERNAL, 'Bezier object created with paths and duplicte')
- print_stack()
- if type(paths) != type(()):
- paths = (paths,)
- self.paths = paths
- elif paths is not None:
- if type(paths) != type(()):
- paths = (paths,)
- self.paths = paths
- else:
- self.paths = (CreatePath(),)
+ if duplicate is not None:
+ if paths is None:
+ paths = []
+ for path in duplicate.paths:
+ paths.append(path.Duplicate())
+ self.paths = tuple(paths)
+ else:
+ # This special case uses the properties kwarg now, I
+ # hope.
+ warn(INTERNAL, 'Bezier object created with paths and duplicte')
+ print_stack()
+ if type(paths) != type(()):
+ paths = (paths,)
+ self.paths = paths
+ elif paths is not None:
+ if type(paths) != type(()):
+ paths = (paths,)
+ self.paths = paths
+ else:
+ self.paths = (CreatePath(),)
- Primitive.__init__(self, properties = properties, duplicate=duplicate)
+ Primitive.__init__(self, properties = properties, duplicate=duplicate)
def Hit(self, p, rect, device, clip = 0):
- for path in self.paths:
- if path.hit_point(rect):
- return 1
- return device.MultiBezierHit(self.paths, p, self.properties,
- clip or self.Filled(),
- ignore_outline_mode = clip)
+ for path in self.paths:
+ if path.hit_point(rect):
+ return 1
+ return device.MultiBezierHit(self.paths, p, self.properties,
+ clip or self.Filled(),
+ ignore_outline_mode = clip)
def do_undo(self, undo_list):
- undo = map(undo_path, undo_list, self.paths)
- self._changed()
- return (self.do_undo, undo)
+ undo = map(undo_path, undo_list, self.paths)
+ self._changed()
+ return (self.do_undo, undo)
def Transform(self, trafo):
- undo = []
- undostyle = NullUndo
- try:
- rect = self.bounding_rect
- for path in self.paths:
- undo.append(path.Transform(trafo))
- self._changed()
- undo = (self.do_undo, undo)
- self.update_rects() # calling update_rects directly is a bit faster
- undostyle = Primitive.Transform(self, trafo,
- rects = (rect, self.bounding_rect))
- return CreateMultiUndo(undostyle, undo)
- except:
- Undo(undostyle)
- if type(undo) != type(()):
- undo = (self.do_undo, undo)
- Undo(undo)
- raise
+ undo = []
+ undostyle = NullUndo
+ try:
+ rect = self.bounding_rect
+ for path in self.paths:
+ undo.append(path.Transform(trafo))
+ self._changed()
+ undo = (self.do_undo, undo)
+ self.update_rects() # calling update_rects directly is a bit faster
+ undostyle = Primitive.Transform(self, trafo,
+ rects = (rect, self.bounding_rect))
+ return CreateMultiUndo(undostyle, undo)
+ except:
+ Undo(undostyle)
+ if type(undo) != type(()):
+ undo = (self.do_undo, undo)
+ Undo(undo)
+ raise
def Translate(self, offset):
- for path in self.paths:
- path.Translate(offset)
- self._changed()
- return self.Translate, -offset
+ for path in self.paths:
+ path.Translate(offset)
+ self._changed()
+ return self.Translate, -offset
def DrawShape(self, device, rect = None, clip = 0):
- Primitive.DrawShape(self, device)
- device.MultiBezier(self.paths, rect, clip)
+ Primitive.DrawShape(self, device)
+ device.MultiBezier(self.paths, rect, clip)
def GetObjectHandle(self, multiple):
- if self.paths:
- return self.paths[0].Node(0)
- return Point(0, 0)
+ if self.paths:
+ return self.paths[0].Node(0)
+ return Point(0, 0)
def GetSnapPoints(self):
- points = []
- for path in self.paths:
- points = points + path.NodeList()
- return points
+ points = []
+ for path in self.paths:
+ points = points + path.NodeList()
+ return points
def Snap(self, p):
- found = [(1e100, p)]
- for path in self.paths:
- t = path.nearest_point(p.x, p.y)
- if t is not None:
- #print p, t
- p2 = path.point_at(t)
- found.append((abs(p - p2), p2))
- return min(found)
+ found = [(1e100, p)]
+ for path in self.paths:
+ t = path.nearest_point(p.x, p.y)
+ if t is not None:
+ #print p, t
+ p2 = path.point_at(t)
+ found.append((abs(p - p2), p2))
+ return min(found)
def update_rects(self):
- if not self.paths:
- # this should never happen...
- self.coord_rect = self.bounding_rect = Rect(0, 0, 0, 0)
- return
+ if not self.paths:
+ # this should never happen...
+ self.coord_rect = self.bounding_rect = Rect(0, 0, 0, 0)
+ return
- rect = self.paths[0].accurate_rect()
- for path in self.paths[1:]:
- rect = UnionRects(rect, path.accurate_rect())
- self.coord_rect = rect
- if self.properties.HasLine():
- rect = self.add_arrow_rects(rect)
- self.bounding_rect = rect.grown(self.properties.GrowAmount())
- else:
- self.bounding_rect = rect
+ rect = self.paths[0].accurate_rect()
+ for path in self.paths[1:]:
+ rect = UnionRects(rect, path.accurate_rect())
+ self.coord_rect = rect
+ if self.properties.HasLine():
+ rect = self.add_arrow_rects(rect)
+ self.bounding_rect = rect.grown(self.properties.GrowAmount())
+ else:
+ self.bounding_rect = rect
def add_arrow_rects(self, rect):
- if self.properties.HasLine():
- arrow1 = self.properties.line_arrow1
- arrow2 = self.properties.line_arrow2
- if arrow1 or arrow2:
- width = self.properties.line_width
- for path in self.paths:
- if not path.closed and path.len > 1:
- if arrow1 is not None:
- type, controls, p3, cont = path.Segment(1)
- p = path.Node(0)
- if type == Bezier:
- dir = p - controls[0]
- else:
- dir = p - p3
- rect = UnionRects(rect,
- arrow1.BoundingRect(p,dir,width))
- if arrow2 is not None:
- type, controls, p, cont = path.Segment(-1)
- if type == Bezier:
- dir = p - controls[1]
- else:
- dir = p - path.Node(-2)
- rect = UnionRects(rect,
- arrow2.BoundingRect(p,dir,width))
- return rect
+ if self.properties.HasLine():
+ arrow1 = self.properties.line_arrow1
+ arrow2 = self.properties.line_arrow2
+ if arrow1 or arrow2:
+ width = self.properties.line_width
+ for path in self.paths:
+ if not path.closed and path.len > 1:
+ if arrow1 is not None:
+ type, controls, p3, cont = path.Segment(1)
+ p = path.Node(0)
+ if type == Bezier:
+ dir = p - controls[0]
+ else:
+ dir = p - p3
+ rect = UnionRects(rect,
+ arrow1.BoundingRect(p,dir,width))
+ if arrow2 is not None:
+ type, controls, p, cont = path.Segment(-1)
+ if type == Bezier:
+ dir = p - controls[1]
+ else:
+ dir = p - path.Node(-2)
+ rect = UnionRects(rect,
+ arrow2.BoundingRect(p,dir,width))
+ return rect
def Info(self):
- nodes = 0
- for path in self.paths:
- nodes = nodes + path.len
- if path.closed:
- nodes = nodes - 1
- return _("PolyBezier (%(nodes)d nodes in %(paths)d paths)") \
- % {'nodes':nodes, 'paths':len(self.paths)}
+ nodes = 0
+ for path in self.paths:
+ nodes = nodes + path.len
+ if path.closed:
+ nodes = nodes - 1
+ return _("PolyBezier (%(nodes)d nodes in %(paths)d paths)") \
+ % {'nodes':nodes, 'paths':len(self.paths)}
def set_paths(self, paths):
- undo = (self.set_paths, self.paths)
- self.paths = tuple(paths)
- self._changed()
- return undo
+ undo = (self.set_paths, self.paths)
+ self.paths = tuple(paths)
+ self._changed()
+ return undo
SetPaths = set_paths
def Paths(self):
- return self.paths
+ return self.paths
def PathsAsObjects(self):
- result = []
- for path in self.paths:
- object = self.__class__(paths = (path.Duplicate(),),
- properties = self.properties.Duplicate())
- result.append(object)
- return result
+ result = []
+ for path in self.paths:
+ object = self.__class__(paths = (path.Duplicate(),),
+ properties = self.properties.Duplicate())
+ result.append(object)
+ return result
script_access['PathsAsObjects'] = SCRIPT_OBJECTLIST
def AsBezier(self):
- # is `return self' enough ?
- return self.Duplicate()
+ # is `return self' enough ?
+ return self.Duplicate()
#
#
#
def SaveToFile(self, file):
- Primitive.SaveToFile(self, file)
- file.PolyBezier(self.paths)
+ Primitive.SaveToFile(self, file)
+ file.PolyBezier(self.paths)
def load_straight(self, *args):
- apply(self.paths[-1].AppendLine, args)
+ apply(self.paths[-1].AppendLine, args)
def load_curve(self, *args):
- apply(self.paths[-1].AppendBezier, args)
+ apply(self.paths[-1].AppendBezier, args)
def load_close(self, copy_cont_from_last = 0):
- self.paths[-1].load_close(copy_cont_from_last)
+ self.paths[-1].load_close(copy_cont_from_last)
def guess_continuity(self):
- for path in self.paths:
- path.guess_continuity()
+ for path in self.paths:
+ path.guess_continuity()
def load_IsComplete(self):
- if self.paths[0].len < 2:
- # we need at least two nodes
- return 0
- return 1
+ if self.paths[0].len < 2:
+ # we need at least two nodes
+ return 0
+ return 1
def Blend(self, other, frac1, frac2):
- if self.__class__ != other.__class__:
- try:
- other = other.AsBezier()
- if not other:
- raise MismatchError
- except AttributeError, value:
- if value == 'AsBezier':
- raise MismatchError
- else:
- raise
+ if self.__class__ != other.__class__:
+ try:
+ other = other.AsBezier()
+ if not other:
+ raise MismatchError
+ except AttributeError, value:
+ if value == 'AsBezier':
+ raise MismatchError
+ else:
+ raise
paths = BlendPaths(self.paths, other.paths, frac1, frac2)
- blended = PolyBezier(paths = paths)
- self.set_blended_properties(blended, other, frac1, frac2)
- return blended
+ blended = PolyBezier(paths = paths)
+ self.set_blended_properties(blended, other, frac1, frac2)
+ return blended
def Editor(self):
- return PolyBezierEditor(self)
+ return PolyBezierEditor(self)
@@ -279,8 +279,8 @@
creation_text = _("Create Curve")
def __init__(self, start):
- self.path = CreatePath()
- Creator.__init__(self, start)
+ self.path = CreatePath()
+ Creator.__init__(self, start)
def apply_constraints(self, p, state):
if self.path.len > 0:
@@ -289,7 +289,7 @@
node = self.drag_start
else:
return p
-
+
if state & ConstraintMask:
radius, angle = (p - node).polar()
pi12 = pi / 12
@@ -299,50 +299,50 @@
def ButtonDown(self, p, button, state):
p = self.apply_constraints(p, state)
- if self.path.len == 0:
- self.path.AppendLine(p)
- else:
- self.path.AppendBezier(self.drag_cur, p, p)
- return self.DragStart(p)
+ if self.path.len == 0:
+ self.path.AppendLine(p)
+ else:
+ self.path.AppendBezier(self.drag_cur, p, p)
+ return self.DragStart(p)
def MouseMove(self, p, state):
- if not (state & Button1Mask):
- return
- self.DragMove(self.apply_constraints(p, state))
+ if not (state & Button1Mask):
+ return
+ self.DragMove(self.apply_constraints(p, state))
def ButtonUp(self, p, button, state):
- if not (state & Button1Mask):
- return
+ if not (state & Button1Mask):
+ return
p = self.apply_constraints(p, state)
- self.DragStop(p)
- if self.path.len > 1:
- type, (p1, p2), p, cont = self.path.Segment(-1)
- p2 = adjust_control_point(p2, p, self.drag_cur, ContSymmetrical)
- self.path.SetBezier(-1, p1, p2, p, ContSymmetrical)
+ self.DragStop(p)
+ if self.path.len > 1:
+ type, (p1, p2), p, cont = self.path.Segment(-1)
+ p2 = adjust_control_point(p2, p, self.drag_cur, ContSymmetrical)
+ self.path.SetBezier(-1, p1, p2, p, ContSymmetrical)
def EndCreation(self):
- return self.path.len > 1
+ return self.path.len > 1
def AppendInteractive(self, p):
- return self
+ return self
def ContinueCreation(self):
- return self.AppendInteractive
+ return self.AppendInteractive
def DrawDragged(self, device, partially):
- if not partially:
- self.path.draw_not_last(device.Bezier, device.Line)
- device.DrawHandleLine(self.path.Node(-1), self.drag_cur)
- device.DrawSmallRectHandle(self.drag_cur)
- if self.path.len > 1:
- type, (p1, p2), p, cont = self.path.Segment(-1)
- p2 = adjust_control_point(p2, p, self.drag_cur, ContSymmetrical)
- device.Bezier(self.path.Node(-2), p1, p2, p)
- device.DrawHandleLine(p, p2)
- device.DrawSmallRectHandle(p2)
+ if not partially:
+ self.path.draw_not_last(device.Bezier, device.Line)
+ device.DrawHandleLine(self.path.Node(-1), self.drag_cur)
+ device.DrawSmallRectHandle(self.drag_cur)
+ if self.path.len > 1:
+ type, (p1, p2), p, cont = self.path.Segment(-1)
+ p2 = adjust_control_point(p2, p, self.drag_cur, ContSymmetrical)
+ device.Bezier(self.path.Node(-2), p1, p2, p)
+ device.DrawHandleLine(p, p2)
+ device.DrawSmallRectHandle(p2)
def CreatedObject(self):
- return PolyBezier(paths = (self.path,),
+ return PolyBezier(paths = (self.path,),
properties = DefaultGraphicsProperties())
@@ -352,9 +352,9 @@
creation_text = _("Create Poly-Line")
def __init__(self, start):
- self.path = CreatePath()
+ self.path = CreatePath()
self.was_dragged = 0
- Creator.__init__(self, start)
+ Creator.__init__(self, start)
def apply_constraints(self, p, state):
if self.path.len > 0:
@@ -363,7 +363,7 @@
node = self.drag_start
else:
return p
-
+
if state & ConstraintMask:
radius, angle = (p - node).polar()
pi12 = pi / 12
@@ -372,43 +372,43 @@
return p
def ButtonDown(self, p, button, state):
- return self.DragStart(self.apply_constraints(p, state))
+ return self.DragStart(self.apply_constraints(p, state))
def MouseMove(self, p, state):
- if not (state & Button1Mask):
- return
+ if not (state & Button1Mask):
+ return
self.was_dragged = 1
- self.DragMove(self.apply_constraints(p, state))
+ self.DragMove(self.apply_constraints(p, state))
def ButtonUp(self, p, button, state):
- if not (state & Button1Mask):
- return
- self.DragStop(self.apply_constraints(p, state))
+ if not (state & Button1Mask):
+ return
+ self.DragStop(self.apply_constraints(p, state))
if self.was_dragged and self.path.len == 0:
self.path.AppendLine(self.drag_start)
self.path.AppendLine(self.drag_cur)
def EndCreation(self):
- return self.path.len > 1
+ return self.path.len > 1
def AppendInteractive(self, p):
- return self
+ return self
def ContinueCreation(self):
- return self.AppendInteractive
+ return self.AppendInteractive
def DrawDragged(self, device, partially):
- if self.path.len > 1:
- if not partially:
+ if self.path.len > 1:
+ if not partially:
device.DrawBezierPath(self.path)
if self.path.len >= 1:
- device.Line(self.path.Node(-1), self.drag_cur)
+ device.Line(self.path.Node(-1), self.drag_cur)
else:
if self.was_dragged:
device.Line(self.drag_start, self.drag_cur)
def CreatedObject(self):
- return PolyBezier(paths = (self.path,),
+ return PolyBezier(paths = (self.path,),
properties = DefaultGraphicsProperties())
SelCurvePoint = -1
@@ -419,12 +419,12 @@
commands = []
def __init__(self, object):
- self.selected_path = -1
- self.selected_idx = -1
- self.selection_type = SelNone
- self.other_segment = -1
- Editor.__init__(self, object)
- self.Deselect()
+ self.selected_path = -1
+ self.selected_idx = -1
+ self.selection_type = SelNone
+ self.other_segment = -1
+ Editor.__init__(self, object)
+ self.Deselect()
def SelectPoint(self, p, rect, device, mode):
self.deselect()
@@ -432,9 +432,9 @@
for i in range(len(self.paths)):
path = self.paths[i]
t = path.nearest_point(p.x, p.y)
- if t is not None:
- p2 = path.point_at(t)
- found.append((abs(p - p2), i, t, p2))
+ if t is not None:
+ p2 = path.point_at(t)
+ found.append((abs(p - p2), i, t, p2))
dist, i, t, p2 = min(found)
self.selected_path = i
self.selected_idx = t
@@ -466,63 +466,63 @@
path.SelectSegment(segment, 0)
def SelectRect(self, rect, mode = SelectSet):
- selected = 0
- for path in self.paths:
- selected = path.select_rect(rect, mode) or selected
+ selected = 0
+ for path in self.paths:
+ selected = path.select_rect(rect, mode) or selected
self.selection_type = SelNodes
- return selected
+ return selected
def SelectAllNodes(self):
- for path in self.paths:
- for i in range(path.len):
- path.SelectSegment(i, 1)
+ for path in self.paths:
+ for i in range(path.len):
+ path.SelectSegment(i, 1)
AddCmd(commands, SelectAllNodes, _("Select All Nodes"))
def deselect(self):
- for path in self.paths:
- path.deselect()
+ for path in self.paths:
+ path.deselect()
def Deselect(self):
self.deselect()
- self.selected_path = -1
- self.selected_idx = -1
- self.selection_type = SelNone
+ self.selected_path = -1
+ self.selected_idx = -1
+ self.selection_type = SelNone
def ButtonDown(self, p, button, state):
- if self.selected_path >= 0:
- path = self.paths[self.selected_path]
- if self.selection_type == SelNodes:
- start = path.Node(self.selected_idx)
- self.DragStart(start)
- return p - start
- elif self.selection_type == SelSegmentFirst:
- segment = self.selected_idx
- if segment > 1 \
- and path.SegmentType(segment - 1) == Bezier\
- and path.Continuity(segment - 1):
- self.other_segment = segment - 1
- elif path.closed and segment == 1 \
- and path.SegmentType(-1) == Bezier\
- and path.Continuity(-1):
- self.other_segment = path.len - 1
- else:
- self.other_segment = -1
- p1 = path.Segment(segment)[1][0]
- self.DragStart(p1)
- return p - p1
- elif self.selection_type == SelSegmentLast:
- segment = self.selected_idx
- self.other_segment = -1
- if path.Continuity(segment):
- if segment < path.len - 1 \
- and path.SegmentType(segment + 1) == Bezier:
- self.other_segment = segment + 1
- elif path.closed and segment == path.len - 1 \
- and path.SegmentType(1) == Bezier:
- self.other_segment = 1
- p2 = path.Segment(segment)[1][1]
- self.DragStart(p2)
- return p - p2
+ if self.selected_path >= 0:
+ path = self.paths[self.selected_path]
+ if self.selection_type == SelNodes:
+ start = path.Node(self.selected_idx)
+ self.DragStart(start)
+ return p - start
+ elif self.selection_type == SelSegmentFirst:
+ segment = self.selected_idx
+ if segment > 1 \
+ and path.SegmentType(segment - 1) == Bezier\
+ and path.Continuity(segment - 1):
+ self.other_segment = segment - 1
+ elif path.closed and segment == 1 \
+ and path.SegmentType(-1) == Bezier\
+ and path.Continuity(-1):
+ self.other_segment = path.len - 1
+ else:
+ self.other_segment = -1
+ p1 = path.Segment(segment)[1][0]
+ self.DragStart(p1)
+ return p - p1
+ elif self.selection_type == SelSegmentLast:
+ segment = self.selected_idx
+ self.other_segment = -1
+ if path.Continuity(segment):
+ if segment < path.len - 1 \
+ and path.SegmentType(segment + 1) == Bezier:
+ self.other_segment = segment + 1
+ elif path.closed and segment == path.len - 1 \
+ and path.SegmentType(1) == Bezier:
+ self.other_segment = 1
+ p2 = path.Segment(segment)[1][1]
+ self.DragStart(p2)
+ return p - p2
elif self.selection_type == SelCurvePoint:
start = path.point_at(self.selected_idx)
segment = int(ceil(self.selected_idx))
@@ -554,14 +554,14 @@
elif path.closed and segment == 1:
prev = path.len - 1
self.other_segment = (prev, next)
- self.DragStart(start)
- return p - start
+ self.DragStart(start)
+ return p - start
def apply_constraints(self, p, state):
if state & ConstraintMask:
if self.selection_type == SelNodes:
- pi4 = pi / 4
- off = p - self.drag_start
+ pi4 = pi / 4
+ off = p - self.drag_start
d = Polar(pi4 * round(atan2(off.y, off.x) / pi4))
p = self.drag_start + (off * d) * d
elif self.selection_type in (SelSegmentFirst, SelSegmentLast):
@@ -575,48 +575,48 @@
angle = pi12 * floor(angle / pi12 + 0.5)
p = node + Polar(radius, angle)
return p
-
+
def MouseMove(self, p, state):
self.DragMove(self.apply_constraints(p, state))
def ButtonUp(self, p, button, state):
p = self.apply_constraints(p, state)
- self.DragStop(p)
- type = self.selection_type
- if type == SelNodes:
- undo = []
- for path in self.paths:
- if path.selection_count() > 0:
- undo.append(path.move_selected_nodes(self.off))
- else:
- undo.append(None)
- if undo:
- self._changed()
- return (self.do_undo, undo)
- elif type in (SelSegmentFirst, SelSegmentLast):
- idx = self.selected_path
- segment = self.selected_idx
- path = self.paths[idx].Duplicate()
- paths = self.paths[:idx] + (path,) + self.paths[idx + 1:]
- if type == SelSegmentFirst:
- type, (p1, p2), node, cont = path.Segment(segment)
- path.SetBezier(segment, self.drag_cur, p2, node, cont)
- if self.other_segment >= 0:
- other = self.other_segment
- type, (p1, p2), node, cont = path.Segment(other)
- p2 = adjust_control_point(p2, node, self.drag_cur, cont)
- path.SetBezier(other, p1, p2, node, cont)
- path.SelectSegment(segment - 1)
- elif type == SelSegmentLast:
- type, (p1, p2), node, cont = path.Segment(segment)
- path.SetBezier(segment, p1, self.drag_cur, node, cont)
- if self.other_segment >= 0:
- other = self.other_segment
- type, (p1, p2), node2, cont2 = path.Segment(other)
- p1 = adjust_control_point(p1, node, self.drag_cur, cont)
- path.SetBezier(other, p1, p2, node2, cont2)
- path.SelectSegment(segment)
- return self.set_paths(paths) # set_paths calls _changed()
+ self.DragStop(p)
+ type = self.selection_type
+ if type == SelNodes:
+ undo = []
+ for path in self.paths:
+ if path.selection_count() > 0:
+ undo.append(path.move_selected_nodes(self.off))
+ else:
+ undo.append(None)
+ if undo:
+ self._changed()
+ return (self.do_undo, undo)
+ elif type in (SelSegmentFirst, SelSegmentLast):
+ idx = self.selected_path
+ segment = self.selected_idx
+ path = self.paths[idx].Duplicate()
+ paths = self.paths[:idx] + (path,) + self.paths[idx + 1:]
+ if type == SelSegmentFirst:
+ type, (p1, p2), node, cont = path.Segment(segment)
+ path.SetBezier(segment, self.drag_cur, p2, node, cont)
+ if self.other_segment >= 0:
+ other = self.other_segment
+ type, (p1, p2), node, cont = path.Segment(other)
+ p2 = adjust_control_point(p2, node, self.drag_cur, cont)
+ path.SetBezier(other, p1, p2, node, cont)
+ path.SelectSegment(segment - 1)
+ elif type == SelSegmentLast:
+ type, (p1, p2), node, cont = path.Segment(segment)
+ path.SetBezier(segment, p1, self.drag_cur, node, cont)
+ if self.other_segment >= 0:
+ other = self.other_segment
+ type, (p1, p2), node2, cont2 = path.Segment(other)
+ p1 = adjust_control_point(p1, node, self.drag_cur, cont)
+ path.SetBezier(other, p1, p2, node2, cont2)
+ path.SelectSegment(segment)
+ return self.set_paths(paths) # set_paths calls _changed()
elif self.selection_type == SelCurvePoint:
idx = self.selected_path
path = self.paths[idx].Duplicate()
@@ -663,51 +663,51 @@
return self.set_paths(paths) # set_paths calls _changed()
def DrawDragged(self, device, partially):
- if self.selection_type == SelNodes:
- for path in self.paths:
- path.draw_dragged_nodes(self.off, partially,
- device.Bezier, device.Line)
- elif self.selection_type == SelSegmentFirst:
- if not partially:
- for path in self.paths:
- path.draw_unselected(device.Bezier, device.Line)
- path = self.paths[self.selected_path]
- segment = self.selected_idx
- node = path.Node(segment - 1)
- type, (p1, p2), node2, cont = path.Segment(segment)
- device.Bezier(node, self.drag_cur, p2, node2)
- device.DrawSmallRectHandle(self.drag_cur)
- device.DrawHandleLine(node, self.drag_cur)
- if self.other_segment >= 0:
- other = self.other_segment
- type, (p1, p2), node, cont = path.Segment(other)
- p2 = adjust_control_point(p2, node, self.drag_cur, cont)
- device.Bezier(path.Node(other - 1), p1, p2, node)
- device.DrawSmallRectHandle(p2)
- device.DrawHandleLine(node, p2)
- elif self.selection_type == SelSegmentLast:
- if not partially:
- for path in self.paths:
- path.draw_unselected(device.Bezier, device.Line)
- path = self.paths[self.selected_path]
- segment = self.selected_idx
- type, (p1, p2), node, cont = path.Segment(segment)
- device.Bezier(path.Node(segment - 1), p1, self.drag_cur, node)
- device.DrawSmallRectHandle(self.drag_cur)
- device.DrawHandleLine(node, self.drag_cur)
- if self.other_segment >= 0:
- other = self.other_segment
- type, (p1, p2), node2, cont2 = path.Segment(other)
- p1 = adjust_control_point(p1, node, self.drag_cur, cont)
- device.Bezier(node, p1, p2, node2)
- device.DrawSmallRectHandle(p1)
- device.DrawHandleLine(node, p1)
+ if self.selection_type == SelNodes:
+ for path in self.paths:
+ path.draw_dragged_nodes(self.off, partially,
+ device.Bezier, device.Line)
+ elif self.selection_type == SelSegmentFirst:
+ if not partially:
+ for path in self.paths:
+ path.draw_unselected(device.Bezier, device.Line)
+ path = self.paths[self.selected_path]
+ segment = self.selected_idx
+ node = path.Node(segment - 1)
+ type, (p1, p2), node2, cont = path.Segment(segment)
+ device.Bezier(node, self.drag_cur, p2, node2)
+ device.DrawSmallRectHandle(self.drag_cur)
+ device.DrawHandleLine(node, self.drag_cur)
+ if self.other_segment >= 0:
+ other = self.other_segment
+ type, (p1, p2), node, cont = path.Segment(other)
+ p2 = adjust_control_point(p2, node, self.drag_cur, cont)
+ device.Bezier(path.Node(other - 1), p1, p2, node)
+ device.DrawSmallRectHandle(p2)
+ device.DrawHandleLine(node, p2)
+ elif self.selection_type == SelSegmentLast:
+ if not partially:
+ for path in self.paths:
+ path.draw_unselected(device.Bezier, device.Line)
+ path = self.paths[self.selected_path]
+ segment = self.selected_idx
+ type, (p1, p2), node, cont = path.Segment(segment)
+ device.Bezier(path.Node(segment - 1), p1, self.drag_cur, node)
+ device.DrawSmallRectHandle(self.drag_cur)
+ device.DrawHandleLine(node, self.drag_cur)
+ if self.other_segment >= 0:
+ other = self.other_segment
+ type, (p1, p2), node2, cont2 = path.Segment(other)
+ p1 = adjust_control_point(p1, node, self.drag_cur, cont)
+ device.Bezier(node, p1, p2, node2)
+ device.DrawSmallRectHandle(p1)
+ device.DrawHandleLine(node, p1)
elif self.selection_type == SelCurvePoint:
path = self.paths[self.selected_path]
segment = int(self.selected_idx)
t = self.selected_idx - segment
prevnode = path.Node(segment)
-
+
type, control, node, cont = path.Segment(segment + 1)
if type == Bezier:
p1, p2 = control
@@ -760,10 +760,10 @@
NodeHandle = handle.MakeNodeHandle
ControlHandle = handle.MakeControlHandle
LineHandle = handle.MakeLineHandle
- handles = []
+ handles = []
node_handles = []
append = handles.append
- for path_idx in range(len(self.paths)):
+ for path_idx in range(len(self.paths)):
path = self.paths[path_idx]
if path.len > 0:
if not path.closed:
@@ -787,33 +787,33 @@
return handles + node_handles
def Info(self):
- selected = 0
- idx = None
- paths = self.paths
- for i in range(len(paths)):
- path = paths[i]
- count = path.selection_count()
- if count > 0:
- selected = selected + count
- idx = i
- if selected > 1:
- return _("%d nodes in PolyBezier") % selected
- else:
- if idx is not None:
- path = paths[idx]
- for i in range(path.len):
- if path.SegmentSelected(i):
- break
- else:
- warn(INTERNAL, 'Strange selection count')
- return _("PolyBezier")
- if i == 0:
- return _("First node of PolyBezier")
- elif i == path.len - 1:
- return _("Last node of PolyBezier")
- else:
- return _("1 node of PolyBezier")
- else:
+ selected = 0
+ idx = None
+ paths = self.paths
+ for i in range(len(paths)):
+ path = paths[i]
+ count = path.selection_count()
+ if count > 0:
+ selected = selected + count
+ idx = i
+ if selected > 1:
+ return _("%d nodes in PolyBezier") % selected
+ else:
+ if idx is not None:
+ path = paths[idx]
+ for i in range(path.len):
+ if path.SegmentSelected(i):
+ break
+ else:
+ warn(INTERNAL, 'Strange selection count')
+ return _("PolyBezier")
+ if i == 0:
+ return _("First node of PolyBezier")
+ elif i == path.len - 1:
+ return _("Last node of PolyBezier")
+ else:
+ return _("1 node of PolyBezier")
+ else:
if self.selection_type == SelCurvePoint:
return _("Point on curve at position %.2f") \
% self.selected_idx
@@ -870,108 +870,108 @@
paths.append(path)
return self.set_paths(paths)
AddCmd(commands, OpenNodes, _("Cut Curve"), key_stroke = 'c',
- bitmap = pixmaps.BezierOpenNodes)
+ bitmap = pixmaps.BezierOpenNodes)
def CloseNodes(self):
- # find out if close is possible
- two = 0
- one = 0
- for i in range(len(self.paths)):
- path = self.paths[i]
- selected = path.selection_count()
- if not selected:
- continue
- if (path.closed and selected) or selected not in (1, 2):
- return
- if selected == 1:
- if path.SegmentSelected(0) or path.SegmentSelected(-1):
- one = one + 1
- continue
- return
- else:
- if path.SegmentSelected(0) and path.SegmentSelected(-1):
- two = two + 1
- continue
- return
- # now, close the nodes
- if one == 2 and two == 0:
- paths = []
- append_to = None
- for path in self.paths:
- if path.selection_count():
- if append_to:
- # path is the second of the paths involved
- end_node = append_to.Node(-1)
- if path.SegmentSelected(0):
- for i in range(1, path.len):
- type, p12, p, cont = path.Segment(i)
- if end_node is not None and type == Bezier:
- p12 = (p12[0] + end_node - path.Node(0),
- p12[1])
- end_node = None
- append_to.AppendSegment(type, p12, p, cont)
- else:
- for i in range(path.len - 1, 0, -1):
- type, p12, p3, cont = path.Segment(i)
- if end_node is not None and type == Bezier:
- p12 = (p12[0],
- p12[1] + end_node - path.Node(-1))
- end_node = None
- p = path.Node(i - 1)
- if type == Bezier:
- p12 = (p12[1], p12[0])
- append_to.AppendSegment(type, p12, p,
- path.Continuity(i - 1))
- continue
- else:
- # path is the first of the paths involved
- if path.SegmentSelected(0):
- # reverse the path
- append_to = CreatePath()
- p = path.Node(-1)
- append_to.AppendLine(p, ContAngle)
- for i in range(path.len - 1, 0, -1):
- type, p12, p3, cont = path.Segment(i)
- p = path.Node(i - 1)
- if type == Bezier:
- p12 = (p12[1], p12[0])
- append_to.AppendSegment(type, p12, p,
- path.Continuity(i - 1))
- path = append_to
- else:
- path = append_to = path.Duplicate()
- append_to.SetContinuity(-1, ContAngle)
- paths.append(path)
- undo = self.set_paths(paths)
- elif one == 0 and two == 1:
- undo_list = []
- for path in self.paths:
- if path.selection_count():
- undo_list.append(path.ClosePath())
- else:
- undo_list.append(None)
- undo = (self.object.do_undo, undo_list)
- self._changed()
- else:
- return
- return undo
+ # find out if close is possible
+ two = 0
+ one = 0
+ for i in range(len(self.paths)):
+ path = self.paths[i]
+ selected = path.selection_count()
+ if not selected:
+ continue
+ if (path.closed and selected) or selected not in (1, 2):
+ return
+ if selected == 1:
+ if path.SegmentSelected(0) or path.SegmentSelected(-1):
+ one = one + 1
+ continue
+ return
+ else:
+ if path.SegmentSelected(0) and path.SegmentSelected(-1):
+ two = two + 1
+ continue
+ return
+ # now, close the nodes
+ if one == 2 and two == 0:
+ paths = []
+ append_to = None
+ for path in self.paths:
+ if path.selection_count():
+ if append_to:
+ # path is the second of the paths involved
+ end_node = append_to.Node(-1)
+ if path.SegmentSelected(0):
+ for i in range(1, path.len):
+ type, p12, p, cont = path.Segment(i)
+ if end_node is not None and type == Bezier:
+ p12 = (p12[0] + end_node - path.Node(0),
+ p12[1])
+ end_node = None
+ append_to.AppendSegment(type, p12, p, cont)
+ else:
+ for i in range(path.len - 1, 0, -1):
+ type, p12, p3, cont = path.Segment(i)
+ if end_node is not None and type == Bezier:
+ p12 = (p12[0],
+ p12[1] + end_node - path.Node(-1))
+ end_node = None
+ p = path.Node(i - 1)
+ if type == Bezier:
+ p12 = (p12[1], p12[0])
+ append_to.AppendSegment(type, p12, p,
+ path.Continuity(i - 1))
+ continue
+ else:
+ # path is the first of the paths involved
+ if path.SegmentSelected(0):
+ # reverse the path
+ append_to = CreatePath()
+ p = path.Node(-1)
+ append_to.AppendLine(p, ContAngle)
+ for i in range(path.len - 1, 0, -1):
+ type, p12, p3, cont = path.Segment(i)
+ p = path.Node(i - 1)
+ if type == Bezier:
+ p12 = (p12[1], p12[0])
+ append_to.AppendSegment(type, p12, p,
+ path.Continuity(i - 1))
+ path = append_to
+ else:
+ path = append_to = path.Duplicate()
+ append_to.SetContinuity(-1, ContAngle)
+ paths.append(path)
+ undo = self.set_paths(paths)
+ elif one == 0 and two == 1:
+ undo_list = []
+ for path in self.paths:
+ if path.selection_count():
+ undo_list.append(path.ClosePath())
+ else:
+ undo_list.append(None)
+ undo = (self.object.do_undo, undo_list)
+ self._changed()
+ else:
+ return
+ return undo
AddCmd(commands, CloseNodes, _("Close Nodes"),
- bitmap = pixmaps.BezierCloseNodes)
+ bitmap = pixmaps.BezierCloseNodes)
def SetContinuity(self, cont):
- new_paths = []
- for path in self.paths:
- if path.selection_count():
- new_paths.append(set_continuity(path, cont))
- else:
- new_paths.append(path)
- return self.set_paths(new_paths)
+ new_paths = []
+ for path in self.paths:
+ if path.selection_count():
+ new_paths.append(set_continuity(path, cont))
+ else:
+ new_paths.append(path)
+ return self.set_paths(new_paths)
AddCmd(commands, 'ContAngle', _("Angle"), SetContinuity,
- args = ContAngle, bitmap = pixmaps.BezierAngle, key_stroke = 'a')
+ args = ContAngle, bitmap = pixmaps.BezierAngle, key_stroke = 'a')
AddCmd(commands, 'ContSmooth', _("Smooth"), SetContinuity,
- args = ContSmooth, bitmap = pixmaps.BezierSmooth, key_stroke = 's')
+ args = ContSmooth, bitmap = pixmaps.BezierSmooth, key_stroke = 's')
AddCmd(commands, 'ContSymmetrical', _("Symmetrical"), SetContinuity,
- args = ContSymmetrical, bitmap = pixmaps.BezierSymm, key_stroke='y')
+ args = ContSymmetrical, bitmap = pixmaps.BezierSymm, key_stroke='y')
def SegmentsToLines(self):
if self.selection_type == SelCurvePoint:
@@ -986,9 +986,9 @@
new_paths.append(segments_to_lines(path))
else:
new_paths.append(path)
- return self.set_paths(new_paths)
+ return self.set_paths(new_paths)
AddCmd(commands, SegmentsToLines, _("Curve->Line"), key_stroke = 'l',
- bitmap = pixmaps.BezierCurveLine)
+ bitmap = pixmaps.BezierCurveLine)
def SegmentsToCurve(self):
if self.selection_type == SelCurvePoint:
@@ -1003,32 +1003,32 @@
new_paths.append(segments_to_beziers(path))
else:
new_paths.append(path)
- return self.set_paths(new_paths)
+ return self.set_paths(new_paths)
AddCmd(commands, SegmentsToCurve, _("Line->Curve"), key_stroke = 'b',
- bitmap = pixmaps.BezierLineCurve)
+ bitmap = pixmaps.BezierLineCurve)
def DeleteNodes(self):
- new_paths = []
- for path in self.paths:
- if path.selection_count() > 0:
- newpath = delete_segments(path)
- else:
- newpath = path
- if newpath.len > 1:
- new_paths.append(newpath)
- else:
- # all nodes of path have been deleted
- if __debug__:
- pdebug('bezier', 'path removed')
- if new_paths:
- return self.set_paths(new_paths)
- else:
- if __debug__:
- pdebug('bezier', 'PolyBezier removed')
- self.document.DeselectObject(self.object)
- return self.parent.Remove(self.object)
+ new_paths = []
+ for path in self.paths:
+ if path.selection_count() > 0:
+ newpath = delete_segments(path)
+ else:
+ newpath = path
+ if newpath.len > 1:
+ new_paths.append(newpath)
+ else:
+ # all nodes of path have been deleted
+ if __debug__:
+ pdebug('bezier', 'path removed')
+ if new_paths:
+ return self.set_paths(new_paths)
+ else:
+ if __debug__:
+ pdebug('bezier', 'PolyBezier removed')
+ self.document.DeselectObject(self.object)
+ return self.parent.Remove(self.object)
AddCmd(commands, DeleteNodes, _("Delete Nodes"),
- bitmap = pixmaps.BezierDeleteNode, key_stroke = ('-', 'Delete'))
+ bitmap = pixmaps.BezierDeleteNode, key_stroke = ('-', 'Delete'))
def InsertNodes(self):
if self.selection_type == SelCurvePoint:
@@ -1045,39 +1045,39 @@
new_paths.append(insert_segments(path))
else:
new_paths.append(path)
- return self.set_paths(new_paths)
+ return self.set_paths(new_paths)
AddCmd(commands, InsertNodes, _("Insert Nodes"), key_stroke = '+',
- bitmap = pixmaps.BezierInsertNode)
+ bitmap = pixmaps.BezierInsertNode)
def ChangeRect(self):
- prop = self.properties
- if prop.IsAlgorithmicFill() or prop.IsAlgorithmicLine() \
- or prop.line_arrow1 is not None or prop.line_arrow2 is not None \
+ prop = self.properties
+ if prop.IsAlgorithmicFill() or prop.IsAlgorithmicLine() \
+ or prop.line_arrow1 is not None or prop.line_arrow2 is not None \
or self.selection_type == SelCurvePoint:
- return self.bounding_rect
+ return self.bounding_rect
- filled = self.Filled()
- pts = []
- for path in self.paths:
- if path.selection_count():
- for i in range(1, path.len):
- if path.SegmentSelected(i - 1) or path.SegmentSelected(i):
- pts.append(path.Node(i - 1))
- type, p12, p, cont = path.Segment(i)
- if type == Bezier:
- p1, p2 = p12
- pts.append(p1)
- pts.append(p2)
- pts.append(p)
- if filled and not path.closed:
- if path.SegmentSelected(-1):
- pts.append(path.Node(0))
- if path.SegmentSelected(0):
- pts.append(path.Node(-1))
- if pts:
- return PointsToRect(pts).grown(prop.GrowAmount())
- else:
- return EmptyRect
+ filled = self.Filled()
+ pts = []
+ for path in self.paths:
+ if path.selection_count():
+ for i in range(1, path.len):
+ if path.SegmentSelected(i - 1) or path.SegmentSelected(i):
+ pts.append(path.Node(i - 1))
+ type, p12, p, cont = path.Segment(i)
+ if type == Bezier:
+ p1, p2 = p12
+ pts.append(p1)
+ pts.append(p2)
+ pts.append(p)
+ if filled and not path.closed:
+ if path.SegmentSelected(-1):
+ pts.append(path.Node(0))
+ if path.SegmentSelected(0):
+ pts.append(path.Node(-1))
+ if pts:
+ return PointsToRect(pts).grown(prop.GrowAmount())
+ else:
+ return EmptyRect
context_commands = ('SelectAllNodes',)
@@ -1085,17 +1085,17 @@
def adjust_control_point(p, node, control, continuity):
if continuity == ContSymmetrical:
- return 2 * node - control
+ return 2 * node - control
elif continuity == ContSmooth:
- try:
- d = (control - node).normalized()
- length = abs(p - node)
- return node - length * d
- except ZeroDivisionError:
- # control == node
- return p
+ try:
+ d = (control - node).normalized()
+ length = abs(p - node)
+ return node - length * d
+ except ZeroDivisionError:
+ # control == node
+ return p
else:
- return p
+ return p
def subdivide(p0, p1, p2, p3, t = 0.5):
t2 = 1 - t
@@ -1112,53 +1112,53 @@
newpath = CreatePath()
selected = path.selection_count()
if (path.closed and selected == path.len - 1) or selected == path.len:
- return newpath
+ return newpath
f13 = 1.0 / 3.0; f23 = 2.0 / 3.0
i = 0
while path.SegmentSelected(i):
- i = i + 1
+ i = i + 1
if path.closed and i > 0:
- if path.SegmentType(i) == Bezier:
- last_p2 = path.Segment(i)[1][1]
- last_type = Bezier
- else:
- last_p2 = f23 * path.Node(i - 1) + f13 * path.Node(i)
- last_type = Line
+ if path.SegmentType(i) == Bezier:
+ last_p2 = path.Segment(i)[1][1]
+ last_type = Bezier
+ else:
+ last_p2 = f23 * path.Node(i - 1) + f13 * path.Node(i)
+ last_type = Line
else:
- last_p2 = None
+ last_p2 = None
newpath.AppendLine(path.Node(i), path.Continuity(i))
seg_p1 = None; seg_type = None
for i in range(i + 1, path.len):
- type, p12, p, cont = path.Segment(i)
- if type == Bezier:
- p1, p2 = p12
- if path.SegmentSelected(i):
- if seg_type is None:
- seg_type = type
- if type == Bezier:
- seg_p1 = p1
- else:
- seg_p1 = f23 * path.Node(i - 1) + f13 * p
- else:
- if seg_type is not None:
- if type == Bezier or seg_type == Bezier:
- if type == Line:
- p2 = f13 * path.Node(i - 1) + f23 * p
- newpath.AppendBezier(seg_p1, p2, p, cont)
- else:
- newpath.AppendLine(p, cont)
- seg_type = None
- else:
- newpath.AppendSegment(type, p12, p, cont)
+ type, p12, p, cont = path.Segment(i)
+ if type == Bezier:
+ p1, p2 = p12
+ if path.SegmentSelected(i):
+ if seg_type is None:
+ seg_type = type
+ if type == Bezier:
+ seg_p1 = p1
+ else:
+ seg_p1 = f23 * path.Node(i - 1) + f13 * p
+ else:
+ if seg_type is not None:
+ if type == Bezier or seg_type == Bezier:
+ if type == Line:
+ p2 = f13 * path.Node(i - 1) + f23 * p
+ newpath.AppendBezier(seg_p1, p2, p, cont)
+ else:
+ newpath.AppendLine(p, cont)
+ seg_type = None
+ else:
+ newpath.AppendSegment(type, p12, p, cont)
if path.closed:
- if last_p2 is not None:
- if last_type == Bezier or seg_type == Bezier:
- newpath.AppendBezier(seg_p1, last_p2, newpath.Node(0),
- newpath.Continuity(0))
- else:
- newpath.AppendLine(newpath.Node(0), newpath.Continuity(0))
- newpath.ClosePath()
+ if last_p2 is not None:
+ if last_type == Bezier or seg_type == Bezier:
+ newpath.AppendBezier(seg_p1, last_p2, newpath.Node(0),
+ newpath.Continuity(0))
+ else:
+ newpath.AppendLine(newpath.Node(0), newpath.Continuity(0))
+ newpath.ClosePath()
return newpath
def insert_segments(path):
@@ -1167,54 +1167,54 @@
newpath.select_segment(0, path.SegmentSelected(0))
for i in range(1, path.len):
- type, p12, p, cont = path.Segment(i)
- if path.SegmentSelected(i) and path.SegmentSelected(i - 1):
- if type == Line:
- node = 0.5 * path.Node(i - 1) + 0.5 * path.Node(i)
- newpath.AppendLine(node)
- newpath.select_segment(-1)
- newpath.AppendLine(path.Node(i))
- newpath.select_segment(-1)
- else:
+ type, p12, p, cont = path.Segment(i)
+ if path.SegmentSelected(i) and path.SegmentSelected(i - 1):
+ if type == Line:
+ node = 0.5 * path.Node(i - 1) + 0.5 * path.Node(i)
+ newpath.AppendLine(node)
+ newpath.select_segment(-1)
+ newpath.AppendLine(path.Node(i))
+ newpath.select_segment(-1)
+ else:
if newpath.Continuity(-1) == ContSymmetrical:
newpath.SetContinuity(-1, ContSmooth)
p1, p2 = p12
- p1, p2, node, p3, p4 = subdivide(path.Node(i - 1), p1, p2, p)
- newpath.AppendBezier(p1, p2, node, ContSymmetrical)
- newpath.select_segment(-1)
+ p1, p2, node, p3, p4 = subdivide(path.Node(i - 1), p1, p2, p)
+ newpath.AppendBezier(p1, p2, node, ContSymmetrical)
+ newpath.select_segment(-1)
if cont == ContSymmetrical:
cont = ContSmooth
- newpath.AppendBezier(p3, p4, p, cont)
- newpath.select_segment(-1)
- else:
- newpath.AppendSegment(type, p12, p, cont)
- newpath.select_segment(-1, path.SegmentSelected(i))
+ newpath.AppendBezier(p3, p4, p, cont)
+ newpath.select_segment(-1)
+ else:
+ newpath.AppendSegment(type, p12, p, cont)
+ newpath.select_segment(-1, path.SegmentSelected(i))
if path.closed:
- newpath.ClosePath()
- newpath.SetContinuity(-1, path.Continuity(-1))
+ newpath.ClosePath()
+ newpath.SetContinuity(-1, path.Continuity(-1))
return newpath
def copy_selection(path, newpath):
for i in range(path.len):
- newpath.select_segment(i, path.SegmentSelected(i))
+ newpath.select_segment(i, path.SegmentSelected(i))
def segments_to_lines(path):
newpath = CreatePath()
newpath.AppendLine(path.Node(0))
for i in range(1, path.len):
- if path.SegmentSelected(i) and path.SegmentSelected(i - 1):
- if path.SegmentType(i) == Bezier:
- cont = ContAngle
- newpath.SetContinuity(-1, ContAngle)
- else:
- cont = path.Continuity(i)
- newpath.AppendLine(path.Node(i), cont)
- else:
- apply(newpath.AppendSegment, path.Segment(i))
+ if path.SegmentSelected(i) and path.SegmentSelected(i - 1):
+ if path.SegmentType(i) == Bezier:
+ cont = ContAngle
+ newpath.SetContinuity(-1, ContAngle)
+ else:
+ cont = path.Continuity(i)
+ newpath.AppendLine(path.Node(i), cont)
+ else:
+ apply(newpath.AppendSegment, path.Segment(i))
if path.closed:
- cont = newpath.Continuity(-1)
- newpath.ClosePath()
- newpath.SetContinuity(-1, cont)
+ cont = newpath.Continuity(-1)
+ newpath.ClosePath()
+ newpath.SetContinuity(-1, cont)
copy_selection(path, newpath)
return newpath
@@ -1223,23 +1223,23 @@
newpath = CreatePath()
newpath.AppendLine(path.Node(0))
for i in range(1, path.len):
- type, p12, p, cont = path.Segment(i)
- if path.SegmentSelected(i) and path.SegmentSelected(i - 1):
- cont = path.Continuity(i)
- if type == Line:
- node1 = path.Node(i - 1); node2 = path.Node(i)
- p1 = f23 * node1 + f13 * node2
- p2 = f13 * node1 + f23 * node2
- cont = ContAngle
- else:
- p1, p2 = p12
- newpath.AppendBezier(p1, p2, p, cont)
- else:
- newpath.AppendSegment(type, p12, p, cont)
+ type, p12, p, cont = path.Segment(i)
+ if path.SegmentSelected(i) and path.SegmentSelected(i - 1):
+ cont = path.Continuity(i)
+ if type == Line:
+ node1 = path.Node(i - 1); node2 = path.Node(i)
+ p1 = f23 * node1 + f13 * node2
+ p2 = f13 * node1 + f23 * node2
+ cont = ContAngle
+ else:
+ p1, p2 = p12
+ newpath.AppendBezier(p1, p2, p, cont)
+ else:
+ newpath.AppendSegment(type, p12, p, cont)
if path.closed:
- cont = newpath.Continuity(-1)
- newpath.ClosePath()
- newpath.SetContinuity(-1, cont)
+ cont = newpath.Continuity(-1)
+ newpath.ClosePath()
+ newpath.SetContinuity(-1, cont)
copy_selection(path, newpath)
return newpath
@@ -1247,31 +1247,31 @@
f13 = 1.0 / 3.0; f23 = 2.0 / 3.0
newpath = path.Duplicate()
for i in range(1, path.len):
- if path.SegmentSelected(i):
- newpath.SetContinuity(i, cont)
- if cont == ContAngle:
- continue
- if newpath.SegmentType(i) != Bezier:
- continue
- if i == path.len - 1:
- if newpath.closed:
- other = 1
- else:
- continue
- else:
- other = i + 1
- if newpath.SegmentType(other) != Bezier:
- continue
- type, (p1, p2), node, oldcont = newpath.Segment(i)
- type, (p3, p4), other_node, other_cont = newpath.Segment(other)
+ if path.SegmentSelected(i):
+ newpath.SetContinuity(i, cont)
+ if cont == ContAngle:
+ continue
+ if newpath.SegmentType(i) != Bezier:
+ continue
+ if i == path.len - 1:
+ if newpath.closed:
+ other = 1
+ else:
+ continue
+ else:
+ other = i + 1
+ if newpath.SegmentType(other) != Bezier:
+ continue
+ type, (p1, p2), node, oldcont = newpath.Segment(i)
+ type, (p3, p4), other_node, other_cont = newpath.Segment(other)
- d = p3 - p2
- if cont == ContSymmetrical:
- d = 0.5 * d
- p2 = adjust_control_point(p2, node, node + d, cont)
- p3 = adjust_control_point(p3, node, node - d, cont)
- newpath.SetBezier(i, p1, p2, node, cont)
- newpath.SetBezier(other, p3, p4, other_node, other_cont)
+ d = p3 - p2
+ if cont == ContSymmetrical:
+ d = 0.5 * d
+ p2 = adjust_control_point(p2, node, node + d, cont)
+ p3 = adjust_control_point(p3, node, node - d, cont)
+ newpath.SetBezier(i, p1, p2, node, cont)
+ newpath.SetBezier(other, p3, p4, other_node, other_cont)
return newpath
@@ -1345,7 +1345,7 @@
copy_path(path1, path, 1, index, copy_selection = 0)
apply(function, args)
return result
-
+
def segment_to_line(path, at):
index = int(at)
if path.SegmentType(index + 1) == Bezier:
@@ -1368,7 +1368,7 @@
newpath = CreatePath()
copy_path(newpath, path, 0, index)
f13 = 1.0 / 3.0;
- f23 = 2.0 / 3.0
+ f23 = 2.0 / 3.0
node1 = path.Node(index);
node2 = path.Node(index + 1)
p1 = f23 * node1 + f13 * node2
@@ -1382,14 +1382,14 @@
else:
newpath = path
return newpath
-
+
def CombineBeziers(beziers):
combined = beziers[0].Duplicate()
paths = combined.paths
for bezier in beziers[1:]:
- paths = paths + bezier.paths
+ paths = paths + bezier.paths
combined.paths = paths
return combined
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/blend.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/blend.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/blend.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -27,42 +27,42 @@
def Blend(obj1, obj2, frac1, frac2 = None):
if frac2 is None:
- frac2 = 1.0 - frac1
+ frac2 = 1.0 - frac1
try:
- return obj1.Blend(obj2, frac1, frac2)
+ return obj1.Blend(obj2, frac1, frac2)
except MismatchError:
- pass
+ pass
try:
- return obj2.Blend(obj1, frac2, frac1)
+ return obj2.Blend(obj1, frac2, frac1)
except MismatchError:
- pass
+ pass
try:
- from bezier import PolyBezier
- if not isinstance(obj1,PolyBezier) and not isinstance(obj2,PolyBezier)\
- and obj1.is_curve and obj2.is_curve:
+ from bezier import PolyBezier
+ if not isinstance(obj1,PolyBezier) and not isinstance(obj2,PolyBezier)\
+ and obj1.is_curve and obj2.is_curve:
paths = BlendPaths(obj1.Paths(), obj2.Paths(), frac1, frac2)
properties = Blend(obj1.Properties(), obj2.Properties(),
frac1, frac2)
- return PolyBezier(paths = paths, properties = properties)
+ return PolyBezier(paths = paths, properties = properties)
except AttributeError, value:
- if str(value) != 'is_curve':
- raise
-
+ if str(value) != 'is_curve':
+ raise
+
return obj1.Duplicate()
def BlendTrafo(t1, t2, frac1, frac2):
return Trafo(frac1 * t1.m11 + frac2 * t2.m11,
- frac1 * t1.m21 + frac2 * t2.m21,
- frac1 * t1.m12 + frac2 * t2.m12,
- frac1 * t1.m22 + frac2 * t2.m22,
- frac1 * t1.v1 + frac2 * t2.v1,
- frac1 * t1.v2 + frac2 * t2.v2)
+ frac1 * t1.m21 + frac2 * t2.m21,
+ frac1 * t1.m12 + frac2 * t2.m12,
+ frac1 * t1.m22 + frac2 * t2.m22,
+ frac1 * t1.v1 + frac2 * t2.v1,
+ frac1 * t1.v2 + frac2 * t2.v2)
def BlendPaths(paths1, paths2, frac1, frac2):
- length = min((len(paths1), len(paths2)))
- paths = [None] * length
- blend_paths = _sketch.blend_paths
- for i in range(length):
- paths[i] = blend_paths(paths1[i], paths2[i], frac1, frac2)
- return tuple(paths)
+ length = min((len(paths1), len(paths2)))
+ paths = [None] * length
+ blend_paths = _sketch.blend_paths
+ for i in range(length):
+ paths[i] = blend_paths(paths1[i], paths2[i], frac1, frac2)
+ return tuple(paths)
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/blendgroup.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/blendgroup.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/blendgroup.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -45,83 +45,83 @@
is_BlendInterpolation = 1
def __init__(self, steps = 2, start = None, end = None,
- duplicate = None):
- if duplicate is not None:
- self.steps = duplicate.steps
- Compound.__init__(self, duplicate = duplicate)
- else:
- self.steps = steps
- if start is not None:
- Compound.__init__(self, self.compute_blend(start, end))
- else:
- Compound.__init__(self)
+ duplicate = None):
+ if duplicate is not None:
+ self.steps = duplicate.steps
+ Compound.__init__(self, duplicate = duplicate)
+ else:
+ self.steps = steps
+ if start is not None:
+ Compound.__init__(self, self.compute_blend(start, end))
+ else:
+ Compound.__init__(self)
def SetParameters(self, steps):
- if steps < 2:
- raise ValueError, 'steps must be >= 2'
- if self.steps != steps:
- undo = (self.SetParameters, self.steps)
- self.steps = steps
- self.parent.RecomputeChild(self)
- else:
- undo = NullUndo
- return undo
+ if steps < 2:
+ raise ValueError, 'steps must be >= 2'
+ if self.steps != steps:
+ undo = (self.SetParameters, self.steps)
+ self.steps = steps
+ self.parent.RecomputeChild(self)
+ else:
+ undo = NullUndo
+ return undo
def Steps(self):
- return self.steps
+ return self.steps
def Recompute(self, start, end):
- self.set_objects(self.compute_blend(start, end))
+ self.set_objects(self.compute_blend(start, end))
def compute_blend(self, start, end):
- steps = self.steps
- blended = []
- for step in range(1, steps):
- fraction = float(step) / steps
- blend = Blend(start, end, fraction)
- blend.SetDocument(self.document)
- blend.SetParent(None)
- blended.append(blend)
- blended.reverse()
- return blended
+ steps = self.steps
+ blended = []
+ for step in range(1, steps):
+ fraction = float(step) / steps
+ blend = Blend(start, end, fraction)
+ blend.SetDocument(self.document)
+ blend.SetParent(None)
+ blended.append(blend)
+ blended.reverse()
+ return blended
def set_objects(self, new_objs):
- # called by __init__ and recompute
- if self.document is not None:
- self.document.AddClearRect(self.bounding_rect)
- for obj in self.objects:
- obj.Destroy()
- self.objects = new_objs
- self.del_lazy_attrs()
- if self.document is not None:
- self.document.AddClearRect(self.bounding_rect)
- self.issue_changed()
+ # called by __init__ and recompute
+ if self.document is not None:
+ self.document.AddClearRect(self.bounding_rect)
+ for obj in self.objects:
+ obj.Destroy()
+ self.objects = new_objs
+ self.del_lazy_attrs()
+ if self.document is not None:
+ self.document.AddClearRect(self.bounding_rect)
+ self.issue_changed()
def SaveToFile(self, file):
- if file.options.full_blend:
- file.BeginBlendInterpolation(self.steps)
- for obj in self.objects:
- obj.SaveToFile(file)
- file.EndBlendInterpolation()
- else:
- file.BlendInterpolation(self.steps)
+ if file.options.full_blend:
+ file.BeginBlendInterpolation(self.steps)
+ for obj in self.objects:
+ obj.SaveToFile(file)
+ file.EndBlendInterpolation()
+ else:
+ file.BlendInterpolation(self.steps)
def AsGroup(self):
- return Group(self.objects[:])
+ return Group(self.objects[:])
def Transform(self, trafo):
- if self.parent.changing_children:
- return Compound.Transform(self, trafo)
- else:
- return NullUndo
+ if self.parent.changing_children:
+ return Compound.Transform(self, trafo)
+ else:
+ return NullUndo
def Translate(self, offset):
- if self.parent.changing_children:
- Compound.Translate(self, offset)
- return NullUndo
+ if self.parent.changing_children:
+ Compound.Translate(self, offset)
+ return NullUndo
def Info(self):
- return _("Interpolation with %d steps") % self.steps
+ return _("Interpolation with %d steps") % self.steps
class BlendGroup(Compound):
@@ -132,138 +132,138 @@
allow_traversal = 1 # allow selection of subobjects via M-Down etc.
def __init__(self, steps = 0, start = None, end = None, duplicate = None):
- # Three different ways to instantiate this class:
- #
- # 1. Duplicating a BlendGroup: duplicate is not None.
- #
- # 2. Creating a BlendGroup from two normal graphics objects:
- # start and end are not None.
- #
- # 3. Creating a BlendGroup from an sk file: steps is 0.
+ # Three different ways to instantiate this class:
+ #
+ # 1. Duplicating a BlendGroup: duplicate is not None.
+ #
+ # 2. Creating a BlendGroup from two normal graphics objects:
+ # start and end are not None.
+ #
+ # 3. Creating a BlendGroup from an sk file: steps is 0.
- if duplicate is not None:
- # case 1
- Compound.__init__(self, duplicate = duplicate)
- #self.Connect()
- elif start is not None:
- # case 2
- inter = BlendInterpolation(steps, start, end)
- Compound.__init__(self, [start, inter, end])
- #self.Connect()
- else:
- # case 3
- Compound.__init__(self)
+ if duplicate is not None:
+ # case 1
+ Compound.__init__(self, duplicate = duplicate)
+ #self.Connect()
+ elif start is not None:
+ # case 2
+ inter = BlendInterpolation(steps, start, end)
+ Compound.__init__(self, [start, inter, end])
+ #self.Connect()
+ else:
+ # case 3
+ Compound.__init__(self)
def load_AppendObject(self, object):
- Compound.load_AppendObject(self, object)
- length = len(self.objects)
- if length > 2 and length & 1:
- # last object was a control object
- if len(self.objects[-2].objects) == 0:
- self.objects[-2].Recompute(self.objects[-3], self.objects[-1])
+ Compound.load_AppendObject(self, object)
+ length = len(self.objects)
+ if length > 2 and length & 1:
+ # last object was a control object
+ if len(self.objects[-2].objects) == 0:
+ self.objects[-2].Recompute(self.objects[-3], self.objects[-1])
def insert(self, obj, at):
- undo_info = None
- try:
- if type(at) != IntType or at > len(self.objects):
- at = len(self.objects)
- self.objects.insert(at, obj)
- obj.SetDocument(self.document)
- obj.SetParent(self)
- obj.Connect()
- undo_info = (self.remove, at)
- self._changed()
- return undo_info
- except:
- if undo_info is not None:
- Undo(undo_info)
- raise
+ undo_info = None
+ try:
+ if type(at) != IntType or at > len(self.objects):
+ at = len(self.objects)
+ self.objects.insert(at, obj)
+ obj.SetDocument(self.document)
+ obj.SetParent(self)
+ obj.Connect()
+ undo_info = (self.remove, at)
+ self._changed()
+ return undo_info
+ except:
+ if undo_info is not None:
+ Undo(undo_info)
+ raise
def remove(self, idx):
- obj = self.objects[idx]
- del self.objects[idx]
- obj.Disconnect()
- obj.SetParent(None)
- self._changed()
- return (self.insert, obj, idx)
+ obj = self.objects[idx]
+ del self.objects[idx]
+ obj.Disconnect()
+ obj.SetParent(None)
+ self._changed()
+ return (self.insert, obj, idx)
def do_remove_child(self, idx):
- undo = []
- try:
- if idx % 2 == 0:
- # a control object
- if self.document is not None:
- undo.append(self.document.AddClearRect(self.bounding_rect))
- if len(self.objects) > 3:
- if idx == 0:
- undo.append(self.remove(1))
- undo.append(self.remove(0))
- elif idx == len(self.objects) - 1:
- undo.append(self.remove(idx))
- undo.append(self.remove(idx - 1))
- else:
- steps = self.objects[idx + 1].Steps() \
- + self.objects[idx - 1].Steps()
- u = (UndoAfter, CreateMultiUndo(self.remove(idx + 1),
- self.remove(idx)),
- self.objects[idx - 1].SetParameters(steps))
- undo.append(u)
- else:
- # remove one of only two control objects -> Remove self
- undo.append(self.parent.Remove(self))
- return CreateListUndo(undo)
- else:
- # XXX implement this case
- raise ValueError, 'BlendGroup: cannot remove non control child'
- except:
- Undo(CreateListUndo(undo))
- raise
+ undo = []
+ try:
+ if idx % 2 == 0:
+ # a control object
+ if self.document is not None:
+ undo.append(self.document.AddClearRect(self.bounding_rect))
+ if len(self.objects) > 3:
+ if idx == 0:
+ undo.append(self.remove(1))
+ undo.append(self.remove(0))
+ elif idx == len(self.objects) - 1:
+ undo.append(self.remove(idx))
+ undo.append(self.remove(idx - 1))
+ else:
+ steps = self.objects[idx + 1].Steps() \
+ + self.objects[idx - 1].Steps()
+ u = (UndoAfter, CreateMultiUndo(self.remove(idx + 1),
+ self.remove(idx)),
+ self.objects[idx - 1].SetParameters(steps))
+ undo.append(u)
+ else:
+ # remove one of only two control objects -> Remove self
+ undo.append(self.parent.Remove(self))
+ return CreateListUndo(undo)
+ else:
+ # XXX implement this case
+ raise ValueError, 'BlendGroup: cannot remove non control child'
+ except:
+ Undo(CreateListUndo(undo))
+ raise
def RemoveSlice(self, min, max):
- raise SketchInternalError('RemoveSlice not allowed for BlendGroup')
+ raise SketchInternalError('RemoveSlice not allowed for BlendGroup')
def RemoveObjects(self, infolist):
- if not infolist:
- return NullUndo
- sliced = selinfo.list_to_tree_sliced(infolist)
- sliced.reverse()
- undo = [self.begin_change_children()]
- try:
- for start, end in sliced:
- if type(end) == IntType:
- # > 1 adjacent children of self. XXX implement this
- raise SketchInternalError('Deletion of multiple objects'
- ' of BlendGroups not yet'
- ' implemented')
- elif type(end) == ListType:
- # remove grandchildren (children of child of self)
- if start % 2 == 0:
- # control object changes. This should result in
- # a recompute() automatically.
- undo.append(self.objects[start].RemoveObjects(end))
- else:
- pass
- else:
- # a single child. If it's one of our control
- # objects, remove self
- undo.append(self.do_remove_child(start))
- undo.append(self.end_change_children())
- return CreateListUndo(undo)
- except:
- Undo(CreateListUndo(undo))
- raise
+ if not infolist:
+ return NullUndo
+ sliced = selinfo.list_to_tree_sliced(infolist)
+ sliced.reverse()
+ undo = [self.begin_change_children()]
+ try:
+ for start, end in sliced:
+ if type(end) == IntType:
+ # > 1 adjacent children of self. XXX implement this
+ raise SketchInternalError('Deletion of multiple objects'
+ ' of BlendGroups not yet'
+ ' implemented')
+ elif type(end) == ListType:
+ # remove grandchildren (children of child of self)
+ if start % 2 == 0:
+ # control object changes. This should result in
+ # a recompute() automatically.
+ undo.append(self.objects[start].RemoveObjects(end))
+ else:
+ pass
+ else:
+ # a single child. If it's one of our control
+ # objects, remove self
+ undo.append(self.do_remove_child(start))
+ undo.append(self.end_change_children())
+ return CreateListUndo(undo)
+ except:
+ Undo(CreateListUndo(undo))
+ raise
def permute_objects(self, permutation):
- # for now, silently ignore this
- return NullUndo
+ # for now, silently ignore this
+ return NullUndo
def DuplicateObjects(self, infolist, offset):
- # XXX: should allow duplication of the control objects by inserting
- # them into the parent.
- return [], NullUndo
+ # XXX: should allow duplication of the control objects by inserting
+ # them into the parent.
+ return [], NullUndo
def ReplaceChild(self, child, object):
- idx = self.objects.index(child)
+ idx = self.objects.index(child)
if idx % 2 == 0:
# the object is a control object
undo = self.ReplaceChild, object, child
@@ -277,16 +277,16 @@
raise SketchError('Cannot replace child')
def SelectSubobject(self, p, rect, device, path = None, *rest):
- idx = self.Hit(p, rect, device) - 1
- obj = self.objects[idx]
- if idx % 2 == 0:
- # a control object
- if path:
- path_idx = path[0]
- path = path[1:]
- obj = obj.SelectSubobject(p, rect, device, path)
- elif path == ():
- obj = obj.SelectSubobject(p, rect, device)
+ idx = self.Hit(p, rect, device) - 1
+ obj = self.objects[idx]
+ if idx % 2 == 0:
+ # a control object
+ if path:
+ path_idx = path[0]
+ path = path[1:]
+ obj = obj.SelectSubobject(p, rect, device, path)
+ elif path == ():
+ obj = obj.SelectSubobject(p, rect, device)
info = selinfo.prepend_idx(idx, obj)
else:
# an interpolation object
@@ -294,110 +294,110 @@
info = self
else:
info = selinfo.prepend_idx(idx, obj)
- return info
+ return info
def ForAllUndo(self, func):
- # XXX: should we just change start and end and recompute?
- self.begin_change_children()
- undo = map(func, self.objects)
- self.end_change_children(ignore_child_changes = 1)
- idx = range(0, len(self.objects), 2)
- undo = map(operator.getitem, [undo] * len(idx), idx)
- return CreateListUndo(undo)
+ # XXX: should we just change start and end and recompute?
+ self.begin_change_children()
+ undo = map(func, self.objects)
+ self.end_change_children(ignore_child_changes = 1)
+ idx = range(0, len(self.objects), 2)
+ undo = map(operator.getitem, [undo] * len(idx), idx)
+ return CreateListUndo(undo)
def begin_change_children(self):
- self.child_has_changed = 0
- return Compound.begin_change_children(self)
+ self.child_has_changed = 0
+ return Compound.begin_change_children(self)
def end_change_children(self, ignore_child_changes = 0):
- if self.child_has_changed and not ignore_child_changes:
- self.document.AddAfterHandler(self.recompute, (), self.depth())
- self.child_has_changed = 0
- return Compound.end_change_children(self)
+ if self.child_has_changed and not ignore_child_changes:
+ self.document.AddAfterHandler(self.recompute, (), self.depth())
+ self.child_has_changed = 0
+ return Compound.end_change_children(self)
def ChildChanged(self, child):
- idx = self.objects.index(child)
- if idx % 2 == 0:
- if self.changing_children:
- self.child_has_changed = 1
- else:
- depth = self.depth(); recompute = self.recompute
- if idx > 0:
- self.document.AddAfterHandler(recompute, (idx - 1,), depth)
- if idx < len(self.objects) - 1:
- self.document.AddAfterHandler(recompute, (idx + 1,), depth)
- else:
- Compound.ChildChanged(self, child)
- self.del_lazy_attrs()
+ idx = self.objects.index(child)
+ if idx % 2 == 0:
+ if self.changing_children:
+ self.child_has_changed = 1
+ else:
+ depth = self.depth(); recompute = self.recompute
+ if idx > 0:
+ self.document.AddAfterHandler(recompute, (idx - 1,), depth)
+ if idx < len(self.objects) - 1:
+ self.document.AddAfterHandler(recompute, (idx + 1,), depth)
+ else:
+ Compound.ChildChanged(self, child)
+ self.del_lazy_attrs()
def recompute(self, idx):
- self.objects[idx].Recompute(self.objects[idx - 1], self.objects[idx+1])
+ self.objects[idx].Recompute(self.objects[idx - 1], self.objects[idx+1])
def RecomputeChild(self, child):
- self.recompute(self.objects.index(child))
+ self.recompute(self.objects.index(child))
def SaveToFile(self, file):
- file.BeginBlendGroup()
- for obj in self.objects:
- obj.SaveToFile(file)
- file.EndBlendGroup()
+ file.BeginBlendGroup()
+ for obj in self.objects:
+ obj.SaveToFile(file)
+ file.EndBlendGroup()
def Info(self):
- return _("BlendGroup with %d control objects") \
- % (len(self.objects) / 2 + 1)
+ return _("BlendGroup with %d control objects") \
+ % (len(self.objects) / 2 + 1)
def CancelEffect(self):
- self.unset_parent()
- idx = range(0, len(self.objects), 2)
- return map(operator.getitem, [self.objects] * len(idx), idx)
+ self.unset_parent()
+ idx = range(0, len(self.objects), 2)
+ return map(operator.getitem, [self.objects] * len(idx), idx)
def SelectControl(self, relative, which):
- idx = self.objects.index(relative)
- if idx % 2 == 1:
- # an interpolation
- if which == SelectStart:
- idx = idx - 1
- else:
- idx = idx + 1
- else:
- # a control
- if which == SelectStart:
- if idx > 0:
- idx = idx - 2
- else:
- if idx < len(self.objects) - 1:
- idx = idx + 2
- self.document.SelectObject(self.objects[idx])
+ idx = self.objects.index(relative)
+ if idx % 2 == 1:
+ # an interpolation
+ if which == SelectStart:
+ idx = idx - 1
+ else:
+ idx = idx + 1
+ else:
+ # a control
+ if which == SelectStart:
+ if idx > 0:
+ idx = idx - 2
+ else:
+ if idx < len(self.objects) - 1:
+ idx = idx + 2
+ self.document.SelectObject(self.objects[idx])
def ExtendBlend(self, start, end, steps):
- idx = self.objects.index(start)
- if idx == 0:
- inter = BlendInterpolation(steps, end, start)
- return CreateMultiUndo(self.insert(inter, 0),
- self.insert(end, 0))
- elif idx == len(self.objects) - 1:
- inter = BlendInterpolation(steps, start, end)
- return CreateMultiUndo(self.insert(inter, None),
- self.insert(end, None))
+ idx = self.objects.index(start)
+ if idx == 0:
+ inter = BlendInterpolation(steps, end, start)
+ return CreateMultiUndo(self.insert(inter, 0),
+ self.insert(end, 0))
+ elif idx == len(self.objects) - 1:
+ inter = BlendInterpolation(steps, start, end)
+ return CreateMultiUndo(self.insert(inter, None),
+ self.insert(end, None))
def Ungroup(self):
- objects = []
- for obj in self.objects:
- if obj.__class__ is BlendInterpolation:
- objects.append(obj.AsGroup())
- else:
- objects.append(obj)
- return objects
+ objects = []
+ for obj in self.objects:
+ if obj.__class__ is BlendInterpolation:
+ objects.append(obj.AsGroup())
+ else:
+ objects.append(obj)
+ return objects
def CreateBlendGroup(start, end, steps):
if isinstance(start.parent, BlendGroup):
- undo = start.parent.ExtendBlend(start, end, steps)
- result = start.parent
+ undo = start.parent.ExtendBlend(start, end, steps)
+ result = start.parent
elif isinstance(end.parent, BlendGroup):
- undo = end.parent.ExtendBlend(end, start, steps)
- result = end.parent
+ undo = end.parent.ExtendBlend(end, start, steps)
+ result = end.parent
else:
- result = BlendGroup(steps, start, end)
- undo = NullUndo
+ result = BlendGroup(steps, start, end)
+ undo = NullUndo
return result, undo
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/clone.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/clone.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/clone.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -38,117 +38,117 @@
original = id(original)
_clone_registry[original]= _clone_registry[original] - 1
if _clone_registry[original] == 0:
- del _clone_registry[original]
+ del _clone_registry[original]
class Clone(Bounded, HierarchyNode):
is_Clone = 1
def __init__(self, original = None, duplicate = None):
- HierarchyNode.__init__(self, duplicate = duplicate)
- if original is not None and original.is_Clone:
- duplicate = original
- original = None
- if duplicate is not None:
- self._original = duplicate._original
- self._center = duplicate._center
- self._offset = duplicate._offset
- else:
- self._original = original
- self._center = self._original.coord_rect.center()
- self._offset = NullPoint
- self.register()
+ HierarchyNode.__init__(self, duplicate = duplicate)
+ if original is not None and original.is_Clone:
+ duplicate = original
+ original = None
+ if duplicate is not None:
+ self._original = duplicate._original
+ self._center = duplicate._center
+ self._offset = duplicate._offset
+ else:
+ self._original = original
+ self._center = self._original.coord_rect.center()
+ self._offset = NullPoint
+ self.register()
def register(self):
- _register_clone(self._original)
- self._original.Subscribe(CHANGED, self.orig_changed)
+ _register_clone(self._original)
+ self._original.Subscribe(CHANGED, self.orig_changed)
def unregister(self):
- self._original.Unsubscribe(CHANGED, self.orig_changed)
- _unregister_clone(self._original)
+ self._original.Unsubscribe(CHANGED, self.orig_changed)
+ _unregister_clone(self._original)
def __getattr__(self, attr):
- if self._lazy_attrs.has_key(attr):
- return Bounded.__getattr__(self, attr)
- #print 'Clone.__getattr__: from original:', attr
- #if attr in ('__nonzero__', 'document'):
- # print_stack()
- return getattr(self._original, attr)
+ if self._lazy_attrs.has_key(attr):
+ return Bounded.__getattr__(self, attr)
+ #print 'Clone.__getattr__: from original:', attr
+ #if attr in ('__nonzero__', 'document'):
+ # print_stack()
+ return getattr(self._original, attr)
def update_rects(self):
- off = self._offset
- self.bounding_rect = self._original.bounding_rect.translated(off)
- self.coord_rect = self._original.coord_rect.translated(off)
+ off = self._offset
+ self.bounding_rect = self._original.bounding_rect.translated(off)
+ self.coord_rect = self._original.coord_rect.translated(off)
def Translate(self, offset):
- self._offset = self._offset + offset
- self.del_lazy_attrs()
- return self.Translate, -offset
+ self._offset = self._offset + offset
+ self.del_lazy_attrs()
+ return self.Translate, -offset
def _set_offset(self, offset):
- undo = (self._set_offset, self._offset)
- self._offset = offset
- self.del_lazy_attrs()
- return undo
+ undo = (self._set_offset, self._offset)
+ self._offset = offset
+ self.del_lazy_attrs()
+ return undo
def offset_center(self, offset):
- undo = (self.offset_center, -offset)
- self._center = self._center + offset
- return undo
+ undo = (self.offset_center, -offset)
+ self._center = self._center + offset
+ return undo
def Transform(self, trafo):
- center = self._center + self._offset
- offset = trafo(center) - center
- if self.document is not None:
- self.document.AddAfterHandler(_transform,
- (self._original, trafo.matrix()), -1)
- return self.offset_center(offset)
+ center = self._center + self._offset
+ offset = trafo(center) - center
+ if self.document is not None:
+ self.document.AddAfterHandler(_transform,
+ (self._original, trafo.matrix()), -1)
+ return self.offset_center(offset)
def orig_changed(self, *args):
- if self.document is not None:
- self.document.AddClearRect(self.bounding_rect)
- self.del_lazy_attrs()
- center = self._center
- self._center = self._original.coord_rect.center()
- self._offset = self._offset + center - self._center
- if self.document is not None:
- self.document.AddClearRect(self.bounding_rect)
+ if self.document is not None:
+ self.document.AddClearRect(self.bounding_rect)
+ self.del_lazy_attrs()
+ center = self._center
+ self._center = self._original.coord_rect.center()
+ self._offset = self._offset + center - self._center
+ if self.document is not None:
+ self.document.AddClearRect(self.bounding_rect)
def DrawShape(self, device, rect = None):
- device.PushTrafo()
- try:
- device.Translate(self._offset)
- self._original.DrawShape(device, rect)
- finally:
- device.PopTrafo()
+ device.PushTrafo()
+ try:
+ device.Translate(self._offset)
+ self._original.DrawShape(device, rect)
+ finally:
+ device.PopTrafo()
def Hit(self, p, rect, device):
- off = -self._offset
- return self._original.Hit(p + off, rect.translated(off), device)
+ off = -self._offset
+ return self._original.Hit(p + off, rect.translated(off), device)
def Info(self):
- return 'Clone of ' + self._original.Info()
+ return 'Clone of ' + self._original.Info()
# overwrite Selectable methods
def SelectSubobject(self, p, rect, device, path = None, *rest):
- return self
+ return self
def GetObjectHandle(self, multiple):
- trafo = Translation(self._offset)
- handle = self._original.GetObjectHandle(multiple)
- if type(handle) == PointType:
- return trafo(handle)
- else:
- return map(trafo, handle)
+ trafo = Translation(self._offset)
+ handle = self._original.GetObjectHandle(multiple)
+ if type(handle) == PointType:
+ return trafo(handle)
+ else:
+ return map(trafo, handle)
# overwrite Bounded methods
def LayoutPoint(self):
- return self._original.LayoutPoint() + self._offset
+ return self._original.LayoutPoint() + self._offset
def GetSnapPoints(self):
- return map(Translation(self._offset), self._original.GetSnapPoints())
+ return map(Translation(self._offset), self._original.GetSnapPoints())
def _transform(original, matrix):
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/color.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/color.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/color.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -35,7 +35,7 @@
# only understands the old x specification with two hex digits per
# component. e.g. `#00FF00'
if s[0] != '#':
- raise ValueError("Color %s dosn't start with a '#'" % s)
+ raise ValueError("Color %s dosn't start with a '#'" % s)
r = atoi(s[1:3], 16) / 255.0
g = atoi(s[3:5], 16) / 255.0
b = atoi(s[5:7], 16) / 255.0
@@ -78,21 +78,21 @@
colors = []
color_idx = []
failed = 0
-
+
shades_r, shades_g, shades_b, shades_gray = config.preferences.color_cube
max_r = shades_r - 1
max_g = shades_g - 1
max_b = shades_b - 1
for red in range(shades_r):
- red = float_to_x(red / float(max_r))
- for green in range(shades_g):
- green = float_to_x(green / float(max_g))
- for blue in range(shades_b):
- blue = float_to_x(blue / float(max_b))
+ red = float_to_x(red / float(max_r))
+ for green in range(shades_g):
+ green = float_to_x(green / float(max_g))
+ for blue in range(shades_b):
+ blue = float_to_x(blue / float(max_b))
colors.append((red, green, blue))
for i in range(shades_gray):
- value = int((i / float(shades_gray - 1)) * max)
+ value = int((i / float(shades_gray - 1)) * max)
colors.append((value, value, value))
for red, green, blue in colors:
@@ -104,9 +104,9 @@
failed = 1
if failed:
- warn(USER,
- _("I can't alloc all needed colors. I'll use a private colormap"))
- warn(INTERNAL, "allocated colors without private colormap: %d",
+ warn(USER,
+ _("I can't alloc all needed colors. I'll use a private colormap"))
+ warn(INTERNAL, "allocated colors without private colormap: %d",
len(filter(lambda i: i is None, color_idx)))
if config.preferences.reduce_color_flashing:
#print 'reduce color flashing'
@@ -121,7 +121,7 @@
color_idx = []
for red, green, blue in colors:
color_idx.append(cmap.AllocColor(red, green, blue)[0])
-
+
return cmap, color_idx
_init_from_widget_done = 0
@@ -129,23 +129,23 @@
def InitFromWidget(tkwin, root = None):
global _init_from_widget_done, skvisual
if _init_from_widget_done:
- return
+ return
if root:
- visual = root.winfo_visual()
- if visual == 'truecolor':
- skvisual = XVisual(tkwin.c_display(), tkwin.c_visual())
- #skvisual.set_gamma(config.preferences.screen_gamma)
- alloc_function = skvisual.get_pixel
- if visual == 'pseudocolor' and root.winfo_depth() == 8:
- global global_colormap
- cmap = tkwin.colormap()
- newcmap, idxs = fill_colormap(cmap)
- if newcmap != cmap:
- cmap = newcmap
- tkwin.SetColormap(cmap)
+ visual = root.winfo_visual()
+ if visual == 'truecolor':
+ skvisual = XVisual(tkwin.c_display(), tkwin.c_visual())
+ #skvisual.set_gamma(config.preferences.screen_gamma)
+ alloc_function = skvisual.get_pixel
+ if visual == 'pseudocolor' and root.winfo_depth() == 8:
+ global global_colormap
+ cmap = tkwin.colormap()
+ newcmap, idxs = fill_colormap(cmap)
+ if newcmap != cmap:
+ cmap = newcmap
+ tkwin.SetColormap(cmap)
shades_r, shades_g, shades_b, shades_gray \
- = config.preferences.color_cube
- skvisual = XVisual(tkwin.c_display(), tkwin.c_visual(),
- (shades_r, shades_g, shades_b, shades_gray, idxs))
- global_colormap = cmap
+ = config.preferences.color_cube
+ skvisual = XVisual(tkwin.c_display(), tkwin.c_visual(),
+ (shades_r, shades_g, shades_b, shades_gray, idxs))
+ global_colormap = cmap
_init_from_widget_done = 1
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/compound.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/compound.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/compound.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -47,80 +47,80 @@
allow_traversal = 0
def __init__(self, objects = None, duplicate = None):
- GraphicsObject.__init__(self, duplicate = duplicate)
- if duplicate is not None:
- objects = []
- for obj in duplicate.objects:
- objects.append(obj.Duplicate())
- self.objects = objects
- elif objects:
- self.objects = objects
- else:
- self.objects = []
- self.changing_children = 0
- self.set_parent()
+ GraphicsObject.__init__(self, duplicate = duplicate)
+ if duplicate is not None:
+ objects = []
+ for obj in duplicate.objects:
+ objects.append(obj.Duplicate())
+ self.objects = objects
+ elif objects:
+ self.objects = objects
+ else:
+ self.objects = []
+ self.changing_children = 0
+ self.set_parent()
def Destroy(self):
- self.destroy_objects()
- GraphicsObject.Destroy(self)
+ self.destroy_objects()
+ GraphicsObject.Destroy(self)
def destroy_objects(self):
- for obj in self.objects:
- obj.Destroy()
- self.objects = []
+ for obj in self.objects:
+ obj.Destroy()
+ self.objects = []
def SetParent(self, parent):
- if parent is self.parent:
- return
- GraphicsObject.SetParent(self, parent)
- if parent is not None:
- self.set_parent()
- else:
- self.unset_parent()
+ if parent is self.parent:
+ return
+ GraphicsObject.SetParent(self, parent)
+ if parent is not None:
+ self.set_parent()
+ else:
+ self.unset_parent()
def set_parent(self):
- for child in self.objects:
- child.SetParent(self)
+ for child in self.objects:
+ child.SetParent(self)
def unset_parent(self):
- for child in self.objects:
- child.SetParent(None)
+ for child in self.objects:
+ child.SetParent(None)
def SelectionInfo(self, child = None):
- info = GraphicsObject.SelectionInfo(self)
- if info and child is not None:
- path = info[0]
- return (path + (_sketch.IdIndex(self.objects, child),),
+ info = GraphicsObject.SelectionInfo(self)
+ if info and child is not None:
+ path = info[0]
+ return (path + (_sketch.IdIndex(self.objects, child),),
child)
- return info
+ return info
def ChildChanged(self, child):
- self.del_lazy_attrs()
- if self.changing_children:
- return
- self.issue_changed()
+ self.del_lazy_attrs()
+ if self.changing_children:
+ return
+ self.issue_changed()
def SetDocument(self, doc):
- for obj in self.objects:
- obj.SetDocument(doc)
- GraphicsObject.SetDocument(self, doc)
- self.set_parent()
+ for obj in self.objects:
+ obj.SetDocument(doc)
+ GraphicsObject.SetDocument(self, doc)
+ self.set_parent()
def disconnect_objects(self):
- for obj in self.objects:
- obj.Disconnect()
+ for obj in self.objects:
+ obj.Disconnect()
def Disconnect(self):
- self.disconnect_objects()
- self.unset_parent()
+ self.disconnect_objects()
+ self.unset_parent()
def connect_objects(self):
- for obj in self.objects:
- obj.Connect()
+ for obj in self.objects:
+ obj.Connect()
def Connect(self):
- self.set_parent()
- self.connect_objects()
+ self.set_parent()
+ self.connect_objects()
def set_objects(self, new_objs):
if self.document is not None:
@@ -138,59 +138,59 @@
self.document.AddClearRect(self.bounding_rect)
def UntieFromDocument(self):
- for obj in self.objects:
- obj.UntieFromDocument()
+ for obj in self.objects:
+ obj.UntieFromDocument()
def TieToDocument(self):
- for obj in self.objects:
- obj.TieToDocument()
+ for obj in self.objects:
+ obj.TieToDocument()
def load_AppendObject(self, object):
- self.objects.append(object)
+ self.objects.append(object)
def load_Done(self):
- pass
+ pass
def __getitem__(self, idx):
- if type(idx) == IntType:
- return self.objects[idx]
- elif type(idx) == TupleType:
- if len(idx) > 1:
- return self.objects[idx[0]][idx[1:]]
- elif len(idx) == 1:
- return self.objects[idx[0]]
- raise ValueError, 'invalid index %s' % `idx`
+ if type(idx) == IntType:
+ return self.objects[idx]
+ elif type(idx) == TupleType:
+ if len(idx) > 1:
+ return self.objects[idx[0]][idx[1:]]
+ elif len(idx) == 1:
+ return self.objects[idx[0]]
+ raise ValueError, 'invalid index %s' % `idx`
def GetObjects(self):
- # XXX should this return a copy of self.objects?
- return self.objects
+ # XXX should this return a copy of self.objects?
+ return self.objects
def del_lazy_attrs(self):
- Bounded.del_lazy_attrs(self)
- return (self.del_lazy_attrs,)
+ Bounded.del_lazy_attrs(self)
+ return (self.del_lazy_attrs,)
def update_rects(self):
- # XXX: should we raise an exception here if self.objects is empty?
- boxes = map(lambda o: o.coord_rect, self.objects)
- if boxes:
- self.coord_rect = reduce(UnionRects, boxes, boxes[0])
- else:
- self.coord_rect = EmptyRect
+ # XXX: should we raise an exception here if self.objects is empty?
+ boxes = map(lambda o: o.coord_rect, self.objects)
+ if boxes:
+ self.coord_rect = reduce(UnionRects, boxes, boxes[0])
+ else:
+ self.coord_rect = EmptyRect
- boxes = map(lambda o: o.bounding_rect, self.objects)
- if boxes:
- self.bounding_rect = reduce(UnionRects, boxes, boxes[0])
- else:
- self.bounding_rect = EmptyRect
+ boxes = map(lambda o: o.bounding_rect, self.objects)
+ if boxes:
+ self.bounding_rect = reduce(UnionRects, boxes, boxes[0])
+ else:
+ self.bounding_rect = EmptyRect
def SelectSubobject(self, p, rect, device, path = None, *rest):
- return self
+ return self
def Insert(self, obj, at):
- raise SketchError('Cannot insert in compound')
+ raise SketchError('Cannot insert in compound')
def Remove(self, *args, **kw):
- raise SketchError('Cannot remove from compound')
+ raise SketchError('Cannot remove from compound')
RemoveSlice = Remove
RemoveObjects = Remove
@@ -198,149 +198,149 @@
ReplaceChild = Remove
def MoveObjectsToTop(self, infolist):
- raise SketchError('Cannot rearrange objects in compound')
+ raise SketchError('Cannot rearrange objects in compound')
MoveObjectsToBottom = MoveObjectsToTop
MoveObjectsDown = MoveObjectsToTop
MoveObjectsUp = MoveObjectsToTop
def move_objects_to_top(self, infolist, to_bottom = 0):
- return infolist, NullUndo
+ return infolist, NullUndo
def DuplicateObjects(self, infolist, offset):
- raise SketchError('Cannot duplicate objects in compound')
+ raise SketchError('Cannot duplicate objects in compound')
def ForAll(self, func):
- self.changing_children = 1
- try:
- return map(func, self.objects)
- finally:
- self.changing_children = 0
+ self.changing_children = 1
+ try:
+ return map(func, self.objects)
+ finally:
+ self.changing_children = 0
def WalkHierarchy(self, func):
- for obj in self.objects:
- if obj.is_Compound:
- obj.WalkHierarchy(func)
- else:
- func(obj)
+ for obj in self.objects:
+ if obj.is_Compound:
+ obj.WalkHierarchy(func)
+ else:
+ func(obj)
def begin_change_children(self):
- self.changing_children = self.changing_children + 1
- return (self.end_change_children,)
+ self.changing_children = self.changing_children + 1
+ return (self.end_change_children,)
def end_change_children(self):
- self.changing_children = self.changing_children - 1
- if not self.changing_children:
- self._changed()
- return (self.begin_change_children,)
+ self.changing_children = self.changing_children - 1
+ if not self.changing_children:
+ self._changed()
+ return (self.begin_change_children,)
def ForAllUndo(self, func):
- if self.objects:
- undo = [self.begin_change_children()]
- undo = undo + map(func, self.objects)
- undo.append(self.end_change_children())
- return CreateListUndo(undo)
- else:
- return NullUndo
+ if self.objects:
+ undo = [self.begin_change_children()]
+ undo = undo + map(func, self.objects)
+ undo.append(self.end_change_children())
+ return CreateListUndo(undo)
+ else:
+ return NullUndo
def FilterAll(self, func):
- return filter(func, self.GetObjects())
+ return filter(func, self.GetObjects())
def NumObjects(self):
- return len(self.objects)
+ return len(self.objects)
def Info(self):
- return _("Compound with %d objects") % len(self.objects)
+ return _("Compound with %d objects") % len(self.objects)
def AddStyle(self, style):
- undo = self.ForAllUndo(lambda o, style = style: o.AddStyle(style))
- return undo
+ undo = self.ForAllUndo(lambda o, style = style: o.AddStyle(style))
+ return undo
def Properties(self):
- return EmptyProperties
+ return EmptyProperties
def SetProperties(self, **kw):
- self.del_lazy_attrs()
- func = lambda o, kw = kw: apply(o.SetProperties, (), kw)
- undo = self.ForAllUndo(func)
- return undo
+ self.del_lazy_attrs()
+ func = lambda o, kw = kw: apply(o.SetProperties, (), kw)
+ undo = self.ForAllUndo(func)
+ return undo
def Hit(self, p, rect, device):
- test = rect.overlaps
- objects = self.objects
- for obj_idx in range(len(objects) - 1, -1, -1):
- obj = objects[obj_idx]
- if test(obj.bounding_rect):
- if obj.Hit(p, rect, device):
- return obj_idx + 1
- return 0
+ test = rect.overlaps
+ objects = self.objects
+ for obj_idx in range(len(objects) - 1, -1, -1):
+ obj = objects[obj_idx]
+ if test(obj.bounding_rect):
+ if obj.Hit(p, rect, device):
+ return obj_idx + 1
+ return 0
def Transform(self, trafo):
- self.del_lazy_attrs()
- undo = self.ForAllUndo(lambda o, t = trafo: o.Transform(t))
- return undo
+ self.del_lazy_attrs()
+ undo = self.ForAllUndo(lambda o, t = trafo: o.Transform(t))
+ return undo
def Translate(self, offset):
- undo = self.ForAllUndo(lambda o, p = offset: o.Translate(p))
- return undo
+ undo = self.ForAllUndo(lambda o, p = offset: o.Translate(p))
+ return undo
def DrawShape(self, device, rect = None):
- if rect:
- test = rect.overlaps
- for o in self.objects:
- if test(o.bounding_rect):
- o.DrawShape(device, rect)
- else:
- for obj in self.objects:
- obj.DrawShape(device)
+ if rect:
+ test = rect.overlaps
+ for o in self.objects:
+ if test(o.bounding_rect):
+ o.DrawShape(device, rect)
+ else:
+ for obj in self.objects:
+ obj.DrawShape(device)
def PickObject(self, point, rect, device):
- objects = self.objects[:]
- objects.reverse()
- test = rect.overlaps
- for obj in objects:
- if test(obj.bounding_rect):
- if obj.is_Compound:
- result = obj.PickObject(point, rect, device)
- if result:
- break
- elif obj.Hit(point, rect, device):
- result = obj
- break
- else:
- result = None
+ objects = self.objects[:]
+ objects.reverse()
+ test = rect.overlaps
+ for obj in objects:
+ if test(obj.bounding_rect):
+ if obj.is_Compound:
+ result = obj.PickObject(point, rect, device)
+ if result:
+ break
+ elif obj.Hit(point, rect, device):
+ result = obj
+ break
+ else:
+ result = None
- return result
+ return result
def Blend(self, other, frac1, frac2):
- try:
- objs = self.objects
- oobjs = other.objects
- blended = []
- for i in range(min(len(objs), len(oobjs))):
- blended.append(Blend(objs[i], oobjs[i], frac1, frac2))
- return Compound(blended)
- except:
- raise MismatchError
+ try:
+ objs = self.objects
+ oobjs = other.objects
+ blended = []
+ for i in range(min(len(objs), len(oobjs))):
+ blended.append(Blend(objs[i], oobjs[i], frac1, frac2))
+ return Compound(blended)
+ except:
+ raise MismatchError
def GetObjectHandle(self, multiple):
- return self.ForAll(lambda o: o.GetObjectHandle(1))
+ return self.ForAll(lambda o: o.GetObjectHandle(1))
def SelectFirstChild(self):
- if self.allow_traversal and self.objects:
- return self.objects[0]
+ if self.allow_traversal and self.objects:
+ return self.objects[0]
def SelectLastChild(self):
- if self.allow_traversal and self.objects:
- return self.objects[-1]
+ if self.allow_traversal and self.objects:
+ return self.objects[-1]
def SelectNextChild(self, child, idx):
- if self.allow_traversal and len(self.objects) > idx + 1:
- return self.objects[idx + 1]
+ if self.allow_traversal and len(self.objects) > idx + 1:
+ return self.objects[idx + 1]
def SelectPreviousChild(self, child, idx):
- if self.allow_traversal and len(self.objects) > idx - 1 and idx > 0:
- return self.objects[idx - 1]
+ if self.allow_traversal and len(self.objects) > idx - 1 and idx > 0:
+ return self.objects[idx - 1]
class EditableCompound(Compound):
@@ -348,361 +348,361 @@
allow_traversal = 1
def SelectSubobject(self, p, rect, device, path = None, *rest):
- test = rect.overlaps
- if path is None:
- return self
- if path:
- path_idx = path[0]
- path = path[1:]
- else:
- path_idx = -1
- path = None
- objects = self.objects
- for obj_idx in range(len(objects) - 1, -1, -1):
- obj = objects[obj_idx]
- if test(obj.bounding_rect) and obj.Hit(p, rect, device):
- if obj_idx == path_idx:
- result = obj.SelectSubobject(p, rect, device, path)
- else:
- result = obj.SelectSubobject(p, rect, device)
- return prepend_idx(obj_idx, result)
- return None
+ test = rect.overlaps
+ if path is None:
+ return self
+ if path:
+ path_idx = path[0]
+ path = path[1:]
+ else:
+ path_idx = -1
+ path = None
+ objects = self.objects
+ for obj_idx in range(len(objects) - 1, -1, -1):
+ obj = objects[obj_idx]
+ if test(obj.bounding_rect) and obj.Hit(p, rect, device):
+ if obj_idx == path_idx:
+ result = obj.SelectSubobject(p, rect, device, path)
+ else:
+ result = obj.SelectSubobject(p, rect, device)
+ return prepend_idx(obj_idx, result)
+ return None
def Insert(self, obj, at):
- # Insert OBJ into the object hierarchy at the position described
- # by AT. AT should be either an integer or a tuple of integers.
- # OBJ can be a graphics object of a list of such objects.
- #
- # If AT is a tuple of 2 or more ints, self's child at AT[0] has
- # to be a compound object and its Insert method is called with
- # OBJ and AT[1:] as arguments.
- #
- # If AT is an int or a singleton of one int, insert OBJ at that
- # position in self's children. If OBJ is a graphics object, this
- # works just like a list objects insert method (insert(AT,
- # OBJ)). If its a list of graphics objects this method
- # effectively assigns that list to the slice AT:AT.
- #
- # As a side effect, this method calls the following methods of
- # the inserted objects:
- #
- # obj.SetDocument(self.document)
- # obj.SetParent(self)
- # obj.Connect()
- #
- # Return a tuple (SELINFO, UNDO), where SELINFO is selection
- # info for the inserted objects at their new positions, and UNDO
- # is the appropriate undo info.
- #
- # If self is modified directly, issue a CHANGED message.
- undo_info = None
- try:
- if type(at) == TupleType and at:
- if len(at) == 1:
- at = at[0]
- else:
- child = at[0]
- at = at[1:]
- sel_info, undo_info = self.objects[child].Insert(obj, at)
- sel_info = prepend_idx(child, sel_info)
- return (sel_info, undo_info)
- if type(at) != IntType or at > len(self.objects):
- at = len(self.objects)
- if type(obj) == InstanceType:
- self.objects.insert(at, obj)
- obj.SetDocument(self.document)
- obj.SetParent(self)
- obj.Connect()
- sel_info = build_info(at, obj)
- undo_info = (self.Remove, obj, at)
- else:
- self.objects[at:at] = obj
- for o in obj:
- # XXX: should we have undo info for these:
- o.SetDocument(self.document)
- o.SetParent(self)
- o.Connect()
- sel_info = select_range(at, obj)
- undo_info = (self.RemoveSlice, at, at + len(obj))
- self._changed()
- return (sel_info, undo_info)
- except:
- if undo_info is not None:
- Undo(undo_info)
- raise
+ # Insert OBJ into the object hierarchy at the position described
+ # by AT. AT should be either an integer or a tuple of integers.
+ # OBJ can be a graphics object of a list of such objects.
+ #
+ # If AT is a tuple of 2 or more ints, self's child at AT[0] has
+ # to be a compound object and its Insert method is called with
+ # OBJ and AT[1:] as arguments.
+ #
+ # If AT is an int or a singleton of one int, insert OBJ at that
+ # position in self's children. If OBJ is a graphics object, this
+ # works just like a list objects insert method (insert(AT,
+ # OBJ)). If its a list of graphics objects this method
+ # effectively assigns that list to the slice AT:AT.
+ #
+ # As a side effect, this method calls the following methods of
+ # the inserted objects:
+ #
+ # obj.SetDocument(self.document)
+ # obj.SetParent(self)
+ # obj.Connect()
+ #
+ # Return a tuple (SELINFO, UNDO), where SELINFO is selection
+ # info for the inserted objects at their new positions, and UNDO
+ # is the appropriate undo info.
+ #
+ # If self is modified directly, issue a CHANGED message.
+ undo_info = None
+ try:
+ if type(at) == TupleType and at:
+ if len(at) == 1:
+ at = at[0]
+ else:
+ child = at[0]
+ at = at[1:]
+ sel_info, undo_info = self.objects[child].Insert(obj, at)
+ sel_info = prepend_idx(child, sel_info)
+ return (sel_info, undo_info)
+ if type(at) != IntType or at > len(self.objects):
+ at = len(self.objects)
+ if type(obj) == InstanceType:
+ self.objects.insert(at, obj)
+ obj.SetDocument(self.document)
+ obj.SetParent(self)
+ obj.Connect()
+ sel_info = build_info(at, obj)
+ undo_info = (self.Remove, obj, at)
+ else:
+ self.objects[at:at] = obj
+ for o in obj:
+ # XXX: should we have undo info for these:
+ o.SetDocument(self.document)
+ o.SetParent(self)
+ o.Connect()
+ sel_info = select_range(at, obj)
+ undo_info = (self.RemoveSlice, at, at + len(obj))
+ self._changed()
+ return (sel_info, undo_info)
+ except:
+ if undo_info is not None:
+ Undo(undo_info)
+ raise
def _insert_with_undo(self, obj, at):
- # The same as the Insert method but return only the undo info.
- return self.Insert(obj, at)[1]
+ # The same as the Insert method but return only the undo info.
+ return self.Insert(obj, at)[1]
def do_remove_child(self, idx):
- obj = self.objects[idx]
- del self.objects[idx]
- obj.Disconnect()
- obj.SetParent(None)
- self._changed()
- return (self._insert_with_undo, obj, idx)
+ obj = self.objects[idx]
+ del self.objects[idx]
+ obj.Disconnect()
+ obj.SetParent(None)
+ self._changed()
+ return (self._insert_with_undo, obj, idx)
def Remove(self, obj, idx = None):
- if type(idx) == TupleType:
- if len(idx) == 1:
- idx = idx[0]
- else:
- return self.objects[idx[0]].Remove(obj, idx[1:])
- if idx is None:
- idx = self.objects.index(obj)
- elif self.objects[idx] is not obj:
- raise ValueError, 'Compound.Remove(): invalid index'
- return self.do_remove_child(idx)
+ if type(idx) == TupleType:
+ if len(idx) == 1:
+ idx = idx[0]
+ else:
+ return self.objects[idx[0]].Remove(obj, idx[1:])
+ if idx is None:
+ idx = self.objects.index(obj)
+ elif self.objects[idx] is not obj:
+ raise ValueError, 'Compound.Remove(): invalid index'
+ return self.do_remove_child(idx)
def RemoveSlice(self, min, max):
- objs = self.objects[min:max]
- self.objects[min:max] = []
- for obj in objs:
- obj.Disconnect()
- obj.SetParent(None)
- self._changed()
- return (self._insert_with_undo, objs, min)
+ objs = self.objects[min:max]
+ self.objects[min:max] = []
+ for obj in objs:
+ obj.Disconnect()
+ obj.SetParent(None)
+ self._changed()
+ return (self._insert_with_undo, objs, min)
def RemoveObjects(self, infolist):
- if not infolist:
- return NullUndo
- sliced = list_to_tree_sliced(infolist)
- sliced.reverse() # important!
- undo = [self.begin_change_children()]
- try:
- for start, end in sliced:
- if type(end) == IntType:
- undo.append(self.RemoveSlice(start, end))
- elif type(end) == ListType:
- undo.append(self.objects[start].RemoveObjects(end))
- else:
- undo.append(self.Remove(end, start))
- undo.append(self.end_change_children())
- return CreateListUndo(undo)
- except:
- Undo(CreateListUndo(undo))
- raise
+ if not infolist:
+ return NullUndo
+ sliced = list_to_tree_sliced(infolist)
+ sliced.reverse() # important!
+ undo = [self.begin_change_children()]
+ try:
+ for start, end in sliced:
+ if type(end) == IntType:
+ undo.append(self.RemoveSlice(start, end))
+ elif type(end) == ListType:
+ undo.append(self.objects[start].RemoveObjects(end))
+ else:
+ undo.append(self.Remove(end, start))
+ undo.append(self.end_change_children())
+ return CreateListUndo(undo)
+ except:
+ Undo(CreateListUndo(undo))
+ raise
def ReplaceChild(self, child, object):
- # replace self's child child with object. Return undo info
- idx = self.objects.index(child)
- self.objects[idx] = object
- object.SetParent(self)
- object.SetDocument(self.document)
- child.SetParent(None)
- self._changed()
- return (self.ReplaceChild, object, child)
+ # replace self's child child with object. Return undo info
+ idx = self.objects.index(child)
+ self.objects[idx] = object
+ object.SetParent(self)
+ object.SetDocument(self.document)
+ child.SetParent(None)
+ self._changed()
+ return (self.ReplaceChild, object, child)
def permute_objects(self, permutation):
- # permutation must be a list of ints and len(permutation) must be
- # equal to len(self.objects). permutation[i] is the index of the
- # object that is moved to index i in the result.
- objects = self.objects
- length = len(objects)
- identity = range(length)
- if permutation == identity:
- return NullUndo
- if len(objects) != len(permutation):
- raise ValueError, 'len(permutation) != len(self.objects)'
+ # permutation must be a list of ints and len(permutation) must be
+ # equal to len(self.objects). permutation[i] is the index of the
+ # object that is moved to index i in the result.
+ objects = self.objects
+ length = len(objects)
+ identity = range(length)
+ if permutation == identity:
+ return NullUndo
+ if len(objects) != len(permutation):
+ raise ValueError, 'len(permutation) != len(self.objects)'
- result = map(operator.getitem, [objects] * length, permutation)
- inverse = [0] * length
- map(operator.setitem, [inverse] * length, permutation, identity)
- self.objects = result
- self._changed()
- return (self.permute_objects, inverse)
+ result = map(operator.getitem, [objects] * length, permutation)
+ inverse = [0] * length
+ map(operator.setitem, [inverse] * length, permutation, identity)
+ self.objects = result
+ self._changed()
+ return (self.permute_objects, inverse)
def move_objects_to_top(self, infolist, to_bottom = 0):
- # Implement the public methods MoveToTop (if to_bottom is false)
- # and MoveToBottom (if to_bottom is true).
- sliced = list_to_tree_sliced(infolist)
- sliced.reverse()
+ # Implement the public methods MoveToTop (if to_bottom is false)
+ # and MoveToBottom (if to_bottom is true).
+ sliced = list_to_tree_sliced(infolist)
+ sliced.reverse()
- undo = [self.begin_change_children()]
- selection = []
- idxs = []
- permutation = range(len(self.objects))
- try:
- for start, end in sliced:
- if type(end) == IntType:
- # a contiguous range of self's children (start:end)
- idxs[:0] = permutation[start:end]
- del permutation[start:end]
- elif type(end) == ListType:
- # children of self.objects[start]
- child = self.objects[start]
- sel, undo_info = child.move_objects_to_top(end, to_bottom)
- if undo_info is not NullUndo:
- undo.append(undo_info)
- selection = selection + prepend_idx(start, sel)
- else:
- # a single object (self.object[start])
- idxs.insert(0, start)
- del permutation[start]
+ undo = [self.begin_change_children()]
+ selection = []
+ idxs = []
+ permutation = range(len(self.objects))
+ try:
+ for start, end in sliced:
+ if type(end) == IntType:
+ # a contiguous range of self's children (start:end)
+ idxs[:0] = permutation[start:end]
+ del permutation[start:end]
+ elif type(end) == ListType:
+ # children of self.objects[start]
+ child = self.objects[start]
+ sel, undo_info = child.move_objects_to_top(end, to_bottom)
+ if undo_info is not NullUndo:
+ undo.append(undo_info)
+ selection = selection + prepend_idx(start, sel)
+ else:
+ # a single object (self.object[start])
+ idxs.insert(0, start)
+ del permutation[start]
- if idxs:
- # direct children of self are involved: apply the
- # permutation
- if to_bottom:
- permutation = idxs + permutation
- else:
- permutation = permutation + idxs
- undo_info = self.permute_objects(permutation)
- if undo_info is not NullUndo:
- undo.append(undo_info)
- # finished:
- undo.append(self.end_change_children())
- if len(undo) <= 2:
- # We haven't really done anything (undo has length 2),
- # so we just pass the selection info back unchanged
- selection = infolist
- undo = NullUndo
- else:
- # We have done something, so figure out the new
- # selection info
- undo = CreateListUndo(undo)
+ if idxs:
+ # direct children of self are involved: apply the
+ # permutation
+ if to_bottom:
+ permutation = idxs + permutation
+ else:
+ permutation = permutation + idxs
+ undo_info = self.permute_objects(permutation)
+ if undo_info is not NullUndo:
+ undo.append(undo_info)
+ # finished:
+ undo.append(self.end_change_children())
+ if len(undo) <= 2:
+ # We haven't really done anything (undo has length 2),
+ # so we just pass the selection info back unchanged
+ selection = infolist
+ undo = NullUndo
+ else:
+ # We have done something, so figure out the new
+ # selection info
+ undo = CreateListUndo(undo)
- if to_bottom:
- selection = selection \
- + select_range(0, self.objects[:len(idxs)])
- else:
- min = len(self.objects) - len(idxs)
- selection = selection \
- + select_range(min, self.objects[min:])
- return (selection, undo)
- except:
- # Ooops, something's gone wrong. Undo everything we've done
- # so far... (hmm, this currently fails to undo everything if
- # undo.append(undo_info) fails... (the undo_info involved
- # would be lost))
- Undo(CreateListUndo(undo))
- raise
+ if to_bottom:
+ selection = selection \
+ + select_range(0, self.objects[:len(idxs)])
+ else:
+ min = len(self.objects) - len(idxs)
+ selection = selection \
+ + select_range(min, self.objects[min:])
+ return (selection, undo)
+ except:
+ # Ooops, something's gone wrong. Undo everything we've done
+ # so far... (hmm, this currently fails to undo everything if
+ # undo.append(undo_info) fails... (the undo_info involved
+ # would be lost))
+ Undo(CreateListUndo(undo))
+ raise
def MoveObjectsToTop(self, infolist):
- return self.move_objects_to_top(infolist)
+ return self.move_objects_to_top(infolist)
def MoveObjectsToBottom(self, infolist):
- return self.move_objects_to_top(infolist, to_bottom = 1)
+ return self.move_objects_to_top(infolist, to_bottom = 1)
def MoveObjectsDown(self, infolist):
- sliced = list_to_tree_sliced(infolist)
- undo = [self.begin_change_children()]
- selection = []
- permutation = range(len(self.objects))
- objects = self.objects
- try:
- for start, end in sliced:
- if type(end) == IntType:
- if start > 0:
- temp = permutation[start:end]
- del permutation[start:end]
- permutation[start - 1:start - 1] = temp
- selection = selection +select_range(start - 1,
- objects[start:end])
- else:
- selection = selection +select_range(start,
- objects[start:end])
+ sliced = list_to_tree_sliced(infolist)
+ undo = [self.begin_change_children()]
+ selection = []
+ permutation = range(len(self.objects))
+ objects = self.objects
+ try:
+ for start, end in sliced:
+ if type(end) == IntType:
+ if start > 0:
+ temp = permutation[start:end]
+ del permutation[start:end]
+ permutation[start - 1:start - 1] = temp
+ selection = selection +select_range(start - 1,
+ objects[start:end])
+ else:
+ selection = selection +select_range(start,
+ objects[start:end])
- elif type(end) == ListType:
- sel, undo_info = objects[start].MoveObjectsDown(end)
- if undo_info is not NullUndo:
- undo.append(undo_info)
- selection = selection + prepend_idx(start, sel)
- else:
- if start > 0:
- del permutation[start]
- permutation.insert(start - 1, start)
- selection.append(build_info(start - 1, objects[start]))
- else:
- selection.append(build_info(start, objects[start]))
+ elif type(end) == ListType:
+ sel, undo_info = objects[start].MoveObjectsDown(end)
+ if undo_info is not NullUndo:
+ undo.append(undo_info)
+ selection = selection + prepend_idx(start, sel)
+ else:
+ if start > 0:
+ del permutation[start]
+ permutation.insert(start - 1, start)
+ selection.append(build_info(start - 1, objects[start]))
+ else:
+ selection.append(build_info(start, objects[start]))
- undo_info = self.permute_objects(permutation)
- if undo_info is not NullUndo:
- undo.append(undo_info)
- undo.append(self.end_change_children())
- if len(undo) <= 2:
- undo = NullUndo
- selection = infolist
- else:
- undo = CreateListUndo(undo)
- return (selection, undo)
- except:
- Undo(CreateListUndo(undo))
- raise
+ undo_info = self.permute_objects(permutation)
+ if undo_info is not NullUndo:
+ undo.append(undo_info)
+ undo.append(self.end_change_children())
+ if len(undo) <= 2:
+ undo = NullUndo
+ selection = infolist
+ else:
+ undo = CreateListUndo(undo)
+ return (selection, undo)
+ except:
+ Undo(CreateListUndo(undo))
+ raise
def MoveObjectsUp(self, infolist):
- sliced = list_to_tree_sliced(infolist)
- sliced.reverse()
- undo = [self.begin_change_children()]
- selection = []
- permutation = range(len(self.objects))
- objects = self.objects
- max = len(objects)
- try:
- for start, end in sliced:
- if type(end) == IntType:
- if end < max:
- temp = permutation[start:end]
- del permutation[start:end]
- permutation[start + 1:start + 1] = temp
- selection = selection + select_range(start + 1,
- objects[start:end])
- else:
- selection = selection + select_range(start,
- objects[start:end])
+ sliced = list_to_tree_sliced(infolist)
+ sliced.reverse()
+ undo = [self.begin_change_children()]
+ selection = []
+ permutation = range(len(self.objects))
+ objects = self.objects
+ max = len(objects)
+ try:
+ for start, end in sliced:
+ if type(end) == IntType:
+ if end < max:
+ temp = permutation[start:end]
+ del permutation[start:end]
+ permutation[start + 1:start + 1] = temp
+ selection = selection + select_range(start + 1,
+ objects[start:end])
+ else:
+ selection = selection + select_range(start,
+ objects[start:end])
- elif type(end) == ListType:
- sel, undo_info = objects[start].MoveObjectsUp(end)
- if undo_info is not NullUndo:
- undo.append(undo_info)
- selection = selection + prepend_idx(start, sel)
- else:
- if start < max - 1:
- del permutation[start]
- permutation.insert(start + 1, start)
- selection.append(build_info(start + 1, objects[start]))
- else:
- selection.append(build_info(start, objects[start]))
+ elif type(end) == ListType:
+ sel, undo_info = objects[start].MoveObjectsUp(end)
+ if undo_info is not NullUndo:
+ undo.append(undo_info)
+ selection = selection + prepend_idx(start, sel)
+ else:
+ if start < max - 1:
+ del permutation[start]
+ permutation.insert(start + 1, start)
+ selection.append(build_info(start + 1, objects[start]))
+ else:
+ selection.append(build_info(start, objects[start]))
- undo_info = self.permute_objects(permutation)
- if undo_info is not NullUndo:
- undo.append(undo_info)
- undo.append(self.end_change_children())
- if len(undo) <= 2:
- undo = NullUndo
- selection = infolist
- else:
- undo = CreateListUndo(undo)
- return (selection, undo)
- except:
- Undo(CreateListUndo(undo))
- raise
+ undo_info = self.permute_objects(permutation)
+ if undo_info is not NullUndo:
+ undo.append(undo_info)
+ undo.append(self.end_change_children())
+ if len(undo) <= 2:
+ undo = NullUndo
+ selection = infolist
+ else:
+ undo = CreateListUndo(undo)
+ return (selection, undo)
+ except:
+ Undo(CreateListUndo(undo))
+ raise
def DuplicateObjects(self, infolist, offset):
- infolist = list_to_tree2(infolist)
+ infolist = list_to_tree2(infolist)
- objects = self.objects
- undo = [self.begin_change_children()]
- selection = []
- added = 0
- try:
- for idx, obj in infolist:
- idx = idx + added
- if type(obj) == ListType:
- # duplicate in subobj
- sel, undoinfo = objects[idx].DuplicateObjects(obj, offset)
- undo.append(undoinfo)
- selection = selection + prepend_idx(idx, sel)
- else:
- obj = obj.Duplicate()
- obj.Translate(offset)
- sel, undoinfo = self.Insert(obj, idx + 1)
- undo.append(undoinfo)
- selection.append(sel)
- added = added + 1
- undo.append(self.end_change_children())
- return (selection, CreateListUndo(undo))
- except:
- Undo(CreateListUndo(undo))
- raise
+ objects = self.objects
+ undo = [self.begin_change_children()]
+ selection = []
+ added = 0
+ try:
+ for idx, obj in infolist:
+ idx = idx + added
+ if type(obj) == ListType:
+ # duplicate in subobj
+ sel, undoinfo = objects[idx].DuplicateObjects(obj, offset)
+ undo.append(undoinfo)
+ selection = selection + prepend_idx(idx, sel)
+ else:
+ obj = obj.Duplicate()
+ obj.Translate(offset)
+ sel, undoinfo = self.Insert(obj, idx + 1)
+ undo.append(undoinfo)
+ selection.append(sel)
+ added = added + 1
+ undo.append(self.end_change_children())
+ return (selection, CreateListUndo(undo))
+ except:
+ Undo(CreateListUndo(undo))
+ raise
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/dashes.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/dashes.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/dashes.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -28,14 +28,14 @@
def StandardDashes():
global std_dashes
if std_dashes is None:
- filename = os.path.join(config.std_res_dir, config.preferences.dashes)
- try:
- std_dashes = []
- read_resource_file(filename, '##Sketch Dashes 0',
- _("%s is not dashes file"),
- {'dashes': std_dashes.append})
- except:
- warn_tb(USER, _("Error trying to read dashes from %s\n"
+ filename = os.path.join(config.std_res_dir, config.preferences.dashes)
+ try:
+ std_dashes = []
+ read_resource_file(filename, '##Sketch Dashes 0',
+ _("%s is not dashes file"),
+ {'dashes': std_dashes.append})
+ except:
+ warn_tb(USER, _("Error trying to read dashes from %s\n"
"Using builtin defaults"), filename)
- std_dashes = [(), (5, 5)]
+ std_dashes = [(), (5, 5)]
return std_dashes
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/document.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/document.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/document.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -77,174 +77,174 @@
script_access = {}
def __init__(self, create_layer = 0):
- self.snap_grid = GridLayer()
- self.snap_grid.SetDocument(self)
- self.guide_layer = GuideLayer(_("Guide Lines"))
- self.guide_layer.SetDocument(self)
- if create_layer:
- # a new empty document
- self.active_layer = Layer(_("Layer 1"))
- self.active_layer.SetDocument(self)
- self.layers = [self.active_layer, self.guide_layer,
- self.snap_grid]
- else:
- # we're being created by the load module
- self.active_layer = None
- self.layers = []
+ self.snap_grid = GridLayer()
+ self.snap_grid.SetDocument(self)
+ self.guide_layer = GuideLayer(_("Guide Lines"))
+ self.guide_layer.SetDocument(self)
+ if create_layer:
+ # a new empty document
+ self.active_layer = Layer(_("Layer 1"))
+ self.active_layer.SetDocument(self)
+ self.layers = [self.active_layer, self.guide_layer,
+ self.snap_grid]
+ else:
+ # we're being created by the load module
+ self.active_layer = None
+ self.layers = []
def __del__(self):
- if __debug__:
- pdebug('__del__', '__del__', self.meta.filename)
+ if __debug__:
+ pdebug('__del__', '__del__', self.meta.filename)
def __getitem__(self, idx):
- if type(idx) == IntType:
- return self.layers[idx]
- elif type(idx) == TupleType:
- if len(idx) > 1:
- return self.layers[idx[0]][idx[1:]]
- elif len(idx) == 1:
- return self.layers[idx[0]]
- raise ValueError, 'invalid index %s' % `idx`
+ if type(idx) == IntType:
+ return self.layers[idx]
+ elif type(idx) == TupleType:
+ if len(idx) > 1:
+ return self.layers[idx[0]][idx[1:]]
+ elif len(idx) == 1:
+ return self.layers[idx[0]]
+ raise ValueError, 'invalid index %s' % `idx`
def AppendLayer(self, layer_name = None, *args, **kw_args):
- try:
- old_layers = self.layers[:]
- if layer_name is None:
- layer_name = _("Layer %d") % (len(self.layers) + 1)
- else:
- layer_name = str(layer_name)
- layer = apply(Layer, (layer_name,) + args, kw_args)
- layer.SetDocument(self)
- self.layers.append(layer)
- if not self.active_layer:
- self.active_layer = layer
- return layer
- except:
- self.layers[:] = old_layers
- raise
+ try:
+ old_layers = self.layers[:]
+ if layer_name is None:
+ layer_name = _("Layer %d") % (len(self.layers) + 1)
+ else:
+ layer_name = str(layer_name)
+ layer = apply(Layer, (layer_name,) + args, kw_args)
+ layer.SetDocument(self)
+ self.layers.append(layer)
+ if not self.active_layer:
+ self.active_layer = layer
+ return layer
+ except:
+ self.layers[:] = old_layers
+ raise
script_access['AppendLayer'] = SCRIPT_OBJECT
def BoundingRect(self, visible = 1, printable = 0):
- rects = []
- for layer in self.layers:
- if ((visible and layer.Visible())
- or (printable and layer.Printable())):
- rect = layer.bounding_rect
- if rect and rect != InfinityRect:
- rects.append(rect)
- if rects:
- return reduce(UnionRects, rects)
- return None
+ rects = []
+ for layer in self.layers:
+ if ((visible and layer.Visible())
+ or (printable and layer.Printable())):
+ rect = layer.bounding_rect
+ if rect and rect != InfinityRect:
+ rects.append(rect)
+ if rects:
+ return reduce(UnionRects, rects)
+ return None
script_access['BoundingRect'] = SCRIPT_GET
def augment_sel_info(self, info, layeridx):
- if type(layeridx) != IntType:
- layeridx = self.layers.index(layeridx)
- return selinfo.prepend_idx(layeridx, info)
+ if type(layeridx) != IntType:
+ layeridx = self.layers.index(layeridx)
+ return selinfo.prepend_idx(layeridx, info)
def insert(self, object, at = None, layer = None):
- undo_info = None
- try:
- if layer is None:
- layer = self.active_layer
- elif type(layer) == IntType:
- layer = self.layers[layer]
- if layer is None or layer.Locked():
- raise SketchInternalError('Layer %s is locked' % layer)
- if type(object) == ListType:
- for obj in object:
- obj.SetDocument(self)
- else:
- object.SetDocument(self)
- sel_info, undo_info = layer.Insert(object, at)
- sel_info = self.augment_sel_info(sel_info, layer)
- return (sel_info, undo_info)
- except:
- if undo_info is not None:
- Undo(undo_info)
- raise
+ undo_info = None
+ try:
+ if layer is None:
+ layer = self.active_layer
+ elif type(layer) == IntType:
+ layer = self.layers[layer]
+ if layer is None or layer.Locked():
+ raise SketchInternalError('Layer %s is locked' % layer)
+ if type(object) == ListType:
+ for obj in object:
+ obj.SetDocument(self)
+ else:
+ object.SetDocument(self)
+ sel_info, undo_info = layer.Insert(object, at)
+ sel_info = self.augment_sel_info(sel_info, layer)
+ return (sel_info, undo_info)
+ except:
+ if undo_info is not None:
+ Undo(undo_info)
+ raise
def selection_from_point(self, p, hitrect, device, path = None):
- # iterate top down (i.e. backwards) through the list of layers
- if path:
- path_layer = path[0]
- path = path[1:]
- else:
- path_layer = -1
- for idx in range(len(self.layers) - 1, -1, -1):
- if idx == path_layer:
- info = self.layers[idx].SelectSubobject(p, hitrect, device,
- path)
- else:
- info = self.layers[idx].SelectSubobject(p, hitrect, device)
- if info:
- return self.augment_sel_info(info, idx)
- else:
- return None
+ # iterate top down (i.e. backwards) through the list of layers
+ if path:
+ path_layer = path[0]
+ path = path[1:]
+ else:
+ path_layer = -1
+ for idx in range(len(self.layers) - 1, -1, -1):
+ if idx == path_layer:
+ info = self.layers[idx].SelectSubobject(p, hitrect, device,
+ path)
+ else:
+ info = self.layers[idx].SelectSubobject(p, hitrect, device)
+ if info:
+ return self.augment_sel_info(info, idx)
+ else:
+ return None
def selection_from_rect(self, rect):
- info = []
- for layer in self.layers:
- info = info + self.augment_sel_info(layer.SelectRect(rect), layer)
- return info
+ info = []
+ for layer in self.layers:
+ info = info + self.augment_sel_info(layer.SelectRect(rect), layer)
+ return info
def Draw(self, device, rect = None):
- for layer in self.layers:
- layer.Draw(device, rect)
+ for layer in self.layers:
+ layer.Draw(device, rect)
def Grid(self):
- return self.snap_grid
+ return self.snap_grid
def SnapToGrid(self, p):
- return self.snap_grid.Snap(p)
+ return self.snap_grid.Snap(p)
def SnapToGuide(self, p, maxdist):
- return self.guide_layer.Snap(p) #, maxdist)
+ return self.guide_layer.Snap(p) #, maxdist)
def DocumentInfo(self):
- info = []
- info.append('%d layers' % len(self.layers))
- for idx in range(len(self.layers)):
- layer = self.layers[idx]
- info.append('%d: %s,\t%d objects' % (idx + 1, layer.name,
- len(layer.objects)))
- return join(info, '\n')
+ info = []
+ info.append('%d layers' % len(self.layers))
+ for idx in range(len(self.layers)):
+ layer = self.layers[idx]
+ info.append('%d: %s,\t%d objects' % (idx + 1, layer.name,
+ len(layer.objects)))
+ return join(info, '\n')
def SaveToFile(self, file):
- file.BeginDocument()
- self.page_layout.SaveToFile(file)
- self.write_styles(file)
- for layer in self.layers:
- layer.SaveToFile(file)
- file.EndDocument()
+ file.BeginDocument()
+ self.page_layout.SaveToFile(file)
+ self.write_styles(file)
+ for layer in self.layers:
+ layer.SaveToFile(file)
+ file.EndDocument()
def load_AppendObject(self, layer):
- self.layers.append(layer)
+ self.layers.append(layer)
def load_Done(self):
- pass
+ pass
def load_Completed(self):
- if not self.layers:
- self.layers = [Layer(_("Layer 1"))]
- if self.active_layer is None:
- for layer in self.layers:
- if layer.CanSelect():
- self.active_layer = layer
- break
- add_guide_layer = add_grid_layer = 1
- for layer in self.layers:
- layer.SetDocument(self)
- if isinstance(layer, GuideLayer):
- self.guide_layer = layer
- add_guide_layer = 0
- if isinstance(layer, GridLayer):
- self.snap_grid = layer
- add_grid_layer = 0
- if add_guide_layer:
- self.layers.append(self.guide_layer)
- if add_grid_layer:
- self.layers.append(self.snap_grid)
+ if not self.layers:
+ self.layers = [Layer(_("Layer 1"))]
+ if self.active_layer is None:
+ for layer in self.layers:
+ if layer.CanSelect():
+ self.active_layer = layer
+ break
+ add_guide_layer = add_grid_layer = 1
+ for layer in self.layers:
+ layer.SetDocument(self)
+ if isinstance(layer, GuideLayer):
+ self.guide_layer = layer
+ add_guide_layer = 0
+ if isinstance(layer, GridLayer):
+ self.snap_grid = layer
+ add_grid_layer = 0
+ if add_guide_layer:
+ self.layers.append(self.guide_layer)
+ if add_grid_layer:
+ self.layers.append(self.snap_grid)
#
@@ -267,747 +267,747 @@
class EditDocument(SketchDocument, QueueingPublisher):
drag_mask = Button1Mask # canvas sometimes has the doc as current
- # object
+ # object
script_access = SketchDocument.script_access.copy()
def __init__(self, create_layer = 0):
- SketchDocument.__init__(self, create_layer)
- QueueingPublisher.__init__(self)
- self.selection = SizeSelection()
- self.__init_undo()
- self.was_dragged = 0
- self.meta = MetaInfo()
- self.hit_cache = None
- self.connector = Connector()
- self.init_transaction()
- self.init_clear()
- self.init_styles()
- self.init_after_handler()
- self.init_layout()
+ SketchDocument.__init__(self, create_layer)
+ QueueingPublisher.__init__(self)
+ self.selection = SizeSelection()
+ self.__init_undo()
+ self.was_dragged = 0
+ self.meta = MetaInfo()
+ self.hit_cache = None
+ self.connector = Connector()
+ self.init_transaction()
+ self.init_clear()
+ self.init_styles()
+ self.init_after_handler()
+ self.init_layout()
def Destroy(self):
- self.undo = None
- self.destroy_styles()
- RemovePublisher(self)
- for layer in self.layers:
- layer.Destroy()
- self.layers = []
- self.active_layer = None
- self.guide_layer = None
- self.snap_grid = None
- # make self.connector empty connector to remove circular refs
- # and to allow object to call document.connector.RemovePublisher
- # in their __del__ methods
- self.connector = Connector()
- self.selection = None
- self.transaction_undo = []
- self.transaction_sel = []
+ self.undo = None
+ self.destroy_styles()
+ RemovePublisher(self)
+ for layer in self.layers:
+ layer.Destroy()
+ self.layers = []
+ self.active_layer = None
+ self.guide_layer = None
+ self.snap_grid = None
+ # make self.connector empty connector to remove circular refs
+ # and to allow object to call document.connector.RemovePublisher
+ # in their __del__ methods
+ self.connector = Connector()
+ self.selection = None
+ self.transaction_undo = []
+ self.transaction_sel = []
def queue_layer(self, *args):
- if self.transaction:
- apply(self.queue_message, (LAYER,) + args)
- return (self.queue_layer, args)
- else:
- apply(self.issue, (LAYER,) + args)
+ if self.transaction:
+ apply(self.queue_message, (LAYER,) + args)
+ return (self.queue_layer, args)
+ else:
+ apply(self.issue, (LAYER,) + args)
def queue_selection(self):
- self.queue_message(SELECTION)
+ self.queue_message(SELECTION)
def queue_edited(self):
- # An EDITED message should probably indicate the type of edit,
- # i.e. whether properties changed, the geometry of objects
- # changed, etc.; hence the additional string argument which may
- # hold this information in the future
- self.queue_message(EDITED, '')
- return (self.queue_edited,)
+ # An EDITED message should probably indicate the type of edit,
+ # i.e. whether properties changed, the geometry of objects
+ # changed, etc.; hence the additional string argument which may
+ # hold this information in the future
+ self.queue_message(EDITED, '')
+ return (self.queue_edited,)
def Subscribe(self, channel, func, *args):
- Connect(self, channel, func, args)
+ Connect(self, channel, func, args)
def Unsubscribe(self, channel, func, *args):
- Disconnect(self, channel, func, args)
+ Disconnect(self, channel, func, args)
def init_after_handler(self):
- self.after_handlers = []
+ self.after_handlers = []
def AddAfterHandler(self, handler, args = (), depth = 0):
- handler = (depth, handler, args)
- try:
- self.after_handlers.remove(handler)
- except ValueError:
- pass
- self.after_handlers.append(handler)
+ handler = (depth, handler, args)
+ try:
+ self.after_handlers.remove(handler)
+ except ValueError:
+ pass
+ self.after_handlers.append(handler)
def call_after_handlers(self):
- if not self.after_handlers:
- return 0
+ if not self.after_handlers:
+ return 0
- while self.after_handlers:
+ while self.after_handlers:
handlers = self.after_handlers
- handlers.sort()
- handlers.reverse()
- depth = handlers[0][0]
+ handlers.sort()
+ handlers.reverse()
+ depth = handlers[0][0]
- count = 0
- for d, handler, args in handlers:
- if d == depth:
- count = count + 1
- else:
- break
- self.after_handlers = handlers[count:]
- handlers = handlers[:count]
+ count = 0
+ for d, handler, args in handlers:
+ if d == depth:
+ count = count + 1
+ else:
+ break
+ self.after_handlers = handlers[count:]
+ handlers = handlers[:count]
- for d, handler, args in handlers:
- try:
- apply(handler, args)
- except:
- warn_tb(INTERNAL, "In after handler `%s'%s", handler, args)
+ for d, handler, args in handlers:
+ try:
+ apply(handler, args)
+ except:
+ warn_tb(INTERNAL, "In after handler `%s'%s", handler, args)
- return 1
+ return 1
def init_clear(self):
- self.clear_rects = []
- self.clear_all = 0
+ self.clear_rects = []
+ self.clear_all = 0
reset_clear = init_clear
def AddClearRect(self, rect):
- self.clear_rects.append(rect)
- return (self.AddClearRect, rect)
+ self.clear_rects.append(rect)
+ return (self.AddClearRect, rect)
def view_redraw_all(self):
- self.clear_all = 1
- return (self.view_redraw_all,)
+ self.clear_all = 1
+ return (self.view_redraw_all,)
def issue_redraw(self):
- try:
- if self.clear_all:
- Issue(self, REDRAW, 1)
- else:
- Issue(self, REDRAW, 0, self.clear_rects)
- finally:
- self.clear_rects = []
- self.clear_all = 0
+ try:
+ if self.clear_all:
+ Issue(self, REDRAW, 1)
+ else:
+ Issue(self, REDRAW, 0, self.clear_rects)
+ finally:
+ self.clear_rects = []
+ self.clear_all = 0
def init_transaction(self):
- self.reset_transaction()
+ self.reset_transaction()
def reset_transaction(self):
- self.transaction = 0
- self.transaction_name = ''
- self.transaction_sel = []
- self.transaction_undo = []
- self.transaction_sel_ignore = 0
- self.transaction_clear = None
- self.transaction_aborted = 0
- self.transaction_cleanup = []
+ self.transaction = 0
+ self.transaction_name = ''
+ self.transaction_sel = []
+ self.transaction_undo = []
+ self.transaction_sel_ignore = 0
+ self.transaction_clear = None
+ self.transaction_aborted = 0
+ self.transaction_cleanup = []
def cleanup_transaction(self):
- for handler, args in self.transaction_cleanup:
- try:
- apply(handler, args)
- except:
- warn_tb(INTERNAL, "in cleanup handler %s%s", handler, `args`)
- self.transaction_cleanup = []
+ for handler, args in self.transaction_cleanup:
+ try:
+ apply(handler, args)
+ except:
+ warn_tb(INTERNAL, "in cleanup handler %s%s", handler, `args`)
+ self.transaction_cleanup = []
def add_cleanup_handler(self, handler, *args):
- handler = (handler, args)
- try:
- self.transaction_cleanup.remove(handler)
- except ValueError:
- pass
- self.transaction_cleanup.append(handler)
+ handler = (handler, args)
+ try:
+ self.transaction_cleanup.remove(handler)
+ except ValueError:
+ pass
+ self.transaction_cleanup.append(handler)
def begin_transaction(self, name = '', no_selection = 0,
- clear_selection_rect = 1):
- if self.transaction_aborted:
- raise AbortTransactionError
- if self.transaction == 0:
- if not no_selection:
- selinfo = self.selection.GetInfo()[:]
- if selinfo != self.transaction_sel:
- self.transaction_sel = selinfo
- self.transaction_sel_mode = self.selection.__class__
- self.transaction_sel_ignore = no_selection
- self.transaction_name = name
- self.transaction_undo = []
- if clear_selection_rect:
- if self.selection:
- self.transaction_clear = self.selection.bounding_rect
- else:
- self.transaction_clear = None
- elif not self.transaction_name:
- self.transaction_name = name
- self.transaction = self.transaction + 1
+ clear_selection_rect = 1):
+ if self.transaction_aborted:
+ raise AbortTransactionError
+ if self.transaction == 0:
+ if not no_selection:
+ selinfo = self.selection.GetInfo()[:]
+ if selinfo != self.transaction_sel:
+ self.transaction_sel = selinfo
+ self.transaction_sel_mode = self.selection.__class__
+ self.transaction_sel_ignore = no_selection
+ self.transaction_name = name
+ self.transaction_undo = []
+ if clear_selection_rect:
+ if self.selection:
+ self.transaction_clear = self.selection.bounding_rect
+ else:
+ self.transaction_clear = None
+ elif not self.transaction_name:
+ self.transaction_name = name
+ self.transaction = self.transaction + 1
def end_transaction(self, issue = (), queue_edited = 0):
- self.transaction = self.transaction - 1
- if self.transaction_aborted:
- # end an aborted transaction
- if self.transaction == 0:
- # undo the changes already done...
- undo = self.transaction_undo
- undo.reverse()
- map(Undo, undo)
- self.cleanup_transaction()
- self.reset_transaction()
- self.reset_clear()
- else:
- # a normal transaction
- if type(issue) == StringType:
- self.queue_message(issue)
- else:
- for channel in issue:
- self.queue_message(channel)
- if self.transaction == 0:
- # the outermost end_transaction
- # increase transaction flag temporarily because some
- # after handlers might call public methods that are
- # themselves transactions...
- self.transaction = 1
- if self.call_after_handlers():
- self.selection.ResetRectangle()
- self.transaction = 0
- undo = CreateListUndo(self.transaction_undo)
- if undo is not NullUndo:
- undo = [undo]
- if self.transaction_clear is not None:
- undo.append(self.AddClearRect(self.transaction_clear))
- if self.selection:
- self.selection.ResetRectangle()
- rect = self.selection.bounding_rect
- undo.append(self.AddClearRect(rect))
- if queue_edited:
- undo.append(self.queue_edited())
- undo = CreateListUndo(undo)
- if self.transaction_sel_ignore:
- self.__real_add_undo(self.transaction_name, undo)
- else:
- self.__real_add_undo(self.transaction_name, undo,
- self.transaction_sel,
- self.transaction_sel_mode)
- self.flush_message_queue()
- self.issue_redraw()
- self.cleanup_transaction()
- self.reset_transaction()
- self.reset_clear()
- elif self.transaction < 0:
- raise SketchInternalError('transaction < 0')
+ self.transaction = self.transaction - 1
+ if self.transaction_aborted:
+ # end an aborted transaction
+ if self.transaction == 0:
+ # undo the changes already done...
+ undo = self.transaction_undo
+ undo.reverse()
+ map(Undo, undo)
+ self.cleanup_transaction()
+ self.reset_transaction()
+ self.reset_clear()
+ else:
+ # a normal transaction
+ if type(issue) == StringType:
+ self.queue_message(issue)
+ else:
+ for channel in issue:
+ self.queue_message(channel)
+ if self.transaction == 0:
+ # the outermost end_transaction
+ # increase transaction flag temporarily because some
+ # after handlers might call public methods that are
+ # themselves transactions...
+ self.transaction = 1
+ if self.call_after_handlers():
+ self.selection.ResetRectangle()
+ self.transaction = 0
+ undo = CreateListUndo(self.transaction_undo)
+ if undo is not NullUndo:
+ undo = [undo]
+ if self.transaction_clear is not None:
+ undo.append(self.AddClearRect(self.transaction_clear))
+ if self.selection:
+ self.selection.ResetRectangle()
+ rect = self.selection.bounding_rect
+ undo.append(self.AddClearRect(rect))
+ if queue_edited:
+ undo.append(self.queue_edited())
+ undo = CreateListUndo(undo)
+ if self.transaction_sel_ignore:
+ self.__real_add_undo(self.transaction_name, undo)
+ else:
+ self.__real_add_undo(self.transaction_name, undo,
+ self.transaction_sel,
+ self.transaction_sel_mode)
+ self.flush_message_queue()
+ self.issue_redraw()
+ self.cleanup_transaction()
+ self.reset_transaction()
+ self.reset_clear()
+ elif self.transaction < 0:
+ raise SketchInternalError('transaction < 0')
def abort_transaction(self):
- self.transaction_aborted = 1
- warn_tb(INTERNAL, "in transaction `%s'" % self.transaction_name)
- raise AbortTransactionError
+ self.transaction_aborted = 1
+ warn_tb(INTERNAL, "in transaction `%s'" % self.transaction_name)
+ raise AbortTransactionError
# public versions of the transaction methods
BeginTransaction = begin_transaction
AbortTransaction = abort_transaction
def EndTransaction(self):
- self.end_transaction(queue_edited = 1)
+ self.end_transaction(queue_edited = 1)
def Insert(self, object, undo_text = _("Create Object")):
- if isinstance(object, guide.GuideLine):
- self.add_guide_line(object)
- else:
- self.begin_transaction(undo_text, clear_selection_rect = 0)
- try:
- try:
- object.SetDocument(self)
- selected, undo = self.insert(object)
- self.add_undo(undo)
- self.add_undo(self.AddClearRect(object.bounding_rect))
- self.__set_selection(selected, SelectSet)
- except:
- self.abort_transaction()
- finally:
- self.end_transaction(queue_edited = 1)
+ if isinstance(object, guide.GuideLine):
+ self.add_guide_line(object)
+ else:
+ self.begin_transaction(undo_text, clear_selection_rect = 0)
+ try:
+ try:
+ object.SetDocument(self)
+ selected, undo = self.insert(object)
+ self.add_undo(undo)
+ self.add_undo(self.AddClearRect(object.bounding_rect))
+ self.__set_selection(selected, SelectSet)
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction(queue_edited = 1)
def SelectPoint(self, p, device, type = SelectSet):
- # find object at point, and modify the current selection
- # according to type
- self.begin_transaction(clear_selection_rect = 0)
- try:
- try:
- if type == SelectSubobjects:
- path = self.selection.GetPath()
- else:
- path = ()
- rect = device.HitRectAroundPoint(p)
- if self.hit_cache:
- cp, cdevice, hit = self.hit_cache
- self.hit_cache = None
- if p is cp and device is cdevice:
- selected = hit
- else:
- selected = self.selection_from_point(p, rect, device,
- path)
- else:
- selected = self.selection_from_point(p, rect, device, path)
- if type == SelectGuide:
+ # find object at point, and modify the current selection
+ # according to type
+ self.begin_transaction(clear_selection_rect = 0)
+ try:
+ try:
+ if type == SelectSubobjects:
+ path = self.selection.GetPath()
+ else:
+ path = ()
+ rect = device.HitRectAroundPoint(p)
+ if self.hit_cache:
+ cp, cdevice, hit = self.hit_cache
+ self.hit_cache = None
+ if p is cp and device is cdevice:
+ selected = hit
+ else:
+ selected = self.selection_from_point(p, rect, device,
+ path)
+ else:
+ selected = self.selection_from_point(p, rect, device, path)
+ if type == SelectGuide:
if selected and selected[-1].is_GuideLine:
return selected[-1]
- return None
- elif selected:
- path, object = selected
- if self.layers[path[0]] is self.guide_layer:
- if object.is_GuideLine:
- # guide lines cannot be selected in the
- # ordinary way, but other objects on the
- # guide layer can.
- selected = None
- self.__set_selection(selected, type)
+ return None
+ elif selected:
+ path, object = selected
+ if self.layers[path[0]] is self.guide_layer:
+ if object.is_GuideLine:
+ # guide lines cannot be selected in the
+ # ordinary way, but other objects on the
+ # guide layer can.
+ selected = None
+ self.__set_selection(selected, type)
if self.IsEditMode():
object = self.CurrentObject()
if object is not None and object.is_Text:
self.SelectPointPart(p, device, SelectSet)
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
- return selected
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
+ return selected
def SelectRect(self, rect, mode = SelectSet):
- # Find all objects contained in rect and modify the current
- # selection according to mode
- self.begin_transaction(clear_selection_rect = 0)
- try:
- try:
- self.hit_cache = None
- selected = self.selection_from_rect(rect)
- self.__set_selection(selected, mode)
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
- return selected
+ # Find all objects contained in rect and modify the current
+ # selection according to mode
+ self.begin_transaction(clear_selection_rect = 0)
+ try:
+ try:
+ self.hit_cache = None
+ selected = self.selection_from_rect(rect)
+ self.__set_selection(selected, mode)
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
+ return selected
def SelectRectPart(self, rect, mode = SelectSet):
- # Select the part of the CSO that lies in rect. Currently this
- # works only in edit mode. For a PolyBezier this means that all
- # nodes within rect are selected.
- if not self.IsEditMode():
- raise SketchInternalError('SelectRectPart requires edit mode')
- self.begin_transaction(clear_selection_rect = 0)
- try:
- try:
- self.hit_cache = None
- self.selection.SelectRect(rect, mode)
- self.queue_selection()
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ # Select the part of the CSO that lies in rect. Currently this
+ # works only in edit mode. For a PolyBezier this means that all
+ # nodes within rect are selected.
+ if not self.IsEditMode():
+ raise SketchInternalError('SelectRectPart requires edit mode')
+ self.begin_transaction(clear_selection_rect = 0)
+ try:
+ try:
+ self.hit_cache = None
+ self.selection.SelectRect(rect, mode)
+ self.queue_selection()
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def SelectPointPart(self, p, device, mode = SelectSet):
- # Select the part of the current object under the point p.
- # Like SelectRectPart this only works in edit mode.
- self.begin_transaction(clear_selection_rect = 0)
- try:
- try:
+ # Select the part of the current object under the point p.
+ # Like SelectRectPart this only works in edit mode.
+ self.begin_transaction(clear_selection_rect = 0)
+ try:
+ try:
self.hit_cache = None
rect = device.HitRectAroundPoint(p)
self.selection.SelectPoint(p, rect, device, mode)
- if mode != SelectDrag:
- self.queue_selection()
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ if mode != SelectDrag:
+ self.queue_selection()
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def SelectHandle(self, handle, mode = SelectSet):
- # Select the handle indicated by handle. This only works in edit
- # mode.
- self.begin_transaction(clear_selection_rect = 0)
- try:
- try:
- self.hit_cache = None
- self.selection.SelectHandle(handle, mode)
- if mode != SelectDrag:
- self.queue_selection()
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ # Select the handle indicated by handle. This only works in edit
+ # mode.
+ self.begin_transaction(clear_selection_rect = 0)
+ try:
+ try:
+ self.hit_cache = None
+ self.selection.SelectHandle(handle, mode)
+ if mode != SelectDrag:
+ self.queue_selection()
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def SelectAll(self):
- # Select all objects that can currently be selected.
- # XXX should the objects in the guide layer also be selected by
- # this method? (currently they are)
- self.begin_transaction(clear_selection_rect = 0)
- try:
- try:
- sel_info = []
- for layer_idx in range(len(self.layers)):
- sel = self.layers[layer_idx].SelectAll()
- if sel:
- sel = self.augment_sel_info(sel, layer_idx)
- sel_info = sel_info + sel
- self.__set_selection(sel_info, SelectSet)
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ # Select all objects that can currently be selected.
+ # XXX should the objects in the guide layer also be selected by
+ # this method? (currently they are)
+ self.begin_transaction(clear_selection_rect = 0)
+ try:
+ try:
+ sel_info = []
+ for layer_idx in range(len(self.layers)):
+ sel = self.layers[layer_idx].SelectAll()
+ if sel:
+ sel = self.augment_sel_info(sel, layer_idx)
+ sel_info = sel_info + sel
+ self.__set_selection(sel_info, SelectSet)
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
script_access['SelectAll'] = SCRIPT_GET
def SelectNone(self):
- # Deselect all objects.
- self.begin_transaction(clear_selection_rect = 0)
- try:
- try:
- self.__set_selection(None, SelectSet)
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ # Deselect all objects.
+ self.begin_transaction(clear_selection_rect = 0)
+ try:
+ try:
+ self.__set_selection(None, SelectSet)
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
script_access['SelectNone'] = SCRIPT_GET
def SelectObject(self, objects, mode = SelectSet):
- # Select the objects defined by OBJECTS. OBJECTS may be a single
- # GraphicsObject or a list of such objects. Modify the current
- # selection according to MODE.
- self.begin_transaction(clear_selection_rect = 0)
- try:
- try:
- if type(objects) != ListType:
- objects = [objects]
- selinfo = []
- for object in objects:
- selinfo.append(object.SelectionInfo())
+ # Select the objects defined by OBJECTS. OBJECTS may be a single
+ # GraphicsObject or a list of such objects. Modify the current
+ # selection according to MODE.
+ self.begin_transaction(clear_selection_rect = 0)
+ try:
+ try:
+ if type(objects) != ListType:
+ objects = [objects]
+ selinfo = []
+ for object in objects:
+ selinfo.append(object.SelectionInfo())
if selinfo:
self.__set_selection(selinfo, mode)
else:
self.__set_selection(None, SelectSet)
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
#script_access['SelectObject'] = SCRIPT_GET
def select_first_in_layer(self, idx = 0):
- for layer in self.layers[idx:]:
- if layer.CanSelect() and not layer.is_SpecialLayer:
- object = layer.SelectFirstChild()
- if object is not None:
- return object
+ for layer in self.layers[idx:]:
+ if layer.CanSelect() and not layer.is_SpecialLayer:
+ object = layer.SelectFirstChild()
+ if object is not None:
+ return object
def SelectNextObject(self):
- # If exactly one object is selected select its next higher
- # sibling. If there is no next sibling and its parent is a
- # layer, select the first object in the next higher layer that
- # allows selections.
- #
- # If more than one object is currently selected, deselect all
- # but the the highest of them.
- self.begin_transaction(clear_selection_rect = 0)
- try:
- try:
- info = self.selection.GetInfo()
- if len(info) > 1:
- self.__set_selection(info[-1], SelectSet)
- elif info:
- path, object = info[0]
- parent = object.parent
- object = parent.SelectNextChild(object, path[-1])
- if object is None and parent.is_Layer:
- idx = self.layers.index(parent)
- object = self.select_first_in_layer(idx + 1)
- if object is not None:
- self.SelectObject(object)
- else:
- object = self.select_first_in_layer()
- if object is not None:
- self.SelectObject(object)
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ # If exactly one object is selected select its next higher
+ # sibling. If there is no next sibling and its parent is a
+ # layer, select the first object in the next higher layer that
+ # allows selections.
+ #
+ # If more than one object is currently selected, deselect all
+ # but the the highest of them.
+ self.begin_transaction(clear_selection_rect = 0)
+ try:
+ try:
+ info = self.selection.GetInfo()
+ if len(info) > 1:
+ self.__set_selection(info[-1], SelectSet)
+ elif info:
+ path, object = info[0]
+ parent = object.parent
+ object = parent.SelectNextChild(object, path[-1])
+ if object is None and parent.is_Layer:
+ idx = self.layers.index(parent)
+ object = self.select_first_in_layer(idx + 1)
+ if object is not None:
+ self.SelectObject(object)
+ else:
+ object = self.select_first_in_layer()
+ if object is not None:
+ self.SelectObject(object)
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
script_access['SelectNextObject'] = SCRIPT_GET
def select_last_in_layer(self, idx):
- if idx < 0:
- return
- layers = self.layers[:idx + 1]
- layers.reverse()
- for layer in layers:
- if layer.CanSelect() and not layer.is_SpecialLayer:
- object = layer.SelectLastChild()
- if object is not None:
- return object
+ if idx < 0:
+ return
+ layers = self.layers[:idx + 1]
+ layers.reverse()
+ for layer in layers:
+ if layer.CanSelect() and not layer.is_SpecialLayer:
+ object = layer.SelectLastChild()
+ if object is not None:
+ return object
def SelectPreviousObject(self):
- # If exactly one object is selected select its next lower
- # sibling. If there is no lower sibling and its parent is a
- # layer, select the last object in the next lower layer that
- # allows selections.
- #
- # If more than one object is currently selected, deselect all
- # but the the lowest of them.
- self.begin_transaction(clear_selection_rect = 0)
- try:
- try:
- info = self.selection.GetInfo()
- if len(info) > 1:
- self.__set_selection(info[0], SelectSet)
- elif info:
- path, object = info[0]
- parent = object.parent
- object = parent.SelectPreviousChild(object, path[-1])
- if object is None and parent.is_Layer:
- idx = self.layers.index(parent)
- object = self.select_last_in_layer(idx - 1)
- if object is not None:
- self.SelectObject(object)
- else:
- object = self.select_last_in_layer(len(self.layers))
- if object is not None:
- self.SelectObject(object)
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ # If exactly one object is selected select its next lower
+ # sibling. If there is no lower sibling and its parent is a
+ # layer, select the last object in the next lower layer that
+ # allows selections.
+ #
+ # If more than one object is currently selected, deselect all
+ # but the the lowest of them.
+ self.begin_transaction(clear_selection_rect = 0)
+ try:
+ try:
+ info = self.selection.GetInfo()
+ if len(info) > 1:
+ self.__set_selection(info[0], SelectSet)
+ elif info:
+ path, object = info[0]
+ parent = object.parent
+ object = parent.SelectPreviousChild(object, path[-1])
+ if object is None and parent.is_Layer:
+ idx = self.layers.index(parent)
+ object = self.select_last_in_layer(idx - 1)
+ if object is not None:
+ self.SelectObject(object)
+ else:
+ object = self.select_last_in_layer(len(self.layers))
+ if object is not None:
+ self.SelectObject(object)
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
script_access['SelectPreviousObject'] = SCRIPT_GET
def SelectFirstChild(self):
- # If exactly one object is selected and this object is a
- # compound object, select its first (lowest) child. The first
- # child is the object returned by the compound object's method
- # SelectFirstChild. If that method returns none, do nothing.
- self.begin_transaction(clear_selection_rect = 0)
- try:
- try:
- objects = self.selection.GetObjects()
- if len(objects) == 1:
- object = objects[0]
- if object.is_Compound:
- object = object.SelectFirstChild()
- if object is not None:
- self.SelectObject(object)
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ # If exactly one object is selected and this object is a
+ # compound object, select its first (lowest) child. The first
+ # child is the object returned by the compound object's method
+ # SelectFirstChild. If that method returns none, do nothing.
+ self.begin_transaction(clear_selection_rect = 0)
+ try:
+ try:
+ objects = self.selection.GetObjects()
+ if len(objects) == 1:
+ object = objects[0]
+ if object.is_Compound:
+ object = object.SelectFirstChild()
+ if object is not None:
+ self.SelectObject(object)
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
script_access['SelectFirstChild'] = SCRIPT_GET
def SelectParent(self):
- # Select the parent of the currently selected object(s).
- self.begin_transaction(clear_selection_rect = 0)
- try:
- try:
- if len(self.selection) > 1:
- path = selinfo.common_prefix(self.selection.GetInfo())
- if len(path) > 1:
- object = self[path]
- self.SelectObject(object)
- elif len(self.selection) == 1:
- object = self.selection.GetObjects()[0].parent
- if not object.is_Layer:
- self.SelectObject(object)
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ # Select the parent of the currently selected object(s).
+ self.begin_transaction(clear_selection_rect = 0)
+ try:
+ try:
+ if len(self.selection) > 1:
+ path = selinfo.common_prefix(self.selection.GetInfo())
+ if len(path) > 1:
+ object = self[path]
+ self.SelectObject(object)
+ elif len(self.selection) == 1:
+ object = self.selection.GetObjects()[0].parent
+ if not object.is_Layer:
+ self.SelectObject(object)
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
script_access['SelectParent'] = SCRIPT_GET
def DeselectObject(self, object):
- # Deselect the object OBJECT.
- # XXX: for large selections this can be very slow.
- selected = self.selection.GetObjects()
- try:
- index = selected.index(object)
- except ValueError:
- return
- info = self.selection.GetInfo()
- del info[index]
- self.__set_selection(info, SelectSet)
+ # Deselect the object OBJECT.
+ # XXX: for large selections this can be very slow.
+ selected = self.selection.GetObjects()
+ try:
+ index = selected.index(object)
+ except ValueError:
+ return
+ info = self.selection.GetInfo()
+ del info[index]
+ self.__set_selection(info, SelectSet)
def __set_selection(self, selected, type):
- # Modify the current selection. SELECTED is a list of selection
- # info describing the new selection, TYPE indicates how the
- # current selection is modified:
- #
- # type Meaning
- # SelectSet Replace the old selection by the new one
- # SelectSubtract Subtract the new selection from the old one
- # SelectAdd Add the new selection to the old one.
- # SelectSubobjects like SelectSet here
- changed = 0
- if type == SelectAdd:
- if selected:
- changed = self.selection.Add(selected)
- elif type == SelectSubtract:
- if selected:
- changed = self.selection.Subtract(selected)
- elif type == SelectGuide:
- if selected:
- pass
- else:
- # type is SelectSet or SelectSubobjects
- # set the selection. make a size selection if necessary
- if self.selection.__class__ == TrafoSelection:
- self.selection = SizeSelection()
- changed = 1
- changed = self.selection.SetSelection(selected) or changed
- if changed:
- self.queue_selection()
+ # Modify the current selection. SELECTED is a list of selection
+ # info describing the new selection, TYPE indicates how the
+ # current selection is modified:
+ #
+ # type Meaning
+ # SelectSet Replace the old selection by the new one
+ # SelectSubtract Subtract the new selection from the old one
+ # SelectAdd Add the new selection to the old one.
+ # SelectSubobjects like SelectSet here
+ changed = 0
+ if type == SelectAdd:
+ if selected:
+ changed = self.selection.Add(selected)
+ elif type == SelectSubtract:
+ if selected:
+ changed = self.selection.Subtract(selected)
+ elif type == SelectGuide:
+ if selected:
+ pass
+ else:
+ # type is SelectSet or SelectSubobjects
+ # set the selection. make a size selection if necessary
+ if self.selection.__class__ == TrafoSelection:
+ self.selection = SizeSelection()
+ changed = 1
+ changed = self.selection.SetSelection(selected) or changed
+ if changed:
+ self.queue_selection()
def SetMode(self, mode):
- self.begin_transaction(clear_selection_rect = 0)
- try:
- try:
- if mode == SelectionMode:
- self.selection = SizeSelection(self.selection)
- else:
- self.selection = EditSelection(self.selection)
- except:
- self.abort_transaction()
- finally:
- self.end_transaction(issue = (SELECTION, MODE))
+ self.begin_transaction(clear_selection_rect = 0)
+ try:
+ try:
+ if mode == SelectionMode:
+ self.selection = SizeSelection(self.selection)
+ else:
+ self.selection = EditSelection(self.selection)
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction(issue = (SELECTION, MODE))
def Mode(self):
- if self.selection.__class__ == EditSelection:
- return EditMode
- return SelectionMode
+ if self.selection.__class__ == EditSelection:
+ return EditMode
+ return SelectionMode
script_access['Mode'] = SCRIPT_GET
def IsSelectionMode(self):
- return self.Mode() == SelectionMode
+ return self.Mode() == SelectionMode
script_access['IsSelectionMode'] = SCRIPT_GET
def IsEditMode(self):
- return self.Mode() == EditMode
+ return self.Mode() == EditMode
script_access['IsEditMode'] = SCRIPT_GET
def SelectionHit(self, p, device, test_all = 1):
- # Return true, if the point P hits the currently selected
- # objects.
- #
- # If test_all is true (the default), find the object that would
- # be selected by SelectPoint and return true if it or one of its
- # ancestors is contained in the current selection and false
- # otherwise.
- #
- # If test_all is false, just test the currently selected objects.
- rect = device.HitRectAroundPoint(p)
- if len(self.selection) < 10 or not test_all:
- selection_hit = self.selection.Hit(p, rect, device)
- if not test_all or not selection_hit:
- return selection_hit
- if test_all:
- path = self.selection.GetPath()
- if len(path) > 2:
- path = path[:-1]
- else:
- path = ()
- hit = self.selection_from_point(p, rect, device, path)
- self.hit_cache = (p, device, hit)
- while hit:
- if hit in self.selection.GetInfo():
- return 1
- hit = selinfo.get_parent(hit)
- #self.hit_cache = None
- return 0
+ # Return true, if the point P hits the currently selected
+ # objects.
+ #
+ # If test_all is true (the default), find the object that would
+ # be selected by SelectPoint and return true if it or one of its
+ # ancestors is contained in the current selection and false
+ # otherwise.
+ #
+ # If test_all is false, just test the currently selected objects.
+ rect = device.HitRectAroundPoint(p)
+ if len(self.selection) < 10 or not test_all:
+ selection_hit = self.selection.Hit(p, rect, device)
+ if not test_all or not selection_hit:
+ return selection_hit
+ if test_all:
+ path = self.selection.GetPath()
+ if len(path) > 2:
+ path = path[:-1]
+ else:
+ path = ()
+ hit = self.selection_from_point(p, rect, device, path)
+ self.hit_cache = (p, device, hit)
+ while hit:
+ if hit in self.selection.GetInfo():
+ return 1
+ hit = selinfo.get_parent(hit)
+ #self.hit_cache = None
+ return 0
def GetSelectionHandles(self):
- if self.selection:
- return self.selection.GetHandles()
- else:
- return []
+ if self.selection:
+ return self.selection.GetHandles()
+ else:
+ return []
#
# Get information about the selected objects
#
def HasSelection(self):
- # Return true, if one or more objects are selected
- return len(self.selection)
+ # Return true, if one or more objects are selected
+ return len(self.selection)
script_access['HasSelection'] = SCRIPT_GET
def CountSelected(self):
- # Return the number of currently selected objects
- return len(self.selection)
+ # Return the number of currently selected objects
+ return len(self.selection)
script_access['CountSelected'] = SCRIPT_GET
def SelectionInfoText(self):
- # Return a string describing the selected object(s)
- return self.selection.InfoText()
+ # Return a string describing the selected object(s)
+ return self.selection.InfoText()
script_access['SelectionInfoText'] = SCRIPT_GET
def CurrentInfoText(self):
return self.selection.CurrentInfoText()
def SelectionBoundingRect(self):
- # Return the bounding rect of the current selection
- return self.selection.bounding_rect
+ # Return the bounding rect of the current selection
+ return self.selection.bounding_rect
script_access['SelectionBoundingRect'] = SCRIPT_GET
def CurrentObject(self):
- # If exactly one object is selected return that, None instead.
- if len(self.selection) == 1:
- return self.selection.GetObjects()[0]
- return None
+ # If exactly one object is selected return that, None instead.
+ if len(self.selection) == 1:
+ return self.selection.GetObjects()[0]
+ return None
script_access['CurrentObject'] = SCRIPT_OBJECT
def SelectedObjects(self):
- # Return the selected objects as a list. They are listed in the
- # order in which they are drawn.
- return self.selection.GetObjects()
+ # Return the selected objects as a list. They are listed in the
+ # order in which they are drawn.
+ return self.selection.GetObjects()
script_access['SelectedObjects'] = SCRIPT_OBJECTLIST
def CurrentProperties(self):
- # Return the properties of the current object if exactly one
- # object is selected. Return EmptyProperties otherwise.
- if self.selection:
- if len(self.selection) > 1:
- return EmptyProperties
- return self.selection.GetInfo()[0][-1].Properties()
- return EmptyProperties
+ # Return the properties of the current object if exactly one
+ # object is selected. Return EmptyProperties otherwise.
+ if self.selection:
+ if len(self.selection) > 1:
+ return EmptyProperties
+ return self.selection.GetInfo()[0][-1].Properties()
+ return EmptyProperties
script_access['CurrentProperties'] = SCRIPT_OBJECT
def CurrentFillColor(self):
- # Return the fill color of the current object if exactly one
- # object is selected and that object has a solid fill. Return
- # None otherwise.
- if len(self.selection) == 1:
- properties = self.selection.GetInfo()[0][-1].Properties()
- try:
- return properties.fill_pattern.Color()
- except AttributeError:
- pass
- return None
+ # Return the fill color of the current object if exactly one
+ # object is selected and that object has a solid fill. Return
+ # None otherwise.
+ if len(self.selection) == 1:
+ properties = self.selection.GetInfo()[0][-1].Properties()
+ try:
+ return properties.fill_pattern.Color()
+ except AttributeError:
+ pass
+ return None
script_access['CurrentFillColor'] = SCRIPT_GET
def PickObject(self, device, point, selectable = 0):
- # Return the object that is hit by a click at POINT. The object
- # is not selected and should not be modified by the caller.
+ # Return the object that is hit by a click at POINT. The object
+ # is not selected and should not be modified by the caller.
#
- # If selectable is false, this function descends into compound
- # objects that are normally selected as a whole when one of
- # their children is hit. If selectable is true, the search is
- # done as for a normal selection.
+ # If selectable is false, this function descends into compound
+ # objects that are normally selected as a whole when one of
+ # their children is hit. If selectable is true, the search is
+ # done as for a normal selection.
#
# This method is intended to be used to
- # let the user click on the drawing and extract properties from
- # the indicated object. The fill and line dialogs use this
- # indirectly (through the canvas object's PickObject) for their
- # 'Update From...' button.
- #
- # XXX should this be implemented by calling WalkHierarchy
- # instead of requiring a special PickObject method in each
- # compound? Unlike the normal hit-test, this method is not that
- # time critical and WalkHierarchy is sufficiently fast for most
- # purposes (see extract_snap_points in the canvas).
- # WalkHierarchy would have to be able to traverse the hierarchy
- # top down and not just bottom up.
+ # let the user click on the drawing and extract properties from
+ # the indicated object. The fill and line dialogs use this
+ # indirectly (through the canvas object's PickObject) for their
+ # 'Update From...' button.
+ #
+ # XXX should this be implemented by calling WalkHierarchy
+ # instead of requiring a special PickObject method in each
+ # compound? Unlike the normal hit-test, this method is not that
+ # time critical and WalkHierarchy is sufficiently fast for most
+ # purposes (see extract_snap_points in the canvas).
+ # WalkHierarchy would have to be able to traverse the hierarchy
+ # top down and not just bottom up.
object = None
- rect = device.HitRectAroundPoint(point)
+ rect = device.HitRectAroundPoint(point)
if not selectable:
layers = self.layers[:]
layers.reverse()
@@ -1019,12 +1019,12 @@
selected = self.selection_from_point(point, rect, device)
if selected:
object = selected[-1]
- return object
+ return object
def PickActiveObject(self, device, p):
# return the object under point if it's selected or a guide
# line. None otherwise.
- rect = device.HitRectAroundPoint(p)
+ rect = device.HitRectAroundPoint(p)
path = self.selection.GetPath()
if len(path) > 2:
path = path[:-1]
@@ -1042,354 +1042,354 @@
else:
hit = hit[-1]
return hit
-
+
#
#
#
def WalkHierarchy(self, func, printable = 1, visible = 1, all = 0):
- # XXX make the selection of layers more versatile
- for layer in self.layers:
- if (all
+ # XXX make the selection of layers more versatile
+ for layer in self.layers:
+ if (all
or printable and layer.Printable()
or visible and layer.Visible()):
- layer.WalkHierarchy(func)
+ layer.WalkHierarchy(func)
#
#
#
def ButtonDown(self, p, button, state):
- self.was_dragged = 0
- self.old_change_rect = self.selection.ChangeRect()
- result = self.selection.ButtonDown(p, button, state)
- return result
+ self.was_dragged = 0
+ self.old_change_rect = self.selection.ChangeRect()
+ result = self.selection.ButtonDown(p, button, state)
+ return result
def MouseMove(self, p, state):
- self.was_dragged = 1
- self.selection.MouseMove(p, state)
+ self.was_dragged = 1
+ self.selection.MouseMove(p, state)
def ButtonUp(self, p, button, state):
- self.begin_transaction(clear_selection_rect = 0)
- try:
- try:
- if self.was_dragged:
- undo_text, undo_edit \
- = self.selection.ButtonUp(p, button, state)
- if undo_edit is not None and undo_edit != NullUndo:
- self.add_undo(undo_text, undo_edit)
- uc1 = self.AddClearRect(self.old_change_rect)
- uc2 = self.AddClearRect(self.selection.ChangeRect())
- self.add_undo(uc1, uc2)
- self.add_undo(self.queue_edited())
- else:
- # the user probably just moved the rotation
- # center point. The canvas has to update the
- # handles
- self.queue_selection()
- else:
- self.selection.ButtonUp(p, button, state, forget_trafo = 1)
- self.ToggleSelectionBehaviour()
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ self.begin_transaction(clear_selection_rect = 0)
+ try:
+ try:
+ if self.was_dragged:
+ undo_text, undo_edit \
+ = self.selection.ButtonUp(p, button, state)
+ if undo_edit is not None and undo_edit != NullUndo:
+ self.add_undo(undo_text, undo_edit)
+ uc1 = self.AddClearRect(self.old_change_rect)
+ uc2 = self.AddClearRect(self.selection.ChangeRect())
+ self.add_undo(uc1, uc2)
+ self.add_undo(self.queue_edited())
+ else:
+ # the user probably just moved the rotation
+ # center point. The canvas has to update the
+ # handles
+ self.queue_selection()
+ else:
+ self.selection.ButtonUp(p, button, state, forget_trafo = 1)
+ self.ToggleSelectionBehaviour()
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def ToggleSelectionBehaviour(self):
- self.begin_transaction(clear_selection_rect = 0)
- try:
- try:
- if self.selection.__class__ == SizeSelection:
- self.selection = TrafoSelection(self.selection)
- elif self.selection.__class__ == TrafoSelection:
- self.selection = SizeSelection(self.selection)
- self.queue_selection()
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ self.begin_transaction(clear_selection_rect = 0)
+ try:
+ try:
+ if self.selection.__class__ == SizeSelection:
+ self.selection = TrafoSelection(self.selection)
+ elif self.selection.__class__ == TrafoSelection:
+ self.selection = SizeSelection(self.selection)
+ self.queue_selection()
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def DrawDragged(self, device, partially = 0):
- self.selection.DrawDragged(device, partially)
+ self.selection.DrawDragged(device, partially)
def Hide(self, device, partially = 0):
- self.selection.Hide(device, partially)
+ self.selection.Hide(device, partially)
def Show(self, device, partially = 0):
- self.selection.Show(device, partially)
+ self.selection.Show(device, partially)
def ChangeRect(self):
- return self.selection.ChangeRect()
+ return self.selection.ChangeRect()
#
# The undo mechanism
#
def __init_undo(self):
- self.undo = UndoRedo()
+ self.undo = UndoRedo()
def CanUndo(self):
- return self.undo.CanUndo()
+ return self.undo.CanUndo()
script_access['CanUndo'] = SCRIPT_GET
def CanRedo(self):
- return self.undo.CanRedo()
+ return self.undo.CanRedo()
script_access['CanRedo'] = SCRIPT_GET
def Undo(self):
- if self.undo.CanUndo():
- self.begin_transaction(clear_selection_rect = 0)
- try:
- try:
- self.undo.Undo()
- except:
- self.abort_transaction()
- finally:
- self.end_transaction(issue = UNDO)
+ if self.undo.CanUndo():
+ self.begin_transaction(clear_selection_rect = 0)
+ try:
+ try:
+ self.undo.Undo()
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction(issue = UNDO)
script_access['Undo'] = SCRIPT_GET
def add_undo(self, *infos):
- # Add undoinfo for the current transaction. should not be called
- # when not in a transaction.
- if infos:
- if type(infos[0]) == StringType:
- if not self.transaction_name:
- self.transaction_name = infos[0]
- infos = infos[1:]
- if not infos:
- return
- for info in infos:
- if type(info) == ListType:
- info = CreateListUndo(info)
- else:
- if type(info[0]) == StringType:
- if __debug__:
- pdebug(None, 'add_undo: info contains text')
- info = info[1:]
- self.transaction_undo.append(info)
+ # Add undoinfo for the current transaction. should not be called
+ # when not in a transaction.
+ if infos:
+ if type(infos[0]) == StringType:
+ if not self.transaction_name:
+ self.transaction_name = infos[0]
+ infos = infos[1:]
+ if not infos:
+ return
+ for info in infos:
+ if type(info) == ListType:
+ info = CreateListUndo(info)
+ else:
+ if type(info[0]) == StringType:
+ if __debug__:
+ pdebug(None, 'add_undo: info contains text')
+ info = info[1:]
+ self.transaction_undo.append(info)
# public version of add_undo. to be called between calls to
# BeginTransaction and EndTransaction/AbortTransaction
AddUndo = add_undo
def __undo_set_sel(self, selclass, selinfo, redo_class, redo_info):
- old_class = self.selection.__class__
- if old_class != selclass:
- self.selection = selclass(selinfo)
- self.queue_message(MODE)
- else:
- # keep the same selection object to avoid creating a new
- # editor object in EditMode
- self.selection.SetSelection(selinfo)
- self.queue_selection()
- return (self.__undo_set_sel, redo_class, redo_info, selclass, selinfo)
+ old_class = self.selection.__class__
+ if old_class != selclass:
+ self.selection = selclass(selinfo)
+ self.queue_message(MODE)
+ else:
+ # keep the same selection object to avoid creating a new
+ # editor object in EditMode
+ self.selection.SetSelection(selinfo)
+ self.queue_selection()
+ return (self.__undo_set_sel, redo_class, redo_info, selclass, selinfo)
def __real_add_undo(self, text, undo, selinfo = None, selclass = None):
- if undo is not NullUndo:
- if selinfo is not None:
- new_class = self.selection.__class__
- new_info = self.selection.GetInfo()[:]
- if new_info == selinfo:
- # make both lists identical
- new_info = selinfo
- undo_sel = (self.__undo_set_sel, selclass, selinfo,
- new_class, new_info)
- info = (text, UndoAfter, undo_sel, undo)
- else:
- info = (text, undo)
- self.undo.AddUndo(info)
- self.queue_message(UNDO)
+ if undo is not NullUndo:
+ if selinfo is not None:
+ new_class = self.selection.__class__
+ new_info = self.selection.GetInfo()[:]
+ if new_info == selinfo:
+ # make both lists identical
+ new_info = selinfo
+ undo_sel = (self.__undo_set_sel, selclass, selinfo,
+ new_class, new_info)
+ info = (text, UndoAfter, undo_sel, undo)
+ else:
+ info = (text, undo)
+ self.undo.AddUndo(info)
+ self.queue_message(UNDO)
def Redo(self):
- if self.undo.CanRedo():
- self.begin_transaction(clear_selection_rect = 0)
- try:
- try:
- self.undo.Redo()
- except:
- self.abort_transaction()
- finally:
- self.end_transaction(issue = UNDO)
+ if self.undo.CanRedo():
+ self.begin_transaction(clear_selection_rect = 0)
+ try:
+ try:
+ self.undo.Redo()
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction(issue = UNDO)
script_access['Redo'] = SCRIPT_GET
def ResetUndo(self):
- self.begin_transaction(clear_selection_rect = 0)
- try:
- try:
- self.undo.Reset()
- except:
- self.abort_transaction()
- finally:
- self.end_transaction(issue = UNDO)
+ self.begin_transaction(clear_selection_rect = 0)
+ try:
+ try:
+ self.undo.Reset()
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction(issue = UNDO)
script_access['ResetUndo'] = SCRIPT_GET
def UndoMenuText(self):
- return self.undo.UndoText()
+ return self.undo.UndoText()
script_access['UndoMenuText'] = SCRIPT_GET
def RedoMenuText(self):
- return self.undo.RedoText()
+ return self.undo.RedoText()
script_access['RedoMenuText'] = SCRIPT_GET
def SetUndoLimit(self, limit):
- self.begin_transaction(clear_selection_rect = 0)
- try:
- try:
- self.undo.SetUndoLimit(limit)
- except:
- self.abort_transaction()
- finally:
- self.end_transaction(issue = UNDO)
+ self.begin_transaction(clear_selection_rect = 0)
+ try:
+ try:
+ self.undo.SetUndoLimit(limit)
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction(issue = UNDO)
script_access['SetUndoLimit'] = SCRIPT_GET
def WasEdited(self):
- # return true if document has changed since last save
- return self.undo.UndoCount()
+ # return true if document has changed since last save
+ return self.undo.UndoCount()
script_access['WasEdited'] = SCRIPT_GET
def ClearEdited(self):
- self.undo.ResetUndoCount()
- self.issue(UNDO)
+ self.undo.ResetUndoCount()
+ self.issue(UNDO)
#
#
def apply_to_selected(self, undo_text, func):
- if self.selection:
- self.begin_transaction(undo_text)
- try:
- try:
- self.add_undo(self.selection.ForAllUndo(func))
- self.queue_selection()
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ if self.selection:
+ self.begin_transaction(undo_text)
+ try:
+ try:
+ self.add_undo(self.selection.ForAllUndo(func))
+ self.queue_selection()
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def AddStyle(self, style):
- if type(style) == StringType:
- style = self.GetDynamicStyle(style)
- self.apply_to_selected(_("Add Style"),
- lambda o, style = style: o.AddStyle(style))
+ if type(style) == StringType:
+ style = self.GetDynamicStyle(style)
+ self.apply_to_selected(_("Add Style"),
+ lambda o, style = style: o.AddStyle(style))
def SetLineColor(self, color):
- # Set the line color of the currently selected objects.
- # XXX this method shpuld be removed in favour of the more
- # generic SetProperties.
- self.SetProperties(line_pattern = SolidPattern(color),
- if_type_present = 1)
+ # Set the line color of the currently selected objects.
+ # XXX this method shpuld be removed in favour of the more
+ # generic SetProperties.
+ self.SetProperties(line_pattern = SolidPattern(color),
+ if_type_present = 1)
def SetProperties(self, **kw):
- self.apply_to_selected(_("Set Properties"),
- lambda o, kw=kw: apply(o.SetProperties, (), kw))
+ self.apply_to_selected(_("Set Properties"),
+ lambda o, kw=kw: apply(o.SetProperties, (), kw))
def SetStyle(self, style):
- if type(style) == StringType:
- style = self.get_dynamic_style(style)
- self.AddStyle(style)
+ if type(style) == StringType:
+ style = self.get_dynamic_style(style)
+ self.AddStyle(style)
#
# Deleting and rearranging objects...
#
def remove_objects(self, infolist):
- split = selinfo.list_to_tree(infolist)
- undo = []
- try:
- for layer, infolist in split:
- undo.append(self.layers[layer].RemoveObjects(infolist))
- return CreateListUndo(undo)
- except:
- Undo(CreateListUndo(undo))
- raise
+ split = selinfo.list_to_tree(infolist)
+ undo = []
+ try:
+ for layer, infolist in split:
+ undo.append(self.layers[layer].RemoveObjects(infolist))
+ return CreateListUndo(undo)
+ except:
+ Undo(CreateListUndo(undo))
+ raise
def remove_selected(self):
- return self.remove_objects(self.selection.GetInfo())
+ return self.remove_objects(self.selection.GetInfo())
def RemoveSelected(self):
- # Remove all selected objects. After successful completion, the
- # selection will be empty.
- if self.selection:
- self.begin_transaction(_("Delete"))
- try:
- try:
- self.add_undo(self.remove_selected())
- self.__set_selection(None, SelectSet)
- self.add_undo(self.queue_edited())
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ # Remove all selected objects. After successful completion, the
+ # selection will be empty.
+ if self.selection:
+ self.begin_transaction(_("Delete"))
+ try:
+ try:
+ self.add_undo(self.remove_selected())
+ self.__set_selection(None, SelectSet)
+ self.add_undo(self.queue_edited())
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def __call_layer_method_sel(self, undotext, methodname, *args):
- if not self.selection:
- return
- self.begin_transaction(undotext)
- try:
- try:
- split = selinfo.list_to_tree(self.selection.GetInfo())
- edited = 0
- selection = []
- for layer, infolist in split:
- method = getattr(self.layers[layer], methodname)
- sel, undo = apply(method, (infolist,) + args)
- if undo is not NullUndo:
- self.add_undo(undo)
- edited = 1
- selection = selection + self.augment_sel_info(sel, layer)
- self.__set_selection(selection, SelectSet)
- if edited:
- self.add_undo(self.queue_edited())
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ if not self.selection:
+ return
+ self.begin_transaction(undotext)
+ try:
+ try:
+ split = selinfo.list_to_tree(self.selection.GetInfo())
+ edited = 0
+ selection = []
+ for layer, infolist in split:
+ method = getattr(self.layers[layer], methodname)
+ sel, undo = apply(method, (infolist,) + args)
+ if undo is not NullUndo:
+ self.add_undo(undo)
+ edited = 1
+ selection = selection + self.augment_sel_info(sel, layer)
+ self.__set_selection(selection, SelectSet)
+ if edited:
+ self.add_undo(self.queue_edited())
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def MoveSelectedToTop(self):
- self.__call_layer_method_sel(_("Move To Top"), 'MoveObjectsToTop')
+ self.__call_layer_method_sel(_("Move To Top"), 'MoveObjectsToTop')
def MoveSelectedToBottom(self):
- self.__call_layer_method_sel(_("Move To Bottom"),'MoveObjectsToBottom')
+ self.__call_layer_method_sel(_("Move To Bottom"),'MoveObjectsToBottom')
def MoveSelectionDown(self):
- self.__call_layer_method_sel(_("Lower"), 'MoveObjectsDown')
+ self.__call_layer_method_sel(_("Lower"), 'MoveObjectsDown')
def MoveSelectionUp(self):
- self.__call_layer_method_sel(_("Raise"), 'MoveObjectsUp')
+ self.__call_layer_method_sel(_("Raise"), 'MoveObjectsUp')
def MoveSelectionToLayer(self, layer):
- if self.selection:
- self.begin_transaction(_("Move Selection to `%s'")
- % self.layers[layer].Name())
- try:
- try:
- # remove the objects from the document...
- self.add_undo(self.remove_selected())
- # ... and insert them a the end of the layer
- objects = self.selection.GetObjects()
- select, undo_insert = self.insert(objects, layer = layer)
+ if self.selection:
+ self.begin_transaction(_("Move Selection to `%s'")
+ % self.layers[layer].Name())
+ try:
+ try:
+ # remove the objects from the document...
+ self.add_undo(self.remove_selected())
+ # ... and insert them a the end of the layer
+ objects = self.selection.GetObjects()
+ select, undo_insert = self.insert(objects, layer = layer)
- self.add_undo(undo_insert)
- self.__set_selection(select, SelectSet)
- self.add_undo(self.queue_edited())
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ self.add_undo(undo_insert)
+ self.__set_selection(select, SelectSet)
+ self.add_undo(self.queue_edited())
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
#
# Cut/Copy
#
def copy_objects(self, objects):
- copies = []
- for obj in objects:
- copies.append(obj.Duplicate())
+ copies = []
+ for obj in objects:
+ copies.append(obj.Duplicate())
- if len(copies) > 1:
- copies = Group(copies)
- else:
- copies = copies[0]
+ if len(copies) > 1:
+ copies = Group(copies)
+ else:
+ copies = copies[0]
# This is ugly: Special case for internal path text objects.
# If the internal path text object is the only selected
# object, turn the copy into a normal simple text object.
@@ -1401,41 +1401,41 @@
copies = text.SimpleText(text = copies.Text(),
properties = properties)
- copies.UntieFromDocument()
- copies.SetDocument(None)
- return copies
+ copies.UntieFromDocument()
+ copies.SetDocument(None)
+ return copies
def CopyForClipboard(self):
- if self.selection:
- return self.copy_objects(self.selection.GetObjects())
+ if self.selection:
+ return self.copy_objects(self.selection.GetObjects())
def CutForClipboard(self):
- result = None
- if self.selection:
- self.begin_transaction(_("Cut"))
- try:
- try:
- objects = self.selection.GetObjects()
- result = self.copy_objects(objects)
- self.add_undo(self.remove_selected())
- self.__set_selection(None, SelectSet)
- self.add_undo(self.queue_edited())
- except:
- result = None
- self.abort_transaction()
- finally:
- self.end_transaction()
- return result
+ result = None
+ if self.selection:
+ self.begin_transaction(_("Cut"))
+ try:
+ try:
+ objects = self.selection.GetObjects()
+ result = self.copy_objects(objects)
+ self.add_undo(self.remove_selected())
+ self.__set_selection(None, SelectSet)
+ self.add_undo(self.queue_edited())
+ except:
+ result = None
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
+ return result
#
# Duplicate
#
def DuplicateSelected(self, offset = None):
- if offset is None:
- offset = Point(config.preferences.duplicate_offset)
- self.__call_layer_method_sel(_("Duplicate"), 'DuplicateObjects',
- offset)
+ if offset is None:
+ offset = Point(config.preferences.duplicate_offset)
+ self.__call_layer_method_sel(_("Duplicate"), 'DuplicateObjects',
+ offset)
#
# Group
@@ -1464,65 +1464,65 @@
self.end_transaction()
def CanGroup(self):
- return len(self.selection) > 1
+ return len(self.selection) > 1
def GroupSelected(self):
- if self.CanGroup():
+ if self.CanGroup():
self.group_selected(_("Create Group"), Group)
def CanUngroup(self):
- infos = self.selection.GetInfo()
- return len(infos) == 1 and infos[0][-1].is_Group
+ infos = self.selection.GetInfo()
+ return len(infos) == 1 and infos[0][-1].is_Group
def UngroupSelected(self):
- if self.CanUngroup():
- self.begin_transaction(_("Ungroup"))
- try:
- try:
- self.add_undo(self.remove_selected())
- info, group = self.selection.GetInfo()[0]
- objects = group.Ungroup()
- select, undo_insert = self.insert(objects, at = info[1:],
- layer = info[0])
- self.add_undo(undo_insert)
- self.__set_selection(select, SelectSet)
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ if self.CanUngroup():
+ self.begin_transaction(_("Ungroup"))
+ try:
+ try:
+ self.add_undo(self.remove_selected())
+ info, group = self.selection.GetInfo()[0]
+ objects = group.Ungroup()
+ select, undo_insert = self.insert(objects, at = info[1:],
+ layer = info[0])
+ self.add_undo(undo_insert)
+ self.__set_selection(select, SelectSet)
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def CanCreateMaskGroup(self):
- infos = self.selection.GetInfo()
- return len(infos) > 1 and infos[-1][-1].is_clip
+ infos = self.selection.GetInfo()
+ return len(infos) > 1 and infos[-1][-1].is_clip
def CreateMaskGroup(self):
- if self.CanCreateMaskGroup():
- self.begin_transaction(_("Create Mask Group"))
- try:
- try:
- import maskgroup
- self.add_undo(self.remove_selected())
- objects = self.selection.GetObjects()
- if config.preferences.topmost_is_mask:
- mask = objects[-1]
- del objects[-1]
- objects.insert(0, mask)
- group = maskgroup.MaskGroup(objects)
- parent = selinfo.common_prefix(self.selection.GetInfo())
- if parent:
- layer = parent[0]
- at = parent[1:]
- else:
- layer = None
- at = None
- select, undo_insert = self.insert(group, at = at,
- layer = layer)
- self.add_undo(undo_insert)
- self.__set_selection(select, SelectSet)
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ if self.CanCreateMaskGroup():
+ self.begin_transaction(_("Create Mask Group"))
+ try:
+ try:
+ import maskgroup
+ self.add_undo(self.remove_selected())
+ objects = self.selection.GetObjects()
+ if config.preferences.topmost_is_mask:
+ mask = objects[-1]
+ del objects[-1]
+ objects.insert(0, mask)
+ group = maskgroup.MaskGroup(objects)
+ parent = selinfo.common_prefix(self.selection.GetInfo())
+ if parent:
+ layer = parent[0]
+ at = parent[1:]
+ else:
+ layer = None
+ at = None
+ select, undo_insert = self.insert(group, at = at,
+ layer = layer)
+ self.add_undo(undo_insert)
+ self.__set_selection(select, SelectSet)
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
#
@@ -1530,14 +1530,14 @@
#
def TransformSelected(self, trafo, undo_text = _("Transform")):
- self.apply_to_selected(undo_text, lambda o, t = trafo: o.Transform(t))
+ self.apply_to_selected(undo_text, lambda o, t = trafo: o.Transform(t))
def TranslateSelected(self, offset, undo_text = _("Translate")):
- self.apply_to_selected(undo_text, lambda o, v = offset: o.Translate(v))
+ self.apply_to_selected(undo_text, lambda o, v = offset: o.Translate(v))
def RemoveTransformation(self):
- self.apply_to_selected(_("Remove Transformation"),
- lambda o: o.RemoveTransformation())
+ self.apply_to_selected(_("Remove Transformation"),
+ lambda o: o.RemoveTransformation())
#
# Align, Flip, ...
@@ -1548,294 +1548,294 @@
def AlignSelection(self, x, y, reference = 'selection'):
if self.selection and (x or y):
- self.begin_transaction(_("Align Objects"))
- try:
- try:
+ self.begin_transaction(_("Align Objects"))
+ try:
+ try:
add_undo = self.add_undo
objects = self.selection.GetObjects()
- if reference == 'page':
- br = self.PageRect()
+ if reference == 'page':
+ br = self.PageRect()
elif reference == 'lowermost':
br = objects[0].coord_rect
- else:
- br = self.selection.coord_rect
- for obj in objects:
- r = obj.coord_rect
- xoff = yoff = 0
- if x == 1:
- xoff = br.left - r.left
- elif x == 3:
- xoff = br.right - r.right
- elif x == 2:
- xoff = (br.left + br.right - r.left - r.right) / 2
+ else:
+ br = self.selection.coord_rect
+ for obj in objects:
+ r = obj.coord_rect
+ xoff = yoff = 0
+ if x == 1:
+ xoff = br.left - r.left
+ elif x == 3:
+ xoff = br.right - r.right
+ elif x == 2:
+ xoff = (br.left + br.right - r.left - r.right) / 2
- if y == 1:
- yoff = br.top - r.top
- elif y == 3:
- yoff = br.bottom - r.bottom
- elif y == 2:
- yoff = (br.top + br.bottom - r.top - r.bottom) / 2
+ if y == 1:
+ yoff = br.top - r.top
+ elif y == 3:
+ yoff = br.bottom - r.bottom
+ elif y == 2:
+ yoff = (br.top + br.bottom - r.top - r.bottom) / 2
- add_undo(obj.Translate(Point(xoff, yoff)))
+ add_undo(obj.Translate(Point(xoff, yoff)))
- add_undo(self.queue_edited())
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ add_undo(self.queue_edited())
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def AbutHorizontal(self):
- if len(self.selection) > 1:
- self.begin_transaction(_("Abut Horizontal"))
- try:
- try:
- pos = []
- for obj in self.selection.GetObjects():
- rect = obj.coord_rect
- pos.append((rect.left, rect.top,
- rect.right - rect.left, obj))
- pos.sort()
- undo = []
- start, top, width, ob = pos[0]
- next = start + width
- for left, top, width, obj in pos[1:]:
- off = Point(next - left, 0)
- self.add_undo(obj.Translate(off))
- next = next + width
+ if len(self.selection) > 1:
+ self.begin_transaction(_("Abut Horizontal"))
+ try:
+ try:
+ pos = []
+ for obj in self.selection.GetObjects():
+ rect = obj.coord_rect
+ pos.append((rect.left, rect.top,
+ rect.right - rect.left, obj))
+ pos.sort()
+ undo = []
+ start, top, width, ob = pos[0]
+ next = start + width
+ for left, top, width, obj in pos[1:]:
+ off = Point(next - left, 0)
+ self.add_undo(obj.Translate(off))
+ next = next + width
- self.add_undo(self.queue_edited())
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ self.add_undo(self.queue_edited())
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def AbutVertical(self):
- if len(self.selection) > 1:
- self.begin_transaction(_("Abut Vertical"))
- try:
- try:
- pos = []
- for obj in self.selection.GetObjects():
- rect = obj.coord_rect
- pos.append((rect.top, -rect.left,
- rect.top - rect.bottom, obj))
- pos.sort()
- pos.reverse()
- undo = []
- start, left, height, ob = pos[0]
- next = start - height
- for top, left, height, obj in pos[1:]:
- off = Point(0, next - top)
- self.add_undo(obj.Translate(off))
- next = next - height
+ if len(self.selection) > 1:
+ self.begin_transaction(_("Abut Vertical"))
+ try:
+ try:
+ pos = []
+ for obj in self.selection.GetObjects():
+ rect = obj.coord_rect
+ pos.append((rect.top, -rect.left,
+ rect.top - rect.bottom, obj))
+ pos.sort()
+ pos.reverse()
+ undo = []
+ start, left, height, ob = pos[0]
+ next = start - height
+ for top, left, height, obj in pos[1:]:
+ off = Point(0, next - top)
+ self.add_undo(obj.Translate(off))
+ next = next - height
- self.add_undo(self.queue_edited())
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ self.add_undo(self.queue_edited())
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def FlipSelected(self, horizontal = 0, vertical = 0):
- if self.selection and (horizontal or vertical):
- self.begin_transaction()
- try:
- try:
- rect = self.selection.coord_rect
- if horizontal:
- xoff = rect.left + rect.right
- factx = -1
- text = _("Flip Horizontal")
- else:
- xoff = 0
- factx = 1
- if vertical:
- yoff = rect.top + rect.bottom
- facty = -1
- text = _("Flip Vertical")
- else:
- yoff = 0
- facty = 1
- if horizontal and vertical:
- text = _("Flip Both")
- trafo = Trafo(factx, 0, 0, facty, xoff, yoff)
- self.TransformSelected(trafo, text)
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ if self.selection and (horizontal or vertical):
+ self.begin_transaction()
+ try:
+ try:
+ rect = self.selection.coord_rect
+ if horizontal:
+ xoff = rect.left + rect.right
+ factx = -1
+ text = _("Flip Horizontal")
+ else:
+ xoff = 0
+ factx = 1
+ if vertical:
+ yoff = rect.top + rect.bottom
+ facty = -1
+ text = _("Flip Vertical")
+ else:
+ yoff = 0
+ facty = 1
+ if horizontal and vertical:
+ text = _("Flip Both")
+ trafo = Trafo(factx, 0, 0, facty, xoff, yoff)
+ self.TransformSelected(trafo, text)
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
#
#
#
def CallObjectMethod(self, aclass, description, methodname, *args):
- self.begin_transaction(description)
- try:
- try:
- undo = self.selection.CallObjectMethod(aclass, methodname,
- args)
- if undo != NullUndo:
- self.add_undo(undo)
- self.add_undo(self.queue_edited())
- # force recomputation of selections rects:
- self.selection.ResetRectangle()
- else:
- # in case the handles have to be updated
- self.queue_selection()
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ self.begin_transaction(description)
+ try:
+ try:
+ undo = self.selection.CallObjectMethod(aclass, methodname,
+ args)
+ if undo != NullUndo:
+ self.add_undo(undo)
+ self.add_undo(self.queue_edited())
+ # force recomputation of selections rects:
+ self.selection.ResetRectangle()
+ else:
+ # in case the handles have to be updated
+ self.queue_selection()
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def GetObjectMethod(self, aclass, method):
- return self.selection.GetObjectMethod(aclass, method)
+ return self.selection.GetObjectMethod(aclass, method)
def CurrentObjectCompatible(self, aclass):
- obj = self.CurrentObject()
- if obj is not None:
- if aclass.is_Editor:
- return isinstance(obj, aclass.EditedClass)
- else:
- return isinstance(obj, aclass)
- return 0
+ obj = self.CurrentObject()
+ if obj is not None:
+ if aclass.is_Editor:
+ return isinstance(obj, aclass.EditedClass)
+ else:
+ return isinstance(obj, aclass)
+ return 0
# XXX the following methods for blend groups, path text, clones and
# bezier objects should perhaps be implemented in their respective
# modules (and then somehow grafted onto the document class?)
def CanBlend(self):
- info = self.selection.GetInfo()
- if len(info) == 2:
- path1, obj1 = info[0]
- path2, obj2 = info[1]
- if len(path1) == len(path2) + 1:
- return obj1.parent.is_Blend and 2
- if len(path1) + 1 == len(path2):
- return obj2.parent.is_Blend and 2
- return len(path1) == len(path2)
- return 0
+ info = self.selection.GetInfo()
+ if len(info) == 2:
+ path1, obj1 = info[0]
+ path2, obj2 = info[1]
+ if len(path1) == len(path2) + 1:
+ return obj1.parent.is_Blend and 2
+ if len(path1) + 1 == len(path2):
+ return obj2.parent.is_Blend and 2
+ return len(path1) == len(path2)
+ return 0
def Blend(self, steps):
- info = self.selection.GetInfo()
- path1, obj1 = info[0]
- path2, obj2 = info[1]
- if len(path1) == len(path2) + 1:
- if obj1.parent.is_Blend:
- del info[0]
- else:
- return
- elif len(path1) + 1 == len(path2):
- if obj2.parent.is_Blend:
- del info[1]
- else:
- return
- elif len(path1) != len(path2):
- return
- if steps >= 2:
- import blendgroup, blend
- self.begin_transaction(_("Blend"))
- try:
- try:
- self.add_undo(self.remove_objects(info))
- try:
- blendgrp, undo = blendgroup.CreateBlendGroup(obj1,obj2,
- steps)
- self.add_undo(undo)
- except blend.MismatchError:
- warn(USER, _("I can't blend the selected objects"))
- # XXX: is there some other solution?:
- raise
+ info = self.selection.GetInfo()
+ path1, obj1 = info[0]
+ path2, obj2 = info[1]
+ if len(path1) == len(path2) + 1:
+ if obj1.parent.is_Blend:
+ del info[0]
+ else:
+ return
+ elif len(path1) + 1 == len(path2):
+ if obj2.parent.is_Blend:
+ del info[1]
+ else:
+ return
+ elif len(path1) != len(path2):
+ return
+ if steps >= 2:
+ import blendgroup, blend
+ self.begin_transaction(_("Blend"))
+ try:
+ try:
+ self.add_undo(self.remove_objects(info))
+ try:
+ blendgrp, undo = blendgroup.CreateBlendGroup(obj1,obj2,
+ steps)
+ self.add_undo(undo)
+ except blend.MismatchError:
+ warn(USER, _("I can't blend the selected objects"))
+ # XXX: is there some other solution?:
+ raise
- if len(info) == 2:
- select, undo_insert = self.insert(blendgrp,
- at = path1[1:],
- layer = path1[0])
- self.add_undo(undo_insert)
- self.__set_selection(select, SelectSet)
- else:
- self.SelectObject(blendgrp)
- self.add_undo(self.queue_edited())
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ if len(info) == 2:
+ select, undo_insert = self.insert(blendgrp,
+ at = path1[1:],
+ layer = path1[0])
+ self.add_undo(undo_insert)
+ self.__set_selection(select, SelectSet)
+ else:
+ self.SelectObject(blendgrp)
+ self.add_undo(self.queue_edited())
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def CanCancelBlend(self):
- info = self.selection.GetInfo()
- return len(info) == 1 and info[0][-1].is_Blend
+ info = self.selection.GetInfo()
+ return len(info) == 1 and info[0][-1].is_Blend
def CancelBlend(self):
- if self.CanCancelBlend():
- self.begin_transaction(_("Cancel Blend"))
- try:
- try:
- info = self.selection.GetInfo()[0]
- self.add_undo(self.remove_selected())
- group = info[-1]
- objs = group.CancelEffect()
- info = info[0]
- layer = info[0]
- at = info[1:]
- select, undo_insert = self.insert(objs, at = at,
- layer = layer)
- self.add_undo(undo_insert)
- self.__set_selection(select, SelectSet)
- self.add_undo(self.queue_edited())
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ if self.CanCancelBlend():
+ self.begin_transaction(_("Cancel Blend"))
+ try:
+ try:
+ info = self.selection.GetInfo()[0]
+ self.add_undo(self.remove_selected())
+ group = info[-1]
+ objs = group.CancelEffect()
+ info = info[0]
+ layer = info[0]
+ at = info[1:]
+ select, undo_insert = self.insert(objs, at = at,
+ layer = layer)
+ self.add_undo(undo_insert)
+ self.__set_selection(select, SelectSet)
+ self.add_undo(self.queue_edited())
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
#
#
def CanCreatePathText(self):
- return CanCreatePathText(self.selection.GetObjects())
+ return CanCreatePathText(self.selection.GetObjects())
def CreatePathText(self):
- if self.CanCreatePathText():
- self.begin_transaction(_("Create Path Text"))
- try:
- try:
- self.add_undo(self.remove_selected())
- object = CreatePathText(self.selection.GetObjects())
+ if self.CanCreatePathText():
+ self.begin_transaction(_("Create Path Text"))
+ try:
+ try:
+ self.add_undo(self.remove_selected())
+ object = CreatePathText(self.selection.GetObjects())
- select, undo_insert = self.insert(object)
- self.add_undo(undo_insert)
- self.__set_selection(select, SelectSet)
- self.add_undo(self.queue_edited())
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ select, undo_insert = self.insert(object)
+ self.add_undo(undo_insert)
+ self.__set_selection(select, SelectSet)
+ self.add_undo(self.queue_edited())
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
#
# Clone (under construction...)
#
def CanCreateClone(self):
- if len(self.selection) == 1:
- obj = self.selection.GetObjects()[0]
- return not obj.is_Compound
- return 0
+ if len(self.selection) == 1:
+ obj = self.selection.GetObjects()[0]
+ return not obj.is_Compound
+ return 0
def CreateClone(self):
- if self.CanCreateClone():
- self.begin_transaction(_("Create Clone"))
- try:
- try:
- from clone import CreateClone
- object = self.selection.GetObjects()[0]
- clone, undo_clone = CreateClone(object)
- self.add_undo(undo_clone)
- select, undo_insert = self.insert(clone)
- self.add_undo(undo_insert)
- self.__set_selection(select, SelectSet)
- self.add_undo(self.queue_edited())
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ if self.CanCreateClone():
+ self.begin_transaction(_("Create Clone"))
+ try:
+ try:
+ from clone import CreateClone
+ object = self.selection.GetObjects()[0]
+ clone, undo_clone = CreateClone(object)
+ self.add_undo(undo_clone)
+ select, undo_insert = self.insert(clone)
+ self.add_undo(undo_insert)
+ self.__set_selection(select, SelectSet)
+ self.add_undo(self.queue_edited())
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
#
@@ -1843,51 +1843,51 @@
#
def CanCombineBeziers(self):
- if len(self.selection) > 1:
- can = 1
- for obj in self.selection.GetObjects():
- can = can and obj.is_Bezier
- return can
- return 0
+ if len(self.selection) > 1:
+ can = 1
+ for obj in self.selection.GetObjects():
+ can = can and obj.is_Bezier
+ return can
+ return 0
def CombineBeziers(self):
- if self.CanCombineBeziers():
- self.begin_transaction(_("Combine Beziers"))
- try:
- try:
- self.add_undo(self.remove_selected())
- objects = self.selection.GetObjects()
- combined = CombineBeziers(objects)
- select, undo_insert = self.insert(combined)
- self.add_undo(undo_insert)
- self.__set_selection(select, SelectSet)
- self.add_undo(self.queue_edited())
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ if self.CanCombineBeziers():
+ self.begin_transaction(_("Combine Beziers"))
+ try:
+ try:
+ self.add_undo(self.remove_selected())
+ objects = self.selection.GetObjects()
+ combined = CombineBeziers(objects)
+ select, undo_insert = self.insert(combined)
+ self.add_undo(undo_insert)
+ self.__set_selection(select, SelectSet)
+ self.add_undo(self.queue_edited())
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def CanSplitBeziers(self):
- return len(self.selection) == 1 \
- and self.selection.GetObjects()[0].is_Bezier
+ return len(self.selection) == 1 \
+ and self.selection.GetObjects()[0].is_Bezier
def SplitBeziers(self):
- if self.CanSplitBeziers():
- self.begin_transaction(_("Split Beziers"))
- try:
- try:
- self.add_undo(self.remove_selected())
- info, bezier = self.selection.GetInfo()[0]
- objects = bezier.PathsAsObjects()
- select, undo_insert = self.insert(objects, at = info[1:],
- layer =info[0])
- self.add_undo(undo_insert)
- self.__set_selection(select, SelectSet)
- self.add_undo(self.queue_edited())
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ if self.CanSplitBeziers():
+ self.begin_transaction(_("Split Beziers"))
+ try:
+ try:
+ self.add_undo(self.remove_selected())
+ info, bezier = self.selection.GetInfo()[0]
+ objects = bezier.PathsAsObjects()
+ select, undo_insert = self.insert(objects, at = info[1:],
+ layer =info[0])
+ self.add_undo(undo_insert)
+ self.__set_selection(select, SelectSet)
+ self.add_undo(self.queue_edited())
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def CanConvertToCurve(self):
for obj in self.selection.GetObjects():
@@ -1896,10 +1896,10 @@
return 0
def ConvertToCurve(self):
- if self.CanConvertToCurve():
- self.begin_transaction(_("Convert To Curve"))
- try:
- try:
+ if self.CanConvertToCurve():
+ self.begin_transaction(_("Convert To Curve"))
+ try:
+ try:
selection = []
edited = 0
for info, object in self.selection.GetInfo():
@@ -1914,254 +1914,254 @@
self.__set_selection(selection, SelectSet)
if edited:
self.add_undo(self.queue_edited())
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
#
#
#
def Layers(self):
- return self.layers[:]
+ return self.layers[:]
def NumLayers(self):
- return len(self.layers)
+ return len(self.layers)
def ActiveLayer(self):
- return self.active_layer
+ return self.active_layer
def ActiveLayerIdx(self):
- if self.active_layer is None:
- return None
- return self.layers.index(self.active_layer)
+ if self.active_layer is None:
+ return None
+ return self.layers.index(self.active_layer)
def SetActiveLayer(self, idx):
- if type(idx) == IntType:
- layer = self.layers[idx]
- else:
- layer = idx
- if not layer.Locked():
- self.active_layer = layer
- self.queue_layer(LAYER_ACTIVE)
+ if type(idx) == IntType:
+ layer = self.layers[idx]
+ else:
+ layer = idx
+ if not layer.Locked():
+ self.active_layer = layer
+ self.queue_layer(LAYER_ACTIVE)
def LayerIndex(self, layer):
- return self.layers.index(layer)
+ return self.layers.index(layer)
def update_active_layer(self):
- if self.active_layer is not None and self.active_layer.CanSelect():
- return
- self.find_active_layer()
+ if self.active_layer is not None and self.active_layer.CanSelect():
+ return
+ self.find_active_layer()
def find_active_layer(self, idx = None):
- if idx is not None:
- layer = self.layers[idx]
- if layer.CanSelect():
- self.SetActiveLayer(idx)
- return
- for layer in self.layers:
- if layer.CanSelect():
- self.SetActiveLayer(layer)
- return
- self.active_layer = None
- self.queue_layer(LAYER_ACTIVE)
+ if idx is not None:
+ layer = self.layers[idx]
+ if layer.CanSelect():
+ self.SetActiveLayer(idx)
+ return
+ for layer in self.layers:
+ if layer.CanSelect():
+ self.SetActiveLayer(layer)
+ return
+ self.active_layer = None
+ self.queue_layer(LAYER_ACTIVE)
def deselect_layer(self, layer_idx):
- # Deselect all objects in layer given by layer_idx
- # Called when a layer is deleted or becomes locked
- sel = selinfo.list_to_tree(self.selection.GetInfo())
- for idx, info in sel:
- if idx == layer_idx:
- self.__set_selection(selinfo.tree_to_list([(idx, info)]),
- SelectSubtract)
+ # Deselect all objects in layer given by layer_idx
+ # Called when a layer is deleted or becomes locked
+ sel = selinfo.list_to_tree(self.selection.GetInfo())
+ for idx, info in sel:
+ if idx == layer_idx:
+ self.__set_selection(selinfo.tree_to_list([(idx, info)]),
+ SelectSubtract)
def SelectLayer(self, layer_idx, mode = SelectSet):
- # Select all children of the layer given by layer_idx
- self.begin_transaction(_("Select Layer"), clear_selection_rect = 0)
- try:
- try:
- layer = self.layers[layer_idx]
- info = self.augment_sel_info(layer.SelectAll(), layer_idx)
- self.__set_selection(info, mode)
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ # Select all children of the layer given by layer_idx
+ self.begin_transaction(_("Select Layer"), clear_selection_rect = 0)
+ try:
+ try:
+ layer = self.layers[layer_idx]
+ info = self.augment_sel_info(layer.SelectAll(), layer_idx)
+ self.__set_selection(info, mode)
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def SetLayerState(self, layer_idx, visible, printable, locked, outlined):
- self.begin_transaction(_("Change Layer State"),
- clear_selection_rect = 0)
- try:
- try:
- layer = self.layers[layer_idx]
- self.add_undo(layer.SetState(visible, printable, locked,
- outlined))
- if not layer.CanSelect():
- # XXX: this depends on whether we're drawing visible or
- # printable layers
- self.deselect_layer(layer_idx)
- self.update_active_layer()
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ self.begin_transaction(_("Change Layer State"),
+ clear_selection_rect = 0)
+ try:
+ try:
+ layer = self.layers[layer_idx]
+ self.add_undo(layer.SetState(visible, printable, locked,
+ outlined))
+ if not layer.CanSelect():
+ # XXX: this depends on whether we're drawing visible or
+ # printable layers
+ self.deselect_layer(layer_idx)
+ self.update_active_layer()
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def SetLayerColor(self, layer_idx, color):
- self.begin_transaction(_("Set Layer Outline Color"),
- clear_selection_rect = 0)
- try:
- try:
- layer = self.layers[layer_idx]
- self.add_undo(layer.SetOutlineColor(color))
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ self.begin_transaction(_("Set Layer Outline Color"),
+ clear_selection_rect = 0)
+ try:
+ try:
+ layer = self.layers[layer_idx]
+ self.add_undo(layer.SetOutlineColor(color))
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def SetLayerName(self, idx, name):
- self.begin_transaction(_("Rename Layer"), clear_selection_rect = 0)
- try:
- try:
- layer = self.layers[idx]
- self.add_undo(layer.SetName(name))
- self.add_undo(self.queue_layer())
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ self.begin_transaction(_("Rename Layer"), clear_selection_rect = 0)
+ try:
+ try:
+ layer = self.layers[idx]
+ self.add_undo(layer.SetName(name))
+ self.add_undo(self.queue_layer())
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def AppendLayer(self, *args, **kw_args):
- self.begin_transaction(_("Append Layer"),clear_selection_rect = 0)
- try:
- try:
- layer = apply(SketchDocument.AppendLayer, (self,) + args,
- kw_args)
- self.add_undo((self._remove_layer, len(self.layers) - 1))
- self.queue_layer(LAYER_ORDER, layer)
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
- return layer
+ self.begin_transaction(_("Append Layer"),clear_selection_rect = 0)
+ try:
+ try:
+ layer = apply(SketchDocument.AppendLayer, (self,) + args,
+ kw_args)
+ self.add_undo((self._remove_layer, len(self.layers) - 1))
+ self.queue_layer(LAYER_ORDER, layer)
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
+ return layer
def NewLayer(self):
- self.begin_transaction(_("New Layer"), clear_selection_rect = 0)
- try:
- try:
- self.AppendLayer()
- self.active_layer = self.layers[-1]
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ self.begin_transaction(_("New Layer"), clear_selection_rect = 0)
+ try:
+ try:
+ self.AppendLayer()
+ self.active_layer = self.layers[-1]
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def _move_layer_up(self, idx):
- # XXX: exception handling
- if idx < len(self.layers) - 1:
- # move the layer...
- layer = self.layers[idx]
- del self.layers[idx]
- self.layers.insert(idx + 1, layer)
- other = self.layers[idx]
- # ... and adjust the selection
- sel = self.selection.GetInfoTree()
- newsel = []
- for i, info in sel:
- if i == idx:
- i = idx + 1
- elif i == idx + 1:
- i = idx
- newsel.append((i, info))
- self.__set_selection(selinfo.tree_to_list(newsel), SelectSet)
- self.queue_layer(LAYER_ORDER, layer, other)
- return (self._move_layer_down, idx + 1)
- return None
+ # XXX: exception handling
+ if idx < len(self.layers) - 1:
+ # move the layer...
+ layer = self.layers[idx]
+ del self.layers[idx]
+ self.layers.insert(idx + 1, layer)
+ other = self.layers[idx]
+ # ... and adjust the selection
+ sel = self.selection.GetInfoTree()
+ newsel = []
+ for i, info in sel:
+ if i == idx:
+ i = idx + 1
+ elif i == idx + 1:
+ i = idx
+ newsel.append((i, info))
+ self.__set_selection(selinfo.tree_to_list(newsel), SelectSet)
+ self.queue_layer(LAYER_ORDER, layer, other)
+ return (self._move_layer_down, idx + 1)
+ return None
def _move_layer_down(self, idx):
- # XXX: exception handling
- if idx > 0:
- # move the layer...
- layer = self.layers[idx]
- del self.layers[idx]
- self.layers.insert(idx - 1, layer)
- other = self.layers[idx]
- # ...and adjust the selection
- sel = self.selection.GetInfoTree()
- newsel = []
- for i, info in sel:
- if i == idx:
- i = idx - 1
- elif i == idx - 1:
- i = idx
- newsel.append((i, info))
- self.__set_selection(selinfo.tree_to_list(newsel), SelectSet)
- self.queue_layer(LAYER_ORDER, layer, other)
- return (self._move_layer_up, idx - 1)
- return NullUndo
+ # XXX: exception handling
+ if idx > 0:
+ # move the layer...
+ layer = self.layers[idx]
+ del self.layers[idx]
+ self.layers.insert(idx - 1, layer)
+ other = self.layers[idx]
+ # ...and adjust the selection
+ sel = self.selection.GetInfoTree()
+ newsel = []
+ for i, info in sel:
+ if i == idx:
+ i = idx - 1
+ elif i == idx - 1:
+ i = idx
+ newsel.append((i, info))
+ self.__set_selection(selinfo.tree_to_list(newsel), SelectSet)
+ self.queue_layer(LAYER_ORDER, layer, other)
+ return (self._move_layer_up, idx - 1)
+ return NullUndo
def MoveLayerUp(self, idx):
- if idx < len(self.layers) - 1:
- self.begin_transaction(_("Move Layer Up"), clear_selection_rect=0)
- try:
- try:
- self.add_undo(self._move_layer_up(idx))
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ if idx < len(self.layers) - 1:
+ self.begin_transaction(_("Move Layer Up"), clear_selection_rect=0)
+ try:
+ try:
+ self.add_undo(self._move_layer_up(idx))
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def MoveLayerDown(self, idx):
- if idx > 0:
- self.begin_transaction(_("Move Layer Down"),clear_selection_rect=0)
- try:
- try:
- self.add_undo(self._move_layer_down(idx))
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ if idx > 0:
+ self.begin_transaction(_("Move Layer Down"),clear_selection_rect=0)
+ try:
+ try:
+ self.add_undo(self._move_layer_down(idx))
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def _remove_layer(self, idx):
- layer = self.layers[idx]
- del self.layers[idx]
- if layer is self.active_layer:
- if idx < len(self.layers):
- self.find_active_layer(idx)
- else:
- self.find_active_layer()
- sel = self.selection.GetInfoTree()
- newsel = []
- for i, info in sel:
- if i == idx:
- continue
- elif i > idx:
- i = i - 1
- newsel.append((i, info))
- self.__set_selection(selinfo.tree_to_list(newsel), SelectSet)
+ layer = self.layers[idx]
+ del self.layers[idx]
+ if layer is self.active_layer:
+ if idx < len(self.layers):
+ self.find_active_layer(idx)
+ else:
+ self.find_active_layer()
+ sel = self.selection.GetInfoTree()
+ newsel = []
+ for i, info in sel:
+ if i == idx:
+ continue
+ elif i > idx:
+ i = i - 1
+ newsel.append((i, info))
+ self.__set_selection(selinfo.tree_to_list(newsel), SelectSet)
- self.queue_layer(LAYER_ORDER, layer)
- return (self._insert_layer, idx, layer)
+ self.queue_layer(LAYER_ORDER, layer)
+ return (self._insert_layer, idx, layer)
def _insert_layer(self, idx, layer):
- self.layers.insert(idx, layer)
- layer.SetDocument(self)
- self.queue_layer(LAYER_ORDER, layer)
- return (self._remove_layer, idx)
+ self.layers.insert(idx, layer)
+ layer.SetDocument(self)
+ self.queue_layer(LAYER_ORDER, layer)
+ return (self._remove_layer, idx)
def CanDeleteLayer(self, idx):
- return (len(self.layers) > 3 and not self.layers[idx].is_SpecialLayer)
+ return (len(self.layers) > 3 and not self.layers[idx].is_SpecialLayer)
def DeleteLayer(self, idx):
- if self.CanDeleteLayer(idx):
- self.begin_transaction(_("Delete Layer"), clear_selection_rect = 0)
- try:
- try:
- self.add_undo(self._remove_layer(idx))
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ if self.CanDeleteLayer(idx):
+ self.begin_transaction(_("Delete Layer"), clear_selection_rect = 0)
+ try:
+ try:
+ self.add_undo(self._remove_layer(idx))
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
@@ -2170,50 +2170,50 @@
#
def queue_style(self):
- self.queue_message(STYLE)
- return (self.queue_style,)
+ self.queue_message(STYLE)
+ return (self.queue_style,)
def init_styles(self):
- self.styles = UndoDict()
- self.auto_assign_styles = 1
- self.asked_about = {}
+ self.styles = UndoDict()
+ self.auto_assign_styles = 1
+ self.asked_about = {}
def destroy_styles(self):
- for style in self.styles.values():
- style.Destroy()
- self.styles = None
+ for style in self.styles.values():
+ style.Destroy()
+ self.styles = None
def get_dynamic_style(self, name):
- return self.styles[name]
+ return self.styles[name]
def GetDynamicStyle(self, name):
- try:
- return self.styles[name]
- except KeyError:
- return None
+ try:
+ return self.styles[name]
+ except KeyError:
+ return None
def Styles(self):
- return self.styles.values()
+ return self.styles.values()
def write_styles(self, file):
- for style in self.styles.values():
- style.SaveToFile(file)
+ for style in self.styles.values():
+ style.SaveToFile(file)
def load_AddStyle(self, style):
- self.styles.SetItem(style.Name(), style)
+ self.styles.SetItem(style.Name(), style)
def add_dynamic_style(self, name, style):
- if style:
- style = style.AsDynamicStyle()
- self.add_undo(self.styles.SetItem(name, style))
- self.add_undo(self.queue_style())
- return style
+ if style:
+ style = style.AsDynamicStyle()
+ self.add_undo(self.styles.SetItem(name, style))
+ self.add_undo(self.queue_style())
+ return style
def update_style_dependencies(self, style):
- def update(obj, style = style):
- obj.ObjectChanged(style)
- self.WalkHierarchy(update)
- return (self.update_style_dependencies, style)
+ def update(obj, style = style):
+ obj.ObjectChanged(style)
+ self.WalkHierarchy(update)
+ return (self.update_style_dependencies, style)
def UpdateDynamicStyleSel(self):
if len(self.selection) == 1:
@@ -2247,115 +2247,115 @@
self.end_transaction()
def CanCreateStyle(self):
- if len(self.selection) == 1:
- obj = self.selection.GetObjects()[0]
- return obj.has_fill or obj.has_line
- return 0
+ if len(self.selection) == 1:
+ obj = self.selection.GetObjects()[0]
+ return obj.has_fill or obj.has_line
+ return 0
def CreateStyleFromSelection(self, name, which_properties):
- if self.CanCreateStyle():
- properties = self.CurrentProperties()
- style = properties.CreateStyle(which_properties)
- self.begin_transaction(_("Create Style %s") % name,
- clear_selection_rect = 0)
- try:
- try:
- style = self.add_dynamic_style(name, style)
- self.AddStyle(style)
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ if self.CanCreateStyle():
+ properties = self.CurrentProperties()
+ style = properties.CreateStyle(which_properties)
+ self.begin_transaction(_("Create Style %s") % name,
+ clear_selection_rect = 0)
+ try:
+ try:
+ style = self.add_dynamic_style(name, style)
+ self.AddStyle(style)
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def RemoveDynamicStyle(self, name):
- style = self.GetDynamicStyle(name)
- if not style:
- # style does not exist. XXX: raise an exception ?
- return
- self.begin_transaction(_("Remove Style %s") % name,
- clear_selection_rect = 0)
- try:
- try:
- def remove(obj, style = style, add_undo = self.add_undo):
- add_undo(obj.ObjectRemoved(style))
- self.WalkHierarchy(remove)
- self.add_undo(self.styles.DelItem(name))
- self.add_undo(self.queue_style())
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ style = self.GetDynamicStyle(name)
+ if not style:
+ # style does not exist. XXX: raise an exception ?
+ return
+ self.begin_transaction(_("Remove Style %s") % name,
+ clear_selection_rect = 0)
+ try:
+ try:
+ def remove(obj, style = style, add_undo = self.add_undo):
+ add_undo(obj.ObjectRemoved(style))
+ self.WalkHierarchy(remove)
+ self.add_undo(self.styles.DelItem(name))
+ self.add_undo(self.queue_style())
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def GetStyleNames(self):
- names = self.styles.keys()
- names.sort()
- return names
+ names = self.styles.keys()
+ names.sort()
+ return names
#
# Layout
#
def queue_layout(self):
- self.queue_message(LAYOUT)
- return (self.queue_layout,)
+ self.queue_message(LAYOUT)
+ return (self.queue_layout,)
def init_layout(self):
- self.page_layout = pagelayout.PageLayout()
+ self.page_layout = pagelayout.PageLayout()
def Layout(self):
- return self.page_layout
+ return self.page_layout
def PageSize(self):
- return (self.page_layout.Width(), self.page_layout.Height())
+ return (self.page_layout.Width(), self.page_layout.Height())
def PageRect(self):
- w, h = self.page_layout.Size()
- return Rect(0, 0, w, h)
+ w, h = self.page_layout.Size()
+ return Rect(0, 0, w, h)
def load_SetLayout(self, layout):
- self.page_layout = layout
+ self.page_layout = layout
def __set_page_layout(self, layout):
- undo = (self.__set_page_layout, self.page_layout)
- self.page_layout = layout
- self.queue_layout()
- return undo
+ undo = (self.__set_page_layout, self.page_layout)
+ self.page_layout = layout
+ self.queue_layout()
+ return undo
def SetLayout(self, layout):
- self.begin_transaction(clear_selection_rect = 0)
- try:
- try:
- undo = self.__set_page_layout(layout)
- self.add_undo(_("Change Page Layout"), undo)
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ self.begin_transaction(clear_selection_rect = 0)
+ try:
+ try:
+ undo = self.__set_page_layout(layout)
+ self.add_undo(_("Change Page Layout"), undo)
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
#
# Grid Settings
#
def queue_grid(self):
- self.queue_message(GRID)
- return (self.queue_grid,)
+ self.queue_message(GRID)
+ return (self.queue_grid,)
def SetGridGeometry(self, geometry):
- self.begin_transaction(_("Set Grid Geometry"))
- try:
- try:
- self.add_undo(self.snap_grid.SetGeometry(geometry))
- self.add_undo(self.queue_grid())
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ self.begin_transaction(_("Set Grid Geometry"))
+ try:
+ try:
+ self.add_undo(self.snap_grid.SetGeometry(geometry))
+ self.add_undo(self.queue_grid())
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def GridGeometry(self):
return self.snap_grid.Geometry()
def GridLayerChanged(self):
- return self.queue_grid()
+ return self.queue_grid()
#
@@ -2363,76 +2363,76 @@
#
def add_guide_line(self, line):
- self.begin_transaction(_("Add Guide Line"), clear_selection_rect = 0)
- try:
- try:
- sel, undo = self.guide_layer.Insert(line, 0)
- self.add_undo(undo)
- self.add_undo(self.AddClearRect(line.get_clear_rect()))
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ self.begin_transaction(_("Add Guide Line"), clear_selection_rect = 0)
+ try:
+ try:
+ sel, undo = self.guide_layer.Insert(line, 0)
+ self.add_undo(undo)
+ self.add_undo(self.AddClearRect(line.get_clear_rect()))
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def AddGuideLine(self, point, horizontal):
- self.add_guide_line(guide.GuideLine(point, horizontal))
+ self.add_guide_line(guide.GuideLine(point, horizontal))
def RemoveGuideLine(self, line):
- if not line.parent is self.guide_layer or not line.is_GuideLine:
- return
- self.begin_transaction(_("Delete Guide Line"),
- clear_selection_rect = 0)
- try:
- try:
- self.add_undo(self.remove_objects([line.SelectionInfo()]))
- self.add_undo(self.AddClearRect(line.get_clear_rect()))
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ if not line.parent is self.guide_layer or not line.is_GuideLine:
+ return
+ self.begin_transaction(_("Delete Guide Line"),
+ clear_selection_rect = 0)
+ try:
+ try:
+ self.add_undo(self.remove_objects([line.SelectionInfo()]))
+ self.add_undo(self.AddClearRect(line.get_clear_rect()))
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def MoveGuideLine(self, line, point):
- if not line.parent is self.guide_layer or not line.is_GuideLine:
- return
- self.begin_transaction(_("Move Guide Line"), clear_selection_rect = 0)
- try:
- try:
- self.add_undo(self.AddClearRect(line.get_clear_rect()))
- self.add_undo(line.SetPoint(point))
- self.add_undo(self.AddClearRect(line.get_clear_rect()))
- self.add_undo(self.GuideLayerChanged(line.parent))
- except:
- self.abort_transaction()
- finally:
- self.end_transaction()
+ if not line.parent is self.guide_layer or not line.is_GuideLine:
+ return
+ self.begin_transaction(_("Move Guide Line"), clear_selection_rect = 0)
+ try:
+ try:
+ self.add_undo(self.AddClearRect(line.get_clear_rect()))
+ self.add_undo(line.SetPoint(point))
+ self.add_undo(self.AddClearRect(line.get_clear_rect()))
+ self.add_undo(self.GuideLayerChanged(line.parent))
+ except:
+ self.abort_transaction()
+ finally:
+ self.end_transaction()
def GuideLayerChanged(self, layer):
- self.queue_message(GUIDE_LINES, layer)
- return (self.GuideLayerChanged, layer)
+ self.queue_message(GUIDE_LINES, layer)
+ return (self.GuideLayerChanged, layer)
def GuideLines(self):
- return self.guide_layer.GuideLines()
+ return self.guide_layer.GuideLines()
#
#
def as_group(self):
- for name in self.GetStyleNames():
- self.RemoveDynamicStyle(name)
- layers = self.layers
- self.layers = []
- groups = []
- for layer in layers:
- if not layer.is_SpecialLayer:
- layer.UntieFromDocument()
- objects = layer.GetObjects()
- layer.objects = []
- if objects:
- groups.append(Group(objects))
- else:
- layer.Destroy()
- if groups:
- return Group(groups)
- else:
- return None
+ for name in self.GetStyleNames():
+ self.RemoveDynamicStyle(name)
+ layers = self.layers
+ self.layers = []
+ groups = []
+ for layer in layers:
+ if not layer.is_SpecialLayer:
+ layer.UntieFromDocument()
+ objects = layer.GetObjects()
+ layer.objects = []
+ if objects:
+ groups.append(Group(objects))
+ else:
+ layer.Destroy()
+ if groups:
+ return Group(groups)
+ else:
+ return None
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/ellipse.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/ellipse.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/ellipse.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -47,16 +47,16 @@
# helper function for snapping (might be useful elsewhere too):
def snap_to_line(start, end, p):
if start != end:
- result = [(abs(start - p), start), (abs(end - p), end)]
- v = end - start
- length = abs(v)
- r = (v * (p - start)) / (length ** 2)
- if 0 <= r <= 1.0:
- p2 = start + r * v
- result.append((abs(p2 - p), p2))
- return min(result)
+ result = [(abs(start - p), start), (abs(end - p), end)]
+ v = end - start
+ length = abs(v)
+ r = (v * (p - start)) / (length ** 2)
+ if 0 <= r <= 1.0:
+ p2 = start + r * v
+ result.append((abs(p2 - p), p2))
+ return min(result)
else:
- return (abs(start - p), start)
+ return (abs(start - p), start)
@@ -70,42 +70,42 @@
commands = RectangularPrimitive.commands[:]
def __init__(self, trafo = None, start_angle = 0.0, end_angle = 0.0,
- arc_type = ArcPieSlice, properties = None, duplicate = None):
- if duplicate is not None:
- self.start_angle = duplicate.start_angle
- self.end_angle = duplicate.end_angle
- self.arc_type = duplicate.arc_type
- else:
- self.start_angle = start_angle
- self.end_angle = end_angle
- self.arc_type = arc_type
- RectangularPrimitive.__init__(self, trafo, properties = properties,
- duplicate = duplicate)
- self.normalize()
+ arc_type = ArcPieSlice, properties = None, duplicate = None):
+ if duplicate is not None:
+ self.start_angle = duplicate.start_angle
+ self.end_angle = duplicate.end_angle
+ self.arc_type = duplicate.arc_type
+ else:
+ self.start_angle = start_angle
+ self.end_angle = end_angle
+ self.arc_type = arc_type
+ RectangularPrimitive.__init__(self, trafo, properties = properties,
+ duplicate = duplicate)
+ self.normalize()
def DrawShape(self, device, rect = None, clip = 0):
- Primitive.DrawShape(self, device)
- device.SimpleEllipse(self.trafo, self.start_angle, self.end_angle,
- self.arc_type, rect, clip)
+ Primitive.DrawShape(self, device)
+ device.SimpleEllipse(self.trafo, self.start_angle, self.end_angle,
+ self.arc_type, rect, clip)
def SetAngles(self, start_angle, end_angle):
- undo = (self.SetAngles, self.start_angle, self.end_angle)
- self.start_angle = start_angle
- self.end_angle = end_angle
- self.normalize()
- self._changed()
- return undo
+ undo = (self.SetAngles, self.start_angle, self.end_angle)
+ self.start_angle = start_angle
+ self.end_angle = end_angle
+ self.normalize()
+ self._changed()
+ return undo
def Angles(self):
return self.start_angle, self.end_angle
def SetArcType(self, arc_type):
- if arc_type == self.arc_type:
- return NullUndo
- undo = (self.SetArcType, self.arc_type)
- self.arc_type = arc_type
- self._changed()
- return undo
+ if arc_type == self.arc_type:
+ return NullUndo
+ undo = (self.SetArcType, self.arc_type)
+ self.arc_type = arc_type
+ self._changed()
+ return undo
def ArcType(self):
return self.arc_type
@@ -113,21 +113,21 @@
AddCmd(commands, 'EllipseArc', _("Arc"), SetArcType, args = ArcArc)
AddCmd(commands, 'EllipseChord', _("Chord"), SetArcType, args = ArcChord)
AddCmd(commands, 'EllipsePieSlice', _("Pie Slice"), SetArcType,
- args = ArcPieSlice)
+ args = ArcPieSlice)
def normalize(self):
- pi2 = 2 * pi
- self.start_angle = fmod(self.start_angle, pi2)
- if self.start_angle < 0:
- self.start_angle = self.start_angle + pi2
- self.end_angle = fmod(self.end_angle, pi2)
- if self.end_angle < 0:
- self.end_angle = self.end_angle + pi2
+ pi2 = 2 * pi
+ self.start_angle = fmod(self.start_angle, pi2)
+ if self.start_angle < 0:
+ self.start_angle = self.start_angle + pi2
+ self.end_angle = fmod(self.end_angle, pi2)
+ if self.end_angle < 0:
+ self.end_angle = self.end_angle + pi2
def Paths(self):
path = _sketch.approx_arc(self.start_angle, self.end_angle,
self.arc_type)
- path.Transform(self.trafo)
+ path.Transform(self.trafo)
return (path,)
def AsBezier(self):
@@ -135,92 +135,92 @@
properties = self.properties.Duplicate())
def Hit(self, p, rect, device, clip = 0):
- return device.SimpleEllipseHit(p, self.trafo, self.start_angle,
- self.end_angle, self.arc_type,
- self.properties, self.Filled() or clip,
- ignore_outline_mode = clip)
+ return device.SimpleEllipseHit(p, self.trafo, self.start_angle,
+ self.end_angle, self.arc_type,
+ self.properties, self.Filled() or clip,
+ ignore_outline_mode = clip)
def Blend(self, other, p, q):
- blended = RectangularPrimitive.Blend(self, other, p, q)
- if self.start_angle != self.end_angle \
- or other.start_angle != other.end_angle:
- blended.start_angle = p * self.start_angle + q * other.start_angle
- blended.end_angle = p * self.end_angle + q * other.end_angle
- if self.start_angle == self.end_angle:
- blended.arc_type = other.arc_type
- elif other.start_angle == other.end_angle:
- blended.arc_type = self.arc_type
- else:
- if self.arc_type == other.arc_type:
- blended.arc_type = self.arc_type
- # The rest of the arc type blends is quite arbitrary
- # XXX: are these rules acceptable? Maybe we should blend
- # the ellipses as bezier curves if the arc types differ
- elif self.arc_type == ArcArc or other.arc_type == ArcArc:
- blended.arc_type = ArcArc
- elif self.arc_type == ArcChord or other.arc_type == ArcChord:
- blended.arc_type = ArcChord
- else:
- blended.arc_type = ArcPieSlice
- return blended
+ blended = RectangularPrimitive.Blend(self, other, p, q)
+ if self.start_angle != self.end_angle \
+ or other.start_angle != other.end_angle:
+ blended.start_angle = p * self.start_angle + q * other.start_angle
+ blended.end_angle = p * self.end_angle + q * other.end_angle
+ if self.start_angle == self.end_angle:
+ blended.arc_type = other.arc_type
+ elif other.start_angle == other.end_angle:
+ blended.arc_type = self.arc_type
+ else:
+ if self.arc_type == other.arc_type:
+ blended.arc_type = self.arc_type
+ # The rest of the arc type blends is quite arbitrary
+ # XXX: are these rules acceptable? Maybe we should blend
+ # the ellipses as bezier curves if the arc types differ
+ elif self.arc_type == ArcArc or other.arc_type == ArcArc:
+ blended.arc_type = ArcArc
+ elif self.arc_type == ArcChord or other.arc_type == ArcChord:
+ blended.arc_type = ArcChord
+ else:
+ blended.arc_type = ArcPieSlice
+ return blended
def GetSnapPoints(self):
- t = self.trafo
- start_angle = self.start_angle; end_angle = self.end_angle
- if self.start_angle == self.end_angle:
- a = Point(t.m11, t.m21)
- b = Point(t.m12, t.m22)
- c = t.offset()
- return [c, c + a, c - a, c + b, c - b]
- else:
- points = [t(Polar(start_angle)), t(Polar(end_angle)), t.offset()]
- if end_angle < start_angle:
- end_angle = end_angle + 2 * pi
- pi2 = pi / 2
- angle = pi2 * (floor(start_angle / pi2) + 1)
- while angle < end_angle:
- points.append(t(Polar(1, angle)))
- angle = angle + pi2
- return points
+ t = self.trafo
+ start_angle = self.start_angle; end_angle = self.end_angle
+ if self.start_angle == self.end_angle:
+ a = Point(t.m11, t.m21)
+ b = Point(t.m12, t.m22)
+ c = t.offset()
+ return [c, c + a, c - a, c + b, c - b]
+ else:
+ points = [t(Polar(start_angle)), t(Polar(end_angle)), t.offset()]
+ if end_angle < start_angle:
+ end_angle = end_angle + 2 * pi
+ pi2 = pi / 2
+ angle = pi2 * (floor(start_angle / pi2) + 1)
+ while angle < end_angle:
+ points.append(t(Polar(1, angle)))
+ angle = angle + pi2
+ return points
def Snap(self, p):
- try:
- r, phi = self.trafo.inverse()(p).polar()
- start_angle = self.start_angle; end_angle = self.end_angle
- p2 = self.trafo(Polar(1, phi))
- if start_angle == end_angle:
- result = (abs(p - p2), p2)
- else:
- result = []
- if phi < 0:
- phi = phi + 2 * pi
- if start_angle < end_angle:
- between = start_angle <= phi <= end_angle
- else:
- between = start_angle <= phi or phi <= end_angle
- if between:
- result.append((abs(p - p2), p2))
- start = self.trafo(Polar(self.start_angle))
- end = self.trafo(Polar(self.end_angle))
- if self.arc_type == ArcArc:
- result.append((abs(start - p), start))
- result.append((abs(end - p), end))
- elif self.arc_type == ArcChord:
- result.append((snap_to_line(start, end, p)))
- elif self.arc_type == ArcPieSlice:
- center = self.trafo.offset()
- result.append(snap_to_line(start, center, p))
- result.append(snap_to_line(end, center, p))
- result = min(result)
- return result
- except SingularMatrix:
- # XXX this case could be handled better.
- return (1e200, p)
+ try:
+ r, phi = self.trafo.inverse()(p).polar()
+ start_angle = self.start_angle; end_angle = self.end_angle
+ p2 = self.trafo(Polar(1, phi))
+ if start_angle == end_angle:
+ result = (abs(p - p2), p2)
+ else:
+ result = []
+ if phi < 0:
+ phi = phi + 2 * pi
+ if start_angle < end_angle:
+ between = start_angle <= phi <= end_angle
+ else:
+ between = start_angle <= phi or phi <= end_angle
+ if between:
+ result.append((abs(p - p2), p2))
+ start = self.trafo(Polar(self.start_angle))
+ end = self.trafo(Polar(self.end_angle))
+ if self.arc_type == ArcArc:
+ result.append((abs(start - p), start))
+ result.append((abs(end - p), end))
+ elif self.arc_type == ArcChord:
+ result.append((snap_to_line(start, end, p)))
+ elif self.arc_type == ArcPieSlice:
+ center = self.trafo.offset()
+ result.append(snap_to_line(start, center, p))
+ result.append(snap_to_line(end, center, p))
+ result = min(result)
+ return result
+ except SingularMatrix:
+ # XXX this case could be handled better.
+ return (1e200, p)
def update_rects(self):
- trafo = self.trafo
- start = trafo.offset()
+ trafo = self.trafo
+ start = trafo.offset()
# On some systems, atan2 can raise a ValueError if both
# parameters are 0. In that case, the actual value the of angle
# is not important since in the computation of p below, the
@@ -235,46 +235,46 @@
phi2 = atan2(trafo.m22, trafo.m21)
except ValueError:
phi2 = 0
- p = Point(trafo.m11 * cos(phi1) + trafo.m12 * sin(phi1),
- trafo.m21 * cos(phi2) + trafo.m22 * sin(phi2))
- self.coord_rect = r = Rect(start + p, start - p)
- if self.properties.HasLine():
- width = self.properties.line_width
- r = r.grown(width / 2 + 1)
- # add the bounding boxes of arrows
- if self.arc_type == ArcArc:
- pi2 = pi / 2
- arrow1 = self.properties.line_arrow1
- if arrow1 is not None:
- pos = trafo(Polar(1, self.start_angle))
- dir = trafo.DTransform(Polar(1, self.start_angle - pi2))
- r = UnionRects(r, arrow1.BoundingRect(pos, dir, width))
- arrow2 = self.properties.line_arrow2
- if arrow2 is not None:
- pos = trafo(Polar(1, self.end_angle))
- dir = trafo.DTransform(Polar(1, self.end_angle + pi2))
- r = UnionRects(r, arrow2.BoundingRect(pos, dir, width))
- self.bounding_rect = r
+ p = Point(trafo.m11 * cos(phi1) + trafo.m12 * sin(phi1),
+ trafo.m21 * cos(phi2) + trafo.m22 * sin(phi2))
+ self.coord_rect = r = Rect(start + p, start - p)
+ if self.properties.HasLine():
+ width = self.properties.line_width
+ r = r.grown(width / 2 + 1)
+ # add the bounding boxes of arrows
+ if self.arc_type == ArcArc:
+ pi2 = pi / 2
+ arrow1 = self.properties.line_arrow1
+ if arrow1 is not None:
+ pos = trafo(Polar(1, self.start_angle))
+ dir = trafo.DTransform(Polar(1, self.start_angle - pi2))
+ r = UnionRects(r, arrow1.BoundingRect(pos, dir, width))
+ arrow2 = self.properties.line_arrow2
+ if arrow2 is not None:
+ pos = trafo(Polar(1, self.end_angle))
+ dir = trafo.DTransform(Polar(1, self.end_angle + pi2))
+ r = UnionRects(r, arrow2.BoundingRect(pos, dir, width))
+ self.bounding_rect = r
def Info(self):
- trafo = self.trafo
- w = hypot(trafo.m11, trafo.m21)
- h = hypot(trafo.m12, trafo.m22)
- dict = {'center': trafo.offset(), 'radius': w, 'axes': (w, h)}
- if w == h:
- text = _("Circle radius %(radius)[length], "
+ trafo = self.trafo
+ w = hypot(trafo.m11, trafo.m21)
+ h = hypot(trafo.m12, trafo.m22)
+ dict = {'center': trafo.offset(), 'radius': w, 'axes': (w, h)}
+ if w == h:
+ text = _("Circle radius %(radius)[length], "
"center %(center)[position]")
else:
text = _("Ellipse axes %(axes)[size], center %(center)[position]")
return text, dict
def SaveToFile(self, file):
- Primitive.SaveToFile(self, file)
- file.Ellipse(self.trafo, self.start_angle, self.end_angle,
- self.arc_type)
+ Primitive.SaveToFile(self, file)
+ file.Ellipse(self.trafo, self.start_angle, self.end_angle,
+ self.arc_type)
def Editor(self):
- return EllipseEditor(self)
+ return EllipseEditor(self)
context_commands = ('EllipseArc', 'EllipseChord', 'EllipsePieSlice')
@@ -305,7 +305,7 @@
end = self.apply_constraint(self.drag_cur, state)
d = (end - start) / 2
self.trafo = Trafo(d.x, 0, 0, d.y, start.x + d.x, start.y + d.y)
-
+
def MouseMove(self, p, state):
# Bypass RectangularCreator
Creator.MouseMove(self, p, state)
@@ -316,7 +316,7 @@
self.compute_trafo(state)
def DrawDragged(self, device, partially):
- device.DrawEllipse(self.trafo(-1, -1), self.trafo(1, 1))
+ device.DrawEllipse(self.trafo(-1, -1), self.trafo(1, 1))
def CurrentInfoText(self):
t = self.trafo
@@ -331,7 +331,7 @@
return text, data
def CreatedObject(self):
- return Ellipse(self.trafo,
+ return Ellipse(self.trafo,
properties = DefaultGraphicsProperties())
@@ -342,88 +342,88 @@
selection = 0
def ButtonDown(self, p, button, state):
- if self.selection == 1:
- start = self.trafo(cos(self.start_angle), sin(self.start_angle))
- else:
- start = self.trafo(cos(self.end_angle), sin(self.end_angle))
- Editor.DragStart(self, start)
- return p - start
+ if self.selection == 1:
+ start = self.trafo(cos(self.start_angle), sin(self.start_angle))
+ else:
+ start = self.trafo(cos(self.end_angle), sin(self.end_angle))
+ Editor.DragStart(self, start)
+ return p - start
def apply_constraint(self, p, state):
- if state & ConstraintMask:
- try:
- inverse = self.trafo.inverse()
- p2 = inverse(p)
- r, phi = p2.polar()
- pi12 = pi / 12
- angle = pi12 * floor(phi / pi12 + 0.5)
- pi2 = 2 * pi
- d1 = fmod(abs(phi - angle), pi2)
- if self.selection == 1:
- selected_angle = self.end_angle
- else:
- selected_angle = self.start_angle
- d2 = fmod(abs(phi - selected_angle), pi2)
- if d2 < d1:
- phi = selected_angle
- else:
- phi = angle
- p = self.trafo(Polar(r, phi))
- except SingularMatrix:
- pass
- return p
+ if state & ConstraintMask:
+ try:
+ inverse = self.trafo.inverse()
+ p2 = inverse(p)
+ r, phi = p2.polar()
+ pi12 = pi / 12
+ angle = pi12 * floor(phi / pi12 + 0.5)
+ pi2 = 2 * pi
+ d1 = fmod(abs(phi - angle), pi2)
+ if self.selection == 1:
+ selected_angle = self.end_angle
+ else:
+ selected_angle = self.start_angle
+ d2 = fmod(abs(phi - selected_angle), pi2)
+ if d2 < d1:
+ phi = selected_angle
+ else:
+ phi = angle
+ p = self.trafo(Polar(r, phi))
+ except SingularMatrix:
+ pass
+ return p
def MouseMove(self, p, state):
- p = self.apply_constraint(p, state)
- Editor.MouseMove(self, p, state)
+ p = self.apply_constraint(p, state)
+ Editor.MouseMove(self, p, state)
def ButtonUp(self, p, button, state):
- p = self.apply_constraint(p, state)
- Editor.DragStop(self, p)
- start_angle, end_angle, arc_type = self.angles()
- return CreateMultiUndo(self.object.SetAngles(start_angle, end_angle),
- self.object.SetArcType(arc_type))
+ p = self.apply_constraint(p, state)
+ Editor.DragStop(self, p)
+ start_angle, end_angle, arc_type = self.angles()
+ return CreateMultiUndo(self.object.SetAngles(start_angle, end_angle),
+ self.object.SetArcType(arc_type))
def angles(self):
- start_angle = self.start_angle; end_angle = self.end_angle
- if self.arc_type == ArcChord:
- arc_type = ArcChord
- else:
- arc_type = ArcPieSlice
+ start_angle = self.start_angle; end_angle = self.end_angle
+ if self.arc_type == ArcChord:
+ arc_type = ArcChord
+ else:
+ arc_type = ArcPieSlice
- try:
- inverse = self.trafo.inverse()
- p = inverse(self.drag_cur)
- if self.selection == 1:
- start_angle = atan2(p.y, p.x)
- elif self.selection == 2:
- end_angle = atan2(p.y, p.x)
- if abs(p) > 1:
- arc_type = ArcArc
- except SingularMatrix:
- pass
- if fmod(abs(start_angle - end_angle), 2 * pi) < 0.0001:
- if self.selection == 1:
- start_angle = end_angle
- else:
- end_angle = start_angle
- return (start_angle, end_angle, arc_type)
+ try:
+ inverse = self.trafo.inverse()
+ p = inverse(self.drag_cur)
+ if self.selection == 1:
+ start_angle = atan2(p.y, p.x)
+ elif self.selection == 2:
+ end_angle = atan2(p.y, p.x)
+ if abs(p) > 1:
+ arc_type = ArcArc
+ except SingularMatrix:
+ pass
+ if fmod(abs(start_angle - end_angle), 2 * pi) < 0.0001:
+ if self.selection == 1:
+ start_angle = end_angle
+ else:
+ end_angle = start_angle
+ return (start_angle, end_angle, arc_type)
def DrawDragged(self, device, partially):
- start_angle, end_angle, arc_type = self.angles()
- device.SimpleEllipse(self.trafo, start_angle, end_angle, arc_type)
+ start_angle, end_angle, arc_type = self.angles()
+ device.SimpleEllipse(self.trafo, start_angle, end_angle, arc_type)
def GetHandles(self):
- trafo = self.trafo
- start_angle = self.start_angle; end_angle = self.end_angle
- p1 = trafo(cos(self.start_angle), sin(self.start_angle))
- if start_angle == end_angle:
- return [handle.MakeNodeHandle(p1)]
- p2 = trafo(cos(self.end_angle), sin(self.end_angle))
- return [handle.MakeNodeHandle(p1), handle.MakeNodeHandle(p2)]
+ trafo = self.trafo
+ start_angle = self.start_angle; end_angle = self.end_angle
+ p1 = trafo(cos(self.start_angle), sin(self.start_angle))
+ if start_angle == end_angle:
+ return [handle.MakeNodeHandle(p1)]
+ p2 = trafo(cos(self.end_angle), sin(self.end_angle))
+ return [handle.MakeNodeHandle(p1), handle.MakeNodeHandle(p2)]
def SelectHandle(self, handle, mode):
- self.selection = handle.index + 1
+ self.selection = handle.index + 1
def SelectPoint(self, p, rect, device, mode):
- return 0
+ return 0
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/eps.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/eps.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/eps.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -32,10 +32,10 @@
gs_command = ('gs -sDEVICE=ppmraw -r%(resolution)d -dNOPAUSE -dSAFER -q'
- ' -sOutputFile=%(temp)s -g%(width)dx%(height)d'
- ' -c %(offx)f %(offy)f translate'
- ' /oldshowpage /showpage load def /showpage \'{}\' def '
- ' -f %(filename)s -c oldshowpage quit')
+ ' -sOutputFile=%(temp)s -g%(width)dx%(height)d'
+ ' -c %(offx)f %(offy)f translate'
+ ' /oldshowpage /showpage load def /showpage \'{}\' def '
+ ' -f %(filename)s -c oldshowpage quit')
def render_preview(filename, startx, starty, width, height, resolution = None):
import tempfile
@@ -50,75 +50,75 @@
factor = resolution / 72.0
width = int(math.ceil(width * factor))
height = int(math.ceil(height * factor))
- offx = -startx
- offy = -starty
- os.system(gs_command % locals())
+ offx = -startx
+ offy = -starty
+ os.system(gs_command % locals())
- image = PIL.Image.open(temp)
- image.load()
- return image
+ image = PIL.Image.open(temp)
+ image.load()
+ return image
finally:
- try:
- os.unlink(temp)
- except:
- pass
+ try:
+ os.unlink(temp)
+ except:
+ pass
class EpsData(ExternalData):
def __init__(self, filename):
- self.info = info = dscparser.parse_eps_file(filename)
- self.filename = filename
- if info.BoundingBox:
- llx, lly, urx, ury = info.BoundingBox
- self.width = Point(urx - llx, 0)
- self.height = Point(0, ury - lly)
- self.start = (llx, lly)
- self.size = (urx - llx, ury - lly)
- self.image = None
- try:
- self.image = render_preview(filename, llx, lly,
- urx - llx, ury - lly)
- except IOError:
- pass
- else:
- raise TypeError, '%s has no BoundingBox' % filename
+ self.info = info = dscparser.parse_eps_file(filename)
+ self.filename = filename
+ if info.BoundingBox:
+ llx, lly, urx, ury = info.BoundingBox
+ self.width = Point(urx - llx, 0)
+ self.height = Point(0, ury - lly)
+ self.start = (llx, lly)
+ self.size = (urx - llx, ury - lly)
+ self.image = None
+ try:
+ self.image = render_preview(filename, llx, lly,
+ urx - llx, ury - lly)
+ except IOError:
+ pass
+ else:
+ raise TypeError, '%s has no BoundingBox' % filename
- ExternalData.__init__(self, filename)
+ ExternalData.__init__(self, filename)
def Start(self):
- return self.start
+ return self.start
def Size(self):
- return self.size
+ return self.size
def WriteLines(self, file):
- write = file.write
+ write = file.write
- try:
- infile = open(self.filename, 'r')
- except IOError, val:
- raise IOError, (filename, val)
- try:
- readline = infile.readline
+ try:
+ infile = open(self.filename, 'r')
+ except IOError, val:
+ raise IOError, (filename, val)
+ try:
+ readline = infile.readline
- line = readline()
- while line:
- if line[:15] == '%%BeginPreview:':
- while line[:12] != '%%EndPreview':
- line = readline()
- continue
- write(line)
- line = readline()
- finally:
- infile.close()
+ line = readline()
+ while line:
+ if line[:15] == '%%BeginPreview:':
+ while line[:12] != '%%EndPreview':
+ line = readline()
+ continue
+ write(line)
+ line = readline()
+ finally:
+ infile.close()
def load_eps(filename):
eps = get_cached(filename)
if eps:
- return eps
+ return eps
return EpsData(filename)
@@ -128,30 +128,30 @@
is_Eps = 1
def __init__(self, filename = '', trafo = None, duplicate = None):
- if duplicate is None:
- if not filename:
- raise ValueError, 'filename must be provided'
- data = load_eps(filename)
- else:
- data = None
- ExternalGraphics.__init__(self, data, trafo,
- duplicate = duplicate)
+ if duplicate is None:
+ if not filename:
+ raise ValueError, 'filename must be provided'
+ data = load_eps(filename)
+ else:
+ data = None
+ ExternalGraphics.__init__(self, data, trafo,
+ duplicate = duplicate)
def DrawShape(self, device, rect = None):
- device.DrawEps(self.data, self.trafo)
+ device.DrawEps(self.data, self.trafo)
def Info(self):
filename = os.path.basename(self.data.Filename())
width, height = self.data.Size()
x, y = self.trafo.offset()
- return _("EpsFile `%(filename)s' %(width)d x %(height)d "
+ return _("EpsFile `%(filename)s' %(width)d x %(height)d "
"at (%(x)d, %(y)d)") % locals()
def SaveToFile(self, file):
- file.EpsFile(self.data, self.trafo)
+ file.EpsFile(self.data, self.trafo)
def PSNeededResources(self):
- return self.data.info.DocumentNeededResources
+ return self.data.info.DocumentNeededResources
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/external.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/external.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/external.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -38,18 +38,18 @@
filename = ''
def __init__(self, filename = '', do_cache = 1):
- if filename and do_cache:
- self.stored_in_cache = 1
- instance_cache[filename] = self
+ if filename and do_cache:
+ self.stored_in_cache = 1
+ instance_cache[filename] = self
if filename:
self.filename = filename
def __del__(self):
- if self.stored_in_cache and instance_cache.has_key(self.filename):
- del instance_cache[self.filename]
+ if self.stored_in_cache and instance_cache.has_key(self.filename):
+ del instance_cache[self.filename]
def Filename(self):
- return self.filename
+ return self.filename
# to be supplied by derived classes
@@ -59,7 +59,7 @@
def get_cached(filename):
if instance_cache.has_key(filename):
- return instance_cache[filename]
+ return instance_cache[filename]
return None
@@ -72,11 +72,11 @@
data = None
def __init__(self, data = None, trafo = None, duplicate = None):
- RectangularObject.__init__(self, trafo, duplicate = duplicate)
- GraphicsObject.__init__(self, duplicate = duplicate)
- if duplicate is not None:
- data = duplicate.data
- self.data = data
+ RectangularObject.__init__(self, trafo, duplicate = duplicate)
+ GraphicsObject.__init__(self, duplicate = duplicate)
+ if duplicate is not None:
+ data = duplicate.data
+ self.data = data
def Data(self):
return self.data
@@ -88,66 +88,66 @@
return undo
def Hit(self, p, rect, device, clip = 0):
- width, height = self.data.Size()
- return device.ParallelogramHit(p, self.trafo, width, height, 1,
- ignore_outline_mode = clip)
+ width, height = self.data.Size()
+ return device.ParallelogramHit(p, self.trafo, width, height, 1,
+ ignore_outline_mode = clip)
def SetLowerLeftCorner(self, corner):
- # Used by the place mode in SketchCanvas. Currently no undo
- # needed since this is called *before* self is a part of a
- # document.
- self.trafo = apply(Trafo, self.trafo.coeff()[:4] + tuple(corner))
- self.del_lazy_attrs()
+ # Used by the place mode in SketchCanvas. Currently no undo
+ # needed since this is called *before* self is a part of a
+ # document.
+ self.trafo = apply(Trafo, self.trafo.coeff()[:4] + tuple(corner))
+ self.del_lazy_attrs()
def RemoveTransformation(self):
- if self.trafo.matrix() != IdentityMatrix:
- center = self.coord_rect.center()
- width, height = self.data.Size()
- trafo = Trafo(1, 0, 0, 1,
- center.x - width / 2, center.y - height / 2)
- return self.set_transformation(trafo)
- return NullUndo
+ if self.trafo.matrix() != IdentityMatrix:
+ center = self.coord_rect.center()
+ width, height = self.data.Size()
+ trafo = Trafo(1, 0, 0, 1,
+ center.x - width / 2, center.y - height / 2)
+ return self.set_transformation(trafo)
+ return NullUndo
def update_rects(self):
- width, height = self.data.Size()
- rect = self.trafo(Rect(0, 0, width, height))
- self.coord_rect = rect
- self.bounding_rect = rect.grown(2)
+ width, height = self.data.Size()
+ rect = self.trafo(Rect(0, 0, width, height))
+ self.coord_rect = rect
+ self.bounding_rect = rect.grown(2)
def Info(self):
- # Should be overwritten by derived classes
- return 'ExternalGraphics'
+ # Should be overwritten by derived classes
+ return 'ExternalGraphics'
def SetProperties(self, **kw):
- return NullUndo
+ return NullUndo
def AddStyle(self, style):
- return NullUndo
+ return NullUndo
def Properties(self):
- return EmptyProperties
+ return EmptyProperties
def GetSnapPoints(self):
width, height = self.data.Size()
corners = ((0, 0), (width, 0), (width, height), (0, height))
- return map(self.trafo, corners)
+ return map(self.trafo, corners)
def Snap(self, p):
width, height = self.data.Size()
- try:
- x, y = self.trafo.inverse()(p)
- if 0 <= x <= width:
- if 0 <= y <= height:
- x = round(x / width) * width
- y = round(y / height) * height
- else:
- y = min(max(y, 0), height)
- else:
+ try:
+ x, y = self.trafo.inverse()(p)
+ if 0 <= x <= width:
+ if 0 <= y <= height:
+ x = round(x / width) * width
+ y = round(y / height) * height
+ else:
+ y = min(max(y, 0), height)
+ else:
x = min(max(x, 0), width)
- if 0 > y or y > height:
+ if 0 > y or y > height:
y = min(max(y, 0), height)
- p2 = self.trafo(x, y)
- return (abs(p - p2), p2)
- except SingularMatrix:
- return (1e200, p)
+ p2 = self.trafo(x, y)
+ return (abs(p - p2), p2)
+ except SingularMatrix:
+ return (1e200, p)
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/font.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/font.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/font.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -67,25 +67,25 @@
charmetrics = {encoding.notdef: (0, 0,0,0,0)}
font_encoding = [encoding.notdef] * 256
while 1:
- line = afm.readline()
- if line == 'EndCharMetrics\n':
- break
- items = filter(None, map(strip, split(line, ';')))
+ line = afm.readline()
+ if line == 'EndCharMetrics\n':
+ break
+ items = filter(None, map(strip, split(line, ';')))
if not items:
continue
- code = name = width = bbox = None
- for item in items:
- [key, value] = split(item, None, 1)
- if key == 'C':
- code = atoi(value)
- elif key == 'WX':
- width = int(round(atof(value)))
- elif key == 'N':
- name = value
- elif key == 'B':
- bbox = tuple(map(int,map(round,map(atof,split(value)))))
- charmetrics[name] = (width,) + bbox
- font_encoding[code] = name
+ code = name = width = bbox = None
+ for item in items:
+ [key, value] = split(item, None, 1)
+ if key == 'C':
+ code = atoi(value)
+ elif key == 'WX':
+ width = int(round(atof(value)))
+ elif key == 'N':
+ name = value
+ elif key == 'B':
+ bbox = tuple(map(int,map(round,map(atof,split(value)))))
+ charmetrics[name] = (width,) + bbox
+ font_encoding[code] = name
return charmetrics, font_encoding
def read_afm_file(filename):
@@ -96,51 +96,51 @@
font_encoding = [encoding.notdef] * 256
while 1:
- line = afm.readline()
- if not line:
- break
+ line = afm.readline()
+ if not line:
+ break
try:
[key, value] = split(line, None, 1)
except ValueError:
# this normally means that a line contained only a keyword
# but no value or that the line was empty
continue
- try:
- action = converters[key]
- except KeyError:
- continue
- if action:
- attribs[key] = action(value)
- elif key == 'StartCharMetrics':
- charmetrics, font_encoding = read_char_metrics(afm)
- break
- else:
- # EndFontMetrics
- break
+ try:
+ action = converters[key]
+ except KeyError:
+ continue
+ if action:
+ attribs[key] = action(value)
+ elif key == 'StartCharMetrics':
+ charmetrics, font_encoding = read_char_metrics(afm)
+ break
+ else:
+ # EndFontMetrics
+ break
if not charmetrics:
- raise ValueError, \
- 'AFM files without individual char metrics not yet supported.'
+ raise ValueError, \
+ 'AFM files without individual char metrics not yet supported.'
if attribs.get('EncodingScheme', StandardEncoding) == StandardEncoding:
- enc = encoding.iso_latin_1
+ enc = encoding.iso_latin_1
else:
- enc = font_encoding
+ enc = font_encoding
try:
- rescharmetrics = map(operator.getitem, [charmetrics] * len(enc), enc)
+ rescharmetrics = map(operator.getitem, [charmetrics] * len(enc), enc)
except KeyError:
- # Some iso-latin-1 glyphs are not defined in the font. Try the
- # slower way and report missing glyphs.
- length = len(enc)
- rescharmetrics = [(0, 0,0,0,0)] * length
- for idx in range(length):
- name = enc[idx]
- try:
- rescharmetrics[idx] = charmetrics[name]
- except KeyError:
- # missing character...
- warn(INTERNAL, '%s: missing character %s', filename, name)
+ # Some iso-latin-1 glyphs are not defined in the font. Try the
+ # slower way and report missing glyphs.
+ length = len(enc)
+ rescharmetrics = [(0, 0,0,0,0)] * length
+ for idx in range(length):
+ name = enc[idx]
+ try:
+ rescharmetrics[idx] = charmetrics[name]
+ except KeyError:
+ # missing character...
+ warn(INTERNAL, '%s: missing character %s', filename, name)
# some fonts don't define ascender and descender (psyr.afm for
# instance). use the values from the font bounding box instead. This
@@ -154,39 +154,39 @@
# reads from afm files are only optional (including ascender and
# descender).
if not attribs.has_key('Ascender'):
- attribs['Ascender'] = attribs['FontBBox'][3]
+ attribs['Ascender'] = attribs['FontBBox'][3]
if not attribs.has_key('Descender'):
- attribs['Descender'] = attribs['FontBBox'][1]
+ attribs['Descender'] = attribs['FontBBox'][1]
return (CreateFontMetric(attribs['Ascender'], attribs['Descender'],
attribs['FontBBox'], attribs['ItalicAngle'],
rescharmetrics),
- enc)
+ enc)
_warned_about_afm = {}
def read_metric(ps_name):
for afm in ps_to_filename[ps_name]:
- afm = afm + '.afm'
- filename = find_in_path(config.font_path, afm)
- if filename:
- if __debug__:
- import time
- start = time.clock()
- metric = read_afm_file(filename)
- if __debug__:
- pdebug('timing', 'time to read afm %s: %g', afm,
- time.clock() - start)
- return metric
+ afm = afm + '.afm'
+ filename = find_in_path(config.font_path, afm)
+ if filename:
+ if __debug__:
+ import time
+ start = time.clock()
+ metric = read_afm_file(filename)
+ if __debug__:
+ pdebug('timing', 'time to read afm %s: %g', afm,
+ time.clock() - start)
+ return metric
else:
- if not _warned_about_afm.get(afm):
- warn(USER,
+ if not _warned_about_afm.get(afm):
+ warn(USER,
_("I cannot find the metrics for the font %(ps_name)s.\n"
"The file %(afm)s is not in the font_path.\n"
"I'll use the metrics for %(fallback)s instead."),
- ps_name = ps_name, afm = afm,
+ ps_name = ps_name, afm = afm,
fallback = config.preferences.fallback_font)
- _warned_about_afm[afm] = 1
+ _warned_about_afm[afm] = 1
if ps_name != config.preferences.fallback_font:
return read_metric(config.preferences.fallback_font)
else:
@@ -197,40 +197,40 @@
def font_file_name(ps_name):
names = []
for basename in ps_to_filename[ps_name]:
- names.append(basename + '.pfb')
- names.append(basename + '.pfa')
+ names.append(basename + '.pfb')
+ names.append(basename + '.pfa')
filename = find_files_in_path(config.font_path, names)
return filename
-
+
def read_outlines(ps_name):
filename = font_file_name(ps_name)
if filename:
- if __debug__:
- pdebug('font', 'read_outlines: %s', filename)
+ if __debug__:
+ pdebug('font', 'read_outlines: %s', filename)
- import Sketch.Lib.type1
- return Sketch.Lib.type1.read_outlines(filename)
+ import Sketch.Lib.type1
+ return Sketch.Lib.type1.read_outlines(filename)
else:
- raise SketchInternalError('Cannot find file for font %s' % ps_name)
+ raise SketchInternalError('Cannot find file for font %s' % ps_name)
def convert_outline(outline):
paths = []
trafo = Scale(0.001)
for closed, sub in outline:
- if closed:
- sub.append(sub[0])
- path = CreatePath()
- paths.append(path)
- for item in sub:
- if len(item) == 2:
- apply(path.AppendLine, item)
- else:
- apply(path.AppendBezier, item)
- if closed:
- path.load_close()
+ if closed:
+ sub.append(sub[0])
+ path = CreatePath()
+ paths.append(path)
+ for item in sub:
+ if len(item) == 2:
+ apply(path.AppendLine, item)
+ else:
+ apply(path.AppendBezier, item)
+ if closed:
+ path.load_close()
for path in paths:
- path.Transform(trafo)
+ path.Transform(trafo)
return tuple(paths)
@@ -243,66 +243,66 @@
def _add_ps_filename(ps_name, filename):
filename = (filename,)
if ps_to_filename.has_key(ps_name):
- filename = ps_to_filename[ps_name] + filename
+ filename = ps_to_filename[ps_name] + filename
ps_to_filename[ps_name] = filename
def read_font_dirs():
#print 'read_font_dirs'
if __debug__:
- import time
- start = time.clock()
+ import time
+ start = time.clock()
rx_sfd = re.compile(r'^.*\.sfd$')
for directory in config.font_path:
#print directory
- try:
- filenames = os.listdir(directory)
- except os.error, exc:
- warn(USER, _("Cannot list directory %s:%s\n"
+ try:
+ filenames = os.listdir(directory)
+ except os.error, exc:
+ warn(USER, _("Cannot list directory %s:%s\n"
"ignoring it in font_path"),
- directory, str(exc))
- continue
- dirfiles = filter(rx_sfd.match, filenames)
- for filename in dirfiles:
- filename = os.path.join(directory, filename)
+ directory, str(exc))
+ continue
+ dirfiles = filter(rx_sfd.match, filenames)
+ for filename in dirfiles:
+ filename = os.path.join(directory, filename)
#print filename
- try:
- file = open(filename, 'r')
- line_nr = 0
- for line in file.readlines():
- line_nr = line_nr + 1
- line = strip(line)
- if not line or line[0] == '#':
- continue
- info = map(intern, split(line, ','))
- if len(info) == 6:
- psname = info[0]
- fontlist.append(tuple(info[:-1]))
- _add_ps_filename(psname, info[-1])
- fontmap[psname] = tuple(info[1:-1])
- elif len(info) == 2:
- psname, basename = info
- _add_ps_filename(psname, basename)
- else:
- warn(INTERNAL,'%s:%d: line must have exactly 6 fields',
- filename, line_nr)
- file.close()
- except IOError, value:
- warn(USER, _("Cannot load sfd file %(filename)s:%(message)s;"
+ try:
+ file = open(filename, 'r')
+ line_nr = 0
+ for line in file.readlines():
+ line_nr = line_nr + 1
+ line = strip(line)
+ if not line or line[0] == '#':
+ continue
+ info = map(intern, split(line, ','))
+ if len(info) == 6:
+ psname = info[0]
+ fontlist.append(tuple(info[:-1]))
+ _add_ps_filename(psname, info[-1])
+ fontmap[psname] = tuple(info[1:-1])
+ elif len(info) == 2:
+ psname, basename = info
+ _add_ps_filename(psname, basename)
+ else:
+ warn(INTERNAL,'%s:%d: line must have exactly 6 fields',
+ filename, line_nr)
+ file.close()
+ except IOError, value:
+ warn(USER, _("Cannot load sfd file %(filename)s:%(message)s;"
"ignoring it"),
- filename = filename, message = value.strerror)
+ filename = filename, message = value.strerror)
if __debug__:
- pdebug('timing', 'time to read font dirs: %g', time.clock() - start)
+ pdebug('timing', 'time to read font dirs: %g', time.clock() - start)
def make_family_to_fonts():
families = {}
for item in fontlist:
- family = item[1]
- fontname = item[0]
- if families.has_key(family):
- families[family] = families[family] + (fontname,)
- else:
- families[family] = (fontname,)
+ family = item[1]
+ fontname = item[0]
+ if families.has_key(family):
+ families[family] = families[family] + (fontname,)
+ else:
+ families[family] = (fontname,)
return families
@@ -314,28 +314,28 @@
class Font:
def __init__(self, name):
- self.name = name
- info = fontmap[name]
- family, font_attrs, xlfd_start, encoding_name = info
- self.family = family
- self.font_attrs = font_attrs
- self.xlfd_start = lower(xlfd_start)
- self.encoding_name = encoding_name
- self.metric, self.encoding = read_metric(self.PostScriptName())
- self.outlines = None
+ self.name = name
+ info = fontmap[name]
+ family, font_attrs, xlfd_start, encoding_name = info
+ self.family = family
+ self.font_attrs = font_attrs
+ self.xlfd_start = lower(xlfd_start)
+ self.encoding_name = encoding_name
+ self.metric, self.encoding = read_metric(self.PostScriptName())
+ self.outlines = None
- self.ref_count = 0
- font_cache[self.name] = self
+ self.ref_count = 0
+ font_cache[self.name] = self
def __del__(self):
- if font_cache is not None and font_cache.has_key(self.name):
- del font_cache[self.name]
+ if font_cache is not None and font_cache.has_key(self.name):
+ del font_cache[self.name]
def __repr__(self):
return "<Font %s>" % self.name
def GetXLFD(self, size_trafo):
- if type(size_trafo) == TrafoType:
+ if type(size_trafo) == TrafoType:
if size_trafo.m11 == size_trafo.m22 > 0\
and size_trafo.m12 == size_trafo.m21 == 0:
# a uniform scaling. Special case for better X11R5
@@ -343,65 +343,65 @@
return xlfd_template % (self.xlfd_start,
int(round(size_trafo.m11)),
self.encoding_name)
- return xlfd_template % (self.xlfd_start, xlfd_matrix(size_trafo),
- self.encoding_name)
- return xlfd_template % (self.xlfd_start, int(round(size_trafo)),
- self.encoding_name)
+ return xlfd_template % (self.xlfd_start, xlfd_matrix(size_trafo),
+ self.encoding_name)
+ return xlfd_template % (self.xlfd_start, int(round(size_trafo)),
+ self.encoding_name)
def PostScriptName(self):
- return self.name
+ return self.name
def TextBoundingBox(self, text, size):
- # Return the bounding rectangle of TEXT when set in this font
- # with a size of SIZE. The coordinates of the rectangle are
- # relative to the origin of the first character.
- llx, lly, urx, ury = self.metric.string_bbox(text)
- size = size / 1000.0
- return (llx * size, lly * size, urx * size, ury * size)
+ # Return the bounding rectangle of TEXT when set in this font
+ # with a size of SIZE. The coordinates of the rectangle are
+ # relative to the origin of the first character.
+ llx, lly, urx, ury = self.metric.string_bbox(text)
+ size = size / 1000.0
+ return (llx * size, lly * size, urx * size, ury * size)
def TextCoordBox(self, text, size):
- # Return the coord rectangle of TEXT when set in this font with
- # a size of SIZE. The coordinates of the rectangle are relative
- # to the origin of the first character.
- metric = self.metric
- width = metric.string_width(text)
- size = size / 1000.0
- return (0, metric.descender * size,
- width * size, metric.ascender * size)
+ # Return the coord rectangle of TEXT when set in this font with
+ # a size of SIZE. The coordinates of the rectangle are relative
+ # to the origin of the first character.
+ metric = self.metric
+ width = metric.string_width(text)
+ size = size / 1000.0
+ return (0, metric.descender * size,
+ width * size, metric.ascender * size)
def TextCaretData(self, text, pos, size):
- from math import tan, pi
- size = size / 1000.0
- x = self.metric.string_width(text, pos) * size
- lly = self.metric.lly * size
- ury = self.metric.ury * size
- t = tan(self.metric.italic_angle * pi / 180.0);
- up = ury - lly
- return Point(x - t * lly, lly), Point(-t * up, up)
+ from math import tan, pi
+ size = size / 1000.0
+ x = self.metric.string_width(text, pos) * size
+ lly = self.metric.lly * size
+ ury = self.metric.ury * size
+ t = tan(self.metric.italic_angle * pi / 180.0);
+ up = ury - lly
+ return Point(x - t * lly, lly), Point(-t * up, up)
def TypesetText(self, text):
- return self.metric.typeset_string(text)
+ return self.metric.typeset_string(text)
def IsPrintable(self, char):
- return self.encoding[ord(char)] != encoding.notdef
+ return self.encoding[ord(char)] != encoding.notdef
def GetOutline(self, char):
- if self.outlines is None:
- self.char_strings, self.cs_interp \
- = read_outlines(self.PostScriptName())
- self.outlines = {}
- char_name = self.encoding[ord(char)]
- outline = self.outlines.get(char_name)
- if outline is None:
- self.cs_interp.execute(self.char_strings[char_name])
- outline = convert_outline(self.cs_interp.paths)
- self.outlines[char_name] = outline
- self.cs_interp.reset()
- copy = []
- for path in outline:
- path = path.Duplicate()
- copy.append(path)
- return tuple(copy)
+ if self.outlines is None:
+ self.char_strings, self.cs_interp \
+ = read_outlines(self.PostScriptName())
+ self.outlines = {}
+ char_name = self.encoding[ord(char)]
+ outline = self.outlines.get(char_name)
+ if outline is None:
+ self.cs_interp.execute(self.char_strings[char_name])
+ outline = convert_outline(self.cs_interp.paths)
+ self.outlines[char_name] = outline
+ self.cs_interp.reset()
+ copy = []
+ for path in outline:
+ path = path.Duplicate()
+ copy.append(path)
+ return tuple(copy)
def FontFileName(self):
return font_file_name(self.PostScriptName())
@@ -411,17 +411,17 @@
_warned_about_font = {}
def GetFont(fontname):
if font_cache.has_key(fontname):
- return font_cache[fontname]
+ return font_cache[fontname]
if not fontmap.has_key(fontname):
- if not _warned_about_font.get(fontname):
- warn(USER, _("I can't find font %(fontname)s. "
+ if not _warned_about_font.get(fontname):
+ warn(USER, _("I can't find font %(fontname)s. "
"I'll use %(fallback)s instead"),
fontname = fontname,
fallback = config.preferences.fallback_font)
- _warned_about_font[fontname] = 1
- if fontname != config.preferences.fallback_font:
- return GetFont(config.preferences.fallback_font)
- raise ValueError, 'Cannot find font %s.' % fontname
+ _warned_about_font[fontname] = 1
+ if fontname != config.preferences.fallback_font:
+ return GetFont(config.preferences.fallback_font)
+ raise ValueError, 'Cannot find font %s.' % fontname
return Font(fontname)
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/gradient.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/gradient.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/gradient.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -24,114 +24,114 @@
class Gradient:
def __init__(self, duplicate = None):
- pass
+ pass
def ColorAt(self, pos):
- pass
+ pass
def Duplicate(self):
- return self.__class__(duplicate = self)
+ return self.__class__(duplicate = self)
class MultiGradient(Gradient):
def __init__(self, colors = (), duplicate = None):
- if duplicate is not None:
- self.colors = duplicate.colors[:]
- else:
- if len(colors) < 2:
- raise ValueError, 'at least 2 colors required'
- self.colors = colors
+ if duplicate is not None:
+ self.colors = duplicate.colors[:]
+ else:
+ if len(colors) < 2:
+ raise ValueError, 'at least 2 colors required'
+ self.colors = colors
def StartColor(self):
- return self.colors[0][-1]
+ return self.colors[0][-1]
def SetStartColor(self, color):
- undo = (self.SetStartColor, self.colors[0][-1])
- self.colors[0] = (0, color)
- return undo
+ undo = (self.SetStartColor, self.colors[0][-1])
+ self.colors[0] = (0, color)
+ return undo
def EndColor(self):
- return self.colors[-1][-1]
+ return self.colors[-1][-1]
def SetEndColor(self, color):
- undo = (self.SetEndColor, self.colors[-1][-1])
- self.colors[-1] = (1, color)
- return undo
+ undo = (self.SetEndColor, self.colors[-1][-1])
+ self.colors[-1] = (1, color)
+ return undo
def ColorAt(self, pos):
- colors = self.colors
- for i in range(len(colors) - 1):
- if colors[i][0] <= pos and colors[i + 1][0] >= pos:
- break
- else:
- return self.EndColor()
- start_pos, start_color = colors[i]
- if i < len(colors) - 1:
- end_pos, end_color = colors[i + 1]
- else:
- return start_color
- return Blend(end_color, start_color,
- (pos - start_pos) / float(end_pos - start_pos))
+ colors = self.colors
+ for i in range(len(colors) - 1):
+ if colors[i][0] <= pos and colors[i + 1][0] >= pos:
+ break
+ else:
+ return self.EndColor()
+ start_pos, start_color = colors[i]
+ if i < len(colors) - 1:
+ end_pos, end_color = colors[i + 1]
+ else:
+ return start_color
+ return Blend(end_color, start_color,
+ (pos - start_pos) / float(end_pos - start_pos))
def Sample(self, num):
- colors = self.colors
- max = num - 1.0
- pos1, color1 = colors[0]
- pos2, color2 = colors[1]
- diff = float(pos2 - pos1)
- cur = 1
- result = []
- blend = color1.Blend
- for i in range(num):
- frac = i / max
- while frac > pos2:
- pos1 = pos2; color1 = color2
- cur = cur + 1
- pos2, color2 = colors[cur]
- diff = float(pos2 - pos1)
- blend = color1.Blend
- frac = (frac - pos1) / diff
- result.append(blend(color2, 1 - frac, frac))
- return result
+ colors = self.colors
+ max = num - 1.0
+ pos1, color1 = colors[0]
+ pos2, color2 = colors[1]
+ diff = float(pos2 - pos1)
+ cur = 1
+ result = []
+ blend = color1.Blend
+ for i in range(num):
+ frac = i / max
+ while frac > pos2:
+ pos1 = pos2; color1 = color2
+ cur = cur + 1
+ pos2, color2 = colors[cur]
+ diff = float(pos2 - pos1)
+ blend = color1.Blend
+ frac = (frac - pos1) / diff
+ result.append(blend(color2, 1 - frac, frac))
+ return result
def Colors(self):
- return self.colors
+ return self.colors
def SetColors(self):
- undo = (self.SetColors, self.colors)
- self.colors = colors
- return undo
+ undo = (self.SetColors, self.colors)
+ self.colors = colors
+ return undo
def Blend(self, other, frac1, frac2):
- if type(other) == type(self.colors[0][-1]):
- # blend a gradient with a single color
- sc = self.colors
- c = []
- for i in range(len(sc)):
- p1, c1 = sc[i]
- c.append((p1, c1.Blend(other, frac1, frac2)))
- return self.__class__(c)
- elif other.__class__ == self.__class__:
- # blend two MultiGradient instances
- # XXX: improve this...
- length = min(len(self.colors), len(other.colors))
- sc = self.colors[:length - 1]
- sc.append(self.colors[-1])
- oc = other.colors[:length - 1]
- oc.append(other.colors[-1])
- c = []
- for i in range(length):
- p1, c1 = sc[i]
- p2, c2 = oc[i]
- c.append((frac1 * p1 + frac2 * p2,
- Blend(c1, c2, frac1, frac2)))
- return self.__class__(c)
- else:
- raise MismatchError
+ if type(other) == type(self.colors[0][-1]):
+ # blend a gradient with a single color
+ sc = self.colors
+ c = []
+ for i in range(len(sc)):
+ p1, c1 = sc[i]
+ c.append((p1, c1.Blend(other, frac1, frac2)))
+ return self.__class__(c)
+ elif other.__class__ == self.__class__:
+ # blend two MultiGradient instances
+ # XXX: improve this...
+ length = min(len(self.colors), len(other.colors))
+ sc = self.colors[:length - 1]
+ sc.append(self.colors[-1])
+ oc = other.colors[:length - 1]
+ oc.append(other.colors[-1])
+ c = []
+ for i in range(length):
+ p1, c1 = sc[i]
+ p2, c2 = oc[i]
+ c.append((frac1 * p1 + frac2 * p2,
+ Blend(c1, c2, frac1, frac2)))
+ return self.__class__(c)
+ else:
+ raise MismatchError
def SaveToFile(self, file):
- file.Gradient(self.colors)
+ file.Gradient(self.colors)
# convenience function for the most common gradient type
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/graphics.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/graphics.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/graphics.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -91,22 +91,22 @@
line = defaultLineStyle
def __init__(self):
- self.orig_x = self.orig_y = 0.0
- self.scale = 1.0
- self.win_to_doc = self.doc_to_win = Identity
- self.init_trafo_stack()
- self.gc = None
- self.outline_mode = 0
- self.font = None
- self.clip_region = None
- self.clip_stack = None
- self.proc_fill = 0
+ self.orig_x = self.orig_y = 0.0
+ self.scale = 1.0
+ self.win_to_doc = self.doc_to_win = Identity
+ self.init_trafo_stack()
+ self.gc = None
+ self.outline_mode = 0
+ self.font = None
+ self.clip_region = None
+ self.clip_stack = None
+ self.proc_fill = 0
def init_gc(self, widget, **gcargs):
- self.gc = widget.CreateGC(gcargs)
- self.widget = widget
- self.visual = color.skvisual
- self.InitClip()
+ self.gc = widget.CreateGC(gcargs)
+ self.widget = widget
+ self.visual = color.skvisual
+ self.InitClip()
#
# Clipping
@@ -138,111 +138,111 @@
def InitClip(self):
- # reset all clipping...
- self.gc.SetClipMask(None)
- self.clip_region = None
- self.clip_stack = ()
+ # reset all clipping...
+ self.gc.SetClipMask(None)
+ self.clip_region = None
+ self.clip_stack = ()
def IsClipping(self):
- return self.clip_stack != ()
+ return self.clip_stack != ()
def PushClip(self):
- self.clip_stack = (self.clip_region, self.clip_stack)
+ self.clip_stack = (self.clip_region, self.clip_stack)
def PopClip(self):
- # Pop the old clip region from the clip stack and make it the
- # active clip region.
- self.clip_region, self.clip_stack = self.clip_stack
- self.gc.SetClipMask(self.clip_region)
+ # Pop the old clip region from the clip stack and make it the
+ # active clip region.
+ self.clip_region, self.clip_stack = self.clip_stack
+ self.gc.SetClipMask(self.clip_region)
def ClipRegion(self, region):
- # Itersect the current clip region and REGION and make the
- # result the new clip region. REGION may be a region object or a
- # pixmap object of depth 1
- self.clip_region = IntersectMasks(self.clip_region, region)
- self.gc.SetClipMask(self.clip_region)
+ # Itersect the current clip region and REGION and make the
+ # result the new clip region. REGION may be a region object or a
+ # pixmap object of depth 1
+ self.clip_region = IntersectMasks(self.clip_region, region)
+ self.gc.SetClipMask(self.clip_region)
def ClipRect(self, recttuple):
- region = self.widget.CreateRegion()
- apply(region.UnionRectWithRegion, recttuple)
- self.ClipRegion(region)
+ region = self.widget.CreateRegion()
+ apply(region.UnionRectWithRegion, recttuple)
+ self.ClipRegion(region)
def ClipPolygon(self, pts):
- self.ClipRegion(self.widget.PolygonRegion(pts))
+ self.ClipRegion(self.widget.PolygonRegion(pts))
ClipBitmap = ClipRegion
def create_clip_bitmap(self):
- width = self.widget.width
- height = self.widget.height
- bitmap = self.widget.CreatePixmap(width, height, 1)
- bitmap_gc = bitmap.CreateGC(foreground = 0)
- bitmap_gc.FillRectangle(0, 0, width, height)
- bitmap_gc.foreground = 1
- return (bitmap, bitmap_gc)
+ width = self.widget.width
+ height = self.widget.height
+ bitmap = self.widget.CreatePixmap(width, height, 1)
+ bitmap_gc = bitmap.CreateGC(foreground = 0)
+ bitmap_gc.FillRectangle(0, 0, width, height)
+ bitmap_gc.foreground = 1
+ return (bitmap, bitmap_gc)
#
# Convert document coordinates to window coordinates and vice versa.
#
def DocToWin(self, *args):
- # Return the point in window coords as a tuple of ints
- return apply(self.doc_to_win.DocToWin, args)
+ # Return the point in window coords as a tuple of ints
+ return apply(self.doc_to_win.DocToWin, args)
def DocToWinPoint(self, p):
- # Return the point in window coords as a point object
- return self.doc_to_win(p)
+ # Return the point in window coords as a point object
+ return self.doc_to_win(p)
def LengthToWin(self, len):
- return int(len * self.scale + 0.5)
+ return int(len * self.scale + 0.5)
def LengthToWinFloat(self, len):
- return len * self.scale
+ return len * self.scale
def LengthToDoc(self, len):
- return len / self.scale
+ return len / self.scale
def WinToDoc(self, *args):
- return apply(self.win_to_doc, args)
+ return apply(self.win_to_doc, args)
def init_trafo_stack(self):
- self.trafo_stack = ()
- self.default_trafo = (self.win_to_doc, self.doc_to_win)
+ self.trafo_stack = ()
+ self.default_trafo = (self.win_to_doc, self.doc_to_win)
def SetViewportTransform(self, scale, doc_to_win, win_to_doc):
- self.scale = scale
- self.doc_to_win = doc_to_win
- self.win_to_doc = win_to_doc
- self.init_trafo_stack()
+ self.scale = scale
+ self.doc_to_win = doc_to_win
+ self.win_to_doc = win_to_doc
+ self.init_trafo_stack()
def InitTrafo():
- self.win_to_doc, self.doc_to_win = self.default_trafo
- self.trafo_stack = ()
+ self.win_to_doc, self.doc_to_win = self.default_trafo
+ self.trafo_stack = ()
def PushTrafo(self):
- self.trafo_stack = (self.win_to_doc, self.doc_to_win, self.trafo_stack)
+ self.trafo_stack = (self.win_to_doc, self.doc_to_win, self.trafo_stack)
def Concat(self, trafo):
- self.doc_to_win = self.doc_to_win(trafo)
- try:
- self.win_to_doc = trafo.inverse()(self.win_to_doc)
- except SingularMatrix:
- pass
+ self.doc_to_win = self.doc_to_win(trafo)
+ try:
+ self.win_to_doc = trafo.inverse()(self.win_to_doc)
+ except SingularMatrix:
+ pass
def Translate(self, *args):
- self.Concat(apply(Translation, args))
+ self.Concat(apply(Translation, args))
def Scale(self, factor):
- self.Concat(Scale(factor))
+ self.Concat(Scale(factor))
def Rotate(self, angle):
- self.Concat(Rotation(angle))
+ self.Concat(Rotation(angle))
def PopTrafo(self):
- self.win_to_doc, self.doc_to_win, self.trafo_stack = self.trafo_stack
+ self.win_to_doc, self.doc_to_win, self.trafo_stack = self.trafo_stack
def WindowResized(self, width, height):
- pass
+ pass
#
@@ -250,15 +250,15 @@
#
def StartDblBuffer(self):
- self.buffer_pixmap = self.widget.CreatePixmap()
- self.gc.SetDrawable(self.buffer_pixmap)
+ self.buffer_pixmap = self.widget.CreatePixmap()
+ self.gc.SetDrawable(self.buffer_pixmap)
def EndDblBuffer(self):
- self.gc.SetDrawable(self.widget)
- self.buffer_pixmap.CopyArea(self.widget, self.gc, 0, 0,
- self.widget.width, self.widget.height,
- 0, 0)
- self.buffer_pixmap = None
+ self.gc.SetDrawable(self.widget)
+ self.buffer_pixmap.CopyArea(self.widget, self.gc, 0, 0,
+ self.widget.width, self.widget.height,
+ 0, 0)
+ self.buffer_pixmap = None
class SimpleGC(GCDevice):
@@ -271,121 +271,121 @@
#
def __init__(self):
- GCDevice.__init__(self)
- self.current_color = StandardColors.black
+ GCDevice.__init__(self)
+ self.current_color = StandardColors.black
def SetFillColor(self, color):
- self.current_color = color
- self.gc.SetForegroundAndFill(self.visual.get_pixel(color))
+ self.current_color = color
+ self.gc.SetForegroundAndFill(self.visual.get_pixel(color))
def SetLineColor(self, color):
- self.current_color = color
- self.gc.SetForegroundAndFill(self.visual.get_pixel(color))
+ self.current_color = color
+ self.gc.SetForegroundAndFill(self.visual.get_pixel(color))
def SetLineAttributes(self, width, cap = X.CapButt, join = X.JoinMiter,
- dashes = None):
- if dashes:
- line = X.LineOnOffDash
- else:
- line = X.LineSolid
- self.gc.SetLineAttributes(int(round(width * self.scale)), line, cap,
+ dashes = None):
+ if dashes:
+ line = X.LineOnOffDash
+ else:
+ line = X.LineSolid
+ self.gc.SetLineAttributes(int(round(width * self.scale)), line, cap,
join)
- if dashes:
- if width < 1.0:
- scale = self.scale
- else:
- scale = width * self.scale
- dashes = map(operator.mul, dashes, [scale] * len(dashes))
- dashes = map(int, map(round, dashes))
- for idx in range(len(dashes)):
- length = dashes[idx]
- if length <= 0:
- dashes[idx] = 1
- elif length > 255:
- dashes[idx] = 255
- self.gc.SetDashes(dashes)
+ if dashes:
+ if width < 1.0:
+ scale = self.scale
+ else:
+ scale = width * self.scale
+ dashes = map(operator.mul, dashes, [scale] * len(dashes))
+ dashes = map(int, map(round, dashes))
+ for idx in range(len(dashes)):
+ length = dashes[idx]
+ if length <= 0:
+ dashes[idx] = 1
+ elif length > 255:
+ dashes[idx] = 255
+ self.gc.SetDashes(dashes)
def SetLineSolid(self):
- self.gc.line_style = X.LineSolid
+ self.gc.line_style = X.LineSolid
def DrawLine(self, start, end):
- startx, starty = self.DocToWin(start)
- endx, endy = self.DocToWin(end)
- self.gc.DrawLine(startx, starty, endx, endy)
+ startx, starty = self.DocToWin(start)
+ endx, endy = self.DocToWin(end)
+ self.gc.DrawLine(startx, starty, endx, endy)
def DrawLineXY(self, x1, y1, x2, y2):
- startx, starty = self.DocToWin(x1, y1)
- endx, endy = self.DocToWin(x2, y2)
- self.gc.DrawLine(startx, starty, endx, endy)
+ startx, starty = self.DocToWin(x1, y1)
+ endx, endy = self.DocToWin(x2, y2)
+ self.gc.DrawLine(startx, starty, endx, endy)
def DrawLines(self, pts):
- pts = map(self.DocToWin, pts)
- self.gc.DrawLines(pts, X.CoordModeOrigin)
+ pts = map(self.DocToWin, pts)
+ self.gc.DrawLines(pts, X.CoordModeOrigin)
def FillPolygon(self, pts):
- pts = map(self.DocToWin, pts)
- self.gc.FillPolygon(pts, X.Complex, X.CoordModeOrigin)
+ pts = map(self.DocToWin, pts)
+ self.gc.FillPolygon(pts, X.Complex, X.CoordModeOrigin)
def DrawRectangle(self, start, end):
- # draw the outline of the rectangle whose opposite corners are
- # start and end.
- pts = TransformRectangle(self.doc_to_win, Rect(start, end))
- if type(pts) == TupleType:
- apply(self.gc.DrawRectangle, pts)
- else:
- self.gc.DrawLines(pts, X.CoordModeOrigin)
+ # draw the outline of the rectangle whose opposite corners are
+ # start and end.
+ pts = TransformRectangle(self.doc_to_win, Rect(start, end))
+ if type(pts) == TupleType:
+ apply(self.gc.DrawRectangle, pts)
+ else:
+ self.gc.DrawLines(pts, X.CoordModeOrigin)
def FillRectangle(self, left, top, right, bottom):
- pts = TransformRectangle(self.doc_to_win,
- Rect(left, top, right, bottom))
- if type(pts) == TupleType:
- apply(self.gc.FillRectangle, pts)
- else:
- self.gc.FillPolygon(pts, X.Convex, X.CoordModeOrigin)
+ pts = TransformRectangle(self.doc_to_win,
+ Rect(left, top, right, bottom))
+ if type(pts) == TupleType:
+ apply(self.gc.FillRectangle, pts)
+ else:
+ self.gc.FillPolygon(pts, X.Convex, X.CoordModeOrigin)
def DrawEllipse(self, start, end):
- pts = TransformRectangle(self.doc_to_win, Rect(start, end))
+ pts = TransformRectangle(self.doc_to_win, Rect(start, end))
- if type(pts) == TupleType:
- apply(self.gc.DrawArc, pts + (0, 360 * 64))
- else:
- d = end - start
- self.PushTrafo()
- self.Concat(Trafo(d.x, 0, 0, d.y, start.x, start.y))
- self.DrawBezierPath(circle_path)
- self.PopTrafo()
+ if type(pts) == TupleType:
+ apply(self.gc.DrawArc, pts + (0, 360 * 64))
+ else:
+ d = end - start
+ self.PushTrafo()
+ self.Concat(Trafo(d.x, 0, 0, d.y, start.x, start.y))
+ self.DrawBezierPath(circle_path)
+ self.PopTrafo()
def DrawCircle(self, center, radius):
- rect = Rect(center.x - radius, center.y - radius,
- center.x + radius, center.y + radius)
- pts = TransformRectangle(self.doc_to_win, rect)
- if type(pts) == TupleType:
- apply(self.gc.DrawArc, pts + (0, 360 * 64))
- else:
- self.PushTrafo()
- self.Concat(Trafo(radius, 0, 0, radius, center.x, center.y))
- self.DrawBezierPath(circle_path)
- self.PopTrafo()
+ rect = Rect(center.x - radius, center.y - radius,
+ center.x + radius, center.y + radius)
+ pts = TransformRectangle(self.doc_to_win, rect)
+ if type(pts) == TupleType:
+ apply(self.gc.DrawArc, pts + (0, 360 * 64))
+ else:
+ self.PushTrafo()
+ self.Concat(Trafo(radius, 0, 0, radius, center.x, center.y))
+ self.DrawBezierPath(circle_path)
+ self.PopTrafo()
def FillCircle(self, center, radius):
- rect = Rect(center.x - radius, center.y - radius,
- center.x + radius, center.y + radius)
- pts = TransformRectangle(self.doc_to_win, rect)
- if type(pts) == TupleType:
- apply(self.gc.FillArc, pts + (0, 360 * 64))
- else:
- self.PushTrafo()
- self.Concat(Trafo(radius, 0, 0, radius, center.x, center.y))
- self.FillBezierPath(circle_path)
- self.PopTrafo()
+ rect = Rect(center.x - radius, center.y - radius,
+ center.x + radius, center.y + radius)
+ pts = TransformRectangle(self.doc_to_win, rect)
+ if type(pts) == TupleType:
+ apply(self.gc.FillArc, pts + (0, 360 * 64))
+ else:
+ self.PushTrafo()
+ self.Concat(Trafo(radius, 0, 0, radius, center.x, center.y))
+ self.FillBezierPath(circle_path)
+ self.PopTrafo()
def DrawBezierPath(self, path, rect = None):
- path.draw_transformed(self.gc, self.doc_to_win, 1, 0, rect)
+ path.draw_transformed(self.gc, self.doc_to_win, 1, 0, rect)
def FillBezierPath(self, path, rect = None):
- path.draw_transformed(self.gc, self.doc_to_win, 0, 1, rect)
+ path.draw_transformed(self.gc, self.doc_to_win, 0, 1, rect)
@@ -394,61 +394,61 @@
# some methods common to GraphicsDevice and PostScriptDevice
def draw_arrow(self, arrow, width, pos, dir, rect = None):
- self.PushTrafo()
- self.Translate(pos.x, pos.y)
- self.Rotate(dir.polar()[1])
- if width >= 1.0:
- self.Scale(width)
- self.SetLineSolid()
- arrow.Draw(self) #, rect)
- self.PopTrafo()
+ self.PushTrafo()
+ self.Translate(pos.x, pos.y)
+ self.Rotate(dir.polar()[1])
+ if width >= 1.0:
+ self.Scale(width)
+ self.SetLineSolid()
+ arrow.Draw(self) #, rect)
+ self.PopTrafo()
def draw_arrows(self, paths, rect = None):
- if self.line:
- arrow1 = self.properties.line_arrow1
- arrow2 = self.properties.line_arrow2
- if arrow1 or arrow2:
- width = self.properties.line_width
- for path in paths:
- if not path.closed and path.len > 1:
- if arrow1:
- type, controls, p3, cont = path.Segment(1)
- p = path.Node(0)
- if type == _sketch.Bezier:
- p1, p2 = controls
- dir = p - p1
- if not abs(dir):
- dir = p - p2
- else:
- dir = p - p3
- self.draw_arrow(arrow1, width, p, dir, rect)
- if arrow2:
- type, controls, p, cont = path.Segment(-1)
- p3 = path.Node(-2)
- if type == _sketch.Bezier:
- p1, p2 = controls
- dir = p - p2
- if not abs(dir):
- dir = p - p1
- else:
- dir = p - p3
- self.draw_arrow(arrow2, width, p, dir, rect)
+ if self.line:
+ arrow1 = self.properties.line_arrow1
+ arrow2 = self.properties.line_arrow2
+ if arrow1 or arrow2:
+ width = self.properties.line_width
+ for path in paths:
+ if not path.closed and path.len > 1:
+ if arrow1:
+ type, controls, p3, cont = path.Segment(1)
+ p = path.Node(0)
+ if type == _sketch.Bezier:
+ p1, p2 = controls
+ dir = p - p1
+ if not abs(dir):
+ dir = p - p2
+ else:
+ dir = p - p3
+ self.draw_arrow(arrow1, width, p, dir, rect)
+ if arrow2:
+ type, controls, p, cont = path.Segment(-1)
+ p3 = path.Node(-2)
+ if type == _sketch.Bezier:
+ p1, p2 = controls
+ dir = p - p2
+ if not abs(dir):
+ dir = p - p1
+ else:
+ dir = p - p3
+ self.draw_arrow(arrow2, width, p, dir, rect)
def draw_ellipse_arrows(self, trafo, start_angle, end_angle, arc_type,
- rect = None):
- if arc_type == const.ArcArc and self.line and start_angle != end_angle:
- pi2 = pi / 2
- width = self.properties.line_width
- arrow1 = self.properties.line_arrow1
- if arrow1 is not None:
- pos = trafo(Polar(1, start_angle))
- dir = trafo.DTransform(Polar(1, start_angle - pi2))
- self.draw_arrow(arrow1, width, pos, dir, rect)
- arrow2 = self.properties.line_arrow2
- if arrow2 is not None:
- pos = trafo(Polar(1, end_angle))
- dir = trafo.DTransform(Polar(1, end_angle + pi2))
- self.draw_arrow(arrow2, width, pos, dir, rect)
+ rect = None):
+ if arc_type == const.ArcArc and self.line and start_angle != end_angle:
+ pi2 = pi / 2
+ width = self.properties.line_width
+ arrow1 = self.properties.line_arrow1
+ if arrow1 is not None:
+ pos = trafo(Polar(1, start_angle))
+ dir = trafo.DTransform(Polar(1, start_angle - pi2))
+ self.draw_arrow(arrow1, width, pos, dir, rect)
+ arrow2 = self.properties.line_arrow2
+ if arrow2 is not None:
+ pos = trafo(Polar(1, end_angle))
+ dir = trafo.DTransform(Polar(1, end_angle + pi2))
+ self.draw_arrow(arrow2, width, pos, dir, rect)
use_shm_images = 0
shm_images_supported = 0
@@ -474,180 +474,180 @@
draw_printable = 0
def __init__(self):
- SimpleGC.__init__(self)
- self.line = 0
- self.fill = 0
- self.properties = PropertyStack()
- self.gradient_steps = config.preferences.gradient_steps_editor
- self.images_drawn = 0
- self.unknown_fonts = {}
+ SimpleGC.__init__(self)
+ self.line = 0
+ self.fill = 0
+ self.properties = PropertyStack()
+ self.gradient_steps = config.preferences.gradient_steps_editor
+ self.images_drawn = 0
+ self.unknown_fonts = {}
self.failed_fonts = {}
def InitClip(self):
- SimpleGC.InitClip(self)
- self.images_drawn = 0
+ SimpleGC.InitClip(self)
+ self.images_drawn = 0
proc_fill = proc_line = 0
fill_rect = None
def set_properties(self, properties):
- self.properties = properties
- if properties.HasFill():
- self.fill = 1
- self.proc_fill = properties.IsAlgorithmicFill()
- else:
- self.fill = 0
- self.proc_fill = 0
- if properties.HasLine():
- self.line = 1
- self.proc_line = properties.IsAlgorithmicLine()
- else:
- self.line = 0
- self.proc_line = 0
+ self.properties = properties
+ if properties.HasFill():
+ self.fill = 1
+ self.proc_fill = properties.IsAlgorithmicFill()
+ else:
+ self.fill = 0
+ self.proc_fill = 0
+ if properties.HasLine():
+ self.line = 1
+ self.proc_line = properties.IsAlgorithmicLine()
+ else:
+ self.line = 0
+ self.proc_line = 0
def SetProperties(self, properties, rect = None):
- if not self.outline_mode:
- self.fill_rect = rect
- self.set_properties(properties)
- else:
- # if outline, set only font properties
- self.properties.SetProperty(font = properties.font,
- font_size = properties.font_size)
+ if not self.outline_mode:
+ self.fill_rect = rect
+ self.set_properties(properties)
+ else:
+ # if outline, set only font properties
+ self.properties.SetProperty(font = properties.font,
+ font_size = properties.font_size)
#
def activate_line(self):
- self.properties.ExecuteLine(self)
+ self.properties.ExecuteLine(self)
def activate_fill(self):
- self.properties.ExecuteFill(self, self.fill_rect)
+ self.properties.ExecuteFill(self, self.fill_rect)
#
# Patterns
#
def get_pattern_image(self):
- width = self.widget.width
- height = self.widget.height
- winrect = self.doc_to_win(self.fill_rect)
- left, top, right, bottom = map(int, map(round, winrect))
- l = max(left, 0); r = min(right, width);
- t = max(top, 0); b = min(bottom, height);
- if type(self.clip_region) == PaxRegionType:
- cx, cy, cw, ch = self.clip_region.ClipBox()
- l = max(l, cx); r = min(r, cx + cw)
- t = max(t, cy); b = min(b, cy + ch)
- if l >= r or t >= b:
- return None, None, None
- image = PIL.Image.new('RGB', (r - l, b - t), (255, 255, 255))
- trafo = Translation(-l, -t)(self.doc_to_win)
- return image, trafo, (l, t)
+ width = self.widget.width
+ height = self.widget.height
+ winrect = self.doc_to_win(self.fill_rect)
+ left, top, right, bottom = map(int, map(round, winrect))
+ l = max(left, 0); r = min(right, width);
+ t = max(top, 0); b = min(bottom, height);
+ if type(self.clip_region) == PaxRegionType:
+ cx, cy, cw, ch = self.clip_region.ClipBox()
+ l = max(l, cx); r = min(r, cx + cw)
+ t = max(t, cy); b = min(b, cy + ch)
+ if l >= r or t >= b:
+ return None, None, None
+ image = PIL.Image.new('RGB', (r - l, b - t), (255, 255, 255))
+ trafo = Translation(-l, -t)(self.doc_to_win)
+ return image, trafo, (l, t)
def draw_pattern_image(self, image, pos):
- if use_shm_images and self.images_drawn:
- # force a shmimage to be drawn if ShmPutImage requests might
- # be in the queue
- self.widget.Sync()
- self.create_ximage()
- ximage = self.ximage
- x, y = pos
- w, h = image.size
- _sketch.copy_image_to_ximage(self.visual, image.im, ximage, x, y, w, h)
- if use_shm_images:
- self.gc.ShmPutImage(ximage, x, y, x, y, w, h, 0)
- self.images_drawn = 1
- else:
- self.gc.PutImage(ximage, x, y, x, y, w, h)
+ if use_shm_images and self.images_drawn:
+ # force a shmimage to be drawn if ShmPutImage requests might
+ # be in the queue
+ self.widget.Sync()
+ self.create_ximage()
+ ximage = self.ximage
+ x, y = pos
+ w, h = image.size
+ _sketch.copy_image_to_ximage(self.visual, image.im, ximage, x, y, w, h)
+ if use_shm_images:
+ self.gc.ShmPutImage(ximage, x, y, x, y, w, h, 0)
+ self.images_drawn = 1
+ else:
+ self.gc.PutImage(ximage, x, y, x, y, w, h)
has_axial_gradient = 1
def AxialGradient(self, gradient, p0, p1):
- # p0 and p1 may be PointSpecs
- image, trafo, pos = self.get_pattern_image()
- if image is None:
- return
- x0, y0 = trafo(p0)
- x1, y1 = trafo(p1)
- #import time
- #_t = time.clock()
- _sketch.fill_axial_gradient(image.im, gradient.Colors(), x0,y0, x1,y1)
- #_t = time.clock() - _t
- #print 'axial:', _t
- self.draw_pattern_image(image, pos)
+ # p0 and p1 may be PointSpecs
+ image, trafo, pos = self.get_pattern_image()
+ if image is None:
+ return
+ x0, y0 = trafo(p0)
+ x1, y1 = trafo(p1)
+ #import time
+ #_t = time.clock()
+ _sketch.fill_axial_gradient(image.im, gradient.Colors(), x0,y0, x1,y1)
+ #_t = time.clock() - _t
+ #print 'axial:', _t
+ self.draw_pattern_image(image, pos)
has_radial_gradient = 1
def RadialGradient(self, gradient, p, r0, r1):
- # p may be PointSpec
- image, trafo, pos = self.get_pattern_image()
- if image is None:
- return
- x, y = trafo.DocToWin(p)
- r0 = int(round(abs(trafo.DTransform(r0, 0))))
- r1 = int(round(abs(trafo.DTransform(r1, 0))))
- #import time
- #_t = time.clock()
- _sketch.fill_radial_gradient(image.im, gradient.Colors(), x, y, r0, r1)
- #_t = time.clock() - _t
- #print 'radial:', _t
- self.draw_pattern_image(image, pos)
+ # p may be PointSpec
+ image, trafo, pos = self.get_pattern_image()
+ if image is None:
+ return
+ x, y = trafo.DocToWin(p)
+ r0 = int(round(abs(trafo.DTransform(r0, 0))))
+ r1 = int(round(abs(trafo.DTransform(r1, 0))))
+ #import time
+ #_t = time.clock()
+ _sketch.fill_radial_gradient(image.im, gradient.Colors(), x, y, r0, r1)
+ #_t = time.clock() - _t
+ #print 'radial:', _t
+ self.draw_pattern_image(image, pos)
has_conical_gradient = 1
def ConicalGradient(self, gradient, p, angle):
- # p may be PointSpec
- image, trafo, pos = self.get_pattern_image()
- if image is None:
- return
- cx, cy = trafo.DocToWin(p)
- #import time
- #_t = time.clock()
- _sketch.fill_conical_gradient(image.im, gradient.Colors(), cx, cy,
- -angle)
- #_t = time.clock() - _t
- #print 'conical:', _t
- self.draw_pattern_image(image, pos)
+ # p may be PointSpec
+ image, trafo, pos = self.get_pattern_image()
+ if image is None:
+ return
+ cx, cy = trafo.DocToWin(p)
+ #import time
+ #_t = time.clock()
+ _sketch.fill_conical_gradient(image.im, gradient.Colors(), cx, cy,
+ -angle)
+ #_t = time.clock() - _t
+ #print 'conical:', _t
+ self.draw_pattern_image(image, pos)
use_pixmap_tile = 1
def TileImage(self, tile, trafo):
- # XXX this could be faster with some caching.
+ # XXX this could be faster with some caching.
width, height = self.doc_to_win(trafo).DTransform(tile.size)
width = int(round(width))
height = int(round(height))
- if self.use_pixmap_tile and trafo.m12 == 0 and trafo.m21 == 0 \
+ if self.use_pixmap_tile and trafo.m12 == 0 and trafo.m21 == 0 \
and width * height < self.widget.width * self.widget.height:
- # the image is only scaled. Use a tile pixmap
- #
- # there are other cases where this could be done:
- # horizontal/vertical shearing, rotation by 90 degrees,...
- # This should also be done like in DrawImage, i.e. use the
- # integer coordintes of the transformed tile to determine if
- # pixmaps can be used. This would be a little less precise,
- # though.
- # degenerate cases
- if width == 0: width = 1
- if height == 0: height = 1
- ximage = self.create_sized_ximage(abs(width), abs(height))
- pixmap = self.widget.CreatePixmap(abs(width), abs(height),
- ximage.depth)
- _sketch.copy_image_to_ximage(self.visual, tile.im, ximage,
- 0, 0, width, height)
- gc = pixmap.CreateGC()
- gc.PutImage(ximage, 0, 0, 0, 0, abs(width), abs(height))
- self.gc.SetForegroundAndFill(pixmap)
- x, y = trafo.DocToWin(0, 0)
- self.gc.SetTSOrigin(x, y)
- self.gc.FillRectangle(0, 0, self.widget.width, self.widget.height)
- else:
- image, temp_trafo, pos = self.get_pattern_image()
- if image is None:
- return
- trafo = temp_trafo(trafo)
- try:
- _sketch.fill_transformed_tile(image.im, tile.im,
- trafo.inverse())
- self.draw_pattern_image(image, pos)
- except SingularMatrix:
- pass
+ # the image is only scaled. Use a tile pixmap
+ #
+ # there are other cases where this could be done:
+ # horizontal/vertical shearing, rotation by 90 degrees,...
+ # This should also be done like in DrawImage, i.e. use the
+ # integer coordintes of the transformed tile to determine if
+ # pixmaps can be used. This would be a little less precise,
+ # though.
+ # degenerate cases
+ if width == 0: width = 1
+ if height == 0: height = 1
+ ximage = self.create_sized_ximage(abs(width), abs(height))
+ pixmap = self.widget.CreatePixmap(abs(width), abs(height),
+ ximage.depth)
+ _sketch.copy_image_to_ximage(self.visual, tile.im, ximage,
+ 0, 0, width, height)
+ gc = pixmap.CreateGC()
+ gc.PutImage(ximage, 0, 0, 0, 0, abs(width), abs(height))
+ self.gc.SetForegroundAndFill(pixmap)
+ x, y = trafo.DocToWin(0, 0)
+ self.gc.SetTSOrigin(x, y)
+ self.gc.FillRectangle(0, 0, self.widget.width, self.widget.height)
+ else:
+ image, temp_trafo, pos = self.get_pattern_image()
+ if image is None:
+ return
+ trafo = temp_trafo(trafo)
+ try:
+ _sketch.fill_transformed_tile(image.im, tile.im,
+ trafo.inverse())
+ self.draw_pattern_image(image, pos)
+ except SingularMatrix:
+ pass
#
@@ -667,23 +667,23 @@
allow_outline = 1
def StartOutlineMode(self, color = None):
- if self.allow_outline:
- self.outline_mode = (self.properties, self.outline_mode)
- if color is None:
- properties = self.outline_style
- else:
- properties = PropertyStack()
+ if self.allow_outline:
+ self.outline_mode = (self.properties, self.outline_mode)
+ if color is None:
+ properties = self.outline_style
+ else:
+ properties = PropertyStack()
properties.SetProperty(fill_pattern = EmptyPattern)
- properties.AddStyle(SolidLine(color))
- self.set_properties(properties)
+ properties.AddStyle(SolidLine(color))
+ self.set_properties(properties)
def EndOutlineMode(self):
- if self.allow_outline and self.outline_mode:
- properties, self.outline_mode = self.outline_mode
- self.set_properties(properties)
+ if self.allow_outline and self.outline_mode:
+ properties, self.outline_mode = self.outline_mode
+ self.set_properties(properties)
def IsOutlineActive(self):
- return not not self.outline_mode
+ return not not self.outline_mode
#
@@ -691,233 +691,233 @@
#
def Rectangle(self, trafo, clip = 0):
- self.PushTrafo()
- self.Concat(trafo)
- pts = TransformRectangle(self.doc_to_win, UnitRect)
- self.PopTrafo()
- if type(pts) == TupleType:
- if self.proc_fill:
- if not clip:
- self.PushClip()
- self.ClipRect(pts)
- self.properties.ExecuteFill(self, self.fill_rect)
- if not clip:
- self.PopClip()
- clip = 0
- elif self.fill:
- self.properties.ExecuteFill(self, self.fill_rect)
- apply(self.gc.FillRectangle, pts)
- if self.line:
- self.properties.ExecuteLine(self)
- apply(self.gc.DrawRectangle, pts)
- else:
- if self.proc_fill:
- if not clip:
- self.PushClip()
- self.ClipPolygon(pts)
- self.properties.ExecuteFill(self, self.fill_rect)
- if not clip:
- self.PopClip()
- clip = 0
- elif self.fill:
- self.properties.ExecuteFill(self, self.fill_rect)
- self.gc.FillPolygon(pts, X.Convex, X.CoordModeOrigin)
- if self.line:
- self.properties.ExecuteLine(self)
- self.gc.DrawLines(pts, X.CoordModeOrigin)
- if clip:
- if type(pts) == TupleType:
- self.ClipRect(pts)
- else:
- self.ClipPolygon(pts)
+ self.PushTrafo()
+ self.Concat(trafo)
+ pts = TransformRectangle(self.doc_to_win, UnitRect)
+ self.PopTrafo()
+ if type(pts) == TupleType:
+ if self.proc_fill:
+ if not clip:
+ self.PushClip()
+ self.ClipRect(pts)
+ self.properties.ExecuteFill(self, self.fill_rect)
+ if not clip:
+ self.PopClip()
+ clip = 0
+ elif self.fill:
+ self.properties.ExecuteFill(self, self.fill_rect)
+ apply(self.gc.FillRectangle, pts)
+ if self.line:
+ self.properties.ExecuteLine(self)
+ apply(self.gc.DrawRectangle, pts)
+ else:
+ if self.proc_fill:
+ if not clip:
+ self.PushClip()
+ self.ClipPolygon(pts)
+ self.properties.ExecuteFill(self, self.fill_rect)
+ if not clip:
+ self.PopClip()
+ clip = 0
+ elif self.fill:
+ self.properties.ExecuteFill(self, self.fill_rect)
+ self.gc.FillPolygon(pts, X.Convex, X.CoordModeOrigin)
+ if self.line:
+ self.properties.ExecuteLine(self)
+ self.gc.DrawLines(pts, X.CoordModeOrigin)
+ if clip:
+ if type(pts) == TupleType:
+ self.ClipRect(pts)
+ else:
+ self.ClipPolygon(pts)
def RoundedRectangle(self, trafo, radius1, radius2, clip = 0):
- path = _sketch.RoundedRectanglePath(trafo, radius1, radius2)
- self.MultiBezier((path,), None, clip)
+ path = _sketch.RoundedRectanglePath(trafo, radius1, radius2)
+ self.MultiBezier((path,), None, clip)
def SimpleEllipse(self, trafo, start_angle, end_angle, arc_type,
- rect = None, clip = 0):
- trafo2 = self.doc_to_win(trafo)
- if trafo2.m12 == 0.0 and trafo2.m21 == 0.0 and not self.proc_fill \
- and start_angle == end_angle and not clip:
- x1, y1 = trafo2.DocToWin(1, 1)
- x2, y2 = trafo2.DocToWin(-1, -1)
- if x1 > x2:
- t = x1; x1 = x2; x2 = t
- if y1 > y2:
- t = y1; y1 = y2; y2 = t
- w = x2 - x1
- h = y2 - y1
- if self.fill:
- self.properties.ExecuteFill(self, self.fill_rect)
- self.gc.FillArc(x1, y1, w, h, 0, 23040) # 360 * 64
- if self.line:
- self.properties.ExecuteLine(self)
- self.gc.DrawArc(x1, y1, w, h, 0, 23040)
- else:
- if self.line:
- line = self.activate_line
- else:
- line = None
- if self.fill:
- fill = self.activate_fill
- else:
- fill = None
+ rect = None, clip = 0):
+ trafo2 = self.doc_to_win(trafo)
+ if trafo2.m12 == 0.0 and trafo2.m21 == 0.0 and not self.proc_fill \
+ and start_angle == end_angle and not clip:
+ x1, y1 = trafo2.DocToWin(1, 1)
+ x2, y2 = trafo2.DocToWin(-1, -1)
+ if x1 > x2:
+ t = x1; x1 = x2; x2 = t
+ if y1 > y2:
+ t = y1; y1 = y2; y2 = t
+ w = x2 - x1
+ h = y2 - y1
+ if self.fill:
+ self.properties.ExecuteFill(self, self.fill_rect)
+ self.gc.FillArc(x1, y1, w, h, 0, 23040) # 360 * 64
+ if self.line:
+ self.properties.ExecuteLine(self)
+ self.gc.DrawArc(x1, y1, w, h, 0, 23040)
+ else:
+ if self.line:
+ line = self.activate_line
+ else:
+ line = None
+ if self.fill:
+ fill = self.activate_fill
+ else:
+ fill = None
- if start_angle != end_angle:
- arc = _sketch.approx_arc(start_angle, end_angle, arc_type)
- else:
- arc = circle_path
- # pass rect as None, because trafo2 is not really the
- # viewport transformation
- _sketch.draw_multipath(self.gc, trafo2, line, fill,
- self.PushClip, self.PopClip,
- self.ClipRegion, None, (arc,),
- CreateRegion(), self.proc_fill, clip)
- self.draw_ellipse_arrows(trafo, start_angle, end_angle, arc_type,
- rect)
+ if start_angle != end_angle:
+ arc = _sketch.approx_arc(start_angle, end_angle, arc_type)
+ else:
+ arc = circle_path
+ # pass rect as None, because trafo2 is not really the
+ # viewport transformation
+ _sketch.draw_multipath(self.gc, trafo2, line, fill,
+ self.PushClip, self.PopClip,
+ self.ClipRegion, None, (arc,),
+ CreateRegion(), self.proc_fill, clip)
+ self.draw_ellipse_arrows(trafo, start_angle, end_angle, arc_type,
+ rect)
def MultiBezier(self, paths, rect = None, clip = 0):
- if self.line:
- line = self.activate_line
- else:
- line = None
- if self.fill:
- fill = self.activate_fill
- else:
- fill = None
+ if self.line:
+ line = self.activate_line
+ else:
+ line = None
+ if self.fill:
+ fill = self.activate_fill
+ else:
+ fill = None
- _sketch.draw_multipath(self.gc, self.doc_to_win, line, fill,
- self.PushClip, self.PopClip, self.ClipRegion,
- rect, paths, CreateRegion(), self.proc_fill,
- clip)
+ _sketch.draw_multipath(self.gc, self.doc_to_win, line, fill,
+ self.PushClip, self.PopClip, self.ClipRegion,
+ rect, paths, CreateRegion(), self.proc_fill,
+ clip)
- if self.line:
- self.draw_arrows(paths, rect)
+ if self.line:
+ self.draw_arrows(paths, rect)
def draw_text_on_gc(self, gc, text, trafo, font, font_size, cache = None):
- self.PushTrafo()
- try:
- self.Concat(trafo)
- self.Scale(font_size)
- up = self.doc_to_win.DTransform(0, 1)
- if abs(up) >= config.preferences.greek_threshold:
- ptrafo = FlipY(self.doc_to_win)
- xlfd = font.GetXLFD(ptrafo)
- if (ptrafo and (ptrafo.m12 != 0 or ptrafo.m21 != 0
- or ptrafo.m11 > 40 or ptrafo.m11 < 0
- or ptrafo.m22 > 40 or ptrafo.m22 < 0)):
- xlfd = '%s[%s]' % (xlfd, _sketch.xlfd_char_range(text))
- try:
- xfont = self.load_font(xlfd, cache)
- except RuntimeError, val:
- # We must be careful here when reporting this to the
- # user. If warn pops up a message box and the user
- # clicks OK, the window gets another expose event
- # and sketch tries to draw the text again which will
- # also fail. To avoid infinite loops we try to
- # report unknown fonts only once for a given font.
- if not self.unknown_fonts.has_key(font.PostScriptName()):
- warn(USER, _("Cannot load %(font)s:\n%(text)s"),
- font = `xlfd`, text = val)
- self.unknown_fonts[font.PostScriptName()] = 1
- # Use a font that will hopefully be always available.
- # XXX Is there a better way to handle this situation?
- # We might try times roman with the same size and trafo
- xfont = self.load_font('fixed', None)
- gc.SetFont(xfont)
+ self.PushTrafo()
+ try:
+ self.Concat(trafo)
+ self.Scale(font_size)
+ up = self.doc_to_win.DTransform(0, 1)
+ if abs(up) >= config.preferences.greek_threshold:
+ ptrafo = FlipY(self.doc_to_win)
+ xlfd = font.GetXLFD(ptrafo)
+ if (ptrafo and (ptrafo.m12 != 0 or ptrafo.m21 != 0
+ or ptrafo.m11 > 40 or ptrafo.m11 < 0
+ or ptrafo.m22 > 40 or ptrafo.m22 < 0)):
+ xlfd = '%s[%s]' % (xlfd, _sketch.xlfd_char_range(text))
+ try:
+ xfont = self.load_font(xlfd, cache)
+ except RuntimeError, val:
+ # We must be careful here when reporting this to the
+ # user. If warn pops up a message box and the user
+ # clicks OK, the window gets another expose event
+ # and sketch tries to draw the text again which will
+ # also fail. To avoid infinite loops we try to
+ # report unknown fonts only once for a given font.
+ if not self.unknown_fonts.has_key(font.PostScriptName()):
+ warn(USER, _("Cannot load %(font)s:\n%(text)s"),
+ font = `xlfd`, text = val)
+ self.unknown_fonts[font.PostScriptName()] = 1
+ # Use a font that will hopefully be always available.
+ # XXX Is there a better way to handle this situation?
+ # We might try times roman with the same size and trafo
+ xfont = self.load_font('fixed', None)
+ gc.SetFont(xfont)
- pos = font.TypesetText(text)
- pos = map(self.DocToWin, pos)
- for i in range(len(text)):
- x, y = pos[i]
- gc.DrawString(x, y, text[i])
- else:
- # 'greek'. XXX is this really necessary. It avoids
- # rendering fonts that are too small to read.
- pos = font.TypesetText(text)
- pos = map(self.DocToWin, pos)
- ux, uy = up
- lx = ux / 2; ly = uy / 2
- uppercase = string.uppercase
- draw = gc.DrawLine # we should draw rectangles...
- for i in range(len(text)):
- x, y = pos[i]
- if text[i] in uppercase:
- draw(x, y, int(round(x + ux)), int(round(y + uy)))
- else:
- draw(x, y, int(round(x + lx)), int(round(y + ly)))
- finally:
- self.PopTrafo()
+ pos = font.TypesetText(text)
+ pos = map(self.DocToWin, pos)
+ for i in range(len(text)):
+ x, y = pos[i]
+ gc.DrawString(x, y, text[i])
+ else:
+ # 'greek'. XXX is this really necessary. It avoids
+ # rendering fonts that are too small to read.
+ pos = font.TypesetText(text)
+ pos = map(self.DocToWin, pos)
+ ux, uy = up
+ lx = ux / 2; ly = uy / 2
+ uppercase = string.uppercase
+ draw = gc.DrawLine # we should draw rectangles...
+ for i in range(len(text)):
+ x, y = pos[i]
+ if text[i] in uppercase:
+ draw(x, y, int(round(x + ux)), int(round(y + uy)))
+ else:
+ draw(x, y, int(round(x + lx)), int(round(y + ly)))
+ finally:
+ self.PopTrafo()
def DrawText(self, text, trafo = None, clip = 0, cache = None):
- if text and self.properties.font:
- if self.fill or clip:
- if self.proc_fill or clip:
- bitmap, bitmapgc = self.create_clip_bitmap()
- self.draw_text_on_gc(bitmapgc, text, trafo,
- self.properties.font,
- self.properties.font_size,
- cache)
- if not clip:
- self.PushClip()
- self.ClipBitmap(bitmap)
- self.properties.ExecuteFill(self, self.fill_rect)
- if not self.proc_fill:
- w, h = bitmap.GetGeometry()[3:5]
- bitmap.CopyPlane(self.widget, self.gc, 0, 0, w, h,
- 0, 0, 1)
- if not clip:
- self.PopClip()
- else:
- self.properties.ExecuteFill(self)
- self.draw_text_on_gc(self.gc, text, trafo,
- self.properties.font,
- self.properties.font_size,
- cache)
- elif self.IsOutlineActive():
- # in outline mode, draw text filled with the current
- # outline color, because we can't draw outlined text at
- # the moment. We could draw a rectangle, though. (?)
- self.properties.ExecuteLine(self)
- self.draw_text_on_gc(self.gc, text, trafo,
- self.properties.font,
- self.properties.font_size,
- cache)
+ if text and self.properties.font:
+ if self.fill or clip:
+ if self.proc_fill or clip:
+ bitmap, bitmapgc = self.create_clip_bitmap()
+ self.draw_text_on_gc(bitmapgc, text, trafo,
+ self.properties.font,
+ self.properties.font_size,
+ cache)
+ if not clip:
+ self.PushClip()
+ self.ClipBitmap(bitmap)
+ self.properties.ExecuteFill(self, self.fill_rect)
+ if not self.proc_fill:
+ w, h = bitmap.GetGeometry()[3:5]
+ bitmap.CopyPlane(self.widget, self.gc, 0, 0, w, h,
+ 0, 0, 1)
+ if not clip:
+ self.PopClip()
+ else:
+ self.properties.ExecuteFill(self)
+ self.draw_text_on_gc(self.gc, text, trafo,
+ self.properties.font,
+ self.properties.font_size,
+ cache)
+ elif self.IsOutlineActive():
+ # in outline mode, draw text filled with the current
+ # outline color, because we can't draw outlined text at
+ # the moment. We could draw a rectangle, though. (?)
+ self.properties.ExecuteLine(self)
+ self.draw_text_on_gc(self.gc, text, trafo,
+ self.properties.font,
+ self.properties.font_size,
+ cache)
def ResetFontCache(self):
- self.font_cache = {}
+ self.font_cache = {}
def load_font(self, xlfd, cache):
- font_cache = self.font_cache
- complex_text = self.complex_text
-
+ font_cache = self.font_cache
+ complex_text = self.complex_text
+
if self.failed_fonts.has_key(xlfd):
# the same xlfd failed before. use fixed as fallback
# immediately to avoid delays. some servers apparantly take
# very long to decide that they can't load a font.
xlfd = 'fixed'
- if cache and cache.has_key(id(self)):
- old_xlfd, old_font = cache[id(self)]
- if old_xlfd == xlfd:
- font_cache[xlfd] = old_font
- return old_font
+ if cache and cache.has_key(id(self)):
+ old_xlfd, old_font = cache[id(self)]
+ if old_xlfd == xlfd:
+ font_cache[xlfd] = old_font
+ return old_font
- if complex_text is not None:
- cache = complex_text.cache
- key = id(self), complex_text.idx
- if cache.has_key(key):
- old_xlfd, old_font = cache[key]
- if old_xlfd == xlfd:
- font_cache[xlfd] = old_font
- return old_font
- cache = None
+ if complex_text is not None:
+ cache = complex_text.cache
+ key = id(self), complex_text.idx
+ if cache.has_key(key):
+ old_xlfd, old_font = cache[key]
+ if old_xlfd == xlfd:
+ font_cache[xlfd] = old_font
+ return old_font
+ cache = None
- if font_cache is not None and font_cache.has_key(xlfd):
- font = font_cache[xlfd]
- else:
+ if font_cache is not None and font_cache.has_key(xlfd):
+ font = font_cache[xlfd]
+ else:
#print 'load font', xlfd
try:
font = self.widget.LoadQueryFont(xlfd)
@@ -925,65 +925,65 @@
self.failed_fonts[xlfd] = 1
raise
- if font_cache is not None:
- font_cache[xlfd] = font
- if cache is not None:
- cache[id(self)] = (xlfd, font)
- elif complex_text is not None:
- complex_text.cache[(id(self), complex_text.idx)] = (xlfd, font)
+ if font_cache is not None:
+ font_cache[xlfd] = font
+ if cache is not None:
+ cache[id(self)] = (xlfd, font)
+ elif complex_text is not None:
+ complex_text.cache[(id(self), complex_text.idx)] = (xlfd, font)
- return font
+ return font
complex_text = None
def BeginComplexText(self, clip = 0, cache = None):
- if self.fill or clip or self.IsOutlineActive():
- if cache is None:
- cache = {}
- if self.proc_fill or clip:
- bitmap, gc = self.create_clip_bitmap()
- self.complex_text = Empty(bitmap = bitmap, gc = gc,
- clip = clip, cache = cache, idx = 0)
- else:
- if self.fill:
- self.properties.ExecuteFill(self)
- else:
- # outline mode
- self.properties.ExecuteLine(self)
- self.complex_text = Empty(gc = self.gc, clip = 0,
- cache = cache, idx = 0)
- else:
- self.complex_text = None
+ if self.fill or clip or self.IsOutlineActive():
+ if cache is None:
+ cache = {}
+ if self.proc_fill or clip:
+ bitmap, gc = self.create_clip_bitmap()
+ self.complex_text = Empty(bitmap = bitmap, gc = gc,
+ clip = clip, cache = cache, idx = 0)
+ else:
+ if self.fill:
+ self.properties.ExecuteFill(self)
+ else:
+ # outline mode
+ self.properties.ExecuteLine(self)
+ self.complex_text = Empty(gc = self.gc, clip = 0,
+ cache = cache, idx = 0)
+ else:
+ self.complex_text = None
def DrawComplexText(self, text, trafo, font, font_size):
- if self.complex_text is not None:
- self.draw_text_on_gc(self.complex_text.gc, text, trafo, font,
- font_size)
- self.complex_text.idx = self.complex_text.idx + 1
+ if self.complex_text is not None:
+ self.draw_text_on_gc(self.complex_text.gc, text, trafo, font,
+ font_size)
+ self.complex_text.idx = self.complex_text.idx + 1
def EndComplexText(self):
- if self.complex_text is not None:
- if self.complex_text.clip or self.proc_fill:
- bitmap = self.complex_text.bitmap
- self.PushClip()
- self.ClipBitmap(bitmap)
- self.properties.ExecuteFill(self, self.fill_rect)
- if not self.proc_fill:
- w, h = bitmap.GetGeometry()[3:5]
- bitmap.CopyPlane(self.widget, self.gc, 0, 0, w, h,
- 0, 0, 1)
- if not self.complex_text.clip:
- self.PopClip()
- self.complex_text = None
+ if self.complex_text is not None:
+ if self.complex_text.clip or self.proc_fill:
+ bitmap = self.complex_text.bitmap
+ self.PushClip()
+ self.ClipBitmap(bitmap)
+ self.properties.ExecuteFill(self, self.fill_rect)
+ if not self.proc_fill:
+ w, h = bitmap.GetGeometry()[3:5]
+ bitmap.CopyPlane(self.widget, self.gc, 0, 0, w, h,
+ 0, 0, 1)
+ if not self.complex_text.clip:
+ self.PopClip()
+ self.complex_text = None
def create_ximage(self):
global use_shm_images
- if not self.ximage:
- w = self.widget
- if use_shm_images and not shm_images_supported:
- warn(INTERNAL,
- 'tried to use unsupported shared memory images\n')
- use_shm_images = 0
- if use_shm_images:
+ if not self.ximage:
+ w = self.widget
+ if use_shm_images and not shm_images_supported:
+ warn(INTERNAL,
+ 'tried to use unsupported shared memory images\n')
+ use_shm_images = 0
+ if use_shm_images:
try:
self.ximage = w.ShmCreateImage(w.depth, X.ZPixmap,
None, w.width, w.height, 1)
@@ -998,206 +998,206 @@
sys.exc_info()[1])
use_shm_images = 0
if not self.ximage:
- self.ximage = self.create_sized_ximage(w.width, w.height)
+ self.ximage = self.create_sized_ximage(w.width, w.height)
def create_sized_ximage(self, width, height):
- w = self.widget
- depth = w.depth
- if depth > 16:
- bpl = 4 * width
- elif depth > 8:
- bpl = ((2 * width + 3) / 4) * 4
- elif depth == 8:
- bpl = ((width + 3) / 4) * 4
- else:
- raise SketchError('unsupported depth for images')
- return w.CreateImage(w.depth, X.ZPixmap, 0, None, width, height,
- 32, bpl)
+ w = self.widget
+ depth = w.depth
+ if depth > 16:
+ bpl = 4 * width
+ elif depth > 8:
+ bpl = ((2 * width + 3) / 4) * 4
+ elif depth == 8:
+ bpl = ((width + 3) / 4) * 4
+ else:
+ raise SketchError('unsupported depth for images')
+ return w.CreateImage(w.depth, X.ZPixmap, 0, None, width, height,
+ 32, bpl)
def DrawImage(self, image, trafo, clip = 0):
- w, h = image.size
- if self.IsOutlineActive():
- self.PushTrafo()
- self.Concat(trafo)
- self.DrawRectangle(Point(0, 0), Point(w, h))
- self.PopTrafo()
- return
- self.create_ximage()
- ximage = self.ximage
- if use_shm_images and self.IsClipping() and self.images_drawn:
- # force a shmimage to be drawn if complex clipping is done
- # or ShmPutImage requests might be in the queue.
- self.widget.Sync()
- self.images_drawn = 0
- llx, lly = self.DocToWin(trafo.offset())
- lrx, lry = self.DocToWin(trafo(w, 0))
- ulx, uly = self.DocToWin(trafo(0, h))
- urx, ury = self.DocToWin(trafo(w, h))
- if llx == ulx and lly == lry:
- if llx < lrx:
- sx = llx; w = lrx - llx + 1
- else:
- sx = lrx; w = lrx - llx - 1
- if uly < lly:
- sy = uly; h = lly - uly + 1
- else:
- sy = lly; h = lly - uly - 1
+ w, h = image.size
+ if self.IsOutlineActive():
+ self.PushTrafo()
+ self.Concat(trafo)
+ self.DrawRectangle(Point(0, 0), Point(w, h))
+ self.PopTrafo()
+ return
+ self.create_ximage()
+ ximage = self.ximage
+ if use_shm_images and self.IsClipping() and self.images_drawn:
+ # force a shmimage to be drawn if complex clipping is done
+ # or ShmPutImage requests might be in the queue.
+ self.widget.Sync()
+ self.images_drawn = 0
+ llx, lly = self.DocToWin(trafo.offset())
+ lrx, lry = self.DocToWin(trafo(w, 0))
+ ulx, uly = self.DocToWin(trafo(0, h))
+ urx, ury = self.DocToWin(trafo(w, h))
+ if llx == ulx and lly == lry:
+ if llx < lrx:
+ sx = llx; w = lrx - llx + 1
+ else:
+ sx = lrx; w = lrx - llx - 1
+ if uly < lly:
+ sy = uly; h = lly - uly + 1
+ else:
+ sy = lly; h = lly - uly - 1
- _sketch.copy_image_to_ximage(self.visual, image.im, ximage,
- sx, sy, w, h)
- if w < 0: w = -w
- if h < 0: h = -h
- if not clip:
- self.PushClip()
- self.ClipRect((sx, sy, w, h))
- else:
- self.PushTrafo()
- self.Concat(trafo)
- self.Concat(Trafo(1, 0, 0, -1, 0, h))
- inverse = self.win_to_doc
- dtw = self.DocToWin
- ulx, uly = dtw(0, 0)
- urx, ury = dtw(0, h)
- llx, lly = dtw(w, 0)
- lrx, lry = dtw(w, h)
- self.PopTrafo()
- sx = min(ulx, llx, urx, lrx)
- ex = max(ulx, llx, urx, lrx)
- sy = min(uly, lly, ury, lry)
- ey = max(uly, lly, ury, lry)
+ _sketch.copy_image_to_ximage(self.visual, image.im, ximage,
+ sx, sy, w, h)
+ if w < 0: w = -w
+ if h < 0: h = -h
+ if not clip:
+ self.PushClip()
+ self.ClipRect((sx, sy, w, h))
+ else:
+ self.PushTrafo()
+ self.Concat(trafo)
+ self.Concat(Trafo(1, 0, 0, -1, 0, h))
+ inverse = self.win_to_doc
+ dtw = self.DocToWin
+ ulx, uly = dtw(0, 0)
+ urx, ury = dtw(0, h)
+ llx, lly = dtw(w, 0)
+ lrx, lry = dtw(w, h)
+ self.PopTrafo()
+ sx = min(ulx, llx, urx, lrx)
+ ex = max(ulx, llx, urx, lrx)
+ sy = min(uly, lly, ury, lry)
+ ey = max(uly, lly, ury, lry)
- if type(self.clip_region) == PaxRegionType:
- cx, cy, cw, ch = self.clip_region.ClipBox()
- cex = cx + cw; cey = cy + ch
- if cx >= ex or cex <= sx or cy >= ey or cey <= sy:
- return
- if cx > sx and cx < ex: sx = cx
- if cex < ex and cex > sx: ex = cex
- if cy > sy and cy < ey: sy = cy
- if cey < ey and cey > sy: ey = cey
- w = ex - sx
- h = ey - sy
+ if type(self.clip_region) == PaxRegionType:
+ cx, cy, cw, ch = self.clip_region.ClipBox()
+ cex = cx + cw; cey = cy + ch
+ if cx >= ex or cex <= sx or cy >= ey or cey <= sy:
+ return
+ if cx > sx and cx < ex: sx = cx
+ if cex < ex and cex > sx: ex = cex
+ if cy > sy and cy < ey: sy = cy
+ if cey < ey and cey > sy: ey = cey
+ w = ex - sx
+ h = ey - sy
- region = self.widget.CreateRegion()
- _sketch.transform_to_ximage(self.visual, inverse,
- image.im, ximage, sx, sy, w, h, region)
- if not clip:
- self.PushClip()
- self.ClipRegion(region)
+ region = self.widget.CreateRegion()
+ _sketch.transform_to_ximage(self.visual, inverse,
+ image.im, ximage, sx, sy, w, h, region)
+ if not clip:
+ self.PushClip()
+ self.ClipRegion(region)
- if sx+w <= 0 or sx >= ximage.width or sy+h <= 0 or sy >= ximage.height:
- if not clip:
- self.PopClip()
- return
+ if sx+w <= 0 or sx >= ximage.width or sy+h <= 0 or sy >= ximage.height:
+ if not clip:
+ self.PopClip()
+ return
- if sx < 0:
- w = w + sx
- sx = 0
- if sx + w > ximage.width:
- w = ximage.width - sx
- if sy < 0:
- h = h + sy
- sy = 0
- if sy + h > ximage.height:
- h = ximage.height - sy
+ if sx < 0:
+ w = w + sx
+ sx = 0
+ if sx + w > ximage.width:
+ w = ximage.width - sx
+ if sy < 0:
+ h = h + sy
+ sy = 0
+ if sy + h > ximage.height:
+ h = ximage.height - sy
- if use_shm_images:
- self.gc.ShmPutImage(ximage, sx, sy, sx, sy, w, h, 0)
- self.images_drawn = 1
- else:
- self.gc.PutImage(ximage, sx, sy, sx, sy, w, h)
- if not clip:
- self.PopClip()
+ if use_shm_images:
+ self.gc.ShmPutImage(ximage, sx, sy, sx, sy, w, h, 0)
+ self.images_drawn = 1
+ else:
+ self.gc.PutImage(ximage, sx, sy, sx, sy, w, h)
+ if not clip:
+ self.PopClip()
def DrawEps(self, data, trafo):
- if not data.image or self.IsOutlineActive():
- w, h = data.Size()
- self.PushTrafo()
- self.Concat(trafo)
- self.DrawRectangle(Point(0, 0), Point(w, h))
- self.PopTrafo()
- else:
- resolution = config.preferences.eps_preview_resolution
- self.DrawImage(data.image, trafo(Scale(72.0 / resolution)))
+ if not data.image or self.IsOutlineActive():
+ w, h = data.Size()
+ self.PushTrafo()
+ self.Concat(trafo)
+ self.DrawRectangle(Point(0, 0), Point(w, h))
+ self.PopTrafo()
+ else:
+ resolution = config.preferences.eps_preview_resolution
+ self.DrawImage(data.image, trafo(Scale(72.0 / resolution)))
#
#
def WindowResized(self, width, height):
- self.ximage = None
- SimpleGC.WindowResized(self, width, height)
+ self.ximage = None
+ SimpleGC.WindowResized(self, width, height)
#
#
def DrawGrid(self, orig_x, orig_y, xwidth, ywidth, rect):
- # Draw a grid with a horitontal width XWIDTH and vertical width
- # YWIDTH whose origin is at (ORIG_X, ORIG_Y). RECT gives the
- # region of the document for which the grid has to be drawn.
- # RECT is usually the parameter of the same name of the
- # Draw/DrawShape methods of the various graphics objects and the
- # document/layer Note: This functions assumes that doc_to_win is
- # in its initial state
- self.SetProperties(self.grid_style)
- xwinwidth = self.LengthToWinFloat(xwidth)
- if not xwinwidth:
- if __debug__:
- pdebug(None, 'GraphicsDevice.DrawGrid: zero winwidth')
- return
- ywinwidth = self.LengthToWinFloat(ywidth)
- if not ywinwidth:
- if __debug__:
- pdebug(None, 'GraphicsDevice.DrawGrid: zero winwidth')
- return
- # make the minimum distance between drawn points at least 5
- # pixels XXX: should be configurable
- if xwinwidth < 5:
- xwinwidth = (int(5.0 / xwinwidth) + 1) * xwinwidth
- xwidth = self.LengthToDoc(xwinwidth)
- if ywinwidth < 5:
- ywinwidth = (int(5.0 / ywinwidth) + 1) * ywinwidth
- ywidth = self.LengthToDoc(ywinwidth)
- startx = int((rect.left - orig_x) / xwidth) * xwidth + orig_x
- starty = int((rect.top - orig_y) / ywidth) * ywidth + orig_y
- winx, winy = self.DocToWinPoint((startx, starty))
- nx = int((rect.right - rect.left) / xwidth) + 2
- ny = int((rect.top - rect.bottom) / ywidth) + 2
- if self.line:
- self.properties.ExecuteLine(self)
- _sketch.DrawGrid(self.gc, winx, winy, xwinwidth, ywinwidth, nx, ny)
+ # Draw a grid with a horitontal width XWIDTH and vertical width
+ # YWIDTH whose origin is at (ORIG_X, ORIG_Y). RECT gives the
+ # region of the document for which the grid has to be drawn.
+ # RECT is usually the parameter of the same name of the
+ # Draw/DrawShape methods of the various graphics objects and the
+ # document/layer Note: This functions assumes that doc_to_win is
+ # in its initial state
+ self.SetProperties(self.grid_style)
+ xwinwidth = self.LengthToWinFloat(xwidth)
+ if not xwinwidth:
+ if __debug__:
+ pdebug(None, 'GraphicsDevice.DrawGrid: zero winwidth')
+ return
+ ywinwidth = self.LengthToWinFloat(ywidth)
+ if not ywinwidth:
+ if __debug__:
+ pdebug(None, 'GraphicsDevice.DrawGrid: zero winwidth')
+ return
+ # make the minimum distance between drawn points at least 5
+ # pixels XXX: should be configurable
+ if xwinwidth < 5:
+ xwinwidth = (int(5.0 / xwinwidth) + 1) * xwinwidth
+ xwidth = self.LengthToDoc(xwinwidth)
+ if ywinwidth < 5:
+ ywinwidth = (int(5.0 / ywinwidth) + 1) * ywinwidth
+ ywidth = self.LengthToDoc(ywinwidth)
+ startx = int((rect.left - orig_x) / xwidth) * xwidth + orig_x
+ starty = int((rect.top - orig_y) / ywidth) * ywidth + orig_y
+ winx, winy = self.DocToWinPoint((startx, starty))
+ nx = int((rect.right - rect.left) / xwidth) + 2
+ ny = int((rect.top - rect.bottom) / ywidth) + 2
+ if self.line:
+ self.properties.ExecuteLine(self)
+ _sketch.DrawGrid(self.gc, winx, winy, xwinwidth, ywinwidth, nx, ny)
def DrawGuideLine(self, point, horizontal):
- if self.line:
- self.properties.ExecuteLine(self)
- self.gc.line_style = X.LineOnOffDash
- self.gc.dashes = 5
- x, y = self.DocToWin(point)
- if horizontal:
- self.gc.DrawLine(0, y, self.widget.width, y)
- else:
- self.gc.DrawLine(x, 0, x, self.widget.height)
- self.gc.line_style = X.LineSolid
+ if self.line:
+ self.properties.ExecuteLine(self)
+ self.gc.line_style = X.LineOnOffDash
+ self.gc.dashes = 5
+ x, y = self.DocToWin(point)
+ if horizontal:
+ self.gc.DrawLine(0, y, self.widget.width, y)
+ else:
+ self.gc.DrawLine(x, 0, x, self.widget.height)
+ self.gc.line_style = X.LineSolid
def DrawPageOutline(self, width, height):
- # Draw the outline of the page whose size is given by width and
- # height. The page's lower left corner is at (0,0) and its upper
- # right corner at (width, height) in doc coords. The outline is
- # drawn as a rectangle with a thin shadow.
- self.gc.line_width = 0
- self.gc.line_style = X.LineSolid
- left, bottom = self.DocToWin(0, 0)
- right, top = self.DocToWin(width, height)
- sw = 5 # shadow width XXX: should be configurable ?
- w = right - left
- h = bottom - top
- self.SetFillColor(StandardColors.gray)
- self.gc.FillRectangles([(left + sw, bottom, w + 1, sw + 1),
- (right, top + sw, sw + 1, h + 1)])
- self.SetFillColor(StandardColors.black)
- self.gc.DrawRectangle(left, top, w, h)
+ # Draw the outline of the page whose size is given by width and
+ # height. The page's lower left corner is at (0,0) and its upper
+ # right corner at (width, height) in doc coords. The outline is
+ # drawn as a rectangle with a thin shadow.
+ self.gc.line_width = 0
+ self.gc.line_style = X.LineSolid
+ left, bottom = self.DocToWin(0, 0)
+ right, top = self.DocToWin(width, height)
+ sw = 5 # shadow width XXX: should be configurable ?
+ w = right - left
+ h = bottom - top
+ self.SetFillColor(StandardColors.gray)
+ self.gc.FillRectangles([(left + sw, bottom, w + 1, sw + 1),
+ (right, top + sw, sw + 1, h + 1)])
+ self.SetFillColor(StandardColors.black)
+ self.gc.DrawRectangle(left, top, w, h)
@@ -1216,7 +1216,7 @@
# DummyLineStyle is needed for the InvertingDevice and the HitTestDevice
class DummyAttr(PropertyStack):
def ExecuteLine(self, gc):
- pass
+ pass
dummyLineStyle = DummyAttr(SolidLine(color_0))
@@ -1231,135 +1231,135 @@
caret_line_width = 2
def __init__(self):
- GraphicsDevice.__init__(self)
- self.handle_size = 3
- self.small_handle_size = 2
- self.properties = dummyLineStyle
- self.fill = 0
- self.line = 1
- self.gc = None
+ GraphicsDevice.__init__(self)
+ self.handle_size = 3
+ self.small_handle_size = 2
+ self.properties = dummyLineStyle
+ self.fill = 0
+ self.line = 1
+ self.gc = None
self.font_cache = {}
def init_gc(self, widget, **gcargs):
- self.visual = color.skvisual
+ self.visual = color.skvisual
line_width = config.preferences.editor_line_width
- self.gc = widget.CreateGC(foreground = ~0,
- function = X.GXxor,
- background = 0,
- line_width = line_width,
- line_style = self.normal_line_style)
- self.widget = widget
+ self.gc = widget.CreateGC(foreground = ~0,
+ function = X.GXxor,
+ background = 0,
+ line_width = line_width,
+ line_style = self.normal_line_style)
+ self.widget = widget
# make sure that the properties are not changed
def SetProperties(self, properties, rect = None):
- pass
+ pass
def IsOutlineActive(self):
- return 1
+ return 1
# Bezier and Line are currently only needed for the bezier objects
# during a drag
def Bezier(self, p1, p2, p3, p4):
- dtw = self.DocToWin
- pts = dtw(p1) + dtw(p2) + dtw(p3) + dtw(p4)
- apply(_sketch.DrawBezier, (self.gc,) + pts)
+ dtw = self.DocToWin
+ pts = dtw(p1) + dtw(p2) + dtw(p3) + dtw(p4)
+ apply(_sketch.DrawBezier, (self.gc,) + pts)
def Line(self, p1, p2):
- if self.line:
- startx, starty = self.DocToWin(p1)
- endx, endy = self.DocToWin(p2)
- self.gc.DrawLine(startx, starty, endx, endy)
+ if self.line:
+ startx, starty = self.DocToWin(p1)
+ endx, endy = self.DocToWin(p2)
+ self.gc.DrawLine(startx, starty, endx, endy)
# draw a rectangular 'handle' at P. The size of the handle is given
# by self.handle_size and is always in window coordinates (i.e. is
# independent of scaling)
def DrawRectHandle(self, p, filled = 1):
- x, y = self.DocToWin(p)
- size = self.handle_size
- x = x - size
- y = y - size
- if filled:
- self.gc.FillRectangle(x, y, 2 * size + 1, 2 * size + 1)
- else:
- self.gc.DrawRectangle(x, y, 2 * size, 2 * size)
+ x, y = self.DocToWin(p)
+ size = self.handle_size
+ x = x - size
+ y = y - size
+ if filled:
+ self.gc.FillRectangle(x, y, 2 * size + 1, 2 * size + 1)
+ else:
+ self.gc.DrawRectangle(x, y, 2 * size, 2 * size)
def DrawSmallRectHandle(self, p, filled = 1):
- x, y = self.DocToWin(p)
- size = self.small_handle_size
- x = x - size
- y = y - size
- if filled:
- self.gc.FillRectangle(x, y, 2 * size + 1, 2 * size + 1)
- else:
- self.gc.DrawRectangle(x, y, 2 * size, 2 * size)
+ x, y = self.DocToWin(p)
+ size = self.small_handle_size
+ x = x - size
+ y = y - size
+ if filled:
+ self.gc.FillRectangle(x, y, 2 * size + 1, 2 * size + 1)
+ else:
+ self.gc.DrawRectangle(x, y, 2 * size, 2 * size)
def DrawCircleHandle(self, p, filled = 1):
- x, y = self.DocToWin(p)
- size = self.handle_size
- x = x - size
- y = y - size
- if filled:
+ x, y = self.DocToWin(p)
+ size = self.handle_size
+ x = x - size
+ y = y - size
+ if filled:
# 23040 = 360 * 64
- self.gc.FillArc(x, y, 2 * size + 1, 2 * size + 1, 0, 23040)
- else:
- self.gc.DrawArc(x, y, 2 * size, 2 * size, 0, 23040)
+ self.gc.FillArc(x, y, 2 * size + 1, 2 * size + 1, 0, 23040)
+ else:
+ self.gc.DrawArc(x, y, 2 * size, 2 * size, 0, 23040)
def DrawSmallCircleHandle(self, p, filled = 1):
- x, y = self.DocToWin(p)
- size = self.small_handle_size
- x = x - size
- y = y - size
- if filled:
+ x, y = self.DocToWin(p)
+ size = self.small_handle_size
+ x = x - size
+ y = y - size
+ if filled:
# 23040 = 360 * 64
- self.gc.FillArc(x, y, 2 * size + 1, 2 * size + 1, 0, 23040)
- else:
- self.gc.DrawArc(x, y, 2 * size, 2 * size, 0, 23040)
+ self.gc.FillArc(x, y, 2 * size + 1, 2 * size + 1, 0, 23040)
+ else:
+ self.gc.DrawArc(x, y, 2 * size, 2 * size, 0, 23040)
def DrawSmallRectHandleList(self, pts, filled = 1):
- pts = map(self.doc_to_win.DocToWin, pts)
- size = self.small_handle_size
- size2 = 2 * size
- if filled:
- size = size + 1
- rects = []
- pts.sort()
- lx = ly = None
- for x, y in pts:
- if y != ly or x != lx:
- rects.append((x - size, y - size, size2, size2))
- lx = x
- ly = y
- if rects:
- if filled:
- self.gc.FillRectangles(rects)
- else:
- self.gc.DrawRectangles(rects)
+ pts = map(self.doc_to_win.DocToWin, pts)
+ size = self.small_handle_size
+ size2 = 2 * size
+ if filled:
+ size = size + 1
+ rects = []
+ pts.sort()
+ lx = ly = None
+ for x, y in pts:
+ if y != ly or x != lx:
+ rects.append((x - size, y - size, size2, size2))
+ lx = x
+ ly = y
+ if rects:
+ if filled:
+ self.gc.FillRectangles(rects)
+ else:
+ self.gc.DrawRectangles(rects)
def DrawHandleLine(self, start, end):
- self.gc.line_style = self.handle_line_style
- self.DrawLine(start, end)
- self.gc.line_style = self.normal_line_style
+ self.gc.line_style = self.handle_line_style
+ self.DrawLine(start, end)
+ self.gc.line_style = self.normal_line_style
def DrawRubberRect(self, start, end):
- self.gc.line_style = self.handle_line_style
- self.DrawRectangle(start, end)
- self.gc.line_style = self.normal_line_style
+ self.gc.line_style = self.handle_line_style
+ self.DrawRectangle(start, end)
+ self.gc.line_style = self.normal_line_style
def DrawPixmapHandle(self, p, pixmap):
- x, y = self.DocToWin(p)
- width, height = pixmap.GetGeometry()[3:5]
- x = x - width / 2
- y = y - height / 2
- pixmap.CopyPlane(self.widget, self.gc, 0, 0, width, height, x, y, 1)
+ x, y = self.DocToWin(p)
+ width, height = pixmap.GetGeometry()[3:5]
+ x = x - width / 2
+ y = y - height / 2
+ pixmap.CopyPlane(self.widget, self.gc, 0, 0, width, height, x, y, 1)
def DrawCaretHandle(self, p, up):
- line_width = self.gc.line_width
- self.gc.line_width = self.caret_line_width
- self.gc.line_style = self.caret_line_style
- self.DrawLine(p, p + up)
- self.gc.line_style = self.normal_line_style
- self.gc.line_width = line_width
+ line_width = self.gc.line_width
+ self.gc.line_width = self.caret_line_width
+ self.gc.line_style = self.caret_line_style
+ self.DrawLine(p, p + up)
+ self.gc.line_style = self.normal_line_style
+ self.gc.line_width = line_width
#
@@ -1379,31 +1379,31 @@
outline_style = hit_properties
def __init__(self):
- GraphicsDevice.__init__(self)
- self.properties = hit_properties
- self.fill = 1
- self.line = 1
- self.gc = None
+ GraphicsDevice.__init__(self)
+ self.properties = hit_properties
+ self.fill = 1
+ self.line = 1
+ self.gc = None
def init_gc(self, widget, **gcargs):
- self.pixmap = widget.CreatePixmap(pixmap_width, pixmap_width, 1)
- self.gc = self.pixmap.CreateGC(foreground = 1, line_width = 3)
- self.visual = color.skvisual
+ self.pixmap = widget.CreatePixmap(pixmap_width, pixmap_width, 1)
+ self.gc = self.pixmap.CreateGC(foreground = 1, line_width = 3)
+ self.visual = color.skvisual
# make sure that the properties are not changed
def SetProperties(self, properties, rect = None):
- if properties.HasLine():
- self.line_width = properties.line_width
- else:
- self.line_width = 0
+ if properties.HasLine():
+ self.line_width = properties.line_width
+ else:
+ self.line_width = 0
#
#
def SetViewportTransform(self, scale, doc_to_win, win_to_doc):
- GraphicsDevice.SetViewportTransform(self, scale, doc_to_win,
- win_to_doc)
- self.hit_radius_doc = self.LengthToDoc(self.hit_radius)
- hit_properties.SetProperty(line_width = self.hit_radius_doc * 2)
+ GraphicsDevice.SetViewportTransform(self, scale, doc_to_win,
+ win_to_doc)
+ self.hit_radius_doc = self.LengthToDoc(self.hit_radius)
+ hit_properties.SetProperty(line_width = self.hit_radius_doc * 2)
#
# Detect various `hits'
#
@@ -1411,204 +1411,204 @@
hit_radius = 2
def SetHitRadius(self, radius):
- self.hit_radius = radius
+ self.hit_radius = radius
def HitRadiusDoc(self):
- return self.LengthToDoc(self.hit_radius)
+ return self.LengthToDoc(self.hit_radius)
def HitRectAroundPoint(self, p):
- rad = self.HitRadiusDoc()
- return Rect(p.x - rad, p.y - rad, p.x + rad, p.y + rad)
+ rad = self.HitRadiusDoc()
+ return Rect(p.x - rad, p.y - rad, p.x + rad, p.y + rad)
def LineHit(self, start, end, p, line_width = 0):
- radius = self.hit_radius / self.scale
- if line_width:
- w = line_width / 2
- if radius < w:
- radius = w
- # check bounding box
- if p.x < min(start.x, end.x) - radius:
- return 0
- if p.x > max(start.x, end.x) + radius:
- return 0
- if p.y < min(start.y, end.y) - radius:
- return 0
- if p.y > max(start.y, end.y) + radius:
- return 0
- # check if line is hit
- try:
- d = end - start
- len = abs(d)
- if len < 1:
- return abs(start.x - p.x) <= radius \
- and abs(start.y - p.y) <= radius
- off = p - start
- dist = abs((float(off.x) * d.y - float(off.y) * d.x) / len)
- linepos = (off * d) / len
- return dist <= radius and linepos > 0 and linepos < len
- except OverflowError:
- warn(INTERNAL, 'HitTestDevice.LineHit: start = %s end = %s p = %s',
- start, end, p)
- return 0
+ radius = self.hit_radius / self.scale
+ if line_width:
+ w = line_width / 2
+ if radius < w:
+ radius = w
+ # check bounding box
+ if p.x < min(start.x, end.x) - radius:
+ return 0
+ if p.x > max(start.x, end.x) + radius:
+ return 0
+ if p.y < min(start.y, end.y) - radius:
+ return 0
+ if p.y > max(start.y, end.y) + radius:
+ return 0
+ # check if line is hit
+ try:
+ d = end - start
+ len = abs(d)
+ if len < 1:
+ return abs(start.x - p.x) <= radius \
+ and abs(start.y - p.y) <= radius
+ off = p - start
+ dist = abs((float(off.x) * d.y - float(off.y) * d.x) / len)
+ linepos = (off * d) / len
+ return dist <= radius and linepos > 0 and linepos < len
+ except OverflowError:
+ warn(INTERNAL, 'HitTestDevice.LineHit: start = %s end = %s p = %s',
+ start, end, p)
+ return 0
def ParallelogramHit(self, p, trafo, maxx, maxy, filled, properties=None,
- ignore_outline_mode = 0):
- filled = filled and (ignore_outline_mode or not self.outline_mode)
- if filled:
- try:
- inverse = trafo.inverse()
- x, y = inverse(p)
- return 0 <= x <= maxx and 0 <= y <= maxy
- except SingularMatrix:
- if properties is not None and properties.HasLine():
- properties = defaultLineStyle
- return self.ParallelogramHit(p, trafo, maxx, maxy,
- 0, properties)
+ ignore_outline_mode = 0):
+ filled = filled and (ignore_outline_mode or not self.outline_mode)
+ if filled:
+ try:
+ inverse = trafo.inverse()
+ x, y = inverse(p)
+ return 0 <= x <= maxx and 0 <= y <= maxy
+ except SingularMatrix:
+ if properties is not None and properties.HasLine():
+ properties = defaultLineStyle
+ return self.ParallelogramHit(p, trafo, maxx, maxy,
+ 0, properties)
- if self.outline_mode or (properties is not None
- and properties.HasLine()):
- p1 = trafo.offset()
- p2 = trafo(0, maxy)
- p3 = trafo(maxx, 0)
- p4 = trafo(maxx, maxy)
- if self.outline_mode:
- line_width = 0
- else:
- line_width = properties.line_width
- return self.LineHit(p1, p2, p, line_width)\
- or self.LineHit(p1, p3, p, line_width) \
- or self.LineHit(p2, p4, p, line_width) \
- or self.LineHit(p3, p4, p, line_width)
+ if self.outline_mode or (properties is not None
+ and properties.HasLine()):
+ p1 = trafo.offset()
+ p2 = trafo(0, maxy)
+ p3 = trafo(maxx, 0)
+ p4 = trafo(maxx, maxy)
+ if self.outline_mode:
+ line_width = 0
+ else:
+ line_width = properties.line_width
+ return self.LineHit(p1, p2, p, line_width)\
+ or self.LineHit(p1, p3, p, line_width) \
+ or self.LineHit(p2, p4, p, line_width) \
+ or self.LineHit(p3, p4, p, line_width)
def SimpleEllipseHit(self, p, trafo, start_angle, end_angle, arc_type,
- properties, filled, ignore_outline_mode = 0):
- # Hmm, the ellipse is not that simple anymore, maybe we should
- # change the name?
- filled = filled and (ignore_outline_mode or not self.outline_mode)
- try:
- inverse = trafo.inverse()
- p2 = inverse(p)
- dist, phi = p2.polar()
- has_line = properties.HasLine() or self.outline_mode
- if has_line:
- # Check whether p is on the outline of the complete
- # ellipse. This check is not entirely correct, but it
- # works well enough for now.
- if not self.outline_mode:
- line_width = properties.line_width
- else:
- line_width = 0
- d = max(line_width / 2, self.HitRadiusDoc())
- d = abs(inverse.DTransform(Point(d, 0)))
- border_hit = abs(1.0 - dist) < d
- else:
- border_hit = 0
- if start_angle == end_angle:
- # The most common case: a complete ellipse
- if filled and dist <= 1.0:
- # p is inside of the ellipse -> Hit!
- return 1
- # Either ellipse is not filled or dist > 1.0. NOw it
- # only depends on the outline.
- return border_hit
- else:
- # The ellipse is not complete. Now it depends on the
- # arc_type.
- if phi < 0:
- phi = phi + pi + pi # map phi into the range 0 - 2*PI
- if start_angle < end_angle:
- between = start_angle <= phi <= end_angle
- else:
- between = start_angle <= phi or phi <= end_angle
- center = trafo.offset()
- start = Polar(start_angle)
- end = Polar(end_angle)
- if arc_type == ArcPieSlice:
- if between:
- # p is somewhere in the painted sector. Just
- # like for a full ellipse:
- if filled and dist <= 1:
- return 1
- return border_hit
- else:
- # p is outside of the painted sector. It might
- # still be on the lines:
- if has_line:
- if (self.LineHit(center, trafo(start), p,
- line_width)
- or self.LineHit(center, trafo(end), p,
- line_width)):
- return 1
- # no line was hit
- return 0
- else:
- # ArcArc or ArcChord.
- if filled:
- # this is identical for both arc_types.
- # Strategy: p is inside of the ellipse if it is
- # in the intersection of the full ellipse the
- # half plane defined by the line through start
- # and end (the plane to the left of the vector
- # (start - end)).
- v = start - end
- d = p2 - end
- in_plane = (v.x * d.y - v.y * d.x) > 0
- if dist <= 1 and in_plane:
- return 1
- #
- if between and border_hit:
- return 1
- if has_line and arc_type == ArcChord:
- return self.LineHit(trafo(start), trafo(end), p,
- line_width)
- return 0
- except SingularMatrix:
- # ellipse degenerates into a line
- # XXX we should use the eigenvectors. The following code is
- # incorrect.
- start = trafo.offset()
- right = Point(trafo.m11, trafo.m21)
- up = Point(trafo.m12, trafo.m22)
- if abs(up) > abs(right):
- dir = up
- else:
- dir = right
- return self.LineHit(start - dir, start + dir, p,
- properties.line_width)
+ properties, filled, ignore_outline_mode = 0):
+ # Hmm, the ellipse is not that simple anymore, maybe we should
+ # change the name?
+ filled = filled and (ignore_outline_mode or not self.outline_mode)
+ try:
+ inverse = trafo.inverse()
+ p2 = inverse(p)
+ dist, phi = p2.polar()
+ has_line = properties.HasLine() or self.outline_mode
+ if has_line:
+ # Check whether p is on the outline of the complete
+ # ellipse. This check is not entirely correct, but it
+ # works well enough for now.
+ if not self.outline_mode:
+ line_width = properties.line_width
+ else:
+ line_width = 0
+ d = max(line_width / 2, self.HitRadiusDoc())
+ d = abs(inverse.DTransform(Point(d, 0)))
+ border_hit = abs(1.0 - dist) < d
+ else:
+ border_hit = 0
+ if start_angle == end_angle:
+ # The most common case: a complete ellipse
+ if filled and dist <= 1.0:
+ # p is inside of the ellipse -> Hit!
+ return 1
+ # Either ellipse is not filled or dist > 1.0. NOw it
+ # only depends on the outline.
+ return border_hit
+ else:
+ # The ellipse is not complete. Now it depends on the
+ # arc_type.
+ if phi < 0:
+ phi = phi + pi + pi # map phi into the range 0 - 2*PI
+ if start_angle < end_angle:
+ between = start_angle <= phi <= end_angle
+ else:
+ between = start_angle <= phi or phi <= end_angle
+ center = trafo.offset()
+ start = Polar(start_angle)
+ end = Polar(end_angle)
+ if arc_type == ArcPieSlice:
+ if between:
+ # p is somewhere in the painted sector. Just
+ # like for a full ellipse:
+ if filled and dist <= 1:
+ return 1
+ return border_hit
+ else:
+ # p is outside of the painted sector. It might
+ # still be on the lines:
+ if has_line:
+ if (self.LineHit(center, trafo(start), p,
+ line_width)
+ or self.LineHit(center, trafo(end), p,
+ line_width)):
+ return 1
+ # no line was hit
+ return 0
+ else:
+ # ArcArc or ArcChord.
+ if filled:
+ # this is identical for both arc_types.
+ # Strategy: p is inside of the ellipse if it is
+ # in the intersection of the full ellipse the
+ # half plane defined by the line through start
+ # and end (the plane to the left of the vector
+ # (start - end)).
+ v = start - end
+ d = p2 - end
+ in_plane = (v.x * d.y - v.y * d.x) > 0
+ if dist <= 1 and in_plane:
+ return 1
+ #
+ if between and border_hit:
+ return 1
+ if has_line and arc_type == ArcChord:
+ return self.LineHit(trafo(start), trafo(end), p,
+ line_width)
+ return 0
+ except SingularMatrix:
+ # ellipse degenerates into a line
+ # XXX we should use the eigenvectors. The following code is
+ # incorrect.
+ start = trafo.offset()
+ right = Point(trafo.m11, trafo.m21)
+ up = Point(trafo.m12, trafo.m22)
+ if abs(up) > abs(right):
+ dir = up
+ else:
+ dir = right
+ return self.LineHit(start - dir, start + dir, p,
+ properties.line_width)
def MultiBezierHit(self, paths, p, properties, filled,
- ignore_outline_mode = 0):
- x, y = self.DocToWin(p)
- filled = filled and (ignore_outline_mode or not self.outline_mode)
- result = _sketch.test_transformed(paths, self.doc_to_win, x, y,
- filled)
- if properties.HasLine():
- line_width = properties.line_width
- else:
- line_width = 0
- if result or self.outline_mode or self.LengthToWin(line_width) <= 1:
- return result
- odtw = self.doc_to_win
- self.doc_to_win = Trafo(odtw.m11, odtw.m21, odtw.m12, odtw.m22,
- -x + pixmap_width_2 + odtw.v1,
- -y + pixmap_width_2 + odtw.v2)
- top_left = self.WinToDoc(x - pixmap_width_2 - 1,
- y - pixmap_width_2 - 1)
- bot_right = self.WinToDoc(x + pixmap_width_2 + 1,
- y + pixmap_width_2 + 1)
- rect = Rect(top_left, bot_right)
- self.gc.function = X.GXclear
- self.gc.FillRectangle(0, 0, pixmap_width + 1, pixmap_width + 1)
- self.gc.function = X.GXcopy
- self.fill = 0
- line_width = max(line_width, hit_properties.line_width)
- undo = self.properties.SetProperty(line_width = line_width,
- line_pattern = SolidPattern(color_1))
- self.MultiBezier(paths, rect)
- self.doc_to_win = odtw
- Undo(undo)
- self.fill = 1
- return _sketch.GetPixel(self.gc, pixmap_width_2, pixmap_width_2)
+ ignore_outline_mode = 0):
+ x, y = self.DocToWin(p)
+ filled = filled and (ignore_outline_mode or not self.outline_mode)
+ result = _sketch.test_transformed(paths, self.doc_to_win, x, y,
+ filled)
+ if properties.HasLine():
+ line_width = properties.line_width
+ else:
+ line_width = 0
+ if result or self.outline_mode or self.LengthToWin(line_width) <= 1:
+ return result
+ odtw = self.doc_to_win
+ self.doc_to_win = Trafo(odtw.m11, odtw.m21, odtw.m12, odtw.m22,
+ -x + pixmap_width_2 + odtw.v1,
+ -y + pixmap_width_2 + odtw.v2)
+ top_left = self.WinToDoc(x - pixmap_width_2 - 1,
+ y - pixmap_width_2 - 1)
+ bot_right = self.WinToDoc(x + pixmap_width_2 + 1,
+ y + pixmap_width_2 + 1)
+ rect = Rect(top_left, bot_right)
+ self.gc.function = X.GXclear
+ self.gc.FillRectangle(0, 0, pixmap_width + 1, pixmap_width + 1)
+ self.gc.function = X.GXcopy
+ self.fill = 0
+ line_width = max(line_width, hit_properties.line_width)
+ undo = self.properties.SetProperty(line_width = line_width,
+ line_pattern = SolidPattern(color_1))
+ self.MultiBezier(paths, rect)
+ self.doc_to_win = odtw
+ Undo(undo)
+ self.fill = 1
+ return _sketch.GetPixel(self.gc, pixmap_width_2, pixmap_width_2)
#
@@ -1626,29 +1626,29 @@
print "Exception in ShmCheckExtension:", exc
img = None
if img is not None:
- if img.depth not in (15, 16, 24, 32, 8):
- # XXX: warn
- print 'depth =', img.depth
- return
+ if img.depth not in (15, 16, 24, 32, 8):
+ # XXX: warn
+ print 'depth =', img.depth
+ return
- if img.format != X.ZPixmap:
- # XXX: warn
- print 'format =', img.format
- return
+ if img.format != X.ZPixmap:
+ # XXX: warn
+ print 'format =', img.format
+ return
- shm_images_supported = 1
+ shm_images_supported = 1
def InitFromWidget(widget):
global _init_from_widget_done, use_shm_images
if not _init_from_widget_done:
- color.InitFromWidget(widget) # make certain that color is initialized
- check_for_shm_images(widget)
- if shm_images_supported:
- warn(INTERNAL, 'shared memory images supported')
- use_shm_images = 1
- else:
- warn(INTERNAL, 'shared memory images not supported')
- use_shm_images = 0
+ color.InitFromWidget(widget) # make certain that color is initialized
+ check_for_shm_images(widget)
+ if shm_images_supported:
+ warn(INTERNAL, 'shared memory images supported')
+ use_shm_images = 1
+ else:
+ warn(INTERNAL, 'shared memory images not supported')
+ use_shm_images = 0
_init_from_widget_done = 1
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/group.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/group.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/group.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -26,24 +26,24 @@
is_Group = 1
def Info(self):
- return _("Group with %d objects") % len(self.objects)
+ return _("Group with %d objects") % len(self.objects)
def Blend(self, other, frac1, frac2):
- try:
- objs = self.objects
- oobjs = other.objects
- blended = []
- for i in range(min(len(objs), len(oobjs))):
- blended.append(Blend(objs[i], oobjs[i], frac1, frac2))
- return Group(blended)
- except:
- warn_tb(INTERNAL)
- raise MismatchError
+ try:
+ objs = self.objects
+ oobjs = other.objects
+ blended = []
+ for i in range(min(len(objs), len(oobjs))):
+ blended.append(Blend(objs[i], oobjs[i], frac1, frac2))
+ return Group(blended)
+ except:
+ warn_tb(INTERNAL)
+ raise MismatchError
Ungroup = EditableCompound.GetObjects
def SaveToFile(self, file):
- file.BeginGroup()
- for obj in self.objects:
- obj.SaveToFile(file)
- file.EndGroup()
+ file.BeginGroup()
+ for obj in self.objects:
+ obj.SaveToFile(file)
+ file.EndGroup()
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/guide.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/guide.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/guide.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -24,23 +24,23 @@
is_GuideLine = 1
def __init__(self, point, horizontal = 0):
- self.point = point
- self.horizontal = horizontal
+ self.point = point
+ self.horizontal = horizontal
def DrawShape(self, device):
- device.DrawGuideLine(self.point, self.horizontal)
+ device.DrawGuideLine(self.point, self.horizontal)
def DrawDragged(self, device, partially):
- device.DrawGuideLine(self.drag_cur, self.horizontal)
+ device.DrawGuideLine(self.drag_cur, self.horizontal)
def Hit(self, p, rect, device):
- if self.horizontal:
- return rect.contains_point(Point(p.x, self.point.y))
- else:
- return rect.contains_point(Point(self.point.x, p.y))
+ if self.horizontal:
+ return rect.contains_point(Point(p.x, self.point.y))
+ else:
+ return rect.contains_point(Point(self.point.x, p.y))
def ButtonDown(self, p, button, state):
- self.DragStart(p)
+ self.DragStart(p)
if self.horizontal:
result = Point(0, p.y - self.point.y)
else:
@@ -48,41 +48,41 @@
return result
def ButtonUp(self, p, button, state):
- self.DragStop(p)
+ self.DragStop(p)
def SetPoint(self, point):
- undo = (self.SetPoint, self.point)
- if type(point) != PointType:
- if type(point) == type(()):
- point = apply(Point, point)
- else:
- if self.horizontal:
- point = Point(self.point.x, point)
- else:
- point = Point(point, self.point.y)
- self.point = point
- return undo
+ undo = (self.SetPoint, self.point)
+ if type(point) != PointType:
+ if type(point) == type(()):
+ point = apply(Point, point)
+ else:
+ if self.horizontal:
+ point = Point(self.point.x, point)
+ else:
+ point = Point(point, self.point.y)
+ self.point = point
+ return undo
def update_rects(self):
- self.bounding_rect = self.coord_rect = InfinityRect
+ self.bounding_rect = self.coord_rect = InfinityRect
def get_clear_rect(self):
- return (self.point, self.horizontal)
+ return (self.point, self.horizontal)
def Snap(self, p):
- if self.horizontal:
- return (abs(p.y - self.point.y), (None, self.point.y))
- else:
- return (abs(p.x - self.point.x), (self.point.x, None))
+ if self.horizontal:
+ return (abs(p.y - self.point.y), (None, self.point.y))
+ else:
+ return (abs(p.x - self.point.x), (self.point.x, None))
def SaveToFile(self, file):
- file.GuideLine(self.point, self.horizontal)
+ file.GuideLine(self.point, self.horizontal)
def Coordinates(self):
- if self.horizontal:
- return (self.point.y, 1)
- else:
- return (self.point.x, 0)
+ if self.horizontal:
+ return (self.point.y, 1)
+ else:
+ return (self.point.x, 0)
def CurrentInfoText(self):
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/handle.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/handle.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/handle.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -67,20 +67,20 @@
class Handle:
def __init__(self, type, p, cursor = const.CurHandle, offset = None,
- p2 = None, list = None, pixmap = None, code = None):
- self.type = type
- self.p = p
- self.cursor = cursor
- self.p2 = p2
- self.offset = offset
- self.list = list
- self.pixmap = pixmap
- self.index = 0
+ p2 = None, list = None, pixmap = None, code = None):
+ self.type = type
+ self.p = p
+ self.cursor = cursor
+ self.p2 = p2
+ self.offset = offset
+ self.list = list
+ self.pixmap = pixmap
+ self.index = 0
self.code = code
def __str__(self):
return "Handle(%d, %s)" % (self.type, self.p)
-
+
def __repr__(self):
return "Handle(%d, %s, index = %s)" % (self.type, self.p, self.index)
@@ -89,7 +89,7 @@
def MakeNodeHandle(p, selected = 0, code = 0):
if selected:
- return Handle(const.HandleSelectedNode, p, code = code)
+ return Handle(const.HandleSelectedNode, p, code = code)
return Handle(const.HandleNode, p, code = code)
def MakeObjectHandleList(list):
@@ -109,7 +109,7 @@
def MakePixmapHandle(p, offset, pixmap, cursor = const.CurHandle):
return Handle(const.Handle_Pixmap, p, cursor, offset = offset,
- pixmap = pixmap)
+ pixmap = pixmap)
def MakeCaretHandle(p, up):
return Handle(const.Handle_Caret, p, p2 = up)
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/image.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/image.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/image.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -36,43 +36,43 @@
attributes = {'mode':0, 'size':0, 'im':0, 'info':0}
def __init__(self, image, filename = '', cache = 1):
- # convert image to mode 'L' or 'RGB' if necessary
- if image.mode not in ('RGB', 'RGBA', 'L'):
- if image.mode == '1':
- mode = 'L'
- else:
- mode = 'RGB'
- image = image.convert(mode)
- else:
- image.load()
- self.image = image
- ExternalData.__init__(self, filename, cache)
+ # convert image to mode 'L' or 'RGB' if necessary
+ if image.mode not in ('RGB', 'RGBA', 'L'):
+ if image.mode == '1':
+ mode = 'L'
+ else:
+ mode = 'RGB'
+ image = image.convert(mode)
+ else:
+ image.load()
+ self.image = image
+ ExternalData.__init__(self, filename, cache)
def __getattr__(self, attr):
- if self.attributes.has_key(attr):
- return getattr(self.image, attr)
- raise AttributeError, attr
+ if self.attributes.has_key(attr):
+ return getattr(self.image, attr)
+ raise AttributeError, attr
def AsEmbedded(self):
- if self.filename:
- return ImageData(self.image)
- else:
- return self
+ if self.filename:
+ return ImageData(self.image)
+ else:
+ return self
def IsEmbedded(self):
- return not self.filename
+ return not self.filename
def Size(self):
- return self.size
+ return self.size
def Image(self):
return self.image
def Convert(self, mode):
- if mode != self.image.mode:
- return ImageData(self.image.convert(mode))
- else:
- return self
+ if mode != self.image.mode:
+ return ImageData(self.image.convert(mode))
+ else:
+ return self
def Invert(self):
return ImageData(PIL.ImageChops.invert(self.image))
@@ -81,12 +81,12 @@
def load_image(filename, cache = 1):
if type(filename) == StringType:
- image = get_cached(filename)
- if image:
- return image
+ image = get_cached(filename)
+ if image:
+ return image
image = PIL.Image.open(filename)
if type(filename) != StringType:
- filename = ''
+ filename = ''
return ImageData(image, filename = filename, cache = cache)
class Image(ExternalGraphics):
@@ -97,53 +97,53 @@
commands = ExternalGraphics.commands[:]
def __init__(self, image = None, imagefile = '', trafo = None,
- duplicate = None):
- if duplicate is None:
- if not image:
- if not imagefile:
- raise ValueError, 'Image must be instantiated with'\
- ' either image or imagefile'
- image = load_image(imagefile)
- ExternalGraphics.__init__(self, image, trafo,
- duplicate = duplicate)
+ duplicate = None):
+ if duplicate is None:
+ if not image:
+ if not imagefile:
+ raise ValueError, 'Image must be instantiated with'\
+ ' either image or imagefile'
+ image = load_image(imagefile)
+ ExternalGraphics.__init__(self, image, trafo,
+ duplicate = duplicate)
def DrawShape(self, device, rect = None, clip = 0):
- device.DrawImage(self.data, self.trafo, clip)
+ device.DrawImage(self.data, self.trafo, clip)
def Info(self):
- width, height = self.data.Size()
- x, y = self.trafo.offset()
- if self.IsEmbedded():
- return _("Embedded Image %(width)d x %(height)d "
- "at (%(x)d, %(y)d)") % locals()
- else:
- filename = os.path.basename(self.data.Filename())
- return _("Linked Image `%(filename)s' %(width)d x %(height)d "
- "at (%(x)d, %(y)d)") % locals()
+ width, height = self.data.Size()
+ x, y = self.trafo.offset()
+ if self.IsEmbedded():
+ return _("Embedded Image %(width)d x %(height)d "
+ "at (%(x)d, %(y)d)") % locals()
+ else:
+ filename = os.path.basename(self.data.Filename())
+ return _("Linked Image `%(filename)s' %(width)d x %(height)d "
+ "at (%(x)d, %(y)d)") % locals()
def SaveToFile(self, file):
- file.Image(self.data, self.trafo)
+ file.Image(self.data, self.trafo)
def IsEmbedded(self):
- return self.data.IsEmbedded()
+ return self.data.IsEmbedded()
def CanEmbed(self):
- return not self.IsEmbedded()
+ return not self.IsEmbedded()
def Embed(self):
- return self.SetData(self.data.AsEmbedded())
+ return self.SetData(self.data.AsEmbedded())
AddCmd(commands, 'EmbedImage', _("Embed Image"), Embed,
sensitive_cb = 'CanEmbed')
def CallImageFunction(self, function, args = ()):
- if type(args) != type(()):
- args = (args,)
- data = apply(getattr(self.data, function), args)
- return self.SetData(data)
+ if type(args) != type(()):
+ args = (args,)
+ data = apply(getattr(self.data, function), args)
+ return self.SetData(data)
AddCmd(commands, 'GrayscaleImage', _("Grayscale Image"),
- CallImageFunction, args = ('Convert', 'L'))
+ CallImageFunction, args = ('Convert', 'L'))
AddCmd(commands, 'InvertImage', _("Invert Image"), CallImageFunction,
- args = 'Invert')
+ args = 'Invert')
context_commands = ('EmbedImage', 'GrayscaleImage', 'InvertImage')
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/layer.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/layer.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/layer.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -38,188 +38,188 @@
is_GuideLayer = 0
def __init__(self, name = _("New Layer"),
- visible = 1, printable = 1, locked = 0,
- outlined = 0, outline_color = (0, 0, 0)):
- EditableCompound.__init__(self, [])
- self.name = name
- self.visible = visible
- self.printable = printable
- self.locked = locked
- self.outlined = outlined
- if type(outline_color) == TupleType:
- self.outline_color = apply(color.CreateRGBColor, outline_color)
- else:
- self.outline_color = outline_color
+ visible = 1, printable = 1, locked = 0,
+ outlined = 0, outline_color = (0, 0, 0)):
+ EditableCompound.__init__(self, [])
+ self.name = name
+ self.visible = visible
+ self.printable = printable
+ self.locked = locked
+ self.outlined = outlined
+ if type(outline_color) == TupleType:
+ self.outline_color = apply(color.CreateRGBColor, outline_color)
+ else:
+ self.outline_color = outline_color
def Draw(self, device, rect = None):
- # Draw all objects on the device device. RECT, if provided,
- # gives the bounding rect of the region to be drawn allowing to
- # optimize the redisplay by drawing only those objects that
- # overlap with this rect.
- if device.draw_visible and self.visible \
- or device.draw_printable and self.printable:
- outlined = self.outlined or device.IsOutlineActive()
- if outlined:
- device.StartOutlineMode(self.outline_color)
- EditableCompound.DrawShape(self, device, rect)
- if outlined:
- device.EndOutlineMode()
+ # Draw all objects on the device device. RECT, if provided,
+ # gives the bounding rect of the region to be drawn allowing to
+ # optimize the redisplay by drawing only those objects that
+ # overlap with this rect.
+ if device.draw_visible and self.visible \
+ or device.draw_printable and self.printable:
+ outlined = self.outlined or device.IsOutlineActive()
+ if outlined:
+ device.StartOutlineMode(self.outline_color)
+ EditableCompound.DrawShape(self, device, rect)
+ if outlined:
+ device.EndOutlineMode()
def SelectSubobject(self, p, rect, device, path = (), *rest):
- if not self.CanSelect():
- return None
- if self.outlined:
- device.StartOutlineMode()
- try:
- result = EditableCompound.SelectSubobject(self, p, rect, device,
- path)
- finally:
- if self.outlined:
- device.EndOutlineMode()
+ if not self.CanSelect():
+ return None
+ if self.outlined:
+ device.StartOutlineMode()
+ try:
+ result = EditableCompound.SelectSubobject(self, p, rect, device,
+ path)
+ finally:
+ if self.outlined:
+ device.EndOutlineMode()
- return result
+ return result
def SelectRect(self, rect):
- if not self.CanSelect():
- return []
- test = rect.contains_rect
- build_info = selinfo.build_info
- selected = []
- objects = self.objects
- for idx in range(len(objects)):
- obj = objects[idx]
- if test(obj.bounding_rect):
- selected.append(build_info(idx, obj))
- return selected
+ if not self.CanSelect():
+ return []
+ test = rect.contains_rect
+ build_info = selinfo.build_info
+ selected = []
+ objects = self.objects
+ for idx in range(len(objects)):
+ obj = objects[idx]
+ if test(obj.bounding_rect):
+ selected.append(build_info(idx, obj))
+ return selected
def SelectAll(self):
- if self.CanSelect():
- return selinfo.select_all(self.objects)
- else:
- return []
+ if self.CanSelect():
+ return selinfo.select_all(self.objects)
+ else:
+ return []
def SelectionInfo(self, child, cache = None):
- info = selinfo.build_info(_sketch.IdIndex(self.objects, child), child)
- return selinfo.prepend_idx(self.document.LayerIndex(self), info)
+ info = selinfo.build_info(_sketch.IdIndex(self.objects, child), child)
+ return selinfo.prepend_idx(self.document.LayerIndex(self), info)
def PickObject(self, p, rect, device):
- if not self.visible:
- return None
- if self.outlined:
- device.StartOutlineMode()
- result = EditableCompound.PickObject(self, p, rect, device)
- if self.outlined:
- device.EndOutlineMode()
- return result
+ if not self.visible:
+ return None
+ if self.outlined:
+ device.StartOutlineMode()
+ result = EditableCompound.PickObject(self, p, rect, device)
+ if self.outlined:
+ device.EndOutlineMode()
+ return result
def SetName(self, name):
- undo = (self.SetName, self.name)
- self.name = name
- return undo
+ undo = (self.SetName, self.name)
+ self.name = name
+ return undo
def Name(self):
- return self.name
+ return self.name
def NumObjects(self):
- return len(self.objects)
+ return len(self.objects)
def Visible(self):
- return self.visible
+ return self.visible
def Printable(self):
- return self.printable
+ return self.printable
def Locked(self):
return self.locked
def CanSelect(self):
- return not self.locked and self.visible
+ return not self.locked and self.visible
def get_state(self):
- return (self.visible, self.printable, self.locked, self.outlined)
+ return (self.visible, self.printable, self.locked, self.outlined)
def SetState(self, visible, printable, locked, outlined):
- # set the layer state. Return undo info.
- #
- # Side Effect:
- # Queue a LAYER message with parameter LAYER_STATE + tuple.
- # The tuple has the form
- #
- # (layer, visible_changed, printable_changed, outline_changed)
- #
- # We assume here that the receiver (usually SketchCanvas or
- # SketchView) uses this to determine whether to repaint parts of
- # the screen. If the receiver shows only visible layers and
- # allows outline, it should use the following expression to
- # determine whether to redraw or not:
- #
- # layer.NumObjects() and (visible_changed or
- # (outlined_changed and layer.Visible()))
- #
- # If you only show printable layers:
- #
- # layer.NumObjects() and printable_changed
- #
- # (in that case outline mode should be ignored as it is only
- # meant for quicker or clearer display while editing)
- #
- # The bounding rect of the now invalid region is
- # layer.bounding_rect
+ # set the layer state. Return undo info.
+ #
+ # Side Effect:
+ # Queue a LAYER message with parameter LAYER_STATE + tuple.
+ # The tuple has the form
+ #
+ # (layer, visible_changed, printable_changed, outline_changed)
+ #
+ # We assume here that the receiver (usually SketchCanvas or
+ # SketchView) uses this to determine whether to repaint parts of
+ # the screen. If the receiver shows only visible layers and
+ # allows outline, it should use the following expression to
+ # determine whether to redraw or not:
+ #
+ # layer.NumObjects() and (visible_changed or
+ # (outlined_changed and layer.Visible()))
+ #
+ # If you only show printable layers:
+ #
+ # layer.NumObjects() and printable_changed
+ #
+ # (in that case outline mode should be ignored as it is only
+ # meant for quicker or clearer display while editing)
+ #
+ # The bounding rect of the now invalid region is
+ # layer.bounding_rect
- oldstate = self.get_state()
- visible_changed = self.visible != visible
- self.visible = visible
- printable_changed = self.printable != printable
- self.printable = printable
+ oldstate = self.get_state()
+ visible_changed = self.visible != visible
+ self.visible = visible
+ printable_changed = self.printable != printable
+ self.printable = printable
locked_changed = self.locked != locked
- self.locked = locked
- outlined_changed = self.outlined != outlined
- self.outlined = outlined
+ self.locked = locked
+ outlined_changed = self.outlined != outlined
+ self.outlined = outlined
- if oldstate != self.get_state():
- undo = (self.SetState,) + oldstate
- visibility = (self, visible_changed, printable_changed,
- outlined_changed)
- if self.document is not None:
- self.document.queue_layer(LAYER_STATE, visibility)
+ if oldstate != self.get_state():
+ undo = (self.SetState,) + oldstate
+ visibility = (self, visible_changed, printable_changed,
+ outlined_changed)
+ if self.document is not None:
+ self.document.queue_layer(LAYER_STATE, visibility)
if locked_changed:
self.document.update_active_layer()
- return undo
-
- return NullUndo
+ return undo
+ return NullUndo
+
def SetOutlineColor(self, color):
- undo = (self.SetOutlineColor, self.outline_color)
- self.outline_color = color
- if self.document is not None:
- self.document.queue_layer(LAYER_COLOR, self)
- return undo
+ undo = (self.SetOutlineColor, self.outline_color)
+ self.outline_color = color
+ if self.document is not None:
+ self.document.queue_layer(LAYER_COLOR, self)
+ return undo
def OutlineColor(self):
- return self.outline_color
+ return self.outline_color
def Outlined(self):
return self.outlined
def SaveToFile(self, file):
- file.BeginLayer(self.name, self.visible, self.printable, self.locked,
- self.outlined, self.outline_color)
- for obj in self.objects:
- obj.SaveToFile(file)
- file.EndLayer()
+ file.BeginLayer(self.name, self.visible, self.printable, self.locked,
+ self.outlined, self.outline_color)
+ for obj in self.objects:
+ obj.SaveToFile(file)
+ file.EndLayer()
class SpecialLayer(Layer):
is_SpecialLayer = 1
def __none(self, *args):
- return None
+ return None
SelectSubobject = __none
PickObject = __none
def SelectRect(self, *rect):
- return []
+ return []
SelectAll = SelectRect
@@ -229,94 +229,94 @@
is_GuideLayer = 1
def __init__(self, name = _("Guides"), visible = 1, printable = 0,
- locked = 0, outlined = 1, outline_color = None):
- if outline_color is None:
- outline_color = config.preferences.guide_color
- SpecialLayer.__init__(self, name, visible, 0, locked, 1,
- outline_color)
+ locked = 0, outlined = 1, outline_color = None):
+ if outline_color is None:
+ outline_color = config.preferences.guide_color
+ SpecialLayer.__init__(self, name, visible, 0, locked, 1,
+ outline_color)
def SetState(self, visible, printable, locked, outlined):
- return SpecialLayer.SetState(self, visible, 0, locked, outlined)
+ return SpecialLayer.SetState(self, visible, 0, locked, outlined)
def Draw(self, device, rect = None):
- if device.draw_visible and self.visible \
- or device.draw_printable and self.printable:
- device.StartOutlineMode(self.outline_color)
- SpecialLayer.DrawShape(self, device)
- device.EndOutlineMode()
+ if device.draw_visible and self.visible \
+ or device.draw_printable and self.printable:
+ device.StartOutlineMode(self.outline_color)
+ SpecialLayer.DrawShape(self, device)
+ device.EndOutlineMode()
def SelectSubobject(self, p, rect, device, path = (), *rest):
- if not self.CanSelect():
- return None
- device.StartOutlineMode()
- try:
- objects = self.objects
- for obj_idx in range(len(objects) - 1, -1, -1):
- obj = objects[obj_idx]
- if obj.Hit(p, rect, device):
- result = obj.SelectSubobject(p, rect, device)
- return selinfo.prepend_idx(obj_idx, result)
- return None
- finally:
- device.EndOutlineMode()
+ if not self.CanSelect():
+ return None
+ device.StartOutlineMode()
+ try:
+ objects = self.objects
+ for obj_idx in range(len(objects) - 1, -1, -1):
+ obj = objects[obj_idx]
+ if obj.Hit(p, rect, device):
+ result = obj.SelectSubobject(p, rect, device)
+ return selinfo.prepend_idx(obj_idx, result)
+ return None
+ finally:
+ device.EndOutlineMode()
def SelectRect(self, rect):
- if not self.CanSelect():
- return []
- test = rect.contains_rect
- build_info = selinfo.build_info
- selected = []
- objects = self.objects
- for idx in range(len(objects)):
- obj = objects[idx]
- if not obj.is_GuideLine and test(obj.bounding_rect):
- selected.append(build_info(idx, obj))
- return selected
+ if not self.CanSelect():
+ return []
+ test = rect.contains_rect
+ build_info = selinfo.build_info
+ selected = []
+ objects = self.objects
+ for idx in range(len(objects)):
+ obj = objects[idx]
+ if not obj.is_GuideLine and test(obj.bounding_rect):
+ selected.append(build_info(idx, obj))
+ return selected
def SelectAll(self):
- return self.SelectRect(InfinityRect)
+ return self.SelectRect(InfinityRect)
def compute_rects(self):
- if self.objects:
- self.bounding_rect = self.coord_rect = InfinityRect
- else:
- self.bounding_rect = self.coord_rect = EmptyRect
+ if self.objects:
+ self.bounding_rect = self.coord_rect = InfinityRect
+ else:
+ self.bounding_rect = self.coord_rect = EmptyRect
def SaveToFile(self, file):
- file.BeginGuideLayer(self.name, self.visible, self.printable,
- self.locked, self.outlined, self.outline_color)
- for obj in self.objects:
- obj.SaveToFile(file)
- file.EndGuideLayer()
+ file.BeginGuideLayer(self.name, self.visible, self.printable,
+ self.locked, self.outlined, self.outline_color)
+ for obj in self.objects:
+ obj.SaveToFile(file)
+ file.EndGuideLayer()
def Snap(self, p):
- default = (1e100, p)
- horizontal = [default]
- vertical = [default]
- result = [default]
- for obj in self.objects:
- dist, snapped = obj.Snap(p)
- if type(snapped) == TupleType:
- if snapped[0] is None:
- horizontal.append((dist, snapped))
- else:
- vertical.append((dist, snapped))
- else:
- result.append((dist, snapped))
+ default = (1e100, p)
+ horizontal = [default]
+ vertical = [default]
+ result = [default]
+ for obj in self.objects:
+ dist, snapped = obj.Snap(p)
+ if type(snapped) == TupleType:
+ if snapped[0] is None:
+ horizontal.append((dist, snapped))
+ else:
+ vertical.append((dist, snapped))
+ else:
+ result.append((dist, snapped))
- return min(horizontal), min(vertical), min(result)
+ return min(horizontal), min(vertical), min(result)
def GuideLines(self):
- result = self.objects[:]
- for idx in range(len(result) - 1, -1, -1):
- if not result[idx].is_GuideLine:
- del result[idx]
- return result
+ result = self.objects[:]
+ for idx in range(len(result) - 1, -1, -1):
+ if not result[idx].is_GuideLine:
+ del result[idx]
+ return result
def issue_changed(self):
- Layer.issue_changed(self)
- if self.document is not None:
- self.document.GuideLayerChanged(self)
+ Layer.issue_changed(self)
+ if self.document is not None:
+ self.document.GuideLayerChanged(self)
class GridLayer(SpecialLayer):
@@ -324,56 +324,56 @@
geometry = (0, 0, 20, 20)
def __init__(self, geometry = None, visible = None, outline_color = None,
- name = _("Grid")):
- # The grid is locked, outlined and not printable
- if geometry is None:
- geometry = config.preferences.grid_geometry
- if visible is None:
- visible = config.preferences.grid_visible
- if outline_color is None:
- outline_color = config.preferences.grid_color
- SpecialLayer.__init__(self, name, visible, 0, 1, 1, outline_color)
- if len(geometry) == 2:
- self.geometry = (0, 0) + geometry
- elif len(geometry) == 4:
- self.geometry = geometry
- else:
- raise ValueError, "grid tuple must have length 2 or 4"
+ name = _("Grid")):
+ # The grid is locked, outlined and not printable
+ if geometry is None:
+ geometry = config.preferences.grid_geometry
+ if visible is None:
+ visible = config.preferences.grid_visible
+ if outline_color is None:
+ outline_color = config.preferences.grid_color
+ SpecialLayer.__init__(self, name, visible, 0, 1, 1, outline_color)
+ if len(geometry) == 2:
+ self.geometry = (0, 0) + geometry
+ elif len(geometry) == 4:
+ self.geometry = geometry
+ else:
+ raise ValueError, "grid tuple must have length 2 or 4"
def Draw(self, device, rect = None):
- if device.draw_visible and self.visible \
- or device.draw_printable and self.printable:
- device.StartOutlineMode(self.outline_color)
- xorg, yorg, xwidth, ywidth = self.geometry
- device.DrawGrid(xorg, yorg, xwidth, ywidth, rect)
- device.EndOutlineMode()
+ if device.draw_visible and self.visible \
+ or device.draw_printable and self.printable:
+ device.StartOutlineMode(self.outline_color)
+ xorg, yorg, xwidth, ywidth = self.geometry
+ device.DrawGrid(xorg, yorg, xwidth, ywidth, rect)
+ device.EndOutlineMode()
def update_rects(self):
- self.bounding_rect = self.coord_rect = InfinityRect
+ self.bounding_rect = self.coord_rect = InfinityRect
def SaveToFile(self, file):
- file.BeginGridLayer(self.geometry, self.visible, self.outline_color,
+ file.BeginGridLayer(self.geometry, self.visible, self.outline_color,
self.name)
file.EndGridLayer()
def Snap(self, p):
- xorg, yorg, xwidth, ywidth = self.geometry
- sx = round((p.x - xorg) / xwidth) * xwidth + xorg
- sy = round((p.y - yorg) / ywidth) * ywidth + yorg
- result = Point(sx, sy)
- return (abs(result - p), result)
+ xorg, yorg, xwidth, ywidth = self.geometry
+ sx = round((p.x - xorg) / xwidth) * xwidth + xorg
+ sy = round((p.y - yorg) / ywidth) * ywidth + yorg
+ result = Point(sx, sy)
+ return (abs(result - p), result)
def SetState(self, visible, printable, locked, outlined):
- return SpecialLayer.SetState(self, visible, 0, 1, 1)
+ return SpecialLayer.SetState(self, visible, 0, 1, 1)
def Geometry(self):
- return self.geometry
+ return self.geometry
def SetGeometry(self, geometry):
- undo = (self.SetGeometry, self.geometry)
- self.geometry = geometry
- if self.document:
- # a hack...
- self.document.queue_layer(LAYER_COLOR, self)
- return undo
+ undo = (self.SetGeometry, self.geometry)
+ self.geometry = geometry
+ if self.document:
+ # a hack...
+ self.document.queue_layer(LAYER_COLOR, self)
+ return undo
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/maskgroup.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/maskgroup.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/maskgroup.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -42,27 +42,27 @@
commands = EditableCompound.commands[:]
def __init__(self, objects = None, duplicate = None):
- EditableCompound.__init__(self, objects,
- duplicate = duplicate)
+ EditableCompound.__init__(self, objects,
+ duplicate = duplicate)
def update_mask_attrs(self):
- if self.objects:
- mask = self.objects[0]
- if mask.has_properties:
- self.mask_fill = mask.Properties().Duplicate()
- self.mask_fill.AddStyle(EmptyLineStyle)
- if mask.has_line and mask.Properties().HasLine():
- self.mask_line = mask.Properties().Duplicate()
- self.mask_line.AddStyle(EmptyFillStyle)
- else:
- self.mask_line = None
- else:
- self.mask_line = self.mask_fill = None
+ if self.objects:
+ mask = self.objects[0]
+ if mask.has_properties:
+ self.mask_fill = mask.Properties().Duplicate()
+ self.mask_fill.AddStyle(EmptyLineStyle)
+ if mask.has_line and mask.Properties().HasLine():
+ self.mask_line = mask.Properties().Duplicate()
+ self.mask_line.AddStyle(EmptyFillStyle)
+ else:
+ self.mask_line = None
+ else:
+ self.mask_line = self.mask_fill = None
def update_rects(self):
- if self.objects:
- self.bounding_rect = self.objects[0].bounding_rect
- self.coord_rect = self.objects[0].coord_rect
+ if self.objects:
+ self.bounding_rect = self.objects[0].bounding_rect
+ self.coord_rect = self.objects[0].coord_rect
def ChildChanged(self, child):
if child is self.objects[0]:
@@ -71,23 +71,23 @@
EditableCompound.ChildChanged(self, child)
def Info(self):
- return _("MaskGroup with %d objects") % len(self.objects)
+ return _("MaskGroup with %d objects") % len(self.objects)
def Hit(self, p, rect, device):
- if self.objects[0].Hit(p, rect, device, clip = 1):
- return EditableCompound.Hit(self, p, rect, device)
+ if self.objects[0].Hit(p, rect, device, clip = 1):
+ return EditableCompound.Hit(self, p, rect, device)
def Blend(self, other, frac1, frac2):
- try:
- objs = self.objects
- oobjs = other.objects
- blended = []
- for i in range(min(len(objs), len(oobjs))):
- blended.append(Blend(objs[i], oobjs[i], frac1, frac2))
- return MaskGroup(blended)
- except:
- warn_tb(INTERNAL)
- raise MismatchError
+ try:
+ objs = self.objects
+ oobjs = other.objects
+ blended = []
+ for i in range(min(len(objs), len(oobjs))):
+ blended.append(Blend(objs[i], oobjs[i], frac1, frac2))
+ return MaskGroup(blended)
+ except:
+ warn_tb(INTERNAL)
+ raise MismatchError
def Ungroup(self):
objects = EditableCompound.GetObjects(self)
@@ -106,49 +106,49 @@
return objects
def SaveToFile(self, file):
- file.BeginMaskGroup()
- for obj in self.objects:
- obj.SaveToFile(file)
- file.EndMaskGroup()
+ file.BeginMaskGroup()
+ for obj in self.objects:
+ obj.SaveToFile(file)
+ file.EndMaskGroup()
def DrawShape(self, device, rect = None):
- if not self.objects:
- return
- mask = self.objects[0]
- if mask.has_properties:
- attr = mask.properties
- mask.properties = self.mask_fill
- device.PushClip()
- clipped = 1
- try:
- mask.DrawShape(device, rect, clip = 1)
- if rect:
- rect = IntersectRects(rect, mask.bounding_rect)
- test = rect.overlaps
- for o in self.objects[1:]:
- if test(o.bounding_rect):
- o.DrawShape(device, rect)
- else:
- for obj in self.objects[1:]:
- obj.DrawShape(device)
- if self.mask_line is not None:
- device.PopClip()
- clipped = 0
- mask.properties = self.mask_line
- mask.DrawShape(device, rect)
- finally:
- if clipped:
- device.PopClip()
- if mask.has_properties:
- mask.properties = attr
+ if not self.objects:
+ return
+ mask = self.objects[0]
+ if mask.has_properties:
+ attr = mask.properties
+ mask.properties = self.mask_fill
+ device.PushClip()
+ clipped = 1
+ try:
+ mask.DrawShape(device, rect, clip = 1)
+ if rect:
+ rect = IntersectRects(rect, mask.bounding_rect)
+ test = rect.overlaps
+ for o in self.objects[1:]:
+ if test(o.bounding_rect):
+ o.DrawShape(device, rect)
+ else:
+ for obj in self.objects[1:]:
+ obj.DrawShape(device)
+ if self.mask_line is not None:
+ device.PopClip()
+ clipped = 0
+ mask.properties = self.mask_line
+ mask.DrawShape(device, rect)
+ finally:
+ if clipped:
+ device.PopClip()
+ if mask.has_properties:
+ mask.properties = attr
def permute_objects(self, permutation):
- # make sure the mask stays at index 0
- if permutation[0] != 0:
- permutation = list(permutation)
- permutation.remove(0)
- permutation.insert(0, 0)
- return EditableCompound.permute_objects(self, permutation)
+ # make sure the mask stays at index 0
+ if permutation[0] != 0:
+ permutation = list(permutation)
+ permutation.remove(0)
+ permutation.insert(0, 0)
+ return EditableCompound.permute_objects(self, permutation)
def Mask(self):
return self.objects[0]
@@ -157,8 +157,8 @@
return self.objects[1:]
def SelectMask(self):
- if self.document is not None:
- self.document.SelectObject(self.objects[0])
+ if self.document is not None:
+ self.document.SelectObject(self.objects[0])
AddCmd(commands, SelectMask, _("Select Mask"), key_stroke = 'm')
context_commands = ('SelectMask',)
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/pagelayout.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/pagelayout.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/pagelayout.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -34,49 +34,49 @@
class PageLayout:
def __init__(self, paperformat = None, width = None, height = None,
- orientation = None):
- if width and height:
- self.width = width
- self.height = height
- self.paperformat = ''
- else:
- if paperformat is None:
- self.paperformat = config.preferences.default_paper_format
- else:
- self.paperformat = paperformat
- self.width, self.height = Papersize[self.paperformat]
- if orientation is None:
- self.orientation = config.preferences.default_page_orientation
- else:
- self.orientation = orientation
- if self.orientation not in (Portrait, Landscape):
- self.orientation = Portrait
+ orientation = None):
+ if width and height:
+ self.width = width
+ self.height = height
+ self.paperformat = ''
+ else:
+ if paperformat is None:
+ self.paperformat = config.preferences.default_paper_format
+ else:
+ self.paperformat = paperformat
+ self.width, self.height = Papersize[self.paperformat]
+ if orientation is None:
+ self.orientation = config.preferences.default_page_orientation
+ else:
+ self.orientation = orientation
+ if self.orientation not in (Portrait, Landscape):
+ self.orientation = Portrait
def Width(self):
- if self.orientation == Portrait:
- return self.width
- else:
- return self.height
+ if self.orientation == Portrait:
+ return self.width
+ else:
+ return self.height
def Height(self):
- if self.orientation == Portrait:
- return self.height
- else:
- return self.width
+ if self.orientation == Portrait:
+ return self.height
+ else:
+ return self.width
def Size(self):
- if self.orientation == Portrait:
- return (self.width, self.height)
- else:
- return (self.height, self.width)
+ if self.orientation == Portrait:
+ return (self.width, self.height)
+ else:
+ return (self.height, self.width)
def FormatName(self):
- return self.paperformat
+ return self.paperformat
def Orientation(self):
- return self.orientation
+ return self.orientation
def SaveToFile(self, file):
- file.PageLayout(self.paperformat, self.width, self.height,
- self.orientation)
+ file.PageLayout(self.paperformat, self.width, self.height,
+ self.orientation)
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/papersize.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/papersize.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/papersize.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -54,8 +54,8 @@
width = 0.5**0.25
height = 2.0**0.25
for i in range(8):
- sizes.append(('A' + `i`, width * m_to_pt, height * m_to_pt))
- width, height = height / 2, width
+ sizes.append(('A' + `i`, width * m_to_pt, height * m_to_pt))
+ width, height = height / 2, width
return sizes[3:]
# The more accurate way to specify the european sizes, contributed by
@@ -65,12 +65,12 @@
# ('A0', 0.841 * m_to_pt, 1.189 * m_to_pt),
# ('A1', 0.594 * m_to_pt, 0.841 * m_to_pt),
# ('A2', 0.420 * m_to_pt, 0.594 * m_to_pt),
- ('A3', 0.297 * m_to_pt, 0.420 * m_to_pt),
- ('A4', 0.210 * m_to_pt, 0.297 * m_to_pt),
- ('A5', 0.148 * m_to_pt, 0.210 * m_to_pt),
- ('A6', 0.105 * m_to_pt, 0.148 * m_to_pt),
- ('A7', 0.074 * m_to_pt, 0.105 * m_to_pt),
- ]
+('A3', 0.297 * m_to_pt, 0.420 * m_to_pt),
+('A4', 0.210 * m_to_pt, 0.297 * m_to_pt),
+('A5', 0.148 * m_to_pt, 0.210 * m_to_pt),
+('A6', 0.105 * m_to_pt, 0.148 * m_to_pt),
+('A7', 0.074 * m_to_pt, 0.105 * m_to_pt),
+]
@@ -78,7 +78,7 @@
('letter', 8.5 * in_to_pt, 11 * in_to_pt),
('legal', 8.5 * in_to_pt, 14 * in_to_pt),
('executive', 7.25 * in_to_pt, 10.5 * in_to_pt)
- ]
+]
Papersize = {}
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/pattern.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/pattern.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/pattern.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -41,23 +41,23 @@
name = ''
def __init__(self, duplicate = None):
- pass
+ pass
def SetName(self, name):
- self.name = name
+ self.name = name
def Name(self):
- return self.name
+ return self.name
def Execute(self, device, rect = None):
- pass
+ pass
def Transform(self, trafo, rects = None):
- # This method is usually called by a primitives Transform method.
- return NullUndo
+ # This method is usually called by a primitives Transform method.
+ return NullUndo
def Duplicate(self):
- return self.__class__(duplicate = self)
+ return self.__class__(duplicate = self)
Copy = Duplicate
@@ -67,18 +67,18 @@
is_Empty = 1
def Duplicate(self):
- return self
+ return self
Copy = Duplicate
def Blend(self, *args):
- return self
+ return self
def SaveToFile(self, file):
- file.EmptyPattern()
+ file.EmptyPattern()
def __str__(self):
- return 'EmptyPattern'
+ return 'EmptyPattern'
EmptyPattern = EmptyPattern_()
@@ -88,58 +88,58 @@
is_Solid = 1
def __init__(self, color = None, duplicate = None):
- if duplicate is not None:
- self.color = duplicate.color
- elif color is not None:
- self.color = color
- else:
- raise ValueError,'SolidPattern be must created with color argument'
+ if duplicate is not None:
+ self.color = duplicate.color
+ elif color is not None:
+ self.color = color
+ else:
+ raise ValueError,'SolidPattern be must created with color argument'
def __cmp__(self, other):
- if self.__class__ == other.__class__:
- return cmp(self.color, other.color)
- else:
- return cmp(id(self), id(other))
+ if self.__class__ == other.__class__:
+ return cmp(self.color, other.color)
+ else:
+ return cmp(id(self), id(other))
def __str__(self):
- return 'SolidPattern(%s)' % `self.color`
+ return 'SolidPattern(%s)' % `self.color`
def Execute(self, device, rect = None):
- device.SetFillColor(self.color)
+ device.SetFillColor(self.color)
def Blend(self, other, frac1, frac2):
- if other.__class__ == self.__class__:
- return SolidPattern(Blend(self.color, other.color, frac1, frac2))
- else:
- raise MismatchError
+ if other.__class__ == self.__class__:
+ return SolidPattern(Blend(self.color, other.color, frac1, frac2))
+ else:
+ raise MismatchError
def Color(self):
- return self.color
+ return self.color
def SaveToFile(self, file):
- file.SolidPattern(self.color)
+ file.SolidPattern(self.color)
class GradientPattern(Pattern):
is_Gradient = 1
def __init__(self, gradient, duplicate = None):
- if duplicate is not None:
- Pattern.__init__(self, duplicate = duplicate)
- self.gradient = duplicate.gradient.Duplicate()
- elif gradient:
- self.gradient = gradient
- else:
- raise ValueError,\
- 'GradientPattern must be created with gradient argument'
+ if duplicate is not None:
+ Pattern.__init__(self, duplicate = duplicate)
+ self.gradient = duplicate.gradient.Duplicate()
+ elif gradient:
+ self.gradient = gradient
+ else:
+ raise ValueError,\
+ 'GradientPattern must be created with gradient argument'
def Gradient(self):
- return self.gradient
+ return self.gradient
def SetGradient(self, gradient):
- undo = (self.SetGradient, self.gradient)
- self.gradient = gradient
- return undo
+ undo = (self.SetGradient, self.gradient)
+ self.gradient = gradient
+ return undo
class LinearGradient(GradientPattern):
@@ -147,106 +147,106 @@
is_AxialGradient = 1
def __init__(self, gradient = None, direction = Point(0, -1),
- border = 0, duplicate = None):
- GradientPattern.__init__(self, gradient,
- duplicate = duplicate)
- self.direction = direction
- self.border = border
- if duplicate is not None:
- if duplicate.__class__ == self.__class__:
- self.direction = duplicate.direction
- self.border = duplicate.border
- elif duplicate.__class__ == ConicalGradient:
- self.direction = duplicate.direction
- elif duplicate.__class__ == RadialGradient:
- self.border = duplicate.border
+ border = 0, duplicate = None):
+ GradientPattern.__init__(self, gradient,
+ duplicate = duplicate)
+ self.direction = direction
+ self.border = border
+ if duplicate is not None:
+ if duplicate.__class__ == self.__class__:
+ self.direction = duplicate.direction
+ self.border = duplicate.border
+ elif duplicate.__class__ == ConicalGradient:
+ self.direction = duplicate.direction
+ elif duplicate.__class__ == RadialGradient:
+ self.border = duplicate.border
def SetDirection(self, dir):
- undo = (self.SetDirection, self.direction)
- self.direction = dir
- return undo
+ undo = (self.SetDirection, self.direction)
+ self.direction = dir
+ return undo
def Direction(self):
- return self.direction
+ return self.direction
def Border(self):
- return self.border
+ return self.border
def SetBorder(self, border):
- undo = (self.SetBorder, self.border)
- self.border = border
- return undo
+ undo = (self.SetBorder, self.border)
+ self.border = border
+ return undo
def Transform(self, trafo, rects = None):
- dx, dy = self.direction
- dx, dy = trafo.DTransform(dy, -dx)
- dir = Point(dy, -dx).normalized()
- if dir * trafo.DTransform(self.direction) < 0:
- dir = -dir
- return self.SetDirection(dir)
+ dx, dy = self.direction
+ dx, dy = trafo.DTransform(dy, -dx)
+ dir = Point(dy, -dx).normalized()
+ if dir * trafo.DTransform(self.direction) < 0:
+ dir = -dir
+ return self.SetDirection(dir)
def Execute(self, device, rect):
- if device.has_axial_gradient:
- self.execute_axial_gradient(device, rect)
- return
+ if device.has_axial_gradient:
+ self.execute_axial_gradient(device, rect)
+ return
- SetFillColor = device.SetFillColor
- FillRectangle = device.FillRectangle
- steps = device.gradient_steps
+ SetFillColor = device.SetFillColor
+ FillRectangle = device.FillRectangle
+ steps = device.gradient_steps
- colors = self.gradient.Sample(steps)
- SetFillColor(colors[0])
- apply(device.FillRectangle, tuple(rect))
+ colors = self.gradient.Sample(steps)
+ SetFillColor(colors[0])
+ apply(device.FillRectangle, tuple(rect))
- device.PushTrafo()
- vx, vy = self.direction
- angle = atan2(vy, vx) - pi / 2
- center = rect.center()
- rot = Rotation(angle, center)
- left, bottom, right, top = rot(rect)
- device.Concat(rot)
- device.Translate(center)
- height = top - bottom
- miny = -height / 2
- height = height * (1.0 - self.border)
- width = right - left
- dy = height / steps
- y = height / 2
- x = width / 2
- for i in range(steps):
- SetFillColor(colors[i])
- FillRectangle(-x, y, +x, miny)
- y = y - dy
- device.PopTrafo()
+ device.PushTrafo()
+ vx, vy = self.direction
+ angle = atan2(vy, vx) - pi / 2
+ center = rect.center()
+ rot = Rotation(angle, center)
+ left, bottom, right, top = rot(rect)
+ device.Concat(rot)
+ device.Translate(center)
+ height = top - bottom
+ miny = -height / 2
+ height = height * (1.0 - self.border)
+ width = right - left
+ dy = height / steps
+ y = height / 2
+ x = width / 2
+ for i in range(steps):
+ SetFillColor(colors[i])
+ FillRectangle(-x, y, +x, miny)
+ y = y - dy
+ device.PopTrafo()
def execute_axial_gradient(self, device, rect):
- vx, vy = self.direction
- angle = atan2(vy, vx) - pi / 2
- center = rect.center()
- rot = Rotation(angle, center)
- left, bottom, right, top = rot(rect)
- height = (top - bottom) * (1.0 - self.border)
- trafo = rot(Translation(center))
- device.AxialGradient(self.gradient, trafo(0, height / 2),
- trafo(0, -height / 2))
+ vx, vy = self.direction
+ angle = atan2(vy, vx) - pi / 2
+ center = rect.center()
+ rot = Rotation(angle, center)
+ left, bottom, right, top = rot(rect)
+ height = (top - bottom) * (1.0 - self.border)
+ trafo = rot(Translation(center))
+ device.AxialGradient(self.gradient, trafo(0, height / 2),
+ trafo(0, -height / 2))
def Blend(self, other, frac1, frac2):
- if other.__class__ == self.__class__:
- gradient = other.gradient
- dir = other.direction
- border = other.border
- elif other.__class__ == SolidPattern:
- gradient = other.Color()
- dir = self.direction
- border = self.border
- else:
- raise MismatchError
- return LinearGradient(Blend(self.gradient, gradient, frac1, frac2),
- frac1 * self.direction + frac2 * dir,
- frac1 * self.border + frac2 * border)
+ if other.__class__ == self.__class__:
+ gradient = other.gradient
+ dir = other.direction
+ border = other.border
+ elif other.__class__ == SolidPattern:
+ gradient = other.Color()
+ dir = self.direction
+ border = self.border
+ else:
+ raise MismatchError
+ return LinearGradient(Blend(self.gradient, gradient, frac1, frac2),
+ frac1 * self.direction + frac2 * dir,
+ frac1 * self.border + frac2 * border)
def SaveToFile(self, file):
- file.LinearGradientPattern(self.gradient, self.direction, self.border)
+ file.LinearGradientPattern(self.gradient, self.direction, self.border)
class RadialGradient(GradientPattern):
@@ -254,117 +254,117 @@
is_RadialGradient = 1
def __init__(self, gradient = None, center = Point(0.5, 0.5),
- border = 0, duplicate = None):
- GradientPattern.__init__(self, gradient,
- duplicate = duplicate)
- self.center = center
- self.border = border
- if duplicate is not None:
- if duplicate.__class__ == self.__class__:
- self.center = duplicate.center
- self.border = duplicate.border
- elif duplicate.__class__ == ConicalGradient:
- self.center = duplicate.center
- elif duplicate.__class__ == LinearGradient:
- self.border = duplicate.border
+ border = 0, duplicate = None):
+ GradientPattern.__init__(self, gradient,
+ duplicate = duplicate)
+ self.center = center
+ self.border = border
+ if duplicate is not None:
+ if duplicate.__class__ == self.__class__:
+ self.center = duplicate.center
+ self.border = duplicate.border
+ elif duplicate.__class__ == ConicalGradient:
+ self.center = duplicate.center
+ elif duplicate.__class__ == LinearGradient:
+ self.border = duplicate.border
def SetCenter(self, center):
- undo = (self.SetCenter, self.center)
- self.center = center
- return undo
+ undo = (self.SetCenter, self.center)
+ self.center = center
+ return undo
def Center(self):
- return self.center
+ return self.center
def Border(self):
- return self.border
+ return self.border
def SetBorder(self, border):
- undo = (self.SetBorder, self.border)
- self.border = border
- return undo
+ undo = (self.SetBorder, self.border)
+ self.border = border
+ return undo
def Transform(self, trafo, rects = None):
- if rects:
- r1, r2 = rects
- left, bottom, right, top = r1
- cx, cy = self.center
- cx = cx * right + (1 - cx) * left
- cy = cy * top + (1 - cy) * bottom
- cx, cy = trafo(cx, cy)
- left, bottom, right, top = r2
- len = right - left
- if len:
- cx = (cx - left) / len
- else:
- cx = 0
- len = top - bottom
- if len:
- cy = (cy - bottom) / len
- else:
- cy = 0
- center = Point(cx, cy)
- else:
- center = self.center
+ if rects:
+ r1, r2 = rects
+ left, bottom, right, top = r1
+ cx, cy = self.center
+ cx = cx * right + (1 - cx) * left
+ cy = cy * top + (1 - cy) * bottom
+ cx, cy = trafo(cx, cy)
+ left, bottom, right, top = r2
+ len = right - left
+ if len:
+ cx = (cx - left) / len
+ else:
+ cx = 0
+ len = top - bottom
+ if len:
+ cy = (cy - bottom) / len
+ else:
+ cy = 0
+ center = Point(cx, cy)
+ else:
+ center = self.center
- return self.SetCenter(center)
+ return self.SetCenter(center)
def Execute(self, device, rect):
- if device.has_radial_gradient:
- self.execute_radial(device, rect)
- return
- steps = device.gradient_steps
- cx, cy = self.center
- cx = cx * rect.right + (1 - cx) * rect.left
- cy = cy * rect.top + (1 - cy) * rect.bottom
- radius = max(hypot(rect.left - cx, rect.top - cy),
- hypot(rect.right - cx, rect.top - cy),
- hypot(rect.right - cx, rect.bottom - cy),
- hypot(rect.left - cx, rect.bottom - cy))
- color = self.gradient.ColorAt
- SetFillColor = device.SetFillColor
- FillCircle = device.FillCircle
- SetFillColor(color(0))
- apply(device.FillRectangle, tuple(rect))
- radius = radius * (1.0 - self.border)
- dr = radius / steps
- device.PushTrafo()
- device.Translate(cx, cy)
- center = NullPoint
- for i in range(steps):
- SetFillColor(color(float(i) / (steps - 1)))
- FillCircle(center, radius)
- radius = radius - dr
- device.PopTrafo()
+ if device.has_radial_gradient:
+ self.execute_radial(device, rect)
+ return
+ steps = device.gradient_steps
+ cx, cy = self.center
+ cx = cx * rect.right + (1 - cx) * rect.left
+ cy = cy * rect.top + (1 - cy) * rect.bottom
+ radius = max(hypot(rect.left - cx, rect.top - cy),
+ hypot(rect.right - cx, rect.top - cy),
+ hypot(rect.right - cx, rect.bottom - cy),
+ hypot(rect.left - cx, rect.bottom - cy))
+ color = self.gradient.ColorAt
+ SetFillColor = device.SetFillColor
+ FillCircle = device.FillCircle
+ SetFillColor(color(0))
+ apply(device.FillRectangle, tuple(rect))
+ radius = radius * (1.0 - self.border)
+ dr = radius / steps
+ device.PushTrafo()
+ device.Translate(cx, cy)
+ center = NullPoint
+ for i in range(steps):
+ SetFillColor(color(float(i) / (steps - 1)))
+ FillCircle(center, radius)
+ radius = radius - dr
+ device.PopTrafo()
def execute_radial(self, device, rect):
- cx, cy = self.center
- cx = cx * rect.right + (1 - cx) * rect.left
- cy = cy * rect.top + (1 - cy) * rect.bottom
- radius = max(hypot(rect.left - cx, rect.top - cy),
- hypot(rect.right - cx, rect.top - cy),
- hypot(rect.right - cx, rect.bottom - cy),
- hypot(rect.left - cx, rect.bottom - cy))
- radius = radius * (1.0 - self.border)
- device.RadialGradient(self.gradient, (cx, cy), radius, 0)
+ cx, cy = self.center
+ cx = cx * rect.right + (1 - cx) * rect.left
+ cy = cy * rect.top + (1 - cy) * rect.bottom
+ radius = max(hypot(rect.left - cx, rect.top - cy),
+ hypot(rect.right - cx, rect.top - cy),
+ hypot(rect.right - cx, rect.bottom - cy),
+ hypot(rect.left - cx, rect.bottom - cy))
+ radius = radius * (1.0 - self.border)
+ device.RadialGradient(self.gradient, (cx, cy), radius, 0)
def Blend(self, other, frac1, frac2):
- if other.__class__ == self.__class__:
- gradient = other.gradient
- center = other.center
- border = other.border
- elif other.__class__ == SolidPattern:
- gradient = other.Color()
- center = self.center
- border = self.border
- else:
- raise MismatchError
- return RadialGradient(Blend(self.gradient, gradient, frac1, frac2),
- frac1 * self.center + frac2 * center,
- frac1 * self.border + frac2 * border)
+ if other.__class__ == self.__class__:
+ gradient = other.gradient
+ center = other.center
+ border = other.border
+ elif other.__class__ == SolidPattern:
+ gradient = other.Color()
+ center = self.center
+ border = self.border
+ else:
+ raise MismatchError
+ return RadialGradient(Blend(self.gradient, gradient, frac1, frac2),
+ frac1 * self.center + frac2 * center,
+ frac1 * self.border + frac2 * border)
def SaveToFile(self, file):
- file.RadialGradientPattern(self.gradient, self.center, self.border)
+ file.RadialGradientPattern(self.gradient, self.center, self.border)
@@ -373,92 +373,92 @@
is_ConicalGradient = 1
def __init__(self, gradient = None,
- center = Point(0.5, 0.5), direction = Point(1, 0),
- duplicate = None):
- GradientPattern.__init__(self, gradient, duplicate = duplicate)
- self.center = center
- self.direction = direction
- if duplicate is not None:
- if duplicate.__class__ == self.__class__:
- self.center = duplicate.center
- self.direction = duplicate.direction
- elif duplicate.__class__ == LinearGradient:
- self.direction = duplicate.direction
- elif duplicate.__class__ == RadialGradient:
- self.center = duplicate.center
+ center = Point(0.5, 0.5), direction = Point(1, 0),
+ duplicate = None):
+ GradientPattern.__init__(self, gradient, duplicate = duplicate)
+ self.center = center
+ self.direction = direction
+ if duplicate is not None:
+ if duplicate.__class__ == self.__class__:
+ self.center = duplicate.center
+ self.direction = duplicate.direction
+ elif duplicate.__class__ == LinearGradient:
+ self.direction = duplicate.direction
+ elif duplicate.__class__ == RadialGradient:
+ self.center = duplicate.center
def __set_center_and_dir(self, center, dir):
- undo = (self.__set_center_and_dir, self.center, self.direction)
- self.center = center
- self.direction = dir
- return undo
+ undo = (self.__set_center_and_dir, self.center, self.direction)
+ self.center = center
+ self.direction = dir
+ return undo
def Transform(self, trafo, rects = None):
- dir = trafo.DTransform(self.direction).normalized()
- if rects:
- r1, r2 = rects
- left, bottom, right, top = r1
- cx, cy = self.center
- cx = cx * right + (1 - cx) * left
- cy = cy * top + (1 - cy) * bottom
- cx, cy = trafo(cx, cy)
- left, bottom, right, top = r2
- len = right - left
- if len:
- cx = (cx - left) / len
- else:
- cx = 0
- len = top - bottom
- if len:
- cy = (cy - bottom) / len
- else:
- cy = 0
- center = Point(cx, cy)
- else:
- center = self.center
+ dir = trafo.DTransform(self.direction).normalized()
+ if rects:
+ r1, r2 = rects
+ left, bottom, right, top = r1
+ cx, cy = self.center
+ cx = cx * right + (1 - cx) * left
+ cy = cy * top + (1 - cy) * bottom
+ cx, cy = trafo(cx, cy)
+ left, bottom, right, top = r2
+ len = right - left
+ if len:
+ cx = (cx - left) / len
+ else:
+ cx = 0
+ len = top - bottom
+ if len:
+ cy = (cy - bottom) / len
+ else:
+ cy = 0
+ center = Point(cx, cy)
+ else:
+ center = self.center
- return self.__set_center_and_dir(center, dir)
+ return self.__set_center_and_dir(center, dir)
def SetCenter(self, center):
- undo = (self.SetCenter, self.center)
- self.center = center
- return undo
+ undo = (self.SetCenter, self.center)
+ self.center = center
+ return undo
def Center(self):
- return self.center
+ return self.center
def SetDirection(self, dir):
- undo = (self.SetDirection, self.direction)
- self.direction = dir
- return undo
+ undo = (self.SetDirection, self.direction)
+ self.direction = dir
+ return undo
def Direction(self):
- return self.direction
+ return self.direction
def Execute(self, device, rect):
- if device.has_conical_gradient:
- self.execute_conical(device, rect)
- return
- steps = device.gradient_steps
- cx, cy = self.center
- left, bottom, right, top = rect
- cx = cx * right + (1 - cx) * left
- cy = cy * top + (1 - cy) * bottom
- vx, vy = self.direction
- angle = atan2(vy, vx)
- rot = Rotation(angle, cx, cy)
- radius = max(hypot(left - cx, top - cy),
- hypot(right - cx, top - cy),
- hypot(right - cx, bottom - cy),
- hypot(left-cx,bottom-cy)) + 10
- device.PushTrafo()
- device.Concat(rot)
- device.Translate(cx, cy)
- device.Scale(radius)
- colors = self.gradient.Sample(steps)
- SetFillColor = device.SetFillColor
- FillPolygon = device.FillPolygon
- da = pi / steps
+ if device.has_conical_gradient:
+ self.execute_conical(device, rect)
+ return
+ steps = device.gradient_steps
+ cx, cy = self.center
+ left, bottom, right, top = rect
+ cx = cx * right + (1 - cx) * left
+ cy = cy * top + (1 - cy) * bottom
+ vx, vy = self.direction
+ angle = atan2(vy, vx)
+ rot = Rotation(angle, cx, cy)
+ radius = max(hypot(left - cx, top - cy),
+ hypot(right - cx, top - cy),
+ hypot(right - cx, bottom - cy),
+ hypot(left-cx,bottom-cy)) + 10
+ device.PushTrafo()
+ device.Concat(rot)
+ device.Translate(cx, cy)
+ device.Scale(radius)
+ colors = self.gradient.Sample(steps)
+ SetFillColor = device.SetFillColor
+ FillPolygon = device.FillPolygon
+ da = pi / steps
points = [(1, 0)]
for i in range(steps):
a = da * (i + 1)
@@ -477,151 +477,151 @@
device.PopTrafo()
def execute_conical(self, device, rect):
- cx, cy = self.center
- left, bottom, right, top = rect
- cx = cx * right + (1 - cx) * left
- cy = cy * top + (1 - cy) * bottom
- angle = self.direction.polar()[1]
- device.ConicalGradient(self.gradient, (cx, cy), angle)
+ cx, cy = self.center
+ left, bottom, right, top = rect
+ cx = cx * right + (1 - cx) * left
+ cy = cy * top + (1 - cy) * bottom
+ angle = self.direction.polar()[1]
+ device.ConicalGradient(self.gradient, (cx, cy), angle)
def Blend(self, other, frac1, frac2):
- if other.__class__ == self.__class__:
- gradient = other.gradient
- dir = other.direction
- center = other.center
- elif other.__class__ == SolidPattern:
- gradient = other.Color()
- dir = self.direction
- center = self.center
- else:
- raise MismatchError
- return ConicalGradient(Blend(self.gradient, gradient, frac1, frac2),
- frac1 * self.center + frac2 * center,
- frac1 * self.direction + frac2 * dir)
+ if other.__class__ == self.__class__:
+ gradient = other.gradient
+ dir = other.direction
+ center = other.center
+ elif other.__class__ == SolidPattern:
+ gradient = other.Color()
+ dir = self.direction
+ center = self.center
+ else:
+ raise MismatchError
+ return ConicalGradient(Blend(self.gradient, gradient, frac1, frac2),
+ frac1 * self.center + frac2 * center,
+ frac1 * self.direction + frac2 * dir)
def SaveToFile(self, file):
- file.ConicalGradientPattern(self.gradient, self.center, self.direction)
+ file.ConicalGradientPattern(self.gradient, self.center, self.direction)
-
+
class HatchingPattern(Pattern):
is_Hatching = 1
def __init__(self, foreground = None, background = None,
- direction = Point(1, 0),
- spacing = 5.0, width = 0.5, duplicate = None):
- if duplicate is not None:
- self.foreground = duplicate.foreground
- self.background = duplicate.background
- self.spacing = duplicate.spacing
- self.width = duplicate.width
- self.direction = duplicate.direction
- elif foreground:
- self.foreground = foreground
- if not background:
- background = color.StandardColors.white
- self.background = background
- self.spacing = spacing
- self.width = width
- self.direction = direction
- else:
- raise ValueError,\
- 'HatchingPattern must be created with color argument'
+ direction = Point(1, 0),
+ spacing = 5.0, width = 0.5, duplicate = None):
+ if duplicate is not None:
+ self.foreground = duplicate.foreground
+ self.background = duplicate.background
+ self.spacing = duplicate.spacing
+ self.width = duplicate.width
+ self.direction = duplicate.direction
+ elif foreground:
+ self.foreground = foreground
+ if not background:
+ background = color.StandardColors.white
+ self.background = background
+ self.spacing = spacing
+ self.width = width
+ self.direction = direction
+ else:
+ raise ValueError,\
+ 'HatchingPattern must be created with color argument'
def SetDirection(self, dir):
- undo = (self.SetDirection, self.direction)
- self.direction = dir
- return undo
+ undo = (self.SetDirection, self.direction)
+ self.direction = dir
+ return undo
def Direction(self):
- return self.direction
+ return self.direction
def SetSpacing(self, spacing):
- undo = (self.SetSpacing, self.spacing)
- self.spacing = spacing
- return undo
+ undo = (self.SetSpacing, self.spacing)
+ self.spacing = spacing
+ return undo
def Spacing(self):
- return self.spacing
+ return self.spacing
def Width(self):
return self.width
def Transform(self, trafo, rects = None):
- # XXX: should spacing be transformed as well? Should the pattern be
- # transformed at all?
- dir = trafo.DTransform(self.direction).normalized()
- return self.SetDirection(dir)
+ # XXX: should spacing be transformed as well? Should the pattern be
+ # transformed at all?
+ dir = trafo.DTransform(self.direction).normalized()
+ return self.SetDirection(dir)
def SetForeground(self, foreground):
- undo = (self.SetForeground, self.foreground)
- self.foreground = foreground
- return undo
+ undo = (self.SetForeground, self.foreground)
+ self.foreground = foreground
+ return undo
def Foreground(self):
- return self.foreground
+ return self.foreground
def SetBackground(self, color):
- undo = (self.SetBackground, self.background)
- self.background = color
- return undo
+ undo = (self.SetBackground, self.background)
+ self.background = color
+ return undo
def Background(self):
- return self.background
+ return self.background
def Execute(self, device, rect):
- left, bottom, right, top = rect
- dy = self.spacing
- if dy > 0:
- device.SetFillColor(self.background)
- device.FillRectangle(left, top, right, bottom)
- device.PushTrafo()
- vx, vy = self.direction
- angle = atan2(vy, vx)
- center = rect.center()
- rot = Rotation(angle, center)
- left, bottom, right, top = rot(rect)
- device.Concat(rot)
- device.Translate(center)
- height = top - bottom
- width = right - left
- steps = int(height / dy + 1)
- y = height / 2
- x = width / 2
- device.SetLineColor(self.foreground)
- device.SetLineAttributes(self.width)
- drawline = device.DrawLineXY
- for i in range(steps):
- drawline(-x, y, +x, y)
- y = y - dy
- device.PopTrafo()
- else:
- device.SetFillColor(self.foreground)
- device.FillRectangle(left, bottom, right, top)
+ left, bottom, right, top = rect
+ dy = self.spacing
+ if dy > 0:
+ device.SetFillColor(self.background)
+ device.FillRectangle(left, top, right, bottom)
+ device.PushTrafo()
+ vx, vy = self.direction
+ angle = atan2(vy, vx)
+ center = rect.center()
+ rot = Rotation(angle, center)
+ left, bottom, right, top = rot(rect)
+ device.Concat(rot)
+ device.Translate(center)
+ height = top - bottom
+ width = right - left
+ steps = int(height / dy + 1)
+ y = height / 2
+ x = width / 2
+ device.SetLineColor(self.foreground)
+ device.SetLineAttributes(self.width)
+ drawline = device.DrawLineXY
+ for i in range(steps):
+ drawline(-x, y, +x, y)
+ y = y - dy
+ device.PopTrafo()
+ else:
+ device.SetFillColor(self.foreground)
+ device.FillRectangle(left, bottom, right, top)
def Blend(self, other, frac1, frac2):
- if other.__class__ == self.__class__:
- fg = other.foreground
- bg = other.background
- dir = other.direction
- spacing = other.spacing
- width = other.width
- elif other.__class__ == SolidPattern:
- fg = bg = other.Color()
- dir = self.direction
- spacing = self.spacing
- width = self.width
- else:
- raise MismatchError
- return HatchingPattern(Blend(self.foreground, fg, frac1, frac2),
- Blend(self.background, bg, frac1, frac2),
- frac1 * self.direction + frac2 * dir,
- frac1 * self.spacing + frac2 * spacing,
- frac1 * self.width + frac2 * width)
+ if other.__class__ == self.__class__:
+ fg = other.foreground
+ bg = other.background
+ dir = other.direction
+ spacing = other.spacing
+ width = other.width
+ elif other.__class__ == SolidPattern:
+ fg = bg = other.Color()
+ dir = self.direction
+ spacing = self.spacing
+ width = self.width
+ else:
+ raise MismatchError
+ return HatchingPattern(Blend(self.foreground, fg, frac1, frac2),
+ Blend(self.background, bg, frac1, frac2),
+ frac1 * self.direction + frac2 * dir,
+ frac1 * self.spacing + frac2 * spacing,
+ frac1 * self.width + frac2 * width)
def SaveToFile(self, file):
- file.HatchingPattern(self.foreground, self.background,
- self.direction, self.spacing, self.width)
+ file.HatchingPattern(self.foreground, self.background,
+ self.direction, self.spacing, self.width)
class ImageTilePattern(Pattern):
@@ -631,39 +631,39 @@
data = None
def __init__(self, data = None, trafo = None, duplicate = None):
- if duplicate is not None:
- data = duplicate.data
- self.trafo = duplicate.trafo
- else:
- if trafo is None:
- #width, height = data.size
- trafo = Trafo(1, 0, 0, -1, 0, 0)
- self.trafo = trafo
- self.data = data
+ if duplicate is not None:
+ data = duplicate.data
+ self.trafo = duplicate.trafo
+ else:
+ if trafo is None:
+ #width, height = data.size
+ trafo = Trafo(1, 0, 0, -1, 0, 0)
+ self.trafo = trafo
+ self.data = data
def set_transformation(self, trafo):
- undo = (self.set_transformation, self.trafo)
- self.trafo = trafo
- return undo
+ undo = (self.set_transformation, self.trafo)
+ self.trafo = trafo
+ return undo
def Transform(self, trafo, rects = None):
- if rects:
- r1, r2 = rects
- trafo = trafo(Translation(r1.left, r1.top))
- trafo = Translation(-r2.left, -r2.top)(trafo)
- return self.set_transformation(trafo(self.trafo))
+ if rects:
+ r1, r2 = rects
+ trafo = trafo(Translation(r1.left, r1.top))
+ trafo = Translation(-r2.left, -r2.top)(trafo)
+ return self.set_transformation(trafo(self.trafo))
def Execute(self, device, rect):
- device.TileImage(self.data,
- Translation(rect.left, rect.top)(self.trafo))
+ device.TileImage(self.data,
+ Translation(rect.left, rect.top)(self.trafo))
def Blend(self, other, frac1, frac2):
- if self.__class__ == other.__class__:
- if self.data is other.data:
- return self.__class__(self.data,
- BlendTrafo(self.trafo, other.trafo,
- frac1, frac2))
- raise MismatchError
+ if self.__class__ == other.__class__:
+ if self.data is other.data:
+ return self.__class__(self.data,
+ BlendTrafo(self.trafo, other.trafo,
+ frac1, frac2))
+ raise MismatchError
def SaveToFile(self, file):
- file.ImageTilePattern(self.data, self.trafo)
+ file.ImageTilePattern(self.data, self.trafo)
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/plugobj.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/plugobj.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/plugobj.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -29,81 +29,81 @@
is_Plugin = 1
def SetParameters(self, kw = None):
- # XXX could be extended to handle keyword arguments.
- undo = {}
- for key, value in kw.items():
- undo[key] = getattr(self, key)
- setattr(self, key, value)
- return self.SetParameters, undo
+ # XXX could be extended to handle keyword arguments.
+ undo = {}
+ for key, value in kw.items():
+ undo[key] = getattr(self, key)
+ setattr(self, key, value)
+ return self.SetParameters, undo
def SaveToFile(self, file, *args, **kw):
- if self.class_name:
- apply(file.BeginPluginCompound, (self.class_name,) + args, kw)
- for obj in self.objects:
- obj.SaveToFile(file)
- file.EndPluginCompound()
- else:
- raise SketchError("Plugin %s doesn't define a class name"
- % self.__class__)
+ if self.class_name:
+ apply(file.BeginPluginCompound, (self.class_name,) + args, kw)
+ for obj in self.objects:
+ obj.SaveToFile(file)
+ file.EndPluginCompound()
+ else:
+ raise SketchError("Plugin %s doesn't define a class name"
+ % self.__class__)
class TrafoPlugin(PluginCompound):
def __init__(self, trafo = None, duplicate = None, loading = 0):
- PluginCompound.__init__(self, duplicate = duplicate)
- if duplicate is not None:
- self.trafo = duplicate.trafo
- else:
- if trafo is None:
- trafo = Identity
- elif type(trafo) == TupleType:
- trafo = apply(Trafo, trafo)
+ PluginCompound.__init__(self, duplicate = duplicate)
+ if duplicate is not None:
+ self.trafo = duplicate.trafo
+ else:
+ if trafo is None:
+ trafo = Identity
+ elif type(trafo) == TupleType:
+ trafo = apply(Trafo, trafo)
elif isinstance(trafo, TrafoType):
# trafo is already a trafo object
pass
- else:
- # assume a number and interpret it as a scaling transformation
- trafo = Scale(trafo)
- self.trafo = trafo
+ else:
+ # assume a number and interpret it as a scaling transformation
+ trafo = Scale(trafo)
+ self.trafo = trafo
def recompute(self):
- # Implement this in the derived class to update the children.
- pass
+ # Implement this in the derived class to update the children.
+ pass
def SetParameters(self, kw):
- undo = PluginCompound.SetParameters(self, kw)
- try:
- self.recompute()
- except:
- Undo(undo)
- raise
- return undo
+ undo = PluginCompound.SetParameters(self, kw)
+ try:
+ self.recompute()
+ except:
+ Undo(undo)
+ raise
+ return undo
def set_transformation(self, trafo):
- undo = (self.set_transformation, self.trafo)
- self.trafo = trafo
- self.recompute()
- return undo
+ undo = (self.set_transformation, self.trafo)
+ self.trafo = trafo
+ self.recompute()
+ return undo
def Transform(self, trafo):
- undo = [self.begin_change_children()]
- try:
- undo.append(PluginCompound.Transform(self, trafo))
- undo.append(self.set_transformation(trafo(self.trafo)))
- undo.append(self.end_change_children())
- except:
- undo.reverse()
- map(Undo, undo)
- raise
- return CreateListUndo(undo)
+ undo = [self.begin_change_children()]
+ try:
+ undo.append(PluginCompound.Transform(self, trafo))
+ undo.append(self.set_transformation(trafo(self.trafo)))
+ undo.append(self.end_change_children())
+ except:
+ undo.reverse()
+ map(Undo, undo)
+ raise
+ return CreateListUndo(undo)
def Translate(self, offset):
- return self.Transform(Translation(offset))
+ return self.Transform(Translation(offset))
def RemoveTransformation(self):
- return self.set_transformation(Translation(self.trafo.offset()))
+ return self.set_transformation(Translation(self.trafo.offset()))
def LayoutPoint(self):
- return self.trafo.offset()
+ return self.trafo.offset()
def Trafo(self):
return self.trafo
@@ -115,58 +115,58 @@
changed = 0
def __init__(self, class_name = '', *args, **kw):
- if kw.has_key('loading'):
- del kw['loading']
- duplicate = kw.get('duplicate')
- if duplicate is not None:
- self.class_name = duplicate.class_name
- self.args = duplicate.args
- self.kw = duplicate.kw
- else:
- self.class_name = class_name
- self.args = args
- self.kw = kw
- PluginCompound.__init__(self, duplicate = duplicate)
- self.disguise()
+ if kw.has_key('loading'):
+ del kw['loading']
+ duplicate = kw.get('duplicate')
+ if duplicate is not None:
+ self.class_name = duplicate.class_name
+ self.args = duplicate.args
+ self.kw = duplicate.kw
+ else:
+ self.class_name = class_name
+ self.args = args
+ self.kw = kw
+ PluginCompound.__init__(self, duplicate = duplicate)
+ self.disguise()
def disguise(self):
- # If self has only one child, try to behave like it:
- if len(self.objects) == 1:
- object = self.objects[0]
- if object.is_curve:
- self.is_curve = object.is_curve
- self.AsBezier = object.AsBezier
- self.Paths = object.Paths
+ # If self has only one child, try to behave like it:
+ if len(self.objects) == 1:
+ object = self.objects[0]
+ if object.is_curve:
+ self.is_curve = object.is_curve
+ self.AsBezier = object.AsBezier
+ self.Paths = object.Paths
def _changed(self):
- PluginCompound._changed(self)
- self.changed = 1
+ PluginCompound._changed(self)
+ self.changed = 1
def load_Done(self):
- PluginCompound.load_Done(self)
- self.disguise()
+ PluginCompound.load_Done(self)
+ self.disguise()
def SaveToFile(self, file):
- if not self.changed:
- apply(PluginCompound.SaveToFile, (self, file) + self.args, self.kw)
- else:
- # XXX an alternative approach for a changed UnknownPlugin
- # might be to store explicitly as an 'UnknownPlugin' so that
- # always is represented by this class.
- if len(self.objects) == 1:
- self.objects[0].SaveToFile(file)
- else:
- # Save as ordinary group. This might not be a good idea,
- # since the UnknownPlugin may (in the future) have some
- # special behaviour, that the group doesn't have.
- file.BeginGroup()
- for obj in self.objects:
- obj.SaveToFile(file)
- file.EndGroup()
+ if not self.changed:
+ apply(PluginCompound.SaveToFile, (self, file) + self.args, self.kw)
+ else:
+ # XXX an alternative approach for a changed UnknownPlugin
+ # might be to store explicitly as an 'UnknownPlugin' so that
+ # always is represented by this class.
+ if len(self.objects) == 1:
+ self.objects[0].SaveToFile(file)
+ else:
+ # Save as ordinary group. This might not be a good idea,
+ # since the UnknownPlugin may (in the future) have some
+ # special behaviour, that the group doesn't have.
+ file.BeginGroup()
+ for obj in self.objects:
+ obj.SaveToFile(file)
+ file.EndGroup()
def Info(self):
- return _("Unknown Plugin Object `%s'") % self.class_name
+ return _("Unknown Plugin Object `%s'") % self.class_name
Ungroup = PluginCompound.GetObjects
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/properties.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/properties.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/properties.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -32,70 +32,70 @@
name = ''
def __init__(self, name = '', duplicate = None, **kw):
- if duplicate is not None:
- self.__dict__ = duplicate.__dict__.copy()
- if hasattr(self, 'fill_pattern'):
- self.fill_pattern = self.fill_pattern.Copy()
- if hasattr(self, 'line_pattern'):
- self.line_pattern = self.line_pattern.Copy()
- else:
- if name:
- self.name = name
- for key, value in kw.items():
- setattr(self, key, value)
+ if duplicate is not None:
+ self.__dict__ = duplicate.__dict__.copy()
+ if hasattr(self, 'fill_pattern'):
+ self.fill_pattern = self.fill_pattern.Copy()
+ if hasattr(self, 'line_pattern'):
+ self.line_pattern = self.line_pattern.Copy()
+ else:
+ if name:
+ self.name = name
+ for key, value in kw.items():
+ setattr(self, key, value)
def SetProperty(self, prop, value):
- dict = self.__dict__
- if dict.has_key(prop):
- undo = (self.SetProperty, prop, dict[prop])
- else:
- undo = (self.DelProperty, prop)
+ dict = self.__dict__
+ if dict.has_key(prop):
+ undo = (self.SetProperty, prop, dict[prop])
+ else:
+ undo = (self.DelProperty, prop)
if prop == 'fill_pattern' or prop == 'line_pattern':
value = value.Copy()
- dict[prop] = value
- self.issue(CHANGED, self)
- return undo
+ dict[prop] = value
+ self.issue(CHANGED, self)
+ return undo
def DelProperty(self, prop):
- undo = (self.SetProperty, prop, getattr(self, prop))
- delattr(self, prop)
- self.issue(CHANGED, self)
- return undo
+ undo = (self.SetProperty, prop, getattr(self, prop))
+ delattr(self, prop)
+ self.issue(CHANGED, self)
+ return undo
def Duplicate(self):
- if self.is_dynamic:
- return self
- return self.__class__(duplicate = self)
+ if self.is_dynamic:
+ return self
+ return self.__class__(duplicate = self)
def Copy(self):
- return self.__class__(duplicate = self)
+ return self.__class__(duplicate = self)
def Name(self):
- return self.name
+ return self.name
def SetName(self, name):
- undo = self.SetName, self.name
- self.name = name
- return undo
+ undo = self.SetName, self.name
+ self.name = name
+ return undo
def AsDynamicStyle(self):
- result = self.Copy()
- result.is_dynamic = 1
- return result
+ result = self.Copy()
+ result.is_dynamic = 1
+ return result
def AsUndynamicStyle(self):
- result = self.Copy()
- if self.is_dynamic:
- del result.is_dynamic
- del result.name
- return result
+ result = self.Copy()
+ if self.is_dynamic:
+ del result.is_dynamic
+ del result.name
+ return result
def SaveToFile(self, file):
- if self.is_dynamic:
- file.DynamicStyle(self)
+ if self.is_dynamic:
+ file.DynamicStyle(self)
def IsEmpty(self):
- return not self.__dict__
+ return not self.__dict__
def FillStyle(pattern):
return Style(fill_pattern = pattern)
@@ -103,11 +103,11 @@
EmptyFillStyle = Style(fill_pattern = EmptyPattern)
def LineStyle(color = None, width = 0, cap = const.CapButt,
- join = const.JoinMiter, dashes = None,
- arrow1 = None, arrow2 = None):
+ join = const.JoinMiter, dashes = None,
+ arrow1 = None, arrow2 = None):
return Style(line_pattern = SolidPattern(color), line_width = width,
- line_cap = cap, line_join = join, line_dashes = dashes,
- line_arrow1 = arrow1, line_arrow2 = arrow2)
+ line_cap = cap, line_join = join, line_dashes = dashes,
+ line_arrow1 = arrow1, line_arrow2 = arrow2)
SolidLine = LineStyle
EmptyLineStyle = Style(line_pattern = EmptyPattern)
@@ -117,246 +117,246 @@
update_cache = 1
def __init__(self, base = None, duplicate = None):
- if duplicate is not None:
- self.stack = []
- for layer in duplicate.stack:
- self.stack.append(layer.Duplicate())
- else:
- if base is None:
- base = factory_defaults.Duplicate()
- self.stack = [base]
+ if duplicate is not None:
+ self.stack = []
+ for layer in duplicate.stack:
+ self.stack.append(layer.Duplicate())
+ else:
+ if base is None:
+ base = factory_defaults.Duplicate()
+ self.stack = [base]
def __getattr__(self, attr):
- if self.update_cache:
- cache = self.__dict__
- stack = self.stack[:]
- stack.reverse()
- for layer in stack:
- cache.update(layer.__dict__)
- self.update_cache = 0
- try:
- return self.__dict__[attr]
- except KeyError:
- raise AttributeError, attr
+ if self.update_cache:
+ cache = self.__dict__
+ stack = self.stack[:]
+ stack.reverse()
+ for layer in stack:
+ cache.update(layer.__dict__)
+ self.update_cache = 0
+ try:
+ return self.__dict__[attr]
+ except KeyError:
+ raise AttributeError, attr
def _clear_cache(self):
- self.__dict__ = {'stack' : self.stack}
- return (self._clear_cache,)
+ self.__dict__ = {'stack' : self.stack}
+ return (self._clear_cache,)
def prop_layer(self, prop):
- # return property layer containing PROP
- for item in self.stack:
- if hasattr(item, prop):
- return item
- # we should never reach this...
- raise SketchInternalError('unknown graphics property "%s"' % prop)
+ # return property layer containing PROP
+ for item in self.stack:
+ if hasattr(item, prop):
+ return item
+ # we should never reach this...
+ raise SketchInternalError('unknown graphics property "%s"' % prop)
def set_property(self, prop, value):
- layer = self.prop_layer(prop)
- if layer.is_dynamic:
- if self.stack[0].is_dynamic:
- layer = Style()
- setattr(layer, prop, value)
- return self.add_layer(layer)
- else:
- layer = self.stack[0]
- return layer.SetProperty(prop, value)
+ layer = self.prop_layer(prop)
+ if layer.is_dynamic:
+ if self.stack[0].is_dynamic:
+ layer = Style()
+ setattr(layer, prop, value)
+ return self.add_layer(layer)
+ else:
+ layer = self.stack[0]
+ return layer.SetProperty(prop, value)
def SetProperty(self, **kw):
- stack = self.stack
- undo = []
- append = undo.append
- if len(stack) == 1 and not stack[0].is_dynamic:
- set = stack[0].SetProperty
- for prop, value in kw.items():
- append(set(prop, value))
- else:
- set = self.set_property
- for prop, value in kw.items():
- append(set(prop, value))
+ stack = self.stack
+ undo = []
+ append = undo.append
+ if len(stack) == 1 and not stack[0].is_dynamic:
+ set = stack[0].SetProperty
+ for prop, value in kw.items():
+ append(set(prop, value))
+ else:
+ set = self.set_property
+ for prop, value in kw.items():
+ append(set(prop, value))
- if len(self.stack) > 1:
- undo_stack = (self.set_stack, self.stack[:])
- if self.delete_shadowed_layers():
- undo.append(undo_stack)
- undo = CreateListUndo(undo)
- undo = (UndoAfter, undo, self._clear_cache())
- return undo
+ if len(self.stack) > 1:
+ undo_stack = (self.set_stack, self.stack[:])
+ if self.delete_shadowed_layers():
+ undo.append(undo_stack)
+ undo = CreateListUndo(undo)
+ undo = (UndoAfter, undo, self._clear_cache())
+ return undo
def set_stack(self, stack):
- undo = (self.set_stack, self.stack)
- self.stack = stack
- self._clear_cache()
- return undo
+ undo = (self.set_stack, self.stack)
+ self.stack = stack
+ self._clear_cache()
+ return undo
def delete_shadowed_layers(self):
- # check if some styles are completely hidden now
- stack = self.stack
- layers = []
- dict = {'name':1, 'is_dynamic':0}
- dict.update(stack[0].__dict__)
- length = len(dict)
- for layer in stack[1:]:
- dict.update(layer.__dict__)
- if length != len(dict):
- layers.append(layer)
- length = len(dict)
- length = len(stack)
- stack[1:] = layers
- return length != len(stack)
+ # check if some styles are completely hidden now
+ stack = self.stack
+ layers = []
+ dict = {'name':1, 'is_dynamic':0}
+ dict.update(stack[0].__dict__)
+ length = len(dict)
+ for layer in stack[1:]:
+ dict.update(layer.__dict__)
+ if length != len(dict):
+ layers.append(layer)
+ length = len(dict)
+ length = len(stack)
+ stack[1:] = layers
+ return length != len(stack)
def add_layer(self, layer):
- undo = (self.set_stack, self.stack[:])
- self.stack.insert(0, layer)
- return undo
+ undo = (self.set_stack, self.stack[:])
+ self.stack.insert(0, layer)
+ return undo
load_AddStyle = add_layer
def AddStyle(self, style):
- if style.is_dynamic:
- undo = self.add_layer(style)
- self.delete_shadowed_layers()
- self._clear_cache()
- return undo
- else:
- return apply(self.SetProperty, (), style.__dict__)
+ if style.is_dynamic:
+ undo = self.add_layer(style)
+ self.delete_shadowed_layers()
+ self._clear_cache()
+ return undo
+ else:
+ return apply(self.SetProperty, (), style.__dict__)
def HasFill(self):
- return self.fill_pattern is not EmptyPattern
+ return self.fill_pattern is not EmptyPattern
def IsAlgorithmicFill(self):
- return self.fill_pattern.is_procedural
+ return self.fill_pattern.is_procedural
def ExecuteFill(self, device, rect = None):
- self.fill_pattern.Execute(device, rect)
+ self.fill_pattern.Execute(device, rect)
def HasLine(self):
- return self.line_pattern is not EmptyPattern
+ return self.line_pattern is not EmptyPattern
def IsAlgorithmicLine(self):
- return self.line_pattern.is_procedural
+ return self.line_pattern.is_procedural
def ExecuteLine(self, device, rect = None):
- line_pattern = self.line_pattern
- if line_pattern is not EmptyPattern:
- line_pattern.Execute(device, rect)
- device.SetLineAttributes(self.line_width, self.line_cap,
- self.line_join, self.line_dashes)
+ line_pattern = self.line_pattern
+ if line_pattern is not EmptyPattern:
+ line_pattern.Execute(device, rect)
+ device.SetLineAttributes(self.line_width, self.line_cap,
+ self.line_join, self.line_dashes)
def HasFont(self):
- return self.font is not None
+ return self.font is not None
def ObjectChanged(self, object):
- if object in self.stack:
- self._clear_cache()
- return 1
- return 0
+ if object in self.stack:
+ self._clear_cache()
+ return 1
+ return 0
def ObjectRemoved(self, object):
- if object in self.stack:
- idx = self.stack.index(object)
- undo = (self.set_stack, self.stack[:])
- self.stack[idx] = self.stack[idx].AsUndynamicStyle()
- pdebug('properties', 'made style undynamic')
- return undo
- return NullUndo
+ if object in self.stack:
+ idx = self.stack.index(object)
+ undo = (self.set_stack, self.stack[:])
+ self.stack[idx] = self.stack[idx].AsUndynamicStyle()
+ pdebug('properties', 'made style undynamic')
+ return undo
+ return NullUndo
def Untie(self):
- info = []
- for i in range(len(self.stack)):
- style = self.stack[i]
- if style.is_dynamic:
- self.stack[i] = style.AsUndynamicStyle()
- info.append((i, style))
- self._clear_cache()
- return info
+ info = []
+ for i in range(len(self.stack)):
+ style = self.stack[i]
+ if style.is_dynamic:
+ self.stack[i] = style.AsUndynamicStyle()
+ info.append((i, style))
+ self._clear_cache()
+ return info
def Tie(self, document, info):
- for i, style in info:
- s = document.GetDynamicStyle(style.Name())
- if s == style:
- self.stack[i] = s
- self._clear_cache()
+ for i, style in info:
+ s = document.GetDynamicStyle(style.Name())
+ if s == style:
+ self.stack[i] = s
+ self._clear_cache()
def Duplicate(self):
- return self.__class__(duplicate = self)
+ return self.__class__(duplicate = self)
grow_join = [5.240843064, 0.5, 0.5]
grow_cap = [None, 0.5, 0.5, 0.70710678]
def GrowAmount(self):
- return self.line_width * max(self.grow_cap[self.line_cap],
- self.grow_join[self.line_join])
+ return self.line_width * max(self.grow_cap[self.line_cap],
+ self.grow_join[self.line_join])
def Blend(self, other, frac1, frac2):
- result = {}
- for prop, func in blend_functions:
- if func:
- result[prop] = func(getattr(self, prop), getattr(other, prop),
- frac1, frac2)
- else:
- result[prop] = getattr(self, prop)
- return PropertyStack(apply(Style, (), result))
+ result = {}
+ for prop, func in blend_functions:
+ if func:
+ result[prop] = func(getattr(self, prop), getattr(other, prop),
+ frac1, frac2)
+ else:
+ result[prop] = getattr(self, prop)
+ return PropertyStack(apply(Style, (), result))
def Transform(self, trafo, rects):
- # XXX hardcoding which properties may need to be transformed is
- # not really a good idea, but it's significantly faster.
- undo = NullUndo
- if len(self.stack) == 1 and not self.stack[0].is_dynamic:
- if self.fill_transform:
- pattern = self.fill_pattern
- if pattern.is_procedural:
- undo = pattern.Transform(trafo, rects)
- elif self.fill_transform:
- pattern = self.fill_pattern
- if pattern.is_procedural:
- pattern = pattern.Duplicate()
- if pattern.Transform(trafo, rects) is not NullUndo:
- undo = self.set_property('fill_pattern', pattern)
- if undo is not NullUndo:
- undo = (UndoAfter, undo, self._clear_cache())
- return undo
+ # XXX hardcoding which properties may need to be transformed is
+ # not really a good idea, but it's significantly faster.
+ undo = NullUndo
+ if len(self.stack) == 1 and not self.stack[0].is_dynamic:
+ if self.fill_transform:
+ pattern = self.fill_pattern
+ if pattern.is_procedural:
+ undo = pattern.Transform(trafo, rects)
+ elif self.fill_transform:
+ pattern = self.fill_pattern
+ if pattern.is_procedural:
+ pattern = pattern.Duplicate()
+ if pattern.Transform(trafo, rects) is not NullUndo:
+ undo = self.set_property('fill_pattern', pattern)
+ if undo is not NullUndo:
+ undo = (UndoAfter, undo, self._clear_cache())
+ return undo
def CreateStyle(self, which_properties):
- properties = {}
- for prop in which_properties:
+ properties = {}
+ for prop in which_properties:
if property_types[prop] == FontProperty and not self.HasFont():
continue
properties[prop] = getattr(self, prop)
- return apply(Style, (), properties)
+ return apply(Style, (), properties)
def DynamicStyleNames(self):
- names = []
- for style in self.stack:
- if style.is_dynamic:
- names.append(style.Name())
- return names
+ names = []
+ for style in self.stack:
+ if style.is_dynamic:
+ names.append(style.Name())
+ return names
def condense(self):
- stack = self.stack
- last = stack[0]
- for style in stack[1:]:
- if not last.is_dynamic and not style.is_dynamic:
- dict = style.__dict__.copy()
- dict.update(last.__dict__)
- last.__dict__ = dict
- last = style
- length = len(stack)
- self.delete_shadowed_layers()
+ stack = self.stack
+ last = stack[0]
+ for style in stack[1:]:
+ if not last.is_dynamic and not style.is_dynamic:
+ dict = style.__dict__.copy()
+ dict.update(last.__dict__)
+ last.__dict__ = dict
+ last = style
+ length = len(stack)
+ self.delete_shadowed_layers()
def SaveToFile(self, file):
- file.Properties(self)
+ file.Properties(self)
class _EmptyProperties:
def HasFill(self):
- return 0
+ return 0
HasLine = HasFill
HasFont = HasFill
def DynamicStyleNames(self):
- return []
+ return []
EmptyProperties = _EmptyProperties()
@@ -382,38 +382,38 @@
OtherProperty = -1
def _set_defaults(prop, title, short_title, type, value,
- blend = None, transform = 0):
+ blend = None, transform = 0):
factory_defaults.SetProperty(prop, value)
property_names.append(prop)
property_titles[prop] = (title, short_title)
property_types[prop] = type
blend_functions.append((prop, blend))
if transform:
- transform_properties.append(prop)
+ transform_properties.append(prop)
black = StandardColors.black
# XXX the default properties should be defined by the user.
_set_defaults('fill_pattern', _("Fill Pattern"), _("Pattern"), FillProperty,
- EmptyPattern, blend = Blend, transform = 1)
+ EmptyPattern, blend = Blend, transform = 1)
_set_defaults('fill_transform', _("Fill Transform Pattern"),
- _("Transform pattern"), FillProperty, 1)
+ _("Transform pattern"), FillProperty, 1)
_set_defaults('line_pattern', _("Line Pattern"), _("Pattern"), LineProperty,
- SolidPattern(black), blend = Blend, transform = 1)
+ SolidPattern(black), blend = Blend, transform = 1)
_set_defaults('line_width', _("Line Width"), _("Width"), LineProperty, 1 ,
- blend = blend_number)
+ blend = blend_number)
_set_defaults('line_cap', _("Line Cap"), _("Cap"), LineProperty,
- const.CapButt)
+ const.CapButt)
_set_defaults('line_join', _("Line Join"), _("Join"), LineProperty,
- const.JoinMiter)
+ const.JoinMiter)
_set_defaults('line_dashes', _("Line Dashes"), _("Dashes"), LineProperty, ())
_set_defaults('line_arrow1', _("Line Arrow 1"), _("Arrow 1"), LineProperty,
- None)
+ None)
_set_defaults('line_arrow2', _("Line Arrow 2"), _("Arrow 2"), LineProperty,
- None)
+ None)
_set_defaults('font', _("Font"), _("Font"), FontProperty, None)
_set_defaults('font_size', _("Font Size"), _("Size"), FontProperty, 12,
- blend = blend_number)
+ blend = blend_number)
factory_text_style = factory_defaults.Copy()
factory_text_style.fill_pattern = SolidPattern(black)
@@ -457,4 +457,4 @@
if key == 'fill_pattern':
value = value.Copy()
default_text_style.SetProperty(key, value)
-
+
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/psdevice.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/psdevice.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/psdevice.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -44,8 +44,8 @@
class _DummyLineStyle:
def Execute(device):
- device.SetLineColor(color.StandardColors.black)
- device.SetLineAttributes(1, 0, 1, 0)
+ device.SetLineColor(color.StandardColors.black)
+ device.SetLineAttributes(1, 0, 1, 0)
defaultLineStyle = _DummyLineStyle()
@@ -54,8 +54,8 @@
# header comments. Currently the type of all parameters is <textline>
HeaderComments = [('For', '%%%%For: %s\n'),
- ('CreationDate', '%%%%CreationDate: %s\n'),
- ('Title', '%%%%Title: %s\n')]
+ ('CreationDate', '%%%%CreationDate: %s\n'),
+ ('Title', '%%%%Title: %s\n')]
class PostScriptDevice(CommonDevice):
@@ -63,30 +63,30 @@
draw_printable = 1
file = None # default value for file in case open fails.
-
+
def __init__(self, file, as_eps = 1, bounding_box = None,
- document = None, printable = 1, visible = 0, rotate = 0,
+ document = None, printable = 1, visible = 0, rotate = 0,
embed_fonts = 0, **options):
- if as_eps and not bounding_box:
- raise ValueError, 'bounding_box required for EPS'
+ if as_eps and not bounding_box:
+ raise ValueError, 'bounding_box required for EPS'
- self.fill = 0; self.line = 0
- self.properties = None
- self.line = defaultLineStyle
- self.as_eps = as_eps
- self.needed_resources = {}
- self.include_resources = {}
- self.supplied_resources = []
- self.draw_visible = visible
- self.draw_printable = printable
- self.gradient_steps = config.preferences.gradient_steps_print
- self.init_props()
+ self.fill = 0; self.line = 0
+ self.properties = None
+ self.line = defaultLineStyle
+ self.as_eps = as_eps
+ self.needed_resources = {}
+ self.include_resources = {}
+ self.supplied_resources = []
+ self.draw_visible = visible
+ self.draw_printable = printable
+ self.gradient_steps = config.preferences.gradient_steps_print
+ self.init_props()
- if document:
- document.WalkHierarchy(self.add_obj_resources,
- visible = self.draw_visible,
- printable = self.draw_printable)
- self.needed_resources.update(self.include_resources)
+ if document:
+ document.WalkHierarchy(self.add_obj_resources,
+ visible = self.draw_visible,
+ printable = self.draw_printable)
+ self.needed_resources.update(self.include_resources)
# take care of the case where we're writing to an EPS that's
# referenced by the document. This is a bit tricky. If the file
@@ -111,74 +111,74 @@
printable = self.draw_printable)
if type(file) == StringType:
- file = open(file, 'w')
- self.close_file = 1
- else:
- self.close_file = 0
- self.file = file
+ file = open(file, 'w')
+ self.close_file = 1
+ else:
+ self.close_file = 0
+ self.file = file
- if rotate:
- width, height = document.PageSize()
- llx, lly, urx, ury = bounding_box
- bounding_box = (height - ury, llx, height - lly, urx)
+ if rotate:
+ width, height = document.PageSize()
+ llx, lly, urx, ury = bounding_box
+ bounding_box = (height - ury, llx, height - lly, urx)
- write = file.write
- if as_eps:
- write("%!PS-Adobe-3.0 EPSF-3.0\n")
- else:
- write("%!PS-Adobe-3.0\n")
- # header comments
- for name, format in HeaderComments:
- if options.has_key(name):
- value = options[name]
- if value:
- write(format % make_textline(value))
- write("%%%%Creator: Skencil %s\n" % SketchVersion)
- write("%%Pages: 1\n") # there is exactly one page
- if bounding_box:
- [llx, lly, urx, ury] = map(int, bounding_box)
- write('%%%%BoundingBox: %d %d %d %d\n'
- % (llx - 1, lly - 1, urx + 1, ury + 1))
+ write = file.write
+ if as_eps:
+ write("%!PS-Adobe-3.0 EPSF-3.0\n")
+ else:
+ write("%!PS-Adobe-3.0\n")
+ # header comments
+ for name, format in HeaderComments:
+ if options.has_key(name):
+ value = options[name]
+ if value:
+ write(format % make_textline(value))
+ write("%%%%Creator: Skencil %s\n" % SketchVersion)
+ write("%%Pages: 1\n") # there is exactly one page
+ if bounding_box:
+ [llx, lly, urx, ury] = map(int, bounding_box)
+ write('%%%%BoundingBox: %d %d %d %d\n'
+ % (llx - 1, lly - 1, urx + 1, ury + 1))
if rotate and document.Layout().Orientation() == pagelayout.Landscape:
write("%%Orientation: Landscape\n")
- # XXX The Extensions comment should take embedded EPS files into
- # account. (the colorimage operator should be optional)
- write("%%Extensions: CMYK\n")
+ # XXX The Extensions comment should take embedded EPS files into
+ # account. (the colorimage operator should be optional)
+ write("%%Extensions: CMYK\n")
- write("%%DocumentSuppliedResources: (atend)\n")
+ write("%%DocumentSuppliedResources: (atend)\n")
- if self.needed_resources:
+ if self.needed_resources:
start_written = 0
- for restype, value in self.needed_resources.keys():
+ for restype, value in self.needed_resources.keys():
if restype == 'font' and embed_fonts:
continue
- if not start_written:
- write('%%%%DocumentNeededResources: %s %s\n'
+ if not start_written:
+ write('%%%%DocumentNeededResources: %s %s\n'
% (restype, value))
- else:
- write('%%%%+ %s %s\n' % (restype, value))
+ else:
+ write('%%%%+ %s %s\n' % (restype, value))
- write("%%EndComments\n\n")
+ write("%%EndComments\n\n")
- write('%%BeginProlog\n')
- procfile = os.path.join(config.sketch_dir, config.postscript_prolog)
- procfile = open(procfile, 'r')
- line = procfile.readline()
- self.supplied_resources.append(join(split(strip(line))[1:]))
- write(line)
- for line in map(lstrip, procfile.readlines()):
- if line and line[0] != '%':
- write(line)
- write('%%EndResource\n')
- procfile.close()
+ write('%%BeginProlog\n')
+ procfile = os.path.join(config.sketch_dir, config.postscript_prolog)
+ procfile = open(procfile, 'r')
+ line = procfile.readline()
+ self.supplied_resources.append(join(split(strip(line))[1:]))
+ write(line)
+ for line in map(lstrip, procfile.readlines()):
+ if line and line[0] != '%':
+ write(line)
+ write('%%EndResource\n')
+ procfile.close()
- write('%%EndProlog\n\n')
+ write('%%EndProlog\n\n')
- write('%%BeginSetup\n')
- if self.needed_resources:
- for res in self.include_resources.keys():
+ write('%%BeginSetup\n')
+ if self.needed_resources:
+ for res in self.include_resources.keys():
restype, value = res
if restype == 'font' and embed_fonts:
fontfile = font.GetFont(value).FontFileName()
@@ -199,27 +199,27 @@
_("Can't find file for font '%s' for embedding")
% value)
write('%%%%IncludeResource: %s %s\n' % res)
- write('\n10.433 setmiterlimit\n') # 11 degree
- write('%%EndSetup\n\n')
+ write('\n10.433 setmiterlimit\n') # 11 degree
+ write('%%EndSetup\n\n')
- write('%%Page: 1 1\n')
- write('SketchDict begin\n')
- if rotate:
- self.Rotate(pi/2)
- self.Translate(0, -height)
+ write('%%Page: 1 1\n')
+ write('SketchDict begin\n')
+ if rotate:
+ self.Rotate(pi/2)
+ self.Translate(0, -height)
def init_props(self):
- self.init_line_props()
- self.init_color_props()
- self.init_font_props()
+ self.init_line_props()
+ self.init_color_props()
+ self.init_font_props()
def add_obj_resources(self, obj):
- # append reources from OBJ to self.needed_resources
- if obj.has_font:
- res = ('font', obj.Font().PostScriptName())
- self.include_resources[res] = 1
- if obj.is_Eps:
- self.needed_resources.update(obj.PSNeededResources())
+ # append reources from OBJ to self.needed_resources
+ if obj.has_font:
+ res = ('font', obj.Font().PostScriptName())
+ self.include_resources[res] = 1
+ if obj.is_Eps:
+ self.needed_resources.update(obj.PSNeededResources())
def handle_writes_to_embedded_eps(self, obj):
if obj.is_Eps:
@@ -235,360 +235,360 @@
trailer_written = 0
def Close(self):
- if self.file is not None and not self.file.closed:
- if not self.trailer_written:
- write = self.file.write
- write('%%PageTrailer\n')
- write('showpage\n')
- write('%%Trailer\n')
- write('end\n')
- if self.supplied_resources:
- write('%%%%DocumentSuppliedResources: %s\n'
- % self.supplied_resources[0])
- for res in self.supplied_resources[1:]:
- write('%%%%+ %s\n' % res)
+ if self.file is not None and not self.file.closed:
+ if not self.trailer_written:
+ write = self.file.write
+ write('%%PageTrailer\n')
+ write('showpage\n')
+ write('%%Trailer\n')
+ write('end\n')
+ if self.supplied_resources:
+ write('%%%%DocumentSuppliedResources: %s\n'
+ % self.supplied_resources[0])
+ for res in self.supplied_resources[1:]:
+ write('%%%%+ %s\n' % res)
- write('%%EOF\n')
- self.trailer_written = 1
- if self.close_file:
- self.file.close()
+ write('%%EOF\n')
+ self.trailer_written = 1
+ if self.close_file:
+ self.file.close()
def __del__(self):
- try:
- self.Close()
- except:
- warn_tb(INTERNAL, "In __del__ of psdevice")
+ try:
+ self.Close()
+ except:
+ warn_tb(INTERNAL, "In __del__ of psdevice")
def PushTrafo(self):
- self.file.write('pusht\n')
+ self.file.write('pusht\n')
def Concat(self, trafo):
- self.file.write('[%g %g %g %g %g %g] concat\n'
- % (trafo.m11, trafo.m21, trafo.m12, trafo.m22,
- trafo.v1, trafo.v2))
+ self.file.write('[%g %g %g %g %g %g] concat\n'
+ % (trafo.m11, trafo.m21, trafo.m12, trafo.m22,
+ trafo.v1, trafo.v2))
def Translate(self, x, y = None):
- if y is None:
- x, y = x
- self.file.write('%g %g translate\n' % (x, y))
+ if y is None:
+ x, y = x
+ self.file.write('%g %g translate\n' % (x, y))
def Rotate(self, angle):
- self.file.write('%g rotate\n' % (angle * 180 / pi))
+ self.file.write('%g rotate\n' % (angle * 180 / pi))
def Scale(self, scale):
- self.file.write('%g dup scale\n' % scale)
+ self.file.write('%g dup scale\n' % scale)
def PopTrafo(self):
- self.file.write('popt\n')
+ self.file.write('popt\n')
def PushClip(self):
- self.file.write('pushc\n')
+ self.file.write('pushc\n')
def PopClip(self):
- self.file.write('popc\n')
- # popc is grestore. make sure properties are set properly again
- # after this.
- self.init_props()
+ self.file.write('popc\n')
+ # popc is grestore. make sure properties are set properly again
+ # after this.
+ self.init_props()
def init_color_props(self):
- self.current_color = None
+ self.current_color = None
def _set_color(self, color):
- if self.current_color != color:
- r, g, b = color
- self.file.write('%g %g %g rgb\n'
- % (round(r, 3), round(g, 3), round(b, 3)))
- self.current_color = color
+ if self.current_color != color:
+ r, g, b = color
+ self.file.write('%g %g %g rgb\n'
+ % (round(r, 3), round(g, 3), round(b, 3)))
+ self.current_color = color
SetFillColor = _set_color
SetLineColor = _set_color
def init_line_props(self):
- self.current_width = self.current_cap = self.current_join = None
- self.current_dash = None
+ self.current_width = self.current_cap = self.current_join = None
+ self.current_dash = None
def SetLineAttributes(self, width, cap = 1, join = 0, dashes = ()):
- write = self.file.write
- if self.current_width != width:
+ write = self.file.write
+ if self.current_width != width:
width_changed = 1
- write('%g w\n' % width)
- self.current_width = width
+ write('%g w\n' % width)
+ self.current_width = width
else:
width_changed = 0
- join = ps_join[join]
- if self.current_join != join:
- write('%d j\n' % join)
- self.current_join = join
- cap = ps_cap[cap]
- if self.current_cap != cap:
- write('%d J\n' % cap)
- self.current_cap = cap
+ join = ps_join[join]
+ if self.current_join != join:
+ write('%d j\n' % join)
+ self.current_join = join
+ cap = ps_cap[cap]
+ if self.current_cap != cap:
+ write('%d J\n' % cap)
+ self.current_cap = cap
- if self.current_dash != dashes or width_changed:
- # for long dashes tuples this could theoretically produce
- # lines longer than 255 chars, which means that the file
- # would not conform to the DSC
- if width < 1:
- width = 1
- write('[')
- for dash in dashes:
- dash = width * dash
- if dash < 0.001:
- dash = 0.001
- write('%g ' % dash)
- write('] 0 d\n')
- self.current_dash = dashes
+ if self.current_dash != dashes or width_changed:
+ # for long dashes tuples this could theoretically produce
+ # lines longer than 255 chars, which means that the file
+ # would not conform to the DSC
+ if width < 1:
+ width = 1
+ write('[')
+ for dash in dashes:
+ dash = width * dash
+ if dash < 0.001:
+ dash = 0.001
+ write('%g ' % dash)
+ write('] 0 d\n')
+ self.current_dash = dashes
def SetLineSolid(self):
- self.file.write('[ ] 0 d\n')
- self.current_dash = ()
+ self.file.write('[ ] 0 d\n')
+ self.current_dash = ()
def DrawLine(self, start, end):
- self.file.write('%g %g m %g %g l s\n' % (tuple(start) + tuple(end)))
+ self.file.write('%g %g m %g %g l s\n' % (tuple(start) + tuple(end)))
def DrawLineXY(self, x1, y1, x2, y2):
- self.file.write('%g %g m %g %g l s\n' % (x1, y1, x2, y2))
+ self.file.write('%g %g m %g %g l s\n' % (x1, y1, x2, y2))
def DrawRectangle(self, start, end):
- self.file.write('%g %g %g %g R s\n' % (tuple(start) + tuple(end)))
+ self.file.write('%g %g %g %g R s\n' % (tuple(start) + tuple(end)))
def FillRectangle(self, left, bottom, right, top):
- self.file.write('%g %g %g %g R f\n' % (left, bottom, right, top))
+ self.file.write('%g %g %g %g R f\n' % (left, bottom, right, top))
def DrawCircle(self, center, radius):
- self.file.write('%g %g %g C s\n' % (center.x, center.y, radius))
+ self.file.write('%g %g %g C s\n' % (center.x, center.y, radius))
def FillCircle(self, center, radius):
- self.file.write('%g %g %g C f\n' % (center.x, center.y, radius))
+ self.file.write('%g %g %g C f\n' % (center.x, center.y, radius))
def FillPolygon(self, pts):
- write = self.file.write
- if len(pts) > 1:
- write('%g %g m\n' % pts[0])
- for p in pts[1:]:
- write('%g %g l\n' % p)
- write('f\n')
+ write = self.file.write
+ if len(pts) > 1:
+ write('%g %g m\n' % pts[0])
+ for p in pts[1:]:
+ write('%g %g l\n' % p)
+ write('f\n')
def DrawBezierPath(self, path, rect = None):
- self.write_path(path.get_save())
- self.file.write('S\n')
+ self.write_path(path.get_save())
+ self.file.write('S\n')
def FillBezierPath(self, path, rect = None):
- self.write_path(path.get_save())
- self.file.write('F\n')
+ self.write_path(path.get_save())
+ self.file.write('F\n')
def fill_path(self, clip = 0):
- write = self.file.write
- if self.proc_fill:
- if not clip:
- self.PushClip()
- write('eoclip newpath\n')
- self.properties.ExecuteFill(self, self.pattern_rect)
- if not clip:
- self.PopClip()
- write('newpath\n')
- else:
- self.properties.ExecuteFill(self, self.pattern_rect)
- if not clip:
- write('F\n')
- else:
- write('gsave F grestore eoclip newpath\n')
+ write = self.file.write
+ if self.proc_fill:
+ if not clip:
+ self.PushClip()
+ write('eoclip newpath\n')
+ self.properties.ExecuteFill(self, self.pattern_rect)
+ if not clip:
+ self.PopClip()
+ write('newpath\n')
+ else:
+ self.properties.ExecuteFill(self, self.pattern_rect)
+ if not clip:
+ write('F\n')
+ else:
+ write('gsave F grestore eoclip newpath\n')
def stroke_path(self):
- self.properties.ExecuteLine(self, self.pattern_rect)
- self.file.write('S\n')
+ self.properties.ExecuteLine(self, self.pattern_rect)
+ self.file.write('S\n')
def fill_and_stroke(self, clip = 0):
- write = self.file.write
+ write = self.file.write
- if not clip and self.line:
- if self.fill:
- write('gsave\n')
- self.fill_path()
- write('grestore\n')
+ if not clip and self.line:
+ if self.fill:
+ write('gsave\n')
+ self.fill_path()
+ write('grestore\n')
self.init_props()
- self.stroke_path()
- else:
- self.stroke_path()
- else:
- if self.fill:
- self.fill_path(clip)
- elif clip:
- write('eoclip newpath\n')
+ self.stroke_path()
+ else:
+ self.stroke_path()
+ else:
+ if self.fill:
+ self.fill_path(clip)
+ elif clip:
+ write('eoclip newpath\n')
def write_path(self, list):
- write = self.file.write
- write('%g %g m\n' % list[0][:-1])
- for item in list[1:]:
- if len(item) == 3:
- write('%g %g l\n' % item[:-1])
- elif len(item) == 7:
- write('%g %g %g %g %g %g c\n' % item[:-1])
- else:
- if __debug__:
- pdebug('PS', 'PostScriptDevice: invalid bezier item:',item)
+ write = self.file.write
+ write('%g %g m\n' % list[0][:-1])
+ for item in list[1:]:
+ if len(item) == 3:
+ write('%g %g l\n' % item[:-1])
+ elif len(item) == 7:
+ write('%g %g %g %g %g %g c\n' % item[:-1])
+ else:
+ if __debug__:
+ pdebug('PS', 'PostScriptDevice: invalid bezier item:',item)
def MultiBezier(self, paths, rect = None, clip = 0):
- # XXX: try to write path only once
- write = self.file.write
- line = self.line; fill = self.fill
+ # XXX: try to write path only once
+ write = self.file.write
+ line = self.line; fill = self.fill
- if line or fill or clip:
- open = 0
- for path in paths:
- open = open or not path.closed
+ if line or fill or clip:
+ open = 0
+ for path in paths:
+ open = open or not path.closed
- write('newpath\n')
- if fill or clip:
- if not open:
- # all subpaths are closed
- for path in paths:
- self.write_path(path.get_save())
- write('closepath\n')
- self.fill_and_stroke(clip)
- line = 0
- else:
- # some but not all sub paths are closed
- for path in paths:
- self.write_path(path.get_save())
- if not path.closed:
- write('closepath\n')
- self.fill_path(clip)
+ write('newpath\n')
+ if fill or clip:
+ if not open:
+ # all subpaths are closed
+ for path in paths:
+ self.write_path(path.get_save())
+ write('closepath\n')
+ self.fill_and_stroke(clip)
+ line = 0
+ else:
+ # some but not all sub paths are closed
+ for path in paths:
+ self.write_path(path.get_save())
+ if not path.closed:
+ write('closepath\n')
+ self.fill_path(clip)
- if line:
- for path in paths:
- self.write_path(path.get_save())
- if path.closed:
- write('closepath\n')
- self.stroke_path()
- self.draw_arrows(paths)
+ if line:
+ for path in paths:
+ self.write_path(path.get_save())
+ if path.closed:
+ write('closepath\n')
+ self.stroke_path()
+ self.draw_arrows(paths)
def Rectangle(self, trafo, clip = 0):
- if self.fill or self.line or clip:
- self.file.write('[%g %g %g %g %g %g] rect\n' % trafo.coeff())
- self.fill_and_stroke(clip)
+ if self.fill or self.line or clip:
+ self.file.write('[%g %g %g %g %g %g] rect\n' % trafo.coeff())
+ self.fill_and_stroke(clip)
def RoundedRectangle(self, trafo, radius1, radius2, clip = 0):
- if self.fill or self.line or clip:
- self.file.write('[%g %g %g %g %g %g] %g %g rect\n'
+ if self.fill or self.line or clip:
+ self.file.write('[%g %g %g %g %g %g] %g %g rect\n'
% (trafo.coeff() + (radius1, radius2)))
- self.fill_and_stroke(clip)
+ self.fill_and_stroke(clip)
def SimpleEllipse(self, trafo, start_angle, end_angle, arc_type,
- rect = None, clip = 0):
- if self.fill or self.line or clip:
- if start_angle == end_angle:
- self.file.write('[%g %g %g %g %g %g] ellipse\n'
- % trafo.coeff())
- self.fill_and_stroke(clip)
- else:
- self.file.write('[%g %g %g %g %g %g] %g %g %d ellipse\n' %
- (trafo.coeff()
- + (start_angle, end_angle, arc_type)))
- self.fill_and_stroke(clip)
- self.draw_ellipse_arrows(trafo, start_angle, end_angle, arc_type,
- rect)
+ rect = None, clip = 0):
+ if self.fill or self.line or clip:
+ if start_angle == end_angle:
+ self.file.write('[%g %g %g %g %g %g] ellipse\n'
+ % trafo.coeff())
+ self.fill_and_stroke(clip)
+ else:
+ self.file.write('[%g %g %g %g %g %g] %g %g %d ellipse\n' %
+ (trafo.coeff()
+ + (start_angle, end_angle, arc_type)))
+ self.fill_and_stroke(clip)
+ self.draw_ellipse_arrows(trafo, start_angle, end_angle, arc_type,
+ rect)
def init_font_props(self):
- self.current_font = None
+ self.current_font = None
def set_font(self, font, size):
- spec = (font.PostScriptName(), size)
- if self.current_font != spec:
- self.file.write('/%s %g sf\n' % spec)
- self.current_font = spec
+ spec = (font.PostScriptName(), size)
+ if self.current_font != spec:
+ self.file.write('/%s %g sf\n' % spec)
+ self.current_font = spec
def DrawText(self, text, trafo, clip = 0, cache = None):
- # XXX: should make sure that lines in eps file will not be
- # longer than 255 characters.
- font = self.properties.font
- if font:
- write = self.file.write
- self.set_font(font, self.properties.font_size)
- write('(%s)\n' % quote_ps_string(text))
- if trafo.matrix() == IdentityMatrix:
- write('%g %g ' % tuple(trafo.offset()))
- else:
- write('[%g %g %g %g %g %g] ' % trafo.coeff())
- if self.proc_fill:
- write('P ')
- write('gsave clip newpath\n')
- self.properties.ExecuteFill(self, self.pattern_rect)
- write('grestore ')
- if clip:
- write('clip ')
- write('newpath\n')
- else:
- self.properties.ExecuteFill(self, self.pattern_rect)
- if clip:
- write('TP clip newpath\n')
- else:
- write('T\n')
+ # XXX: should make sure that lines in eps file will not be
+ # longer than 255 characters.
+ font = self.properties.font
+ if font:
+ write = self.file.write
+ self.set_font(font, self.properties.font_size)
+ write('(%s)\n' % quote_ps_string(text))
+ if trafo.matrix() == IdentityMatrix:
+ write('%g %g ' % tuple(trafo.offset()))
+ else:
+ write('[%g %g %g %g %g %g] ' % trafo.coeff())
+ if self.proc_fill:
+ write('P ')
+ write('gsave clip newpath\n')
+ self.properties.ExecuteFill(self, self.pattern_rect)
+ write('grestore ')
+ if clip:
+ write('clip ')
+ write('newpath\n')
+ else:
+ self.properties.ExecuteFill(self, self.pattern_rect)
+ if clip:
+ write('TP clip newpath\n')
+ else:
+ write('T\n')
complex_text = None
def BeginComplexText(self, clip = 0, cache = None):
- # XXX clip does not work yet...
- self.complex_text = Empty(clip = clip, fontname = '', size = None)
- if self.proc_fill or clip:
- self.PushClip()
- else:
- self.properties.ExecuteFill(self, self.pattern_rect)
+ # XXX clip does not work yet...
+ self.complex_text = Empty(clip = clip, fontname = '', size = None)
+ if self.proc_fill or clip:
+ self.PushClip()
+ else:
+ self.properties.ExecuteFill(self, self.pattern_rect)
def DrawComplexText(self, text, trafo, font, font_size):
- write = self.file.write
- complex_text = self.complex_text
- self.set_font(font, font_size)
- write('(%s) ' % quote_ps_string(text))
- if trafo.matrix() == IdentityMatrix:
- write('%g %g ' % tuple(trafo.offset()))
- else:
- write('[%g %g %g %g %g %g] ' % trafo.coeff())
- if self.proc_fill:
- write('P\n')
- else:
- write('T\n')
+ write = self.file.write
+ complex_text = self.complex_text
+ self.set_font(font, font_size)
+ write('(%s) ' % quote_ps_string(text))
+ if trafo.matrix() == IdentityMatrix:
+ write('%g %g ' % tuple(trafo.offset()))
+ else:
+ write('[%g %g %g %g %g %g] ' % trafo.coeff())
+ if self.proc_fill:
+ write('P\n')
+ else:
+ write('T\n')
def EndComplexText(self):
- if self.proc_fill:
- self.file.write('eoclip newpath\n')
- self.properties.ExecuteFill(self, self.pattern_rect)
- self.PopClip()
- self.complex_text = None
+ if self.proc_fill:
+ self.file.write('eoclip newpath\n')
+ self.properties.ExecuteFill(self, self.pattern_rect)
+ self.PopClip()
+ self.complex_text = None
def DrawImage(self, image, trafo, clip = 0):
- write = self.file.write
- w, h = image.size
- if len(image.mode) >= 3:
- # compute number of hex lines. 80 hex digits per line. 3 bytes
- # per pixel
- digits = w * h * 6 # 3 bytes per pixel, 2 digits per byte
- if digits <= 0:
- # an empty image. (it should never be < 0 ...)
- return
- lines = (digits - 1) / 80 + 1
- write('%d %d ' % image.size)
- write('[%g %g %g %g %g %g] true\n' % trafo.coeff())
- write('%%%%BeginData: %d Hex Lines\n' % (lines + 1))
- write('skcimg\n')
- else:
- digits = w * h * 2 # 2 digits per byte
- if digits <= 0:
- # an empty image. (it should never be < 0 ...)
- return
- lines = (digits - 1) / 80 + 1
- write('%d %d ' % image.size)
- write('[%g %g %g %g %g %g] true\n' % trafo.coeff())
- write('%%%%BeginData: %d Hex Lines\n' % (lines + 1))
- write('skgimg\n')
+ write = self.file.write
+ w, h = image.size
+ if len(image.mode) >= 3:
+ # compute number of hex lines. 80 hex digits per line. 3 bytes
+ # per pixel
+ digits = w * h * 6 # 3 bytes per pixel, 2 digits per byte
+ if digits <= 0:
+ # an empty image. (it should never be < 0 ...)
+ return
+ lines = (digits - 1) / 80 + 1
+ write('%d %d ' % image.size)
+ write('[%g %g %g %g %g %g] true\n' % trafo.coeff())
+ write('%%%%BeginData: %d Hex Lines\n' % (lines + 1))
+ write('skcimg\n')
+ else:
+ digits = w * h * 2 # 2 digits per byte
+ if digits <= 0:
+ # an empty image. (it should never be < 0 ...)
+ return
+ lines = (digits - 1) / 80 + 1
+ write('%d %d ' % image.size)
+ write('[%g %g %g %g %g %g] true\n' % trafo.coeff())
+ write('%%%%BeginData: %d Hex Lines\n' % (lines + 1))
+ write('skgimg\n')
- _sketch.write_ps_hex(image.im, self.file)
- write('%%EndData\n')
- if clip:
- write('pusht [%g %g %g %g %g %g] concat\n' % trafo.coeff())
- write('%d %d scale\n' % image.size)
- write('0 0 m 1 0 l 1 1 l 0 1 l closepath popt clip\n')
+ _sketch.write_ps_hex(image.im, self.file)
+ write('%%EndData\n')
+ if clip:
+ write('pusht [%g %g %g %g %g %g] concat\n' % trafo.coeff())
+ write('%d %d scale\n' % image.size)
+ write('0 0 m 1 0 l 1 1 l 0 1 l closepath popt clip\n')
def DrawEps(self, data, trafo):
@@ -608,82 +608,82 @@
pass
def DrawGuideLine(self, *args):
- pass
+ pass
def SetProperties(self, properties, rect = None):
- self.properties = properties
- self.line = properties.HasLine()
- self.fill = properties.HasFill()
- self.pattern_rect = rect
- self.proc_fill = properties.IsAlgorithmicFill()
- self.proc_line = properties.IsAlgorithmicLine()
+ self.properties = properties
+ self.line = properties.HasLine()
+ self.fill = properties.HasFill()
+ self.pattern_rect = rect
+ self.proc_fill = properties.IsAlgorithmicFill()
+ self.proc_line = properties.IsAlgorithmicLine()
def write_gradient(self, gradient):
- # self.current_color is implicitly reset because gradients are
- # nested in a PushClip/PopClip, so we don't have to update that
- write = self.file.write
- samples = gradient.Sample(self.gradient_steps)
- write('%d gradient\n' % len(samples))
- last = None
- for color in samples:
- if color != last:
- r, g, b = last = color
- write('%g %g %g $\n' % (round(r, 3), round(g, 3), round(b, 3)))
- else:
- write('!\n')
+ # self.current_color is implicitly reset because gradients are
+ # nested in a PushClip/PopClip, so we don't have to update that
+ write = self.file.write
+ samples = gradient.Sample(self.gradient_steps)
+ write('%d gradient\n' % len(samples))
+ last = None
+ for color in samples:
+ if color != last:
+ r, g, b = last = color
+ write('%g %g %g $\n' % (round(r, 3), round(g, 3), round(b, 3)))
+ else:
+ write('!\n')
has_axial_gradient = 1
def AxialGradient(self, gradient, p0, p1):
- # must accept p0 and p1 as PointSpecs
- self.write_gradient(gradient)
- self.file.write('%g %g %g %g axial\n' % (tuple(p0) + tuple(p1)))
+ # must accept p0 and p1 as PointSpecs
+ self.write_gradient(gradient)
+ self.file.write('%g %g %g %g axial\n' % (tuple(p0) + tuple(p1)))
has_radial_gradient = 1
def RadialGradient(self, gradient, p, r0, r1):
- # must accept p as PointSpec
- self.write_gradient(gradient)
- self.file.write('%g %g %g %g radial\n' % (tuple(p) + (r0, r1)))
+ # must accept p as PointSpec
+ self.write_gradient(gradient)
+ self.file.write('%g %g %g %g radial\n' % (tuple(p) + (r0, r1)))
has_conical_gradient = 1
def ConicalGradient(self, gradient, p, angle):
- # must accept p as PointSpec
- self.write_gradient(gradient)
- self.file.write('%g %g %g conical\n' % (tuple(p) + (angle,)))
+ # must accept p as PointSpec
+ self.write_gradient(gradient)
+ self.file.write('%g %g %g conical\n' % (tuple(p) + (angle,)))
def TileImage(self, image, trafo):
- width, height = image.size
+ width, height = image.size
if image.mode == 'RGBA':
# We don't support transparency in textures, so we simply
# treat RGBA as as RGB images
mode = 'RGB'
else:
mode = image.mode
- length = width * height * len(mode)
- if length > 65536:
- # the tile image is too large to fit into a PostScript
- # string. Resize it.
- #warn(USER, "Image data to big for tiling, resizing...")
- ratio = float(width) / height
- max_size = 65536 / len(mode)
- width = int(sqrt(max_size * ratio))
- height = int(sqrt(max_size / ratio))
- tile = image.im.resize((width, height))
- length = width * height * len(mode)
- trafo = trafo(Scale(float(image.size[0]) / width,
- float(image.size[1]) / height))
- else:
- tile = image.im
- write = self.file.write
- write('%d %d %d [%g %g %g %g %g %g]\n'
- % ((width, height, len(mode)) + trafo.coeff()))
- digits = length * 2 # 2 digits per byte
- lines = (digits - 1) / 80 + 1
- write('%%%%BeginData: %d Hex Lines\n' % (lines + 1))
- write("tileimage\n")
+ length = width * height * len(mode)
+ if length > 65536:
+ # the tile image is too large to fit into a PostScript
+ # string. Resize it.
+ #warn(USER, "Image data to big for tiling, resizing...")
+ ratio = float(width) / height
+ max_size = 65536 / len(mode)
+ width = int(sqrt(max_size * ratio))
+ height = int(sqrt(max_size / ratio))
+ tile = image.im.resize((width, height))
+ length = width * height * len(mode)
+ trafo = trafo(Scale(float(image.size[0]) / width,
+ float(image.size[1]) / height))
+ else:
+ tile = image.im
+ write = self.file.write
+ write('%d %d %d [%g %g %g %g %g %g]\n'
+ % ((width, height, len(mode)) + trafo.coeff()))
+ digits = length * 2 # 2 digits per byte
+ lines = (digits - 1) / 80 + 1
+ write('%%%%BeginData: %d Hex Lines\n' % (lines + 1))
+ write("tileimage\n")
# write_ps_hex treats RGBA like RGB
- _sketch.write_ps_hex(tile, self.file)
- write('%%EndData\n')
+ _sketch.write_ps_hex(tile, self.file)
+ write('%%EndData\n')
#
# Outline Mode
@@ -691,10 +691,10 @@
#
def StartOutlineMode(self, *rest):
- pass
+ pass
def EndOutlineMode(self, *rest):
- pass
+ pass
def IsOutlineActive(self, *rest):
- return 0
+ return 0
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/rectangle.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/rectangle.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/rectangle.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -51,7 +51,7 @@
def __init__(self, trafo = None, radius1 = 0, radius2 = 0,
properties = None, duplicate = None):
- RectangularPrimitive.__init__(self, trafo, properties = properties,
+ RectangularPrimitive.__init__(self, trafo, properties = properties,
duplicate = duplicate)
if duplicate is not None:
self.radius1 = duplicate.radius1
@@ -81,7 +81,7 @@
return undo
def DrawShape(self, device, rect = None, clip = 0):
- Primitive.DrawShape(self, device)
+ Primitive.DrawShape(self, device)
if self.radius1 == self.radius2 == 0:
device.Rectangle(self.trafo, clip)
else:
@@ -99,7 +99,7 @@
return self.rect_path
def AsBezier(self):
- return PolyBezier(paths = self.rect_path,
+ return PolyBezier(paths = self.rect_path,
properties = self.properties.Duplicate())
def Hit(self, p, rect, device, clip = 0):
@@ -116,16 +116,16 @@
return map(self.trafo, corners + [(0.5, 0.5)])
def Snap(self, p):
- try:
- x, y = self.trafo.inverse()(p)
+ try:
+ x, y = self.trafo.inverse()(p)
minx = self.radius1
maxx = 1 - self.radius1
miny = self.radius2
maxy = 1 - self.radius2
- if minx < x < maxx:
- if miny < y < maxy:
+ if minx < x < maxx:
+ if miny < y < maxy:
ratio = hypot(self.trafo.m11, self.trafo.m21) \
- / hypot(self.trafo.m12, self.trafo.m22)
+ / hypot(self.trafo.m12, self.trafo.m22)
if x < 0.5:
dx = x
else:
@@ -142,7 +142,7 @@
y = 1
else:
y = 0
- elif miny < y < maxy:
+ elif miny < y < maxy:
if x > maxx:
x = 1
else:
@@ -165,27 +165,27 @@
x = round(min(max(x, 0), 1))
y = round(min(max(y, 0), 1))
- p2 = self.trafo(x, y)
- return (abs(p - p2), p2)
- except SingularMatrix:
- return (1e200, p)
+ p2 = self.trafo(x, y)
+ return (abs(p - p2), p2)
+ except SingularMatrix:
+ return (1e200, p)
def update_rects(self):
- rect = PointsToRect(map(self.trafo, corners))
- self.coord_rect = rect
- if self.properties.HasLine():
- self.bounding_rect = rect.grown(self.properties.GrowAmount())
- else:
- self.bounding_rect = rect
+ rect = PointsToRect(map(self.trafo, corners))
+ self.coord_rect = rect
+ if self.properties.HasLine():
+ self.bounding_rect = rect.grown(self.properties.GrowAmount())
+ else:
+ self.bounding_rect = rect
def Info(self):
- trafo = self.trafo
- w = hypot(trafo.m11, trafo.m21)
- h = hypot(trafo.m12, trafo.m22)
- return _("Rectangle %(size)[size]"), {'size': (w, h)}
+ trafo = self.trafo
+ w = hypot(trafo.m11, trafo.m21)
+ h = hypot(trafo.m12, trafo.m22)
+ return _("Rectangle %(size)[size]"), {'size': (w, h)}
def SaveToFile(self, file):
- Primitive.SaveToFile(self, file)
+ Primitive.SaveToFile(self, file)
file.Rectangle(self.trafo, self.radius1, self.radius2)
def Blend(self, other, p, q):
@@ -195,7 +195,7 @@
return result
def Editor(self):
- return RectangleEditor(self)
+ return RectangleEditor(self)
@@ -204,11 +204,11 @@
creation_text = _("Create Rectangle")
state = 0
-
+
def MouseMove(self, p, state):
self.state = state
RectangularCreator.MouseMove(self, p, state)
-
+
def ButtonUp(self, p, button, state):
if self.state & AlternateMask:
p = self.apply_constraint(p, state)
@@ -223,7 +223,7 @@
start = self.drag_start
if self.state & AlternateMask:
start = start - self.off
- device.DrawRectangle(start, self.drag_cur)
+ device.DrawRectangle(start, self.drag_cur)
def CurrentInfoText(self):
start = self.drag_start
@@ -233,7 +233,7 @@
return 'Rectangle: %(size)[size]', {'size': (abs(width), abs(height))}
def CreatedObject(self):
- return Rectangle(self.trafo,
+ return Rectangle(self.trafo,
properties = DefaultGraphicsProperties())
@@ -345,7 +345,7 @@
ratio = height / width
else:
ratio = radius1 / radius2
-
+
if ratio > 1:
max1 = 0.5
max2 = max1 / ratio
@@ -363,14 +363,14 @@
radius2 = max(min(y, max2), 0)
radius1 = radius2 * ratio
return trafo, radius1, radius2
-
+
def DrawDragged(self, device, partially):
if self.selection is not None:
trafo, radius1, radius2 = self.resize()
device.RoundedRectangle(trafo, radius1, radius2)
def GetHandles(self):
- trafo = self.trafo; radius1 = self.radius1; radius2 = self.radius2
+ trafo = self.trafo; radius1 = self.radius1; radius2 = self.radius2
handles = []
if radius1 == radius2 == 0:
@@ -416,9 +416,9 @@
return handles
def SelectHandle(self, handle, mode):
- self.selection = handle
+ self.selection = handle
def SelectPoint(self, p, rect, device, mode):
- return 0
+ return 0
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/selection.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/selection.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/selection.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -64,183 +64,183 @@
handle_idx_to_sel = (7, 6, 5, 8, 4, 1, 2, 3)
def __init__(self):
- SelectAndDrag.__init__(self)
- self.outline_object = None
+ SelectAndDrag.__init__(self)
+ self.outline_object = None
def update_rects(self):
- self.coord_rect = Rect(self.start, self.end)
- self.bounding_rect = self.coord_rect
+ self.coord_rect = Rect(self.start, self.end)
+ self.bounding_rect = self.coord_rect
def SetOutlineObject(self, obj):
- # XXX: this is a hack...
- if obj is not None:
- if obj.is_Compound:
- objects = obj.GetObjects()
- if len(objects) == 1:
- obj = objects[0]
- else:
- return
- if not obj.is_Compound and not obj.is_Text:
- self.outline_object = obj
+ # XXX: this is a hack...
+ if obj is not None:
+ if obj.is_Compound:
+ objects = obj.GetObjects()
+ if len(objects) == 1:
+ obj = objects[0]
+ else:
+ return
+ if not obj.is_Compound and not obj.is_Text:
+ self.outline_object = obj
class SelectionRectangle(SelRectBase):
def __init__(self, rect, anchor = None):
- SelRectBase.__init__(self)
- if type(rect) == RectType:
- self.start = Point(rect.left, rect.bottom)
- self.end = Point(rect.right, rect.top)
- self.Normalize()
- self.anchor = anchor
- else:
- # assume type Point and interactive creation
- self.start = rect
- self.end = rect
- self.anchor = None
- self.selection = 5
+ SelRectBase.__init__(self)
+ if type(rect) == RectType:
+ self.start = Point(rect.left, rect.bottom)
+ self.end = Point(rect.right, rect.top)
+ self.Normalize()
+ self.anchor = anchor
+ else:
+ # assume type Point and interactive creation
+ self.start = rect
+ self.end = rect
+ self.anchor = None
+ self.selection = 5
def DrawDragged(self, device, partially):
- sel = self.selection
+ sel = self.selection
- if sel == -1:
- sx, sy = self.start + self.off
- ex, ey = self.end + self.off
- else:
- if sel in self.selTop:
- sy = self.drag_cur.y
- else:
- sy = self.start.y
+ if sel == -1:
+ sx, sy = self.start + self.off
+ ex, ey = self.end + self.off
+ else:
+ if sel in self.selTop:
+ sy = self.drag_cur.y
+ else:
+ sy = self.start.y
- if sel in self.selBottom:
- ey = self.drag_cur.y
- else:
- ey = self.end.y
+ if sel in self.selBottom:
+ ey = self.drag_cur.y
+ else:
+ ey = self.end.y
- if sel in self.selLeft:
- sx = self.drag_cur.x
- else:
- sx = self.start.x
+ if sel in self.selLeft:
+ sx = self.drag_cur.x
+ else:
+ sx = self.start.x
- if sel in self.selRight:
- ex = self.drag_cur.x
- else:
- ex = self.end.x
+ if sel in self.selRight:
+ ex = self.drag_cur.x
+ else:
+ ex = self.end.x
- if sx > ex:
- tmp = sx; sx = ex; ex = tmp
- if sy < ey:
- tmp = sy; sy = ey; ey = tmp
+ if sx > ex:
+ tmp = sx; sx = ex; ex = tmp
+ if sy < ey:
+ tmp = sy; sy = ey; ey = tmp
- device.DrawRubberRect(Point(sx, sy), Point(ex, ey))
+ device.DrawRubberRect(Point(sx, sy), Point(ex, ey))
def ButtonDown(self, p, button, state):
- SelectAndDrag.DragStart(self, p)
- sel = self.selection
- if sel == -1:
- if self.anchor: #XXX shouldn't this be 'if self.anchor is not None'
- start = self.anchor
- else:
- start = self.start
- self.drag_start = self.drag_cur = start
- return (p - start, self.coord_rect.translated(-start))
- ds_x , ds_y = (self.start + self.end) / 2
- if sel in self.selLeft:
- ds_x = self.start.x
- if sel in self.selTop:
- ds_y = self.start.y
- if sel in self.selRight:
- ds_x = self.end.x
- if sel in self.selBottom:
- ds_y = self.end.y
- self.drag_cur = self.drag_start = ds = Point(ds_x, ds_y)
- self.init_constraint()
- return p - ds
+ SelectAndDrag.DragStart(self, p)
+ sel = self.selection
+ if sel == -1:
+ if self.anchor: #XXX shouldn't this be 'if self.anchor is not None'
+ start = self.anchor
+ else:
+ start = self.start
+ self.drag_start = self.drag_cur = start
+ return (p - start, self.coord_rect.translated(-start))
+ ds_x , ds_y = (self.start + self.end) / 2
+ if sel in self.selLeft:
+ ds_x = self.start.x
+ if sel in self.selTop:
+ ds_y = self.start.y
+ if sel in self.selRight:
+ ds_x = self.end.x
+ if sel in self.selBottom:
+ ds_y = self.end.y
+ self.drag_cur = self.drag_start = ds = Point(ds_x, ds_y)
+ self.init_constraint()
+ return p - ds
def init_constraint(self):
- pass
+ pass
def apply_constraint(self, p, state):
- return p
+ return p
def MouseMove(self, p, state):
- p = self.apply_constraint(p, state)
- SelectAndDrag.MouseMove(self, p, state)
+ p = self.apply_constraint(p, state)
+ SelectAndDrag.MouseMove(self, p, state)
def compute_endpoints(self):
- cur = self.drag_cur
- start = self.start
- end = self.end
- sel = self.selection
- if sel in self.selTop:
- start = Point(start.x, cur.y)
- if sel in self.selBottom:
- end = Point(end.x, cur.y)
- if sel in self.selLeft:
- start = Point(cur.x, start.y)
- if sel in self.selRight:
- end = Point(cur.x, end.y)
- if sel == -1:
- start = start + self.off
- end = end + self.off
+ cur = self.drag_cur
+ start = self.start
+ end = self.end
+ sel = self.selection
+ if sel in self.selTop:
+ start = Point(start.x, cur.y)
+ if sel in self.selBottom:
+ end = Point(end.x, cur.y)
+ if sel in self.selLeft:
+ start = Point(cur.x, start.y)
+ if sel in self.selRight:
+ end = Point(cur.x, end.y)
+ if sel == -1:
+ start = start + self.off
+ end = end + self.off
return start, end
def ButtonUp(self, p, button, state):
- p = self.apply_constraint(p, state)
- SelectAndDrag.DragStop(self, p)
- cur = self.drag_cur
- oldstart = self.start
- oldend = self.end
- start, end = self.compute_endpoints()
- self.start = start
- self.end = end
- result = self.ComputeTrafo(oldstart, oldend, start, end)
- self.Normalize()
- return result
+ p = self.apply_constraint(p, state)
+ SelectAndDrag.DragStop(self, p)
+ cur = self.drag_cur
+ oldstart = self.start
+ oldend = self.end
+ start, end = self.compute_endpoints()
+ self.start = start
+ self.end = end
+ result = self.ComputeTrafo(oldstart, oldend, start, end)
+ self.Normalize()
+ return result
def ComputeTrafo(self, oldStart, oldEnd, start, end):
- pass
+ pass
def Normalize(self):
- sx, sy = self.start
- ex, ey = self.end
- if sx > ex:
- sx, ex = ex, sx
- if sy > ey:
- sy, ey = ey, sy
- self.start = Point(sx, sy)
- self.end = Point(ex, ey)
+ sx, sy = self.start
+ ex, ey = self.end
+ if sx > ex:
+ sx, ex = ex, sx
+ if sy > ey:
+ sy, ey = ey, sy
+ self.start = Point(sx, sy)
+ self.end = Point(ex, ey)
def Hit(self, p, rect, device):
- pass
+ pass
def Select(self):
- self.selection = -1
+ self.selection = -1
def SelectPoint(self, p, rect, device, mode = SelectSet):
- if p:
- self.selection = 0
- else:
- self.selection = -1
- return self.selection
+ if p:
+ self.selection = 0
+ else:
+ self.selection = -1
+ return self.selection
def SelectHandle(self, handle, mode = SelectSet):
- self.selection = self.handle_idx_to_sel[handle.index]
+ self.selection = self.handle_idx_to_sel[handle.index]
def GetHandles(self):
- sx = self.start.x
- sy = self.start.y
- ex = self.end.x
- ey = self.end.y
- x2 = (sx + ex) / 2
- y2 = (sy + ey) / 2
- return map(handle.MakeOffsetHandle,
- [Point(sx, ey), Point(x2, ey), Point(ex, ey),
- Point(sx, y2), Point(ex, y2),
- Point(sx, sy), Point(x2, sy), Point(ex, sy)],
- [(-1, 1), (0, 1), ( 1, 1),
- (-1, 0), ( 1, 0),
- (-1, -1), (0, -1), ( 1, -1)])
+ sx = self.start.x
+ sy = self.start.y
+ ex = self.end.x
+ ey = self.end.y
+ x2 = (sx + ex) / 2
+ y2 = (sy + ey) / 2
+ return map(handle.MakeOffsetHandle,
+ [Point(sx, ey), Point(x2, ey), Point(ex, ey),
+ Point(sx, y2), Point(ex, y2),
+ Point(sx, sy), Point(x2, sy), Point(ex, sy)],
+ [(-1, 1), (0, 1), ( 1, 1),
+ (-1, 0), ( 1, 0),
+ (-1, -1), (0, -1), ( 1, -1)])
@@ -250,46 +250,46 @@
_lazy_attrs = Bounded._lazy_attrs.copy()
_lazy_attrs['rect'] = 'update_rectangle'
-
+
def __init__(self, copy_from = None):
- if copy_from is not None:
- if type(copy_from) == ListType:
- self.objects = copy_from[:]
- else:
- # assume copy_from is another instance of a selection class
- self.objects = copy_from.objects
- self.coord_rect = copy_from.coord_rect
- self.bounding_rect = copy_from.bounding_rect
- self.anchor = copy_from.anchor
- else:
- self.objects = []
- self.anchor = None
+ if copy_from is not None:
+ if type(copy_from) == ListType:
+ self.objects = copy_from[:]
+ else:
+ # assume copy_from is another instance of a selection class
+ self.objects = copy_from.objects
+ self.coord_rect = copy_from.coord_rect
+ self.bounding_rect = copy_from.bounding_rect
+ self.anchor = copy_from.anchor
+ else:
+ self.objects = []
+ self.anchor = None
def normalize(self):
- # make sure that self.objects contains no object more than once
- # and that no two objects have a direct or indirect parent/child
- # relationship.
- objs = self.objects
- changed = 0
- if len(objs) > 1:
- objs.sort()
- last_info, obj = objs[-1]
- for idx in range(len(objs) - 2, -1, -1):
- info, obj = objs[idx]
- if info == last_info:
- del objs[idx]
- changed = 1
- continue
- if len(info) < len(last_info):
- while info == last_info[:len(info)]:
- del objs[idx + 1]
- changed = 1
- if idx + 1 < len(objs):
- last_info = objs[idx + 1][0]
- else:
- break
- last_info = info
- return changed
+ # make sure that self.objects contains no object more than once
+ # and that no two objects have a direct or indirect parent/child
+ # relationship.
+ objs = self.objects
+ changed = 0
+ if len(objs) > 1:
+ objs.sort()
+ last_info, obj = objs[-1]
+ for idx in range(len(objs) - 2, -1, -1):
+ info, obj = objs[idx]
+ if info == last_info:
+ del objs[idx]
+ changed = 1
+ continue
+ if len(info) < len(last_info):
+ while info == last_info[:len(info)]:
+ del objs[idx + 1]
+ changed = 1
+ if idx + 1 < len(objs):
+ last_info = objs[idx + 1][0]
+ else:
+ break
+ last_info = info
+ return changed
def update_selinfo(self):
objs = self.objects
@@ -297,185 +297,185 @@
objs[i] = objs[i][-1].SelectionInfo()
def SetSelection(self, info):
- old_objs = self.objects
- if info:
- if type(info) == ListType:
- self.objects = info
- self.objects.sort()
- else:
- self.objects = [info]
- else:
- self.objects = []
- self.del_lazy_attrs()
- return old_objs != self.objects
+ old_objs = self.objects
+ if info:
+ if type(info) == ListType:
+ self.objects = info
+ self.objects.sort()
+ else:
+ self.objects = [info]
+ else:
+ self.objects = []
+ self.del_lazy_attrs()
+ return old_objs != self.objects
def SetSelectionTree(self, info):
- return self.SetSelection(selinfo.tree_to_list(info))
+ return self.SetSelection(selinfo.tree_to_list(info))
def Add(self, info):
- if not info:
- return 0
- old_len = len(self.objects)
- if type(info) == ListType:
- self.objects = self.objects + info
- elif info:
- self.objects.append(info)
- changed = self.normalize()
- self.del_lazy_attrs()
- return changed or old_len != len(self.objects)
+ if not info:
+ return 0
+ old_len = len(self.objects)
+ if type(info) == ListType:
+ self.objects = self.objects + info
+ elif info:
+ self.objects.append(info)
+ changed = self.normalize()
+ self.del_lazy_attrs()
+ return changed or old_len != len(self.objects)
def Subtract(self, info):
- if not info:
- return 0
- old_len = len(self.objects)
- if type(info) != ListType:
- info = [info]
- objects = self.objects
- for item in info:
- if item in objects:
- objects.remove(item)
- self.del_lazy_attrs()
- return old_len != len(self.objects)
+ if not info:
+ return 0
+ old_len = len(self.objects)
+ if type(info) != ListType:
+ info = [info]
+ objects = self.objects
+ for item in info:
+ if item in objects:
+ objects.remove(item)
+ self.del_lazy_attrs()
+ return old_len != len(self.objects)
def GetObjects(self):
- return map(operator.getitem, self.objects, [-1] * len(self.objects))
+ return map(operator.getitem, self.objects, [-1] * len(self.objects))
def GetInfo(self):
- return self.objects
+ return self.objects
def GetInfoTree(self):
- return selinfo.list_to_tree(self.objects)
+ return selinfo.list_to_tree(self.objects)
def Depth(self):
- if self.objects:
- lengths = map(len, map(operator.getitem, self.objects,
- [0] * len(self.objects)))
- lmin = min(lengths)
- lmax = max(lengths)
- if lmin == lmax:
- return lmin
- return (lmin, lmax)
- return 0
+ if self.objects:
+ lengths = map(len, map(operator.getitem, self.objects,
+ [0] * len(self.objects)))
+ lmin = min(lengths)
+ lmax = max(lengths)
+ if lmin == lmax:
+ return lmin
+ return (lmin, lmax)
+ return 0
def IsSingleDepth(self):
- if self.objects:
- return type(self.Depth()) != TupleType
- return 1
+ if self.objects:
+ return type(self.Depth()) != TupleType
+ return 1
def GetPath(self):
- if len(self.objects) == 1:
- return self.objects[0][0]
- return ()
+ if len(self.objects) == 1:
+ return self.objects[0][0]
+ return ()
def for_all(self, func):
- return map(func, self.GetObjects())
+ return map(func, self.GetObjects())
def ForAllUndo(self, func):
- undoinfo = self.for_all(func)
- self.del_lazy_attrs()
- if len(undoinfo) == 1:
- undoinfo = undoinfo[0]
- if type(undoinfo) == ListType:
- return CreateListUndo(undoinfo)
- return undoinfo
+ undoinfo = self.for_all(func)
+ self.del_lazy_attrs()
+ if len(undoinfo) == 1:
+ undoinfo = undoinfo[0]
+ if type(undoinfo) == ListType:
+ return CreateListUndo(undoinfo)
+ return undoinfo
def ForAllUndo2(self, method, *args):
- t = time.clock()
- methods = map(getattr, self.GetObjects(), [method] * len(self.objects))
- #print time.clock() - t,
- #undoinfo = self.for_all(func)
- undoinfo = map(apply, methods, [args] * len(methods))
- #print time.clock() - t
- self.del_lazy_attrs()
- if len(undoinfo) == 1:
- undoinfo = undoinfo[0]
- if type(undoinfo) == ListType:
- return CreateListUndo(undoinfo)
- return undoinfo
+ t = time.clock()
+ methods = map(getattr, self.GetObjects(), [method] * len(self.objects))
+ #print time.clock() - t,
+ #undoinfo = self.for_all(func)
+ undoinfo = map(apply, methods, [args] * len(methods))
+ #print time.clock() - t
+ self.del_lazy_attrs()
+ if len(undoinfo) == 1:
+ undoinfo = undoinfo[0]
+ if type(undoinfo) == ListType:
+ return CreateListUndo(undoinfo)
+ return undoinfo
def __len__(self):
- return len(self.objects)
+ return len(self.objects)
__nonzero__ = __len__
def update_rects(self):
- objects = self.GetObjects()
- boxes = map(lambda o: o.coord_rect, objects)
- if boxes:
- self.coord_rect = reduce(UnionRects, boxes)
- else:
- self.coord_rect = None
- boxes = map(lambda o: o.bounding_rect, objects)
- if boxes:
- self.bounding_rect = reduce(UnionRects, boxes)
- else:
- self.bounding_rect = None
- if len(objects) == 1:
- self.anchor = objects[0].LayoutPoint()
- else:
- self.anchor = None
+ objects = self.GetObjects()
+ boxes = map(lambda o: o.coord_rect, objects)
+ if boxes:
+ self.coord_rect = reduce(UnionRects, boxes)
+ else:
+ self.coord_rect = None
+ boxes = map(lambda o: o.bounding_rect, objects)
+ if boxes:
+ self.bounding_rect = reduce(UnionRects, boxes)
+ else:
+ self.bounding_rect = None
+ if len(objects) == 1:
+ self.anchor = objects[0].LayoutPoint()
+ else:
+ self.anchor = None
def ChangeRect(self):
- return self.bounding_rect
+ return self.bounding_rect
def ResetRectangle(self):
- self.del_lazy_attrs()
+ self.del_lazy_attrs()
def Hit(self, p, rect, device):
- test = rect.overlaps
- for obj in self.GetObjects():
- if test(obj.bounding_rect):
- if obj.Hit(p, rect, device):
- return 1
- return 0
+ test = rect.overlaps
+ for obj in self.GetObjects():
+ if test(obj.bounding_rect):
+ if obj.Hit(p, rect, device):
+ return 1
+ return 0
def DragCancel(self):
- self.rect.DragCancel()
+ self.rect.DragCancel()
def GetHandles(self):
- rect_handles = self.rect.GetHandles()
- multiple = len(self.objects) > 1
- handles = flatten(self.for_all(lambda o, m = multiple:
- o.GetObjectHandle(m)))
- rect_handles.append(handle.MakeObjectHandleList(handles))
- return rect_handles
+ rect_handles = self.rect.GetHandles()
+ multiple = len(self.objects) > 1
+ handles = flatten(self.for_all(lambda o, m = multiple:
+ o.GetObjectHandle(m)))
+ rect_handles.append(handle.MakeObjectHandleList(handles))
+ return rect_handles
def CallObjectMethod(self, aclass, methodname, args):
- if len(self.objects) == 1:
- obj = self.objects[0][-1]
- if not isinstance(obj, aclass):
- return NullUndo
- try:
- method = getattr(obj, methodname)
- except AttributeError:
- return NullUndo
+ if len(self.objects) == 1:
+ obj = self.objects[0][-1]
+ if not isinstance(obj, aclass):
+ return NullUndo
+ try:
+ method = getattr(obj, methodname)
+ except AttributeError:
+ return NullUndo
- undo = apply(method, args)
- if undo is None:
- undo = NullUndo
- return undo
- return NullUndo
+ undo = apply(method, args)
+ if undo is None:
+ undo = NullUndo
+ return undo
+ return NullUndo
def GetObjectMethod(self, aclass, method):
- if len(self.objects) == 1:
- obj = self.objects[0][-1]
- if isinstance(obj, aclass):
- try:
- return getattr(obj, method)
- except AttributeError:
- pass
- return None
+ if len(self.objects) == 1:
+ obj = self.objects[0][-1]
+ if isinstance(obj, aclass):
+ try:
+ return getattr(obj, method)
+ except AttributeError:
+ pass
+ return None
def InfoText(self):
- # Return a string describing the selected object(s)
+ # Return a string describing the selected object(s)
result = _("No Selection")
- if self.objects:
- sel_info = self.objects
- document = sel_info[0][1].document
- if len(sel_info) == 1:
+ if self.objects:
+ sel_info = self.objects
+ document = sel_info[0][1].document
+ if len(sel_info) == 1:
path, obj = sel_info[0]
dict = {'layer': document[path[0]].Name()}
- info = obj.Info()
+ info = obj.Info()
if type(info) == TupleType:
dict.update(info[1])
# the %% is correct here. The result has to be a
@@ -485,15 +485,15 @@
dict['object'] = info
text = _("%(object)s on `%(layer)s'")
result = text, dict
- else:
- layer = sel_info[0][0][0]
- if layer == sel_info[-1][0][0]:
- # a single layer
- layer_name = document.layers[layer].Name()
- result = _("%(number)d objects on `%(layer)s'") \
- % {'number':len(sel_info), 'layer':layer_name}
- else:
- result = _("%d objects on several layers") % len(sel_info)
+ else:
+ layer = sel_info[0][0][0]
+ if layer == sel_info[-1][0][0]:
+ # a single layer
+ layer_name = document.layers[layer].Name()
+ result = _("%(number)d objects on `%(layer)s'") \
+ % {'number':len(sel_info), 'layer':layer_name}
+ else:
+ result = _("%d objects on several layers") % len(sel_info)
return result
@@ -501,7 +501,7 @@
return ''
def _dummy(self, *args):
- pass
+ pass
Hide = _dummy
DragStart = None
@@ -519,98 +519,98 @@
class SizeRectangle(SelectionRectangle):
def init_constraint(self):
- sel = self.selection
- if sel == 1:
- self.reference = tuple(self.end)
- elif sel == 3:
- self.reference = (self.start.x, self.end.y)
- elif sel == 5:
- self.reference = tuple(self.start)
- elif sel == 7:
- self.reference = (self.end.x, self.start.y)
- else:
- return
- width = abs(self.start.x - self.end.x)
- height = abs(self.start.y - self.end.y)
- if width >= 1e-10:
- self.aspect = height / width
- else:
- self.aspect = None
+ sel = self.selection
+ if sel == 1:
+ self.reference = tuple(self.end)
+ elif sel == 3:
+ self.reference = (self.start.x, self.end.y)
+ elif sel == 5:
+ self.reference = tuple(self.start)
+ elif sel == 7:
+ self.reference = (self.end.x, self.start.y)
+ else:
+ return
+ width = abs(self.start.x - self.end.x)
+ height = abs(self.start.y - self.end.y)
+ if width >= 1e-10:
+ self.aspect = height / width
+ else:
+ self.aspect = None
def apply_constraint(self, p, state):
- if state & const.ConstraintMask:
- if self.selection in self.selAspect:
- ref_x, ref_y = self.reference
- aspect = self.aspect
- if aspect is None:
- # width is 0
- p = Point(self.drag_start.x, p.y)
- else:
- w = p.x - ref_x
- h = p.y - ref_y
- if w == 0:
- w = 0.00001
- a = h / w
- if a > 0:
- sign = 1
- else:
- sign = -1
- if abs(a) > aspect:
- h = sign * w * aspect
- else:
- w = sign * h / aspect
- p = Point(ref_x + w, ref_y + h)
- elif self.selection == -1:
- pi4 = math.pi / 4
- off = p - self.drag_start
+ if state & const.ConstraintMask:
+ if self.selection in self.selAspect:
+ ref_x, ref_y = self.reference
+ aspect = self.aspect
+ if aspect is None:
+ # width is 0
+ p = Point(self.drag_start.x, p.y)
+ else:
+ w = p.x - ref_x
+ h = p.y - ref_y
+ if w == 0:
+ w = 0.00001
+ a = h / w
+ if a > 0:
+ sign = 1
+ else:
+ sign = -1
+ if abs(a) > aspect:
+ h = sign * w * aspect
+ else:
+ w = sign * h / aspect
+ p = Point(ref_x + w, ref_y + h)
+ elif self.selection == -1:
+ pi4 = math.pi / 4
+ off = p - self.drag_start
d = Polar(pi4 * round(math.atan2(off.y, off.x) / pi4))
p = self.drag_start + (off * d) * d
- return p
+ return p
def ButtonDown(self, p, button, state):
self.trafo = Identity
return SelectionRectangle.ButtonDown(self, p, button, state)
def MouseMove(self, p, state):
- p = self.apply_constraint(p, state)
- SelectAndDrag.MouseMove(self, p, state)
+ p = self.apply_constraint(p, state)
+ SelectAndDrag.MouseMove(self, p, state)
start, end = self.compute_endpoints()
text, self.trafo = self.ComputeTrafo(self.start, self.end, start, end)
def ComputeTrafo(self, oldStart, oldEnd, start, end):
- oldDelta = oldEnd - oldStart
- delta = end - start
- if self.selection == -1:
- # a translation.
- return _("Move Objects"), start - oldStart
- else:
- try:
- m11 = delta.x / oldDelta.x
- except ZeroDivisionError:
- m11 = 0
- if __debug__:
- pdebug(None, 'ComputeTrafo: ZeroDivisionError')
- try:
- m22 = delta.y / oldDelta.y
- except ZeroDivisionError:
- m22 = 0
- if __debug__:
- pdebug(None, 'ComputeTrafo: ZeroDivisionError')
- offx = start.x - m11 * oldStart.x
- offy = start.y - m22 * oldStart.y
- return _("Resize Objects"), Trafo(m11, 0, 0, m22, offx, offy)
+ oldDelta = oldEnd - oldStart
+ delta = end - start
+ if self.selection == -1:
+ # a translation.
+ return _("Move Objects"), start - oldStart
+ else:
+ try:
+ m11 = delta.x / oldDelta.x
+ except ZeroDivisionError:
+ m11 = 0
+ if __debug__:
+ pdebug(None, 'ComputeTrafo: ZeroDivisionError')
+ try:
+ m22 = delta.y / oldDelta.y
+ except ZeroDivisionError:
+ m22 = 0
+ if __debug__:
+ pdebug(None, 'ComputeTrafo: ZeroDivisionError')
+ offx = start.x - m11 * oldStart.x
+ offy = start.y - m22 * oldStart.y
+ return _("Resize Objects"), Trafo(m11, 0, 0, m22, offx, offy)
def DrawDragged(self, device, partial):
- SelectionRectangle.DrawDragged(self, device, partial)
- if self.outline_object is not None:
- trafo = self.trafo
- device.PushTrafo()
- if type(trafo) == TrafoType:
- device.Concat(trafo)
- else:
- device.Translate(trafo.x, trafo.y)
- self.outline_object.DrawShape(device)
- device.PopTrafo()
+ SelectionRectangle.DrawDragged(self, device, partial)
+ if self.outline_object is not None:
+ trafo = self.trafo
+ device.PushTrafo()
+ if type(trafo) == TrafoType:
+ device.Concat(trafo)
+ else:
+ device.Translate(trafo.x, trafo.y)
+ self.outline_object.DrawShape(device)
+ device.PopTrafo()
def CurrentInfoText(self):
t = self.trafo
@@ -636,60 +636,60 @@
class SizeSelection(Selection):
def __init__(self, arg = None):
- Selection.__init__(self, arg)
+ Selection.__init__(self, arg)
def update_rectangle(self):
- if self:
- self.rect = SizeRectangle(self.coord_rect, self.anchor)
- else:
- self.rect = SizeRectangle(Rect(0, 0, 0, 0))
+ if self:
+ self.rect = SizeRectangle(self.coord_rect, self.anchor)
+ else:
+ self.rect = SizeRectangle(Rect(0, 0, 0, 0))
def ButtonDown(self, p, button, state):
- if len(self.objects) == 1:
- self.rect.SetOutlineObject(self.objects[0][-1])
- return self.rect.ButtonDown(p, button, state)
+ if len(self.objects) == 1:
+ self.rect.SetOutlineObject(self.objects[0][-1])
+ return self.rect.ButtonDown(p, button, state)
def MouseMove(self, p, state):
- self.rect.MouseMove(p, state)
+ self.rect.MouseMove(p, state)
def ButtonUp(self, p, button, state, forget_trafo = 0):
- self.rect.SetOutlineObject(None)
- undo_text, trafo = self.rect.ButtonUp(p, button, state)
- if forget_trafo:
- return None, None
- t = time.clock()
- if type(trafo) == TrafoType:
- #undo = self.ForAllUndo(lambda o, t = trafo: o.Transform(t))
- undo = self.ForAllUndo2('Transform', trafo)
- else:
- # trafo is point representing a translation
- undo = self.ForAllUndo2('Translate', trafo)
- #print 'transform/translate', time.clock() - t
- self.del_lazy_attrs()
- return undo_text, undo
+ self.rect.SetOutlineObject(None)
+ undo_text, trafo = self.rect.ButtonUp(p, button, state)
+ if forget_trafo:
+ return None, None
+ t = time.clock()
+ if type(trafo) == TrafoType:
+ #undo = self.ForAllUndo(lambda o, t = trafo: o.Transform(t))
+ undo = self.ForAllUndo2('Transform', trafo)
+ else:
+ # trafo is point representing a translation
+ undo = self.ForAllUndo2('Translate', trafo)
+ #print 'transform/translate', time.clock() - t
+ self.del_lazy_attrs()
+ return undo_text, undo
def Show(self, device, partially = 0):
- self.rect.Show(device, partially)
+ self.rect.Show(device, partially)
def Hide(self, device, partially = 0):
- self.rect.Hide(device, partially)
+ self.rect.Hide(device, partially)
def DrawDragged(self, device, partial):
- self.rect.DrawDragged(device, partial)
+ self.rect.DrawDragged(device, partial)
def SelectPoint(self, p, rect, device, mode = SelectSet):
- if not self.rect.SelectPoint(p, rect, device, mode):
- if self.Hit(p, rect, device):
- self.rect.Select()
+ if not self.rect.SelectPoint(p, rect, device, mode):
+ if self.Hit(p, rect, device):
+ self.rect.Select()
def SelectHandle(self, handle, mode = SelectSet):
- self.rect.SelectHandle(handle, mode)
+ self.rect.SelectHandle(handle, mode)
def Hit(self, p, rect, device):
- if self.objects:
- return (rect.overlaps(self.bounding_rect)
- and Selection.Hit(self, p, rect, device))
- return 0
+ if self.objects:
+ return (rect.overlaps(self.bounding_rect)
+ and Selection.Hit(self, p, rect, device))
+ return 0
def CurrentInfoText(self):
return self.rect.CurrentInfoText()
@@ -701,133 +701,133 @@
selCenter = 100
def __init__(self, rect, center = None):
- SelRectBase.__init__(self)
- self.start = Point(rect.left, rect.bottom)
- self.end = Point(rect.right, rect.top)
- if center is None:
- self.center = rect.center()
- else:
- self.center = center
+ SelRectBase.__init__(self)
+ self.start = Point(rect.left, rect.bottom)
+ self.end = Point(rect.right, rect.top)
+ if center is None:
+ self.center = rect.center()
+ else:
+ self.center = center
def compute_trafo(self, state = 0):
- sel = self.selection
- if sel in self.selTurn:
- # rotation
- vec = self.drag_cur - self.center
- angle = math.atan2(vec.y, vec.x)
- angle = angle - self.start_angle + 2 * math.pi
- if state & const.ConstraintMask:
- pi12 = math.pi / 12
- angle = pi12 * int(angle / pi12 + 0.5)
+ sel = self.selection
+ if sel in self.selTurn:
+ # rotation
+ vec = self.drag_cur - self.center
+ angle = math.atan2(vec.y, vec.x)
+ angle = angle - self.start_angle + 2 * math.pi
+ if state & const.ConstraintMask:
+ pi12 = math.pi / 12
+ angle = pi12 * int(angle / pi12 + 0.5)
self.trafo = Rotation(angle, self.center)
self.trafo_desc = (1, angle)
- elif sel in self.selShear:
- if sel in (2,6):
- # horiz. shear
- height = self.drag_start.y - self.reference
- if height:
- ratio = self.off.x / height
- self.trafo = Trafo(1, 0, ratio, 1,
+ elif sel in self.selShear:
+ if sel in (2,6):
+ # horiz. shear
+ height = self.drag_start.y - self.reference
+ if height:
+ ratio = self.off.x / height
+ self.trafo = Trafo(1, 0, ratio, 1,
- ratio * self.reference, 0)
self.trafo_desc = (2, ratio)
- else:
- # vert. shear
- width = self.drag_start.x - self.reference
- if width:
- ratio = self.off.y / width
- self.trafo = Trafo(1, ratio, 0, 1, 0,
+ else:
+ # vert. shear
+ width = self.drag_start.x - self.reference
+ if width:
+ ratio = self.off.y / width
+ self.trafo = Trafo(1, ratio, 0, 1, 0,
- ratio * self.reference)
self.trafo_desc = (3, ratio)
def DrawDragged(self, device, partially):
- sel = self.selection
- if sel == self.selCenter:
- device.DrawPixmapHandle(self.drag_cur, pixmaps.Center)
- else:
- trafo = self.trafo
- if trafo:
- device.PushTrafo()
- device.Concat(trafo)
- device.DrawRubberRect(self.start, self.end)
- if self.outline_object is not None:
- self.outline_object.DrawShape(device)
- device.PopTrafo()
+ sel = self.selection
+ if sel == self.selCenter:
+ device.DrawPixmapHandle(self.drag_cur, pixmaps.Center)
+ else:
+ trafo = self.trafo
+ if trafo:
+ device.PushTrafo()
+ device.Concat(trafo)
+ device.DrawRubberRect(self.start, self.end)
+ if self.outline_object is not None:
+ self.outline_object.DrawShape(device)
+ device.PopTrafo()
def ButtonDown(self, p, button, state):
- self.drag_state = state
+ self.drag_state = state
self.trafo = Identity
self.trafo_desc = (0, 0)
- SelectAndDrag.DragStart(self, p)
- sel = self.selection
- if sel == self.selCenter:
- self.drag_cur = self.drag_start = self.center
- return p - self.center
- ds_x = ds_y = 0
- if sel in self.selLeft:
- ds_x = self.start.x
- if sel in self.selTop:
- ds_y = self.start.y
- if sel in self.selRight:
- ds_x = self.end.x
- if sel in self.selBottom:
- ds_y = self.end.y
- self.drag_cur = self.drag_start = ds = Point(ds_x, ds_y)
- if sel in self.selTurn:
- vec = ds - self.center
- self.start_angle = math.atan2(vec.y, vec.x)
- else:
- if sel == 2:
- self.reference = self.end.y
- elif sel == 4:
- self.reference = self.start.x
- elif sel == 6:
- self.reference = self.start.y
- elif sel == 8:
- self.reference = self.end.x
- return p - ds
+ SelectAndDrag.DragStart(self, p)
+ sel = self.selection
+ if sel == self.selCenter:
+ self.drag_cur = self.drag_start = self.center
+ return p - self.center
+ ds_x = ds_y = 0
+ if sel in self.selLeft:
+ ds_x = self.start.x
+ if sel in self.selTop:
+ ds_y = self.start.y
+ if sel in self.selRight:
+ ds_x = self.end.x
+ if sel in self.selBottom:
+ ds_y = self.end.y
+ self.drag_cur = self.drag_start = ds = Point(ds_x, ds_y)
+ if sel in self.selTurn:
+ vec = ds - self.center
+ self.start_angle = math.atan2(vec.y, vec.x)
+ else:
+ if sel == 2:
+ self.reference = self.end.y
+ elif sel == 4:
+ self.reference = self.start.x
+ elif sel == 6:
+ self.reference = self.start.y
+ elif sel == 8:
+ self.reference = self.end.x
+ return p - ds
def constrain_center(self, p, state):
- if state & const.ConstraintMask:
- start = self.start
- end = self.end
- if p.x < 0.75 * start.x + 0.25 * end.x:
- x = start.x
- elif p.x > 0.25 * start.x + 0.75 * end.x:
- x = end.x
- else:
- x = (start.x + end.x) / 2
- if p.y < 0.75 * start.y + 0.25 * end.y:
- y = start.y
- elif p.y > 0.25 * start.y + 0.75 * end.y:
- y = end.y
- else:
- y = (start.y + end.y) / 2
- return Point(x, y)
- return p
+ if state & const.ConstraintMask:
+ start = self.start
+ end = self.end
+ if p.x < 0.75 * start.x + 0.25 * end.x:
+ x = start.x
+ elif p.x > 0.25 * start.x + 0.75 * end.x:
+ x = end.x
+ else:
+ x = (start.x + end.x) / 2
+ if p.y < 0.75 * start.y + 0.25 * end.y:
+ y = start.y
+ elif p.y > 0.25 * start.y + 0.75 * end.y:
+ y = end.y
+ else:
+ y = (start.y + end.y) / 2
+ return Point(x, y)
+ return p
def MouseMove(self, p, state):
- self.drag_state = state
- if self.selection == self.selCenter:
- p = self.constrain_center(p, state)
- SelectAndDrag.MouseMove(self, p, state)
+ self.drag_state = state
+ if self.selection == self.selCenter:
+ p = self.constrain_center(p, state)
+ SelectAndDrag.MouseMove(self, p, state)
self.compute_trafo(state)
def ButtonUp(self, p, button, state):
- if self.selection == self.selCenter:
- p = self.constrain_center(p, state)
- SelectAndDrag.DragStop(self, p)
- sel = self.selection
- if sel == self.selCenter:
- self.center = self.drag_cur
- return '', None
- else:
+ if self.selection == self.selCenter:
+ p = self.constrain_center(p, state)
+ SelectAndDrag.DragStop(self, p)
+ sel = self.selection
+ if sel == self.selCenter:
+ self.center = self.drag_cur
+ return '', None
+ else:
self.compute_trafo(state)
- trafo = self.trafo
- if self.selection in self.selShear:
- text = _("Shear Objects")
- else:
- text = _("Rotate Objects")
- return text, trafo
+ trafo = self.trafo
+ if self.selection in self.selShear:
+ text = _("Shear Objects")
+ else:
+ text = _("Rotate Objects")
+ return text, trafo
def CurrentInfoText(self):
if self.selection == self.selCenter:
@@ -850,100 +850,100 @@
return text, data
def Hit(self, p, rect, device):
- pass
+ pass
def Select(self):
- pass
+ pass
def SelectPoint(self, p, rect, device, mode = SelectSet):
- self.selection = 0
- return self.selection
+ self.selection = 0
+ return self.selection
def SelectHandle(self, handle, mode = SelectSet):
- handle = handle.index
- if handle == len(self.handle_idx_to_sel):
- self.selection = self.selCenter
- else:
- self.selection = self.handle_idx_to_sel[handle]
+ handle = handle.index
+ if handle == len(self.handle_idx_to_sel):
+ self.selection = self.selCenter
+ else:
+ self.selection = self.handle_idx_to_sel[handle]
def GetHandles(self):
- sx = self.start.x
- sy = self.start.y
- ex = self.end.x
- ey = self.end.y
- x2 = (sx + ex) / 2
- y2 = (sy + ey) / 2
- return map(handle.MakePixmapHandle,
- [Point(sx, ey), Point(x2, ey), Point(ex, ey),
- Point(sx, y2), Point(ex, y2),
- Point(sx, sy), Point(x2, sy), Point(ex, sy)],
- [(-1, 1), (0, 1), ( 1, 1),
- (-1, 0), ( 1, 0),
- (-1, -1), (0, -1), ( 1, -1)],
- [pixmaps.TurnTL, pixmaps.ShearLR, pixmaps.TurnTR,
- pixmaps.ShearUD, pixmaps.ShearUD,
- pixmaps.TurnBL, pixmaps.ShearLR, pixmaps.TurnBR],
- [const.CurTurn] * 8) \
- + [handle.MakePixmapHandle(self.center, (0, 0), pixmaps.Center)]
+ sx = self.start.x
+ sy = self.start.y
+ ex = self.end.x
+ ey = self.end.y
+ x2 = (sx + ex) / 2
+ y2 = (sy + ey) / 2
+ return map(handle.MakePixmapHandle,
+ [Point(sx, ey), Point(x2, ey), Point(ex, ey),
+ Point(sx, y2), Point(ex, y2),
+ Point(sx, sy), Point(x2, sy), Point(ex, sy)],
+ [(-1, 1), (0, 1), ( 1, 1),
+ (-1, 0), ( 1, 0),
+ (-1, -1), (0, -1), ( 1, -1)],
+ [pixmaps.TurnTL, pixmaps.ShearLR, pixmaps.TurnTR,
+ pixmaps.ShearUD, pixmaps.ShearUD,
+ pixmaps.TurnBL, pixmaps.ShearLR, pixmaps.TurnBR],
+ [const.CurTurn] * 8) \
+ + [handle.MakePixmapHandle(self.center, (0, 0), pixmaps.Center)]
class TrafoSelection(Selection):
def __init__(self, copy_from = None):
- Selection.__init__(self, copy_from)
- self.center = None
+ Selection.__init__(self, copy_from)
+ self.center = None
def update_rectangle(self, same_center = 1):
- if self:
- self.rect = TrafoRectangle(self.coord_rect, self.center)
- else:
- self.rect = TrafoRectangle(Rect(0, 0, 0, 0))
+ if self:
+ self.rect = TrafoRectangle(self.coord_rect, self.center)
+ else:
+ self.rect = TrafoRectangle(Rect(0, 0, 0, 0))
def ButtonDown(self, p, button, state):
- if len(self.objects) == 1:
- self.rect.SetOutlineObject(self.objects[0][-1])
- return self.rect.ButtonDown(p, button, state)
+ if len(self.objects) == 1:
+ self.rect.SetOutlineObject(self.objects[0][-1])
+ return self.rect.ButtonDown(p, button, state)
def MouseMove(self, p, state):
- self.rect.MouseMove(p, state)
+ self.rect.MouseMove(p, state)
def ButtonUp(self, p, button, state, forget_trafo = 0):
- self.rect.SetOutlineObject(None)
- undo_text, trafo = self.rect.ButtonUp(p, button, state)
- self.center = self.rect.center
- if forget_trafo:
- return None, None
- if trafo is not None:
- t = time.clock()
- #undo = self.ForAllUndo(lambda o, t = trafo: o.Transform(t))
- undo = self.ForAllUndo2('Transform', trafo)
- self.del_lazy_attrs()
- #print 'transform/translate', time.clock() - t
- return undo_text, undo
- return '', None
+ self.rect.SetOutlineObject(None)
+ undo_text, trafo = self.rect.ButtonUp(p, button, state)
+ self.center = self.rect.center
+ if forget_trafo:
+ return None, None
+ if trafo is not None:
+ t = time.clock()
+ #undo = self.ForAllUndo(lambda o, t = trafo: o.Transform(t))
+ undo = self.ForAllUndo2('Transform', trafo)
+ self.del_lazy_attrs()
+ #print 'transform/translate', time.clock() - t
+ return undo_text, undo
+ return '', None
def Show(self, device, partially = 0):
- self.rect.Show(device, partially)
+ self.rect.Show(device, partially)
def Hide(self, device, partially = 0):
- self.rect.Hide(device, partially)
+ self.rect.Hide(device, partially)
def DrawDragged(self, device, partial):
- self.rect.DrawDragged(device, partial)
+ self.rect.DrawDragged(device, partial)
def SelectPoint(self, p, rect, device, mode = SelectSet):
- if not self.rect.SelectPoint(p, rect, device, mode):
- if self.Hit(p, rect, device):
- self.rect.Select()
+ if not self.rect.SelectPoint(p, rect, device, mode):
+ if self.Hit(p, rect, device):
+ self.rect.Select()
def SelectHandle(self, handle, mode = SelectSet):
- self.rect.SelectHandle(handle, mode)
+ self.rect.SelectHandle(handle, mode)
def Hit(self, p, rect, device):
- if self.objects:
- return (rect.overlaps(self.rect.bounding_rect)
- and Selection.Hit(self, p, rect, device))
- return 0
+ if self.objects:
+ return (rect.overlaps(self.rect.bounding_rect)
+ and Selection.Hit(self, p, rect, device))
+ return 0
def CurrentInfoText(self):
return self.rect.CurrentInfoText()
@@ -951,179 +951,179 @@
class EditorWrapper:
def __init__(self, editor):
- self.editor = editor
+ self.editor = editor
def __del__(self):
- self.editor.Destroy()
+ self.editor.Destroy()
def __getattr__(self, attr):
- return getattr(self.editor, attr)
+ return getattr(self.editor, attr)
def compatible(self, aclass):
- obj = self.editor
- return isinstance(obj, aclass) or issubclass(obj.EditedClass, aclass)
+ obj = self.editor
+ return isinstance(obj, aclass) or issubclass(obj.EditedClass, aclass)
class EditSelection(Selection):
is_EditSelection = 1
-
+
drag_this = None
editor = None
def __init__(self, copy_from = None):
- Selection.__init__(self, copy_from)
- self.check_edit_mode()
- if type(copy_from) == InstanceType \
- and copy_from.__class__ == self.__class__:
- self.editor = copy_from.editor
- else:
- self.get_editor()
+ Selection.__init__(self, copy_from)
+ self.check_edit_mode()
+ if type(copy_from) == InstanceType \
+ and copy_from.__class__ == self.__class__:
+ self.editor = copy_from.editor
+ else:
+ self.get_editor()
def check_edit_mode(self):
- # allow only one object for editing at a time
- if self.objects:
- if len(self.objects) > 1 or not self.objects[0][-1].has_edit_mode:
- self.objects = []
+ # allow only one object for editing at a time
+ if self.objects:
+ if len(self.objects) > 1 or not self.objects[0][-1].has_edit_mode:
+ self.objects = []
def get_editor(self):
- if self.objects:
- self.editor = EditorWrapper(self.objects[0][-1].Editor())
- else:
- self.editor = None
+ if self.objects:
+ self.editor = EditorWrapper(self.objects[0][-1].Editor())
+ else:
+ self.editor = None
def GetHandles(self):
- if self.editor is not None:
- return self.editor.GetHandles()
- return []
+ if self.editor is not None:
+ return self.editor.GetHandles()
+ return []
def ButtonDown(self, p, button, state):
- if self.drag_this is not None:
- return self.drag_this.ButtonDown(p, button, state)
- else:
- return None
+ if self.drag_this is not None:
+ return self.drag_this.ButtonDown(p, button, state)
+ else:
+ return None
def MouseMove(self, p, state):
- if self.drag_this is not None:
- self.drag_this.MouseMove(p, state)
+ if self.drag_this is not None:
+ self.drag_this.MouseMove(p, state)
def ButtonUp(self, p, button, state, forget_trafo = 0):
- if self.drag_this is not None:
- self.del_lazy_attrs()
- return _("Edit Object"), self.drag_this.ButtonUp(p, button, state)
- return ('', None)
- # XXX make the undo text more general by a method of graphics objects
+ if self.drag_this is not None:
+ self.del_lazy_attrs()
+ return _("Edit Object"), self.drag_this.ButtonUp(p, button, state)
+ return ('', None)
+ # XXX make the undo text more general by a method of graphics objects
def Show(self, device, partially = 0):
- if self.editor is not None:
- self.editor.Show(device, partially)
+ if self.editor is not None:
+ self.editor.Show(device, partially)
def Hide(self, device, partially = 0):
- if self.editor is not None:
- self.editor.Hide(device, partially)
+ if self.editor is not None:
+ self.editor.Hide(device, partially)
def DrawDragged(self, device, partial):
- if self.editor is not None:
+ if self.editor is not None:
self.editor.DrawDragged(device, partial)
def SetSelection(self, info):
- old_sel = self.objects
- Selection.SetSelection(self, info)
- self.check_edit_mode()
- if old_sel != self.objects:
- self.get_editor()
- return 1
- return 0
+ old_sel = self.objects
+ Selection.SetSelection(self, info)
+ self.check_edit_mode()
+ if old_sel != self.objects:
+ self.get_editor()
+ return 1
+ return 0
def SelectPoint(self, p, rect, device, mode = const.SelectSet):
- self.drag_this = None
- if self.editor is not None:
- if self.editor.SelectPoint(p, rect, device, mode):
- self.drag_this = self.editor
- return self.drag_this != None
+ self.drag_this = None
+ if self.editor is not None:
+ if self.editor.SelectPoint(p, rect, device, mode):
+ self.drag_this = self.editor
+ return self.drag_this != None
def SelectHandle(self, handle, mode = SelectSet):
- if self.editor is not None:
- self.editor.SelectHandle(handle, mode)
- self.drag_this = self.editor
- else:
- self.drag_this = None
+ if self.editor is not None:
+ self.editor.SelectHandle(handle, mode)
+ self.drag_this = self.editor
+ else:
+ self.drag_this = None
def SelectRect(self, rect, mode = SelectSet):
- self.drag_this = None
- if self.editor is not None:
- if self.editor.SelectRect(rect, mode):
- self.drag_this = self.editor
- return self.drag_this != None
+ self.drag_this = None
+ if self.editor is not None:
+ if self.editor.SelectRect(rect, mode):
+ self.drag_this = self.editor
+ return self.drag_this != None
def CallObjectMethod(self, aclass, methodname, args):
- if len(self.objects) == 1:
- if self.editor is not None:
- obj = self.editor
- if not obj.compatible(aclass):
- warn(INTERNAL, 'EditSelection.GetObjectMethod: '
- 'editor %s is not compatible with class %s',
- self.editor, aclass)
- return NullUndo
- else:
- obj = self.objects[0][-1]
- if not isinstance(obj, aclass):
- warn(INTERNAL, 'EditSelection.GetObjectMethod: '
- 'object is not instance of %s', aclass)
- return NullUndo
- try:
- method = getattr(obj, methodname)
- except AttributeError:
- warn(INTERNAL, 'EditSelection.GetObjectMethod: '
- 'no method %s for class %s', methodname, aclass)
- return NullUndo
+ if len(self.objects) == 1:
+ if self.editor is not None:
+ obj = self.editor
+ if not obj.compatible(aclass):
+ warn(INTERNAL, 'EditSelection.GetObjectMethod: '
+ 'editor %s is not compatible with class %s',
+ self.editor, aclass)
+ return NullUndo
+ else:
+ obj = self.objects[0][-1]
+ if not isinstance(obj, aclass):
+ warn(INTERNAL, 'EditSelection.GetObjectMethod: '
+ 'object is not instance of %s', aclass)
+ return NullUndo
+ try:
+ method = getattr(obj, methodname)
+ except AttributeError:
+ warn(INTERNAL, 'EditSelection.GetObjectMethod: '
+ 'no method %s for class %s', methodname, aclass)
+ return NullUndo
- undo = apply(method, args)
- if undo is None:
- undo = NullUndo
- return undo
- return NullUndo
+ undo = apply(method, args)
+ if undo is None:
+ undo = NullUndo
+ return undo
+ return NullUndo
def GetObjectMethod(self, aclass, method):
- if len(self.objects) == 1:
- if self.editor is not None:
- obj = self.editor
- if not obj.compatible(aclass):
- warn(INTERNAL, 'EditSelection.GetObjectMethod: '
- 'editor is not compatible with class %s', aclass)
- return None
- else:
- obj = self.objects[0][-1]
- if not isinstance(obj, aclass):
- warn(INTERNAL, 'EditSelection.GetObjectMethod: '
- 'object is not instance of %s', aclass)
- return None
- try:
- return getattr(obj, method)
- except AttributeError:
- warn(INTERNAL, 'EditSelection.GetObjectMethod: '
- 'no method %s for class %s', method, aclass)
- pass
- return None
+ if len(self.objects) == 1:
+ if self.editor is not None:
+ obj = self.editor
+ if not obj.compatible(aclass):
+ warn(INTERNAL, 'EditSelection.GetObjectMethod: '
+ 'editor is not compatible with class %s', aclass)
+ return None
+ else:
+ obj = self.objects[0][-1]
+ if not isinstance(obj, aclass):
+ warn(INTERNAL, 'EditSelection.GetObjectMethod: '
+ 'object is not instance of %s', aclass)
+ return None
+ try:
+ return getattr(obj, method)
+ except AttributeError:
+ warn(INTERNAL, 'EditSelection.GetObjectMethod: '
+ 'no method %s for class %s', method, aclass)
+ pass
+ return None
def ChangeRect(self):
- if self.editor is not None:
- return self.editor.ChangeRect()
- return self.bounding_rect
+ if self.editor is not None:
+ return self.editor.ChangeRect()
+ return self.bounding_rect
def InfoText(self):
- # Return a string describing the selected object(s)
- # XXX we shouldn't access document.layers directly
- if self.editor is not None:
- return self.editor.Info()
- else:
- return _("No Selection")
+ # Return a string describing the selected object(s)
+ # XXX we shouldn't access document.layers directly
+ if self.editor is not None:
+ return self.editor.Info()
+ else:
+ return _("No Selection")
def CurrentInfoText(self):
- if self.editor is not None:
- return self.editor.CurrentInfoText()
- else:
- return ""
-
+ if self.editor is not None:
+ return self.editor.CurrentInfoText()
+ else:
+ return ""
+
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/selinfo.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/selinfo.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/selinfo.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -122,14 +122,14 @@
def prepend_idx(idx, info):
# prepend idx to the path of info.
if type(info) == TupleType:
- return ((idx,) + info[0], info[1])
+ return ((idx,) + info[0], info[1])
if type(info) == ListType:
- idx = (idx,)
- for i in range(len(info)):
- tmp = info[i]
- info[i] = (idx + tmp[0], tmp[1])
- return info
+ idx = (idx,)
+ for i in range(len(info)):
+ tmp = info[i]
+ info[i] = (idx + tmp[0], tmp[1])
+ return info
# assume info is an instance object
return ((idx,), info)
@@ -139,14 +139,14 @@
def select_range(min, objects):
return map(None, map(lambda *t: t, range(min, min + len(objects))),
- objects)
+ objects)
def get_parent(info):
path, obj = info
if len(path) > 1:
- parent = obj.parent
- if parent is not None:
- return (path[:-1], parent)
+ parent = obj.parent
+ if parent is not None:
+ return (path[:-1], parent)
return None
@@ -154,42 +154,42 @@
# convert standard representation to Tree1 representation
dict = {}
for info in infolist:
- path, obj = info
- idx = path[0]
- info = (path[1:], obj)
- try:
- dict[idx].append(info)
- except KeyError:
- dict[idx] = [info]
+ path, obj = info
+ idx = path[0]
+ info = (path[1:], obj)
+ try:
+ dict[idx].append(info)
+ except KeyError:
+ dict[idx] = [info]
result = dict.items()
result.sort()
for idx, info in result:
- info.sort()
+ info.sort()
return result
def list_to_tree2(infolist):
# convert standard representation to Tree2 representation
dict = {}
for info in infolist:
- path, obj = info
- idx = path[0]
- path = path[1:]
- if path:
- info = (path, obj)
- else:
- info = obj
- try:
- dict[idx].append(info)
- except KeyError:
- dict[idx] = [info]
+ path, obj = info
+ idx = path[0]
+ path = path[1:]
+ if path:
+ info = (path, obj)
+ else:
+ info = obj
+ try:
+ dict[idx].append(info)
+ except KeyError:
+ dict[idx] = [info]
result = dict.items()
result.sort()
for i in range(len(result)):
- idx, info = result[i]
- if len(info) == 1 and type(info[0]) != TupleType:
- result[i] = (idx, info[0])
- else:
- info.sort()
+ idx, info = result[i]
+ if len(info) == 1 and type(info[0]) != TupleType:
+ result[i] = (idx, info[0])
+ else:
+ info.sort()
return result
def list_to_tree_sliced(infolist):
@@ -198,36 +198,36 @@
slice_start = slice_end = -1
last_obj = None
for idx, list in list_to_tree2(infolist):
- if type(list) != ListType:
- # list is a child
- if idx == slice_end:
- slice_end = idx + 1
- else:
- if slice_start > -1:
- if slice_end > slice_start + 1:
- result.append((slice_start, slice_end))
- else:
- result.append((slice_start, last_obj))
- slice_start = idx
- slice_end = idx + 1
- last_obj = list
- else:
- # list is a list of children of child
- if slice_start > -1:
- if slice_end > slice_start + 1:
- result.append((slice_start, slice_end))
- else:
- result.append((slice_start, last_obj))
- slice_start = -1
- slice_end = -1
- last_obj = None
- result.append((idx, list))
+ if type(list) != ListType:
+ # list is a child
+ if idx == slice_end:
+ slice_end = idx + 1
+ else:
+ if slice_start > -1:
+ if slice_end > slice_start + 1:
+ result.append((slice_start, slice_end))
+ else:
+ result.append((slice_start, last_obj))
+ slice_start = idx
+ slice_end = idx + 1
+ last_obj = list
+ else:
+ # list is a list of children of child
+ if slice_start > -1:
+ if slice_end > slice_start + 1:
+ result.append((slice_start, slice_end))
+ else:
+ result.append((slice_start, last_obj))
+ slice_start = -1
+ slice_end = -1
+ last_obj = None
+ result.append((idx, list))
else:
- if slice_start > -1:
- if slice_end > slice_start + 1:
- result.append((slice_start, slice_end))
- else:
- result.append((slice_start, last_obj))
+ if slice_start > -1:
+ if slice_end > slice_start + 1:
+ result.append((slice_start, slice_end))
+ else:
+ result.append((slice_start, last_obj))
return result
@@ -235,9 +235,9 @@
def tree_to_list(tree):
result = []
for idx, info in tree:
- idx = (idx,)
- for path, obj in info:
- result.append((idx + path, obj))
+ idx = (idx,)
+ for path, obj in info:
+ result.append((idx + path, obj))
return result
@@ -246,20 +246,20 @@
# LIST is in standard representation. Since that is a sorted list,
# we just have to compare the first and last elements.
if not list:
- return ()
+ return ()
if len(list) == 1:
- return list[0][0]
+ return list[0][0]
first = list[0][0]
last = list[-1][0]
if len(first) > len(last):
- length = len(last)
- first = first[:length]
+ length = len(last)
+ first = first[:length]
else:
- length = len(first)
- last = last[:length]
+ length = len(first)
+ last = last[:length]
for i in range(length):
- if first[i] != last[i]:
- return first[:i]
+ if first[i] != last[i]:
+ return first[:i]
return first
Modified: skencil/branches/skencil-0.6/src/Sketch/Graphics/text.py
===================================================================
--- skencil/branches/skencil-0.6/src/Sketch/Graphics/text.py 2010-09-22 19:13:59 UTC (rev 726)
+++ skencil/branches/skencil-0.6/src/Sketch/Graphics/text.py 2010-09-22 21:52:28 UTC (rev 727)
@@ -77,7 +77,7 @@
from string import split
from math import sin, cos, atan2, hypot, pi, fmod, floor
-
+
from Sketch import _, Rect, UnionRects, EmptyRect, NullPoint, Polar, \
IdentityMatrix, SingularMatrix, Identity, Trafo, Scale, Translation, \
Rotation, NullUndo, CreateMultiUndo, RegisterCommands
@@ -104,7 +104,7 @@
printable = ''
for n in range(len(iso_latin_1)):
if iso_latin_1[n] != encoding.notdef:
- printable = printable + chr(n)
+ printable = printable + chr(n)
# Alignment. Defaults are 0
@@ -121,50 +121,50 @@
commands = []
def __init__(self, text = '', duplicate = None):
- if duplicate is not None:
- self.text = duplicate.text
- else:
- self.text = text
+ if duplicate is not None:
+ self.text = duplicate.text
+ else:
+ self.text = text
def SetText(self, text, caret = None):
- if self.editor is not None:
- oldcaret = self.editor.Caret()
- else:
- oldcaret = 0
- undo = (self.SetText, self.text, oldcaret)
- self.text = text
- if caret is not None and self.editor is not None:
- self.editor.SetCaret(caret)
- self._changed()
- return undo
+ if self.editor is not None:
+ oldcaret = self.editor.Caret()
+ else:
+ oldcaret = 0
+ undo = (self.SetText, self.text, oldcaret)
+ self.text = text
+ if caret is not None and self.editor is not None:
+ self.editor.SetCaret(caret)
+ self._changed()
+ return undo
def Text(self):
- return self.text
+ return self.text
editor = None
def set_editor(self, editor):
- self.editor = editor
+ self.editor = editor
def unset_editor(self, editor):
- if self.editor is editor:
- self.editor = None
+ if self.editor is editor:
+ self.editor = None
def SetFont(self, font, size = None):
- if size is not None:
- undo = self.properties.SetProperty(font = font, font_size = size)
- else:
- undo = self.properties.SetProperty(font = font)
- return self.properties_changed(undo)
+ if size is not None:
+ undo = self.properties.SetProperty(font = font, font_size = size)
+ else:
+ undo = self.properties.SetProperty(font = font)
+ return self.properties_changed(undo)
def SetFontSize(self, size):
- undo = self.properties.SetProperty(font_size = size)
- return self.properties_changed(undo)
+ undo = self.properties.SetProperty(font_size = size)
+ return self.properties_changed(undo)
def Font(self):
- return self.properties.font
+ return self.properties.font
def FontSize(self):
- return self.properties.font_size
+ return self.properties.font_size
class CommonTextEditor(Editor):
@@ -173,81 +173,81 @@
commands = []
def __init__(self, object):
- Editor.__init__(self, object)
- self.caret = 0
- object.set_editor(self)
+ Editor.__init__(self, object)
+ self.caret = 0
+ object.set_editor(self)
def Destroy(self):
- self.object.unset_editor(self)
+ self.object.unset_editor(self)
def ButtonDown(self, p, button, state):
- Editor.DragStart(self, p)
+ Editor.DragStart(self, p)
def ButtonUp(self, p, button, state):
- Editor.DragStop(self, p)
+ Editor.DragStop(self, p)
def update_selection(self):
- # a bit ugly...
- if self.document is not None:
- self.document.queue_selection()
+ # a bit ugly...
+ if self.document is not None:
+ self.document.queue_selection()
def SetCaret(self, caret):
if caret > len(self.text):
caret = len(self.text)
- self.caret = caret
+ self.caret = caret
def Caret(self):
- return self.caret
+ return self.caret
def InsertCharacter(self, char):
- if len(char) == 1 and self.properties.font.IsPrintable(char):
- text = self.text; caret = self.caret
- text = text[:caret] + char + text[caret:]
- return self.SetText(text, caret + 1)
- return NullUndo
+ if len(char) == 1 and self.properties.font.IsPrintable(char):
+ text = self.text; caret = self.caret
+ text = text[:caret] + char + text[caret:]
+ return self.SetText(text, caret + 1)
+ return NullUndo
AddCmd(commands, InsertCharacter, '', key_stroke = tuple(printable),
- invoke_with_keystroke = 1)
+ invoke_with_keystroke = 1)
def DeleteCharBackward(self):
- if self.text and self.caret > 0:
- text = self.text; caret = self.caret
- text = text[:caret - 1] + text[caret:]
- return self.SetText(text, caret - 1)
- return NullUndo
+ if self.text and self.caret > 0:
+ text = self.text; caret = self.caret
+ text = text[:caret - 1] + text[caret:]
+ return self.SetText(text, caret - 1)
+ return NullUndo
AddCmd(commands, DeleteCharBackward, '', key_stroke = 'BackSpace')
def DeleteCharForward(self):
- if self.text and self.caret < len(self.text):
- text = self.text; caret = self.caret
- text = text[:caret] + text[caret + 1:]
- return self.SetText(text, caret)
- return NullUndo
+ if self.text and self.caret < len(self.text):
+ text = self.text; caret = self.caret
+ text = text[:caret] + text[caret + 1:]
+ return self.SetText(text, caret)
+ return NullUndo
AddCmd(commands, DeleteCharForward, '', key_stroke = ('Delete', 'C-d'))
def MoveForwardChar(self):
- if self.caret < len(self.text):
- self.SetCaret(self.caret + 1)
- self.update_selection()
- return NullUndo
+ if self.caret < len(self.text):
+ self.SetCaret(self.caret + 1)
+ self.update_selection()
+ return NullUndo
AddCmd(commands, MoveForwardChar, '', key_stroke = ('Right', 'C-f'))
def MoveBackwardChar(self):
- if self.caret > 0:
- self.SetCaret(self.caret - 1)
- self.update_selection()
- return NullUndo
+ if self.caret > 0:
+ self.SetCaret(self.caret - 1)
+ self.update_selection()
+ return NullUndo
AddCmd(commands, MoveBackwardChar, '', key_stroke = ('Left', 'C-b'))
def MoveToBeginningOfLine(self):
- self.SetCaret(0)
- self.update_selection()
- return NullUndo
+ self.SetCaret(0)
+ self.update_selection()
+ return NullUndo
AddCmd(commands, MoveToBeginningOfLine, '', key_stroke = ('Home', 'C-a'))
def MoveToEndOfLine(self):
- self.SetCaret(len(self.text))
- self.update_selection()
- return NullUndo
+ self.SetCaret(len(self.text))
+ self.update_selection()
+ return NullUndo
AddCmd(commands, MoveToEndOfLine, '', key_stroke = ('End', 'C-e'))
@@ -272,115 +272,115 @@
def __init__(self, trafo = None, text = '', halign = ALIGN_LEFT,
valign = ALIGN_BASE, properties = None, duplicate = None):
- CommonText.__init__(self, text, duplicate)
- RectangularPrimitive.__init__(self, trafo, properties = properties,
- duplicate = duplicate)
- if duplicate != None:
- self.halign = duplicate.halign
- self.valign = duplicate.valign
- self.atrafo = duplicate.atrafo
- else:
- self.halign = halign
- self.valign = valign
- if properties is None:
+ CommonText.__init__(self, text, duplicate)
+ RectangularPrimitive.__init__(self, trafo, properties = properties,
+ duplicate = duplicate)
+ if duplicate != None:
+ self.halign = duplicate.halign
+ self.valign = duplicate.valign
+ self.atrafo = duplicate.atrafo
+ else:
+ self.halign = halign
+ self.valign = valign
+ if properties is None:
self.properties = PropertyStack(base=FactoryTextStyle())
- self.cache = {}
+ self.cache = {}
def Disconnect(self):
- self.cache = {}
- RectangularPrimitive.Disconnect(self)
+ self.cache = {}
+ RectangularPrimitive.Disconnect(self)
def Hit(self, p, rect, device, clip = 0):
- a = self.properties
- llx, lly, urx, ury = a.font.TextBoundingBox(self.text, a.font_size)
- trafo = self.trafo(self.atrafo)
- trafo = trafo(Trafo(urx - llx, 0, 0, ury - lly, llx, lly))
- return device.ParallelogramHit(p, trafo, 1, 1, 1,
- ignore_outline_mode = 1)
+ a = self.properties
+ llx, lly, urx, ury = a.font.TextBoundingBox(self.text, a.font_size)
+ trafo = self.trafo(self.atrafo)
+ trafo = trafo(Trafo(urx - llx, 0, 0, ury - lly, llx, lly))
+ return device.ParallelogramHit(p, trafo, 1, 1, 1,
+ ignore_outline_mode = 1)
def GetObjectHandle(self, multiple):
- trafo = self.trafo(self.atrafo(Scale(self.properties.font_size)))
- if multiple:
- return trafo(NullPoint)
- else:
- pts = self.properties.font.TypesetText(self.text)
- return map(trafo, pts)
+ trafo = self.trafo(self.atrafo(Scale(self.properties.font_size)))
+ if multiple:
+ return trafo(NullPoint)
+ else:
+ pts = self.properties.font.TypesetText(self.text)
+ return map(trafo, pts)
def SetAlignment(self, horizontal, vertical):
- undo = (self.SetAlignment, self.halign, self.valign)
- if horizontal is not None:
- self.halign = horizontal
- if vertical is not None:
- self.valign = vertical
- self._changed()
- return undo
+ undo = (self.SetAlignment, self.halign, self.valign)
+ if horizontal is not None:
+ self.halign = horizontal
+ if vertical is not None:
+ self.valign = vertical
+ self._changed()
+ return undo
AddCmd(commands, 'AlignLeft', _("Align Left"), SetAlignment,
- args = (ALIGN_LEFT, None))
+ args = (ALIGN_LEFT, None))
AddCmd(commands, 'AlignRight', _("Align Right"), SetAlignment,
- args =(ALIGN_RIGHT,None))
+ args =(ALIGN_RIGHT,None))
AddCmd(commands, 'AlignHCenter', _("Align H. Center"), SetAlignment,
- args = (ALIGN_CENTER, None))
+ args = (ALIGN_CENTER, None))
AddCmd(commands, 'AlignTop', _("Align Top"), SetAlignment,
- args = (None, ALIGN_TOP))
+ args = (None, ALIGN_TOP))
AddCmd(commands, 'AlignVCenter', _("Align V. Center"), SetAlignment,
- args =(None, ALIGN_CENTER))
+ args =(None, ALIGN_CENTER))
AddCmd(commands, 'AlignBase', _("Align Baseline"), SetAlignment,
- args = (None, ALIGN_BASE))
+ args = (None, ALIGN_BASE))
AddCmd(commands, 'AlignBottom', _("Align Bottom"), SetAlignment,
- args = (None, ALIGN_BOTTOM))
+ args = (None, ALIGN_BOTTOM))
def Alignment(self):
- return self.halign, self.valign
+ return self.halign, self.valign
def RemoveTransformation(self):
- if self.trafo.matrix() != IdentityMatrix:
- a = self.properties
- trafo = self.trafo
- llx, lly, urx, ury = a.font.TextCoordBox(self.text, a.font_size)
- try:
- undostyle = Primitive.Transform(self, trafo.inverse())
- except SingularMatrix:
- undostyle = None
- undotrafo = self.set_transformation(Translation(trafo.offset()))
- return CreateMultiUndo(undostyle, undotrafo)
- return NullUndo
+ if self.trafo.matrix() != IdentityMatrix:
+ a = self.properties
+ trafo = self.trafo
+ llx, lly, urx, ury = a.font.TextCoordBox(self.text, a.font_size)
+ try:
+ undostyle = Primitive.Transform(self, trafo.inverse())
+ except SingularMatrix:
+ undostyle = None
+ undotrafo = self.set_transformation(Translation(trafo.offset()))
+ return CreateMultiUndo(undostyle, undotrafo)
+ return NullUndo
def DrawShape(self, device, rect = None, clip = 0):
- RectangularPrimitive.DrawShape(self, device)
+ RectangularPrimitive.DrawShape(self, device)
# Workaround for a bug in my Xserver.
text = split(self.text, '\n')[0]
- device.DrawText(self.text, self.trafo(self.atrafo), clip,
- cache = self.cache)
+ device.DrawText(self.text, self.trafo(self.atrafo), clip,
+ cache = self.cache)
def update_atrafo(self):
- a = self.properties
- llx, lly, urx, ury = a.font.TextCoordBox(self.text, a.font_size)
- hj = self.halign
- if hj == ALIGN_RIGHT:
- xoff = llx - urx
- elif hj == ALIGN_CENTER:
- xoff = (llx - urx) / 2
- else:
- xoff = 0
- vj = self.valign
- if vj == ALIGN_TOP:
- yoff = -ury
- elif vj == ALIGN_CENTER:
- yoff = (lly - ury) / 2 - lly
- elif vj == ALIGN_BOTTOM:
- yoff = -lly
- else:
- yoff = 0
- self.atrafo = Translation(xoff, yoff)
+ a = self.properties
+ llx, lly, urx, ury = a.font.TextCoordBox(self.text, a.font_size)
+ hj = self.halign
+ if hj == ALIGN_RIGHT:
+ xoff = llx - urx
+ elif hj == ALIGN_CENTER:
+ xoff = (llx - urx) / 2
+ else:
+ xoff = 0
+ vj = self.valign
+ if vj == ALIGN_TOP:
+ yoff = -ury
+ elif vj == ALIGN_CENTER:
+ yoff = (lly - ury) / 2 - lly
+ elif vj == ALIGN_BOTTOM:
+ yoff = -lly
+ else:
+ yoff = 0
+ self.atrafo = Translation(xoff, yoff)
def update_rects(self):
- trafo = self.trafo(self.atrafo)
- a = self.properties
- rect = apply(Rect, a.font.TextBoundingBox(self.text, a.font_size))
- self.bounding_rect = trafo(rect).grown(2)
- rect = apply(Rect, a.font.TextCoordBox(self.text, a.font_size))
- self.coord_rect = trafo(rect)
+ trafo = self.trafo(self.atrafo)
+ a = self.properties
+ rect = apply(Rect, a.font.TextBoundingBox(self.text, a.font_size))
+ self.bounding_rect = trafo(rect).grown(2)
+ rect = apply(Rect, a.font.TextCoordBox(self.text, a.font_size))
+ self.coord_rect = trafo(rect)
def Info(self):
return (_("Text `%(text)s' at %(position)[position]"),
@@ -392,43 +392,43 @@
return self.trafo(self.atrafo)
def SaveToFile(self, file):
- RectangularPrimitive.SaveToFile(self, file)
- file.SimpleText(self.text, self.trafo, self.halign, self.valign)
+ RectangularPrimitive.SaveToFile(self, file)
+ file.SimpleText(self.text, self.trafo, self.halign, self.valign)
def Blend(self, other, p, q):
- if self.__class__ != other.__class__ \
- or self.properties.font != other.properties.font \
- or self.text != other.text:
- raise MismatchError
- blended = self.__class__(BlendTrafo(self.trafo, other.trafo, p, q),
- self.text)
- self.set_blended_properties(blended, other, p, q)
- return blended
+ if self.__class__ != other.__class__ \
+ or self.properties.font != other.properties.font \
+ or self.text != other.text:
+ raise MismatchError
+ blended = self.__class__(BlendTrafo(self.trafo, other.trafo, p, q),
+ self.text)
+ self.set_blended_properties(blended, other, p, q)
+ return blended
def AsBezier(self):
- if self.text:
- objects = []
- base_trafo = self.trafo(self.atrafo)
- base_trafo = base_trafo(Scale(self.properties.font_size))
- pos = self.properties.font.TypesetText(self.text)
- for i in range(len(self.text)):
- paths = self.properties.font.GetOutline(self.text[i])
- if paths:
+ if self.text:
+ objects = []
+ base_trafo = self.trafo(self.atrafo)
+ base_trafo = base_trafo(Scale(self.properties.font_size))
+ pos = self.properties.font.TypesetText(self.text)
+ for i in range(len(self.text)):
+ paths = self.properties.font.GetOutline(self.text[i])
+ if paths:
obj = PolyBezier(paths = paths,
- properties = self.properties.Duplicate())
- trafo = base_trafo(Translation(pos[i]))
- obj.Transform(trafo)
- objects.append(obj)
- return Group(objects)
+ properties = self.properties.Duplicate())
+ trafo = base_trafo(Translation(pos[i]))
+ obj.Transform(trafo)
+ objects.append(obj)
+ return Group(objects)
def Paths(self):
paths = []
if self.text:
- base_trafo = self.trafo(self.atrafo)
- base_trafo = base_trafo(Scale(self.properties.font_size))
- pos = self.properties.font.TypesetText(self.text)
- for i in range(len(self.text)):
- outline = self.properties.font.GetOutline(self.text[i])
+ base_trafo = self.trafo(self.atrafo)
+ base_trafo = base_trafo(Scale(self.properties.font_size))
+ pos = self.properties.font.TypesetText(self.text)
+ for i in range(len(self.text)):
+ outline = self.properties.font.GetOutline(self.text[i])
trafo = base_trafo(Translation(pos[i]))
for path in outline:
path.Transform(trafo)
@@ -436,10 +436,10 @@
return tuple(paths)
def Editor(self):
- return SimpleTextEditor(self)
+ return SimpleTextEditor(self)
context_commands = ('AlignLeft', 'AlignRight', 'AlignHCenter', None,
- 'AlignTop', 'AlignVCenter', 'AlignBase', 'AlignBottom')
+ 'AlignTop', 'AlignVCenter', 'AlignBase', 'AlignBottom')
RegisterCommands(SimpleText)
@@ -450,24 +450,24 @@
creation_text = _("Create Text")
def __init__(self, start):
- Creator.__init__(self, start)
+ Creator.__init__(self, start)
def ButtonDown(self, p, button, state):
- Creator.DragStart(self, p)
+ Creator.DragStart(self, p)
def MouseMove(self, p, state):
- p = self.apply_constraint(p, state)
- Creator.MouseMove(self, p, state)
-
+ p = self.apply_constraint(p, state)
+ Creator.MouseMove(self, p, state)
+
def ButtonUp(self, p, button, state):
p = self.apply_constraint(p, state)
- Creator.DragStop(self, p)
+ Creator.DragStop(self, p)
def DrawDragged(self, device, partially):
- device.DrawLine(self.start, self.drag_cur)
+ device.DrawLine(self.start, self.drag_cur)
def apply_constraint(self, p, state):
- if state & const.ConstraintMask:
+ if state & const.ConstraintMask:
r, phi = (p - self.start).polar()
pi12 = pi / 12
phi = pi12 * floor(phi / pi12 + 0.5)
@@ -475,10 +475,10 @@
return p
def CreatedObject(self):
- trafo = Translation(self.start)
- r, phi = (self.drag_cur - self.start).polar()
- if r:
- trafo = trafo(Rotation(phi))
+ trafo = Translation(self.start)
+ r, phi = (self.drag_cur - self.start).polar()
+ if r:
+ trafo = trafo(Rotation(phi))
return SimpleText(trafo = trafo, properties = DefaultTextProperties())
class SimpleTextEditor(CommonTextEditor):
@@ -487,11 +487,11 @@
commands = CommonTextEditor.commands[:]
def GetHandles(self):
- a = self.properties
- pos, up = a.font.TextCaretData(self.text, self.caret, a.font_size)
- pos = self.trafo(self.atrafo(pos))
- up = self.trafo.DTransform(up)
- return [handle.MakeCaretHandle(pos, up)]
+ a = self.properties
+ pos, up = a.font.TextCaretData(self.text, self.caret, a.font_size)
+ pos = self.trafo(self.atrafo(pos))
+ up = self.trafo.DTransform(up)
+ return [handle.MakeCaretHandle(pos, up)]
def SelectPoint(self, p, rect, device, mode):
trafo = self.trafo(self.atrafo(Scale(self.properties.font_size)))
@@ -530,7 +530,7 @@
if len(lengths) < 2:
return None
for idx in range(len(lengths)):
- if lengths[idx][0] > pos:
+ if lengths[idx][0] > pos:
d2, p2 = lengths[idx]
d1, p1 = lengths[idx - 1]
if d2 != d1 and p1 != p2:
@@ -542,9 +542,9 @@
diff = (p2 - p1).normalized()
del lengths[:idx - 1]
if type == PATHTEXT_SKEW:
- return Trafo(diff.x, diff.y, 0, 1, p.x, p.y)
+ return Trafo(diff.x, diff.y, 0, 1, p.x, p.y)
else:
- return Trafo(diff.x, diff.y, -diff.y, diff.x, p.x, p.y)
+ return Trafo(diff.x, diff.y, -diff.y, diff.x, p.x, p.y)
def pathtext(path, start_pos, text, font, size, type):
@@ -555,10 +555,10 @@
pos = map(scale, pos)
trafos = []
for idx in range(len(text)):
- char = text[idx]
- width2 = metric.char_width(ord(char)) * factor
- x = pos[idx].x + width2
- trafo = coord_sys_at(lengths, x, type)
+ char = text[idx]
+ width2 = metric.char_width(ord(char)) * factor
+ x = pos[idx].x + width2
+ trafo = coord_sys_at(lengths, x, type)
if trafo is not None:
trafos.append(trafo(Translation(-width2, 0)))
else:
@@ -587,154 +587,154 @@
commands = CommonText.commands + Primitive.commands
def __init__(self, text = '', trafo = None, model = PATHTEXT_ROTATE,
- start_pos = 0.0, properties = None, duplicate = None):
- CommonText.__init__(self, text, duplicate = duplicate)
- Primitive.__init__(self, properties = properties,
- duplicate = duplicate)
- if duplicate is not None and isinstance(duplicate, self.__class__):
- # dont copy paths, update it from parent
- self.trafo = duplicate.trafo
- self.model = duplicate.model
- self.start_pos = duplicate.start_pos
- else:
- if trafo is None:
- self.trafo = Identity
- else:
- self.trafo = trafo
- self.model = model
- self.start_pos = start_pos
- self.cache = {}
+ start_pos = 0.0, properties = None, duplicate = None):
+ CommonText.__init__(self, text, duplicate = duplicate)
+ Primitive.__init__(self, properties = properties,
+ duplicate = duplicate)
+ if duplicate is not None and isinstance(duplicate, self.__class__):
+ # dont copy paths, update it from parent
+ self.trafo = duplicate.trafo
+ self.model = duplicate.model
+ self.start_pos = duplicate.start_pos
+ else:
+ if trafo is None:
+ self.trafo = Identity
+ else:
+ self.trafo = trafo
+ self.model = model
+ self.start_pos = start_pos
+ self.cache = {}
def update_rects(self):
- a = self.properties
- length = len(self.trafos)
- sizes = [a.font_size] * length
+ a = self.properties
+ length = len(self.trafos)
+ sizes = [a.font_size] * length
boxes = map(a.font.TextBoundingBox, self.text[:length], sizes)
- rects = map(lambda *a:a, map(apply, [Rect] * length, boxes))
- self.bounding_rect = reduce(UnionRects, map(apply, self.trafos, rects),
- EmptyRect)
+ rects = map(lambda *a:a, map(apply, [Rect] * length, boxes))
+ self.bounding_rect = reduce(UnionRects, map(apply, self.trafos, rects),
+ EmptyRect)
boxes = map(a.font.TextCoordBox, self.text[:length], sizes)
- rects = map(lambda *a:a, map(apply, [Rect] * length, boxes))
- self.coord_rect = reduce(UnionRects, map(apply, self.trafos, rects),
- EmptyRect)
+ rects = map(lambda *a:a, map(apply, [Rect] * length, boxes))
+ self.coord_rect = reduce(UnionRects, map(apply, self.trafos, rects),
+ EmptyRect)
def update_trafos(self):
- self.trafos = map(self.trafo, pathtext(self.paths[0], self.start_pos,
- self.text, self.properties.font,
- self.properties.font_size,
- self.model))
+ self.trafos = map(self.trafo, pathtext(self.paths[0], self.start_pos,
+ self.text, self.properties.font,
+ self.properties.font_size,
+ self.model))
def update_paths(self):
- paths = self.parent.get_paths()
- try:
- itrafo = self.trafo.inverse()
- transformed = []
- for path in paths:
- path = path.Duplicate()
- path.Transform(itrafo)
- transformed.append(path)
- paths = tuple(transformed)
- except SingularMatrix:
- # XXX what do we do?
- pass
- self.paths = paths
+ paths = self.parent.get_paths()
+ try:
+ itrafo = self.trafo.inverse()
+ transformed = []
+ for path in paths:
+ path = path.Duplicate()
+ path.Transform(itrafo)
+ transformed.append(path)
+ paths = tuple(transformed)
+ except SingularMatrix:
+ # XXX what do we do?
+ pass
+ self.paths = paths
def SetText(self, text, caret = None):
- self.cache = {}
- return CommonText.SetText(self, text, caret)
+ self.cache = {}
+ return CommonText.SetText(self, text, caret)
def PathChanged(self):
- self.del_lazy_attrs()
+ self.del_lazy_attrs()
def SetModel(self, model):
- undo = (self.SetModel, self.model)
- self.model = model
- self._changed()
- return undo
+ undo = (self.SetModel, self.model)
+ self.model = model
+ self._changed()
+ return undo
def Model(self):
- return self.model
+ return self.model
def SetStartPos(self, start_pos):
- undo = (self.SetStartPos, self.start_pos)
- self.start_pos = start_pos
- self._changed()
- return undo
+ undo = (self.SetStartPos, self.start_pos)
+ self.start_pos = start_pos
+ self._changed()
+ return undo
def StartPos(self):
- return self.start_pos
+ return self.start_pos
def CharacterTransformations(self):
return self.trafos
def DrawShape(self, device, rect = None, clip = 0):
- text = self.text; trafos = self.trafos
- font = self.properties.font; font_size = self.properties.font_size
+ text = self.text; trafos = self.trafos
+ font = self.properties.font; font_size = self.properties.font_size
- Primitive.DrawShape(self, device)
- device.BeginComplexText(clip, self.cache)
- for idx in range(len(trafos)):
+ Primitive.DrawShape(self, device)
+ device.BeginComplexText(clip, self.cache)
+ for idx in range(len(trafos)):
char = text[idx]
if char not in '\r\n': # avoid control chars
device.DrawComplexText(text[idx], trafos[idx], font, font_size)
- device.EndComplexText()
+ device.EndComplexText()
def Disconnect(self):
- self.cache = {}
- Primitive.Disconnect(self)
+ self.cache = {}
+ Primitive.Disconnect(self)
def Hit(self, p, rect, device, clip = 0):
- bbox = self.properties.font.TextBoundingBox
- font_size = self.properties.font_size
- text = self.text; trafos = self.trafos
+ bbox = self.properties.font.TextBoundingBox
+ font_size = self.properties.font_size
+ text = self.text; trafos = self.trafos
- for idx in range(len(trafos)):
- llx, lly, urx, ury = bbox(text[idx], font_size)
- trafo = trafos[idx](Trafo(urx - llx, 0, 0, ury - lly, llx, lly))
- if device.ParallelogramHit(p, trafo, 1, 1, 1,
- ignore_outline_mode = 1):
- return 1
- return 0
+ for idx in range(len(trafos)):
+ llx, lly, urx, ury = bbox(text[idx], font_size)
+ trafo = trafos[idx](Trafo(urx - llx, 0, 0, ury - lly, llx, lly))
+ if device.ParallelogramHit(p, trafo, 1, 1, 1,
+ ignore_outline_mode = 1):
+ return 1
+ return 0
def Translate(self, offset):
- return NullUndo
+ return NullUndo
def Transform(self, trafo):
- return self.set_transformation(trafo(self.trafo))
+ return self.set_transformation(trafo(self.trafo))
def set_transformation(self, trafo):
- undo = (self.set_transformation, self.trafo)
- self.trafo = trafo
- self._changed()
- return undo
+ undo = (self.set_transformation, self.trafo)
+ self.trafo = trafo
+ self._changed()
+ return undo
def RemoveTransformation(self):
- return self.set_transformation(Identity)
+ return self.set_transformation(Identity)
def Blend(self, other, p, q):
- if self.__class__ != other.__class__ \
- or self.properties.font != other.properties.font \
- or self.text != other.text:
- raise MismatchError
+ if self.__class__ != other.__class__ \
+ or self.properties.font != other.properties.font \
+ or self.text != other.text:
+ raise MismatchError
trafo = BlendTrafo(self.trafo, other.trafo, p, q)
start_pos = p * self.start_pos + q * other.start_pos
- blended = self.__class__(self.text, trafo = trafo,
+ blended = self.__class__(self.text, trafo = trafo,
start_pos = start_pos, model = self.model)
- self.set_blended_properties(blended, other, p, q)
- return blended
+ self.set_blended_properties(blended, other, p, q)
+ return blended
def SaveToFile(self, file):
- Primitive.SaveToFile(self, file)
- file.InternalPathText(self.text, self.trafo, self.model,
+ Primitive.SaveToFile(self, file)
+ file.InternalPathText(self.text, self.trafo, self.model,
self.start_pos)
def Info(self):
- return _("Text on Path: `%(text)s'") % {'text':self.text[:10]}
+ return _("Text on Path: `%(text)s'") % {'text':self.text[:10]}
def Editor(self):
- return InternalPathTextEditor(self)
+ return InternalPathTextEditor(self)
class InternalPathTextEditor(CommonTextEditor):
@@ -742,31 +742,31 @@
commands = CommonTextEditor.commands
def GetHandles(self):
- a = self.properties
- if self.caret > 0 and self.trafos:
+ a = self.properties
+ if self.caret > 0 and self.trafos:
# special case to deal with here: the characters that fall
# off the end of the path are not visible. If the caret is
# in this invisible area, display the caret after the last
# visible character
- caret = 1
+ caret = 1
index = min(self.caret, len(self.text), len(self.trafos)) - 1
text = self.text[index]
- trafo = self.trafos[index]
- else:
- caret = 0
- if self.text and self.trafos:
- text = self.text[0]
- trafo = self.trafos[0]
- else:
- # XXX fix this
+ trafo = self.trafos[index]
+ else:
+ caret = 0
+ if self.text and self.trafos:
+ text = self.text[0]
+ trafo = self.trafos[0]
+ else:
+ # XXX fix this
self.start_point = self.paths[0].point_at(self.start_pos)
- return [handle.MakeNodeHandle(self.start_point, 1)]
- pos, up = a.font.TextCaretData(text, caret, a.font_size)
- pos = trafo(pos)
- up = trafo.DTransform(up)
+ return [handle.MakeNodeHandle(self.start_point, 1)]
+ pos, up = a.font.TextCaretData(text, caret, a.font_size)
+ pos = trafo(pos)
+ up = trafo.DTransform(up)
self.start_point = self.trafos[0].offset()
- return [handle.MakeCaretHandle(pos, up),
- handle.MakeNodeHandle(self.start_point, 1)]
+ return [handle.MakeCaretHandle(pos, up),
+ handle.MakeNodeHandle(self.start_point, 1)]
selection = None
def SelectHandle(self, handle, mode = const.SelectSet):
@@ -777,7 +777,7 @@
dists = []
for i in range(len(self.trafos)):
dists.append((abs(p - self.trafos[i].offset()), i))
-
+
char = self.text[len(self.trafos) - 1]
width = self.properties.font.metric.char_width(ord(char)) / 1000.0
pos = self.trafos[-1](width * self.properties.font_size, 0)
@@ -800,7 +800,7 @@
def DrawDragged(self, device, partially):
text = self.text; trafos = self.trafos
- font = self.properties.font; font_size = self.properties.font_size
+ font = self.properties.font; font_size = self.properties.font_size
t = self.nearest_start_pos(self.drag_cur)
trafos = map(self.trafo, pathtext(self.paths[0], t, text, font,
font_size, self.model))
@@ -828,55 +828,55 @@
commands = Compound.commands[:]
def __init__(self, text = None, path = None, model = PATHTEXT_ROTATE,
- start_pos = 0.0, duplicate = None, _blended_text = None):
- if duplicate is not None:
- Compound.__init__(self, duplicate = duplicate)
- self.text = self.objects[0]
- self.path = self.objects[1]
- else:
+ start_pos = 0.0, duplicate = None, _blended_text = None):
+ if duplicate is not None:
+ Compound.__init__(self, duplicate = duplicate)
+ self.text = self.objects[0]
+ self.path = self.objects[1]
+ else:
if _blended_text is not None:
self.text = _blended_text
self.path = path
Compound.__init__(self, [self.text, self.path])
elif text is not None:
- self.text = InternalPathText(text.Text(),
+ self.text = InternalPathText(text.Text(),
start_pos = start_pos,
model = model,
duplicate = text)
- self.path = path
- Compound.__init__(self, [self.text, self.path])
- else:
- # we're being loaded
- self.text = self.path = None
- Compound.__init__(self)
+ self.path = path
+ Compound.__init__(self, [self.text, self.path])
+ else:
+ # we're being loaded
+ self.text = self.path = None
+ Compound.__init__(self)
def ChildChanged(self, child):
if self.document is not None:
self.document.AddClearRect(self.bounding_rect)
- Compound.ChildChanged(self, child)
- if child is self.path:
- self.text.PathChanged()
+ Compound.ChildChanged(self, child)
+ if child is self.path:
+ self.text.PathChanged()
if self.document is not None:
self.document.AddClearRect(self.bounding_rect)
def load_AppendObject(self, object):
- Compound.load_AppendObject(self, object)
- if len(self.objects) == 2:
- self.text, self.path = self.objects
+ Compound.load_AppendObject(self, object)
+ if len(self.objects) == 2:
+ self.text, self.path = self.objects
def SelectSubobject(self, p, rect, device, path = None, *rest):
- idx = self.Hit(p, rect, device) - 1
- obj = self.objects[idx]
- if path:
- path_idx = path[0]
- path = path[1:]
- if path_idx == idx:
- obj = obj.SelectSubobject(p, rect, device, path)
- elif path == ():
- obj = obj.SelectSubobject(p, rect, device)
- else:
- return self
- return selinfo.prepend_idx(idx, obj)
+ idx = self.Hit(p, rect, device) - 1
+ obj = self.objects[idx]
+ if path:
+ path_idx = path[0]
+ path = path[1:]
+ if path_idx == idx:
+ obj = obj.SelectSubobject(p, rect, device, path)
+ elif path == ():
+ obj = obj.SelectSubobject(p, rect, device)
+ else:
+ return self
+ return selinfo.prepend_idx(idx, obj)
def ReplaceChild(self, child, object):
if child is self.path and object.is_curve:
@@ -892,64 +892,64 @@
raise SketchError('Cannot replace child')
def Info(self):
- return _("Path Text: `%(text)s'") % {'text':self.text.Text()[:10]}
+ return _("Path Text: `%(text)s'") % {'text':self.text.Text()[:10]}
def SaveToFile(self, file):
- file.BeginPathText()
- self.text.SaveToFile(file)
- self.path.SaveToFile(file)
- file.EndPathText()
+ file.BeginPathText()
+ self.text.SaveToFile(file)
+ self.path.SaveToFile(file)
+ file.EndPathText()
def SelectTextObject(self):
- self.document.SelectObject(self.text)
+ self.document.SelectObject(self.text)
AddCmd(commands, SelectTextObject, _("Select Text"), key_stroke = 't')
def SelectPathObject(self):
- self.document.SelectObject(self.path)
+ self.document.SelectObject(self.path)
AddCmd(commands, SelectPathObject, _("Select Path"), key_stroke = 'p')
def get_paths(self):
return self.path.Paths()
def SetModel(self, model):
- return self.text.SetModel(model)
+ return self.text.SetModel(model)
AddCmd(commands, 'SetModelRotate', _("Rotate Letters"), SetModel,
- args = PATHTEXT_ROTATE)
+ args = PATHTEXT_ROTATE)
AddCmd(commands, 'SetModelSkew', _("Skew Letters"), SetModel,
- args = PATHTEXT_SKEW)
+ args = PATHTEXT_SKEW)
def Model(self):
- return self.text.Model()
+ return self.text.Model()
def Blend(self, other, p, q):
if self.__class__ != other.__class__:
- raise MismatchError
+ raise MismatchError
return self.__class__(_blended_text = Blend(self.text,other.text, p,q),
path = Blend(self.path, other.path, p, q))
context_commands = ('SelectTextObject', 'SelectPathObject', None,
- 'SetModelRotate', 'SetModelSkew')
+ 'SetModelRotate', 'SetModelSkew')
RegisterCommands(PathText)
def CanCreatePathText(objects):
if len(objects) == 2:
- if objects[0].is_Text:
- return objects[1].is_curve
- elif objects[0].is_curve:
- return objects[1].is_Text
+ if objects[0].is_Text:
+ return objects[1].is_curve
+ elif objects[0].is_curve:
+ return objects[1].is_Text
def CreatePathText(objects):
if len(objects) == 2:
- if objects[0].is_Text:
- text, curve = objects
- elif objects[1].is_Text:
- curve, text = objects
+ if objects[0].is_Text:
+ text, curve = objects
+ elif objects[1].is_Text:
+ curve, text = objects
if not curve.is_curve:
- # XXX what do we do here?
- return text
- return PathText(text, curve)
+ # XXX what do we do here?
+ return text
+ return PathText(text, curve)
More information about the Skencil-commits
mailing list