Browse Source

Merge remote-tracking branch 'origin' into DumbPaintTool

pull/244/head
Eugenio Parodi 2 years ago
parent
commit
b1ef2d9f8a
  1. 8
      .vscode/launch.json
  2. 1
      README.md
  3. 29
      TermTk/TTkCore/TTkTerm/input_thread.py
  4. 2
      TermTk/TTkCore/signal.py
  5. 21
      TermTk/TTkGui/clipboard.py
  6. 84
      tests/sandbox/clipbboard.test.html
  7. 1
      tests/sandbox/js
  8. 98
      tools/webExporter/index.html
  9. 26
      tools/webExporter/js/ttkproxy.js
  10. 10
      tools/webExporter/package.json
  11. 115
      tools/webExporterInit.sh
  12. 1
      ttkDesigner/app/widgetbox.py

8
.vscode/launch.json vendored

@ -41,6 +41,14 @@
"program": "tools/dumb.paint.tool.py",
"console": "integratedTerminal",
"justMyCode": true
},{
"name": "Python: DumbPaintTool File",
"type": "debugpy",
"request": "launch",
"program": "tools/dumb.paint.tool.py",
"console": "integratedTerminal",
"justMyCode": true,
"args":["experiments/paint.test.json"]
},{
"name": "Python: Demo",
"type": "debugpy",

1
README.md

@ -88,6 +88,7 @@ python3 tests/test.ui.018.TextEdit.Pygments.py README.md
- [pytest-fold](https://github.com/jeffwright13/pytest-fold) - A Pytest plugin to make console output more manageable when there are multiple failed tests
- [pytest-tui](https://github.com/jeffwright13/pytest-tui) - A Text User Interface (TUI) for Pytest, automatically launched after your test run is finished
- [breakoutRL](https://ceccopierangiolieugenio.itch.io/breakoutrl) - Breakout the Roguelike
- [7drl-2024](https://ceccopierangiolieugenio.itch.io/a-snake-on-a-plane) - A Snake🐍 on a Plane✈ - The Roguelike
## Related Projects
- Honourable mention

29
TermTk/TTkCore/TTkTerm/input_thread.py

@ -111,20 +111,24 @@ class TTkInput:
TTkInput._inputQueue.put(outq)
TTkInput._inputQueue.put(None)
@staticmethod
def _handleBracketedPaste(stdinRead:str):
if stdinRead.endswith("\033[201~"):
TTkInput._pasteBuffer += stdinRead[:-6]
TTkInput._bracketedPaste = False
# due to the CRNL methos (don't ask me why) the terminal
# is substituting all the \n with \r
_paste = TTkInput._pasteBuffer.replace('\r','\n')
TTkInput._pasteBuffer = ""
return None, None, _paste
else:
TTkInput._pasteBuffer += stdinRead
return None, None, None
@staticmethod
def key_process(stdinRead:str) -> None:
if TTkInput._bracketedPaste:
if stdinRead.endswith("\033[201~"):
TTkInput._pasteBuffer += stdinRead[:-6]
TTkInput._bracketedPaste = False
# due to the CRNL methos (don't ask me why) the terminal
# is substituting all the \n with \r
_paste = TTkInput._pasteBuffer.replace('\r','\n')
TTkInput._pasteBuffer = ""
return None, None, _paste
else:
TTkInput._pasteBuffer += stdinRead
return None, None, None
return TTkInput._handleBracketedPaste(stdinRead)
mevt,kevt = None,None
@ -205,9 +209,8 @@ class TTkInput:
return kevt, mevt, None
if stdinRead.startswith("\033[200~"):
TTkInput._pasteBuffer = stdinRead[6:]
TTkInput._bracketedPaste = True
return None, None, None
return TTkInput._handleBracketedPaste(stdinRead[6:])
hex = [f"0x{ord(x):02x}" for x in stdinRead]
TTkLog.error("UNHANDLED: "+stdinRead.replace("\033","<ESC>") + " - "+",".join(hex))

2
TermTk/TTkCore/signal.py

@ -123,7 +123,7 @@ class _pyTTkSignal_obj():
raise TypeError(error)
else:
for a,b in zip(slot._TTkslot_attr, self._types):
if not issubclass(a,b):
if a!=b and not issubclass(a,b):
error = "Decorated slot has no signature compatible: "+slot.__name__+str(slot._TTkslot_attr)+" != signal"+str(self._types)
raise TypeError(error)
if slot not in self._connected_slots:

21
TermTk/TTkGui/clipboard.py

@ -59,7 +59,13 @@ class TTkClipboard():
@staticmethod
def _loadClipboardManager():
try:
if importlib.util.find_spec('copykitten'):
if importlib.util.find_spec('pyodideProxy'):
TTkLog.info("Using 'pyodideProxy' as clipboard manager")
import pyodideProxy as _c
TTkClipboard._manager = _c
TTkClipboard._setText = _c.copy
TTkClipboard._text = _c.paste
elif importlib.util.find_spec('copykitten'):
TTkLog.info("Using 'copykitten' as clipboard manager")
import copykitten as _c
TTkClipboard._manager = _c
@ -113,9 +119,14 @@ class TTkClipboard():
def text():
'''text'''
if TTkClipboard._text:
txt = TTkClipboard._text()
if txt == str(TTkClipboard._clipboard):
txt = ""
try:
txt = TTkClipboard._text()
except Exception as e:
TTkLog.error("Clipboard error, try to export X11 if you are running this UI via SSH")
for line in str(e).split("\n"):
TTkLog.error(line)
if txt == None or txt == str(TTkClipboard._clipboard):
return TTkClipboard._clipboard
else:
return TTkClipboard._text()
return txt
return TTkClipboard._clipboard

84
tests/sandbox/clipbboard.test.html

@ -0,0 +1,84 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Clipboard Test</title>
</head>
<body>
<h2>Clipboard Test</h2>
<p>Click the button below to copy the text to your clipboard:</p>
<button onclick="copyToClipboard()">CopyTo Text</button>
<button onclick="copyFromClipboard()">CopyFrom Text</button>
<button onclick="copyTA()">CopyFrom TextArea</button>
<button onclick="pasteTA()">PasteTo TextArea</button>
<br/>
<textarea id="TB" rows="10" cols="50">
████████╗ ████████╗
╚══██╔══╝ ╚══██╔══╝
██║ ▄▄ ▄ ▄▄ ▄▄▖▄▖ ██║ █ ▗▖
▞▀▚ ▖▗ ██║ █▄▄█ █▀▘ █ █ █ ██║ █▟▘
▙▄▞▐▄▟ ██║ ▀▄▄▖ █ █ ▝ █ ██║ █ ▀▄
▌ ▐ ╚═╝ ╚═╝
▚▄▄▘
Test
</textarea>
<br/>
<input type="text" id="myInput" value="Paste something here" size="40">
<p id="demo"></p>
<script>
document.getElementById("myInput").addEventListener("paste", myFunction);
function myFunction(abc) {
document.getElementById("demo").innerHTML = "You pasted text!:"+abc.clipboardData.getData("Text");
}
function copyTA() {
let textarea = document.getElementById("TB");
textarea.select();
document.execCommand("copy");
}
function pasteTA() {
let textarea = document.getElementById("TB");
textarea.select();
document.execCommand("paste");
}
function copyToClipboard() {
// Text to be copied
var textToCopy = "Hello, world! This is a clipboard test.";
// Use the navigator.clipboard API to copy text to clipboard
window.navigator.clipboard.writeText(textToCopy)
.then(function() {
// Success callback
alert("Text copied to clipboard: " + textToCopy);
})
.catch(function(error) {
// Error callback
console.error("Failed to copy text: ", error);
});
}
function copyFromClipboard() {
// Create a temporary textarea element
var textarea = document.createElement("textarea");
textarea.value = textToCopy;
document.body.appendChild(textarea);
// Select and copy the text from the textarea
textarea.select();
document.execCommand("copy");
// Remove the temporary textarea
document.body.removeChild(textarea);
// Alert the user that the text has been copied
alert("Text copied to clipboard: " + textToCopy);
}
</script>
</body>
</html>

1
tests/sandbox/js

@ -0,0 +1 @@
../../tools/webExporter/js

98
tools/webExporter/index.html

@ -0,0 +1,98 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="icon" type="image/x-icon" href="www/favicon.ico">
<script src="www/pyodide/pyodide.js"></script>
<link href="www/xterm/xterm.css" rel="stylesheet" />
<script src="www/xterm/xterm.js"></script>
<script src="www/xterm-addon-fit/xterm-addon-fit.js"></script>
<script src="www/xterm-addon-unicode11/xterm-addon-unicode11.js"></script>
<script src="js/ttkproxy.js"></script>
<style>
.xterm .xterm-viewport {overflow-y: hidden;}
</style>
</head>
<body>
<div id="terminal" contenteditable="true" onpaste="pasteFunction()" oncontextmenu="return false;" style="position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px"></div>
<script type="text/javascript">
function pasteFunction(abc) {
text = abc.clipboardData.getData("Text")
console.log(`Pasted: ${text}`);
}
// Workaround from: https://developer.mozilla.org/en-US/docs/Web/API/CSS_Font_Loading_API
// const font = new FontFace("NerdFont", "url(www/nerdfonts/DejaVuSansMNerdFont-Regular.ttf)");
const font = new FontFace("NerdFont", "url(www/opentype/3270SemiCondensed-Regular.otf)");
document.fonts.add(font);
font.load();
document.fonts.ready.then(() => {fetchData()});
function fetchData(){
fetch("package.json")
.then(response => response.json())
.then(json => processAndStart(json));
}
function processAndStart(json){
console.log(json)
main(json)
}
/* pyodide demo */
async function mainTTk(term,json){
ttkProxy = new TTkProxy(term)
await ttkProxy.init()
for (lib of json['libs']){
await ttkProxy.loadLib(lib['pkg']);
term.write(`${lib['name']} - Loaded\n\r`)
}
term.write('Starting...\n\r')
ttkProxy.preRun()
let file = json['main']
let content = ttkProxy.readFile(file)
ttkProxy.run(content, file, 60)
}
function main(json){
/* xterm.js */
var term = new Terminal({
allowProposedApi: true,
fontFamily: 'NerdFont'});
/* https://www.npmjs.com/package/xterm-addon-fit */
const fitAddon = new FitAddon.FitAddon();
/* https://www.npmjs.com/package/xterm-addon-unicode11 */
const unicode11Addon = new Unicode11Addon.Unicode11Addon();
term.loadAddon(fitAddon);
term.loadAddon(unicode11Addon);
term.unicode.activeVersion = '11';
term.open(document.getElementById('terminal'));
fitAddon.fit()
// start observing the terminal for resize
const resize_ob = new ResizeObserver(function(entries) {fitAddon.fit();});
resize_ob.observe(document.querySelector("#terminal"));
term.write('xterm.js - Loaded\n\r')
mainTTk(term,json)
}
</script>
</body>
</html>

26
tests/sandbox/js/ttkproxy.js → tools/webExporter/js/ttkproxy.js

@ -29,6 +29,32 @@ class TTkProxy {
}
pyodideProxy = {
copy: function(text){
console.log("Copying:",text)
if(navigator.clipboard){
navigator.clipboard.writeText(text)
return //codes below wont be executed
}
const textArea = document.createElement("textarea")
textArea.value = text
document.body.appendChild(textArea)
textArea.focus()
textArea.select()
document.execCommand('copy')
document.body.removeChild(textArea)
},
paste: function(){
if(navigator.clipboard){
text = navigator.clipboard.readText()
console.log("Pasted:",text)
return text
}
return null
},
consoleLog: function(m){
console.log("TTk:",m)
},

10
tools/webExporter/package.json

@ -0,0 +1,10 @@
{
"libs" : [
{"pkg" :"bin/TermTk.tgz",
"name": "TermTk"},
{"pkg" :"bin/dpt.tgz",
"name": "Dumb Paint Tool"}
],
"mainOld": "main.py",
"main": "dumb.paint.tool.py"
}

115
tools/webExporterInit.sh

@ -0,0 +1,115 @@
#!/usr/bin/env bash
# MIT License
#
# Copyright (c) 2024 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.
_PWD=`pwd`
_TOOLS_BASE_PATH=$(dirname $(readlink -f $0))
_BASE_PATH=$( readlink -f ${_TOOLS_BASE_PATH}/.. )
_TMP_PATH=$( readlink -f ${_BASE_PATH}/tmp )
_MAJOR=$( git describe --tags | sed 's,\([0-9]*\)\..*,\1,' )
_MINOR=$( git describe --tags | sed 's,[0-9]*\.\([0-9]*\)\..*,\1,' )
_PATCH=$( git describe --tags | sed 's,[0-9]*\.[0-9]*\.\([0-9]*\)[^0-9].*,\1,' )
_STAGE=$( git describe --tags | sed 's,[^-]*-a-\?\([0-9]*\).*,\1,' )
_VERSION="${_MAJOR}.${_MINOR}.${_PATCH}-a${_STAGE}"
_DOCVERSION="${_MAJOR}.${_MINOR}.${_PATCH}-a"
echo Version: ${_VERSION}
echo Name: ${_NAME}
mkdir -p ${_TMP_PATH}
rm -rf ${_TMP_PATH}/* itchExport.zip
${_TOOLS_BASE_PATH}/prepareBuild.sh release
mkdir -p ${_TMP_PATH}/bin \
${_TMP_PATH}/www/pyodide \
${_TMP_PATH}/www/xterm/ \
${_TMP_PATH}/www/xterm-addon-fit \
${_TMP_PATH}/www/xterm-addon-unicode11 \
${_TMP_PATH}/www/webfonts \
${_TMP_PATH}/www/nerdfonts \
${_TMP_PATH}/www/opentype
function _download {
_P=$1
_F=$2
if [ -f tests/sandbox/${_F} ] ;
then cp tests/sandbox/${_F} ${_P} ;
else wget -P ${_P} https://ceccopierangiolieugenio.github.io/binaryRepo/pyTermTk/${_F};
fi ;
};
_download ${_TMP_PATH}/www/pyodide/ www/pyodide/pyodide.js
# _download ${_TMP_PATH}/www/pyodide/ www/pyodide/pyodide.js
_download ${_TMP_PATH}/www/pyodide/ www/pyodide/pyodide-lock.json
_download ${_TMP_PATH}/www/pyodide/ www/pyodide/python_stdlib.zip
_download ${_TMP_PATH}/www/pyodide/ www/pyodide/pyodide.asm.js
_download ${_TMP_PATH}/www/pyodide/ www/pyodide/repodata.json
_download ${_TMP_PATH}/www/pyodide/ www/pyodide/pyodide.asm.wasm
_download ${_TMP_PATH}/www/xterm/ www/xterm/xterm.css
_download ${_TMP_PATH}/www/xterm/ www/xterm/xterm.js
_download ${_TMP_PATH}/www/xterm/ www/xterm/xterm.js.map
_download ${_TMP_PATH}/www/xterm-addon-fit/ www/xterm-addon-fit/xterm-addon-fit.js
_download ${_TMP_PATH}/www/xterm-addon-fit/ www/xterm-addon-fit/xterm-addon-fit.js.map
_download ${_TMP_PATH}/www/xterm-addon-unicode11/ www/xterm-addon-unicode11/xterm-addon-unicode11.js
# _download ${_TMP_PATH}/www/webfonts/ www/webfonts/fa-regular-400.woff2
# _download ${_TMP_PATH}/www/nerdfonts/ www/nerdfonts/HurmitNerdFontMono-Regular.otf
# _download ${_TMP_PATH}/www/nerdfonts/ www/nerdfonts/DejaVuSansMNerdFont-Regular.ttf
_download ${_TMP_PATH}/www/opentype/ www/opentype/3270SemiCondensed-Regular.otf
_download ${_TMP_PATH}/www/ www/favicon.ico
tar cvzf ${_TMP_PATH}/bin/TermTk.tgz --exclude='__pycache__' --transform "s,^.*TermTk/,TermTk/," ${_TMP_PATH}/TermTk
tar cvzf ${_TMP_PATH}/bin/DPT.tgz --exclude='__pycache__' --transform "s,^.*/dumb,dumb," ${_TOOLS_BASE_PATH}/dumb.paint.tool.py ${_TOOLS_BASE_PATH}/dumb_paint_lib
# find ${_TMP_PATH}/TermTk \
# | grep -v __pycache__ | xargs tar cvzf ${_TMP_PATH}/bin/TermTk.tgz -C ${_TMP_PATH}
#
# find ${_TOOLS_BASE_PATH}/dumb.paint.tool.py ${_TOOLS_BASE_PATH}/dumb_paint_lib \
# | grep -v __pycache__ | xargs tar cvzf ${_TMP_PATH}/bin/DPT.tgz -C ${_TOOLS_BASE_PATH}
cp -a ${_TOOLS_BASE_PATH}/webExporter/* ${_TMP_PATH}/
echo '{
"libs" : [
{"pkg" :"bin/TermTk.tgz",
"name": "TermTk"},
{"pkg" :"bin/DPT.tgz",
"name": "Dumb Paint Tool"}
],
"mainOld": "main.py",
"main": "dumb.paint.tool.py"
}' > ${_TMP_PATH}/package.json
rm -rf ${_TMP_PATH}/TermTk
pushd ${_TMP_PATH}
zip -r ${_PWD}/itchExport.zip *
popd

1
ttkDesigner/app/widgetbox.py

@ -65,6 +65,7 @@ dWidgets = {
},
'Pickers':{
"Color Picker" : { "class":ttk.TTkColorButtonPicker, "params":{'size':( 6,3), 'border':True}},
"Color Picker Slim": { "class":ttk.TTkColorButtonPicker, "params":{'size':( 6,1), 'border':False}},
"File Picker" : { "class":ttk.TTkFileButtonPicker, "params":{'size':(20,3), 'border':True}},
"Date Picker" : { "class":ttk.TTkButton, "params":{'size':(20,3)}, "disabled": True},
"TtkString Picker" : { "class":ttk.TTkButton, "params":{'size':(20,3)}, "disabled": True},

Loading…
Cancel
Save