From 14dad08d98d69810450e32d99e1739039b7d7f14 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Sun, 3 Jan 2021 10:43:53 -0500 Subject: [PATCH] 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. --- piker/ui/_graphics/_lines.py | 103 ++++++++++++++++++++++++++++++----- 1 file changed, 90 insertions(+), 13 deletions(-) diff --git a/piker/ui/_graphics/_lines.py b/piker/ui/_graphics/_lines.py index 61d2fd41..ef4c00f1 100644 --- a/piker/ui/_graphics/_lines.py +++ b/piker/ui/_graphics/_lines.py @@ -33,8 +33,6 @@ from .._axes import YSticky class LevelLabel(YSticky): - line_pen = pg.mkPen(hcolor('bracket')) - _w_margin = 4 _h_margin = 3 level: float = 0 @@ -43,13 +41,15 @@ class LevelLabel(YSticky): self, chart, *args, + color: str = 'bracket', orient_v: str = 'bottom', orient_h: str = 'left', **kwargs ) -> None: 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 self._orient_v = orient_v @@ -77,7 +77,7 @@ class LevelLabel(YSticky): br = self.boundingRect() h, w = br.height(), br.width() - # this triggers ``.pain()`` implicitly? + # this triggers ``.paint()`` implicitly? self.setPos(QPointF( self._h_shift * w - offset, abs_pos.y() - (self._v_shift * h) - offset @@ -118,11 +118,10 @@ class LevelLabel(YSticky): self.update() def unhighlight(self): - self._pen = self.line_pen + self._pen = self.pen self.update() - class L1Label(LevelLabel): size: float = 0 @@ -192,52 +191,124 @@ class L1Labels: class LevelLine(pg.InfiniteLine): + + # TODO: fill in these slots for orders + # .sigPositionChangeFinished.emit(self) + def __init__( self, + chart: 'ChartPlotWidget', # type: ignore # noqa label: LevelLabel, + highlight_color: str = 'default_light', **kwargs, ) -> None: self.label = label super().__init__(**kwargs) + self.sigPositionChanged.connect(self.set_level) + self._chart = chart + # use slightly thicker highlight - self.setHoverPen( - color=(255, 0, 0), - width=self.pen.width() + 1 - ) + pen = pg.mkPen(hcolor(highlight_color)) + pen.setWidth(2) + self.setHoverPen(pen) + self._track_cursor: bool = False def set_level(self, value: float) -> None: 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: """Mouse hover callback. """ if self.mouseHovering == hover: return + self.mouseHovering = hover + chart = self._chart + if hover: self.currentPen = 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: self.currentPen = self.pen self.label.unhighlight() + chart._cursor._hovered.remove(self) + # highlight any attached label # self.setCursor(QtCore.Qt.OpenHandCursor) # self.setCursor(QtCore.Qt.DragMoveCursor) 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( chart: 'ChartPlogWidget', # noqa level: float, digits: int = 1, + color: str = 'default', # size 4 font on 4k screen scaled down, so small-ish. font_size_inches: float = _down_2_font_inches_we_like, @@ -254,11 +325,13 @@ def level_line( parent=chart.getAxis('right'), # TODO: pass this from symbol data digits=digits, - opacity=1, + opacity=0.666, font_size_inches=font_size_inches, + color=color, + # TODO: make this take the view's bg pen bg_color='papas_special', - fg_color='default', + fg_color=color, **linelabelkwargs ) label.update_from_data(0, level) @@ -267,12 +340,16 @@ def level_line( label._size_br_from_str(label.label_str) line = LevelLine( + chart, label, + # lookup "highlight" equivalent + highlight_color=color + '_light', movable=True, angle=0, ) line.setValue(level) - line.setPen(pg.mkPen(hcolor('default'))) + line.setPen(pg.mkPen(hcolor(color))) + # activate/draw label line.setValue(level)