summaryrefslogtreecommitdiff
path: root/src/silx/gui/data/DataViewerSelector.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/silx/gui/data/DataViewerSelector.py')
-rw-r--r--src/silx/gui/data/DataViewerSelector.py175
1 files changed, 175 insertions, 0 deletions
diff --git a/src/silx/gui/data/DataViewerSelector.py b/src/silx/gui/data/DataViewerSelector.py
new file mode 100644
index 0000000..a1e9947
--- /dev/null
+++ b/src/silx/gui/data/DataViewerSelector.py
@@ -0,0 +1,175 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-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 a widget to be able to select the available view
+of the DataViewer.
+"""
+from __future__ import division
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "12/02/2019"
+
+import weakref
+import functools
+from silx.gui import qt
+import silx.utils.weakref
+
+
+class DataViewerSelector(qt.QWidget):
+ """Widget to be able to select a custom view from the DataViewer"""
+
+ def __init__(self, parent=None, dataViewer=None):
+ """Constructor
+
+ :param QWidget parent: The parent of the widget
+ :param DataViewer dataViewer: The connected `DataViewer`
+ """
+ super(DataViewerSelector, self).__init__(parent)
+
+ self.__group = None
+ self.__buttons = {}
+ self.__buttonLayout = None
+ self.__buttonDummy = None
+ self.__dataViewer = None
+
+ # Create the fixed layout
+ self.setLayout(qt.QHBoxLayout())
+ layout = self.layout()
+ layout.setContentsMargins(0, 0, 0, 0)
+ self.__buttonLayout = qt.QHBoxLayout()
+ self.__buttonLayout.setContentsMargins(0, 0, 0, 0)
+ layout.addLayout(self.__buttonLayout)
+ layout.addStretch(1)
+
+ if dataViewer is not None:
+ self.setDataViewer(dataViewer)
+
+ def __updateButtons(self):
+ if self.__group is not None:
+ self.__group.deleteLater()
+
+ # Clean up
+ for _, b in self.__buttons.items():
+ b.deleteLater()
+ if self.__buttonDummy is not None:
+ self.__buttonDummy.deleteLater()
+ self.__buttonDummy = None
+ self.__buttons = {}
+ self.__buttonDummy = None
+
+ self.__group = qt.QButtonGroup(self)
+ if self.__dataViewer is None:
+ return
+
+ iconSize = qt.QSize(16, 16)
+
+ for view in self.__dataViewer.getReachableViews():
+ label = view.label()
+ icon = view.icon()
+ button = qt.QPushButton(label)
+ button.setIcon(icon)
+ button.setIconSize(iconSize)
+ button.setCheckable(True)
+ # the weak objects are needed to be able to destroy the widget safely
+ weakView = weakref.ref(view)
+ weakMethod = silx.utils.weakref.WeakMethodProxy(self.__setDisplayedView)
+ callback = functools.partial(weakMethod, weakView)
+ button.clicked.connect(callback)
+ self.__buttonLayout.addWidget(button)
+ self.__group.addButton(button)
+ self.__buttons[view] = button
+
+ button = qt.QPushButton("Dummy")
+ button.setCheckable(True)
+ button.setVisible(False)
+ self.__buttonLayout.addWidget(button)
+ self.__group.addButton(button)
+ self.__buttonDummy = button
+
+ self.__updateButtonsVisibility()
+ self.__displayedViewChanged(self.__dataViewer.displayedView())
+
+ def setDataViewer(self, dataViewer):
+ """Define the dataviewer connected to this status bar
+
+ :param DataViewer dataViewer: The connected `DataViewer`
+ """
+ if self.__dataViewer is dataViewer:
+ return
+ if self.__dataViewer is not None:
+ self.__dataViewer.dataChanged.disconnect(self.__updateButtonsVisibility)
+ self.__dataViewer.displayedViewChanged.disconnect(self.__displayedViewChanged)
+ self.__dataViewer = dataViewer
+ if self.__dataViewer is not None:
+ self.__dataViewer.dataChanged.connect(self.__updateButtonsVisibility)
+ self.__dataViewer.displayedViewChanged.connect(self.__displayedViewChanged)
+ self.__updateButtons()
+
+ def setFlat(self, isFlat):
+ """Set the flat state of all the buttons.
+
+ :param bool isFlat: True to display the buttons flatten.
+ """
+ for b in self.__buttons.values():
+ b.setFlat(isFlat)
+ self.__buttonDummy.setFlat(isFlat)
+
+ def __displayedViewChanged(self, view):
+ """Called on displayed view changes"""
+ selectedButton = self.__buttons.get(view, self.__buttonDummy)
+ selectedButton.setChecked(True)
+
+ def __setDisplayedView(self, refView, clickEvent=None):
+ """Display a data using the requested view
+
+ :param DataView view: Requested view
+ :param clickEvent: Event sent by the clicked event
+ """
+ if self.__dataViewer is None:
+ return
+ view = refView()
+ if view is None:
+ return
+ self.__dataViewer.setDisplayedView(view)
+
+ def __checkAvailableButtons(self):
+ views = set(self.__dataViewer.getReachableViews())
+ if views == set(self.__buttons.keys()):
+ return
+ # Recreate all the buttons
+ # TODO: We dont have to create everything again
+ # We expect the views stay quite stable
+ self.__updateButtons()
+
+ def __updateButtonsVisibility(self):
+ """Called on data changed"""
+ if self.__dataViewer is None:
+ for b in self.__buttons.values():
+ b.setVisible(False)
+ else:
+ self.__checkAvailableButtons()
+ availableViews = set(self.__dataViewer.currentAvailableViews())
+ for view, button in self.__buttons.items():
+ button.setVisible(view in availableViews)