From eab5aad9bc004d517c0ec2c95e07db1972a90eaa Mon Sep 17 00:00:00 2001 From: Eugenio Parodi Date: Tue, 6 Dec 2022 18:34:59 +0000 Subject: [PATCH] Tree: Use TTkString to support non conventional chars, and Fix borderline issues --- TermTk/TTkCore/string.py | 26 +++++++- TermTk/TTkTemplates/text.py | 5 +- TermTk/TTkWidgets/TTkModelView/treewidget.py | 5 +- .../TTkWidgets/TTkModelView/treewidgetitem.py | 4 +- tests/test.draw.006.py | 2 - tests/test.draw.007.py | 66 +++++++++++++++++++ 6 files changed, 99 insertions(+), 9 deletions(-) create mode 100755 tests/test.draw.007.py diff --git a/TermTk/TTkCore/string.py b/TermTk/TTkCore/string.py index f151c608..1a06f73b 100644 --- a/TermTk/TTkCore/string.py +++ b/TermTk/TTkCore/string.py @@ -294,7 +294,27 @@ class TTkString(): # TODO: Text Justification ret._text = self._text + " " *pad ret._colors = self._colors + [color]*pad + elif self._hasSpecialWidth: + # Trim the string to a fixed size taking care of the variable width unicode chars + rt = "" + sz = 0 + for ch in self._text: + if unicodedata.category(ch) in ('Me','Mn'): + rt += ch + continue + if sz == width: + ret._text = rt + ret._colors = self._colors[:len(rt)] + break + elif sz > width: + ret._text = rt[:-1]+">" + ret._colors = self._colors[:len(ret._text)] + ret._colors[-1] = TTkColor.fg("#888888")+TTkColor.bg("000088") + break + rt += ch + sz += 2 if unicodedata.east_asian_width(ch) == 'W' else 1 else: + # Legacy, trim the string ret._text = self._text[:width] ret._colors = self._colors[:width] @@ -565,9 +585,9 @@ class TTkString(): elif unicodedata.category(ch) in ('Me','Mn'): if retTxt: retTxt[-1]+=ch - else: - retTxt = [f" {ch}"] - retCol = [TTkColor.RST] + #else: + # retTxt = [f"{ch}"] + # retCol = [TTkColor.RST] else: retTxt.append(ch) retCol.append(self._colors[i]) diff --git a/TermTk/TTkTemplates/text.py b/TermTk/TTkTemplates/text.py index 29fda085..9636267d 100644 --- a/TermTk/TTkTemplates/text.py +++ b/TermTk/TTkTemplates/text.py @@ -42,6 +42,9 @@ class TText(): @text.setter def text(self, text): if self.text != text: - self._text = text + if issubclass(type(text), TTkString): + self._text = text + else: + self._text = TTkString(text) self.textUpdated(text) diff --git a/TermTk/TTkWidgets/TTkModelView/treewidget.py b/TermTk/TTkWidgets/TTkModelView/treewidget.py index 51ce5336..7952e3f2 100644 --- a/TermTk/TTkWidgets/TTkModelView/treewidget.py +++ b/TermTk/TTkWidgets/TTkModelView/treewidget.py @@ -24,6 +24,7 @@ from TermTk.TTkCore.cfg import TTkCfg from TermTk.TTkCore.constant import TTkK +from TermTk.TTkCore.string import TTkString from TermTk.TTkWidgets.TTkModelView.treewidgetitem import TTkTreeWidgetItem from TermTk.TTkAbstract.abstractscrollview import TTkAbstractScrollView from TermTk.TTkCore.signal import pyTTkSignal, pyTTkSlot @@ -250,9 +251,9 @@ class TTkTreeWidget(TTkAbstractScrollView): if _icon: _icon = ' '+_icon+' ' if _il==0: - _data.append(' '*_level+_icon+_child.data(_il)) + _data.append(TTkString(' '*_level+_icon+_child.data(_il))) else: - _data.append(_icon+_child.data(_il)) + _data.append(TTkString(_icon+_child.data(_il))) self._cache.append(TTkTreeWidget._Cache( item = _child, diff --git a/TermTk/TTkWidgets/TTkModelView/treewidgetitem.py b/TermTk/TTkWidgets/TTkModelView/treewidgetitem.py index a2fa1f55..4425c1f0 100644 --- a/TermTk/TTkWidgets/TTkModelView/treewidgetitem.py +++ b/TermTk/TTkWidgets/TTkModelView/treewidgetitem.py @@ -24,6 +24,7 @@ from TermTk.TTkCore.cfg import TTkCfg from TermTk.TTkCore.constant import TTkK +from TermTk.TTkCore.string import TTkString from TermTk.TTkCore.signal import pyTTkSlot from TermTk.TTkAbstract.abstractitemmodel import TTkAbstractItemModel @@ -41,7 +42,8 @@ class TTkTreeWidgetItem(TTkAbstractItemModel): # self.refreshData = pyTTkSignal(TTkTreeWidgetItem) super().__init__(*args, **kwargs) self._children = [] - self._data = args[0] if len(args)>0 and type(args[0])==list else [''] + data = args[0] if len(args)>0 and type(args[0])==list else [TTkString()] + self._data = [i if issubclass(type(i), TTkString) else TTkString(i) if isinstance(i,str) else TTkString() for i in data] self._alignment = [TTkK.LEFT_ALIGN]*len(self._data) self._parent = kwargs.get('parent', None) self._childIndicatorPolicy = kwargs.get('childIndicatorPolicy', TTkK.DontShowIndicatorWhenChildless) diff --git a/tests/test.draw.006.py b/tests/test.draw.006.py index 1d99fe58..e2387ce3 100755 --- a/tests/test.draw.006.py +++ b/tests/test.draw.006.py @@ -80,8 +80,6 @@ s01 = TTkString(f"👩🏽‍🔧 = {chr(0x1F469)}{chr(0x1F3FD)}{chr(0x0200D)} s01 = TTkString(f"👩🏾‍🔧 = {chr(0x1F469)}{chr(0x1F3FE)}{chr(0x0200D)}{chr(0x1F527)}") # 1F469 1F3FE 200D 1F527 : 👩🏾‍🔧 s01 = TTkString(f"👩🏿‍🔧 = {chr(0x1F469)}{chr(0x1F3FF)}{chr(0x0200D)}{chr(0x1F527)}") # 1F469 1F3FF 200D 1F527 : 👩🏿‍🔧 - - print(s1.getData()[0]) print(s2.getData()[0]) print(s3.getData()[0]) diff --git a/tests/test.draw.007.py b/tests/test.draw.007.py new file mode 100755 index 00000000..60785ca8 --- /dev/null +++ b/tests/test.draw.007.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 + +# MIT License +# +# Copyright (c) 2022 Eugenio Parodi +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import sys, os +import logging +import time + +sys.path.append(os.path.join(sys.path[0],'..')) +from TermTk import TTkLog +from TermTk.TTkCore import TTkColor +from TermTk.TTkCore import TTkHelper +from TermTk.TTkCore import TTkString +from TermTk.TTkCore import TTkTerm +from TermTk.TTkCore import TTkCanvas + + +# TTkLog.use_default_file_logging() +TTkLog.use_default_stdout_logging() + +# TTkTerm.init(mouse=False) +TTkLog.info("Starting") + +s1 = TTkString("-😁😂😍😎----") +s2 = TTkString("--😐😁😂😍😎-") + +zc1 = chr(0x07a6) +zc2 = chr(0x20D7) +zc3 = chr(0x065f) +s3 = TTkString(f"Zero Size: - o{zc1} o{zc2} o{zc3} o{zc1}{zc2} o{zc1}{zc2}{zc3} -") + +s4 = TTkString("This is a normal string") + +s5 = TTkString(f"-😁- o{zc1} o{zc2} o{zc3} o{zc1}{zc2} o{zc1}{zc2}{zc3} -") +s6 = TTkString(f"{zc1} o{zc2} o{zc3} o{zc1}{zc2} o{zc1}{zc2}{zc3} -") +TTkLog.debug(f"o{zc1}{zc2}{zc3} - Zero") +TTkLog.debug(f"{zc1}{zc2}{zc3} - Zero") + +canvas = TTkCanvas(width=100,height=100) +canvas.drawTTkString(pos=(0,0),text=s1,width=4) +canvas.drawTTkString(pos=(0,0),text=s1,width=11) +canvas.drawTTkString(pos=(0,0),text=s5,width=8) +canvas.drawTTkString(pos=(0,0),text=s6,width=4) + + +TTkLog.info("Ending")