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): | ||||
| 
 | ||||
|     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) | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue