Browse Source

chore(crossTools): improve typing (#571)

pull/573/head
Pier CeccoPierangioliEugenio 3 months ago committed by GitHub
parent
commit
ebd13f94c5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 48
      apps/dumbPaintTool/dumbPaintTool/app/maintemplate.py
  2. 4
      libs/pyTermTk/TermTk/TTkCore/constant.py
  3. 416
      libs/pyTermTk/TermTk/TTkCrossTools/savetools.py
  4. 6
      libs/pyTermTk/TermTk/TTkWidgets/TTkPickers/messagebox.py
  5. 16
      tools/webExporter/js/ttkproxy.js

48
apps/dumbPaintTool/dumbPaintTool/app/maintemplate.py

@ -127,8 +127,8 @@ class PaintTemplate(ttk.TTkAppTemplate):
glbls.clearSnapshot()
glbls.saveSnapshot()
ttk.ttkConnectDragOpen(ttk.TTkEncoding.APPLICATION_JSON, self._openDragData)
ttk.ttkConnectDragOpen(ttk.TTkEncoding.IMAGE, self._openImageData)
ttk.TTkCrossTools.ttkConnectDragOpen(ttk.TTkCrossTools.Encoding.APPLICATION_JSON, self._openDragData)
ttk.TTkCrossTools.ttkConnectDragOpen(ttk.TTkCrossTools.Encoding.IMAGE, self._openImageData)
ttk.TTkShortcut(ttk.TTkK.CTRL | ttk.TTkK.Key_Z).activated.connect(glbls.undo)
ttk.TTkShortcut(ttk.TTkK.CTRL | ttk.TTkK.Key_Y).activated.connect(glbls.redo)
@ -147,56 +147,68 @@ class PaintTemplate(ttk.TTkAppTemplate):
@ttk.pyTTkSlot()
def _open(self):
ttk.ttkCrossOpen(
ttk.TTkCrossTools.open(
path='.',
encoding=ttk.TTkEncoding.APPLICATION_JSON,
encoding=ttk.TTkCrossTools.Encoding.APPLICATION_JSON,
filter="DumbPaintTool Files (*.DPT.json);;Json Files (*.json);;All Files (*)",
cb=self._openDragData)
@ttk.pyTTkSlot()
def _openImage(self):
ttk.ttkCrossOpen(
ttk.TTkCrossTools.open(
path='.',
encoding=ttk.TTkEncoding.IMAGE,
encoding=ttk.TTkCrossTools.Encoding.IMAGE,
filter="Images (*.png *.jpg *.gif *.ico);;All Files (*)",
cb=self._openImageData)
@ttk.pyTTkSlot()
def _save(self):
doc = self._parea.exportDocument()
ttk.ttkCrossSave(glbls.fileName(), json.dumps(doc, indent=1), ttk.TTkEncoding.APPLICATION_JSON)
ttk.TTkCrossTools.save(
filePath=glbls.fileName(),
content=json.dumps(doc, indent=1),
encoding=ttk.TTkCrossTools.Encoding.APPLICATION_JSON)
@ttk.pyTTkSlot()
def _saveAs(self):
doc = self._parea.exportDocument()
ttk.ttkCrossSaveAs(glbls.fileName(), json.dumps(doc, indent=1), ttk.TTkEncoding.APPLICATION_JSON,
ttk.TTkCrossTools.saveAs(
filePath=glbls.fileName(),
content=json.dumps(doc, indent=1),
encoding=ttk.TTkCrossTools.Encoding.APPLICATION_JSON,
filter="DumbPaintTool Files (*.DPT.json);;Json Files (*.json);;All Files (*)",
cb=lambda _d:glbls.setFilename(_d['name']))
cb=lambda _d:glbls.setFilename(_d.name))
@ttk.pyTTkSlot()
def _saveAsAnsi(self):
image = self._parea.exportImage()
text = ttk.TTkString(image)
ttk.ttkCrossSaveAs(glbls.fileName(), text.toAnsi(), ttk.TTkEncoding.TEXT_PLAIN_UTF8,
ttk.TTkCrossTools.saveAs(
filePath=glbls.fileName(),
content=text.toAnsi(),
encoding=ttk.TTkCrossTools.Encoding.TEXT_PLAIN_UTF8,
filter="Ansi text Files (*.Ansi.txt);;Text Files (*.txt);;All Files (*)")
@ttk.pyTTkSlot()
def _saveAsAscii(self):
image = self._parea.exportImage()
text = ttk.TTkString(image)
ttk.ttkCrossSaveAs('untitled.DPT.ASCII.txt', text.toAscii(), ttk.TTkEncoding.TEXT_PLAIN_UTF8,
ttk.TTkCrossTools.saveAs(
filePath='untitled.DPT.ASCII.txt',
content=text.toAscii(),
encoding=ttk.TTkCrossTools.Encoding.TEXT_PLAIN_UTF8,
filter="ASCII Text Files (*.ASCII.txt);;Text Files (*.txt);;All Files (*)")
@ttk.pyTTkSlot(dict)
def _openImageData(self, data):
newWindow = ImportImage(data['data'])
@ttk.pyTTkSlot(ttk.TTkCrossTools.CB_Data_Open)
def _openImageData(self, data:ttk.TTkCrossTools.CB_Data_Open):
newWindow = ImportImage(data.data)
newWindow.exportedImage.connect(self._parea.pasteEvent)
ttk.TTkHelper.overlay(None, newWindow, 10, 4, modal=True)
@ttk.pyTTkSlot(dict)
def _openDragData(self, data):
dd = json.loads(data['data'])
glbls.setFilename(data['name'])
@ttk.pyTTkSlot(ttk.TTkCrossTools.CB_Data_Open)
def _openDragData(self, data:ttk.TTkCrossTools.CB_Data_Open):
dd = json.loads(data.data)
glbls.setFilename(data.name)
if 'layers' in dd:
self.importDocument(dd)
else:

4
libs/pyTermTk/TermTk/TTkCore/constant.py

@ -471,7 +471,7 @@ class TTkConstant:
CENTER_ALIGN = Alignment.CENTER_ALIGN
JUSTIFY = Alignment.JUSTIFY
class FileMode(int):
class FileMode(IntEnum):
'''FileMode
.. autosummary::
@ -492,7 +492,7 @@ class TTkConstant:
# Directory = FileMode.Directory
# ExistingFiles = FileMode.ExistingFiles
class AcceptMode(int):
class AcceptMode(IntEnum):
'''AcceptMode
.. autosummary::

416
libs/pyTermTk/TermTk/TTkCrossTools/savetools.py

@ -20,34 +20,133 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = [
'ttkCrossOpen',
'ttkCrossSave', 'ttkCrossSaveAs',
'TTkEncoding', 'ImageData',
'ttkConnectDragOpen',
'ttkEmitDragOpen', 'ttkEmitFileOpen']
'''savetools.py
Cross-platform file operations and clipboard management for pyTermTk.
This module provides a unified interface for file I/O operations that work seamlessly
across different platforms, including native desktop environments and web-based
Pyodide/WASM deployments. It automatically detects the runtime environment and
adapts its behavior accordingly.
Key Features:
- **Cross-platform file operations**: Open, save, and saveAs methods that work
identically on desktop and web platforms
- **Multiple encoding support**: Text, JSON, and image formats with automatic
decoding and encoding
- **Drag and drop integration**: Native drag-drop support in web environments
- **File dialog integration**: Automatic file picker dialogs on desktop with
JavaScript-based file selection in browsers
- **Image handling**: PIL/Pillow integration for image file operations
- **Type-safe callbacks**: Protocol-based type hints for callback functions
Platform Detection:
The module automatically detects whether it's running in a Pyodide/WASM environment
by checking for the 'pyodideProxy' module. Based on this detection, it provides
platform-specific implementations while maintaining a consistent API.
- **Desktop mode**: Uses native file dialogs (:py:class:`TTkFileDialogPicker`) and
standard Python file I/O
- **Web mode**: Uses JavaScript interop via pyodideProxy for browser-based file
selection and download
Usage Example:
.. code-block:: python
from TermTk.TTkCrossTools import TTkCrossTools
# Open a text file
def handle_open(data: TTkCrossTools.CB_Data_Open):
print(f"Opened: {data.name}")
print(f"Content: {data.data}")
TTkCrossTools.open(
path=".",
encoding=TTkCrossTools.Encoding.TEXT_PLAIN,
filter="Text Files (*.txt)",
cb=handle_open
)
# Save a file
TTkCrossTools.save(
filePath="output.txt",
content="Hello, World!",
encoding=TTkCrossTools.Encoding.TEXT_PLAIN
)
# Save with dialog
def handle_save(data: TTkCrossTools.CB_Data_Save):
print(f"Saved to: {data.name}")
TTkCrossTools.saveAs(
filePath="output.json",
content='{"key": "value"}',
encoding=TTkCrossTools.Encoding.APPLICATION_JSON,
filter="JSON Files (*.json)",
cb=handle_save
)
Supported Encodings:
See :py:class:`TTkCrossTools.Encoding` for the full list of supported MIME types and
encoding formats.
Callback Data Structures:
- :py:class:`_CB_Data_Open`: Contains file name and decoded content
- :py:class:`_CB_Data_Save`: Contains the saved file name
See Also:
- :py:class:`TTkCrossTools`: Main API class
- :py:class:`TTkCrossTools.Encoding`: Encoding type definitions
- :py:class:`TTkFileDialogPicker`: Native file dialog widget
'''
from __future__ import annotations
__all__ = ['TTkCrossTools', '_TTkEncoding']
import os
import importlib.util
import json
from enum import Enum
from dataclasses import dataclass
from typing import Callable,Optional,List,Tuple,Dict,Any,Protocol,Type
try:
from typing import TypeAlias
except ImportError:
# TODO: Remove this workaround for Python 3.9
TypeAlias = type # Fallback for Python < 3.10 without typing_extensions
from TermTk import pyTTkSlot, pyTTkSignal
from TermTk import TTkLog
from TermTk import TTkMessageBox, TTkFileDialogPicker, TTkHelper, TTkString, TTkK, TTkColor
class ImageData:
size:list[int,int] = (0,0)
data:list[list[list[int,int,int,int]]] = []
class _TTkEncoding(str, Enum):
''' Encoding types for cross-platform file operations.
ttkCrossOpen = None
ttkCrossSave = None
ttkCrossSaveAs = None
ttkEmitDragOpen = None
ttkEmitFileOpen = None
ttkConnectDragOpen = None
Defines MIME types and encoding identifiers used by :py:class:`TTkCrossTools`
for file operations. These encodings determine how file content is decoded
when opening and encoded when saving.
class TTkEncoding(str):
Text Encodings:
- **TEXT**: Generic text encoding
- **TEXT_PLAIN**: Plain text MIME type
- **TEXT_PLAIN_UTF8**: UTF-8 encoded plain text
Application Encodings:
- **APPLICATION**: Generic application data
- **APPLICATION_JSON**: JSON format with automatic parsing
Image Encodings:
- **IMAGE**: Generic image format
- **IMAGE_PNG**: PNG image format
- **IMAGE_SVG**: SVG vector image format
- **IMAGE_JPG**: JPEG image format
Note:
Image encodings require PIL/Pillow to be installed. When opening image
files, the decoded data will be a PIL Image object.
'''
TEXT = "text"
TEXT_PLAIN = "text/plain"
TEXT_PLAIN_UTF8 = "text/plain;charset=utf-8"
@ -58,112 +157,187 @@ class TTkEncoding(str):
IMAGE_SVG = 'image/svg+xml'
IMAGE_JPG = 'image/jpeg'
class _OpenProtocol(Protocol):
def __call__(
self,
path: str,
encoding: _TTkEncoding,
filter: str,
cb: Optional[TTkCrossTools.TTkCross_Callback_Open] = None
) -> None: ...
class _SaveProtocol(Protocol):
def __call__(
self,
filePath: str,
content: str,
encoding: _TTkEncoding
) -> None: ...
class _SaveAsProtocol(Protocol):
def __call__(
self,
filePath: str,
content: str,
encoding: _TTkEncoding,
filter: str,
cb: Optional[TTkCrossTools.TTkCross_Callback_Save] = None
) -> None: ...
class _EmitDragOpenProtocol(Protocol):
def __call__(
self,
encoding: _TTkEncoding,
data: _CB_Data_Open
) -> None: ...
class _EmitFileOpenProtocol(Protocol):
def __call__(
self,
encoding: _TTkEncoding,
data: _CB_Data_Open
) -> None: ...
class _ConnectDragOpenProtocol(Protocol):
def __call__(
self,
encoding: _TTkEncoding,
cb: TTkCrossTools.TTkCross_Callback_Open
) -> None: ...
@dataclass
class _CB_Data_Save():
''' Callback data for save operations.
:param name: The full path or name of the saved file
:type name: str
'''
name:str
@dataclass
class _CB_Data_Open():
''' Callback data for open/load operations.
:param name: The full path or name of the opened file
:type name: str
:param data: The decoded file content. Type depends on the encoding:
- Text encodings: str
- JSON encodings: str (raw JSON content)
- Image encodings: PIL.Image.Image object
:type data: Any
'''
name:str
data:Any
if importlib.util.find_spec('pyodideProxy'):
TTkLog.info("Using 'pyodideProxy' as clipboard manager")
import pyodideProxy
ttkDragOpen = {}
ttkFileOpen = pyTTkSignal(dict)
import pyodideProxy # type: ignore[import-not-found]
ttkDragOpen:Dict[_TTkEncoding,pyTTkSignal] = {}
ttkFileOpen = pyTTkSignal(_CB_Data_Open)
def _open(path, encoding, filter, cb=None):
def _open(path:str, encoding:_TTkEncoding, filter:str, cb: Optional[TTkCrossTools.TTkCross_Callback_Open] = None) -> None:
if not cb: return
ttkFileOpen.connect(cb)
pyodideProxy.openFile(encoding)
def _save(filePath, content, encoding, filter=None, cb=lambda _d:None):
def _save(filePath: str, content: str, encoding: _TTkEncoding) -> None:
pyodideProxy.saveFile(os.path.basename(filePath), content, encoding)
def _connectDragOpen(encoding, cb):
if encoding not in ttkDragOpen:
ttkDragOpen[encoding] = pyTTkSignal(dict)
return ttkDragOpen[encoding].connect(cb)
def _saveAs(filePath:str, content:str, encoding:_TTkEncoding, filter:str, cb: Optional[TTkCrossTools.TTkCross_Callback_Save] = None) -> None:
return _save(
filePath=filePath,
content=content,
encoding=encoding
)
def _emitDragOpen(encoding, data):
if encoding.startswith(TTkEncoding.IMAGE):
def _emitDragOpen(encoding: _TTkEncoding, data: _CB_Data_Open) -> None:
if encoding.startswith(_TTkEncoding.IMAGE):
from PIL import Image
import io
im = Image.open(io.BytesIO(data['data']))
data['data'] = im
for do in [ttkDragOpen[e] for e in ttkDragOpen if encoding.startswith(e)]:
do.emit(data)
im = Image.open(io.BytesIO(data.data))
data.data = im
for _drag_open in [ttkDragOpen[e] for e in ttkDragOpen if encoding.startswith(e)]:
_drag_open.emit(data)
def _emitFileOpen(encoding, data):
if encoding.startswith(TTkEncoding.IMAGE):
def _emitFileOpen(encoding: _TTkEncoding, data: _CB_Data_Open) -> None:
if encoding.startswith(_TTkEncoding.IMAGE):
from PIL import Image
import io
# TTkLog.debug(data['data'])
# TTkLog.debug(type(data['data']))
# Image.open(data['data'])
im = Image.open(io.BytesIO(data['data']))
im = Image.open(io.BytesIO(data.data))
# TTkLog.debug(f"{im.size}")
data['data'] = im
data.data = im
ttkFileOpen.emit(data)
ttkFileOpen.clear()
ttkCrossOpen = _open
ttkCrossSave = _save
ttkCrossSaveAs = _save
ttkEmitDragOpen = _emitDragOpen
ttkEmitFileOpen = _emitFileOpen
ttkConnectDragOpen = _connectDragOpen
def _connectDragOpen(encoding: _TTkEncoding, cb: TTkCrossTools.TTkCross_Callback_Open) -> None:
if encoding not in ttkDragOpen:
ttkDragOpen[encoding] = pyTTkSignal(_CB_Data_Open)
return ttkDragOpen[encoding].connect(cb)
else:
def _crossDecoder_text(fileName) :
def _crossDecoder_text(fileName: str) -> str:
with open(fileName) as fp:
return fp.read()
def _crossDecoder_json(fileName) :
def _crossDecoder_json(fileName: str) -> str:
with open(fileName) as fp:
# return json.load(fp)
return fp.read()
def _crossDecoder_image(fileName):
def _crossDecoder_image(fileName: str) -> Any:
from PIL import Image
pilImage = Image.open(fileName)
# pilImage = pilImage.convert('RGBA')
# pilData = list(pilImage.getdata())
# pilData = List(pilImage.getdata())
# data = ImageData()
# w,h = data.size = pilImage.size
# data.data = [pilData[i:i+w] for i in range(0, len(pilData), w)]
return pilImage
_crossDecoder = {
TTkEncoding.TEXT : _crossDecoder_text ,
TTkEncoding.TEXT_PLAIN : _crossDecoder_text ,
TTkEncoding.TEXT_PLAIN_UTF8 : _crossDecoder_text ,
TTkEncoding.APPLICATION : _crossDecoder_json ,
TTkEncoding.APPLICATION_JSON : _crossDecoder_json ,
TTkEncoding.IMAGE : _crossDecoder_image ,
TTkEncoding.IMAGE_PNG : _crossDecoder_image ,
TTkEncoding.IMAGE_SVG : _crossDecoder_image ,
TTkEncoding.IMAGE_JPG : _crossDecoder_image ,
_TTkEncoding.TEXT : _crossDecoder_text ,
_TTkEncoding.TEXT_PLAIN : _crossDecoder_text ,
_TTkEncoding.TEXT_PLAIN_UTF8 : _crossDecoder_text ,
_TTkEncoding.APPLICATION : _crossDecoder_json ,
_TTkEncoding.APPLICATION_JSON : _crossDecoder_json ,
_TTkEncoding.IMAGE : _crossDecoder_image ,
_TTkEncoding.IMAGE_PNG : _crossDecoder_image ,
_TTkEncoding.IMAGE_SVG : _crossDecoder_image ,
_TTkEncoding.IMAGE_JPG : _crossDecoder_image ,
}
def _open(path, encoding:TTkEncoding, filter:str, cb=None):
def _open(path:str, encoding:_TTkEncoding, filter:str, cb: Optional[TTkCrossTools.TTkCross_Callback_Open] = None) -> None:
if not cb: return
if encoding.startswith(TTkEncoding.IMAGE):
if encoding.startswith(_TTkEncoding.IMAGE):
if not importlib.util.find_spec('PIL'): return
def __openFile(fileName):
def __openFile(fileName: str) -> None:
_decoder = _crossDecoder.get(encoding,lambda _:None)
content = _decoder(fileName)
cb({'name':fileName, 'data':content})
cb(TTkCrossTools.CB_Data_Open(name=fileName, data=content))
filePicker = TTkFileDialogPicker(pos = (3,3), size=(100,30), caption="Open", path=path, fileMode=TTkK.FileMode.ExistingFile ,filter=filter)
filePicker.pathPicked.connect(__openFile)
TTkHelper.overlay(None, filePicker, 5, 5, True)
def _save(filePath, content, encoding):
def _save(filePath:str, content:str, encoding:_TTkEncoding) -> None:
TTkLog.info(f"Saving to: {filePath}")
with open(filePath,'w') as fp:
fp.write(content)
def _saveAs(filePath, content, encoding, filter, cb=lambda _d:None):
def _approveFile(fileName):
def _saveAs(filePath:str, content:str, encoding:_TTkEncoding, filter:str, cb: Optional[TTkCrossTools.TTkCross_Callback_Save] = None) -> None:
def _approveFile(fileName: str) -> None:
if os.path.exists(fileName):
@pyTTkSlot(TTkMessageBox.StandardButton)
def _cb(btn):
if btn == TTkMessageBox.StandardButton.Save:
ttkCrossSave(fileName,content,encoding)
_save(fileName,content,encoding)
elif btn == TTkMessageBox.StandardButton.Cancel:
return
if cb:
cb({'name':fileName})
cb(TTkCrossTools.CB_Data_Save(name=fileName))
messageBox = TTkMessageBox(
text= (
TTkString( f'A file named "{os.path.basename(fileName)}" already exists.\nDo you want to replace it?', TTkColor.BOLD) +
@ -173,9 +347,9 @@ else:
messageBox.buttonSelected.connect(_cb)
TTkHelper.overlay(None, messageBox, 5, 5, True)
else:
ttkCrossSave(fileName,content,encoding)
_save(fileName,content,encoding)
if cb:
cb({'name':fileName})
cb(TTkCrossTools.CB_Data_Save(name=fileName))
filePicker = TTkFileDialogPicker(
size=(100,30), path=filePath,
acceptMode=TTkK.AcceptMode.AcceptSave,
@ -185,9 +359,107 @@ else:
filePicker.pathPicked.connect(_approveFile)
TTkHelper.overlay(None, filePicker, 5, 5, True)
ttkCrossOpen = _open
ttkCrossSave = _save
ttkCrossSaveAs = _saveAs
ttkEmitDragOpen = lambda a:None
ttkEmitFileOpen = lambda a:None
ttkConnectDragOpen = lambda a,b:None
def _emitDragOpen(encoding: _TTkEncoding, data: _CB_Data_Open) -> None:
pass
def _emitFileOpen(encoding: _TTkEncoding, data: _CB_Data_Open) -> None:
pass
def _connectDragOpen(encoding: _TTkEncoding, cb: TTkCrossTools.TTkCross_Callback_Open) -> None:
pass
class TTkCrossTools():
''' Cross-platform file operations and clipboard management.
Provides a unified API for file I/O operations across desktop and web platforms.
Automatically adapts to the runtime environment (native Python or Pyodide/WASM)
and provides appropriate file dialogs and file handling mechanisms.
Class Attributes:
Encoding: Alias for :py:class:`_TTkEncoding` enum
CB_Data_Save: Type alias for save callback data
CB_Data_Open: Type alias for open callback data
TTkCross_Callback: Generic callback type
TTkCross_Callback_Open: Callback type for open operations
TTkCross_Callback_Save: Callback type for save operations
Methods:
open: Open a file with automatic dialog and decoding
save: Save content to a file
saveAs: Save with file picker dialog
ttkEmitDragOpen: Emit drag-drop open events (web only)
ttkEmitFileOpen: Emit file open events (web only)
ttkConnectDragOpen: Connect to drag-drop events (web only)
Platform Behavior:
**Desktop Mode**:
- Uses :py:class:`TTkFileDialogPicker` for file selection
- Direct filesystem access via Python's built-in file operations
- Automatic confirmation dialogs for overwrite operations
**Web Mode (Pyodide)**:
- Uses JavaScript file input elements via pyodideProxy
- Downloads trigger browser's save dialog
- Drag-drop integration for file loading
Usage Example:
.. code-block:: python
# Open a text file
def on_open(data: TTkCrossTools.CB_Data_Open):
print(f"File: {data.name}")
print(f"Content: {data.data}")
TTkCrossTools.open(
path="/home/user",
encoding=TTkCrossTools.Encoding.TEXT_PLAIN,
filter="Text Files (*.txt);;All Files (*)",
cb=on_open
)
# Save with confirmation
def on_save(data: TTkCrossTools.CB_Data_Save):
print(f"Saved to: {data.name}")
TTkCrossTools.saveAs(
filePath="document.txt",
content="Hello, World!",
encoding=TTkCrossTools.Encoding.TEXT_PLAIN,
filter="Text Files (*.txt)",
cb=on_save
)
# Open an image
def on_image(data: TTkCrossTools.CB_Data_Open):
pil_image = data.data # PIL.Image.Image object
print(f"Image size: {pil_image.size}")
TTkCrossTools.open(
path=".",
encoding=TTkCrossTools.Encoding.IMAGE_PNG,
filter="PNG Images (*.png)",
cb=on_image
)
Note:
Image operations require PIL/Pillow to be installed. The library will
gracefully handle missing dependencies by skipping image operations.
'''
Encoding = _TTkEncoding
CB_Data_Save: TypeAlias = _CB_Data_Save
CB_Data_Open: TypeAlias = _CB_Data_Open
# Type alias for callback functions that receive file data
TTkCross_Callback: TypeAlias = Callable[[Dict[str, Any]], None]
TTkCross_Callback_Open: TypeAlias = Callable[[CB_Data_Open], None]
TTkCross_Callback_Save: TypeAlias = Callable[[CB_Data_Save], None]
open: _OpenProtocol = _open
save: _SaveProtocol = _save
saveAs: _SaveAsProtocol = _saveAs
ttkEmitDragOpen: _EmitDragOpenProtocol = _emitDragOpen
ttkEmitFileOpen: _EmitFileOpenProtocol = _emitFileOpen
ttkConnectDragOpen: _ConnectDragOpenProtocol = _connectDragOpen

6
libs/pyTermTk/TermTk/TTkWidgets/TTkPickers/messagebox.py

@ -22,6 +22,8 @@
__all__ = ['TTkMessageBox']
from enum import IntEnum, Flag
from TermTk.TTkCore.cfg import TTkCfg
from TermTk.TTkCore.signal import pyTTkSignal,pyTTkSlot
from TermTk.TTkCore.color import TTkColor
@ -37,7 +39,7 @@ from TermTk.TTkWidgets.label import TTkLabel
from TermTk.TTkWidgets.button import TTkButton
class TTkMessageBox(TTkWindow):
class Icon(int):
class Icon(IntEnum):
NoIcon = 0
'''the message box does not have any icon.'''
Question = 4
@ -49,7 +51,7 @@ class TTkMessageBox(TTkWindow):
Critical = 3
'''an icon indicating that the message represents a critical problem.'''
class StandardButton(int):
class StandardButton(Flag):
Ok = 0x00000400
'''An "OK" button defined with the AcceptRole.'''
Open = 0x00002000

16
tools/webExporter/js/ttkproxy.js

@ -228,12 +228,24 @@ class TTkProxy {
def ttk_dragOpen(data):
data = data.to_py()
ttk.ttkEmitDragOpen(data['type'],data)
ttk.TTkCrossTools.ttkEmitDragOpen(
data['type'],
ttk.TTkCrossTools.CB_Data_Open(
name=data['name'],
data=data['data'],
)
)
# ttk_log(f"{type(data.to_py())=}, {str(data.to_py())}")
def ttk_fileOpen(data):
data = data.to_py()
ttk.ttkEmitFileOpen(data['type'],data)
ttk.TTkCrossTools.ttkEmitFileOpen(
data['type'],
ttk.TTkCrossTools.CB_Data_Open(
name=data['name'],
data=data['data'],
)
)
# ttk_log(f"{type(data.to_py())=}, {str(data.to_py())}")
def ttk_input(val):

Loading…
Cancel
Save