def _test_create(): frame = wx.GetApp().GetTopWindow() items = [random.randint(1, 100) for i in range(5)] labels = [str(i) for i in items] tooltips = ['tip: {}'.format(i) for i in items] listbox = elistbox.EditableListBox(frame, labels=labels, clientData=items, tooltips=tooltips) assert listbox.VisibleItemCount() == 5 assert listbox.GetCount() == 5 assert listbox.GetSelection() == wx.NOT_FOUND listbox.SetSelection(3) assert listbox.GetSelection() == 3 for idx, i in enumerate(items): assert listbox.IndexOf(i) == idx assert list(listbox.GetLabels()) == list(labels) assert list(listbox.GetData()) == list(items) for i in range(len(items)): assert listbox.GetItemTooltip(i) == tooltips[i] assert listbox.GetItemLabel(i) == labels[i] assert listbox.GetItemData(i) == items[i]
def _test_add_remove(): frame = wx.GetApp().GetTopWindow() items = [str(random.randint(1, 100)) for i in range(5)] listbox = elistbox.EditableListBox(frame, items) # delete for i in range(5): ridx = random.randint(0, len(items) - 1) items.pop(ridx) listbox.Delete(ridx) assert list(listbox.GetLabels()) == items # append for i in range(5): item = str(random.randint(0, 100)) items.append(item) listbox.Append(item) assert list(listbox.GetLabels()) == items # insert for i in range(5): item = str(random.randint(0, 100)) idx = random.randint(0, len(items) - 1) items.insert(idx, item) listbox.Insert(item, idx) assert list(listbox.GetLabels()) == items
def _listEmbedWidget(parent, hasProps, propObj, propVal): if not isinstance(propObj._listType, (ptypes.String, ptypes.Int, ptypes.Real)): raise RuntimeError('Unsupported property ' 'type: {}'.format(propObj.__class__)) widget = elistbox.EditableListBox( parent, ['{}'.format(v) for v in propVal], style=(elistbox.ELB_NO_ADD | elistbox.ELB_NO_REMOVE | elistbox.ELB_EDITABLE)) changeTriggeredByWidget = [False] def _listBoxMove(ev): changeTriggeredByWidget[0] = True propVal.move(ev.oldIdx, ev.newIdx) changeTriggeredByWidget[0] = False def _listBoxEdit(ev): changeTriggeredByWidget[0] = True propVal[ev.idx] = ev.label changeTriggeredByWidget[0] = False def _listChanged(*a): if changeTriggeredByWidget[0]: return sel = widget.GetSelection() widget.Clear() for val in propVal: widget.Append('{}'.format(val)) if sel < widget.GetCount(): widget.SetSelection(sel) else: widget.SetSelection(widget.GetCount() - 1) widget.Bind(elistbox.EVT_ELB_MOVE_EVENT, _listBoxMove) widget.Bind(elistbox.EVT_ELB_EDIT_EVENT, _listBoxEdit) propVal.addListener('widgets_list_py_{}'.format(id(widget)), _listChanged, weak=False) return widget
def __init__(self, parent, overlayList, displayCtx, frame, atlasPanel): """Create an ``AtlasManagementPanel``. :arg parent: the :mod:`wx` parent object. :arg overlayList: The :class:`.OverlayList` instance. :arg displayCtx: The :class:`.DisplayContext` instance. :arg frame: The :class:`.FSLeyesFrame` instance. :arg atlasPanel: The :class:`.AtlasPanel` instance that has created this ``AtlasManagementPanel``. """ fslpanel.FSLeyesPanel.__init__( self, parent, overlayList, displayCtx, frame) descs = atlases.listAtlases() names = [d.name for d in descs] paths = [d.specPath for d in descs] self.__atlasList = elistbox.EditableListBox( self, labels=names, clientData=descs, tooltips=paths, style=(elistbox.ELB_NO_MOVE | elistbox.ELB_TOOLTIP_DOWN)) self.__sizer = wx.BoxSizer(wx.HORIZONTAL) self.__sizer.Add(self.__atlasList, flag=wx.EXPAND, proportion=1) self.SetSizer(self.__sizer) self.SetMinSize(self.__sizer.GetMinSize()) self.__atlasList.Bind(elistbox.EVT_ELB_ADD_EVENT, self.__onListAdd) self.__atlasList.Bind(elistbox.EVT_ELB_REMOVE_EVENT, self.__onListRemove) atlases.registry.register(self.name, self.__atlasAdded, 'add') atlases.registry.register(self.name, self.__atlasRemoved, 'remove')
def __init__(self, parent, overlayList, displayCtx, frame, plotPanel): """Create a ``PlotListPanel``. :arg parent: The :mod:`wx` parent object. :arg overlayList: The :class:`.OverlayList`. :arg displayCtx: The :class:`.DisplayContext` instance. :arg frame: The :class:`.FSLeyesFrame` instance. :arg plotPanel: The :class:`.OverlayPlotPanel` associated with this ``PlotListPanel``. """ fslpanel.FSLeyesPanel.__init__(self, parent, overlayList, displayCtx, frame) self.__plotPanel = plotPanel self.__dsList = elistbox.EditableListBox( self, style=(elistbox.ELB_NO_MOVE | elistbox.ELB_EDITABLE | elistbox.ELB_WIDGET_RIGHT)) self.__sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(self.__sizer) self.__sizer.Add(self.__dsList, flag=wx.EXPAND, proportion=1) self.__dsList.Bind(elistbox.EVT_ELB_ADD_EVENT, self.__onListAdd) self.__dsList.Bind(elistbox.EVT_ELB_REMOVE_EVENT, self.__onListRemove) self.__dsList.Bind(elistbox.EVT_ELB_EDIT_EVENT, self.__onListEdit) self.__dsList.Bind(elistbox.EVT_ELB_SELECT_EVENT, self.__onListSelect) self.__plotPanel.addListener('dataSeries', self.name, self.__dataSeriesChanged) self.__dataSeriesChanged() self.Layout() self.SetMinSize(self.__sizer.GetMinSize())
def __init__(self, parent, overlayList, displayCtx, frame, canvasPanel, limit=500): """Create a ``LocationHistoryPanel``. :arg parent: The :mod:`wx` parent object. :arg overlayList: The :class:`.OverlayList` instance. :arg displayCtx: The :class:`.DisplayContext` instance. :arg frame: The :class:`.FSLeyesFrame` instance. :arg canvasPanel: The :class:`.CanvasPanel` which owns this ``LocationHistoryPanel``. :arg limit: Maximum number of locations to save before dropping old locations. """ fslpanel.FSLeyesPanel.__init__( self, parent, overlayList, displayCtx, frame) self.__profile = None self.__limit = limit self.__canvas = canvasPanel self.__sizer = wx.BoxSizer(wx.VERTICAL) self.__btnSizer = wx.BoxSizer(wx.HORIZONTAL) self.__load = wx.Button(self, style=wx.BU_EXACTFIT) self.__save = wx.Button(self, style=wx.BU_EXACTFIT) self.__clear = wx.Button(self, style=wx.BU_EXACTFIT) self.__hint = wx.StaticText(self) self.__list = elistbox.EditableListBox( self, style=(elistbox.ELB_REVERSE | elistbox.ELB_NO_ADD | elistbox.ELB_NO_REMOVE | elistbox.ELB_NO_MOVE | elistbox.ELB_EDITABLE | elistbox.ELB_SCROLL_BUTTONS)) self.__load .SetLabel(strings.labels[self, 'load']) self.__save .SetLabel(strings.labels[self, 'save']) self.__clear.SetLabel(strings.labels[self, 'clear']) self.__hint .SetLabel(strings.labels[self, 'hint']) self.__btnSizer.Add((10, 1)) self.__btnSizer.Add(self.__hint, flag=wx.EXPAND, proportion=1) self.__btnSizer.Add(self.__load) self.__btnSizer.Add((10, 1)) self.__btnSizer.Add(self.__save) self.__btnSizer.Add((10, 1)) self.__btnSizer.Add(self.__clear) self.__btnSizer.Add((10, 1)) self.__sizer.Add(self.__btnSizer, flag=wx.EXPAND | wx.TOP | wx.BOTTOM, border=3) self.__sizer.Add(self.__list, flag=wx.EXPAND, proportion=1) self.SetSizer(self.__sizer) self.Layout() self.__list .Bind(elistbox.EVT_ELB_SELECT_EVENT, self.__onListSelect) self.__load .Bind(wx.EVT_BUTTON, self.__onLoad) self.__save .Bind(wx.EVT_BUTTON, self.__onSave) self.__clear.Bind(wx.EVT_BUTTON, self.__onClear) self.__canvas.addListener('profile', self.name, self.__profileChanged) self.__profileChanged()
def __init__(self, parent, overlayList, displayCtx, frame): """Create a ``LookupTablePanel``. :arg parent: The :mod:`wx` parent object. :arg overlayList: The :class:`.OverlayList` instance. :arg displayCtx: The :class:`.DisplayContext` instance. :arg frame: The :class:`.FSLeyesFrame` instance. """ ctrlpanel.ControlPanel.__init__(self, parent, overlayList, displayCtx, frame) self.__controlCol = wx.Panel(self) self.__labelList = elistbox.EditableListBox( self, style=(elistbox.ELB_NO_MOVE | elistbox.ELB_NO_ADD | elistbox.ELB_NO_REMOVE | elistbox.ELB_WIDGET_RIGHT)) self.__lutChoice = wx.Choice(self.__controlCol) self.__selAllButton = wx.Button(self.__controlCol) self.__selNoneButton = wx.Button(self.__controlCol) self.__addLabelButton = wx.Button(self.__controlCol) self.__rmLabelButton = wx.Button(self.__controlCol) self.__newLutButton = wx.Button(self.__controlCol) self.__copyLutButton = wx.Button(self.__controlCol) self.__saveLutButton = wx.Button(self.__controlCol) self.__loadLutButton = wx.Button(self.__controlCol) self.__controlColSizer = wx.BoxSizer(wx.VERTICAL) self.__sizer = wx.BoxSizer(wx.VERTICAL) self.__controlCol.SetSizer(self.__controlColSizer) self.SetSizer(self.__sizer) self.__controlColSizer.Add(self.__lutChoice, flag=wx.EXPAND) self.__controlColSizer.Add(self.__selAllButton, flag=wx.EXPAND) self.__controlColSizer.Add(self.__selNoneButton, flag=wx.EXPAND) self.__controlColSizer.Add(self.__addLabelButton, flag=wx.EXPAND) self.__controlColSizer.Add(self.__rmLabelButton, flag=wx.EXPAND) self.__controlColSizer.Add(self.__newLutButton, flag=wx.EXPAND) self.__controlColSizer.Add(self.__copyLutButton, flag=wx.EXPAND) self.__controlColSizer.Add(self.__loadLutButton, flag=wx.EXPAND) self.__controlColSizer.Add(self.__saveLutButton, flag=wx.EXPAND) self.__sizer.Add(self.__controlCol, flag=wx.EXPAND) self.__sizer.Add(self.__labelList, flag=wx.EXPAND, proportion=1) # Label the buttons self.__selAllButton.SetLabel(strings.labels[self, 'selectAll']) self.__selNoneButton.SetLabel(strings.labels[self, 'selectNone']) self.__addLabelButton.SetLabel(strings.labels[self, 'addLabel']) self.__rmLabelButton.SetLabel(strings.labels[self, 'removeLabel']) self.__newLutButton.SetLabel(strings.labels[self, 'newLut']) self.__copyLutButton.SetLabel(strings.labels[self, 'copyLut']) self.__loadLutButton.SetLabel(strings.labels[self, 'loadLut']) self.__saveLutButton.SetLabel(strings.labels[self, 'saveLut']) self.__lutChoice.Bind(wx.EVT_CHOICE, self.__onLutChoice) self.__selAllButton.Bind(wx.EVT_BUTTON, self.__onSelectAll) self.__selNoneButton.Bind(wx.EVT_BUTTON, self.__onSelectNone) self.__addLabelButton.Bind(wx.EVT_BUTTON, self.__onLabelAdd) self.__rmLabelButton.Bind(wx.EVT_BUTTON, self.__onLabelRemove) self.__newLutButton.Bind(wx.EVT_BUTTON, self.__onNewLut) self.__copyLutButton.Bind(wx.EVT_BUTTON, self.__onCopyLut) self.__loadLutButton.Bind(wx.EVT_BUTTON, self.__onLoadLut) self.__saveLutButton.Bind(wx.EVT_BUTTON, self.__onSaveLut) # The selected overlay / DisplayOpts # are tracked if they use an LUT # (e.g. LabelOpts). And the currently # selected/displayed LUT is always # tracked. self.__selectedOverlay = None self.__selectedOpts = None self.__selectedLut = None # See the __createLabelList method self.__labelListCreateKey = 0 overlayList.addListener('overlays', self.name, self.__selectedOverlayChanged) displayCtx.addListener('selectedOverlay', self.name, self.__selectedOverlayChanged) self.__updateLutChoices() self.__selectedOverlayChanged() # If the selected lut was not set # via the selectedOverlayChanged # call, we'll manually set it here if self.__selectedLut is None: self.__setLut(fslcmaps.getLookupTables()[0]) self.Layout() # The label values (used as labels in the # EditableListBox) seem to get squashed # easily. So we're adding a bit of padding # to force this panel to have a minimum # size, to ensure that the labels are # visible. dc = wx.ClientDC(self.__labelList) w, h = dc.GetTextExtent('9999') minSize = self.__sizer.GetMinSize() self.SetMinSize((minSize[0] + w, minSize[1]))
def __init__(self, parent, overlayList, displayCtx, frame, atlasPanel): """Create an ``AtlasOverlayPanel``. :arg parent: the :mod:`wx` parent object. :arg overlayList: The :class:`.OverlayList` instance. :arg displayCtx: The :class:`.DisplayContext` instance. :arg frame: The :class:`.FSLeyesFrame` instance. :arg atlasPanel: The :class:`.AtlasPanel` instance that has created this ``AtlasInfoPanel``. """ fslpanel.FSLeyesPanel.__init__(self, parent, overlayList, displayCtx, frame) # References to an EditableListBox # for each atlas, containing a list # of its regions. These are created # on-demand in the __onAtlasSelect # method. self.__regionLists = {} self.__atlasPanel = atlasPanel self.__contentPanel = wx.SplitterWindow(self, style=wx.SP_LIVE_UPDATE) self.__atlasList = elistbox.EditableListBox( self.__contentPanel, style=(elistbox.ELB_NO_ADD | elistbox.ELB_NO_REMOVE | elistbox.ELB_NO_MOVE)) self.__regionPanel = wx.Panel(self.__contentPanel) self.__regionFilter = plctext.PlaceholderTextCtrl(self.__regionPanel, placeholder='Search') self.__contentPanel.SetMinimumPaneSize(50) self.__contentPanel.SplitVertically(self.__atlasList, self.__regionPanel) self.__contentPanel.SetSashGravity(0.4) self.__sizer = wx.BoxSizer(wx.HORIZONTAL) self.__regionSizer = wx.BoxSizer(wx.VERTICAL) self.__regionSizer.Add(self.__regionFilter, flag=wx.EXPAND) self.__regionSizer.AddStretchSpacer() self.__sizer.Add(self.__contentPanel, flag=wx.EXPAND, proportion=1) self.__regionPanel.SetSizer(self.__regionSizer) self.SetSizer(self.__sizer) self.__regionFilter.Bind(wx.EVT_TEXT, self.__onRegionFilter) self.__atlasList.Bind(elistbox.EVT_ELB_SELECT_EVENT, self.__onAtlasSelect) fslplatform.register(self.name, self.__fslDirChanged) atlases.registry.register(self.name, self.__atlasAdded, 'add') atlases.registry.register(self.name, self.__atlasRemoved, 'remove') self.__buildAtlasList() self.__regionSizer.Layout() self.__sizer.Layout() # Allow the atlas list # to be minimised self.__atlasList.SetMinSize((50, -1)) self.SetMinSize(self.__sizer.GetMinSize())
def __onAtlasSelect(self, ev=None, atlasDesc=None): """Called when the user selects an atlas in the atlas list, or the :meth:`selectAtlas` method is called. If a region list (a list of :class:`OverlayListWidget` items for every region in the atlas, to be displayed in the region list) has not yet been created, it is created - this is done asynchronously (via the :func:`idle.idle` function), as it can take quite a long time for some of the atlases (e.g. the Talairach and Juelich). Then the region list is updated to show the regions for the newly selected atlas. """ if ev is not None: atlasDesc = ev.data regionList = self.__regionLists.get(atlasDesc.atlasID, None) atlasPanelDisabled = regionList is None # This function changes the displayed region # list. We schedule it on the wx idle loop, # so it will get called after the region list # has been populated (if it has not been # displayed before). def changeAtlasList(): # See comment above about # suppressing wx complaints try: filterStr = self.__regionFilter.GetValue().lower().strip() regionList.ApplyFilter(filterStr, ignoreCase=True) self.__updateAtlasState(atlasDesc) status.update(strings.messages[self, 'regionsLoaded'].format( atlasDesc.name)) log.debug('Showing region list for {} ({})'.format( atlasDesc.atlasID, id(regionList))) # Hide the currently # shown region list old = self.__regionSizer.GetItem(1).GetWindow() if old is not None: old.Show(False) regionList.Show(True) self.__regionSizer.Remove(1) self.__regionSizer.Insert(1, regionList, flag=wx.EXPAND, proportion=1) self.__regionSizer.Layout() if atlasPanelDisabled: self.__atlasPanel.enableAtlasPanel() except wx.PyDeadObjectError: pass if regionList is None: # The region list for this atlas has not yet been # created. So we create the list, and then create # a widget for every region in the atlas. Some of # the atlases (Juelich and Talairach in particular) # have a large number of regions, so we create the # widgets asynchronously on the wx idle loop. regionList = elistbox.EditableListBox( self.__regionPanel, style=(elistbox.ELB_NO_ADD | elistbox.ELB_NO_REMOVE | elistbox.ELB_NO_MOVE)) regionList.Show(False) self.__regionLists[atlasDesc.atlasID] = regionList # Add blockSize labels, starting from label[i], # to the region list. Then, if necessary, # schedule more labels be added, starting from # label[i + blockSize]. blockSize = 20 nlabels = len(atlasDesc.labels) def addToRegionList(start): # If the user kills this panel while # the region list is being updated, # suppress wx complaints. try: for i in range(start, min(start + blockSize, nlabels)): label = atlasDesc.labels[i] widget = OverlayListWidget(regionList, atlasDesc.atlasID, self.__atlasPanel, self, label.index) regionList.Append(label.name, extraWidget=widget) if i < nlabels - 1: idle.idle(addToRegionList, i + 1) else: idle.idle(changeAtlasList) except wx.PyDeadObjectError: pass log.debug('Creating region list for {} ({})'.format( atlasDesc.atlasID, id(regionList))) status.update(strings.messages[self, 'loadRegions'].format( atlasDesc.name), timeout=None) # Schedule addToRegionList on the # wx idle loop for the first region. # The function will recursively # schedule itself to run for subsequent # regions. # # Disable the panel while this is # occurring. atlasPanelDisabled = True self.__atlasPanel.enableAtlasPanel(False) idle.idle(addToRegionList, 0) else: idle.idle(changeAtlasList)
def __init__(self, parent, overlayList, displayCtx, frame, atlasPanel): """Create an ``AtlasInfoPanel``. :arg parent: the :mod:`wx` parent object. :arg overlayList: The :class:`.OverlayList` instance. :arg displayCtx: The :class:`.DisplayContext` instance. :arg frame: The :class:`.FSLeyesFrame` instance. :arg atlasPanel: The :class:`.AtlasPanel` instance that has created this ``AtlasInfoPanel``. """ fslpanel.FSLeyesPanel.__init__(self, parent, overlayList, displayCtx, frame) self.__enabledAtlases = {} self.__atlasPanel = atlasPanel self.__contentPanel = wx.SplitterWindow(self, style=wx.SP_LIVE_UPDATE) self.__infoPanel = wxhtml.HtmlWindow(self.__contentPanel) self.__atlasList = elistbox.EditableListBox( self.__contentPanel, style=(elistbox.ELB_NO_ADD | elistbox.ELB_NO_REMOVE | elistbox.ELB_NO_MOVE)) # Force the HTML info panel to # use the default font size self.__infoPanel.SetStandardFonts(self.GetFont().GetPointSize()) self.__sizer = wx.BoxSizer(wx.HORIZONTAL) self.__sizer.Add(self.__contentPanel, flag=wx.EXPAND, proportion=1) self.SetSizer(self.__sizer) self.__contentPanel.SetMinimumPaneSize(50) self.__contentPanel.SplitVertically(self.__atlasList, self.__infoPanel) self.__contentPanel.SetSashGravity(0.4) # The info panel contains clickable links # for the currently displayed regions - # when a link is clicked, the location # is centred at the corresponding region self.__infoPanel.Bind(wxhtml.EVT_HTML_LINK_CLICKED, self.__infoPanelLinkClicked) fslplatform.register(self.name, self.__fslDirChanged) atlases.registry.register(self.name, self.__atlasAdded, topic='add') atlases.registry.register(self.name, self.__atlasRemoved, topic='remove') overlayList.addListener('overlays', self.name, self.__selectedOverlayChanged) displayCtx.addListener('selectedOverlay', self.name, self.__selectedOverlayChanged) displayCtx.addListener('location', self.name, self.__locationChanged) self.__atlasList.SetMinSize((50, 60)) self.__infoPanel.SetMinSize((50, 60)) self.SetMinSize(self.__sizer.GetMinSize()) self.__buildAtlasList() self.__selectedOverlayChanged() # Enable the Harvard/Oxford # atlases by default. We do this # asynchronously because methods # on the AtlasPanel will be called, # and the AtlasPanel may not have # finished initialising itself. enable = ['harvardoxford-cortical', 'harvardoxford-subcortical'] enable = [e for e in enable if atlases.hasAtlas(e)] for i, e in enumerate(enable): refresh = i == len(enable) - 1 idle.idle(self.enableAtlasInfo, e, refresh=refresh)
def __init__(self, parent, overlayList, displayCtx, frame, showVis=True, showGroup=True, showSave=True, propagateSelect=True, elistboxStyle=None, filterFunc=None): """Create an ``OverlayListPanel``. :arg parent: The :mod:`wx` parent object. :arg overlayList: An :class:`.OverlayList` instance. :arg displayCtx: A :class:`.DisplayContext` instance. :arg frame: The :class:`.FSLeyesFrame` instance. :arg showVis: If ``True`` (the default), a button will be shown alongside each overlay, allowing the user to toggle the overlay visibility. :arg showGroup: If ``True`` (the default), a button will be shown alongside each overlay, allowing the user to toggle overlay grouping. :arg showSave: If ``True`` (the default), a button will be shown alongside each overlay, allowing the user to save the overlay (if it is not saved). :arg propagateSelect: If ``True`` (the default), when the user interacts with the :class:`.ListItemWidget` for an overlay which is *not* the currently selected overlay, that overlay is updated to be the selected overlay. :arg elistboxStyle: Style flags passed through to the :class:`.EditableListBox`. :arg filterFunc: Function which must accept an overlay as its sole argument, and return ``True`` or ``False``. If this function returns ``False`` for an overlay, the :class:`ListItemWidget` for that overlay will be disabled. """ def defaultFilter(o): return True if filterFunc is None: filterFunc = defaultFilter fslpanel.FSLeyesPanel.__init__( self, parent, overlayList, displayCtx, frame) self.__showVis = showVis self.__showGroup = showGroup self.__showSave = showSave self.__propagateSelect = propagateSelect self.__filterFunc = filterFunc if elistboxStyle is None: elistboxStyle = (elistbox.ELB_REVERSE | elistbox.ELB_TOOLTIP_DOWN | elistbox.ELB_SCROLL_BUTTONS) # list box containing the list of overlays - it # is populated in the _overlayListChanged method self.__listBox = elistbox.EditableListBox(self, style=elistboxStyle) # listeners for when the user does # something with the list box self.__listBox.Bind(elistbox.EVT_ELB_SELECT_EVENT, self.__lbSelect) self.__listBox.Bind(elistbox.EVT_ELB_MOVE_EVENT, self.__lbMove) self.__listBox.Bind(elistbox.EVT_ELB_REMOVE_EVENT, self.__lbRemove) self.__listBox.Bind(elistbox.EVT_ELB_ADD_EVENT, self.__lbAdd) self.__listBox.Bind(elistbox.EVT_ELB_DBLCLICK_EVENT, self.__lbDblClick) self.__sizer = wx.BoxSizer(wx.HORIZONTAL) self.SetSizer(self.__sizer) self.__sizer.Add(self.__listBox, flag=wx.EXPAND, proportion=1) self.overlayList.addListener( 'overlays', self.name, self.__overlayListChanged) self.displayCtx.addListener( 'overlayOrder', self.name, self.__overlayListChanged) self.displayCtx.addListener( 'selectedOverlay', self.name, self.__selectedOverlayChanged) self.__overlayListChanged() self.__selectedOverlayChanged() self.Layout() self.__minSize = self.__sizer.GetMinSize() self.SetMinSize(self.__minSize)