Make line editor multi-line aware, drop `dataclass` for `Struct`

history_view
Tyler Goodlet 2022-09-06 16:09:13 -04:00
parent 2b76baeb10
commit a4935b8fa8
1 changed files with 55 additions and 48 deletions

View File

@ -18,7 +18,8 @@
Higher level annotation editors. Higher level annotation editors.
""" """
from dataclasses import dataclass, field from __future__ import annotations
from collections import defaultdict
from typing import ( from typing import (
Optional, Optional,
TYPE_CHECKING TYPE_CHECKING
@ -33,6 +34,7 @@ import numpy as np
from ._style import hcolor, _font from ._style import hcolor, _font
from ._lines import LevelLine from ._lines import LevelLine
from ..log import get_logger from ..log import get_logger
from ..data.types import Struct
if TYPE_CHECKING: if TYPE_CHECKING:
from ._chart import GodWidget from ._chart import GodWidget
@ -41,11 +43,10 @@ if TYPE_CHECKING:
log = get_logger(__name__) log = get_logger(__name__)
@dataclass class ArrowEditor(Struct):
class ArrowEditor:
chart: 'ChartPlotWidget' # noqa chart: 'ChartPlotWidget' # noqa
_arrows: field(default_factory=dict) _arrows: dict[str, pg.ArrowItem]
def add( def add(
self, self,
@ -55,9 +56,10 @@ class ArrowEditor:
color='default', color='default',
pointing: Optional[str] = None, pointing: Optional[str] = None,
) -> pg.ArrowItem: ) -> pg.ArrowItem:
"""Add an arrow graphic to view at given (x, y). '''
Add an arrow graphic to view at given (x, y).
""" '''
angle = { angle = {
'up': 90, 'up': 90,
'down': -90, 'down': -90,
@ -92,14 +94,13 @@ class ArrowEditor:
self.chart.plotItem.removeItem(arrow) self.chart.plotItem.removeItem(arrow)
@dataclass class LineEditor(Struct):
class LineEditor:
''' '''
The great editor of linez. The great editor of linez.
''' '''
godw: 'ChartPlotWidget' = None # type: ignore # noqa godw: GodWidget = None # type: ignore # noqa
_order_lines: dict[str, LevelLine] = field(default_factory=dict) _order_lines: defaultdict[str, LevelLine] = defaultdict(list)
_active_staged_line: LevelLine = None _active_staged_line: LevelLine = None
def stage_line( def stage_line(
@ -122,10 +123,10 @@ class LineEditor:
return line return line
def unstage_line(self) -> LevelLine: def unstage_line(self) -> LevelLine:
"""Inverse of ``.stage_line()``. '''
Inverse of ``.stage_line()``.
""" '''
# chart = self.chart._cursor.active_plot
cursor = self.godw.get_cursor() cursor = self.godw.get_cursor()
# delete "staged" cursor tracking line from view # delete "staged" cursor tracking line from view
@ -146,9 +147,9 @@ class LineEditor:
# show the crosshair y line and label # show the crosshair y line and label
cursor.show_xhair() cursor.show_xhair()
def submit_line( def submit_lines(
self, self,
line: LevelLine, lines: list[LevelLine],
uuid: str, uuid: str,
) -> LevelLine: ) -> LevelLine:
@ -158,33 +159,30 @@ class LineEditor:
# raise RuntimeError("No line is currently staged!?") # raise RuntimeError("No line is currently staged!?")
# for now, until submission reponse arrives # for now, until submission reponse arrives
line.hide_labels() for line in lines:
line.hide_labels()
# register for later lookup/deletion # register for later lookup/deletion
self._order_lines[uuid] = line self._order_lines[uuid] += lines
return line return lines
def commit_line(self, uuid: str) -> LevelLine: def commit_line(self, uuid: str) -> list[LevelLine]:
"""Commit a "staged line" to view. '''
Commit a "staged line" to view.
Submits the line graphic under the cursor as a (new) permanent Submits the line graphic under the cursor as a (new) permanent
graphic in view. graphic in view.
""" '''
try: lines = self._order_lines.get(uuid)
line = self._order_lines[uuid] if lines:
except KeyError: for line in self._order_lines.get(uuid, []):
log.warning(f'No line for {uuid} could be found?') line.show_labels()
return log.debug(f'Level active for level: {line.value()}')
else: # TODO: other flashy things to indicate the order is active
line.show_labels()
# TODO: other flashy things to indicate the order is active return lines
log.debug(f'Level active for level: {line.value()}')
return line
def lines_under_cursor(self) -> list[LevelLine]: def lines_under_cursor(self) -> list[LevelLine]:
"""Get the line(s) under the cursor position. """Get the line(s) under the cursor position.
@ -193,8 +191,13 @@ class LineEditor:
# Delete any hoverable under the cursor # Delete any hoverable under the cursor
return self.godw.get_cursor()._hovered return self.godw.get_cursor()._hovered
def all_lines(self) -> tuple[LevelLine]: def all_lines(self) -> list[LevelLine]:
return tuple(self._order_lines.values()) all_lines = []
for lines in list(self._order_lines.values()):
all_lines.extend(lines)
# return tuple(self._order_lines.values())
return all_lines
def remove_line( def remove_line(
self, self,
@ -209,26 +212,30 @@ class LineEditor:
''' '''
# try to look up line from our registry # try to look up line from our registry
line = self._order_lines.pop(uuid, line) # line = self._order_lines.pop(uuid, line)
if line: lines = self._order_lines.pop(uuid)
# if line:
# if hovered remove from cursor set if lines:
cursor = self.godw.get_cursor() cursor = self.godw.get_cursor()
hovered = cursor._hovered
if line in hovered:
hovered.remove(line)
# make sure the xhair doesn't get left off for line in lines:
# just because we never got a un-hover event # if hovered remove from cursor set
cursor.show_xhair() # cursor = self.godw.get_cursor()
hovered = cursor._hovered
if line in hovered:
hovered.remove(line)
log.debug(f'deleting {line} with oid: {uuid}') # make sure the xhair doesn't get left off
line.delete() # just because we never got a un-hover event
cursor.show_xhair()
log.debug(f'deleting {line} with oid: {uuid}')
line.delete()
else: else:
log.warning(f'Could not find line for {line}') log.warning(f'Could not find line for {line}')
return line return lines
class SelectRect(QtGui.QGraphicsRectItem): class SelectRect(QtGui.QGraphicsRectItem):