mirror of
https://github.com/lalbornoz/roar.git
synced 2024-12-22 12: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
|
||||
2) Incremental auto{load,save} & {backup,restore}
|
||||
3) Implement instrumentation & unit tests, document
|
||||
4) Open and toggle a reference image in the background
|
||||
5) Client-Server or Peer-to-Peer realtime collaboration
|
||||
6) Arbitrary {format,palette}s ({4,8} bit ANSI/mIRC, etc.)
|
||||
7) Hotkey & graphical interfaces to {composed,parametrised} tools
|
||||
8) Layers, layout (e.g. for comics, zines, etc.) & asset management (e.g. kade, lion, etc.) & traits w/ {inserting,merging,linking}
|
||||
9) Sprites & scripted (Python?) animation on the basis of asset traits and {composable,parametrised} patterns (metric flow, particle system, rigging, ...)
|
||||
10) Composition and parametrisation of tools from higher-order operators (brushes, filters, outlines, patterns & shaders) and unit tools; unit tools:
|
||||
2) Implement instrumentation & unit tests, document
|
||||
3) Open and toggle a reference image in the background
|
||||
4) Client-Server or Peer-to-Peer realtime collaboration
|
||||
5) Arbitrary {format,palette}s ({4,8} bit ANSI/mIRC, etc.)
|
||||
6) Hotkey & graphical interfaces to {composed,parametrised} tools
|
||||
7) Incremental auto{load,save} & {backup,restore} (needs Settings window)
|
||||
8) GUI: a) switch from wxPython to GTK b) {copy,cut,insert from,paste}, {de,in}crease cell size c) MRU {directories,files}
|
||||
9) Layers, layout (e.g. for comics, zines, etc.) & asset management (e.g. kade, lion, etc.) & traits w/ {inserting,merging,linking}
|
||||
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)
|
||||
b) regions (crop, duplicate, erase, fill, invert, measure, pick, rotate, scale, select, shift, slice, tile, translate)
|
||||
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
|
||||
|
@ -7,6 +7,27 @@
|
||||
from GuiCanvasColours import Colours
|
||||
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():
|
||||
# {{{ _drawBrushPatch(self, eventDc, patch, point)
|
||||
def _drawBrushPatch(self, eventDc, patch, point):
|
||||
@ -95,30 +116,22 @@ class GuiCanvasWxBackend():
|
||||
else:
|
||||
return False
|
||||
# }}}
|
||||
# {{{ getDeviceContext(self, parentWindow, viewRect)
|
||||
def getDeviceContext(self, parentWindow, viewRect):
|
||||
# {{{ getDeviceContext(self, clientSize, parentWindow, viewRect)
|
||||
def getDeviceContext(self, clientSize, parentWindow, viewRect):
|
||||
if viewRect == (0, 0):
|
||||
eventDc = wx.BufferedDC(wx.ClientDC(parentWindow), self.canvasBitmap)
|
||||
else:
|
||||
eventDc = wx.ClientDC(parentWindow)
|
||||
eventDc = GuiBufferedDC(self, self.canvasBitmap, clientSize, wx.ClientDC(parentWindow), viewRect)
|
||||
self._lastBrushBg, self._lastBrushFg, self._lastPen = None, None, None
|
||||
return eventDc
|
||||
# }}}
|
||||
# {{{ onPaintEvent(self, canvasSize, cellSize, clientSize, panelWindow, viewRect)
|
||||
def onPaintEvent(self, canvasSize, cellSize, clientSize, panelWindow, viewRect):
|
||||
# {{{ onPaint(self, clientSize, panelWindow, viewRect)
|
||||
def onPaint(self, clientSize, panelWindow, viewRect):
|
||||
if self.canvasBitmap != None:
|
||||
if viewRect == (0, 0):
|
||||
eventDc = wx.BufferedPaintDC(panelWindow, self.canvasBitmap)
|
||||
else:
|
||||
canvasSize = [a - b for a, b in zip(canvasSize, 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)
|
||||
eventDc = GuiBufferedDC(self, self.canvasBitmap, clientSize, wx.PaintDC(panelWindow), viewRect)
|
||||
# }}}
|
||||
# {{{ resize(self, canvasSize, cellSize):
|
||||
def resize(self, canvasSize, cellSize):
|
||||
|
@ -31,7 +31,7 @@ class RoarCanvasCommandsTools():
|
||||
toolBar.ToggleTool(self.canvasTool.attrList[idx]["id"], True)
|
||||
self.update(toolName=self.currentTool.name)
|
||||
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)
|
||||
setattr(canvasTool_, "attrDict", f.attrList[idx])
|
||||
setattr(canvasTool_, "isSelect", True)
|
||||
|
@ -38,12 +38,12 @@ class RoarCanvasWindow(GuiWindow):
|
||||
# }}}
|
||||
# {{{ 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:
|
||||
if patch == None:
|
||||
continue
|
||||
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:
|
||||
self.canvas._commitPatch(patch); self.backend.drawPatch(eventDc, patch, self.GetViewStart());
|
||||
# }}}
|
||||
@ -64,7 +64,7 @@ class RoarCanvasWindow(GuiWindow):
|
||||
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)
|
||||
viewRect = self.GetViewStart(); eventDc = self.backend.getDeviceContext(self, viewRect);
|
||||
viewRect = self.GetViewStart(); eventDc = self.backend.getDeviceContext(self.GetClientSize(), self, viewRect);
|
||||
if deltaSize[0] > 0:
|
||||
for numRow in range(oldSize[1]):
|
||||
for numNewCol in range(oldSize[0], newSize[0]):
|
||||
@ -79,7 +79,7 @@ class RoarCanvasWindow(GuiWindow):
|
||||
def update(self, newSize, commitUndo=True, newCanvas=None):
|
||||
self.resize(newSize, commitUndo)
|
||||
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 numCol in range(newSize[0]):
|
||||
self.backend.drawPatch(eventDc, [numCol, numRow, *self.canvas.map[numRow][numCol]], self.GetViewStart())
|
||||
@ -87,19 +87,19 @@ class RoarCanvasWindow(GuiWindow):
|
||||
|
||||
# {{{ 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()
|
||||
if not self.applyTool(eventDc, False, keyChar, keyModifiers, None, None, None, None, self.commands.currentTool, viewRect):
|
||||
event.Skip()
|
||||
# }}}
|
||||
# {{{ 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())
|
||||
# }}}
|
||||
# {{{ 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()
|
||||
mapPoint = self.backend.xlateEventPoint(event, eventDc, 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)
|
||||
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)
|
||||
def onScroll(self, event):
|
||||
if self.canvas.dirtyCursor:
|
||||
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.canvas.dirtyCursor = False
|
||||
event.Skip()
|
||||
|
Loading…
Reference in New Issue
Block a user