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. 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 position Relative position (0.0-1.0) within the view to position the label
along the line. 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 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 option here is to use `rotateAxis=(1, 0)`, which will cause the text to
be automatically rotated parallel to the line. 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.line = line
self.movable = movable self.movable = movable
self.orthoPos = position # text will always be placed on the line at a position relative to view bounds self.orthoPos = position # text will always be placed on the line at a position relative to view bounds
self.format = text self.format = text
self.line.sigPositionChanged.connect(self.valueChanged) self.line.sigPositionChanged.connect(self.valueChanged)
self._endpoints = (None, None) 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) TextItem.__init__(self, **kwds)
self.setParentItem(line) self.setParentItem(line)
self.valueChanged() self.valueChanged()
@ -372,6 +390,11 @@ class InfLineLabel(TextItem):
pt = pt2 * self.orthoPos + pt1 * (1-self.orthoPos) pt = pt2 * self.orthoPos + pt1 * (1-self.orthoPos)
self.setPos(pt) 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): def setVisible(self, v):
TextItem.setVisible(self, v) TextItem.setVisible(self, v)
if v: if v:

View File

@ -56,7 +56,6 @@ class TextItem(GraphicsObject):
self.fill = fn.mkBrush(fill) self.fill = fn.mkBrush(fill)
self.border = fn.mkPen(border) self.border = fn.mkPen(border)
self.setAngle(angle) 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)): def setText(self, text, color=(200,200,200)):
""" """
@ -67,14 +66,7 @@ class TextItem(GraphicsObject):
color = fn.mkColor(color) color = fn.mkColor(color)
self.textItem.setDefaultTextColor(color) self.textItem.setDefaultTextColor(color)
self.textItem.setPlainText(text) self.textItem.setPlainText(text)
self.updateText() self.updateTextPos()
#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)
def setPlainText(self, *args): def setPlainText(self, *args):
""" """
@ -83,7 +75,7 @@ class TextItem(GraphicsObject):
See QtGui.QGraphicsTextItem.setPlainText(). See QtGui.QGraphicsTextItem.setPlainText().
""" """
self.textItem.setPlainText(*args) self.textItem.setPlainText(*args)
self.updateText() self.updateTextPos()
def setHtml(self, *args): def setHtml(self, *args):
""" """
@ -92,7 +84,7 @@ class TextItem(GraphicsObject):
See QtGui.QGraphicsTextItem.setHtml(). See QtGui.QGraphicsTextItem.setHtml().
""" """
self.textItem.setHtml(*args) self.textItem.setHtml(*args)
self.updateText() self.updateTextPos()
def setTextWidth(self, *args): def setTextWidth(self, *args):
""" """
@ -104,7 +96,7 @@ class TextItem(GraphicsObject):
See QtGui.QGraphicsTextItem.setTextWidth(). See QtGui.QGraphicsTextItem.setTextWidth().
""" """
self.textItem.setTextWidth(*args) self.textItem.setTextWidth(*args)
self.updateText() self.updateTextPos()
def setFont(self, *args): def setFont(self, *args):
""" """
@ -113,13 +105,17 @@ class TextItem(GraphicsObject):
See QtGui.QGraphicsTextItem.setFont(). See QtGui.QGraphicsTextItem.setFont().
""" """
self.textItem.setFont(*args) self.textItem.setFont(*args)
self.updateText() self.updateTextPos()
def setAngle(self, angle): def setAngle(self, angle):
self.angle = angle self.angle = angle
self.updateTransform() self.updateTransform()
def updateText(self): def setAnchor(self, anchor):
self.anchor = Point(anchor)
self.updateTextPos()
def updateTextPos(self):
# update text position to obey anchor # update text position to obey anchor
r = self.textItem.boundingRect() r = self.textItem.boundingRect()
tl = self.textItem.mapToParent(r.topLeft()) tl = self.textItem.mapToParent(r.topLeft())
@ -184,6 +180,6 @@ class TextItem(GraphicsObject):
self._lastTransform = pt self._lastTransform = pt
self.updateText() self.updateTextPos()