📄 _composit.py
字号:
# -*- coding: iso-8859-1 -*-
#----------------------------------------------------------------------------
# Name: composit.py
# Purpose: Composite class
#
# Author: Pierre Hj鋖m (from C++ original by Julian Smart)
#
# Created: 2004-05-08
# RCS-ID: $Id: _composit.py,v 1.5 2006/02/03 06:51:34 RD Exp $
# Copyright: (c) 2004 Pierre Hj鋖m - 1998 Julian Smart
# Licence: wxWindows license
#----------------------------------------------------------------------------
import sys
import wx
from _basic import RectangleShape, Shape, ControlPoint
from _oglmisc import *
KEY_SHIFT, KEY_CTRL = 1, 2
_objectStartX = 0.0
_objectStartY = 0.0
CONSTRAINT_CENTRED_VERTICALLY = 1
CONSTRAINT_CENTRED_HORIZONTALLY = 2
CONSTRAINT_CENTRED_BOTH = 3
CONSTRAINT_LEFT_OF = 4
CONSTRAINT_RIGHT_OF = 5
CONSTRAINT_ABOVE = 6
CONSTRAINT_BELOW = 7
CONSTRAINT_ALIGNED_TOP = 8
CONSTRAINT_ALIGNED_BOTTOM = 9
CONSTRAINT_ALIGNED_LEFT = 10
CONSTRAINT_ALIGNED_RIGHT = 11
# Like aligned, but with the objects centred on the respective edge
# of the reference object.
CONSTRAINT_MIDALIGNED_TOP = 12
CONSTRAINT_MIDALIGNED_BOTTOM = 13
CONSTRAINT_MIDALIGNED_LEFT = 14
CONSTRAINT_MIDALIGNED_RIGHT = 15
# Backwards compatibility names. These should be removed eventually.
gyCONSTRAINT_CENTRED_VERTICALLY = CONSTRAINT_CENTRED_VERTICALLY
gyCONSTRAINT_CENTRED_HORIZONTALLY = CONSTRAINT_CENTRED_HORIZONTALLY
gyCONSTRAINT_CENTRED_BOTH = CONSTRAINT_CENTRED_BOTH
gyCONSTRAINT_LEFT_OF = CONSTRAINT_LEFT_OF
gyCONSTRAINT_RIGHT_OF = CONSTRAINT_RIGHT_OF
gyCONSTRAINT_ABOVE = CONSTRAINT_ABOVE
gyCONSTRAINT_BELOW = CONSTRAINT_BELOW
gyCONSTRAINT_ALIGNED_TOP = CONSTRAINT_ALIGNED_TOP
gyCONSTRAINT_ALIGNED_BOTTOM = CONSTRAINT_ALIGNED_BOTTOM
gyCONSTRAINT_ALIGNED_LEFT = CONSTRAINT_ALIGNED_LEFT
gyCONSTRAINT_ALIGNED_RIGHT = CONSTRAINT_ALIGNED_RIGHT
gyCONSTRAINT_MIDALIGNED_TOP = CONSTRAINT_MIDALIGNED_TOP
gyCONSTRAINT_MIDALIGNED_BOTTOM = CONSTRAINT_MIDALIGNED_BOTTOM
gyCONSTRAINT_MIDALIGNED_LEFT = CONSTRAINT_MIDALIGNED_LEFT
gyCONSTRAINT_MIDALIGNED_RIGHT = CONSTRAINT_MIDALIGNED_RIGHT
class ConstraintType(object):
def __init__(self, theType, theName, thePhrase):
self._type = theType
self._name = theName
self._phrase = thePhrase
ConstraintTypes = [
[CONSTRAINT_CENTRED_VERTICALLY,
ConstraintType(CONSTRAINT_CENTRED_VERTICALLY, "Centre vertically", "centred vertically w.r.t.")],
[CONSTRAINT_CENTRED_HORIZONTALLY,
ConstraintType(CONSTRAINT_CENTRED_HORIZONTALLY, "Centre horizontally", "centred horizontally w.r.t.")],
[CONSTRAINT_CENTRED_BOTH,
ConstraintType(CONSTRAINT_CENTRED_BOTH, "Centre", "centred w.r.t.")],
[CONSTRAINT_LEFT_OF,
ConstraintType(CONSTRAINT_LEFT_OF, "Left of", "left of")],
[CONSTRAINT_RIGHT_OF,
ConstraintType(CONSTRAINT_RIGHT_OF, "Right of", "right of")],
[CONSTRAINT_ABOVE,
ConstraintType(CONSTRAINT_ABOVE, "Above", "above")],
[CONSTRAINT_BELOW,
ConstraintType(CONSTRAINT_BELOW, "Below", "below")],
# Alignment
[CONSTRAINT_ALIGNED_TOP,
ConstraintType(CONSTRAINT_ALIGNED_TOP, "Top-aligned", "aligned to the top of")],
[CONSTRAINT_ALIGNED_BOTTOM,
ConstraintType(CONSTRAINT_ALIGNED_BOTTOM, "Bottom-aligned", "aligned to the bottom of")],
[CONSTRAINT_ALIGNED_LEFT,
ConstraintType(CONSTRAINT_ALIGNED_LEFT, "Left-aligned", "aligned to the left of")],
[CONSTRAINT_ALIGNED_RIGHT,
ConstraintType(CONSTRAINT_ALIGNED_RIGHT, "Right-aligned", "aligned to the right of")],
# Mid-alignment
[CONSTRAINT_MIDALIGNED_TOP,
ConstraintType(CONSTRAINT_MIDALIGNED_TOP, "Top-midaligned", "centred on the top of")],
[CONSTRAINT_MIDALIGNED_BOTTOM,
ConstraintType(CONSTRAINT_MIDALIGNED_BOTTOM, "Bottom-midaligned", "centred on the bottom of")],
[CONSTRAINT_MIDALIGNED_LEFT,
ConstraintType(CONSTRAINT_MIDALIGNED_LEFT, "Left-midaligned", "centred on the left of")],
[CONSTRAINT_MIDALIGNED_RIGHT,
ConstraintType(CONSTRAINT_MIDALIGNED_RIGHT, "Right-midaligned", "centred on the right of")]
]
class Constraint(object):
"""A Constraint object helps specify how child shapes are laid out with
respect to siblings and parents.
Derived from:
wxObject
"""
def __init__(self, type, constraining, constrained):
self._xSpacing = 0.0
self._ySpacing = 0.0
self._constraintType = type
self._constrainingObject = constraining
self._constraintId = 0
self._constraintName = "noname"
self._constrainedObjects = constrained[:]
def __repr__(self):
return "<%s.%s>" % (self.__class__.__module__, self.__class__.__name__)
def SetSpacing(self, x, y):
"""Sets the horizontal and vertical spacing for the constraint."""
self._xSpacing = x
self._ySpacing = y
def Equals(self, a, b):
"""Return TRUE if x and y are approximately equal (for the purposes
of evaluating the constraint).
"""
marg = 0.5
return b <= a + marg and b >= a - marg
def Evaluate(self):
"""Evaluate this constraint and return TRUE if anything changed."""
maxWidth, maxHeight = self._constrainingObject.GetBoundingBoxMax()
minWidth, minHeight = self._constrainingObject.GetBoundingBoxMin()
x = self._constrainingObject.GetX()
y = self._constrainingObject.GetY()
dc = wx.ClientDC(self._constrainingObject.GetCanvas())
self._constrainingObject.GetCanvas().PrepareDC(dc)
if self._constraintType == CONSTRAINT_CENTRED_VERTICALLY:
n = len(self._constrainedObjects)
totalObjectHeight = 0.0
for constrainedObject in self._constrainedObjects:
width2, height2 = constrainedObject.GetBoundingBoxMax()
totalObjectHeight += height2
# Check if within the constraining object...
if totalObjectHeight + (n + 1) * self._ySpacing <= minHeight:
spacingY = (minHeight - totalObjectHeight) / (n + 1.0)
startY = y - minHeight / 2.0
else: # Otherwise, use default spacing
spacingY = self._ySpacing
startY = y - (totalObjectHeight + (n + 1) * spacingY) / 2.0
# Now position the objects
changed = False
for constrainedObject in self._constrainedObjects:
width2, height2 = constrainedObject.GetBoundingBoxMax()
startY += spacingY + height2 / 2.0
if not self.Equals(startY, constrainedObject.GetY()):
constrainedObject.Move(dc, constrainedObject.GetX(), startY, False)
changed = True
startY += height2 / 2.0
return changed
elif self._constraintType == CONSTRAINT_CENTRED_HORIZONTALLY:
n = len(self._constrainedObjects)
totalObjectWidth = 0.0
for constrainedObject in self._constrainedObjects:
width2, height2 = constrainedObject.GetBoundingBoxMax()
totalObjectWidth += width2
# Check if within the constraining object...
if totalObjectWidth + (n + 1) * self._xSpacing <= minWidth:
spacingX = (minWidth - totalObjectWidth) / (n + 1.0)
startX = x - minWidth / 2.0
else: # Otherwise, use default spacing
spacingX = self._xSpacing
startX = x - (totalObjectWidth + (n + 1) * spacingX) / 2.0
# Now position the objects
changed = False
for constrainedObject in self._constrainedObjects:
width2, height2 = constrainedObject.GetBoundingBoxMax()
startX += spacingX + width2 / 2.0
if not self.Equals(startX, constrainedObject.GetX()):
constrainedObject.Move(dc, startX, constrainedObject.GetY(), False)
changed = True
startX += width2 / 2.0
return changed
elif self._constraintType == CONSTRAINT_CENTRED_BOTH:
n = len(self._constrainedObjects)
totalObjectWidth = 0.0
totalObjectHeight = 0.0
for constrainedObject in self._constrainedObjects:
width2, height2 = constrainedObject.GetBoundingBoxMax()
totalObjectWidth += width2
totalObjectHeight += height2
# Check if within the constraining object...
if totalObjectHeight + (n + 1) * self._xSpacing <= minWidth:
spacingX = (minWidth - totalObjectWidth) / (n + 1.0)
startX = x - minWidth / 2.0
else: # Otherwise, use default spacing
spacingX = self._xSpacing
startX = x - (totalObjectWidth + (n + 1) * spacingX) / 2.0
# Check if within the constraining object...
if totalObjectHeight + (n + 1) * self._ySpacing <= minHeight:
spacingY = (minHeight - totalObjectHeight) / (n + 1.0)
startY = y - minHeight / 2.0
else: # Otherwise, use default spacing
spacingY = self._ySpacing
startY = y - (totalObjectHeight + (n + 1) * spacingY) / 2.0
# Now position the objects
changed = False
for constrainedObject in self._constrainedObjects:
width2, height2 = constrainedObject.GetBoundingBoxMax()
startX += spacingX + width2 / 2.0
startY += spacingY + height2 / 2.0
if not self.Equals(startX, constrainedObject.GetX()) or not self.Equals(startY, constrainedObject.GetY()):
constrainedObject.Move(dc, startX, startY, False)
changed = True
startX += width2 / 2.0
startY += height2 / 2.0
return changed
elif self._constraintType == CONSTRAINT_LEFT_OF:
changed = False
for constrainedObject in self._constrainedObjects:
width2, height2 = constrainedObject.GetBoundingBoxMax()
x3 = x - minWidth / 2.0 - width2 / 2.0 - self._xSpacing
if not self.Equals(x3, constrainedObject.GetX()):
changed = True
constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
return changed
elif self._constraintType == CONSTRAINT_RIGHT_OF:
changed = False
for constrainedObject in self._constrainedObjects:
width2, height2 = constrainedObject.GetBoundingBoxMax()
x3 = x + minWidth / 2.0 + width2 / 2.0 + self._xSpacing
if not self.Equals(x3, constrainedObject.GetX()):
constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
changed = True
return changed
elif self._constraintType == CONSTRAINT_ABOVE:
changed = False
for constrainedObject in self._constrainedObjects:
width2, height2 = constrainedObject.GetBoundingBoxMax()
y3 = y - minHeight / 2.0 - height2 / 2.0 - self._ySpacing
if not self.Equals(y3, constrainedObject.GetY()):
changed = True
constrainedObject.Move(dc, constrainedObject.GetX(), y3, False)
return changed
elif self._constraintType == CONSTRAINT_BELOW:
changed = False
for constrainedObject in self._constrainedObjects:
width2, height2 = constrainedObject.GetBoundingBoxMax()
y3 = y + minHeight / 2.0 + height2 / 2.0 + self._ySpacing
if not self.Equals(y3, constrainedObject.GetY()):
changed = True
constrainedObject.Move(dc, constrainedObject.GetX(), y3, False)
return changed
elif self._constraintType == CONSTRAINT_ALIGNED_LEFT:
changed = False
for constrainedObject in self._constrainedObjects:
width2, height2 = constrainedObject.GetBoundingBoxMax()
x3 = x - minWidth / 2.0 + width2 / 2.0 + self._xSpacing
if not self.Equals(x3, constrainedObject.GetX()):
changed = True
constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
return changed
elif self._constraintType == CONSTRAINT_ALIGNED_RIGHT:
changed = False
for constrainedObject in self._constrainedObjects:
width2, height2 = constrainedObject.GetBoundingBoxMax()
x3 = x + minWidth / 2.0 - width2 / 2.0 - self._xSpacing
if not self.Equals(x3, constrainedObject.GetX()):
changed = True
constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
return changed
elif self._constraintType == CONSTRAINT_ALIGNED_TOP:
changed = False
for constrainedObject in self._constrainedObjects:
width2, height2 = constrainedObject.GetBoundingBoxMax()
y3 = y - minHeight / 2.0 + height2 / 2.0 + self._ySpacing
if not self.Equals(y3, constrainedObject.GetY()):
changed = True
constrainedObject.Move(dc, constrainedObject.GetX(), y3, False)
return changed
elif self._constraintType == CONSTRAINT_ALIGNED_BOTTOM:
changed = False
for constrainedObject in self._constrainedObjects:
width2, height2 = constrainedObject.GetBoundingBoxMax()
y3 = y + minHeight / 2.0 - height2 / 2.0 - self._ySpacing
if not self.Equals(y3, constrainedObject.GetY()):
changed = True
constrainedObject.Move(dc, constrainedObject.GetX(), y3, False)
return changed
elif self._constraintType == CONSTRAINT_MIDALIGNED_LEFT:
changed = False
for constrainedObject in self._constrainedObjects:
x3 = x - minWidth / 2.0
if not self.Equals(x3, constrainedObject.GetX()):
changed = True
constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
return changed
elif self._constraintType == CONSTRAINT_MIDALIGNED_RIGHT:
changed = False
for constrainedObject in self._constrainedObjects:
x3 = x + minWidth / 2.0
if not self.Equals(x3, constrainedObject.GetX()):
changed = True
constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
return changed
elif self._constraintType == CONSTRAINT_MIDALIGNED_TOP:
changed = False
for constrainedObject in self._constrainedObjects:
y3 = y - minHeight / 2.0
if not self.Equals(y3, constrainedObject.GetY()):
changed = True
constrainedObject.Move(dc, constrainedObject.GetX(), y3, False)
return changed
elif self._constraintType == CONSTRAINT_MIDALIGNED_BOTTOM:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -