|
|
|
|
@ -23,25 +23,22 @@
|
|
|
|
|
import os |
|
|
|
|
import json |
|
|
|
|
|
|
|
|
|
from TermTk import TTk, TTkK, TTkLog, TTkCfg, TTkColor, TTkTheme, TTkTerm, TTkHelper |
|
|
|
|
from TermTk import TTkK, TTkLog, TTkColor, TTkHelper, TTkShortcut |
|
|
|
|
from TermTk import TTkString |
|
|
|
|
from TermTk import TTkColorGradient |
|
|
|
|
from TermTk import pyTTkSlot, pyTTkSignal |
|
|
|
|
|
|
|
|
|
from TermTk import TTkWidget, TTkFrame, TTkButton, TTkLabel, TTkMenuButton |
|
|
|
|
from TermTk import TTkTabWidget |
|
|
|
|
from TermTk import TTkAbstractScrollArea, TTkAbstractScrollView, TTkScrollArea |
|
|
|
|
from TermTk import TTkFileDialogPicker, TTkMessageBox |
|
|
|
|
from TermTk import TTkFileTree, TTkTextEdit |
|
|
|
|
|
|
|
|
|
from TermTk import TTkLayout, TTkGridLayout, TTkVBoxLayout, TTkHBoxLayout |
|
|
|
|
from TermTk import TTkGridLayout, TTkVBoxLayout, TTkHBoxLayout |
|
|
|
|
from TermTk import TTkSplitter |
|
|
|
|
from TermTk import TTkLogViewer |
|
|
|
|
from TermTk import TTkUiLoader, TTkUtil |
|
|
|
|
|
|
|
|
|
from .cfg import * |
|
|
|
|
from .about import * |
|
|
|
|
from .widgetbox import DragDesignItem, WidgetBox, WidgetBoxScrollArea |
|
|
|
|
from .widgetbox import WidgetBoxScrollArea |
|
|
|
|
from .windoweditor import WindowEditor |
|
|
|
|
from .treeinspector import TreeInspector |
|
|
|
|
from .propertyeditor import PropertyEditor |
|
|
|
|
@ -51,6 +48,8 @@ from .notepad import NotePad
|
|
|
|
|
|
|
|
|
|
from .superobj import SuperWidget, SuperWidgetFrame |
|
|
|
|
|
|
|
|
|
import pickle |
|
|
|
|
|
|
|
|
|
# |
|
|
|
|
# Mimic the QT Designer layout |
|
|
|
|
# |
|
|
|
|
@ -78,11 +77,16 @@ from .superobj import SuperWidget, SuperWidgetFrame
|
|
|
|
|
# |
|
|
|
|
|
|
|
|
|
class TTkDesigner(TTkGridLayout): |
|
|
|
|
__slots__ = ('_pippo', '_main', '_windowEditor', '_toolBar', '_fileNameLabel', '_sigslotEditor', '_treeInspector', '_fileName', '_currentPath', '_notepad', |
|
|
|
|
__slots__ = ('_main', '_toolBar', '_fileNameLabel', |
|
|
|
|
'_sigslotEditor', '_treeInspector', '_windowEditor', '_notepad', |
|
|
|
|
'_fileName', '_currentPath', |
|
|
|
|
'_snapshot', '_snapId', |
|
|
|
|
# Signals |
|
|
|
|
'weModified', 'thingSelected', 'widgetNameChanged' |
|
|
|
|
) |
|
|
|
|
def __init__(self, fileName=None, *args, **kwargs): |
|
|
|
|
self._snapshot = [] |
|
|
|
|
self._snapId = -1 |
|
|
|
|
self._fileName = "untitled.tui.json" |
|
|
|
|
self._currentPath = self._currentPath = os.path.abspath('.') |
|
|
|
|
|
|
|
|
|
@ -131,22 +135,26 @@ class TTkDesigner(TTkGridLayout):
|
|
|
|
|
self.thingSelected.connect(propertyEditor.setDetail) |
|
|
|
|
|
|
|
|
|
self.weModified.connect(self._treeInspector.refresh) |
|
|
|
|
self.weModified.connect(self._takeSnapshot) |
|
|
|
|
|
|
|
|
|
fileMenu = topMenuFrame.newMenubarTop().addMenu("&File") |
|
|
|
|
fileMenu.addMenu("New").menuButtonClicked.connect(self.new) |
|
|
|
|
fileMenu.addMenu("Open").menuButtonClicked.connect(self.open) |
|
|
|
|
fileMenu.addMenu("Save").menuButtonClicked.connect(self.save) |
|
|
|
|
fileMenu.addMenu("Save As...").menuButtonClicked.connect(self.saveAs) |
|
|
|
|
fileMenu.addMenu("&New").menuButtonClicked.connect(self.new) |
|
|
|
|
fileMenu.addMenu("&Open").menuButtonClicked.connect(self.open) |
|
|
|
|
fileMenu.addMenu("&Save").menuButtonClicked.connect(self.save) |
|
|
|
|
fileMenu.addMenu("Save &As...").menuButtonClicked.connect(self.saveAs) |
|
|
|
|
fileMenu.addSpacer() |
|
|
|
|
fileMenu.addMenu("Import 🎁").menuButtonClicked.connect(self.importDictWin) |
|
|
|
|
fileMenu.addMenu("Export 📦").menuButtonClicked.connect(self.quickExport) |
|
|
|
|
fileMenu.addMenu("&Import 🎁").menuButtonClicked.connect(self.importDictWin) |
|
|
|
|
fileMenu.addMenu("&Export 📦").menuButtonClicked.connect(self.quickExport) |
|
|
|
|
fileMenu.addSpacer() |
|
|
|
|
fileMenu.addMenu("Exit").menuButtonClicked.connect(TTkHelper.quit) |
|
|
|
|
fileMenu.addMenu("E&xit").menuButtonClicked.connect(TTkHelper.quit) |
|
|
|
|
|
|
|
|
|
extraMenu = topMenuFrame.newMenubarTop().addMenu("E&xtra") |
|
|
|
|
extraMenu.addMenu("Scratchpad").menuButtonClicked.connect(self.scratchpad) |
|
|
|
|
extraMenu = topMenuFrame.newMenubarTop().addMenu("E&dit") |
|
|
|
|
extraMenu.addMenu("&Undo (CTRL+Z)").menuButtonClicked.connect(self.undo) |
|
|
|
|
extraMenu.addMenu("&Redo (CTRL+Y)").menuButtonClicked.connect(self.redo) |
|
|
|
|
extraMenu.addSpacer() |
|
|
|
|
extraMenu.addMenu("&Scratchpad 📝").menuButtonClicked.connect(self.scratchpad) |
|
|
|
|
extraMenu.addSpacer() |
|
|
|
|
extraMenu.addMenu("Preview...").menuButtonClicked.connect(self.preview) |
|
|
|
|
extraMenu.addMenu("&Preview...").menuButtonClicked.connect(self.preview) |
|
|
|
|
|
|
|
|
|
def _showAbout(btn): |
|
|
|
|
TTkHelper.overlay(None, About(), 30,10) |
|
|
|
|
@ -176,9 +184,72 @@ class TTkDesigner(TTkGridLayout):
|
|
|
|
|
|
|
|
|
|
self._toolBar.addWidget(self._fileNameLabel) |
|
|
|
|
|
|
|
|
|
TTkShortcut(TTkK.CTRL | TTkK.Key_Z).activated.connect(self.undo) |
|
|
|
|
TTkShortcut(TTkK.CTRL | TTkK.Key_Y).activated.connect(self.redo) |
|
|
|
|
self._takeSnapshot() |
|
|
|
|
|
|
|
|
|
if fileName: |
|
|
|
|
self._openFile(fileName) |
|
|
|
|
|
|
|
|
|
# Snapshot Logic: |
|
|
|
|
# _snapshots = [ s0 , s1 , s2 , s3 , s4 , s5 , s6 ] |
|
|
|
|
# _snapId = 3 ^ |
|
|
|
|
# |
|
|
|
|
# Undo: |
|
|
|
|
# _snapId-- = 2 ^ = s2 |
|
|
|
|
# load s2 |
|
|
|
|
# |
|
|
|
|
# Redo: |
|
|
|
|
# _snapId++ = 4 ^ = s4 |
|
|
|
|
# load s4 |
|
|
|
|
# |
|
|
|
|
# Take Snapshot: |
|
|
|
|
# Remove the forward Snapshots: |
|
|
|
|
# _snapshots = [ s0 , s1 , s2 , s3 ] |
|
|
|
|
# Append The new one and update snapId |
|
|
|
|
# _snapshots = [ s0 , s1 , s2 , s3 , s4+ ] |
|
|
|
|
# _snapId++ = 4 |
|
|
|
|
|
|
|
|
|
@pyTTkSlot() |
|
|
|
|
def _takeSnapshot(self): |
|
|
|
|
tui = self._windowEditor.dumpDict() |
|
|
|
|
connections = self._sigslotEditor.dumpDict() |
|
|
|
|
data = { |
|
|
|
|
'version':'2.0.0', |
|
|
|
|
'tui':tui, |
|
|
|
|
'connections':connections} |
|
|
|
|
TTkLog.debug(f"{len(pickle.dumps(data))=} {len(self._snapshot)=}") |
|
|
|
|
if ( self._snapshot and |
|
|
|
|
0 <= self._snapId < len(self._snapshot) and |
|
|
|
|
data == self._snapshot[self._snapId]): return |
|
|
|
|
self._snapshot = self._snapshot[:self._snapId+1]+[data] |
|
|
|
|
self._snapId = len(self._snapshot)-1 |
|
|
|
|
|
|
|
|
|
def _loadSnapshot(self): |
|
|
|
|
self.weModified.disconnect(self._takeSnapshot) |
|
|
|
|
data = self._snapshot[self._snapId] |
|
|
|
|
sw = SuperWidget.loadDict(self, self._windowEditor.viewport(), data['tui']) |
|
|
|
|
self._windowEditor.importSuperWidget(sw) |
|
|
|
|
self._sigslotEditor.importConnections(data['connections']) |
|
|
|
|
self._treeInspector.refresh() |
|
|
|
|
self.weModified.connect(self._takeSnapshot) |
|
|
|
|
|
|
|
|
|
@pyTTkSlot() |
|
|
|
|
def undo(self): |
|
|
|
|
TTkLog.debug(f"Undo: {len(self._snapshot)=}") |
|
|
|
|
if not self._snapshot: return |
|
|
|
|
if self._snapId <= 0: return |
|
|
|
|
self._snapId -= 1 |
|
|
|
|
self._loadSnapshot() |
|
|
|
|
|
|
|
|
|
@pyTTkSlot() |
|
|
|
|
def redo(self): |
|
|
|
|
TTkLog.debug(f"Undo: {len(self._snapshot)=}") |
|
|
|
|
if not self._snapshot: return |
|
|
|
|
if self._snapId >= len(self._snapshot)-1: return |
|
|
|
|
self._snapId += 1 |
|
|
|
|
self._loadSnapshot() |
|
|
|
|
|
|
|
|
|
def getWidgets(self): |
|
|
|
|
widgets = set() |
|
|
|
|
def _getMenu(menu): |
|
|
|
|
@ -237,7 +308,7 @@ class TTkDesigner(TTkGridLayout):
|
|
|
|
|
@pyTTkSlot() |
|
|
|
|
def scratchpad(self): |
|
|
|
|
win = TTkWindow( |
|
|
|
|
title="Mr Scratchpad", |
|
|
|
|
title="Mr Scratchpad 📝", |
|
|
|
|
size=(80,30), |
|
|
|
|
layout=self._notepad, |
|
|
|
|
flags=TTkK.WindowFlag.WindowMaximizeButtonHint|TTkK.WindowFlag.WindowCloseButtonHint) |
|
|
|
|
|