diff options
author | Picca Frédéric-Emmanuel <picca@synchrotron-soleil.fr> | 2017-08-18 14:48:52 +0200 |
---|---|---|
committer | Picca Frédéric-Emmanuel <picca@synchrotron-soleil.fr> | 2017-08-18 14:48:52 +0200 |
commit | f7bdc2acff3c13a6d632c28c4569690ab106eed7 (patch) | |
tree | 9d67cdb7152ee4e711379e03fe0546c7c3b97303 /silx/gui/plot/AlphaSlider.py |
Import Upstream version 0.5.0+dfsg
Diffstat (limited to 'silx/gui/plot/AlphaSlider.py')
-rw-r--r-- | silx/gui/plot/AlphaSlider.py | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/silx/gui/plot/AlphaSlider.py b/silx/gui/plot/AlphaSlider.py new file mode 100644 index 0000000..ab2e5aa --- /dev/null +++ b/silx/gui/plot/AlphaSlider.py @@ -0,0 +1,300 @@ +# coding: utf-8 +# /*########################################################################## +# +# Copyright (c) 2017 European Synchrotron Radiation Facility +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# +# ###########################################################################*/ +"""This module defines slider widgets interacting with the transparency +of an image on a :class:`PlotWidget` + +Classes: +-------- + +- :class:`BaseAlphaSlider` (abstract class) +- :class:`NamedImageAlphaSlider` +- :class:`ActiveImageAlphaSlider` + +Example: +-------- + +This widget can, for instance, be added to a plot toolbar. + +.. code-block:: python + + import numpy + from silx.gui import qt + from silx.gui.plot import PlotWidget + from silx.gui.plot.ImageAlphaSlider import NamedImageAlphaSlider + + app = qt.QApplication([]) + pw = PlotWidget() + + img0 = numpy.arange(200*150).reshape((200, 150)) + pw.addImage(img0, legend="my background", z=0, origin=(50, 50)) + + x, y = numpy.meshgrid(numpy.linspace(-10, 10, 200), + numpy.linspace(-10, 5, 150), + indexing="ij") + img1 = numpy.asarray(numpy.sin(x * y) / (x * y), + dtype='float32') + + pw.addImage(img1, legend="my data", z=1, + replace=False) + + alpha_slider = NamedImageAlphaSlider(parent=pw, + plot=pw, + legend="my data") + alpha_slider.setOrientation(qt.Qt.Horizontal) + + toolbar = qt.QToolBar("plot", pw) + toolbar.addWidget(alpha_slider) + pw.addToolBar(toolbar) + + pw.show() + app.exec_() + +""" + +__authors__ = ["P. Knobel"] +__license__ = "MIT" +__date__ = "24/03/2017" + +import logging + +from silx.gui import qt + +_logger = logging.getLogger(__name__) + + +class BaseAlphaSlider(qt.QSlider): + """Slider widget to be used in a plot toolbar to control the + transparency of a plot primitive (image, scatter or curve). + + Internally, the slider stores its state as an integer between + 0 and 255. This is the value emitted by the :attr:`valueChanged` + signal. + + The method :meth:`getAlpha` returns the corresponding opacity/alpha + as a float between 0. and 1. (with a step of :math:`\frac{1}{255}`). + + You must subclass this class and implement :meth:`getItem`. + """ + sigAlphaChanged = qt.Signal(float) + """Emits the alpha value when the slider's value changes, + as a float between 0. and 1.""" + + def __init__(self, parent=None, plot=None): + """ + + :param parent: Parent QWidget + :param plot: Parent plot widget + """ + assert plot is not None + super(BaseAlphaSlider, self).__init__(parent) + + self.plot = plot + + self.setRange(0, 255) + + # if already connected to an item, use its alpha as initial value + if self.getItem() is None: + self.setValue(255) + self.setEnabled(False) + else: + alpha = self.getItem().getAlpha() + self.setValue(round(255*alpha)) + + self.valueChanged.connect(self._valueChanged) + + def getItem(self): + """You must implement this class to define which item + to work on. It must return an item that inherits + :class:`silx.gui.plot.items.core.AlphaMixIn`. + + :return: Item on which to operate, or None + :rtype: :class:`silx.plot.items.Item` + """ + raise NotImplementedError( + "BaseAlphaSlider must be subclassed to " + + "implement getItem()") + + def getAlpha(self): + """Get the opacity, as a float between 0. and 1. + + :return: Alpha value in [0., 1.] + :rtype: float + """ + return self.value() / 255. + + def _valueChanged(self, value): + self._updateItem() + self.sigAlphaChanged.emit(value / 255.) + + def _updateItem(self): + """Update the item's alpha channel. + """ + item = self.getItem() + if item is not None: + item.setAlpha(self.getAlpha()) + + +class ActiveImageAlphaSlider(BaseAlphaSlider): + """Slider widget to be used in a plot toolbar to control the + transparency of the **active image**. + + :param parent: Parent QWidget + :param plot: Plot on which to operate + + See documentation of :class:`BaseAlphaSlider` + """ + def __init__(self, parent=None, plot=None): + """ + + :param parent: Parent QWidget + :param plot: Plot widget on which to operate + """ + super(ActiveImageAlphaSlider, self).__init__(parent, plot) + plot.sigActiveImageChanged.connect(self._activeImageChanged) + + def getItem(self): + return self.plot.getActiveImage() + + def _activeImageChanged(self, previous, new): + """Activate or deactivate slider depending on presence of a new + active image. + Apply transparency value to new active image. + + :param previous: Legend of previous active image, or None + :param new: Legend of new active image, or None + """ + if new is not None and not self.isEnabled(): + self.setEnabled(True) + elif new is None and self.isEnabled(): + self.setEnabled(False) + + self._updateItem() + + +class NamedItemAlphaSlider(BaseAlphaSlider): + """Slider widget to be used in a plot toolbar to control the + transparency of an item (defined by its kind and legend). + + :param parent: Parent QWidget + :param plot: Plot on which to operate + :param str kind: Kind of item whose transparency is to be + controlled: "scatter", "image" or "curve". + :param str legend: Legend of item whose transparency is to be + controlled. + """ + def __init__(self, parent=None, plot=None, + kind=None, legend=None): + self._item_legend = legend + self._item_kind = kind + + super(NamedItemAlphaSlider, self).__init__(parent, plot) + + self._updateState() + plot.sigContentChanged.connect(self._onContentChanged) + + def _onContentChanged(self, action, kind, legend): + if legend == self._item_legend and kind == self._item_kind: + if action == "add": + self.setEnabled(True) + elif action == "remove": + self.setEnabled(False) + + def _updateState(self): + """Enable or disable widget based on item's availability.""" + if self.getItem() is not None: + self.setEnabled(True) + else: + self.setEnabled(False) + + def getItem(self): + """Return plot item currently associated to this widget (can be + a curve, an image, a scatter...) + + :rtype: subclass of :class:`silx.gui.plot.items.Item`""" + if self._item_legend is None or self._item_kind is None: + return None + return self.plot._getItem(kind=self._item_kind, + legend=self._item_legend) + + def setLegend(self, legend): + """Associate a different item (of the same kind) to the slider. + + :param legend: New legend of item whose transparency is to be + controlled. + """ + self._item_legend = legend + self._updateState() + + def getLegend(self): + """Return legend of the item currently controlled by this slider. + + :return: Image legend associated to the slider + """ + return self._item_kind + + def setItemKind(self, legend): + """Associate a different item (of the same kind) to the slider. + + :param legend: New legend of item whose transparency is to be + controlled. + """ + self._item_legend = legend + self._updateState() + + def getItemKind(self): + """Return kind of the item currently controlled by this slider. + + :return: Item kind ("image", "scatter"...) + :rtype: str on None + """ + return self._item_kind + + +class NamedImageAlphaSlider(NamedItemAlphaSlider): + """Slider widget to be used in a plot toolbar to control the + transparency of an image (defined by its legend). + + :param parent: Parent QWidget + :param plot: Plot on which to operate + :param str legend: Legend of image whose transparency is to be + controlled. + """ + def __init__(self, parent=None, plot=None, legend=None): + NamedItemAlphaSlider.__init__(self, parent, plot, + kind="image", legend=legend) + + +class NamedScatterAlphaSlider(NamedItemAlphaSlider): + """Slider widget to be used in a plot toolbar to control the + transparency of a scatter (defined by its legend). + + :param parent: Parent QWidget + :param plot: Plot on which to operate + :param str legend: Legend of scatter whose transparency is to be + controlled. + """ + def __init__(self, parent=None, plot=None, legend=None): + NamedItemAlphaSlider.__init__(self, parent, plot, + kind="scatter", legend=legend) |