diff --git a/.gitignore b/.gitignore index b6e47617..56548c06 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,9 @@ __pycache__/ *.py[cod] *$py.class +# tmp folder +tmp + # C extensions *.so diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..93d50e4a --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +doc: + sphinx-build -b html doc/source doc/build \ No newline at end of file diff --git a/README.md b/README.md index be52465f..8df13754 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,15 @@ # pyTermTk -Python Terminal Toolkit +#### Python Terminal Toolkit +Text-based user interface library ([TUI](https://en.wikipedia.org/wiki/Text-based_user_interface)) +Evolved from the dead project [pyCuT](https://github.com/ceccopierangiolieugenio/pyCuT) +and inspired by a mix of [Qt5](https://www.riverbankcomputing.com/static/Docs/PyQt5/),[GTK](https://pygobject.readthedocs.io/en/latest/) and [tkinter](https://docs.python.org/3/library/tkinter.html) api definition with a touch of personal interpretation ## Quick Test/Try #### Clone ```shell clone git@github.com:ceccopierangiolieugenio/pyTermTk.git -pyTermTk +cd pyTermTk ``` #### Run Basic input test diff --git a/TermTk/TTkCore/__init__.py b/TermTk/TTkCore/__init__.py index 2472d25a..d06af7c5 100644 --- a/TermTk/TTkCore/__init__.py +++ b/TermTk/TTkCore/__init__.py @@ -1,3 +1,4 @@ from .log import * from .cfg import * -from .ttk import * \ No newline at end of file +from .ttk import * +from .color import * \ No newline at end of file diff --git a/TermTk/TTkCore/canvas.py b/TermTk/TTkCore/canvas.py index bf0c1f91..5a156db9 100644 --- a/TermTk/TTkCore/canvas.py +++ b/TermTk/TTkCore/canvas.py @@ -25,6 +25,7 @@ import TermTk.libbpytop as lbt from TermTk.TTkCore.log import TTkLog from TermTk.TTkCore.cfg import * +from TermTk.TTkCore.color import * from TermTk.TTkCore.helper import * class TTkCanvas: @@ -49,7 +50,7 @@ class TTkCanvas: self._width = kwargs.get('width', 0 ) self._height = kwargs.get('height', 0 ) self.resize(self._width, self._height) - TTkLog.debug((self._width, self._height)) + # TTkLog.debug((self._width, self._height)) def getWidget(self): return self._widget @@ -65,7 +66,7 @@ class TTkCanvas: self._colors = [[]]*h for i in range(0,h): self._data[i] = [' ']*w - self._colors[i] = [None]*w + self._colors[i] = [TTkColor.RST]*w self._width = w self._height = h TTkHelper.addPaintBuffer(self) @@ -74,10 +75,29 @@ class TTkCanvas: # TODO: Figure out how to use this pass - def drawBox(self, x, y, w, h): + def drawText(self, pos, text, color=TTkColor.RST): def _set(_y,_x,_c): - if _y= 0 and _y >=0 : self._data[_y][_x] = _c + self._colors[_y][_x] = color + x,y = pos + arr = list(text) + for i in range(0, len(arr)): + _set(y, x+i, arr[i]) + + + def drawBox(self, pos, size, color=TTkColor.RST): + x,y = pos + w,h = size + # TODO: Handle Clip/OutOfBorder + def _set(_y,_x,_c): + if _y < self._height and \ + _x < self._width and \ + _x >= 0 and _y >=0 : + self._data[_y][_x] = _c + self._colors[_y][_x] = color # 4 corners _set(y, x, "╔") _set(y, x+w-1, "╗") @@ -96,25 +116,43 @@ class TTkCanvas: def execPaint(self, winw, winh): pass - def paintCanvas(self, canvas, x, y, w, h): + ''' + geom = (x,y,w,h) + bound = (x,y,w,h) + ''' + def paintCanvas(self, canvas, geom, slice, bound): # TTkLog.debug(f"PaintCanvas:{(x,y,w,h)}") - x = x if x=self._width: x=self._width-1 + if y>=self._height: y=self._height-1 + if w>=self._width-x: w=self._width-x + if h>=self._height-y: h=self._height-y + + xoffset = 0 if x>=bx else bx-x + yoffset = 0 if y>=by else by-y + wslice = w if x+w < bx+bw else bx+bw-x + hslice = h if y+h < by+bh else by+bh-y + + for iy in range(yoffset,hslice): + for ix in range(xoffset,wslice): + #TTkLog.debug(f"PaintCanvas:{(ix,iy)}") self._data[y+iy][x+ix] = canvas._data[iy][ix] self._colors[y+iy][x+ix] = canvas._colors[iy][ix] def pushToTerminal(self, x, y, w, h): - TTkLog.debug("pushToTerminal") - ansi = "" + # TTkLog.debug("pushToTerminal") + lastcolor = None for y in range(0, self._height): - s = lbt.Mv.t(y+1,1) + ansi = lbt.Mv.t(y+1,1) for x in range(0, self._width): - c = self._data[y][x] - s+=c - ansi += s - - lbt.Term.push(ansi) + ch = self._data[y][x] + color = self._colors[y][x] + if color != lastcolor: + ansi += color + lastcolor = color + ansi+=ch + lbt.Term.push(ansi) \ No newline at end of file diff --git a/TermTk/TTkCore/color.py b/TermTk/TTkCore/color.py new file mode 100644 index 00000000..95a3b2f2 --- /dev/null +++ b/TermTk/TTkCore/color.py @@ -0,0 +1,36 @@ +#!/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.log import TTkLog +from TermTk.TTkCore.cfg import * +from TermTk.TTkCore.helper import * + +class TTkColor: + RST = '\033[0m' + @staticmethod + def fg(*args, **kwargs): + return TTkHelper.Color.fg(*args, **kwargs) + @staticmethod + def bg(*args, **kwargs): + return TTkHelper.Color.bg(*args, **kwargs) \ No newline at end of file diff --git a/TermTk/TTkCore/helper.py b/TermTk/TTkCore/helper.py index 82f81c2d..b2d6338d 100644 --- a/TermTk/TTkCore/helper.py +++ b/TermTk/TTkCore/helper.py @@ -49,39 +49,32 @@ class TTkHelper: TTkHelper._paintBuffer = [] TTkHelper._updateWidget = [] - @staticmethod - def execPaint(cw, ch): - if TTkHelper._rootCanvas is None : - return - for canvas in TTkHelper._paintBuffer: - widget = canvas.getWidget() - x = widget.getX() - y = widget.getY() - w = widget.getWidth() - h = widget.getHeight() - TTkHelper._rootCanvas.paintCanvas(canvas, x, y, w, h) - TTkHelper._paintBuffer = [] - @staticmethod def paintAll(): if TTkHelper._rootCanvas is None: return + processed = [] for widget in TTkHelper._updateWidget: + processed.append(widget) widget.paintEvent() + widget.paintChildCanvas() + p = widget.parentWidget() + #if p in TTkHelper._updateWidget and p not in processed: + widget.paintNotifyParent() TTkHelper._updateWidget = [] - TTkHelper.execPaint(TTkGlbl.term_w,TTkGlbl.term_h) TTkHelper._rootCanvas.pushToTerminal(0, 0, TTkGlbl.term_w, TTkGlbl.term_h) - # curses.panel.update_panels() - # TTkGlbl.GLBL['screen'].refresh() - @staticmethod def absPos(widget) -> (int,int): - pos = TTkHelper.absParentPos(widget) - return widget.pos() + pos + ppos = TTkHelper.absParentPos(widget) + wpos = widget.pos() + return (wpos[0]+ppos[0], wpos[1]+ppos[1]) @staticmethod def absParentPos(widget) -> (int,int): if widget is None or widget.parentWidget() is None: return (0, 0) - return TTkHelper.absPos(widget.parentWidget()) \ No newline at end of file + return TTkHelper.absPos(widget.parentWidget()) + + class Color(lbt.Color): pass + class Mv(lbt.Mv): pass diff --git a/TermTk/TTkCore/ttk.py b/TermTk/TTkCore/ttk.py index 33fda681..9948e087 100644 --- a/TermTk/TTkCore/ttk.py +++ b/TermTk/TTkCore/ttk.py @@ -78,10 +78,12 @@ class TTk(TTkWidget): evt = self.events.get() if evt is TTk.MOUSE_EVENT: mevt = self.mouse_events.get() - TTkLog.info(f"Mouse Event: {mevt}") + self.mouseEvent(mevt) + # TTkLog.info(f"Mouse Event: {mevt}") elif evt is TTk.KEY_EVENT: kevt = self.key_events.get() - TTkLog.info(f"Key Event: {kevt}") + self.keyEvent(kevt) + # TTkLog.info(f"Key Event: {kevt}") pass elif evt is TTk.TIME_EVENT: pass diff --git a/TermTk/TTkWidgets/__init__.py b/TermTk/TTkWidgets/__init__.py index 93b9ca9d..b4ee4ee3 100644 --- a/TermTk/TTkWidgets/__init__.py +++ b/TermTk/TTkWidgets/__init__.py @@ -1 +1,5 @@ -from .frame import * +from .frame import * +from .button import * +from .layout import * +from .widget import * +from .testwidget import * \ No newline at end of file diff --git a/TermTk/TTkWidgets/button.py b/TermTk/TTkWidgets/button.py index a0033998..30e80a9f 100644 --- a/TermTk/TTkWidgets/button.py +++ b/TermTk/TTkWidgets/button.py @@ -20,4 +20,42 @@ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. \ No newline at end of file +# SOFTWARE. + +from TermTk.TTkCore.log import TTkLog +from TermTk.TTkCore.color import TTkColor +from TermTk.TTkWidgets.widget import * + +class TTkButton(TTkWidget): + def __init__(self, *args, **kwargs): + TTkWidget.__init__(self, *args, **kwargs) + self._text = kwargs.get('text', "" ) + self._border = kwargs.get('border', True ) + if self._border: + self._padt = 1 + self._padb = 1 + self._padl = 1 + self._padr = 1 + self._pressed = False + self.update() + + def paintEvent(self): + if self._pressed: + borderColor = TTkColor.fg("#00ffff") + textColor = TTkColor.fg("#0000ff") + else: + borderColor = TTkColor.fg("#ffff00") + textColor = TTkColor.fg("#00ff00") + self._canvas.drawText(pos=(1,1), color=textColor ,text=self._text) + if self._border: + self._canvas.drawBox(pos=(0,0),size=(self._width,self._height),color=borderColor) + + def mousePressEvent(self, evt): + TTkLog.debug(f"{self._name} Test Mouse {evt}") + self._pressed = True + self.update() + + def mouseReleaseEvent(self, evt): + TTkLog.debug(f"{self._name} Test Mouse {evt}") + self._pressed = False + self.update() \ No newline at end of file diff --git a/TermTk/TTkWidgets/frame.py b/TermTk/TTkWidgets/frame.py index bb549d15..6cf5745f 100644 --- a/TermTk/TTkWidgets/frame.py +++ b/TermTk/TTkWidgets/frame.py @@ -29,11 +29,12 @@ class TTkFrame(TTkWidget): def __init__(self, *args, **kwargs): TTkWidget.__init__(self, *args, **kwargs) self._border = kwargs.get('border', True ) - self.update() + if self._border: + self._padt = 1 + self._padb = 1 + self._padl = 1 + self._padr = 1 def paintEvent(self): if self._border: - self._canvas.drawBox(0,0,self._width,self._height) - - - + self._canvas.drawBox(pos=(0,0),size=(self._width,self._height)) \ No newline at end of file diff --git a/TermTk/TTkWidgets/testwidget.py b/TermTk/TTkWidgets/testwidget.py new file mode 100644 index 00000000..f06ed634 --- /dev/null +++ b/TermTk/TTkWidgets/testwidget.py @@ -0,0 +1,64 @@ +#!/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.log import TTkLog +from TermTk.TTkCore.color import TTkColor +from TermTk.TTkWidgets.widget import * +from TermTk.TTkWidgets.button import * +from TermTk.TTkWidgets.frame import * + +class _TestContent(TTkWidget): + def paintEvent(self): + # TTkLog.debug(f"Test Paint - {self._name}") + self._canvas.drawText(pos=(0,0),text=f"Test Widget [{self._parent._name}]") + self._canvas.drawText(pos=(0,1),text=f"x,y ({self._parent._x},{self._parent._y})") + self._canvas.drawText(pos=(0,2),text=f"w,h ({self._parent._width},{self._parent._height})") + self._canvas.drawText(pos=(0,3),text=f"max w,h ({self._parent._maxw},{self._parent._maxh})") + self._canvas.drawText(pos=(0,4),text=f"min w,h ({self._parent._minw},{self._parent._minh})") + y=6; self._canvas.drawText(pos=(0,y),color=TTkColor.fg("#ff0000"),text="Lorem ipsum dolor sit amet,") + y+=1; self._canvas.drawText(pos=(0,y),color=TTkColor.fg("#ff8800"),text="consectetur adipiscing elit,") + y+=1; self._canvas.drawText(pos=(0,y),color=TTkColor.fg("#ffff00"),text="sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.") + y+=1; self._canvas.drawText(pos=(0,y),color=TTkColor.fg("#00ff00"),text="Ut enim ad minim veniam,") + y+=1; self._canvas.drawText(pos=(0,y),color=TTkColor.fg("#00ffff"),text="quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.") + y+=1; self._canvas.drawText(pos=(0,y),color=TTkColor.fg("#0088ff"),text="Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.") + y+=1; self._canvas.drawText(pos=(0,y),color=TTkColor.fg("#0000ff"),text="Excepteur sint occaecat cupidatat non proident,") + y+=1; self._canvas.drawText(pos=(0,y),color=TTkColor.fg("#ff00ff"),text="sunt in culpa qui officia deserunt mollit anim id est laborum.") + + + +class TTkTestWidget(TTkFrame): + ID = 1 + def __init__(self, *args, **kwargs): + TTkFrame.__init__(self, *args, **kwargs) + #self.setLayout(TTkHBoxLayout()) + self._name = f"TestWidget-{TTkTestWidget.ID}" + TTkButton(parent=self, x=1, y=1, width=15, height=3, text=' Test Button') + _TestContent(parent=self, x=1, y=4, width=50, height=50, name=f"content-{self._name}") + TTkTestWidget.ID+=1 + + def mousePressEvent(self, evt): + TTkLog.debug(f"{self._name} Test Mouse {evt}") + + def mouseDragEvent(self, evt): + TTkLog.debug(f"{self._name} Test Mouse {evt}") \ No newline at end of file diff --git a/TermTk/TTkWidgets/widget.py b/TermTk/TTkWidgets/widget.py index 37284ada..0f352105 100644 --- a/TermTk/TTkWidgets/widget.py +++ b/TermTk/TTkWidgets/widget.py @@ -22,50 +22,81 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +import TermTk.libbpytop as lbt from TermTk.TTkCore.canvas import * from TermTk.TTkCore.cfg import * -from .layout import * +from TermTk.TTkWidgets.layout import * class TTkWidget: + ''' + Terminal + ┌─────────────────────────────────────────┐ + │ │ + │ TTkWidget width │ + │ (x,y)┌─────────────────────────┐ │ + │ │ padt │ │ + │ │ ┌───────────────┐ │ height │ + │ │padl│ Layout/childs │padr│ │ + │ │ └───────────────┘ │ │ + │ │ padl │ │ + │ └─────────────────────────┘ │ + └─────────────────────────────────────────┘ + ''' def __init__(self, *args, **kwargs): self._childs = [] + self._name = kwargs.get('name', None ) self._parent = kwargs.get('parent', None ) self._x = kwargs.get('x', 0 ) self._y = kwargs.get('y', 0 ) self._width = kwargs.get('width' , 0 ) self._height = kwargs.get('height', 0 ) - self._maxw = 0x80000000 - self._maxh = 0x80000000 - self._minw = 0x00000000 - self._minh = 0x00000000 - self._layout = TTkLayout() + self._padt = kwargs.get('paddingTop', 0 ) + self._padb = kwargs.get('paddingBottom', 0 ) + self._padl = kwargs.get('paddingLeft', 0 ) + self._padr = kwargs.get('paddingRight', 0 ) + self._maxw = 0x10000 + self._maxh = 0x10000 + self._minw = 0x00000 + self._minh = 0x00000 self._canvas = TTkCanvas( widget = self, width = self._width , height = self._height ) + self.setLayout(TTkLayout()) if self._parent is not None and \ self._parent._layout is not None: self._parent._layout.addWidget(self) - def getX(self): return self._x - def getY(self): return self._y - def getWidth(self): return self._width - def getHeight(self): return self._height - - def pos(self): - return (self._x, self._y) - def addLayout(self, l): self._layout = l def paintEvent(self): pass + def paintChildCanvas(self): + # paint over child canvas + lx,ly,lw,lh = self._layout.geometry() + for i in range(self._layout.count()): + item = self._layout.itemAt(i) + 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)) + + def paintNotifyParent(self): + parent = self._parent + while parent is not None: + parent.paintChildCanvas() + parent = parent._parent + + def move(self, x, y): self._x = x self._y = y self._canvas.move(self._x, self._y) - if self._layout is not None: - self._layout.setGeometry(self._x, self._y, self._width, self._height) self.update() def resize(self, w, h): @@ -73,7 +104,10 @@ class TTkWidget: self._height = h self._canvas.resize(self._width, self._height) if self._layout is not None: - self._layout.setGeometry(self._x, self._y, self._width, self._height) + self._layout.setGeometry( + self._padl, self._padt, + self._width - self._padl - self._padr, + self._height - self._padt - self._padb) self.update() def setGeometry(self, x, y, w, h): @@ -82,6 +116,7 @@ class TTkWidget: def mouseDoubleClickEvent(self, evt): pass def mouseMoveEvent(self, evt): pass + def mouseDragEvent(self, evt): pass def mousePressEvent(self, evt): pass def mouseReleaseEvent(self, evt): pass def wheelEvent(self, evt): pass @@ -90,8 +125,87 @@ class TTkWidget: def keyPressEvent(self, evt): pass def keyReleaseEvent(self, evt): pass - def event(self, evt): + @staticmethod + def _mouseEventLayoutHandle(evt, layout): + x, y = evt.x, evt.y + lx,ly,lw,lh =layout.geometry() + # opt of bounds + #x-=lx + #y-=ly + if x<0 or x>lw or y<0 or y>lh: + return True + for i in range(layout.count()): + item = layout.itemAt(i) + if isinstance(item, TTkWidgetItem) and not item.isEmpty(): + widget = item.widget() + wevt = None + mouseEvent = False + if isinstance(evt, lbt.MouseEvent): + mouseEvent = True + wx,wy,ww,wh = widget.geometry() + # Skip the mouse event if outside this widget + if x >= wx and x=wy and y")) continue code = int(m.group(1)) - x = int(m.group(2)) - y = int(m.group(3)) + x = int(m.group(2))-1 + y = int(m.group(3))-1 state = m.group(4) key = MouseEvent.NoButton evt = MouseEvent.NoEvent diff --git a/docs/TODO.md b/docs/TODO.md index b65db7f1..62c74ecc 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -25,6 +25,8 @@ ## Logs - [x] Log Class + - [ ] Run Logger on a separate thread (push sring to a queue) + - [ ] Include option to force print - [ ] Log helpers - [x] File and Stdout logger - [ ] logger auto integration diff --git a/tests/test.draw.002.py b/tests/test.draw.002.py index 262d4f4e..3e40f772 100755 --- a/tests/test.draw.002.py +++ b/tests/test.draw.002.py @@ -29,43 +29,33 @@ import time sys.path.append(os.path.join(sys.path[0],'..')) from TermTk.libbpytop import Term, Mv, Color from TermTk import TTkLog +from TermTk.TTkCore import TTkColor +from TermTk.TTkCore import TTkHelper -def message_handler(mode, context, message): - log = logging.debug - if mode == TTkLog.InfoMsg: log = logging.info - elif mode == TTkLog.WarningMsg: log = logging.warning - elif mode == TTkLog.CriticalMsg: log = logging.critical - elif mode == TTkLog.FatalMsg: log = logging.fatal - elif mode == TTkLog.ErrorMsg: log = logging.error - log(f"{context.file} {message}") - -logging.basicConfig(level=logging.DEBUG, - filename='session.log', - format='%(levelname)s:(%(threadName)-9s) %(message)s',) -TTkLog.installMessageHandler(message_handler) +TTkLog.use_default_file_logging() Term.init(mouse=False) TTkLog.info("Starting") Term.push( - Mv.t(2,4) + # Cursor x:2, y:4 - Color.fg("#ff0000") + + TTkHelper.Mv.t(2,4) + # Cursor x:2, y:4 + TTkColor.fg("#ff0000") + "Test Text 3" ) time.sleep(1) TTkLog.info("next : 2") Term.push( - Mv.d(1) + Mv.l(3) + # Cursor 1 Down, 3 Left - Color.bg("#550088") + + TTkHelper.Mv.d(1) + Mv.l(3) + # Cursor 1 Down, 3 Left + TTkColor.bg("#550088") + "Test Text 2" ) time.sleep(1) TTkLog.info("next : 1") Term.push( - Mv.d(1) + Mv.l(3) + # Cursor 1 Down, 3 Left - Color.fg("#00ff00") + - Color.bg("#555500") + + TTkHelper.Mv.d(1) + Mv.l(3) + # Cursor 1 Down, 3 Left + TTkColor.fg("#00ff00") + + TTkColor.bg("#555500") + "Test Text 1" ) time.sleep(1) diff --git a/tests/test.ui.002.py b/tests/test.ui.002.py index 35c68f2a..d3c06eeb 100755 --- a/tests/test.ui.002.py +++ b/tests/test.ui.002.py @@ -30,16 +30,16 @@ import TermTk as ttk ttk.TTkLog.use_default_file_logging() root = ttk.TTk() -root._layout = ttk.TTkHBoxLayout() +root.setLayout(ttk.TTkHBoxLayout()) ttk.TTkFrame(parent=root,border=True) rightframe = ttk.TTkFrame(parent=root) -rightframe._layout = ttk.TTkVBoxLayout() +rightframe.setLayout(ttk.TTkVBoxLayout()) ttk.TTkFrame(parent=rightframe, border=True) -centerrightframe=ttk.TTkFrame(parent=rightframe) +centerrightframe=ttk.TTkFrame(parent=rightframe, border=True) ttk.TTkFrame(parent=rightframe, border=True) -centerrightframe._layout = ttk.TTkHBoxLayout() +centerrightframe.setLayout(ttk.TTkHBoxLayout()) ttk.TTkFrame(parent=centerrightframe, border=True) ttk.TTkFrame(parent=centerrightframe, border=True) diff --git a/tests/test.ui.003.py b/tests/test.ui.003.py new file mode 100755 index 00000000..d0211cfc --- /dev/null +++ b/tests/test.ui.003.py @@ -0,0 +1,54 @@ +#!/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() +root.setLayout(ttk.TTkHBoxLayout()) + +ttk.TTkTestWidget(parent=root,border=True) +rightframe = ttk.TTkFrame(parent=root) +rightframe.setLayout(ttk.TTkVBoxLayout()) + +ttk.TTkFrame(parent=rightframe, border=True) +centerrightframe=ttk.TTkFrame(parent=rightframe, border=True) +centerrightframe.setLayout(ttk.TTkHBoxLayout()) +ttk.TTkTestWidget(parent=rightframe, border=True) + + +smallframe = ttk.TTkFrame(parent=centerrightframe, border=True) +# smallframe.setLayout(ttk.TTkVBoxLayout()) +ttk.TTkTestWidget(parent=centerrightframe, border=True) +ttk.TTkFrame(parent=centerrightframe, border=True) + +ttk.TTkButton(parent=smallframe, x=3, y=1, width=20, height=3, text=" Ui.003 Button") +ttk.TTkTestWidget(parent=smallframe, x=3, y=5, width=50, height=8, border=True) +ttk.TTkTestWidget(parent=smallframe, x=-5, y=14, width=50, height=15, border=True) + +root.mainloop() \ No newline at end of file