BodyBalanceEvaluation/backend/venv/Lib/site-packages/reportlab/graphics/widgets/adjustableArrow.py
2025-07-31 17:23:05 +08:00

127 lines
3.8 KiB
Python

from reportlab.lib import colors
from reportlab.lib.validators import *
from reportlab.lib.attrmap import *
from reportlab.graphics.shapes import Drawing, _DrawingEditorMixin, Group, Polygon
from reportlab.graphics.widgetbase import Widget
class AdjustableArrow(Widget):
"""This widget draws an arrow (style one).
possible attributes:
'x', 'y', 'size', 'fillColor'
"""
_attrMap = AttrMap(
x = AttrMapValue(isNumber,desc='symbol x coordinate'),
y = AttrMapValue(isNumber,desc='symbol y coordinate'),
dx = AttrMapValue(isNumber,desc='symbol x coordinate adjustment'),
dy = AttrMapValue(isNumber,desc='symbol x coordinate adjustment'),
stemThickness = AttrMapValue(isNumber, 'width of the stem'),
stemLength = AttrMapValue(isNumber, 'length of the stem'),
headProjection = AttrMapValue(isNumber, 'how much the head projects from the stem'),
headLength = AttrMapValue(isNumber, 'length of the head'),
headSweep = AttrMapValue(isNumber, 'howmuch the head sweeps back (-ve) or forwards (+ve)'),
scale = AttrMapValue(isNumber, 'scaling factor'),
fillColor = AttrMapValue(isColorOrNone),
strokeColor = AttrMapValue(isColorOrNone),
strokeWidth = AttrMapValue(isNumber),
boxAnchor = AttrMapValue(isBoxAnchor,desc='anchoring point of the label'),
right =AttrMapValue(isBoolean,desc='If True (default) the arrow is horizontal pointing right\nFalse means it points up'),
angle = AttrMapValue(isNumber, desc='angle of arrow default (0), right True 0 is horizontal to right else vertical up'),
)
def __init__(self,**kwds):
self._setKeywords(**kwds)
self._setKeywords(**dict(
x = 0,
y = 0,
fillColor = colors.red,
strokeWidth = 0,
strokeColor = None,
boxAnchor = 'c',
angle = 0,
stemThickness = 33,
stemLength = 50,
headProjection = 15,
headLength = 50,
headSweep = 0,
scale = 1.,
right=True,
))
def draw(self):
# general widget bits
g = Group()
x = self.x
y = self.y
scale = self.scale
stemThickness = self.stemThickness*scale
stemLength = self.stemLength*scale
headProjection = self.headProjection*scale
headLength = self.headLength*scale
headSweep = self.headSweep*scale
w = stemLength+headLength
h = 2*headProjection+stemThickness
# shift to the boxAnchor
boxAnchor = self.boxAnchor
if self.right:
if boxAnchor in ('sw','w','nw'):
dy = -h
elif boxAnchor in ('s','c','n'):
dy = -h*0.5
else:
dy = 0
if boxAnchor in ('w','c','e'):
dx = -w*0.5
elif boxAnchor in ('nw','n','ne'):
dx = -w
else:
dx = 0
points = [
dx, dy+headProjection+stemThickness,
dx+stemLength, dy+headProjection+stemThickness,
dx+stemLength+headSweep, dy+2*headProjection+stemThickness,
dx+stemLength+headLength, dy+0.5*stemThickness+headProjection,
dx+stemLength+headSweep, dy,
dx+stemLength, dy+headProjection,
dx, dy+headProjection,
]
else:
w,h = h,w
if boxAnchor in ('nw','n','ne'):
dy = -h
elif boxAnchor in ('w','c','e'):
dy = -h*0.5
else:
dy = 0
if boxAnchor in ('ne','e','se'):
dx = -w
elif boxAnchor in ('n','c','s'):
dx = -w*0.5
else:
dx = 0
points = [
dx+headProjection, dy, #sw
dx+headProjection+stemThickness, dy, #se
dx+headProjection+stemThickness, dy+stemLength,
dx+w, dy+stemLength+headSweep,
dx+headProjection+0.5*stemThickness, dy+h,
dx, dy+stemLength+headSweep,
dx+headProjection, dy+stemLength,
]
g.add(Polygon(
points = points,
fillColor = self.fillColor,
strokeColor = self.strokeColor,
strokeWidth = self.strokeWidth,
))
g.translate(x,y)
g.rotate(self.angle)
return g
class AdjustableArrowDrawing(_DrawingEditorMixin,Drawing):
def __init__(self,width=100,height=63,*args,**kw):
Drawing.__init__(self,width,height,*args,**kw)
self._add(self,AdjustableArrow(),name='adjustableArrow',validate=None,desc=None)