mirror of
https://github.com/lalbornoz/roar.git
synced 2024-11-22 23:36:36 +00:00
Various bugfixes & usability improvements.
1) Correctly unmask cursor and dispatch delta patches on successful {re,un}do. 2) Don't prompt to save twice on exit via Exit {accelerator,menu item}. 3) Fix cursor artifacts by always resetting origin point on DC whilst unmasking cursor cells. 4) Fix {re,un}do {accelerator,{menu,toolbar} item} desynchronisation with actual canvas journal undo level. 5) Remove scattered remnants of initial implementation of unimplemented italic support. 6) Replace rendering transparent cursor w/ manual blending over wx.GraphicsContext() due to canvas bitmap masking & performance degradation. assets/text/TODO: updated.
This commit is contained in:
parent
fb9fbf940f
commit
404394b8a6
@ -1,4 +1,4 @@
|
|||||||
1) ANSI CSI CU[BDPU] sequences & italic
|
1) ANSI CSI CU[BDPU] sequences
|
||||||
2) Fix & finish Arabic/RTL text tool support
|
2) Fix & finish Arabic/RTL text tool support
|
||||||
3) Documentation, instrumentation & unit tests
|
3) Documentation, instrumentation & unit tests
|
||||||
4) Layers & layout (e.g. for comics, zines, etc.)
|
4) Layers & layout (e.g. for comics, zines, etc.)
|
||||||
|
@ -23,8 +23,7 @@ class CanvasExportStore():
|
|||||||
class _CellState():
|
class _CellState():
|
||||||
CS_NONE = 0x00
|
CS_NONE = 0x00
|
||||||
CS_BOLD = 0x01
|
CS_BOLD = 0x01
|
||||||
CS_ITALIC = 0x02
|
CS_UNDERLINE = 0x02
|
||||||
CS_UNDERLINE = 0x04
|
|
||||||
|
|
||||||
ImgurUploadUrl = "https://api.imgur.com/3/upload.json"
|
ImgurUploadUrl = "https://api.imgur.com/3/upload.json"
|
||||||
PastebinPostUrl = "https://pastebin.com/api/api_post.php"
|
PastebinPostUrl = "https://pastebin.com/api/api_post.php"
|
||||||
|
@ -12,8 +12,7 @@ class CanvasImportStore():
|
|||||||
class _CellState():
|
class _CellState():
|
||||||
CS_NONE = 0x00
|
CS_NONE = 0x00
|
||||||
CS_BOLD = 0x01
|
CS_BOLD = 0x01
|
||||||
CS_ITALIC = 0x02
|
CS_UNDERLINE = 0x02
|
||||||
CS_UNDERLINE = 0x04
|
|
||||||
|
|
||||||
def _flipCellStateBit(self, bit, cellState):
|
def _flipCellStateBit(self, bit, cellState):
|
||||||
return cellState & ~bit if cellState & bit else cellState | bit
|
return cellState & ~bit if cellState & bit else cellState | bit
|
||||||
@ -108,7 +107,7 @@ class CanvasImportStore():
|
|||||||
else:
|
else:
|
||||||
inCurColours = (15, -1); inCurCol += 1;
|
inCurColours = (15, -1); inCurCol += 1;
|
||||||
elif inChar == "\u0006":
|
elif inChar == "\u0006":
|
||||||
inCellState = self._flipCellStateBit(self._CellState.CS_ITALIC, inCellState); inCurCol += 1;
|
inCurCol += 1
|
||||||
elif inChar == "\u000f":
|
elif inChar == "\u000f":
|
||||||
inCellState |= self._CellState.CS_NONE; inCurColours = (15, -1); inCurCol += 1;
|
inCellState |= self._CellState.CS_NONE; inCurColours = (15, -1); inCurCol += 1;
|
||||||
elif inChar == "\u0016":
|
elif inChar == "\u0016":
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
#
|
#
|
||||||
# Colours: mIRC colour number to RGBA map given none of ^[BFV_] (bold, italic, reverse, underline)
|
# Colours: mIRC colour number to RGBA map given none of ^[BV_] (bold, reverse, underline)
|
||||||
#
|
#
|
||||||
Colours = [
|
Colours = [
|
||||||
[255, 255, 255, 255, "White"],
|
[255, 255, 255, 255, "White"],
|
||||||
|
@ -67,62 +67,64 @@ class GuiCanvasWxBackend():
|
|||||||
class _CellState():
|
class _CellState():
|
||||||
CS_NONE = 0x00
|
CS_NONE = 0x00
|
||||||
CS_BOLD = 0x01
|
CS_BOLD = 0x01
|
||||||
CS_ITALIC = 0x02
|
CS_UNDERLINE = 0x02
|
||||||
CS_UNDERLINE = 0x04
|
|
||||||
|
|
||||||
def _drawBrushPatch(self, eventDc, isCursor, patch, point):
|
def _blendColours(self, bg, fg):
|
||||||
absPoint = self._xlatePoint(point)
|
return [int((fg * 0.75) + (bg * (1.0 - 0.75))) for bg, fg in zip(Colours[bg][:3], Colours[fg][:3])]
|
||||||
dc = self._setBrushPatchColours(eventDc, isCursor, patch)
|
|
||||||
dc.DrawRectangle(*absPoint, *self.cellSize)
|
|
||||||
|
|
||||||
def _drawCharPatch(self, eventDc, isCursor, patch, point):
|
def _blendColoursBrush(self, bg, fg):
|
||||||
absPoint = self._xlatePoint(point)
|
colour = self._blendColours(bg, fg)
|
||||||
dc, pen = self._setCharPatchColours(eventDc, isCursor, patch)
|
return wx.Brush(wx.Colour(colour), wx.BRUSHSTYLE_SOLID), wx.Pen(wx.Colour(colour), 1)
|
||||||
dc.DrawRectangle(*absPoint, *self.cellSize)
|
|
||||||
if (patch[2] & self._CellState.CS_UNDERLINE) or (patch[3] == "_"):
|
def _drawPatch(self, eventDc, isCursor, patch, patchBg, point):
|
||||||
dc.SetPen(self._pens[patch[0]]);
|
absPoint, charFlag = self._xlatePoint(point), False
|
||||||
if not isCursor:
|
if (patch[3] == " ") and (patch[1] == -1):
|
||||||
dc.DrawLine(absPoint[0], absPoint[1] + self.cellSize[1] - 1, absPoint[0] + self.cellSize[0], absPoint[1] + self.cellSize[1] - 1)
|
charFlag, patch = True, [*patch[:-1], "░"]
|
||||||
else:
|
textBg, textFg = wx.Colour(Colours[patch[1]][:4]), wx.Colour(Colours[patch[0]][:4])
|
||||||
dc.DrawLines((wx.Point2D(absPoint[0], absPoint[1] + self.cellSize[1] - 1), wx.Point2D(absPoint[0] + self.cellSize[0], absPoint[1] + self.cellSize[1] - 1),))
|
if isCursor and (patch[3] == " ") and ((patchBg[3] != " ") or (patchBg[2] & self._CellState.CS_UNDERLINE)):
|
||||||
dc.SetPen(pen)
|
charFlag, patch = True, [*patch[:-2], *patchBg[2:]]
|
||||||
if patch[3] != "_":
|
textFg = wx.Colour(self._blendColours(patchBg[0], patch[1]))
|
||||||
if not isCursor:
|
elif (patch[3] != " ") or (patch[2] & self._CellState.CS_UNDERLINE):
|
||||||
oldClippingRegion = dc.GetClippingBox()
|
charFlag = True
|
||||||
dc.DestroyClippingRegion(); dc.SetClippingRegion(*absPoint, *self.cellSize);
|
textBg, textFg = wx.Colour(Colours[patch[1]][:4]), wx.Colour(Colours[patch[0]][:4])
|
||||||
dc.SetTextBackground(wx.Colour(Colours[patch[1]][:4])); dc.SetTextForeground(wx.Colour(Colours[patch[0]][:4]));
|
brush, pen = self._setBrushColours(eventDc, isCursor, patch, patchBg)
|
||||||
else:
|
eventDc.DrawRectangle(*absPoint, *self.cellSize)
|
||||||
dc.ResetClip(); dc.Clip(wx.Region(*absPoint, *self.cellSize));
|
if charFlag:
|
||||||
dc.DrawText(patch[3], *absPoint)
|
if (patch[2] & self._CellState.CS_UNDERLINE) or (patch[3] == "_"):
|
||||||
if not isCursor:
|
eventDc.SetPen(self._pens[patch[0]]);
|
||||||
dc.DestroyClippingRegion()
|
eventDc.DrawLine(absPoint[0], absPoint[1] + self.cellSize[1] - 1, absPoint[0] + self.cellSize[0], absPoint[1] + self.cellSize[1] - 1)
|
||||||
|
eventDc.SetPen(pen)
|
||||||
|
if patch[3] != "_":
|
||||||
|
oldClippingRegion = eventDc.GetClippingBox()
|
||||||
|
eventDc.SetFont(self._font)
|
||||||
|
eventDc.DestroyClippingRegion(); eventDc.SetClippingRegion(*absPoint, *self.cellSize);
|
||||||
|
eventDc.SetTextForeground(textFg)
|
||||||
|
eventDc.DrawText(patch[3], *absPoint)
|
||||||
|
eventDc.DestroyClippingRegion()
|
||||||
|
if isCursor:
|
||||||
|
brush.Destroy(); pen.Destroy();
|
||||||
|
if self._lastBrush != None:
|
||||||
|
eventDc.SetBrush(self._lastBrush)
|
||||||
|
if self._lastPen != None:
|
||||||
|
eventDc.SetPen(self._lastPen)
|
||||||
|
|
||||||
def _finiBrushesAndPens(self):
|
def _finiBrushesAndPens(self):
|
||||||
[brush.Destroy() for brush in self._brushes or []]
|
[brush.Destroy() for brush in self._brushes or []]
|
||||||
[brushTransp.Destroy() for brushTransp in self._brushesTransp or []]
|
|
||||||
[pen.Destroy() for pen in self._pens or []]
|
[pen.Destroy() for pen in self._pens or []]
|
||||||
[penTransp.Destroy() for penTransp in self._pensTransp or []]
|
|
||||||
self._brushAlpha.Destroy(); self._penAlpha.Destroy();
|
self._brushAlpha.Destroy(); self._penAlpha.Destroy();
|
||||||
self._brushAlphaTransp.Destroy(); self._penAlphaTransp.Destroy();
|
|
||||||
self._brushes, self._lastBrush, self._lastPen, self._pens = None, None, None, None
|
self._brushes, self._lastBrush, self._lastPen, self._pens = None, None, None, None
|
||||||
self._brushesTransp, self._lastBrushTransp, self._lastPenTransp, self._pensTransp = None, None, None, None
|
|
||||||
|
|
||||||
def _initBrushesAndPens(self):
|
def _initBrushesAndPens(self):
|
||||||
self._brushes, self._pens = [None for x in range(len(Colours))], [None for x in range(len(Colours))]
|
self._brushes, self._pens = [None for x in range(len(Colours))], [None for x in range(len(Colours))]
|
||||||
self._brushesTransp, self._pensTransp = [None for x in range(len(Colours))], [None for x in range(len(Colours))]
|
|
||||||
for mircColour in range(len(Colours)):
|
for mircColour in range(len(Colours)):
|
||||||
self._brushes[mircColour] = wx.Brush(wx.Colour(Colours[mircColour][:4]), wx.BRUSHSTYLE_SOLID)
|
self._brushes[mircColour] = wx.Brush(wx.Colour(Colours[mircColour][:4]), wx.BRUSHSTYLE_SOLID)
|
||||||
self._brushesTransp[mircColour] = wx.Brush(wx.Colour(*Colours[mircColour][:3], 200), wx.BRUSHSTYLE_SOLID)
|
|
||||||
self._pens[mircColour] = wx.Pen(wx.Colour(Colours[mircColour][:4]), 1)
|
self._pens[mircColour] = wx.Pen(wx.Colour(Colours[mircColour][:4]), 1)
|
||||||
self._pensTransp[mircColour] = wx.Pen(wx.Colour(*Colours[mircColour][:3], 200), 1, wx.PENSTYLE_TRANSPARENT)
|
|
||||||
self._brushAlpha = wx.Brush(wx.Colour(Colours[14][:4]), wx.BRUSHSTYLE_SOLID)
|
self._brushAlpha = wx.Brush(wx.Colour(Colours[14][:4]), wx.BRUSHSTYLE_SOLID)
|
||||||
self._brushAlphaTransp = wx.Brush(wx.Colour(*Colours[14][:3], 200), wx.BRUSHSTYLE_SOLID)
|
|
||||||
self._penAlpha = wx.Pen(wx.Colour(Colours[14][:4]), 1)
|
self._penAlpha = wx.Pen(wx.Colour(Colours[14][:4]), 1)
|
||||||
self._penAlphaTransp = wx.Pen(wx.Colour(*Colours[14][:3], 200), 1, wx.PENSTYLE_TRANSPARENT)
|
|
||||||
self._lastBrush, self._lastPen = None, None
|
self._lastBrush, self._lastPen = None, None
|
||||||
self._lastBrushTransp, self._lastPenTransp = None, None
|
|
||||||
|
|
||||||
def _reshapeArabic(self, canvas, eventDc, isCursor, patch, point):
|
def _reshapeArabic(self, canvas, eventDc, isCursor, patch, point):
|
||||||
|
patches = []
|
||||||
lastCell = point[0]
|
lastCell = point[0]
|
||||||
while True:
|
while True:
|
||||||
if ((lastCell + 1) >= (canvas.size[0] - 1)) \
|
if ((lastCell + 1) >= (canvas.size[0] - 1)) \
|
||||||
@ -147,76 +149,52 @@ class GuiCanvasWxBackend():
|
|||||||
runCell[3] = self.arabicShapes[runCell[3]][1]; connect = True;
|
runCell[3] = self.arabicShapes[runCell[3]][1]; connect = True;
|
||||||
else:
|
else:
|
||||||
runCell[3] = self.arabicShapes[runCell[3]][0]; connect = False;
|
runCell[3] = self.arabicShapes[runCell[3]][0]; connect = False;
|
||||||
self._drawCharPatch(eventDc, isCursor, runCell, [runX, point[1]])
|
patches += [[runX, point[1], *runCell]]
|
||||||
runCell = list(patch[2:])
|
runCell = list(patch[2:])
|
||||||
if connect and (self.arabicShapes[patch[5]][3] != None):
|
if connect and (self.arabicShapes[patch[5]][3] != None):
|
||||||
runCell[3] = self.arabicShapes[patch[5]][3]
|
runCell[3] = self.arabicShapes[patch[5]][3]
|
||||||
else:
|
else:
|
||||||
runCell[3] = self.arabicShapes[patch[5]][0]
|
runCell[3] = self.arabicShapes[patch[5]][0]
|
||||||
self._drawCharPatch(eventDc, isCursor, runCell, [point[0], point[1]])
|
patches += [[*point, *runCell]]
|
||||||
|
return patches
|
||||||
|
|
||||||
def _setBrushPatchColours(self, dc, isCursor, patch):
|
def _setBrushColours(self, dc, isCursor, patch, patchBg):
|
||||||
if not isCursor:
|
|
||||||
brushAlpha, brushes, dc_, penAlpha, pens = self._brushAlpha, self._brushes, dc, self._penAlpha, self._pens
|
|
||||||
else:
|
|
||||||
brushAlpha, brushes, dc_, penAlpha, pens = self._brushAlphaTransp, self._brushesTransp, wx.GraphicsContext.Create(dc), self._penAlphaTransp, self._pensTransp
|
|
||||||
if ((patch[0] != -1) and (patch[1] != -1)) \
|
if ((patch[0] != -1) and (patch[1] != -1)) \
|
||||||
or ((patch[0] == -1) and (patch[1] != -1)):
|
or ((patch[0] == -1) and (patch[1] != -1)):
|
||||||
brush, pen = brushes[patch[1]], pens[patch[1]]
|
if not isCursor:
|
||||||
|
brush, pen = self._brushes[patch[1]], self._pens[patch[1]]
|
||||||
|
else:
|
||||||
|
brush, pen = self._blendColoursBrush(patchBg[1], patch[1])
|
||||||
else:
|
else:
|
||||||
brush, pen = brushAlpha, penAlpha
|
if not isCursor:
|
||||||
|
brush, pen = self._brushAlpha, self._penAlpha
|
||||||
|
else:
|
||||||
|
brush, pen = self._blendColoursBrush(patchBg[1], 14)
|
||||||
if not isCursor:
|
if not isCursor:
|
||||||
if self._lastBrush != brush:
|
if self._lastBrush != brush:
|
||||||
dc_.SetBrush(brush); self._lastBrush = brush;
|
dc.SetBrush(brush); self._lastBrush = brush;
|
||||||
if self._lastPen != pen:
|
if self._lastPen != pen:
|
||||||
dc_.SetPen(pen); self._lastPen = pen;
|
dc.SetPen(pen); self._lastPen = pen;
|
||||||
else:
|
else:
|
||||||
dc_.SetBrush(brush); dc_.SetPen(pen);
|
dc.SetBrush(brush); dc.SetPen(pen);
|
||||||
return dc_
|
return brush, pen
|
||||||
|
|
||||||
def _setCharPatchColours(self, dc, isCursor, patch):
|
|
||||||
if not isCursor:
|
|
||||||
brushAlpha, brushes, dc_, penAlpha, pens = self._brushAlpha, self._brushes, dc, self._penAlpha, self._pens
|
|
||||||
dc_.SetFont(self._font)
|
|
||||||
else:
|
|
||||||
brushAlpha, brushes, dc_, penAlpha, pens = self._brushAlphaTransp, self._brushesTransp, wx.GraphicsContext.Create(dc), self._penAlphaTransp, self._pensTransp
|
|
||||||
if (patch[0] != -1) and (patch[1] != -1):
|
|
||||||
brush, fontColour, pen = brushes[patch[1]], Colours[patch[0]][:3], pens[patch[1]]
|
|
||||||
elif (patch[0] == -1) and (patch[1] == -1):
|
|
||||||
brush, fontColour, pen = brushAlpha, Colours[14][:4], penAlpha
|
|
||||||
elif patch[0] == -1:
|
|
||||||
brush, fontColour, pen = brushes[patch[1]], Colours[14][:3], pens[patch[1]]
|
|
||||||
elif patch[1] == -1:
|
|
||||||
brush, fontColour, pen = brushAlpha, Colours[patch[0]][:3], penAlpha
|
|
||||||
if not isCursor:
|
|
||||||
if self._lastBrush != brush:
|
|
||||||
dc_.SetBrush(brush); self._lastBrush = brush;
|
|
||||||
if self._lastPen != pen:
|
|
||||||
dc_.SetPen(pen); self._lastPen = pen;
|
|
||||||
else:
|
|
||||||
dc_.SetBrush(brush); dc_.SetFont(self._font, wx.Colour(fontColour)); dc_.SetPen(pen);
|
|
||||||
return dc_, pen
|
|
||||||
|
|
||||||
def _xlatePoint(self, point):
|
def _xlatePoint(self, point):
|
||||||
return [a * b for a, b in zip(point, self.cellSize)]
|
return [a * b for a, b in zip(point, self.cellSize)]
|
||||||
|
|
||||||
def drawCursorMaskWithJournal(self, canvas, canvasJournal, eventDc):
|
def drawCursorMaskWithJournal(self, canvas, canvasJournal, eventDc):
|
||||||
|
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0);
|
||||||
[self.drawPatch(canvas, eventDc, patch) for patch in canvasJournal.popCursor()]
|
[self.drawPatch(canvas, eventDc, patch) for patch in canvasJournal.popCursor()]
|
||||||
|
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||||
|
|
||||||
def drawPatch(self, canvas, eventDc, patch, isCursor=False):
|
def drawPatch(self, canvas, eventDc, patch, isCursor=False):
|
||||||
point = patch[:2]
|
point = patch[:2]
|
||||||
if [(c >= 0) and (c < s) for c, s in zip(point, self.canvasSize)] == [True, True]:
|
if [(c >= 0) and (c < s) for c, s in zip(point, self.canvasSize)] == [True, True]:
|
||||||
if patch[5] == " ":
|
if patch[5] in self.arabicShapes:
|
||||||
if patch[3] == -1:
|
for patchReshaped in self._reshapeArabic(canvas, eventDc, isCursor, patch, point):
|
||||||
self._drawCharPatch(eventDc, isCursor, [*patch[2:-1], "░"], point)
|
self._drawPatch(eventDc, isCursor, patchReshaped[2:], canvas.map[patchReshaped[1]][patchReshaped[0]], patchReshaped[:2])
|
||||||
elif patch[4] & self._CellState.CS_UNDERLINE:
|
|
||||||
self._drawCharPatch(eventDc, isCursor, patch[2:], point)
|
|
||||||
else:
|
|
||||||
self._drawBrushPatch(eventDc, isCursor, patch[2:], point)
|
|
||||||
elif patch[5] in self.arabicShapes:
|
|
||||||
self._reshapeArabic(canvas, eventDc, isCursor, patch, point)
|
|
||||||
else:
|
else:
|
||||||
self._drawCharPatch(eventDc, isCursor, patch[2:], point)
|
self._drawPatch(eventDc, isCursor, patch[2:], canvas.map[patch[1]][patch[0]], point)
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
@ -195,15 +195,13 @@ class RoarCanvasCommandsEdit():
|
|||||||
@GuiCommandDecorator("Redo", "&Redo", ["", wx.ART_REDO], [wx.ACCEL_CTRL, ord("Y")], False)
|
@GuiCommandDecorator("Redo", "&Redo", ["", wx.ART_REDO], [wx.ACCEL_CTRL, ord("Y")], False)
|
||||||
def canvasRedo(self, event):
|
def canvasRedo(self, event):
|
||||||
eventDc = self.parentCanvas.backend.getDeviceContext(self.parentCanvas.GetClientSize(), self.parentCanvas, self.parentCanvas.GetViewStart())
|
eventDc = self.parentCanvas.backend.getDeviceContext(self.parentCanvas.GetClientSize(), self.parentCanvas, self.parentCanvas.GetViewStart())
|
||||||
self.parentCanvas.backend.drawCursorMaskWithJournal(self.parentCanvas.canvas, self.parentCanvas.canvas.journal, eventDc)
|
self.parentCanvas.dispatchDeltaPatches(self.parentCanvas.canvas.journal.popRedo(), eventDc=eventDc, forceDirtyCursor=True)
|
||||||
self.parentCanvas.dispatchDeltaPatches(self.parentCanvas.canvas.journal.popRedo())
|
|
||||||
self.update(size=self.parentCanvas.canvas.size, undoLevel=self.parentCanvas.canvas.journal.patchesUndoLevel)
|
self.update(size=self.parentCanvas.canvas.size, undoLevel=self.parentCanvas.canvas.journal.patchesUndoLevel)
|
||||||
|
|
||||||
@GuiCommandDecorator("Undo", "&Undo", ["", wx.ART_UNDO], [wx.ACCEL_CTRL, ord("Z")], False)
|
@GuiCommandDecorator("Undo", "&Undo", ["", wx.ART_UNDO], [wx.ACCEL_CTRL, ord("Z")], False)
|
||||||
def canvasUndo(self, event):
|
def canvasUndo(self, event):
|
||||||
eventDc = self.parentCanvas.backend.getDeviceContext(self.parentCanvas.GetClientSize(), self.parentCanvas, self.parentCanvas.GetViewStart())
|
eventDc = self.parentCanvas.backend.getDeviceContext(self.parentCanvas.GetClientSize(), self.parentCanvas, self.parentCanvas.GetViewStart())
|
||||||
self.parentCanvas.backend.drawCursorMaskWithJournal(self.parentCanvas.canvas, self.parentCanvas.canvas.journal, eventDc)
|
self.parentCanvas.dispatchDeltaPatches(self.parentCanvas.canvas.journal.popUndo(), eventDc=eventDc, forceDirtyCursor=True)
|
||||||
self.parentCanvas.dispatchDeltaPatches(self.parentCanvas.canvas.journal.popUndo())
|
|
||||||
self.update(size=self.parentCanvas.canvas.size, undoLevel=self.parentCanvas.canvas.journal.patchesUndoLevel)
|
self.update(size=self.parentCanvas.canvas.size, undoLevel=self.parentCanvas.canvas.journal.patchesUndoLevel)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -116,8 +116,9 @@ class RoarCanvasCommandsFile():
|
|||||||
|
|
||||||
@GuiCommandDecorator("Exit", "E&xit", None, [wx.ACCEL_CTRL, ord("X")], None)
|
@GuiCommandDecorator("Exit", "E&xit", None, [wx.ACCEL_CTRL, ord("X")], None)
|
||||||
def canvasExit(self, event):
|
def canvasExit(self, event):
|
||||||
if self._promptSaveChanges():
|
if not self.exiting:
|
||||||
self.parentFrame.Close(True)
|
if self._promptSaveChanges():
|
||||||
|
self.exiting = True; self.parentFrame.Close(True);
|
||||||
|
|
||||||
@GuiCommandDecorator("Export as ANSI...", "Export as &ANSI...", None, None, None)
|
@GuiCommandDecorator("Export as ANSI...", "Export as &ANSI...", None, None, None)
|
||||||
def canvasExportAsAnsi(self, event):
|
def canvasExportAsAnsi(self, event):
|
||||||
@ -144,6 +145,8 @@ class RoarCanvasCommandsFile():
|
|||||||
else:
|
else:
|
||||||
outPathName = dialog.GetPath(); self.lastDir = os.path.dirname(outPathName); self._storeLastDir(self.lastDir);
|
outPathName = dialog.GetPath(); self.lastDir = os.path.dirname(outPathName); self._storeLastDir(self.lastDir);
|
||||||
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
|
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
|
||||||
|
eventDc = self.parentCanvas.backend.getDeviceContext(self.parentCanvas.GetClientSize(), self.parentCanvas)
|
||||||
|
self.parentCanvas.backend.drawCursorMaskWithJournal(self.parentCanvas.canvas, self.parentCanvas.canvas.journal, eventDc)
|
||||||
self.parentCanvas.canvas.exportStore.exportBitmapToPngFile(self.parentCanvas.backend.canvasBitmap, outPathName, wx.BITMAP_TYPE_PNG)
|
self.parentCanvas.canvas.exportStore.exportBitmapToPngFile(self.parentCanvas.backend.canvasBitmap, outPathName, wx.BITMAP_TYPE_PNG)
|
||||||
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
|
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
|
||||||
return True
|
return True
|
||||||
@ -151,6 +154,8 @@ class RoarCanvasCommandsFile():
|
|||||||
@GuiCommandDecorator("Export to Imgur...", "Export to I&mgur...", None, None, haveImgurApiKey and haveUrllib)
|
@GuiCommandDecorator("Export to Imgur...", "Export to I&mgur...", None, None, haveImgurApiKey and haveUrllib)
|
||||||
def canvasExportImgur(self, event):
|
def canvasExportImgur(self, event):
|
||||||
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
|
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
|
||||||
|
eventDc = self.parentCanvas.backend.getDeviceContext(self.parentCanvas.GetClientSize(), self.parentCanvas)
|
||||||
|
self.parentCanvas.backend.drawCursorMaskWithJournal(self.parentCanvas.canvas, self.parentCanvas.canvas.journal, eventDc)
|
||||||
rc, status, result = self.parentCanvas.canvas.exportStore.exportBitmapToImgur(self.imgurApiKey, self.parentCanvas.backend.canvasBitmap, "", "", wx.BITMAP_TYPE_PNG)
|
rc, status, result = self.parentCanvas.canvas.exportStore.exportBitmapToImgur(self.imgurApiKey, self.parentCanvas.backend.canvasBitmap, "", "", wx.BITMAP_TYPE_PNG)
|
||||||
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
|
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
|
||||||
if rc:
|
if rc:
|
||||||
@ -291,5 +296,6 @@ class RoarCanvasCommandsFile():
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
self.toolBars = ()
|
self.toolBars = ()
|
||||||
|
self.exiting = False
|
||||||
|
|
||||||
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=0
|
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=0
|
||||||
|
@ -111,12 +111,12 @@ class RoarCanvasWindow(GuiWindow):
|
|||||||
rc, dirty = tool.onKeyboardEvent(mapPoint, self.brushColours, self.brushPos, self.brushSize, self.canvas, self.dispatchPatchSingle, eventDc, keyChar, keyCode, keyModifiers, self.brushPos)
|
rc, dirty = tool.onKeyboardEvent(mapPoint, self.brushColours, self.brushPos, self.brushSize, self.canvas, self.dispatchPatchSingle, eventDc, keyChar, keyCode, keyModifiers, self.brushPos)
|
||||||
elif mapPoint != None:
|
elif mapPoint != None:
|
||||||
self.dispatchPatchSingle(eventDc, True, [*mapPoint, self.brushColours[0], self.brushColours[0], 0, " "])
|
self.dispatchPatchSingle(eventDc, True, [*mapPoint, self.brushColours[0], self.brushColours[0], 0, " "])
|
||||||
|
self.canvas.journal.end()
|
||||||
if dirty:
|
if dirty:
|
||||||
self.dirty = True
|
self.dirty = True
|
||||||
self.commands.update(dirty=self.dirty, cellPos=self.brushPos, undoLevel=self.canvas.journal.patchesUndoLevel)
|
self.commands.update(dirty=self.dirty, cellPos=self.brushPos, undoLevel=self.canvas.journal.patchesUndoLevel)
|
||||||
else:
|
else:
|
||||||
self.commands.update(cellPos=self.brushPos)
|
self.commands.update(cellPos=self.brushPos)
|
||||||
self.canvas.journal.end()
|
|
||||||
if rc and (tool.__class__ == ToolObject):
|
if rc and (tool.__class__ == ToolObject):
|
||||||
if tool.toolState > tool.TS_NONE:
|
if tool.toolState > tool.TS_NONE:
|
||||||
self.commands.update(undoInhibit=True)
|
self.commands.update(undoInhibit=True)
|
||||||
@ -133,10 +133,11 @@ class RoarCanvasWindow(GuiWindow):
|
|||||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||||
return rc
|
return rc
|
||||||
|
|
||||||
def dispatchDeltaPatches(self, deltaPatches):
|
def dispatchDeltaPatches(self, deltaPatches, eventDc=None, forceDirtyCursor=True):
|
||||||
eventDc = self.backend.getDeviceContext(self.GetClientSize(), self)
|
if eventDc == None:
|
||||||
|
eventDc = self.backend.getDeviceContext(self.GetClientSize(), self)
|
||||||
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0);
|
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0);
|
||||||
if self.canvas.dirtyCursor:
|
if self.canvas.dirtyCursor or forceDirtyCursor:
|
||||||
self.backend.drawCursorMaskWithJournal(self.canvas, self.canvas.journal, eventDc)
|
self.backend.drawCursorMaskWithJournal(self.canvas, self.canvas.journal, eventDc)
|
||||||
self.canvas.dirtyCursor = False
|
self.canvas.dirtyCursor = False
|
||||||
for patch in deltaPatches:
|
for patch in deltaPatches:
|
||||||
@ -239,9 +240,7 @@ class RoarCanvasWindow(GuiWindow):
|
|||||||
def onLeaveWindow(self, event):
|
def onLeaveWindow(self, event):
|
||||||
if False:
|
if False:
|
||||||
eventDc = self.backend.getDeviceContext(self.GetClientSize(), self, self.GetViewStart())
|
eventDc = self.backend.getDeviceContext(self.GetClientSize(), self, self.GetViewStart())
|
||||||
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0);
|
|
||||||
self.backend.drawCursorMaskWithJournal(self.canvas, self.canvas.journal, eventDc)
|
self.backend.drawCursorMaskWithJournal(self.canvas, self.canvas.journal, eventDc)
|
||||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
|
||||||
self.lastCellState = None
|
self.lastCellState = None
|
||||||
|
|
||||||
def onMouseInput(self, event):
|
def onMouseInput(self, event):
|
||||||
@ -278,9 +277,7 @@ class RoarCanvasWindow(GuiWindow):
|
|||||||
|
|
||||||
def onPaint(self, event):
|
def onPaint(self, event):
|
||||||
eventDc = self.backend.getDeviceContext(self.GetClientSize(), self)
|
eventDc = self.backend.getDeviceContext(self.GetClientSize(), self)
|
||||||
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0);
|
|
||||||
self.backend.drawCursorMaskWithJournal(self.canvas, self.canvas.journal, eventDc)
|
self.backend.drawCursorMaskWithJournal(self.canvas, self.canvas.journal, eventDc)
|
||||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
|
||||||
self.backend.onPaint(self.GetClientSize(), self, self.GetViewStart())
|
self.backend.onPaint(self.GetClientSize(), self, self.GetViewStart())
|
||||||
|
|
||||||
def __init__(self, backend, canvas, cellSize, commands, parent, parentFrame, pos, scrollStep, size):
|
def __init__(self, backend, canvas, cellSize, commands, parent, parentFrame, pos, scrollStep, size):
|
||||||
|
@ -32,7 +32,11 @@ class RoarClient(GuiFrame):
|
|||||||
self.canvasPanel.GetEventHandler().ProcessEvent(event)
|
self.canvasPanel.GetEventHandler().ProcessEvent(event)
|
||||||
|
|
||||||
def onClose(self, event):
|
def onClose(self, event):
|
||||||
if self.canvasPanel.commands._promptSaveChanges():
|
if not self.canvasPanel.commands.exiting:
|
||||||
|
closeFlag = self.canvasPanel.commands._promptSaveChanges()
|
||||||
|
else:
|
||||||
|
closeFlag = True
|
||||||
|
if closeFlag:
|
||||||
event.Skip();
|
event.Skip();
|
||||||
|
|
||||||
def onSize(self, event):
|
def onSize(self, event):
|
||||||
|
Loading…
Reference in New Issue
Block a user