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