{libcanvas/Canvas,libgui/GuiCanvas{Interface,Panel}}.py: implement dirty flag.

libgui/GuiCanvasInterface.py:canvas{Exit,New,Open,Save,Import{Ansi,FromClipboard,Sauce}}(): prompt to save canvas if dirty.
libgui/GuiCanvasInterface.py: minor cleanup.
libcanvas/Canvas.py:resize(): don't push undo patches when extending canvas.
This commit is contained in:
Lucio Andrés Illanes Albornoz 2019-09-08 18:00:11 +02:00
parent 34dddd3e2b
commit 318b4436f3
3 changed files with 100 additions and 116 deletions

View File

@ -23,15 +23,15 @@ class Canvas():
self.journal.pushCursor(patchDelta) self.journal.pushCursor(patchDelta)
else: else:
if commitUndo: if commitUndo:
if not self.dirty: if not self.dirtyJournal:
self.journal.pushDeltas([], []); self.dirty = True; self.journal.pushDeltas([], []); self.dirtyJournal = True;
self.journal.updateCurrentDeltas(patch, patchDelta) self.journal.updateCurrentDeltas(patch, patchDelta)
self._commitPatch(patch) self._commitPatch(patch)
# }}} # }}}
# {{{ resize(self, newSize, commitUndo=True): XXX # {{{ resize(self, newSize, commitUndo=True): XXX
def resize(self, newSize, commitUndo=True): def resize(self, newSize, commitUndo=True):
if newSize != self.size: if newSize != self.size:
self.dirty = False self.dirtyJournal = False
if self.map == None: if self.map == None:
self.map, oldSize = [], [0, 0] self.map, oldSize = [], [0, 0]
else: else:
@ -40,35 +40,43 @@ class Canvas():
self.journal.resetCursor() self.journal.resetCursor()
if commitUndo: if commitUndo:
undoPatches, redoPatches = ["resize", *oldSize], ["resize", *newSize] undoPatches, redoPatches = ["resize", *oldSize], ["resize", *newSize]
if not self.dirty: if not self.dirtyJournal:
self.journal.pushDeltas([], []); self.dirty = True; self.journal.pushDeltas([], []); self.dirtyJournal = True;
self.journal.updateCurrentDeltas(redoPatches, undoPatches) self.journal.updateCurrentDeltas(redoPatches, undoPatches)
if deltaSize[0] < 0: if deltaSize[0] < 0:
for numRow in range(oldSize[1]): for numRow in range(oldSize[1]):
if commitUndo: if commitUndo:
for numCol in range((oldSize[0] + deltaSize[0]), oldSize[0]): for numCol in range((oldSize[0] + deltaSize[0]), oldSize[0]):
if not self.dirty: if not self.dirtyJournal:
self.journal.pushDeltas([], []); self.dirty = True; self.journal.pushDeltas([], []); self.dirtyJournal = True;
self.journal.updateCurrentDeltas(None, [numCol, numRow, *self.map[numRow][numCol]]) self.journal.updateCurrentDeltas(None, [numCol, numRow, *self.map[numRow][numCol]])
del self.map[numRow][-1:(deltaSize[0]-1):-1] del self.map[numRow][-1:(deltaSize[0]-1):-1]
else: else:
for numRow in range(oldSize[1]): for numRow in range(oldSize[1]):
self.map[numRow].extend([[1, 1, 0, " "]] * deltaSize[0]) self.map[numRow].extend([[1, 1, 0, " "]] * deltaSize[0])
for numNewCol in range(oldSize[0], newSize[0]): for numNewCol in range(oldSize[0], newSize[0]):
self.dispatchPatch(False, [numNewCol, numRow, 1, 1, 0, " "], commitUndo) if commitUndo:
if not self.dirtyJournal:
self.journal.pushDeltas([], []); self.dirtyJournal = True;
self.journal.updateCurrentDeltas([numNewCol, numRow, 1, 1, 0, " "], None)
self.dispatchPatch(False, [numNewCol, numRow, 1, 1, 0, " "], False)
if deltaSize[1] < 0: if deltaSize[1] < 0:
if commitUndo: if commitUndo:
for numRow in range((oldSize[1] + deltaSize[1]), oldSize[1]): for numRow in range((oldSize[1] + deltaSize[1]), oldSize[1]):
for numCol in range(oldSize[0] + deltaSize[0]): for numCol in range(oldSize[0] + deltaSize[0]):
if not self.dirty: if not self.dirtyJournal:
self.journal.pushDeltas([], []); self.dirty = True; self.journal.pushDeltas([], []); self.dirtyJournal = True;
self.journal.updateCurrentDeltas(None, [numCol, numRow, *self.map[numRow][numCol]]) self.journal.updateCurrentDeltas(None, [numCol, numRow, *self.map[numRow][numCol]])
del self.map[-1:(deltaSize[1]-1):-1] del self.map[-1:(deltaSize[1]-1):-1]
else: else:
for numNewRow in range(oldSize[1], newSize[1]): for numNewRow in range(oldSize[1], newSize[1]):
self.map.extend([[[1, 1, 0, " "]] * newSize[0]]) self.map.extend([[[1, 1, 0, " "]] * newSize[0]])
for numNewCol in range(newSize[0]): for numNewCol in range(newSize[0]):
self.dispatchPatch(False, [numNewCol, numNewRow, 1, 1, 0, " "], commitUndo) if commitUndo:
if not self.dirtyJournal:
self.journal.pushDeltas([], []); self.dirtyJournal = True;
self.journal.updateCurrentDeltas([numNewCol, numNewRow, 1, 1, 0, " "], None)
self.dispatchPatch(False, [numNewCol, numNewRow, 1, 1, 0, " "], False)
self.size = newSize self.size = newSize
return True return True
else: else:
@ -87,7 +95,7 @@ class Canvas():
# #
# __init__(self, size): initialisation method # __init__(self, size): initialisation method
def __init__(self, size): def __init__(self, size):
self.dirty, self.dirtyCursor, self.map, self.size = False, False, None, size self.dirtyJournal, self.dirtyCursor, self.map, self.size = False, False, None, size
self.exportStore, self.importStore, self.journal = CanvasExportStore(), CanvasImportStore(), CanvasJournal() self.exportStore, self.importStore, self.journal = CanvasExportStore(), CanvasImportStore(), CanvasJournal()
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 # vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -52,14 +52,6 @@ def GuiCanvasSelectDecorator(idx, caption, label, icon, accel, initialState):
class GuiCanvasInterface(): class GuiCanvasInterface():
"""XXX""" """XXX"""
# {{{ _dialogSaveChanges(self): XXX
def _dialogSaveChanges(self):
with wx.MessageDialog(self.parentCanvas, \
"Do you want to save changes to {}?".format(self.canvasPathName), \
"", wx.CANCEL|wx.CANCEL_DEFAULT|wx.ICON_QUESTION|wx.YES_NO) as dialog:
dialogChoice = dialog.ShowModal()
return dialogChoice
# }}}
# {{{ _initColourBitmaps(self): XXX # {{{ _initColourBitmaps(self): XXX
def _initColourBitmaps(self): def _initColourBitmaps(self):
for numColour in range(len(self.canvasColour.attrList)): for numColour in range(len(self.canvasColour.attrList)):
@ -84,6 +76,24 @@ class GuiCanvasInterface():
toolBitmapDc.DrawRectangle(8, 8, 16, 16) toolBitmapDc.DrawRectangle(8, 8, 16, 16)
self.canvasColourAlpha.attrList[0]["icon"] = ["", None, toolBitmap] self.canvasColourAlpha.attrList[0]["icon"] = ["", None, toolBitmap]
# }}} # }}}
# {{{ _promptSaveChanges(self): XXX
def _promptSaveChanges(self):
if self.parentCanvas.dirty:
with wx.MessageDialog(self.parentCanvas, \
"Do you want to save changes to {}?".format(self.canvasPathName if self.canvasPathName != None else "(Untitled)"), \
"", wx.CANCEL|wx.CANCEL_DEFAULT|wx.ICON_QUESTION|wx.YES_NO) as dialog:
dialogChoice = dialog.ShowModal()
if dialogChoice == wx.ID_CANCEL:
return False
elif dialogChoice == wx.ID_NO:
return True
elif dialogChoice == wx.ID_YES:
return self.canvasSaveAs(None) if self.canvasPathName == None else self.canvasSave(None)
else:
return False
else:
return True
# }}}
# {{{ canvasAbout(self, event): XXX # {{{ canvasAbout(self, event): XXX
@GuiCanvasCommandDecorator("About", "&About", None, None, True) @GuiCanvasCommandDecorator("About", "&About", None, None, True)
@ -158,62 +168,43 @@ class GuiCanvasInterface():
# {{{ canvasExit(self, event): XXX # {{{ canvasExit(self, event): XXX
@GuiCanvasCommandDecorator("Exit", "E&xit", None, [wx.ACCEL_CTRL, ord("X")], None) @GuiCanvasCommandDecorator("Exit", "E&xit", None, [wx.ACCEL_CTRL, ord("X")], None)
def canvasExit(self, event): def canvasExit(self, event):
if self.canvasPathName != None: if self._promptSaveChanges():
saveChanges = self._dialogSaveChanges() self.parentFrame.Close(True)
if saveChanges == wx.ID_CANCEL:
return
elif saveChanges == wx.ID_NO:
pass
elif saveChanges == wx.ID_YES:
self.canvasSave(event)
self.parentFrame.Close(True)
# }}} # }}}
# {{{ canvasNew(self, event, newCanvasSize=None): XXX # {{{ canvasNew(self, event, newCanvasSize=None): XXX
@GuiCanvasCommandDecorator("New", "&New", ["", wx.ART_NEW], [wx.ACCEL_CTRL, ord("N")], None) @GuiCanvasCommandDecorator("New", "&New", ["", wx.ART_NEW], [wx.ACCEL_CTRL, ord("N")], None)
def canvasNew(self, event, newCanvasSize=None): def canvasNew(self, event, newCanvasSize=None):
if self.canvasPathName != None: if self._promptSaveChanges():
saveChanges = self._dialogSaveChanges() self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
if saveChanges == wx.ID_CANCEL: if newCanvasSize == None:
return newCanvasSize = list(self.parentCanvas.defaultCanvasSize)
elif saveChanges == wx.ID_NO: newMap = [[[1, 1, 0, " "] for x in range(newCanvasSize[0])] for y in range(newCanvasSize[1])]
pass self.parentCanvas.dirty = False
elif saveChanges == wx.ID_YES: self.parentCanvas.update(newCanvasSize, False, newMap)
self.canvasSave(event) self.canvasPathName = None
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
if newCanvasSize == None: self.update(dirty=self.parentCanvas.dirty, pathName=self.canvasPathName, undoLevel=-1)
newCanvasSize = list(self.parentCanvas.defaultCanvasSize)
newMap = [[[1, 1, 0, " "] for x in range(newCanvasSize[0])] for y in range(newCanvasSize[1])]
self.parentCanvas.update(newCanvasSize, False, newMap)
self.canvasPathName = None
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.update(pathName="", undoLevel=-1)
# }}} # }}}
# {{{ canvasOpen(self, event): XXX # {{{ canvasOpen(self, event): XXX
@GuiCanvasCommandDecorator("Open", "&Open", ["", wx.ART_FILE_OPEN], [wx.ACCEL_CTRL, ord("O")], None) @GuiCanvasCommandDecorator("Open", "&Open", ["", wx.ART_FILE_OPEN], [wx.ACCEL_CTRL, ord("O")], None)
def canvasOpen(self, event): def canvasOpen(self, event):
if self.canvasPathName != None: if self._promptSaveChanges():
saveChanges = self._dialogSaveChanges() with wx.FileDialog(self.parentCanvas, "Open", os.getcwd(), "", "mIRC art files (*.txt)|*.txt|All Files (*.*)|*.*", wx.FD_OPEN) as dialog:
if saveChanges == wx.ID_CANCEL: if dialog.ShowModal() == wx.ID_CANCEL:
return
elif saveChanges == wx.ID_NO:
pass
elif saveChanges == wx.ID_YES:
self.canvasSave(event)
with wx.FileDialog(self.parentCanvas, "Open", os.getcwd(), "", "mIRC art files (*.txt)|*.txt|All Files (*.*)|*.*", wx.FD_OPEN) as dialog:
if dialog.ShowModal() == wx.ID_CANCEL:
return False
else:
self.canvasPathName = dialog.GetPath()
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
rc, error = self.parentCanvas.canvas.importStore.importTextFile(self.canvasPathName)
if rc:
self.parentCanvas.update(self.parentCanvas.canvas.importStore.inSize, False, self.parentCanvas.canvas.importStore.outMap)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.update(pathName=self.canvasPathName, undoLevel=-1)
return True
else:
print("error: {}".format(error), file=sys.stderr)
return False return False
else:
self.canvasPathName = dialog.GetPath()
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
rc, error = self.parentCanvas.canvas.importStore.importTextFile(self.canvasPathName)
if rc:
self.parentCanvas.dirty = False
self.parentCanvas.update(self.parentCanvas.canvas.importStore.inSize, False, self.parentCanvas.canvas.importStore.outMap)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.update(dirty=self.parentCanvas.dirty, pathName=self.canvasPathName, undoLevel=-1)
return True
else:
print("error: {}".format(error), file=sys.stderr)
return False
# }}} # }}}
# {{{ canvasPaste(self, event): XXX # {{{ canvasPaste(self, event): XXX
@GuiCanvasCommandDecorator("Paste", "&Paste", ["", wx.ART_PASTE], None, False) @GuiCanvasCommandDecorator("Paste", "&Paste", ["", wx.ART_PASTE], None, False)
@ -231,14 +222,15 @@ class GuiCanvasInterface():
def canvasSave(self, event): def canvasSave(self, event):
if self.canvasPathName == None: if self.canvasPathName == None:
if self.canvasSaveAs(event) == False: if self.canvasSaveAs(event) == False:
return return False
try: try:
with open(self.canvasPathName, "w", encoding="utf-8") as outFile: with open(self.canvasPathName, "w", encoding="utf-8") as outFile:
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
self.parentCanvas.canvas.exportStore.exportTextFile( \ self.parentCanvas.canvas.exportStore.exportTextFile(self.parentCanvas.canvas.map, self.parentCanvas.canvas.size, outFile)
self.parentCanvas.canvas.map, self.parentCanvas.canvas.size, outFile)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
return True self.parentCanvas.dirty = False
self.update(dirty=self.parentCanvas.dirty)
return True
except IOError as error: except IOError as error:
return False return False
# }}} # }}}
@ -420,26 +412,19 @@ class GuiCanvasInterface():
# {{{ canvasImportAnsi(self, event): XXX # {{{ canvasImportAnsi(self, event): XXX
@GuiCanvasCommandDecorator("Import ANSI...", "Import ANSI...", None, None, None) @GuiCanvasCommandDecorator("Import ANSI...", "Import ANSI...", None, None, None)
def canvasImportAnsi(self, event): def canvasImportAnsi(self, event):
if self.canvasPathName != None:
saveChanges = self._dialogSaveChanges()
if saveChanges == wx.ID_CANCEL:
return
elif saveChanges == wx.ID_NO:
pass
elif saveChanges == wx.ID_YES:
self.canvasSave(event)
with wx.FileDialog(self.parentCanvas, "Open", os.getcwd(), "", "ANSI files (*.ans;*.txt)|*.ans;*.txt|All Files (*.*)|*.*", wx.FD_OPEN) as dialog: with wx.FileDialog(self.parentCanvas, "Open", os.getcwd(), "", "ANSI files (*.ans;*.txt)|*.ans;*.txt|All Files (*.*)|*.*", wx.FD_OPEN) as dialog:
if dialog.ShowModal() == wx.ID_CANCEL: if dialog.ShowModal() == wx.ID_CANCEL:
return False return False
else: elif self._promptSaveChanges():
self.canvasPathName = dialog.GetPath() self.canvasPathName = dialog.GetPath()
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
rc, error = self.parentCanvas.canvas.importStore.importAnsiFile(self.canvasPathName) rc, error = self.parentCanvas.canvas.importStore.importAnsiFile(self.canvasPathName)
if rc: if rc:
self.parentCanvas.dirty = True
self.parentCanvas.update(self.parentCanvas.canvas.importStore.inSize, False, self.parentCanvas.canvas.importStore.outMap) self.parentCanvas.update(self.parentCanvas.canvas.importStore.inSize, False, self.parentCanvas.canvas.importStore.outMap)
self.canvasPathName = "(Imported)" self.canvasPathName = None
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.update(pathName="(Imported)", undoLevel=-1) self.update(dirty=self.parentCanvas.dirty, pathName=self.canvasPathName, undoLevel=-1)
return True return True
else: else:
print("error: {}".format(error), file=sys.stderr) print("error: {}".format(error), file=sys.stderr)
@ -449,27 +434,21 @@ class GuiCanvasInterface():
@GuiCanvasCommandDecorator("Import from clipboard", "&Import from clipboard", None, None, None) @GuiCanvasCommandDecorator("Import from clipboard", "&Import from clipboard", None, None, None)
def canvasImportFromClipboard(self, event): def canvasImportFromClipboard(self, event):
rc = False rc = False
if wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_TEXT)) \ if wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_TEXT)) \
and wx.TheClipboard.Open(): and wx.TheClipboard.Open():
inBuffer = wx.TextDataObject() inBuffer = wx.TextDataObject()
if wx.TheClipboard.GetData(inBuffer): if wx.TheClipboard.GetData(inBuffer):
if self.canvasPathName != None: if self._promptSaveChanges():
saveChanges = self._dialogSaveChanges() self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
if saveChanges == wx.ID_CANCEL: rc, error = self.parentCanvas.canvas.importStore.importTextBuffer(io.StringIO(inBuffer.GetText()))
return if rc:
elif saveChanges == wx.ID_NO: self.parentCanvas.dirty = True
pass self.parentCanvas.update(self.parentCanvas.canvas.importStore.inSize, False, self.parentCanvas.canvas.importStore.outMap)
elif saveChanges == wx.ID_YES: self.canvasPathName = None
self.canvasSave(event) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) self.update(dirty=self.parentCanvas.dirty, pathName=self.canvasPathName, undoLevel=-1)
rc, error = self.parentCanvas.canvas.importStore.importTextBuffer(io.StringIO(inBuffer.GetText())) else:
if rc: print("error: {}".format(error), file=sys.stderr)
self.parentCanvas.update(self.parentCanvas.canvas.importStore.inSize, False, self.parentCanvas.canvas.importStore.outMap)
self.canvasPathName = "(Clipboard)"
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.update(pathName="(Clipboard)", undoLevel=-1)
else:
print("error: {}".format(error), file=sys.stderr)
wx.TheClipboard.Close() wx.TheClipboard.Close()
if not rc: if not rc:
with wx.MessageDialog(self.parentCanvas, "Clipboard does not contain text data and/or cannot be opened", "", wx.ICON_QUESTION | wx.OK | wx.OK_DEFAULT) as dialog: with wx.MessageDialog(self.parentCanvas, "Clipboard does not contain text data and/or cannot be opened", "", wx.ICON_QUESTION | wx.OK | wx.OK_DEFAULT) as dialog:
@ -478,26 +457,19 @@ class GuiCanvasInterface():
# {{{ canvasImportSauce(self, event): XXX # {{{ canvasImportSauce(self, event): XXX
@GuiCanvasCommandDecorator("Import SAUCE...", "Import SAUCE...", None, None, None) @GuiCanvasCommandDecorator("Import SAUCE...", "Import SAUCE...", None, None, None)
def canvasImportSauce(self, event): def canvasImportSauce(self, event):
if self.canvasPathName != None:
saveChanges = self._dialogSaveChanges()
if saveChanges == wx.ID_CANCEL:
return
elif saveChanges == wx.ID_NO:
pass
elif saveChanges == wx.ID_YES:
self.canvasSave(event)
with wx.FileDialog(self.parentCanvas, "Open", os.getcwd(), "", "SAUCE files (*.ans;*.txt)|*.ans;*.txt|All Files (*.*)|*.*", wx.FD_OPEN) as dialog: with wx.FileDialog(self.parentCanvas, "Open", os.getcwd(), "", "SAUCE files (*.ans;*.txt)|*.ans;*.txt|All Files (*.*)|*.*", wx.FD_OPEN) as dialog:
if dialog.ShowModal() == wx.ID_CANCEL: if dialog.ShowModal() == wx.ID_CANCEL:
return False return False
else: elif self._promptSaveChanges():
self.canvasPathName = dialog.GetPath() self.canvasPathName = dialog.GetPath()
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
rc, error = self.parentCanvas.canvas.importStore.importSauceFile(self.canvasPathName) rc, error = self.parentCanvas.canvas.importStore.importSauceFile(self.canvasPathName)
if rc: if rc:
self.parentCanvas.dirty = True
self.parentCanvas.update(self.parentCanvas.canvas.importStore.inSize, False, self.parentCanvas.canvas.importStore.outMap) self.parentCanvas.update(self.parentCanvas.canvas.importStore.inSize, False, self.parentCanvas.canvas.importStore.outMap)
self.canvasPathName = "(Imported)" self.canvasPathName = None
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.update(pathName="(Imported)", undoLevel=-1) self.update(dirty=self.parentCanvas.dirty, pathName=self.canvasPathName, undoLevel=-1)
return True return True
else: else:
print("error: {}".format(error), file=sys.stderr) print("error: {}".format(error), file=sys.stderr)
@ -519,7 +491,7 @@ class GuiCanvasInterface():
Colours[self.lastPanelState["colours"][0]][4] if self.lastPanelState["colours"][0] != -1 else "Transparent", Colours[self.lastPanelState["colours"][0]][4] if self.lastPanelState["colours"][0] != -1 else "Transparent",
Colours[self.lastPanelState["colours"][1]][4] if self.lastPanelState["colours"][1] != -1 else "Transparent")) Colours[self.lastPanelState["colours"][1]][4] if self.lastPanelState["colours"][1] != -1 else "Transparent"))
if "pathName" in self.lastPanelState: if "pathName" in self.lastPanelState:
if self.lastPanelState["pathName"] != "": if self.lastPanelState["pathName"] != None:
basePathName = os.path.basename(self.lastPanelState["pathName"]) basePathName = os.path.basename(self.lastPanelState["pathName"])
textItems.append("Current file: {}".format(basePathName)) textItems.append("Current file: {}".format(basePathName))
self.parentFrame.SetTitle("{} - roar".format(basePathName)) self.parentFrame.SetTitle("{} - roar".format(basePathName))
@ -527,6 +499,9 @@ class GuiCanvasInterface():
self.parentFrame.SetTitle("roar") self.parentFrame.SetTitle("roar")
if "toolName" in self.lastPanelState: if "toolName" in self.lastPanelState:
textItems.append("Current tool: {}".format(self.lastPanelState["toolName"])) textItems.append("Current tool: {}".format(self.lastPanelState["toolName"]))
if "dirty" in self.lastPanelState \
and self.lastPanelState["dirty"]:
textItems.append("*")
self.parentFrame.statusBar.SetStatusText(" | ".join(textItems)) self.parentFrame.statusBar.SetStatusText(" | ".join(textItems))
if "undoLevel" in self.lastPanelState: if "undoLevel" in self.lastPanelState:
if self.lastPanelState["undoLevel"] >= 0: if self.lastPanelState["undoLevel"] >= 0:

View File

@ -80,7 +80,7 @@ class GuiCanvasPanel(wx.Panel):
# }}} # }}}
# {{{ onPanelInput(self, event): XXX # {{{ onPanelInput(self, event): XXX
def onPanelInput(self, event): def onPanelInput(self, event):
self.canvas.dirty, self.canvas.dirtyCursor = False, False self.canvas.dirtyJournal, self.canvas.dirtyCursor = False, False
eventDc, eventType, tool = self.backend.getDeviceContext(self), event.GetEventType(), self.interface.currentTool eventDc, eventType, tool = self.backend.getDeviceContext(self), event.GetEventType(), self.interface.currentTool
if eventType == wx.wxEVT_CHAR: if eventType == wx.wxEVT_CHAR:
mapPoint = self.brushPos mapPoint = self.brushPos
@ -97,8 +97,9 @@ class GuiCanvasPanel(wx.Panel):
event, mapPoint, self.brushColours, self.brushSize, \ event, mapPoint, self.brushColours, self.brushSize, \
event.Dragging(), event.LeftIsDown(), event.RightIsDown(), \ event.Dragging(), event.LeftIsDown(), event.RightIsDown(), \
self.dispatchPatch, eventDc) self.dispatchPatch, eventDc)
if self.canvas.dirty: if self.canvas.dirtyJournal:
self.interface.update(cellPos=self.brushPos, undoLevel=self.canvas.journal.patchesUndoLevel) self.dirty = True
self.interface.update(dirty=self.dirty, cellPos=self.brushPos, undoLevel=self.canvas.journal.patchesUndoLevel)
if eventType == wx.wxEVT_MOTION: if eventType == wx.wxEVT_MOTION:
self.interface.update(cellPos=mapPoint) self.interface.update(cellPos=mapPoint)
# }}} # }}}
@ -119,7 +120,7 @@ class GuiCanvasPanel(wx.Panel):
self.backend, self.interface = backend(defaultCanvasSize, defaultCellSize), interface(self, parentFrame) self.backend, self.interface = backend(defaultCanvasSize, defaultCellSize), interface(self, parentFrame)
self.brushColours, self.brushPos, self.brushSize = [4, 1], [0, 0], [1, 1] self.brushColours, self.brushPos, self.brushSize = [4, 1], [0, 0], [1, 1]
self.canvas, self.canvasPos, self.defaultCanvasPos, self.defaultCanvasSize, self.defaultCellSize = canvas, defaultCanvasPos, defaultCanvasPos, defaultCanvasSize, defaultCellSize self.canvas, self.canvasPos, self.defaultCanvasPos, self.defaultCanvasSize, self.defaultCellSize = canvas, defaultCanvasPos, defaultCanvasPos, defaultCanvasSize, defaultCellSize
self.parentFrame = parentFrame self.dirty, self.parentFrame = False, parentFrame
self.Bind(wx.EVT_CLOSE, self.onPanelClose) self.Bind(wx.EVT_CLOSE, self.onPanelClose)
self.Bind(wx.EVT_ENTER_WINDOW, self.onPanelEnterWindow) self.Bind(wx.EVT_ENTER_WINDOW, self.onPanelEnterWindow)