From 7cbc9309699e2b37fd092ebbae8c92f525b7356a Mon Sep 17 00:00:00 2001 From: Eugenio Parodi Date: Tue, 23 Feb 2021 23:09:08 +0000 Subject: [PATCH] Click Signal, Scrollbar Signal/slots, Basic Table, Demos --- TermTk/TTkWidgets/__init__.py | 3 +- TermTk/TTkWidgets/button.py | 7 +- TermTk/TTkWidgets/label.py | 5 +- TermTk/TTkWidgets/scrollarea.py | 60 ++++++++++++++ TermTk/TTkWidgets/scrollbar.py | 58 +++++++++++--- TermTk/TTkWidgets/table.py | 134 ++++++++++++++++++++++++++++++++ TermTk/TTkWidgets/widget.py | 21 +++-- tests/test.showcase.001.py | 131 +++++++++++++++++++++++++++++++ tests/test.ui.007.events.py | 66 ++++++++++++++++ tests/test.ui.008.table.py | 53 +++++++++++++ 10 files changed, 517 insertions(+), 21 deletions(-) create mode 100644 TermTk/TTkWidgets/scrollarea.py create mode 100644 TermTk/TTkWidgets/table.py create mode 100755 tests/test.showcase.001.py create mode 100755 tests/test.ui.007.events.py create mode 100755 tests/test.ui.008.table.py diff --git a/TermTk/TTkWidgets/__init__.py b/TermTk/TTkWidgets/__init__.py index a80295ce..50103619 100644 --- a/TermTk/TTkWidgets/__init__.py +++ b/TermTk/TTkWidgets/__init__.py @@ -6,5 +6,6 @@ from .button import * from .label import * from .scrollbar import * from .window import * +from .table import * from .logviewer import * -from .testwidget import * \ No newline at end of file +from .testwidget import * diff --git a/TermTk/TTkWidgets/button.py b/TermTk/TTkWidgets/button.py index d61af0dd..a8b44b39 100644 --- a/TermTk/TTkWidgets/button.py +++ b/TermTk/TTkWidgets/button.py @@ -23,13 +23,17 @@ # SOFTWARE. from TermTk.TTkCore.log import TTkLog +from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal from TermTk.TTkCore.color import TTkColor from TermTk.TTkWidgets.widget import * class TTkButton(TTkWidget): - __slots__ = ('_text', '_border', '_pressed') + __slots__ = ('_text', '_border', '_pressed', 'clicked') def __init__(self, *args, **kwargs): TTkWidget.__init__(self, *args, **kwargs) + # Define Signals + self.clicked = pyTTkSignal() + self._name = kwargs.get('name' , 'TTkButton' ) self.text = kwargs.get('text', "" ) self._border = kwargs.get('border', True ) @@ -61,6 +65,7 @@ class TTkButton(TTkWidget): TTkLog.debug(f"{self._name} Test Mouse {evt}") self._pressed = False self.update() + self.clicked.emit() return True @property diff --git a/TermTk/TTkWidgets/label.py b/TermTk/TTkWidgets/label.py index 358f562e..dac5d8b3 100644 --- a/TermTk/TTkWidgets/label.py +++ b/TermTk/TTkWidgets/label.py @@ -31,15 +31,18 @@ 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) - self._name = kwargs.get('name' , 'TTkLabel' ) def paintEvent(self): self._canvas.drawText(pos=(0,0), text=' '*self.width(), color=self.color) self._canvas.drawText(pos=(0,0), text=self.text, color=self.color) def textUpdated(self, text): + w, h = self.size() + if w +# +# 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.log import TTkLog +from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal +from TermTk.TTkCore.color import TTkColor +from TermTk.TTkWidgets.widget import TTkWidget, TTkScrollBar, TTkLayout + +''' + + +''' +class TTkScrollArea(TTkWidget): + __slots__ = ('_border', '_hszroll', '_vscroll', '_widgetScroller') + 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) + + #def setWidget(self, widget): + + #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 paintEvent(self): + # if self._border: + # self._canvas.drawBox(pos=(0,0),size=(self._width,self._height)) \ No newline at end of file diff --git a/TermTk/TTkWidgets/scrollbar.py b/TermTk/TTkWidgets/scrollbar.py index 7c4da79d..ec0665e8 100644 --- a/TermTk/TTkWidgets/scrollbar.py +++ b/TermTk/TTkWidgets/scrollbar.py @@ -26,6 +26,7 @@ import math 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 @@ -44,11 +45,20 @@ class TTkScrollBar(TTkWidget): # |---| Screen Scroller # |-----| Screen Pg Up # <------|XXX|-----> - '_screenPgDown','_screenPgUp','_screenScroller') + '_screenPgDown','_screenPgUp','_screenScroller', + # Signals + 'valueChanged', 'rangeChanged', 'sliderMoved' + ) def __init__(self, *args, **kwargs): TTkWidget.__init__(self, *args, **kwargs) self._name = kwargs.get('name' , 'TTkScrollBar' ) + # Define Signals + self.valueChanged = pyTTkSignal(int) # Value + self.rangeChanged = pyTTkSignal(int, int) # Min, Max + self.sliderMoved = pyTTkSignal(int) # Value + + self._orientation = kwargs.get('orientation' , TTkK.VERTICAL ) if self._orientation == TTkK.VERTICAL: self.setMaximumWidth(1) @@ -91,15 +101,19 @@ class TTkScrollBar(TTkWidget): color = self.focusColor else: color = self.color - - size2 = size-2 - asciiStep = size2 * self._pagestep // (self._maximum - self._minimum + self._pagestep) - if asciiStep==0: asciiStep=1 # Force the slider to be at least one char wide - asciiDrawingSize = size2 - asciiStep - a = self._value - self._minimum - # covert i screen coordinates - aa = asciiDrawingSize * a // (self._maximum - self._minimum) - bb = aa + asciiStep + if self._maximum == self._minimum: + # Special case where no scroll is needed + aa=0 + bb=size-2 + else: + size2 = size-2 + asciiStep = size2 * self._pagestep // (self._maximum - self._minimum + self._pagestep) + if asciiStep==0: asciiStep=1 # Force the slider to be at least one char wide + asciiDrawingSize = size2 - asciiStep + a = self._value - self._minimum + # covert i screen coordinates + aa = asciiDrawingSize * a // (self._maximum - self._minimum) + bb = aa + asciiStep self._canvas.drawScroll(pos=(0,0),size=size,slider=(aa+1,bb+1),orientation=self._orientation, color=color) # Update the screen position coordinates self._screenPgDown = ( 1 , aa+1 ) @@ -159,6 +173,7 @@ class TTkScrollBar(TTkWidget): a = aa * (self._maximum - self._minimum) // asciiDrawingSize self.value = a + self._minimum + self.sliderMoved.emit(aa) # TTkLog.debug(f"m={mouse}, md:{self._mouseDelta}, aa:{aa}") return True @@ -170,15 +185,33 @@ class TTkScrollBar(TTkWidget): def focusOutEvent(self): self.update() + @pyTTkSlot(int, int) + def setRange(self, min, max): + self.minimum = min + self.maximum = max + self.rangeChanged.emit(min, max) + + @pyTTkSlot(int) + def setValue(self, v): + self.value = v + @property def minimum(self): return self._minimum @minimum.setter - def minimum(self, v): self._minimum = v; self.update() + def minimum(self, v): + if v > self._maximum: + v = self._maximum + self._minimum = v + self.update() @property def maximum(self): return self._maximum @minimum.setter - def minimum(self, v): self._maximum = v; self.update() + def maximum(self, v): + if v < self._minimum: + v = self._minimum + self._maximum = v + self.update() @property def singlestep(self): return self._singlestep @@ -197,6 +230,7 @@ class TTkScrollBar(TTkWidget): if v > self._maximum: v = self._maximum if v < self._minimum: v = self._minimum self._value = v + self.valueChanged.emit(v) self.update() @property diff --git a/TermTk/TTkWidgets/table.py b/TermTk/TTkWidgets/table.py new file mode 100644 index 00000000..156227fa --- /dev/null +++ b/TermTk/TTkWidgets/table.py @@ -0,0 +1,134 @@ +#!/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.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.layout import * +from TermTk.TTkWidgets.spacer import TTkSpacer +from TermTk.TTkWidgets.scrollbar import TTkScrollBar + +''' + + +''' +class TTkTable(TTkWidget): + __slots__ = ('_hlayout','_vscroller','_columns','_tableData', '_moveTo') + def __init__(self, *args, **kwargs): + self._vscroller = None # This is required to avoid crash int he vScroller Tuning + self._moveTo = 0 + self._tableData = [] + TTkWidget.__init__(self, *args, **kwargs) + self._name = kwargs.get('name' , 'TTkTable' ) + self._columns = kwargs.get('columns' , 'TTkTable' ) + self._hlayout = TTkHBoxLayout() + self.setLayout(self._hlayout) + TTkSpacer(parent=self) + self._vscroller = TTkScrollBar(parent=self) + self._vscroller.valueChanged.connect(self.scrollTo) + + def setColumnSize(self, columns): + self._columns = columns + + def appendItem(self, item): + self._tableData.append(item) + self._tuneTheScroller() + + def resizeEvent(self, w, h): + if self._moveTo > len(self._tableData)-h: + self._moveTo = len(self._tableData)-h + self._tuneTheScroller() + + def _tuneTheScroller(self): + if self._vscroller is None: return + scrollTo = len(self._tableData) - self.height() + self._vscroller.setRange(0, scrollTo) + self._vscroller.pagestep = self.height() + + def wheelEvent(self, evt): + # delta = self.height() + delta = 5 + if evt.evt == TTkK.WHEEL_Up: + delta = -delta + # self.scrollTo(self._moveTo + delta) + self._vscroller.value = self._moveTo + delta + return True + + @pyTTkSlot(int) + def scrollTo(self, to): + max = len(self._tableData) - self.height() + if to>max: to=max + if to<0: to=0 + self._moveTo = to + self.update() + + def paintEvent(self): + y = 0 + w,h = self.size() + total = 0 + variableCols = 0 + slicesize = 0 + for width in self._columns: + if width > 0: + total += width + else: + variableCols += 1 + if variableCols > 0: + slicesize = int((w-total)/variableCols) + TTkLog.debug(f"ss:{slicesize}, w:{w}") + + maxItems = len(self._tableData) + itemFrom = self._moveTo + itemTo = itemFrom + h + if itemFrom > maxItems: itemFrom = maxItems + if itemTo > maxItems: itemTo = maxItems + for i in range(itemFrom, itemTo): + item= self._tableData[i] + line = "" + for i in range(0,len(item)): + txt = item[i] + width = self._columns[i] + if width < 0: + width = slicesize + if width > 0: + lentxt = len(txt) + if lentxt > width: + line += txt[0:width] + else: + line += txt + " "*(width-lentxt) + line += " " + lentxt = len(line) + if lentxt > w-2: + line = line[0:w-2] + else: + line = line + " "*(w-2-lentxt) + self._canvas.drawText(pos=(0,y), text=line) + y+=1 + + + + + diff --git a/TermTk/TTkWidgets/widget.py b/TermTk/TTkWidgets/widget.py index 18f4a446..b795cb4e 100644 --- a/TermTk/TTkWidgets/widget.py +++ b/TermTk/TTkWidgets/widget.py @@ -25,8 +25,10 @@ import TermTk.libbpytop as lbt from TermTk.TTkCore.canvas import * from TermTk.TTkCore.cfg import * +from TermTk.TTkCore.signal import * from TermTk.TTkWidgets.layout import * + class TTkWidget: # Focus Policies NoFocus = 0x0000 @@ -97,15 +99,16 @@ class TTkWidget: width = self._width , height = self._height ) self.setLayout(kwargs.get('layout',TTkLayout())) - if self._parent is not None and \ - self._parent._layout is not None: - self._parent._layout.addWidget(self) + if self._parent is not None: + self._parent.addWidget(self) self._parent.update(repaint=True, updateLayout=True) self.update(repaint=True, updateLayout=True) - def addLayout(self, l): - self._layout = l + def addWidget(self, widget): + if self._layout is not None: + self._layout.addWidget(widget) + self.update(repaint=True, updateLayout=True) def paintEvent(self): pass @@ -130,11 +133,14 @@ class TTkWidget: parent.paintChildCanvas() parent = parent._parent + def moveEvent(self, x, y): pass + def resizeEvent(self, w, h): pass def move(self, x, y): self._x = x self._y = y self.update(repaint=False, updateLayout=False) + self.moveEvent(x,y) def resize(self, w, h): self._width = w @@ -146,6 +152,7 @@ class TTkWidget: self._width - self._padl - self._padr, self._height - self._padt - self._padb) self.update(repaint=True, updateLayout=True) + self.resizeEvent(w,h) def setGeometry(self, x, y, w, h): self.resize(w, h) @@ -365,6 +372,7 @@ class TTkWidget: # elif isinstance(item, CuLayout): # CuWidget._showHandle(item) + @pyTTkSlot() def show(self): self._canvas.show() self._visible = True @@ -381,10 +389,11 @@ class TTkWidget: # elif isinstance(item, CuLayout): # CuWidget._hideHandle(item) + @pyTTkSlot() def hide(self): self._canvas.hide() self._visible = False - #self._parent._canvas.clean(self.pos(),self.size()) + # self._parent._canvas.clean(self.pos(),self.size()) self.update() # if self._layout is not None: # TTkWidget._hideHandle(self._layout]) diff --git a/tests/test.showcase.001.py b/tests/test.showcase.001.py new file mode 100755 index 00000000..e997fa81 --- /dev/null +++ b/tests/test.showcase.001.py @@ -0,0 +1,131 @@ +#!/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. + +import sys, os +import random + +sys.path.append(os.path.join(sys.path[0],'..')) +import TermTk as ttk + + + +ttk.TTkLog.use_default_file_logging() + +root = ttk.TTk() + +btn1 = ttk.TTkButton(parent=root, pos=(0,0), size=(5,3), text='On') +btn2 = ttk.TTkButton(parent=root, pos=(5,0), size=(5,3), text='Off') +btn3 = ttk.TTkButton(parent=root, pos=(0,3), size=(5,3), text='On') +btn4 = ttk.TTkButton(parent=root, pos=(5,3), size=(5,3), text='Off') +btn5 = ttk.TTkButton(parent=root, pos=(0,6), size=(5,3), text='On') +btn6 = ttk.TTkButton(parent=root, pos=(5,6), size=(5,3), text='Off') +ttk.TTkLabel(parent=root, pos=(10,1), text='zOrder and max/min size') +ttk.TTkLabel(parent=root, pos=(10,4), text='Scollbars') +ttk.TTkLabel(parent=root, pos=(10,7), text='Basic Table') + +# Testing Widgets from "test.ui.004.windows.py" +test_win1 = ttk.TTkWindow(parent=root,pos = (10,1), size=(70,35), title="Test Window 1", border=True) +test_win1.hide() +btn1.clicked.connect(test_win1.show) +btn2.clicked.connect(test_win1.hide) + +test_win2_1 = ttk.TTkWindow(parent=test_win1,pos = (3,3), size=(40,20), title="Test Window 2.1", border=True) +test_win2_1.setLayout(ttk.TTkHBoxLayout()) +ttk.TTkTestWidget(parent=test_win2_1, border=False) + +test_win2_2 = ttk.TTkWindow(parent=test_win1,pos = (5,5), size=(40,20), title="Test Window 2.2", border=True) +test_win2_2.setLayout(ttk.TTkHBoxLayout()) +ttk.TTkTestWidget(parent=test_win2_2, border=False) + + +test_win3 = ttk.TTkWindow(parent=root,pos = (20,5), size=(70,25), title="Test Window 3", border=True) +test_win3.hide() +test_win3.setLayout(ttk.TTkHBoxLayout()) +btn1.clicked.connect(test_win3.show) +btn2.clicked.connect(test_win3.hide) + +ttk.TTkTestWidget(parent=test_win3, border=True, maxWidth=30, minWidth=20) +rightFrame = ttk.TTkFrame(parent=test_win3, border=True) +rightFrame.setLayout(ttk.TTkVBoxLayout()) + +ttk.TTkTestWidget(parent=rightFrame, border=True, maxSize=(50,15), minSize=(30,8)) +bottomrightframe = ttk.TTkFrame(parent=rightFrame,border=True) + +test_win4 = ttk.TTkWindow(parent=bottomrightframe, pos = (3,3), size=(40,20), title="Test Window 4", border=True) +test_win4.setLayout(ttk.TTkHBoxLayout()) +ttk.TTkTestWidget(parent=test_win4, border=False) + + +# Scroller window from test.ui.006.scroll.py +win_scroller = ttk.TTkWindow(parent=root,pos=(30,3), size=(50,30), title="Test Window 1", border=True) +win_scroller.hide() +btn3.clicked.connect(win_scroller.show) +btn4.clicked.connect(win_scroller.hide) +win_scroller.setLayout(ttk.TTkVBoxLayout()) +top = ttk.TTkFrame(parent=win_scroller, layout=ttk.TTkHBoxLayout()) +ttk.TTkScrollBar(parent=win_scroller, orientation=ttk.TTk.HORIZONTAL, value=0, color=ttk.TTkColor.bg('#990044')+ttk.TTkColor.fg('#ffff00')) +ttk.TTkScrollBar(parent=win_scroller, orientation=ttk.TTk.HORIZONTAL, value=10, color=ttk.TTkColor.bg('#770044')+ttk.TTkColor.fg('#ccff00')) +ttk.TTkScrollBar(parent=win_scroller, orientation=ttk.TTk.HORIZONTAL, value=50, color=ttk.TTkColor.bg('#660044')+ttk.TTkColor.fg('#88ff00')) +ttk.TTkScrollBar(parent=win_scroller, orientation=ttk.TTk.HORIZONTAL, value=80, color=ttk.TTkColor.bg('#550044')+ttk.TTkColor.fg('#55ff00')) +ttk.TTkScrollBar(parent=win_scroller, orientation=ttk.TTk.HORIZONTAL, value=99, color=ttk.TTkColor.bg('#330044')+ttk.TTkColor.fg('#33ff00')) + + +ttk.TTkScrollBar(parent=top, orientation=ttk.TTk.VERTICAL, value=0) +ttk.TTkScrollBar(parent=top, orientation=ttk.TTk.VERTICAL, value=10) +ttk.TTkScrollBar(parent=top, orientation=ttk.TTk.VERTICAL, value=40) +ttk.TTkSpacer(parent=top) +ttk.TTkScrollBar(parent=top, orientation=ttk.TTk.VERTICAL, value=40, pagestep=3) +ttk.TTkScrollBar(parent=top, orientation=ttk.TTk.VERTICAL, value=50, pagestep=5) +ttk.TTkScrollBar(parent=top, orientation=ttk.TTk.VERTICAL, value=60, pagestep=20) +ttk.TTkScrollBar(parent=top, orientation=ttk.TTk.VERTICAL, value=70, pagestep=30) +ttk.TTkScrollBar(parent=top, orientation=ttk.TTk.VERTICAL, value=80, pagestep=60) +ttk.TTkSpacer(parent=top) +ttk.TTkScrollBar(parent=top, orientation=ttk.TTk.VERTICAL, value=80) +ttk.TTkScrollBar(parent=top, orientation=ttk.TTk.VERTICAL, value=90) +ttk.TTkScrollBar(parent=top, orientation=ttk.TTk.VERTICAL, value=99) + + +# Table window from test.ui.008.table.py +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(): + return " ".join([getWord() for i in range(0,random.randint(6, 20))]) + +win_table = ttk.TTkWindow(parent=root,pos = (10,0), size=(60,30), title="Test Table 1", layout=ttk.TTkHBoxLayout(), border=True) +win_table.hide() +btn5.clicked.connect(win_table.show) +btn6.clicked.connect(win_table.hide) +table = ttk.TTkTable(parent=win_table) + +table.setColumnSize((20,-1,10,15)) +table.appendItem(("","You see it's all clear, You were meant to be here, From the beginning","","")) +for i in range(0, 100): + table.appendItem((str(i)+" - "+getWord(), getSentence(), getWord(), getWord())) +table.appendItem(("This is the end", "Beautiful friend, This is the end My only friend", "the end", "...")) + + + + +root.mainloop() \ No newline at end of file diff --git a/tests/test.ui.007.events.py b/tests/test.ui.007.events.py new file mode 100755 index 00000000..7a17c9fa --- /dev/null +++ b/tests/test.ui.007.events.py @@ -0,0 +1,66 @@ +#!/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. + +import sys, os + +sys.path.append(os.path.join(sys.path[0],'..')) +import TermTk as ttk + +ttk.TTkLog.use_default_file_logging() + +root = ttk.TTk() +btn1 = ttk.TTkButton(parent=root, x=0, y=0, width=15, height=3, text='Hide Window1') +btn2 = ttk.TTkButton(parent=root, x=0, y=3, width=15, height=3, text='Show Window1') +btn3 = ttk.TTkButton(parent=root, x=0, y=6, width=28, height=3, text='Hide Window2.1 and Window3') +btn4 = ttk.TTkButton(parent=root, x=0, y=9, width=28, height=3, text='Show Window2.1 and Window3') + +win1 = ttk.TTkWindow(parent=root,pos = (1,4), size=(60,30), title="Test Window 1", border=True) +# Connect the Buttons (clicked) signals to the Window slots (hide/show) +btn1.clicked.connect(win1.hide) +btn2.clicked.connect(win1.show) + +win2_1 = ttk.TTkWindow(parent=win1,pos = (3,3), size=(40,20), title="Test Window 2.1", layout=ttk.TTkHBoxLayout(), border=True) +btn3.clicked.connect(win2_1.hide) +btn4.clicked.connect(win2_1.show) +ttk.TTkTestWidget(parent=win2_1, border=False) + + +win2_2 = ttk.TTkWindow(parent=win1,pos = (5,5), size=(40,20), title="Test Window 2.2", layout=ttk.TTkHBoxLayout(), border=True) +ttk.TTkTestWidget(parent=win2_2, border=False) + + +win3 = ttk.TTkWindow(parent=root,pos = (20,7), size=(60,20), title="Test Window 3", layout=ttk.TTkHBoxLayout(), border=True) +btn3.clicked.connect(win3.hide) +btn4.clicked.connect(win3.show) + +ttk.TTkTestWidget(parent=win3, border=True, maxWidth=30, minWidth=20) +rightFrame = ttk.TTkFrame(parent=win3, layout=ttk.TTkVBoxLayout(), border=True) + +ttk.TTkTestWidget(parent=rightFrame, border=True, maxSize=(50,15), minSize=(30,8)) +bottomrightframe = ttk.TTkFrame(parent=rightFrame,border=True) + +win4 = ttk.TTkWindow(parent=bottomrightframe, pos = (3,3), size=(40,20), title="Test Window 4", layout=ttk.TTkHBoxLayout(), border=True) +ttk.TTkTestWidget(parent=win4, border=False) + +root.mainloop() \ No newline at end of file diff --git a/tests/test.ui.008.table.py b/tests/test.ui.008.table.py new file mode 100755 index 00000000..2ae4a0a5 --- /dev/null +++ b/tests/test.ui.008.table.py @@ -0,0 +1,53 @@ +#!/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. + +import sys, os +import 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 getSentence(): + return " ".join([getWord() for i in range(0,random.randint(8, 30))]) + + +ttk.TTkLog.use_default_file_logging() + +root = ttk.TTk() +win1 = ttk.TTkWindow(parent=root,pos = (3,3), size=(40,20), title="Test Table 1", layout=ttk.TTkHBoxLayout(), border=True) +table = ttk.TTkTable(parent=win1) + +table.setColumnSize((20,-1,10,15)) +table.appendItem(("","You see it's all clear, You were meant to be here, From the beginning","","")) +for i in range(0, 100): + table.appendItem((str(i)+" - "+getWord(), getSentence(), getWord(), getWord())) +table.appendItem(("This is the end", "Beautiful friend, This is the end My only friend", "the end", "...")) + + + + +root.mainloop() \ No newline at end of file