Arrow editor refinements in prep for gap checker

Namely exposing `ArrowEditor.add()` params to provide access to
coloring/transparency settings over the remote-ctl annotation API and
also adding a new `.remove_all()` to easily clear all arrows from
a single call. Also add `.remove()` compat methods to the other editors
(i.e. for lines, rects).
ib_async
Gud Boi 2026-01-25 14:14:42 -05:00
parent ad299789db
commit 809ec6accb
1 changed files with 74 additions and 11 deletions

View File

@ -21,6 +21,7 @@ Higher level annotation editors.
from __future__ import annotations from __future__ import annotations
from collections import defaultdict from collections import defaultdict
from typing import ( from typing import (
Literal,
Sequence, Sequence,
TYPE_CHECKING, TYPE_CHECKING,
) )
@ -66,9 +67,18 @@ log = get_logger(__name__)
class ArrowEditor(Struct): class ArrowEditor(Struct):
'''
Annotate a chart-view with arrows most often used for indicating,
- order txns/clears,
- positions directions,
- general points-of-interest like nooz events.
'''
godw: GodWidget = None # type: ignore # noqa godw: GodWidget = None # type: ignore # noqa
_arrows: dict[str, list[pg.ArrowItem]] = {} _arrows: dict[
str,
list[pg.ArrowItem]
] = {}
def add( def add(
self, self,
@ -76,8 +86,14 @@ class ArrowEditor(Struct):
uid: str, uid: str,
x: float, x: float,
y: float, y: float,
color: str = 'default', color: str|None = None,
pointing: str | None = None, pointing: Literal[
'up',
'down',
None,
] = None,
alpha: int = 255,
zval: float = 1e9,
) -> pg.ArrowItem: ) -> pg.ArrowItem:
''' '''
@ -93,6 +109,11 @@ class ArrowEditor(Struct):
# scale arrow sizing to dpi-aware font # scale arrow sizing to dpi-aware font
size = _font.font.pixelSize() * 0.8 size = _font.font.pixelSize() * 0.8
color = color or 'default'
color = QColor(hcolor(color))
color.setAlpha(alpha)
pen = fn.mkPen(color, width=1)
brush = fn.mkBrush(color)
arrow = pg.ArrowItem( arrow = pg.ArrowItem(
angle=angle, angle=angle,
baseAngle=0, baseAngle=0,
@ -100,22 +121,58 @@ class ArrowEditor(Struct):
headWidth=size/2, headWidth=size/2,
tailLen=None, tailLen=None,
pxMode=True, pxMode=True,
# coloring # coloring
pen=pg.mkPen(hcolor('papas_special')), pen=pen,
brush=pg.mkBrush(hcolor(color)), brush=brush,
) )
arrow.setZValue(zval)
arrow.setPos(x, y) arrow.setPos(x, y)
self._arrows.setdefault(uid, []).append(arrow) plot.addItem(arrow) # render to view
# render to view # register for removal
plot.addItem(arrow) arrow._uid = uid
self._arrows.setdefault(
uid, []
).append(arrow)
return arrow return arrow
def remove(self, arrow) -> bool: def remove(
self,
arrow: pg.ArrowItem,
) -> None:
'''
Remove a *single arrow* from all chart views to which it was
added.
'''
uid: str = arrow._uid
arrows: list[pg.ArrowItem] = self._arrows[uid]
log.info(
f'Removing arrow from views\n'
f'uid: {uid!r}\n'
f'{arrow!r}\n'
)
for linked in self.godw.iter_linked(): for linked in self.godw.iter_linked():
linked.chart.plotItem.removeItem(arrow) linked.chart.plotItem.removeItem(arrow)
try:
arrows.remove(arrow)
except ValueError:
log.warning(
f'Arrow was already removed?\n'
f'uid: {uid!r}\n'
f'{arrow!r}\n'
)
def remove_all(self) -> set[pg.ArrowItem]:
'''
Remove all arrows added by this editor from all
chart-views.
'''
for uid, arrows in self._arrows.items():
for arrow in arrows:
self.remove(arrow)
class LineEditor(Struct): class LineEditor(Struct):
@ -261,6 +318,9 @@ class LineEditor(Struct):
return lines return lines
# compat with ArrowEditor
remove = remove_line
def as_point( def as_point(
pair: Sequence[float, float] | QPointF, pair: Sequence[float, float] | QPointF,
@ -293,7 +353,7 @@ class SelectRect(QtWidgets.QGraphicsRectItem):
def __init__( def __init__(
self, self,
viewbox: ViewBox, viewbox: ViewBox,
color: str | None = None, color: str|None = None,
) -> None: ) -> None:
super().__init__(0, 0, 1, 1) super().__init__(0, 0, 1, 1)
@ -609,3 +669,6 @@ class SelectRect(QtWidgets.QGraphicsRectItem):
): ):
scen.removeItem(self._label_proxy) scen.removeItem(self._label_proxy)
# compat with ArrowEditor
remove = delete