Browse Source

reimplemented remove/add widget/item in the grid layout to support nested items

pull/4/head
Eugenio Parodi 5 years ago
parent
commit
5fd1142731
  1. 2
      TermTk/TTkLayouts/boxlayout.py
  2. 86
      TermTk/TTkLayouts/gridlayout.py
  3. 20
      TermTk/TTkLayouts/layout.py
  4. 71
      tests/showcase/layoutnested.py

2
TermTk/TTkLayouts/boxlayout.py

@ -33,5 +33,7 @@ class TTkHBoxLayout(TTkGridLayout):
pass
class TTkVBoxLayout(TTkGridLayout):
def addItem(self, item):
TTkGridLayout.addItem(self, item, self.count(), 0)
def addWidget(self, widget):
TTkGridLayout.addWidget(self, widget, self.count(), 0)

86
TermTk/TTkLayouts/gridlayout.py

@ -30,17 +30,10 @@ from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.log import TTkLog
from TermTk.TTkLayouts.layout import TTkLayout, TTkWidgetItem
class TTkGridWidgetItem(TTkWidgetItem):
__slots__ = ('_row','_col')
def __init__(self, *args, **kwargs):
TTkWidgetItem.__init__(self, args[0])
self._row = kwargs.get('row')
self._col = kwargs.get('col')
class TTkGridLayout(TTkLayout):
__slots__ = ('_gridItems','_columnMinWidth','_columnMinHeight')
def __init__(self, *args, **kwargs):
TTkLayout.__init__(self, args, kwargs)
TTkLayout.__init__(self, *args, **kwargs)
self._gridItems = [[]]
self._columnMinWidth = kwargs.get('columnMinWidth',0)
self._columnMinHeight = kwargs.get('columnMinHeight',0)
@ -82,6 +75,14 @@ class TTkGridLayout(TTkLayout):
widget = args[0]
self.removeWidget(widget)
widget._parent = self.parentWidget()
item = TTkWidgetItem(widget=widget)
self.addItem(*[item], **kwargs)
widget.update(updateParent=True)
def replaceItem(self, item, index): pass
def addItem(self, *args, **kwargs):
item = args[0]
self.removeItem(item)
if len(args) == 3:
row = args[1]
col = args[2]
@ -93,9 +94,9 @@ class TTkGridLayout(TTkLayout):
#retrieve the max col/rows to reshape the grid
maxrow = row
maxcol = col
for item in self.children():
if maxrow < item._row: maxrow = item._row
if maxcol < item._col: maxcol = item._col
for child in self.children():
if maxrow < child._row: maxrow = child._row
if maxcol < child._col: maxcol = child._col
# reshape the gridItems
maxrow += 1
maxcol += 1
@ -103,18 +104,29 @@ class TTkGridLayout(TTkLayout):
if self._gridItems[row][col] is not None:
# TODO: Handle the LayoutItem
self.removeWidget(self._gridItems[row][col])
self.removeItem(self._gridItems[row][col])
item = TTkGridWidgetItem(widget, row=row, col=col)
item._row = row
item._col = col
self._gridItems[row][col] = item
self.addItem(item)
widget.update(updateParent=True)
TTkLayout.addItem(self, item)
if self.parentWidget():
self.parentWidget().update()
def removeItem(self, item):
TTkLayout.removeItem(self, item)
for gridRow in range(len(self._gridItems)):
for gridCol in range(len(self._gridItems[0])):
if self._gridItems[gridRow][gridCol] == item:
self._gridItems[gridRow][gridCol] = None
self._reshapeGrid(self._gridUsedsize())
def removeWidget(self, widget):
TTkLayout.removeWidget(self, widget)
for gridRow in range(len(self._gridItems)):
for gridCol in range(len(self._gridItems[0])):
if self._gridItems[gridRow][gridCol] is not None and \
self._gridItems[gridRow][gridCol].layoutItemType == TTkK.WidgetItem and \
self._gridItems[gridRow][gridCol].widget() == widget:
self._gridItems[gridRow][gridCol] = None
self._reshapeGrid(self._gridUsedsize())
@ -130,11 +142,12 @@ class TTkGridLayout(TTkLayout):
anyItem = False
for gridRow in range(len(self._gridItems)):
item = self._gridItems[gridRow][gridCol]
if item is not None and item.isVisible():
anyItem = True
w = item.minimumWidth()
if colw < w:
colw = w
if item is not None and \
( item.layoutItemType == TTkK.LayoutItem or item.isVisible() ):
anyItem = True
w = item.minimumWidth()
if colw < w:
colw = w
if not anyItem:
return self._columnMinWidth
return colw
@ -143,11 +156,12 @@ class TTkGridLayout(TTkLayout):
rowh = 0
anyItem = False
for item in self._gridItems[gridRow]:
if item is not None and item.isVisible():
anyItem = True
h = item.minimumHeight()
if rowh < h:
rowh = h
if item is not None and \
( item.layoutItemType == TTkK.LayoutItem or item.isVisible() ):
anyItem = True
h = item.minimumHeight()
if rowh < h:
rowh = h
if not anyItem:
return self._columnMinHeight
return rowh
@ -157,11 +171,12 @@ class TTkGridLayout(TTkLayout):
anyItem = False
for gridRow in range(len(self._gridItems)):
item = self._gridItems[gridRow][gridCol]
if item is not None and item.isVisible():
anyItem = True
w = item.maximumWidth()
if colw > w:
colw = w
if item is not None and \
( item.layoutItemType == TTkK.LayoutItem or item.isVisible() ):
anyItem = True
w = item.maximumWidth()
if colw > w:
colw = w
if not anyItem:
return self._columnMinWidth
return colw
@ -170,11 +185,12 @@ class TTkGridLayout(TTkLayout):
rowh = 0x10000
anyItem = False
for item in self._gridItems[gridRow]:
if item is not None and item.isVisible():
anyItem = True
h = item.maximumHeight()
if rowh > h:
rowh = h
if item is not None and \
( item.layoutItemType == TTkK.LayoutItem or item.isVisible() ):
anyItem = True
h = item.maximumHeight()
if rowh > h:
rowh = h
if not anyItem:
return self._columnMinHeight
return rowh

20
TermTk/TTkLayouts/layout.py

@ -30,10 +30,12 @@ from TermTk.TTkCore.log import TTkLog
from TermTk.TTkCore.constant import TTkK
class TTkLayoutItem:
__slots__ = ('_x', '_y', '_z', '_w', '_h', '_sMax', '_sMaxVal', '_sMin', '_sMinVal', '_layoutItemType')
__slots__ = ('_x', '_y', '_z', '_w', '_h', '_row','_col', '_sMax', '_sMaxVal', '_sMin', '_sMinVal', '_layoutItemType')
def __init__(self, *args, **kwargs):
self._x, self._y = 0, 0
self._z = kwargs.get('z',0)
self._row = kwargs.get('row', 0)
self._col = kwargs.get('col', 0)
self._layoutItemType = kwargs.get('layoutItemType', TTkK.NONE)
self._w, self._h = 0, 0
self._sMax, self._sMin = False, False
@ -95,7 +97,7 @@ class TTkLayout(TTkLayoutItem):
if isinstance(parent, TTkLayoutItem):
self._parent = parent
else:
self._parent = TTkWidgetItem(parent)
self._parent = TTkWidgetItem(widget=parent)
def parentWidget(self):
if self._parent is None: return None
@ -121,15 +123,17 @@ class TTkLayout(TTkLayoutItem):
def addWidget(self, widget):
if widget.parentWidget() is not None:
widget.parentWidget().removeWidget(self)
self.addItem(TTkWidgetItem(widget))
self.addItem(TTkWidgetItem(widget=widget))
def removeItem(self, item):
self._items.remove(item)
if item in self._items:
self._items.remove(item)
self._zSortItems()
def removeWidget(self, widget):
for item in self._items:
if item.widget() == widget:
if item.layoutItemType == TTkK.WidgetItem and \
item.widget() == widget:
self.removeItem(item)
def findBranchWidget(self, widget):
@ -200,9 +204,9 @@ class TTkLayout(TTkLayoutItem):
class TTkWidgetItem(TTkLayoutItem):
slots = ('_widget')
def __init__(self, widget, z=0):
TTkLayoutItem.__init__(self)
self._widget = widget
def __init__(self, *args, **kwargs):
TTkLayoutItem.__init__(self, *args, **kwargs)
self._widget = kwargs.get('widget', None)
self.layoutItemType = TTkK.WidgetItem
def widget(self):

71
tests/showcase/layoutnested.py

@ -0,0 +1,71 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
#
# 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.
import sys, os, argparse
sys.path.append(os.path.join(sys.path[0],'../..'))
import TermTk as ttk
def demoLayoutNested(root=None):
frame = ttk.TTkFrame(parent=root, border=False)
mainLayout = ttk.TTkVBoxLayout()
frame.setLayout(mainLayout)
gridLayout = ttk.TTkGridLayout()
mainLayout.addItem(gridLayout)
mainLayout.addWidget(ttk.TTkFrame(border=True,title="Frame1"))
mainLayout.addWidget(ttk.TTkFrame(border=True,title="Frame2"))
gridLayout.addWidget(ttk.TTkButton(border=True, text="Button1"),0,0)
gridLayout.addWidget(ttk.TTkButton(border=True, text="Button2"),1,1)
gridLayout.addWidget(ttk.TTkButton(border=True, text="Button3"),2,2)
gridLayout.addWidget(ttk.TTkFrame(border=True,title="Frame3"),0,1)
gridLayout.addWidget(ttk.TTkFrame(border=True,title="Frame4"),2,3)
return frame
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:
rootLayout = root
root.setLayout(ttk.TTkGridLayout())
else:
rootLayout = ttk.TTkWindow(title="Test Layout", parent=root,pos=(1,1), size=(100,40), border=True, layout=ttk.TTkGridLayout())
demoLayoutNested(rootLayout)
root.mainloop()
if __name__ == "__main__":
main()
Loading…
Cancel
Save