diff --git a/TermTk/TTkCore/canvas.py b/TermTk/TTkCore/canvas.py index c577256b..056c3ea7 100644 --- a/TermTk/TTkCore/canvas.py +++ b/TermTk/TTkCore/canvas.py @@ -468,7 +468,7 @@ class TTkCanvas: self.drawText(pos=(x+1,y), color=color ,text=text) off = 1 else: - self.drawText(pos=(x,y), color=color ,text=text) + self.drawText(pos=(x,y), width=width, color=color ,text=text) if submenu: self._set(y,x+width-1, mb[5], color) off = 0 diff --git a/TermTk/TTkCore/helper.py b/TermTk/TTkCore/helper.py index 75e96291..2242b74e 100644 --- a/TermTk/TTkCore/helper.py +++ b/TermTk/TTkCore/helper.py @@ -42,6 +42,7 @@ class TTkHelper: def __init__(self,x,y,widget): self._widget = widget widget.move(x,y) + _savedFocus = None _overlay = [] class _Shortcut(): @@ -111,6 +112,8 @@ class TTkHelper: def overlay(caller, widget, x, y): wx, wy = TTkHelper.absPos(caller) w,h = widget.size() + if not TTkHelper._savedFocus: + 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 ) @@ -130,6 +133,24 @@ class TTkHelper: for widget in TTkHelper._overlay: TTkHelper._rootWidget.rootLayout().removeWidget(widget._widget) TTkHelper._overlay = [] + if TTkHelper._focusWidget: + TTkHelper._focusWidget.clearFocus() + if TTkHelper._savedFocus: + bk = TTkHelper._savedFocus + TTkHelper._savedFocus = None + bk.setFocus() + + @staticmethod + def removeSingleOverlay(widget): + if len(TTkHelper._overlay) <= 1: + return TTkHelper.removeOverlay() + rootWidget = TTkHelper.rootOverlay(widget) + rootWidget + for o in TTkHelper._overlay: + if o._widget == rootWidget: + TTkHelper._overlay.remove(o) + TTkHelper._rootWidget.rootLayout().removeWidget(rootWidget) + TTkHelper._overlay[-1]._widget.setFocus() @staticmethod def paintAll(): diff --git a/TermTk/TTkWidgets/list.py b/TermTk/TTkWidgets/list.py index 964869d6..31d79656 100644 --- a/TermTk/TTkWidgets/list.py +++ b/TermTk/TTkWidgets/list.py @@ -35,7 +35,7 @@ class TTkList(TTkAbstractScrollArea): TTkAbstractScrollArea.__init__(self, *args, **kwargs) self._name = kwargs.get('name' , 'TTkList' ) if 'parent' in kwargs: kwargs.pop('parent') - self._listView = TTkListWidget(*args, **kwargs) + self._listView = kwargs.get('listWidget',TTkListWidget(*args, **kwargs)) self.setViewport(self._listView) self.itemClicked = self._listView.itemClicked self.textClicked = self._listView.textClicked diff --git a/TermTk/TTkWidgets/listwidget.py b/TermTk/TTkWidgets/listwidget.py index f5d42335..c6959a5e 100644 --- a/TermTk/TTkWidgets/listwidget.py +++ b/TermTk/TTkWidgets/listwidget.py @@ -60,6 +60,7 @@ class TTkAbstractListItem(TTkLabel): def mousePressEvent(self, evt): self._pressed = True self.highlighted = True + self.update() return True def mouseReleaseEvent(self, evt): @@ -186,11 +187,11 @@ class TTkListWidget(TTkAbstractScrollView): self.viewMoveTo(offx, index) def keyEvent(self, evt): - if not self._highlighted: return + if not self._highlighted: return False if ( evt.type == TTkK.Character and evt.key==" " ) or \ ( evt.type == TTkK.SpecialKey and evt.key == TTkK.Key_Enter ): if self._highlighted: - TTkLog.debug(self._highlighted) + # TTkLog.debug(self._highlighted) self._highlighted.listItemClicked.emit(self._highlighted) return True elif evt.type == TTkK.SpecialKey: diff --git a/TermTk/TTkWidgets/menubar.py b/TermTk/TTkWidgets/menubar.py index 56847fc7..2ae0b4a6 100644 --- a/TermTk/TTkWidgets/menubar.py +++ b/TermTk/TTkWidgets/menubar.py @@ -32,28 +32,47 @@ from TermTk.TTkWidgets.listwidget import TTkListWidget, TTkAbstractListItem from TermTk.TTkLayouts.layout import TTkLayout from TermTk.TTkLayouts.boxlayout import TTkHBoxLayout -class _TTkMenuSpacer(TTkWidget): - __slots__ = ('clicked') + +class _TTkMenuListWidget(TTkListWidget): + __slots__ = ('_previous') + def __init__(self, *args, **kwargs): + TTkListWidget.__init__(self, *args, **kwargs) + self._name = kwargs.get('name' , '_TTkMenuListWidget' ) + self._previous = kwargs.get('previous',None) + + def keyEvent(self, evt): + if evt.type == TTkK.SpecialKey: + if evt.key == TTkK.Key_Left: + TTkHelper.removeSingleOverlay(self) + if self._previous: + self._previous.setFocus() + return True + elif evt.key == TTkK.Key_Right: + if self._highlighted and \ + self._highlighted._menu: + self._highlighted.menuButtonEvent() + return True + return TTkListWidget.keyEvent(self, evt) + + +class _TTkMenuSpacer(TTkAbstractListItem): def __init__(self, *args, **kwargs): - TTkWidget.__init__(self, *args, **kwargs) + TTkAbstractListItem.__init__(self, *args, **kwargs) self._name = kwargs.get('name' , '_TTkMenuSpacer' ) - # Define Signals - self.clicked = pyTTkSignal() self.resize(1,1) - #self.setMinimumHeight(1) def paintEvent(self): - TTkLog.debug("pippo") self._canvas.drawText(pos=(0,0), text="-"*self.width()) class _TTkMenuButton(TTkAbstractListItem): - __slots__ = ('_color', '_borderColor', '_shortcut', '_menu', 'menuButtonClicked') + __slots__ = ('_border', '_borderColor', '_shortcut', '_menu', 'menuButtonClicked') def __init__(self, *args, **kwargs): TTkAbstractListItem.__init__(self, *args, **kwargs) self._name = kwargs.get('name' , '_TTkMenuButton' ) # signals self.menuButtonClicked = pyTTkSignal(TTkButton) self._color = kwargs.get('color', TTkCfg.theme.menuButtonColor ) + self._border = kwargs.get('border', TTkCfg.theme.menuButtonColor ) self._borderColor = kwargs.get('borderColor', TTkCfg.theme.menuButtonBorderColor ) self._shortcut = [] self._menu = [] @@ -94,7 +113,7 @@ class _TTkMenuButton(TTkAbstractListItem): #self._id = self._list.index(label) TTkLog.debug(f"Bind Clicked {button._text}") self.menuButtonClicked.emit(button) - self.setFocus() + TTkHelper.removeOverlay() self.update() @pyTTkSlot(TTkAbstractListItem) @@ -118,20 +137,22 @@ class _TTkMenuButton(TTkAbstractListItem): else: frame = TTkResizableFrame(layout=TTkHBoxLayout(), size=(frameWidth,frameHeight), title=self._text, titleAlign=TTkK.LEFT_ALIGN) pos = (-1, 0) - listw = TTkList(parent=frame) + menuListWidget = _TTkMenuListWidget(previous=self) + listw = TTkList(parent=frame, listWidget = menuListWidget) # listw.textClicked.connect(self._menuCallback) # listw.textClicked.connect(self._menuCallback) TTkLog.debug(f"{self._menu}") for item in self._menu: listw.addItem(item) TTkHelper.overlay(self, frame, pos[0], pos[1]) + listw.viewport().setFocus() self.update() def paintEvent(self): if self._pressed: borderColor = self._borderColor textColor = TTkCfg.theme.menuButtonColorClicked - scColor = TTkCfg.theme.menuButtonShortcutColor + scColor = TTkCfg.theme.menuButtonShortcutColor else: borderColor = self._borderColor textColor = self._color @@ -146,6 +167,12 @@ class _TTkMenuButton(TTkAbstractListItem): borderColor=borderColor, shortcutColor=scColor ) + def focusInEvent(self): + self.highlighted=True + + def focusOutEvent(self): + self.highlighted=False + class TTkMenuLayout(TTkHBoxLayout): __slots__ = ('_itemsLeft', '_itemsCenter', '_itemsRight', '_buttons') def __init__(self, *args, **kwargs): diff --git a/TermTk/TTkWidgets/widget.py b/TermTk/TTkWidgets/widget.py index 98f066b6..d9a68fa3 100644 --- a/TermTk/TTkWidgets/widget.py +++ b/TermTk/TTkWidgets/widget.py @@ -548,6 +548,7 @@ class TTkWidget(TMouseEvents,TKeyEvents): self.layoutUpdated() def setFocus(self): + if self._focus: return TTkLog.debug(self._name) tmp = TTkHelper.getFocus() if tmp == self: return @@ -562,6 +563,7 @@ class TTkWidget(TMouseEvents,TKeyEvents): self.focusInEvent() def clearFocus(self): + if not self._focus: return TTkHelper.clearFocus() self._focus = False self.focusOutEvent()