summaryrefslogtreecommitdiff
path: root/silx/gui/plot/_BaseMaskToolsWidget.py
diff options
context:
space:
mode:
Diffstat (limited to 'silx/gui/plot/_BaseMaskToolsWidget.py')
-rw-r--r--silx/gui/plot/_BaseMaskToolsWidget.py124
1 files changed, 64 insertions, 60 deletions
diff --git a/silx/gui/plot/_BaseMaskToolsWidget.py b/silx/gui/plot/_BaseMaskToolsWidget.py
index 91bbe1c..35a48ae 100644
--- a/silx/gui/plot/_BaseMaskToolsWidget.py
+++ b/silx/gui/plot/_BaseMaskToolsWidget.py
@@ -27,17 +27,19 @@
"""
from __future__ import division
-
__authors__ = ["T. Vincent", "P. Knobel"]
__license__ = "MIT"
-__date__ = "20/04/2017"
+__date__ = "02/10/2017"
import os
import numpy
from silx.gui import qt, icons
+from silx.gui.widgets.FloatEdit import FloatEdit
+from silx.gui.plot.Colormap import Colormap
from silx.gui.plot.Colors import rgba
+from .actions.mode import PanModeAction
class BaseMask(qt.QObject):
@@ -353,24 +355,38 @@ class BaseMaskToolsWidget(qt.QWidget):
sigMaskChanged = qt.Signal()
_maxLevelNumber = 255
- def __init__(self, parent=None, plot=None):
+ def __init__(self, parent=None, plot=None, mask=None):
+ """
+
+ :param parent: Parent QWidget
+ :param plot: Plot widget on which to operate
+ :param mask: Instance of subclass of :class:`BaseMask`
+ (e.g. :class:`ImageMask`)
+ """
+ super(BaseMaskToolsWidget, self).__init__(parent)
# register if the user as force a color for the corresponding mask level
self._defaultColors = numpy.ones((self._maxLevelNumber + 1), dtype=numpy.bool)
# overlays colors set by the user
self._overlayColors = numpy.zeros((self._maxLevelNumber + 1, 3), dtype=numpy.float32)
+ # as parent have to be the first argument of the widget to fit
+ # QtDesigner need but here plot can't be None by default.
+ assert plot is not None
self._plot = plot
self._maskName = '__MASK_TOOLS_%d' % id(self) # Legend of the mask
- self._colormap = {
- 'name': None,
- 'normalization': 'linear',
- 'autoscale': False,
- 'vmin': 0, 'vmax': self._maxLevelNumber,
- 'colors': None}
+ self._colormap = Colormap(name="",
+ normalization='linear',
+ vmin=0,
+ vmax=self._maxLevelNumber,
+ colors=None)
self._defaultOverlayColor = rgba('gray') # Color of the mask
self._setMaskColors(1, 0.5)
+ if not isinstance(mask, BaseMask):
+ raise TypeError("mask is not an instance of BaseMask")
+ self._mask = mask
+
self._mask.sigChanged.connect(self._updatePlotMask)
self._mask.sigChanged.connect(self._emitSigMaskChanged)
@@ -378,12 +394,12 @@ class BaseMaskToolsWidget(qt.QWidget):
self._lastPencilPos = None
self._multipleMasks = 'exclusive'
- super(BaseMaskToolsWidget, self).__init__(parent)
-
self._maskFileDir = qt.QDir.home().absolutePath()
self.plot.sigInteractiveModeChanged.connect(
self._interactiveModeChanged)
+ self._initWidgets()
+
def _emitSigMaskChanged(self):
"""Notify mask changes"""
self.sigMaskChanged.emit()
@@ -570,17 +586,10 @@ class BaseMaskToolsWidget(qt.QWidget):
"""Init drawing tools widgets"""
layout = qt.QVBoxLayout()
- # Draw tools
- self.browseAction = qt.QAction(
- icons.getQIcon('normal'), 'Browse', None)
- self.browseAction.setShortcut(qt.QKeySequence(qt.Qt.Key_B))
- self.browseAction.setToolTip(
- 'Disables drawing tools, enables zooming interaction mode'
- ' <b>B</b>')
- self.browseAction.setCheckable(True)
- self.browseAction.triggered.connect(self._activeBrowseMode)
+ self.browseAction = PanModeAction(self.plot, self.plot)
self.addAction(self.browseAction)
+ # Draw tools
self.rectAction = qt.QAction(
icons.getQIcon('shape-rectangle'), 'Rectangle selection', None)
self.rectAction.setToolTip(
@@ -608,23 +617,22 @@ class BaseMaskToolsWidget(qt.QWidget):
'Pencil tool: (Un)Mask using a pencil <b>P</b>')
self.pencilAction.setCheckable(True)
self.pencilAction.triggered.connect(self._activePencilMode)
- self.addAction(self.polygonAction)
+ self.addAction(self.pencilAction)
self.drawActionGroup = qt.QActionGroup(self)
self.drawActionGroup.setExclusive(True)
- self.drawActionGroup.addAction(self.browseAction)
self.drawActionGroup.addAction(self.rectAction)
self.drawActionGroup.addAction(self.polygonAction)
self.drawActionGroup.addAction(self.pencilAction)
- self.browseAction.setChecked(True)
-
- self.drawButtons = {}
- for action in self.drawActionGroup.actions():
+ actions = (self.browseAction, self.rectAction,
+ self.polygonAction, self.pencilAction)
+ drawButtons = []
+ for action in actions:
btn = qt.QToolButton()
btn.setDefaultAction(action)
- self.drawButtons[action.text()] = btn
- container = self._hboxWidget(*self.drawButtons.values())
+ drawButtons.append(btn)
+ container = self._hboxWidget(*drawButtons)
layout.addWidget(container)
# Mask/Unmask radio buttons
@@ -644,10 +652,7 @@ class BaseMaskToolsWidget(qt.QWidget):
self.maskStateWidget = self._hboxWidget(maskRadioBtn, unmaskRadioBtn)
layout.addWidget(self.maskStateWidget)
- # Connect mask state widget visibility with browse action
- self.maskStateWidget.setHidden(self.browseAction.isChecked())
- self.browseAction.toggled[bool].connect(
- self.maskStateWidget.setHidden)
+ self.maskStateWidget.setHidden(True)
# Pencil settings
self.pencilSetting = self._createPencilSettings(None)
@@ -752,15 +757,11 @@ class BaseMaskToolsWidget(qt.QWidget):
form = qt.QFormLayout()
- self.minLineEdit = qt.QLineEdit()
- self.minLineEdit.setText('0')
- self.minLineEdit.setValidator(qt.QDoubleValidator())
+ self.minLineEdit = FloatEdit(self, value=0)
self.minLineEdit.setEnabled(False)
form.addRow('Min:', self.minLineEdit)
- self.maxLineEdit = qt.QLineEdit()
- self.maxLineEdit.setText('0')
- self.maxLineEdit.setValidator(qt.QDoubleValidator())
+ self.maxLineEdit = FloatEdit(self, value=0)
self.maxLineEdit.setEnabled(False)
form.addRow('Max:', self.maxLineEdit)
@@ -790,8 +791,9 @@ class BaseMaskToolsWidget(qt.QWidget):
"""Reset drawing action when disabling widget"""
if (event.type() == qt.QEvent.EnabledChange and
not self.isEnabled() and
- not self.browseAction.isChecked()):
- self.browseAction.trigger() # Disable drawing tool
+ self.drawActionGroup.checkedAction()):
+ # Disable drawing tool by setting interaction to zoom
+ self.browseAction.trigger()
def save(self, filename, kind):
"""Save current mask in a file
@@ -839,7 +841,7 @@ class BaseMaskToolsWidget(qt.QWidget):
# Set no mask level
colors[0] = (0., 0., 0., 0.)
- self._colormap['colors'] = colors
+ self._colormap.setColormapLUT(colors)
def resetMaskColors(self, level=None):
"""Reset the mask color at the given level to be defaultColors
@@ -928,10 +930,11 @@ class BaseMaskToolsWidget(qt.QWidget):
If changed from elsewhere, disable drawing tool
"""
if source is not self:
- # Do not trigger browseAction to avoid to call
- # self.plot.setInteractiveMode
- self.browseAction.setChecked(True)
+ self.pencilAction.setChecked(False)
+ self.rectAction.setChecked(False)
+ self.polygonAction.setChecked(False)
self._releaseDrawingMode()
+ self._updateDrawingModeWidgets()
def _releaseDrawingMode(self):
"""Release the drawing mode if is was used"""
@@ -940,16 +943,6 @@ class BaseMaskToolsWidget(qt.QWidget):
self.plot.sigPlotSignal.disconnect(self._plotDrawEvent)
self._drawingMode = None
- def _activeBrowseMode(self):
- """Handle browse action mode triggered by user.
-
- Set plot interactive mode only when
- the user is triggering the browse action.
- """
- self._releaseDrawingMode()
- self.plot.setInteractiveMode('zoom', source=self)
- self._updateDrawingModeWidgets()
-
def _activeRectMode(self):
"""Handle rect action mode triggering"""
self._releaseDrawingMode()
@@ -981,6 +974,7 @@ class BaseMaskToolsWidget(qt.QWidget):
self._updateDrawingModeWidgets()
def _updateDrawingModeWidgets(self):
+ self.maskStateWidget.setVisible(self._drawingMode is not None)
self.pencilSetting.setVisible(self._drawingMode == 'pencil')
# Handle plot drawing events
@@ -1032,20 +1026,20 @@ class BaseMaskToolsWidget(qt.QWidget):
if self.belowThresholdAction.isChecked():
if self.minLineEdit.text():
self._mask.updateBelowThreshold(self.levelSpinBox.value(),
- float(self.minLineEdit.text()))
+ self.minLineEdit.value())
self._mask.commit()
elif self.betweenThresholdAction.isChecked():
if self.minLineEdit.text() and self.maxLineEdit.text():
- min_ = float(self.minLineEdit.text())
- max_ = float(self.maxLineEdit.text())
+ min_ = self.minLineEdit.value()
+ max_ = self.maxLineEdit.value()
self._mask.updateBetweenThresholds(self.levelSpinBox.value(),
min_, max_)
self._mask.commit()
elif self.aboveThresholdAction.isChecked():
if self.maxLineEdit.text():
- max_ = float(self.maxLineEdit.text())
+ max_ = float(self.maxLineEdit.value())
self._mask.updateAboveThreshold(self.levelSpinBox.value(),
max_)
self._mask.commit()
@@ -1059,7 +1053,7 @@ class BaseMaskToolsWidget(qt.QWidget):
class BaseMaskToolsDockWidget(qt.QDockWidget):
"""Base class for :class:`MaskToolsWidget` and
- :class:`ScatterMaskToolsWidget`
+ :class:`ScatterMaskToolsWidget`.
For integration in a :class:`PlotWindow`.
@@ -1069,10 +1063,15 @@ class BaseMaskToolsDockWidget(qt.QDockWidget):
sigMaskChanged = qt.Signal()
- def __init__(self, parent=None, name='Mask'):
+ def __init__(self, parent=None, name='Mask', widget=None):
super(BaseMaskToolsDockWidget, self).__init__(parent)
self.setWindowTitle(name)
+ if not isinstance(widget, BaseMaskToolsWidget):
+ raise TypeError("BaseMaskToolsDockWidget requires a MaskToolsWidget")
+ self.setWidget(widget)
+ self.widget().sigMaskChanged.connect(self._emitSigMaskChanged)
+
self.layout().setContentsMargins(0, 0, 0, 0)
self.dockLocationChanged.connect(self._dockLocationChanged)
self.topLevelChanged.connect(self._topLevelChanged)
@@ -1107,6 +1106,11 @@ class BaseMaskToolsDockWidget(qt.QDockWidget):
"""
return self.widget().setSelectionMask(mask, copy=copy)
+ def resetSelectionMask(self):
+ """Reset the mask to an array of zeros with the shape of the
+ current data."""
+ self.widget().resetSelectionMask()
+
def toggleViewAction(self):
"""Returns a checkable action that shows or closes this widget.