13 changed files with 1168 additions and 0 deletions
@ -1 +1,2 @@
|
||||
from .terminal import * |
||||
from .terminalview import * |
||||
|
||||
@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env python3 |
||||
|
||||
# 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. |
||||
|
||||
import os |
||||
import pty |
||||
import sys |
||||
import threading |
||||
import argparse |
||||
from select import select |
||||
|
||||
sys.path.append(os.path.join(sys.path[0],'..')) |
||||
import TermTk as ttk |
||||
|
||||
parser = argparse.ArgumentParser() |
||||
parser.add_argument('-d', help='Debug (Add LogViewer Panel)', action='store_true') |
||||
args = parser.parse_args() |
||||
|
||||
# ttk.TTkLog.use_default_file_logging() |
||||
root = ttk.TTk(layout=ttk.TTkGridLayout()) |
||||
|
||||
split = ttk.TTkSplitter(parent=root, orientation=ttk.TTkK.VERTICAL) |
||||
|
||||
split.addItem(top := ttk.TTkLayout()) |
||||
|
||||
if args.d: |
||||
split.addWidget(ttk.TTkLogViewer(follow=False ), title='Log', size=20) |
||||
|
||||
quitBtn = ttk.TTkButton(text="QUIT", border=True) |
||||
quitBtn.clicked.connect(ttk.TTkHelper.quit) |
||||
|
||||
cb_c = ttk.TTkCheckbox(pos=(0,3),size=(20,1), text="CTRL-C (VINTR) ", checked=ttk.TTkK.Checked) |
||||
cb_s = ttk.TTkCheckbox(pos=(0,4),size=(20,1), text="CTRL-S (VSTOP) ", checked=ttk.TTkK.Checked) |
||||
cb_z = ttk.TTkCheckbox(pos=(0,5),size=(20,1), text="CTRL-Z (VSUSP) ", checked=ttk.TTkK.Checked) |
||||
cb_q = ttk.TTkCheckbox(pos=(0,6),size=(20,1), text="CTRL-Q (VSTART)", checked=ttk.TTkK.Checked) |
||||
|
||||
cb_c.stateChanged.connect(lambda x: ttk.TTkTerm.setSigmask(ttk.TTkTerm.Sigmask.CTRL_C,x==ttk.TTkK.Checked)) |
||||
cb_s.stateChanged.connect(lambda x: ttk.TTkTerm.setSigmask(ttk.TTkTerm.Sigmask.CTRL_S,x==ttk.TTkK.Checked)) |
||||
cb_z.stateChanged.connect(lambda x: ttk.TTkTerm.setSigmask(ttk.TTkTerm.Sigmask.CTRL_Z,x==ttk.TTkK.Checked)) |
||||
cb_q.stateChanged.connect(lambda x: ttk.TTkTerm.setSigmask(ttk.TTkTerm.Sigmask.CTRL_Q,x==ttk.TTkK.Checked)) |
||||
|
||||
win1 = ttk.TTkWindow(pos=(90,5), size=(70,15), title="Terminallo n.1", border=True, layout=ttk.TTkVBoxLayout(), flags = ttk.TTkK.WindowFlag.WindowMinMaxButtonsHint) |
||||
term1 = ttk.TTkTerminal(parent=win1) |
||||
term1.runShell() |
||||
|
||||
win2 = ttk.TTkWindow(pos=(0,0), size=(150,30), title="Terminallo n.2", border=True, layout=ttk.TTkVBoxLayout(), flags = ttk.TTkK.WindowFlag.WindowMinMaxButtonsHint) |
||||
term2 = ttk.TTkTerminal(parent=win2) |
||||
term2.runShell() |
||||
|
||||
win3 = ttk.TTkWindow(pos=(92,8), size=(70,15), title="Terminallo n.3", border=True, layout=ttk.TTkVBoxLayout(), flags = ttk.TTkK.WindowFlag.WindowMinMaxButtonsHint) |
||||
term3 = ttk.TTkTerminal(parent=win3) |
||||
term3.runShell() |
||||
|
||||
win4 = ttk.TTkWindow(pos=(94,11), size=(70,15), title="Terminallo n.4", border=True, layout=ttk.TTkVBoxLayout(), flags = ttk.TTkK.WindowFlag.WindowMinMaxButtonsHint) |
||||
term4 = ttk.TTkTerminal(parent=win4) |
||||
term4.runShell() |
||||
|
||||
top.addWidgets([quitBtn, cb_c, cb_s, cb_z, cb_q, win1, win2, win3, win4]) |
||||
|
||||
term2.setFocus() |
||||
|
||||
root.mainloop() |
||||
@ -0,0 +1,53 @@
|
||||
|
||||
|
||||
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄🬿 |
||||
█ █ ▄▄▄▄ █ 🭢🭕🭏🬼 |
||||
█ █ █ █ █ 🭥🭌 |
||||
█ █ █▄▄█ █ █ |
||||
█ █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█ █ |
||||
█ █ |
||||
█ █ |
||||
█ █ |
||||
█ █ |
||||
█ ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ █ |
||||
█ █ █ █ |
||||
█ █ █ █ |
||||
█ █ █ █ |
||||
█ █ █ █ |
||||
█ █ █ █ |
||||
█ █ █ █ |
||||
█ █ █ █ |
||||
█▄▄▄▄▄█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█▄▄▄▄█ |
||||
|
||||
🭖🭏🭡 🭖🭩🭡 🭇▖ ▖▖ |
||||
🭤🭓🭛 🭦█🭛 ▌● ▞▖ |
||||
|
||||
🭇🬼 |
||||
🭃🭌 ▄🬿 |
||||
🭥🭒█ 🭢🭕🭏🬼 |
||||
🭋🭍🭑🬽🭢🭕 🭥🭌 🬿 |
||||
🭅███🭀 🭥🭒🭒█🭏🬼 🭒 |
||||
🭋██🭥██🭐 🭢🭕█🭌🬿 |
||||
|
||||
|
||||
🭇🬼 🭇 __X__ 🬼 🬼 X |
||||
🭃🭌🬿 🭃 🭌🬿 🭌 🬿 X |
||||
🭥🭒█🭏🬼 🭥🭒 🭏🬼 🭏 🬼 X |
||||
🭋🭍🭑🬽🭢🭕█🭌🬿 🭋🭍🭑🬽 🭢🭕 🭌🬿 🭌 🬿 X |
||||
🭅███🭀 🭥🭒█🭏🬼 🭅███🭀 🭥🭒 🭏🬼 🭏 🬼 X |
||||
🭋████🭐 🭢🭕█🭌🬿 🭋████🭐 🭢🭕 🭌🬿 🭌 🬿 X |
||||
|
||||
|
||||
|
||||
🬼 🭇 🭗 🭢 |
||||
🬽 🭈 🭘 🭣 |
||||
🬾 🭉 🭙 🭤 |
||||
🬿 🭊 🭚 🭥 |
||||
🭀 🭋 🭛 🭦 |
||||
🭌 🭁 🭝 🭒 |
||||
🭍 🭂 🭞 🭓 |
||||
🭎 🭃 🭟 🭔 |
||||
🭏 🭄 🭠 🭕 |
||||
🭐 🭅 🭡 🭖 |
||||
🭑 🭆 🭜 🭧 |
||||
|
||||
@ -0,0 +1,212 @@
|
||||
#!/usr/bin/env python3 |
||||
|
||||
# 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. |
||||
|
||||
import os |
||||
import pty |
||||
import sys |
||||
import threading |
||||
import argparse |
||||
from select import select |
||||
|
||||
|
||||
sys.path.append(os.path.join(sys.path[0],'../..')) |
||||
import TermTk as ttk |
||||
|
||||
from TermTk.TTkCore.canvas import TTkCanvas |
||||
from TermTk.TTkTestWidgets.logviewer import _TTkLogViewer |
||||
|
||||
|
||||
from wblib import * |
||||
|
||||
# parser = argparse.ArgumentParser() |
||||
# parser.add_argument('-d', help='Debug (Add LogViewer Panel)', action='store_true') |
||||
# args = parser.parse_args() |
||||
|
||||
# class WBWindow(ttk.TTkWindow): |
||||
|
||||
class WorkBench(ttk.TTkContainer): |
||||
__slots__ = ('_barSelected', '_barPosition', '_backLayout') |
||||
def __init__(self, *args, **kwargs): |
||||
self._barselected = False |
||||
self._barPosition = 0 |
||||
self._backLayout = ttk.TTkLayout() |
||||
self._backLayout.setGeometry(0,0,0,0) |
||||
self._barSelected = False |
||||
super().__init__(*args, **kwargs) |
||||
self.setPadding(1,0,0,0) |
||||
self.setFocusPolicy(ttk.TTkK.ClickFocus) |
||||
self.rootLayout().addItem(self._backLayout) |
||||
|
||||
_win = ttk.TTkWindow(pos=(10,0), size=(100,30),title=f"Loader Demo", layout=ttk.TTkGridLayout()) |
||||
WBLoader(parent=_win) |
||||
self._backLayout.addWidget(_win) |
||||
|
||||
if os.path.isfile(_fileName := os.path.join(sys.path[0],"dontsavethisfile.txt")): |
||||
with open(_fileName,'r') as f: |
||||
data = ttk.TTkUtil.base64_deflate_2_obj(f.read()) |
||||
_win = ttk.TTkWindow(pos=(10,0), size=(100,30),title=f"Guru Meditation", layout=ttk.TTkGridLayout()) |
||||
_sa = ttk.TTkScrollArea(parent=_win) |
||||
ttk.TTkImage(parent=_sa.viewport(), data=data) |
||||
self._backLayout.addWidget(_win) |
||||
|
||||
def mousePressEvent(self, evt): |
||||
self._barSelected = evt.y == self._barPosition |
||||
return True |
||||
|
||||
def mouseReleaseEvent(self, evt) -> bool: |
||||
self._barSelected = False |
||||
return True |
||||
|
||||
def mouseDragEvent(self, evt): |
||||
if not self._barSelected: return True |
||||
w,h = self.size() |
||||
y = max(0,min(evt.y,h-1)) |
||||
self.setPadding(y+1,0,0,0) |
||||
self._barPosition = y |
||||
self._backLayout.setGeometry(0,0,w,y) |
||||
self.update() |
||||
return True |
||||
|
||||
def paintEvent(self, canvas: TTkCanvas): |
||||
w,h = self.size() |
||||
|
||||
canvas.fill(size=(w,self._barPosition)) |
||||
canvas.fill(pos=(0,self._barPosition),color=bgBLUE) |
||||
# draw the title |
||||
canvas.drawText( |
||||
pos=(0,self._barPosition), |
||||
text=" pyTermTk Workbench. Version 1.0 plenty of free memory", |
||||
width=w, |
||||
color=bgWHITE+fgBLUE) |
||||
|
||||
canvas.drawText( |
||||
pos=(w-5,self._barPosition), |
||||
text="│◪│◩│", |
||||
color=bgWHITE+fgBLUE) |
||||
|
||||
class TTkWorkbench(ttk.TTk): |
||||
def paintEvent(self, canvas: TTkCanvas): |
||||
canvas.fill(color=bgBLUE) |
||||
|
||||
logWin = WBScrollWin(pos=(10,10), size=(60,20), |
||||
whiteBg=False, |
||||
title=f"Key Press Viewer",layout=ttk.TTkVBoxLayout()) |
||||
logWin.setViewport(_TTkLogViewer()) |
||||
|
||||
root = TTkWorkbench(layout=ttk.TTkGridLayout(), mouseTrack=True) |
||||
root.setPadding(3,3,15,10) |
||||
|
||||
wbl = WBLoader(size=root.size()) |
||||
root.rootLayout().addWidget(wbl) |
||||
|
||||
wb = WorkBench(parent=root) |
||||
|
||||
clipboard = ttk.TTkClipboard() |
||||
|
||||
ttk.pyTTkSlot() |
||||
def _openTerminal(term=[]): |
||||
global clipboard |
||||
_x,_y = 15,5 |
||||
while (_x,_y) in [_t['pos'] for _t in term]: |
||||
_x += 4 |
||||
_y += 2 |
||||
_win = WBScrollWin(parent=wb, pos=(_x,_y), size=(60,20), |
||||
whiteBg=False, |
||||
title=f"Terminallo n.{len(term)+1}",layout=ttk.TTkVBoxLayout()) |
||||
_win.setViewport(_term := ttk.TTkTerminalView()) |
||||
_term.runShell() |
||||
_term.bell.connect(lambda : ttk.TTkLog.debug("BELL!!! 🔔🔔🔔")) |
||||
_term.titleChanged.connect(_win.setTitle) |
||||
_term.textSelected.connect(clipboard.setText) |
||||
term.append({'pos':(_x,_y),'term':_term,'win':_win}) |
||||
_win.raiseWidget() |
||||
|
||||
ttk.pyTTkSlot() |
||||
def _openInputViewer(): |
||||
_win = WBWindow(parent=wb, pos=(10,10), size=(60,6), |
||||
whiteBg=False, |
||||
title=f"Key Press Viewer",layout=ttk.TTkVBoxLayout()) |
||||
ttk.TTkKeyPressView(parent=_win) |
||||
_win.raiseWidget() |
||||
|
||||
def _openPreferences(): |
||||
_style = {'default': {'color': fgWHITE+bgBLUE},} |
||||
_win = WBWindow(parent=wb, pos=(10,10), size=(60,7),title=f"Preferences") |
||||
ttk.TTkLabel(parent=_win, pos=(0,0), text="Padding").setStyle(_style) |
||||
ttk.TTkLabel(parent=_win, pos=(2,1), text="Top" ).setStyle(_style) |
||||
ttk.TTkLabel(parent=_win, pos=(2,2), text="Bottom" ).setStyle(_style) |
||||
ttk.TTkLabel(parent=_win, pos=(2,3), text="Left" ).setStyle(_style) |
||||
ttk.TTkLabel(parent=_win, pos=(2,4), text="Right" ).setStyle(_style) |
||||
|
||||
ttk.TTkLabel(parent=_win, pos=(30,0), text="Style\nComing soon...\nOr Not").setStyle(_style) |
||||
|
||||
t,b,l,r = root.getPadding() |
||||
_sbT = ttk.TTkSpinBox(parent=_win, pos=(10,1), size=(6,1), value=t, maximum=30, minimum=0) |
||||
_sbB = ttk.TTkSpinBox(parent=_win, pos=(10,2), size=(6,1), value=b, maximum=30, minimum=0) |
||||
_sbL = ttk.TTkSpinBox(parent=_win, pos=(10,3), size=(6,1), value=l, maximum=30, minimum=0) |
||||
_sbR = ttk.TTkSpinBox(parent=_win, pos=(10,4), size=(6,1), value=r, maximum=30, minimum=0) |
||||
|
||||
_sbT.setStyle(_style) |
||||
_sbB.setStyle(_style) |
||||
_sbL.setStyle(_style) |
||||
_sbR.setStyle(_style) |
||||
|
||||
def _updatePadding(_,_sbT=_sbT,_sbB=_sbB,_sbL=_sbL,_sbR=_sbR): |
||||
root.setPadding(_sbT.value(),_sbB.value(),_sbL.value(),_sbR.value()) |
||||
|
||||
_sbT.valueChanged.connect(_updatePadding) |
||||
_sbB.valueChanged.connect(_updatePadding) |
||||
_sbL.valueChanged.connect(_updatePadding) |
||||
_sbR.valueChanged.connect(_updatePadding) |
||||
|
||||
_win.raiseWidget() |
||||
|
||||
|
||||
|
||||
ttk.pyTTkSlot() |
||||
def _openLogViewer(): |
||||
wb.layout().addWidget(logWin) |
||||
logWin.show() |
||||
logWin.resize(80,30) |
||||
logWin.raiseWidget() |
||||
|
||||
winWb = WBScrollWin(parent=wb, pos=(5,2), size=(50,15), title="euWorkbench") |
||||
|
||||
winWb.viewport().addWidget(_bttn:=WBIconButton(pos=(3,0), icon=WBIconButton.IconTerminal, |
||||
text="Terminal")) |
||||
_bttn.clicked.connect(_openTerminal) |
||||
|
||||
winWb.viewport().addWidget(_bttn:=WBIconButton(pos=(18,0), icon=WBIconButton.IconInputLog, |
||||
text="Input Viewer")) |
||||
_bttn.clicked.connect(_openInputViewer) |
||||
|
||||
winWb.viewport().addWidget(_bttn:=WBIconButton(pos=(35,3), icon=WBIconButton.IconLogViewer, |
||||
text="Log Viewer")) |
||||
_bttn.clicked.connect(_openLogViewer) |
||||
|
||||
winWb.viewport().addWidget(_bttn:=WBIconButton(pos=(0,6), icon=WBIconButton.IconPreferences, |
||||
text="Preferences")) |
||||
_bttn.clicked.connect(_openPreferences) |
||||
|
||||
root.mainloop() |
||||
@ -0,0 +1,6 @@
|
||||
from .colors import * |
||||
from .window import * |
||||
from .scrollwin import * |
||||
from .scrollbar import * |
||||
from .iconbutton import * |
||||
from .loader import * |
||||
@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env python3 |
||||
|
||||
# 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. |
||||
|
||||
import os |
||||
import sys |
||||
|
||||
sys.path.append(os.path.join(sys.path[0],'../..')) |
||||
import TermTk as ttk |
||||
|
||||
# Colors: |
||||
# Blue: 0055aa |
||||
# Orange: ff8800 |
||||
|
||||
__all__ = [ |
||||
'fgBLUE','fgORANGE','fgBLACK','fgWHITE', |
||||
'bgBLUE','bgORANGE','bgBLACK','bgWHITE'] |
||||
|
||||
fgBLUE = ttk.TTkColor.fg('#0055aa') |
||||
fgORANGE = ttk.TTkColor.fg('#ff8800') |
||||
fgBLACK = ttk.TTkColor.fg('#000000') |
||||
fgWHITE = ttk.TTkColor.fg('#ffffff') |
||||
|
||||
bgBLUE = ttk.TTkColor.bg('#0055aa') |
||||
bgORANGE = ttk.TTkColor.bg('#ff8800') |
||||
bgBLACK = ttk.TTkColor.bg('#000000') |
||||
bgWHITE = ttk.TTkColor.bg('#ffffff') |
||||
@ -0,0 +1,90 @@
|
||||
# MIT License |
||||
# |
||||
# Copyright (c) 2021 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. |
||||
|
||||
from TermTk.TTkCore.constant import TTkK |
||||
from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal |
||||
from TermTk.TTkCore.color import TTkColor |
||||
from TermTk.TTkCore.canvas import TTkCanvas |
||||
from TermTk.TTkCore.string import TTkString |
||||
from TermTk.TTkWidgets.widget import TTkWidget |
||||
from TermTk.TTkWidgets.scrollbar import TTkScrollBar |
||||
|
||||
from .colors import * |
||||
|
||||
__all__ = ['WBIconButton'] |
||||
|
||||
class WBIconButton(TTkWidget): |
||||
IconTerminal = 0x01 |
||||
IconPreferences = 0x02 |
||||
IconInputLog = 0x03 |
||||
IconLogViewer = 0x03 |
||||
|
||||
_iconS = { IconTerminal: [ |
||||
# TTkString("🬦" "🬹🬹🬹🬹🬹🬹" "🬓"), |
||||
TTkString("▗" "▄▄▄▄▄▄" "▖"), |
||||
TTkString("▐")+ TTkString(" C:\ ",fgORANGE+bgWHITE+TTkColor.BOLD)+ TTkString("▌",fgWHITE+bgBLACK), |
||||
TTkString("🬉")+ TTkString("🬎🬎🬎🬎🬎🬎", fgWHITE+bgBLACK)+ TTkString("🬄",fgWHITE+bgBLACK)], |
||||
# TTkString("┌──────┐"), |
||||
# TTkString("│ C:\ │"), |
||||
# TTkString("└──────┘")] |
||||
IconPreferences: [ |
||||
TTkString(" ┌───┐"), |
||||
TTkString(" │ ? │"), |
||||
TTkString(" └───┘")], |
||||
IconInputLog: [ |
||||
TTkString("┌────────┐"), |
||||
TTkString("│ ABC... │"), |
||||
TTkString("└────────┘")], |
||||
IconLogViewer: [ |
||||
TTkString("┌──────┐"), |
||||
TTkString("│ LOGS │"), |
||||
TTkString("└──────┘")], |
||||
} |
||||
|
||||
classStyle = { |
||||
'default': {'color': fgWHITE+bgBLUE}, |
||||
'disabled': {'color': fgWHITE+bgBLUE}, |
||||
'focus': {'color': fgWHITE+bgBLUE}, |
||||
'clicked': {'color': fgWHITE+bgBLACK}, |
||||
} |
||||
|
||||
__slots__ = ('_text', '_icon', 'clicked') |
||||
def __init__(self, text="", icon=IconTerminal, **kwargs): |
||||
self.clicked = pyTTkSignal() |
||||
self._text = text |
||||
self._icon = WBIconButton._iconS[icon] |
||||
super().__init__(**kwargs) |
||||
self.getCanvas().setTransparent(True) |
||||
self.resize(len(text),len(self._icon)+1) |
||||
|
||||
def mouseDoubleClickEvent(self, evt) -> bool: |
||||
self.clicked.emit() |
||||
return True |
||||
|
||||
def paintEvent(self, canvas: TTkCanvas): |
||||
style = self.currentStyle() |
||||
color = style['color'] |
||||
|
||||
y=-1 |
||||
for y,l in enumerate(self._icon): |
||||
canvas.drawTTkString(text=l, pos=(0,y),color=color) |
||||
canvas.drawText(text=self._text, pos=(0,y+1),color=color) |
||||
@ -0,0 +1,117 @@
|
||||
# MIT License |
||||
# |
||||
# Copyright (c) 2021 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. |
||||
|
||||
from TermTk import TTkUtil, TTkWidget, TTkLabel, TTkCanvas, TTkString |
||||
|
||||
from .colors import * |
||||
|
||||
__all__ = ['WBLoader'] |
||||
|
||||
class WBLoader(TTkWidget): |
||||
__slots__ = ('_data') |
||||
def __init__(self, *args, **kwargs): |
||||
super().__init__(*args, **kwargs) |
||||
|
||||
# ANSII dumb.image.tool.py |
||||
data = TTkUtil.base64_deflate_2_obj( |
||||
"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") |
||||
|
||||
self._data = TTkString(data).split('\n') |
||||
|
||||
# |
||||
# ▀▄ █ ██ █ ▖ █ █ ▝▀▀▄ ██ |
||||
# ▗▛█ ██ █ █ █ ▗▄█ █▀▀█ ██ |
||||
# ▝▘ █ ██ ▝▀▝▀▀ ▀▀ ▀ ▀▀ ██ |
||||
# ██ ██ |
||||
# ████████ ████████ |
||||
# |
||||
# |
||||
# ████████╗ ████████╗ |
||||
# ╚══██╔══╝ ╚══██╔══╝ |
||||
# ██║ ▄▄ ▄ ▄▄ ▄▄▖▄▖ ██║ █ ▗▖ |
||||
# ▞▀▚ ▖▗ ██║ █▄▄█ █▀▘ █ █ █ ██║ █▟▘ |
||||
# ▙▄▞▐▄▟ ██║ ▀▄▄▖ █ █ ▝ █ ██║ █ ▀▄ |
||||
# ▌ ▐ ╚═╝ ╚═╝ |
||||
# ▚▄▄▘ |
||||
|
||||
def mousePressEvent(self, evt) -> bool: |
||||
self.close() |
||||
return True |
||||
|
||||
def paintEvent(self, canvas: TTkCanvas): |
||||
w,h = self.size() |
||||
dw = self._data[0].termWidth() |
||||
dh = len(self._data) |
||||
x = (w-dw)//2 |
||||
y = (h-dh)//2 |
||||
canvas.fill(color=bgWHITE) |
||||
for dy, txt in enumerate(self._data,y): |
||||
canvas.drawTTkString(pos=(x,dy), text=txt) |
||||
@ -0,0 +1,47 @@
|
||||
# MIT License |
||||
# |
||||
# Copyright (c) 2021 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. |
||||
|
||||
from TermTk.TTkCore.constant import TTkK |
||||
from TermTk.TTkCore.signal import pyTTkSlot, pyTTkSignal |
||||
from TermTk.TTkCore.color import TTkColor |
||||
from TermTk.TTkCore.canvas import TTkCanvas |
||||
from TermTk.TTkWidgets.widget import TTkWidget |
||||
from TermTk.TTkWidgets.scrollbar import TTkScrollBar |
||||
|
||||
import wblib.theme as draw_custom |
||||
from TermTk.TTkTheme.theme import TTkTheme |
||||
|
||||
from .colors import * |
||||
|
||||
__all__ = ['WBScrollBar'] |
||||
|
||||
CUSTOM_THEME = TTkTheme.NERD | {'draw':draw_custom} |
||||
|
||||
TTkTheme.loadTheme( CUSTOM_THEME ) |
||||
|
||||
class WBScrollBar(TTkScrollBar): |
||||
classStyle = { |
||||
'default': {'color': bgWHITE+fgBLUE}, |
||||
'disabled': {'color': bgWHITE+fgBLUE}, |
||||
'focus': {'color': bgWHITE+fgBLUE}, |
||||
} |
||||
|
||||
@ -0,0 +1,292 @@
|
||||
# MIT License |
||||
# |
||||
# Copyright (c) 2021 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. |
||||
|
||||
from TermTk.TTkCore.cfg import TTkCfg |
||||
from TermTk.TTkCore.signal import pyTTkSignal, pyTTkSlot |
||||
from TermTk.TTkCore.constant import TTkK |
||||
from TermTk.TTkCore.color import TTkColor |
||||
from TermTk.TTkCore.canvas import TTkCanvas |
||||
from TermTk.TTkLayouts import TTkGridLayout, TTkLayout |
||||
from TermTk.TTkWidgets.widget import TTkWidget |
||||
from TermTk.TTkWidgets.button import TTkButton |
||||
from TermTk.TTkWidgets.resizableframe import TTkResizableFrame |
||||
from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollArea |
||||
from TermTk.TTkAbstract.abstractscrollview import TTkAbstractScrollView, TTkAbstractScrollViewLayout, TTkAbstractScrollViewInterface |
||||
|
||||
|
||||
from .colors import * |
||||
from .scrollbar import * |
||||
|
||||
__all__ = ['WBScrollWin'] |
||||
|
||||
|
||||
class _MinimizedButton(TTkButton): |
||||
__slots__ = ('_windowWidget') |
||||
def __init__(self, *args, **kwargs): |
||||
super().__init__(*args, **kwargs) |
||||
self._windowWidget = kwargs.get('windowWidget') |
||||
def _cb(): |
||||
self._windowWidget.show() |
||||
self.close() |
||||
self.clicked.connect(_cb) |
||||
|
||||
class WBScrollWiewport(TTkAbstractScrollView): |
||||
classStyle = { |
||||
'default': {'color': fgWHITE+bgBLUE}, |
||||
'disabled': {'color': fgWHITE+bgBLUE}, |
||||
'focus': {'color': fgWHITE+bgBLUE}, |
||||
} |
||||
|
||||
__slots__ = () |
||||
def __init__(self, *args, **kwargs): |
||||
TTkAbstractScrollView.__init__(self, *args, **kwargs) |
||||
self.viewChanged.connect(self._viewChangedHandler) |
||||
|
||||
@pyTTkSlot() |
||||
def _viewChangedHandler(self): |
||||
x,y = self.getViewOffsets() |
||||
self.layout().setOffset(-x,-y) |
||||
|
||||
def viewFullAreaSize(self) -> (int, int): |
||||
_,_,w,h = self.layout().fullWidgetAreaGeometry() |
||||
return w , h |
||||
|
||||
def viewDisplayedSize(self) -> (int, int): |
||||
return self.size() |
||||
|
||||
def maximumWidth(self): return 0x10000 |
||||
def maximumHeight(self): return 0x10000 |
||||
def minimumWidth(self): return 0 |
||||
def minimumHeight(self): return 0 |
||||
|
||||
def paintEvent(self, canvas: TTkCanvas): |
||||
style = self.currentStyle() |
||||
color = style['color'] |
||||
canvas.fill(color=color) |
||||
|
||||
class WBScrollWin(TTkResizableFrame): |
||||
'''WBScrollWin''' |
||||
|
||||
_styleScrollBar = { |
||||
'default': {'color': bgWHITE+fgBLUE}, |
||||
'disabled': {'color': bgWHITE+fgBLUE}, |
||||
'focus': {'color': bgWHITE+fgBLUE}, |
||||
} |
||||
|
||||
_styleBgWhite = { |
||||
'default': {'color': fgWHITE+bgBLUE}, |
||||
'disabled': {'color': fgWHITE+bgBLUE}, |
||||
'focus': {'color': fgWHITE+bgBLUE}, |
||||
} |
||||
|
||||
_styleBgNone = { |
||||
'default': {'color': fgWHITE}, |
||||
'disabled': {'color': fgWHITE}, |
||||
'focus': {'color': fgWHITE}, |
||||
} |
||||
|
||||
classStyle = { |
||||
'default': {'titleChar': '⚏', |
||||
'borderColor': bgWHITE+fgBLUE}, |
||||
'disabled': {'titleChar': '⚏', |
||||
'borderColor':bgWHITE+fgBLUE}, |
||||
'focus': {'titleChar': '☰', |
||||
'borderColor': bgWHITE+fgBLUE} |
||||
} |
||||
|
||||
__slots__ = ( |
||||
# Copied from Scroll Area |
||||
'_viewport', |
||||
'_verticalScrollBar', |
||||
'_horizontalScrollBar', |
||||
|
||||
# Copied from Window |
||||
'_mouseDelta', '_draggable', |
||||
'_btnClose', '_btnMax', '_btnMin', '_btnReduce', |
||||
'_flags', '_winTopLayout', |
||||
'_sbRight', '_sbBottom') |
||||
|
||||
def __init__(self, whiteBg=True, *args, **kwargs): |
||||
self._winTopLayout = TTkGridLayout() |
||||
self._viewport = WBScrollWiewport() |
||||
|
||||
super().__init__(*args, **kwargs|{'layout':TTkGridLayout()}) |
||||
|
||||
self._verticalScrollBar = WBScrollBar(orientation=TTkK.VERTICAL) |
||||
self._horizontalScrollBar = WBScrollBar(orientation=TTkK.HORIZONTAL) |
||||
|
||||
self.rootLayout().addWidgets([self._verticalScrollBar, self._horizontalScrollBar]) |
||||
|
||||
|
||||
if whiteBg: |
||||
self.mergeStyle(self._styleBgWhite) |
||||
else: |
||||
self.mergeStyle(self._styleBgNone) |
||||
|
||||
self._flags = TTkK.NONE |
||||
self.setPadding(1,1,1,1) |
||||
self._mouseDelta = (0,0) |
||||
self.setFocusPolicy(TTkK.ClickFocus) |
||||
self._draggable = False |
||||
|
||||
self.setViewport(self._viewport) |
||||
|
||||
def setViewport(self, viewport): |
||||
if not isinstance(viewport, TTkAbstractScrollViewInterface): |
||||
raise TypeError("TTkAbstractScrollViewInterface is required in TTkAbstractScrollArea.setVewport(viewport)") |
||||
if self._viewport: |
||||
self._viewport.viewChanged.disconnect(self._viewportChanged) |
||||
if isinstance(self._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) |
||||
self._horizontalScrollBar.sliderMoved.connect(self._hscrollMoved) |
||||
if isinstance(viewport, TTkWidget): |
||||
self.layout().addWidget(viewport) |
||||
else: |
||||
self.layout().addItem(viewport) |
||||
self._resizeEvent() |
||||
|
||||
def viewport(self): |
||||
return self._viewport |
||||
|
||||
def _resizeEvent(self): |
||||
w,h = self.size() |
||||
self._verticalScrollBar.setGeometry( w-1, 1, 1, h-2) |
||||
self._horizontalScrollBar.setGeometry( 0 , h-1, w-1, 1 ) |
||||
# if self._viewport: |
||||
# self._viewport.setGeometry(0,0,w-2,h-2) |
||||
self._winTopLayout.setGeometry(1,1,w-2,1) |
||||
|
||||
def resizeEvent(self, w, h): |
||||
super().resizeEvent(w,h) |
||||
self._resizeEvent() |
||||
|
||||
@pyTTkSlot() |
||||
def _viewportChanged(self): |
||||
if not self.isVisible(): return |
||||
w,h = self.size() |
||||
fw, fh = self._viewport.viewFullAreaSize() |
||||
dw, dh = self._viewport.viewDisplayedSize() |
||||
ox, oy = self._viewport.getViewOffsets() |
||||
if 0 in [fw,fh,dw,dh]: |
||||
return |
||||
hpage = dw |
||||
vpage = dh |
||||
hrange = fw - dw |
||||
vrange = fh - dh |
||||
# TTkLog.debug(f"f:{fw,fh=}, d:{dw,dh=}, o:{ox,oy=}") |
||||
self._verticalScrollBar.setPageStep(vpage) |
||||
self._verticalScrollBar.setRange(0, vrange) |
||||
self._verticalScrollBar.setValue(oy) |
||||
self._horizontalScrollBar.setPageStep(hpage) |
||||
self._horizontalScrollBar.setRange(0, hrange) |
||||
self._horizontalScrollBar.setValue(ox) |
||||
|
||||
self._resizeEvent() |
||||
|
||||
@pyTTkSlot(int) |
||||
def _vscrollMoved(self, val): |
||||
ox, _ = self._viewport.getViewOffsets() |
||||
self._viewport.viewMoveTo(ox, val) |
||||
|
||||
@pyTTkSlot(int) |
||||
def _hscrollMoved(self, val): |
||||
_, oy = self._viewport.getViewOffsets() |
||||
self._viewport.viewMoveTo(val, oy) |
||||
|
||||
def update(self, repaint=True, updateLayout=False, updateParent=False): |
||||
if self._viewport: |
||||
self._viewport.update(repaint, updateLayout, updateParent) |
||||
return super().update(repaint, updateLayout, updateParent) |
||||
|
||||
def mousePressEvent(self, evt): |
||||
self._mouseDelta = (evt.x, evt.y) |
||||
self._draggable = False |
||||
w,_ = self.size() |
||||
x,y = evt.x, evt.y |
||||
# If the mouse position is inside the header box enable the dragging feature |
||||
if y==0 and 1<=x<w-1: |
||||
if x<4: |
||||
self.close() |
||||
return True |
||||
if x>w-4: |
||||
self.lowerWidget() |
||||
return True |
||||
self._draggable = True |
||||
return True |
||||
return TTkResizableFrame.mousePressEvent(self, evt) |
||||
|
||||
def mouseDragEvent(self, evt): |
||||
if self._draggable: |
||||
x,y = self.pos() |
||||
dx = evt.x-self._mouseDelta[0] |
||||
dy = evt.y-self._mouseDelta[1] |
||||
self.move(x+dx, y+dy) |
||||
return True |
||||
return TTkResizableFrame.mouseDragEvent(self, evt) |
||||
|
||||
def focusInEvent(self): |
||||
if self._menubarTop: |
||||
self._menubarTop.setBorderColor(TTkColor.fg("#ffff55")) |
||||
self.update() |
||||
|
||||
def focusOutEvent(self): |
||||
self._draggable = False |
||||
if self._menubarTop: |
||||
self._menubarTop.setBorderColor(TTkColor.RST) |
||||
self.update() |
||||
|
||||
# # Stupid hack to paint on top of the child widgets |
||||
# def paintChildCanvas(self): |
||||
# super().paintChildCanvas() |
||||
# style = self.currentStyle() |
||||
# borderColor = style['borderColor'] |
||||
# w,h = self.size() |
||||
# canvas = self.getCanvas() |
||||
# canvas.drawChar(pos=(w-1,h-1),char='⇱',color=borderColor) |
||||
|
||||
def paintEvent(self, canvas=TTkCanvas): |
||||
style = self.currentStyle() |
||||
color = style['color'] |
||||
borderColor = style['borderColor'] |
||||
titleChar = style['titleChar'] |
||||
|
||||
w,h = self.size() |
||||
|
||||
canvas.fill(color=bgBLUE) |
||||
canvas.fill(char='▎',pos=(0,1), size=(1,h-2), color=color) |
||||
# draw the title ┃ │ |
||||
canvas.drawText( |
||||
text=f"│▣│ {self._title} {titleChar*w}", |
||||
# text=f"│⚀│ {self._title} {titleChar*w}", |
||||
color=borderColor) |
||||
|
||||
canvas.drawText( |
||||
text="│◪│◩│", |
||||
pos=(w-5,0), |
||||
color=borderColor) |
||||
|
||||
canvas.drawChar(pos=(w-1,h-1),char='⇱',color=borderColor) |
||||
@ -0,0 +1,32 @@
|
||||
# MIT License |
||||
# |
||||
# Copyright (c) 2021 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. |
||||
|
||||
|
||||
from TermTk.TTkTheme.theme import TTkTheme |
||||
|
||||
class TTkTheme(TTkTheme.NERD['draw'].TTkTheme): |
||||
# hscroll = ('←','┄','▓','→') |
||||
# vscroll = ('↑','┊','▓','↓') |
||||
# hscroll = ('<','┄','░','>') |
||||
# vscroll = ('∆','┊','░','∇') |
||||
hscroll = ('<','┄','⣿','>') |
||||
vscroll = ('∆','┊','⣿','∇') |
||||
@ -0,0 +1,167 @@
|
||||
# MIT License |
||||
# |
||||
# Copyright (c) 2021 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. |
||||
|
||||
from TermTk.TTkCore.cfg import TTkCfg |
||||
from TermTk.TTkCore.constant import TTkK |
||||
from TermTk.TTkCore.color import TTkColor |
||||
from TermTk.TTkCore.canvas import TTkCanvas |
||||
from TermTk.TTkLayouts import TTkGridLayout, TTkLayout |
||||
from TermTk.TTkWidgets.button import TTkButton |
||||
from TermTk.TTkWidgets.resizableframe import TTkResizableFrame |
||||
|
||||
from .colors import * |
||||
from .scrollbar import * |
||||
|
||||
__all__ = ['WBWindow'] |
||||
|
||||
|
||||
class _MinimizedButton(TTkButton): |
||||
__slots__ = ('_windowWidget') |
||||
def __init__(self, *args, **kwargs): |
||||
super().__init__(*args, **kwargs) |
||||
self._windowWidget = kwargs.get('windowWidget') |
||||
def _cb(): |
||||
self._windowWidget.show() |
||||
self.close() |
||||
self.clicked.connect(_cb) |
||||
|
||||
class WBWindow(TTkResizableFrame): |
||||
'''WBWindow''' |
||||
|
||||
_styleBgWhite = { |
||||
'default': {'color': fgWHITE+bgBLUE}, |
||||
'disabled': {'color': fgWHITE+bgBLUE}, |
||||
'focus': {'color': fgWHITE+bgBLUE}, |
||||
} |
||||
|
||||
_styleBgNone = { |
||||
'default': {'color': fgWHITE}, |
||||
'disabled': {'color': fgWHITE}, |
||||
'focus': {'color': fgWHITE}, |
||||
} |
||||
|
||||
classStyle = { |
||||
'default': {'titleChar': '⚏', |
||||
'borderColor': bgWHITE+fgBLUE}, |
||||
'disabled': {'titleChar': '⚏', |
||||
'borderColor':bgWHITE+fgBLUE}, |
||||
'focus': {'titleChar': '☰', |
||||
'borderColor': bgWHITE+fgBLUE} |
||||
} |
||||
|
||||
__slots__ = ( |
||||
'_title', '_mouseDelta', '_draggable', |
||||
'_btnClose', '_btnMax', '_btnMin', '_btnReduce', |
||||
'_flags', '_winTopLayout', |
||||
'_sbRight', '_sbBottom') |
||||
|
||||
def __init__(self, whiteBg=True, *args, **kwargs): |
||||
self._winTopLayout = TTkGridLayout() |
||||
super().__init__(*args, **kwargs) |
||||
|
||||
if whiteBg: |
||||
self.mergeStyle(self._styleBgWhite) |
||||
else: |
||||
self.mergeStyle(self._styleBgNone) |
||||
|
||||
self._flags = TTkK.NONE |
||||
self.setPadding(1,1,1,1) |
||||
self._mouseDelta = (0,0) |
||||
self.setFocusPolicy(TTkK.ClickFocus) |
||||
self._draggable = False |
||||
self._sbRight = WBScrollBar(orientation=TTkK.VERTICAL) |
||||
self._sbBottom = WBScrollBar(orientation=TTkK.HORIZONTAL) |
||||
self._sbRight.setPageStep(60) |
||||
self._sbRight.setRange(0, 100) |
||||
self._sbBottom.setPageStep(60) |
||||
self._sbBottom.setRange(0, 100) |
||||
self.rootLayout().addWidgets([self._sbRight,self._sbBottom]) |
||||
w,h = self.size() |
||||
self._sbRight.setGeometry( w-1, 1, 1, h-2) |
||||
self._sbBottom.setGeometry( 0 , h-1, w-1, 1 ) |
||||
|
||||
def resizeEvent(self, w, h): |
||||
self._winTopLayout.setGeometry(1,1,w-2,1) |
||||
self._sbRight.setGeometry( w-1, 1, 1, h-2) |
||||
self._sbBottom.setGeometry( 0 , h-1, w-1, 1 ) |
||||
super().resizeEvent(w,h) |
||||
|
||||
def mousePressEvent(self, evt): |
||||
self._mouseDelta = (evt.x, evt.y) |
||||
self._draggable = False |
||||
w,_ = self.size() |
||||
x,y = evt.x, evt.y |
||||
# If the mouse position is inside the header box enable the dragging feature |
||||
if y==0 and 1<=x<w-1: |
||||
if x<4: |
||||
self.close() |
||||
return True |
||||
if x>w-4: |
||||
self.lowerWidget() |
||||
return True |
||||
self._draggable = True |
||||
return True |
||||
return TTkResizableFrame.mousePressEvent(self, evt) |
||||
|
||||
def mouseDragEvent(self, evt): |
||||
if self._draggable: |
||||
x,y = self.pos() |
||||
dx = evt.x-self._mouseDelta[0] |
||||
dy = evt.y-self._mouseDelta[1] |
||||
self.move(x+dx, y+dy) |
||||
return True |
||||
return TTkResizableFrame.mouseDragEvent(self, evt) |
||||
|
||||
def focusInEvent(self): |
||||
if self._menubarTop: |
||||
self._menubarTop.setBorderColor(TTkColor.fg("#ffff55")) |
||||
self.update() |
||||
|
||||
def focusOutEvent(self): |
||||
self._draggable = False |
||||
if self._menubarTop: |
||||
self._menubarTop.setBorderColor(TTkColor.RST) |
||||
self.update() |
||||
|
||||
def paintEvent(self, canvas=TTkCanvas): |
||||
style = self.currentStyle() |
||||
color = style['color'] |
||||
borderColor = style['borderColor'] |
||||
titleChar = style['titleChar'] |
||||
|
||||
w,h = self.size() |
||||
|
||||
|
||||
canvas.fill(color=bgBLUE) |
||||
canvas.fill(char='▎',pos=(0,1), size=(1,h-2), color=color) |
||||
# draw the title ┃ │ |
||||
canvas.drawText( |
||||
text=f"│▣│ {self._title} {titleChar*w}", |
||||
# text=f"│⚀│ {self._title} {titleChar*w}", |
||||
color=borderColor) |
||||
|
||||
canvas.drawText( |
||||
text="│◪│◩│", |
||||
pos=(w-5,0), |
||||
color=borderColor) |
||||
|
||||
canvas.drawChar(pos=(w-1,h-1),char='⇱',color=borderColor) |
||||
Loading…
Reference in new issue