diff --git a/apps/ttkode/ttkode/app/activitybar.py b/apps/ttkode/ttkode/app/activitybar.py new file mode 100644 index 00000000..74f2c855 --- /dev/null +++ b/apps/ttkode/ttkode/app/activitybar.py @@ -0,0 +1,133 @@ +# MIT License +# +# Copyright (c) 2021 Eugenio Parodi +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +__all__ = ['TTKodeActivityBar'] + +import TermTk as ttk +from typing import List + +from dataclasses import dataclass + +class _ActivityWidget(ttk.TTkRadioButton): + classStyle = { + 'default': {'color': ttk.TTkColor.RST}, + 'disabled': {'color': ttk.TTkColor.fg('#888888')}, + 'hover': {'color': ttk.TTkColor.bg('#888800')}} + __slots__ = ('_actionName', '_icon', '_widget') + _actionName: ttk.TTkString + _icon: List[ttk.TTkString] + _widget: ttk.TTkWidget + def __init__(self, actionName: ttk.TTkString, icon: ttk.TTkString, widget: ttk.TTkWidget, **kwargs): + self._actionName = actionName + self._icon = icon.split('\n') + self._widget = widget + width = max(i.termWidth() for i in self._icon) + params = { + 'toolTip':actionName, + 'maxSize':(width,2), + 'minSize':(width,2), + 'size':(width,2), + 'radiogroup':'ttkodeActionBar'} + super().__init__(**kwargs|params) + + def actionName(self) -> ttk.TTkString: + return self._actionName + def icon(self) -> List[ttk.TTkString]: + return self._icon + def widget(self) -> ttk.TTkWidget: + return self._widget + + def paintEvent(self, canvas): + style = self.currentStyle() + iconLine1 = self._icon[0].setColor(style['color']) + iconLine2 = self._icon[1].setColor(style['color']) + canvas.drawTTkString(pos=(0,0),text=iconLine1) + if self.isChecked(): + canvas.drawTTkString(pos=(0,1),text=iconLine2.setColor(ttk.ttk.TTkColor.UNDERLINE)) + else: + canvas.drawTTkString(pos=(0,1),text=iconLine2) + + +class _SideBar(ttk.TTkLayout): + __slots__ = ('_sideWidgets', '_position') + _sideWidgets:List[_ActivityWidget] + _position:int + def __init__(self, position:int=ttk.TTkK.TOP, **kwargs) -> None: + self._sideWidgets = [] + self._position = position + params = { + 'maxHeight':2, + 'minHeught':2} + super().__init__(**kwargs|params) + + def _refreshItems(self) -> None: + x = 1 + for wid in self._sideWidgets: + wid.move(x,0) + x+=wid.width()+1 + + def activities(self) -> List[_ActivityWidget]: + return self._sideWidgets + + def addActivity(self, widget: _ActivityWidget): + self._sideWidgets.append(widget) + self.addWidget(widget) + self._refreshItems() + self.update() + + def removeActivity(self, widget: _ActivityWidget): + self._sideWidgets.remove(widget) + self.removeWidget(widget) + self._refreshItems() + self.update() + + def clearActivities(self) -> None: + self.removeWidgets(self._sideWidgets) + self._sideWidgets.clear() + self.update() + + +class TTKodeActivityBar(ttk.TTkVBoxLayout): + __slots__ = ('_sideBar') + def __init__(self, **kwargs) -> None: + super().__init__(**kwargs) + self._sideBar = _SideBar() + self.addItem(self._sideBar) + + @ttk.pyTTkSlot() + def _activityChanged(self) -> None: + for act in self._sideBar.activities(): + if act.isChecked(): + act.widget().setVisible(True) + else: + act.widget().setVisible(False) + + 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) + activityWidget.toggled.connect(self._activityChanged) + self._sideBar.addActivity(activityWidget) + if select: + activityWidget.setChecked(True) + widget.setVisible(True) + diff --git a/apps/ttkode/ttkode/app/main.py b/apps/ttkode/ttkode/app/main.py index 354aa3f4..6a8c01d6 100644 --- a/apps/ttkode/ttkode/app/main.py +++ b/apps/ttkode/ttkode/app/main.py @@ -62,7 +62,9 @@ def main(): TTkodeHelper._loadPlugins() - root = TTk( layout=TTKode(files=args.filename), title="TTkode", + root = TTk( layout=TTKode(files=args.filename), + title="TTkode", + mouseTrack=True, sigmask=( # TTkTerm.Sigmask.CTRL_C | TTkTerm.Sigmask.CTRL_Q | diff --git a/apps/ttkode/ttkode/app/ttkode.py b/apps/ttkode/ttkode/app/ttkode.py index c7b509df..7438d482 100644 --- a/apps/ttkode/ttkode/app/ttkode.py +++ b/apps/ttkode/ttkode/app/ttkode.py @@ -41,8 +41,10 @@ from TermTk import TextDocumentHighlight from TermTk import TTkLogViewer from TermTk import TTkMenuBarLayout from TermTk import TTkAbout +from TermTk import TTkTestWidget, TTkTestWidgetSizes from .about import About +from .activitybar import TTKodeActivityBar class _TextDocument(TextDocumentHighlight): __slots__ = ('_filePath') @@ -52,20 +54,18 @@ class _TextDocument(TextDocumentHighlight): self.guessLexerFromFilename(filePath) class TTKode(TTkGridLayout): - __slots__ = ('_kodeTab', '_documents') + __slots__ = ('_kodeTab', '_documents', '_activityBar') def __init__(self, *, files, **kwargs): self._documents = {} super().__init__(**kwargs) - layoutLeft = TTkGridLayout() - appTemplate = TTkAppTemplate(border=False) self.addWidget(appTemplate) self._kodeTab = TTkKodeTab(border=False, closable=True) - appTemplate.setMenuBar(appMenuBar:=TTkMenuBarLayout(), TTkAppTemplate.LEFT) + appTemplate.setMenuBar(appMenuBar:=TTkMenuBarLayout(), TTkAppTemplate.MAIN) fileMenu = appMenuBar.addMenu("&File") fileMenu.addMenu("Open").menuButtonClicked.connect(self._showFileDialog) fileMenu.addMenu("Close") # .menuButtonClicked.connect(self._closeFile) @@ -76,21 +76,21 @@ class TTKode(TTkGridLayout): def _showAboutTTk(btn): TTkHelper.overlay(None, TTkAbout(), 30,10) + appMenuBar.addMenu("&Quit", alignment=TTkK.RIGHT_ALIGN).menuButtonClicked.connect(TTkHelper.quit) helpMenu = appMenuBar.addMenu("&Help", alignment=TTkK.RIGHT_ALIGN) helpMenu.addMenu("About ...").menuButtonClicked.connect(_showAbout) helpMenu.addMenu("About ttk").menuButtonClicked.connect(_showAboutTTk) fileTree = TTkFileTree(path='.') - - layoutLeft.addWidget(fileTree, 1,0) - layoutLeft.addWidget(quitbtn := TTkButton(border=True, text="Quit", maxHeight=3), 2,0) + 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(layoutLeft, TTkAppTemplate.LEFT, size=30) + appTemplate.setItem(self._activityBar, TTkAppTemplate.LEFT, size=30) appTemplate.setWidget(TTkLogViewer(), TTkAppTemplate.BOTTOM, title="Logs", size=3) - quitbtn.clicked.connect(TTkHelper.quit) - for file in files: self._openFile(file) diff --git a/run.ttkode.sh b/run.ttkode.sh new file mode 100755 index 00000000..6f50d820 --- /dev/null +++ b/run.ttkode.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +_PATH_SCRIPT="$(dirname $(realpath $0))" +PYTHONPATH=${_PATH_SCRIPT}/libs/pyTermTk:${_PATH_SCRIPT}/apps/ttkode python3 -m ttkode $@