Skip to content

Commit 1615690

Browse files
committed
implemented EditChannelEvent, refactored ChannelEditor widget, bug fixes
1 parent dcadb89 commit 1615690

8 files changed

Lines changed: 528 additions & 322 deletions

File tree

src/pymapmanager/annotations/spineAnnotationsCore.py

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,25 +34,6 @@ def _buildDataFrame(self):
3434

3535
if len(allSpinesDf) > 0:
3636

37-
# abb removed 202508
38-
# if 0:
39-
# # abb 202504 reduce columns to existing channel keys
40-
# # the channel keys actually in the timepoint
41-
# existingChannelKeys = self.singleTimepoint.timepointMetadata().channelKeys
42-
# existingChannelKeys = set(existingChannelKeys)
43-
# # all possible channel keys
44-
# possibleChannelKeys = self._fullMap.getMapMetadata().possibleChannelKeys
45-
# possibleChannelKeys = set(possibleChannelKeys)
46-
# # the keys to remove
47-
# _removeChannelKeys = possibleChannelKeys - existingChannelKeys
48-
# # logger.info(f'existingChannelKeys:{existingChannelKeys} possibleChannelKeys:{possibleChannelKeys} _removeChannelKeys:{_removeChannelKeys}')
49-
# # logger.info(f'before drop _ch3_ num columns:{len(allSpinesDf.columns)}')
50-
# for _removeChannelKey in _removeChannelKeys:
51-
# _regExp = f'_ch{_removeChannelKey}_' # like _ch3_
52-
# logger.info(f' removing columns with _regExp:{_regExp}')
53-
# allSpinesDf = allSpinesDf[allSpinesDf.columns.drop(list(allSpinesDf.filter(regex=_regExp)))]
54-
# # logger.info(f'after drop _ch3_ num columns:{len(allSpinesDf.columns)}')
55-
5637
# when there is 1 spine, points[:] returns
5738
# <class 'pandas.core.series.Series'>
5839
try:

src/pymapmanager/interface/stackWidgets/base/mmWidget2.py

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,17 +54,15 @@ class pmmEventType(Enum):
5454
autoConnectSpine = auto()
5555

5656
setSlice = auto()
57-
setColorChannel = auto()
5857

5958
setRadius = auto() # abj
59+
6060
updateChannelMetadata = auto()
61+
setColorChannel = auto() # when user chooses channel (1,2,3,rgb,...)
6162

6263
# added to refresh gui after modifying the core with undo and redo
6364
refreshSpineEvent = auto()
6465

65-
# undoSpineEvent = auto()
66-
# redoSpineEvent = auto()
67-
6866
# abj
6967
undoEvent = auto() # for both spines and segments
7068
redoEvent = auto()
@@ -75,13 +73,14 @@ class pmmEventType(Enum):
7573
deleteSegment = auto()
7674
addSegmentPoint = auto()
7775
deleteSegmentPoint = auto()
78-
79-
# setPivotPoint = auto() # abj
80-
importNewChannel = auto() # abj
8176
setSegmentPivot = auto() # abj
77+
setSegmentColor = auto()
78+
8279
moveBackgroundRoi = auto()
8380

84-
setSegmentColor = auto()
81+
# abb 202508, one event for all channel edits(import, delete, swap, set name, set color LUT)
82+
editChannel = auto()
83+
importNewChannel = auto() # abj, abb 202508 TODO: depreciate
8584

8685
@property
8786
def category(self):
@@ -918,7 +917,7 @@ def slot_pmmEvent(self, event : pmmEvent):
918917

919918
elif event.type == pmmEventType.redoEvent:
920919

921-
logger.info(f"test redo")
920+
# logger.info(f"test redo")
922921
acceptEvent = self.redoEvent(event)
923922

924923
# abb 20240906
@@ -934,7 +933,7 @@ def slot_pmmEvent(self, event : pmmEvent):
934933
acceptEvent = self.addedEvent(event)
935934

936935
elif event.type == pmmEventType.delete:
937-
logger.info(f"test delete")
936+
# logger.info(f"test delete")
938937
acceptEvent = self.deletedEvent(event)
939938

940939
elif event.type == pmmEventType.edit:
@@ -960,9 +959,6 @@ def slot_pmmEvent(self, event : pmmEvent):
960959
elif event.type == pmmEventType.setSlice:
961960
acceptEvent = self.setSliceEvent(event)
962961

963-
elif event.type == pmmEventType.setColorChannel:
964-
acceptEvent = self.setColorChannelEvent(event)
965-
966962
# elif event.type == pmmEventType.undoSpineEvent:
967963
# acceptEvent = self.undoEvent(event)
968964
# elif event.type == pmmEventType.redoSpineEvent:
@@ -971,10 +967,18 @@ def slot_pmmEvent(self, event : pmmEvent):
971967
#abj
972968
elif event.type == pmmEventType.setRadius:
973969
acceptEvent = self.setRadiusEvent(event)
970+
971+
# abb 202508 add ChannelEditEvent()
972+
# for import channel, delete channel, swap channel,set name, set color LUT
973+
elif event.type == pmmEventType.editChannel:
974+
acceptEvent = self.editChannelEvent(event)
975+
976+
# not used?
974977
elif event.type == pmmEventType.updateChannelMetadata:
975978
acceptEvent = self.updateChannelMetadataEvent(event)
979+
elif event.type == pmmEventType.setColorChannel:
980+
acceptEvent = self.setColorChannelEvent(event)
976981

977-
# abb 20240716
978982
# segment events
979983
elif event.type == pmmEventType.addSegment:
980984
# stack widget needs to select new segment
@@ -1327,6 +1331,11 @@ def setRadiusEvent(self, event : pmmEvent):
13271331
# logger.warning(f'{self.getClassName()} base class called')
13281332
pass
13291333

1334+
# channel event
1335+
def editChannelEvent(self, event : pmmEvent):
1336+
pass
1337+
1338+
# TODO: depreciate
13301339
def updateChannelMetadataEvent(self, event: pmmEvent):
13311340
pass
13321341

src/pymapmanager/interface/stackWidgets/base/stacktoolbar.py

Lines changed: 44 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from qtpy import QtGui, QtCore, QtWidgets
44

5-
from pymapmanager.interface.stackWidgets.base.mmWidget2 import pmmEvent
5+
# from pymapmanager.interface.stackWidgets.base.mmWidget2 import pmmEvent
66
from pymapmanager.stack import stack
77

88
from pymapmanager._logger import logger
@@ -18,44 +18,30 @@ class StackToolBar(QtWidgets.QToolBar):
1818
signalRadiusChanged = QtCore.Signal(object) # dict : {checked, upDownSlices}
1919
signalPlotCheckBoxChanged = QtCore.Signal(object) # str: plot name being checked/ unchecked
2020
def __init__(self,
21-
myStack,
21+
myStack: stack,
2222
displayOptionsDict : dict,
23+
channelKey, # the channel to init with
2324
parent=None):
2425
"""
2526
Parameters:
2627
myStack : pymapmanager.stack
2728
"""
2829
super().__init__(parent)
2930

30-
self._myStack = myStack
31+
self._myStack:stack = myStack
3132
self._displayOptionsDict = displayOptionsDict
3233

33-
# list of channel strings 1,2,3,...
34-
# self._channelList = [str(x+1) for x in range(self._myStack.numChannels+1)]
35-
self._channelList = self._myStack.getChannelKeys()
36-
37-
self._currentChannel = None # abj
38-
39-
# iconsFolderPath = '' # TODO: get from canvas.util'
34+
self._currentChannel = channelKey
4035

4136
self.setWindowTitle('Stack Toolbar')
4237

4338
self.setFloatable(False)
4439
self.setMovable(False)
4540

46-
#self.setOrientation(QtCore.Qt.Vertical);
47-
#self.setOrientation(QtCore.Qt.Horizontal);
48-
49-
#myIconSize = 12 #32
50-
#self.setIconSize(QtCore.QSize(myIconSize,myIconSize))
5141
self.setToolButtonStyle( QtCore.Qt.ToolButtonTextUnderIcon )
5242

53-
# myFontSize = 10
54-
# myFont = self.font();
55-
# myFont.setPointSize(myFontSize);
56-
# self.setFont(myFont)
57-
58-
self._buildUI()
43+
# set in _setStack
44+
# self._buildUI()
5945

6046
# refresh interface
6147
self._setStack(self._myStack)
@@ -64,6 +50,7 @@ def _setStack(self, theStack: stack):
6450
"""Set the state of the interface based on a stack.
6551
6652
Parameters:
53+
-----------
6754
theStack :pymapmanager.stack
6855
The stack to dislpay in the widget
6956
"""
@@ -78,10 +65,10 @@ def _setStack(self, theStack: stack):
7865
actionWidget.setVisible(False)
7966

8067
# for channelIdx in range(self._myStack.numChannels):
81-
for channelIdx in self._myStack.getChannelKeys():
68+
for channelKey in self._myStack.getChannelKeys():
8269
# logger.info(f"channelIdx visible {channelIdx} ")
83-
self._actionDict[channelIdx].setDisabled(False)
84-
self._actionDict[channelIdx].setVisible(True)
70+
self._actionDict[channelKey].setDisabled(False)
71+
self._actionDict[channelKey].setVisible(True)
8572

8673
if self._myStack.numChannels > 1:
8774
self._actionDict['rgb'].setDisabled(False)
@@ -100,7 +87,8 @@ def _on_channel_callback(self, toolNameStr : str, checked : bool):
10087
if toolNameStr == 'rgb':
10188
pass
10289
else:
103-
toolNameStr = int(toolNameStr)
90+
# toolNameStr = int(toolNameStr) # TODO: don't cast int() here, do it in signal slot
91+
pass
10492

10593
self.slot_setChannel(toolNameStr)
10694

@@ -145,30 +133,30 @@ def _on_slidingz_value_changed(self, value):
145133
}
146134
self.signalSlidingZChanged.emit(d)
147135

148-
def slot_setChannel(self, channelIdx: int):
136+
def slot_setChannel(self, channelKey):
149137
"""Turn on button for selected channel.
150138
151139
These are a disjoint list, only one can be active. Others automatically disable.
152140
"""
153-
logger.info(f'channelIdx:{channelIdx} {type(channelIdx)}')
141+
logger.info(f'channelIdx:{channelKey} {type(channelKey)}')
154142

155143
# turn off sliding z
156144
# slidingEnabled = channelIdx != 'rgb'
157145
# self.slidingCheckbox.setEnabled(slidingEnabled)
158146
# self.slidingUpDown.setEnabled(slidingEnabled)
159147

160148
# TODO: use stack metadata channels to determine type
161-
if channelIdx == 'rgb':
149+
if channelKey == 'rgb':
162150
pass
163151
else:
164-
channelIdx = int(channelIdx)
152+
channelKey = int(channelKey)
165153

166154
# logger.info(f' is now {channelIdx} {type(channelIdx)}')
167155

168156
# activate one action in [1, 2, 3, rgb]
169-
self._actionDict[channelIdx].setChecked(True)
157+
self._actionDict[channelKey].setChecked(True)
170158

171-
self.setCurrentChannel(channelIdx) # abj
159+
self.setCurrentChannel(channelKey) # abj
172160

173161
# self.signalChannelChange.emit(channelIdx) # channel can be 'rgb'
174162

@@ -177,37 +165,35 @@ def _buildUI(self):
177165
# used when we update stack after changing channels
178166
self.clear()
179167

168+
# abb 202508 this is problematic as we do not know the type of channelKey
180169
# see: https://stackoverflow.com/questions/45511056/pyqt-how-to-make-a-toolbar-button-appeared-as-pressed
181-
_defaultChannel = self._displayOptionsDict['windowState']['defaultChannel']
170+
# _defaultChannel = self._displayOptionsDict['windowState']['defaultChannel']
182171

183172
self._actionDict = {}
184173

185174
# make ['1', '2', '3', 'rgb'] disjoint selections
186175
self.channelActionGroup = QtWidgets.QActionGroup(self)
187176

188-
if len(self._myStack.getChannelKeys()) > 0:
189-
logger.info(f"channel keys {self._myStack.getChannelKeys()}")
190-
for channelIdx in self._myStack.getChannelKeys():
191-
iconPath = '' # use toolName to get from canvas.util
192-
theIcon = QtGui.QIcon(iconPath)
193-
194-
# toolNameStr = str(int(channelIdx) + 1)
195-
toolNameStr = str(channelIdx)
196-
197-
theAction = QtWidgets.QAction(theIcon, toolNameStr)
198-
theAction.setCheckable(True)
199-
if toolNameStr == str(_defaultChannel):
200-
theAction.setChecked(True)
201-
self.setCurrentChannel(_defaultChannel) # abj
202-
# do not set shortcut, handled by main stack widget
203-
#theAction.setShortcut('1')# or 'Ctrl+r' or '&r' for alt+r
204-
theAction.setToolTip(f'View Channel {toolNameStr}')
205-
theAction.triggered.connect(partial(self._on_channel_callback, toolNameStr))
206-
207-
# add action
208-
self.addAction(theAction)
209-
self.channelActionGroup.addAction(theAction)
210-
self._actionDict[channelIdx] = theAction
177+
for channelKey in self._myStack.getChannelKeys():
178+
iconPath = '' # use toolName to get from canvas.util
179+
theIcon = QtGui.QIcon(iconPath)
180+
181+
toolNameStr = str(channelKey) # dangerous but should usually work?
182+
183+
theAction = QtWidgets.QAction(theIcon, toolNameStr)
184+
theAction.setCheckable(True)
185+
if toolNameStr == str(self.getCurrentChannel()):
186+
theAction.setChecked(True)
187+
# self.setCurrentChannel(_defaultChannel) # abj
188+
# do not set shortcut, handled by main stack widget
189+
#theAction.setShortcut('1')# or 'Ctrl+r' or '&r' for alt+r
190+
theAction.setToolTip(f'View Channel {toolNameStr}')
191+
theAction.triggered.connect(partial(self._on_channel_callback, toolNameStr))
192+
193+
# add action
194+
self.addAction(theAction)
195+
self.channelActionGroup.addAction(theAction)
196+
self._actionDict[channelKey] = theAction
211197

212198
#
213199
toolNameStr = 'rgb'
@@ -351,11 +337,11 @@ def plotMenuChange(self, action):
351337
plotName = action.text()
352338
self.signalPlotCheckBoxChanged.emit(plotName)
353339

354-
def setCurrentChannel(self, channelIdx):
340+
def setCurrentChannel(self, channelKey):
355341
""" set current channel selected
356342
"""
357-
logger.info(f"setCurrentChannel {channelIdx} {type(channelIdx)}")
358-
self._currentChannel = channelIdx
343+
logger.info(f"setCurrentChannel {channelKey} {type(channelKey)}")
344+
self._currentChannel = channelKey
359345

360346
def getCurrentChannel(self):
361347
""" Get current channel selected

0 commit comments

Comments
 (0)