diff --git a/demo/demo.py b/demo/demo.py index a569277d..ae96d143 100755 --- a/demo/demo.py +++ b/demo/demo.py @@ -54,7 +54,7 @@ from showcase.dragndrop import demoDnD from showcase.dndtabs import demoDnDTabs from showcase.sigmask import demoSigmask from showcase.apptemplate import demoAppTemplate -from showcase.datetime import demoDateTimePicker +from showcase.date_time import demoDateTimePicker def stupidPythonHighlighter(txt): def _colorize(regex, txt, color): @@ -185,7 +185,7 @@ def demoShowcase(root=None, border=True): tabPickers.addTab(demoFilePicker(), " File Picker ", 'showcase/filepicker.py') tabPickers.addTab(demoColorPicker(), " Color Picker ", 'showcase/colorpicker.py') tabPickers.addTab(demoTextPicker(), " Text Picker ", 'showcase/textpicker.py') - tabPickers.addTab(demoDateTimePicker(), " DateTime Picker ", 'showcase/datetime.py') + tabPickers.addTab(demoDateTimePicker(), " DateTime Picker ", 'showcase/date_time.py') tabPickers.addMenu("sources", ttk.TTkK.RIGHT, tabPickers).menuButtonClicked.connect(lambda _menuButton : showSource(_menuButton.data().currentData())) listMenu.addItem(f"Graphs") @@ -243,7 +243,7 @@ def main(): root = ttk.TTk(title="pyTermTk Demo", mouseTrack=mouseTrack) if windowed: - winTabbed1 = ttk.TTkWindow(parent=root,pos=(0,0), size=(120,40), title="pyTermTk Showcase", border=True, layout=ttk.TTkGridLayout(), flags=ttk.TTkK.NONE) + winTabbed1 = ttk.TTkWindow(parent=root,pos=(0,0), size=(120,40), title="pyTermTk Showcase", border=True, layout=ttk.TTkGridLayout(), flags=ttk.TTkK.WindowFlag.NONE) border = True else: root.setLayout(ttk.TTkGridLayout()) diff --git a/demo/showcase/datetime.py b/demo/showcase/date_time.py similarity index 100% rename from demo/showcase/datetime.py rename to demo/showcase/date_time.py diff --git a/demo/showcase/windowsflags.py b/demo/showcase/windowsflags.py index 12ec669d..4bb1f4f2 100755 --- a/demo/showcase/windowsflags.py +++ b/demo/showcase/windowsflags.py @@ -69,7 +69,7 @@ def demoWindowsFlags(root=None): flags = ttk.TTkK.WindowFlag.WindowMaximizeButtonHint | ttk.TTkK.WindowFlag.WindowCloseButtonHint) # Disable all the control buttons WindowFlagsTest(parent=frame, pos = (4,4), size=(40,8), title="Test Window 3", - flags = ttk.TTkK.NONE) + flags = ttk.TTkK.WindowFlag.NONE) # Enable only the Max and Min Buttons WindowFlagsTest(parent=frame, pos = (6,6), size=(40,8), title="Test Window 4", flags = ttk.TTkK.WindowFlag.WindowMinMaxButtonsHint) diff --git a/libs/pyTermTk/TermTk/TTkCore/TTkTerm/inputkey.py b/libs/pyTermTk/TermTk/TTkCore/TTkTerm/inputkey.py index 66476865..4fb5c5d1 100644 --- a/libs/pyTermTk/TermTk/TTkCore/TTkTerm/inputkey.py +++ b/libs/pyTermTk/TermTk/TTkCore/TTkTerm/inputkey.py @@ -22,6 +22,8 @@ __all__ = ['TTkKeyEvent'] +from typing import Union + from TermTk.TTkCore.constant import TTkK class TTkKeyEvent: @@ -60,7 +62,7 @@ class TTkKeyEvent: ''' __slots__ = ('type', 'key', 'code', 'mod') - def __init__(self, type:int, key: str, code: str, mod: int): + def __init__(self, type:int, key: Union[str,int], code: str, mod: int): self.type = type self.key = key self.mod = mod diff --git a/libs/pyTermTk/TermTk/TTkCore/cfg.py b/libs/pyTermTk/TermTk/TTkCore/cfg.py index 303c104f..c3f6a086 100644 --- a/libs/pyTermTk/TermTk/TTkCore/cfg.py +++ b/libs/pyTermTk/TermTk/TTkCore/cfg.py @@ -19,13 +19,18 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from __future__ import annotations __all__ = ['TTkCfg', 'TTkGlbl'] -from TermTk.TTkCore.constant import TTkK +from typing import TYPE_CHECKING, Optional +if TYPE_CHECKING: + from TermTk.TTkTheme.theme import TTkTheme + from TermTk import __version__ +from TermTk.TTkCore.constant import TTkK -class TTkCfg: +class _TTkCfg: version:str = __version__ name:str = "pyTermTk" @@ -36,8 +41,17 @@ class TTkCfg: doubleBuffer:bool = True doubleBufferNew:bool = False - scrollDelta:bool = 5 - theme = None + scrollDelta:int = 5 + + _theme:Optional[TTkTheme] = None + @property + def theme(self) -> TTkTheme: + if not TTkCfg._theme: + from TermTk.TTkTheme.theme import TTkTheme + TTkCfg._theme = TTkTheme() + return TTkCfg._theme + +TTkCfg = _TTkCfg() class TTkGlbl: term_w: int = 0 diff --git a/libs/pyTermTk/TermTk/TTkCore/constant.py b/libs/pyTermTk/TermTk/TTkCore/constant.py index f9ab4732..25fd581c 100644 --- a/libs/pyTermTk/TermTk/TTkCore/constant.py +++ b/libs/pyTermTk/TermTk/TTkCore/constant.py @@ -565,7 +565,7 @@ class TTkConstant: LayoutItem = LayoutItemTypes.LayoutItem WidgetItem = LayoutItemTypes.WidgetItem - class WindowFlag(int): + class WindowFlag(Flag): ''' Those flags are used to enable customization of the window controls. @@ -576,6 +576,8 @@ class TTkConstant: WindowMinMaxButtonsHint WindowCloseButtonHint ''' + NONE = 0 + '''Empty flag''' # FramelessWindowHint = 0x00000800 # ''' Produces a borderless window.''' # CustomizeWindowHint = 0x02000000 @@ -676,7 +678,7 @@ class TTkConstant: CTRL = KeyModifier.CTRL ALT = KeyModifier.ALT - class ShortcutContext(int): + class ShortcutContext(IntEnum): ''' For a :py:class:`TTkShortcut` event to occur, the shortcut's key sequence must be entered by the user in a context where the shortcut is active. diff --git a/libs/pyTermTk/TermTk/TTkCore/shortcut.py b/libs/pyTermTk/TermTk/TTkCore/shortcut.py index ec8dbcd8..a6b0f8e0 100644 --- a/libs/pyTermTk/TermTk/TTkCore/shortcut.py +++ b/libs/pyTermTk/TermTk/TTkCore/shortcut.py @@ -20,21 +20,27 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from __future__ import annotations + __all__ = ['TTkShortcut'] +from typing import TYPE_CHECKING,Dict,List,Union,Optional + from TermTk.TTkCore.log import TTkLog from TermTk.TTkCore.constant import TTkK from TermTk.TTkCore.helper import TTkHelper from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal from TermTk.TTkCore.TTkTerm.inputkey import TTkKeyEvent -class TTkStandardKey(): +if TYPE_CHECKING: + from TermTk.TTkWidgets.widget import TTkWidget + +class _TTkStandardKey(): pass -class TTkKeySequence(): +class _TTkKeySequence(): __slots__ = ('_key') def __init__(self, key:int): - self._key = key mod = ( ( TTkK.ControlModifier if key & TTkK.CTRL else 0 ) | ( TTkK.AltModifier if key & TTkK.ALT else 0 ) | @@ -47,27 +53,27 @@ class TTkKeySequence(): else: self._key = TTkKeyEvent(mod=mod, code="", type=TTkK.Character, key=chr(key) ) - - def __hash__(self) -> int: return self._key.__hash__() - def __eq__(self, __value: object) -> bool: - pass class TTkShortcut(): '''TTkShortcut''' - _shortcuts = {} + _shortcuts:Dict[TTkKeyEvent,List[TTkShortcut]] = {} __slots__ = ( - '_key', '_parent', '_shortcutContext', + '_parent', '_shortcutContext', # Signals 'activated') def __init__(self, - key:int, parent=None, + key:Union[int,TTkKeyEvent], parent:Optional['TTkWidget']=None, shortcutContext: TTkK.ShortcutContext = TTkK.ShortcutContext.WindowShortcut): if type(key) == int: - key = TTkKeySequence(key)._key - self._key = key + key = _TTkKeySequence(key)._key + elif isinstance(key, TTkKeyEvent): + key = key + else: + raise TypeError(f"{key=} is not int or TTkKeyEvent") + self._parent = parent self._shortcutContext = shortcutContext # Signals @@ -77,24 +83,17 @@ class TTkShortcut(): TTkShortcut._shortcuts[key].append(self) @staticmethod - def processKey(key, focusWidget): - # TTkLog.debug(f"{str(key)=}") - # for k in TTkShortcut._shortcuts: - # TTkLog.debug(f"{str(k)=} - {key==k=}") - if key in TTkShortcut._shortcuts: - for sc in TTkShortcut._shortcuts[key]: - # if sc._parent: - # TTkLog.debug(f"{focusWidget=} {sc._parent=} {sc._parent._parent=}") - # else: - # TTkLog.debug(f"{focusWidget=} {sc._parent=}") - if ( ( sc._shortcutContext == TTkK.WidgetShortcut - and focusWidget == sc._parent ) - or ( sc._shortcutContext == TTkK.WidgetWithChildrenShortcut - and ( focusWidget == sc._parent - or TTkHelper.isParent(sc._parent,focusWidget) ) ) - or ( sc._shortcutContext == TTkK.WindowShortcut ) - or ( sc._shortcutContext == TTkK.ApplicationShortcut )): - if sc.activated._connected_slots: - sc.activated.emit() - return True + def processKey(key:TTkKeyEvent, focusWidget:'TTkWidget') -> bool: + for sc in TTkShortcut._shortcuts.get(key,[]): + if ( ( sc._shortcutContext == TTkK.WidgetShortcut + and focusWidget == sc._parent ) + or ( sc._shortcutContext == TTkK.WidgetWithChildrenShortcut + and sc._parent + and ( focusWidget == sc._parent + or TTkHelper.isParent(sc._parent,focusWidget) ) ) + or ( sc._shortcutContext == TTkK.WindowShortcut ) + or ( sc._shortcutContext == TTkK.ApplicationShortcut )): + if sc.activated._connected_slots: + sc.activated.emit() + return True return False diff --git a/libs/pyTermTk/TermTk/TTkCore/string.py b/libs/pyTermTk/TermTk/TTkCore/string.py index c2f42643..04a90758 100644 --- a/libs/pyTermTk/TermTk/TTkCore/string.py +++ b/libs/pyTermTk/TermTk/TTkCore/string.py @@ -179,8 +179,8 @@ class TTkString(): def __gt__(self, other): return self._text > other._text if issubclass(type(other),TTkString) else self._text > other def __ge__(self, other): return self._text >= other._text if issubclass(type(other),TTkString) else self._text >= other - def sameAs(self, other:TTkString) -> bool: - if not issubclass(type(other),TTkString): return False + def sameAs(self, other:TTkStringType) -> bool: + if not isinstance(other,TTkString): return False return ( self==other and len(self._colors) == len(other._colors) and @@ -602,7 +602,7 @@ class TTkString(): def getIndexes(self, char): return [i for i,c in enumerate(self._text) if c==char] - def join(self, strings:Union[GeneratorType[TTkStringType,None,None],List[TTkStringType]]) -> TTkString: + def join(self, strings:Union[GeneratorType[TTkStringType,None,None],List[TTkStringType],List[TTkString],List[str]]) -> TTkString: ''' Join the input strings using the current as separator :param strings: the list of strings to be joined @@ -638,7 +638,7 @@ class TTkString(): sum(unicodedata.category(ch) in ('Me','Mn') for ch in txt) ) @staticmethod - def _getLenTextWoZero(txt:str): + def _getLenTextWoZero(txt:str) -> int: return ( len(txt) - sum(unicodedata.category(ch) in ('Me','Mn') for ch in txt) ) diff --git a/libs/pyTermTk/TermTk/TTkCore/timer_pyodide.py b/libs/pyTermTk/TermTk/TTkCore/timer_pyodide.py index 9fb60096..1b01e659 100644 --- a/libs/pyTermTk/TermTk/TTkCore/timer_pyodide.py +++ b/libs/pyTermTk/TermTk/TTkCore/timer_pyodide.py @@ -20,9 +20,11 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from __future__ import annotations + __all__ = ['TTkTimer'] -from typing import Optional,Callable +from typing import Optional,Callable,Dict from TermTk.TTkCore.helper import TTkHelper from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal @@ -30,7 +32,7 @@ from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal import pyodideProxy class TTkTimer(): - _timers = {} + _timers:Dict[int,TTkTimer] = {} _uid = 0 __slots__ = ( diff --git a/libs/pyTermTk/TermTk/TTkCore/ttk.py b/libs/pyTermTk/TermTk/TTkCore/ttk.py index e199083f..fead7f3d 100644 --- a/libs/pyTermTk/TermTk/TTkCore/ttk.py +++ b/libs/pyTermTk/TermTk/TTkCore/ttk.py @@ -119,6 +119,7 @@ class TTk(TTkContainer): _timer:TTkTimer _exceptions:List[Exception] + _mouseCursor:Optional[_MouseCursor] def __init__(self, *, title:str='TermTk', @@ -223,7 +224,6 @@ class TTk(TTkContainer): if self._showMouseCursor: self._mouseCursor = _MouseCursor() self._mouseCursor.updated.connect(self.update) - self.paintChildCanvas = self._mouseCursorPaintChildCanvas if platform.system() != 'Emscripten': TTkInput.start() @@ -278,7 +278,7 @@ class TTk(TTkContainer): self._timer.quit() self._paintEvent.set() - def _mouseCursorPaintChildCanvas(self) -> None: + def paintChildCanvas(self) -> None: super().paintChildCanvas() if self._mouseCursor: ch = self._mouseCursor._cursor diff --git a/libs/pyTermTk/TermTk/TTkGui/drag.py b/libs/pyTermTk/TermTk/TTkGui/drag.py index 8dcec576..e2ab7b11 100644 --- a/libs/pyTermTk/TermTk/TTkGui/drag.py +++ b/libs/pyTermTk/TermTk/TTkGui/drag.py @@ -157,12 +157,12 @@ class TTkDrag(TTkDnD): :param pixmap: the pixmap :type pixmap: :py:class:`TTkWidget` or :py:class:`TTkCanvas` ''' - if issubclass(type(pixmap),TTkWidget): + if isinstance(pixmap, TTkWidget): canvas = pixmap.getCanvas() canvas.updateSize() pixmap.paintEvent(canvas) pixmap = canvas - if type(pixmap) is TTkCanvas: + if isinstance(pixmap, TTkCanvas): pixmap.updateSize() self._pixmap.setPixmap(pixmap, self._hotSpot) diff --git a/libs/pyTermTk/TermTk/TTkGui/textcursor.py b/libs/pyTermTk/TermTk/TTkGui/textcursor.py index 249656bc..8461031e 100644 --- a/libs/pyTermTk/TermTk/TTkGui/textcursor.py +++ b/libs/pyTermTk/TermTk/TTkGui/textcursor.py @@ -20,16 +20,13 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from __future__ import annotations + __all__ = ['TTkTextCursor'] from enum import IntEnum -from typing import List - -try: - from typing import Self -except: - class Self(): pass +from typing import List, Optional, Tuple from TermTk.TTkCore.log import TTkLog from TermTk.TTkCore.color import TTkColor @@ -48,7 +45,7 @@ class _CP(): pos:int def __init__(self, l:int=0, p:int=0) -> None: self.set(l,p) - def copy(self) -> Self: + def copy(self) -> _CP: return _CP(self.line, self.pos) def set(self, l, p) -> None: self.pos = p @@ -64,7 +61,7 @@ class _Prop(): self.anchor:_CP = anchor self.position:_CP = position - def copy(self) -> Self: + def copy(self) -> _Prop: return _Prop(self.anchor.copy(), self.position.copy()) def selectionStart(self) -> _CP: @@ -183,30 +180,31 @@ class TTkTextCursor(): PreviousRow = MoveOperation.PreviousRow __slots__ = ('_document', '_properties', '_cID', '_color', '_autoChanged') - def __init__(self, document:TTkTextDocument=None) -> None: + _color:Optional[TTkColor] + _document:TTkTextDocument + _properties:list[_Prop] + def __init__(self, document:TTkTextDocument) -> None: self._color = None self._cID = 0 self._autoChanged = False self._properties = [_Prop(_CP(),_CP())] - if document: - self._document = document - self._document.contentsChanged.connect(self._documentContentChanged) + self._document = document + self._document.contentsChanged.connect(self._documentContentChanged) def _documentContentChanged(self): if self._autoChanged: return True self.clearCursors() self.clearSelection() - def copy(self) -> Self: - ret = TTkTextCursor() - ret._document = self._document + def copy(self) -> TTkTextCursor: + ret = TTkTextCursor(self._document) ret._properties = [p.copy() for p in self._properties] ret._cID = self._cID ret._color = self._color ret._autoChanged = self._autoChanged return ret - def restore(self, cursor:Self) -> None: + def restore(self, cursor:TTkTextCursor) -> None: self._document = cursor._document self._properties = [p.copy() for p in cursor._properties] self._cID = cursor._cID @@ -226,7 +224,7 @@ class TTkTextCursor(): def position(self) -> _CP: return self._properties[self._cID].position - def cursors(self) -> list[_CP]: + def cursors(self) -> list[_Prop]: return self._properties def addCursor(self, line:int, pos:int) -> None: @@ -302,7 +300,7 @@ class TTkTextCursor(): if notify or currPos != currCurs.position.toNum(): self._document.cursorPositionChanged.emit(self) - def movePosition(self, operation:MoveOperation, moveMode:MoveMode=MoveMode.MoveAnchor, n=1, textWrap:TTkTextWrap=None) -> None: + def movePosition(self, operation:MoveOperation, moveMode:MoveMode=MoveMode.MoveAnchor, n=1, textWrap:Optional[TTkTextWrap]=None) -> None: currPos = self.position().toNum() def moveRight(cID,p,_): if p.pos < len(self._document._dataLines[p.line]): @@ -318,6 +316,8 @@ class TTkTextCursor(): self.setPosition(p.line-1, len(self._document._dataLines[p.line-1]) , moveMode, cID=cID) def moveUpDown(offset): def _moveUpDown(cID,p,n): + if not textWrap: + raise ValueError("textWrap is required for the Up,Down movement") cx, cy = textWrap.dataToScreenPosition(p.line, p.pos) x, y = textWrap.normalizeScreenPosition(cx,cy+offset*n) line, pos = textWrap.screenToDataPosition(x,y) @@ -359,11 +359,13 @@ class TTkTextCursor(): # if there is no selection, just select the next n chars till the end of the line # the newline is not replaced self._document._acquire() + if isinstance(text,str): + text=TTkString(text) for p in self._properties: if not p.hasSelection(): line = p.position.line pos = p.position.pos - lenWoZero = TTkString._getLenTextWoZero(text) + lenWoZero =text.termWidth() size = len(self._document._dataLines[line]) for _ in range(lenWoZero): pos = self._document._dataLines[line].nextPos(pos) @@ -525,7 +527,7 @@ class TTkTextCursor(): return True return False - def _removeSelectedText(self) -> None: + def _removeSelectedText(self) -> Tuple[int,int,int]: currPos = self.position().toNum() lineFirst = self._properties[0].selectionStart().line diff --git a/libs/pyTermTk/TermTk/TTkGui/textdocument.py b/libs/pyTermTk/TermTk/TTkGui/textdocument.py index 9f0e7ab2..aa1fef2c 100644 --- a/libs/pyTermTk/TermTk/TTkGui/textdocument.py +++ b/libs/pyTermTk/TermTk/TTkGui/textdocument.py @@ -316,7 +316,7 @@ class TTkTextDocument(): self.undoAvailable.emit(self.isUndoAvailable()) self.redoAvailable.emit(self.isRedoAvailable()) - def find(self, exp:TTkStringType) -> TTkTextCursor: + def find(self, exp:TTkStringType) -> Optional[TTkTextCursor]: for i,line in enumerate(self._dataLines): if -1 != (pos := line.find(str(exp))): from .textcursor import TTkTextCursor diff --git a/libs/pyTermTk/TermTk/TTkGui/textwrap1.py b/libs/pyTermTk/TermTk/TTkGui/textwrap1.py index 75456e88..d34ee702 100644 --- a/libs/pyTermTk/TermTk/TTkGui/textwrap1.py +++ b/libs/pyTermTk/TermTk/TTkGui/textwrap1.py @@ -22,6 +22,8 @@ __all__ = ['TTkTextWrap'] +from typing import Optional + from TermTk.TTkCore.constant import TTkK from TermTk.TTkCore.signal import pyTTkSignal from TermTk.TTkCore.string import TTkString @@ -35,7 +37,7 @@ class TTkTextWrap(): # Signals 'wrapChanged' ) - def __init__(self, document:TTkTextDocument=None) -> None: + def __init__(self, document:Optional[TTkTextDocument]=None) -> None: # signals self.wrapChanged = pyTTkSignal() @@ -78,33 +80,33 @@ class TTkTextWrap(): def rewrap(self): self._lines = [] if not self._enable: - def _process(i,l): - self._lines.append((i,(0,len(l)+1))) + def _process(_i:int, _l:TTkString): + self._lines.append((_i,(0,len(_l)+1))) else: if not (w := self._wrapWidth): return - def _process(i,l:TTkString): + def _process(_i:int, _l:TTkString): fr = 0 to = 0 - if not len(l): # if the line is empty append it - self._lines.append((i,(0,0))) + if not len(_l): # if the line is empty append it + self._lines.append((_i,(0,0))) return - while len(l): - fl = l.tab2spaces(self._tabSpaces) + while len(_l): + fl = _l.tab2spaces(self._tabSpaces) if fl.termWidth() <= w: - self._lines.append((i,(fr,fr+len(l)+1))) - l=[] + self._lines.append((_i,(fr,fr+len(_l)+1))) + return else: - to = max(1,l.tabCharPos(w,self._tabSpaces)) + to = max(1,_l.tabCharPos(w,self._tabSpaces)) if self._wordWrapMode == TTkK.WordWrap: # Find the index of the first white space - s = str(l) + s = str(_l) newTo = to while newTo and ( s[newTo] != ' ' and s[newTo] != '\t' ): newTo-=1 if newTo: to = newTo - self._lines.append((i,(fr,fr+to))) - l = l.substring(to) + self._lines.append((_i,(fr,fr+to))) + _l = _l.substring(to) fr += to for i,l in enumerate(self._textDocument._dataLines): _process(i,l) diff --git a/libs/pyTermTk/TermTk/TTkTheme/theme.py b/libs/pyTermTk/TermTk/TTkTheme/theme.py index ab9b81a4..870585db 100644 --- a/libs/pyTermTk/TermTk/TTkTheme/theme.py +++ b/libs/pyTermTk/TermTk/TTkTheme/theme.py @@ -23,8 +23,8 @@ __all__ = ['TTkTheme'] from TermTk.TTkCore.color import TTkColor -from TermTk.TTkCore.helper import TTkHelper -# from TermTk.TTkCore.string import TTkString +from TermTk.TTkCore.signal import pyTTkSignal + import TermTk.TTkTheme.fileicon_nerd as fi_nerd import TermTk.TTkTheme.fileicon_utf8 as fi_utf8 import TermTk.TTkTheme.fileicon_ascii as fi_ascii @@ -68,7 +68,9 @@ class TTkTheme(): folderIconColor = TTkColor.fg("#FFFFAA") # Yellowish '''Default to **TTkColor.fg("#FFFFAA") # Yellowish**''' - fileIcon = fi_utf8.FileIcon + fileIcon = fi_utf8.FileIcon + + themeLoaded = pyTTkSignal() @staticmethod def loadTheme(theme): @@ -87,5 +89,5 @@ class TTkTheme(): TTkTheme.progressbarBlocks = theme['draw'].TTkTheme.progressbarBlocks TTkTheme.fileIcon = theme['file'].FileIcon - TTkHelper.updateAll() + TTkTheme.themeLoaded.emit() diff --git a/libs/pyTermTk/TermTk/TTkWidgets/button.py b/libs/pyTermTk/TermTk/TTkWidgets/button.py index cd7e8190..ea43b244 100644 --- a/libs/pyTermTk/TermTk/TTkWidgets/button.py +++ b/libs/pyTermTk/TermTk/TTkWidgets/button.py @@ -24,7 +24,7 @@ __all__ = ['TTkButton'] from TermTk.TTkCore.cfg import TTkCfg from TermTk.TTkCore.constant import TTkK -from TermTk.TTkCore.string import TTkString +from TermTk.TTkCore.string import TTkString, TTkStringType from TermTk.TTkCore.signal import pyTTkSignal from TermTk.TTkCore.color import TTkColor from TermTk.TTkCore.canvas import TTkCanvas @@ -102,7 +102,7 @@ class TTkButton(TTkWidget): 'clicked', 'toggled' ) def __init__(self, *, - text:TTkString="", + text:TTkStringType="", border:bool=False, checked:bool=False, checkable:bool=False, @@ -119,7 +119,10 @@ class TTkButton(TTkWidget): :param bool checkable: define if the button is checkable, defaults to "False" :type checkable: bool, optional ''' - self._text = TTkString(text).split('\n') + if isinstance(text, TTkString): + self._text = text.split('\n') + else: + self._text = TTkString(text).split('\n') textWidth = max(t.termWidth() for t in self._text) self._border = border if self._border: diff --git a/libs/pyTermTk/TermTk/TTkWidgets/datetime_date.py b/libs/pyTermTk/TermTk/TTkWidgets/datetime_date.py index 703d36d9..93852a75 100644 --- a/libs/pyTermTk/TermTk/TTkWidgets/datetime_date.py +++ b/libs/pyTermTk/TermTk/TTkWidgets/datetime_date.py @@ -61,7 +61,7 @@ class _TTkTimeWidgetState(): class TTkDate(TTkWidget): ''' TTkDate: - A widget for displaying and editing dates. (`demo `__) + A widget for displaying and editing dates. (`demo `__) :: diff --git a/libs/pyTermTk/TermTk/TTkWidgets/datetime_date_form.py b/libs/pyTermTk/TermTk/TTkWidgets/datetime_date_form.py index eaa25da8..ebba8d65 100644 --- a/libs/pyTermTk/TermTk/TTkWidgets/datetime_date_form.py +++ b/libs/pyTermTk/TermTk/TTkWidgets/datetime_date_form.py @@ -684,7 +684,7 @@ class TTkDateForm(TTkContainer): An interactive calendar widget for date selection. - Combines year/month selectors with a calendar grid for intuitive date picking. (`demo `__) + Combines year/month selectors with a calendar grid for intuitive date picking. (`demo `__) :: diff --git a/libs/pyTermTk/TermTk/TTkWidgets/datetime_datetime.py b/libs/pyTermTk/TermTk/TTkWidgets/datetime_datetime.py index 979af1e2..5acbcc9a 100644 --- a/libs/pyTermTk/TermTk/TTkWidgets/datetime_datetime.py +++ b/libs/pyTermTk/TermTk/TTkWidgets/datetime_datetime.py @@ -37,7 +37,7 @@ class TTkDateTime(TTkContainer): A composite widget for displaying and editing date and time values. Combines :class:`~TermTk.TTkWidgets.datetime_date.TTkDate` and :class:`~TermTk.TTkWidgets.datetime_time.TTkTime` widgets - into a single datetime editor. (`demo `__) + into a single datetime editor. (`demo `__) :: diff --git a/libs/pyTermTk/TermTk/TTkWidgets/datetime_time.py b/libs/pyTermTk/TermTk/TTkWidgets/datetime_time.py index bd865409..b173226d 100644 --- a/libs/pyTermTk/TermTk/TTkWidgets/datetime_time.py +++ b/libs/pyTermTk/TermTk/TTkWidgets/datetime_time.py @@ -24,7 +24,7 @@ __all__ = ['TTkTime'] from enum import IntEnum,auto from dataclasses import dataclass -import datetime +import datetime as dt from typing import Optional @@ -57,7 +57,7 @@ class _TTkTimeWidgetState(): class TTkTime(TTkWidget): ''' TTkTime: - A widget for displaying and editing times. (`demo `__) + A widget for displaying and editing times. (`demo `__) :: @@ -88,7 +88,7 @@ class TTkTime(TTkWidget): } __slots__ = ('_time', '_state', 'timeChanged') - _time:datetime.time + _time:dt.time _state:_TTkTimeWidgetState timeChanged:pyTTkSignal @@ -100,7 +100,7 @@ class TTkTime(TTkWidget): ''' def __init__(self, *, - time:Optional[datetime.time] = None, + time:Optional[dt.time] = None, # handleSeconds:bool=False, **kwargs) -> None: ''' @@ -110,8 +110,8 @@ class TTkTime(TTkWidget): :type time: :class:`datetime.time`, optional ''' if not time: - time = datetime.datetime.now().time().replace(microsecond=0) - self.timeChanged = pyTTkSignal(datetime.time) + time = dt.datetime.now().time().replace(microsecond=0) + self.timeChanged = pyTTkSignal(dt.time) self._time = time self._state = _TTkTimeWidgetState() super().__init__(**kwargs|{'size':(8,1)}) @@ -151,7 +151,7 @@ class TTkTime(TTkWidget): :type uni: int ''' uni = max(0,min(24*3600-1,uni)) - self.setTime(time=datetime.time( + self.setTime(time=dt.time( hour=uni//3600, minute=(uni//60)%60, second=uni%60) @@ -169,7 +169,7 @@ class TTkTime(TTkWidget): uni = delta + self._time.hour * 3600 + self._time.minute * 60 + self._time.second self._setUni(uni=uni) - def time(self) -> datetime.time: + def time(self) -> dt.time: ''' Returns the current time of the widget. @@ -178,7 +178,7 @@ class TTkTime(TTkWidget): ''' return self._time - def setTime(self, time:datetime.time) -> None: + def setTime(self, time:dt.time) -> None: ''' Sets the current time of the widget. @@ -254,7 +254,7 @@ class TTkTime(TTkWidget): m = 0 elif selected == _FieldSelected.SECONDS: s = 0 - self.setTime(time=datetime.time(hour=h,minute=m,second=s)) + self.setTime(time=dt.time(hour=h,minute=m,second=s)) self.update() return True @@ -278,7 +278,7 @@ class TTkTime(TTkWidget): elif selected == _FieldSelected.SECONDS: s = (value + s*10) if secondDigit else value s = max(0,min(59,s)) - self.setTime(time=datetime.time(hour=h,minute=m,second=s)) + self.setTime(time=dt.time(hour=h,minute=m,second=s)) self.update() return True return False diff --git a/libs/pyTermTk/TermTk/TTkWidgets/label.py b/libs/pyTermTk/TermTk/TTkWidgets/label.py index 80a6b642..9be8a69a 100644 --- a/libs/pyTermTk/TermTk/TTkWidgets/label.py +++ b/libs/pyTermTk/TermTk/TTkWidgets/label.py @@ -22,6 +22,8 @@ __all__ = ['TTkLabel'] +from typing import Optional + from TermTk.TTkCore.constant import TTkK from TermTk.TTkCore.color import TTkColor from TermTk.TTkCore.canvas import TTkCanvas @@ -39,11 +41,11 @@ class TTkLabel(TTkWidget): __slots__ = ('_text', '_alignment') def __init__(self, *, - text:TTkString="", - color:TTkColor=None, + text:TTkStringType="", + color:Optional[TTkColor]=None, alignment:TTkK.Alignment=TTkK.LEFT_ALIGN, **kwargs) -> None: - if issubclass(type(text), TTkString): + if isinstance(text, TTkString): self._text = text.split('\n') else: self._text = TTkString(text).split('\n') diff --git a/libs/pyTermTk/TermTk/TTkWidgets/texedit.py b/libs/pyTermTk/TermTk/TTkWidgets/texedit.py index 25f6fd2a..f813420a 100644 --- a/libs/pyTermTk/TermTk/TTkWidgets/texedit.py +++ b/libs/pyTermTk/TermTk/TTkWidgets/texedit.py @@ -223,12 +223,12 @@ class TTkTextEditView(TTkAbstractScrollView): __slots__ = ('_format', '_color', '_cursor') def __init__(self, + cursor:TTkTextCursor, format:TTkK.SelectionFormat=TTkK.NONE, - color:TTkColor=TTkColor.RST, - cursor:Optional[TTkTextCursor]=None) -> None: + color:TTkColor=TTkColor.RST) -> None: self._color = color self._format = format - self._cursor = cursor if cursor else TTkTextCursor() + self._cursor = cursor def color(self) -> TTkColor: ''' diff --git a/libs/pyTermTk/TermTk/TTkWidgets/window.py b/libs/pyTermTk/TermTk/TTkWidgets/window.py index 52e3f44c..bd86081d 100644 --- a/libs/pyTermTk/TermTk/TTkWidgets/window.py +++ b/libs/pyTermTk/TermTk/TTkWidgets/window.py @@ -68,12 +68,15 @@ class TTkWindow(TTkResizableFrame): '_btnClose', '_btnMax', '_btnMin', '_btnReduce', '_flags', '_winTopLayout', '_maxBk', '_redBk' ) + + _flags:TTkK.WindowFlag + def __init__(self, *, flags:TTkK.WindowFlag=TTkK.WindowFlag.WindowCloseButtonHint, **kwargs) -> None: self._winTopLayout = TTkGridLayout() - self._flags = TTkK.NONE self._mouseDelta = (0,0) + self._flags = TTkK.WindowFlag.NONE self._draggable = False super().__init__(**kwargs) # This is a little hack used in TTKWindow to define the placement of the TOP menubar inside TTKFrame @@ -146,11 +149,11 @@ class TTkWindow(TTkResizableFrame): pl.addWidget(mb) self.hide() - def windowFlag(self): + def windowFlag(self) -> TTkK.WindowFlag: '''windowFlag''' return self._flags - def setWindowFlag(self, flag): + def setWindowFlag(self, flag:TTkK.WindowFlag): '''setWindowFlag''' if self._flags == flag: return self._flags = flag diff --git a/libs/pyTermTk/TermTk/__init__.py b/libs/pyTermTk/TermTk/__init__.py index 449b3566..a021c1c7 100644 --- a/libs/pyTermTk/TermTk/__init__.py +++ b/libs/pyTermTk/TermTk/__init__.py @@ -22,8 +22,8 @@ __version__:str = '0.47.2-a.0' -from .TTkCore import * from .TTkTheme import * +from .TTkCore import * from .TTkGui import * from .TTkWidgets import * from .TTkTypes import * @@ -33,4 +33,4 @@ from .TTkAbstract import * from .TTkUiTools import * from .TTkCrossTools import * -TTkCfg.theme = TTkTheme() +TTkTheme.themeLoaded.connect(TTkHelper.updateAll) \ No newline at end of file