From 9420adf68e2184482cd71266f280c560ea911f45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parodi=2C=20Eugenio=20=F0=9F=8C=B6?= Date: Thu, 1 May 2025 20:41:32 +0100 Subject: [PATCH] refactor(TabWidget)!: tab request close event need to be handled inside the app --- apps/tlogg/tlogg/app/main.py | 7 ++++- apps/ttkode/ttkode/app/ttkode.py | 5 +++ demo/ttkode.01.py | 4 ++- demo/ttkode.py | 3 +- libs/pyTermTk/TermTk/TTkWidgets/kodetab.py | 33 ++++++++++++++------ libs/pyTermTk/TermTk/TTkWidgets/tabwidget.py | 4 +-- run.tlogg.sh | 3 ++ 7 files changed, 44 insertions(+), 15 deletions(-) create mode 100755 run.tlogg.sh diff --git a/apps/tlogg/tlogg/app/main.py b/apps/tlogg/tlogg/app/main.py index a1c606be..13a5cd1d 100644 --- a/apps/tlogg/tlogg/app/main.py +++ b/apps/tlogg/tlogg/app/main.py @@ -70,7 +70,7 @@ class TLOGG(TTkGridLayout): self.addWidget(appTemplate:=TTkAppTemplate(border=False)) - self._kodeTab = TTkKodeTab(border=False, closable=True) + self._kodeTab = TTkKodeTab(border=False, closable=True) appTemplate.setMenuBar(appMenuBar:=TTkMenuBarLayout(), TTkAppTemplate.LEFT) fileMenu = appMenuBar.addMenu("&File") @@ -96,6 +96,7 @@ class TLOGG(TTkGridLayout): tloggProxy.tloggFocussed.emit(None, data) self._kodeTab.currentChanged.connect(_tabChanged) + self._kodeTab.kodeTabCloseRequested.connect(self._handleTabCloseRequested) # fileTree.fileActivated.connect(lambda x: self.openFile(x.path())) @@ -116,6 +117,10 @@ class TLOGG(TTkGridLayout): appTemplate.setWidget(self._kodeTab, TTkAppTemplate.MAIN) appTemplate.setWidget(TTkLogViewer(),TTkAppTemplate.BOTTOM,size=1,title="Logs") + @ttk.pyTTkSlot(TTkTabWidget, int) + def _handleTabCloseRequested(self, tab:TTkTabWidget, num:int): + tab.removeTab(num) + @pyTTkSlot() def scratchpad(self): win = TTkWindow( diff --git a/apps/ttkode/ttkode/app/ttkode.py b/apps/ttkode/ttkode/app/ttkode.py index e052898a..24341b2e 100644 --- a/apps/ttkode/ttkode/app/ttkode.py +++ b/apps/ttkode/ttkode/app/ttkode.py @@ -159,6 +159,11 @@ class TTKode(ttk.TTkGridLayout): fileTree.fileActivated.connect(lambda x: self._openFile(x.path())) self._kodeTab.tabAdded.connect(self._tabAdded) + self._kodeTab.kodeTabCloseRequested.connect(self._handleTabCloseRequested) + + @ttk.pyTTkSlot(ttk.TTkTabWidget, int) + def _handleTabCloseRequested(self, tab:ttk.TTkTabWidget, num:int): + tab.removeTab(num) def _getTabButtonFromWidget(self, widget:ttk.TTkWidget) -> ttk.TTkTabButton: for item, tab in self._kodeTab.iterWidgets(): diff --git a/demo/ttkode.01.py b/demo/ttkode.01.py index 74a2e563..837d5628 100755 --- a/demo/ttkode.01.py +++ b/demo/ttkode.01.py @@ -114,10 +114,12 @@ def main(): fileTree.fileActivated.connect(_openFile) + @ttk.pyTTkSlot(ttk.TTkTabWidget, int) def _reportClose(tab:ttk.TTkTabWidget, num:int): ttk.TTkLog.debug(f"DEL: {num} - {tab} - {tab.widget(num).text()}") + tab.removeTab(num) - kodeTab.tabCloseRequested.connect(_reportClose) + kodeTab.kodeTabCloseRequested.connect(_reportClose) root.mainloop() diff --git a/demo/ttkode.py b/demo/ttkode.py index 57a7808c..a74f6230 100755 --- a/demo/ttkode.py +++ b/demo/ttkode.py @@ -116,8 +116,9 @@ def main(): def _reportClose(tab:ttk.TTkTabWidget, num:int): ttk.TTkLog.debug(f"DEL: {num} - {tab} - {tab.widget(num).text()}") + tab.removeTab(num) - kodeTab.tabCloseRequested.connect(_reportClose) + kodeTab.kodeTabCloseRequested.connect(_reportClose) root.mainloop() diff --git a/libs/pyTermTk/TermTk/TTkWidgets/kodetab.py b/libs/pyTermTk/TermTk/TTkWidgets/kodetab.py index 7eee6055..cd0bd458 100644 --- a/libs/pyTermTk/TermTk/TTkWidgets/kodetab.py +++ b/libs/pyTermTk/TermTk/TTkWidgets/kodetab.py @@ -52,17 +52,22 @@ _splitter_NERD_1_style = { } class _TTkKodeTab(TTkTabWidget): __slots__ = ( - '_frameOverlay','_baseWidget') + '_frameOverlay','_baseWidget', + #Signals + 'kodeTabCloseRequested') def __init__(self, *, baseWidget=None, **kwargs) -> None: + self.kodeTabCloseRequested = pyTTkSignal(_TTkKodeTab,int) self._baseWidget:TTkKodeTab = baseWidget self._frameOverlay = None super().__init__(**kwargs) self.tabBarClicked.connect( lambda i:self._baseWidget.tabBarClicked.emit( self, i, self.widget(i), self.tabData(i))) self.currentChanged.connect( lambda i:self._baseWidget.currentChanged.emit( self, i, self.widget(i), self.tabData(i))) - self.tabCloseRequested.connect(lambda i:self._baseWidget.tabCloseRequested.emit(self, i)) - self.tabCloseRequested.connect( self._kodeTabClosed) + self.tabCloseRequested.connect(self._handleTabCloseRequested) + + def _handleTabCloseRequested(self, index): + self.kodeTabCloseRequested.emit(self,index) def _hasMenu(self): return True if (self._topLeftLayout or self._topRightLayout) else False @@ -112,7 +117,7 @@ class _TTkKodeTab(TTkTabWidget): elif y>h*3//4: self._frameOverlay = (0,k+h-h//4,w,h//4) else: - self._frameOverlay = None + self._frameOverlay = (0,k,w,h) self.update() return True @@ -133,10 +138,12 @@ class _TTkKodeTab(TTkTabWidget): index = splitter.indexOf(self) if splitter.orientation() != orientation: splitter.replaceWidget(index, splitter := TTkSplitter(orientation=orientation, style=self.parentWidget().classStyle)) + splitter.mergeStyle(_splitter_NERD_1_style) splitter.addWidget(self) index=offset splitter.insertWidget(index+offset, kt:=_TTkKodeTab(baseWidget=self._baseWidget, border=self.border(), barType=self._barType, closable=self.tabsClosable())) kt._dropEventProxy = self._dropEventProxy + kt.kodeTabCloseRequested.connect(self._baseWidget._handleKodeTabCloseRequested) ret = kt.addTab(widget,label) self._baseWidget.tabAdded.emit(kt, ret) if fwold!=(fwnew := self._baseWidget._getFirstWidget()) and fwold._hasMenu(): @@ -206,6 +213,7 @@ class _TTkKodeTab(TTkTabWidget): widget = splitter splitter = widget.parentWidget() splitter.removeWidget(widget) + widget.kodeTabCloseRequested.clear() if splitter == self._baseWidget and splitter.count() == 0: splitter.addWidget(self) if fwold!=(fwnew := self._baseWidget._getFirstWidget()) and fwold._hasMenu(): @@ -224,26 +232,33 @@ class TTkKodeTab(TTkSplitter): __slots__ = ( '_lastKodeTabWidget', '_barType', # Signals - 'currentChanged','tabBarClicked','tabCloseRequested', 'tabAdded' ) + 'currentChanged','tabBarClicked','kodeTabCloseRequested', 'tabAdded' ) def __init__(self, barType:TTkBarType=TTkBarType.NONE, **kwargs) -> None: self.currentChanged = pyTTkSignal(TTkTabWidget,int,TTkWidget,object) self.tabBarClicked = pyTTkSignal(TTkTabWidget,int,TTkWidget,object) - self.tabCloseRequested = pyTTkSignal(TTkTabWidget,int) + self.kodeTabCloseRequested = pyTTkSignal(TTkTabWidget,int) self.tabAdded = pyTTkSignal(TTkTabWidget, int) self._barType = barType - self.classStyle |= _splitter_NERD_1_style - super().__init__(**kwargs|{'layout':TTkGridLayout()}) + + self.mergeStyle(_splitter_NERD_1_style) kwargs.pop('parent',None) kwargs.pop('visible',None) # self.layout().addWidget(splitter := TTkSplitter()) - self._lastKodeTabWidget = _TTkKodeTab(baseWidget=self, barType=self._barType, **kwargs) + self._lastKodeTabWidget = kt = _TTkKodeTab(baseWidget=self, barType=self._barType, **kwargs) self._lastKodeTabWidget._dropEventProxy = self._dropEventProxy self.addWidget(self._lastKodeTabWidget) + kt.kodeTabCloseRequested.connect(self._handleKodeTabCloseRequested) + + @pyTTkSlot(_TTkKodeTab,int) + def _handleKodeTabCloseRequested(self, kt:_TTkKodeTab, index:int) -> None: + TTkLog.debug(f"{kt} -> {index}") + self.kodeTabCloseRequested.emit(kt, index) + # kt.removeTab(index) def _getFirstWidget(self): kt = self diff --git a/libs/pyTermTk/TermTk/TTkWidgets/tabwidget.py b/libs/pyTermTk/TermTk/TTkWidgets/tabwidget.py index d34a7bff..c33f6d71 100644 --- a/libs/pyTermTk/TermTk/TTkWidgets/tabwidget.py +++ b/libs/pyTermTk/TermTk/TTkWidgets/tabwidget.py @@ -747,7 +747,6 @@ class TTkTabWidget(TTkFrame): self.rootLayout().addItem(self._tabBarTopLayout) self._tabBarTopLayout.setGeometry(0,0,self._width,self._padt) - self._tabBar.tabCloseRequested.connect(self.removeTab) # forwarded methods self.currentIndex = self._tabBar.currentIndex self.setCurrentIndex = self._tabBar.setCurrentIndex @@ -759,7 +758,7 @@ class TTkTabWidget(TTkFrame): # forwarded Signals self.currentChanged = self._tabBar.currentChanged self.tabBarClicked = self._tabBar.tabBarClicked - self.tabCloseRequested = pyTTkSignal(int) + self.tabCloseRequested = self._tabBar.tabCloseRequested self.focusChanged.connect(self._focusChanged) @@ -902,7 +901,6 @@ class TTkTabWidget(TTkFrame): @pyTTkSlot(int) def removeTab(self, index) -> None: '''removeTab''' - self.tabCloseRequested.emit(index) self.layout().removeWidget(self._tabWidgets[index]) self._tabWidgets.pop(index) self._tabBar.removeTab(index) diff --git a/run.tlogg.sh b/run.tlogg.sh new file mode 100755 index 00000000..09d6a2b5 --- /dev/null +++ b/run.tlogg.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +_PATH_SCRIPT="$(dirname $(realpath $0))" +PYTHONPATH=${_PATH_SCRIPT}/libs/pyTermTk:${_PATH_SCRIPT}/apps/tlogg python3 -m tlogg $@