Switch text anchor when line crosses center of view

This commit is contained in:
Luke Campagnola 2016-02-28 20:52:07 -08:00
parent ac14139c2d
commit bb97f2e98d
2 changed files with 36 additions and 17 deletions

View File

@ -310,20 +310,38 @@ class InfLineLabel(TextItem):
movable Bool; if True, then the label can be dragged along the line.
position Relative position (0.0-1.0) within the view to position the label
along the line.
anchors List of (x,y) pairs giving the text anchor positions that should
be used when the line is moved to one side of the view or the
other. This allows text to switch to the opposite side of the line
as it approaches the edge of the view.
=============== ==================================================================
All extra keyword arguments are passed to TextItem. A particularly useful
option here is to use `rotateAxis=(1, 0)`, which will cause the text to
be automatically rotated parallel to the line.
"""
def __init__(self, line, text="", movable=False, position=0.5, **kwds):
def __init__(self, line, text="", movable=False, position=0.5, anchors=None, **kwds):
self.line = line
self.movable = movable
self.orthoPos = position # text will always be placed on the line at a position relative to view bounds
self.format = text
self.line.sigPositionChanged.connect(self.valueChanged)
self._endpoints = (None, None)
self.anchors = [(0, 0), (1, 0)]
if anchors is None:
# automatically pick sensible anchors
rax = kwds.get('rotateAxis', None)
if rax is not None:
if tuple(rax) == (1,0):
anchors = [(0.5, 0), (0.5, 1)]
else:
anchors = [(0, 0.5), (1, 0.5)]
else:
if line.angle % 180 == 0:
anchors = [(0.5, 0), (0.5, 1)]
else:
anchors = [(0, 0.5), (1, 0.5)]
self.anchors = anchors
TextItem.__init__(self, **kwds)
self.setParentItem(line)
self.valueChanged()
@ -372,6 +390,11 @@ class InfLineLabel(TextItem):
pt = pt2 * self.orthoPos + pt1 * (1-self.orthoPos)
self.setPos(pt)
# update anchor to keep text visible as it nears the view box edge
vr = self.line.viewRect()
if vr is not None:
self.setAnchor(self.anchors[0 if vr.center().y() < 0 else 1])
def setVisible(self, v):
TextItem.setVisible(self, v)
if v:

View File

@ -56,7 +56,6 @@ class TextItem(GraphicsObject):
self.fill = fn.mkBrush(fill)
self.border = fn.mkPen(border)
self.setAngle(angle)
#self.textItem.setFlag(self.ItemIgnoresTransformations) ## This is required to keep the text unscaled inside the viewport
def setText(self, text, color=(200,200,200)):
"""
@ -67,14 +66,7 @@ class TextItem(GraphicsObject):
color = fn.mkColor(color)
self.textItem.setDefaultTextColor(color)
self.textItem.setPlainText(text)
self.updateText()
#html = '<span style="color: #%s; text-align: center;">%s</span>' % (color, text)
#self.setHtml(html)
def updateAnchor(self):
pass
#self.resetTransform()
#self.translate(0, 20)
self.updateTextPos()
def setPlainText(self, *args):
"""
@ -83,7 +75,7 @@ class TextItem(GraphicsObject):
See QtGui.QGraphicsTextItem.setPlainText().
"""
self.textItem.setPlainText(*args)
self.updateText()
self.updateTextPos()
def setHtml(self, *args):
"""
@ -92,7 +84,7 @@ class TextItem(GraphicsObject):
See QtGui.QGraphicsTextItem.setHtml().
"""
self.textItem.setHtml(*args)
self.updateText()
self.updateTextPos()
def setTextWidth(self, *args):
"""
@ -104,7 +96,7 @@ class TextItem(GraphicsObject):
See QtGui.QGraphicsTextItem.setTextWidth().
"""
self.textItem.setTextWidth(*args)
self.updateText()
self.updateTextPos()
def setFont(self, *args):
"""
@ -113,13 +105,17 @@ class TextItem(GraphicsObject):
See QtGui.QGraphicsTextItem.setFont().
"""
self.textItem.setFont(*args)
self.updateText()
self.updateTextPos()
def setAngle(self, angle):
self.angle = angle
self.updateTransform()
def updateText(self):
def setAnchor(self, anchor):
self.anchor = Point(anchor)
self.updateTextPos()
def updateTextPos(self):
# update text position to obey anchor
r = self.textItem.boundingRect()
tl = self.textItem.mapToParent(r.topLeft())
@ -184,6 +180,6 @@ class TextItem(GraphicsObject):
self._lastTransform = pt
self.updateText()
self.updateTextPos()