From 228d8288716cf5286555eb3a5b9ff63d72e8487b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parodi=2C=20Eugenio=20=F0=9F=8C=B6?= Date: Wed, 9 Apr 2025 09:32:18 +0100 Subject: [PATCH] feat: prototyping search plugin iin ttkode --- apps/ttkode/ttkode/__init__.py | 4 +- apps/ttkode/ttkode/app/activitybar.py | 7 +++- apps/ttkode/ttkode/app/cfg.py | 2 - apps/ttkode/ttkode/app/main.py | 6 ++- apps/ttkode/ttkode/app/ttkode.py | 2 - apps/ttkode/ttkode/helper.py | 23 ++++------ apps/ttkode/ttkode/plugin.py | 42 ++++++++++++------- apps/ttkode/ttkode/plugins/_010/findwidget.py | 42 +++++++++++++++++++ apps/ttkode/ttkode/plugins/_010_findplugin.py | 40 ++++++++++++++++++ .../ttkode/ttkode/plugins/_020_debugplugin.py | 39 +++++++++++++++++ apps/ttkode/ttkode/proxy.py | 19 +++++++-- 11 files changed, 185 insertions(+), 41 deletions(-) create mode 100644 apps/ttkode/ttkode/plugins/_010/findwidget.py create mode 100644 apps/ttkode/ttkode/plugins/_010_findplugin.py create mode 100644 apps/ttkode/ttkode/plugins/_020_debugplugin.py diff --git a/apps/ttkode/ttkode/__init__.py b/apps/ttkode/ttkode/__init__.py index 691fdfcd..c810b28f 100755 --- a/apps/ttkode/ttkode/__init__.py +++ b/apps/ttkode/ttkode/__init__.py @@ -25,5 +25,5 @@ __version__:str = '0.2.15-a.2' from .helper import TTkodeHelper -from .plugin import TTkodePlugin -from .proxy import TTkodeViewerProxy, TTkodeProxy, tloggProxy \ No newline at end of file +from .plugin import TTkodePlugin, TTkodePluginActivity +from .proxy import TTKodeViewerProxy, ttkodeProxy \ No newline at end of file diff --git a/apps/ttkode/ttkode/app/activitybar.py b/apps/ttkode/ttkode/app/activitybar.py index 74f2c855..3ebc2c27 100644 --- a/apps/ttkode/ttkode/app/activitybar.py +++ b/apps/ttkode/ttkode/app/activitybar.py @@ -121,7 +121,12 @@ class TTKodeActivityBar(ttk.TTkVBoxLayout): else: act.widget().setVisible(False) - def addActivity(self, name: ttk.TTkString, icon: ttk.TTkString, widget: ttk.TTkWidget, select:bool=False) -> None: + def addActivity( + self, + name: ttk.TTkString, + icon: ttk.TTkString, + widget: ttk.TTkWidget, + select:bool=False) -> None: activityWidget = _ActivityWidget(name, icon, widget) self.addWidget(widget) widget.setVisible(False) diff --git a/apps/ttkode/ttkode/app/cfg.py b/apps/ttkode/ttkode/app/cfg.py index 17f4c49c..a38ac2b8 100644 --- a/apps/ttkode/ttkode/app/cfg.py +++ b/apps/ttkode/ttkode/app/cfg.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - # MIT License # # Copyright (c) 2021 Eugenio Parodi diff --git a/apps/ttkode/ttkode/app/main.py b/apps/ttkode/ttkode/app/main.py index 6a8c01d6..04ceb784 100644 --- a/apps/ttkode/ttkode/app/main.py +++ b/apps/ttkode/ttkode/app/main.py @@ -32,6 +32,7 @@ from TermTk import TTk, TTkTerm, TTkTheme from TermTk import TTkLog from ttkode import TTkodeHelper +from ttkode import ttkodeProxy from .ttkode import TTKode from .cfg import TTKodeCfg @@ -62,7 +63,10 @@ def main(): TTkodeHelper._loadPlugins() - root = TTk( layout=TTKode(files=args.filename), + ttkode = TTKode(files=args.filename) + ttkodeProxy.setTTKode(ttkode) + + root = TTk( layout=ttkode, title="TTkode", mouseTrack=True, sigmask=( diff --git a/apps/ttkode/ttkode/app/ttkode.py b/apps/ttkode/ttkode/app/ttkode.py index 7438d482..14160cfa 100644 --- a/apps/ttkode/ttkode/app/ttkode.py +++ b/apps/ttkode/ttkode/app/ttkode.py @@ -84,8 +84,6 @@ class TTKode(TTkGridLayout): fileTree = TTkFileTree(path='.') self._activityBar = TTKodeActivityBar() self._activityBar.addActivity(name="Explorer", icon=TTkString("╔██\n╚═╝"), widget=fileTree, select=True) - self._activityBar.addActivity(name="Search", icon=TTkString("╔═╗\n🔎╝"), widget=TTkTestWidget()) - self._activityBar.addActivity(name="Debug", icon=TTkString(" 🭑🬽\n🪲🭘"), widget=TTkTestWidgetSizes()) appTemplate.setWidget(self._kodeTab, TTkAppTemplate.MAIN) appTemplate.setItem(self._activityBar, TTkAppTemplate.LEFT, size=30) diff --git a/apps/ttkode/ttkode/helper.py b/apps/ttkode/ttkode/helper.py index 5e9b784b..b3ea4306 100644 --- a/apps/ttkode/ttkode/helper.py +++ b/apps/ttkode/ttkode/helper.py @@ -26,7 +26,8 @@ import os import importlib, pkgutil import TermTk as ttk -from .plugin import TTkodePlugin +from .plugin import TTkodePlugin, TTkodePluginActivity +from .proxy import ttkodeProxy class TTkodeHelper(): @staticmethod @@ -36,7 +37,7 @@ class TTkodeHelper(): if not os.path.exists(pluginFolder): ttk.TTkLog.error("No 'plugins' folder found in the 'tlogg' main directory") else: - for fn in os.listdir(pluginFolder): + for fn in sorted(os.listdir(pluginFolder)): filePath = os.path.join(pluginFolder,fn) if not os.path.isfile(filePath): continue absolute_name = importlib.util.resolve_name(filePath, None) @@ -48,7 +49,7 @@ class TTkodeHelper(): # Check installed plugins for finder, name, ispkg in pkgutil.iter_modules(): - if name.startswith("tlogg_"): + if name.startswith("ttkode_"): loader = importlib.find_loader(name) spec = importlib.util.find_spec(name) mod = importlib.util.module_from_spec(spec) @@ -63,6 +64,11 @@ class TTkodeHelper(): @staticmethod def _runPlugins(): for mod in TTkodePlugin.instances: + if isinstance(mod, TTkodePluginActivity): + ttkodeProxy.ttkode()._activityBar.addActivity( + name=mod.activityName, + icon=mod.icon, + widget=mod.widget) if mod.apply is not None: mod.apply() @@ -70,14 +76,3 @@ class TTkodeHelper(): def _getPlugins(): return TTkodePlugin.instances - @staticmethod - def _getPluginPlacements(): - ret = ttk.TTkK.NONE - for mod in TTkodePlugin.instances: - ret |= mod.position - return ret - - @staticmethod - def _getPlacedPlugins(placement): - return [mod for mod in TTkodePlugin.instances if mod.position & placement] - diff --git a/apps/ttkode/ttkode/plugin.py b/apps/ttkode/ttkode/plugin.py index 155bf196..54292e49 100644 --- a/apps/ttkode/ttkode/plugin.py +++ b/apps/ttkode/ttkode/plugin.py @@ -20,24 +20,36 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -__all__ = ['TTkodePlugin'] +__all__ = ['TTkodePlugin', 'TTkodePluginActivity'] from dataclasses import dataclass -from typing import Callable +from typing import Callable, Self, List, Optional, Union +from enum import Enum import TermTk as ttk -@dataclass -class TTkodePlugin: - instances = [] - name : str - init : Callable[[],None] = None - apply : Callable[[],None] = None - run : Callable[[],None] = None - position : int = ttk.TTkK.NONE # Accepted Values are ; NONE, LEFT, RIGHT - widget : ttk.TTkWidget = None # Required if a position is defined - menu : bool = False - visible: bool = False +class TTkodePlugin(): + instances: List['Self'] = [] + def __init__( + self, + name : str, + init : Optional[Callable[[],None]] = None, + apply : Optional[Callable[[],None]] = None, + run : Optional[Callable[[],None]] = None ): + self.name = name + self.init = init + self.apply = apply + self.run = run + self.instances.append(self) - def __post_init__(self): - TTkodePlugin.instances.append(self) +class TTkodePluginActivity(TTkodePlugin): + def __init__( + self, + activityName: str, + widget: ttk.TTkWidget, + icon:ttk.TTkString, + **kwargs): + self.activityName = activityName + self.widget = widget + self.icon = icon + super().__init__(**kwargs) diff --git a/apps/ttkode/ttkode/plugins/_010/findwidget.py b/apps/ttkode/ttkode/plugins/_010/findwidget.py new file mode 100644 index 00000000..5f46bfa6 --- /dev/null +++ b/apps/ttkode/ttkode/plugins/_010/findwidget.py @@ -0,0 +1,42 @@ +# MIT License +# +# Copyright (c) 2025 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. + +__all__ = ['FindWidget'] + +import TermTk as ttk + +import ttkode + +class FindWidget(ttk.TTkContainer): + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.setLayout(layout:=ttk.TTkGridLayout()) + searchLayout = ttk.TTkGridLayout() + searchLayout.addWidget(expandReplace:=ttk.TTkButton(text=">", maxWidth=3, checkable=True), 0, 0) + searchLayout.addWidget(ttk.TTkLineEdit(), 0, 1) + searchLayout.addWidget(replace:=ttk.TTkLineEdit(), 1, 0, 1, 2) + layout.addItem(searchLayout, 0, 0) + layout.addWidget(ttk.TTkButton(text="Find", border=False), 1,0) + layout.addWidget(ttk.TTkButton(text="Find", border=False), 2,0) + layout.addWidget(ttk.TTkButton(text="Find", border=True), 3,0) + expandReplace.toggled.connect(replace.setVisible) + replace.setVisible(False) \ No newline at end of file diff --git a/apps/ttkode/ttkode/plugins/_010_findplugin.py b/apps/ttkode/ttkode/plugins/_010_findplugin.py new file mode 100644 index 00000000..f6a4e04a --- /dev/null +++ b/apps/ttkode/ttkode/plugins/_010_findplugin.py @@ -0,0 +1,40 @@ +# MIT License +# +# Copyright (c) 2025 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. + +__all__:list[str] = [] + +import TermTk as ttk + +import ttkode + +from ttkode.plugins._010.findwidget import FindWidget + +_icon:str = ( + "╔═╗\n" + "🔎╝") + +ttkode.TTkodePluginActivity( + name="Find Plugin", + activityName='Search', + widget=FindWidget(), + icon=ttk.TTkString(_icon) + ) diff --git a/apps/ttkode/ttkode/plugins/_020_debugplugin.py b/apps/ttkode/ttkode/plugins/_020_debugplugin.py new file mode 100644 index 00000000..49a1c510 --- /dev/null +++ b/apps/ttkode/ttkode/plugins/_020_debugplugin.py @@ -0,0 +1,39 @@ + +# MIT License +# +# Copyright (c) 2025 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. + +__all__:list[str] = [] + +import TermTk as ttk + +import ttkode + +_icon:str = ( + " 🭑🬽\n" + "🪲🭘") + +ttkode.TTkodePluginActivity( + name="Debug Plugin", + activityName='Debug', + widget=ttk.TTkTestWidget(), + icon=ttk.TTkString(_icon) + ) diff --git a/apps/ttkode/ttkode/proxy.py b/apps/ttkode/ttkode/proxy.py index 5aac29f9..e74ef61d 100644 --- a/apps/ttkode/ttkode/proxy.py +++ b/apps/ttkode/ttkode/proxy.py @@ -20,11 +20,13 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -__all__ = ['TTkodeViewerProxy', 'TTkodeProxy', 'tloggProxy'] +__all__ = ['TTKodeViewerProxy', 'ttkodeProxy'] import TermTk as ttk -class TTkodeViewerProxy(): +from ttkode.app.ttkode import TTKode + +class TTKodeViewerProxy(): __slots__ = ('_fileName') def __init__(self, fileName) -> None: self._fileName = fileName @@ -32,12 +34,21 @@ class TTkodeViewerProxy(): def fileName(self): return self._fileName -class TTkodeProxy(): +class TTKodeProxy(): __slots__ = ('_openFileCb', + '_ttkode', # Signals ) + _ttkode:TTKode def __init__(self) -> None: self._openFileCb = lambda _ : None + self._ttkode = None + + def setTTKode(self, ttkode:TTKode) -> None: + self._ttkode = ttkode + + def ttkode(self) -> TTKode: + return self._ttkode def setOpenFile(self, cb): self._openFileCb = cb @@ -45,4 +56,4 @@ class TTkodeProxy(): def openFile(self, fileName): return self._openFileCb(fileName) -tloggProxy = TTkodeProxy() \ No newline at end of file +ttkodeProxy:TTKodeProxy = TTKodeProxy() \ No newline at end of file