# 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__ = "26/01/2017" import weakref import functools from silx.gui import qt from silx.gui.data.DataViewer import DataViewer 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.__buttonDummy = None self.__dataViewer = None if dataViewer is not None: self.setDataViewer(dataViewer) def __updateButtons(self): if self.__group is not None: self.__group.deleteLater() self.__buttons = {} self.__buttonDummy = None self.__group = qt.QButtonGroup(self) self.setLayout(qt.QHBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) if self.__dataViewer is None: return iconSize = qt.QSize(16, 16) for view in self.__dataViewer.availableViews(): 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.layout().addWidget(button) self.__group.addButton(button) self.__buttons[view] = button button = qt.QPushButton("Dummy") button.setCheckable(True) button.setVisible(False) self.layout().addWidget(button) self.__group.addButton(button) self.__buttonDummy = button self.layout().addStretch(1) 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 __updateButtonsVisibility(self): """Called on data changed""" if self.__dataViewer is None: for b in self.__buttons.values(): b.setVisible(False) else: availableViews = set(self.__dataViewer.currentAvailableViews()) for view, button in self.__buttons.items(): button.setVisible(view in availableViews)