Browse Source

Merge pull request #4 from ceccopierangiolieugenio/Nested_Layouts

Nested layouts
pull/5/head
Ceccopierangiolieugenio 5 years ago committed by GitHub
parent
commit
4290d4e1f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      TermTk/TTkCore/canvas.py
  2. 4
      TermTk/TTkCore/constant.py
  3. 4
      TermTk/TTkCore/ttk.py
  4. 2
      TermTk/TTkLayouts/boxlayout.py
  5. 108
      TermTk/TTkLayouts/gridlayout.py
  6. 121
      TermTk/TTkLayouts/layout.py
  7. 22
      TermTk/TTkWidgets/combobox.py
  8. 11
      TermTk/TTkWidgets/frame.py
  9. 4
      TermTk/TTkWidgets/resizableframe.py
  10. 134
      TermTk/TTkWidgets/widget.py
  11. 77
      tests/showcase/layoutnested.py
  12. 22
      tests/test.showcase.001.py

8
TermTk/TTkCore/canvas.py

@ -422,6 +422,14 @@ class TTkCanvas:
'''
geom = (x,y,w,h)
bound = (x,y,w,h)
x x+w
canvas: |xxxxxxxxxxxxxxxxxxxxxxx|
slice: |-----------|
bx bx+bw
bound: |--------|
0 self._width
self._canvas: |----|xxxxxx|----------|
'''
def paintCanvas(self, canvas, geom, slice, bound):
# TTkLog.debug(f"PaintCanvas:{(x,y,w,h)}")

4
TermTk/TTkCore/constant.py

@ -109,6 +109,10 @@ class TTkConstant:
CENTER_ALIGN = 0x0003
JUSTIFY = 0x0004
# LayoutItem Types
LayoutItem = 0x01
WidgetItem = 0x02
Character = 0x0001
SpecialKey = 0x0002

4
TermTk/TTkCore/ttk.py

@ -95,7 +95,9 @@ class TTk(TTkWidget):
mevt = self.mouse_events.get()
focusWidget = TTkHelper.getFocus()
overlayWidget = TTkHelper.getOverlay()
if focusWidget is not None and mevt.evt != TTkK.Press:
if focusWidget is not None and \
mevt.evt != TTkK.Press and \
mevt.key != TTkK.Wheel:
x,y = TTkHelper.absPos(focusWidget)
nmevt = mevt.clone(pos=(mevt.x-x, mevt.y-y))
focusWidget.mouseEvent(nmevt)

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)

108
TermTk/TTkLayouts/gridlayout.py

@ -26,20 +26,14 @@
Layout System
'''
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)
@ -68,7 +62,7 @@ class TTkGridLayout(TTkLayout):
# remove extra cols
for gridRow in range(len(self._gridItems)):
if self._gridItems[gridRow] is None:
self._gridItems[gridRow] = [None]*(cols+1)
self._gridItems[gridRow] = [None]*(cols)
continue
sizeRow = len(self._gridItems[gridRow])
if cols < sizeRow:
@ -80,7 +74,18 @@ class TTkGridLayout(TTkLayout):
def addWidget(self, *args, **kwargs):
widget = args[0]
self.removeWidget(widget)
widget._parent = self.parentWidget()
item = TTkWidgetItem(widget=widget)
if len(args) == 3:
TTkGridLayout.addItem(self, item, args[1], args[2])
else:
TTkGridLayout.addItem(self, item)
widget.update()
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]
@ -92,28 +97,39 @@ 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
self._reshapeGrid(size=(maxrow,maxcol))
# TODO: This is RUBBISH!!!
self._reshapeGrid(size=(maxrow,maxcol))
if self._gridItems[row][col] is not None:
# TODO: Handle the LayoutItem
self.removeWidget(self._gridItems[row][col])
self.removeItem(self._gridItems[row][col])
self._reshapeGrid(size=(maxrow,maxcol))
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)
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())
@ -129,11 +145,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
@ -142,11 +159,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
@ -156,11 +174,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
@ -169,11 +188,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
@ -211,7 +231,7 @@ class TTkGridLayout(TTkLayout):
return maxh
def update(self):
def update(self, *args, **kwargs):
x, y, w, h = self.geometry()
newx, newy = x, y
@ -286,8 +306,10 @@ class TTkGridLayout(TTkLayout):
item.setGeometry(
horSizes[col][0], vertSizes[row][0] ,
horSizes[col][1], vertSizes[row][1] )
if isinstance(item, TTkWidgetItem) and not item.isEmpty():
item.widget().update()
elif isinstance(item, TTkLayout):
item.update()
#TTkLog.debug(f"Children: {item.geometry()}")
if item.layoutItemType == TTkK.WidgetItem and not item.isEmpty():
#TTkLog.debug(f"Children name: {item.widget()._name}")
item.widget().update(*args, **kwargs)
elif item.layoutItemType == TTkK.LayoutItem:
item.update(*args, **kwargs)
return True

121
TermTk/TTkLayouts/layout.py

@ -27,15 +27,20 @@
'''
from TermTk.TTkCore.log import TTkLog
from TermTk.TTkCore.constant import TTkK
class TTkLayoutItem:
__slots__ = ('_x', '_y', '_w', '_h', '_sMax', '_sMaxVal', '_sMin', '_sMinVal')
__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
self._sMaxVal, self._sMinVal = 0, 0
pass
def minimumSize(self):
return self.minimumWidth(), self.minimumHeight()
def minDimension(self,o)-> int: return 0
@ -57,6 +62,16 @@ class TTkLayoutItem:
self._w = w
self._h = h
@property
def z(self): return self._z
@z.setter
def z(self, z): self._z = z
@property
def layoutItemType(self): return self._layoutItemType
@layoutItemType.setter
def layoutItemType(self, t): self._layoutItemType = t
class TTkLayout(TTkLayoutItem):
__slots__ = ('_items', '_zSortedItems', '_parent')
@ -65,7 +80,7 @@ class TTkLayout(TTkLayoutItem):
self._items = []
self._zSortedItems = []
self._parent = None
pass
self.layoutItemType = TTkK.LayoutItem
def children(self):
return self._items
@ -79,10 +94,22 @@ class TTkLayout(TTkLayoutItem):
return 0
def setParent(self, parent):
self._parent = parent
if isinstance(parent, TTkLayoutItem):
self._parent = parent
else:
self._parent = TTkWidgetItem(widget=parent)
for item in self._items:
if item.layoutItemType == TTkK.LayoutItem:
item.setParent(self)
else:
item.widget().setParent(self.parentWidget())
def parentWidget(self):
return self._parent
if self._parent is None: return None
if self._parent.layoutItemType == TTkK.WidgetItem:
return self._parent.widget()
else:
return self._parent.parentWidget()
def _zSortItems(self):
self._zSortedItems = sorted(self._items, key=lambda item: item.z)
@ -90,50 +117,72 @@ class TTkLayout(TTkLayoutItem):
@property
def zSortedItems(self): return self._zSortedItems
def replaceItem(self, item, index):
self._items[index] = item
self._zSortItems()
def addItem(self, item):
self._items.append(item)
self._zSortItems()
self.update()
if item.layoutItemType == TTkK.LayoutItem:
item.setParent(self)
else:
item.widget().setParent(self.parentWidget())
if self.parentWidget():
self.parentWidget().update(repaint=True, updateLayout=True)
def addWidget(self, widget):
if widget.parentWidget() is not None:
widget.parentWidget().removeWidget(self)
self.addItem(TTkWidgetItem(widget))
self.addItem(TTkWidgetItem(widget=widget))
def removeWidget(self, widget):
for i in self._items:
if i.widget() == widget:
self._items.remove(i)
return
def removeItem(self, item):
if item in self._items:
self._items.remove(item)
self._zSortItems()
def removeWidget(self, widget):
for item in self._items:
if item.layoutItemType == TTkK.WidgetItem and \
item.widget() == widget:
self.removeItem(item)
def findBranchWidget(self, widget):
for item in self._items:
if item.layoutItemType == TTkK.LayoutItem:
if item.findBranchWidget(widget) is not None:
return item
else:
if item.widget() == widget:
return item
return None
def raiseWidget(self, widget):
maxz = 0
item = None
item = self.findBranchWidget(widget)
for i in self._items:
if i.widget() == widget:
item = i
elif i.z >= maxz:
maxz=i.z+1
maxz=max(i.z+1,maxz)
item.z = maxz
if item.layoutItemType == TTkK.LayoutItem:
item.raiseWidget(widget)
self._zSortItems()
def lowerWidget(self, widget):
minz = 0
item = None
item = self.findBranchWidget(widget)
for i in self._items:
if i.widget() == widget:
item = i
elif i.z <= minz:
minz=i.z-1
minz=min(i.z-1,minz)
item.z = minz
if item.layoutItemType == TTkK.LayoutItem:
item.lowerWidget(widget)
self._zSortItems()
def setGeometry(self, x, y, w, h):
ax, ay, aw, ah = self.geometry()
if ax==x and ay==y and aw==w and ah==h: return
TTkLayoutItem.setGeometry(self, x, y, w, h)
self.update()
self.update(repaint=True, updateLayout=True)
def groupMoveTo(self, x, y):
ox,oy,_,_ = self.fullWidgetAreaGeometry()
@ -154,23 +203,23 @@ class TTkLayout(TTkLayoutItem):
maxy = max(maxy,y+h)
return minx, miny, maxx-minx, maxy-miny
def update(self):
def update(self, *args, **kwargs):
ret = False
for i in self.children():
if isinstance(i, TTkWidgetItem) and not i.isEmpty():
ret = ret or i.widget().update()
if i.layoutItemType == TTkK.WidgetItem and not i.isEmpty():
ret = ret or i.widget().update(*args, **kwargs)
# TODO: Have a look at this:
# i.getCanvas().top()
elif isinstance(i, TTkLayout):
ret= ret or i.update()
elif i.layoutItemType == TTkK.LayoutItem:
ret= ret or i.update(*args, **kwargs)
return ret
class TTkWidgetItem(TTkLayoutItem):
slots = ('_widget','_z')
def __init__(self, widget, z=0):
TTkLayoutItem.__init__(self)
self._widget = widget
self.z = z
slots = ('_widget')
def __init__(self, *args, **kwargs):
TTkLayoutItem.__init__(self, *args, **kwargs)
self._widget = kwargs.get('widget', None)
self.layoutItemType = TTkK.WidgetItem
def widget(self):
return self._widget
@ -193,7 +242,5 @@ class TTkWidgetItem(TTkLayoutItem):
def setGeometry(self, x, y, w, h):
self._widget.setGeometry(x, y, w, h)
@property
def z(self): return self._z
@z.setter
def z(self, z): self._z = z
#def update(self, *args, **kwargs):
# self.widget().update(*args, **kwargs)

22
TermTk/TTkWidgets/combobox.py

@ -27,10 +27,12 @@ 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.widget import *
from TermTk.TTkWidgets.button import *
from TermTk.TTkWidgets.table import *
from TermTk.TTkWidgets.resizableframe import *
from TermTk.TTkCore.helper import TTkHelper
from TermTk.TTkLayouts.gridlayout import TTkGridLayout
from TermTk.TTkWidgets.widget import TTkWidget
from TermTk.TTkWidgets.button import TTkButton
from TermTk.TTkWidgets.list import TTkList
from TermTk.TTkWidgets.resizableframe import TTkResizableFrame
class TTkComboBox(TTkWidget):
__slots__ = ('_list', '_id', )
@ -58,9 +60,9 @@ class TTkComboBox(TTkWidget):
self._canvas.drawText(pos=(0,0), text="[", color=borderColor)
self._canvas.drawText(pos=(w-2,0), text="^]", color=borderColor)
@pyTTkSlot(int)
def _callback(self, val):
self._id = val
@pyTTkSlot(str)
def _callback(self, label):
self._id = self._list.index(label)
#TTkHelper.removeOverlay()
self.setFocus()
self.update()
@ -72,11 +74,11 @@ class TTkComboBox(TTkWidget):
if frameWidth < 20: frameWidth = 20
frame = TTkResizableFrame(layout=TTkGridLayout(), size=(frameWidth,frameHeight))
table = TTkTable(parent=frame, showHeader=False)
table.activated.connect(self._callback)
listw = TTkList(parent=frame)
listw.textClicked.connect(self._callback)
TTkLog.debug(f"{self._list}")
for item in self._list:
table.appendItem([item])
listw.addItem(item)
TTkHelper.overlay(self, frame, 0, 0)
self.update()
return True

11
TermTk/TTkWidgets/frame.py

@ -26,8 +26,17 @@ from TermTk.TTkCore.cfg import *
from TermTk.TTkCore.log import TTkLog
from TermTk.TTkWidgets.widget import TTkWidget
class _TTkMenuBar():
__slots__ = ('_itemsLeft', '_itemsCenter', '_itemsRight')
def __init__(self, *args, **kwargs):
pass
def addMenu(self):
pass
class TTkFrame(TTkWidget):
__slots__ = ('_border','_title', '_titleColor', '_borderColor')
__slots__ = ('_border','_title', '_titleColor', '_borderColor', '_menubarTop', '_menubarBottom')
def __init__(self, *args, **kwargs):
TTkWidget.__init__(self, *args, **kwargs)
self._name = kwargs.get('name' , 'TTkFrame' )

4
TermTk/TTkWidgets/resizableframe.py

@ -53,8 +53,8 @@ class TTkResizableFrame(TTkFrame):
elif y==h-1:
self._resizable |= TTkK.BOTTOM
# TTkLog.debug(f"{(x,y)} - {self._resizable}")
return self._resizable != TTkK.NONE
#return True
#return self._resizable != TTkK.NONE
return True
def mouseDragEvent(self, evt):
if self._resizable:

134
TermTk/TTkWidgets/widget.py

@ -22,12 +22,14 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from TermTk.TTkCore.cfg import *
from TermTk.TTkCore.constant import *
import TermTk.libbpytop as lbt
from TermTk.TTkCore.canvas import *
from TermTk.TTkCore.signal import *
from TermTk.TTkCore.cfg import TTkCfg, TTkGlbl
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.log import TTkLog
from TermTk.TTkCore.helper import TTkHelper
from TermTk.TTkCore.canvas import TTkCanvas
from TermTk.TTkCore.signal import pyTTkSignal, pyTTkSlot
from TermTk.TTkLayouts.layout import TTkLayout, TTkWidgetItem
import TermTk.libbpytop as lbt
class TTkWidget:
@ -57,6 +59,8 @@ class TTkWidget:
self._name = kwargs.get('name', 'TTkWidget' )
self._parent = kwargs.get('parent', None )
self._layout = TTkLayout() # root layout
self._layout.addItem(TTkLayout()) # main layout
self._x = kwargs.get('x', 0 )
self._y = kwargs.get('y', 0 )
self._x, self._y = kwargs.get('pos', (self._x, self._y))
@ -101,30 +105,43 @@ class TTkWidget:
def addWidget(self, widget):
widget._parent = self
if self._layout is not None:
self._layout.addWidget(widget)
if self.layout() is not None:
self.layout().addWidget(widget)
self.update(repaint=True, updateLayout=True)
# widget.show()
def removeWidget(self, widget):
if self._layout is not None:
self._layout.removeWidget(widget)
if self.layout() is not None:
self.layout().removeWidget(widget)
self.update(repaint=True, updateLayout=True)
def paintEvent(self): pass
@staticmethod
def _paintChildCanvas(canvas, item, geometry):
lx,ly,lw,lh = geometry
if item.layoutItemType == TTkK.WidgetItem and not item.isEmpty():
child = item.widget()
cx,cy,cw,ch = child.geometry()
canvas.paintCanvas(
child.getCanvas(),
(cx, cy, cw, ch), # geometry
(0,0,cw,ch), # slice
(lx, ly, lw, lh)) # bound
else:
for child in item.zSortedItems:
ix, iy, iw, ih = item.geometry()
# child outside the bound
if ix+iw < lx and ix > lx+lw and iy+ih < ly and y > ly+lh: continue
# Reduce the bound to the minimum visible
bx = max(ix,lx)
by = max(iy,ly)
bw = min(ix+iw,lx+lw)-bx
bh = min(iy+ih,ly+lh)-by
TTkWidget._paintChildCanvas(canvas, child, (bx,by,bw,bh))
def paintChildCanvas(self):
# paint over child canvas
lx,ly,lw,lh = self._layout.geometry()
for item in self._layout.zSortedItems:
if isinstance(item, TTkWidgetItem) and not item.isEmpty():
child = item.widget()
cx,cy,cw,ch = child.geometry()
self._canvas.paintCanvas(
child.getCanvas(),
(cx, cy, cw, ch),
(0,0,cw,ch),
(lx, ly, lw, lh))
TTkWidget._paintChildCanvas(self._canvas, self.layout(), self.layout().geometry())
def paintNotifyParent(self):
parent = self._parent
@ -188,7 +205,7 @@ class TTkWidget:
return False
for item in reversed(layout.zSortedItems):
# for item in layout.zSortedItems:
if isinstance(item, TTkWidgetItem) and not item.isEmpty():
if item.layoutItemType == TTkK.WidgetItem and not item.isEmpty():
widget = item.widget()
if not widget._visible: continue
wevt = None
@ -216,7 +233,7 @@ class TTkWidget:
#if widget.event(evt):
# return True
elif isinstance(item, TTkLayout):
elif item.layoutItemType == TTkK.LayoutItem:
levt = evt.clone(pos=(x, y))
if TTkWidget._mouseEventLayoutHandle(levt, item):
return True
@ -225,26 +242,26 @@ class TTkWidget:
def mouseEvent(self, evt):
# Mouse Drag has priority because it
# should be handled by the focussed widget
if evt.evt == lbt.MouseEvent.Drag:
if evt.evt == TTkK.Drag:
if self.mouseDragEvent(evt):
return True
if self._layout is not None:
if TTkWidget._mouseEventLayoutHandle(evt, self._layout):
if self.rootLayout() is not None:
if TTkWidget._mouseEventLayoutHandle(evt, self.rootLayout()):
return True
# handle own events
if evt.evt == lbt.MouseEvent.Move:
if evt.evt == TTkK.Move:
if self.mouseMoveEvent(evt):
return True
if evt.evt == lbt.MouseEvent.Release:
if evt.evt == TTkK.Release:
#if self.hasFocus():
# self.clearFocus()
if self.mouseReleaseEvent(evt):
return True
if evt.evt == lbt.MouseEvent.Press:
if evt.evt == TTkK.Press:
if self.focusPolicy() & TTkK.ClickFocus == TTkK.ClickFocus:
self.setFocus()
self.raiseWidget()
@ -252,7 +269,7 @@ class TTkWidget:
# TTkLog.debug(f"Click {self._name}")
return True
if evt.key == lbt.MouseEvent.Wheel:
if evt.key == TTkK.Wheel:
if self.wheelEvent(evt):
return True
#if self.focusPolicy() & CuT.WheelFocus == CuT.WheelFocus:
@ -288,15 +305,16 @@ class TTkWidget:
# elif evt.type() == CuEvent.KeyRelease:
# self.keyReleaseEvent(evt)
# # Trigger this event to the childs
# if self._layout is not None:
# return CuWidget._eventLayoutHandle(evt, self._layout)
# if self.layout() is not None:
# return CuWidget._eventLayoutHandle(evt, self.layout())
def setLayout(self, layout):
self._layout = layout
self._layout.setParent(self)
self._layout.replaceItem(layout, 0)
self.layout().setParent(self)
self.update(repaint=True, updateLayout=True)
def layout(self): return self._layout
def layout(self): return self._layout.itemAt(0)
def rootLayout(self): return self._layout
def setParent(self, parent):
self._parent = parent
@ -321,15 +339,15 @@ class TTkWidget:
return self.maximumHeight()
def maximumHeight(self):
wMaxH = self._maxh
if self._layout is not None:
lMaxH = self._layout.maximumHeight() + self._padt + self._padb
if self.layout() is not None:
lMaxH = self.layout().maximumHeight() + self._padt + self._padb
if lMaxH < wMaxH:
return lMaxH
return wMaxH
def maximumWidth(self):
wMaxW = self._maxw
if self._layout is not None:
lMaxW = self._layout.maximumWidth() + self._padl + self._padr
if self.layout() is not None:
lMaxW = self.layout().maximumWidth() + self._padl + self._padr
if lMaxW < wMaxW:
return lMaxW
return wMaxW
@ -343,15 +361,15 @@ class TTkWidget:
return self.minimumHeight()
def minimumHeight(self):
wMinH = self._minh
if self._layout is not None:
lMinH = self._layout.minimumHeight() + self._padt + self._padb
if self.layout() is not None:
lMinH = self.layout().minimumHeight() + self._padt + self._padb
if lMinH > wMinH:
return lMinH
return wMinH
def minimumWidth(self):
wMinW = self._minw
if self._layout is not None:
lMinW = self._layout.minimumWidth() + self._padl + self._padr
if self.layout() is not None:
lMinW = self.layout().minimumWidth() + self._padl + self._padr
if lMinW > wMinW:
return lMinW
return wMinW
@ -389,13 +407,20 @@ class TTkWidget:
# elif isinstance(item, CuLayout):
# CuWidget._showHandle(item)
@staticmethod
def _propagateShowToLayout(layout):
if layout is None: return
for item in layout.zSortedItems:
if item.layoutItemType == TTkK.WidgetItem and not item.isEmpty():
child = item.widget()
child._propagateShow()
else:
TTkWidget._propagateShowToLayout(item)
def _propagateShow(self):
if not self._visible: return
self.update(updateLayout=True, updateParent=True)
for item in self._layout.zSortedItems:
if isinstance(item, TTkWidgetItem) and not item.isEmpty():
child = item.widget()
child._propagateShow()
TTkWidget._propagateShowToLayout(self.rootLayout())
@pyTTkSlot()
def show(self):
@ -422,15 +447,15 @@ class TTkWidget:
def raiseWidget(self):
if self._parent is not None and \
self._parent._layout is not None:
self._parent.rootLayout() is not None:
self._parent.raiseWidget()
self._parent._layout.raiseWidget(self)
self._parent.rootLayout().raiseWidget(self)
def lowerWidget(self):
if self._parent is not None and \
self._parent._layout is not None:
self._parent.rootLayout() is not None:
self._parent.lowerWidget()
self._parent._layout.lowerWidget(self)
self._parent.rootLayout().lowerWidget(self)
def close(self): pass
@ -448,15 +473,16 @@ class TTkWidget:
if repaint:
TTkHelper.addUpdateBuffer(self)
TTkHelper.addUpdateWidget(self)
if updateLayout and self._layout is not None:
self._layout.setGeometry(
if updateLayout and self.layout() is not None:
self.rootLayout().setGeometry(0,0,self._width,self._height)
self.layout().setGeometry(
self._padl, self._padt,
self._width - self._padl - self._padr,
self._height - self._padt - self._padb)
if updateParent and self._parent is not None:
self._parent.update(updateLayout=True)
if updateLayout and self._layout is not None:
if self._layout.update():
if updateLayout and self.layout() is not None:
if self.layout().update():
self.layoutUpdated()
def setFocus(self):

77
tests/showcase/layoutnested.py

@ -0,0 +1,77 @@
#!/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)
nestedLayout = ttk.TTkGridLayout()
gridLayout.addItem(nestedLayout,1,2)
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)
nestedLayout.addWidget(ttk.TTkButton(border=True, text="Button4"),0,1)
nestedLayout.addWidget(ttk.TTkButton(border=True, text="Button5"),1,0)
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()

22
tests/test.showcase.001.py

@ -28,22 +28,24 @@ import random
sys.path.append(os.path.join(sys.path[0],'..'))
import TermTk as ttk
from showcase.layout import demoLayout
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
from showcase.formwidgets import demoFormWidgets
from showcase.scrollarea import demoScrollArea
from showcase.list import demoList
from showcase.layout import demoLayout
from showcase.layoutnested import demoLayoutNested
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
from showcase.formwidgets import demoFormWidgets
from showcase.scrollarea import demoScrollArea
from showcase.list import demoList
def demoShowcase(root= None, border=True):
tabWidget1 = ttk.TTkTabWidget(parent=root, border=border)
tabWidget1.addTab(ttk.TTkTestWidgetSizes(border=True, title="Frame1.1"), " Label 1.1 ")
tabWidget1.addTab(ttk.TTkTestWidget(border=True, title="Frame1.2"), " Label Test 1.2 ")
tabWidget1.addTab(demoLayout(), " Layout Test ")
tabWidget1.addTab(demoLayoutNested()," Nested Layout Test ")
tabWidget1.addTab(demoFormWidgets(), " Form Test ")
tabWidget1.addTab(demoList(), " List Test ")
tabWidget1.addTab(demoGraph(), " Graph Test ")

Loading…
Cancel
Save