Browse Source

Merge pull request #160 from ceccopierangiolieugenio/dev

Current Dev Branch
pull/182/head 0.34.0-a
Ceccopierangiolieugenio 3 years ago committed by GitHub
parent
commit
52ec550156
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      TermTk/TTkAbstract/__init__.py
  2. 4
      TermTk/TTkAbstract/abstractitemmodel.py
  3. 12
      TermTk/TTkAbstract/abstractscrollarea.py
  4. 45
      TermTk/TTkAbstract/abstractscrollview.py
  5. 10
      TermTk/TTkCore/TTkTerm/__init__.py
  6. 60
      TermTk/TTkCore/TTkTerm/colors.py
  7. 2
      TermTk/TTkCore/TTkTerm/colors_ansi_map.py
  8. 36
      TermTk/TTkCore/TTkTerm/input.py
  9. 4
      TermTk/TTkCore/TTkTerm/inputkey.py
  10. 4
      TermTk/TTkCore/TTkTerm/inputmouse.py
  11. 5
      TermTk/TTkCore/TTkTerm/readinputlinux.py
  12. 2
      TermTk/TTkCore/TTkTerm/readinputlinux_thread.py
  13. 6
      TermTk/TTkCore/TTkTerm/term.py
  14. 24
      TermTk/TTkCore/TTkTerm/term_base.py
  15. 2
      TermTk/TTkCore/TTkTerm/term_pyodide.py
  16. 12
      TermTk/TTkCore/TTkTerm/term_unix.py
  17. 28
      TermTk/TTkCore/__init__.py
  18. 124
      TermTk/TTkCore/canvas.py
  19. 5
      TermTk/TTkCore/cfg.py
  20. 48
      TermTk/TTkCore/color.py
  21. 4
      TermTk/TTkCore/constant.py
  22. 4
      TermTk/TTkCore/filebuffer.py
  23. 33
      TermTk/TTkCore/helper.py
  24. 4
      TermTk/TTkCore/log.py
  25. 2
      TermTk/TTkCore/propertyanimation.py
  26. 10
      TermTk/TTkCore/signal.py
  27. 18
      TermTk/TTkCore/string.py
  28. 3
      TermTk/TTkCore/timer.py
  29. 4
      TermTk/TTkCore/timer_pyodide.py
  30. 9
      TermTk/TTkCore/timer_unix.py
  31. 46
      TermTk/TTkCore/ttk.py
  32. 2
      TermTk/TTkCore/util.py
  33. 12
      TermTk/TTkGui/__init__.py
  34. 4
      TermTk/TTkGui/clipboard.py
  35. 4
      TermTk/TTkGui/drag.py
  36. 24
      TermTk/TTkGui/textcursor.py
  37. 4
      TermTk/TTkGui/textdocument.py
  38. 6
      TermTk/TTkGui/textwrap1.py
  39. 2
      TermTk/TTkGui/tooltip.py
  40. 4
      TermTk/TTkLayouts/__init__.py
  41. 4
      TermTk/TTkLayouts/boxlayout.py
  42. 4
      TermTk/TTkLayouts/gridlayout.py
  43. 22
      TermTk/TTkLayouts/layout.py
  44. 2
      TermTk/TTkTemplates/__init__.py
  45. 2
      TermTk/TTkTemplates/dragevents.py
  46. 2
      TermTk/TTkTemplates/keyevents.py
  47. 2
      TermTk/TTkTemplates/mouseevents.py
  48. 12
      TermTk/TTkTestWidgets/__init__.py
  49. 4
      TermTk/TTkTestWidgets/keypressview.py
  50. 4
      TermTk/TTkTestWidgets/keypressviewfont.py
  51. 4
      TermTk/TTkTestWidgets/logviewer.py
  52. 5
      TermTk/TTkTestWidgets/testabstractscroll.py
  53. 4
      TermTk/TTkTestWidgets/testwidget.py
  54. 6
      TermTk/TTkTestWidgets/testwidgetsizes.py
  55. 6
      TermTk/TTkTestWidgets/tominspector.py
  56. 2
      TermTk/TTkTheme/draw_ascii.py
  57. 2
      TermTk/TTkTheme/draw_utf8.py
  58. 170
      TermTk/TTkTheme/theme.py
  59. 4
      TermTk/TTkUiTools/__init__.py
  60. 39
      TermTk/TTkUiTools/properties/__init__.py
  61. 2
      TermTk/TTkUiTools/properties/button.py
  62. 2
      TermTk/TTkUiTools/properties/checkbox.py
  63. 2
      TermTk/TTkUiTools/properties/colorpicker.py
  64. 2
      TermTk/TTkUiTools/properties/combobox.py
  65. 49
      TermTk/TTkUiTools/properties/container.py
  66. 2
      TermTk/TTkUiTools/properties/filepicker.py
  67. 2
      TermTk/TTkUiTools/properties/frame.py
  68. 2
      TermTk/TTkUiTools/properties/label.py
  69. 22
      TermTk/TTkUiTools/properties/layout.py
  70. 2
      TermTk/TTkUiTools/properties/lineedit.py
  71. 2
      TermTk/TTkUiTools/properties/list_.py
  72. 2
      TermTk/TTkUiTools/properties/listwidget.py
  73. 3
      TermTk/TTkUiTools/properties/menu.py
  74. 4
      TermTk/TTkUiTools/properties/radiobutton.py
  75. 4
      TermTk/TTkUiTools/properties/resizableframe.py
  76. 2
      TermTk/TTkUiTools/properties/scrollarea.py
  77. 4
      TermTk/TTkUiTools/properties/scrollbar.py
  78. 2
      TermTk/TTkUiTools/properties/spacer.py
  79. 4
      TermTk/TTkUiTools/properties/spinbox.py
  80. 4
      TermTk/TTkUiTools/properties/splitter.py
  81. 2
      TermTk/TTkUiTools/properties/tabwidget.py
  82. 4
      TermTk/TTkUiTools/properties/texedit.py
  83. 19
      TermTk/TTkUiTools/properties/widget.py
  84. 4
      TermTk/TTkUiTools/properties/window.py
  85. 42
      TermTk/TTkUiTools/uiloader.py
  86. 5
      TermTk/TTkUiTools/uiproperties.py
  87. 1
      TermTk/TTkWidgets/Fancy/__init__.py
  88. 29
      TermTk/TTkWidgets/Fancy/progressbar.py
  89. 4
      TermTk/TTkWidgets/Fancy/table.py
  90. 4
      TermTk/TTkWidgets/Fancy/tableview.py
  91. 4
      TermTk/TTkWidgets/Fancy/tree.py
  92. 4
      TermTk/TTkWidgets/Fancy/treeview.py
  93. 7
      TermTk/TTkWidgets/Fancy/treewidget.py
  94. 4
      TermTk/TTkWidgets/Fancy/treewidgetitem.py
  95. 12
      TermTk/TTkWidgets/TTkModelView/__init__.py
  96. 4
      TermTk/TTkWidgets/TTkModelView/filetree.py
  97. 4
      TermTk/TTkWidgets/TTkModelView/filetreewidget.py
  98. 4
      TermTk/TTkWidgets/TTkModelView/filetreewidgetitem.py
  99. 7
      TermTk/TTkWidgets/TTkModelView/tree.py
  100. 56
      TermTk/TTkWidgets/TTkModelView/treewidget.py
  101. Some files were not shown because too many files have changed in this diff Show More

6
TermTk/TTkAbstract/__init__.py

@ -1,3 +1,3 @@
from .abstractscrollview import TTkAbstractScrollViewInterface, TTkAbstractScrollView, TTkAbstractScrollViewGridLayout
from .abstractscrollarea import TTkAbstractScrollArea
from .abstractitemmodel import TTkAbstractItemModel
from .abstractscrollview import *
from .abstractscrollarea import *
from .abstractitemmodel import *

4
TermTk/TTkAbstract/abstractitemmodel.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkAbstractItemModel']
from TermTk.TTkCore.signal import pyTTkSignal
class TTkAbstractItemModel():

12
TermTk/TTkAbstract/abstractscrollarea.py

@ -20,15 +20,18 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkAbstractScrollArea']
from TermTk.TTkCore.constant import TTkK
# from TermTk.TTkCore.log import TTkLog
from TermTk.TTkCore.signal import pyTTkSlot
from TermTk.TTkWidgets.widget import TTkWidget
from TermTk.TTkWidgets.container import TTkContainer
from TermTk.TTkWidgets.scrollbar import TTkScrollBar
from TermTk.TTkLayouts.gridlayout import TTkGridLayout
from TermTk.TTkAbstract.abstractscrollview import TTkAbstractScrollViewInterface
class TTkAbstractScrollArea(TTkWidget):
class TTkAbstractScrollArea(TTkContainer):
__slots__ = (
'_processing', # this flag is required to avoid unnecessary loop on edge cases
'_viewport',
@ -123,7 +126,12 @@ class TTkAbstractScrollArea(TTkWidget):
raise TypeError("TTkAbstractScrollViewInterface is required in TTkAbstractScrollArea.setVewport(viewport)")
if self._viewport:
self._viewport.viewChanged.disconnect(self._viewportChanged)
self.layout().removeWidget(self._viewport)
# TODO: Remove this check once
# unified "addWidget" and "addItem" in the TTKGridLayout
if isinstance(viewport, TTkWidget):
self.layout().removeWidget(self._viewport)
else:
self.layout().removeItem(self._viewport)
self._viewport = viewport
self._viewport.viewChanged.connect(self._viewportChanged)
self._verticalScrollBar.sliderMoved.connect(self._vscrollMoved)

45
TermTk/TTkAbstract/abstractscrollview.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,10 +20,13 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkAbstractScrollViewInterface', 'TTkAbstractScrollView', 'TTkAbstractScrollViewGridLayout']
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.cfg import TTkCfg
from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal
from TermTk.TTkWidgets.widget import TTkWidget
from TermTk.TTkWidgets.container import TTkContainer
from TermTk.TTkLayouts.layout import TTkLayout
from TermTk.TTkLayouts.gridlayout import TTkGridLayout
class TTkAbstractScrollViewInterface():
@ -44,7 +45,7 @@ class TTkAbstractScrollViewInterface():
def getViewOffsets(self):
return self._viewOffsetX, self._viewOffsetY
class TTkAbstractScrollView(TTkWidget, TTkAbstractScrollViewInterface):
class TTkAbstractScrollView(TTkContainer, TTkAbstractScrollViewInterface):
__slots__ = (
'_viewOffsetX', '_viewOffsetY',
# Signals
@ -55,9 +56,9 @@ class TTkAbstractScrollView(TTkWidget, TTkAbstractScrollViewInterface):
self.viewMovedTo = pyTTkSignal(int, int) # x, y
self.viewSizeChanged = pyTTkSignal(int, int) # w, h
self.viewChanged = pyTTkSignal()
TTkWidget.__init__(self, *args, **kwargs)
self._viewOffsetX = 0
self._viewOffsetY = 0
TTkContainer.__init__(self, *args, **kwargs)
@pyTTkSlot(int, int)
def viewMoveTo(self, x: int, y: int):
@ -96,6 +97,38 @@ class TTkAbstractScrollView(TTkWidget, TTkAbstractScrollViewInterface):
self.viewChanged.emit()
return super().update(repaint, updateLayout, updateParent)
class TTkAbstractScrollViewLayout(TTkLayout, TTkAbstractScrollViewInterface):
__slots__ = (
'_viewOffsetX', '_viewOffsetY',
# Signals
'viewMovedTo', 'viewSizeChanged', 'viewChanged', '_excludeEvent')
def __init__(self, *args, **kwargs):
# Signals
self.viewMovedTo = pyTTkSignal(int, int) # x, y
self.viewSizeChanged = pyTTkSignal(int, int) # w, h
self.viewChanged = pyTTkSignal()
self._viewOffsetX = 0
self._viewOffsetY = 0
self._excludeEvent = False
TTkLayout.__init__(self, *args, **kwargs)
def viewFullAreaSize(self) -> (int, int):
_,_,w,h = self.fullWidgetAreaGeometry()
return w,h
def viewDisplayedSize(self) -> (int, int):
_,_,w,h = self.geometry()
return w,h
@pyTTkSlot(int, int)
def viewMoveTo(self, x: int, y: int):
self.setOffset(-x,-y)
def setGeometry(self, x, y, w, h):
TTkLayout.setGeometry(self, x, y, w, h)
self.viewChanged.emit()
class TTkAbstractScrollViewGridLayout(TTkGridLayout, TTkAbstractScrollViewInterface):
__slots__ = (
'_viewOffsetX', '_viewOffsetY',
@ -107,10 +140,10 @@ class TTkAbstractScrollViewGridLayout(TTkGridLayout, TTkAbstractScrollViewInterf
self.viewMovedTo = pyTTkSignal(int, int) # x, y
self.viewSizeChanged = pyTTkSignal(int, int) # w, h
self.viewChanged = pyTTkSignal()
TTkGridLayout.__init__(self, *args, **kwargs)
self._viewOffsetX = 0
self._viewOffsetY = 0
self._excludeEvent = False
TTkGridLayout.__init__(self, *args, **kwargs)
@pyTTkSlot(int, int)
def viewMoveTo(self, x: int, y: int):

10
TermTk/TTkCore/TTkTerm/__init__.py

@ -1,5 +1,5 @@
from .inputkey import TTkKeyEvent
from .inputmouse import TTkMouseEvent
from .colors import TTkTermColor
from .term import TTkTerm
from .input import TTkInput
from .inputkey import *
from .inputmouse import *
from .colors import *
from .term import *
from .input import *

60
TermTk/TTkCore/TTkTerm/colors.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2022 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkTermColor']
# Ansi Escape Codes:
# https://conemu.github.io/en/AnsiEscapeCodes.html
@ -30,14 +30,38 @@ import re
from .colors_ansi_map import ansiMap256, ansiMap16
class TTkTermColor():
BOLD = 0x01
ITALIC = 0x02
UNDERLINE = 0x04
STRIKETROUGH = 0x08
BLINKING = 0x10
BOLD = 0x01 # <ESC>[1m
FAINT = 0x02 # <ESC>[2m
ITALIC = 0x04 # <ESC>[3m
UNDERLINE = 0x08 # <ESC>[4m
BLINKING = 0x10 # <ESC>[5m
REVERSED = 0x20 # <ESC>[7m
HIDDEN = 0x40 # <ESC>[8m
STRIKETROUGH = 0x80 # <ESC>[9m
SGR_SET = { # CSI Pm m Character Attributes (SGR).
# Ps = 0 ⇒ Normal (default), VT100.
1: BOLD , # Ps = 1 ⇒ Bold, VT100.
2: FAINT , # Ps = 2 ⇒ Faint, decreased intensity, ECMA-48 2nd.
3: ITALIC , # Ps = 3 ⇒ Italicized, ECMA-48 2nd.
4: UNDERLINE , # Ps = 4 ⇒ Underlined, VT100.
5: BLINKING , # Ps = 5 ⇒ Blink, VT100. - This appears as Bold in X11R6 xterm.
7: REVERSED , # Ps = 7 ⇒ Inverse, VT100.
8: HIDDEN , # Ps = 8 ⇒ Invisible, i.e., hidden, ECMA-48 2nd, VT300.
9: STRIKETROUGH } # Ps = 9 ⇒ Crossed-out characters, ECMA-48 3rd.
SGR_RST = { # CSI Pm m Character Attributes (SGR).
# Ps = 2 1 ⇒ Doubly-underlined, ECMA-48 3rd.
22: ~(BOLD|FAINT), # Ps = 2 2 ⇒ Normal (neither bold nor faint), ECMA-48 3rd.
23: ~ITALIC, # Ps = 2 3 ⇒ Not italicized, ECMA-48 3rd.
24: ~UNDERLINE, # Ps = 2 4 ⇒ Not underlined, ECMA-48 3rd.
25: ~BLINKING, # Ps = 2 5 ⇒ Steady (not blinking), ECMA-48 3rd.
27: ~REVERSED, # Ps = 2 7 ⇒ Positive (not inverse), ECMA-48 3rd.
28: ~HIDDEN, # Ps = 2 8 ⇒ Visible, i.e., not hidden, ECMA-48 3rd, VT300.
29: ~STRIKETROUGH } # Ps = 2 9 ⇒ Not crossed-out, ECMA-48 3rd.
@staticmethod
def rgb2ansi(fg: tuple=None, bg:tuple=None, mod:int=0, clean:bool=False):
def rgb2ansi(fg: tuple=None, bg:tuple=None, mod:int=0, link:str='', clean:bool=False):
ret = []
if clean:
@ -50,15 +74,20 @@ class TTkTermColor():
if mod & TTkTermColor.BOLD:
ret.append('1')
if mod & TTkTermColor.FAINT:
ret.append('2')
if mod & TTkTermColor.ITALIC:
ret.append('3')
if mod & TTkTermColor.UNDERLINE:
ret.append('4')
if mod & TTkTermColor.STRIKETROUGH:
ret.append('9')
if mod & TTkTermColor.BLINKING:
ret.append('5')
if mod & TTkTermColor.REVERSED:
ret.append('7')
if mod & TTkTermColor.HIDDEN:
ret.append('8')
if mod & TTkTermColor.STRIKETROUGH:
ret.append('9')
if ret:
return f'\033[{";".join(str(x) for x in ret)}m'
else:
@ -108,11 +137,10 @@ class TTkTermColor():
bg = None
mod = 0
clean = True
elif s==1: mod += TTkTermColor.BOLD
elif s==3: mod += TTkTermColor.ITALIC
elif s==4: mod += TTkTermColor.UNDERLINE
elif s==9: mod += TTkTermColor.STRIKETROUGH
elif s==5: mod += TTkTermColor.BLINKING
elif _sgr:=TTkTermColor.SGR_SET.get(s,None):
mod |= _sgr
elif _sgr:=TTkTermColor.SGR_RST.get(s,None):
mod &= _sgr
return fg,bg,mod,clean

2
TermTk/TTkCore/TTkTerm/colors_ansi_map.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2022 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>

36
TermTk/TTkCore/TTkTerm/input.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkInput']
import re
from time import time
@ -46,12 +46,16 @@ class TTkInput:
'_readInput',
'_leftLastTime', '_midLastTime', '_rightLastTime',
'_leftTap', '_midTap', '_rightTap',
'_pasteBuffer', '_bracketedPaste',
# Signals
'inputEvent'
'inputEvent', 'pasteEvent'
)
def __init__(self):
self.inputEvent = pyTTkSignal(TTkKeyEvent, TTkMouseEvent)
self.pasteEvent = pyTTkSignal(str)
self._pasteBuffer = ""
self._bracketedPaste = False
self._readInput = None
self._leftLastTime = 0
self._midLastTime = 0
@ -79,7 +83,20 @@ class TTkInput:
mouse_re = re.compile(r"\033\[<(\d+);(\d+);(\d+)([mM])")
def key_process(self, stdinRead):
if self._bracketedPaste:
if stdinRead.endswith("\033[201~"):
self._pasteBuffer += stdinRead[:-6]
self._bracketedPaste = False
# due to the CRNL methos (don't ask me why) the terminal
# is substituting all the \n with \r
self.pasteEvent.emit(self._pasteBuffer.replace('\r','\n'))
self._pasteBuffer = ""
else:
self._pasteBuffer += stdinRead
return
mevt,kevt = None, None
if not stdinRead.startswith("\033[<"):
# Key Event
kevt = TTkKeyEvent.parse(stdinRead)
@ -153,12 +170,17 @@ class TTkInput:
evt = TTkMouseEvent.Move
mevt = TTkMouseEvent(x, y, key, evt, mod, tap, m.group(0).replace("\033", "<ESC>"))
if kevt or mevt:
self.inputEvent.emit(kevt, mevt)
return
if kevt is None and mevt is None:
hex = [f"0x{ord(x):02x}" for x in stdinRead]
TTkLog.error("UNHANDLED: "+stdinRead.replace("\033","<ESC>") + " - "+",".join(hex))
if stdinRead.startswith("\033[200~"):
self._pasteBuffer = stdinRead[6:]
self._bracketedPaste = True
return
self.inputEvent.emit(kevt, mevt)
hex = [f"0x{ord(x):02x}" for x in stdinRead]
TTkLog.error("UNHANDLED: "+stdinRead.replace("\033","<ESC>") + " - "+",".join(hex))
def main():

4
TermTk/TTkCore/TTkTerm/inputkey.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkKeyEvent']
from TermTk.TTkCore.constant import TTkK
class TTkKeyEvent:

4
TermTk/TTkCore/TTkTerm/inputmouse.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkMouseEvent']
from TermTk.TTkCore.constant import TTkK
class TTkMouseEvent:

5
TermTk/TTkCore/TTkTerm/readinputlinux.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2022 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -57,6 +55,9 @@ class ReadInput():
# Split all the ansi sequences
# or yield any separate input char
if stdinRead == '\033':
yield '\033'
continue
for sr in rm.findall(stdinRead):
if '\033' == sr[0]:
yield sr

2
TermTk/TTkCore/TTkTerm/readinputlinux_thread.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2022 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>

6
TermTk/TTkCore/TTkTerm/term.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2022 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,9 +20,11 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkTerm']
import importlib.util
if importlib.util.find_spec('pyodideProxy'):
from .term_pyodide import TTkTerm
else:
from .term_unix import TTkTerm
from .term_unix import TTkTerm

24
TermTk/TTkCore/TTkTerm/term_base.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2022 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -29,11 +27,14 @@ class TTkTermBase():
ALT_SCREEN = "\033[?1049h" #* Switch to alternate screen
NORMAL_SCREEN = "\033[?1049l" #* Switch to normal screen
SET_BRACKETED_PM = "\033[?2004h" # Ps = 2 0 0 4 ⇒ Set bracketed paste mode, xterm.
RESET_BRACKETED_PM = "\033[?2004l" # Ps = 2 0 0 4 ⇒ Reset bracketed paste mode, xterm.
class Mouse():
ON = "\033[?1002h\033[?1015h\033[?1006h" # Enable reporting of mouse position on click and release
OFF = "\033[?1002l" # Disable mouse reporting
DIRECT_ON = "\033[?1003h" # Enable reporting of mouse position at any movement
DIRECT_OFF = "\033[?1003l" # Disable direct mouse reporting
ON = "\033[?1002h\033[?1006h" # Enable reporting of mouse position on click and release
OFF = "\033[?1002l\033[?1006l" # Disable mouse reporting
DIRECT_ON = "\033[?1003h" # Enable reporting of mouse position at any movement
DIRECT_OFF = "\033[?1003l" # Disable direct mouse reporting
class Cursor():
# from:
@ -95,7 +96,10 @@ class TTkTermBase():
TTkTermBase.mouse = mouse | directMouse
TTkTermBase.directMouse = directMouse
TTkTermBase.Cursor.hide()
TTkTermBase.push(TTkTermBase.ALT_SCREEN + TTkTermBase.CLEAR + TTkTermBase.Cursor.HIDE + TTkTermBase.escTitle(TTkTermBase.title))
TTkTermBase.push(TTkTermBase.escTitle(TTkTermBase.title))
TTkTermBase.push(TTkTermBase.ALT_SCREEN)
TTkTermBase.push(TTkTermBase.SET_BRACKETED_PM)
TTkTermBase.push(TTkTermBase.CLEAR + TTkTermBase.Cursor.HIDE)
if TTkTermBase.mouse:
TTkTermBase.push(TTkTermBase.Mouse.ON)
if TTkTermBase.directMouse:
@ -107,20 +111,20 @@ class TTkTermBase():
@staticmethod
def exit():
TTkTermBase.push(TTkTermBase.Mouse.OFF + TTkTermBase.Mouse.DIRECT_OFF)
TTkTermBase.push(TTkTermBase.CLEAR + TTkTermBase.NORMAL_SCREEN + TTkTermBase.Cursor.SHOW + TTkTermBase.escTitle())
TTkTermBase.push(TTkTermBase.CLEAR + TTkTermBase.NORMAL_SCREEN + TTkTermBase.RESET_BRACKETED_PM + TTkTermBase.Cursor.SHOW + TTkTermBase.escTitle())
TTkTermBase.setEcho(True)
TTkTermBase.CRNL(True)
@staticmethod
def stop():
TTkTermBase.push(TTkTermBase.Mouse.OFF + TTkTermBase.Mouse.DIRECT_OFF)
TTkTermBase.push(TTkTermBase.CLEAR + TTkTermBase.NORMAL_SCREEN + TTkTermBase.Cursor.SHOW + TTkTermBase.escTitle())
TTkTermBase.push(TTkTermBase.CLEAR + TTkTermBase.NORMAL_SCREEN + TTkTermBase.RESET_BRACKETED_PM + TTkTermBase.Cursor.SHOW + TTkTermBase.escTitle())
TTkTermBase.setEcho(True)
TTkTermBase.CRNL(True)
@staticmethod
def cont():
TTkTermBase.push(TTkTermBase.ALT_SCREEN + TTkTermBase.CLEAR + TTkTermBase.Cursor.HIDE + TTkTermBase.escTitle(TTkTermBase.title))
TTkTermBase.push(TTkTermBase.ALT_SCREEN + TTkTermBase.SET_BRACKETED_PM + TTkTermBase.CLEAR + TTkTermBase.Cursor.HIDE + TTkTermBase.escTitle(TTkTermBase.title))
if TTkTermBase.mouse:
TTkTermBase.push(TTkTermBase.Mouse.ON)
if TTkTermBase.directMouse:

2
TermTk/TTkCore/TTkTerm/term_pyodide.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2022 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>

12
TermTk/TTkCore/TTkTerm/term_unix.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2022 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -31,6 +29,7 @@ except Exception as e:
exit(1)
from .term_base import TTkTermBase
from TermTk.TTkCore.log import TTkLog
class TTkTerm(TTkTermBase):
_sigWinChCb = None
@ -82,8 +81,13 @@ class TTkTerm(TTkTermBase):
@staticmethod
def _push(*args):
sys.stdout.write(str(*args))
sys.stdout.flush()
try:
sys.stdout.write(str(*args))
sys.stdout.flush()
except BlockingIOError as e:
TTkLog.fatal(f"{e=} {e.characters_written=}")
except Exception as e:
TTkLog.fatal(e)
TTkTermBase.push = _push
@staticmethod

28
TermTk/TTkCore/__init__.py

@ -1,13 +1,15 @@
from .signal import pyTTkSlot, pyTTkSignal
from .log import TTkLog
from .cfg import TTkCfg,TTkGlbl
from .util import TTkUtil
from .helper import TTkHelper
from .propertyanimation import TTkPropertyAnimation, TTkEasingCurve
from .ttk import TTk
from .canvas import TTkCanvas
from .color import TTkColor, TTkColorGradient, TTkLinearGradient
from .string import TTkString
from .timer import TTkTimer
from .filebuffer import TTkFileBuffer
from .TTkTerm import *
from .constant import *
from .signal import *
from .log import *
from .cfg import *
from .util import *
from .helper import *
from .propertyanimation import *
from .ttk import *
from .canvas import *
from .color import *
from .string import *
from .timer import *
from .filebuffer import *
from .TTkTerm import *

124
TermTk/TTkCore/canvas.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkCanvas']
from TermTk.TTkCore.TTkTerm.term import TTkTerm
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.log import TTkLog
@ -36,21 +36,19 @@ class TTkCanvas:
:param height: the height of the Canvas
'''
__slots__ = (
'_widget',
'_width', '_height', '_newWidth', '_newHeight',
'_theme',
'_data', '_colors',
'_bufferedData', '_bufferedColors',
'_visible', '_transparent', '_doubleBuffer')
def __init__(self, *args, **kwargs):
self._widget = kwargs.get('widget', None)
self._visible = True
self._transparent = False
self._doubleBuffer = False
self._width = 0
self._height = 0
self._data = [[0]]
self._colors = [[TTkColor.RST]]
self._data = [[]]
self._colors = [[]]
self._newWidth = kwargs.get('width', 0 )
self._newHeight = kwargs.get('height', 0 )
self.updateSize()
@ -63,8 +61,6 @@ class TTkCanvas:
def setTransparent(self, tr):
self._transparent = tr
def getWidget(self): return self._widget
def enableDoubleBuffer(self):
self._doubleBuffer = True
self._bufferedData, self._bufferedColors = self.copyBuffers()
@ -140,25 +136,23 @@ class TTkCanvas:
w,h = self.size()
if not size:
size=(w,h)
fx,fy = pos
fxa,fya = pos
fw,fh = size
fxb,fyb = fxa+fw, fya+fh
# the fill area is outside the boundaries
if fx >= w or fy>=h: return
if fx<0:
fw += fx
fx = 0
if fy<0:
fh += fy
fy = 0
if fw<=0 or fh<=0: return
fw = min(fw, w+fx)
fh = min(fh, h+fy)
if ( fxa >= w or fya >= h or
fxb <= 0 or fyb <= 0): return
fxa = max(0,fxa)
fya = max(0,fya)
fxb = min(w,fxb)
fyb = min(h,fyb)
fillCh = [char]*fw
fillColor = [color]*fw
for iy in range(fy,fy+fh):
self._data[iy][fx:fx+fw] = fillCh
self._colors[iy][fx:fx+fw] = fillColor
for iy in range(fya,fyb):
self._data[iy][fxa:fxb] = fillCh
self._colors[iy][fxa:fxb] = fillColor
def drawVLine(self, pos, size, color=TTkColor.RST):
if size == 0: return
@ -239,10 +233,10 @@ class TTkCanvas:
# Check the full wide chars on the edge of the two canvasses
if ((0 <= (x+a) < self._width) and self._data[y][x+a] == ''):
self._data[y][x+a] = TTkCfg.theme.unicodeWideOverflowCh[0]
self._colors[y][x+a] = TTkCfg.theme.unicodeWideOverflowColor
self._colors[y][x+a] = TTkString.unicodeWideOverflowColor
if ((0 <= (x+b-1) < self._width) and TTkString._isWideCharData(self._data[y][x+b-1])):
self._data[y][x+b-1] = TTkCfg.theme.unicodeWideOverflowCh[1]
self._colors[y][x+b-1] = TTkCfg.theme.unicodeWideOverflowColor
self._colors[y][x+b-1] = TTkString.unicodeWideOverflowColor
def drawText(self, text="", pos=(0,0), width=None, color=TTkColor.RST, alignment=TTkK.NONE, forceColor=False):
'''
@ -640,6 +634,14 @@ class TTkCanvas:
if bx+bw<0 or by+bh<0 or bx>=cw or by>=ch: return
if x+w<=bx or y+h<=by or bx+bw<=x or by+bh<=y: return
if (0,0,cw,ch)==geom==bound and (cw,ch)==canvas.size() and not canvas._transparent:
# fast Copy
# the canvas match exactly on top of the current one
for y in range(h):
self._data[y] = canvas._data[y].copy()
self._colors[y] = canvas._colors[y].copy()
return
x = min(x,cw-1)
y = min(y,ch-1)
w = min(w,cw-x)
@ -672,16 +674,32 @@ class TTkCanvas:
# Check the full wide chars on the edge of the two canvasses
if ((0 <= a < cw) and self._data[y+iy][a]==''):
self._data[y+iy][a] = TTkCfg.theme.unicodeWideOverflowCh[0]
self._colors[y+iy][a] = TTkCfg.theme.unicodeWideOverflowColor
self._colors[y+iy][a] = TTkString.unicodeWideOverflowColor
if ((0 < b <= cw) and self._data[y+iy][b-1] and TTkString._isWideCharData(self._data[y+iy][b-1])):
self._data[y+iy][b-1] = TTkCfg.theme.unicodeWideOverflowCh[1]
self._colors[y+iy][b-1] = TTkCfg.theme.unicodeWideOverflowColor
self._colors[y+iy][b-1] = TTkString.unicodeWideOverflowColor
if ((0 < a <= cw) and self._data[y+iy][a-1] and TTkString._isWideCharData(self._data[y+iy][a-1])):
self._data[y+iy][a-1] = TTkCfg.theme.unicodeWideOverflowCh[1]
self._colors[y+iy][a-1] = TTkCfg.theme.unicodeWideOverflowColor
self._colors[y+iy][a-1] = TTkString.unicodeWideOverflowColor
if ((0 <= b < cw) and self._data[y+iy][b]==''):
self._data[y+iy][b] = TTkCfg.theme.unicodeWideOverflowCh[0]
self._colors[y+iy][b] = TTkCfg.theme.unicodeWideOverflowColor
self._colors[y+iy][b] = TTkString.unicodeWideOverflowColor
def toAnsi(self):
# TTkLog.debug("pushToTerminal")
ret = ""
lastcolor = TTkColor.RST
for y in range(0, self._height):
ansi = str(TTkColor.RST)
for x in range(0, self._width):
ch = self._data[y][x]
color = self._colors[y][x]
if color != lastcolor:
ansi += str(color-lastcolor)
lastcolor = color
ansi+=ch
ret += ansi + '\n'
return ret
def pushToTerminal(self, x, y, w, h):
# TTkLog.debug("pushToTerminal")
@ -733,6 +751,56 @@ class TTkCanvas:
empty=True
# Reset the color at the end
TTkTerm.push(TTkColor.RST)
# TTkTerm.flush()
# Switch the buffer
self._bufferedData, self._bufferedColors = data, colors
self._data, self._colors = oldData, oldColors
def pushToTerminalBufferedNew(self, x, y, w, h):
# TTkLog.debug("pushToTerminal")
data, colors = self._data, self._colors
oldData, oldColors = self._bufferedData, self._bufferedColors
lastcolor = TTkColor.RST
empty = True
ansi = ""
for y,(lda,ldb,lca,lcb) in enumerate(zip(data,oldData,colors,oldColors)):
count = 0
chBk = ''
for x,(da,db,ca,cb) in enumerate(zip(lda,ldb,lca,lcb)):
if da==db and ca==cb:
if not empty:
ansi += "" if not chBk else chBk*count if count<=4 else f"{chBk}\033[{count-1}b"
TTkTerm.push(ansi)
count = 0
chBk = ''
empty=True
continue
ch = da
color = ca
if empty:
ansi = ("" if not chBk else chBk*count if count<=4 else f"{chBk}\033[{count-1}b") + TTkTerm.Cursor.moveTo(y+1,x+1)
empty = False
count = 0
chBk = ''
if color != lastcolor:
ansi += ("" if not chBk else chBk*count if count<=4 else f"{chBk}\033[{count-1}b") + str(color-lastcolor)
lastcolor = color
count = 0
chBk = ''
# "Collect the consecutive characters"
if ch == chBk:
count+=1
else:
ansi += "" if not chBk else chBk*count if count<=4 else f"{chBk}\033[{count-1}b"
chBk = ch
count=1
# ansi+=ch
if not empty:
ansi += "" if not chBk else chBk*count if count<=4 else f"{chBk}\033[{count-1}b"
TTkTerm.push(ansi)
empty=True
# Reset the color at the end
TTkTerm.push(TTkColor.RST)
# Switch the buffer
self._bufferedData, self._bufferedColors = data, colors
self._data, self._colors = oldData, oldColors

5
TermTk/TTkCore/cfg.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkCfg', 'TTkGlbl']
from TermTk.TTkCore.constant import TTkK
class TTkCfg:
@ -33,6 +33,7 @@ class TTkCfg:
toolTipTime = 1
maxFps = 65
doubleBuffer = True
doubleBufferNew = False
scrollDelta = 5
theme = None

48
TermTk/TTkCore/color.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkColor', 'TTkColorGradient', 'TTkLinearGradient']
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.helper import TTkHelper
@ -61,12 +61,13 @@ from TermTk.TTkCore.helper import TTkHelper
# [49m 2.53 set background color to default (black)
class _TTkColor:
__slots__ = ('_fg','_bg','_mod', '_colorMod', '_buffer', '_clean')
__slots__ = ('_fg','_bg','_mod', '_colorMod', '_link', '_buffer', '_clean')
_fg: tuple; _bg: tuple; _mod: int
def __init__(self, fg:tuple=None, bg:tuple=None, mod:int=0, colorMod=None, clean=False):
def __init__(self, fg:tuple=None, bg:tuple=None, mod:int=0, colorMod=None, link:str='', clean=False):
self._fg = fg
self._bg = bg
self._mod = mod
self._link = link
self._clean = clean or not (fg or bg or mod)
self._colorMod = colorMod
self._buffer = None
@ -181,15 +182,18 @@ class _TTkColor:
def __str__(self):
if not self._buffer:
self._buffer = TTkHelper.Color.rgb2ansi(self._fg,self._bg,self._mod,self._clean)
self._buffer = TTkHelper.Color.rgb2ansi(
fg=self._fg, bg=self._bg, mod=self._mod,
link=self._link, clean=self._clean)
return self._buffer
def __eq__(self, other):
if other is None: return False
return \
self._fg == other._fg and \
self._bg == other._bg and \
self._mod == other._mod
return (
self._fg == other._fg and
self._bg == other._bg and
self._mod == other._mod and
self._link == other._link )
# self | other
def __or__(self, other):
@ -200,8 +204,12 @@ class _TTkColor:
fg: str = self._fg or other._fg
bg: str = self._bg or other._bg
mod: str = self._mod + other._mod
link:str = self._link or other._link
colorMod = self._colorMod or other._colorMod
return TTkColor(fg,bg,mod,colorMod,clean)
return TTkColor(
fg=fg, bg=bg, mod=mod,
colorMod=colorMod, link=link,
clean=clean)
# self + other
def __add__(self, other):
@ -212,15 +220,20 @@ class _TTkColor:
fg: str = other._fg or self._fg
bg: str = other._bg or self._bg
mod: str = self._mod + other._mod
link:str = self._link or other._link
colorMod = other._colorMod or self._colorMod
return TTkColor(fg,bg,mod,colorMod,clean)
return TTkColor(
fg=fg, bg=bg, mod=mod,
colorMod=colorMod, link=link,
clean=clean)
def __sub__(self, other):
# TTkLog.debug("__sub__")
# if other is None: return str(self)
if ( None == self._bg != other._bg or
None == self._fg != other._fg or
self._mod != other._mod ):
if ( None == self._bg != other._bg or
None == self._fg != other._fg or
self._link != other._link or
self._mod != other._mod ):
ret = self.copy()
ret._clean = True
return ret
@ -241,6 +254,7 @@ class _TTkColor:
ret._fg = self._fg
ret._bg = self._bg
ret._mod = self._mod
ret._link = self._link
ret._clean = self._clean
if modifier and self._colorMod:
ret._colorMod = self._colorMod.copy()
@ -421,11 +435,12 @@ class TTkColor(_TTkColor):
:type modifier: TTkColorModifier, optional
'''
mod = kwargs.get('modifier', None )
link = kwargs.get('link', '' )
if len(args) > 0:
color = args[0]
else:
color = kwargs.get('color', "" )
return TTkColor(fg=TTkColor.hexToRGB(color), colorMod=mod)
return TTkColor(fg=TTkColor.hexToRGB(color), colorMod=mod, link=link)
@staticmethod
def bg(*args, **kwargs):
@ -445,8 +460,9 @@ class TTkColor(_TTkColor):
:type modifier: TTkColorModifier, optional
'''
mod = kwargs.get('modifier', None )
link = kwargs.get('link', '' )
if len(args) > 0:
color = args[0]
else:
color = kwargs.get('color', "" )
return TTkColor(bg=TTkColor.hexToRGB(color), colorMod=mod)
return TTkColor(bg=TTkColor.hexToRGB(color), colorMod=mod, link=link)

4
TermTk/TTkCore/constant.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkConstant', 'TTkK']
class TTkConstant:
'''Class container of all the constants used in :mod:`~TermTk`'''

4
TermTk/TTkCore/filebuffer.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkFileBuffer']
import os
import re
import threading

33
TermTk/TTkCore/helper.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,12 +20,19 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkHelper']
from TermTk.TTkCore.TTkTerm.colors import TTkTermColor
from TermTk.TTkCore.TTkTerm.term import TTkTerm
from TermTk.TTkCore.cfg import TTkCfg, TTkGlbl
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.signal import pyTTkSignal, pyTTkSlot
class TTkHelper:
'''TTkHelper
This is a collection of helper utilities to be used all around TermTk
'''
# TODO: Add Setter/Getter
_focusWidget = None
_rootCanvas = None
@ -83,8 +88,9 @@ class TTkHelper:
@staticmethod
def addUpdateWidget(widget):
# if not widget.isVisibleAndParent(): return
TTkHelper._updateWidget.add(widget)
TTkHelper.unlockPaint()
if widget not in TTkHelper._updateWidget:
TTkHelper._updateWidget.add(widget)
TTkHelper.unlockPaint()
@staticmethod
def addUpdateBuffer(canvas):
@ -97,10 +103,15 @@ class TTkHelper:
TTkHelper._rootWidget = widget
TTkHelper._rootCanvas.enableDoubleBuffer()
quitEvent = pyTTkSignal()
@staticmethod
@pyTTkSlot()
def quit():
'''Quit TermTk'''
TTkHelper.quitEvent.emit()
if TTkHelper._rootWidget:
TTkHelper._rootWidget.quit()
TTkHelper._rootWidget._quit()
@staticmethod
def getTerminalSize():
@ -187,8 +198,9 @@ class TTkHelper:
TTkHelper._rootWidget.rootLayout().addWidget(widget)
widget.setFocus()
widget.raiseWidget()
for w in widget.rootLayout().iterWidgets(onlyVisible=True):
w.update()
if hasattr(widget,'rootLayout'):
for w in widget.rootLayout().iterWidgets(onlyVisible=True):
w.update()
@staticmethod
def getOverlay():
@ -318,6 +330,8 @@ class TTkHelper:
TTkTerm.Cursor.hide()
if TTkCfg.doubleBuffer:
TTkHelper._rootCanvas.pushToTerminalBuffered(0, 0, TTkGlbl.term_w, TTkGlbl.term_h)
elif TTkCfg.doubleBufferNew:
TTkHelper._rootCanvas.pushToTerminalBufferedNew(0, 0, TTkGlbl.term_w, TTkGlbl.term_h)
else:
TTkHelper._rootCanvas.pushToTerminal(0, 0, TTkGlbl.term_w, TTkGlbl.term_h)
if TTkHelper._cursor:
@ -362,7 +376,10 @@ class TTkHelper:
wx,wy,ww,wh = widget.geometry()
if wx <= x < wx+ww and wy <= y < wy+wh:
return TTkHelper.widgetAt(x-wx, y-wy, widget.rootLayout())
if hasattr(widget,'rootLayout'):
return TTkHelper.widgetAt(x-wx, y-wy, widget.rootLayout())
else:
return widget
continue
elif item.layoutItemType() == TTkK.LayoutItem:

4
TermTk/TTkCore/log.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkLog']
# This code is inspired by
# https://github.com/ceccopierangiolieugenio/pyCuT/blob/master/cupy/CuTCore/CuDebug.py

2
TermTk/TTkCore/propertyanimation.py

@ -20,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkPropertyAnimation', 'TTkEasingCurve']
import time, math
from inspect import getfullargspec
from types import LambdaType

10
TermTk/TTkCore/signal.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -57,8 +55,11 @@ Methods
.. autodecorator:: TermTk.pyTTkSlot
'''
__all__ = ['pyTTkSlot', 'pyTTkSignal']
from inspect import getfullargspec
from types import LambdaType
from threading import Lock
def pyTTkSlot(*args, **kwargs):
def pyTTkSlot_d(func):
@ -72,7 +73,7 @@ def pyTTkSignal(*args, **kwargs):
class _pyTTkSignal_obj():
_signals = []
__slots__ = ('_types', '_name', '_revision', '_connected_slots')
__slots__ = ('_types', '_name', '_revision', '_connected_slots', '_mutex')
def __init__(self, *args, **kwargs):
# ref: http://pyqt.sourceforge.net/Docs/PyQt5/signals_slots.html#PyQt5.QtCore.pyqtSignal
@ -90,6 +91,7 @@ class _pyTTkSignal_obj():
self._name = kwargs.get('name', None)
self._revision = kwargs.get('revision', 0)
self._connected_slots = {}
self._mutex = Lock()
_pyTTkSignal_obj._signals.append(self)
def connect(self, slot):
@ -133,11 +135,13 @@ class _pyTTkSignal_obj():
del self._connected_slots[slot]
def emit(self, *args, **kwargs):
if not self._mutex.acquire(False): return
if len(args) != len(self._types):
error = "func"+str(self._types)+" signal has "+str(len(self._types))+" argument(s) but "+str(len(args))+" provided"
raise TypeError(error)
for slot,sl in self._connected_slots.copy().items():
slot(*args[sl], **kwargs)
self._mutex.release()
def clear(self):
self._connected_slots = {}

18
TermTk/TTkCore/string.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkString']
import re
import unicodedata
@ -58,6 +58,8 @@ class TTkString():
# Combination of constructors (Highly Unrecommended)
str7 = TTkString("test 7", color=TTkColor.fg('#FF0000'))
'''
unicodeWideOverflowColor = TTkColor.fg("#888888")+TTkColor.bg("#000088")
__slots__ = ('_text','_colors','_baseColor','_hasTab','_hasSpecialWidth')
def __init__(self, text="", color=None):
@ -72,6 +74,16 @@ class TTkString():
self._checkWidth()
# raise AttributeError(f"{type(text)} not supported in TTkString")
@staticmethod
def _importString1(text, colors):
ret = TTkString()
ret._text = text
ret._colors = colors
ret._baseColor = colors[-1]
ret._hasTab = '\t' in text
ret._checkWidth()
return ret
@staticmethod
def _parseAnsi(text, color = TTkColor.RST):
pos = 0
@ -348,7 +360,7 @@ class TTkString():
elif sz > width:
ret._text = rt[:-1]+TTkCfg.theme.unicodeWideOverflowCh[1]
ret._colors = self._colors[:len(ret._text)]
ret._colors[-1] = TTkCfg.theme.unicodeWideOverflowColor
ret._colors[-1] = TTkString.unicodeWideOverflowColor
break
else:
# Legacy, trim the string

3
TermTk/TTkCore/timer.py

@ -20,9 +20,12 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkTimer']
import importlib.util
if importlib.util.find_spec('pyodideProxy'):
from .timer_pyodide import TTkTimer
else:
from .timer_unix import TTkTimer

4
TermTk/TTkCore/timer_pyodide.py

@ -53,10 +53,6 @@ class TTkTimer():
rw._paintEvent.set()
TTkTimer._timers[tid].timeout.emit()
@staticmethod
def quitAll():
pass
@staticmethod
def pyodideQuit():
for timer in TTkTimer._timers:

9
TermTk/TTkCore/timer_unix.py

@ -23,9 +23,9 @@
import threading
from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal
from TermTk.TTkCore.helper import TTkHelper
class TTkTimer(threading.Thread):
_timers = []
__slots__ = (
'timeout', '_delay',
'_timer', '_quit', '_start')
@ -36,12 +36,7 @@ class TTkTimer(threading.Thread):
self._start = threading.Event()
self._timer = threading.Event()
super().__init__()
TTkTimer._timers.append(self)
@staticmethod
def quitAll():
for timer in TTkTimer._timers:
timer.quit()
TTkHelper.quitEvent.connect(self.quit)
def quit(self):
self._quit.set()

46
TermTk/TTkCore/ttk.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTk']
import os
import signal
import time
@ -42,8 +42,9 @@ from TermTk.TTkCore.timer import TTkTimer
from TermTk.TTkCore.color import TTkColor
from TermTk.TTkTheme.theme import TTkTheme
from TermTk.TTkWidgets.widget import TTkWidget
from TermTk.TTkWidgets.container import TTkContainer
class TTk(TTkWidget):
class TTk(TTkContainer):
class _mouseCursor(TTkWidget):
__slots__ = ('_cursor','_color')
def __init__(self, input):
@ -79,7 +80,7 @@ class TTk(TTkWidget):
'_input', '_termMouse', '_termDirectMouse',
'_title',
'_showMouseCursor',
'_sigmask',
'_sigmask', '_timer',
'_drawMutex',
'_paintEvent',
'_lastMultiTap',
@ -93,12 +94,14 @@ class TTk(TTkWidget):
if ('TERMTK_FILE_LOG' in os.environ and (_logFile := os.environ['TERMTK_FILE_LOG'])):
TTkLog.use_default_file_logging(_logFile)
self._timer = None
self.paintExecuted = pyTTkSignal()
super().__init__(*args, **kwargs)
self._termMouse = True
self._termDirectMouse = kwargs.get('mouseTrack',False)
self._input = TTkInput()
self._input.inputEvent.connect(self._processInput)
self._input.pasteEvent.connect(self._processPaste)
self._title = kwargs.get('title','TermTk')
self._sigmask = kwargs.get('sigmask', TTkK.NONE)
self._showMouseCursor = os.environ.get("TTK_MOUSE",kwargs.get('mouseCursor', False))
@ -110,6 +113,10 @@ class TTk(TTkWidget):
w,h = TTkTerm.getTerminalSize()
self.setGeometry(0,0,w,h)
if 'TERMTK_NEWRENDERER' in os.environ:
TTkCfg.doubleBuffer = False
TTkCfg.doubleBufferNew = True
TTkHelper.registerRootWidget(self)
frame = 0
@ -178,6 +185,12 @@ class TTk(TTkWidget):
return
self._input.start()
@pyTTkSlot(str)
def _processPaste(self, txt:str):
if focusWidget := TTkHelper.getFocus():
while focusWidget and not focusWidget.pasteEvent(txt):
focusWidget = focusWidget.parentWidget()
@pyTTkSlot(TTkKeyEvent, TTkMouseEvent)
def _processInput(self, kevt, mevt):
self._drawMutex.acquire()
@ -289,11 +302,30 @@ class TTk(TTkWidget):
self._drawMutex.release()
TTkLog.info(f"Resize: w:{TTkGlbl.term_w}, h:{TTkGlbl.term_h}")
@pyTTkSlot()
def quit(self):
'''quit TermTk
.. warning::
Method Deprecated,
use :class:`~TermTk.TTkCore.helper.TTkHelper` -> :class:`~TermTk.TTkCore.helper.TTkHelper.quit` instead
i.e.
.. code:: python
buttonQuit = TTkButton(text="QUIT",border=True)
buttonQuit.clicked.connect(TTkHelper.quit)
'''
TTkHelper.quit()
@pyTTkSlot()
def _quit(self):
'''Tells the application to exit with a return code.'''
if self._timer:
self._timer.timeout.disconnect(self._time_event)
self._input.inputEvent.clear()
TTkTimer.quitAll()
self._paintEvent.set()
self._input.close()
@ -328,7 +360,7 @@ class TTk(TTkWidget):
# Deregister the handler
# so CTRL-C can be redirected to the default handler if the app does not exit
signal.signal(signal.SIGINT, signal.SIG_DFL)
self.quit()
TTkHelper.quit()
def isVisibleAndParent(self):
return self.isVisible()

2
TermTk/TTkCore/util.py

@ -20,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkUtil']
import zlib, pickle, base64
class TTkUtil():

12
TermTk/TTkGui/__init__.py

@ -1,6 +1,6 @@
from .drag import TTkDrag, TTkDropEvent
from .textwrap1 import TTkTextWrap
from .textcursor import TTkTextCursor
from .textdocument import TTkTextDocument
from .clipboard import TTkClipboard
from .tooltip import TTkToolTip
from .drag import *
from .textwrap1 import *
from .textcursor import *
from .textdocument import *
from .clipboard import *
from .tooltip import *

4
TermTk/TTkGui/clipboard.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2022 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkClipboard']
import importlib.util
class TTkClipboard():

4
TermTk/TTkGui/drag.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2022 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkDrag', 'TTkDropEvent']
from TermTk.TTkCore.helper import TTkHelper
from TermTk.TTkCore.canvas import TTkCanvas
from TermTk.TTkWidgets.widget import TTkWidget

24
TermTk/TTkGui/textcursor.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2022 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkTextCursor']
from TermTk.TTkCore.log import TTkLog
from TermTk.TTkCore.color import TTkColor
from TermTk.TTkCore.string import TTkString
@ -308,7 +308,7 @@ class TTkTextCursor():
l = self._document._dataLines[-1]
self.setPosition(len(self._document._dataLines)-1, len(l), moveMode, cID=cID)
operations = {
op = {
TTkTextCursor.Right : moveRight,
TTkTextCursor.Left : moveLeft,
TTkTextCursor.Up : moveUpDown(-1),
@ -316,18 +316,19 @@ class TTkTextCursor():
TTkTextCursor.EndOfLine : moveEndOfLine,
TTkTextCursor.StartOfLine: moveHome,
TTkTextCursor.End: moveEnd,
}
}.get(operation,lambda _:_)
for cID, prop in enumerate(self._properties):
for _ in range(n):
for cID, prop in enumerate(self._properties):
p = prop.position
operations.get(operation,lambda _:_)(cID,p,n)
op(cID,p,n)
self._checkCursors(notify=self.position().toNum()!=currPos)
def document(self):
return self._document
def replaceText(self, text):
def replaceText(self, text, moveCursor=False):
# if there is no selection, just select the next n chars till the end of the line
# the newline is not replaced
for p in self._properties:
@ -340,9 +341,9 @@ class TTkTextCursor():
pos = self._document._dataLines[line].nextPos(pos)
pos = min(size,pos)
p.anchor.set(line,pos)
return self.insertText(text)
return self.insertText(text, moveCursor)
def insertText(self, text):
def insertText(self, text, moveCursor=False):
_lineFirst = -1
if self.hasSelection():
_lineFirst, _lineRem, _lineAdd = self._removeSelectedText()
@ -395,6 +396,8 @@ class TTkTextCursor():
for nl in reversed(newLines[1:]):
self._document._dataLines.insert(l+1, nl)
# Move/Shift the cursors based on the pasted content
#
# 2 scenarios:
# 1) No Newline(s) added
# p p+1 p+2
@ -417,7 +420,8 @@ class TTkTextCursor():
diffPos = len(text.split('\n')[-1]) - p
else:
diffPos = len(text)
for pp in self._properties[i+1:]:
# Realign all the cursos (move the same if required)
for pp in self._properties[i+(0 if moveCursor else 1):]:
if pp.position.line == l:
pp.position.pos += diffPos
pp.anchor.pos += diffPos

4
TermTk/TTkGui/textdocument.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2022 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkTextDocument']
from TermTk.TTkCore.log import TTkLog
from TermTk.TTkCore.signal import pyTTkSignal, pyTTkSlot
from TermTk.TTkCore.string import TTkString

6
TermTk/TTkGui/textwrap1.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2022 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkTextWrap']
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.signal import pyTTkSignal
from TermTk.TTkCore.string import TTkString
@ -83,7 +83,7 @@ class TTkTextWrap():
if not (w := self._wrapWidth):
return
def _process(i,l):
def _process(i,l:TTkString):
fr = 0
to = 0
if not len(l): # if the line is empty append it

2
TermTk/TTkGui/tooltip.py

@ -20,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkToolTip']
# from TermTk.TTkCore.helper import TTkHelper
from TermTk.TTkCore.log import TTkLog
from TermTk.TTkCore.canvas import TTkCanvas

4
TermTk/TTkLayouts/__init__.py

@ -4,6 +4,6 @@ Layouts
.. image:: /../_images/Layout.HLD.001.svg
'''
from .layout import *
from .layout import *
from .gridlayout import *
from .boxlayout import *
from .boxlayout import *

4
TermTk/TTkLayouts/boxlayout.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -26,6 +24,8 @@
**Box Layout** [`Tutorial <https://ceccopierangiolieugenio.github.io/pyTermTk/tutorial/002-layout.html#simple-ttkvboxlayout>`__]
'''
__all__ = ['TTkHBoxLayout', 'TTkVBoxLayout']
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkLayouts.gridlayout import TTkGridLayout

4
TermTk/TTkLayouts/gridlayout.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -26,6 +24,8 @@
**Grid Layout** [`Tutorial <https://ceccopierangiolieugenio.github.io/pyTermTk/tutorial/002-layout.html#simple-ttkgridlayout>`__]
'''
__all__ = ['TTkGridLayout']
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkLayouts.layout import TTkLayout

22
TermTk/TTkLayouts/layout.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -26,6 +24,8 @@
**Layout** [`Tutorial <https://ceccopierangiolieugenio.github.io/pyTermTk/tutorial/002-layout.html#simple-ttklayout>`__]
'''
__all__ = ['TTkLayoutItem', 'TTkLayout']
from TermTk.TTkCore.constant import TTkK
class TTkLayoutItem:
@ -213,8 +213,8 @@ class TTkLayout(TTkLayoutItem):
if child._layoutItemType == TTkK.WidgetItem:
if onlyVisible and not child.widget().isVisible(): continue
yield child.widget()
if recurse:
yield from child.widget().rootLayout().iterWidgets()
if recurse and hasattr(cw:=child.widget(),'rootLayout'):
yield from cw.rootLayout().iterWidgets()
if child._layoutItemType == TTkK.LayoutItem and recurse:
yield from child.iterWidgets()
@ -312,7 +312,7 @@ class TTkLayout(TTkLayoutItem):
:param widgets: the widget to be removed
:type widgets: list of :class:`~TermTk.TTkWidgets`
'''
for item in self._items:
for item in reversed(self._items):
if item._layoutItemType == TTkK.WidgetItem and \
item.widget() in widgets:
self.removeItem(item)
@ -340,7 +340,7 @@ class TTkLayout(TTkLayoutItem):
def lowerWidget(self, widget):
'''lowerWidget'''
item = self._findBranchWidget(widget)
for item in self._items: item.z+=1
for i in self._items: i._z+=1
item._z = item._layer
if item._layoutItemType == TTkK.LayoutItem:
item.lowerWidget(widget)
@ -366,13 +366,11 @@ class TTkLayout(TTkLayoutItem):
def update(self, *args, **kwargs):
ret = False
for i in self.children():
if i._layoutItemType == TTkK.WidgetItem and not i.isEmpty():
ret = ret or i.widget().update(*args, **kwargs)
# TODO: Have a look at this:
# i.getCanvas().top()
for i in self._items:
if i._layoutItemType == TTkK.WidgetItem and (_wid:=i._widget):
ret = ret or _wid.update(*args, **kwargs)
elif i._layoutItemType == TTkK.LayoutItem:
ret= ret or i.update(*args, **kwargs)
ret = ret or i.update(*args, **kwargs)
return ret
class TTkWidgetItem(TTkLayoutItem):

2
TermTk/TTkTemplates/__init__.py

@ -1 +1 @@
from .lookandfeel import TTkLookAndFeel
# from .lookandfeel import TTkLookAndFeel

2
TermTk/TTkTemplates/dragevents.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2022 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>

2
TermTk/TTkTemplates/keyevents.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>

2
TermTk/TTkTemplates/mouseevents.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>

12
TermTk/TTkTestWidgets/__init__.py

@ -1,6 +1,6 @@
from .logviewer import TTkLogViewer
from .testwidget import TTkTestWidget
from .testwidgetsizes import TTkTestWidgetSizes
from .testabstractscroll import TTkTestAbstractScrollWidget
from .keypressview import TTkKeyPressView
from .tominspector import TTkTomInspector
from .logviewer import *
from .testwidget import *
from .testwidgetsizes import *
from .testabstractscroll import *
from .keypressview import *
# from .tominspector import *

4
TermTk/TTkTestWidgets/keypressview.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkKeyPressView']
from TermTk.TTkCore.TTkTerm.inputkey import TTkKeyEvent, mod2str, key2str
from TermTk.TTkCore.TTkTerm.inputmouse import TTkMouseEvent
from TermTk.TTkCore.helper import TTkHelper

4
TermTk/TTkTestWidgets/keypressviewfont.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkKeyPressViewFont']
from TermTk.TTkCore.TTkTerm.inputkey import TTkKeyEvent, mod2str, key2str
from TermTk.TTkCore.TTkTerm.inputmouse import TTkMouseEvent
from TermTk.TTkCore.helper import TTkHelper

4
TermTk/TTkTestWidgets/logviewer.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkLogViewer']
import os
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.log import TTkLog

5
TermTk/TTkTestWidgets/testabstractscroll.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,8 +20,9 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkTestAbstractScrollWidget']
from TermTk.TTkCore.signal import pyTTkSlot
from TermTk.TTkWidgets.frame import TTkFrame
from TermTk.TTkAbstract.abstractscrollview import TTkAbstractScrollView
class TTkTestAbstractScrollWidget(TTkAbstractScrollView):

4
TermTk/TTkTestWidgets/testwidget.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkTestWidget']
from TermTk.TTkCore.log import TTkLog
from TermTk.TTkCore.color import TTkColor
from TermTk.TTkCore.string import TTkString

6
TermTk/TTkTestWidgets/testwidgetsizes.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,7 +20,9 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from TermTk.TTkWidgets.frame import *
__all__ = ['TTkTestWidgetSizes']
from TermTk.TTkWidgets.frame import TTkFrame
class TTkTestWidgetSizes(TTkFrame):
ID = 1

6
TermTk/TTkTestWidgets/tominspector.py

@ -20,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkTomInspector']
from TermTk.TTkCore.cfg import TTkCfg
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.helper import TTkHelper
@ -37,7 +39,7 @@ from TermTk.TTkWidgets.lineedit import TTkLineEdit
from TermTk.TTkWidgets.combobox import TTkComboBox
from TermTk.TTkWidgets.checkbox import TTkCheckbox
from TermTk.TTkWidgets.spinbox import TTkSpinBox
from TermTk.TTkWidgets.widget import TTkWidget
from TermTk.TTkWidgets.container import TTkContainer
from TermTk.TTkWidgets.splitter import TTkSplitter
from TermTk.TTkWidgets.frame import TTkFrame
from TermTk.TTkWidgets.button import TTkButton
@ -142,7 +144,7 @@ class _TTkDomTreeWidgetItem(TTkTreeWidgetItem):
def domWidget(self):
return self._domWidget
class TTkTomInspector(TTkWidget):
class TTkTomInspector(TTkContainer):
__slots__ = ('_domTree','_detail','_splitter')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

2
TermTk/TTkTheme/draw_ascii.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>

2
TermTk/TTkTheme/draw_utf8.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>

170
TermTk/TTkTheme/theme.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkTheme']
from TermTk.TTkCore.color import TTkColor
from TermTk.TTkCore.helper import TTkHelper
# from TermTk.TTkCore.string import TTkString
@ -31,7 +31,6 @@ import TermTk.TTkTheme.fileicon_ascii as fi_ascii
import TermTk.TTkTheme.draw_utf8 as draw_utf8
import TermTk.TTkTheme.draw_ascii as draw_ascii
class TTkTheme():
'''Default Theme Class
This class can be reimplemented/extended to include new themes and default colors
@ -90,168 +89,3 @@ class TTkTheme():
TTkTheme.fileIcon = theme['file'].FileIcon
TTkHelper.updateAll()
frameBorderColor = TTkColor.RST
'''Default to :class:`~TermTk.TTkCore.color.TTkColor.RST`'''
frameTitleColor = TTkColor.fg("#dddddd")+TTkColor.bg("#222222")
'''Default to **TTkColor.fg("#dddddd")+TTkColor.bg("#222222")**'''
windowBorderColor = TTkColor.RST
'''Default to :class:`~TermTk.TTkCore.color.TTkColor.RST`'''
windowBorderColorFocus = TTkColor.fg("#ffff55")
'''Default to **TTkColor.fg("#ffff55")**'''
textColorDisabled = TTkColor.fg("#888888")
'''Default to **TTkColor.fg("#888888")**'''
borderColorDisabled= TTkColor.fg("#888888")
'''Default to **TTkColor.fg("#888888")**'''
buttonBoxGrid = 1
'''Default to **1**'''
buttonBoxGridClicked = 0
'''Default to **0**'''
buttonBoxGridDisabled = 0
'''Default to **0**'''
buttonBoxGridChecked = 1
'''Default to **0**'''
buttonBoxGridUnchecked = 3
'''Default to **2**'''
buttonTextColor = TTkColor.fg("#dddd88")+TTkColor.bg("#000044")
'''Default to **TTkColor.fg("#dddd88")+TTkColor.bg("#000044")**'''
buttonBorderColor = TTkColor.RST
'''Default to :class:`~TermTk.TTkCore.color.TTkColor.RST`'''
buttonTextColorClicked = TTkColor.fg("#ffffdd")+TTkColor.BOLD
'''Default to **TTkColor.fg("#ffffdd")+**:class:`~TermTk.TTkCore.color.TTkColor.BOLD`'''
buttonBorderColorClicked = TTkColor.fg("#dddddd")+TTkColor.BOLD
'''Default to **TTkColor.fg("#dddddd")+**:class:`~TermTk.TTkCore.color.TTkColor.BOLD`'''
buttonTextColorFocus = buttonTextColor + TTkColor.BOLD
'''Default to :class:`buttonTextColor` **+** :class:`~TermTk.TTkCore.color.TTkColor.BOLD`'''
buttonBorderColorFocus = TTkColor.fg("#ffff00") + TTkColor.BOLD
'''Default to **TTkColor.fg("#ffff00") + **:class:`~TermTk.TTkCore.color.TTkColor.BOLD`'''
buttonTextColorHover = TTkColor.fg("#dddd88")+TTkColor.bg("#000050")+TTkColor.BOLD
'''Default to **TTkColor.fg("#dddd88")+TTkColor.bg("#000066")+** :class:`~TermTk.TTkCore.color.TTkColor.BOLD`'''
buttonBorderColorHover = TTkColor.fg("#ffffcc") + TTkColor.BOLD
'''Default to **TTkColor.fg("#ffff88") + **:class:`~TermTk.TTkCore.color.TTkColor.BOLD`'''
buttonTextColorDisabled = textColorDisabled
'''Default to :class:`textColorDisabled`'''
buttonBorderColorDisabled= borderColorDisabled
'''Default to :class:`borderColorDisabled`'''
buttonTextColorChecked = TTkColor.fg("#dddd88")+TTkColor.bg("#004488")
'''Default to **TTkColor.fg("#dddd88")+TTkColor.bg("#004488")**'''
buttonTextColorUnchecked = buttonTextColor
'''Default to :class:`buttonTextColor`'''
buttonBorderColorChecked= TTkColor.fg("#FFFFFF")
'''Default to **TTkColor.fg("#FFFFFF")**'''
buttonBorderColorUnchecked= buttonBorderColor
'''Default to :class:`buttonBorderColor`'''
menuButtonShortcutColor = TTkColor.fg("#dddddd") + TTkColor.UNDERLINE
'''Default to **TTkColor.fg("#dddddd") + TTkColor.UNDERLINE**'''
menuButtonColor = TTkColor.BOLD
'''Default to :class:`~TermTk.TTkCore.color.TTkColor.BOLD`'''
menuButtonBorderColor = frameBorderColor
'''Default to :class:`frameBorderColor`'''
menuButtonColorClicked = TTkColor.fg("#ffff88")
'''Default to **TTkColor.fg("#ffff88")**'''
menuButtonBorderColorClicked = frameBorderColor
'''Default to :class:`frameBorderColor`'''
listColor = TTkColor.RST
'''Default to :class:`~TermTk.TTkCore.color.TTkColor.RST`'''
listColorSelected = TTkColor.fg("#ffffdd")+TTkColor.bg("#000044") + TTkColor.BOLD
'''Default to **TTkColor.fg("#ffffdd")+TTkColor.bg("#000044") + **:class:`~TermTk.TTkCore.color.TTkColor.BOLD`'''
listColorHighlighted = TTkColor.bg("#000088") + TTkColor.BOLD
'''Default to **TTkColor.bg("#000088") + **:class:`~TermTk.TTkCore.color.TTkColor.BOLD`'''
lineEditTextColor = TTkColor.fg("#dddddd")+TTkColor.bg("#222222")
'''Default to **TTkColor.fg("#dddddd")+TTkColor.bg("#222222")**'''
lineEditTextColorFocus = TTkColor.fg("#dddddd")+TTkColor.bg("#000044")
'''Default to **TTkColor.fg("#dddddd")+TTkColor.bg("#000044")**'''
lineEditTextColorSelected = TTkColor.fg("#ffffff")+TTkColor.bg("#008844")
'''Default to **TTkColor.fg("#ffffff")+TTkColor.bg("#008844")**'''
comboboxContentColor = TTkColor.fg("#dddd88")+TTkColor.bg("#111111")
'''Default to **TTkColor.fg("#dddd88")+TTkColor.bg("#111111")**'''
comboboxBorderColor = buttonBorderColor
'''Default to :class:`buttonBorderColor`'''
comboboxContentColorFocus = TTkColor.fg("#ffff88")+TTkColor.bg("#111111")
'''Default to **TTkColor.fg("#ffff88")+TTkColor.bg("#111111")**'''
comboboxBorderColorFocus = buttonBorderColorFocus
'''Default to :class:`buttonBorderColorFocus`'''
comboboxContentColorDisabled = TTkColor.fg("#888888")
'''Default to **TTkColor.fg("#888888")**'''
comboboxBorderColorDisabled= TTkColor.fg("#888888")
'''Default to **TTkColor.fg("#888888")**'''
checkboxContentColor = buttonTextColor
'''Default to :class:`buttonTextColor`'''
checkboxBorderColor = buttonBorderColor
'''Default to :class:`buttonBorderColor`'''
checkboxTextColor = TTkColor.RST
'''Default to :class:`~TermTk.TTkCore.color.TTkColor.RST`'''
checkboxContentColorFocus = buttonTextColorFocus
'''Default to :class:`buttonTextColorFocus`'''
checkboxBorderColorFocus = buttonBorderColorFocus
'''Default to :class:`buttonBorderColorFocus`'''
checkboxTextColorFocus = TTkColor.fg("#ffff88")+TTkColor.bg("#111111")
'''Default to **TTkColor.fg("#ffff88")+TTkColor.bg("#111111")**'''
radioButtonContentColor = checkboxContentColor
'''Default to :class:`checkboxContentColor`'''
radioButtonBorderColor = checkboxBorderColor
'''Default to :class:`checkboxBorderColor`'''
radioButtonTextColor = checkboxTextColor
'''Default to :class:`checkboxTextColor`'''
radioButtonContentColorFocus = checkboxContentColorFocus
'''Default to :class:`checkboxContentColorFocus`'''
radioButtonBorderColorFocus = checkboxBorderColorFocus
'''Default to :class:`checkboxBorderColorFocus`'''
radioButtonTextColorFocus = checkboxTextColorFocus
'''Default to :class:`checkboxTextColorFocus`'''
tabColor = TTkColor.fg("#aaaaaa")
'''Default to **TTkColor.fg("#aaaaaa")**'''
tabOffsetColor = TTkColor.RST
'''Default to **TTkColor.RST**'''
tabBorderColor = frameBorderColor
'''Default to :class:`frameBorderColor`'''
tabSelectColor = TTkColor.fg("#ffff88")+TTkColor.bg("#000066")+TTkColor.BOLD
'''Default to **TTkColor.fg("#ffff88")+TTkColor.bg("#000066")+**:class:`~TermTk.TTkCore.color.TTkColor.BOLD`'''
tabColorFocus = TTkColor.fg("#aaaaaa")
'''Default to **TTkColor.fg("#aaaaaa")**'''
tabOffsetColorFocus = tabOffsetColor
'''Default to :class:`tabOffsetColor`'''
tabBorderColorFocus = TTkColor.fg("#ffff88")
'''Default to **TTkColor.fg("#ffff88")**'''
tabSelectColorFocus = TTkColor.fg("#ffff88")+TTkColor.bg("#000066")+TTkColor.BOLD
'''Default to **TTkColor.fg("#ffff88")+TTkColor.bg("#000066")+**:class:`~TermTk.TTkCore.color.TTkColor.BOLD`'''
treeHeaderColor = TTkColor.fg("#ffffff")+TTkColor.bg("#444444")+TTkColor.BOLD
'''Default to **TTkColor.fg("#ffffff")+TTkColor.bg("#444444")+**:class:`~TermTk.TTkCore.color.TTkColor.BOLD`'''
treeSelectedColor = TTkColor.fg("#ffff88")+TTkColor.bg("#000066")+TTkColor.BOLD
'''Default to **TTkColor.fg("#ffff88")+TTkColor.bg("#000066")+**:class:`~TermTk.TTkCore.color.TTkColor.BOLD`'''
treeLineColor = TTkColor.fg("#444444")
'''Default to **TTkColor.fg("#444444")**'''
textEditLineNumberColor = TTkColor.fg("#88aaaa")+TTkColor.bg("#333333")
'''Default to **TTkColor.fg("#aaaaaa")+TTkColor.bg("#333333")**'''
textEditLineNumberWrapcharColor = TTkColor.fg("#888888")+TTkColor.bg("#333333")
'''Default to **TTkColor.fg("#aaaaaa")+TTkColor.bg("#333333")**'''
textEditLineNumberSeparatorColor = TTkColor.fg("#444444")
'''Default to **TTkColor.fg("#444444")**'''
unicodeWideOverflowColor = TTkColor.fg("#888888")+TTkColor.bg("#000088")
'''Default to **TTkColor.fg("#888888")**+**TTkColor.bg("#000088")**'''
progresssBarColor = TTkColor.fg('#0000aa')+TTkColor.bg("#000044")
'''Default to **TTkColor.fg('#0000aa')**+**TTkColor.bg("#000044")**'''
progressBarTextColor = TTkColor.fg('#ffffff')
'''Default to **TTkColor.fg('#ffffff')**'''

4
TermTk/TTkUiTools/__init__.py

@ -1,2 +1,2 @@
from .uiloader import TTkUiLoader
from .uiproperties import TTkUiProperties
from .uiloader import *
from .uiproperties import *

39
TermTk/TTkUiTools/properties/__init__.py

@ -1,32 +1,33 @@
# from .about import
from .button import TTkButtonProperties
from .checkbox import TTkCheckboxProperties
from .combobox import TTkComboBoxProperties
from .frame import TTkFrameProperties
from .button import *
from .checkbox import *
from .combobox import *
from .container import *
from .frame import *
# from .graph import
# from .image import
from .label import TTkLabelProperties
from .lineedit import TTkLineEditProperties
from .list_ import TTkListProperties
from .label import *
from .lineedit import *
from .list_ import *
# from .listwidget import
# from .menubar import
from .menu import TTkMenuButtonProperties
from .menu import *
# from .progressbar import
from .radiobutton import TTkRadioButtonProperties
from .resizableframe import TTkResizableFrameProperties
from .radiobutton import *
from .resizableframe import *
# from .scrollarea import
from .scrollbar import TTkScrollBarProperties
from .scrollbar import *
# from .spacer import
from .spinbox import TTkSpinBoxProperties
from .splitter import TTkSplitterProperties
from .spinbox import *
from .splitter import *
# from .tabwidget import
from .texedit import TTkTextEditProperties
from .widget import TTkWidgetProperties
from .window import TTkWindowProperties
from .texedit import *
from .widget import *
from .window import *
# Pickers
from .colorpicker import TTkColorButtonPickerProperties
from .filepicker import TTkFileButtonPickerProperties
from .colorpicker import *
from .filepicker import *
# Layouts
from .layout import TTkLayoutProperties
from .layout import *

2
TermTk/TTkUiTools/properties/button.py

@ -20,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkButtonProperties']
from TermTk.TTkCore.string import TTkString
from TermTk.TTkWidgets.button import TTkButton

2
TermTk/TTkUiTools/properties/checkbox.py

@ -20,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkCheckboxProperties']
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.string import TTkString
from TermTk.TTkWidgets.checkbox import TTkCheckbox

2
TermTk/TTkUiTools/properties/colorpicker.py

@ -20,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkColorButtonPickerProperties']
from TermTk.TTkCore.color import TTkColor
from TermTk.TTkWidgets.TTkPickers.colorpicker import TTkColorButtonPicker

2
TermTk/TTkUiTools/properties/combobox.py

@ -20,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkComboBoxProperties']
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.string import TTkString
from TermTk.TTkWidgets.combobox import TTkComboBox

49
TermTk/TTkUiTools/properties/container.py

@ -0,0 +1,49 @@
# MIT License
#
# Copyright (c) 2023 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.
__all__ = ['TTkContainerProperties']
from TermTk.TTkCore.string import TTkString
from TermTk.TTkLayouts.layout import TTkLayout
from TermTk.TTkWidgets.container import TTkContainer
TTkContainerProperties = {
'properties' : {
'Padding': {
'get': { 'cb':TTkContainer.getPadding, 'type': [
{ 'name': 'top', 'type':int } ,
{ 'name': 'bottom', 'type':int } ,
{ 'name': 'left', 'type':int } ,
{ 'name': 'right', 'type':int } ] },
'set': { 'cb':TTkContainer.setPadding, 'type': [
{ 'name': 'top', 'type':int } ,
{ 'name': 'bottom', 'type':int } ,
{ 'name': 'left', 'type':int } ,
{ 'name': 'right', 'type':int } ] } },
'Layout' : {
'init': {'name':'layout', 'type':TTkLayout} ,
'get': { 'cb':TTkContainer.layout, 'type':TTkLayout} ,
'set': { 'cb':TTkContainer.setLayout, 'type':TTkLayout} },
},'signals' : {
},'slots' : {
}
}

2
TermTk/TTkUiTools/properties/filepicker.py

@ -20,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkFileButtonPickerProperties']
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.color import TTkColor
from TermTk.TTkWidgets.TTkPickers.filepicker import TTkFileButtonPicker

2
TermTk/TTkUiTools/properties/frame.py

@ -20,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkFrameProperties']
from TermTk.TTkCore.string import TTkString
from TermTk.TTkWidgets.frame import TTkFrame

2
TermTk/TTkUiTools/properties/label.py

@ -20,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkLabelProperties']
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.color import TTkColor
from TermTk.TTkCore.string import TTkString

22
TermTk/TTkUiTools/properties/layout.py

@ -20,27 +20,7 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# MIT License
#
# Copyright (c) 2023 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.
__all__ = ['TTkLayoutProperties']
from TermTk.TTkLayouts.layout import TTkLayout

2
TermTk/TTkUiTools/properties/lineedit.py

@ -20,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkLineEditProperties']
from TermTk.TTkCore.string import TTkString
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkWidgets.lineedit import TTkLineEdit

2
TermTk/TTkUiTools/properties/list_.py

@ -20,4 +20,6 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkListProperties']
TTkListProperties = {'properties' : {},'signals' : {},'slots' : {}}

2
TermTk/TTkUiTools/properties/listwidget.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2023 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>

3
TermTk/TTkUiTools/properties/menu.py

@ -19,6 +19,9 @@
# 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.
__all__ = ['TTkMenuButtonProperties']
from TermTk.TTkCore.string import TTkString
from TermTk.TTkWidgets.menu import TTkMenuButton

4
TermTk/TTkUiTools/properties/radiobutton.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2023 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkRadioButtonProperties']
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.string import TTkString
from TermTk.TTkWidgets.radiobutton import TTkRadioButton

4
TermTk/TTkUiTools/properties/resizableframe.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2023 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,4 +20,6 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkResizableFrameProperties']
TTkResizableFrameProperties = {'properties':{}, 'signals':{}, 'slots':{}}

2
TermTk/TTkUiTools/properties/scrollarea.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2023 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>

4
TermTk/TTkUiTools/properties/scrollbar.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2023 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkScrollBarProperties']
from TermTk.TTkCore.string import TTkString
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkWidgets.scrollbar import TTkScrollBar

2
TermTk/TTkUiTools/properties/spacer.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2023 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>

4
TermTk/TTkUiTools/properties/spinbox.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2023 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkSpinBoxProperties']
from TermTk.TTkWidgets.spinbox import TTkSpinBox
TTkSpinBoxProperties = {

4
TermTk/TTkUiTools/properties/splitter.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2023 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkSplitterProperties']
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkWidgets.splitter import TTkSplitter

2
TermTk/TTkUiTools/properties/tabwidget.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2023 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>

4
TermTk/TTkUiTools/properties/texedit.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2023 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkTextEditProperties']
# from TermTk.TTkCore.string import TTkString
# from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.color import TTkColor

19
TermTk/TTkUiTools/properties/widget.py

@ -20,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkWidgetProperties']
from TermTk.TTkCore.string import TTkString
from TermTk.TTkLayouts.layout import TTkLayout
from TermTk.TTkWidgets.widget import TTkWidget
@ -78,21 +80,6 @@ TTkWidgetProperties = {
'init': {'name':'maxHeight', 'type':int } ,
'get': { 'cb':TTkWidget.maximumHeight, 'type':int } ,
'set': { 'cb':TTkWidget.setMaximumHeight,'type':int } },
'Padding': {
'get': { 'cb':TTkWidget.getPadding, 'type': [
{ 'name': 'top', 'type':int } ,
{ 'name': 'bottom', 'type':int } ,
{ 'name': 'left', 'type':int } ,
{ 'name': 'right', 'type':int } ] },
'set': { 'cb':TTkWidget.setPadding, 'type': [
{ 'name': 'top', 'type':int } ,
{ 'name': 'bottom', 'type':int } ,
{ 'name': 'left', 'type':int } ,
{ 'name': 'right', 'type':int } ] } },
'Layout' : {
'init': {'name':'layout', 'type':TTkLayout} ,
'get': { 'cb':TTkWidget.layout, 'type':TTkLayout} ,
'set': { 'cb':TTkWidget.setLayout, 'type':TTkLayout} },
'Visible' : {
'init': {'name':'visible', 'type':bool } ,
'get': { 'cb':TTkWidget.isVisible, 'type':bool } ,
@ -106,6 +93,8 @@ TTkWidgetProperties = {
'get': { 'cb':TTkWidget.toolTip, 'type':TTkString } ,
'set': { 'cb':TTkWidget.setToolTip, 'type':TTkString } },
},'signals' : {
'closed(TTkWidget)' : {'name' : 'closed', 'type':TTkWidget},
'currentStyleChanged(style)' : {'name' : 'currentStyleChanged', 'type':dict},
'focusChanged(bool)' : {'name' : 'focusChanged', 'type':bool},
'sizeChanged(int,int)' : {'name' : 'sizeChanged', 'type':(int, int)}
},'slots' : {

4
TermTk/TTkUiTools/properties/window.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2023 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkWindowProperties']
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkWidgets.window import TTkWindow

42
TermTk/TTkUiTools/uiloader.py

@ -20,12 +20,14 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkUiLoader']
# Yaml is not included by default
# import yaml
import os, json
from TermTk import TTkLog
from TermTk import TTkCfg
from TermTk import TTkCfg, TTkColor
from TermTk.TTkLayouts import TTkLayout, TTkGridLayout, TTkVBoxLayout, TTkHBoxLayout
from TermTk.TTkWidgets import *
from TermTk.TTkTestWidgets import *
@ -73,8 +75,33 @@ class TTkUiLoader():
'''
return TTkUiLoader.loadDict(json.loads(text), baseWidget, kwargs)
def _convert_1_0_1_to_2_0_0(ui):
def _processWidget(_wid):
if issubclass(globals()[_wid['class']],TTkContainer):
if hasattr(_wid,'layout'):
_wid['layout']['children'] = [_processWidget(_ch) for _ch in _wid['layout']['children']]
elif _wid['layout']['children']:
_wid['class'] = 'TTkContainer'
_wid['layout']['children'] = [_processWidget(_ch) for _ch in _wid['layout']['children']]
else:
_wid.pop('layout',None)
_wid['params'].pop("layout",None)
return _wid
tui = _processWidget(ui['tui'])
return {
"version": "2.0.0",
"connections" : ui['connections'],
"tui": tui }
@staticmethod
def _loadDict_1_0_0(ui, baseWidget:TTkWidget=None, args=None):
def _loadDict_1_0_0(ui, *args, **kwargs):
ui = TTkUiLoader._convert_1_0_1_to_2_0_0(ui)
return TTkUiLoader._loadDict_2_0_0(ui, *args, **kwargs)
@staticmethod
def _loadDict_2_0_0(ui, baseWidget:TTkWidget=None, args=None):
def _setMenuButton(_menuButtonProp, _menuButton:TTkMenuButton):
if 'submenu' in _menuButtonProp:
for _sm in _menuButtonProp['submenu']:
@ -259,6 +286,14 @@ class TTkUiLoader():
return widget
@staticmethod
def normalise(ui):
cb = {'1.0.0' : TTkUiLoader._convert_1_0_1_to_2_0_0,
'1.0.1' : TTkUiLoader._convert_1_0_1_to_2_0_0,
'2.0.0' : lambda x: x
}.get(ui['version'], lambda x: x)
return cb(ui)
@staticmethod
def loadDict(ui, baseWidget:TTkWidget=None, kwargs=None) -> TTkWidget:
'''load the dictionary representing the ui definition of the widget
@ -273,7 +308,8 @@ class TTkUiLoader():
:return: :class:`~TermTk.TTkWidgets.widget.TTkWidget`
'''
cb = {'1.0.0' : TTkUiLoader._loadDict_1_0_0,
'1.0.1' : TTkUiLoader._loadDict_1_0_0
'1.0.1' : TTkUiLoader._loadDict_1_0_0,
'2.0.0' : TTkUiLoader._loadDict_2_0_0
}.get(ui['version'], None)
if cb:
return cb(ui, baseWidget, kwargs)

5
TermTk/TTkUiTools/uiproperties.py

@ -20,7 +20,9 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from TermTk.TTkLayouts import TTkLayout, TTkGridLayout, TTkVBoxLayout, TTkHBoxLayout
__all__ = ['TTkUiProperties']
from TermTk.TTkLayouts import *
from TermTk.TTkWidgets import *
from .properties import *
@ -28,6 +30,7 @@ TTkUiProperties = {
# Widgets
TTkButton.__name__: TTkButtonProperties,
TTkCheckbox.__name__: TTkCheckboxProperties,
TTkContainer.__name__: TTkContainerProperties,
TTkComboBox.__name__: TTkComboBoxProperties,
TTkFrame.__name__: TTkFrameProperties,
TTkLabel.__name__: TTkLabelProperties,

1
TermTk/TTkWidgets/Fancy/__init__.py

@ -4,3 +4,4 @@ from .tree import *
from .treeview import *
from .treewidget import *
from .treewidgetitem import *
from .progressbar import *

29
TermTk/TTkWidgets/progressbar.py → TermTk/TTkWidgets/Fancy/progressbar.py

@ -21,16 +21,26 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkFancyProgressBar', 'TTkLookAndFeelFPBar']
import math
from TermTk.TTkCore.cfg import TTkCfg
from TermTk.TTkCore.color import TTkColor
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.string import TTkString
from TermTk.TTkCore.signal import pyTTkSignal, pyTTkSlot
from TermTk.TTkWidgets.widget import TTkWidget
from TermTk.TTkTemplates.lookandfeel import TTkLookAndFeel
class TTkLookAndFeelPBar(TTkLookAndFeel):
class TTkLookAndFeel():
__slots__ = ('modified')
def __init__(self, *args, **kwargs):
self.modified = pyTTkSignal()
class TTkLookAndFeelFPBar(TTkLookAndFeel):
progresssBarColor = TTkColor.fg('#0000aa')+TTkColor.bg("#000044")
progressBarTextColor = TTkColor.fg('#ffffff')
__slots__ = ('_textWidth', '_showText')
def __init__(self, showText=True, textWidth=4):
super().__init__()
@ -56,21 +66,22 @@ class TTkLookAndFeelPBar(TTkLookAndFeel):
self.modified.emit()
def color(self, value, minimum, maximum):
return TTkCfg.theme.progresssBarColor
return self.progresssBarColor
def text(self, value, minimum, maximum):
percent = round(100*(value-minimum)/(maximum-minimum))
return TTkString(f"{percent:3}%", color=TTkCfg.theme.progressBarTextColor)
return TTkString(f"{percent:3}%", color=self.progressBarTextColor)
'''
Progressbar: | |
rest block ^
full blocks ^^^^^^^^
'''
class TTkProgressBar(TTkWidget):
'''TTkProgressBar'''
class TTkFancyProgressBar(TTkWidget):
'''TTkFancyProgressBar'''
__slots__ = (
'_lookAndFeel',
'_value', '_minimum', '_maximum',
# Signals
'valueChanged')
@ -78,8 +89,8 @@ class TTkProgressBar(TTkWidget):
def __init__(self, *args, **kwargs):
self.valueChanged = pyTTkSignal(float)
TTkWidget.__init__(self, *args, **kwargs)
if not kwargs.get('lookAndFeel'):
self.setLookAndFeel(TTkLookAndFeelPBar())
self._lookAndFeel = kwargs.get('lookAndFeel',TTkLookAndFeelFPBar())
self._lookAndFeel.modified.connect(self.update)
self._value_min, self._value_max, self._value = 0.0, 1.0, 0.0
self.setValue(kwargs.get('value', 0.0))
self.setMinimumSize(3, 1)
@ -154,7 +165,7 @@ class TTkProgressBar(TTkWidget):
def paintEvent(self, canvas):
width, height = self.size()
laf = self.lookAndFeel()
laf = self._lookAndFeel
text = laf.text(self._value, self._value_min, self._value_max)
color_bar = laf.color(self._value, self._value_min, self._value_max)
blocks = TTkCfg.theme.progressbarBlocks

4
TermTk/TTkWidgets/Fancy/table.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkFancyTable']
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkWidgets.Fancy.tableview import TTkFancyTableView
from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollArea

4
TermTk/TTkWidgets/Fancy/tableview.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkFancyTableView']
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal
from TermTk.TTkCore.color import TTkColor

4
TermTk/TTkWidgets/Fancy/tree.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkFancyTree']
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkWidgets.Fancy.treewidget import TTkFancyTreeWidget
from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollArea

4
TermTk/TTkWidgets/Fancy/treeview.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkFancyTreeView']
from TermTk.TTkWidgets.Fancy.tableview import TTkFancyTableView
class TTkFancyTreeView(TTkFancyTableView):

7
TermTk/TTkWidgets/Fancy/treewidget.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,11 +20,14 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkFancyTreeWidget']
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.log import TTkLog
from TermTk.TTkCore.string import TTkString
from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal
from TermTk.TTkWidgets.widget import TTkWidget
from TermTk.TTkWidgets.container import TTkContainer
from TermTk.TTkWidgets.checkbox import TTkCheckbox
from TermTk.TTkWidgets.Fancy.tableview import TTkFancyTableView
from TermTk.TTkWidgets.Fancy.treewidgetitem import TTkFancyTreeWidgetItem
@ -43,7 +44,7 @@ class _TTkDisplayedTreeItemControl(TTkCheckbox):
canvas.drawText(pos=(0,0), text="")
class _TTkDisplayedTreeItem(TTkWidget):
class _TTkDisplayedTreeItem(TTkContainer):
__slots__ = ('_depth', '_control', '_text', '_id', '_clicked', '_treeWidgetItem', '_isLeaf' )
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

4
TermTk/TTkWidgets/Fancy/treewidgetitem.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkFancyTreeWidgetItem']
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.signal import pyTTkSignal

12
TermTk/TTkWidgets/TTkModelView/__init__.py

@ -1,6 +1,6 @@
from .tree import TTkTree
from .treewidget import TTkTreeWidget
from .treewidgetitem import TTkTreeWidgetItem
from .filetree import TTkFileTree
from .filetreewidget import TTkFileTreeWidget
from .filetreewidgetitem import TTkFileTreeWidgetItem
from .tree import *
from .treewidget import *
from .treewidgetitem import *
from .filetree import *
from .filetreewidget import *
from .filetreewidgetitem import *

4
TermTk/TTkWidgets/TTkModelView/filetree.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkFileTree']
from TermTk.TTkWidgets.TTkModelView.tree import TTkTree
from TermTk.TTkWidgets.TTkModelView.filetreewidget import TTkFileTreeWidget

4
TermTk/TTkWidgets/TTkModelView/filetreewidget.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkFileTreeWidget']
import os
import datetime

4
TermTk/TTkWidgets/TTkModelView/filetreewidgetitem.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkFileTreeWidgetItem']
import re
from TermTk.TTkCore.constant import TTkK

7
TermTk/TTkWidgets/TTkModelView/tree.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkTree']
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkWidgets.TTkModelView.treewidget import TTkTreeWidget
from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollArea
@ -33,7 +33,7 @@ class TTkTree(TTkAbstractScrollArea):
'itemActivated', 'itemChanged', 'itemClicked', 'itemExpanded', 'itemCollapsed', 'itemDoubleClicked',
# Forwarded Methods
'setAlignment', 'setHeader', 'setHeaderLabels', 'setColumnSize', 'setColumnColors', 'appendItem',
'addTopLevelItem', 'takeTopLevelItem', 'topLevelItem', 'indexOfTopLevelItem', 'selectedItems', 'clear' )
'addTopLevelItem', 'addTopLevelItems', 'takeTopLevelItem', 'topLevelItem', 'indexOfTopLevelItem', 'selectedItems', 'clear' )
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@ -58,6 +58,7 @@ class TTkTree(TTkAbstractScrollArea):
#self.setColumnColors = self._treeView.setColumnColors
#self.appendItem = self._treeView.appendItem
self.addTopLevelItem = self._treeView.addTopLevelItem
self.addTopLevelItems = self._treeView.addTopLevelItems
self.takeTopLevelItem = self._treeView.takeTopLevelItem
self.topLevelItem = self._treeView.topLevelItem
self.indexOfTopLevelItem = self._treeView.indexOfTopLevelItem

56
TermTk/TTkWidgets/TTkModelView/treewidget.py

@ -1,5 +1,3 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
@ -22,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkTreeWidget']
from TermTk.TTkCore.cfg import TTkCfg
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.string import TTkString
@ -33,9 +33,25 @@ from TermTk.TTkCore.signal import pyTTkSignal, pyTTkSlot
from dataclasses import dataclass
class TTkTreeWidget(TTkAbstractScrollView):
'''TTkTreeWidget'''
classStyle = {
'default': {
'color': TTkColor.RST,
'lineColor': TTkColor.fg("#444444"),
'headerColor': TTkColor.fg("#ffffff")+TTkColor.bg("#444444")+TTkColor.BOLD,
'selectedColor': TTkColor.fg("#ffff88")+TTkColor.bg("#000066")+TTkColor.BOLD,
'separatorColor': TTkColor.fg("#444444")},
'disabled': {
'color': TTkColor.fg("#888888"),
'lineColor': TTkColor.fg("#888888"),
'headerColor': TTkColor.fg("#888888"),
'selectedColor': TTkColor.fg("#888888"),
'separatorColor': TTkColor.fg("#888888")},
}
__slots__ = ( '_rootItem', '_header', '_columnsPos', '_cache',
'_selectedId', '_selected', '_separatorSelected', '_mouseDelta',
'_headerColor', '_selectedColor', '_lineColor',
'_sortColumn', '_sortOrder',
# Signals
'itemChanged', 'itemClicked', 'itemDoubleClicked', 'itemExpanded', 'itemCollapsed', 'itemActivated'
@ -66,9 +82,6 @@ class TTkTreeWidget(TTkAbstractScrollView):
self._cache = []
self._sortColumn = -1
self._sortOrder = TTkK.AscendingOrder
self._headerColor = kwargs.get('headerColor', TTkCfg.theme.treeHeaderColor)
self._selectedColor = kwargs.get('selectedColor', TTkCfg.theme.treeSelectedColor)
self._lineColor = kwargs.get('lineColor', TTkCfg.theme.treeLineColor)
self.setMinimumHeight(1)
self.setFocusPolicy(TTkK.ClickFocus)
self._rootItem = TTkTreeWidgetItem(expanded=True)
@ -96,7 +109,7 @@ class TTkTreeWidget(TTkAbstractScrollView):
def clear(self):
# Remove all the widgets
for ri in self._rootItem.children():
ri.setParent(None)
ri.setTreeItemParent(None)
if self._rootItem:
self._rootItem.dataChanged.disconnect(self._refreshCache)
self._rootItem = TTkTreeWidgetItem(expanded=True)
@ -108,7 +121,16 @@ class TTkTreeWidget(TTkAbstractScrollView):
def addTopLevelItem(self, item):
self._rootItem.addChild(item)
item.setParent(self)
item.setTreeItemParent(self)
self._refreshCache()
self.viewChanged.emit()
self.update()
def addTopLevelItems(self, items):
self._rootItem.addChildren(items)
self._rootItem.setTreeItemParent(self)
#for item in items:
# item.setTreeItemParent(self)
self._refreshCache()
self.viewChanged.emit()
self.update()
@ -334,6 +356,14 @@ class TTkTreeWidget(TTkAbstractScrollView):
self.viewChanged.emit()
def paintEvent(self, canvas):
style = self.currentStyle()
color= style['color']
lineColor= style['lineColor']
headerColor= style['headerColor']
selectedColor= style['selectedColor']
separatorColor= style['separatorColor']
x,y = self.getViewOffsets()
w,h = self.size()
tt = TTkCfg.theme.tree
@ -342,15 +372,15 @@ class TTkTreeWidget(TTkAbstractScrollView):
for i,l in enumerate(self._header):
hx = 0 if i==0 else self._columnsPos[i-1]+1
hx1 = self._columnsPos[i]
canvas.drawText(pos=(hx-x,0), text=l, width=hx1-hx, color=self._headerColor)
canvas.drawText(pos=(hx-x,0), text=l, width=hx1-hx, color=headerColor)
if i == self._sortColumn:
s = tt[6] if self._sortOrder == TTkK.AscendingOrder else tt[7]
canvas.drawText(pos=(hx1-x-1,0), text=s, color=self._headerColor)
canvas.drawText(pos=(hx1-x-1,0), text=s, color=headerColor)
# Draw header separators
for sx in self._columnsPos:
canvas.drawChar(pos=(sx-x,0), char=tt[5], color=self._headerColor)
canvas.drawChar(pos=(sx-x,0), char=tt[5], color=headerColor)
for sy in range(1,h):
canvas.drawChar(pos=(sx-x,sy), char=tt[4], color=self._lineColor)
canvas.drawChar(pos=(sx-x,sy), char=tt[4], color=lineColor)
# Draw cache
for i, c in enumerate(self._cache):
@ -362,6 +392,6 @@ class TTkTreeWidget(TTkAbstractScrollView):
text = c.data[il]
if item.isSelected():
canvas.drawText(pos=(lx-x,i-y+1), text=text.completeColor(self._selectedColor), width=lx1-lx, alignment=item.textAlignment(il), color=self._selectedColor)
canvas.drawText(pos=(lx-x,i-y+1), text=text.completeColor(selectedColor), width=lx1-lx, alignment=item.textAlignment(il), color=selectedColor)
else:
canvas.drawText(pos=(lx-x,i-y+1), text=text, width=lx1-lx, alignment=item.textAlignment(il))

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save