Skip to content

Commit

Permalink
Store active items instead of legends
Browse files Browse the repository at this point in the history
  • Loading branch information
t20100 committed Dec 8, 2023
1 parent ea8842b commit b8fe042
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 98 deletions.
179 changes: 82 additions & 97 deletions src/silx/gui/plot/PlotWidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ def setCurrentItem(self, item: Optional[items.Item]):
# Sync active item if needed
if (kind in plot._ACTIVE_ITEM_KINDS and
item is not plot._getActiveItem(kind)):
plot._setActiveItem(kind, item.getName())
plot._setActiveItem(kind, item)
else:
raise ValueError("Not an Item: %s" % str(item))

Expand Down Expand Up @@ -387,6 +387,7 @@ def __init__(self, parent=None, backend=None):
# Items handling
self.__items = []
self.__itemsToUpdate = [] # Used as an OrderedSet
self.__activeItems = {'curve': None, 'image': None, 'scatter': None}

self._dataRange = None

Expand All @@ -401,8 +402,6 @@ def __init__(self, parent=None, backend=None):
color=silx.config.DEFAULT_PLOT_ACTIVE_CURVE_COLOR,
linewidth=silx.config.DEFAULT_PLOT_ACTIVE_CURVE_LINEWIDTH,
)
self._activeLegend = {'curve': None, 'image': None,
'scatter': None}

# plot colors (updated later to sync backend)
self._foregroundColor = 0., 0., 0., 1.
Expand Down Expand Up @@ -1162,9 +1161,6 @@ def addCurve(self, x, y, legend=None, info=None,

legend = 'Unnamed curve 1.1' if legend is None else str(legend)

# Check if curve was previously active
wasActive = self.getActiveCurve(just_legend=True) == legend

if replace:
self._resetColorAndStyle()

Expand Down Expand Up @@ -1238,14 +1234,13 @@ def addCurve(self, x, y, legend=None, info=None,
else:
self._notifyContentChanged(curve)

if wasActive:
self.setActiveCurve(curve.getName())
elif self.getActiveCurveSelectionMode() == "legacy":
if self.getActiveCurve(just_legend=True) is None:
if len(self.getAllCurves(just_legend=True,
withhidden=False)) == 1:
if curve.isVisible():
self.setActiveCurve(curve.getName())
if curve is self.getActiveCurve() or (
self.getActiveCurveSelectionMode() == "legacy"
and self.getActiveCurve() is None
and len(self.getAllCurves(just_legend=True, withhidden=False)) == 1
and curve.isVisible()
):
self.setActiveCurve(curve)

if resetzoom:
# We ask for a zoom reset in order to handle the plot scaling
Expand Down Expand Up @@ -1402,9 +1397,6 @@ def addImage(self, data, legend=None, info=None,
"""
legend = "Unnamed Image 1.1" if legend is None else str(legend)

# Check if image was previously active
wasActive = self.getActiveImage(just_legend=True) == legend

data = numpy.array(data, copy=False)
assert data.ndim in (2, 3)

Expand Down Expand Up @@ -1470,8 +1462,8 @@ def addImage(self, data, legend=None, info=None,
else:
self._notifyContentChanged(image)

if len(self.getAllImages()) == 1 or wasActive:
self.setActiveImage(legend)
if len(self.getAllImages()) == 1 or image is self.getActiveImage():
self.setActiveImage(image)

if resetzoom:
# We ask for a zoom reset in order to handle the plot scaling
Expand Down Expand Up @@ -1530,10 +1522,6 @@ def addScatter(self, x, y, value, legend=None, colormap=None,
"""
legend = 'Unnamed scatter 1.1' if legend is None else str(legend)

# Check if scatter was previously active
wasActive = self._getActiveItem(kind='scatter',
just_legend=True) == legend

# Create/Update curve object
scatter = self._getItem(kind='scatter', legend=legend)
mustBeAdded = scatter is None
Expand Down Expand Up @@ -1579,8 +1567,8 @@ def addScatter(self, x, y, value, legend=None, colormap=None,

scatters = [item for item in self.getItems()
if isinstance(item, items.Scatter) and item.isVisible()]
if len(scatters) == 1 or wasActive:
self._setActiveItem('scatter', scatter.getName())
if len(scatters) == 1 or scatter is self.getActiveScatter():
self.setActiveScatter(scatter)

return legend

Expand Down Expand Up @@ -2153,7 +2141,7 @@ def setActiveCurve(self, legend):
'setActiveCurve(None) ignored due to active curve selection mode')
return

return self._setActiveItem(kind='curve', legend=legend)
return self._setActiveItem(kind='curve', item=legend)

def setActiveCurveSelectionMode(self, mode):
"""Sets the current selection mode.
Expand All @@ -2166,7 +2154,7 @@ def setActiveCurveSelectionMode(self, mode):
if mode != self._activeCurveSelectionMode:
self._activeCurveSelectionMode = mode
if mode == 'none': # reset active curve
self._setActiveItem(kind='curve', legend=None)
self._setActiveItem(kind='curve', item=None)

elif mode == 'legacy' and self.getActiveCurve() is None:
# Select an active curve
Expand Down Expand Up @@ -2205,7 +2193,7 @@ def setActiveImage(self, legend):
:param str legend: The legend associated to the image
or None to have no active image.
"""
return self._setActiveItem(kind='image', legend=legend)
return self._setActiveItem(kind='image', item=legend)

def getActiveScatter(self, just_legend=False):
"""Returns the currently active scatter.
Expand All @@ -2226,78 +2214,81 @@ def setActiveScatter(self, legend):
:param str legend: The legend associated to the scatter
or None to have no active scatter.
"""
return self._setActiveItem(kind='scatter', legend=legend)
return self._setActiveItem(kind='scatter', item=legend)

def _getActiveItem(self, kind, just_legend=False):
"""Return the currently active item of that kind if any
def _getActiveItem(
self,
kind: str | None,
just_legend: bool = False,
) -> items.Curve | items.Scatter | items.ImageBase | None:
"""Return the currently active item of given kind if any.
:param str kind: Type of item: 'curve', 'scatter' or 'image'
:param bool just_legend: True to get the legend,
False (default) to get the item
:return: legend or item or None if no active item
:param kind: Type of item: 'curve', 'scatter' or 'image'
:param just_legend:
True to get the item's legend, False (the default) to get the item
"""
assert kind in self._ACTIVE_ITEM_KINDS
item = self.__activeItems[kind]
if item is not None and just_legend:
return item.getName()
return item

if self._activeLegend[kind] is None:
return None
def _setActiveItem(
self,
kind: str,
item: items.Curve | items.ImageBase | items.Scatter | str | None,
) -> str | None:
"""Make the given item active.
Note: There is one active item per "kind" of item.
"""
assert kind in self._ACTIVE_ITEM_KINDS

item = self._getItem(kind, self._activeLegend[kind])
if item is None:
return None
legend = None
elif isinstance(item, items.Item):
legend = item.getName()
else:
legend = str(item)
item = self._getItem(kind, legend)
if item is None:
_logger.warning("This %s does not exist: %s", kind, legend)

return item.getName() if just_legend else item
oldActiveItem = self._getActiveItem(kind=kind)

def _setActiveItem(self, kind, legend):
"""Make the curve associated to legend the active curve.
if oldActiveItem is None and item is None:
return None

:param str kind: Type of item: 'curve' or 'image'
:param legend: The legend associated to the curve
or None to have no active curve.
:type legend: str or None
"""
assert kind in self._ACTIVE_ITEM_KINDS
if oldActiveItem is not None:
# Stop listening previous active item
oldActiveItem.sigItemChanged.disconnect(self._activeItemChanged)
# Curve specific: Reset highlight of previous active curve
if kind == 'curve':
oldActiveItem.setHighlighted(False)

self.__activeItems[kind] = item

xLabel = None
yLabel = None
yRightLabel = None

oldActiveItem = self._getActiveItem(kind=kind)

if oldActiveItem is not None: # Stop listening previous active image
oldActiveItem.sigItemChanged.disconnect(self._activeItemChanged)

# Curve specific: Reset highlight of previous active curve
if kind == 'curve' and oldActiveItem is not None:
oldActiveItem.setHighlighted(False)
if item is not None:
# Curve specific: handle highlight
if kind == 'curve':
item.setHighlightedStyle(self.getActiveCurveStyle())
item.setHighlighted(True)

if isinstance(item, items.LabelsMixIn):
xLabel = item.getXLabel()
if (isinstance(item, items.YAxisMixIn) and
item.getYAxis() == 'right'
):
yRightLabel = item.getYLabel()
else:
yLabel = item.getYLabel()

if legend is None:
self._activeLegend[kind] = None
else:
legend = str(legend)
item = self._getItem(kind, legend)
if item is None:
_logger.warning("This %s does not exist: %s", kind, legend)
self._activeLegend[kind] = None
else:
self._activeLegend[kind] = legend

# Curve specific: handle highlight
if kind == 'curve':
item.setHighlightedStyle(self.getActiveCurveStyle())
item.setHighlighted(True)

if isinstance(item, items.LabelsMixIn):
if item.getXLabel() is not None:
xLabel = item.getXLabel()
if item.getYLabel() is not None:
if (isinstance(item, items.YAxisMixIn) and
item.getYAxis() == 'right'):
yRightLabel = item.getYLabel()
else:
yLabel = item.getYLabel()

# Start listening new active item
item.sigItemChanged.connect(self._activeItemChanged)
# Start listening new active item
item.sigItemChanged.connect(self._activeItemChanged)

# Store current labels and update plot
self._xAxis._setCurrentLabel(xLabel)
Expand All @@ -2306,19 +2297,13 @@ def _setActiveItem(self, kind, legend):

self._setDirtyPlot()

activeLegend = self._activeLegend[kind]
if oldActiveItem is not None or activeLegend is not None:
if oldActiveItem is None:
oldActiveLegend = None
else:
oldActiveLegend = oldActiveItem.getName()
self.notify(
'active' + kind[0].upper() + kind[1:] + 'Changed',
updated=oldActiveLegend != activeLegend,
previous=oldActiveLegend,
legend=activeLegend)

return activeLegend
self.notify(
f"active{kind.capitalize()}Changed",
updated=oldActiveItem is not item,
previous=None if oldActiveItem is None else oldActiveItem.getName(),
legend=legend,
)
return legend

def _activeItemChanged(self, type_):
"""Listen for active item changed signal and broadcast signal
Expand Down
2 changes: 1 addition & 1 deletion src/silx/gui/plot/StatsWidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ def setCurrentItem(self, item):
kind = self.getKind(item)
if kind in plot._ACTIVE_ITEM_KINDS:
if plot._getActiveItem(kind) != item:
plot._setActiveItem(kind, item.getName())
plot._setActiveItem(kind, item)

def getLabel(self, item):
return item.getName()
Expand Down

0 comments on commit b8fe042

Please sign in to comment.