Skip to content

Commit

Permalink
Spectra: move view range selections to visual settings
Browse files Browse the repository at this point in the history
  • Loading branch information
markotoplak committed Mar 21, 2023
1 parent aa28309 commit 414d52e
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 56 deletions.
24 changes: 16 additions & 8 deletions orangecontrib/spectroscopy/tests/test_owspectra.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,14 +233,6 @@ def numcurves(curves):
curves_plotted = self.widget.curveplot.curves_plotted
self.assertEqual(numcurves(curves_plotted), 150)

def test_limits(self):
self.send_signal("Data", self.iris)
vr = self.widget.curveplot.plot.viewRect()
# there should ne no change
self.widget.curveplot.set_limits()
vr2 = self.widget.curveplot.plot.viewRect()
self.assertEqual(vr, vr2)

def test_line_intersection(self):
data = self.collagen
x = getx(data)
Expand Down Expand Up @@ -631,6 +623,22 @@ def test_visual_settings(self, timeout=5):
self.assertEqual(axis.label.toPlainText().strip(), "Foo3")
self.assertEqual(axis.labelText, "Foo3")

key, value = ("View Range", "X", "xMin"), 1.
self.widget.set_visual_settings(key, value)
key, value = ("View Range", "X", "xMax"), 3.
self.widget.set_visual_settings(key, value)
vr = graph.plot.vb.viewRect()
self.assertEqual(vr.left(), 1)
self.assertEqual(vr.right(), 3)

key, value = ("View Range", "Y", "yMin"), 2.
self.widget.set_visual_settings(key, value)
key, value = ("View Range", "Y", "yMax"), 42.
self.widget.set_visual_settings(key, value)
vr = graph.plot.vb.viewRect()
self.assertEqual(vr.top(), 2)
self.assertEqual(vr.bottom(), 42)

def assertFontEqual(self, font1, font2):
self.assertEqual(font1.family(), font2.family())
self.assertEqual(font1.pointSize(), font2.pointSize())
Expand Down
15 changes: 9 additions & 6 deletions orangecontrib/spectroscopy/widgets/owhyper.py
Original file line number Diff line number Diff line change
Expand Up @@ -1174,11 +1174,12 @@ def __init__(self):
self._setup_plot_parameters()

def _setup_plot_parameters(self):
parts_from_spectra = [SpectraParameterSetter.ANNOT_BOX]
self.imageplot.parameter_setter.initial_settings[SpectraParameterSetter.ANNOT_BOX] = \
self.curveplot.parameter_setter.initial_settings[SpectraParameterSetter.ANNOT_BOX]
self.imageplot.parameter_setter.initial_settings[SpectraParameterSetter.LABELS_BOX] = \
self.curveplot.parameter_setter.initial_settings[SpectraParameterSetter.LABELS_BOX]
parts_from_spectra = [SpectraParameterSetter.ANNOT_BOX,
SpectraParameterSetter.LABELS_BOX,
SpectraParameterSetter.VIEW_RANGE_BOX]
for cp in parts_from_spectra:
self.imageplot.parameter_setter.initial_settings[cp] = \
self.curveplot.parameter_setter.initial_settings[cp]

VisualSettingsDialog(self, self.imageplot.parameter_setter.initial_settings)

Expand Down Expand Up @@ -1402,7 +1403,9 @@ def valid_context(data):
def set_visual_settings(self, key, value):
im_setter = self.imageplot.parameter_setter
cv_setter = self.curveplot.parameter_setter
if key[0] not in ["Annotations"] and key[0] in im_setter.initial_settings:
skip_im_setter = [SpectraParameterSetter.ANNOT_BOX,
SpectraParameterSetter.VIEW_RANGE_BOX]
if key[0] not in skip_im_setter and key[0] in im_setter.initial_settings:
im_setter.set_parameter(key, value)
if key[0] in cv_setter.initial_settings:
cv_setter.set_parameter(key, value)
Expand Down
106 changes: 64 additions & 42 deletions orangecontrib/spectroscopy/widgets/owspectra.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
VerticalPeakLine, float_to_str_decimals as strdec
from orangecontrib.spectroscopy.widgets.utils import \
SelectionGroupMixin, SelectionOutputsMixin

from orangecontrib.spectroscopy.widgets.visual_settings import FloatOrUndefined

SELECT_SQUARE = 123
SELECT_POLYGON = 124
Expand Down Expand Up @@ -80,6 +80,8 @@ def selection_modifiers():

class ParameterSetter(CommonParameterSetter):

VIEW_RANGE_BOX = "View Range"

def __init__(self, master):
super().__init__()
self.master = master
Expand All @@ -98,8 +100,30 @@ def update_setters(self):
self.AXIS_TICKS_LABEL: self.FONT_SETTING,
self.LEGEND_LABEL: self.FONT_SETTING,
},
self.VIEW_RANGE_BOX: {
"X": {"xMin": (FloatOrUndefined(), None), "xMax": (FloatOrUndefined(), None)},
"Y": {"yMin": (FloatOrUndefined(), None), "yMax": (FloatOrUndefined(), None)}
}
}

def set_limits(**args):
for a, v in args.items():
if a == "xMin":
self.viewbox.fixed_range_x[0] = v
if a == "xMax":
self.viewbox.fixed_range_x[1] = v
if a == "yMin":
self.viewbox.fixed_range_y[0] = v
if a == "yMax":
self.viewbox.fixed_range_y[1] = v
self.viewbox.setRange(self.viewbox.viewRect())

self._setters[self.VIEW_RANGE_BOX] = {"X": set_limits, "Y": set_limits}

@property
def viewbox(self):
return self.master.plot.vb

@property
def title_item(self):
return self.master.plot.titleLabel
Expand Down Expand Up @@ -388,6 +412,9 @@ def __init__(self, graph):
self.sigRangeChanged.connect(self.resized)
self.sigResized.connect(self.resized)

self.fixed_range_x = [None, None]
self.fixed_range_y = [None, None]

self.tiptexts = None

def resized(self):
Expand Down Expand Up @@ -618,6 +645,42 @@ def autoRange(self):
self.pad_current_view_y()
self.pad_current_view_x()

def setRange(self, rect=None, xRange=None, yRange=None, **kwargs):
""" Always respect limitations in fixed_range_x and _y. """

if all(a is None for a in self.fixed_range_x + self.fixed_range_y):
super().setRange(rect=rect, xRange=xRange, yRange=yRange, **kwargs)

# if any limit is defined disregard padding
kwargs["padding"] = 0

if rect is not None:
rect = QRectF(rect)
if self.fixed_range_x[0] is not None:
rect.setLeft(self.fixed_range_x[0])
if self.fixed_range_x[1] is not None:
rect.setRight(self.fixed_range_x[1])
if self.fixed_range_y[0] is not None:
rect.setTop(self.fixed_range_y[0])
if self.fixed_range_y[1] is not None:
rect.setBottom(self.fixed_range_y[1])

if xRange is not None:
xRange = list(xRange)
if self.fixed_range_x[0] is not None:
xRange[0] = self.fixed_range_x[0]
if self.fixed_range_x[1] is not None:
xRange[1] = self.fixed_range_x[1]

if yRange is not None:
yRange = list(yRange)
if self.fixed_range_y[0] is not None:
yRange[0] = self.fixed_range_y[0]
if self.fixed_range_y[1] is not None:
yRange[1] = self.fixed_range_y[1]

super().setRange(rect=rect, xRange=xRange, yRange=yRange, **kwargs)

def cancel_zoom(self):
self.setMouseMode(self.PanMode)
self.rbScaleBox.hide()
Expand Down Expand Up @@ -699,10 +762,6 @@ class NoSuchCurve(ValueError):
class CurvePlot(QWidget, OWComponent, SelectionGroupMixin):

sample_seed = Setting(0, schema_only=True)
range_x1 = Setting(None)
range_x2 = Setting(None)
range_y1 = Setting(None)
range_y2 = Setting(None)
peak_labels_saved = Setting([], schema_only=True)
feature_color = ContextSetting(None)
color_individual = Setting(False) # color individual curves (in a cycle) if no feature_color
Expand Down Expand Up @@ -885,29 +944,6 @@ def __init__(self, parent: OWWidget, select=SELECTNONE):
save_graph.setShortcutContext(Qt.WidgetWithChildrenShortcut)
actions.append(save_graph)

range_menu = MenuFocus("Define view range", self)
range_action = QWidgetAction(self)
layout = QGridLayout()
range_box = gui.widgetBox(self, margin=5, orientation=layout)
range_box.setFocusPolicy(Qt.TabFocus)
self.range_e_x1 = lineEditFloatOrNone(None, self, "range_x1")
range_box.setFocusProxy(self.range_e_x1)
self.range_e_x2 = lineEditFloatOrNone(None, self, "range_x2")
layout.addWidget(QLabel("X"), 0, 0, Qt.AlignRight)
layout.addWidget(self.range_e_x1, 0, 1)
layout.addWidget(QLabel("-"), 0, 2)
layout.addWidget(self.range_e_x2, 0, 3)
self.range_e_y1 = lineEditFloatOrNone(None, self, "range_y1")
self.range_e_y2 = lineEditFloatOrNone(None, self, "range_y2")
layout.addWidget(QLabel("Y"), 1, 0, Qt.AlignRight)
layout.addWidget(self.range_e_y1, 1, 1)
layout.addWidget(QLabel("-"), 1, 2)
layout.addWidget(self.range_e_y2, 1, 3)
b = gui.button(None, self, "Apply", callback=self.set_limits)
layout.addWidget(b, 2, 3, Qt.AlignRight)
range_action.setDefaultWidget(range_box)
range_menu.addAction(range_action)

layout = QGridLayout()
self.plotview.setLayout(layout)
self.button = QPushButton("Menu", self.plotview)
Expand All @@ -918,7 +954,6 @@ def __init__(self, parent: OWWidget, select=SELECTNONE):
view_menu = MenuFocus(self)
self.button.setMenu(view_menu)
view_menu.addActions(actions)
view_menu.addMenu(range_menu)
self.addActions(actions)

self.color_individual_menu = QAction(
Expand Down Expand Up @@ -1024,15 +1059,6 @@ def cycle_color_attr(self):
self.feature_color = elements[next]
self.update_view()

def set_limits(self):
vr = self.plot.vb.viewRect()
x1 = self.range_x1 if self.range_x1 is not None else vr.left()
x2 = self.range_x2 if self.range_x2 is not None else vr.right()
y1 = self.range_y1 if self.range_y1 is not None else vr.top()
y2 = self.range_y2 if self.range_y2 is not None else vr.bottom()
self.plot.vb.setXRange(x1, x2)
self.plot.vb.setYRange(y1, y2)

def grid_changed(self):
self.show_grid = not self.show_grid
self.grid_apply()
Expand Down Expand Up @@ -1143,10 +1169,6 @@ def resized(self):
else:
self.label.setPos(vr.bottomRight())
xd, yd = self.important_decimals
self.range_e_x1.setPlaceholderText(strdec(vr.left(), xd))
self.range_e_x2.setPlaceholderText(strdec(vr.right(), xd))
self.range_e_y1.setPlaceholderText(strdec(vr.top(), yd))
self.range_e_y2.setPlaceholderText(strdec(vr.bottom(), yd))

def make_selection(self, data_indices):
add_to_group, add_group, remove = selection_modifiers()
Expand Down
33 changes: 33 additions & 0 deletions orangecontrib/spectroscopy/widgets/visual_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from AnyQt.QtWidgets import QLineEdit

from orangewidget.utils.visual_settings_dlg import _add_control, _set_control_value

from orangecontrib.spectroscopy.widgets.gui import FloatOrEmptyValidator, floatornone, str_or_empty


class FloatOrUndefined:
pass


class FloatOrEmptyLineEdit(QLineEdit):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
validator = FloatOrEmptyValidator(self, allow_empty=True)
self.setValidator(validator)

def setValue(self, value):
self.setText(str_or_empty(value))


@_add_control.register(FloatOrUndefined)
def _(_: FloatOrUndefined, value, key, signal):
line_edit = FloatOrEmptyLineEdit()
line_edit.setValue(value)
line_edit.textChanged.connect(lambda text: signal.emit(key, floatornone(text)))
return line_edit


@_set_control_value.register(FloatOrEmptyLineEdit)
def _(edit: QLineEdit, value: str):
edit.setValue(value)

0 comments on commit 414d52e

Please sign in to comment.