Browse Source

Merge pull request #228 from ceccopierangiolieugenio/227-add-undoredo-in-ttkdesigner

Undo/Redo in ttkDesigner
pull/231/head 0.38.0-a
Pier CeccoPierangioliEugenio 2 years ago committed by GitHub
parent
commit
adcdf05f08
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      multiplexers/workbench/.gitignore
  2. 1
      tests/timeit/24.socket.01.client.py
  3. 107
      ttkDesigner/app/designer.py
  4. 10
      ttkDesigner/app/superobj/supercontrol.py

1
multiplexers/workbench/.gitignore vendored

@ -0,0 +1 @@
dontsavethisfile.txt

1
tests/timeit/24.socket.01.client.py

@ -37,7 +37,6 @@ def test1():
sock.sendall(bytes(data + "\n", "utf-8"))
received = str(sock.recv(1024), "utf-8")
return len(received)
https://github.com/ceccopierangiolieugenio/pyTermTk/issues/210
a = {}

107
ttkDesigner/app/designer.py

@ -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)

10
ttkDesigner/app/superobj/supercontrol.py

@ -88,14 +88,16 @@ class SuperControlWidget(ttk.TTkResizableFrame):
return True
bkPos = self.pos()
x,y = 0,0
if evt.key == ttk.TTkK.Key_Up: y=-1
elif evt.key == ttk.TTkK.Key_Down: y=1
if evt.key == ttk.TTkK.Key_Up: y=-1
elif evt.key == ttk.TTkK.Key_Down: y= 1
elif evt.key == ttk.TTkK.Key_Left: x=-1
elif evt.key == ttk.TTkK.Key_Right: x=1
elif evt.key == ttk.TTkK.Key_Right: x= 1
else: return super().keyEvent(evt)
if any((x,y)):
self.move(bkPos[0]+x, bkPos[1]+y)
self._alignWidToPos(bkPos)
return True
return True
return super().keyEvent(evt)
def paintEvent(self, canvas):
w,h = self.size()

Loading…
Cancel
Save