summaryrefslogtreecommitdiff
path: root/silx/gui/plot3d/_model/core.py
diff options
context:
space:
mode:
Diffstat (limited to 'silx/gui/plot3d/_model/core.py')
-rw-r--r--silx/gui/plot3d/_model/core.py372
1 files changed, 0 insertions, 372 deletions
diff --git a/silx/gui/plot3d/_model/core.py b/silx/gui/plot3d/_model/core.py
deleted file mode 100644
index e8e0820..0000000
--- a/silx/gui/plot3d/_model/core.py
+++ /dev/null
@@ -1,372 +0,0 @@
-# coding: utf-8
-# /*##########################################################################
-#
-# Copyright (c) 2017-2018 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 provides base classes to implement models for 3D scene content.
-"""
-
-from __future__ import absolute_import, division
-
-__authors__ = ["T. Vincent"]
-__license__ = "MIT"
-__date__ = "11/01/2018"
-
-
-import collections
-import weakref
-
-from ....utils.weakref import WeakMethodProxy
-from ... import qt
-
-
-class BaseRow(qt.QObject):
- """Base class for rows of the tree model.
-
- The root node parent MUST be set to the QAbstractItemModel it belongs to.
- By default item is enabled.
-
- :param children: Iterable of BaseRow to start with (not signaled)
- """
-
- def __init__(self, children=()):
- self.__modelRef = None
- self.__parentRef = None
- super(BaseRow, self).__init__()
- self.__children = []
- for row in children:
- assert isinstance(row, BaseRow)
- row.setParent(self)
- self.__children.append(row)
- self.__flags = collections.defaultdict(lambda: qt.Qt.ItemIsEnabled)
- self.__tooltip = None
-
- def setParent(self, parent):
- """Override :meth:`QObject.setParent` to cache model and parent"""
- self.__parentRef = None if parent is None else weakref.ref(parent)
-
- if isinstance(parent, qt.QAbstractItemModel):
- model = parent
- elif isinstance(parent, BaseRow):
- model = parent.model()
- else:
- model = None
-
- self._updateModel(model)
-
- super(BaseRow, self).setParent(parent)
-
- def parent(self):
- """Override :meth:`QObject.setParent` to use cached parent
-
- :rtype: Union[QObject, None]"""
- return self.__parentRef() if self.__parentRef is not None else None
-
- def _updateModel(self, model):
- """Update the model this row belongs to"""
- if model != self.model():
- self.__modelRef = weakref.ref(model) if model is not None else None
- for child in self.children():
- child._updateModel(model)
-
- def model(self):
- """Return the model this node belongs to or None if not in a model.
-
- :rtype: Union[QAbstractItemModel, None]
- """
- return self.__modelRef() if self.__modelRef is not None else None
-
- def index(self, column=0):
- """Return corresponding index in the model or None if not in a model.
-
- :param int column: The column to make the index for
- :rtype: Union[QModelIndex, None]
- """
- parent = self.parent()
- model = self.model()
-
- if model is None: # Not in a model
- return None
- elif parent is model: # Root node
- return qt.QModelIndex()
- else:
- index = parent.index()
- row = parent.children().index(self)
- return model.index(row, column, index)
-
- def columnCount(self):
- """Returns number of columns (default: 2)
-
- :rtype: int
- """
- return 2
-
- def children(self):
- """Returns the list of children nodes
-
- :rtype: tuple of Node
- """
- return tuple(self.__children)
-
- def rowCount(self):
- """Returns number of rows
-
- :rtype: int
- """
- return len(self.__children)
-
- def addRow(self, row, index=None):
- """Add a node to the children
-
- :param BaseRow row: The node to add
- :param int index: The index at which to insert it or
- None to append
- """
- if index is None:
- index = self.rowCount()
- assert index <= self.rowCount()
-
- model = self.model()
-
- if model is not None:
- parent = self.index()
- model.beginInsertRows(parent, index, index)
-
- self.__children.insert(index, row)
- row.setParent(self)
-
- if model is not None:
- model.endInsertRows()
-
- def removeRow(self, row):
- """Remove a row from the children list.
-
- It removes either a node or a row index.
-
- :param row: BaseRow object or index of row to remove
- :type row: Union[BaseRow, int]
- """
- if isinstance(row, BaseRow):
- row = self.__children.index(row)
- else:
- row = int(row)
- assert row < self.rowCount()
-
- model = self.model()
-
- if model is not None:
- index = self.index()
- model.beginRemoveRows(index, row, row)
-
- node = self.__children.pop(row)
- node.setParent(None)
-
- if model is not None:
- model.endRemoveRows()
-
- def data(self, column, role):
- """Returns data for given column and role
-
- :param int column: Column index for this row
- :param int role: The role to get
- :return: Corresponding data (Default: None)
- """
- if role == qt.Qt.ToolTipRole and self.__tooltip is not None:
- return self.__tooltip
- else:
- return None
-
- def setData(self, column, value, role):
- """Set data for given column and role
-
- :param int column: Column index for this row
- :param value: The data to set
- :param int role: The role to set
- :return: True on success, False on failure
- :rtype: bool
- """
- return False
-
- def setToolTip(self, tooltip):
- """Set the tooltip of the whole row.
-
- If None there is no tooltip.
-
- :param Union[str, None] tooltip:
- """
- self.__tooltip = tooltip
-
- def setFlags(self, flags, column=None):
- """Set the static flags to return.
-
- Default is ItemIsEnabled for all columns.
-
- :param int column: The column for which to set the flags
- :param flags: Item flags
- """
- if column is None:
- self.__flags = collections.defaultdict(lambda: flags)
- else:
- self.__flags[column] = flags
-
- def flags(self, column):
- """Returns flags for given column
-
- :rtype: int
- """
- return self.__flags[column]
-
-
-class StaticRow(BaseRow):
- """Row with static data.
-
- :param tuple display: List of data for DisplayRole for each column
- :param dict roles: Optional mapping of roles to list of data.
- :param children: Iterable of BaseRow to start with (not signaled)
- """
-
- def __init__(self, display=('', None), roles=None, children=()):
- super(StaticRow, self).__init__(children)
- self._dataByRoles = {} if roles is None else roles
- self._dataByRoles[qt.Qt.DisplayRole] = display
-
- def data(self, column, role):
- if role in self._dataByRoles:
- data = self._dataByRoles[role]
- if column < len(data):
- return data[column]
- return super(StaticRow, self).data(column, role)
-
- def columnCount(self):
- return len(self._dataByRoles[qt.Qt.DisplayRole])
-
-
-class ProxyRow(BaseRow):
- """Provides a node to proxy a data accessible through functions.
-
- Warning: Only weak reference are kept on fget and fset.
-
- :param str name: The name of this node
- :param callable fget: A callable returning the data
- :param callable fset:
- An optional callable setting the data with data as a single argument.
- :param notify:
- An optional signal emitted when data has changed.
- :param callable toModelData:
- An optional callable to convert from fget
- callable to data returned by the model.
- :param callable fromModelData:
- An optional callable converting data provided to the model to
- data for fset.
- :param editorHint: Data to provide as UserRole for editor selection/setup
- """
-
- def __init__(self,
- name='',
- fget=None,
- fset=None,
- notify=None,
- toModelData=None,
- fromModelData=None,
- editorHint=None):
-
- super(ProxyRow, self).__init__()
- self.__name = name
- self.__editorHint = editorHint
-
- assert fget is not None
- self._fget = WeakMethodProxy(fget)
- self._fset = WeakMethodProxy(fset) if fset is not None else None
- if fset is not None:
- self.setFlags(qt.Qt.ItemIsEnabled | qt.Qt.ItemIsEditable, 1)
- self._toModelData = toModelData
- self._fromModelData = fromModelData
-
- if notify is not None:
- notify.connect(self._notified) # TODO support sigItemChanged flags
-
- def _notified(self, *args, **kwargs):
- """Send update to the model upon signal notifications"""
- index = self.index(column=1)
- model = self.model()
- if model is not None:
- model.dataChanged.emit(index, index)
-
- def data(self, column, role):
- if column == 0:
- if role == qt.Qt.DisplayRole:
- return self.__name
-
- elif column == 1:
- if role == qt.Qt.UserRole: # EditorHint
- return self.__editorHint
- elif role == qt.Qt.DisplayRole or (role == qt.Qt.EditRole and
- self._fset is not None):
- data = self._fget()
- if self._toModelData is not None:
- data = self._toModelData(data)
- return data
-
- return super(ProxyRow, self).data(column, role)
-
- def setData(self, column, value, role):
- if role == qt.Qt.EditRole and self._fset is not None:
- if self._fromModelData is not None:
- value = self._fromModelData(value)
- self._fset(value)
- return True
-
- return super(ProxyRow, self).setData(column, value, role)
-
-
-class ColorProxyRow(ProxyRow):
- """Provides a proxy to a QColor property.
-
- The color is returned through the decorative role.
-
- See :class:`ProxyRow`
- """
-
- def data(self, column, role):
- if column == 1: # Show color as decoration, not text
- if role == qt.Qt.DisplayRole:
- return None
- if role == qt.Qt.DecorationRole:
- role = qt.Qt.DisplayRole
- return super(ColorProxyRow, self).data(column, role)
-
-
-class AngleDegreeRow(ProxyRow):
- """ProxyRow patching display of column 1 to add degree symbol
-
- See :class:`ProxyRow`
- """
-
- def __init__(self, *args, **kwargs):
- super(AngleDegreeRow, self).__init__(*args, **kwargs)
-
- def data(self, column, role):
- if column == 1 and role == qt.Qt.DisplayRole:
- return u'%g°' % super(AngleDegreeRow, self).data(column, role)
- else:
- return super(AngleDegreeRow, self).data(column, role)