diff --git a/TermTk/TTkCore/helper.py b/TermTk/TTkCore/helper.py index 45ad89df..b25b2759 100644 --- a/TermTk/TTkCore/helper.py +++ b/TermTk/TTkCore/helper.py @@ -38,11 +38,11 @@ class TTkHelper: _cursor = False _cursorType = lbt.Term.cursor_blinking_block class _Overlay(): - __slots__ = ('_widget','_x','_y') - def __init__(self,x,y,widget): + __slots__ = ('_widget','_prevFocus','_x','_y') + def __init__(self,x,y,widget,prevFocus): self._widget = widget + self._prevFocus = prevFocus widget.move(x,y) - _savedFocus = None _overlay = [] class _Shortcut(): @@ -119,13 +119,10 @@ class TTkHelper: def overlay(caller, widget, x, y): wx, wy = TTkHelper.absPos(caller) w,h = widget.size() - if not TTkHelper._savedFocus and \ - not TTkHelper.isOverlay(TTkHelper._focusWidget): - TTkHelper._savedFocus = TTkHelper._focusWidget # Try to keep the overlay widget inside the terminal wx = max(0, wx+x if wx+x+w < TTkGlbl.term_w else TTkGlbl.term_w-w ) wy = max(0, wy+y if wy+y+h < TTkGlbl.term_h else TTkGlbl.term_h-h ) - TTkHelper._overlay.append(TTkHelper._Overlay(wx,wy,widget)) + TTkHelper._overlay.append(TTkHelper._Overlay(wx,wy,widget,TTkHelper._focusWidget)) TTkHelper._rootWidget.rootLayout().addWidget(widget) widget.setFocus() widget.raiseWidget() @@ -140,26 +137,55 @@ class TTkHelper: def removeOverlay(refocus=True): for widget in TTkHelper._overlay: TTkHelper._rootWidget.rootLayout().removeWidget(widget._widget) + bkFocus = None + if TTkHelper._overlay: + bkFocus = TTkHelper._overlay[0]._prevFocus TTkHelper._overlay = [] if TTkHelper._focusWidget: TTkHelper._focusWidget.clearFocus() - if TTkHelper._savedFocus: - bk = TTkHelper._savedFocus - TTkHelper._savedFocus = None - if refocus: - bk.setFocus() + if bkFocus: + bkFocus.setFocus() @staticmethod - def removeSingleOverlay(widget): + def removeOverlayAndChild(widget): if len(TTkHelper._overlay) <= 1: return TTkHelper.removeOverlay() rootWidget = TTkHelper.rootOverlay(widget) - rootWidget + bkFocus = None + found = False + newOverlay = [] + for o in TTkHelper._overlay: + if o._widget == rootWidget: + found = True + bkFocus = o._prevFocus + if not found: + newOverlay.append(o) + else: + TTkHelper._rootWidget.rootLayout().removeWidget(o._widget) + TTkHelper._overlay = newOverlay + if bkFocus: + bkFocus.setFocus() + if not found: + TTkHelper.removeOverlay() + + @staticmethod + def removeOverlayChild(widget): + rootWidget = TTkHelper.rootOverlay(widget) + found = False + newOverlay = [] for o in TTkHelper._overlay: if o._widget == rootWidget: - TTkHelper._overlay.remove(o) - TTkHelper._rootWidget.rootLayout().removeWidget(rootWidget) - TTkHelper._overlay[-1]._widget.setFocus() + found = True + newOverlay.append(o) + continue + if not found: + newOverlay.append(o) + else: + TTkHelper._rootWidget.rootLayout().removeWidget(o._widget) + TTkHelper._overlay = newOverlay + if not found: + TTkHelper.removeOverlay() + @staticmethod def paintAll(): diff --git a/TermTk/TTkWidgets/combobox.py b/TermTk/TTkWidgets/combobox.py index afd9f764..f24991e7 100644 --- a/TermTk/TTkWidgets/combobox.py +++ b/TermTk/TTkWidgets/combobox.py @@ -36,7 +36,7 @@ from TermTk.TTkWidgets.lineedit import TTkLineEdit from TermTk.TTkWidgets.resizableframe import TTkResizableFrame class TTkComboBox(TTkWidget): - __slots__ = ('_list', '_id', '_lineEdit', '_editable', '_insertPolicy' + __slots__ = ('_list', '_id', '_lineEdit', '_listw', '_editable', '_insertPolicy' #signals 'currentIndexChanged', 'currentTextChanged', 'editTextChanged') def __init__(self, *args, **kwargs): @@ -52,6 +52,7 @@ class TTkComboBox(TTkWidget): self._insertPolicy = kwargs.get('insertPolicy', TTkK.InsertAtBottom ) self._lineEdit.returnPressed.connect(self._lineEditChanged) self._id = -1 + self._popupFrame = None self.setEditable(kwargs.get('editable', False )) self.setMinimumSize(5, 1) self.setMaximumHeight(1) @@ -162,6 +163,8 @@ class TTkComboBox(TTkWidget): def _callback(self, label): self._lineEdit.setText(label) self._id = self._list.index(label) + TTkHelper.removeOverlayAndChild(self._popupFrame) + self._popupFrame = None self.setFocus() self.update() @@ -171,15 +174,15 @@ class TTkComboBox(TTkWidget): if frameHeight > 20: frameHeight = 20 if frameWidth < 20: frameWidth = 20 - frame = TTkResizableFrame(layout=TTkGridLayout(), size=(frameWidth,frameHeight)) - listw = TTkList(parent=frame) - listw.textClicked.connect(self._callback) + self._popupFrame = TTkResizableFrame(layout=TTkGridLayout(), size=(frameWidth,frameHeight)) + TTkHelper.overlay(self, self._popupFrame, 0, 0) + listw = TTkList(parent=self._popupFrame) TTkLog.debug(f"{self._list}") for item in self._list: listw.addItem(item) if self._id != -1: listw.setCurrentRow(self._id) - TTkHelper.overlay(self, frame, 0, 0) + listw.textClicked.connect(self._callback) listw.viewport().setFocus() self.update() return True diff --git a/TermTk/TTkWidgets/menubar.py b/TermTk/TTkWidgets/menubar.py index 33e8b5cb..ad39b7a8 100644 --- a/TermTk/TTkWidgets/menubar.py +++ b/TermTk/TTkWidgets/menubar.py @@ -43,7 +43,7 @@ class _TTkMenuListWidget(TTkListWidget): def keyEvent(self, evt): if evt.type == TTkK.SpecialKey: if evt.key == TTkK.Key_Left: - TTkHelper.removeSingleOverlay(self) + TTkHelper.removeOverlayAndChild(self) if self._previous: self._previous.setFocus() return True diff --git a/TermTk/TTkWidgets/widget.py b/TermTk/TTkWidgets/widget.py index 0f005d08..f0471fd6 100644 --- a/TermTk/TTkWidgets/widget.py +++ b/TermTk/TTkWidgets/widget.py @@ -501,7 +501,7 @@ class TTkWidget(TMouseEvents,TKeyEvents): if self._parent is not None and \ self._parent.rootLayout() is not None: self._parent.rootLayout().removeWidget(self) - TTkHelper.removeSingleOverlay(self) + TTkHelper.removeOverlayAndChild(self) def isVisible(self): @@ -537,8 +537,9 @@ class TTkWidget(TMouseEvents,TKeyEvents): if tmp == self: return if tmp is not None: tmp.clearFocus() - if not TTkHelper.isOverlay(self): - TTkHelper.removeOverlay(refocus=False) + #if not TTkHelper.isOverlay(self): + # TTkHelper.removeOverlay(refocus=False) + TTkHelper.removeOverlayChild(self) TTkHelper.setFocus(self) self._focus = True self.focusChanged.emit(self._focus)