11from .myqt import QT
22import pyqtgraph as pg
33import markdown
4-
4+ import numpy as np
5+ from copy import copy
56
67import weakref
78
89from .viewlist import possible_class_views
910from .layout_presets import get_layout_description
11+ from .utils_global import get_size_bottom_row , get_size_top_row
1012
1113from .utils_qt import qt_style , add_stretch_to_qtoolbar
1214
13-
1415# Used by views to emit/trigger signals
1516class SignalNotifier (QT .QObject ):
1617 spike_selection_changed = QT .pyqtSignal ()
@@ -153,7 +154,6 @@ def __init__(self, controller, parent=None, layout_preset=None, layout=None):
153154 # refresh do not work because view are not yet visible at init
154155 view ._refresh ()
155156 self .controller .signal_handler .activate ()
156-
157157 # TODO sam : all veiws are always refreshed at the moment so this is useless.
158158 # uncommen this when ViewBase.is_view_visible() work correctly
159159 # for view_name, dock in self.docks.items():
@@ -200,47 +200,8 @@ def create_main_layout(self):
200200 view_names = [view_name for view_name in view_names if view_name in self .views .keys ()]
201201 widgets_zone [zone ] = view_names
202202
203- ## Handle left
204- first_left = None
205- for zone in ['zone1' , 'zone5' , 'zone2' , 'zone6' ]:
206- if len (widgets_zone [zone ]) == 0 :
207- continue
208- view_name = widgets_zone [zone ][0 ]
209- dock = self .docks [view_name ]
210- if len (widgets_zone [zone ]) > 0 and first_left is None :
211- self .addDockWidget (areas ['left' ], dock )
212- first_left = view_name
213- elif zone == 'zone5' :
214- self .splitDockWidget (self .docks [first_left ], dock , orientations ['vertical' ])
215- elif zone == 'zone2' :
216- self .splitDockWidget (self .docks [first_left ], dock , orientations ['horizontal' ])
217- elif zone == 'zone6' :
218- if len (widgets_zone ['zone5' ]) > 0 :
219- z = widgets_zone ['zone5' ][0 ]
220- self .splitDockWidget (self .docks [z ], dock , orientations ['horizontal' ])
221- else :
222- self .splitDockWidget (self .docks [first_left ], dock , orientations ['vertical' ])
223-
224- ## Handle right
225- first_top = None
226- for zone in ['zone3' , 'zone4' , 'zone7' , 'zone8' ]:
227- if len (widgets_zone [zone ]) == 0 :
228- continue
229- view_name = widgets_zone [zone ][0 ]
230- dock = self .docks [view_name ]
231- if len (widgets_zone [zone ]) > 0 and first_top is None :
232- self .addDockWidget (areas ['right' ], dock )
233- first_top = view_name
234- elif zone == 'zone4' :
235- self .splitDockWidget (self .docks [first_top ], dock , orientations ['horizontal' ])
236- elif zone == 'zone7' :
237- self .splitDockWidget (self .docks [first_top ], dock , orientations ['vertical' ])
238- elif zone == 'zone8' :
239- if len (widgets_zone ['zone4' ]) > 0 :
240- z = widgets_zone ['zone4' ][0 ]
241- self .splitDockWidget (self .docks [z ], dock , orientations ['vertical' ])
242- else :
243- self .splitDockWidget (self .docks [first_top ], dock , orientations ['horizontal' ])
203+ self .make_dock (widgets_zone , ['zone1' , 'zone2' , 'zone5' , 'zone6' ], "left" , col_shift = 0 )
204+ self .make_dock (widgets_zone , ['zone3' , 'zone4' , 'zone7' , 'zone8' ], "right" , col_shift = 2 )
244205
245206 # make tabs
246207 for zone , view_names in widgets_zone .items ():
@@ -256,6 +217,104 @@ def create_main_layout(self):
256217 # make visible the first of each zone
257218 self .docks [view_name0 ].raise_ ()
258219
220+ def make_dock (self , widgets_zone , all_zones , side_of_window , col_shift ):
221+
222+ all_zones_array = np .transpose (np .reshape (all_zones , (2 ,2 )))
223+ is_zone = np .array ([(widgets_zone .get (zone ) is not None ) and (len (widgets_zone .get (zone )) > 0 ) for zone in all_zones ])
224+ is_zone_array = np .reshape (is_zone , (2 ,2 ))
225+
226+ # If the first non-zero zero (from left to right) is on the bottom, move it up
227+ for column_index , zones_in_columns in enumerate (is_zone_array ):
228+ if np .any (zones_in_columns ):
229+ first_is_top = zones_in_columns [0 ]
230+ if not first_is_top :
231+ top_zone = f"zone{ column_index + 1 + col_shift } "
232+ bottom_zone = f"zone{ column_index + 5 + col_shift } "
233+ widgets_zone [top_zone ] = widgets_zone [bottom_zone ]
234+ widgets_zone [bottom_zone ] = []
235+ continue
236+
237+ is_zone = np .array ([(widgets_zone .get (zone ) is not None ) and (len (widgets_zone .get (zone )) > 0 ) for zone in all_zones ])
238+ is_zone_array = np .reshape (is_zone , (2 ,2 ))
239+ original_zone_array = copy (is_zone_array )
240+
241+ # First we split horizontally any columns which are two rows long.
242+ # For later, group the zones between these splits
243+ all_groups = []
244+ group = []
245+ for col_index , zones in enumerate (all_zones_array ):
246+ col = col_index % 2
247+ is_a_zone = original_zone_array [:,col ]
248+ num_row_0 , _ = get_size_top_row (0 , col , is_zone_array , original_zone_array )
249+ # this function affects is_zone_array so must be run
250+ _ , _ = get_size_bottom_row (1 , col , is_zone_array , original_zone_array )
251+
252+ if num_row_0 == 2 :
253+ if len (group ) > 0 :
254+ all_groups .append (group )
255+ group = []
256+ allowed_zones = zones [is_a_zone ]
257+ all_groups .append (allowed_zones )
258+ else :
259+ for zone in zones [is_a_zone ]:
260+ group .append (zone )
261+
262+ if len (group ) > 0 :
263+ all_groups .append (group )
264+
265+ if len (all_groups ) == 0 :
266+ return
267+
268+ first_zone = all_groups [0 ][0 ]
269+ first_dock = widgets_zone [first_zone ][0 ]
270+ dock = self .docks [first_dock ]
271+ self .addDockWidget (areas [side_of_window ], dock )
272+
273+ for group in reversed (all_groups [1 :]):
274+ digits = np .array ([int (s [- 1 ]) for s in group ])
275+ sorted_indices = np .argsort (digits )
276+ sorted_arr = np .array (group )[sorted_indices ]
277+ view_name = widgets_zone [sorted_arr [0 ]][0 ]
278+ dock = self .docks [view_name ]
279+ self .splitDockWidget (self .docks [first_dock ], dock , orientations ['horizontal' ])
280+
281+ # Now take each sub-group, and split vertically if appropriate
282+ new_all_groups = []
283+ for group in all_groups :
284+
285+ if len (group ) == 1 :
286+ # if only one in group, not need to split
287+ continue
288+
289+ top_zones = [zone for zone in group if zone in ['zone1' , 'zone2' , 'zone3' , 'zone4' ]]
290+ bottom_zones = [zone for zone in group if zone in ['zone5' , 'zone6' , 'zone7' , 'zone8' ]]
291+ new_all_groups .append ([top_zones , bottom_zones ])
292+
293+ if len (top_zones ) > 0 and len (bottom_zones ) > 0 :
294+
295+ top_view_name = widgets_zone [top_zones [0 ]][0 ]
296+ top_dock = self .docks [top_view_name ]
297+
298+ bottom_view_name = widgets_zone [bottom_zones [0 ]][0 ]
299+ bottom_dock = self .docks [bottom_view_name ]
300+
301+ self .splitDockWidget (top_dock , bottom_dock , orientations ['vertical' ])
302+
303+ # Finally, split all the sub-sub-groups horizontally
304+ for top_bottom_groups in new_all_groups :
305+ for group in top_bottom_groups :
306+
307+ if len (group ) <= 1 :
308+ # if only one in group, no need to split
309+ continue
310+
311+ first_zone_name = widgets_zone [group [0 ]][0 ]
312+ for zone in reversed (group [1 :]):
313+ zone_name = widgets_zone [zone ][0 ]
314+ self .splitDockWidget (self .docks [first_zone_name ], self .docks [zone_name ], orientations ['horizontal' ])
315+
316+
317+
259318 # used by to tell the launcher this is closed
260319 def closeEvent (self , event ):
261320 self .main_window_closed .emit (self )
0 commit comments