Browse Source

List Widget, Scroll Area

pull/4/head
Eugenio Parodi 5 years ago
parent
commit
a1f01c29d9
  1. 3
      TermTk/TTkAbstract/abstractscrollarea.py
  2. 7
      TermTk/TTkAbstract/abstractscrollview.py
  3. 12
      TermTk/TTkCore/canvas.py
  4. 9
      TermTk/TTkCore/color.py
  5. 7
      TermTk/TTkCore/constant.py
  6. 10
      TermTk/TTkGui/theme.py
  7. 19
      TermTk/TTkLayouts/layout.py
  8. 3
      TermTk/TTkTemplates/color.py
  9. 3
      TermTk/TTkTemplates/text.py
  10. 1
      TermTk/TTkTestWidgets/__init__.py
  11. 98
      TermTk/TTkTestWidgets/logviewer.py
  12. 4
      TermTk/TTkWidgets/__init__.py
  13. 6
      TermTk/TTkWidgets/label.py
  14. 50
      TermTk/TTkWidgets/list.py
  15. 126
      TermTk/TTkWidgets/listwidget.py
  16. 62
      TermTk/TTkWidgets/logviewer.py
  17. 56
      TermTk/TTkWidgets/scrollarea.py
  18. 2
      TermTk/TTkWidgets/splitter.py
  19. 2
      TermTk/TTkWidgets/tabwidget.py
  20. 14
      TermTk/TTkWidgets/widget.py
  21. 2
      docs/TODO.md
  22. 2
      tests/gittk.py
  23. 92
      tests/showcase/list.py
  24. 77
      tests/showcase/scrollarea.py
  25. 6
      tests/test.showcase.001.py
  26. 92
      tests/test.ui.014.list.py
  27. 58
      tests/test.ui.015.scrollArea.py

3
TermTk/TTkAbstract/abstractscrollarea.py

@ -109,4 +109,5 @@ class TTkAbstractScrollArea(TTkWidget):
def setHorizontalScrollBarPolicy(self, policy):
self._horizontalScrollBarPolicy = policy
def viewport(self):
return self._viewport

7
TermTk/TTkAbstract/abstractscrollview.py

@ -42,7 +42,6 @@ class TTkAbstractScrollView(TTkWidget):
super().__init__(self, *args, **kwargs)
self._name = kwargs.get('name' , 'TTkAbstractScrollView')
self._viewOffsetX = 0
self._viewOffsetY = 0
@ -61,10 +60,8 @@ class TTkAbstractScrollView(TTkWidget):
rangex = fw - dw
rangey = fh - dh
# TTkLog.debug(f"x:{x},y:{y}, full:{fw,fh}, display:{dw,dh}, range:{rangex,rangey}")
if x>rangex: x = rangex
if y>rangey: y = rangey
if x<0 : x = 0
if y<0 : y = 0
x = max(0,min(rangex,x))
y = max(0,min(rangey,y))
# TTkLog.debug(f"x:{x},y:{y}, wo:{self._viewOffsetX,self._viewOffsetY}")
if self._viewOffsetX == x and \
self._viewOffsetY == y: # Nothong to do

12
TermTk/TTkCore/canvas.py

@ -299,7 +299,7 @@ class TTkCanvas:
tt = TTkCfg.theme.tab
# phase 0 - Draw the Bottom bar
if slim:
bottomBar = tt[16]+tt[12]*(w-2)+tt[17]
bottomBar = tt[18]+tt[19]*(w-2)+tt[20]
bottomPos = y+1
else:
bottomBar = tt[11]+tt[12]*(w-2)+tt[15]
@ -329,22 +329,22 @@ class TTkCanvas:
list(reversed(range(offset+1, len(labels)) )):
text = labels[i]
posx = labelsPos[i]
_drawTab(x+posx,y,tt[0],tt[1],tt[3],tt[9],tt[9],tt[12],tt[12],tt[12],tt[9],tt[9],tt[13],tt[12],tt[13], text, color, borderColor, slim)
_drawTab(x+posx,y,tt[0],tt[1],tt[3],tt[9],tt[9],tt[12],tt[12],tt[12],tt[9],tt[9],tt[23],tt[19],tt[24], text, color, borderColor, slim)
# phase 3 - Draw 'Selected'
if selected != -1:
i = selected
text = labels[i]
posx = labelsPos[i]
_drawTab(x+posx,y,tt[4],tt[5],tt[6],tt[10],tt[10],tt[14],tt[12],tt[14],tt[10],tt[10],tt[14],tt[12],tt[14], text, selectColor, borderColor, slim)
_drawTab(x+posx,y,tt[4],tt[5],tt[6],tt[10],tt[10],tt[14],tt[12],tt[14],tt[10],tt[10],tt[21],tt[12],tt[22], text, selectColor, borderColor, slim)
if selected != offset:
i = offset
text = labels[i]
posx = labelsPos[i]
_drawTab(x+posx,y,tt[0],tt[1],tt[3],tt[9],tt[9],tt[13],tt[12],tt[13],tt[9],tt[9],tt[13],tt[12],tt[13], text, color, borderColor, slim)
_drawTab(x+posx,y,tt[0],tt[1],tt[3],tt[9],tt[9],tt[13],tt[12],tt[13],tt[9],tt[9],tt[18],tt[19],tt[20], text, color, borderColor, slim)
# phase 4 - Draw left right tilt
if leftScroller:
top = tt[7]+tt[1]
center = tt[9]+tt[18]
center = tt[9]+tt[31]
if slim:
self.drawText(pos=(x,y),text=center, color=borderColor)
else:
@ -352,7 +352,7 @@ class TTkCanvas:
self.drawText(pos=(x,y+1),text=center, color=borderColor)
if rightScroller:
top = tt[1]+tt[8]
center = tt[19]+tt[9]
center = tt[32]+tt[9]
if slim:
self.drawText(pos=(x+w-2,y),text=center, color=borderColor)
else:

9
TermTk/TTkCore/color.py

@ -154,12 +154,9 @@ class TTkColorGradient(_TTkColorModifier):
r = int(cc[2]) + self._increment * multiplier
g = int(cc[3]) + self._increment * multiplier
b = int(cc[4][:-1])+ self._increment * multiplier
if r>255: r=255
if g>255: g=255
if b>255: b=255
if r<0: r=0
if g<0: g=0
if b<0: b=0
r = max(min(255,r),0)
g = max(min(255,g),0)
b = max(min(255,b),0)
return f"{cc[0]};{cc[1]};{r};{g};{b}m"
bname = str(color)

7
TermTk/TTkCore/constant.py

@ -43,6 +43,13 @@ class TTkConstant:
RIGHT = 0x0008
CENTER = 0x0010
# SelectionMode
NoSelection = 0x00
SingleSelection = 0x01
MultiSelection = 0x02
ExtendedSelection = 0x03
ContiguousSelection = 0x04
# Graph types
FILLED = 0x0001
LINE = 0x0002

10
TermTk/TTkGui/theme.py

@ -136,9 +136,11 @@ class TTkTheme():
'','','','','','','','','',
#9 10
'','',
#11 12 13 14 15 16 17
'','','','','','','',
#18 19
#11 12 13 14 15 16 17 18 19 20
'','','','','','','','','','',
#21 22 23 24 25 26 27 28 29 30
'','','','','X','X','X','X','X','X',
#31 32
'',''
)
'''
@ -195,6 +197,8 @@ class TTkTheme():
buttonTextColorFocus = buttonTextColor + TTkColor.BOLD
buttonBorderColorFocus = buttonBorderColor + TTkColor.BOLD
listColor = TTkColor.RST
listColorSelected = TTkColor.fg("#ffffdd")+TTkColor.bg("#000044") + TTkColor.BOLD
lineEditTextColor = TTkColor.fg("#dddddd")+TTkColor.bg("#222222")
lineEditTextColorFocus = TTkColor.fg("#dddddd")+TTkColor.bg("#000044")

19
TermTk/TTkLayouts/layout.py

@ -135,6 +135,25 @@ class TTkLayout(TTkLayoutItem):
TTkLayoutItem.setGeometry(self, x, y, w, h)
self.update()
def groupMoveTo(self, x, y):
ox,oy,_,_ = self.fullWidgetAreaGeometry()
dx = x-ox
dy = y-oy
for item in self._items:
x,y,w,h = item.geometry()
item.setGeometry(x+dx,y+dy,w,h)
def fullWidgetAreaGeometry(self):
if not self._items: return 0,0,0,0
minx,miny,maxx,maxy = 0x10000,0x10000,-0x10000,-0x10000
for item in self._items:
x,y,w,h = item.geometry()
minx = min(minx,x)
miny = min(miny,y)
maxx = max(maxx,x+w)
maxy = max(maxy,y+h)
return minx, miny, maxx-minx, maxy-miny
def update(self):
ret = False
for i in self.children():

3
TermTk/TTkTemplates/color.py

@ -27,8 +27,7 @@ from TermTk.TTkCore.color import TTkColor
class TColor():
#__slots__ = ('_color')
def __init__(self, *args, **kwargs):
self._color = TTkColor.RST
self.color = kwargs.get('color', TTkColor.RST )
self._color = kwargs.get('color', TTkColor.RST )
def colorUpdated(self, color): pass

3
TermTk/TTkTemplates/text.py

@ -25,8 +25,7 @@
class TText():
#__slots__ = ('_text')
def __init__(self, *args, **kwargs):
self._text = ""
self.text = kwargs.get('text', "" )
self._text = kwargs.get('text', "" )
def textUpdated(self, text): pass

1
TermTk/TTkTestWidgets/__init__.py

@ -1,2 +1,3 @@
from .logviewer import *
from .testwidget import *
from .testwidgetsizes import *

98
TermTk/TTkTestWidgets/logviewer.py

@ -0,0 +1,98 @@
#!/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 os
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.log import TTkLog
from TermTk.TTkCore.color import TTkColor
from TermTk.TTkWidgets.frame import TTkFrame
from TermTk.TTkTemplates.color import TColor
from TermTk.TTkTemplates.text import TText
from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal
from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollArea
from TermTk.TTkAbstract.abstractscrollview import TTkAbstractScrollView
class _TTkLogViewer(TTkAbstractScrollView):
__slots__ = ('_color', '_text', '_messages', '_cwd')
def __init__(self, *args, **kwargs):
TTkAbstractScrollView.__init__(self, *args, **kwargs)
self._name = kwargs.get('name' , '_TTkLogViewer' )
self._messages = [""]
self._cwd = os.getcwd()
TTkLog.installMessageHandler(self.loggingCallback)
self.viewChanged.connect(self._viewChangedHandler)
@pyTTkSlot()
def _viewChangedHandler(self):
self.update()
def viewFullAreaSize(self) -> (int, int):
w = max([ len(m) for m in self._messages])
h = len(self._messages)
return w , h
def viewDisplayedSize(self) -> (int, int):
return self.size()
def loggingCallback(self, mode, context, message):
logType = "NONE"
if mode == TTkLog.InfoMsg: logType = "INFO "
elif mode == TTkLog.DebugMsg: logType = "DEBUG"
elif mode == TTkLog.ErrorMsg: logType = "ERROR"
elif mode == TTkLog.FatalMsg: logType = "FATAL"
elif mode == TTkLog.WarningMsg: logType = "WARNING "
elif mode == TTkLog.CriticalMsg: logType = "CRITICAL"
self._messages.append(f"{logType}: {context.file}:{context.line} {message}".replace(self._cwd,"_"))
offx, offy = self.getViewOffsets()
_,h = self.size()
if offy == len(self._messages)-h-1:
offy = len(self._messages)-h
self.viewMoveTo(offx, offy)
self.viewChanged.emit()
self.update()
def paintEvent(self):
ox,oy = self.getViewOffsets()
y = 0
_,h = self.size()
offset = max(0,ox)
for message in self._messages[oy:]:
self._canvas.drawText(pos=(0,y),text=message[ox:])
c = TTkColor.RST
if message.startswith("INFO ") : c = TTkColor.fg("#00ff00")
elif message.startswith("DEBUG") : c = TTkColor.fg("#00ffff")
elif message.startswith("ERROR") : c = TTkColor.fg("#ff0000")
elif message.startswith("FATAL") : c = TTkColor.fg("#ff0000")
self._canvas.drawText(pos=(-ox,y),text=message[:5], color=c)
y+=1
class TTkLogViewer(TTkAbstractScrollArea):
__slots__ = ('_logView')
def __init__(self, *args, **kwargs):
TTkAbstractScrollArea.__init__(self, *args, **kwargs)
self._name = kwargs.get('name' , 'TTkLogViewer' )
if 'parent' in kwargs: kwargs.pop('parent')
self._logView = _TTkLogViewer(*args, **kwargs)
self.setFocusPolicy(TTkK.ClickFocus)
self.setViewport(self._logView)

4
TermTk/TTkWidgets/__init__.py

@ -11,12 +11,14 @@ 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 .table import *
from .tableview import *
from .tree import *
from .treeview import *
from .treewidget import *
from .logviewer import *
from .graph import *

6
TermTk/TTkWidgets/label.py

@ -30,10 +30,12 @@ from TermTk.TTkTemplates.text import TText
class TTkLabel(TTkWidget, TColor, TText):
__slots__ = ('_color', '_text')
def __init__(self, *args, **kwargs):
TTkWidget.__init__(self, *args, **kwargs)
self._name = kwargs.get('name' , 'TTkLabel' )
TColor.__init__(self, *args, **kwargs)
TText.__init__(self, *args, **kwargs)
TTkWidget.__init__(self, *args, **kwargs)
self._name = kwargs.get('name' , 'TTkLabel' )
# self.setMinimumSize(len(self.text), 1)
self.textUpdated(self.text)
def paintEvent(self):
self._canvas.drawText(pos=(0,0), text=' '*self.width(), color=self.color)

50
TermTk/TTkWidgets/list.py

@ -0,0 +1,50 @@
#!/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.
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.TTkWidgets.listwidget import TTkListWidget
from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollArea
class TTkList(TTkAbstractScrollArea):
__slots__ = ('_listView', 'itemClicked', 'textClicked')
def __init__(self, *args, **kwargs):
TTkAbstractScrollArea.__init__(self, *args, **kwargs)
self._name = kwargs.get('name' , 'TTkList' )
if 'parent' in kwargs: kwargs.pop('parent')
self._listView = TTkListWidget(*args, **kwargs)
self.setFocusPolicy(TTkK.ClickFocus)
self.setViewport(self._listView)
self.itemClicked = self._listView.itemClicked
self.textClicked = self._listView.textClicked
def addItem(self, *args, **kwargs):
return self._listView.addItem(*args, **kwargs)
def setSelectionMode(self, *args, **kwargs):
return self._listView.setSelectionMode(*args, **kwargs)
def selectedLabels(self, *args, **kwargs):
return self._listView.selectedLabels(*args, **kwargs)

126
TermTk/TTkWidgets/listwidget.py

@ -0,0 +1,126 @@
#!/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.
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.widget import TTkWidget
from TermTk.TTkWidgets.label import TTkLabel
from TermTk.TTkTestWidgets.testwidgetsizes import TTkTestWidgetSizes
from TermTk.TTkAbstract.abstractscrollview import TTkAbstractScrollView
class _TTkListWidgetText(TTkLabel):
__slots__ = ('selected', '_selected')
def __init__(self, *args, **kwargs):
TTkLabel.__init__(self, *args, **kwargs)
self._name = kwargs.get('name' , '_TTkListWidgetText' )
# Define Signals
self.selected = pyTTkSignal(_TTkListWidgetText)
self._selected = False
def mouseReleaseEvent(self, evt):
self.selected.emit(self)
return True
class TTkListWidget(TTkAbstractScrollView):
__slots__ = ('itemClicked', 'textClicked', '_color', '_selectedColor', '_selectedItems', '_selectionMode')
def __init__(self, *args, **kwargs):
# Default Class Specific Values
self._selectionMode = kwargs.get("selectionMode", TTkK.SingleSelection)
self._selectedItems = []
self._color = TTkCfg.theme.listColor
self._selectedColor = TTkCfg.theme.listColorSelected
# Signals
self.itemClicked = pyTTkSignal(TTkWidget)
self.textClicked = pyTTkSignal(str)
# Init Super
TTkAbstractScrollView.__init__(self, *args, **kwargs)
self._name = kwargs.get('name' , 'TTkListWidget' )
self.viewChanged.connect(self._viewChangedHandler)
@pyTTkSlot()
def _viewChangedHandler(self):
x,y = self.getViewOffsets()
self.layout().groupMoveTo(-x,-y)
@pyTTkSlot(_TTkListWidgetText)
def _labelSelectedHandler(self, label):
if self._selectionMode == TTkK.SingleSelection:
for i in self._selectedItems:
i._selected = False
i.color = TTkCfg.theme.listColor
label._selected = True
elif self._selectionMode == TTkK.MultiSelection:
label._selected = not label._selected
if label._selected:
self._selectedItems.append(label)
else:
self._selectedItems.remove(label)
if label._selected:
label.color = TTkCfg.theme.listColorSelected
else:
label.color = TTkCfg.theme.listColor
self.textClicked.emit(label.text)
def setSelectionMode(self, mode):
self._selectionMode = mode
def selectedLabels(self):
return [i.text for i in self._selectedItems]
def resizeEvent(self, w, h):
maxw = 0
for item in self.layout().children():
maxw = max(maxw,item.minimumWidth())
maxw = max(self.width(),maxw)
for item in self.layout().children():
x,y,_,h = item.geometry()
item.setGeometry(x,y,maxw,h)
self.viewChanged.emit()
def viewFullAreaSize(self) -> (int, int):
_,_,w,h = self.layout().fullWidgetAreaGeometry()
return w , h
def viewDisplayedSize(self) -> (int, int):
return self.size()
def addItem(self, item):
if isinstance(item, str):
label = _TTkListWidgetText(text=item, width=max(len(item),self.width()))
label.selected.connect(self._labelSelectedHandler)
return self.addItem(label)
_,y,_,h = self.layout().fullWidgetAreaGeometry()
self.addWidget(item)
item.move(0,y+h)
_,_,fw,_ = self.layout().fullWidgetAreaGeometry()
w = self.width()
for item in self.layout().children():
x,y,_,h = item.geometry()
minw = item.minimumWidth()
item.setGeometry(x,y,max(w-1,fw),h)
self.viewChanged.emit()

62
TermTk/TTkWidgets/logviewer.py

@ -1,62 +0,0 @@
#!/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 os
from TermTk.TTkCore.log import TTkLog
from TermTk.TTkWidgets.widget import *
from TermTk.TTkTemplates.color import TColor
from TermTk.TTkTemplates.text import TText
class TTkLogViewer(TTkWidget):
__slots__ = ('_color', '_text', '_messages', '_cwd')
def __init__(self, *args, **kwargs):
TTkWidget.__init__(self, *args, **kwargs)
self._name = kwargs.get('name' , 'TTkLabel' )
self._messages = []
self._cwd = os.getcwd()
TTkLog.installMessageHandler(self.loggingCallback)
def loggingCallback(self, mode, context, message):
logType = "NONE"
if mode == TTkLog.InfoMsg: logType = "INFO"
elif mode == TTkLog.DebugMsg: logType = "DEBUG"
elif mode == TTkLog.WarningMsg: logType = "WARNING"
elif mode == TTkLog.CriticalMsg: logType = "CRITICAL"
elif mode == TTkLog.FatalMsg: logType = "FATAL"
elif mode == TTkLog.ErrorMsg: logType = "ERROR"
self._messages.append(f"{logType}: {context.file}:{context.line} {message}".replace(self._cwd,"_"))
self.update()
def paintEvent(self):
y = 0
_,h = self.size()
offset = len(self._messages)-h
if offset<0: offset = 0
for message in self._messages[offset:]:
self._canvas.drawText(pos=(0,y),text=message)
y+=1

56
TermTk/TTkWidgets/scrollarea.py

@ -23,38 +23,36 @@
# SOFTWARE.
from TermTk.TTkCore.log import TTkLog
from TermTk.TTkCore.constant import TTkConstant, TTkK
from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal
from TermTk.TTkCore.color import TTkColor
from TermTk.TTkWidgets.widget import TTkWidget, TTkScrollBar, TTkLayout
from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollArea
from TermTk.TTkAbstract.abstractscrollview import TTkAbstractScrollView
'''
'''
class TTkScrollArea(TTkWidget):
__slots__ = ('_border', '_hszroll', '_vscroll', '_widgetScroller')
class _TTkAreaWidget(TTkAbstractScrollView):
__slots__ = ()
def __init__(self, *args, **kwargs):
TTkWidget.__init__(self, *args, **kwargs)
self._name = kwargs.get('name' , 'TTkScrollArea' )
# self._border = kwargs.get('border', True )
# if self._border:
# self.setPadding(1,2,1,2)
# else:
# self.setPadding(0,1,0,1)
# self._hscroll = TTkScrollBar(parent=self)
# self._vscroll = TTkScrollBar(parent=self)
TTkAbstractScrollView.__init__(self, *args, **kwargs)
self._name = kwargs.get('name' , '_TTkAreaWidget' )
self.viewChanged.connect(self._viewChangedHandler)
#def setWidget(self, widget):
@pyTTkSlot()
def _viewChangedHandler(self):
x,y = self.getViewOffsets()
self.layout().groupMoveTo(-x,-y)
#def setLayout(self, layout):
# self._layout = layout
# self._layout.setParent(self)
# self._layout.setGeometry(
# self._padl, self._padt,
# self._width - self._padl - self._padr,
# self._height - self._padt - self._padb)
# self.update(repaint=True, updateLayout=True)
def viewFullAreaSize(self) -> (int, int):
_,_,w,h = self.layout().fullWidgetAreaGeometry()
return w , h
#def paintEvent(self):
# if self._border:
# self._canvas.drawBox(pos=(0,0),size=(self._width,self._height))
def viewDisplayedSize(self) -> (int, int):
return self.size()
class TTkScrollArea(TTkAbstractScrollArea):
__slots__ = ('_areaView')
def __init__(self, *args, **kwargs):
TTkAbstractScrollArea.__init__(self, *args, **kwargs)
self._name = kwargs.get('name' , 'TTkScrollArea' )
if 'parent' in kwargs: kwargs.pop('parent')
self._areaView = _TTkAreaWidget(*args, **kwargs)
self.setFocusPolicy(TTkK.ClickFocus)
self.setViewport(self._areaView)

2
TermTk/TTkWidgets/splitter.py

@ -64,7 +64,7 @@ class TTkSplitter(TTkFrame):
return 0, 0x1000
# this is because there is a hidden splitter at position -1
minsize = -1
maxsize = 0x0
maxsize = -1
for i in range(self._separatorSelected):
item = self.layout().itemAt(i)
minsize += item.minDimension(self._orientation)+1

2
TermTk/TTkWidgets/tabwidget.py

@ -62,7 +62,7 @@ class TTkTabWidget(TTkFrame):
self._tabColor = TTkCfg.theme.tabColor
self._tabBorderColor = TTkCfg.theme.tabBorderColor
self._tabSelectColor = TTkCfg.theme.tabSelectColor
super().__init__(self, *args, **kwargs)
TTkFrame.__init__(self, *args, **kwargs)
self._name = kwargs.get('name' , 'TTkTabWidget')
self.setLayout(TTkGridLayout())
self._viewport = TTkWidget(layout=TTkGridLayout())

14
TermTk/TTkWidgets/widget.py

@ -145,11 +145,11 @@ class TTkWidget:
self.moveEvent(x,y)
def resize(self, w, h):
if w==self._width and h==self._height: return
self._width = w
self._height = h
self._canvas.resize(self._width, self._height)
self.update(repaint=True, updateLayout=True)
if w!=self._width or h!=self._height:
self._width = w
self._height = h
self._canvas.resize(self._width, self._height)
self.update(repaint=True, updateLayout=True)
self.resizeEvent(w,h)
def setGeometry(self, x, y, w, h):
@ -360,9 +360,11 @@ class TTkWidget:
self.setMaximumWidth(maxw)
self.setMaximumHeight(maxh)
def setMaximumHeight(self, maxh):
if self._maxh == maxh: return
self._maxh = maxh
self.update(updateLayout=True, updateParent=True)
def setMaximumWidth(self, maxw):
if self._maxw == maxw: return
self._maxw = maxw
self.update(updateLayout=True, updateParent=True)
@ -370,9 +372,11 @@ class TTkWidget:
self.setMinimumWidth(minw)
self.setMinimumHeight(minh)
def setMinimumHeight(self, minh):
if self._minh == minh: return
self._minh = minh
self.update(updateLayout=True, updateParent=True)
def setMinimumWidth(self, minw):
if self._minw == minw: return
self._minw = minw
self.update(updateLayout=True, updateParent=True)

2
docs/TODO.md

@ -20,6 +20,8 @@
- [ ] Investigate the middle mouse button paste
*note: It works only in "INSERT" mode on Vim*
- [x] Handle Special Keys (UP, Down, . . .)
- [ ] Handle CTRL-Mouse
- [ ] Handle CTRL,ALT,SHIFT + Key (Tab, UP, Down, . . .)
- [ ] Events
https://tkinterexamples.com/events/events.html
https://www.pythontutorial.net/tkinter/tkinter-event-binding/

2
tests/gittk.py

@ -80,7 +80,7 @@ for commit in commitResults:
@ttk.pyTTkSlot(int)
def _tableCallback(val):
commit = allCommits[val]
diff = repo.git.diff(f"{commit.hexsha}",f"{commit.hexsha}~")
diff = repo.git.diff(f"{commit.hexsha}~",f"{commit.hexsha}")
# ttk.TTkLog.debug(diff)
lines = []
for line in diff.split('\n'):

92
tests/showcase/list.py

@ -0,0 +1,92 @@
#!/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, math, random
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 demoList(root= None):
# Define the main Layout
splitter = ttk.TTkSplitter(parent=root, orientation=ttk.TTkK.HORIZONTAL)
frame2 = ttk.TTkFrame(parent=splitter, border=0, layout=ttk.TTkVBoxLayout())
frame1 = ttk.TTkFrame(parent=splitter, border=0, layout=ttk.TTkVBoxLayout())
frame3 = ttk.TTkFrame(parent=splitter, border=0, layout=ttk.TTkVBoxLayout())
# Multi Selection List
ttk.TTkLabel(parent=frame1, text="[ MultiSelect ]",maxHeight=2)
listWidgetMulti = ttk.TTkList(parent=frame1, maxWidth=40, minWidth=10, selectionMode=ttk.TTkK.MultiSelection)
# Single Selection List
ttk.TTkLabel(parent=frame2, text="[ SingleSelect ]",maxHeight=2)
listWidgetSingle = ttk.TTkList(parent=frame2, maxWidth=40, minWidth=10)
# Log Viewer
label1 = ttk.TTkLabel(parent=frame3, text="[ list1 ]",maxHeight=2)
label2 = ttk.TTkLabel(parent=frame3, text="[ list2 ]",maxHeight=2)
ttk.TTkLogViewer(parent=frame3)#, border=True)
@ttk.pyTTkSlot(str)
def _listCallback1(label):
ttk.TTkLog.info(f"Clicked label1: {label}")
label1.text = f"[ list1 ] clicked {label}"
@ttk.pyTTkSlot(str)
def _listCallback2(label):
ttk.TTkLog.info(f"Clicked label2: {label} - selected: {listWidgetMulti.selectedLabels()}")
label2.text = f"[ list2 ] {listWidgetMulti.selectedLabels()}"
# Connect the signals to the 2 slots defines
listWidgetSingle.textClicked.connect(_listCallback1)
listWidgetMulti.textClicked.connect(_listCallback2)
# populate the lists with random entries
for i in range(100):
listWidgetSingle.addItem(f"{i}) {getWord()} {getWord()}")
listWidgetMulti.addItem(f"{getWord()} {getWord()}")
return splitter
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:
rootGraph = root
root.setLayout(ttk.TTkGridLayout())
else:
rootGraph = ttk.TTkWindow(parent=root,pos=(1,1), size=(100,40), title="Test List", border=True, layout=ttk.TTkGridLayout())
demoList(rootGraph)
root.mainloop()
if __name__ == "__main__":
main()

77
tests/showcase/scrollarea.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, math, random
sys.path.append(os.path.join(sys.path[0],'../..'))
import TermTk as ttk
class graphTimerEvent():
def __init__(self, w, delay):
self.timer = ttk.TTkTimer()
self.val = 10
self.delay = delay
self.w = w
self.timer.timeout.connect(self.timerEvent)
self.timer.start(1)
@ttk.pyTTkSlot()
def timerEvent(self):
plot = [ math.sin( self.val *math.pi/40)*4*10 ,
math.sin((self.val+15)*math.pi/40)*4*7,
math.sin((self.val+20)*math.pi/30)*4*5,]
self.val+=1
self.w.addValue(plot)
self.timer.start(self.delay)
def demoScrollArea(root= None):
scrollArea = ttk.TTkScrollArea(parent=root)
ttk.TTkTestWidgetSizes(pos=(0,0) , size=(50,25), parent=scrollArea.viewport(), border=True)
ttk.TTkTestWidgetSizes(pos=(10,25) , size=(40,20), parent=scrollArea.viewport(), border=True)
ttk.TTkTestWidgetSizes(pos=(20,50) , size=(60,10), parent=scrollArea.viewport(), border=True)
ttk.TTkTestWidgetSizes(pos=(50,0) , size=(40,10), parent=scrollArea.viewport(), border=True)
ttk.TTkTestWidgetSizes(pos=(100,0) , size=(40,10), parent=scrollArea.viewport(), border=True)
ttk.TTkTestWidgetSizes(pos=(150,0) , size=(40,10), parent=scrollArea.viewport(), border=True)
ttk.TTkTestWidgetSizes(pos=(50,31) , size=(60,10), parent=scrollArea.viewport(), border=True)
graph = ttk.TTkGraph( pos=(50,11) , size=(150,20), parent=scrollArea.viewport(), color=ttk.TTkColor.fg('#ff8800', modifier=ttk.TTkColorGradient(increment= 40)))
graphTimerEvent(graph, 0.1)
return scrollArea
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:
rootGraph = root
root.setLayout(ttk.TTkGridLayout())
else:
rootGraph = ttk.TTkWindow(parent=root,pos=(1,1), size=(100,40), title="Test Graph", border=True, layout=ttk.TTkGridLayout())
demoScrollArea(rootGraph)
root.mainloop()
if __name__ == "__main__":
main()

6
tests/test.showcase.001.py

@ -32,10 +32,12 @@ 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.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)
@ -43,12 +45,14 @@ def demoShowcase(root= None, border=True):
tabWidget1.addTab(ttk.TTkTestWidget(border=True, title="Frame1.2"), " Label Test 1.2 ")
tabWidget1.addTab(demoLayout(), " Layout Test ")
tabWidget1.addTab(demoFormWidgets(), " Form Test ")
tabWidget1.addTab(demoList(), " List Test ")
tabWidget1.addTab(demoGraph(), " Graph Test ")
tabWidget1.addTab(demoTable(), " Table Test ")
tabWidget1.addTab(demoTree(), " Tree Test ")
tabWidget1.addTab(demoSplitter(), " Splitter Test ")
tabWidget1.addTab(demoWindows(), " Windows Test ")
tabWidget1.addTab(demoTab(), " Tab Test ")
tabWidget1.addTab(demoScrollArea(), " Scroll Area ")
return tabWidget1
def main():

92
tests/test.ui.014.list.py

@ -0,0 +1,92 @@
#!/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, math, random
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 demoList(root= None):
# Define the main Layout
splitter = ttk.TTkSplitter(parent=root, orientation=ttk.TTkK.HORIZONTAL)
frame2 = ttk.TTkFrame(parent=splitter, border=0, layout=ttk.TTkVBoxLayout())
frame1 = ttk.TTkFrame(parent=splitter, border=0, layout=ttk.TTkVBoxLayout())
frame3 = ttk.TTkFrame(parent=splitter, border=0, layout=ttk.TTkVBoxLayout())
# Multi Selection List
ttk.TTkLabel(parent=frame1, text="[ MultiSelect ]",maxHeight=2)
listWidgetMulti = ttk.TTkList(parent=frame1, maxWidth=40, minWidth=10, selectionMode=ttk.TTkK.MultiSelection)
# Single Selection List
ttk.TTkLabel(parent=frame2, text="[ SingleSelect ]",maxHeight=2)
listWidgetSingle = ttk.TTkList(parent=frame2, maxWidth=40, minWidth=10)
# Log Viewer
label1 = ttk.TTkLabel(parent=frame3, text="[ list1 ]",maxHeight=2)
label2 = ttk.TTkLabel(parent=frame3, text="[ list2 ]",maxHeight=2)
ttk.TTkLogViewer(parent=frame3)#, border=True)
@ttk.pyTTkSlot(str)
def _listCallback1(label):
ttk.TTkLog.info(f"Clicked label1: {label}")
label1.text = f"[ list1 ] clicked {label}"
@ttk.pyTTkSlot(str)
def _listCallback2(label):
ttk.TTkLog.info(f"Clicked label2: {label} - selected: {listWidgetMulti.selectedLabels()}")
label2.text = f"[ list2 ] {listWidgetMulti.selectedLabels()}"
# Connect the signals to the 2 slots defines
listWidgetSingle.textClicked.connect(_listCallback1)
listWidgetMulti.textClicked.connect(_listCallback2)
# populate the lists with random entries
for i in range(100):
listWidgetSingle.addItem(f"{i}) {getWord()} {getWord()}")
listWidgetMulti.addItem(f"{getWord()} {getWord()}")
return splitter
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:
rootGraph = root
root.setLayout(ttk.TTkGridLayout())
else:
rootGraph = ttk.TTkWindow(parent=root,pos=(1,1), size=(100,40), title="Test List", border=True, layout=ttk.TTkGridLayout())
demoList(rootGraph)
root.mainloop()
if __name__ == "__main__":
main()

58
tests/test.ui.015.scrollArea.py

@ -0,0 +1,58 @@
#!/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, math, random
sys.path.append(os.path.join(sys.path[0],'..'))
import TermTk as ttk
def demoScrollArea(root= None):
scrollArea = ttk.TTkScrollArea(parent=root)
ttk.TTkTestWidgetSizes(pos=(0,0) , size=(40,20), parent=scrollArea.viewport(), border=True)
ttk.TTkTestWidgetSizes(pos=(10,25) , size=(40,20), parent=scrollArea.viewport(), border=True)
ttk.TTkTestWidgetSizes(pos=(20,50) , size=(60,10), parent=scrollArea.viewport(), border=True)
ttk.TTkTestWidgetSizes(pos=(50,0) , size=(40,10), parent=scrollArea.viewport(), border=True)
ttk.TTkTestWidgetSizes(pos=(100,0) , size=(40,10), parent=scrollArea.viewport(), border=True)
ttk.TTkTestWidgetSizes(pos=(150,0) , size=(40,10), parent=scrollArea.viewport(), border=True)
ttk.TTkTestWidgetSizes(pos=(60,30) , size=(60,10), parent=scrollArea.viewport(), border=True)
return scrollArea
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:
rootGraph = root
root.setLayout(ttk.TTkGridLayout())
else:
rootGraph = ttk.TTkWindow(parent=root,pos=(1,1), size=(100,40), title="Test Graph", border=True, layout=ttk.TTkGridLayout())
demoScrollArea(rootGraph)
root.mainloop()
if __name__ == "__main__":
main()
Loading…
Cancel
Save