mirror of
https://github.com/lalbornoz/roar.git
synced 2024-11-25 00:26:38 +00:00
Improve backend latency and throughput via batching.
assets/text/TODO: updated. libtools/ToolLine.py: reflect brush width in pre-line dragging cursor.
This commit is contained in:
parent
86e2c9e904
commit
76e57bd081
@ -14,14 +14,16 @@
|
||||
a) switch to Gtk
|
||||
b) https://material.io/resources/icons/?style=baseline
|
||||
c) replace logo w/ canvas panel in About dialogue, revisit melp? dialogue
|
||||
d) Settings/Settings window (e.g. autosave, hide cursor on leaving window, ...)
|
||||
e) replace resize buttons w/ {-,edit box,+} buttons & lock button re: ratio (ty lol3)
|
||||
d) replace resize buttons w/ {-,edit box,+} buttons & lock button re: ratio (ty lol3)
|
||||
e) Settings/Settings window (e.g. autosave, cursor opacity, hide cursor on leaving window, ...)
|
||||
|
||||
Release roadmap:
|
||||
1) {copy,cut,delete,insert from,paste}, edit asset in new canvas, import from {canvas,object}
|
||||
2) operators: crop, scale, shift, slice
|
||||
3) auto{load,save} & {backup,restore}
|
||||
4) tools: unicode block elements
|
||||
5) floating/dockable toolbar https://wxpython.org/Phoenix/docs/html/wx.aui.AuiManager.html
|
||||
2) floating/dockable toolbar https://wxpython.org/Phoenix/docs/html/wx.aui.AuiManager.html
|
||||
3) allow dragging {circle,rect,...} w/ <Ctrl> irrespective of current brush size
|
||||
4) reimplement cursor unmasking w/ simple list of points
|
||||
5) operators: crop, scale, shift, slice
|
||||
6) auto{load,save} & {backup,restore}
|
||||
7) tools: unicode block elements
|
||||
|
||||
vim:ff=dos tw=0
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
from ctypes import *
|
||||
from GuiCanvasColours import Colours
|
||||
import math, os, platform, wx
|
||||
import math, os, platform, Rtl, wx
|
||||
|
||||
class GuiBufferedDC(wx.MemoryDC):
|
||||
def __del__(self):
|
||||
@ -72,60 +72,28 @@ class GuiCanvasWxBackend():
|
||||
def _blendColours(self, bg, fg):
|
||||
return [int((fg * 0.75) + (bg * (1.0 - 0.75))) for bg, fg in zip(Colours[bg][:3], Colours[fg][:3])]
|
||||
|
||||
def _blendColoursBrush(self, bg, fg):
|
||||
colour = self._blendColours(bg, fg)
|
||||
return wx.Brush(wx.Colour(colour), wx.BRUSHSTYLE_SOLID), wx.Pen(wx.Colour(colour), 1)
|
||||
|
||||
def _drawPatch(self, eventDc, isCursor, patch, patchBg, point):
|
||||
absPoint, charFlag = self._xlatePoint(point), False
|
||||
if (patch[3] == " ") and (patch[1] == -1):
|
||||
charFlag, patch = True, [*patch[:-1], "░"]
|
||||
textBg, textFg = wx.Colour(Colours[patch[1]][:4]), wx.Colour(Colours[patch[0]][:4])
|
||||
if isCursor and (patch[3] == " ") and ((patchBg[3] != " ") or (patchBg[2] & self._CellState.CS_UNDERLINE)):
|
||||
charFlag, patch = True, [*patch[:-2], *patchBg[2:]]
|
||||
textFg = wx.Colour(self._blendColours(patchBg[0], patch[1]))
|
||||
elif (patch[3] != " ") or (patch[2] & self._CellState.CS_UNDERLINE):
|
||||
charFlag = True
|
||||
textBg, textFg = wx.Colour(Colours[patch[1]][:4]), wx.Colour(Colours[patch[0]][:4])
|
||||
brush, pen = self._setBrushColours(eventDc, isCursor, patch, patchBg)
|
||||
eventDc.DrawRectangle(*absPoint, *self.cellSize)
|
||||
if charFlag:
|
||||
if (patch[2] & self._CellState.CS_UNDERLINE) or (patch[3] == "_"):
|
||||
eventDc.SetPen(self._pens[patch[0]]);
|
||||
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):
|
||||
[brush.Destroy() for brush in self._brushes or []]
|
||||
[pen.Destroy() for pen in self._pens or []]
|
||||
self._brushAlpha.Destroy(); self._penAlpha.Destroy();
|
||||
self._brushes, self._lastBrush, self._lastPen, self._pens = None, None, None, None
|
||||
for wxObject in Rtl.flatten([
|
||||
(self._brushAlpha,), (*(self._brushes or ()),), (self._penAlpha,), (*(self._pens or ()),),
|
||||
*[[self._brushesBlend[bg][fg] for fg in self._brushesBlend[bg].keys()] for bg in self._brushesBlend.keys()],
|
||||
*[[self._pensBlend[bg][fg] for fg in self._pensBlend[bg].keys()] for bg in self._pensBlend.keys()]]):
|
||||
if wxObject != None:
|
||||
wxObject.Destroy()
|
||||
self._brushAlpha, self._brushes, self._brushesBlend, self._lastBrush, self._lastPen, self._penAlpha, self._pens, self._pensBlend = None, [], {}, None, None, None, [], {}
|
||||
|
||||
def _initBrushesAndPens(self):
|
||||
self._brushes, self._pens = [None for x in range(len(Colours))], [None for x in range(len(Colours))]
|
||||
self._brushes, self._brushesBlend, self._lastBrush, self._lastPen, self._pens, self._pensBlend = [], {}, None, None, [], {}
|
||||
self._brushAlpha, self._penAlpha = wx.Brush(wx.Colour(Colours[14][:4]), wx.BRUSHSTYLE_SOLID), wx.Pen(wx.Colour(Colours[14][:4]), 1)
|
||||
for mircColour in range(len(Colours)):
|
||||
self._brushes[mircColour] = wx.Brush(wx.Colour(Colours[mircColour][:4]), wx.BRUSHSTYLE_SOLID)
|
||||
self._pens[mircColour] = wx.Pen(wx.Colour(Colours[mircColour][:4]), 1)
|
||||
self._brushAlpha = wx.Brush(wx.Colour(Colours[14][:4]), wx.BRUSHSTYLE_SOLID)
|
||||
self._penAlpha = wx.Pen(wx.Colour(Colours[14][:4]), 1)
|
||||
self._lastBrush, self._lastPen = None, None
|
||||
self._brushes += [wx.Brush(wx.Colour(Colours[mircColour][:4]), wx.BRUSHSTYLE_SOLID)]; self._brushesBlend[mircColour] = {};
|
||||
self._pens += [wx.Pen(wx.Colour(Colours[mircColour][:4]), 1)]; self._pensBlend[mircColour] = {};
|
||||
for mircColourFg in range(len(Colours)):
|
||||
colourBlend = self._blendColours(mircColour, mircColourFg)
|
||||
self._brushesBlend[mircColour][mircColourFg] = wx.Brush(wx.Colour(colourBlend), wx.BRUSHSTYLE_SOLID)
|
||||
self._pensBlend[mircColour][mircColourFg] = wx.Pen(wx.Colour(colourBlend), 1)
|
||||
|
||||
def _reshapeArabic(self, canvas, eventDc, isCursor, patch, point):
|
||||
patches = []
|
||||
lastCell = point[0]
|
||||
lastCell, patches = point[0], []
|
||||
while True:
|
||||
if ((lastCell + 1) >= (canvas.size[0] - 1)) \
|
||||
or (not canvas.map[point[1]][lastCell + 1][3] in self.arabicShapes):
|
||||
@ -164,40 +132,64 @@ class GuiCanvasWxBackend():
|
||||
if not isCursor:
|
||||
brush, pen = self._brushes[patch[1]], self._pens[patch[1]]
|
||||
else:
|
||||
brush, pen = self._blendColoursBrush(patchBg[1], patch[1])
|
||||
bg = patchBg[1] if patchBg[1] != -1 else 14
|
||||
brush, pen = self._brushesBlend[bg][patch[1]], self._pensBlend[bg][patch[1]]
|
||||
else:
|
||||
if not isCursor:
|
||||
brush, pen = self._brushAlpha, self._penAlpha
|
||||
else:
|
||||
brush, pen = self._blendColoursBrush(patchBg[1], 14)
|
||||
if not isCursor:
|
||||
bg = patchBg[1] if patchBg[1] != -1 else 14
|
||||
brush, pen = self._brushesBlend[bg][14], self._pensBlend[bg][14]
|
||||
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.SetPen(pen);
|
||||
return brush, pen
|
||||
|
||||
def _xlatePoint(self, point):
|
||||
return [a * b for a, b in zip(point, self.cellSize)]
|
||||
|
||||
def drawCursorMaskWithJournal(self, canvas, canvasJournal, eventDc):
|
||||
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0);
|
||||
[self.drawPatch(canvas, eventDc, patch) for patch in canvasJournal.popCursor()]
|
||||
self.drawPatches(canvas, eventDc, canvasJournal.popCursor(), True)
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
|
||||
def drawPatch(self, canvas, eventDc, patch, isCursor=False):
|
||||
def drawPatches(self, canvas, eventDc, patches, isCursor=False):
|
||||
patchDeltaCells, patchesRender = [], []
|
||||
for patch in patches:
|
||||
point = patch[:2]
|
||||
if [(c >= 0) and (c < s) for c, s in zip(point, self.canvasSize)] == [True, True]:
|
||||
if patch[5] in self.arabicShapes:
|
||||
for patchReshaped in self._reshapeArabic(canvas, eventDc, isCursor, patch, point):
|
||||
self._drawPatch(eventDc, isCursor, patchReshaped[2:], canvas.map[patchReshaped[1]][patchReshaped[0]], patchReshaped[:2])
|
||||
patchesRender += [patchReshaped]
|
||||
else:
|
||||
self._drawPatch(eventDc, isCursor, patch[2:], canvas.map[patch[1]][patch[0]], point)
|
||||
return True
|
||||
patchesRender += [patch]
|
||||
for patchRender in patchesRender:
|
||||
absPoint, charFlag = [a * b for a, b in zip(self.cellSize, patchRender[:2])], False
|
||||
if (patchRender[5] == " ") and (patchRender[3] == -1):
|
||||
charFlag, patchRender = True, [*patchRender[:-1], "░"]
|
||||
textBg, textFg = wx.Colour(Colours[patchRender[3]][:4]), wx.Colour(Colours[patchRender[2]][:4])
|
||||
if isCursor and (patchRender[5] == " ") and ((canvas.map[patchRender[1]][patchRender[0]][3] != " ") or (canvas.map[patchRender[1]][patchRender[0]][2] & self._CellState.CS_UNDERLINE)):
|
||||
charFlag, patchRender = True, [*patchRender[:-2], *canvas.map[patchRender[1]][patchRender[0]][2:]]
|
||||
textFg = wx.Colour(self._blendColours(canvas.map[patchRender[1]][patchRender[0]][0], patchRender[2]))
|
||||
elif (patchRender[5] != " ") or (patchRender[4] & self._CellState.CS_UNDERLINE):
|
||||
charFlag = True
|
||||
textBg, textFg = wx.Colour(Colours[patchRender[3]][:4]), wx.Colour(Colours[patchRender[2]][:4])
|
||||
brush, pen = self._setBrushColours(eventDc, isCursor, patchRender[2:], canvas.map[patchRender[1]][patchRender[0]])
|
||||
eventDc.DrawRectangle(*absPoint, *self.cellSize)
|
||||
if charFlag:
|
||||
if (patchRender[4] & self._CellState.CS_UNDERLINE) or (patchRender[5] == "_"):
|
||||
if isCursor and (patchRender[5] == " ") and ((canvas.map[patchRender[1]][patchRender[0]][3] != " ") or (canvas.map[patchRender[1]][patchRender[0]][2] & self._CellState.CS_UNDERLINE)):
|
||||
eventDc.SetPen(self._pensBlend[patchRender[2]][patchRender[3]])
|
||||
else:
|
||||
return False
|
||||
eventDc.SetPen(self._pens[patchRender[2]])
|
||||
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 patchRender[5] != "_":
|
||||
oldClippingRegion = eventDc.GetClippingBox()
|
||||
eventDc.SetFont(self._font)
|
||||
eventDc.DestroyClippingRegion(); eventDc.SetClippingRegion(*absPoint, *self.cellSize);
|
||||
eventDc.SetTextForeground(textFg); eventDc.DrawText(patchRender[5], *absPoint);
|
||||
eventDc.DestroyClippingRegion()
|
||||
patchDeltaCells += [[*patchRender[:2], *canvas.map[patchRender[1]][patchRender[0]]]]
|
||||
return patchDeltaCells
|
||||
|
||||
def getDeviceContext(self, clientSize, parentWindow, viewRect=None):
|
||||
if viewRect == None:
|
||||
|
0
liboperators/OperatorRotate.py
Executable file → Normal file
0
liboperators/OperatorRotate.py
Executable file → Normal file
0
liboperators/OperatorTile.py
Executable file → Normal file
0
liboperators/OperatorTile.py
Executable file → Normal file
@ -11,10 +11,6 @@ from RtlPlatform import getLocalConfPathName
|
||||
import json, os, sys, wx
|
||||
|
||||
class RoarAssetsWindow(GuiMiniFrame):
|
||||
def _drawPatch(self, canvas, eventDc, isCursor, patch):
|
||||
if not isCursor:
|
||||
self.backend.drawPatch(canvas, eventDc, patch)
|
||||
|
||||
def _import(self, f, pathName):
|
||||
rc = False
|
||||
self.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
|
||||
@ -118,9 +114,11 @@ class RoarAssetsWindow(GuiMiniFrame):
|
||||
self.backend.resize(canvas.size, self.cellSize)
|
||||
eventDc = self.backend.getDeviceContext(self.panelCanvas.GetClientSize(), self.panelCanvas)
|
||||
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0);
|
||||
patches = []
|
||||
for numRow in range(canvas.size[1]):
|
||||
for numCol in range(canvas.size[0]):
|
||||
self.backend.drawPatch(canvas, eventDc, [numCol, numRow, *canvas.map[numRow][numCol]])
|
||||
patches += [[numCol, numRow, *canvas.map[numRow][numCol]]]
|
||||
self.backend.drawPatches(canvas, eventDc, patches, isCursor=False)
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
|
||||
def onPaint(self, event):
|
||||
@ -154,14 +152,16 @@ class RoarAssetsWindow(GuiMiniFrame):
|
||||
self.backend.resize(newSize, self.cellSize)
|
||||
eventDc = self.backend.getDeviceContext(self.panelCanvas.GetClientSize(), self.panelCanvas)
|
||||
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0);
|
||||
patches = []
|
||||
if deltaSize[0] > 0:
|
||||
for numRow in range(oldSize[1]):
|
||||
for numNewCol in range(oldSize[0], newSize[0]):
|
||||
self._drawPatch(canvas, eventDc, False, [numNewCol, numRow, 1, 1, 0, " "])
|
||||
patches += [[numNewCol, numRow, 1, 1, 0, " "]]
|
||||
if deltaSize[1] > 1:
|
||||
for numNewRow in range(oldSize[1], newSize[1]):
|
||||
for numNewCol in range(newSize[0]):
|
||||
self._drawPatch(canvas, eventDc, False, [numNewCol, numNewRow, 1, 1, 0, " "])
|
||||
patches += [[numNewCol, numNewRow, 1, 1, 0, " "]]
|
||||
self.backend.drawPatches(canvas, eventDc, patches, isCursor=False)
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
|
||||
def update(self, canvas, newSize, newCanvas=None):
|
||||
@ -169,9 +169,11 @@ class RoarAssetsWindow(GuiMiniFrame):
|
||||
canvas.update(newSize, newCanvas);
|
||||
eventDc = self.backend.getDeviceContext(self.panelCanvas.GetClientSize(), self.panelCanvas)
|
||||
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0);
|
||||
patches = []
|
||||
for numRow in range(canvas.size[1]):
|
||||
for numCol in range(canvas.size[0]):
|
||||
self.backend.drawPatch(canvas, eventDc, [numCol, numRow, *canvas.map[numRow][numCol]])
|
||||
patches += [[numCol, numRow, *canvas.map[numRow][numCol]]]
|
||||
self.backend.drawPatches(canvas, eventDc, patches, isCursor=False)
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
|
||||
def onImportAnsi(self, event):
|
||||
|
@ -194,14 +194,12 @@ class RoarCanvasCommandsEdit():
|
||||
|
||||
@GuiCommandDecorator("Redo", "&Redo", ["", wx.ART_REDO], [wx.ACCEL_CTRL, ord("Y")], False)
|
||||
def canvasRedo(self, event):
|
||||
eventDc = self.parentCanvas.backend.getDeviceContext(self.parentCanvas.GetClientSize(), self.parentCanvas, self.parentCanvas.GetViewStart())
|
||||
self.parentCanvas.dispatchDeltaPatches(self.parentCanvas.canvas.journal.popRedo(), eventDc=eventDc, forceDirtyCursor=True)
|
||||
self.parentCanvas.dispatchDeltaPatches(self.parentCanvas.canvas.journal.popRedo(), forceDirtyCursor=True)
|
||||
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)
|
||||
def canvasUndo(self, event):
|
||||
eventDc = self.parentCanvas.backend.getDeviceContext(self.parentCanvas.GetClientSize(), self.parentCanvas, self.parentCanvas.GetViewStart())
|
||||
self.parentCanvas.dispatchDeltaPatches(self.parentCanvas.canvas.journal.popUndo(), eventDc=eventDc, forceDirtyCursor=True)
|
||||
self.parentCanvas.dispatchDeltaPatches(self.parentCanvas.canvas.journal.popUndo(), forceDirtyCursor=True)
|
||||
self.update(size=self.parentCanvas.canvas.size, undoLevel=self.parentCanvas.canvas.journal.patchesUndoLevel)
|
||||
|
||||
def __init__(self):
|
||||
|
@ -40,97 +40,86 @@ class RoarCanvasWindowDropTarget(wx.TextDropTarget):
|
||||
super().__init__(); self.inProgress, self.parent = False, parent;
|
||||
|
||||
class RoarCanvasWindow(GuiWindow):
|
||||
def _drawPatch(self, eventDc, isCursor, patch):
|
||||
if not self.canvas.dirtyCursor:
|
||||
self.backend.drawCursorMaskWithJournal(self.canvas, self.canvas.journal, eventDc)
|
||||
self.canvas.dirtyCursor = True
|
||||
if self.backend.drawPatch(self.canvas, eventDc, patch, isCursor=isCursor) and isCursor:
|
||||
patchDeltaCell = self.canvas.map[patch[1]][patch[0]]; patchDelta = [*patch[0:2], *patchDeltaCell];
|
||||
self.canvas.journal.pushCursor(patchDelta)
|
||||
def _applyPatches(self, eventDc, patches, patchesCursor, rc):
|
||||
if rc:
|
||||
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0);
|
||||
if ((patches != None) and (len(patches) > 0)) \
|
||||
or ((patchesCursor != None) and (len(patchesCursor) > 0)):
|
||||
self.backend.drawCursorMaskWithJournal(self.canvas, self.canvas.journal, eventDc); self.canvas.dirtyCursor = True;
|
||||
if (patches != None) and (len(patches) > 0):
|
||||
self.backend.drawPatches(self.canvas, eventDc, patches, isCursor=False)
|
||||
self.dirty = True if not self.dirty else self.dirty;
|
||||
self.canvas.journal.begin()
|
||||
for patch in patches if patches != None else []:
|
||||
self.canvas.dispatchPatchSingle(False, patch, commitUndo=True)
|
||||
self.canvas.journal.end()
|
||||
if patchesCursor != None:
|
||||
patchesCursorDeltaCells = self.backend.drawPatches(self.canvas, eventDc, patchesCursor, isCursor=True)
|
||||
if len(patchesCursorDeltaCells) > 0:
|
||||
self.canvas.dirtyCursor = False if self.canvas.dirtyCursor else self.canvas.dirtyCursor
|
||||
for patchCursorDeltaCell in patchesCursorDeltaCells:
|
||||
self.canvas.journal.pushCursor(patchCursorDeltaCell)
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
self.commands.update(dirty=self.dirty, cellPos=self.brushPos, undoLevel=self.canvas.journal.patchesUndoLevel)
|
||||
|
||||
def applyOperator(self, currentTool, mapPoint, mouseLeftDown, mousePoint, operator, viewRect):
|
||||
self.canvas.dirtyCursor = False
|
||||
if (currentTool.__class__ == ToolObject) \
|
||||
and (currentTool.toolState >= currentTool.TS_SELECT):
|
||||
eventDc, patches, patchesCursor, rc = self.backend.getDeviceContext(self.GetClientSize(), self), None, None, True
|
||||
if (currentTool.__class__ == ToolObject) and (currentTool.toolState >= currentTool.TS_SELECT):
|
||||
region = currentTool.getRegion(self.canvas)
|
||||
else:
|
||||
region = self.canvas.map
|
||||
if hasattr(operator, "apply2"):
|
||||
if mouseLeftDown:
|
||||
if self.commands.operatorState == None:
|
||||
self.commands.operatorState = True
|
||||
self.commands.operatorState = True if self.commands.operatorState == None else self.commands.operatorState
|
||||
region = operator.apply2(mapPoint, mousePoint, region, copy.deepcopy(region))
|
||||
self.commands.update(operator=self.commands.currentOperator.name)
|
||||
elif self.commands.operatorState != None:
|
||||
self.commands.currentOperator = None
|
||||
self.commands.update(operator=None)
|
||||
return
|
||||
self.commands.currentOperator = None; self.commands.update(operator=None); rc = False;
|
||||
else:
|
||||
region = operator.apply(copy.deepcopy(region))
|
||||
self.commands.currentOperator = None
|
||||
if (currentTool.__class__ == ToolObject) \
|
||||
and (currentTool.toolState >= currentTool.TS_SELECT):
|
||||
eventDc = self.backend.getDeviceContext(self.GetClientSize(), self) if self.popupEventDc == None else self.popupEventDc
|
||||
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0);
|
||||
region = operator.apply(copy.deepcopy(region)); self.commands.currentOperator = None;
|
||||
if rc:
|
||||
if (currentTool.__class__ == ToolObject) and (currentTool.toolState >= currentTool.TS_SELECT):
|
||||
currentTool.setRegion(self.canvas, None, region, [len(region[0]), len(region)], currentTool.external)
|
||||
currentTool.onSelectEvent(self.canvas, (0, 0), self.dispatchPatchSingle, eventDc, True, wx.MOD_NONE, None, currentTool.targetRect)
|
||||
currentTool._drawSelectRect(currentTool.targetRect, self.dispatchPatchSingle, eventDc)
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
rc, patches, patchesCursor = currentTool.onSelectEvent(self.canvas, (0, 0), True, wx.MOD_NONE, None, currentTool.targetRect)
|
||||
patchesCursor = [] if patchesCursor == None else patchesCursor
|
||||
patchesCursor += currentTool._drawSelectRect(currentTool.targetRect)
|
||||
else:
|
||||
eventDc = self.backend.getDeviceContext(self.GetClientSize(), self) if self.popupEventDc == None else self.popupEventDc
|
||||
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0);
|
||||
self.canvas.journal.begin()
|
||||
patches = []
|
||||
for numRow in range(len(region)):
|
||||
for numCol in range(len(region[numRow])):
|
||||
self.dirty = True if not self.dirty else self.dirty
|
||||
self.dispatchPatchSingle(eventDc, False, [numCol, numRow, *region[numRow][numCol]])
|
||||
self.canvas.journal.end()
|
||||
self.commands.update(dirty=self.dirty, undoLevel=self.canvas.journal.patchesUndoLevel)
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
patches += [[numCol, numRow, *region[numRow][numCol]]]
|
||||
self._applyPatches(eventDc, patches, patchesCursor, rc)
|
||||
return rc
|
||||
|
||||
def applyTool(self, eventDc, eventMouse, keyChar, keyCode, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown, tool, viewRect, force=False):
|
||||
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0);
|
||||
dirty, self.canvas.dirtyCursor, rc = False, False, False
|
||||
self.canvas.journal.begin()
|
||||
dirty, patches, patchesCursor, rc = False, None, None, False
|
||||
if eventMouse:
|
||||
if force:
|
||||
self.lastCellState = None
|
||||
if ((mapPoint[0] < self.canvas.size[0]) \
|
||||
and (mapPoint[1] < self.canvas.size[1])) \
|
||||
and ((self.lastCellState == None) \
|
||||
or (self.lastCellState != [list(mapPoint), mouseDragging, mouseLeftDown, mouseRightDown, list(viewRect)])):
|
||||
if tool.__class__ != ToolText:
|
||||
self.brushPos = list(mapPoint)
|
||||
self.lastCellState = None if force else self.lastCellState
|
||||
if ((mapPoint[0] < self.canvas.size[0]) and (mapPoint[1] < self.canvas.size[1])) \
|
||||
and ((self.lastCellState == None) or (self.lastCellState != [list(mapPoint), mouseDragging, mouseLeftDown, mouseRightDown, list(viewRect)])):
|
||||
self.brushPos = list(mapPoint) if tool.__class__ != ToolText else self.brushPos
|
||||
if tool != None:
|
||||
rc, dirty = tool.onMouseEvent(mapPoint, self.brushColours, self.brushPos, self.brushSize, self.canvas, self.dispatchPatchSingle, eventDc, keyModifiers, self.brushPos, mouseDragging, mouseLeftDown, mouseRightDown)
|
||||
rc, patches, patchesCursor = tool.onMouseEvent(mapPoint, self.brushColours, self.brushPos, self.brushSize, self.canvas, keyModifiers, self.brushPos, mouseDragging, mouseLeftDown, mouseRightDown)
|
||||
else:
|
||||
self.dispatchPatchSingle(eventDc, True, [*mapPoint, self.brushColours[0], self.brushColours[0], 0, " "])
|
||||
rc, patches, patchesCursor = True, None, [[*mapPoint, self.brushColours[0], self.brushColours[0], 0, " "]]
|
||||
self.lastCellState = [list(mapPoint), mouseDragging, mouseLeftDown, mouseRightDown, list(viewRect)]
|
||||
else:
|
||||
if tool != None:
|
||||
rc, dirty = tool.onKeyboardEvent(mapPoint, self.brushColours, self.brushPos, self.brushSize, self.canvas, self.dispatchPatchSingle, eventDc, keyChar, keyCode, keyModifiers, self.brushPos)
|
||||
rc, patches, patchesCursor = tool.onKeyboardEvent(mapPoint, self.brushColours, self.brushPos, self.brushSize, self.canvas, keyChar, keyCode, keyModifiers, self.brushPos)
|
||||
elif mapPoint != None:
|
||||
self.dispatchPatchSingle(eventDc, True, [*mapPoint, self.brushColours[0], self.brushColours[0], 0, " "])
|
||||
self.canvas.journal.end()
|
||||
if dirty:
|
||||
self.dirty = True
|
||||
self.commands.update(dirty=self.dirty, cellPos=self.brushPos, undoLevel=self.canvas.journal.patchesUndoLevel)
|
||||
else:
|
||||
self.commands.update(cellPos=self.brushPos)
|
||||
if rc and (tool.__class__ == ToolObject):
|
||||
rc, patches, patchesCursor = True, None, [[*mapPoint, self.brushColours[0], self.brushColours[0], 0, " "]]
|
||||
if rc:
|
||||
self._applyPatches(eventDc, patches, patchesCursor, rc)
|
||||
if tool.__class__ == ToolObject:
|
||||
if tool.toolState > tool.TS_NONE:
|
||||
self.commands.update(undoInhibit=True)
|
||||
elif tool.toolState == tool.TS_NONE:
|
||||
if tool.external:
|
||||
self.dropTarget.done()
|
||||
self.commands.currentTool, self.commands.lastTool = self.commands.lastTool, self.commands.currentTool
|
||||
if self.commands.currentTool != None:
|
||||
self.commands.update(toolName=self.commands.currentTool.name, undoInhibit=False)
|
||||
else:
|
||||
self.commands.update(toolName="Cursor", undoInhibit=False)
|
||||
self.dropTarget.done(); self.commands.currentTool, self.commands.lastTool = self.commands.lastTool, self.commands.currentTool;
|
||||
newToolName = "Cursor" if self.commands.currentTool == None else self.commands.currentTool.name
|
||||
self.commands.update(toolName=newToolName, undoInhibit=False)
|
||||
else:
|
||||
self.commands.update(undoInhibit=False)
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
return rc
|
||||
|
||||
def dispatchDeltaPatches(self, deltaPatches, eventDc=None, forceDirtyCursor=True):
|
||||
@ -140,6 +129,7 @@ class RoarCanvasWindow(GuiWindow):
|
||||
if self.canvas.dirtyCursor or forceDirtyCursor:
|
||||
self.backend.drawCursorMaskWithJournal(self.canvas, self.canvas.journal, eventDc)
|
||||
self.canvas.dirtyCursor = False
|
||||
patches = []
|
||||
for patch in deltaPatches:
|
||||
if patch == None:
|
||||
continue
|
||||
@ -148,46 +138,8 @@ class RoarCanvasWindow(GuiWindow):
|
||||
eventDc = self.backend.getDeviceContext(self.GetClientSize(), self)
|
||||
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0);
|
||||
else:
|
||||
self.canvas._commitPatch(patch); self.backend.drawPatch(self.canvas, eventDc, patch)
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
|
||||
def dispatchPatch(self, eventDc, isCursor, patch):
|
||||
if self.canvas.dispatchPatch(isCursor, patch, False if isCursor else True):
|
||||
self._drawPatch(eventDc, isCursor, patch)
|
||||
|
||||
def dispatchPatchSingle(self, eventDc, isCursor, patch):
|
||||
if self.canvas.dispatchPatchSingle(isCursor, patch, False if isCursor else True):
|
||||
self._drawPatch(eventDc, isCursor, patch)
|
||||
|
||||
def resize(self, newSize, commitUndo=True, dirty=True):
|
||||
viewRect = self.GetViewStart()
|
||||
oldSize = [0, 0] if self.canvas.map == None else self.canvas.size
|
||||
deltaSize = [b - a for a, b in zip(oldSize, newSize)]
|
||||
if self.canvas.resize(newSize, commitUndo):
|
||||
super().resize([a * b for a, b in zip(newSize, self.backend.cellSize)])
|
||||
self.backend.resize(newSize, self.backend.cellSize)
|
||||
eventDc = self.backend.getDeviceContext(self.GetClientSize(), self)
|
||||
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0);
|
||||
if deltaSize[0] > 0:
|
||||
for numRow in range(oldSize[1]):
|
||||
for numNewCol in range(oldSize[0], newSize[0]):
|
||||
self._drawPatch(eventDc, False, [numNewCol, numRow, 1, 1, 0, " "])
|
||||
if deltaSize[1] > 1:
|
||||
for numNewRow in range(oldSize[1], newSize[1]):
|
||||
for numNewCol in range(newSize[0]):
|
||||
self._drawPatch(eventDc, False, [numNewCol, numNewRow, 1, 1, 0, " "])
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
self.Scroll(*viewRect); self.dirty = dirty;
|
||||
self.commands.update(dirty=self.dirty, size=newSize, undoLevel=self.canvas.journal.patchesUndoLevel)
|
||||
|
||||
def update(self, newSize, commitUndo=True, newCanvas=None, dirty=True):
|
||||
self.resize(newSize, commitUndo, dirty)
|
||||
self.canvas.update(newSize, newCanvas)
|
||||
eventDc = self.backend.getDeviceContext(self.GetClientSize(), self, self.GetViewStart())
|
||||
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0);
|
||||
for numRow in range(newSize[1]):
|
||||
for numCol in range(newSize[0]):
|
||||
self.backend.drawPatch(self.canvas, eventDc, [numCol, numRow, *self.canvas.map[numRow][numCol]])
|
||||
self.canvas._commitPatch(patch); patches += [patch];
|
||||
self.backend.drawPatches(self.canvas, eventDc, patches, isCursor=False)
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
|
||||
def onKeyboardInput(self, event):
|
||||
@ -268,9 +220,11 @@ class RoarCanvasWindow(GuiWindow):
|
||||
self.backend.resize(self.canvas.size, self.backend.cellSize)
|
||||
eventDc = self.backend.getDeviceContext(self.GetClientSize(), self)
|
||||
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0);
|
||||
patches = []
|
||||
for numRow in range(self.canvas.size[1]):
|
||||
for numCol in range(len(self.canvas.map[numRow])):
|
||||
self._drawPatch(eventDc, False, [numCol, numRow, *self.canvas.map[numRow][numCol]])
|
||||
patches += [[numCol, numRow, *self.canvas.map[numRow][numCol]]]
|
||||
self.backend.drawPatches(self.canvas, eventDc, patches, isCursor=False)
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
else:
|
||||
event.Skip()
|
||||
@ -280,6 +234,40 @@ class RoarCanvasWindow(GuiWindow):
|
||||
self.backend.drawCursorMaskWithJournal(self.canvas, self.canvas.journal, eventDc)
|
||||
self.backend.onPaint(self.GetClientSize(), self, self.GetViewStart())
|
||||
|
||||
def resize(self, newSize, commitUndo=True, dirty=True):
|
||||
viewRect = self.GetViewStart()
|
||||
oldSize = [0, 0] if self.canvas.map == None else self.canvas.size
|
||||
deltaSize = [b - a for a, b in zip(oldSize, newSize)]
|
||||
if self.canvas.resize(newSize, commitUndo):
|
||||
super().resize([a * b for a, b in zip(newSize, self.backend.cellSize)])
|
||||
self.backend.resize(newSize, self.backend.cellSize)
|
||||
eventDc = self.backend.getDeviceContext(self.GetClientSize(), self)
|
||||
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0);
|
||||
patches = []
|
||||
if deltaSize[0] > 0:
|
||||
for numRow in range(oldSize[1]):
|
||||
for numNewCol in range(oldSize[0], newSize[0]):
|
||||
patches += [[numNewCol, numRow, 1, 1, 0, " "]]
|
||||
if deltaSize[1] > 1:
|
||||
for numNewRow in range(oldSize[1], newSize[1]):
|
||||
for numNewCol in range(newSize[0]):
|
||||
patches += [[numNewCol, numNewRow, 1, 1, 0, " "]]
|
||||
self.backend.drawPatches(self.canvas, eventDc, patches, isCursor=False)
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
self.Scroll(*viewRect); self.dirty = dirty;
|
||||
self.commands.update(dirty=self.dirty, size=newSize, undoLevel=self.canvas.journal.patchesUndoLevel)
|
||||
|
||||
def update(self, newSize, commitUndo=True, newCanvas=None, dirty=True):
|
||||
self.resize(newSize, commitUndo, dirty)
|
||||
self.canvas.update(newSize, newCanvas)
|
||||
eventDc = self.backend.getDeviceContext(self.GetClientSize(), self, self.GetViewStart())
|
||||
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0); patches = [];
|
||||
for numRow in range(newSize[1]):
|
||||
for numCol in range(newSize[0]):
|
||||
patches += [[numCol, numRow, *self.canvas.map[numRow][numCol]]]
|
||||
self.backend.drawPatches(self.canvas, eventDc, patches, isCursor=False)
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
|
||||
def __init__(self, backend, canvas, cellSize, commands, parent, parentFrame, pos, scrollStep, size):
|
||||
super().__init__(parent, pos, scrollStep)
|
||||
self.size = size
|
||||
|
30
librtl/Rtl.py
Normal file
30
librtl/Rtl.py
Normal file
@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Rtl.py
|
||||
# Copyright (c) 2018, 2019 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
|
||||
# This project is licensed under the terms of the MIT licence.
|
||||
#
|
||||
|
||||
import statistics, time
|
||||
|
||||
timeState = [None, None, 0, []]
|
||||
|
||||
def flatten(l):
|
||||
return [li for l_ in l for li in l_]
|
||||
|
||||
def timePrint(pfx):
|
||||
timeState[0] = time.time() if timeState[0] == None else timeState[0]
|
||||
t1 = time.time(); td = t1 - timeState[0]
|
||||
if td > 0:
|
||||
timeState[1] = td if timeState[1] == None else min(td, timeState[1])
|
||||
timeState[2] = max(td, timeState[2])
|
||||
timeState[3] += [td]
|
||||
print("{} took {:.4f} ms (min: {:.4f} max: {:.4f} avg: {:.4f})".format(pfx, td * 1000, timeState[1] * 1000, timeState[2] * 1000, statistics.mean(timeState[3]) * 1000))
|
||||
|
||||
def timeReset():
|
||||
timeState = [None, None, 0, []]
|
||||
|
||||
def timeStart():
|
||||
timeState[0] = time.time()
|
||||
|
||||
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
@ -5,10 +5,10 @@
|
||||
#
|
||||
|
||||
class Tool(object):
|
||||
def onKeyboardEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyChar, keyCode, keyModifiers, mapPoint):
|
||||
return False, False
|
||||
def onKeyboardEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, keyChar, keyCode, keyModifiers, mapPoint):
|
||||
return False, None, None
|
||||
|
||||
def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown):
|
||||
return False, False
|
||||
def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown):
|
||||
return False, None, None
|
||||
|
||||
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
||||
|
@ -9,8 +9,8 @@ from Tool import Tool
|
||||
class ToolCircle(Tool):
|
||||
name = "Circle"
|
||||
|
||||
def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown):
|
||||
brushColours, brushSize, dirty = list(brushColours), [brushSize[0] * 2, brushSize[1]], False
|
||||
def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown):
|
||||
brushColours, brushSize, isCursor = list(brushColours), [brushSize[0] * 2, brushSize[1]], not (mouseLeftDown or mouseRightDown)
|
||||
originPoint, radius = (brushSize[0] / 2, brushSize[0] / 2), brushSize[0]
|
||||
if mouseRightDown:
|
||||
brushColours = [brushColours[1], brushColours[0]]
|
||||
@ -22,6 +22,7 @@ class ToolCircle(Tool):
|
||||
cells[-1] += [[mapPoint[i] + int(originPoint[i] + o) for i, o in zip((0, 1,), (brushX, brushY,))]]
|
||||
if cells[-1] == []:
|
||||
del cells[-1]
|
||||
patches = []
|
||||
for numRow in range(len(cells)):
|
||||
for numCol in range(len(cells[numRow])):
|
||||
if ((numRow == 0) or (numRow == (len(cells) - 1))) \
|
||||
@ -41,12 +42,7 @@ class ToolCircle(Tool):
|
||||
patch = [*cells[numRow][numCol], brushColours[1], brushColours[1], 0, " "]
|
||||
else:
|
||||
patch = [*cells[numRow][numCol], brushColours[1], brushColours[1], 0, " "]
|
||||
if mouseLeftDown or mouseRightDown:
|
||||
if not dirty:
|
||||
dirty = True
|
||||
dispatchFn(eventDc, False, patch); dispatchFn(eventDc, True, patch);
|
||||
else:
|
||||
dispatchFn(eventDc, True, patch)
|
||||
return True, dirty
|
||||
patches += [patch]
|
||||
return True, patches if not isCursor else None, patches if isCursor else None
|
||||
|
||||
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
||||
|
@ -9,28 +9,21 @@ from Tool import Tool
|
||||
class ToolErase(Tool):
|
||||
name = "Erase"
|
||||
|
||||
def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown):
|
||||
brushColours, brushSize, dirty = list(brushColours), list(brushSize), False
|
||||
def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown):
|
||||
brushColours, brushSize, isCursor, patches, patchesCursor = list(brushColours), list(brushSize), not (mouseLeftDown or mouseRightDown), [], []
|
||||
if brushSize[0] > 1:
|
||||
brushSize[0] *= 2
|
||||
for brushRow in range(brushSize[1]):
|
||||
for brushCol in range(brushSize[0]):
|
||||
if mouseLeftDown:
|
||||
patch = [mapPoint[0] + brushCol, mapPoint[1] + brushRow, brushColours[1], brushColours[1], 0, " "]
|
||||
if not dirty:
|
||||
dirty = True
|
||||
dispatchFn(eventDc, False, patch); dispatchFn(eventDc, True, patch);
|
||||
patches += [[mapPoint[0] + brushCol, mapPoint[1] + brushRow, brushColours[1], brushColours[1], 0, " "]]
|
||||
elif mouseRightDown \
|
||||
and ((mapPoint[0] + brushCol) < canvas.size[0]) \
|
||||
and ((mapPoint[1] + brushRow) < canvas.size[1]) \
|
||||
and (canvas.map[mapPoint[1] + brushRow][mapPoint[0] + brushCol][1] == brushColours[1]):
|
||||
patch = [mapPoint[0] + brushCol, mapPoint[1] + brushRow, canvas.map[mapPoint[1] + brushRow][mapPoint[0] + brushCol][0], brushColours[0], *canvas.map[mapPoint[1] + brushRow][mapPoint[0] + brushCol][2:]]
|
||||
if not dirty:
|
||||
dirty = True
|
||||
dispatchFn(eventDc, False, patch); dispatchFn(eventDc, True, patch);
|
||||
patches += [[mapPoint[0] + brushCol, mapPoint[1] + brushRow, canvas.map[mapPoint[1] + brushRow][mapPoint[0] + brushCol][0], brushColours[0], *canvas.map[mapPoint[1] + brushRow][mapPoint[0] + brushCol][2:]]]
|
||||
else:
|
||||
patch = [mapPoint[0] + brushCol, mapPoint[1] + brushRow, brushColours[1], brushColours[1], 0, " "]
|
||||
dispatchFn(eventDc, True, patch)
|
||||
return True, dirty
|
||||
patchesCursor += [[mapPoint[0] + brushCol, mapPoint[1] + brushRow, brushColours[1], brushColours[1], 0, " "]]
|
||||
return True, patches if not isCursor else None, patchesCursor
|
||||
|
||||
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
||||
|
@ -10,22 +10,17 @@ import wx
|
||||
class ToolFill(Tool):
|
||||
name = "Fill"
|
||||
|
||||
def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown):
|
||||
dirty, pointsDone, pointStack, testChar, testColour = False, [], [list(mapPoint)], canvas.map[mapPoint[1]][mapPoint[0]][3], canvas.map[mapPoint[1]][mapPoint[0]][0:2]
|
||||
def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown):
|
||||
isCursor, patches, pointsDone, pointStack, testChar, testColour = not (mouseLeftDown or mouseRightDown), [], [], [list(mapPoint)], canvas.map[mapPoint[1]][mapPoint[0]][3], canvas.map[mapPoint[1]][mapPoint[0]][0:2]
|
||||
if mouseLeftDown or mouseRightDown:
|
||||
if mouseLeftDown:
|
||||
fillColour = brushColours[0]
|
||||
else:
|
||||
fillColour = brushColours[1]
|
||||
fillColour = brushColours[0] if mouseLeftDown else brushColours[1]
|
||||
while len(pointStack) > 0:
|
||||
point = pointStack.pop()
|
||||
pointCell = canvas.map[point[1]][point[0]]
|
||||
if ((pointCell[1] == testColour[1]) and ((pointCell[3] == testChar) or (keyModifiers == wx.MOD_CONTROL))) \
|
||||
or ((pointCell[3] == " ") and (pointCell[1] == testColour[1])):
|
||||
if not point in pointsDone:
|
||||
if not dirty:
|
||||
dirty = True
|
||||
dispatchFn(eventDc, False, [*point, fillColour, fillColour, 0, " "])
|
||||
patches += [[*point, fillColour, fillColour, 0, " "]]
|
||||
if point[0] > 0:
|
||||
pointStack.append([point[0] - 1, point[1]])
|
||||
if point[0] < (canvas.size[0] - 1):
|
||||
@ -36,8 +31,7 @@ class ToolFill(Tool):
|
||||
pointStack.append([point[0], point[1] + 1])
|
||||
pointsDone += [point]
|
||||
else:
|
||||
patch = [mapPoint[0], mapPoint[1], brushColours[0], brushColours[0], 0, " "]
|
||||
dispatchFn(eventDc, True, patch)
|
||||
return True, dirty
|
||||
patches = [[mapPoint[0], mapPoint[1], brushColours[0], brushColours[0], 0, " "]]
|
||||
return True, patches if not isCursor else None, patches if isCursor else None
|
||||
|
||||
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
||||
|
@ -11,9 +11,8 @@ class ToolLine(Tool):
|
||||
TS_NONE = 0
|
||||
TS_ORIGIN = 1
|
||||
|
||||
def _getLine(self, brushColours, brushSize, dispatchFn, eventDc, isCursor, originPoint, targetPoint):
|
||||
dirty = False
|
||||
originPoint, targetPoint = originPoint.copy(), targetPoint.copy()
|
||||
def _getLine(self, brushColours, brushSize, isCursor, originPoint, targetPoint):
|
||||
originPoint, patches, targetPoint = originPoint.copy(), [], targetPoint.copy()
|
||||
pointDelta = self._pointDelta(originPoint, targetPoint)
|
||||
lineXSign = 1 if pointDelta[0] > 0 else -1; lineYSign = 1 if pointDelta[1] > 0 else -1;
|
||||
pointDelta = [abs(a) for a in pointDelta]
|
||||
@ -27,21 +26,15 @@ class ToolLine(Tool):
|
||||
for lineX in range(pointDelta[0] + 1):
|
||||
for brushStep in range(brushSize[0]):
|
||||
if not ([originPoint[0] + lineX * lineXX + lineY * lineYX + brushStep, originPoint[1] + lineX * lineXY + lineY * lineYY] in pointsDone):
|
||||
patch = [ \
|
||||
patches += [[ \
|
||||
originPoint[0] + lineX * lineXX + lineY * lineYX + brushStep, \
|
||||
originPoint[1] + lineX * lineXY + lineY * lineYY, \
|
||||
*brushColours, 0, " "]
|
||||
if not isCursor:
|
||||
if not dirty:
|
||||
dirty = True
|
||||
dispatchFn(eventDc, False, patch)
|
||||
else:
|
||||
dispatchFn(eventDc, True, patch)
|
||||
*brushColours, 0, " "]]
|
||||
pointsDone += [[originPoint[0] + lineX * lineXX + lineY * lineYX + brushStep, originPoint[1] + lineX * lineXY + lineY * lineYY]]
|
||||
if lineD > 0:
|
||||
lineD -= pointDelta[0]; lineY += 1;
|
||||
lineD += pointDelta[1]
|
||||
return dirty
|
||||
return patches
|
||||
|
||||
def _pointDelta(self, a, b):
|
||||
return [a2 - a1 for a1, a2 in zip(a, b)]
|
||||
@ -49,8 +42,8 @@ class ToolLine(Tool):
|
||||
def _pointSwap(self, a, b):
|
||||
return [b, a]
|
||||
|
||||
def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown):
|
||||
brushColours, dirty = brushColours.copy(), False
|
||||
def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown):
|
||||
brushColours, isCursor, patches, rc = brushColours.copy(), not (mouseLeftDown or mouseRightDown), [], False
|
||||
if mouseLeftDown:
|
||||
brushColours[1] = brushColours[0]
|
||||
elif mouseRightDown:
|
||||
@ -60,17 +53,20 @@ class ToolLine(Tool):
|
||||
if self.toolState == self.TS_NONE:
|
||||
if mouseLeftDown or mouseRightDown:
|
||||
self.toolOriginPoint, self.toolState = list(mapPoint), self.TS_ORIGIN
|
||||
dispatchFn(eventDc, True, [*mapPoint, *brushColours, 0, " "])
|
||||
patches, rc = [], True
|
||||
for brushCol in range(brushSize[0]):
|
||||
if ((mapPoint[0] + brushCol) < canvas.size[0]) \
|
||||
and (mapPoint[1] < canvas.size[1]):
|
||||
patches += [[mapPoint[0] + brushCol, mapPoint[1], *brushColours, 0, " "]]
|
||||
elif self.toolState == self.TS_ORIGIN:
|
||||
originPoint, targetPoint = self.toolOriginPoint, list(mapPoint)
|
||||
if mouseLeftDown or mouseRightDown:
|
||||
dirty = self._getLine(brushColours, brushSize, dispatchFn, eventDc, False, originPoint, targetPoint)
|
||||
patches = self._getLine(brushColours, brushSize, False, originPoint, targetPoint)
|
||||
self.toolOriginPoint, self.toolState = None, self.TS_NONE
|
||||
else:
|
||||
dirty = self._getLine(brushColours, brushSize, dispatchFn, eventDc, True, originPoint, targetPoint)
|
||||
else:
|
||||
return False, dirty
|
||||
return True, dirty
|
||||
patches = self._getLine(brushColours, brushSize, True, originPoint, targetPoint)
|
||||
rc = True
|
||||
return rc, patches if not isCursor else None, patches if isCursor else None
|
||||
|
||||
def __init__(self, *args):
|
||||
super().__init__(*args)
|
||||
|
@ -14,19 +14,21 @@ class ToolObject(Tool):
|
||||
TS_SELECT = 2
|
||||
TS_TARGET = 3
|
||||
|
||||
def _dispatchSelectEvent(self, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseLeftDown, selectRect):
|
||||
def _dispatchSelectEvent(self, canvas, keyModifiers, mapPoint, mouseLeftDown, selectRect):
|
||||
if mouseLeftDown:
|
||||
disp, isCursor = [mapPoint[m] - self.lastAtPoint[m] for m in [0, 1]], True
|
||||
newTargetRect = [[selectRect[n][m] + disp[m] for m in [0, 1]] for n in [0, 1]]
|
||||
self.lastAtPoint = list(mapPoint)
|
||||
else:
|
||||
disp, isCursor, newTargetRect = [0, 0], True, selectRect.copy()
|
||||
dirty = self.onSelectEvent(canvas, disp, dispatchFn, eventDc, isCursor, keyModifiers, newTargetRect, selectRect)
|
||||
self._drawSelectRect(newTargetRect, dispatchFn, eventDc)
|
||||
rc, patches, patchesCursor = self.onSelectEvent(canvas, disp, isCursor, keyModifiers, newTargetRect, selectRect)
|
||||
patchesCursor = [] if patchesCursor == None else patchesCursor
|
||||
patchesCursor += self._drawSelectRect(newTargetRect)
|
||||
self.targetRect = newTargetRect
|
||||
return dirty
|
||||
return rc, patches, patchesCursor
|
||||
|
||||
def _drawSelectRect(self, rect, dispatchFn, eventDc):
|
||||
def _drawSelectRect(self, rect):
|
||||
patches = []
|
||||
rectFrame = [[rect[m][n] for n in [0, 1]] for m in (0, 1)]
|
||||
if rectFrame[0][0] > rectFrame[1][0]:
|
||||
rectFrame[0][0], rectFrame[1][0] = rectFrame[1][0], rectFrame[0][0]
|
||||
@ -35,25 +37,19 @@ class ToolObject(Tool):
|
||||
curColours, rectFrame = [0, 0], [[rectFrame[m[0]][n] + m[1] for n in [0, 1]] for m in [[0, -1], [1, +1]]]
|
||||
for rectX in range(rectFrame[0][0], rectFrame[1][0] + 1):
|
||||
curColours = [1, 1] if curColours == [0, 0] else [0, 0]
|
||||
dispatchFn(eventDc, True, [rectX, rectFrame[0][1], *curColours, 0, " "])
|
||||
dispatchFn(eventDc, True, [rectX, rectFrame[1][1], *curColours, 0, " "])
|
||||
patches += [[rectX, rectFrame[0][1], *curColours, 0, " "], [rectX, rectFrame[1][1], *curColours, 0, " "]]
|
||||
for rectY in range(rectFrame[0][1], rectFrame[1][1] + 1):
|
||||
curColours = [1, 1] if curColours == [0, 0] else [0, 0]
|
||||
dispatchFn(eventDc, True, [rectFrame[0][0], rectY, *curColours, 0, " "])
|
||||
dispatchFn(eventDc, True, [rectFrame[1][0], rectY, *curColours, 0, " "])
|
||||
patches += [[rectFrame[0][0], rectY, *curColours, 0, " "], [rectFrame[1][0], rectY, *curColours, 0, " "]]
|
||||
return patches
|
||||
|
||||
def _mouseEventTsNone(self, brushColours, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown):
|
||||
self.substract = False
|
||||
if self.external:
|
||||
dispatchFn(eventDc, True, [*mapPoint, *brushColours, 0, " "])
|
||||
else:
|
||||
if mouseLeftDown:
|
||||
def _mouseEventTsNone(self, brushColours, canvas, keyModifiers, mapPoint, mouseDragging, mouseLeftDown):
|
||||
patchesCursor = [[*mapPoint, brushColours[0], brushColours[0], 0, " "]]; self.substract = False;
|
||||
if (not self.external) and mouseLeftDown:
|
||||
self.targetRect, self.toolState = [list(mapPoint), []], self.TS_ORIGIN
|
||||
else:
|
||||
dispatchFn(eventDc, True, [*mapPoint, *brushColours, 0, " "])
|
||||
return False
|
||||
return True, None, patchesCursor
|
||||
|
||||
def _mouseEventTsOrigin(self, brushColours, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown):
|
||||
def _mouseEventTsOrigin(self, brushColours, canvas, keyModifiers, mapPoint, mouseDragging, mouseLeftDown):
|
||||
self.targetRect[1] = list(mapPoint)
|
||||
if not mouseLeftDown:
|
||||
if self.targetRect[0][0] > self.targetRect[1][0]:
|
||||
@ -66,13 +62,10 @@ class ToolObject(Tool):
|
||||
for numCol in range((self.targetRect[1][0] - self.targetRect[0][0]) + 1):
|
||||
rectX, rectY = self.targetRect[0][0] + numCol, self.targetRect[0][1] + numRow
|
||||
self.objectMap[numRow].append(canvas.map[rectY][rectX])
|
||||
self._drawSelectRect(self.targetRect, dispatchFn, eventDc)
|
||||
else:
|
||||
self._drawSelectRect(self.targetRect, dispatchFn, eventDc)
|
||||
return False
|
||||
return True, None, self._drawSelectRect(self.targetRect)
|
||||
|
||||
def _mouseEventTsSelect(self, brushColours, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown):
|
||||
dirty = False
|
||||
def _mouseEventTsSelect(self, brushColours, canvas, keyModifiers, mapPoint, mouseDragging, mouseLeftDown):
|
||||
rc, patches, patchesCursor = False, None, None
|
||||
if mouseLeftDown:
|
||||
if (mapPoint[0] >= (self.targetRect[0][0] - 1)) \
|
||||
and (mapPoint[0] <= (self.targetRect[1][0] + 1)) \
|
||||
@ -80,80 +73,78 @@ class ToolObject(Tool):
|
||||
and (mapPoint[1] <= (self.targetRect[1][1] + 1)):
|
||||
self.lastAtPoint, self.toolState = list(mapPoint), self.TS_TARGET
|
||||
else:
|
||||
dirty = self.onSelectEvent(canvas, (0, 0), dispatchFn, eventDc, False, keyModifiers, self.targetRect.copy(), self.targetRect)
|
||||
self._drawSelectRect(self.targetRect, dispatchFn, eventDc)
|
||||
rc, patches, patchesCursor = self.onSelectEvent(canvas, (0, 0), False, keyModifiers, self.targetRect.copy(), self.targetRect)
|
||||
patchesCursor = [] if patchesCursor == None else patchesCursor
|
||||
patchesCursor += self._drawSelectRect(self.targetRect)
|
||||
self.objectMap, self.objectSize, self.targetRect, self.toolState = None, None, None, self.TS_NONE
|
||||
else:
|
||||
dirty = self._dispatchSelectEvent(canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseLeftDown, self.targetRect)
|
||||
return dirty
|
||||
rc, patches, patchesCursor = self._dispatchSelectEvent(canvas, keyModifiers, mapPoint, mouseLeftDown, self.targetRect)
|
||||
return rc, patches, patchesCursor
|
||||
|
||||
def _mouseEventTsTarget(self, brushColours, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown):
|
||||
def _mouseEventTsTarget(self, brushColours, canvas, keyModifiers, mapPoint, mouseDragging, mouseLeftDown):
|
||||
rc, patches, patchesCursor = False, None, None
|
||||
if (keyModifiers == wx.MOD_CONTROL) and (self.srcRect == self.targetRect):
|
||||
self.substract = True
|
||||
dirty = False
|
||||
if mouseLeftDown:
|
||||
dirty = self._dispatchSelectEvent(canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseLeftDown, self.targetRect)
|
||||
rc, patches, patchesCursor = self._dispatchSelectEvent(canvas, keyModifiers, mapPoint, mouseLeftDown, self.targetRect)
|
||||
else:
|
||||
self.toolState = self.TS_SELECT
|
||||
return dirty
|
||||
return rc, patches, patchesCursor
|
||||
|
||||
def getRegion(self, canvas):
|
||||
return self.objectMap
|
||||
|
||||
def onKeyboardEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyChar, keyCode, keyModifiers, mapPoint):
|
||||
rc, dirty = False, False
|
||||
if (ord(keyChar) == wx.WXK_ESCAPE) \
|
||||
and (self.toolState >= self.TS_SELECT):
|
||||
dirty = self.onSelectEvent(canvas, (0, 0), dispatchFn, eventDc, False, keyModifiers, self.targetRect.copy(), self.targetRect)
|
||||
self._drawSelectRect(self.targetRect, dispatchFn, eventDc)
|
||||
def onKeyboardEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, keyChar, keyCode, keyModifiers, mapPoint):
|
||||
if (ord(keyChar) == wx.WXK_ESCAPE) and (self.toolState >= self.TS_SELECT):
|
||||
rc, patches, patchesCursor = self.onSelectEvent(canvas, (0, 0), False, keyModifiers, self.targetRect.copy(), self.targetRect)
|
||||
patchesCursor = [] if patchesCursor == None else patchesCursor
|
||||
patchesCursor += self._drawSelectRect(self.targetRect)
|
||||
self.objectMap, self.objectSize, self.targetRect, self.toolState = None, None, None, self.TS_NONE
|
||||
return rc, dirty
|
||||
|
||||
def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown):
|
||||
dirty = False
|
||||
if self.toolState == self.TS_NONE:
|
||||
dirty = self._mouseEventTsNone(brushColours, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown)
|
||||
elif self.toolState == self.TS_SELECT:
|
||||
dirty = self._mouseEventTsSelect(brushColours, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown)
|
||||
elif self.toolState == self.TS_ORIGIN:
|
||||
dirty = self._mouseEventTsOrigin(brushColours, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown)
|
||||
elif self.toolState == self.TS_TARGET:
|
||||
dirty = self._mouseEventTsTarget(brushColours, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown)
|
||||
else:
|
||||
return False, dirty
|
||||
return True, dirty
|
||||
rc, patches, patchesCursor = False, None, None
|
||||
return rc, patches, patchesCursor
|
||||
|
||||
def onSelectEvent(self, canvas, disp, dispatchFn, eventDc, isCursor, keyModifiers, newTargetRect, selectRect):
|
||||
dirty = False
|
||||
def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown):
|
||||
if self.toolState == self.TS_NONE:
|
||||
rc, patches, patchesCursor = self._mouseEventTsNone(brushColours, canvas, keyModifiers, mapPoint, mouseDragging, mouseLeftDown)
|
||||
elif self.toolState == self.TS_SELECT:
|
||||
rc, patches, patchesCursor = self._mouseEventTsSelect(brushColours, canvas, keyModifiers, mapPoint, mouseDragging, mouseLeftDown)
|
||||
elif self.toolState == self.TS_ORIGIN:
|
||||
rc, patches, patchesCursor = self._mouseEventTsOrigin(brushColours, canvas, keyModifiers, mapPoint, mouseDragging, mouseLeftDown)
|
||||
elif self.toolState == self.TS_TARGET:
|
||||
rc, patches, patchesCursor = self._mouseEventTsTarget(brushColours, canvas, keyModifiers, mapPoint, mouseDragging, mouseLeftDown)
|
||||
else:
|
||||
rc, patches, patchesCursor = False, None, None
|
||||
return rc, patches, patchesCursor
|
||||
|
||||
def onSelectEvent(self, canvas, disp, isCursor, keyModifiers, newTargetRect, selectRect):
|
||||
patches = []
|
||||
if self.external:
|
||||
for numRow in range(len(self.objectMap)):
|
||||
for numCol in range(len(self.objectMap[numRow])):
|
||||
rectX, rectY = selectRect[0][0] + numCol, selectRect[0][1] + numRow
|
||||
dirty = False if isCursor else True
|
||||
cellNew = self.objectMap[numRow][numCol]
|
||||
if (cellNew[1] == -1) and (cellNew[3] == " "):
|
||||
if ((rectY + disp[1]) < canvas.size[1]) and ((rectX + disp[0]) < canvas.size[0]):
|
||||
cellNew = canvas.map[rectY + disp[1]][rectX + disp[0]]
|
||||
dispatchFn(eventDc, isCursor, [rectX + disp[0], rectY + disp[1], *cellNew])
|
||||
patches += [[rectX + disp[0], rectY + disp[1], *cellNew]]
|
||||
else:
|
||||
if self.substract:
|
||||
for numRow in range(self.srcRect[0][1], self.srcRect[1][1]):
|
||||
for numCol in range(self.srcRect[0][0], self.srcRect[1][0]):
|
||||
if ((numCol < selectRect[0][0]) or (numCol > selectRect[1][0])) \
|
||||
or ((numRow < selectRect[0][1]) or (numRow > selectRect[1][1])):
|
||||
dirty = False if isCursor else True
|
||||
dispatchFn(eventDc, isCursor, [numCol, numRow, 1, 1, 0, " "])
|
||||
patches += [[numCol, numRow, 1, 1, 0, " "]]
|
||||
for numRow in range(len(self.objectMap)):
|
||||
for numCol in range(len(self.objectMap[numRow])):
|
||||
cellOld = self.objectMap[numRow][numCol]
|
||||
rectX, rectY = selectRect[0][0] + numCol, selectRect[0][1] + numRow
|
||||
dirty = False if isCursor else True
|
||||
cellNew = self.objectMap[numRow][numCol]
|
||||
if (cellNew[1] == -1) and (cellNew[3] == " "):
|
||||
if ((rectY + disp[1]) < canvas.size[1]) and ((rectX + disp[0]) < canvas.size[0]):
|
||||
cellNew = canvas.map[rectY + disp[1]][rectX + disp[0]]
|
||||
dispatchFn(eventDc, isCursor, [rectX + disp[0], rectY + disp[1], *cellNew])
|
||||
return dirty
|
||||
patches += [[rectX + disp[0], rectY + disp[1], *cellNew]]
|
||||
return True, patches if not isCursor else None, patches if isCursor else None
|
||||
|
||||
def setRegion(self, canvas, mapPoint, objectMap, objectSize, external=True):
|
||||
self.external, self.toolState = external, self.TS_SELECT
|
||||
|
@ -9,9 +9,8 @@ from Tool import Tool
|
||||
class ToolPickColour(Tool):
|
||||
name = "Pick colour"
|
||||
|
||||
def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown):
|
||||
if (mapPoint[0] < canvas.size[0]) \
|
||||
and (mapPoint[1] < canvas.size[1]):
|
||||
def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown):
|
||||
if (mapPoint[0] < canvas.size[0]) and (mapPoint[1] < canvas.size[1]):
|
||||
if mouseLeftDown:
|
||||
if canvas.map[mapPoint[1]][mapPoint[0]][3] == " ":
|
||||
brushColours[0] = canvas.map[mapPoint[1]][mapPoint[0]][1]
|
||||
@ -19,7 +18,6 @@ class ToolPickColour(Tool):
|
||||
brushColours[0] = canvas.map[mapPoint[1]][mapPoint[0]][0]
|
||||
elif mouseRightDown:
|
||||
brushColours[1] = canvas.map[mapPoint[1]][mapPoint[0]][1]
|
||||
dispatchFn(eventDc, True, [*mapPoint, *brushColours, 0, "░"])
|
||||
return True, False
|
||||
return True, None, [[*mapPoint, *brushColours, 0, "░"]]
|
||||
|
||||
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
||||
|
@ -9,8 +9,8 @@ from Tool import Tool
|
||||
class ToolRect(Tool):
|
||||
name = "Rectangle"
|
||||
|
||||
def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown):
|
||||
brushColours, brushSize, dirty = list(brushColours), list(brushSize), False
|
||||
def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown):
|
||||
brushColours, brushSize, isCursor, patches = list(brushColours), list(brushSize), not (mouseLeftDown or mouseRightDown), []
|
||||
if mouseRightDown:
|
||||
brushColours = [brushColours[1], brushColours[0]]
|
||||
if brushSize[0] > 1:
|
||||
@ -30,12 +30,7 @@ class ToolRect(Tool):
|
||||
else:
|
||||
patchColours = [brushColours[1]] * 2
|
||||
patch = [mapPoint[0] + brushCol, mapPoint[1] + brushRow, *patchColours, 0, " "]
|
||||
if mouseLeftDown or mouseRightDown:
|
||||
if not dirty:
|
||||
dirty = True
|
||||
dispatchFn(eventDc, False, patch); dispatchFn(eventDc, True, patch);
|
||||
else:
|
||||
dispatchFn(eventDc, True, patch)
|
||||
return True, dirty
|
||||
patches += [patch]
|
||||
return True, patches if not isCursor else None, patches if isCursor else None
|
||||
|
||||
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
||||
|
@ -41,11 +41,12 @@ class ToolText(Tool):
|
||||
break
|
||||
return rtlFlag
|
||||
|
||||
def _processKeyChar(self, brushColours, brushPos, canvas, dispatchFn, eventDc, keyChar, keyModifiers):
|
||||
def _processKeyChar(self, brushColours, brushPos, canvas, keyChar, keyModifiers):
|
||||
patches, rc = [], False
|
||||
if (ord(keyChar) != wx.WXK_NONE) \
|
||||
and (not keyChar in set("\t\n\v\f\r")) \
|
||||
and ((ord(keyChar) >= 32) if ord(keyChar) < 127 else True):
|
||||
dispatchFn(eventDc, False, [*brushPos, *brushColours, 0, keyChar]);
|
||||
patches += [[*brushPos, *brushColours, 0, keyChar]]
|
||||
if not self._checkRtl(canvas, brushPos, keyChar):
|
||||
if brushPos[0] < (canvas.size[0] - 1):
|
||||
brushPos[0] += 1
|
||||
@ -60,38 +61,36 @@ class ToolText(Tool):
|
||||
brushPos[0], brushPos[1] = canvas.size[0] - 1, brushPos[1] - 1
|
||||
else:
|
||||
brushPos[0], brushPos[1] = canvas.size[0] - 1, canvas.size[1] - 1
|
||||
rc, dirty = True, True
|
||||
else:
|
||||
rc, dirty = False, False
|
||||
return rc, dirty
|
||||
rc = True
|
||||
return rc, patches
|
||||
|
||||
def onKeyboardEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyChar, keyCode, keyModifiers, mapPoint):
|
||||
def onKeyboardEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, keyChar, keyCode, keyModifiers, mapPoint):
|
||||
patches, patchesCursor, rc = [], [], False
|
||||
if re.match(self.arabicCombiningRegEx, keyChar):
|
||||
rc, dirty = True, False
|
||||
rc = True
|
||||
elif keyCode == wx.WXK_CONTROL_V:
|
||||
rc, dirty = True, False
|
||||
rc = True
|
||||
if wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_TEXT)) \
|
||||
and wx.TheClipboard.Open():
|
||||
inBuffer = wx.TextDataObject()
|
||||
if wx.TheClipboard.GetData(inBuffer):
|
||||
for inBufferChar in list(inBuffer.GetText()):
|
||||
if not re.match(self.arabicCombiningRegEx, inBufferChar):
|
||||
rc_, dirty_ = self._processKeyChar(brushColours, brushPos, canvas, dispatchFn, eventDc, inBufferChar, 0)
|
||||
rc = True if rc_ else rc; dirty = True if dirty_ else dirty;
|
||||
rc_, patches_ = self._processKeyChar(brushColours, brushPos, canvas, inBufferChar, 0)
|
||||
patches += patches_
|
||||
rc = True if rc_ else rc
|
||||
if rc:
|
||||
dispatchFn(eventDc, True, [*brushPos, *brushColours, 0, "_"])
|
||||
patchesCursor += [[*brushPos, *brushColours, 0, "_"]]
|
||||
wx.TheClipboard.Close()
|
||||
else:
|
||||
rc, error = False, "Clipboard does not contain text data and/or cannot be opened"
|
||||
elif keyCode == wx.WXK_BACK:
|
||||
if ((brushPos[0] + 1) >= canvas.size[0]):
|
||||
if brushPos[1] > 0:
|
||||
lastBrushPos = [0, brushPos[1] - 1]
|
||||
else:
|
||||
lastBrushPos = [0, 0]
|
||||
lastBrushPos = [0, brushPos[1] - 1] if brushPos[1] > 0 else [0, 0]
|
||||
else:
|
||||
lastBrushPos = [brushPos[0] + 1, brushPos[1]]
|
||||
if not self._checkRtl(canvas, lastBrushPos, None):
|
||||
patches += [[*brushPos, *brushColours, 0, " "]]
|
||||
if brushPos[0] > 0:
|
||||
brushPos[0] -= 1
|
||||
elif brushPos[1] > 0:
|
||||
@ -105,24 +104,23 @@ class ToolText(Tool):
|
||||
brushPos[0], brushPos[1] = 0, brushPos[1] - 1
|
||||
else:
|
||||
brushPos[0], brushPos[1] = canvas.size[0] - 1, 0
|
||||
rc, dirty = True, False; dispatchFn(eventDc, False, [*brushPos, *brushColours, 0, " "]);
|
||||
dispatchFn(eventDc, True, [*brushPos, *brushColours, 0, "_"]);
|
||||
rc = True; patchesCursor += [[*brushPos, *brushColours, 0, "_"]];
|
||||
elif keyCode == wx.WXK_RETURN:
|
||||
if brushPos[1] < (canvas.size[1] - 1):
|
||||
brushPos[0], brushPos[1] = 0, brushPos[1] + 1
|
||||
else:
|
||||
brushPos[0], brushPos[1] = 0, 0
|
||||
rc, dirty = True, False; dispatchFn(eventDc, True, [*brushPos, *brushColours, 0, "_"]);
|
||||
rc = True; patchesCursor += [[*brushPos, *brushColours, 0, "_"]];
|
||||
else:
|
||||
rc, dirty = self._processKeyChar(brushColours, brushPos, canvas, dispatchFn, eventDc, keyChar, keyModifiers)
|
||||
rc, patches_ = self._processKeyChar(brushColours, brushPos, canvas, keyChar, keyModifiers)
|
||||
patches += patches_
|
||||
if rc:
|
||||
dispatchFn(eventDc, True, [*brushPos, *brushColours, 0, "_"])
|
||||
return rc, dirty
|
||||
patchesCursor += [[*brushPos, *brushColours, 0, "_"]]
|
||||
return rc, patches, patchesCursor
|
||||
|
||||
def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown):
|
||||
def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown):
|
||||
if mouseLeftDown or mouseRightDown:
|
||||
brushPos[0], brushPos[1] = atPoint[0], atPoint[1]
|
||||
dispatchFn(eventDc, True, [*brushPos, *brushColours, 0, "_"])
|
||||
return True, False
|
||||
return True, None, [[*brushPos, *brushColours, 0, "_"]]
|
||||
|
||||
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
||||
|
Loading…
Reference in New Issue
Block a user