From baf59d9ac51948b44c4286fb212574de46842fd1 Mon Sep 17 00:00:00 2001 From: Eugenio Parodi Date: Sun, 5 Dec 2021 13:02:08 +0000 Subject: [PATCH 1/7] Moved old table/tree to 'FancyTable/Tre' --- TermTk/TTkTypes/treewidgetitem.py | 4 +- TermTk/TTkWidgets/Fancy/__init__.py | 5 ++ TermTk/TTkWidgets/Fancy/table.py | 62 +++++++++++++++++++++ TermTk/TTkWidgets/{ => Fancy}/tableview.py | 16 +++--- TermTk/TTkWidgets/Fancy/tree.py | 61 ++++++++++++++++++++ TermTk/TTkWidgets/Fancy/treeview.py | 39 +++++++++++++ TermTk/TTkWidgets/{ => Fancy}/treewidget.py | 26 ++++----- TermTk/TTkWidgets/TTkPickers/__init__.py | 3 +- TermTk/TTkWidgets/TTkPickers/filepicker.py | 43 ++++++++++++++ TermTk/TTkWidgets/__init__.py | 6 +- TermTk/TTkWidgets/table.py | 8 +-- TermTk/TTkWidgets/tree.py | 8 +-- TermTk/TTkWidgets/treeview.py | 6 +- demo/gittk.py | 2 +- demo/showcase/table.py | 2 +- demo/showcase/tree.py | 30 +++++----- tests/test.ui.008.table.py | 6 +- tests/test.ui.011.tree.py | 24 ++++---- 18 files changed, 279 insertions(+), 72 deletions(-) create mode 100644 TermTk/TTkWidgets/Fancy/__init__.py create mode 100644 TermTk/TTkWidgets/Fancy/table.py rename TermTk/TTkWidgets/{ => Fancy}/tableview.py (96%) create mode 100644 TermTk/TTkWidgets/Fancy/tree.py create mode 100644 TermTk/TTkWidgets/Fancy/treeview.py rename TermTk/TTkWidgets/{ => Fancy}/treewidget.py (88%) create mode 100644 TermTk/TTkWidgets/TTkPickers/filepicker.py diff --git a/TermTk/TTkTypes/treewidgetitem.py b/TermTk/TTkTypes/treewidgetitem.py index 18af1571..8df89b01 100644 --- a/TermTk/TTkTypes/treewidgetitem.py +++ b/TermTk/TTkTypes/treewidgetitem.py @@ -27,13 +27,13 @@ from TermTk.TTkCore.constant import TTkK from TermTk.TTkCore.log import TTkLog from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal -class TTkTreeWidgetItem(): +class TtkFancyTreeWidgetItem(): __slots__ = ('_parent', '_data', '_childs', '_expand', '_childIndicatorPolicy', # Signals 'refreshData') def __init__(self, *args, **kwargs): # Signals - self.refreshData = pyTTkSignal(TTkTreeWidgetItem) + self.refreshData = pyTTkSignal(TtkFancyTreeWidgetItem) self._data = args[0] self._childs = [] self._childIndicatorPolicy = kwargs.get('childIndicatorPolicy', TTkK.DontShowIndicatorWhenChildless) diff --git a/TermTk/TTkWidgets/Fancy/__init__.py b/TermTk/TTkWidgets/Fancy/__init__.py new file mode 100644 index 00000000..8674408d --- /dev/null +++ b/TermTk/TTkWidgets/Fancy/__init__.py @@ -0,0 +1,5 @@ +from .table import * +from .tableview import * +from .tree import * +from .treeview import * +from .treewidget import * diff --git a/TermTk/TTkWidgets/Fancy/table.py b/TermTk/TTkWidgets/Fancy/table.py new file mode 100644 index 00000000..6d36ef87 --- /dev/null +++ b/TermTk/TTkWidgets/Fancy/table.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 + +# MIT License +# +# Copyright (c) 2021 Eugenio Parodi +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from TermTk.TTkCore.cfg import TTkCfg +from TermTk.TTkCore.constant import TTkK +from TermTk.TTkCore.log import TTkLog +from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal +from TermTk.TTkCore.color import TTkColor +from TermTk.TTkWidgets.Fancy.tableview import TtkFancyTableView +from TermTk.TTkLayouts.gridlayout import TTkGridLayout +from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollArea + +class TtkFancyTable(TTkAbstractScrollArea): + __slots__ = ( + '_tableView', 'activated', + # Forwarded Methods + 'setAlignment', 'setHeader', 'setColumnSize', 'setColumnColors', 'appendItem' ) + + + + + def __init__(self, *args, **kwargs): + TTkAbstractScrollArea.__init__(self, *args, **kwargs) + self._name = kwargs.get('name' , 'TtkFancyTable' ) + if 'parent' in kwargs: kwargs.pop('parent') + self._tableView = TtkFancyTableView(*args, **kwargs) + # Forward the signal + self.activated = self._tableView.activated + + self.setFocusPolicy(TTkK.ClickFocus) + self.setViewport(self._tableView) + # Forwarded Methods + self.setAlignment = self._tableView.setAlignment + self.setHeader = self._tableView.setHeader + self.setColumnSize = self._tableView.setColumnSize + self.setColumnColors = self._tableView.setColumnColors + self.appendItem = self._tableView.appendItem + + + + diff --git a/TermTk/TTkWidgets/tableview.py b/TermTk/TTkWidgets/Fancy/tableview.py similarity index 96% rename from TermTk/TTkWidgets/tableview.py rename to TermTk/TTkWidgets/Fancy/tableview.py index 63022be5..5a94bbc2 100644 --- a/TermTk/TTkWidgets/tableview.py +++ b/TermTk/TTkWidgets/Fancy/tableview.py @@ -31,11 +31,11 @@ from TermTk.TTkWidgets.widget import TTkWidget from TermTk.TTkLayouts.gridlayout import TTkGridLayout from TermTk.TTkAbstract.abstractscrollview import TTkAbstractScrollView -class _TTkTableViewHeader(TTkWidget): +class _TtkFancyTableViewHeader(TTkWidget): __slots__ = ('_header', '_alignments', '_headerColor', '_columns') def __init__(self, *args, **kwargs): TTkWidget.__init__(self, *args, **kwargs) - self._name = kwargs.get('name' , '_TTkTableViewHeader' ) + self._name = kwargs.get('name' , '_TtkFancyTableViewHeader' ) self._columns = kwargs.get('columns' , [-1] ) self._header = [""]*len(self._columns) self._alignments = [TTkK.NONE]*len(self._columns) @@ -80,7 +80,7 @@ class _TTkTableViewHeader(TTkWidget): self._canvas.drawTableLine(pos=(0,0), items=self._header, sizes=sizes, colors=colors, alignments=self._alignments) -class _TTkTableView(TTkAbstractScrollView): +class _TtkFancyTableView(TTkAbstractScrollView): __slots__ = ( '_alignments', '_headerColor', '_columns', '_columnColors', @@ -94,7 +94,7 @@ class _TTkTableView(TTkAbstractScrollView): self._tableDataWidget = [] self._shownWidgets = [] TTkAbstractScrollView.__init__(self, *args, **kwargs) - self._name = kwargs.get('name' , '_TTkTableView' ) + self._name = kwargs.get('name' , '_TtkFancyTableView' ) # define signals self.activated = pyTTkSignal(int) # Value self.doubleClicked = pyTTkSignal(int) # Value @@ -335,7 +335,7 @@ class _TTkTableView(TTkAbstractScrollView): colors = [c.modParam(val=-val) for c in self._columnColors] self._canvas.drawTableLine(pos=(0,y), items=item, sizes=sizes, colors=colors, alignments=self._alignments) -class TTkTableView(TTkAbstractScrollView): +class TtkFancyTableView(TTkAbstractScrollView): __slots__ = ( '_header', '_tableView', '_showHeader', 'activated', # Forwarded Methods @@ -344,12 +344,12 @@ class TTkTableView(TTkAbstractScrollView): def __init__(self, *args, **kwargs): super().__init__(self, *args, **kwargs) - self._name = kwargs.get('name' , 'TTkTableView' ) + self._name = kwargs.get('name' , 'TtkFancyTableView' ) if 'parent' in kwargs: kwargs.pop('parent') self._showHeader = kwargs.get('showHeader', True) self.setLayout(TTkGridLayout()) - self._tableView = _TTkTableView(*args, **kwargs) - self._header = _TTkTableViewHeader(*args, **kwargs) + self._tableView = _TtkFancyTableView(*args, **kwargs) + self._header = _TtkFancyTableViewHeader(*args, **kwargs) self.layout().addWidget(self._header,0,0) self.layout().addWidget(self._tableView,1,0) # Forward the tableSignals diff --git a/TermTk/TTkWidgets/Fancy/tree.py b/TermTk/TTkWidgets/Fancy/tree.py new file mode 100644 index 00000000..d4af583a --- /dev/null +++ b/TermTk/TTkWidgets/Fancy/tree.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 + +# MIT License +# +# Copyright (c) 2021 Eugenio Parodi +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from TermTk.TTkCore.cfg import TTkCfg +from TermTk.TTkCore.constant import TTkK +from TermTk.TTkCore.log import TTkLog +from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal +from TermTk.TTkCore.color import TTkColor +from TermTk.TTkWidgets.Fancy.treewidget import TtkFancyTreeWidget +from TermTk.TTkLayouts.gridlayout import TTkGridLayout +from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollArea + +class TtkFancyTree(TTkAbstractScrollArea): + __slots__ = ( + '_treeView', 'activated', + # Forwarded Methods + 'setAlignment', 'setHeader', 'setHeaderLabels', 'setColumnSize', 'setColumnColors', 'appendItem', 'addTopLevelItem' ) + + def __init__(self, *args, **kwargs): + TTkAbstractScrollArea.__init__(self, *args, **kwargs) + self._name = kwargs.get('name' , 'TtkFancyTree' ) + if 'parent' in kwargs: kwargs.pop('parent') + self._treeView = TtkFancyTreeWidget(*args, **kwargs) + # Forward the signal + self.activated = self._treeView.activated + + self.setFocusPolicy(TTkK.ClickFocus) + self.setViewport(self._treeView) + + # Forwarded Methods + self.setAlignment = self._treeView.setAlignment + self.setHeader = self._treeView.setHeader + self.setHeaderLabels = self._treeView.setHeaderLabels + self.setColumnSize = self._treeView.setColumnSize + self.setColumnColors = self._treeView.setColumnColors + self.appendItem = self._treeView.appendItem + self.addTopLevelItem = self._treeView.addTopLevelItem + + + diff --git a/TermTk/TTkWidgets/Fancy/treeview.py b/TermTk/TTkWidgets/Fancy/treeview.py new file mode 100644 index 00000000..d4757df8 --- /dev/null +++ b/TermTk/TTkWidgets/Fancy/treeview.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 + +# MIT License +# +# Copyright (c) 2021 Eugenio Parodi +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from TermTk.TTkCore.cfg import TTkCfg +from TermTk.TTkCore.constant import TTkK +from TermTk.TTkCore.log import TTkLog +from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal +from TermTk.TTkCore.color import TTkColor +from TermTk.TTkWidgets.Fancy.tableview import TtkFancyTableView + +class TtkFancyTreeView(TtkFancyTableView): + __slots__ = ( '_header', '_treeView', '_showHeader', 'activated') + + def __init__(self, *args, **kwargs): + super().__init__(self, *args, **kwargs) + self._name = kwargs.get('name' , 'TtkFancyTreeView' ) + # if 'parent' in kwargs: kwargs.pop('parent') + diff --git a/TermTk/TTkWidgets/treewidget.py b/TermTk/TTkWidgets/Fancy/treewidget.py similarity index 88% rename from TermTk/TTkWidgets/treewidget.py rename to TermTk/TTkWidgets/Fancy/treewidget.py index c2529cfb..68468eeb 100644 --- a/TermTk/TTkWidgets/treewidget.py +++ b/TermTk/TTkWidgets/Fancy/treewidget.py @@ -29,9 +29,9 @@ from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal from TermTk.TTkCore.color import TTkColor from TermTk.TTkWidgets.widget import TTkWidget from TermTk.TTkWidgets.checkbox import TTkCheckbox -from TermTk.TTkWidgets.tableview import TTkTableView +from TermTk.TTkWidgets.Fancy.tableview import TtkFancyTableView from TermTk.TTkLayouts.gridlayout import TTkGridLayout -from TermTk.TTkTypes.treewidgetitem import TTkTreeWidgetItem +from TermTk.TTkTypes.treewidgetitem import TtkFancyTreeWidgetItem class _TTkDisplayedTreeItemControl(TTkCheckbox): def __init__(self, *args, **kwargs): @@ -51,7 +51,7 @@ class _TTkDisplayedTreeItem(TTkWidget): def __init__(self, *args, **kwargs): super().__init__(self, *args, **kwargs) #Signals - self._clicked = pyTTkSignal(bool, _TTkDisplayedTreeItem, TTkTreeWidgetItem) + self._clicked = pyTTkSignal(bool, _TTkDisplayedTreeItem, TtkFancyTreeWidgetItem) self._name = kwargs.get('name' , '_TTkDisplayedTreeItem' ) self._depth = kwargs.get('depth' , 0 ) @@ -77,13 +77,13 @@ class _TTkDisplayedTreeItem(TTkWidget): self._canvas.drawText(pos=(self._depth+2, 0), text=self._text) -class TTkTreeWidget(TTkTableView): +class TtkFancyTreeWidget(TtkFancyTableView): __slots__ = ( '_topLevelItems') def __init__(self, *args, **kwargs): super().__init__(self, *args, **kwargs) - self._name = kwargs.get('name' , 'TTkTreeView' ) - self._topLevelItems = TTkTreeWidgetItem(None) + self._name = kwargs.get('name' , 'TtkFancyTreeView' ) + self._topLevelItems = TtkFancyTreeWidgetItem(None) self.doubleClicked.connect(self._doubleClickItem) # if 'parent' in kwargs: kwargs.pop('parent') @@ -120,23 +120,23 @@ class TTkTreeWidget(TTkTableView): def _doubleClickItem(self, index): if not (item := self.itemAt(index)): return if item[0]._isLeaf: return - if not item[0]._treeWidgetItem.expand(): # we need to expand the TtkTreeWidgetItem + if not item[0]._treeWidgetItem.expand(): # we need to expand the TtkFancyTreeWidgetItem self._expand(item=item[0]._treeWidgetItem, depth=item[0]._depth+1) - else: # we need to shrink the TtkTreeWidgetItem + else: # we need to shrink the TtkFancyTreeWidgetItem self._shrink(item=item[0]._treeWidgetItem) - @pyTTkSlot(bool, _TTkDisplayedTreeItem, TTkTreeWidgetItem) + @pyTTkSlot(bool, _TTkDisplayedTreeItem, TtkFancyTreeWidgetItem) def _controlClicked(self, status, widget, item): TTkLog.debug(f"{status} {widget._name}") - if status: # we need to expand the TtkTreeWidgetItem + if status: # we need to expand the TtkFancyTreeWidgetItem self._expand(item=item, depth=(widget._depth+1)) - else: # we need to shrink the TtkTreeWidgetItem + else: # we need to shrink the TtkFancyTreeWidgetItem self._shrink(item=item) def _addTreeWidgetItem(self, item, depth=0, index=-1): - if not isinstance(item, TTkTreeWidgetItem): - raise TypeError("TTkTreeWidgetItem is required in TTkTreeWidget.addTopLevelItem(item)") + if not isinstance(item, TtkFancyTreeWidgetItem): + raise TypeError("TtkFancyTreeWidgetItem is required in TtkFancyTreeWidget.addTopLevelItem(item)") if item.parent() is None: self._topLevelItems.addChild(item) displayedItems = item.data().copy() diff --git a/TermTk/TTkWidgets/TTkPickers/__init__.py b/TermTk/TTkWidgets/TTkPickers/__init__.py index d06eed9f..4fad8737 100644 --- a/TermTk/TTkWidgets/TTkPickers/__init__.py +++ b/TermTk/TTkWidgets/TTkPickers/__init__.py @@ -1 +1,2 @@ -from .colorpicker import * \ No newline at end of file +from .colorpicker import * +from .filepicker import * \ No newline at end of file diff --git a/TermTk/TTkWidgets/TTkPickers/filepicker.py b/TermTk/TTkWidgets/TTkPickers/filepicker.py new file mode 100644 index 00000000..3a926d00 --- /dev/null +++ b/TermTk/TTkWidgets/TTkPickers/filepicker.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 + +# MIT License +# +# Copyright (c) 2021 Eugenio Parodi +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from os import walk + +from TermTk.TTkWidgets.window import TTkWindow +from TermTk.TTkTypes.treewidgetitem import TtkFancyTreeWidgetItem + +class _FileWidgetItem(TtkFancyTreeWidgetItem): + def __init__(self, *args, **kwargs): + TtkFancyTreeWidgetItem.__init__(self, *args, **kwargs) + +class TTkFileDialogPicker(TTkWindow): + def __init__(self, *args, **kwargs): + TTkWindow.__init__(self, *args, **kwargs) + self._name = kwargs.get('name' , 'TTkFileDialogPicker' ) + +''' +for (dirpath, dirnames, filenames) in walk('/tmp'): + print(f"{dirpath} {dirnames} {filenames}") + break +''' \ No newline at end of file diff --git a/TermTk/TTkWidgets/__init__.py b/TermTk/TTkWidgets/__init__.py index 473fc6a1..ba51473f 100644 --- a/TermTk/TTkWidgets/__init__.py +++ b/TermTk/TTkWidgets/__init__.py @@ -16,14 +16,10 @@ from .window import * from .tabwidget import * from .list_ import * from .listwidget import * -from .table import * -from .tableview import * -from .tree import * -from .treeview import * -from .treewidget import * from .graph import * from .menubar import * from .TTkPickers import * from .spinbox import * from .image import TTkImage from .about import TTkAbout +from .Fancy import * diff --git a/TermTk/TTkWidgets/table.py b/TermTk/TTkWidgets/table.py index 713fad50..6d36ef87 100644 --- a/TermTk/TTkWidgets/table.py +++ b/TermTk/TTkWidgets/table.py @@ -27,11 +27,11 @@ from TermTk.TTkCore.constant import TTkK from TermTk.TTkCore.log import TTkLog from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal from TermTk.TTkCore.color import TTkColor -from TermTk.TTkWidgets.tableview import TTkTableView +from TermTk.TTkWidgets.Fancy.tableview import TtkFancyTableView from TermTk.TTkLayouts.gridlayout import TTkGridLayout from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollArea -class TTkTable(TTkAbstractScrollArea): +class TtkFancyTable(TTkAbstractScrollArea): __slots__ = ( '_tableView', 'activated', # Forwarded Methods @@ -42,9 +42,9 @@ class TTkTable(TTkAbstractScrollArea): def __init__(self, *args, **kwargs): TTkAbstractScrollArea.__init__(self, *args, **kwargs) - self._name = kwargs.get('name' , 'TTkTable' ) + self._name = kwargs.get('name' , 'TtkFancyTable' ) if 'parent' in kwargs: kwargs.pop('parent') - self._tableView = TTkTableView(*args, **kwargs) + self._tableView = TtkFancyTableView(*args, **kwargs) # Forward the signal self.activated = self._tableView.activated diff --git a/TermTk/TTkWidgets/tree.py b/TermTk/TTkWidgets/tree.py index f427b37c..d4af583a 100644 --- a/TermTk/TTkWidgets/tree.py +++ b/TermTk/TTkWidgets/tree.py @@ -27,11 +27,11 @@ from TermTk.TTkCore.constant import TTkK from TermTk.TTkCore.log import TTkLog from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal from TermTk.TTkCore.color import TTkColor -from TermTk.TTkWidgets.treewidget import TTkTreeWidget +from TermTk.TTkWidgets.Fancy.treewidget import TtkFancyTreeWidget from TermTk.TTkLayouts.gridlayout import TTkGridLayout from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollArea -class TTkTree(TTkAbstractScrollArea): +class TtkFancyTree(TTkAbstractScrollArea): __slots__ = ( '_treeView', 'activated', # Forwarded Methods @@ -39,9 +39,9 @@ class TTkTree(TTkAbstractScrollArea): def __init__(self, *args, **kwargs): TTkAbstractScrollArea.__init__(self, *args, **kwargs) - self._name = kwargs.get('name' , 'TTkTree' ) + self._name = kwargs.get('name' , 'TtkFancyTree' ) if 'parent' in kwargs: kwargs.pop('parent') - self._treeView = TTkTreeWidget(*args, **kwargs) + self._treeView = TtkFancyTreeWidget(*args, **kwargs) # Forward the signal self.activated = self._treeView.activated diff --git a/TermTk/TTkWidgets/treeview.py b/TermTk/TTkWidgets/treeview.py index fc08dd5b..d4757df8 100644 --- a/TermTk/TTkWidgets/treeview.py +++ b/TermTk/TTkWidgets/treeview.py @@ -27,13 +27,13 @@ from TermTk.TTkCore.constant import TTkK from TermTk.TTkCore.log import TTkLog from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal from TermTk.TTkCore.color import TTkColor -from TermTk.TTkWidgets.tableview import TTkTableView +from TermTk.TTkWidgets.Fancy.tableview import TtkFancyTableView -class TTkTreeView(TTkTableView): +class TtkFancyTreeView(TtkFancyTableView): __slots__ = ( '_header', '_treeView', '_showHeader', 'activated') def __init__(self, *args, **kwargs): super().__init__(self, *args, **kwargs) - self._name = kwargs.get('name' , 'TTkTreeView' ) + self._name = kwargs.get('name' , 'TtkFancyTreeView' ) # if 'parent' in kwargs: kwargs.pop('parent') diff --git a/demo/gittk.py b/demo/gittk.py index 4ed584f2..cb255f89 100755 --- a/demo/gittk.py +++ b/demo/gittk.py @@ -59,7 +59,7 @@ else: gittk = ttk.TTkWindow(parent=root,pos = (1,1), size=(100,40), title="gittk", border=True, layout=ttk.TTkGridLayout()) gittkVsplitter = ttk.TTkSplitter(parent=gittk, orientation=ttk.TTkK.VERTICAL) -tableCommit = ttk.TTkTable(parent=gittkVsplitter, selectColor=ttk.TTkColor.bg('#882200')) +tableCommit = ttk.TtkFancyTable(parent=gittkVsplitter, selectColor=ttk.TTkColor.bg('#882200')) gittkHsplitter = ttk.TTkSplitter(parent=gittkVsplitter, orientation=ttk.TTkK.HORIZONTAL) diffText = ttk.TTkTextEdit(parent=gittkHsplitter) gittkHsplitter.addWidget(ttk.TTkTestWidgetSizes(border=True, title="Details"),20) diff --git a/demo/showcase/table.py b/demo/showcase/table.py index 91585c04..50c239cf 100755 --- a/demo/showcase/table.py +++ b/demo/showcase/table.py @@ -42,7 +42,7 @@ def demoTable(root=None): btn1 = ttk.TTkButton(parent=top, maxHeight=3, border=True, text='Add') btn2 = ttk.TTkButton(parent=top, maxHeight=3, border=True, text='Add Many') - table1 = ttk.TTkTable(parent=frame, selectColor=ttk.TTkColor.bg('#882200')) + table1 = ttk.TtkFancyTable(parent=frame, selectColor=ttk.TTkColor.bg('#882200')) table1.setColumnSize((5,10,-1,10,20)) table1.setAlignment(( diff --git a/demo/showcase/tree.py b/demo/showcase/tree.py index afd98bdb..43291bb4 100755 --- a/demo/showcase/tree.py +++ b/demo/showcase/tree.py @@ -40,49 +40,49 @@ def getSentence(a,b): return " ".join([getWord() for i in range(0,random.randint(a,b))]) def demoTree(root=None): - # tw = ttk.TTkTreeWidget(parent=rootTree1) - tw = ttk.TTkTree(parent=root) + # tw = ttk.TtkFancyTreeWidget(parent=rootTree1) + tw = ttk.TtkFancyTree(parent=root) tw.setHeaderLabels(["Column 1", "Column 2", "Column 3"]) - tw.setColumnSize((20,20,-1)) + tw.setColumnSize((-1,20,20)) tw.setColumnColors(( ttk.TTkColor.RST, ttk.TTkColor.fg('#00dddd', modifier=ttk.TTkColorGradient(increment=-4)), ttk.TTkColor.fg('#cccc00', modifier=ttk.TTkColorGradient(increment=-2)) )) - l1 = ttk.TTkTreeWidgetItem(["String A", "String B", "String C"]) - l2 = ttk.TTkTreeWidgetItem(["String AA", "String BB", "String CC"]) - l3 = ttk.TTkTreeWidgetItem(["String AAA", "String BBB", "String CCC"]) - l4 = ttk.TTkTreeWidgetItem(["String AAAA", "String BBBB", "String CCCC"]) - l5 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) + l1 = ttk.TtkFancyTreeWidgetItem(["String A", "String B", "String C"]) + l2 = ttk.TtkFancyTreeWidgetItem(["String AA", "String BB", "String CC"]) + l3 = ttk.TtkFancyTreeWidgetItem(["String AAA", "String BBB", "String CCC"]) + l4 = ttk.TtkFancyTreeWidgetItem(["String AAAA", "String BBBB", "String CCCC"]) + l5 = ttk.TtkFancyTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) l2.addChild(l5) for i in range(3): - l1_child = ttk.TTkTreeWidgetItem(["Child A" + str(i), "Child B" + str(i), "Child C" + str(i)]) + l1_child = ttk.TtkFancyTreeWidgetItem(["Child A" + str(i), "Child B" + str(i), "Child C" + str(i)]) l1.addChild(l1_child) for j in range(2): - l2_child = ttk.TTkTreeWidgetItem(["Child AA" + str(j), "Child BB" + str(j), "Child CC" + str(j)]) + l2_child = ttk.TtkFancyTreeWidgetItem(["Child AA" + str(j), "Child BB" + str(j), "Child CC" + str(j)]) l2.addChild(l2_child) for j in range(2): - l3_child = ttk.TTkTreeWidgetItem(["Child AAA" + str(j), "Child BBB" + str(j), "Child CCC" + str(j)]) + l3_child = ttk.TtkFancyTreeWidgetItem(["Child AAA" + str(j), "Child BBB" + str(j), "Child CCC" + str(j)]) l3.addChild(l3_child) for j in range(2): - l4_child = ttk.TTkTreeWidgetItem(["Child AAAA" + str(j), "Child BBBB" + str(j), "Child CCCC" + str(j)]) + l4_child = ttk.TtkFancyTreeWidgetItem(["Child AAAA" + str(j), "Child BBBB" + str(j), "Child CCCC" + str(j)]) l4.addChild(l4_child) for j in range(2): - l5_child = ttk.TTkTreeWidgetItem(["Child AAAAA" + str(j), "Child BBBBB" + str(j), "Child CCCCC" + str(j)]) + l5_child = ttk.TtkFancyTreeWidgetItem(["Child AAAAA" + str(j), "Child BBBBB" + str(j), "Child CCCCC" + str(j)]) l5.addChild(l5_child) - l6 = ttk.TTkTreeWidgetItem(["RND", "RND", "RND"], childIndicatorPolicy=ttk.TTkK.ShowIndicator) + l6 = ttk.TtkFancyTreeWidgetItem(["RND", "RND", "RND"], childIndicatorPolicy=ttk.TTkK.ShowIndicator) def updateChilds(item): if item.childs(): return for _ in range(0,random.randint(3,8)): - child = ttk.TTkTreeWidgetItem([getWord(),getWord(),getWord()]) + child = ttk.TtkFancyTreeWidgetItem([getWord(),getWord(),getWord()]) if random.randint(0,10)>5: child.setChildIndicatorPolicy(ttk.TTkK.ShowIndicator) child.refreshData.connect(updateChilds) diff --git a/tests/test.ui.008.table.py b/tests/test.ui.008.table.py index 1677d550..606a14b8 100755 --- a/tests/test.ui.008.table.py +++ b/tests/test.ui.008.table.py @@ -42,13 +42,13 @@ btn1 = ttk.TTkButton(parent=root, pos=(0,0), size=(5,3), border=True, text='Add' btn2 = ttk.TTkButton(parent=root, pos=(5,0), size=(10,3), border=True, text='Add Many') win_table1 = ttk.TTkWindow(parent=root,pos = (3,3), size=(150,40), title="Test Table 1", layout=ttk.TTkHBoxLayout(), border=True) -table1 = ttk.TTkTable(parent=win_table1, selectColor=ttk.TTkColor.bg('#882200')) +table1 = ttk.TtkFancyTable(parent=win_table1, selectColor=ttk.TTkColor.bg('#882200')) win_table2 = ttk.TTkWindow(parent=root,pos = (15,5), size=(100,30), title="Test Table 2 Default", layout=ttk.TTkHBoxLayout(), border=True) -table2 = ttk.TTkTable(parent=win_table2) +table2 = ttk.TtkFancyTable(parent=win_table2) win_table3 = ttk.TTkWindow(parent=root,pos = (15,5), size=(130,40), title="Test Table 2 Default", layout=ttk.TTkHBoxLayout(), border=True) -table3 = ttk.TTkTable(parent=win_table3, showHeader=False) +table3 = ttk.TtkFancyTable(parent=win_table3, showHeader=False) table1.setColumnSize((5,10,-1,10,20)) table1.setAlignment(( diff --git a/tests/test.ui.011.tree.py b/tests/test.ui.011.tree.py index 96b5ce0e..730dda70 100755 --- a/tests/test.ui.011.tree.py +++ b/tests/test.ui.011.tree.py @@ -42,8 +42,8 @@ if fullscreen: else: rootTree1 = ttk.TTkWindow(parent=root,pos = (0,0), size=(150,50), title="Test Tree 1", layout=ttk.TTkGridLayout(), border=True) -# tw = ttk.TTkTreeWidget(parent=rootTree1) -tw = ttk.TTkTree(parent=rootTree1) +# tw = ttk.TtkFancyTreeWidget(parent=rootTree1) +tw = ttk.TtkFancyTree(parent=rootTree1) tw.setHeaderLabels(["Column 1", "Column 2", "Column 3"]) tw.setColumnSize((20,20,-1)) tw.setColumnColors(( @@ -51,32 +51,32 @@ tw.setColumnColors(( ttk.TTkColor.fg('#00dddd', modifier=ttk.TTkColorGradient(increment=-4)), ttk.TTkColor.fg('#cccc00', modifier=ttk.TTkColorGradient(increment=-2)) )) -l1 = ttk.TTkTreeWidgetItem(["String A", "String B", "String C"]) -l2 = ttk.TTkTreeWidgetItem(["String AA", "String BB", "String CC"]) -l3 = ttk.TTkTreeWidgetItem(["String AAA", "String BBB", "String CCC"]) -l4 = ttk.TTkTreeWidgetItem(["String AAAA", "String BBBB", "String CCCC"]) -l5 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) +l1 = ttk.TtkFancyTreeWidgetItem(["String A", "String B", "String C"]) +l2 = ttk.TtkFancyTreeWidgetItem(["String AA", "String BB", "String CC"]) +l3 = ttk.TtkFancyTreeWidgetItem(["String AAA", "String BBB", "String CCC"]) +l4 = ttk.TtkFancyTreeWidgetItem(["String AAAA", "String BBBB", "String CCCC"]) +l5 = ttk.TtkFancyTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) l2.addChild(l5) for i in range(3): - l1_child = ttk.TTkTreeWidgetItem(["Child A" + str(i), "Child B" + str(i), "Child C" + str(i)]) + l1_child = ttk.TtkFancyTreeWidgetItem(["Child A" + str(i), "Child B" + str(i), "Child C" + str(i)]) l1.addChild(l1_child) for j in range(2): - l2_child = ttk.TTkTreeWidgetItem(["Child AA" + str(j), "Child BB" + str(j), "Child CC" + str(j)]) + l2_child = ttk.TtkFancyTreeWidgetItem(["Child AA" + str(j), "Child BB" + str(j), "Child CC" + str(j)]) l2.addChild(l2_child) for j in range(2): - l3_child = ttk.TTkTreeWidgetItem(["Child AAA" + str(j), "Child BBB" + str(j), "Child CCC" + str(j)]) + l3_child = ttk.TtkFancyTreeWidgetItem(["Child AAA" + str(j), "Child BBB" + str(j), "Child CCC" + str(j)]) l3.addChild(l3_child) for j in range(2): - l4_child = ttk.TTkTreeWidgetItem(["Child AAAA" + str(j), "Child BBBB" + str(j), "Child CCCC" + str(j)]) + l4_child = ttk.TtkFancyTreeWidgetItem(["Child AAAA" + str(j), "Child BBBB" + str(j), "Child CCCC" + str(j)]) l4.addChild(l4_child) for j in range(2): - l5_child = ttk.TTkTreeWidgetItem(["Child AAAAA" + str(j), "Child BBBBB" + str(j), "Child CCCCC" + str(j)]) + l5_child = ttk.TtkFancyTreeWidgetItem(["Child AAAAA" + str(j), "Child BBBBB" + str(j), "Child CCCCC" + str(j)]) l5.addChild(l5_child) From 9c327ee79ebe8645df41f9e107b4eeb8de075cff Mon Sep 17 00:00:00 2001 From: Eugenio Parodi Date: Sun, 5 Dec 2021 18:43:49 +0000 Subject: [PATCH 2/7] Fix Typo --- TermTk/TTkTypes/treewidgetitem.py | 4 +- TermTk/TTkWidgets/Fancy/table.py | 8 +-- TermTk/TTkWidgets/Fancy/tableview.py | 16 +++--- TermTk/TTkWidgets/Fancy/tree.py | 8 +-- TermTk/TTkWidgets/Fancy/treeview.py | 6 +-- TermTk/TTkWidgets/Fancy/treewidget.py | 26 ++++----- TermTk/TTkWidgets/TTkPickers/filepicker.py | 6 +-- TermTk/TTkWidgets/table.py | 8 +-- TermTk/TTkWidgets/tree.py | 61 ---------------------- TermTk/TTkWidgets/treeview.py | 6 +-- TermTk/TTkWidgets/treewidget.py | 23 ++++++++ TermTk/TTkWidgets/treewidgetitem.py | 23 ++++++++ demo/gittk.py | 2 +- demo/showcase/table.py | 2 +- demo/showcase/tree.py | 28 +++++----- tests/test.ui.008.table.py | 6 +-- tests/test.ui.011.tree.py | 24 ++++----- 17 files changed, 121 insertions(+), 136 deletions(-) delete mode 100644 TermTk/TTkWidgets/tree.py create mode 100644 TermTk/TTkWidgets/treewidget.py create mode 100644 TermTk/TTkWidgets/treewidgetitem.py diff --git a/TermTk/TTkTypes/treewidgetitem.py b/TermTk/TTkTypes/treewidgetitem.py index 8df89b01..e23e48ba 100644 --- a/TermTk/TTkTypes/treewidgetitem.py +++ b/TermTk/TTkTypes/treewidgetitem.py @@ -27,13 +27,13 @@ from TermTk.TTkCore.constant import TTkK from TermTk.TTkCore.log import TTkLog from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal -class TtkFancyTreeWidgetItem(): +class TTkFancyTreeWidgetItem(): __slots__ = ('_parent', '_data', '_childs', '_expand', '_childIndicatorPolicy', # Signals 'refreshData') def __init__(self, *args, **kwargs): # Signals - self.refreshData = pyTTkSignal(TtkFancyTreeWidgetItem) + self.refreshData = pyTTkSignal(TTkFancyTreeWidgetItem) self._data = args[0] self._childs = [] self._childIndicatorPolicy = kwargs.get('childIndicatorPolicy', TTkK.DontShowIndicatorWhenChildless) diff --git a/TermTk/TTkWidgets/Fancy/table.py b/TermTk/TTkWidgets/Fancy/table.py index 6d36ef87..0987fa18 100644 --- a/TermTk/TTkWidgets/Fancy/table.py +++ b/TermTk/TTkWidgets/Fancy/table.py @@ -27,11 +27,11 @@ from TermTk.TTkCore.constant import TTkK from TermTk.TTkCore.log import TTkLog from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal from TermTk.TTkCore.color import TTkColor -from TermTk.TTkWidgets.Fancy.tableview import TtkFancyTableView +from TermTk.TTkWidgets.Fancy.tableview import TTkFancyTableView from TermTk.TTkLayouts.gridlayout import TTkGridLayout from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollArea -class TtkFancyTable(TTkAbstractScrollArea): +class TTkFancyTable(TTkAbstractScrollArea): __slots__ = ( '_tableView', 'activated', # Forwarded Methods @@ -42,9 +42,9 @@ class TtkFancyTable(TTkAbstractScrollArea): def __init__(self, *args, **kwargs): TTkAbstractScrollArea.__init__(self, *args, **kwargs) - self._name = kwargs.get('name' , 'TtkFancyTable' ) + self._name = kwargs.get('name' , 'TTkFancyTable' ) if 'parent' in kwargs: kwargs.pop('parent') - self._tableView = TtkFancyTableView(*args, **kwargs) + self._tableView = TTkFancyTableView(*args, **kwargs) # Forward the signal self.activated = self._tableView.activated diff --git a/TermTk/TTkWidgets/Fancy/tableview.py b/TermTk/TTkWidgets/Fancy/tableview.py index 5a94bbc2..1c6e2930 100644 --- a/TermTk/TTkWidgets/Fancy/tableview.py +++ b/TermTk/TTkWidgets/Fancy/tableview.py @@ -31,11 +31,11 @@ from TermTk.TTkWidgets.widget import TTkWidget from TermTk.TTkLayouts.gridlayout import TTkGridLayout from TermTk.TTkAbstract.abstractscrollview import TTkAbstractScrollView -class _TtkFancyTableViewHeader(TTkWidget): +class _TTkFancyTableViewHeader(TTkWidget): __slots__ = ('_header', '_alignments', '_headerColor', '_columns') def __init__(self, *args, **kwargs): TTkWidget.__init__(self, *args, **kwargs) - self._name = kwargs.get('name' , '_TtkFancyTableViewHeader' ) + self._name = kwargs.get('name' , '_TTkFancyTableViewHeader' ) self._columns = kwargs.get('columns' , [-1] ) self._header = [""]*len(self._columns) self._alignments = [TTkK.NONE]*len(self._columns) @@ -80,7 +80,7 @@ class _TtkFancyTableViewHeader(TTkWidget): self._canvas.drawTableLine(pos=(0,0), items=self._header, sizes=sizes, colors=colors, alignments=self._alignments) -class _TtkFancyTableView(TTkAbstractScrollView): +class _TTkFancyTableView(TTkAbstractScrollView): __slots__ = ( '_alignments', '_headerColor', '_columns', '_columnColors', @@ -94,7 +94,7 @@ class _TtkFancyTableView(TTkAbstractScrollView): self._tableDataWidget = [] self._shownWidgets = [] TTkAbstractScrollView.__init__(self, *args, **kwargs) - self._name = kwargs.get('name' , '_TtkFancyTableView' ) + self._name = kwargs.get('name' , '_TTkFancyTableView' ) # define signals self.activated = pyTTkSignal(int) # Value self.doubleClicked = pyTTkSignal(int) # Value @@ -335,7 +335,7 @@ class _TtkFancyTableView(TTkAbstractScrollView): colors = [c.modParam(val=-val) for c in self._columnColors] self._canvas.drawTableLine(pos=(0,y), items=item, sizes=sizes, colors=colors, alignments=self._alignments) -class TtkFancyTableView(TTkAbstractScrollView): +class TTkFancyTableView(TTkAbstractScrollView): __slots__ = ( '_header', '_tableView', '_showHeader', 'activated', # Forwarded Methods @@ -344,12 +344,12 @@ class TtkFancyTableView(TTkAbstractScrollView): def __init__(self, *args, **kwargs): super().__init__(self, *args, **kwargs) - self._name = kwargs.get('name' , 'TtkFancyTableView' ) + self._name = kwargs.get('name' , 'TTkFancyTableView' ) if 'parent' in kwargs: kwargs.pop('parent') self._showHeader = kwargs.get('showHeader', True) self.setLayout(TTkGridLayout()) - self._tableView = _TtkFancyTableView(*args, **kwargs) - self._header = _TtkFancyTableViewHeader(*args, **kwargs) + self._tableView = _TTkFancyTableView(*args, **kwargs) + self._header = _TTkFancyTableViewHeader(*args, **kwargs) self.layout().addWidget(self._header,0,0) self.layout().addWidget(self._tableView,1,0) # Forward the tableSignals diff --git a/TermTk/TTkWidgets/Fancy/tree.py b/TermTk/TTkWidgets/Fancy/tree.py index d4af583a..1e51b9b0 100644 --- a/TermTk/TTkWidgets/Fancy/tree.py +++ b/TermTk/TTkWidgets/Fancy/tree.py @@ -27,11 +27,11 @@ from TermTk.TTkCore.constant import TTkK from TermTk.TTkCore.log import TTkLog from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal from TermTk.TTkCore.color import TTkColor -from TermTk.TTkWidgets.Fancy.treewidget import TtkFancyTreeWidget +from TermTk.TTkWidgets.Fancy.treewidget import TTkFancyTreeWidget from TermTk.TTkLayouts.gridlayout import TTkGridLayout from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollArea -class TtkFancyTree(TTkAbstractScrollArea): +class TTkFancyTree(TTkAbstractScrollArea): __slots__ = ( '_treeView', 'activated', # Forwarded Methods @@ -39,9 +39,9 @@ class TtkFancyTree(TTkAbstractScrollArea): def __init__(self, *args, **kwargs): TTkAbstractScrollArea.__init__(self, *args, **kwargs) - self._name = kwargs.get('name' , 'TtkFancyTree' ) + self._name = kwargs.get('name' , 'TTkFancyTree' ) if 'parent' in kwargs: kwargs.pop('parent') - self._treeView = TtkFancyTreeWidget(*args, **kwargs) + self._treeView = TTkFancyTreeWidget(*args, **kwargs) # Forward the signal self.activated = self._treeView.activated diff --git a/TermTk/TTkWidgets/Fancy/treeview.py b/TermTk/TTkWidgets/Fancy/treeview.py index d4757df8..3a5d296e 100644 --- a/TermTk/TTkWidgets/Fancy/treeview.py +++ b/TermTk/TTkWidgets/Fancy/treeview.py @@ -27,13 +27,13 @@ from TermTk.TTkCore.constant import TTkK from TermTk.TTkCore.log import TTkLog from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal from TermTk.TTkCore.color import TTkColor -from TermTk.TTkWidgets.Fancy.tableview import TtkFancyTableView +from TermTk.TTkWidgets.Fancy.tableview import TTkFancyTableView -class TtkFancyTreeView(TtkFancyTableView): +class TTkFancyTreeView(TTkFancyTableView): __slots__ = ( '_header', '_treeView', '_showHeader', 'activated') def __init__(self, *args, **kwargs): super().__init__(self, *args, **kwargs) - self._name = kwargs.get('name' , 'TtkFancyTreeView' ) + self._name = kwargs.get('name' , 'TTkFancyTreeView' ) # if 'parent' in kwargs: kwargs.pop('parent') diff --git a/TermTk/TTkWidgets/Fancy/treewidget.py b/TermTk/TTkWidgets/Fancy/treewidget.py index 68468eeb..11055678 100644 --- a/TermTk/TTkWidgets/Fancy/treewidget.py +++ b/TermTk/TTkWidgets/Fancy/treewidget.py @@ -29,9 +29,9 @@ from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal from TermTk.TTkCore.color import TTkColor from TermTk.TTkWidgets.widget import TTkWidget from TermTk.TTkWidgets.checkbox import TTkCheckbox -from TermTk.TTkWidgets.Fancy.tableview import TtkFancyTableView +from TermTk.TTkWidgets.Fancy.tableview import TTkFancyTableView from TermTk.TTkLayouts.gridlayout import TTkGridLayout -from TermTk.TTkTypes.treewidgetitem import TtkFancyTreeWidgetItem +from TermTk.TTkTypes.treewidgetitem import TTkFancyTreeWidgetItem class _TTkDisplayedTreeItemControl(TTkCheckbox): def __init__(self, *args, **kwargs): @@ -51,7 +51,7 @@ class _TTkDisplayedTreeItem(TTkWidget): def __init__(self, *args, **kwargs): super().__init__(self, *args, **kwargs) #Signals - self._clicked = pyTTkSignal(bool, _TTkDisplayedTreeItem, TtkFancyTreeWidgetItem) + self._clicked = pyTTkSignal(bool, _TTkDisplayedTreeItem, TTkFancyTreeWidgetItem) self._name = kwargs.get('name' , '_TTkDisplayedTreeItem' ) self._depth = kwargs.get('depth' , 0 ) @@ -77,13 +77,13 @@ class _TTkDisplayedTreeItem(TTkWidget): self._canvas.drawText(pos=(self._depth+2, 0), text=self._text) -class TtkFancyTreeWidget(TtkFancyTableView): +class TTkFancyTreeWidget(TTkFancyTableView): __slots__ = ( '_topLevelItems') def __init__(self, *args, **kwargs): super().__init__(self, *args, **kwargs) - self._name = kwargs.get('name' , 'TtkFancyTreeView' ) - self._topLevelItems = TtkFancyTreeWidgetItem(None) + self._name = kwargs.get('name' , 'TTkFancyTreeView' ) + self._topLevelItems = TTkFancyTreeWidgetItem(None) self.doubleClicked.connect(self._doubleClickItem) # if 'parent' in kwargs: kwargs.pop('parent') @@ -120,23 +120,23 @@ class TtkFancyTreeWidget(TtkFancyTableView): def _doubleClickItem(self, index): if not (item := self.itemAt(index)): return if item[0]._isLeaf: return - if not item[0]._treeWidgetItem.expand(): # we need to expand the TtkFancyTreeWidgetItem + if not item[0]._treeWidgetItem.expand(): # we need to expand the TTkFancyTreeWidgetItem self._expand(item=item[0]._treeWidgetItem, depth=item[0]._depth+1) - else: # we need to shrink the TtkFancyTreeWidgetItem + else: # we need to shrink the TTkFancyTreeWidgetItem self._shrink(item=item[0]._treeWidgetItem) - @pyTTkSlot(bool, _TTkDisplayedTreeItem, TtkFancyTreeWidgetItem) + @pyTTkSlot(bool, _TTkDisplayedTreeItem, TTkFancyTreeWidgetItem) def _controlClicked(self, status, widget, item): TTkLog.debug(f"{status} {widget._name}") - if status: # we need to expand the TtkFancyTreeWidgetItem + if status: # we need to expand the TTkFancyTreeWidgetItem self._expand(item=item, depth=(widget._depth+1)) - else: # we need to shrink the TtkFancyTreeWidgetItem + else: # we need to shrink the TTkFancyTreeWidgetItem self._shrink(item=item) def _addTreeWidgetItem(self, item, depth=0, index=-1): - if not isinstance(item, TtkFancyTreeWidgetItem): - raise TypeError("TtkFancyTreeWidgetItem is required in TtkFancyTreeWidget.addTopLevelItem(item)") + if not isinstance(item, TTkFancyTreeWidgetItem): + raise TypeError("TTkFancyTreeWidgetItem is required in TTkFancyTreeWidget.addTopLevelItem(item)") if item.parent() is None: self._topLevelItems.addChild(item) displayedItems = item.data().copy() diff --git a/TermTk/TTkWidgets/TTkPickers/filepicker.py b/TermTk/TTkWidgets/TTkPickers/filepicker.py index 3a926d00..ecfd745d 100644 --- a/TermTk/TTkWidgets/TTkPickers/filepicker.py +++ b/TermTk/TTkWidgets/TTkPickers/filepicker.py @@ -25,11 +25,11 @@ from os import walk from TermTk.TTkWidgets.window import TTkWindow -from TermTk.TTkTypes.treewidgetitem import TtkFancyTreeWidgetItem +from TermTk.TTkTypes.treewidgetitem import TTkFancyTreeWidgetItem -class _FileWidgetItem(TtkFancyTreeWidgetItem): +class _FileWidgetItem(TTkFancyTreeWidgetItem): def __init__(self, *args, **kwargs): - TtkFancyTreeWidgetItem.__init__(self, *args, **kwargs) + TTkFancyTreeWidgetItem.__init__(self, *args, **kwargs) class TTkFileDialogPicker(TTkWindow): def __init__(self, *args, **kwargs): diff --git a/TermTk/TTkWidgets/table.py b/TermTk/TTkWidgets/table.py index 6d36ef87..0987fa18 100644 --- a/TermTk/TTkWidgets/table.py +++ b/TermTk/TTkWidgets/table.py @@ -27,11 +27,11 @@ from TermTk.TTkCore.constant import TTkK from TermTk.TTkCore.log import TTkLog from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal from TermTk.TTkCore.color import TTkColor -from TermTk.TTkWidgets.Fancy.tableview import TtkFancyTableView +from TermTk.TTkWidgets.Fancy.tableview import TTkFancyTableView from TermTk.TTkLayouts.gridlayout import TTkGridLayout from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollArea -class TtkFancyTable(TTkAbstractScrollArea): +class TTkFancyTable(TTkAbstractScrollArea): __slots__ = ( '_tableView', 'activated', # Forwarded Methods @@ -42,9 +42,9 @@ class TtkFancyTable(TTkAbstractScrollArea): def __init__(self, *args, **kwargs): TTkAbstractScrollArea.__init__(self, *args, **kwargs) - self._name = kwargs.get('name' , 'TtkFancyTable' ) + self._name = kwargs.get('name' , 'TTkFancyTable' ) if 'parent' in kwargs: kwargs.pop('parent') - self._tableView = TtkFancyTableView(*args, **kwargs) + self._tableView = TTkFancyTableView(*args, **kwargs) # Forward the signal self.activated = self._tableView.activated diff --git a/TermTk/TTkWidgets/tree.py b/TermTk/TTkWidgets/tree.py deleted file mode 100644 index d4af583a..00000000 --- a/TermTk/TTkWidgets/tree.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env python3 - -# MIT License -# -# Copyright (c) 2021 Eugenio Parodi -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -from TermTk.TTkCore.cfg import TTkCfg -from TermTk.TTkCore.constant import TTkK -from TermTk.TTkCore.log import TTkLog -from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal -from TermTk.TTkCore.color import TTkColor -from TermTk.TTkWidgets.Fancy.treewidget import TtkFancyTreeWidget -from TermTk.TTkLayouts.gridlayout import TTkGridLayout -from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollArea - -class TtkFancyTree(TTkAbstractScrollArea): - __slots__ = ( - '_treeView', 'activated', - # Forwarded Methods - 'setAlignment', 'setHeader', 'setHeaderLabels', 'setColumnSize', 'setColumnColors', 'appendItem', 'addTopLevelItem' ) - - def __init__(self, *args, **kwargs): - TTkAbstractScrollArea.__init__(self, *args, **kwargs) - self._name = kwargs.get('name' , 'TtkFancyTree' ) - if 'parent' in kwargs: kwargs.pop('parent') - self._treeView = TtkFancyTreeWidget(*args, **kwargs) - # Forward the signal - self.activated = self._treeView.activated - - self.setFocusPolicy(TTkK.ClickFocus) - self.setViewport(self._treeView) - - # Forwarded Methods - self.setAlignment = self._treeView.setAlignment - self.setHeader = self._treeView.setHeader - self.setHeaderLabels = self._treeView.setHeaderLabels - self.setColumnSize = self._treeView.setColumnSize - self.setColumnColors = self._treeView.setColumnColors - self.appendItem = self._treeView.appendItem - self.addTopLevelItem = self._treeView.addTopLevelItem - - - diff --git a/TermTk/TTkWidgets/treeview.py b/TermTk/TTkWidgets/treeview.py index d4757df8..3a5d296e 100644 --- a/TermTk/TTkWidgets/treeview.py +++ b/TermTk/TTkWidgets/treeview.py @@ -27,13 +27,13 @@ from TermTk.TTkCore.constant import TTkK from TermTk.TTkCore.log import TTkLog from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal from TermTk.TTkCore.color import TTkColor -from TermTk.TTkWidgets.Fancy.tableview import TtkFancyTableView +from TermTk.TTkWidgets.Fancy.tableview import TTkFancyTableView -class TtkFancyTreeView(TtkFancyTableView): +class TTkFancyTreeView(TTkFancyTableView): __slots__ = ( '_header', '_treeView', '_showHeader', 'activated') def __init__(self, *args, **kwargs): super().__init__(self, *args, **kwargs) - self._name = kwargs.get('name' , 'TtkFancyTreeView' ) + self._name = kwargs.get('name' , 'TTkFancyTreeView' ) # if 'parent' in kwargs: kwargs.pop('parent') diff --git a/TermTk/TTkWidgets/treewidget.py b/TermTk/TTkWidgets/treewidget.py new file mode 100644 index 00000000..a0033998 --- /dev/null +++ b/TermTk/TTkWidgets/treewidget.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 + +# MIT License +# +# Copyright (c) 2021 Eugenio Parodi +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. \ No newline at end of file diff --git a/TermTk/TTkWidgets/treewidgetitem.py b/TermTk/TTkWidgets/treewidgetitem.py new file mode 100644 index 00000000..a0033998 --- /dev/null +++ b/TermTk/TTkWidgets/treewidgetitem.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 + +# MIT License +# +# Copyright (c) 2021 Eugenio Parodi +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. \ No newline at end of file diff --git a/demo/gittk.py b/demo/gittk.py index cb255f89..1ca04cea 100755 --- a/demo/gittk.py +++ b/demo/gittk.py @@ -59,7 +59,7 @@ else: gittk = ttk.TTkWindow(parent=root,pos = (1,1), size=(100,40), title="gittk", border=True, layout=ttk.TTkGridLayout()) gittkVsplitter = ttk.TTkSplitter(parent=gittk, orientation=ttk.TTkK.VERTICAL) -tableCommit = ttk.TtkFancyTable(parent=gittkVsplitter, selectColor=ttk.TTkColor.bg('#882200')) +tableCommit = ttk.TTkFancyTable(parent=gittkVsplitter, selectColor=ttk.TTkColor.bg('#882200')) gittkHsplitter = ttk.TTkSplitter(parent=gittkVsplitter, orientation=ttk.TTkK.HORIZONTAL) diffText = ttk.TTkTextEdit(parent=gittkHsplitter) gittkHsplitter.addWidget(ttk.TTkTestWidgetSizes(border=True, title="Details"),20) diff --git a/demo/showcase/table.py b/demo/showcase/table.py index 50c239cf..171ffe1d 100755 --- a/demo/showcase/table.py +++ b/demo/showcase/table.py @@ -42,7 +42,7 @@ def demoTable(root=None): btn1 = ttk.TTkButton(parent=top, maxHeight=3, border=True, text='Add') btn2 = ttk.TTkButton(parent=top, maxHeight=3, border=True, text='Add Many') - table1 = ttk.TtkFancyTable(parent=frame, selectColor=ttk.TTkColor.bg('#882200')) + table1 = ttk.TTkFancyTable(parent=frame, selectColor=ttk.TTkColor.bg('#882200')) table1.setColumnSize((5,10,-1,10,20)) table1.setAlignment(( diff --git a/demo/showcase/tree.py b/demo/showcase/tree.py index 43291bb4..8bc3066b 100755 --- a/demo/showcase/tree.py +++ b/demo/showcase/tree.py @@ -40,8 +40,8 @@ def getSentence(a,b): return " ".join([getWord() for i in range(0,random.randint(a,b))]) def demoTree(root=None): - # tw = ttk.TtkFancyTreeWidget(parent=rootTree1) - tw = ttk.TtkFancyTree(parent=root) + # tw = ttk.TTkFancyTreeWidget(parent=rootTree1) + tw = ttk.TTkFancyTree(parent=root) tw.setHeaderLabels(["Column 1", "Column 2", "Column 3"]) tw.setColumnSize((-1,20,20)) tw.setColumnColors(( @@ -49,40 +49,40 @@ def demoTree(root=None): ttk.TTkColor.fg('#00dddd', modifier=ttk.TTkColorGradient(increment=-4)), ttk.TTkColor.fg('#cccc00', modifier=ttk.TTkColorGradient(increment=-2)) )) - l1 = ttk.TtkFancyTreeWidgetItem(["String A", "String B", "String C"]) - l2 = ttk.TtkFancyTreeWidgetItem(["String AA", "String BB", "String CC"]) - l3 = ttk.TtkFancyTreeWidgetItem(["String AAA", "String BBB", "String CCC"]) - l4 = ttk.TtkFancyTreeWidgetItem(["String AAAA", "String BBBB", "String CCCC"]) - l5 = ttk.TtkFancyTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) + l1 = ttk.TTkFancyTreeWidgetItem(["String A", "String B", "String C"]) + l2 = ttk.TTkFancyTreeWidgetItem(["String AA", "String BB", "String CC"]) + l3 = ttk.TTkFancyTreeWidgetItem(["String AAA", "String BBB", "String CCC"]) + l4 = ttk.TTkFancyTreeWidgetItem(["String AAAA", "String BBBB", "String CCCC"]) + l5 = ttk.TTkFancyTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) l2.addChild(l5) for i in range(3): - l1_child = ttk.TtkFancyTreeWidgetItem(["Child A" + str(i), "Child B" + str(i), "Child C" + str(i)]) + l1_child = ttk.TTkFancyTreeWidgetItem(["Child A" + str(i), "Child B" + str(i), "Child C" + str(i)]) l1.addChild(l1_child) for j in range(2): - l2_child = ttk.TtkFancyTreeWidgetItem(["Child AA" + str(j), "Child BB" + str(j), "Child CC" + str(j)]) + l2_child = ttk.TTkFancyTreeWidgetItem(["Child AA" + str(j), "Child BB" + str(j), "Child CC" + str(j)]) l2.addChild(l2_child) for j in range(2): - l3_child = ttk.TtkFancyTreeWidgetItem(["Child AAA" + str(j), "Child BBB" + str(j), "Child CCC" + str(j)]) + l3_child = ttk.TTkFancyTreeWidgetItem(["Child AAA" + str(j), "Child BBB" + str(j), "Child CCC" + str(j)]) l3.addChild(l3_child) for j in range(2): - l4_child = ttk.TtkFancyTreeWidgetItem(["Child AAAA" + str(j), "Child BBBB" + str(j), "Child CCCC" + str(j)]) + l4_child = ttk.TTkFancyTreeWidgetItem(["Child AAAA" + str(j), "Child BBBB" + str(j), "Child CCCC" + str(j)]) l4.addChild(l4_child) for j in range(2): - l5_child = ttk.TtkFancyTreeWidgetItem(["Child AAAAA" + str(j), "Child BBBBB" + str(j), "Child CCCCC" + str(j)]) + l5_child = ttk.TTkFancyTreeWidgetItem(["Child AAAAA" + str(j), "Child BBBBB" + str(j), "Child CCCCC" + str(j)]) l5.addChild(l5_child) - l6 = ttk.TtkFancyTreeWidgetItem(["RND", "RND", "RND"], childIndicatorPolicy=ttk.TTkK.ShowIndicator) + l6 = ttk.TTkFancyTreeWidgetItem(["RND", "RND", "RND"], childIndicatorPolicy=ttk.TTkK.ShowIndicator) def updateChilds(item): if item.childs(): return for _ in range(0,random.randint(3,8)): - child = ttk.TtkFancyTreeWidgetItem([getWord(),getWord(),getWord()]) + child = ttk.TTkFancyTreeWidgetItem([getWord(),getWord(),getWord()]) if random.randint(0,10)>5: child.setChildIndicatorPolicy(ttk.TTkK.ShowIndicator) child.refreshData.connect(updateChilds) diff --git a/tests/test.ui.008.table.py b/tests/test.ui.008.table.py index 606a14b8..3b1dfb74 100755 --- a/tests/test.ui.008.table.py +++ b/tests/test.ui.008.table.py @@ -42,13 +42,13 @@ btn1 = ttk.TTkButton(parent=root, pos=(0,0), size=(5,3), border=True, text='Add' btn2 = ttk.TTkButton(parent=root, pos=(5,0), size=(10,3), border=True, text='Add Many') win_table1 = ttk.TTkWindow(parent=root,pos = (3,3), size=(150,40), title="Test Table 1", layout=ttk.TTkHBoxLayout(), border=True) -table1 = ttk.TtkFancyTable(parent=win_table1, selectColor=ttk.TTkColor.bg('#882200')) +table1 = ttk.TTkFancyTable(parent=win_table1, selectColor=ttk.TTkColor.bg('#882200')) win_table2 = ttk.TTkWindow(parent=root,pos = (15,5), size=(100,30), title="Test Table 2 Default", layout=ttk.TTkHBoxLayout(), border=True) -table2 = ttk.TtkFancyTable(parent=win_table2) +table2 = ttk.TTkFancyTable(parent=win_table2) win_table3 = ttk.TTkWindow(parent=root,pos = (15,5), size=(130,40), title="Test Table 2 Default", layout=ttk.TTkHBoxLayout(), border=True) -table3 = ttk.TtkFancyTable(parent=win_table3, showHeader=False) +table3 = ttk.TTkFancyTable(parent=win_table3, showHeader=False) table1.setColumnSize((5,10,-1,10,20)) table1.setAlignment(( diff --git a/tests/test.ui.011.tree.py b/tests/test.ui.011.tree.py index 730dda70..11e8cd29 100755 --- a/tests/test.ui.011.tree.py +++ b/tests/test.ui.011.tree.py @@ -42,8 +42,8 @@ if fullscreen: else: rootTree1 = ttk.TTkWindow(parent=root,pos = (0,0), size=(150,50), title="Test Tree 1", layout=ttk.TTkGridLayout(), border=True) -# tw = ttk.TtkFancyTreeWidget(parent=rootTree1) -tw = ttk.TtkFancyTree(parent=rootTree1) +# tw = ttk.TTkFancyTreeWidget(parent=rootTree1) +tw = ttk.TTkFancyTree(parent=rootTree1) tw.setHeaderLabels(["Column 1", "Column 2", "Column 3"]) tw.setColumnSize((20,20,-1)) tw.setColumnColors(( @@ -51,32 +51,32 @@ tw.setColumnColors(( ttk.TTkColor.fg('#00dddd', modifier=ttk.TTkColorGradient(increment=-4)), ttk.TTkColor.fg('#cccc00', modifier=ttk.TTkColorGradient(increment=-2)) )) -l1 = ttk.TtkFancyTreeWidgetItem(["String A", "String B", "String C"]) -l2 = ttk.TtkFancyTreeWidgetItem(["String AA", "String BB", "String CC"]) -l3 = ttk.TtkFancyTreeWidgetItem(["String AAA", "String BBB", "String CCC"]) -l4 = ttk.TtkFancyTreeWidgetItem(["String AAAA", "String BBBB", "String CCCC"]) -l5 = ttk.TtkFancyTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) +l1 = ttk.TTkFancyTreeWidgetItem(["String A", "String B", "String C"]) +l2 = ttk.TTkFancyTreeWidgetItem(["String AA", "String BB", "String CC"]) +l3 = ttk.TTkFancyTreeWidgetItem(["String AAA", "String BBB", "String CCC"]) +l4 = ttk.TTkFancyTreeWidgetItem(["String AAAA", "String BBBB", "String CCCC"]) +l5 = ttk.TTkFancyTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) l2.addChild(l5) for i in range(3): - l1_child = ttk.TtkFancyTreeWidgetItem(["Child A" + str(i), "Child B" + str(i), "Child C" + str(i)]) + l1_child = ttk.TTkFancyTreeWidgetItem(["Child A" + str(i), "Child B" + str(i), "Child C" + str(i)]) l1.addChild(l1_child) for j in range(2): - l2_child = ttk.TtkFancyTreeWidgetItem(["Child AA" + str(j), "Child BB" + str(j), "Child CC" + str(j)]) + l2_child = ttk.TTkFancyTreeWidgetItem(["Child AA" + str(j), "Child BB" + str(j), "Child CC" + str(j)]) l2.addChild(l2_child) for j in range(2): - l3_child = ttk.TtkFancyTreeWidgetItem(["Child AAA" + str(j), "Child BBB" + str(j), "Child CCC" + str(j)]) + l3_child = ttk.TTkFancyTreeWidgetItem(["Child AAA" + str(j), "Child BBB" + str(j), "Child CCC" + str(j)]) l3.addChild(l3_child) for j in range(2): - l4_child = ttk.TtkFancyTreeWidgetItem(["Child AAAA" + str(j), "Child BBBB" + str(j), "Child CCCC" + str(j)]) + l4_child = ttk.TTkFancyTreeWidgetItem(["Child AAAA" + str(j), "Child BBBB" + str(j), "Child CCCC" + str(j)]) l4.addChild(l4_child) for j in range(2): - l5_child = ttk.TtkFancyTreeWidgetItem(["Child AAAAA" + str(j), "Child BBBBB" + str(j), "Child CCCCC" + str(j)]) + l5_child = ttk.TTkFancyTreeWidgetItem(["Child AAAAA" + str(j), "Child BBBBB" + str(j), "Child CCCCC" + str(j)]) l5.addChild(l5_child) From ab2e95655a8e6b058bed47e889ef8acfb357de0c Mon Sep 17 00:00:00 2001 From: Eugenio Parodi Date: Sun, 5 Dec 2021 18:52:00 +0000 Subject: [PATCH 3/7] Moved all the old MVC items in 'Fancy' --- TermTk/TTkTypes/__init__.py | 3 +-- TermTk/TTkWidgets/Fancy/__init__.py | 11 ++++++----- TermTk/TTkWidgets/Fancy/treewidget.py | 4 ++-- .../{TTkTypes => TTkWidgets/Fancy}/treewidgetitem.py | 0 TermTk/TTkWidgets/TTkPickers/filepicker.py | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) rename TermTk/{TTkTypes => TTkWidgets/Fancy}/treewidgetitem.py (100%) diff --git a/TermTk/TTkTypes/__init__.py b/TermTk/TTkTypes/__init__.py index 976bfc8b..2c64069d 100644 --- a/TermTk/TTkTypes/__init__.py +++ b/TermTk/TTkTypes/__init__.py @@ -1,2 +1 @@ -from .viewitem import * -from .treewidgetitem import * +from .viewitem import * \ No newline at end of file diff --git a/TermTk/TTkWidgets/Fancy/__init__.py b/TermTk/TTkWidgets/Fancy/__init__.py index 8674408d..85b8abe8 100644 --- a/TermTk/TTkWidgets/Fancy/__init__.py +++ b/TermTk/TTkWidgets/Fancy/__init__.py @@ -1,5 +1,6 @@ -from .table import * -from .tableview import * -from .tree import * -from .treeview import * -from .treewidget import * +from .table import * +from .tableview import * +from .tree import * +from .treeview import * +from .treewidget import * +from .treewidgetitem import * diff --git a/TermTk/TTkWidgets/Fancy/treewidget.py b/TermTk/TTkWidgets/Fancy/treewidget.py index 11055678..6fc7d665 100644 --- a/TermTk/TTkWidgets/Fancy/treewidget.py +++ b/TermTk/TTkWidgets/Fancy/treewidget.py @@ -29,9 +29,9 @@ from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal from TermTk.TTkCore.color import TTkColor from TermTk.TTkWidgets.widget import TTkWidget from TermTk.TTkWidgets.checkbox import TTkCheckbox -from TermTk.TTkWidgets.Fancy.tableview import TTkFancyTableView from TermTk.TTkLayouts.gridlayout import TTkGridLayout -from TermTk.TTkTypes.treewidgetitem import TTkFancyTreeWidgetItem +from TermTk.TTkWidgets.Fancy.tableview import TTkFancyTableView +from TermTk.TTkWidgets.Fancy.treewidgetitem import TTkFancyTreeWidgetItem class _TTkDisplayedTreeItemControl(TTkCheckbox): def __init__(self, *args, **kwargs): diff --git a/TermTk/TTkTypes/treewidgetitem.py b/TermTk/TTkWidgets/Fancy/treewidgetitem.py similarity index 100% rename from TermTk/TTkTypes/treewidgetitem.py rename to TermTk/TTkWidgets/Fancy/treewidgetitem.py diff --git a/TermTk/TTkWidgets/TTkPickers/filepicker.py b/TermTk/TTkWidgets/TTkPickers/filepicker.py index ecfd745d..bc8801f9 100644 --- a/TermTk/TTkWidgets/TTkPickers/filepicker.py +++ b/TermTk/TTkWidgets/TTkPickers/filepicker.py @@ -25,7 +25,7 @@ from os import walk from TermTk.TTkWidgets.window import TTkWindow -from TermTk.TTkTypes.treewidgetitem import TTkFancyTreeWidgetItem +from TermTk.TTkWidgets.Fancy.treewidgetitem import TTkFancyTreeWidgetItem class _FileWidgetItem(TTkFancyTreeWidgetItem): def __init__(self, *args, **kwargs): From abe322186b773aa4fb601c07e9736757f42eb122 Mon Sep 17 00:00:00 2001 From: Eugenio Parodi Date: Sun, 5 Dec 2021 22:47:42 +0000 Subject: [PATCH 4/7] Typo --- TermTk/TTkCore/helper.py | 2 +- TermTk/TTkWidgets/Fancy/treewidget.py | 10 ++-- TermTk/TTkWidgets/Fancy/treewidgetitem.py | 10 ++-- TermTk/TTkWidgets/table.py | 62 ----------------------- TermTk/TTkWidgets/treeview.py | 39 -------------- TermTk/TTkWidgets/treewidgetitem.py | 26 +++++++++- TermTk/TTkWidgets/widget.py | 2 +- demo/showcase/tree.py | 8 +-- 8 files changed, 41 insertions(+), 118 deletions(-) delete mode 100644 TermTk/TTkWidgets/table.py delete mode 100644 TermTk/TTkWidgets/treeview.py diff --git a/TermTk/TTkCore/helper.py b/TermTk/TTkCore/helper.py index c44ed3e3..e597b584 100644 --- a/TermTk/TTkCore/helper.py +++ b/TermTk/TTkCore/helper.py @@ -196,7 +196,7 @@ class TTkHelper: widget.paintEvent() # Compose all the canvas to the parents - # From the deepest childs to the bottom + # From the deepest children to the bottom pushToTerminal = False sortedUpdateWidget = [ (w, TTkHelper.widgetDepth(w)) for w in updateWidgets] sortedUpdateWidget = sorted(sortedUpdateWidget, key=lambda w: -w[1]) diff --git a/TermTk/TTkWidgets/Fancy/treewidget.py b/TermTk/TTkWidgets/Fancy/treewidget.py index 6fc7d665..80cd4959 100644 --- a/TermTk/TTkWidgets/Fancy/treewidget.py +++ b/TermTk/TTkWidgets/Fancy/treewidget.py @@ -59,7 +59,7 @@ class _TTkDisplayedTreeItem(TTkWidget): self._id = kwargs.get('id' , 0 ) self._treeWidgetItem = kwargs.get('treeWidgetItem', None) self._isLeaf = self._treeWidgetItem.childIndicatorPolicy() == TTkK.DontShowIndicator - self._isLeaf |= self._treeWidgetItem.childIndicatorPolicy() == TTkK.DontShowIndicatorWhenChildless and not self._treeWidgetItem.childs() + self._isLeaf |= self._treeWidgetItem.childIndicatorPolicy() == TTkK.DontShowIndicatorWhenChildless and not self._treeWidgetItem.children() if self._isLeaf: self._control = None else: @@ -93,7 +93,7 @@ class TTkFancyTreeWidget(TTkFancyTableView): toExpand = [] index = self.indexOf(item.data())+1 if index != 0: - for child in item.childs(): + for child in item.children(): self._addTreeWidgetItem(item=child, depth=depth, index=index) index+=1 if child.expand(): @@ -107,11 +107,11 @@ class TTkFancyTreeWidget(TTkFancyTableView): item.refresh() index = self.indexOf(item.data()) parent = item.parent() - if item == parent.childs()[-1]: + if item == parent.children()[-1]: self.removeItemsFrom(index+1) else: - nextItemIndex = parent.childs().index(item) - nextItem = parent.childs()[nextItemIndex+1] + nextItemIndex = parent.children().index(item) + nextItem = parent.children()[nextItemIndex+1] indexTo = self.indexOf(nextItem.data()) for id in reversed(range(index+1,indexTo)): self.removeItemAt(id) diff --git a/TermTk/TTkWidgets/Fancy/treewidgetitem.py b/TermTk/TTkWidgets/Fancy/treewidgetitem.py index e23e48ba..0b2c7cd8 100644 --- a/TermTk/TTkWidgets/Fancy/treewidgetitem.py +++ b/TermTk/TTkWidgets/Fancy/treewidgetitem.py @@ -28,14 +28,14 @@ from TermTk.TTkCore.log import TTkLog from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal class TTkFancyTreeWidgetItem(): - __slots__ = ('_parent', '_data', '_childs', '_expand', '_childIndicatorPolicy', + __slots__ = ('_parent', '_data', '_children', '_expand', '_childIndicatorPolicy', # Signals 'refreshData') def __init__(self, *args, **kwargs): # Signals self.refreshData = pyTTkSignal(TTkFancyTreeWidgetItem) self._data = args[0] - self._childs = [] + self._children = [] self._childIndicatorPolicy = kwargs.get('childIndicatorPolicy', TTkK.DontShowIndicatorWhenChildless) self._expand = False self._parent = kwargs.get("parent", None) @@ -56,7 +56,7 @@ class TTkFancyTreeWidgetItem(): return self._expand def addChild(self, item): - self._childs.append(item) + self._children.append(item) item._parent = self def data(self): @@ -65,5 +65,5 @@ class TTkFancyTreeWidgetItem(): def parent(self): return self._parent - def childs(self): - return self._childs \ No newline at end of file + def children(self): + return self._children \ No newline at end of file diff --git a/TermTk/TTkWidgets/table.py b/TermTk/TTkWidgets/table.py deleted file mode 100644 index 0987fa18..00000000 --- a/TermTk/TTkWidgets/table.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env python3 - -# MIT License -# -# Copyright (c) 2021 Eugenio Parodi -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -from TermTk.TTkCore.cfg import TTkCfg -from TermTk.TTkCore.constant import TTkK -from TermTk.TTkCore.log import TTkLog -from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal -from TermTk.TTkCore.color import TTkColor -from TermTk.TTkWidgets.Fancy.tableview import TTkFancyTableView -from TermTk.TTkLayouts.gridlayout import TTkGridLayout -from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollArea - -class TTkFancyTable(TTkAbstractScrollArea): - __slots__ = ( - '_tableView', 'activated', - # Forwarded Methods - 'setAlignment', 'setHeader', 'setColumnSize', 'setColumnColors', 'appendItem' ) - - - - - def __init__(self, *args, **kwargs): - TTkAbstractScrollArea.__init__(self, *args, **kwargs) - self._name = kwargs.get('name' , 'TTkFancyTable' ) - if 'parent' in kwargs: kwargs.pop('parent') - self._tableView = TTkFancyTableView(*args, **kwargs) - # Forward the signal - self.activated = self._tableView.activated - - self.setFocusPolicy(TTkK.ClickFocus) - self.setViewport(self._tableView) - # Forwarded Methods - self.setAlignment = self._tableView.setAlignment - self.setHeader = self._tableView.setHeader - self.setColumnSize = self._tableView.setColumnSize - self.setColumnColors = self._tableView.setColumnColors - self.appendItem = self._tableView.appendItem - - - - diff --git a/TermTk/TTkWidgets/treeview.py b/TermTk/TTkWidgets/treeview.py deleted file mode 100644 index 3a5d296e..00000000 --- a/TermTk/TTkWidgets/treeview.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env python3 - -# MIT License -# -# Copyright (c) 2021 Eugenio Parodi -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -from TermTk.TTkCore.cfg import TTkCfg -from TermTk.TTkCore.constant import TTkK -from TermTk.TTkCore.log import TTkLog -from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal -from TermTk.TTkCore.color import TTkColor -from TermTk.TTkWidgets.Fancy.tableview import TTkFancyTableView - -class TTkFancyTreeView(TTkFancyTableView): - __slots__ = ( '_header', '_treeView', '_showHeader', 'activated') - - def __init__(self, *args, **kwargs): - super().__init__(self, *args, **kwargs) - self._name = kwargs.get('name' , 'TTkFancyTreeView' ) - # if 'parent' in kwargs: kwargs.pop('parent') - diff --git a/TermTk/TTkWidgets/treewidgetitem.py b/TermTk/TTkWidgets/treewidgetitem.py index a0033998..f69bc5e1 100644 --- a/TermTk/TTkWidgets/treewidgetitem.py +++ b/TermTk/TTkWidgets/treewidgetitem.py @@ -20,4 +20,28 @@ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. \ No newline at end of file +# SOFTWARE. + +from TermTk.TTkCore.cfg import TTkCfg +from TermTk.TTkCore.constant import TTkK +from TermTk.TTkCore.log import TTkLog +from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal + +class TTkTreeWidgetItem(): + __slots__ = ('_parent', '_data', '_children', '_expand', '_childIndicatorPolicy', + # Signals + 'refreshData') + def __init__(self, *args, **kwargs): + self._parent = kwargs.get('parent', None) + + def addChild(self, child): + pass + + def addChildren(self, children): + pass + + def child(self, index): + pass + + def children(self): + pass \ No newline at end of file diff --git a/TermTk/TTkWidgets/widget.py b/TermTk/TTkWidgets/widget.py index 2e846b20..0f005d08 100644 --- a/TermTk/TTkWidgets/widget.py +++ b/TermTk/TTkWidgets/widget.py @@ -48,7 +48,7 @@ class TTkWidget(TMouseEvents,TKeyEvents): │ (x,y)┌─────────────────────────┐ │ │ │ padt (Top Padding) │ │ │ │ ┌───────────────┐ │ height │ - │ │padl│ Layout/childs │padr│ │ + │ │padl│ Layout/child │padr│ │ │ │ └───────────────┘ │ │ │ │ padb (Bottom Pad.) │ │ │ └─────────────────────────┘ │ diff --git a/demo/showcase/tree.py b/demo/showcase/tree.py index 8bc3066b..892de952 100755 --- a/demo/showcase/tree.py +++ b/demo/showcase/tree.py @@ -79,17 +79,17 @@ def demoTree(root=None): l6 = ttk.TTkFancyTreeWidgetItem(["RND", "RND", "RND"], childIndicatorPolicy=ttk.TTkK.ShowIndicator) - def updateChilds(item): - if item.childs(): return + def updateChildren(item): + if item.children(): return for _ in range(0,random.randint(3,8)): child = ttk.TTkFancyTreeWidgetItem([getWord(),getWord(),getWord()]) if random.randint(0,10)>5: child.setChildIndicatorPolicy(ttk.TTkK.ShowIndicator) - child.refreshData.connect(updateChilds) + child.refreshData.connect(updateChildren) item.addChild(child) - l6.refreshData.connect(updateChilds) + l6.refreshData.connect(updateChildren) tw.addTopLevelItem(l1) tw.addTopLevelItem(l2) From 0d8fdc66359a8f2d5a1b9e32c15cabb1931824c7 Mon Sep 17 00:00:00 2001 From: Eugenio Parodi Date: Sun, 5 Dec 2021 23:24:56 +0000 Subject: [PATCH 5/7] Initial drop of the treewidget implementation --- TermTk/TTkWidgets/treewidgetitem.py | 15 +++- ...08.table.py => test.ui.008.fancy.table.py} | 0 tests/test.ui.011.fancy.tree.py | 88 +++++++++++++++++++ tests/test.ui.011.tree.py | 31 +++---- 4 files changed, 112 insertions(+), 22 deletions(-) rename tests/{test.ui.008.table.py => test.ui.008.fancy.table.py} (100%) create mode 100755 tests/test.ui.011.fancy.tree.py diff --git a/TermTk/TTkWidgets/treewidgetitem.py b/TermTk/TTkWidgets/treewidgetitem.py index f69bc5e1..1cc3925c 100644 --- a/TermTk/TTkWidgets/treewidgetitem.py +++ b/TermTk/TTkWidgets/treewidgetitem.py @@ -31,17 +31,24 @@ class TTkTreeWidgetItem(): __slots__ = ('_parent', '_data', '_children', '_expand', '_childIndicatorPolicy', # Signals 'refreshData') + def __init__(self, *args, **kwargs): + self._children = [] + self._data = args[0] if len(args)>0 and type(args[0])==list else None self._parent = kwargs.get('parent', None) def addChild(self, child): - pass + self._children.append(child) + child._parent = self def addChildren(self, children): - pass + for child in children: + self.addChild(child) def child(self, index): - pass + if 0 <= index < len(self._children): + return self._children[index] + return None def children(self): - pass \ No newline at end of file + return self._children \ No newline at end of file diff --git a/tests/test.ui.008.table.py b/tests/test.ui.008.fancy.table.py similarity index 100% rename from tests/test.ui.008.table.py rename to tests/test.ui.008.fancy.table.py diff --git a/tests/test.ui.011.fancy.tree.py b/tests/test.ui.011.fancy.tree.py new file mode 100755 index 00000000..11e8cd29 --- /dev/null +++ b/tests/test.ui.011.fancy.tree.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 + +# MIT License +# +# Copyright (c) 2021 Eugenio Parodi +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# Demo inspired from: +# https://stackoverflow.com/questions/41204234/python-pyqt5-qtreewidget-sub-item + +import os +import sys + +sys.path.append(os.path.join(sys.path[0],'..')) +import TermTk as ttk + +ttk.TTkLog.use_default_file_logging() + +fullscreen = False + +root = ttk.TTk() +if fullscreen: + rootTree1 = root + root.setLayout(ttk.TTkGridLayout()) +else: + rootTree1 = ttk.TTkWindow(parent=root,pos = (0,0), size=(150,50), title="Test Tree 1", layout=ttk.TTkGridLayout(), border=True) + +# tw = ttk.TTkFancyTreeWidget(parent=rootTree1) +tw = ttk.TTkFancyTree(parent=rootTree1) +tw.setHeaderLabels(["Column 1", "Column 2", "Column 3"]) +tw.setColumnSize((20,20,-1)) +tw.setColumnColors(( + ttk.TTkColor.RST, + ttk.TTkColor.fg('#00dddd', modifier=ttk.TTkColorGradient(increment=-4)), + ttk.TTkColor.fg('#cccc00', modifier=ttk.TTkColorGradient(increment=-2)) + )) +l1 = ttk.TTkFancyTreeWidgetItem(["String A", "String B", "String C"]) +l2 = ttk.TTkFancyTreeWidgetItem(["String AA", "String BB", "String CC"]) +l3 = ttk.TTkFancyTreeWidgetItem(["String AAA", "String BBB", "String CCC"]) +l4 = ttk.TTkFancyTreeWidgetItem(["String AAAA", "String BBBB", "String CCCC"]) +l5 = ttk.TTkFancyTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) +l2.addChild(l5) + + +for i in range(3): + l1_child = ttk.TTkFancyTreeWidgetItem(["Child A" + str(i), "Child B" + str(i), "Child C" + str(i)]) + l1.addChild(l1_child) + +for j in range(2): + l2_child = ttk.TTkFancyTreeWidgetItem(["Child AA" + str(j), "Child BB" + str(j), "Child CC" + str(j)]) + l2.addChild(l2_child) + +for j in range(2): + l3_child = ttk.TTkFancyTreeWidgetItem(["Child AAA" + str(j), "Child BBB" + str(j), "Child CCC" + str(j)]) + l3.addChild(l3_child) + +for j in range(2): + l4_child = ttk.TTkFancyTreeWidgetItem(["Child AAAA" + str(j), "Child BBBB" + str(j), "Child CCCC" + str(j)]) + l4.addChild(l4_child) + +for j in range(2): + l5_child = ttk.TTkFancyTreeWidgetItem(["Child AAAAA" + str(j), "Child BBBBB" + str(j), "Child CCCCC" + str(j)]) + l5.addChild(l5_child) + + +tw.addTopLevelItem(l1) +tw.addTopLevelItem(l2) +tw.addTopLevelItem(l3) +tw.addTopLevelItem(l4) + +root.mainloop() \ No newline at end of file diff --git a/tests/test.ui.011.tree.py b/tests/test.ui.011.tree.py index 11e8cd29..18eae735 100755 --- a/tests/test.ui.011.tree.py +++ b/tests/test.ui.011.tree.py @@ -42,41 +42,36 @@ if fullscreen: else: rootTree1 = ttk.TTkWindow(parent=root,pos = (0,0), size=(150,50), title="Test Tree 1", layout=ttk.TTkGridLayout(), border=True) -# tw = ttk.TTkFancyTreeWidget(parent=rootTree1) -tw = ttk.TTkFancyTree(parent=rootTree1) +# tw = ttk.TTkTreeWidget(parent=rootTree1) +tw = ttk.TTkTree(parent=rootTree1) tw.setHeaderLabels(["Column 1", "Column 2", "Column 3"]) -tw.setColumnSize((20,20,-1)) -tw.setColumnColors(( - ttk.TTkColor.RST, - ttk.TTkColor.fg('#00dddd', modifier=ttk.TTkColorGradient(increment=-4)), - ttk.TTkColor.fg('#cccc00', modifier=ttk.TTkColorGradient(increment=-2)) - )) -l1 = ttk.TTkFancyTreeWidgetItem(["String A", "String B", "String C"]) -l2 = ttk.TTkFancyTreeWidgetItem(["String AA", "String BB", "String CC"]) -l3 = ttk.TTkFancyTreeWidgetItem(["String AAA", "String BBB", "String CCC"]) -l4 = ttk.TTkFancyTreeWidgetItem(["String AAAA", "String BBBB", "String CCCC"]) -l5 = ttk.TTkFancyTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) + +l1 = ttk.TTkTreeWidgetItem(["String A", "String B", "String C"]) +l2 = ttk.TTkTreeWidgetItem(["String AA", "String BB", "String CC"]) +l3 = ttk.TTkTreeWidgetItem(["String AAA", "String BBB", "String CCC"]) +l4 = ttk.TTkTreeWidgetItem(["String AAAA", "String BBBB", "String CCCC"]) +l5 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) l2.addChild(l5) for i in range(3): - l1_child = ttk.TTkFancyTreeWidgetItem(["Child A" + str(i), "Child B" + str(i), "Child C" + str(i)]) + l1_child = ttk.TTkTreeWidgetItem(["Child A" + str(i), "Child B" + str(i), "Child C" + str(i)]) l1.addChild(l1_child) for j in range(2): - l2_child = ttk.TTkFancyTreeWidgetItem(["Child AA" + str(j), "Child BB" + str(j), "Child CC" + str(j)]) + l2_child = ttk.TTkTreeWidgetItem(["Child AA" + str(j), "Child BB" + str(j), "Child CC" + str(j)]) l2.addChild(l2_child) for j in range(2): - l3_child = ttk.TTkFancyTreeWidgetItem(["Child AAA" + str(j), "Child BBB" + str(j), "Child CCC" + str(j)]) + l3_child = ttk.TTkTreeWidgetItem(["Child AAA" + str(j), "Child BBB" + str(j), "Child CCC" + str(j)]) l3.addChild(l3_child) for j in range(2): - l4_child = ttk.TTkFancyTreeWidgetItem(["Child AAAA" + str(j), "Child BBBB" + str(j), "Child CCCC" + str(j)]) + l4_child = ttk.TTkTreeWidgetItem(["Child AAAA" + str(j), "Child BBBB" + str(j), "Child CCCC" + str(j)]) l4.addChild(l4_child) for j in range(2): - l5_child = ttk.TTkFancyTreeWidgetItem(["Child AAAAA" + str(j), "Child BBBBB" + str(j), "Child CCCCC" + str(j)]) + l5_child = ttk.TTkTreeWidgetItem(["Child AAAAA" + str(j), "Child BBBBB" + str(j), "Child CCCCC" + str(j)]) l5.addChild(l5_child) From f94e89d215bbe0a2e5f3ff54222035ee5dea872c Mon Sep 17 00:00:00 2001 From: Eugenio Parodi Date: Sun, 2 Jan 2022 00:28:17 +0000 Subject: [PATCH 6/7] SuperBasic [proper] tree implementation --- TermTk/TTkAbstract/abstractitemmodel.py | 8 +- TermTk/TTkWidgets/__init__.py | 51 +++++----- TermTk/TTkWidgets/tree.py | 57 +++++++++++ TermTk/TTkWidgets/treewidget.py | 128 +++++++++++++++++++++++- TermTk/TTkWidgets/treewidgetitem.py | 44 +++++++- docs/MDNotes/TODO.md | 8 +- tests/test.ui.011.tree.py | 12 ++- 7 files changed, 274 insertions(+), 34 deletions(-) create mode 100644 TermTk/TTkWidgets/tree.py diff --git a/TermTk/TTkAbstract/abstractitemmodel.py b/TermTk/TTkAbstract/abstractitemmodel.py index 550d84eb..402e7d5d 100644 --- a/TermTk/TTkAbstract/abstractitemmodel.py +++ b/TermTk/TTkAbstract/abstractitemmodel.py @@ -22,6 +22,12 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal + class TTkAbstractItemModel(): + __slots__ = ( + # Signals + 'dataChanged' + ) def __init__(self, *args, **kwargs): - pass \ No newline at end of file + self.dataChanged = pyTTkSignal() diff --git a/TermTk/TTkWidgets/__init__.py b/TermTk/TTkWidgets/__init__.py index ba51473f..48f7e891 100644 --- a/TermTk/TTkWidgets/__init__.py +++ b/TermTk/TTkWidgets/__init__.py @@ -1,25 +1,28 @@ -from .widget import * -from .spacer import * -from .frame import * +from .widget import * +from .spacer import * +from .frame import * from .resizableframe import * -from .splitter import * -from .label import * -from .button import * -from .checkbox import * -from .radiobutton import * -from .combobox import * -from .lineedit import * -from .texedit import * -from .scrollbar import * -from .scrollarea import * -from .window import * -from .tabwidget import * -from .list_ import * -from .listwidget import * -from .graph import * -from .menubar import * -from .TTkPickers import * -from .spinbox import * -from .image import TTkImage -from .about import TTkAbout -from .Fancy import * +from .splitter import * +from .label import * +from .button import * +from .checkbox import * +from .radiobutton import * +from .combobox import * +from .lineedit import * +from .texedit import * +from .scrollbar import * +from .scrollarea import * +from .window import * +from .tabwidget import * +from .list_ import * +from .listwidget import * +from .graph import * +from .menubar import * +from .TTkPickers import * +from .spinbox import * +from .image import TTkImage +from .about import TTkAbout +from .tree import TTkTree +from .treewidget import TTkTreeWidget +from .treewidgetitem import TTkTreeWidgetItem +from .Fancy import * diff --git a/TermTk/TTkWidgets/tree.py b/TermTk/TTkWidgets/tree.py new file mode 100644 index 00000000..b0c39704 --- /dev/null +++ b/TermTk/TTkWidgets/tree.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 + +# MIT License +# +# Copyright (c) 2021 Eugenio Parodi +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from TermTk.TTkCore.constant import TTkK +from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal +from TermTk.TTkWidgets.treewidget import TTkTreeWidget +from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollArea + +class TTkTree(TTkAbstractScrollArea): + __slots__ = ( + '_treeView', 'activated', + # Forwarded Methods + 'setAlignment', 'setHeader', 'setHeaderLabels', 'setColumnSize', 'setColumnColors', 'appendItem', 'addTopLevelItem' ) + + def __init__(self, *args, **kwargs): + TTkAbstractScrollArea.__init__(self, *args, **kwargs) + self._name = kwargs.get('name' , 'TTkTree' ) + if 'parent' in kwargs: kwargs.pop('parent') + self._treeView = TTkTreeWidget(*args, **kwargs) + # Forward the signal + # self.activated = self._treeView.activated + + self.setFocusPolicy(TTkK.ClickFocus) + self.setViewport(self._treeView) + + # Forwarded Methods + #self.setAlignment = self._treeView.setAlignment + #self.setHeader = self._treeView.setHeader + self.setHeaderLabels = self._treeView.setHeaderLabels + #self.setColumnSize = self._treeView.setColumnSize + #self.setColumnColors = self._treeView.setColumnColors + #self.appendItem = self._treeView.appendItem + self.addTopLevelItem = self._treeView.addTopLevelItem + + + diff --git a/TermTk/TTkWidgets/treewidget.py b/TermTk/TTkWidgets/treewidget.py index a0033998..d0631c7c 100644 --- a/TermTk/TTkWidgets/treewidget.py +++ b/TermTk/TTkWidgets/treewidget.py @@ -20,4 +20,130 @@ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. \ No newline at end of file +# SOFTWARE. + +from TermTk.TTkCore.log import TTkLog +from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollView +from TermTk.TTkCore.signal import pyTTkSlot + +class TTkTreeWidget(TTkAbstractScrollView): + __slots__ = ( '_items', '_header', '_columnsPos', '_cache', '_selected') + + def __init__(self, *args, **kwargs): + super().__init__(self, *args, **kwargs) + self._name = kwargs.get('name' , 'TTkTreeView' ) + self._selected = -1 + self._items = [] + self._header = kwargs.get('header',[]) + self._columnsPos = [] + self._cache = [] + self.setMinimumHeight(1) + + # Overridden function + def viewFullAreaSize(self) -> (int, int): + w = self._columnsPos[-1] if self._columnsPos else 0 + h = 1+sum([c.size() for c in self._items]) + # TTkLog.debug(f"{w=} {h=}") + return w,h + + # Overridden function + def viewDisplayedSize(self) -> (int, int): + # TTkLog.debug(f"{self.size()=}") + return self.size() + + def addTopLevelItem(self, item): + item.dataChanged.connect(self._refreshCache) + self._items.append(item) + self._refreshCache() + self.viewChanged.emit() + self.update() + + def setHeaderLabels(self, labels): + self._header = labels + # Set 20 as default column size + self._columnsPos = [20+x*20 for x in range(len(labels))] + self.viewChanged.emit() + self.update() + + def mouseDoubleClickEvent(self, evt): + _,y = evt.x, evt.y + _, oy = self.getViewOffsets() + y -= 1-oy + if 0 <= y < len(self._cache): + item = self._cache[y][0] + item.setExpanded(not item.isExpanded()) + self._selected = y + self.update() + return True + + def mousePressEvent(self, evt): + x,y = evt.x, evt.y + ox, oy = self.getViewOffsets() + y += oy-1 + x += ox + if 0 <= y < len(self._cache): + item = self._cache[y][0] + level = self._cache[y][1] + if level*2 <= x < level*2+3: + item.setExpanded(not item.isExpanded()) + else: + self._selected = y + self.update() + return True + + @pyTTkSlot() + def _refreshCache(self): + ''' I save a representation fo the displayed tree in a cache array + to avoid eccessve recursion over the items and + identify quickly the nth displayed line to improve the interaction + + _cache is an array of: + [ item, level, txtCol1, txtCol2, txtCol3, ... ] + ''' + self._cache = [] + def _addToCache(_child, _level): + _entry = [_child, _level] + for _il in range(len(self._header)): + _entry.append(_child.data(_il)) + self._cache.append(_entry) + if _child.isExpanded(): + for _c in _child.children(): + _addToCache(_c, _level+1) + for c in self._items: + _addToCache(c,0) + self.update() + + def paintEvent(self): + x,y = self.getViewOffsets() + w,h = self.size() + + # Draw header first: + for i,l in enumerate(self._header): + hx = 0 if i==0 else self._columnsPos[i-1]+1 + self._canvas.drawText(pos=(hx-x,0), text=l) + # Draw header separators + for sx in self._columnsPos: + self._canvas.drawText(pos=(sx-x,0), text='|') + + # Draw cache + for i, l in enumerate(self._cache): + if i-y<0 : continue + item = l[0] + level = l[1] + l1 = l[2] + if not item.children(): + l1 = ' '*level + " • " + l1 + elif item.isExpanded(): + l1 = ' '*level + " ▼ " + l1 + else: + l1 = ' '*level + " ▶ " + l1 + + self._canvas.drawText(pos=(-x,i-y+1), text=l1) + for il in range(1,len(self._header)): + lx = self._columnsPos[il-1]+1 + self._canvas.drawText(pos=(lx-x,i-y+1), text=l[2+il]) + + + + + diff --git a/TermTk/TTkWidgets/treewidgetitem.py b/TermTk/TTkWidgets/treewidgetitem.py index 1cc3925c..85f262f8 100644 --- a/TermTk/TTkWidgets/treewidgetitem.py +++ b/TermTk/TTkWidgets/treewidgetitem.py @@ -26,20 +26,30 @@ from TermTk.TTkCore.cfg import TTkCfg from TermTk.TTkCore.constant import TTkK from TermTk.TTkCore.log import TTkLog from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal +from TermTk.TTkAbstract.abstractitemmodel import TTkAbstractItemModel -class TTkTreeWidgetItem(): - __slots__ = ('_parent', '_data', '_children', '_expand', '_childIndicatorPolicy', + +class TTkTreeWidgetItem(TTkAbstractItemModel): + __slots__ = ('_parent', '_data', '_children', '_expanded', '_childIndicatorPolicy', # Signals 'refreshData') def __init__(self, *args, **kwargs): + # Signals + self.refreshData = pyTTkSignal(TTkTreeWidgetItem) + super().__init__(self, *args, **kwargs) self._children = [] self._data = args[0] if len(args)>0 and type(args[0])==list else None self._parent = kwargs.get('parent', None) + self._childIndicatorPolicy = kwargs.get('childIndicatorPolicy', TTkK.DontShowIndicatorWhenChildless) + self._expanded = False + self._parent = kwargs.get("parent", None) def addChild(self, child): self._children.append(child) child._parent = self + child.dataChanged.connect(self.emitDataChanged) + self.dataChanged.emit() def addChildren(self, children): for child in children: @@ -51,4 +61,32 @@ class TTkTreeWidgetItem(): return None def children(self): - return self._children \ No newline at end of file + return self._children + + def data(self, column, role=None): + if column >= len(self._data): + return None + return self._data[column] + + @pyTTkSlot() + def emitDataChanged(self): + self.dataChanged.emit() + + # def setDisabled(disabled): + # pass + + def setExpanded(self, expand): + self._expanded = expand + self.emitDataChanged() + + # def isDisabled(): + # pass + + def isExpanded(self): + return self._expanded + + def size(self): + if self._expanded: + return 1 + sum([c.size() for c in self._children]) + else: + return 1 diff --git a/docs/MDNotes/TODO.md b/docs/MDNotes/TODO.md index 2cee2620..c4081684 100644 --- a/docs/MDNotes/TODO.md +++ b/docs/MDNotes/TODO.md @@ -93,10 +93,16 @@ - [ ] Basic Implementation - [ ] Events (Signal/Slots) - [x] Themes - #### Table Widget + #### Fancy Table Widget - [x] Basic Implementation - [ ] Events (Signal/Slots) - [ ] Themes + + #### Tree Widget + - [x] Basic Implementation + - [ ] Implement cache/pagination for big data + - [ ] Events (Signal/Slots) + - [ ] Themes #### Window Widget - [x] Basic Implementation - [ ] Events (Signal/Slots) diff --git a/tests/test.ui.011.tree.py b/tests/test.ui.011.tree.py index 18eae735..338cc4ed 100755 --- a/tests/test.ui.011.tree.py +++ b/tests/test.ui.011.tree.py @@ -27,22 +27,24 @@ import os import sys +import argparse sys.path.append(os.path.join(sys.path[0],'..')) import TermTk as ttk ttk.TTkLog.use_default_file_logging() -fullscreen = False +parser = argparse.ArgumentParser() +parser.add_argument('-f', help='Full Screen', action='store_true') +args = parser.parse_args() root = ttk.TTk() -if fullscreen: +if args.f: rootTree1 = root root.setLayout(ttk.TTkGridLayout()) else: - rootTree1 = ttk.TTkWindow(parent=root,pos = (0,0), size=(150,50), title="Test Tree 1", layout=ttk.TTkGridLayout(), border=True) + rootTree1 = ttk.TTkWindow(parent=root,pos = (0,0), size=(150,40), title="Test Tree 1", layout=ttk.TTkGridLayout(), border=True) -# tw = ttk.TTkTreeWidget(parent=rootTree1) tw = ttk.TTkTree(parent=rootTree1) tw.setHeaderLabels(["Column 1", "Column 2", "Column 3"]) @@ -79,5 +81,7 @@ tw.addTopLevelItem(l1) tw.addTopLevelItem(l2) tw.addTopLevelItem(l3) tw.addTopLevelItem(l4) +l1.setExpanded(True) +l3.setExpanded(True) root.mainloop() \ No newline at end of file From 659fefd2eceeae6df4ffdbb04e64b3a11d7033e6 Mon Sep 17 00:00:00 2001 From: Eugenio Parodi Date: Sun, 2 Jan 2022 15:56:33 +0000 Subject: [PATCH 7/7] Initial feature incomplete tree widget --- TermTk/TTkGui/theme.py | 9 +- TermTk/TTkWidgets/splitter.py | 6 +- TermTk/TTkWidgets/treewidget.py | 150 ++++++++++++++++------ TermTk/TTkWidgets/treewidgetitem.py | 10 +- demo/demo.py | 10 +- demo/showcase/{table.py => fancytable.py} | 4 +- demo/showcase/fancytree.py | 119 +++++++++++++++++ demo/showcase/tree.py | 34 ++--- 8 files changed, 273 insertions(+), 69 deletions(-) rename demo/showcase/{table.py => fancytable.py} (98%) create mode 100755 demo/showcase/fancytree.py diff --git a/TermTk/TTkGui/theme.py b/TermTk/TTkGui/theme.py index a6aa24ab..648daaca 100644 --- a/TermTk/TTkGui/theme.py +++ b/TermTk/TTkGui/theme.py @@ -115,8 +115,6 @@ class TTkTheme(): └ ─ ┴ ┘ ''' - - buttonBox = ( ('┌','─','┐', '│',' ','│', @@ -136,6 +134,10 @@ class TTkTheme(): hscroll = ('◀','┄','▓','▶') vscroll = ('▲','┊','▓','▼') + tree = ('•','▶','▼',' ', + '│','╿') + + # 0 1 2 3 4 5 menuBar = ('├','─','┤','┄','┄','▶') @@ -268,3 +270,6 @@ class TTkTheme(): tabOffsetColorFocus = tabOffsetColor tabBorderColorFocus = TTkColor.fg("#ffff88") tabSelectColorFocus = TTkColor.fg("#ffff88")+TTkColor.bg("#000066")+TTkColor.BOLD + + treeHeaderColor = TTkColor.fg("#ffffff")+TTkColor.bg("#444444")+TTkColor.BOLD + treeSelectedColor = TTkColor.fg("#ffff88")+TTkColor.bg("#000066")+TTkColor.BOLD \ No newline at end of file diff --git a/TermTk/TTkWidgets/splitter.py b/TermTk/TTkWidgets/splitter.py index b5182b28..6c20f0cc 100644 --- a/TermTk/TTkWidgets/splitter.py +++ b/TermTk/TTkWidgets/splitter.py @@ -32,7 +32,7 @@ class TTkSplitter(TTkFrame): __slots__ = ( '_splitterInitialized', '_orientation', '_separators', '_separatorsRef', '_sizeRef', '_initSizes', - '_separatorSelected', '_mouseDelta') + '_separatorSelected') def __init__(self, *args, **kwargs): self._splitterInitialized = False # self._splitterInitialized = True @@ -194,11 +194,9 @@ class TTkSplitter(TTkFrame): def mousePressEvent(self, evt): self._separatorSelected = None - self._mouseDelta = (evt.x, evt.y) x,y = evt.x, evt.y # TTkLog.debug(f"{self._separators} {evt}") - for i in range(len(self._separators)): - val = self._separators[i] + for i, val in enumerate(self._separators): if self._orientation == TTkK.HORIZONTAL: if x == val: self._separatorSelected = i diff --git a/TermTk/TTkWidgets/treewidget.py b/TermTk/TTkWidgets/treewidget.py index d0631c7c..218f24bd 100644 --- a/TermTk/TTkWidgets/treewidget.py +++ b/TermTk/TTkWidgets/treewidget.py @@ -22,22 +22,40 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from TermTk.TTkCore.cfg import TTkCfg +from TermTk.TTkCore.color import TTkColor +from TermTk.TTkCore.constant import TTkK from TermTk.TTkCore.log import TTkLog +from TermTk.TTkWidgets.treewidgetitem import TTkTreeWidgetItem from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollView from TermTk.TTkCore.signal import pyTTkSlot +from dataclasses import dataclass + class TTkTreeWidget(TTkAbstractScrollView): - __slots__ = ( '_items', '_header', '_columnsPos', '_cache', '_selected') + __slots__ = ( '_items', '_header', '_columnsPos', '_cache', + '_selectedId', '_selected', '_separatorSelected', '_mouseDelta', + '_headerColor', '_selectedColor') + @dataclass(frozen=True) + class _Cache: + item: TTkTreeWidgetItem + level: int + data: list def __init__(self, *args, **kwargs): super().__init__(self, *args, **kwargs) self._name = kwargs.get('name' , 'TTkTreeView' ) - self._selected = -1 + self._selected = None + self._selectedId = None + self._separatorSelected = None self._items = [] self._header = kwargs.get('header',[]) self._columnsPos = [] self._cache = [] + self._headerColor = kwargs.get('headerColor',TTkCfg.theme.treeHeaderColor) + self._selectedColor = kwargs.get('selectedColor',TTkCfg.theme.treeSelectedColor) self.setMinimumHeight(1) + self.setFocusPolicy(TTkK.ClickFocus) # Overridden function def viewFullAreaSize(self) -> (int, int): @@ -70,80 +88,140 @@ class TTkTreeWidget(TTkAbstractScrollView): _, oy = self.getViewOffsets() y -= 1-oy if 0 <= y < len(self._cache): - item = self._cache[y][0] + item = self._cache[y].item item.setExpanded(not item.isExpanded()) - self._selected = y + if self._selected: + self._selected.setSelected(False) + self._selectedId = y + self._selected = item + self._selected.setSelected(True) + self.update() return True + def focusOutEvent(self): + self._separatorSelected = None + def mousePressEvent(self, evt): x,y = evt.x, evt.y ox, oy = self.getViewOffsets() - y += oy-1 + x += ox + + self._separatorSelected = None + self._mouseDelta = (evt.x, evt.y) + + # Handle Header Events + if y == 0: + for i, c in enumerate(self._columnsPos): + if x == c: + self._separatorSelected = i + self.update() + return True + # Handle Tree/Table Events + y += oy-1 if 0 <= y < len(self._cache): - item = self._cache[y][0] - level = self._cache[y][1] + item = self._cache[y].item + level = self._cache[y].level if level*2 <= x < level*2+3: item.setExpanded(not item.isExpanded()) else: - self._selected = y + if self._selected: + self._selected.setSelected(False) + self._selectedId = y + self._selected = item + self._selected.setSelected(True) self.update() return True + def mouseDragEvent(self, evt): + ''' + :: + + columnPos (Selected = 2) + 0 1 2 3 4 + ----|-------|--------|----------|---| + Mouse (Drag) Pos + ^ + I consider at least 4 char (3+1) as spacing + Min Selected Pos = (Selected+1) * 4 + + ''' + if self._separatorSelected is not None: + x,y = evt.x, evt.y + ox, oy = self.getViewOffsets() + y += oy + x += ox + ss = self._separatorSelected + pos = max((ss+1)*4, x) + self._columnsPos[ss] = pos + # Align the previous Separators if pushed + for i in range(ss): + self._columnsPos[i] = min(self._columnsPos[i], pos-(ss-i)*4) + # Align the next Separators if pushed + for i in range(ss, len(self._columnsPos)): + self._columnsPos[i] = max(self._columnsPos[i], pos+(i-ss)*4) + self.update() + self.viewChanged.emit() + return True + return False + @pyTTkSlot() def _refreshCache(self): ''' I save a representation fo the displayed tree in a cache array to avoid eccessve recursion over the items and identify quickly the nth displayed line to improve the interaction - _cache is an array of: - [ item, level, txtCol1, txtCol2, txtCol3, ... ] + _cache is an array of TTkTreeWidget._Cache: + [ item, level, data=[txtCol1, txtCol2, txtCol3, ... ]] ''' self._cache = [] def _addToCache(_child, _level): - _entry = [_child, _level] + tt = TTkCfg.theme.tree + _data = [] for _il in range(len(self._header)): - _entry.append(_child.data(_il)) - self._cache.append(_entry) + _data.append(_child.data(_il)) + if not _child.children(): + _data[0] = f"{' '*_level} {tt[0]} {_data[0]}" + elif _child.isExpanded(): + _data[0] = f"{' '*_level} {tt[2]} {_data[0]}" + else: + _data[0] = f"{' '*_level} {tt[1]} {_data[0]}" + self._cache.append(TTkTreeWidget._Cache( + item = _child, + level = _level, + data = _data)) if _child.isExpanded(): for _c in _child.children(): _addToCache(_c, _level+1) for c in self._items: _addToCache(c,0) self.update() + self.viewChanged.emit() def paintEvent(self): x,y = self.getViewOffsets() w,h = self.size() + tt = TTkCfg.theme.tree # Draw header first: for i,l in enumerate(self._header): - hx = 0 if i==0 else self._columnsPos[i-1]+1 - self._canvas.drawText(pos=(hx-x,0), text=l) + hx = 0 if i==0 else self._columnsPos[i-1]+1 + hx1 = self._columnsPos[i] + self._canvas.drawText(pos=(hx-x,0), text=l, width=hx1-hx, color=self._headerColor) # Draw header separators for sx in self._columnsPos: - self._canvas.drawText(pos=(sx-x,0), text='|') + self._canvas.drawChar(pos=(sx-x,0), char=tt[5], color=self._headerColor) + for sy in range(1,h): + self._canvas.drawChar(pos=(sx-x,sy), char=tt[4]) # Draw cache - for i, l in enumerate(self._cache): + for i, c in enumerate(self._cache): if i-y<0 : continue - item = l[0] - level = l[1] - l1 = l[2] - if not item.children(): - l1 = ' '*level + " • " + l1 - elif item.isExpanded(): - l1 = ' '*level + " ▼ " + l1 - else: - l1 = ' '*level + " ▶ " + l1 - - self._canvas.drawText(pos=(-x,i-y+1), text=l1) - for il in range(1,len(self._header)): - lx = self._columnsPos[il-1]+1 - self._canvas.drawText(pos=(lx-x,i-y+1), text=l[2+il]) - - - - - + item = c.item + level = c.level + color = self._selectedColor if item.isSelected() else TTkColor.RST + for il in range(len(self._header)): + lx = 0 if il==0 else self._columnsPos[il-1]+1 + lx1 = self._columnsPos[il] + self._canvas.drawText(pos=(lx-x,i-y+1), text=c.data[il], width=lx1-lx, color=color) diff --git a/TermTk/TTkWidgets/treewidgetitem.py b/TermTk/TTkWidgets/treewidgetitem.py index 85f262f8..357b3a99 100644 --- a/TermTk/TTkWidgets/treewidgetitem.py +++ b/TermTk/TTkWidgets/treewidgetitem.py @@ -30,7 +30,8 @@ from TermTk.TTkAbstract.abstractitemmodel import TTkAbstractItemModel class TTkTreeWidgetItem(TTkAbstractItemModel): - __slots__ = ('_parent', '_data', '_children', '_expanded', '_childIndicatorPolicy', + __slots__ = ('_parent', '_data', '_children', '_expanded', '_selected', + '_childIndicatorPolicy', # Signals 'refreshData') @@ -43,6 +44,7 @@ class TTkTreeWidgetItem(TTkAbstractItemModel): self._parent = kwargs.get('parent', None) self._childIndicatorPolicy = kwargs.get('childIndicatorPolicy', TTkK.DontShowIndicatorWhenChildless) self._expanded = False + self._selected = False self._parent = kwargs.get("parent", None) def addChild(self, child): @@ -79,12 +81,18 @@ class TTkTreeWidgetItem(TTkAbstractItemModel): self._expanded = expand self.emitDataChanged() + def setSelected(self, select): + self._selected = select + # def isDisabled(): # pass def isExpanded(self): return self._expanded + def isSelected(self): + return self._selected + def size(self): if self._expanded: return 1 + sum([c.size() for c in self._children]) diff --git a/demo/demo.py b/demo/demo.py index 3eb048b7..9199cb36 100755 --- a/demo/demo.py +++ b/demo/demo.py @@ -32,9 +32,7 @@ import TermTk as ttk from showcase.layout_basic import demoLayout from showcase.layout_nested import demoLayoutNested from showcase.layout_span import demoLayoutSpan -from showcase.table import demoTable from showcase.tab import demoTab -from showcase.tree import demoTree from showcase.graph import demoGraph from showcase.splitter import demoSplitter from showcase.windows import demoWindows @@ -43,6 +41,9 @@ from showcase.scrollarea import demoScrollArea from showcase.list import demoList from showcase.menubar import demoMenuBar from showcase.colorpicker import demoColorPicker +from showcase.tree import demoTree +from showcase.fancytable import demoFancyTable +from showcase.fancytree import demoFancyTree words = ["Lorem", "ipsum", "dolor", "sit", "amet,", "consectetur", "adipiscing", "elit,", "sed", "do", "eiusmod", "tempor", "incididunt", "ut", "labore", "et", "dolore", "magna", "aliqua.", "Ut", "enim", "ad", "minim", "veniam,", "quis", "nostrud", "exercitation", "ullamco", "laboris", "nisi", "ut", "aliquip", "ex", "ea", "commodo", "consequat.", "Duis", "aute", "irure", "dolor", "in", "reprehenderit", "in", "voluptate", "velit", "esse", "cillum", "dolore", "eu", "fugiat", "nulla", "pariatur.", "Excepteur", "sint", "occaecat", "cupidatat", "non", "proident,", "sunt", "in", "culpa", "qui", "officia", "deserunt", "mollit", "anim", "id", "est", "laborum."] def getWord(): @@ -78,9 +79,10 @@ def demoShowcase(root=None, border=True): tabWidgets = ttk.TTkTabWidget(parent=mainFrame, border=False, visible=False) tabWidgets.addTab(demoFormWidgets(), " Form Test ") tabWidgets.addTab(demoList(), " List Test ") - tabWidgets.addTab(demoTable(), " Table Test ") - tabWidgets.addTab(demoTree(), " Tree Test ") + tabWidgets.addTab(demoTree(), " Tree Test") tabWidgets.addTab(demoTab(), " Tab Test ") + tabWidgets.addTab(demoFancyTable(), " Old Table ") + tabWidgets.addTab(demoFancyTree(), " Old Tree ") listMenu.addItem(f"Pickers") tabPickers = ttk.TTkTabWidget(parent=mainFrame, border=False, visible=False) diff --git a/demo/showcase/table.py b/demo/showcase/fancytable.py similarity index 98% rename from demo/showcase/table.py rename to demo/showcase/fancytable.py index 171ffe1d..a3a52195 100755 --- a/demo/showcase/table.py +++ b/demo/showcase/fancytable.py @@ -36,7 +36,7 @@ def getSentence(a,b): table_ii = 1000 -def demoTable(root=None): +def demoFancyTable(root=None): frame = ttk.TTkFrame(parent=root, border=False, layout=ttk.TTkVBoxLayout()) top = ttk.TTkFrame(parent=frame, border=False, layout=ttk.TTkHBoxLayout()) btn1 = ttk.TTkButton(parent=top, maxHeight=3, border=True, text='Add') @@ -88,7 +88,7 @@ def main(): root = ttk.TTk() win_table = ttk.TTkWindow(parent=root,pos = (3,3), size=(150,40), title="Test Table 1", layout=ttk.TTkHBoxLayout(), border=True) - demoTable(win_table) + demoFancyTable(win_table) root.mainloop() if __name__ == "__main__": diff --git a/demo/showcase/fancytree.py b/demo/showcase/fancytree.py new file mode 100755 index 00000000..1517e3f5 --- /dev/null +++ b/demo/showcase/fancytree.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python3 + +# MIT License +# +# Copyright (c) 2021 Eugenio Parodi +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# Demo inspired from: +# https://stackoverflow.com/questions/41204234/python-pyqt5-qtreewidget-sub-item + +import os +import sys +import random +import argparse + +sys.path.append(os.path.join(sys.path[0],'../..')) +import TermTk as ttk + +words = ["Lorem", "ipsum", "dolor", "sit", "amet,", "consectetur", "adipiscing", "elit,", "sed", "do", "eiusmod", "tempor", "incididunt", "ut", "labore", "et", "dolore", "magna", "aliqua.", "Ut", "enim", "ad", "minim", "veniam,", "quis", "nostrud", "exercitation", "ullamco", "laboris", "nisi", "ut", "aliquip", "ex", "ea", "commodo", "consequat.", "Duis", "aute", "irure", "dolor", "in", "reprehenderit", "in", "voluptate", "velit", "esse", "cillum", "dolore", "eu", "fugiat", "nulla", "pariatur.", "Excepteur", "sint", "occaecat", "cupidatat", "non", "proident,", "sunt", "in", "culpa", "qui", "officia", "deserunt", "mollit", "anim", "id", "est", "laborum."] +def getWord(): + return random.choice(words) +def getSentence(a,b): + return " ".join([getWord() for i in range(0,random.randint(a,b))]) + +def demoFancyTree(root=None): + # tw = ttk.TTkFancyTreeWidget(parent=rootTree1) + tw = ttk.TTkFancyTree(parent=root) + tw.setHeaderLabels(["Column 1", "Column 2", "Column 3"]) + tw.setColumnSize((-1,20,20)) + tw.setColumnColors(( + ttk.TTkColor.RST, + ttk.TTkColor.fg('#00dddd', modifier=ttk.TTkColorGradient(increment=-4)), + ttk.TTkColor.fg('#cccc00', modifier=ttk.TTkColorGradient(increment=-2)) + )) + l1 = ttk.TTkFancyTreeWidgetItem(["String A", "String B", "String C"]) + l2 = ttk.TTkFancyTreeWidgetItem(["String AA", "String BB", "String CC"]) + l3 = ttk.TTkFancyTreeWidgetItem(["String AAA", "String BBB", "String CCC"]) + l4 = ttk.TTkFancyTreeWidgetItem(["String AAAA", "String BBBB", "String CCCC"]) + l5 = ttk.TTkFancyTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) + + l2.addChild(l5) + + for i in range(3): + l1_child = ttk.TTkFancyTreeWidgetItem(["Child A" + str(i), "Child B" + str(i), "Child C" + str(i)]) + l1.addChild(l1_child) + + for j in range(2): + l2_child = ttk.TTkFancyTreeWidgetItem(["Child AA" + str(j), "Child BB" + str(j), "Child CC" + str(j)]) + l2.addChild(l2_child) + + for j in range(2): + l3_child = ttk.TTkFancyTreeWidgetItem(["Child AAA" + str(j), "Child BBB" + str(j), "Child CCC" + str(j)]) + l3.addChild(l3_child) + + for j in range(2): + l4_child = ttk.TTkFancyTreeWidgetItem(["Child AAAA" + str(j), "Child BBBB" + str(j), "Child CCCC" + str(j)]) + l4.addChild(l4_child) + + for j in range(2): + l5_child = ttk.TTkFancyTreeWidgetItem(["Child AAAAA" + str(j), "Child BBBBB" + str(j), "Child CCCCC" + str(j)]) + l5.addChild(l5_child) + + l6 = ttk.TTkFancyTreeWidgetItem(["RND", "RND", "RND"], childIndicatorPolicy=ttk.TTkK.ShowIndicator) + + def updateChildren(item): + if item.children(): return + for _ in range(0,random.randint(3,8)): + child = ttk.TTkFancyTreeWidgetItem([getWord(),getWord(),getWord()]) + if random.randint(0,10)>5: + child.setChildIndicatorPolicy(ttk.TTkK.ShowIndicator) + child.refreshData.connect(updateChildren) + item.addChild(child) + + + l6.refreshData.connect(updateChildren) + + tw.addTopLevelItem(l1) + tw.addTopLevelItem(l2) + tw.addTopLevelItem(l3) + tw.addTopLevelItem(l4) + tw.addTopLevelItem(l6) + + return tw + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('-f', help='Full Screen', action='store_true') + args = parser.parse_args() + + ttk.TTkLog.use_default_file_logging() + + root = ttk.TTk() + if args.f: + rootTree1 = root + root.setLayout(ttk.TTkGridLayout()) + else: + rootTree1 = ttk.TTkWindow(parent=root,pos = (0,0), size=(70,40), title="Test Tree 1", layout=ttk.TTkGridLayout(), border=True) + demoFancyTree(rootTree1) + root.mainloop() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/demo/showcase/tree.py b/demo/showcase/tree.py index 892de952..af57feea 100755 --- a/demo/showcase/tree.py +++ b/demo/showcase/tree.py @@ -40,49 +40,43 @@ def getSentence(a,b): return " ".join([getWord() for i in range(0,random.randint(a,b))]) def demoTree(root=None): - # tw = ttk.TTkFancyTreeWidget(parent=rootTree1) - tw = ttk.TTkFancyTree(parent=root) + tw = ttk.TTkTree(parent=root) tw.setHeaderLabels(["Column 1", "Column 2", "Column 3"]) - tw.setColumnSize((-1,20,20)) - tw.setColumnColors(( - ttk.TTkColor.RST, - ttk.TTkColor.fg('#00dddd', modifier=ttk.TTkColorGradient(increment=-4)), - ttk.TTkColor.fg('#cccc00', modifier=ttk.TTkColorGradient(increment=-2)) - )) - l1 = ttk.TTkFancyTreeWidgetItem(["String A", "String B", "String C"]) - l2 = ttk.TTkFancyTreeWidgetItem(["String AA", "String BB", "String CC"]) - l3 = ttk.TTkFancyTreeWidgetItem(["String AAA", "String BBB", "String CCC"]) - l4 = ttk.TTkFancyTreeWidgetItem(["String AAAA", "String BBBB", "String CCCC"]) - l5 = ttk.TTkFancyTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) + + l1 = ttk.TTkTreeWidgetItem(["String A", "String B", "String C"]) + l2 = ttk.TTkTreeWidgetItem(["String AA", "String BB", "String CC"]) + l3 = ttk.TTkTreeWidgetItem(["String AAA", "String BBB", "String CCC"]) + l4 = ttk.TTkTreeWidgetItem(["String AAAA", "String BBBB", "String CCCC"]) + l5 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) l2.addChild(l5) for i in range(3): - l1_child = ttk.TTkFancyTreeWidgetItem(["Child A" + str(i), "Child B" + str(i), "Child C" + str(i)]) + l1_child = ttk.TTkTreeWidgetItem(["Child A" + str(i), "Child B" + str(i), "Child C" + str(i)]) l1.addChild(l1_child) for j in range(2): - l2_child = ttk.TTkFancyTreeWidgetItem(["Child AA" + str(j), "Child BB" + str(j), "Child CC" + str(j)]) + l2_child = ttk.TTkTreeWidgetItem(["Child AA" + str(j), "Child BB" + str(j), "Child CC" + str(j)]) l2.addChild(l2_child) for j in range(2): - l3_child = ttk.TTkFancyTreeWidgetItem(["Child AAA" + str(j), "Child BBB" + str(j), "Child CCC" + str(j)]) + l3_child = ttk.TTkTreeWidgetItem(["Child AAA" + str(j), "Child BBB" + str(j), "Child CCC" + str(j)]) l3.addChild(l3_child) for j in range(2): - l4_child = ttk.TTkFancyTreeWidgetItem(["Child AAAA" + str(j), "Child BBBB" + str(j), "Child CCCC" + str(j)]) + l4_child = ttk.TTkTreeWidgetItem(["Child AAAA" + str(j), "Child BBBB" + str(j), "Child CCCC" + str(j)]) l4.addChild(l4_child) for j in range(2): - l5_child = ttk.TTkFancyTreeWidgetItem(["Child AAAAA" + str(j), "Child BBBBB" + str(j), "Child CCCCC" + str(j)]) + l5_child = ttk.TTkTreeWidgetItem(["Child AAAAA" + str(j), "Child BBBBB" + str(j), "Child CCCCC" + str(j)]) l5.addChild(l5_child) - l6 = ttk.TTkFancyTreeWidgetItem(["RND", "RND", "RND"], childIndicatorPolicy=ttk.TTkK.ShowIndicator) + l6 = ttk.TTkTreeWidgetItem(["RND", "RND", "RND"], childIndicatorPolicy=ttk.TTkK.ShowIndicator) def updateChildren(item): if item.children(): return for _ in range(0,random.randint(3,8)): - child = ttk.TTkFancyTreeWidgetItem([getWord(),getWord(),getWord()]) + child = ttk.TTkTreeWidgetItem([getWord(),getWord(),getWord()]) if random.randint(0,10)>5: child.setChildIndicatorPolicy(ttk.TTkK.ShowIndicator) child.refreshData.connect(updateChildren)