Browse Source

Added DelLayer support in the snapshot

pull/260/head
Eugenio Parodi 2 years ago
parent
commit
5f17bb6eb3
  1. 55
      tools/dumbPaintTool/app/canvaslayer.py
  2. 30
      tools/dumbPaintTool/app/glbls.py
  3. 26
      tools/dumbPaintTool/app/paintarea.py
  4. 3
      tools/dumbPaintTool/app/state/layers.py
  5. 4
      tools/ttkDesigner/app/signalsloteditor.py

55
tools/dumbPaintTool/app/canvaslayer.py

@ -42,14 +42,16 @@ from .const import ToolType
# \---w--/
class CanvasLayer():
__slot__ = ('_pos','_name','_visible','_size','_data','_colors','_preview','_offset','_modified'
__slot__ = ('_pos','_name','_visible','_size','_data','_colors','_preview','_offset',
'_snapVersion', '_snapshots',
#signals
'nameChanged','changed')
def __init__(self,name:ttk.TTkString=ttk.TTkString('New')) -> None:
self._modified = False
self.changed = ttk.pyTTkSignal()
self._name:ttk.TTkString = ttk.TTkString(name) if isinstance(name,str) else name
self.nameChanged = ttk.pyTTkSignal(ttk.TTkString)
self._snapVersion = 0
self._snapshots = {}
self._pos = (0,0)
self._size = (0,0)
self._offset = (0,0)
@ -58,9 +60,9 @@ class CanvasLayer():
self._data: list[list[str ]] = []
self._colors:list[list[ttk.TTkColor]] = []
def clone(self) -> None:
def clone(self) -> object:
cl = CanvasLayer()
cl._modified = False
cl._snapVersion = self._snapVersion
cl._pos = self._pos
cl._size = self._size
cl._offset = self._offset
@ -69,8 +71,9 @@ class CanvasLayer():
cl._colors = [row.copy() for row in self._colors]
return cl
def restore(self, cl) -> None:
self._modified = False
def restore(self, cl: object) -> None:
self._preview = None
self._snapVersion = cl._snapVersion
self._pos = cl._pos
self._size = cl._size
self._offset = cl._offset
@ -79,6 +82,24 @@ class CanvasLayer():
self._colors = [row.copy() for row in cl._colors]
self.changed.emit()
def restoreSnapshot(self, id:int) -> None:
if id == self._snapVersion:
return
ttk.TTkLog.debug(f"restore {id=}")
if id in self._snapshots:
self.restore(self._snapshots[id])
def saveSnapshot(self) -> int:
self._snapshots = {key:self._snapshots[key] for key in self._snapshots if key <= self._snapVersion}
if self._snapVersion not in self._snapshots:
ttk.TTkLog.debug(f"{self._snapVersion=}")
self._snapshots[self._snapVersion] = self.clone()
return self._snapVersion
def clearSnapshot(self) -> None:
self._snapshots = {}
self.saveSnapshot()
def __eq__(self, value: object) -> bool:
return (
issubclass(type(value),CanvasLayer) and
@ -102,7 +123,7 @@ class CanvasLayer():
@ttk.pyTTkSlot(bool)
def setVisible(self, visible):
if visible == self._visible: return
self._modified = True
self._snapVersion += 1
self._visible = visible
self.changed.emit()
@ -110,7 +131,7 @@ class CanvasLayer():
return self._name
@ttk.pyTTkSlot(str)
def setName(self, name):
self._modified = True
self._snapVersion += 1
self._name = name
def isOpaque(self,x,y):
@ -125,7 +146,7 @@ class CanvasLayer():
def move(self,x,y):
self._pos=(x,y)
self._modified = True
self._snapVersion += 1
self.changed.emit()
def resize(self,w,h):
@ -135,7 +156,7 @@ class CanvasLayer():
for i in range(h):
self._data[i] = (self._data[i] + [' ' for _ in range(w)])[:w]
self._colors[i] = (self._colors[i] + [ttk.TTkColor.RST for _ in range(w)])[:w]
self._modified = True
self._snapVersion += 1
self.changed.emit()
def superResize(self,dx,dy,dw,dh):
@ -169,7 +190,7 @@ class CanvasLayer():
self._offset = (ox+diffx,oy+diffy)
self._pos = (dx,dy)
self._size = (dw,dh)
self._modified = True
self._snapVersion += 1
self.changed.emit()
def clean(self):
@ -179,7 +200,7 @@ class CanvasLayer():
for i in range(h):
self._data[i] = [' ']*w
self._colors[i] = [ttk.TTkColor.RST]*w
self._modified = True
self._snapVersion += 1
self.changed.emit()
def toTTkString(self):
@ -324,7 +345,7 @@ class CanvasLayer():
self._import_v1_1_0(dd)
else:
self._import_v0_0_0(dd)
self._modified = True
self._snapVersion += 1
self.changed.emit()
def trim(self):
@ -384,7 +405,7 @@ class CanvasLayer():
self._size = (w,h)
self._name = ttk.TTkString("Pasted")
self._modified = True
self._snapVersion += 1
def placeFill(self,geometry,tool,glyph:str,color:ttk.TTkColor,glyphEnabled=True,preview=False):
ox,oy = self._offset
@ -402,6 +423,7 @@ class CanvasLayer():
colors = [_r.copy() for _r in self._colors]
self._preview = {'data':data,'colors':colors}
else:
self._snapVersion += 1
self._preview = None
data = self._data
colors = self._colors
@ -417,7 +439,6 @@ class CanvasLayer():
for y in range(fay,fby+1):
self._placeGlyph(data,colors,fax,y,glyph,color,glyphEnabled,preview)
self._placeGlyph(data,colors,fbx,y,glyph,color,glyphEnabled,preview)
self._modified = True
self.changed.emit()
return True
@ -427,11 +448,11 @@ class CanvasLayer():
colors = [_r.copy() for _r in self._colors]
self._preview = {'data':data,'colors':colors}
else:
self._snapVersion += 1
self._preview = None
data = self._data
colors = self._colors
self._modified = True
self.changed.emit()
return self._placeGlyph(data,colors,x,y,glyph,color,glyphEnabled,preview)
@ -478,6 +499,7 @@ class CanvasLayer():
colors = [_r.copy() for _r in self._colors]
self._preview = {'data':data,'colors':colors}
else:
self._snapVersion += 1
self._preview = None
data = self._data
colors = self._colors
@ -495,7 +517,6 @@ class CanvasLayer():
newC._bg = ca._bg if ca._bg else cc._bg
colors[_y][_x] = newC
self._modified = True
self.changed.emit()
def drawInCanvas(self, pos, canvas:ttk.TTkCanvas):

30
tools/dumbPaintTool/app/glbls.py

@ -33,31 +33,19 @@ from .state.layers import Layers
class Snapshot():
__slots__ = ('_layer','_canvasLayers')
def __init__(self) -> None:
self._layer = None
self._canvasLayers = []
if glbls.layers._modified:
self._layer = glbls.layers.clone()
glbls.layers._modified = False
for cl in glbls.layers.layers():
if cl._modified:
cl._modified = False
self._canvasLayers.append((cl,cl.clone()))
def valid(self) -> None:
if self._layer or self._canvasLayers:
return True
return False
self._layer = glbls.layers.clone()
self._canvasLayers = [cl.saveSnapshot() for cl in glbls.layers.layers()]
def restore(self) -> None:
if self._layer:
glbls.layers.restore(self._layer)
for cl,clone in self._canvasLayers:
cl.restore(clone)
for cl,snapId in zip(glbls.layers.layers(),self._canvasLayers):
cl.restoreSnapshot(snapId)
def __eq__(self, value: object) -> bool:
return (
self._layer == value._layer and
all(a==b for a,b in self._canvasLayers))
self._canvasLayers == value._canvasLayers )
@dataclass()
class Glbls:
@ -75,13 +63,17 @@ class Glbls:
def saveSnapshot(self):
# TODO: Dispose properly of the unused clones
snapshot = Snapshot()
if not snapshot.valid():
return
# if not snapshot.valid():
# return
if 0 <= self._snapId < len(self._snaphots):
if self._snaphots[self._snapId] == snapshot:
return
self._snaphots = self._snaphots[:self._snapId+1] + [snapshot]
self._snapId = len(self._snaphots)-1
@ttk.pyTTkSlot()
def undo(self):
# ttk.TTkLog.debug(f"{self._snapId=} - {len(self._snaphots)=}")
if self._snapId:
self._snapId -= 1
self._snaphots[self._snapId].restore()

26
tools/dumbPaintTool/app/paintarea.py

@ -370,6 +370,9 @@ class PaintArea(ttk.TTkAbstractScrollView):
text = glbls.layers.selected().toTTkString()
self.copy(text)
ret = True
elif cl and evt.key == ttk.TTkK.Key_Delete:
glbls.layers.delLayer()
glbls.saveSnapshot()
else:
return super().keyEvent(evt)
self._retuneGeometry()
@ -389,6 +392,7 @@ class PaintArea(ttk.TTkAbstractScrollView):
def pasteEvent(self, txt:str):
glbls.layers.addLayer().importTTkString(ttk.TTkString(txt))
glbls.saveSnapshot()
self.update()
return True
@ -462,29 +466,29 @@ class PaintArea(ttk.TTkAbstractScrollView):
if self._tool & ToolType.RESIZE:
rd = self._resizeData
def _drawResizeBorders(_rx,_ry,_rw,_rh,_sel):
def _drawResizeBorders(_rx,_ry,_rw,_rh,_sel,_color=ttk.TTkColor.RST):
selColor = ttk.TTkColor.YELLOW + ttk.TTkColor.BG_BLUE
# canvas.drawBox(pos=_pos,size=_size)
canvas.drawText(pos=(_rx ,_ry ),text=''*_rw, color=selColor if _sel & ttk.TTkK.TOP else ttk.TTkColor.RST)
canvas.drawText(pos=(_rx ,_ry+_rh-1),text=''*_rw, color=selColor if _sel & ttk.TTkK.BOTTOM else ttk.TTkColor.RST)
canvas.drawText(pos=(_rx ,_ry ),text=''*_rw, color=selColor if _sel & ttk.TTkK.TOP else _color)
canvas.drawText(pos=(_rx ,_ry+_rh-1),text=''*_rw, color=selColor if _sel & ttk.TTkK.BOTTOM else _color)
for _y in range(_ry,_ry+_rh):
canvas.drawText(pos=(_rx ,_y),text='',color=selColor if _sel & ttk.TTkK.LEFT else ttk.TTkColor.RST)
canvas.drawText(pos=(_rx+_rw-1,_y),text='',color=selColor if _sel & ttk.TTkK.RIGHT else ttk.TTkColor.RST)
canvas.drawChar(pos=(_rx ,_ry ), char='')
canvas.drawChar(pos=(_rx+_rw-1,_ry ), char='')
canvas.drawChar(pos=(_rx ,_ry+_rh-1), char='')
canvas.drawChar(pos=(_rx+_rw-1,_ry+_rh-1), char='')
canvas.drawText(pos=(_rx ,_y),text='',color=selColor if _sel & ttk.TTkK.LEFT else _color)
canvas.drawText(pos=(_rx+_rw-1,_y),text='',color=selColor if _sel & ttk.TTkK.RIGHT else _color)
canvas.drawChar(pos=(_rx ,_ry ), char='', color=_color)
canvas.drawChar(pos=(_rx+_rw-1,_ry ), char='', color=_color)
canvas.drawChar(pos=(_rx ,_ry+_rh-1), char='', color=_color)
canvas.drawChar(pos=(_rx+_rw-1,_ry+_rh-1), char='', color=_color)
sMain = rd['selected'] if rd and rd['type'] == PaintArea else ttk.TTkK.NONE
sLayer = rd['selected'] if rd and rd['type'] == CanvasLayer else ttk.TTkK.NONE
_drawResizeBorders(dx-ox-1, dy-oy-1, dw+2, dh+2, sMain)
if cl:=glbls.layers.selected():
lx,ly = cl.pos()
lw,lh = cl.size()
_drawResizeBorders(lx+dx-ox-1, ly+dy-oy-1, lw+2, lh+2, sLayer)
_drawResizeBorders(dx-ox-1, dy-oy-1, dw+2, dh+2, sMain, _color=ttk.TTkColor.YELLOW)
class PaintScrollArea(ttk.TTkAbstractScrollArea):
def __init__(self, pwidget:PaintArea, **kwargs):

3
tools/dumbPaintTool/app/state/layers.py

@ -54,6 +54,7 @@ class Layers():
self._layers = la._layers.copy()
self.layersOrderChanged.emit(self._layers)
self.layerSelected.emit(self._selected)
self.changed.emit()
def __eq__(self, value: object) -> bool:
return self._layers == value._layers
@ -99,8 +100,8 @@ class Layers():
la = self._layers
dl = la.pop(la.index(self._selected))
self._selected = la[0] if la else None
self.layerDeleted.emit(dl)
self._modified = True
self.layerDeleted.emit(dl)
self.layersOrderChanged.emit(self._layers)
return dl

4
tools/ttkDesigner/app/signalsloteditor.py

@ -119,7 +119,7 @@ class _SignalSlotItem(ttk.TTkTreeWidgetItem):
curSlot = str(self._slot.currentText())
filter = None
for c in self._slotData:
if not str(curSlot) in self._slotData[c]: continue
if str(curSlot) not in self._slotData[c]: continue
filter = self._slotData[c][curSlot]['type']
break
@ -151,7 +151,7 @@ class _SignalSlotItem(ttk.TTkTreeWidgetItem):
curSlot = self._slot.currentText()
filter = 'ALL'
for c in self._signalData:
if not str(curSignal) in self._signalData[c]: continue
if str(curSignal) not in self._signalData[c]: continue
filter = self._signalData[c][curSignal]['type']
break

Loading…
Cancel
Save