Extend level line interaction
Support tracking the mouse cursor using a new `on_tracked_sources()` callback method. Make hovered highlight a bit thicker and highlight when click-dragged. Add a delete method for removing from the scene along with label.basic_alerts
parent
edbbcbf954
commit
14dad08d98
|
@ -33,8 +33,6 @@ from .._axes import YSticky
|
||||||
|
|
||||||
class LevelLabel(YSticky):
|
class LevelLabel(YSticky):
|
||||||
|
|
||||||
line_pen = pg.mkPen(hcolor('bracket'))
|
|
||||||
|
|
||||||
_w_margin = 4
|
_w_margin = 4
|
||||||
_h_margin = 3
|
_h_margin = 3
|
||||||
level: float = 0
|
level: float = 0
|
||||||
|
@ -43,13 +41,15 @@ class LevelLabel(YSticky):
|
||||||
self,
|
self,
|
||||||
chart,
|
chart,
|
||||||
*args,
|
*args,
|
||||||
|
color: str = 'bracket',
|
||||||
orient_v: str = 'bottom',
|
orient_v: str = 'bottom',
|
||||||
orient_h: str = 'left',
|
orient_h: str = 'left',
|
||||||
**kwargs
|
**kwargs
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(chart, *args, **kwargs)
|
super().__init__(chart, *args, **kwargs)
|
||||||
|
|
||||||
self._pen = self.line_pen
|
# TODO: this is kinda cludgy
|
||||||
|
self._pen = self.pen = pg.mkPen(hcolor(color))
|
||||||
|
|
||||||
# orientation around axis options
|
# orientation around axis options
|
||||||
self._orient_v = orient_v
|
self._orient_v = orient_v
|
||||||
|
@ -77,7 +77,7 @@ class LevelLabel(YSticky):
|
||||||
br = self.boundingRect()
|
br = self.boundingRect()
|
||||||
h, w = br.height(), br.width()
|
h, w = br.height(), br.width()
|
||||||
|
|
||||||
# this triggers ``.pain()`` implicitly?
|
# this triggers ``.paint()`` implicitly?
|
||||||
self.setPos(QPointF(
|
self.setPos(QPointF(
|
||||||
self._h_shift * w - offset,
|
self._h_shift * w - offset,
|
||||||
abs_pos.y() - (self._v_shift * h) - offset
|
abs_pos.y() - (self._v_shift * h) - offset
|
||||||
|
@ -118,11 +118,10 @@ class LevelLabel(YSticky):
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def unhighlight(self):
|
def unhighlight(self):
|
||||||
self._pen = self.line_pen
|
self._pen = self.pen
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class L1Label(LevelLabel):
|
class L1Label(LevelLabel):
|
||||||
|
|
||||||
size: float = 0
|
size: float = 0
|
||||||
|
@ -192,52 +191,124 @@ class L1Labels:
|
||||||
|
|
||||||
|
|
||||||
class LevelLine(pg.InfiniteLine):
|
class LevelLine(pg.InfiniteLine):
|
||||||
|
|
||||||
|
# TODO: fill in these slots for orders
|
||||||
|
# .sigPositionChangeFinished.emit(self)
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
chart: 'ChartPlotWidget', # type: ignore # noqa
|
||||||
label: LevelLabel,
|
label: LevelLabel,
|
||||||
|
highlight_color: str = 'default_light',
|
||||||
**kwargs,
|
**kwargs,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.label = label
|
self.label = label
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
self.sigPositionChanged.connect(self.set_level)
|
self.sigPositionChanged.connect(self.set_level)
|
||||||
|
|
||||||
|
self._chart = chart
|
||||||
|
|
||||||
# use slightly thicker highlight
|
# use slightly thicker highlight
|
||||||
self.setHoverPen(
|
pen = pg.mkPen(hcolor(highlight_color))
|
||||||
color=(255, 0, 0),
|
pen.setWidth(2)
|
||||||
width=self.pen.width() + 1
|
self.setHoverPen(pen)
|
||||||
)
|
self._track_cursor: bool = False
|
||||||
|
|
||||||
def set_level(self, value: float) -> None:
|
def set_level(self, value: float) -> None:
|
||||||
self.label.update_from_data(0, self.value())
|
self.label.update_from_data(0, self.value())
|
||||||
|
|
||||||
|
def on_tracked_source(
|
||||||
|
self,
|
||||||
|
x: int,
|
||||||
|
y: float
|
||||||
|
) -> None:
|
||||||
|
self.movable = True
|
||||||
|
self.setPos(y) # implictly calls ``.set_level()``
|
||||||
|
self.update()
|
||||||
|
|
||||||
def setMouseHover(self, hover: bool) -> None:
|
def setMouseHover(self, hover: bool) -> None:
|
||||||
"""Mouse hover callback.
|
"""Mouse hover callback.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if self.mouseHovering == hover:
|
if self.mouseHovering == hover:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.mouseHovering = hover
|
self.mouseHovering = hover
|
||||||
|
|
||||||
|
chart = self._chart
|
||||||
|
|
||||||
if hover:
|
if hover:
|
||||||
|
|
||||||
self.currentPen = self.hoverPen
|
self.currentPen = self.hoverPen
|
||||||
self.label.highlight(self.hoverPen)
|
self.label.highlight(self.hoverPen)
|
||||||
|
|
||||||
|
# add us to cursor state
|
||||||
|
chart._cursor.add_hovered(self)
|
||||||
|
|
||||||
|
# # hide y-crosshair
|
||||||
|
# chart._cursor.graphics[chart]['hl'].hide()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.currentPen = self.pen
|
self.currentPen = self.pen
|
||||||
self.label.unhighlight()
|
self.label.unhighlight()
|
||||||
|
|
||||||
|
chart._cursor._hovered.remove(self)
|
||||||
|
|
||||||
# highlight any attached label
|
# highlight any attached label
|
||||||
|
|
||||||
# self.setCursor(QtCore.Qt.OpenHandCursor)
|
# self.setCursor(QtCore.Qt.OpenHandCursor)
|
||||||
# self.setCursor(QtCore.Qt.DragMoveCursor)
|
# self.setCursor(QtCore.Qt.DragMoveCursor)
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
|
def mouseDragEvent(self, ev):
|
||||||
|
chart = self._chart
|
||||||
|
# hide y-crosshair
|
||||||
|
chart._cursor.graphics[chart]['hl'].hide()
|
||||||
|
|
||||||
|
# highlight
|
||||||
|
self.currentPen = self.hoverPen
|
||||||
|
self.label.highlight(self.hoverPen)
|
||||||
|
|
||||||
|
# normal tracking behavior
|
||||||
|
super().mouseDragEvent(ev)
|
||||||
|
|
||||||
|
# This is the final position in the drag
|
||||||
|
if ev.isFinish():
|
||||||
|
# show y-crosshair again
|
||||||
|
chart = self._chart
|
||||||
|
chart._cursor.graphics[chart]['hl'].show()
|
||||||
|
|
||||||
|
def mouseDoubleClickEvent(
|
||||||
|
self,
|
||||||
|
ev: QtGui.QMouseEvent,
|
||||||
|
) -> None:
|
||||||
|
print(f'double click {ev}')
|
||||||
|
|
||||||
|
# def mouseMoved(
|
||||||
|
# self,
|
||||||
|
# ev: Tuple[QtGui.QMouseEvent],
|
||||||
|
# ) -> None:
|
||||||
|
# pos = evt[0]
|
||||||
|
# print(pos)
|
||||||
|
|
||||||
|
def delete(self) -> None:
|
||||||
|
"""Remove this line from containing chart/view/scene.
|
||||||
|
|
||||||
|
"""
|
||||||
|
scene = self.scene()
|
||||||
|
if scene:
|
||||||
|
# self.label.parent.scene().removeItem(self.label)
|
||||||
|
scene.removeItem(self.label)
|
||||||
|
|
||||||
|
self._chart.plotItem.removeItem(self)
|
||||||
|
|
||||||
|
|
||||||
def level_line(
|
def level_line(
|
||||||
chart: 'ChartPlogWidget', # noqa
|
chart: 'ChartPlogWidget', # noqa
|
||||||
level: float,
|
level: float,
|
||||||
digits: int = 1,
|
digits: int = 1,
|
||||||
|
color: str = 'default',
|
||||||
|
|
||||||
# size 4 font on 4k screen scaled down, so small-ish.
|
# size 4 font on 4k screen scaled down, so small-ish.
|
||||||
font_size_inches: float = _down_2_font_inches_we_like,
|
font_size_inches: float = _down_2_font_inches_we_like,
|
||||||
|
@ -254,11 +325,13 @@ def level_line(
|
||||||
parent=chart.getAxis('right'),
|
parent=chart.getAxis('right'),
|
||||||
# TODO: pass this from symbol data
|
# TODO: pass this from symbol data
|
||||||
digits=digits,
|
digits=digits,
|
||||||
opacity=1,
|
opacity=0.666,
|
||||||
font_size_inches=font_size_inches,
|
font_size_inches=font_size_inches,
|
||||||
|
color=color,
|
||||||
|
|
||||||
# TODO: make this take the view's bg pen
|
# TODO: make this take the view's bg pen
|
||||||
bg_color='papas_special',
|
bg_color='papas_special',
|
||||||
fg_color='default',
|
fg_color=color,
|
||||||
**linelabelkwargs
|
**linelabelkwargs
|
||||||
)
|
)
|
||||||
label.update_from_data(0, level)
|
label.update_from_data(0, level)
|
||||||
|
@ -267,12 +340,16 @@ def level_line(
|
||||||
label._size_br_from_str(label.label_str)
|
label._size_br_from_str(label.label_str)
|
||||||
|
|
||||||
line = LevelLine(
|
line = LevelLine(
|
||||||
|
chart,
|
||||||
label,
|
label,
|
||||||
|
# lookup "highlight" equivalent
|
||||||
|
highlight_color=color + '_light',
|
||||||
movable=True,
|
movable=True,
|
||||||
angle=0,
|
angle=0,
|
||||||
)
|
)
|
||||||
line.setValue(level)
|
line.setValue(level)
|
||||||
line.setPen(pg.mkPen(hcolor('default')))
|
line.setPen(pg.mkPen(hcolor(color)))
|
||||||
|
|
||||||
# activate/draw label
|
# activate/draw label
|
||||||
line.setValue(level)
|
line.setValue(level)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue