mirror of
https://github.com/lalbornoz/roar.git
synced 2024-11-22 15:26:37 +00:00
libgui/GuiCanvasWxBackend.py:GuiBufferedDC(): implement double-buffered wx.MemoryDC() honouring view{Rect,Size}.
libgui/GuiCanvasWxBackend.py:{getDeviceContext,onPaint}(): use GuiBufferedDC() if viewRect > (0, 0). libroar/RoarCanvas{CommandsTools,Window}.py: updated. assets/text/TODO: updated.
This commit is contained in:
parent
968e7d45c5
commit
6109e9b38c
@ -1,20 +1,16 @@
|
|||||||
1) Implement ANSI CSI CU[BDPU] sequences & italic
|
1) Implement ANSI CSI CU[BDPU] sequences & italic
|
||||||
2) Incremental auto{load,save} & {backup,restore}
|
2) Implement instrumentation & unit tests, document
|
||||||
3) Implement instrumentation & unit tests, document
|
3) Open and toggle a reference image in the background
|
||||||
4) Open and toggle a reference image in the background
|
4) Client-Server or Peer-to-Peer realtime collaboration
|
||||||
5) Client-Server or Peer-to-Peer realtime collaboration
|
5) Arbitrary {format,palette}s ({4,8} bit ANSI/mIRC, etc.)
|
||||||
6) Arbitrary {format,palette}s ({4,8} bit ANSI/mIRC, etc.)
|
6) Hotkey & graphical interfaces to {composed,parametrised} tools
|
||||||
7) Hotkey & graphical interfaces to {composed,parametrised} tools
|
7) Incremental auto{load,save} & {backup,restore} (needs Settings window)
|
||||||
8) Layers, layout (e.g. for comics, zines, etc.) & asset management (e.g. kade, lion, etc.) & traits w/ {inserting,merging,linking}
|
8) GUI: a) switch from wxPython to GTK b) {copy,cut,insert from,paste}, {de,in}crease cell size c) MRU {directories,files}
|
||||||
9) Sprites & scripted (Python?) animation on the basis of asset traits and {composable,parametrised} patterns (metric flow, particle system, rigging, ...)
|
9) Layers, layout (e.g. for comics, zines, etc.) & asset management (e.g. kade, lion, etc.) & traits w/ {inserting,merging,linking}
|
||||||
10) Composition and parametrisation of tools from higher-order operators (brushes, filters, outlines, patterns & shaders) and unit tools; unit tools:
|
10) Sprites & scripted (Python?) animation on the basis of asset traits and {composable,parametrised} patterns (metric flow, particle system, rigging, ...)
|
||||||
|
11) Composition and parametrisation of tools from higher-order operators (brushes, filters, outlines, patterns & shaders) and unit tools; unit tools:
|
||||||
a) geometric primitives (arrow, circle, cloud/speech bubble, curve, heart, hexagon, line, pentagon, polygon, rhombus, triangle, square, star)
|
a) geometric primitives (arrow, circle, cloud/speech bubble, curve, heart, hexagon, line, pentagon, polygon, rhombus, triangle, square, star)
|
||||||
b) regions (crop, duplicate, erase, fill, invert, measure, pick, rotate, scale, select, shift, slice, tile, translate)
|
b) regions (crop, duplicate, erase, fill, invert, measure, pick, rotate, scale, select, shift, slice, tile, translate)
|
||||||
c) text (edit, Unicode sets)
|
c) text (edit, Unicode sets)
|
||||||
11) GUI:
|
|
||||||
a) Settings panel
|
|
||||||
b) switch from wxPython to GTK
|
|
||||||
c) {fix,reduce} flickering when viewRect > (0, 0)
|
|
||||||
d) {copy,cut,insert from,paste}, {de,in}crease cell size
|
|
||||||
|
|
||||||
vim:ff=dos tw=0
|
vim:ff=dos tw=0
|
||||||
|
@ -7,6 +7,27 @@
|
|||||||
from GuiCanvasColours import Colours
|
from GuiCanvasColours import Colours
|
||||||
import math, wx
|
import math, wx
|
||||||
|
|
||||||
|
class GuiBufferedDC(wx.MemoryDC):
|
||||||
|
# {{{ __del__(self)
|
||||||
|
def __del__(self):
|
||||||
|
self.dc.Blit(0, 0, *self.viewSize, self, 0, 0)
|
||||||
|
self.SelectObject(wx.NullBitmap)
|
||||||
|
# }}}
|
||||||
|
# {{{ __init__(self, backend, buffer, clientSize, dc, viewRect)
|
||||||
|
def __init__(self, backend, buffer, clientSize, dc, viewRect):
|
||||||
|
super().__init__()
|
||||||
|
canvasSize = [a - b for a, b in zip(backend.canvasSize, viewRect)]
|
||||||
|
clientSize = [math.ceil(m / n) for m, n in zip(clientSize, backend.cellSize)]
|
||||||
|
viewRect = [m * n for m, n in zip(backend.cellSize, viewRect)]
|
||||||
|
viewSize = [min(m, n) for m, n in zip(canvasSize, clientSize)]
|
||||||
|
viewSize = [m * n for m, n in zip(backend.cellSize, viewSize)]
|
||||||
|
bitmap = wx.Bitmap(viewSize); self.SelectObject(bitmap);
|
||||||
|
bufferDc = wx.MemoryDC(); bufferDc.SelectObject(buffer);
|
||||||
|
self.Blit(0, 0, *viewSize, bufferDc, *viewRect)
|
||||||
|
bufferDc.SelectObject(wx.NullBitmap)
|
||||||
|
self.dc, self.viewSize = dc, viewSize
|
||||||
|
# }}}
|
||||||
|
|
||||||
class GuiCanvasWxBackend():
|
class GuiCanvasWxBackend():
|
||||||
# {{{ _drawBrushPatch(self, eventDc, patch, point)
|
# {{{ _drawBrushPatch(self, eventDc, patch, point)
|
||||||
def _drawBrushPatch(self, eventDc, patch, point):
|
def _drawBrushPatch(self, eventDc, patch, point):
|
||||||
@ -95,30 +116,22 @@ class GuiCanvasWxBackend():
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
# }}}
|
# }}}
|
||||||
# {{{ getDeviceContext(self, parentWindow, viewRect)
|
# {{{ getDeviceContext(self, clientSize, parentWindow, viewRect)
|
||||||
def getDeviceContext(self, parentWindow, viewRect):
|
def getDeviceContext(self, clientSize, parentWindow, viewRect):
|
||||||
if viewRect == (0, 0):
|
if viewRect == (0, 0):
|
||||||
eventDc = wx.BufferedDC(wx.ClientDC(parentWindow), self.canvasBitmap)
|
eventDc = wx.BufferedDC(wx.ClientDC(parentWindow), self.canvasBitmap)
|
||||||
else:
|
else:
|
||||||
eventDc = wx.ClientDC(parentWindow)
|
eventDc = GuiBufferedDC(self, self.canvasBitmap, clientSize, wx.ClientDC(parentWindow), viewRect)
|
||||||
self._lastBrushBg, self._lastBrushFg, self._lastPen = None, None, None
|
self._lastBrushBg, self._lastBrushFg, self._lastPen = None, None, None
|
||||||
return eventDc
|
return eventDc
|
||||||
# }}}
|
# }}}
|
||||||
# {{{ onPaintEvent(self, canvasSize, cellSize, clientSize, panelWindow, viewRect)
|
# {{{ onPaint(self, clientSize, panelWindow, viewRect)
|
||||||
def onPaintEvent(self, canvasSize, cellSize, clientSize, panelWindow, viewRect):
|
def onPaint(self, clientSize, panelWindow, viewRect):
|
||||||
if self.canvasBitmap != None:
|
if self.canvasBitmap != None:
|
||||||
if viewRect == (0, 0):
|
if viewRect == (0, 0):
|
||||||
eventDc = wx.BufferedPaintDC(panelWindow, self.canvasBitmap)
|
eventDc = wx.BufferedPaintDC(panelWindow, self.canvasBitmap)
|
||||||
else:
|
else:
|
||||||
canvasSize = [a - b for a, b in zip(canvasSize, viewRect)]
|
eventDc = GuiBufferedDC(self, self.canvasBitmap, clientSize, wx.PaintDC(panelWindow), viewRect)
|
||||||
clientSize = [math.ceil(m / n) for m, n in zip(clientSize, cellSize)]
|
|
||||||
viewSize = [min(m, n) for m, n in zip(canvasSize, clientSize)]
|
|
||||||
viewSize = [m * n for m, n in zip(cellSize, viewSize)]
|
|
||||||
canvasDc = wx.MemoryDC(); canvasDc.SelectObject(self.canvasBitmap);
|
|
||||||
viewDc = wx.MemoryDC(); viewBitmap = wx.Bitmap(viewSize); viewDc.SelectObject(viewBitmap);
|
|
||||||
viewDc.Blit(0, 0, *viewSize, canvasDc, *[m * n for m, n in zip(cellSize, viewRect)])
|
|
||||||
canvasDc.SelectObject(wx.NullBitmap); viewDc.SelectObject(wx.NullBitmap);
|
|
||||||
eventDc = wx.BufferedPaintDC(panelWindow, viewBitmap)
|
|
||||||
# }}}
|
# }}}
|
||||||
# {{{ resize(self, canvasSize, cellSize):
|
# {{{ resize(self, canvasSize, cellSize):
|
||||||
def resize(self, canvasSize, cellSize):
|
def resize(self, canvasSize, cellSize):
|
||||||
|
@ -31,7 +31,7 @@ class RoarCanvasCommandsTools():
|
|||||||
toolBar.ToggleTool(self.canvasTool.attrList[idx]["id"], True)
|
toolBar.ToggleTool(self.canvasTool.attrList[idx]["id"], True)
|
||||||
self.update(toolName=self.currentTool.name)
|
self.update(toolName=self.currentTool.name)
|
||||||
viewRect = self.parentCanvas.GetViewStart()
|
viewRect = self.parentCanvas.GetViewStart()
|
||||||
eventDc = self.parentCanvas.backend.getDeviceContext(self.parentCanvas, viewRect)
|
eventDc = self.parentCanvas.backend.getDeviceContext(self.parentCanvas.GetClientSize(), self.parentCanvas, viewRect)
|
||||||
self.parentCanvas.applyTool(eventDc, True, None, None, self.parentCanvas.brushPos, False, False, False, self.currentTool, viewRect)
|
self.parentCanvas.applyTool(eventDc, True, None, None, self.parentCanvas.brushPos, False, False, False, self.currentTool, viewRect)
|
||||||
setattr(canvasTool_, "attrDict", f.attrList[idx])
|
setattr(canvasTool_, "attrDict", f.attrList[idx])
|
||||||
setattr(canvasTool_, "isSelect", True)
|
setattr(canvasTool_, "isSelect", True)
|
||||||
|
@ -38,12 +38,12 @@ class RoarCanvasWindow(GuiWindow):
|
|||||||
# }}}
|
# }}}
|
||||||
# {{{ dispatchDeltaPatches(self, deltaPatches)
|
# {{{ dispatchDeltaPatches(self, deltaPatches)
|
||||||
def dispatchDeltaPatches(self, deltaPatches):
|
def dispatchDeltaPatches(self, deltaPatches):
|
||||||
eventDc = self.backend.getDeviceContext(self, self.GetViewStart())
|
eventDc = self.backend.getDeviceContext(self.GetClientSize(), self, self.GetViewStart())
|
||||||
for patch in deltaPatches:
|
for patch in deltaPatches:
|
||||||
if patch == None:
|
if patch == None:
|
||||||
continue
|
continue
|
||||||
elif patch[0] == "resize":
|
elif patch[0] == "resize":
|
||||||
del eventDc; self.resize(patch[1:], False); eventDc = self.backend.getDeviceContext(self, self.GetViewStart());
|
del eventDc; self.resize(patch[1:], False); eventDc = self.backend.getDeviceContext(self.GetClientSize(), self, self.GetViewStart());
|
||||||
else:
|
else:
|
||||||
self.canvas._commitPatch(patch); self.backend.drawPatch(eventDc, patch, self.GetViewStart());
|
self.canvas._commitPatch(patch); self.backend.drawPatch(eventDc, patch, self.GetViewStart());
|
||||||
# }}}
|
# }}}
|
||||||
@ -64,7 +64,7 @@ class RoarCanvasWindow(GuiWindow):
|
|||||||
if self.canvas.resize(newSize, commitUndo):
|
if self.canvas.resize(newSize, commitUndo):
|
||||||
super().resize([a * b for a, b in zip(newSize, self.backend.cellSize)])
|
super().resize([a * b for a, b in zip(newSize, self.backend.cellSize)])
|
||||||
self.backend.resize(newSize, self.backend.cellSize)
|
self.backend.resize(newSize, self.backend.cellSize)
|
||||||
viewRect = self.GetViewStart(); eventDc = self.backend.getDeviceContext(self, viewRect);
|
viewRect = self.GetViewStart(); eventDc = self.backend.getDeviceContext(self.GetClientSize(), self, viewRect);
|
||||||
if deltaSize[0] > 0:
|
if deltaSize[0] > 0:
|
||||||
for numRow in range(oldSize[1]):
|
for numRow in range(oldSize[1]):
|
||||||
for numNewCol in range(oldSize[0], newSize[0]):
|
for numNewCol in range(oldSize[0], newSize[0]):
|
||||||
@ -79,7 +79,7 @@ class RoarCanvasWindow(GuiWindow):
|
|||||||
def update(self, newSize, commitUndo=True, newCanvas=None):
|
def update(self, newSize, commitUndo=True, newCanvas=None):
|
||||||
self.resize(newSize, commitUndo)
|
self.resize(newSize, commitUndo)
|
||||||
self.canvas.update(newSize, newCanvas)
|
self.canvas.update(newSize, newCanvas)
|
||||||
eventDc = self.backend.getDeviceContext(self, self.GetViewStart())
|
eventDc = self.backend.getDeviceContext(self.GetClientSize(), self, self.GetViewStart())
|
||||||
for numRow in range(newSize[1]):
|
for numRow in range(newSize[1]):
|
||||||
for numCol in range(newSize[0]):
|
for numCol in range(newSize[0]):
|
||||||
self.backend.drawPatch(eventDc, [numCol, numRow, *self.canvas.map[numRow][numCol]], self.GetViewStart())
|
self.backend.drawPatch(eventDc, [numCol, numRow, *self.canvas.map[numRow][numCol]], self.GetViewStart())
|
||||||
@ -87,19 +87,19 @@ class RoarCanvasWindow(GuiWindow):
|
|||||||
|
|
||||||
# {{{ onKeyboardInput(self, event)
|
# {{{ onKeyboardInput(self, event)
|
||||||
def onKeyboardInput(self, event):
|
def onKeyboardInput(self, event):
|
||||||
viewRect = self.GetViewStart(); eventDc = self.backend.getDeviceContext(self, viewRect);
|
viewRect = self.GetViewStart(); eventDc = self.backend.getDeviceContext(self.GetClientSize(), self, viewRect);
|
||||||
keyChar, keyModifiers = chr(event.GetUnicodeKey()), event.GetModifiers()
|
keyChar, keyModifiers = chr(event.GetUnicodeKey()), event.GetModifiers()
|
||||||
if not self.applyTool(eventDc, False, keyChar, keyModifiers, None, None, None, None, self.commands.currentTool, viewRect):
|
if not self.applyTool(eventDc, False, keyChar, keyModifiers, None, None, None, None, self.commands.currentTool, viewRect):
|
||||||
event.Skip()
|
event.Skip()
|
||||||
# }}}
|
# }}}
|
||||||
# {{{ onLeaveWindow(self, event)
|
# {{{ onLeaveWindow(self, event)
|
||||||
def onLeaveWindow(self, event):
|
def onLeaveWindow(self, event):
|
||||||
eventDc = self.backend.getDeviceContext(self, self.GetViewStart())
|
eventDc = self.backend.getDeviceContext(self.GetClientSize(), self, self.GetViewStart())
|
||||||
self.backend.drawCursorMaskWithJournal(self.canvas.journal, eventDc, self.GetViewStart())
|
self.backend.drawCursorMaskWithJournal(self.canvas.journal, eventDc, self.GetViewStart())
|
||||||
# }}}
|
# }}}
|
||||||
# {{{ onMouseInput(self, event)
|
# {{{ onMouseInput(self, event)
|
||||||
def onMouseInput(self, event):
|
def onMouseInput(self, event):
|
||||||
viewRect = self.GetViewStart(); eventDc = self.backend.getDeviceContext(self, viewRect);
|
viewRect = self.GetViewStart(); eventDc = self.backend.getDeviceContext(self.GetClientSize(), self, viewRect);
|
||||||
mouseDragging, mouseLeftDown, mouseRightDown = event.Dragging(), event.LeftIsDown(), event.RightIsDown()
|
mouseDragging, mouseLeftDown, mouseRightDown = event.Dragging(), event.LeftIsDown(), event.RightIsDown()
|
||||||
mapPoint = self.backend.xlateEventPoint(event, eventDc, viewRect)
|
mapPoint = self.backend.xlateEventPoint(event, eventDc, viewRect)
|
||||||
if not self.applyTool(eventDc, True, None, None, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown, self.commands.currentTool, viewRect):
|
if not self.applyTool(eventDc, True, None, None, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown, self.commands.currentTool, viewRect):
|
||||||
@ -107,13 +107,13 @@ class RoarCanvasWindow(GuiWindow):
|
|||||||
# }}}
|
# }}}
|
||||||
# {{{ onPaint(self, event)
|
# {{{ onPaint(self, event)
|
||||||
def onPaint(self, event):
|
def onPaint(self, event):
|
||||||
self.backend.onPaintEvent(self.canvas.size, self.cellSize, self.GetClientSize(), self, self.GetViewStart())
|
self.backend.onPaint(self.GetClientSize(), self, self.GetViewStart())
|
||||||
# }}}
|
# }}}
|
||||||
# {{{ onScroll(self, event)
|
# {{{ onScroll(self, event)
|
||||||
def onScroll(self, event):
|
def onScroll(self, event):
|
||||||
if self.canvas.dirtyCursor:
|
if self.canvas.dirtyCursor:
|
||||||
viewRect = self.GetViewStart()
|
viewRect = self.GetViewStart()
|
||||||
eventDc = self.backend.getDeviceContext(self, viewRect)
|
eventDc = self.backend.getDeviceContext(self.GetClientSize(), self, viewRect)
|
||||||
self.backend.drawCursorMaskWithJournal(self.canvas.journal, eventDc, viewRect)
|
self.backend.drawCursorMaskWithJournal(self.canvas.journal, eventDc, viewRect)
|
||||||
self.canvas.dirtyCursor = False
|
self.canvas.dirtyCursor = False
|
||||||
event.Skip()
|
event.Skip()
|
||||||
|
Loading…
Reference in New Issue
Block a user