epicure.preferences
EpiCure preferences functions
Proposes to set and save the shortcut preferences so that each user can choose his/her favorite keys.
This is loaded from and saved to a file called epicure_preferences.pkl placed in the home directory of the user, in the .napari folder.
1""" 2 **EpiCure preferences functions** 3 4 Proposes to set and save the shortcut preferences so that each user can choose his/her favorite keys. 5 This is loaded from and saved to a file called `epicure_preferences.pkl` placed in the home directory of the user, in the .napari folder. 6""" 7 8from qtpy.QtWidgets import QPushButton, QVBoxLayout, QTabWidget, QWidget, QComboBox, QLabel, QLineEdit, QGroupBox, QHBoxLayout, QColorDialog 9#from qtpy.QtGui import QColor 10import napari 11import epicure.Utils as ut 12from pathlib import Path 13import os, pickle 14from sys import platform 15 16def edit_preferences(): 17 """ Launch preferences edition interface""" 18 viewer = napari.current_viewer() 19 prefgui = PreferencesGUI( viewer ) 20 return prefgui 21 22class PreferencesGUI( QWidget ): 23 """ Handles user preferences for shortcuts, default widget state """ 24 25 def __init__(self, napari_viewer): 26 """ Initialize the tab with the different widgets """ 27 super().__init__() 28 29 ## preferences (shortcuts, plugin state) object 30 self.pref = Preferences() 31 32 layout = QVBoxLayout() 33 tabs = QTabWidget() 34 tabs.setObjectName("Preferences") 35 36 ## shortcut and plugin state preferences tabs 37 self.shortcuts = ShortCut( napari_viewer, self.pref ) 38 tabs.addTab( self.shortcuts, "Shortcuts Config." ) 39 self.displays = DisplaySettings( napari_viewer, self.pref ) 40 tabs.addTab( self.displays, "Display Config." ) 41 layout.addWidget(tabs) 42 43 ## save option 44 self.save_pref = QPushButton("Save preferences", parent=self) 45 layout.addWidget( self.save_pref ) 46 self.save_pref.clicked.connect( self.save ) 47 48 ## add to main interface 49 self.setLayout( layout ) 50 #napari_viewer.window.add_dock_widget( main_widget, name="Preferences" ) 51 52 def save( self ): 53 """ Save current preferences: update them and save to default file """ 54 self.shortcuts.update_pref() 55 self.pref.save() 56 57 58class Preferences(): 59 """ Handles user-specific preferences (shortcuts, widgets states) """ 60 61 def __init__( self ): 62 """ Initialise file path, load current preferences""" 63 self.build_preferences_path() 64 #print("Running on "+platform.lower()) 65 66 self.ctl = "Control" 67 self.alt = "Alt" 68 if platform.lower() == "darwin": 69 self.ctl = "Command" 70 71 self.load_default_shortcuts() 72 self.load_default_settings() 73 if os.path.exists( self.preference_path ): 74 self.load() 75 76 def build_preferences_path( self ): 77 """ Build (create directories if necessary) preference path """ 78 home_dir = Path.home() 79 self.preference_path = os.path.join( home_dir, ".napari" ) 80 if not os.path.exists( self.preference_path ): 81 os.mkdir( self.preference_path ) 82 self.preference_path = os.path.join( self.preference_path, "epicure_preferences.pkl" ) 83 84 def save( self ): 85 """ Save the current preferences to the preference files in user home """ 86 outfile = open( self.preference_path, "wb" ) 87 pickle.dump( self.shortcuts, outfile ) 88 pickle.dump( self.settings, outfile ) 89 outfile.close() 90 print( "Preferences saved in file "+self.preference_path ) 91 92 def set_preferences( self, default_prefs, prefs ): 93 """ Merge (recursively) the preferences with the default ones """ 94 for key, vals in prefs.items(): 95 if key in default_prefs.keys(): 96 if isinstance( vals, dict ): 97 self.set_preferences( default_prefs[key], vals ) 98 else: 99 default_prefs[key] = vals 100 else: 101 default_prefs[key] = vals 102 103 def load( self ): 104 """ Load the current preferences to the preference files in user home """ 105 infile = open( self.preference_path, "rb" ) 106 shortcuts = pickle.load( infile ) 107 self.set_preferences( self.shortcuts, shortcuts ) 108 try: 109 settings = pickle.load( infile ) 110 #print(settings) 111 self.set_preferences( self.settings, settings ) 112 #print(self.settings) 113 except: 114 self.load_default_settings() 115 #print(self.shortcuts) 116 infile.close() 117 #print( "Preferences loaded from file "+self.preference_path ) 118 119 def get_settings( self ): 120 """ Return the dict of prefered settings (widget state) """ 121 return self.settings 122 123 def get_shortcuts( self ): 124 """ Return the dict of shortcuts """ 125 return self.shortcuts 126 127 def add_key_shortcut( self, main_type, shortname, fulltext, key ): 128 """ Add a keyboard shortcut """ 129 if main_type not in self.shortcuts.keys(): 130 self.shortcuts[ main_type ] = {} 131 ## initialize the new shortcut object 132 self.shortcuts[ main_type ][ shortname ] = {} 133 sc = self.shortcuts[ main_type ][ shortname ] 134 sc["type"] = "key" 135 sc["text"] = fulltext 136 sc["key"] = key 137 138 def add_click_shortcut( self, main_type, shortname, fulltext, button, modifiers=None ): 139 """ Add a keyboard shortcut """ 140 if main_type not in self.shortcuts.keys(): 141 self.shortcuts[ main_type ] = {} 142 ## initialize the new shortcut object 143 self.shortcuts[ main_type ][ shortname ] = {} 144 sc = self.shortcuts[ main_type ][ shortname ] 145 sc["type"] = "click" 146 sc["text"] = fulltext 147 sc["button"] = button 148 if modifiers is not None: 149 sc["modifiers"] = ["Control" if item=="Command" else item for item in modifiers] 150 151 152 def load_default_shortcuts( self ): 153 """ Load all default shortcuts """ 154 155 self.shortcuts = {} 156 157 ## General shortcuts 158 self.add_key_shortcut( "General", shortname="show help", fulltext="show/hide overlay help message", key="h" ) 159 self.add_key_shortcut( "General", shortname="show all", fulltext="show all shortcuts in a separate window", key="a" ) 160 self.add_key_shortcut( "General", shortname="save segmentation", fulltext="save the segmentation and epicure files", key="s" ) 161 self.add_key_shortcut( "General", shortname="save movie", fulltext="save the movie with current display", key="Shift-s" ) 162 163 ## Labels edition (static) shortcuts 164 self.add_key_shortcut( "Labels", shortname="unused paint", fulltext="set the current label to unused value and go to paint mode", key="n" ) 165 self.add_key_shortcut( "Labels", shortname="unused fill", fulltext="set the current label to unused value and go to fill mode", key="Shift-n" ) 166 self.add_key_shortcut( "Labels", shortname="swap mode", fulltext="then <"+self.ctl+">+Left click on one cell to another to swap their values", key="w" ) 167 168 self.add_click_shortcut( "Labels", shortname="erase", fulltext="erase the cell under the click", button="Right", modifiers=None ) 169 self.add_click_shortcut( "Labels", shortname="merge", fulltext="drag-click from one cell to another to merge them", button="Left", modifiers=["Control"] ) 170 self.add_click_shortcut( "Labels", shortname="split accross", fulltext="drag-click in the cell to split into 2 cells ", button="Right", modifiers=["Control"] ) 171 self.add_click_shortcut( "Labels", shortname="split draw", fulltext="drag-click draw a junction to split in 2 cells", button="Right", modifiers=["Alt"] ) 172 self.add_click_shortcut( "Labels", shortname="redraw junction", fulltext="drag-click draw a junction to correct it", button="Left", modifiers=["Alt"] ) 173 self.add_key_shortcut( "Labels", shortname="draw junction mode", fulltext="Draw junction(s) mode ON", key="j" ) 174 self.add_click_shortcut( "Labels", shortname="drawing junction", fulltext="Draw junction mode ON. Drag-click draw a junction to create new cell(s)", button="Left", modifiers=["Control"] ) 175 176 ## Seeds (manual segmentation) shortcuts 177 self.add_key_shortcut( "Seeds", shortname="new seed", fulltext="<key shortcut> then left-click to place a seed", key="e" ) 178 179 ## Groups shortcuts 180 self.add_click_shortcut( "Groups", shortname="add group", fulltext="add the clicked cell to the current group", button="Left", modifiers=["Shift"] ) 181 self.add_click_shortcut( "Groups", shortname="remove group", fulltext="remove the clicked cell from the group", button="Right", modifiers=["Shift"] ) 182 183 ## events edition shortcuts 184 self.add_key_shortcut( "Events", shortname="next", fulltext="zoom on next event", key="Space" ) 185 self.add_click_shortcut( "Events", shortname="zoom", fulltext="Zoom on the clicked event", button="Left", modifiers=["Control", "Alt"] ) 186 self.add_click_shortcut( "Events", shortname="delete", fulltext="Remove the clicked event", button="Right", modifiers=["Control", "Alt"] ) 187 self.add_click_shortcut( "Events", shortname="add division", fulltext="add a division: drag-click from first to second daugther", button="Left", modifiers=["Control", "Shift"] ) 188 self.add_click_shortcut( "Events", shortname="add extrusion", fulltext="add an extrusion: click on the last cell of the track", button="Right", modifiers=["Control", "Shift"] ) 189 190 ## Tracks edition shortcuts 191 self.add_key_shortcut( "Tracks", shortname="show", fulltext="show/hide the tracks", key="r" ) 192 self.add_key_shortcut( "Tracks", shortname="lineage color", fulltext="color the tracks by lineage", key="l" ) 193 self.add_key_shortcut( "Tracks", shortname="mode", fulltext="on/off track editing mode", key="t" ) 194 self.add_click_shortcut( "Tracks", shortname="merge first", fulltext="+track mode ON. Merge tracks: select the first", button="Left" ) 195 self.add_click_shortcut( "Tracks", shortname="merge second", fulltext="+trackmode ON. Merge tracks: selec the second", button="Right" ) 196 self.add_click_shortcut( "Tracks", shortname="split track", fulltext="+trackmode ON. Split the track temporally in 2", button="Right", modifiers=["Shift"] ) 197 self.add_click_shortcut( "Tracks", shortname="start manual", fulltext="+trackmode ON. Start manual tracking, clicking on cells", button="Left", modifiers=["Control"] ) 198 self.add_click_shortcut( "Tracks", shortname="end manual", fulltext="+trackmode ON. Finish manual tracking", button="Right", modifiers=["Control"] ) 199 self.add_click_shortcut( "Tracks", shortname="interpolate first", fulltext="+trackmode ON. Interpolate temporally labels: select first", button="Left", modifiers=["Alt"] ) 200 self.add_click_shortcut( "Tracks", shortname="interpolate second", fulltext="+trackmode ON. Interpolate temporally labels: select second", button="Right", modifiers=["Alt"] ) 201 self.add_click_shortcut( "Tracks", shortname="swap", fulltext="+trackmode ON. Drag click to swap 2 tracks from current frame", button="Left", modifiers=["Shift"] ) 202 self.add_click_shortcut( "Tracks", shortname="delete", fulltext="+trackmode ON. Delete all the track from current frame", button="Right", modifiers=["Control", "Alt"] ) 203 204 ## Visualisation option shortcuts 205 self.add_key_shortcut( "Display", shortname="vis. segmentation", fulltext="show/hide segmentation layer", key="b" ) 206 self.add_key_shortcut( "Display", shortname="vis. movie", fulltext="show/hide movie layer", key="v" ) 207 self.add_key_shortcut( "Display", shortname="vis. event", fulltext="show.hide events layer", key="x" ) 208 self.add_key_shortcut( "Display", shortname="only movie", fulltext="show ONLY movie layer on/off", key="c" ) 209 self.add_key_shortcut( "Display", shortname="light view", fulltext="on/off light segmentation view", key="d" ) 210 self.add_key_shortcut( "Display", shortname="skeleton", fulltext="show/hide/update segmentation skeleton", key="k" ) 211 self.add_key_shortcut( "Display", shortname="show side", fulltext="view layers side by side on/off", key="z" ) 212 self.add_key_shortcut( "Display", shortname="grid", fulltext="show/hide grid", key="g" ) 213 self.add_key_shortcut( "Display", shortname="increase", fulltext="increase label contour size", key="Control-c" ) 214 self.add_key_shortcut( "Display", shortname="decrease", fulltext="decrease label contour size", key="Control-d" ) 215 216 ## Info shortcuts 217 self.add_key_shortcut( "Info", shortname="measure length", fulltext="draw and measure a line length", key="Control"+"-i" ) 218 219 220 def load_default_settings( self ): 221 """ Load all default widget settings """ 222 self.settings = {} 223 224 ## Default visualisation set-up 225 self.settings["Display"] = {} 226 self.settings["Display"]["Layers"] = { 'Tracks': True, 'events': True, 'ROIs': False, 'Segmentation': True, 'Movie': True, 'EpicGrid': False, 'Groups': False } 227 228 self.settings["Info"] = {} 229 230 ## widgets colors 231 self.load_default_colors() 232 233 ## default visualisation of events widget 234 self.settings["events"] = {} 235 236 def load_default_colors( self ): 237 """ Load the defualt GUI colors """ 238 self.settings["Display"]["Colors"] = {} 239 col_set = self.settings["Display"]["Colors"] 240 col_set["button"] = "rgb(40, 60, 75)" 241 col_set["Help button"] = "rgb(62, 60, 75)" 242 col_set["Reset button"] = "rgb(70, 68, 85)" 243 col_set["checkbox"] = "rgb(40, 52, 65)" 244 col_set["line edit"] = "rgb(30, 30, 40)" 245 col_set["group"] = "rgb(33,42,55)" 246 col_set["group4"] = "rgb(37,37,57)" 247 col_set["group3"] = "rgb(30,35,40)" 248 col_set["group2"] = "rgb(30,40,50)" 249 250 251class ShortCut( QWidget ): 252 """ Class to handle edit EpiCure shortcuts """ 253 254 def __init__( self, napari_viewer, pref ): 255 super().__init__() 256 257 layout = QVBoxLayout() 258 self.ctl = "Control" 259 if platform.lower() == "darwin": 260 self.ctl = "Command" 261 262 self.sc = pref.get_shortcuts() 263 ## choice list to choose which shortcuts to edit 264 self.shortcut_types = self.sc.keys() 265 self.sc_types = QComboBox() 266 self.sc_groups = {} 267 self.sc_guis = {} 268 layout.addWidget( self.sc_types ) 269 for sc_type in self.shortcut_types: 270 self.sc_types.addItem( sc_type ) 271 self.sc_guis[sc_type] = {} 272 self.sc_groups[sc_type] = self.create_sc_type( sc_type ) 273 layout.addWidget( self.sc_groups[sc_type] ) 274 self.show_sc_type() 275 276 self.setLayout(layout) 277 self.sc_types.currentIndexChanged.connect( self.show_sc_type ) 278 279 def show_sc_type( self ): 280 """ Show only selected shortcut subset """ 281 for sc_type in self.shortcut_types: 282 self.sc_groups[ sc_type ].setVisible( self.sc_types.currentText() == sc_type ) 283 284 def create_sc_type( self, sc_type ): 285 """ Interface to edit shortcut subset of a given type """ 286 sc_curgroup = QGroupBox( "" ) 287 sc_layout = QVBoxLayout() 288 289 ## add each shortcut from the current selected group 290 cur_shortcuts = self.sc[ sc_type ] 291 for shortname, val in cur_shortcuts.items(): 292 new_line = QHBoxLayout() 293 ## current keyboard shortcut 294 if val["type"] == "click": 295 ## shortcut is a mouse shortcut 296 if "modifiers" in val.keys(): 297 ind = 0 298 for modif in val["modifiers"]: 299 cur_modif = QComboBox() 300 cur_modif.addItem("") 301 cur_modif.addItem("Control") 302 cur_modif.addItem("Shift") 303 cur_modif.addItem("Alt") 304 if platform.lower() == "darwin": 305 cur_modif.addItem("Command") 306 cur_modif.addItem("Option") 307 new_line.addWidget( cur_modif ) 308 cur_modif.setCurrentText( modif ) 309 self.sc_guis[sc_type][ shortname+"modifiers"+str(ind) ] = cur_modif 310 ind = ind + 1 311 cur_click = QComboBox() 312 cur_click.addItem("Left-click") 313 cur_click.addItem("Right-click") 314 new_line.addWidget( cur_click ) 315 if val["button"] == "Right": 316 cur_click.setCurrentText( "Right-click" ) 317 self.sc_guis[sc_type][ shortname ] = cur_click 318 if val["type"] == "key": 319 new_line_val = QLineEdit() 320 new_line_val.setText( val["key"] ) 321 self.sc_guis[sc_type][ shortname ] = new_line_val 322 new_line.addWidget( new_line_val ) 323 ## full description of the shortcut 324 long_description = QLabel() 325 long_description.setText( val["text"] ) 326 new_line.addWidget( long_description ) 327 sc_layout.addLayout( new_line ) 328 #empty = QLabel() 329 #sc_layout.addWidget( empty ) 330 331 sc_curgroup.setLayout( sc_layout ) 332 return sc_curgroup 333 334 def update_pref( self ): 335 """ Update the shortcuts in the Preference based on current values """ 336 for sc_type in self.shortcut_types: 337 gui = self.sc_guis[ sc_type ] 338 sc_group = self.sc[ sc_type ] 339 for shortname, vals in sc_group.items(): 340 if vals["type"] == "click": 341 ## update the modifiers if there are some 342 ind = 0 343 if "modifiers" in vals.keys(): 344 del vals["modifiers"] 345 while shortname+"modifiers"+str(ind) in gui.keys(): 346 modif = gui[ shortname+"modifiers"+str(ind) ].currentText() 347 if "modifiers" not in vals.keys(): 348 vals["modifiers"] = [] 349 if modif != "": 350 vals["modifiers"].append(modif) 351 ind = ind + 1 352 if len( vals["modifiers"] ) == 0: 353 del vals["modifiers"] 354 ## update the button information 355 click = gui[shortname].currentText() 356 if click == "Left-click": 357 vals["button"] = "Left" 358 else: 359 vals["button"] = "Right" 360 if vals["type"] == "key": 361 vals["key"] = gui[shortname].text() 362 363 364class DisplaySettings( QWidget ): 365 """ Class to handle edit EpiCure display button colors...)""" 366 367 def __init__( self, napari_viewer, pref ): 368 super().__init__() 369 self.settings = pref.get_settings() 370 if "Colors" not in self.settings["Display"]: 371 pref.load_default_colors() 372 colors = self.settings["Display"]["Colors"] 373 374 ## interface of display choices 375 layout = QVBoxLayout() 376 self.grid_color = QPushButton("EpicGrid color", self) 377 self.grid_color.clicked.connect( self.get_grid_color ) 378 layout.addWidget( self.grid_color ) 379 380 self.add_color( layout, "Buttons color", "button", "Choose default color of buttons" ) 381 self.add_color( layout, "Help buttons color", "Help button", "Choose color of buttons for Help actions" ) 382 self.add_color( layout, "Reset buttons color", "Reset button", "Choose color of buttons for Reset actions" ) 383 self.add_color( layout, "CheckBox color", "checkbox", "Choose color of checkboxes" ) 384 self.add_color( layout, "Input color", "line edit", "Choose color of editable parameters boxes" ) 385 self.add_color( layout, "Subpanels color", "group", "Choose color of option subpanels that appears when clicked/selected" ) 386 self.add_color( layout, "Subpanels color 2", "group2", "Choose second color of option subpanels that appears when clicked/selected" ) 387 self.add_color( layout, "Subpanels color 3", "group3", "Choose third color of option subpanels that appears when clicked/selected" ) 388 self.add_color( layout, "Subpanels color 4", "group4", "Choose fourth color of option subpanels that appears when clicked/selected" ) 389 390 self.setLayout(layout) 391 392 def add_color( self, layout, label, setname, descr="" ): 393 """ Add a choice of color (push button that opens a color dialog) """ 394 btn = QPushButton( label ) 395 if descr != "": 396 btn.setToolTip( descr ) 397 def get_color(): 398 """ opens color dialog and set button color to it """ 399 color = QColorDialog.getColor() 400 if color.isValid(): 401 self.settings["Display"]["Colors"][setname] = color.name() 402 btn.setStyleSheet( 'QPushButton {background-color: '+color.name()+'}' ) 403 btn.clicked.connect( get_color ) 404 if setname in self.settings["Display"]["Colors"]: 405 color = self.settings["Display"]["Colors"][setname] 406 btn.setStyleSheet( 'QPushButton {background-color: '+color+'}' ) 407 layout.addWidget( btn ) 408 409 def get_grid_color( self ): 410 """ Get the EpiCGrid color """ 411 color = QColorDialog.getColor() 412 if color.isValid(): 413 if "Display" not in self.settings: 414 self.settings["Display"] = {} 415 self.settings["Display"]["Grid color"] = color.name() 416 self.grid_color.setStyleSheet( 'QPushButton {background-color: '+color.name()+'}' ) 417 418
17def edit_preferences(): 18 """ Launch preferences edition interface""" 19 viewer = napari.current_viewer() 20 prefgui = PreferencesGUI( viewer ) 21 return prefgui
Launch preferences edition interface
23class PreferencesGUI( QWidget ): 24 """ Handles user preferences for shortcuts, default widget state """ 25 26 def __init__(self, napari_viewer): 27 """ Initialize the tab with the different widgets """ 28 super().__init__() 29 30 ## preferences (shortcuts, plugin state) object 31 self.pref = Preferences() 32 33 layout = QVBoxLayout() 34 tabs = QTabWidget() 35 tabs.setObjectName("Preferences") 36 37 ## shortcut and plugin state preferences tabs 38 self.shortcuts = ShortCut( napari_viewer, self.pref ) 39 tabs.addTab( self.shortcuts, "Shortcuts Config." ) 40 self.displays = DisplaySettings( napari_viewer, self.pref ) 41 tabs.addTab( self.displays, "Display Config." ) 42 layout.addWidget(tabs) 43 44 ## save option 45 self.save_pref = QPushButton("Save preferences", parent=self) 46 layout.addWidget( self.save_pref ) 47 self.save_pref.clicked.connect( self.save ) 48 49 ## add to main interface 50 self.setLayout( layout ) 51 #napari_viewer.window.add_dock_widget( main_widget, name="Preferences" ) 52 53 def save( self ): 54 """ Save current preferences: update them and save to default file """ 55 self.shortcuts.update_pref() 56 self.pref.save()
Handles user preferences for shortcuts, default widget state
26 def __init__(self, napari_viewer): 27 """ Initialize the tab with the different widgets """ 28 super().__init__() 29 30 ## preferences (shortcuts, plugin state) object 31 self.pref = Preferences() 32 33 layout = QVBoxLayout() 34 tabs = QTabWidget() 35 tabs.setObjectName("Preferences") 36 37 ## shortcut and plugin state preferences tabs 38 self.shortcuts = ShortCut( napari_viewer, self.pref ) 39 tabs.addTab( self.shortcuts, "Shortcuts Config." ) 40 self.displays = DisplaySettings( napari_viewer, self.pref ) 41 tabs.addTab( self.displays, "Display Config." ) 42 layout.addWidget(tabs) 43 44 ## save option 45 self.save_pref = QPushButton("Save preferences", parent=self) 46 layout.addWidget( self.save_pref ) 47 self.save_pref.clicked.connect( self.save ) 48 49 ## add to main interface 50 self.setLayout( layout ) 51 #napari_viewer.window.add_dock_widget( main_widget, name="Preferences" )
Initialize the tab with the different widgets
59class Preferences(): 60 """ Handles user-specific preferences (shortcuts, widgets states) """ 61 62 def __init__( self ): 63 """ Initialise file path, load current preferences""" 64 self.build_preferences_path() 65 #print("Running on "+platform.lower()) 66 67 self.ctl = "Control" 68 self.alt = "Alt" 69 if platform.lower() == "darwin": 70 self.ctl = "Command" 71 72 self.load_default_shortcuts() 73 self.load_default_settings() 74 if os.path.exists( self.preference_path ): 75 self.load() 76 77 def build_preferences_path( self ): 78 """ Build (create directories if necessary) preference path """ 79 home_dir = Path.home() 80 self.preference_path = os.path.join( home_dir, ".napari" ) 81 if not os.path.exists( self.preference_path ): 82 os.mkdir( self.preference_path ) 83 self.preference_path = os.path.join( self.preference_path, "epicure_preferences.pkl" ) 84 85 def save( self ): 86 """ Save the current preferences to the preference files in user home """ 87 outfile = open( self.preference_path, "wb" ) 88 pickle.dump( self.shortcuts, outfile ) 89 pickle.dump( self.settings, outfile ) 90 outfile.close() 91 print( "Preferences saved in file "+self.preference_path ) 92 93 def set_preferences( self, default_prefs, prefs ): 94 """ Merge (recursively) the preferences with the default ones """ 95 for key, vals in prefs.items(): 96 if key in default_prefs.keys(): 97 if isinstance( vals, dict ): 98 self.set_preferences( default_prefs[key], vals ) 99 else: 100 default_prefs[key] = vals 101 else: 102 default_prefs[key] = vals 103 104 def load( self ): 105 """ Load the current preferences to the preference files in user home """ 106 infile = open( self.preference_path, "rb" ) 107 shortcuts = pickle.load( infile ) 108 self.set_preferences( self.shortcuts, shortcuts ) 109 try: 110 settings = pickle.load( infile ) 111 #print(settings) 112 self.set_preferences( self.settings, settings ) 113 #print(self.settings) 114 except: 115 self.load_default_settings() 116 #print(self.shortcuts) 117 infile.close() 118 #print( "Preferences loaded from file "+self.preference_path ) 119 120 def get_settings( self ): 121 """ Return the dict of prefered settings (widget state) """ 122 return self.settings 123 124 def get_shortcuts( self ): 125 """ Return the dict of shortcuts """ 126 return self.shortcuts 127 128 def add_key_shortcut( self, main_type, shortname, fulltext, key ): 129 """ Add a keyboard shortcut """ 130 if main_type not in self.shortcuts.keys(): 131 self.shortcuts[ main_type ] = {} 132 ## initialize the new shortcut object 133 self.shortcuts[ main_type ][ shortname ] = {} 134 sc = self.shortcuts[ main_type ][ shortname ] 135 sc["type"] = "key" 136 sc["text"] = fulltext 137 sc["key"] = key 138 139 def add_click_shortcut( self, main_type, shortname, fulltext, button, modifiers=None ): 140 """ Add a keyboard shortcut """ 141 if main_type not in self.shortcuts.keys(): 142 self.shortcuts[ main_type ] = {} 143 ## initialize the new shortcut object 144 self.shortcuts[ main_type ][ shortname ] = {} 145 sc = self.shortcuts[ main_type ][ shortname ] 146 sc["type"] = "click" 147 sc["text"] = fulltext 148 sc["button"] = button 149 if modifiers is not None: 150 sc["modifiers"] = ["Control" if item=="Command" else item for item in modifiers] 151 152 153 def load_default_shortcuts( self ): 154 """ Load all default shortcuts """ 155 156 self.shortcuts = {} 157 158 ## General shortcuts 159 self.add_key_shortcut( "General", shortname="show help", fulltext="show/hide overlay help message", key="h" ) 160 self.add_key_shortcut( "General", shortname="show all", fulltext="show all shortcuts in a separate window", key="a" ) 161 self.add_key_shortcut( "General", shortname="save segmentation", fulltext="save the segmentation and epicure files", key="s" ) 162 self.add_key_shortcut( "General", shortname="save movie", fulltext="save the movie with current display", key="Shift-s" ) 163 164 ## Labels edition (static) shortcuts 165 self.add_key_shortcut( "Labels", shortname="unused paint", fulltext="set the current label to unused value and go to paint mode", key="n" ) 166 self.add_key_shortcut( "Labels", shortname="unused fill", fulltext="set the current label to unused value and go to fill mode", key="Shift-n" ) 167 self.add_key_shortcut( "Labels", shortname="swap mode", fulltext="then <"+self.ctl+">+Left click on one cell to another to swap their values", key="w" ) 168 169 self.add_click_shortcut( "Labels", shortname="erase", fulltext="erase the cell under the click", button="Right", modifiers=None ) 170 self.add_click_shortcut( "Labels", shortname="merge", fulltext="drag-click from one cell to another to merge them", button="Left", modifiers=["Control"] ) 171 self.add_click_shortcut( "Labels", shortname="split accross", fulltext="drag-click in the cell to split into 2 cells ", button="Right", modifiers=["Control"] ) 172 self.add_click_shortcut( "Labels", shortname="split draw", fulltext="drag-click draw a junction to split in 2 cells", button="Right", modifiers=["Alt"] ) 173 self.add_click_shortcut( "Labels", shortname="redraw junction", fulltext="drag-click draw a junction to correct it", button="Left", modifiers=["Alt"] ) 174 self.add_key_shortcut( "Labels", shortname="draw junction mode", fulltext="Draw junction(s) mode ON", key="j" ) 175 self.add_click_shortcut( "Labels", shortname="drawing junction", fulltext="Draw junction mode ON. Drag-click draw a junction to create new cell(s)", button="Left", modifiers=["Control"] ) 176 177 ## Seeds (manual segmentation) shortcuts 178 self.add_key_shortcut( "Seeds", shortname="new seed", fulltext="<key shortcut> then left-click to place a seed", key="e" ) 179 180 ## Groups shortcuts 181 self.add_click_shortcut( "Groups", shortname="add group", fulltext="add the clicked cell to the current group", button="Left", modifiers=["Shift"] ) 182 self.add_click_shortcut( "Groups", shortname="remove group", fulltext="remove the clicked cell from the group", button="Right", modifiers=["Shift"] ) 183 184 ## events edition shortcuts 185 self.add_key_shortcut( "Events", shortname="next", fulltext="zoom on next event", key="Space" ) 186 self.add_click_shortcut( "Events", shortname="zoom", fulltext="Zoom on the clicked event", button="Left", modifiers=["Control", "Alt"] ) 187 self.add_click_shortcut( "Events", shortname="delete", fulltext="Remove the clicked event", button="Right", modifiers=["Control", "Alt"] ) 188 self.add_click_shortcut( "Events", shortname="add division", fulltext="add a division: drag-click from first to second daugther", button="Left", modifiers=["Control", "Shift"] ) 189 self.add_click_shortcut( "Events", shortname="add extrusion", fulltext="add an extrusion: click on the last cell of the track", button="Right", modifiers=["Control", "Shift"] ) 190 191 ## Tracks edition shortcuts 192 self.add_key_shortcut( "Tracks", shortname="show", fulltext="show/hide the tracks", key="r" ) 193 self.add_key_shortcut( "Tracks", shortname="lineage color", fulltext="color the tracks by lineage", key="l" ) 194 self.add_key_shortcut( "Tracks", shortname="mode", fulltext="on/off track editing mode", key="t" ) 195 self.add_click_shortcut( "Tracks", shortname="merge first", fulltext="+track mode ON. Merge tracks: select the first", button="Left" ) 196 self.add_click_shortcut( "Tracks", shortname="merge second", fulltext="+trackmode ON. Merge tracks: selec the second", button="Right" ) 197 self.add_click_shortcut( "Tracks", shortname="split track", fulltext="+trackmode ON. Split the track temporally in 2", button="Right", modifiers=["Shift"] ) 198 self.add_click_shortcut( "Tracks", shortname="start manual", fulltext="+trackmode ON. Start manual tracking, clicking on cells", button="Left", modifiers=["Control"] ) 199 self.add_click_shortcut( "Tracks", shortname="end manual", fulltext="+trackmode ON. Finish manual tracking", button="Right", modifiers=["Control"] ) 200 self.add_click_shortcut( "Tracks", shortname="interpolate first", fulltext="+trackmode ON. Interpolate temporally labels: select first", button="Left", modifiers=["Alt"] ) 201 self.add_click_shortcut( "Tracks", shortname="interpolate second", fulltext="+trackmode ON. Interpolate temporally labels: select second", button="Right", modifiers=["Alt"] ) 202 self.add_click_shortcut( "Tracks", shortname="swap", fulltext="+trackmode ON. Drag click to swap 2 tracks from current frame", button="Left", modifiers=["Shift"] ) 203 self.add_click_shortcut( "Tracks", shortname="delete", fulltext="+trackmode ON. Delete all the track from current frame", button="Right", modifiers=["Control", "Alt"] ) 204 205 ## Visualisation option shortcuts 206 self.add_key_shortcut( "Display", shortname="vis. segmentation", fulltext="show/hide segmentation layer", key="b" ) 207 self.add_key_shortcut( "Display", shortname="vis. movie", fulltext="show/hide movie layer", key="v" ) 208 self.add_key_shortcut( "Display", shortname="vis. event", fulltext="show.hide events layer", key="x" ) 209 self.add_key_shortcut( "Display", shortname="only movie", fulltext="show ONLY movie layer on/off", key="c" ) 210 self.add_key_shortcut( "Display", shortname="light view", fulltext="on/off light segmentation view", key="d" ) 211 self.add_key_shortcut( "Display", shortname="skeleton", fulltext="show/hide/update segmentation skeleton", key="k" ) 212 self.add_key_shortcut( "Display", shortname="show side", fulltext="view layers side by side on/off", key="z" ) 213 self.add_key_shortcut( "Display", shortname="grid", fulltext="show/hide grid", key="g" ) 214 self.add_key_shortcut( "Display", shortname="increase", fulltext="increase label contour size", key="Control-c" ) 215 self.add_key_shortcut( "Display", shortname="decrease", fulltext="decrease label contour size", key="Control-d" ) 216 217 ## Info shortcuts 218 self.add_key_shortcut( "Info", shortname="measure length", fulltext="draw and measure a line length", key="Control"+"-i" ) 219 220 221 def load_default_settings( self ): 222 """ Load all default widget settings """ 223 self.settings = {} 224 225 ## Default visualisation set-up 226 self.settings["Display"] = {} 227 self.settings["Display"]["Layers"] = { 'Tracks': True, 'events': True, 'ROIs': False, 'Segmentation': True, 'Movie': True, 'EpicGrid': False, 'Groups': False } 228 229 self.settings["Info"] = {} 230 231 ## widgets colors 232 self.load_default_colors() 233 234 ## default visualisation of events widget 235 self.settings["events"] = {} 236 237 def load_default_colors( self ): 238 """ Load the defualt GUI colors """ 239 self.settings["Display"]["Colors"] = {} 240 col_set = self.settings["Display"]["Colors"] 241 col_set["button"] = "rgb(40, 60, 75)" 242 col_set["Help button"] = "rgb(62, 60, 75)" 243 col_set["Reset button"] = "rgb(70, 68, 85)" 244 col_set["checkbox"] = "rgb(40, 52, 65)" 245 col_set["line edit"] = "rgb(30, 30, 40)" 246 col_set["group"] = "rgb(33,42,55)" 247 col_set["group4"] = "rgb(37,37,57)" 248 col_set["group3"] = "rgb(30,35,40)" 249 col_set["group2"] = "rgb(30,40,50)"
Handles user-specific preferences (shortcuts, widgets states)
62 def __init__( self ): 63 """ Initialise file path, load current preferences""" 64 self.build_preferences_path() 65 #print("Running on "+platform.lower()) 66 67 self.ctl = "Control" 68 self.alt = "Alt" 69 if platform.lower() == "darwin": 70 self.ctl = "Command" 71 72 self.load_default_shortcuts() 73 self.load_default_settings() 74 if os.path.exists( self.preference_path ): 75 self.load()
Initialise file path, load current preferences
77 def build_preferences_path( self ): 78 """ Build (create directories if necessary) preference path """ 79 home_dir = Path.home() 80 self.preference_path = os.path.join( home_dir, ".napari" ) 81 if not os.path.exists( self.preference_path ): 82 os.mkdir( self.preference_path ) 83 self.preference_path = os.path.join( self.preference_path, "epicure_preferences.pkl" )
Build (create directories if necessary) preference path
85 def save( self ): 86 """ Save the current preferences to the preference files in user home """ 87 outfile = open( self.preference_path, "wb" ) 88 pickle.dump( self.shortcuts, outfile ) 89 pickle.dump( self.settings, outfile ) 90 outfile.close() 91 print( "Preferences saved in file "+self.preference_path )
Save the current preferences to the preference files in user home
93 def set_preferences( self, default_prefs, prefs ): 94 """ Merge (recursively) the preferences with the default ones """ 95 for key, vals in prefs.items(): 96 if key in default_prefs.keys(): 97 if isinstance( vals, dict ): 98 self.set_preferences( default_prefs[key], vals ) 99 else: 100 default_prefs[key] = vals 101 else: 102 default_prefs[key] = vals
Merge (recursively) the preferences with the default ones
104 def load( self ): 105 """ Load the current preferences to the preference files in user home """ 106 infile = open( self.preference_path, "rb" ) 107 shortcuts = pickle.load( infile ) 108 self.set_preferences( self.shortcuts, shortcuts ) 109 try: 110 settings = pickle.load( infile ) 111 #print(settings) 112 self.set_preferences( self.settings, settings ) 113 #print(self.settings) 114 except: 115 self.load_default_settings() 116 #print(self.shortcuts) 117 infile.close() 118 #print( "Preferences loaded from file "+self.preference_path )
Load the current preferences to the preference files in user home
120 def get_settings( self ): 121 """ Return the dict of prefered settings (widget state) """ 122 return self.settings
Return the dict of prefered settings (widget state)
128 def add_key_shortcut( self, main_type, shortname, fulltext, key ): 129 """ Add a keyboard shortcut """ 130 if main_type not in self.shortcuts.keys(): 131 self.shortcuts[ main_type ] = {} 132 ## initialize the new shortcut object 133 self.shortcuts[ main_type ][ shortname ] = {} 134 sc = self.shortcuts[ main_type ][ shortname ] 135 sc["type"] = "key" 136 sc["text"] = fulltext 137 sc["key"] = key
Add a keyboard shortcut
139 def add_click_shortcut( self, main_type, shortname, fulltext, button, modifiers=None ): 140 """ Add a keyboard shortcut """ 141 if main_type not in self.shortcuts.keys(): 142 self.shortcuts[ main_type ] = {} 143 ## initialize the new shortcut object 144 self.shortcuts[ main_type ][ shortname ] = {} 145 sc = self.shortcuts[ main_type ][ shortname ] 146 sc["type"] = "click" 147 sc["text"] = fulltext 148 sc["button"] = button 149 if modifiers is not None: 150 sc["modifiers"] = ["Control" if item=="Command" else item for item in modifiers]
Add a keyboard shortcut
153 def load_default_shortcuts( self ): 154 """ Load all default shortcuts """ 155 156 self.shortcuts = {} 157 158 ## General shortcuts 159 self.add_key_shortcut( "General", shortname="show help", fulltext="show/hide overlay help message", key="h" ) 160 self.add_key_shortcut( "General", shortname="show all", fulltext="show all shortcuts in a separate window", key="a" ) 161 self.add_key_shortcut( "General", shortname="save segmentation", fulltext="save the segmentation and epicure files", key="s" ) 162 self.add_key_shortcut( "General", shortname="save movie", fulltext="save the movie with current display", key="Shift-s" ) 163 164 ## Labels edition (static) shortcuts 165 self.add_key_shortcut( "Labels", shortname="unused paint", fulltext="set the current label to unused value and go to paint mode", key="n" ) 166 self.add_key_shortcut( "Labels", shortname="unused fill", fulltext="set the current label to unused value and go to fill mode", key="Shift-n" ) 167 self.add_key_shortcut( "Labels", shortname="swap mode", fulltext="then <"+self.ctl+">+Left click on one cell to another to swap their values", key="w" ) 168 169 self.add_click_shortcut( "Labels", shortname="erase", fulltext="erase the cell under the click", button="Right", modifiers=None ) 170 self.add_click_shortcut( "Labels", shortname="merge", fulltext="drag-click from one cell to another to merge them", button="Left", modifiers=["Control"] ) 171 self.add_click_shortcut( "Labels", shortname="split accross", fulltext="drag-click in the cell to split into 2 cells ", button="Right", modifiers=["Control"] ) 172 self.add_click_shortcut( "Labels", shortname="split draw", fulltext="drag-click draw a junction to split in 2 cells", button="Right", modifiers=["Alt"] ) 173 self.add_click_shortcut( "Labels", shortname="redraw junction", fulltext="drag-click draw a junction to correct it", button="Left", modifiers=["Alt"] ) 174 self.add_key_shortcut( "Labels", shortname="draw junction mode", fulltext="Draw junction(s) mode ON", key="j" ) 175 self.add_click_shortcut( "Labels", shortname="drawing junction", fulltext="Draw junction mode ON. Drag-click draw a junction to create new cell(s)", button="Left", modifiers=["Control"] ) 176 177 ## Seeds (manual segmentation) shortcuts 178 self.add_key_shortcut( "Seeds", shortname="new seed", fulltext="<key shortcut> then left-click to place a seed", key="e" ) 179 180 ## Groups shortcuts 181 self.add_click_shortcut( "Groups", shortname="add group", fulltext="add the clicked cell to the current group", button="Left", modifiers=["Shift"] ) 182 self.add_click_shortcut( "Groups", shortname="remove group", fulltext="remove the clicked cell from the group", button="Right", modifiers=["Shift"] ) 183 184 ## events edition shortcuts 185 self.add_key_shortcut( "Events", shortname="next", fulltext="zoom on next event", key="Space" ) 186 self.add_click_shortcut( "Events", shortname="zoom", fulltext="Zoom on the clicked event", button="Left", modifiers=["Control", "Alt"] ) 187 self.add_click_shortcut( "Events", shortname="delete", fulltext="Remove the clicked event", button="Right", modifiers=["Control", "Alt"] ) 188 self.add_click_shortcut( "Events", shortname="add division", fulltext="add a division: drag-click from first to second daugther", button="Left", modifiers=["Control", "Shift"] ) 189 self.add_click_shortcut( "Events", shortname="add extrusion", fulltext="add an extrusion: click on the last cell of the track", button="Right", modifiers=["Control", "Shift"] ) 190 191 ## Tracks edition shortcuts 192 self.add_key_shortcut( "Tracks", shortname="show", fulltext="show/hide the tracks", key="r" ) 193 self.add_key_shortcut( "Tracks", shortname="lineage color", fulltext="color the tracks by lineage", key="l" ) 194 self.add_key_shortcut( "Tracks", shortname="mode", fulltext="on/off track editing mode", key="t" ) 195 self.add_click_shortcut( "Tracks", shortname="merge first", fulltext="+track mode ON. Merge tracks: select the first", button="Left" ) 196 self.add_click_shortcut( "Tracks", shortname="merge second", fulltext="+trackmode ON. Merge tracks: selec the second", button="Right" ) 197 self.add_click_shortcut( "Tracks", shortname="split track", fulltext="+trackmode ON. Split the track temporally in 2", button="Right", modifiers=["Shift"] ) 198 self.add_click_shortcut( "Tracks", shortname="start manual", fulltext="+trackmode ON. Start manual tracking, clicking on cells", button="Left", modifiers=["Control"] ) 199 self.add_click_shortcut( "Tracks", shortname="end manual", fulltext="+trackmode ON. Finish manual tracking", button="Right", modifiers=["Control"] ) 200 self.add_click_shortcut( "Tracks", shortname="interpolate first", fulltext="+trackmode ON. Interpolate temporally labels: select first", button="Left", modifiers=["Alt"] ) 201 self.add_click_shortcut( "Tracks", shortname="interpolate second", fulltext="+trackmode ON. Interpolate temporally labels: select second", button="Right", modifiers=["Alt"] ) 202 self.add_click_shortcut( "Tracks", shortname="swap", fulltext="+trackmode ON. Drag click to swap 2 tracks from current frame", button="Left", modifiers=["Shift"] ) 203 self.add_click_shortcut( "Tracks", shortname="delete", fulltext="+trackmode ON. Delete all the track from current frame", button="Right", modifiers=["Control", "Alt"] ) 204 205 ## Visualisation option shortcuts 206 self.add_key_shortcut( "Display", shortname="vis. segmentation", fulltext="show/hide segmentation layer", key="b" ) 207 self.add_key_shortcut( "Display", shortname="vis. movie", fulltext="show/hide movie layer", key="v" ) 208 self.add_key_shortcut( "Display", shortname="vis. event", fulltext="show.hide events layer", key="x" ) 209 self.add_key_shortcut( "Display", shortname="only movie", fulltext="show ONLY movie layer on/off", key="c" ) 210 self.add_key_shortcut( "Display", shortname="light view", fulltext="on/off light segmentation view", key="d" ) 211 self.add_key_shortcut( "Display", shortname="skeleton", fulltext="show/hide/update segmentation skeleton", key="k" ) 212 self.add_key_shortcut( "Display", shortname="show side", fulltext="view layers side by side on/off", key="z" ) 213 self.add_key_shortcut( "Display", shortname="grid", fulltext="show/hide grid", key="g" ) 214 self.add_key_shortcut( "Display", shortname="increase", fulltext="increase label contour size", key="Control-c" ) 215 self.add_key_shortcut( "Display", shortname="decrease", fulltext="decrease label contour size", key="Control-d" ) 216 217 ## Info shortcuts 218 self.add_key_shortcut( "Info", shortname="measure length", fulltext="draw and measure a line length", key="Control"+"-i" )
Load all default shortcuts
221 def load_default_settings( self ): 222 """ Load all default widget settings """ 223 self.settings = {} 224 225 ## Default visualisation set-up 226 self.settings["Display"] = {} 227 self.settings["Display"]["Layers"] = { 'Tracks': True, 'events': True, 'ROIs': False, 'Segmentation': True, 'Movie': True, 'EpicGrid': False, 'Groups': False } 228 229 self.settings["Info"] = {} 230 231 ## widgets colors 232 self.load_default_colors() 233 234 ## default visualisation of events widget 235 self.settings["events"] = {}
Load all default widget settings
237 def load_default_colors( self ): 238 """ Load the defualt GUI colors """ 239 self.settings["Display"]["Colors"] = {} 240 col_set = self.settings["Display"]["Colors"] 241 col_set["button"] = "rgb(40, 60, 75)" 242 col_set["Help button"] = "rgb(62, 60, 75)" 243 col_set["Reset button"] = "rgb(70, 68, 85)" 244 col_set["checkbox"] = "rgb(40, 52, 65)" 245 col_set["line edit"] = "rgb(30, 30, 40)" 246 col_set["group"] = "rgb(33,42,55)" 247 col_set["group4"] = "rgb(37,37,57)" 248 col_set["group3"] = "rgb(30,35,40)" 249 col_set["group2"] = "rgb(30,40,50)"
Load the defualt GUI colors
252class ShortCut( QWidget ): 253 """ Class to handle edit EpiCure shortcuts """ 254 255 def __init__( self, napari_viewer, pref ): 256 super().__init__() 257 258 layout = QVBoxLayout() 259 self.ctl = "Control" 260 if platform.lower() == "darwin": 261 self.ctl = "Command" 262 263 self.sc = pref.get_shortcuts() 264 ## choice list to choose which shortcuts to edit 265 self.shortcut_types = self.sc.keys() 266 self.sc_types = QComboBox() 267 self.sc_groups = {} 268 self.sc_guis = {} 269 layout.addWidget( self.sc_types ) 270 for sc_type in self.shortcut_types: 271 self.sc_types.addItem( sc_type ) 272 self.sc_guis[sc_type] = {} 273 self.sc_groups[sc_type] = self.create_sc_type( sc_type ) 274 layout.addWidget( self.sc_groups[sc_type] ) 275 self.show_sc_type() 276 277 self.setLayout(layout) 278 self.sc_types.currentIndexChanged.connect( self.show_sc_type ) 279 280 def show_sc_type( self ): 281 """ Show only selected shortcut subset """ 282 for sc_type in self.shortcut_types: 283 self.sc_groups[ sc_type ].setVisible( self.sc_types.currentText() == sc_type ) 284 285 def create_sc_type( self, sc_type ): 286 """ Interface to edit shortcut subset of a given type """ 287 sc_curgroup = QGroupBox( "" ) 288 sc_layout = QVBoxLayout() 289 290 ## add each shortcut from the current selected group 291 cur_shortcuts = self.sc[ sc_type ] 292 for shortname, val in cur_shortcuts.items(): 293 new_line = QHBoxLayout() 294 ## current keyboard shortcut 295 if val["type"] == "click": 296 ## shortcut is a mouse shortcut 297 if "modifiers" in val.keys(): 298 ind = 0 299 for modif in val["modifiers"]: 300 cur_modif = QComboBox() 301 cur_modif.addItem("") 302 cur_modif.addItem("Control") 303 cur_modif.addItem("Shift") 304 cur_modif.addItem("Alt") 305 if platform.lower() == "darwin": 306 cur_modif.addItem("Command") 307 cur_modif.addItem("Option") 308 new_line.addWidget( cur_modif ) 309 cur_modif.setCurrentText( modif ) 310 self.sc_guis[sc_type][ shortname+"modifiers"+str(ind) ] = cur_modif 311 ind = ind + 1 312 cur_click = QComboBox() 313 cur_click.addItem("Left-click") 314 cur_click.addItem("Right-click") 315 new_line.addWidget( cur_click ) 316 if val["button"] == "Right": 317 cur_click.setCurrentText( "Right-click" ) 318 self.sc_guis[sc_type][ shortname ] = cur_click 319 if val["type"] == "key": 320 new_line_val = QLineEdit() 321 new_line_val.setText( val["key"] ) 322 self.sc_guis[sc_type][ shortname ] = new_line_val 323 new_line.addWidget( new_line_val ) 324 ## full description of the shortcut 325 long_description = QLabel() 326 long_description.setText( val["text"] ) 327 new_line.addWidget( long_description ) 328 sc_layout.addLayout( new_line ) 329 #empty = QLabel() 330 #sc_layout.addWidget( empty ) 331 332 sc_curgroup.setLayout( sc_layout ) 333 return sc_curgroup 334 335 def update_pref( self ): 336 """ Update the shortcuts in the Preference based on current values """ 337 for sc_type in self.shortcut_types: 338 gui = self.sc_guis[ sc_type ] 339 sc_group = self.sc[ sc_type ] 340 for shortname, vals in sc_group.items(): 341 if vals["type"] == "click": 342 ## update the modifiers if there are some 343 ind = 0 344 if "modifiers" in vals.keys(): 345 del vals["modifiers"] 346 while shortname+"modifiers"+str(ind) in gui.keys(): 347 modif = gui[ shortname+"modifiers"+str(ind) ].currentText() 348 if "modifiers" not in vals.keys(): 349 vals["modifiers"] = [] 350 if modif != "": 351 vals["modifiers"].append(modif) 352 ind = ind + 1 353 if len( vals["modifiers"] ) == 0: 354 del vals["modifiers"] 355 ## update the button information 356 click = gui[shortname].currentText() 357 if click == "Left-click": 358 vals["button"] = "Left" 359 else: 360 vals["button"] = "Right" 361 if vals["type"] == "key": 362 vals["key"] = gui[shortname].text()
Class to handle edit EpiCure shortcuts
255 def __init__( self, napari_viewer, pref ): 256 super().__init__() 257 258 layout = QVBoxLayout() 259 self.ctl = "Control" 260 if platform.lower() == "darwin": 261 self.ctl = "Command" 262 263 self.sc = pref.get_shortcuts() 264 ## choice list to choose which shortcuts to edit 265 self.shortcut_types = self.sc.keys() 266 self.sc_types = QComboBox() 267 self.sc_groups = {} 268 self.sc_guis = {} 269 layout.addWidget( self.sc_types ) 270 for sc_type in self.shortcut_types: 271 self.sc_types.addItem( sc_type ) 272 self.sc_guis[sc_type] = {} 273 self.sc_groups[sc_type] = self.create_sc_type( sc_type ) 274 layout.addWidget( self.sc_groups[sc_type] ) 275 self.show_sc_type() 276 277 self.setLayout(layout) 278 self.sc_types.currentIndexChanged.connect( self.show_sc_type )
280 def show_sc_type( self ): 281 """ Show only selected shortcut subset """ 282 for sc_type in self.shortcut_types: 283 self.sc_groups[ sc_type ].setVisible( self.sc_types.currentText() == sc_type )
Show only selected shortcut subset
285 def create_sc_type( self, sc_type ): 286 """ Interface to edit shortcut subset of a given type """ 287 sc_curgroup = QGroupBox( "" ) 288 sc_layout = QVBoxLayout() 289 290 ## add each shortcut from the current selected group 291 cur_shortcuts = self.sc[ sc_type ] 292 for shortname, val in cur_shortcuts.items(): 293 new_line = QHBoxLayout() 294 ## current keyboard shortcut 295 if val["type"] == "click": 296 ## shortcut is a mouse shortcut 297 if "modifiers" in val.keys(): 298 ind = 0 299 for modif in val["modifiers"]: 300 cur_modif = QComboBox() 301 cur_modif.addItem("") 302 cur_modif.addItem("Control") 303 cur_modif.addItem("Shift") 304 cur_modif.addItem("Alt") 305 if platform.lower() == "darwin": 306 cur_modif.addItem("Command") 307 cur_modif.addItem("Option") 308 new_line.addWidget( cur_modif ) 309 cur_modif.setCurrentText( modif ) 310 self.sc_guis[sc_type][ shortname+"modifiers"+str(ind) ] = cur_modif 311 ind = ind + 1 312 cur_click = QComboBox() 313 cur_click.addItem("Left-click") 314 cur_click.addItem("Right-click") 315 new_line.addWidget( cur_click ) 316 if val["button"] == "Right": 317 cur_click.setCurrentText( "Right-click" ) 318 self.sc_guis[sc_type][ shortname ] = cur_click 319 if val["type"] == "key": 320 new_line_val = QLineEdit() 321 new_line_val.setText( val["key"] ) 322 self.sc_guis[sc_type][ shortname ] = new_line_val 323 new_line.addWidget( new_line_val ) 324 ## full description of the shortcut 325 long_description = QLabel() 326 long_description.setText( val["text"] ) 327 new_line.addWidget( long_description ) 328 sc_layout.addLayout( new_line ) 329 #empty = QLabel() 330 #sc_layout.addWidget( empty ) 331 332 sc_curgroup.setLayout( sc_layout ) 333 return sc_curgroup
Interface to edit shortcut subset of a given type
335 def update_pref( self ): 336 """ Update the shortcuts in the Preference based on current values """ 337 for sc_type in self.shortcut_types: 338 gui = self.sc_guis[ sc_type ] 339 sc_group = self.sc[ sc_type ] 340 for shortname, vals in sc_group.items(): 341 if vals["type"] == "click": 342 ## update the modifiers if there are some 343 ind = 0 344 if "modifiers" in vals.keys(): 345 del vals["modifiers"] 346 while shortname+"modifiers"+str(ind) in gui.keys(): 347 modif = gui[ shortname+"modifiers"+str(ind) ].currentText() 348 if "modifiers" not in vals.keys(): 349 vals["modifiers"] = [] 350 if modif != "": 351 vals["modifiers"].append(modif) 352 ind = ind + 1 353 if len( vals["modifiers"] ) == 0: 354 del vals["modifiers"] 355 ## update the button information 356 click = gui[shortname].currentText() 357 if click == "Left-click": 358 vals["button"] = "Left" 359 else: 360 vals["button"] = "Right" 361 if vals["type"] == "key": 362 vals["key"] = gui[shortname].text()
Update the shortcuts in the Preference based on current values
365class DisplaySettings( QWidget ): 366 """ Class to handle edit EpiCure display button colors...)""" 367 368 def __init__( self, napari_viewer, pref ): 369 super().__init__() 370 self.settings = pref.get_settings() 371 if "Colors" not in self.settings["Display"]: 372 pref.load_default_colors() 373 colors = self.settings["Display"]["Colors"] 374 375 ## interface of display choices 376 layout = QVBoxLayout() 377 self.grid_color = QPushButton("EpicGrid color", self) 378 self.grid_color.clicked.connect( self.get_grid_color ) 379 layout.addWidget( self.grid_color ) 380 381 self.add_color( layout, "Buttons color", "button", "Choose default color of buttons" ) 382 self.add_color( layout, "Help buttons color", "Help button", "Choose color of buttons for Help actions" ) 383 self.add_color( layout, "Reset buttons color", "Reset button", "Choose color of buttons for Reset actions" ) 384 self.add_color( layout, "CheckBox color", "checkbox", "Choose color of checkboxes" ) 385 self.add_color( layout, "Input color", "line edit", "Choose color of editable parameters boxes" ) 386 self.add_color( layout, "Subpanels color", "group", "Choose color of option subpanels that appears when clicked/selected" ) 387 self.add_color( layout, "Subpanels color 2", "group2", "Choose second color of option subpanels that appears when clicked/selected" ) 388 self.add_color( layout, "Subpanels color 3", "group3", "Choose third color of option subpanels that appears when clicked/selected" ) 389 self.add_color( layout, "Subpanels color 4", "group4", "Choose fourth color of option subpanels that appears when clicked/selected" ) 390 391 self.setLayout(layout) 392 393 def add_color( self, layout, label, setname, descr="" ): 394 """ Add a choice of color (push button that opens a color dialog) """ 395 btn = QPushButton( label ) 396 if descr != "": 397 btn.setToolTip( descr ) 398 def get_color(): 399 """ opens color dialog and set button color to it """ 400 color = QColorDialog.getColor() 401 if color.isValid(): 402 self.settings["Display"]["Colors"][setname] = color.name() 403 btn.setStyleSheet( 'QPushButton {background-color: '+color.name()+'}' ) 404 btn.clicked.connect( get_color ) 405 if setname in self.settings["Display"]["Colors"]: 406 color = self.settings["Display"]["Colors"][setname] 407 btn.setStyleSheet( 'QPushButton {background-color: '+color+'}' ) 408 layout.addWidget( btn ) 409 410 def get_grid_color( self ): 411 """ Get the EpiCGrid color """ 412 color = QColorDialog.getColor() 413 if color.isValid(): 414 if "Display" not in self.settings: 415 self.settings["Display"] = {} 416 self.settings["Display"]["Grid color"] = color.name() 417 self.grid_color.setStyleSheet( 'QPushButton {background-color: '+color.name()+'}' )
Class to handle edit EpiCure display button colors...)
368 def __init__( self, napari_viewer, pref ): 369 super().__init__() 370 self.settings = pref.get_settings() 371 if "Colors" not in self.settings["Display"]: 372 pref.load_default_colors() 373 colors = self.settings["Display"]["Colors"] 374 375 ## interface of display choices 376 layout = QVBoxLayout() 377 self.grid_color = QPushButton("EpicGrid color", self) 378 self.grid_color.clicked.connect( self.get_grid_color ) 379 layout.addWidget( self.grid_color ) 380 381 self.add_color( layout, "Buttons color", "button", "Choose default color of buttons" ) 382 self.add_color( layout, "Help buttons color", "Help button", "Choose color of buttons for Help actions" ) 383 self.add_color( layout, "Reset buttons color", "Reset button", "Choose color of buttons for Reset actions" ) 384 self.add_color( layout, "CheckBox color", "checkbox", "Choose color of checkboxes" ) 385 self.add_color( layout, "Input color", "line edit", "Choose color of editable parameters boxes" ) 386 self.add_color( layout, "Subpanels color", "group", "Choose color of option subpanels that appears when clicked/selected" ) 387 self.add_color( layout, "Subpanels color 2", "group2", "Choose second color of option subpanels that appears when clicked/selected" ) 388 self.add_color( layout, "Subpanels color 3", "group3", "Choose third color of option subpanels that appears when clicked/selected" ) 389 self.add_color( layout, "Subpanels color 4", "group4", "Choose fourth color of option subpanels that appears when clicked/selected" ) 390 391 self.setLayout(layout)
393 def add_color( self, layout, label, setname, descr="" ): 394 """ Add a choice of color (push button that opens a color dialog) """ 395 btn = QPushButton( label ) 396 if descr != "": 397 btn.setToolTip( descr ) 398 def get_color(): 399 """ opens color dialog and set button color to it """ 400 color = QColorDialog.getColor() 401 if color.isValid(): 402 self.settings["Display"]["Colors"][setname] = color.name() 403 btn.setStyleSheet( 'QPushButton {background-color: '+color.name()+'}' ) 404 btn.clicked.connect( get_color ) 405 if setname in self.settings["Display"]["Colors"]: 406 color = self.settings["Display"]["Colors"][setname] 407 btn.setStyleSheet( 'QPushButton {background-color: '+color+'}' ) 408 layout.addWidget( btn )
Add a choice of color (push button that opens a color dialog)
410 def get_grid_color( self ): 411 """ Get the EpiCGrid color """ 412 color = QColorDialog.getColor() 413 if color.isValid(): 414 if "Display" not in self.settings: 415 self.settings["Display"] = {} 416 self.settings["Display"]["Grid color"] = color.name() 417 self.grid_color.setStyleSheet( 'QPushButton {background-color: '+color.name()+'}' )
Get the EpiCGrid color