Rename crosshair (type) to cursor

Since the "crosshair" is growing more and more UX implementation details
it probably makes sense to call it what it is; a python level mouse
abstraction. Add 2 internal sets: `_hovered` for allowing mouse hovered
objects to register themselves to other cursor aware components, and
`_trackers` for allowing scene items to "track" cursor movements via
a `on_tracked_source()` callback.
basic_alerts
Tyler Goodlet 2021-01-03 10:46:28 -05:00
parent 14dad08d98
commit 08aa5984ec
1 changed files with 29 additions and 10 deletions

View File

@ -17,7 +17,7 @@
Mouse interaction graphics Mouse interaction graphics
""" """
from typing import Optional, Tuple from typing import Optional, Tuple, Set, Dict
import inspect import inspect
import numpy as np import numpy as np
@ -198,7 +198,7 @@ class ContentsLabel(pg.LabelItem):
self.setText(f"{name}: {data:.2f}") self.setText(f"{name}: {data:.2f}")
class CrossHair(pg.GraphicsObject): class Cursor(pg.GraphicsObject):
def __init__( def __init__(
self, self,
@ -217,11 +217,21 @@ class CrossHair(pg.GraphicsObject):
style=QtCore.Qt.DashLine, style=QtCore.Qt.DashLine,
) )
self.lsc = linkedsplitcharts self.lsc = linkedsplitcharts
self.graphics = {} self.graphics: Dict[str, pg.GraphicsObject] = {}
self.plots = [] self.plots: List['PlotChartWidget'] = [] # type: ignore # noqa
self.active_plot = None self.active_plot = None
self.digits = digits self.digits: int = digits
self._lastx = None self._datum_xy: Tuple[int, float] = (0, 0)
self._hovered: Set[pg.GraphicsObject] = set()
self._trackers: Set[pg.GraphicsObject] = set()
def add_hovered(
self,
item: pg.GraphicsObject,
) -> None:
assert getattr(item, 'delete'), f"{item} must define a ``.delete()``"
self._hovered.add(item)
def add_plot( def add_plot(
self, self,
@ -293,7 +303,11 @@ class CrossHair(pg.GraphicsObject):
) -> LineDot: ) -> LineDot:
# if this plot contains curves add line dot "cursors" to denote # if this plot contains curves add line dot "cursors" to denote
# the current sample under the mouse # the current sample under the mouse
cursor = LineDot(curve, index=plot._ohlc[-1]['index'], plot=plot) cursor = LineDot(
curve,
index=plot._ohlc[-1]['index'],
plot=plot
)
plot.addItem(cursor) plot.addItem(cursor)
self.graphics[plot].setdefault('cursors', []).append(cursor) self.graphics[plot].setdefault('cursors', []).append(cursor)
return cursor return cursor
@ -336,15 +350,21 @@ class CrossHair(pg.GraphicsObject):
# update y-range items # update y-range items
self.graphics[plot]['hl'].setY(y) self.graphics[plot]['hl'].setY(y)
self.graphics[self.active_plot]['yl'].update_label( self.graphics[self.active_plot]['yl'].update_label(
abs_pos=pos, value=y abs_pos=pos, value=y
) )
# Update x if cursor changed after discretization calc # Update x if cursor changed after discretization calc
# (this saves draw cycles on small mouse moves) # (this saves draw cycles on small mouse moves)
lastx = self._lastx lastx, lasty = self._datum_xy
ix = round(x) # since bars are centered around index ix = round(x) # since bars are centered around index
# update all trackers
for item in self._trackers:
# print(f'setting {item} with {(ix, y)}')
item.on_tracked_source(ix, y)
if ix != lastx: if ix != lastx:
for plot, opts in self.graphics.items(): for plot, opts in self.graphics.items():
@ -355,7 +375,6 @@ class CrossHair(pg.GraphicsObject):
plot.update_contents_labels(ix) plot.update_contents_labels(ix)
# update all subscribed curve dots # update all subscribed curve dots
# first = plot._ohlc[0]['index']
for cursor in opts.get('cursors', ()): for cursor in opts.get('cursors', ()):
cursor.setIndex(ix) cursor.setIndex(ix)
@ -371,7 +390,7 @@ class CrossHair(pg.GraphicsObject):
value=x, value=x,
) )
self._lastx = ix self._datum_xy = ix, y
def boundingRect(self): def boundingRect(self):
try: try: