Verze po zapracovani prvni vlny pozadavku
This commit is contained in:
139
src/detektor_region.py
Normal file
139
src/detektor_region.py
Normal file
@@ -0,0 +1,139 @@
|
||||
from enum import Enum
|
||||
from math import trunc
|
||||
|
||||
import pyqtgraph as pg
|
||||
|
||||
from callbacks import CallbackDispatcher, CallbackType
|
||||
from detektor_plot import DetektorPlot
|
||||
from detektor_data import DetektorContainer
|
||||
|
||||
|
||||
class DetektorRegionState(Enum):
|
||||
UNSET = 1
|
||||
SET = 4
|
||||
COPIED = 5
|
||||
|
||||
|
||||
class DetektorRegion(pg.LinearRegionItem):
|
||||
"""Encapsulates a linear region that snaps to discrete X-axis values and shows a context menu."""
|
||||
|
||||
# in which mode the region is
|
||||
_state: DetektorRegionState = DetektorRegionState.UNSET
|
||||
_plot: DetektorPlot = None
|
||||
|
||||
# the start and end is integer, not a label (time)
|
||||
_start_position: int = 0
|
||||
_end_position: int = 0
|
||||
|
||||
def __init__(self, plot: DetektorPlot):
|
||||
super().__init__()
|
||||
|
||||
# reference to the chart so we can add and remove the widget
|
||||
self._plot = plot
|
||||
|
||||
# move the rectangle behind the plot lines
|
||||
self.setZValue(-10)
|
||||
|
||||
# color is the same for selecting and hovering
|
||||
grid_color = pg.mkBrush((100, 100, 250, 50))
|
||||
self.setBrush(grid_color)
|
||||
self.setHoverBrush(grid_color)
|
||||
|
||||
self.setAcceptHoverEvents(True)
|
||||
|
||||
# callback for changing the width
|
||||
self.sigRegionChanged.connect(self.snap_to_x_labels)
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
return self._state
|
||||
|
||||
@state.setter
|
||||
def state(self, v: DetektorRegionState):
|
||||
""" Sets state and calls hooks if it changes from the previous one """
|
||||
if v != self._state:
|
||||
self._state = v
|
||||
|
||||
CallbackDispatcher().call(CallbackType.REGION_STATE)
|
||||
|
||||
def set(self):
|
||||
""" Displays region occupying roughly a third of the actual view range """
|
||||
self.state = DetektorRegionState.SET
|
||||
x_range, y_range = self._plot.view_box.viewRange()
|
||||
x_min, x_max = x_range
|
||||
third = (x_max - x_min) / 3
|
||||
self.setRegion([x_min + third, x_max - third])
|
||||
self.display()
|
||||
|
||||
def unset(self):
|
||||
self.state = DetektorRegionState.UNSET
|
||||
self.hide()
|
||||
|
||||
def get_safe_region(self):
|
||||
start, end = self.getRegion()
|
||||
if start < 0:
|
||||
start = 0
|
||||
if end > DetektorContainer().get().data_count()-1:
|
||||
end = DetektorContainer().get().data_count()
|
||||
|
||||
return trunc(start), trunc(end)
|
||||
|
||||
def delete(self):
|
||||
""" Deletes data by cutting the region without keeping it """
|
||||
start, end = self.get_safe_region()
|
||||
DetektorContainer().duplicate()
|
||||
DetektorContainer().get().cut(start, end)
|
||||
|
||||
self.state = DetektorRegionState.UNSET
|
||||
self.hide()
|
||||
|
||||
def copy(self):
|
||||
""" Copies the data """
|
||||
start, end = self.get_safe_region()
|
||||
DetektorContainer().get().copy(start, end)
|
||||
|
||||
self.state = DetektorRegionState.COPIED
|
||||
|
||||
def cut(self):
|
||||
""" Cuts the data and hiding the region """
|
||||
start, end = self.get_safe_region()
|
||||
DetektorContainer().duplicate()
|
||||
DetektorContainer().get().cut(start, end)
|
||||
|
||||
self.state = DetektorRegionState.COPIED
|
||||
self.hide()
|
||||
|
||||
def paste_end(self):
|
||||
DetektorContainer().duplicate()
|
||||
DetektorContainer().get().paste(
|
||||
DetektorContainer().get().data_count()
|
||||
)
|
||||
|
||||
self.unset()
|
||||
|
||||
def paste_after(self):
|
||||
_, end = self.get_safe_region()
|
||||
DetektorContainer().duplicate()
|
||||
DetektorContainer().get().paste(end)
|
||||
|
||||
self.unset()
|
||||
|
||||
def paste_at(self):
|
||||
cursor_x = self._plot.cursorLine.getXPos()
|
||||
DetektorContainer().duplicate()
|
||||
DetektorContainer().get().paste(cursor_x)
|
||||
|
||||
self.unset()
|
||||
|
||||
def snap_to_x_labels(self):
|
||||
"""Snaps the region boundaries to the nearest discrete X-axis values."""
|
||||
min_x, max_x = self.getRegion()
|
||||
self.setRegion([int(round(min_x)), int(round(max_x))])
|
||||
|
||||
def display(self):
|
||||
""" Adds the region to the plot """
|
||||
self._plot.graphWidget.addItem(self)
|
||||
|
||||
def hide(self):
|
||||
""" Removes the region from the plot """
|
||||
self._plot.graphWidget.removeItem(self)
|
||||
Reference in New Issue
Block a user