From a628ed6471b4f2fe8424e8f130d9cf0cdffe76a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucio=20Andr=C3=A9s=20Illanes=20Albornoz?= Date: Sun, 8 Sep 2019 16:57:45 +0200 Subject: [PATCH] Implements transparent colour. libgui/Gui{CanvasInterface,{General,}Frame}.py: refactored. {libcanvas/CanvasExportStore,libgui/GuiCanvas{Interface,WxBackend}}.py: implements transparent colour. libgui/GuiCanvasPanel.py: updated. libtools/ToolText.py: updated. assets/text/TODO: updated. --- assets/text/TODO | 23 ++- libcanvas/Canvas.py | 2 +- libcanvas/CanvasExportStore.py | 34 +++- libgui/GuiCanvasInterface.py | 347 +++++++++++++++++++++++++-------- libgui/GuiCanvasPanel.py | 13 +- libgui/GuiCanvasWxBackend.py | 28 ++- libgui/GuiFrame.py | 305 ++++++++++++----------------- libgui/GuiGeneralFrame.py | 155 --------------- libtools/ToolText.py | 15 +- roar.py | 8 +- 10 files changed, 468 insertions(+), 462 deletions(-) delete mode 100644 libgui/GuiGeneralFrame.py diff --git a/assets/text/TODO b/assets/text/TODO index efce91d..155454f 100644 --- a/assets/text/TODO +++ b/assets/text/TODO @@ -1,16 +1,15 @@ 1) General {cleanup,refactor} -2) Transparent {back,fore}ground colour -3) Implement instrumentation & unit tests -4) Implement ANSI CSI CU[BDPU] sequences -5) Incremental auto{load,save} & {backup,restore} -6) Open and toggle a reference image in the background -7) Client-Server or Peer-to-Peer realtime collaboration -8) Arbitrary {format,palette}s ({4,8} bit ANSI/mIRC, etc.) -9) Hotkey & graphical interfaces to {composed,parametrised} tools -10) GUI: a) scrollbar b) switch from wxPython to GTK c) revisit About dialogue -11) Layers, layout (e.g. for comics, zines, etc.) & asset management (e.g. kade, lion, etc.) & traits w/ {inserting,merging,linking} -12) Sprites & scripted (Python?) animation on the basis of asset traits and {composable,parametrised} patterns (metric flow, particle system, rigging, ...) -13) Composition and parametrisation of tools from higher-order operators (brushes, filters, outlines, patterns & shaders) and unit tools; unit tools: +2) Implement ANSI CSI CU[BDPU] sequences & italic +3) Incremental auto{load,save} & {backup,restore} +4) Implement instrumentation & unit tests, document +5) Open and toggle a reference image in the background +6) Client-Server or Peer-to-Peer realtime collaboration +7) Arbitrary {format,palette}s ({4,8} bit ANSI/mIRC, etc.) +8) Hotkey & graphical interfaces to {composed,parametrised} tools +9) GUI: a) scrollbar b) {de,in}crease cell size c) revisit About dialogue d) Settings panel e) switch from wxPython to GTK +10) Layers, layout (e.g. for comics, zines, etc.) & asset management (e.g. kade, lion, etc.) & traits w/ {inserting,merging,linking} +11) Sprites & scripted (Python?) animation on the basis of asset traits and {composable,parametrised} patterns (metric flow, particle system, rigging, ...) +12) 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) diff --git a/libcanvas/Canvas.py b/libcanvas/Canvas.py index d754b43..3e0e32f 100644 --- a/libcanvas/Canvas.py +++ b/libcanvas/Canvas.py @@ -90,4 +90,4 @@ class Canvas(): self.dirty, self.dirtyCursor, self.map, self.size = False, False, None, size self.exportStore, self.importStore, self.journal = CanvasExportStore(), CanvasImportStore(), CanvasJournal() -# vim:expandtab foldmethod=marker sw=4 ts=4 tw=0 +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/libcanvas/CanvasExportStore.py b/libcanvas/CanvasExportStore.py index fbfd4a3..550797f 100644 --- a/libcanvas/CanvasExportStore.py +++ b/libcanvas/CanvasExportStore.py @@ -53,9 +53,16 @@ class CanvasExportStore(): outBuffer += "\u001b[4m" lastAttribs = inCurCell[2] if lastColours == None or lastColours != inCurCell[:2]: - ansiBg = MiRCARTToAnsiColours[int(inCurCell[1])] + 10 - ansiFg = MiRCARTToAnsiColours[int(inCurCell[0])] - outBuffer += "\u001b[{:02d}m\u001b[{:02d}m{}".format(ansiBg, ansiFg, inCurCell[3]) + if (inCurCell[0] == -1) \ + and (inCurCell[1] == -1): + outBuffer += "\u001b[39;49m{}".format(" ") + elif inCurCell[1] == -1: + ansiFg = MiRCARTToAnsiColours[inCurCell[0]] + outBuffer += "\u001b[49;{:02d}m{}".format(ansiFg, inCurCell[3]) + else: + ansiBg = MiRCARTToAnsiColours[inCurCell[1]] + 10 + ansiFg = MiRCARTToAnsiColours[inCurCell[0] if inCurCell[0] != -1 else inCurCell[1]] + outBuffer += "\u001b[{:02d};{:02d}m{}".format(ansiBg, ansiFg, inCurCell[3]) lastColours = inCurCell[:2] else: outBuffer += inCurCell[3] @@ -145,7 +152,6 @@ class CanvasExportStore(): outImgDraw.rectangle((*outCurPos, outCurPos[0] + outImgFontSize[0], outCurPos[1] + outImgFontSize[1]), fill=(*outColours[1], 255)) if not inCurCell[3] in " █" \ and outColours[0] != outColours[1]: - # XXX implement italic outImgDraw.text(outCurPos, inCurCell[3], (*outColours[0], 255), outImgFont) if inCurCell[2] & self._CellState.CS_UNDERLINE: outColours[0] = ColourMapNormal[inCurCell[0]] @@ -165,16 +171,26 @@ class CanvasExportStore(): for canvasCol in range(canvasSize[0]): canvasColColours = canvasMap[canvasRow][canvasCol][0:2] canvasColText = canvasMap[canvasRow][canvasCol][3] - if canvasColColours[0] != canvasLastColours[0] \ - and canvasColColours[1] != canvasLastColours[1]: - if canvasColColours[0] == canvasLastColours[1] \ - and canvasColColours[1] == canvasLastColours[0]: + if canvasColColours[0] == -1: + canvasColColours[0] = canvasColColours[1] + if (canvasColColours[0] != canvasLastColours[0]) \ + and (canvasColColours[1] != canvasLastColours[1]): + if (canvasColColours[0] == -1) \ + and (canvasColColours[1] == -1): + outBuffer += "\u0003 " + elif canvasColColours[1] == -1: + outBuffer += "\u0003\u0003{}".format(canvasColColours[0]) + elif (canvasColColours[0] == canvasLastColours[1]) \ + and (canvasColColours[1] == canvasLastColours[0]): outBuffer += "\u0016" else: outBuffer += "\u0003{},{}".format(canvasColColours[0], canvasColColours[1]) canvasLastColours = canvasColColours elif canvasColColours[1] != canvasLastColours[1]: - outBuffer += "\u0003{},{}".format(canvasLastColours[0], canvasColColours[1]) + if canvasColColours[1] == -1: + outBuffer += "\u0003\u0003{}".format(canvasLastColours[0]) + else: + outBuffer += "\u0003{},{}".format(canvasLastColours[0], canvasColColours[1]) canvasLastColours[1] = canvasColColours[1] elif canvasColColours[0] != canvasLastColours[0]: outBuffer += "\u0003{}".format(canvasColColours[0]) diff --git a/libgui/GuiCanvasInterface.py b/libgui/GuiCanvasInterface.py index f644866..5dacb3c 100644 --- a/libgui/GuiCanvasInterface.py +++ b/libgui/GuiCanvasInterface.py @@ -4,21 +4,54 @@ # Copyright (c) 2018, 2019 Lucio Andrés Illanes Albornoz # +try: + import base64, json, requests, urllib.request + haveUrllib = True +except ImportError: + haveUrllib = False + from ToolCircle import ToolCircle from ToolFill import ToolFill from ToolLine import ToolLine +from ToolRect import ToolRect from ToolSelectClone import ToolSelectClone from ToolSelectMove import ToolSelectMove -from ToolRect import ToolRect from ToolText import ToolText -from glob import glob +from GuiCanvasColours import Colours from GuiCanvasInterfaceAbout import GuiCanvasInterfaceAbout +from GuiFrame import NID_MENU_SEP, NID_TOOLBAR_HSEP from ImgurApiKey import ImgurApiKey -import io, os, random, sys, wx, wx.adv +import io, os, sys, wx + +def GuiCanvasCommandDecorator(caption, label, icon, accel, initialState): + """XXX""" + # {{{ GuiCanvasCommandDecoratorOuter(targetObject): XXX + def GuiCanvasCommandDecoratorOuter(targetObject): + if callable(targetObject): + if not hasattr(targetObject, "attrDict"): + setattr(targetObject, "attrDict", []) + targetObject.attrDict = {"caption": caption, "label": label, "icon": icon, "accel": accel, "initialState": initialState, "id": None} + return targetObject + return GuiCanvasCommandDecoratorOuter + # }}} + +def GuiCanvasSelectDecorator(idx, caption, label, icon, accel, initialState): + """XXX""" + # {{{ GuiCanvasSelectDecoratorOuter(targetObject): XXX + def GuiCanvasSelectDecoratorOuter(targetObject): + if callable(targetObject): + if not hasattr(targetObject, "attrList"): + setattr(targetObject, "attrList", []) + setattr(targetObject, "isSelect", True) + targetObject.attrList.insert(0, {"caption": caption, "label": label, "icon": icon, "accel": accel, "initialState": initialState, "id": None, "idx": idx}) + return targetObject + return GuiCanvasSelectDecoratorOuter + # }}} class GuiCanvasInterface(): """XXX""" + # {{{ _dialogSaveChanges(self): XXX def _dialogSaveChanges(self): with wx.MessageDialog(self.parentCanvas, \ @@ -27,36 +60,103 @@ class GuiCanvasInterface(): dialogChoice = dialog.ShowModal() return dialogChoice # }}} + # {{{ _initColourBitmaps(self): XXX + def _initColourBitmaps(self): + for numColour in range(len(self.canvasColour.attrList)): + if numColour < len(Colours): + toolBitmapColour = Colours[numColour][0:4] + toolBitmap = wx.Bitmap((16, 16)) + toolBitmapDc = wx.MemoryDC(); toolBitmapDc.SelectObject(toolBitmap); + toolBitmapBrush = wx.Brush(wx.Colour(toolBitmapColour), wx.BRUSHSTYLE_SOLID) + toolBitmapDc.SetBrush(toolBitmapBrush) + toolBitmapDc.SetBackground(toolBitmapBrush) + toolBitmapDc.SetPen(wx.Pen(wx.Colour(toolBitmapColour), 1)) + toolBitmapDc.DrawRectangle(0, 0, 16, 16) + self.canvasColour.attrList[numColour]["icon"] = ["", None, toolBitmap] + toolBitmapColours = ((0, 0, 0, 255), (255, 255, 255, 255)) + toolBitmap = wx.Bitmap((16, 16)) + toolBitmapDc = wx.MemoryDC(); toolBitmapDc.SelectObject(toolBitmap); + toolBitmapBrush = [wx.Brush(wx.Colour(c), wx.BRUSHSTYLE_SOLID) for c in toolBitmapColours] + toolBitmapDc.SetBrush(toolBitmapBrush[1]) + toolBitmapDc.SetBackground(toolBitmapBrush[1]) + toolBitmapDc.SetPen(wx.Pen(wx.Colour(toolBitmapColours[1]), 1)) + toolBitmapDc.DrawRectangle(0, 0, 8, 8) + toolBitmapDc.DrawRectangle(8, 8, 16, 16) + self.canvasColourAlpha.attrList[0]["icon"] = ["", None, toolBitmap] + # }}} # {{{ canvasAbout(self, event): XXX + @GuiCanvasCommandDecorator("About", "&About", None, None, True) def canvasAbout(self, event): GuiCanvasInterfaceAbout(self.parentFrame) # }}} - # {{{ canvasBrushSolid(self, event): XXX - def canvasBrushSolid(self, event): - pass + # {{{ canvasBrush(self, f, idx): XXX + @GuiCanvasSelectDecorator(0, "Solid brush", "Solid brush", None, None, True) + def canvasBrush(self, f, idx): + def canvasBrush_(self, event): + pass + setattr(canvasBrush_, "attrDict", f.attrList[idx]) + setattr(canvasBrush_, "isSelect", True) + return canvasBrush_ # }}} - # {{{ canvasColour(self, event, numColour): XXX - def canvasColour(self, event, numColour): - if event.GetEventType() == wx.wxEVT_TOOL: - self.parentCanvas.brushColours[0] = numColour - elif event.GetEventType() == wx.wxEVT_TOOL_RCLICKED: - self.parentCanvas.brushColours[1] = numColour - self.parentFrame.update(colours=self.parentCanvas.brushColours) + # {{{ canvasColour(self, f, idx): XXX + @GuiCanvasSelectDecorator(0, "Colour #00", "Colour #00 (Bright White)", None, None, False) + @GuiCanvasSelectDecorator(1, "Colour #01", "Colour #01 (Black)", None, None, False) + @GuiCanvasSelectDecorator(2, "Colour #02", "Colour #02 (Blue)", None, None, False) + @GuiCanvasSelectDecorator(3, "Colour #03", "Colour #03 (Green)", None, None, False) + @GuiCanvasSelectDecorator(4, "Colour #04", "Colour #04 (Red)", None, None, False) + @GuiCanvasSelectDecorator(5, "Colour #05", "Colour #05 (Light Red)", None, None, False) + @GuiCanvasSelectDecorator(6, "Colour #06", "Colour #06 (Pink)", None, None, False) + @GuiCanvasSelectDecorator(7, "Colour #07", "Colour #07 (Yellow)", None, None, False) + @GuiCanvasSelectDecorator(8, "Colour #08", "Colour #08 (Light Yellow)", None, None, False) + @GuiCanvasSelectDecorator(9, "Colour #09", "Colour #09 (Light Green)", None, None, False) + @GuiCanvasSelectDecorator(10, "Colour #10", "Colour #10 (Cyan)", None, None, False) + @GuiCanvasSelectDecorator(11, "Colour #11", "Colour #11 (Light Cyan)", None, None, False) + @GuiCanvasSelectDecorator(12, "Colour #12", "Colour #12 (Light Blue)", None, None, False) + @GuiCanvasSelectDecorator(13, "Colour #13", "Colour #13 (Light Pink)", None, None, False) + @GuiCanvasSelectDecorator(14, "Colour #14", "Colour #14 (Grey)", None, None, False) + @GuiCanvasSelectDecorator(15, "Colour #15", "Colour #15 (Light Grey)", None, None, False) + def canvasColour(self, f, idx): + def canvasColour_(self, event): + if event.GetEventType() == wx.wxEVT_TOOL: + self.parentCanvas.brushColours[0] = idx + elif event.GetEventType() == wx.wxEVT_TOOL_RCLICKED: + self.parentCanvas.brushColours[1] = idx + self.update(colours=self.parentCanvas.brushColours) + setattr(canvasColour_, "attrDict", f.attrList[idx]) + setattr(canvasColour_, "isSelect", True) + return canvasColour_ + # }}} + # {{{ canvasColourAlpha(self, f, idx): XXX + @GuiCanvasSelectDecorator(0, "Transparent colour", "Transparent colour", None, None, False) + def canvasColourAlpha(self, f, idx): + def canvasColourAlpha_(self, event): + if event.GetEventType() == wx.wxEVT_TOOL: + self.parentCanvas.brushColours[0] = -1 + elif event.GetEventType() == wx.wxEVT_TOOL_RCLICKED: + self.parentCanvas.brushColours[1] = -1 + self.update(colours=self.parentCanvas.brushColours) + setattr(canvasColourAlpha_, "attrDict", f.attrList[idx]) + setattr(canvasColourAlpha_, "isSelect", True) + return canvasColourAlpha_ # }}} # {{{ canvasCopy(self, event): XXX + @GuiCanvasCommandDecorator("Copy", "&Copy", ["", wx.ART_COPY], None, False) def canvasCopy(self, event): pass # }}} # {{{ canvasCut(self, event): XXX + @GuiCanvasCommandDecorator("Cut", "Cu&t", ["", wx.ART_CUT], None, False) def canvasCut(self, event): pass # }}} # {{{ canvasDelete(self, event): XXX + @GuiCanvasCommandDecorator("Delete", "De&lete", ["", wx.ART_DELETE], None, False) def canvasDelete(self, event): pass # }}} # {{{ canvasExit(self, event): XXX + @GuiCanvasCommandDecorator("Exit", "E&xit", None, [wx.ACCEL_CTRL, ord("X")], None) def canvasExit(self, event): if self.canvasPathName != None: saveChanges = self._dialogSaveChanges() @@ -69,6 +169,7 @@ class GuiCanvasInterface(): self.parentFrame.Close(True) # }}} # {{{ canvasNew(self, event, newCanvasSize=None): XXX + @GuiCanvasCommandDecorator("New", "&New", ["", wx.ART_NEW], [wx.ACCEL_CTRL, ord("N")], None) def canvasNew(self, event, newCanvasSize=None): if self.canvasPathName != None: saveChanges = self._dialogSaveChanges() @@ -85,9 +186,10 @@ class GuiCanvasInterface(): self.parentCanvas.update(newCanvasSize, False, newMap) self.canvasPathName = None self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) - self.parentFrame.update(pathName="", undoLevel=-1) + self.update(pathName="", undoLevel=-1) # }}} # {{{ canvasOpen(self, event): XXX + @GuiCanvasCommandDecorator("Open", "&Open", ["", wx.ART_FILE_OPEN], [wx.ACCEL_CTRL, ord("O")], None) def canvasOpen(self, event): if self.canvasPathName != None: saveChanges = self._dialogSaveChanges() @@ -107,22 +209,25 @@ class GuiCanvasInterface(): if rc: self.parentCanvas.update(self.parentCanvas.canvas.importStore.inSize, False, self.parentCanvas.canvas.importStore.outMap) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) - self.parentFrame.update(pathName=self.canvasPathName, undoLevel=-1) + self.update(pathName=self.canvasPathName, undoLevel=-1) return True else: print("error: {}".format(error), file=sys.stderr) return False # }}} # {{{ canvasPaste(self, event): XXX + @GuiCanvasCommandDecorator("Paste", "&Paste", ["", wx.ART_PASTE], None, False) def canvasPaste(self, event): pass # }}} # {{{ canvasRedo(self, event): XXX + @GuiCanvasCommandDecorator("Redo", "&Redo", ["", wx.ART_REDO], [wx.ACCEL_CTRL, ord("Y")], False) def canvasRedo(self, event): self.parentCanvas.dispatchDeltaPatches(self.parentCanvas.canvas.journal.popRedo()) - self.parentFrame.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) # }}} # {{{ canvasSave(self, event): XXX + @GuiCanvasCommandDecorator("Save", "&Save", ["", wx.ART_FILE_SAVE], [wx.ACCEL_CTRL, ord("S")], None) def canvasSave(self, event): if self.canvasPathName == None: if self.canvasSaveAs(event) == False: @@ -138,6 +243,7 @@ class GuiCanvasInterface(): return False # }}} # {{{ canvasSaveAs(self, event): XXX + @GuiCanvasCommandDecorator("Save As...", "Save &As...", ["", wx.ART_FILE_SAVE_AS], None, None) def canvasSaveAs(self, event): with wx.FileDialog(self.parentCanvas, "Save As", os.getcwd(), "", "mIRC art files (*.txt)|*.txt|All Files (*.*)|*.*", wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dialog: if dialog.ShowModal() == wx.ID_CANCEL: @@ -147,73 +253,106 @@ class GuiCanvasInterface(): return self.canvasSave(event) # }}} # {{{ canvasUndo(self, event): XXX + @GuiCanvasCommandDecorator("Undo", "&Undo", ["", wx.ART_UNDO], [wx.ACCEL_CTRL, ord("Z")], False) def canvasUndo(self, event): self.parentCanvas.dispatchDeltaPatches(self.parentCanvas.canvas.journal.popUndo()) - self.parentFrame.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) # }}} # {{{ canvasDecrBrushHeight(self, event): XXX + @GuiCanvasCommandDecorator("Decrease brush height", "Decrease brush height", ["toolDecrBrushH.png"], None, None) def canvasDecrBrushHeight(self, event): if self.parentCanvas.brushSize[1] > 1: self.parentCanvas.brushSize[1] -= 1 - self.parentFrame.update(brushSize=self.parentCanvas.brushSize) + self.update(brushSize=self.parentCanvas.brushSize) # }}} # {{{ canvasDecrBrushHeightWidth(self, event): XXX + @GuiCanvasCommandDecorator("Decrease brush size", "Decrease brush size", ["toolDecrBrushHW.png"], None, None) def canvasDecrBrushHeightWidth(self, event): self.canvasDecrBrushHeight(event) self.canvasDecrBrushWidth(event) # }}} # {{{ canvasDecrBrushWidth(self, event): XXX + @GuiCanvasCommandDecorator("Decrease brush width", "Decrease brush width", ["toolDecrBrushW.png"], None, None) def canvasDecrBrushWidth(self, event): if self.parentCanvas.brushSize[0] > 1: self.parentCanvas.brushSize[0] -= 1 - self.parentFrame.update(brushSize=self.parentCanvas.brushSize) + self.update(brushSize=self.parentCanvas.brushSize) # }}} # {{{ canvasDecrCanvasHeight(self, event): XXX + @GuiCanvasCommandDecorator("Decrease canvas height", "Decrease canvas height", ["toolDecrCanvasH.png"], None, None) def canvasDecrCanvasHeight(self, event): if self.parentCanvas.canvas.size[1] > 1: self.parentCanvas.resize([self.parentCanvas.canvas.size[0], self.parentCanvas.canvas.size[1] - 1]) # }}} # {{{ canvasDecrCanvasHeightWidth(self, event): XXX + @GuiCanvasCommandDecorator("Decrease canvas size", "Decrease canvas size", ["toolDecrCanvasHW.png"], None, None) def canvasDecrCanvasHeightWidth(self, event): self.canvasDecrCanvasHeight(event) self.canvasDecrCanvasWidth(event) # }}} # {{{ canvasDecrCanvasWidth(self, event): XXX + @GuiCanvasCommandDecorator("Decrease canvas width", "Decrease canvas width", ["toolDecrCanvasW.png"], None, None) def canvasDecrCanvasWidth(self, event): if self.parentCanvas.canvas.size[0] > 1: self.parentCanvas.resize([self.parentCanvas.canvas.size[0] - 1, self.parentCanvas.canvas.size[1]]) # }}} # {{{ canvasIncrBrushHeight(self, event): XXX + @GuiCanvasCommandDecorator("Increase brush height", "Increase brush height", ["toolIncrBrushH.png"], None, None) def canvasIncrBrushHeight(self, event): self.parentCanvas.brushSize[1] += 1 - self.parentFrame.update(brushSize=self.parentCanvas.brushSize) + self.update(brushSize=self.parentCanvas.brushSize) # }}} # {{{ canvasIncrBrushHeightWidth(self, event): XXX + @GuiCanvasCommandDecorator("Increase brush size", "Increase brush size", ["toolIncrBrushHW.png"], None, None) def canvasIncrBrushHeightWidth(self, event): self.canvasIncrBrushHeight(event) self.canvasIncrBrushWidth(event) # }}} # {{{ canvasIncrBrushWidth(self, event): XXX + @GuiCanvasCommandDecorator("Increase brush width", "Increase brush width", ["toolIncrBrushW.png"], None, None) def canvasIncrBrushWidth(self, event): self.parentCanvas.brushSize[0] += 1 - self.parentFrame.update(brushSize=self.parentCanvas.brushSize) + self.update(brushSize=self.parentCanvas.brushSize) # }}} # {{{ canvasIncrCanvasHeight(self, event): XXX + @GuiCanvasCommandDecorator("Increase canvas height", "Increase canvas height", ["toolIncrCanvasH.png"], None, None) def canvasIncrCanvasHeight(self, event): self.parentCanvas.resize([self.parentCanvas.canvas.size[0], self.parentCanvas.canvas.size[1] + 1]) # }}} # {{{ canvasIncrCanvasHeightWidth(self, event): XXX + @GuiCanvasCommandDecorator("Increase canvas size", "Increase canvas size", ["toolIncrCanvasHW.png"], None, None) def canvasIncrCanvasHeightWidth(self, event): self.canvasIncrCanvasHeight(event) self.canvasIncrCanvasWidth(event) # }}} # {{{ canvasIncrCanvasWidth(self, event): XXX + @GuiCanvasCommandDecorator("Increase canvas width", "Increase canvas width", ["toolIncrCanvasW.png"], None, None) def canvasIncrCanvasWidth(self, event): self.parentCanvas.resize([self.parentCanvas.canvas.size[0] + 1, self.parentCanvas.canvas.size[1]]) # }}} + # {{{ canvasTool(self, f, idx): XXX + @GuiCanvasSelectDecorator(0, "Circle", "&Circle", ["toolCircle.png"], [wx.ACCEL_CTRL, ord("C")], False) + @GuiCanvasSelectDecorator(1, "Clone", "Cl&one", ["toolClone.png"], [wx.ACCEL_CTRL, ord("E")], False) + @GuiCanvasSelectDecorator(2, "Fill", "&Fill", ["toolFill.png"], [wx.ACCEL_CTRL, ord("F")], False) + @GuiCanvasSelectDecorator(3, "Line", "&Line", ["toolLine.png"], [wx.ACCEL_CTRL, ord("L")], False) + @GuiCanvasSelectDecorator(4, "Move", "&Move", ["toolMove.png"], [wx.ACCEL_CTRL, ord("M")], False) + @GuiCanvasSelectDecorator(5, "Rectangle", "&Rectangle", ["toolRect.png"], [wx.ACCEL_CTRL, ord("R")], True) + @GuiCanvasSelectDecorator(6, "Text", "&Text", ["toolText.png"], [wx.ACCEL_CTRL, ord("T")], False) + def canvasTool(self, f, idx): + def canvasTool_(self, event): + self.currentTool = [ToolCircle, ToolSelectClone, ToolFill, ToolLine, ToolSelectMove, ToolRect, ToolText][idx](self.parentCanvas) + self.parentFrame.menuItemsById[self.canvasTool.attrList[idx]["id"]].Check(True) + toolBar = self.parentFrame.toolBarItemsById[self.canvasTool.attrList[idx]["id"]].GetToolBar() + toolBar.ToggleTool(self.canvasTool.attrList[idx]["id"], True) + self.update(toolName=self.currentTool.name) + setattr(canvasTool_, "attrDict", f.attrList[idx]) + setattr(canvasTool_, "isSelect", True) + return canvasTool_ + # }}} # {{{ canvasExportAsAnsi(self, event): XXX + @GuiCanvasCommandDecorator("Export as ANSI...", "Export as ANSI...", None, None, None) def canvasExportAsAnsi(self, event): with wx.FileDialog(self.parentFrame, "Save As...", os.getcwd(), "", "ANSI files (*.ans;*.txt)|*.ans;*.txt|All Files (*.*)|*.*", wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dialog: if dialog.ShowModal() == wx.ID_CANCEL: @@ -227,6 +366,7 @@ class GuiCanvasInterface(): return True # }}} # {{{ canvasExportAsPng(self, event): XXX + @GuiCanvasCommandDecorator("Export as PNG...", "Export as PN&G...", None, None, None) def canvasExportAsPng(self, event): with wx.FileDialog(self.parentFrame, "Save As...", os.getcwd(), "", "PNG (*.png)|*.png|All Files (*.*)|*.*", wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dialog: if dialog.ShowModal() == wx.ID_CANCEL: @@ -234,16 +374,15 @@ class GuiCanvasInterface(): else: outPathName = dialog.GetPath() self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) - self.parentCanvas.canvas.exportStore.exportBitmapToPngFile( \ - self.parentCanvas.canvasBackend.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)) return True # }}} # {{{ canvasExportImgur(self, event): XXX + @GuiCanvasCommandDecorator("Export to Imgur...", "Export to I&mgur...", None, None, haveUrllib) def canvasExportImgur(self, event): self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) - rc, status, result = self.parentCanvas.canvas.exportStore.exportBitmapToImgur( \ - self.imgurApiKey, self.parentCanvas.canvasBackend.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)) if rc: if not wx.TheClipboard.IsOpened(): @@ -253,6 +392,7 @@ class GuiCanvasInterface(): wx.MessageBox("Failed to export to Imgur: {}".format(result), "Export to Imgur", wx.ICON_EXCLAMATION | wx.OK) # }}} # {{{ canvasExportPastebin(self, event): XXX + @GuiCanvasCommandDecorator("Export to Pastebin...", "Export to Pasteb&in...", None, None, haveUrllib) def canvasExportPastebin(self, event): self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) pasteStatus, pasteResult = self.parentCanvas.canvas.exportStore.exportPastebin("", self.parentCanvas.canvas.map, self.parentCanvas.canvas.size) @@ -267,6 +407,7 @@ class GuiCanvasInterface(): wx.MessageBox("Failed to export to Pastebin: " + pasteResult, "Export to Pastebin", wx.OK|wx.ICON_EXCLAMATION) # }}} # {{{ canvasExportToClipboard(self, event): XXX + @GuiCanvasCommandDecorator("Export to clipboard", "&Export to clipboard", None, None, None) def canvasExportToClipboard(self, event): self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) rc, outBuffer = self.parentCanvas.canvas.exportStore.exportTextBuffer(self.parentCanvas.canvas.map, self.parentCanvas.canvas.size) @@ -277,6 +418,7 @@ class GuiCanvasInterface(): return True # }}} # {{{ canvasImportAnsi(self, event): XXX + @GuiCanvasCommandDecorator("Import ANSI...", "Import ANSI...", None, None, None) def canvasImportAnsi(self, event): if self.canvasPathName != None: saveChanges = self._dialogSaveChanges() @@ -297,13 +439,14 @@ class GuiCanvasInterface(): self.parentCanvas.update(self.parentCanvas.canvas.importStore.inSize, False, self.parentCanvas.canvas.importStore.outMap) self.canvasPathName = "(Imported)" self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) - self.parentFrame.update(pathName="(Imported)", undoLevel=-1) + self.update(pathName="(Imported)", undoLevel=-1) return True else: print("error: {}".format(error), file=sys.stderr) return False # }}} # {{{ canvasImportFromClipboard(self, event): XXX + @GuiCanvasCommandDecorator("Import from clipboard", "&Import from clipboard", None, None, None) def canvasImportFromClipboard(self, event): rc = False if wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_TEXT)) \ @@ -324,7 +467,7 @@ class GuiCanvasInterface(): self.parentCanvas.update(self.parentCanvas.canvas.importStore.inSize, False, self.parentCanvas.canvas.importStore.outMap) self.canvasPathName = "(Clipboard)" self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) - self.parentFrame.update(pathName="(Clipboard)", undoLevel=-1) + self.update(pathName="(Clipboard)", undoLevel=-1) else: print("error: {}".format(error), file=sys.stderr) wx.TheClipboard.Close() @@ -333,6 +476,7 @@ class GuiCanvasInterface(): dialog.ShowModal() # }}} # {{{ canvasImportSauce(self, event): XXX + @GuiCanvasCommandDecorator("Import SAUCE...", "Import SAUCE...", None, None, None) def canvasImportSauce(self, event): if self.canvasPathName != None: saveChanges = self._dialogSaveChanges() @@ -353,75 +497,110 @@ class GuiCanvasInterface(): self.parentCanvas.update(self.parentCanvas.canvas.importStore.inSize, False, self.parentCanvas.canvas.importStore.outMap) self.canvasPathName = "(Imported)" self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) - self.parentFrame.update(pathName="(Imported)", undoLevel=-1) + self.update(pathName="(Imported)", undoLevel=-1) return True else: print("error: {}".format(error), file=sys.stderr) return False # }}} - # {{{ canvasToolCircle(self, event): XXX - def canvasToolCircle(self, event): - self.canvasTool = ToolCircle(self.parentCanvas) - self.parentFrame.menuItemsById[self.parentFrame.CID_CIRCLE[0]].Check(True) - toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_CIRCLE[0]].GetToolBar() - toolBar.ToggleTool(self.parentFrame.CID_CIRCLE[0], True) - self.parentFrame.update(toolName=self.canvasTool.name) + # {{{ update(self, **kwargs): XXX + def update(self, **kwargs): + self.lastPanelState.update(kwargs); textItems = []; + if "cellPos" in self.lastPanelState: + textItems.append("X: {:03d} Y: {:03d}".format(*self.lastPanelState["cellPos"])) + if "size" in self.lastPanelState: + textItems.append("W: {:03d} H: {:03d}".format(*self.lastPanelState["size"])) + if "brushSize" in self.lastPanelState: + textItems.append("Brush: {:02d}x{:02d}".format(*self.lastPanelState["brushSize"])) + if "colours" in self.lastPanelState: + textItems.append("FG: {:02d}, BG: {:02d}".format(*self.lastPanelState["colours"])) + textItems.append("{} on {}".format( + Colours[self.lastPanelState["colours"][0]][4] if self.lastPanelState["colours"][0] != -1 else "Transparent", + Colours[self.lastPanelState["colours"][1]][4] if self.lastPanelState["colours"][1] != -1 else "Transparent")) + if "pathName" in self.lastPanelState: + if self.lastPanelState["pathName"] != "": + basePathName = os.path.basename(self.lastPanelState["pathName"]) + textItems.append("Current file: {}".format(basePathName)) + self.parentFrame.SetTitle("{} - roar".format(basePathName)) + else: + self.parentFrame.SetTitle("roar") + if "toolName" in self.lastPanelState: + textItems.append("Current tool: {}".format(self.lastPanelState["toolName"])) + self.parentFrame.statusBar.SetStatusText(" | ".join(textItems)) + if "undoLevel" in self.lastPanelState: + if self.lastPanelState["undoLevel"] >= 0: + self.parentFrame.menuItemsById[self.canvasUndo.attrDict["id"]].Enable(True) + toolBar = self.parentFrame.toolBarItemsById[self.canvasUndo.attrDict["id"]].GetToolBar() + toolBar.EnableTool(self.canvasUndo.attrDict["id"], True) + else: + self.parentFrame.menuItemsById[self.canvasUndo.attrDict["id"]].Enable(False) + toolBar = self.parentFrame.toolBarItemsById[self.canvasUndo.attrDict["id"]].GetToolBar() + toolBar.EnableTool(self.canvasUndo.attrDict["id"], False) + if self.lastPanelState["undoLevel"] > 0: + self.parentFrame.menuItemsById[self.canvasRedo.attrDict["id"]].Enable(True) + toolBar = self.parentFrame.toolBarItemsById[self.canvasRedo.attrDict["id"]].GetToolBar() + toolBar.EnableTool(self.canvasRedo.attrDict["id"], True) + else: + self.parentFrame.menuItemsById[self.canvasRedo.attrDict["id"]].Enable(False) + toolBar = self.parentFrame.toolBarItemsById[self.canvasRedo.attrDict["id"]].GetToolBar() + toolBar.EnableTool(self.canvasRedo.attrDict["id"], False) # }}} - # {{{ canvasToolFill(self, event): XXX - def canvasToolFill(self, event): - self.canvasTool = ToolFill(self.parentCanvas) - self.parentFrame.menuItemsById[self.parentFrame.CID_FILL[0]].Check(True) - toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_FILL[0]].GetToolBar() - toolBar.ToggleTool(self.parentFrame.CID_FILL[0], True) - self.parentFrame.update(toolName=self.canvasTool.name) + + # {{{ accels + accels = ( + canvasNew, canvasOpen, canvasSave, canvasExit, canvasUndo, canvasRedo, + canvasTool(None, canvasTool, 5), canvasTool(None, canvasTool, 0), canvasTool(None, canvasTool, 2), canvasTool(None, canvasTool, 3), canvasTool(None, canvasTool, 6), canvasTool(None, canvasTool, 1), canvasTool(None, canvasTool, 4), + ) # }}} - # {{{ canvasToolLine(self, event): XXX - def canvasToolLine(self, event): - self.canvasTool = ToolLine(self.parentCanvas) - self.parentFrame.menuItemsById[self.parentFrame.CID_LINE[0]].Check(True) - toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_LINE[0]].GetToolBar() - toolBar.ToggleTool(self.parentFrame.CID_LINE[0], True) - self.parentFrame.update(toolName=self.canvasTool.name) + # {{{ menus + menus = ( + ("&File", + canvasNew, canvasOpen, canvasSave, canvasSaveAs, NID_MENU_SEP, + canvasExportAsAnsi, canvasExportToClipboard, canvasExportImgur, canvasExportPastebin, canvasExportAsPng, NID_MENU_SEP, + canvasImportAnsi, canvasImportFromClipboard, canvasImportSauce, NID_MENU_SEP, + canvasExit, + ), + ("&Edit", + canvasUndo, canvasRedo, NID_MENU_SEP, + canvasCut, canvasCopy, canvasPaste, + canvasDelete, NID_MENU_SEP, + canvasIncrCanvasWidth, canvasDecrCanvasWidth, canvasIncrCanvasHeight, canvasDecrCanvasHeight, NID_MENU_SEP, + canvasIncrCanvasHeightWidth, canvasDecrBrushHeightWidth, NID_MENU_SEP, + canvasIncrBrushWidth, canvasDecrBrushWidth, canvasIncrBrushHeight, canvasDecrBrushHeight, NID_MENU_SEP, + canvasIncrBrushHeightWidth, canvasDecrBrushHeightWidth, NID_MENU_SEP, + canvasBrush(None, canvasBrush, 0), + ), + ("&Tools", + canvasTool(None, canvasTool, 5), canvasTool(None, canvasTool, 0), canvasTool(None, canvasTool, 2), canvasTool(None, canvasTool, 3), canvasTool(None, canvasTool, 6), canvasTool(None, canvasTool, 1), canvasTool(None, canvasTool, 4),), + ("&Help", + canvasAbout,), + ) # }}} - # {{{ canvasToolSelectClone(self, event): XXX - def canvasToolSelectClone(self, event): - self.canvasTool = ToolSelectClone(self.parentCanvas) - self.parentFrame.menuItemsById[self.parentFrame.CID_CLONE_SELECT[0]].Check(True) - toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_CLONE_SELECT[0]].GetToolBar() - toolBar.ToggleTool(self.parentFrame.CID_CLONE_SELECT[0], True) - self.parentFrame.update(toolName=self.canvasTool.name) - # }}} - # {{{ canvasToolSelectMove(self, event): XXX - def canvasToolSelectMove(self, event): - self.canvasTool = ToolSelectMove(self.parentCanvas) - self.parentFrame.menuItemsById[self.parentFrame.CID_MOVE_SELECT[0]].Check(True) - toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_MOVE_SELECT[0]].GetToolBar() - toolBar.ToggleTool(self.parentFrame.CID_MOVE_SELECT[0], True) - self.parentFrame.update(toolName=self.canvasTool.name) - # }}} - # {{{ canvasToolRect(self, event): XXX - def canvasToolRect(self, event): - self.canvasTool = ToolRect(self.parentCanvas) - self.parentFrame.menuItemsById[self.parentFrame.CID_RECT[0]].Check(True) - toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_RECT[0]].GetToolBar() - toolBar.ToggleTool(self.parentFrame.CID_RECT[0], True) - self.parentFrame.update(toolName=self.canvasTool.name) - # }}} - # {{{ canvasToolText(self, event): XXX - def canvasToolText(self, event): - self.canvasTool = ToolText(self.parentCanvas) - self.parentFrame.menuItemsById[self.parentFrame.CID_TEXT[0]].Check(True) - toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_TEXT[0]].GetToolBar() - toolBar.ToggleTool(self.parentFrame.CID_TEXT[0], True) - self.parentFrame.update(toolName=self.canvasTool.name) + # {{{ toolBars + toolBars = ( + (canvasNew, canvasOpen, canvasSave, canvasSaveAs, NID_TOOLBAR_HSEP, + canvasUndo, canvasRedo, NID_TOOLBAR_HSEP, + canvasCut, canvasCopy, canvasPaste, canvasDelete, NID_TOOLBAR_HSEP, + canvasIncrCanvasWidth, canvasDecrCanvasWidth, canvasIncrCanvasHeight, canvasDecrCanvasHeight, NID_TOOLBAR_HSEP, + canvasIncrCanvasHeightWidth, canvasDecrCanvasHeightWidth, NID_TOOLBAR_HSEP, + canvasTool(None, canvasTool, 5), canvasTool(None, canvasTool, 0), canvasTool(None, canvasTool, 2), canvasTool(None, canvasTool, 3), canvasTool(None, canvasTool, 6), canvasTool(None, canvasTool, 1), canvasTool(None, canvasTool, 4), + ), + (canvasColour(None, canvasColour, 0), canvasColour(None, canvasColour, 1), canvasColour(None, canvasColour, 2), canvasColour(None, canvasColour, 3), + canvasColour(None, canvasColour, 4), canvasColour(None, canvasColour, 5), canvasColour(None, canvasColour, 6), canvasColour(None, canvasColour, 7), + canvasColour(None, canvasColour, 8), canvasColour(None, canvasColour, 9), canvasColour(None, canvasColour, 10), canvasColour(None, canvasColour, 11), + canvasColour(None, canvasColour, 12), canvasColour(None, canvasColour, 13), canvasColour(None, canvasColour, 14), canvasColour(None, canvasColour, 15), + canvasColourAlpha(None, canvasColourAlpha, 0), NID_TOOLBAR_HSEP, + canvasIncrBrushWidth, canvasDecrBrushWidth, canvasIncrBrushHeight, canvasDecrBrushHeight, NID_TOOLBAR_HSEP, + canvasIncrBrushHeightWidth, canvasDecrBrushHeightWidth, + ), + ) # }}} # # __init__(self, parentCanvas, parentFrame): def __init__(self, parentCanvas, parentFrame): - self.canvasPathName, self.imgurApiKey = None, ImgurApiKey.imgurApiKey - self.parentCanvas, self.parentFrame = parentCanvas, parentFrame - self.canvasToolRect(None) + self.canvasPathName, self.imgurApiKey, self.lastPanelState, self.parentCanvas, self.parentFrame = None, ImgurApiKey.imgurApiKey, {}, parentCanvas, parentFrame + self._initColourBitmaps() -# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=0 diff --git a/libgui/GuiCanvasPanel.py b/libgui/GuiCanvasPanel.py index 36117fe..b2f9791 100644 --- a/libgui/GuiCanvasPanel.py +++ b/libgui/GuiCanvasPanel.py @@ -57,7 +57,7 @@ class GuiCanvasPanel(wx.Panel): for numNewCol in range(newSize[0]): self._drawPatch(eventDc, False, [numNewCol, numNewRow, 1, 1, 0, " "]) del eventDc; wx.SafeYield(); - self.parentFrame.update(size=newSize, undoLevel=self.canvas.journal.patchesUndoLevel) + self.interface.update(size=newSize, undoLevel=self.canvas.journal.patchesUndoLevel) # }}} # {{{ update(self, newSize, commitUndo=True, newCanvas=None): XXX def update(self, newSize, commitUndo=True, newCanvas=None): @@ -81,7 +81,7 @@ class GuiCanvasPanel(wx.Panel): # {{{ onPanelInput(self, event): XXX def onPanelInput(self, event): self.canvas.dirty, self.canvas.dirtyCursor = False, False - eventDc, eventType, tool = self.backend.getDeviceContext(self), event.GetEventType(), self.interface.canvasTool + eventDc, eventType, tool = self.backend.getDeviceContext(self), event.GetEventType(), self.interface.currentTool if eventType == wx.wxEVT_CHAR: mapPoint = self.brushPos doSkip = tool.onKeyboardEvent(event, mapPoint, self.brushColours, self.brushSize, chr(event.GetUnicodeKey()), self.dispatchPatch, eventDc) @@ -89,7 +89,7 @@ class GuiCanvasPanel(wx.Panel): event.Skip(); return; else: mapPoint = self.backend.xlateEventPoint(event, eventDc) - if mapPoint[0] >= self.canvas.size[0] \ + if mapPoint[0] >= self.canvas.size[0] \ or mapPoint[1] >= self.canvas.size[1]: return self.brushPos = mapPoint @@ -98,9 +98,9 @@ class GuiCanvasPanel(wx.Panel): event.Dragging(), event.LeftIsDown(), event.RightIsDown(), \ self.dispatchPatch, eventDc) if self.canvas.dirty: - self.parentFrame.update(cellPos=self.brushPos, undoLevel=self.canvas.journal.patchesUndoLevel) + self.interface.update(cellPos=self.brushPos, undoLevel=self.canvas.journal.patchesUndoLevel) if eventType == wx.wxEVT_MOTION: - self.parentFrame.update(cellPos=mapPoint) + self.interface.update(cellPos=mapPoint) # }}} # {{{ onPanelLeaveWindow(self, event): XXX def onPanelLeaveWindow(self, event): @@ -120,7 +120,6 @@ class GuiCanvasPanel(wx.Panel): self.brushColours, self.brushPos, self.brushSize = [4, 1], [0, 0], [1, 1] self.canvas, self.canvasPos, self.defaultCanvasPos, self.defaultCanvasSize, self.defaultCellSize = canvas, defaultCanvasPos, defaultCanvasPos, defaultCanvasSize, defaultCellSize self.parentFrame = parentFrame - self.parentFrame.update(brushSize=self.brushSize, colours=self.brushColours) self.Bind(wx.EVT_CLOSE, self.onPanelClose) self.Bind(wx.EVT_ENTER_WINDOW, self.onPanelEnterWindow) @@ -130,4 +129,4 @@ class GuiCanvasPanel(wx.Panel): self.Bind(eventType, self.onPanelInput) self.Bind(wx.EVT_PAINT, self.onPanelPaint) -# vim:expandtab foldmethod=marker sw=4 ts=4 tw=0 +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/libgui/GuiCanvasWxBackend.py b/libgui/GuiCanvasWxBackend.py index bdcf8ba..42bdf78 100644 --- a/libgui/GuiCanvasWxBackend.py +++ b/libgui/GuiCanvasWxBackend.py @@ -13,14 +13,14 @@ class GuiCanvasWxBackend(): # {{{ _drawBrushPatch(self, eventDc, patch): XXX def _drawBrushPatch(self, eventDc, patch): absPoint = self._xlatePoint(patch) - brushBg, brushFg, pen = self._brushes[patch[2]], self._brushes[patch[3]], self._pens[patch[3]] + brushBg, brushFg, pen = self._getBrushPatchColours(patch) self._setBrushDc(brushBg, brushFg, eventDc, pen) eventDc.DrawRectangle(*absPoint, *self.cellSize) # }}} # {{{ _drawCharPatch(self, eventDc, patch): XXX def _drawCharPatch(self, eventDc, patch): absPoint, fontBitmap = self._xlatePoint(patch), wx.Bitmap(*self.cellSize) - brushBg, brushFg, pen = self._brushes[patch[3]], self._brushes[patch[2]], self._pens[patch[3]] + brushBg, brushFg, pen = self._getCharPatchColours(patch) fontDc = wx.MemoryDC(); fontDc.SelectObject(fontBitmap); fontDc.SetTextForeground(wx.Colour(Colours[patch[2]][:4])) fontDc.SetTextBackground(wx.Colour(Colours[patch[3]][:4])) @@ -35,6 +35,30 @@ class GuiCanvasWxBackend(): [pen.Destroy() for pen in self._pens or []] self._brushes, self._lastBrushBg, self._lastBrushFg, self._lastPen, self._pens = None, None, None, None, None # }}} + # {{{ _getBrushPatchColours(self, patch): XXX + def _getBrushPatchColours(self, patch): + if (patch[2] != -1) and (patch[3] != -1): + brushBg, brushFg, pen = self._brushes[patch[2]], self._brushes[patch[3]], self._pens[patch[3]] + elif (patch[2] == -1) and (patch[3] == -1): + brushBg, brushFg, pen = self._brushes[1], self._brushes[1], self._pens[1] + elif patch[2] == -1: + brushBg, brushFg, pen = self._brushes[patch[3]], self._brushes[patch[3]], self._pens[patch[3]] + elif patch[3] == -1: + brushBg, brushFg, pen = self._brushes[1], self._brushes[patch[2]], self._pens[1] + return (brushBg, brushFg, pen) + # }}} + # {{{ _getCharPatchColours(self, patch): XXX + def _getCharPatchColours(self, patch): + if (patch[2] != -1) and (patch[3] != -1): + brushBg, brushFg, pen = self._brushes[patch[3]], self._brushes[patch[2]], self._pens[patch[3]] + elif (patch[2] == -1) and (patch[3] == -1): + brushBg, brushFg, pen = self._brushes[1], self._brushes[1], self._pens[1] + elif patch[2] == -1: + brushBg, brushFg, pen = self._brushes[patch[3]], self._brushes[patch[3]], self._pens[patch[3]] + elif patch[3] == -1: + brushBg, brushFg, pen = self._brushes[1], self._brushes[patch[2]], self._pens[1] + return (brushBg, brushFg, pen) + # }}} # {{{ _initBrushesAndPens(self): XXX def _initBrushesAndPens(self): self._brushes, self._pens = [None for x in range(len(Colours))], [None for x in range(len(Colours))] diff --git a/libgui/GuiFrame.py b/libgui/GuiFrame.py index 967945b..df239e6 100644 --- a/libgui/GuiFrame.py +++ b/libgui/GuiFrame.py @@ -5,208 +5,161 @@ # from Canvas import Canvas -from CanvasExportStore import haveUrllib from GuiCanvasColours import Colours -from GuiCanvasInterface import GuiCanvasInterface from GuiCanvasPanel import GuiCanvasPanel from GuiCanvasWxBackend import GuiCanvasWxBackend -from GuiGeneralFrame import GuiGeneralFrame, \ - TID_ACCELS, TID_COMMAND, TID_LIST, TID_MENU, TID_NOTHING, TID_SELECT, TID_TOOLBAR, \ - NID_MENU_SEP, NID_TOOLBAR_HSEP, NID_TOOLBAR_VSEP from glob import glob -import os, random, wx +import os, random, sys, wx -class GuiFrame(GuiGeneralFrame): +# +# Non-items (0xf000-0xffff) +NID_MENU_SEP = 0xf000 +NID_TOOLBAR_HSEP = 0xf001 + +class GuiFrame(wx.Frame): """XXX""" - # {{{ Commands (0x0100-0x0fff) - # - # MID_FILE - # Id Type Id Labels Icon bitmap Accelerator [Initial state] - CID_NEW = [0x0100, TID_COMMAND, "New", "&New", ["", wx.ART_NEW], [wx.ACCEL_CTRL, ord("N")], None, GuiCanvasInterface.canvasNew] - CID_OPEN = [0x0101, TID_COMMAND, "Open", "&Open", ["", wx.ART_FILE_OPEN], [wx.ACCEL_CTRL, ord("O")], None, GuiCanvasInterface.canvasOpen] - CID_SAVE = [0x0102, TID_COMMAND, "Save", "&Save", ["", wx.ART_FILE_SAVE], [wx.ACCEL_CTRL, ord("S")], None, GuiCanvasInterface.canvasSave] - CID_SAVEAS = [0x0103, TID_COMMAND, "Save As...", "Save &As...", ["", wx.ART_FILE_SAVE_AS], None, None, GuiCanvasInterface.canvasSaveAs] - CID_EXPORT_CLIPB = [0x0104, TID_COMMAND, "Export to clipboard", "&Export to clipboard", None, None, None, GuiCanvasInterface.canvasExportToClipboard] - CID_EXPORT_AS_ANSI = [0x0105, TID_COMMAND, "Export as ANSI...", "Export as ANSI...", None, None, None, GuiCanvasInterface.canvasExportAsAnsi] - CID_EXPORT_AS_PNG = [0x0106, TID_COMMAND, "Export as PNG...", "Export as PN&G...", None, None, None, GuiCanvasInterface.canvasExportAsPng] - CID_EXPORT_IMGUR = [0x0107, TID_COMMAND, "Export to Imgur...", "Export to I&mgur...", None, None, haveUrllib, GuiCanvasInterface.canvasExportImgur] - CID_EXPORT_PASTEBIN = [0x0108, TID_COMMAND, "Export to Pastebin...", "Export to Pasteb&in...", None, None, haveUrllib, GuiCanvasInterface.canvasExportPastebin] - CID_IMPORT_ANSI = [0x0109, TID_COMMAND, "Import ANSI...", "Import ANSI...", None, None, None, GuiCanvasInterface.canvasImportAnsi] - CID_IMPORT_CLIPB = [0x010a, TID_COMMAND, "Import from clipboard", "&Import from clipboard", None, None, None, GuiCanvasInterface.canvasImportFromClipboard] - CID_IMPORT_SAUCE = [0x010b, TID_COMMAND, "Import SAUCE...", "Import SAUCE...", None, None, None, GuiCanvasInterface.canvasImportSauce] - CID_EXIT = [0x010c, TID_COMMAND, "Exit", "E&xit", None, [wx.ACCEL_CTRL, ord("X")], None, GuiCanvasInterface.canvasExit] - - # - # MID_EDIT - # Id Type Id Labels Icon bitmap Accelerator [Initial state] - CID_UNDO = [0x0200, TID_COMMAND, "Undo", "&Undo", ["", wx.ART_UNDO], [wx.ACCEL_CTRL, ord("Z")], False, GuiCanvasInterface.canvasUndo] - CID_REDO = [0x0201, TID_COMMAND, "Redo", "&Redo", ["", wx.ART_REDO], [wx.ACCEL_CTRL, ord("Y")], False, GuiCanvasInterface.canvasRedo] - CID_CUT = [0x0202, TID_COMMAND, "Cut", "Cu&t", ["", wx.ART_CUT], None, False, GuiCanvasInterface.canvasCut] - CID_COPY = [0x0203, TID_COMMAND, "Copy", "&Copy", ["", wx.ART_COPY], None, False, GuiCanvasInterface.canvasCopy] - CID_PASTE = [0x0204, TID_COMMAND, "Paste", "&Paste", ["", wx.ART_PASTE], None, False, GuiCanvasInterface.canvasPaste] - CID_DELETE = [0x0205, TID_COMMAND, "Delete", "De&lete", ["", wx.ART_DELETE], None, False, GuiCanvasInterface.canvasDelete] - CID_INCRW_CANVAS = [0x0206, TID_COMMAND, "Increase canvas width", "Increase canvas width", ["toolIncrCanvasW.png"], None, None, GuiCanvasInterface.canvasIncrCanvasWidth] - CID_DECRW_CANVAS = [0x0207, TID_COMMAND, "Decrease canvas width", "Decrease canvas width", ["toolDecrCanvasW.png"], None, None, GuiCanvasInterface.canvasDecrCanvasWidth] - CID_INCRH_CANVAS = [0x0208, TID_COMMAND, "Increase canvas height", "Increase canvas height", ["toolIncrCanvasH.png"], None, None, GuiCanvasInterface.canvasIncrCanvasHeight] - CID_DECRH_CANVAS = [0x0209, TID_COMMAND, "Decrease canvas height", "Decrease canvas height", ["toolDecrCanvasH.png"], None, None, GuiCanvasInterface.canvasDecrCanvasHeight] - CID_INCRHW_CANVAS = [0x020a, TID_COMMAND, "Increase canvas size", "Increase canvas size", ["toolIncrCanvasHW.png"], None, None, GuiCanvasInterface.canvasIncrCanvasHeightWidth] - CID_DECRHW_CANVAS = [0x020b, TID_COMMAND, "Decrease canvas size", "Decrease canvas size", ["toolDecrCanvasHW.png"], None, None, GuiCanvasInterface.canvasDecrCanvasHeightWidth] - CID_INCRW_BRUSH = [0x020c, TID_COMMAND, "Increase brush width", "Increase brush width", ["toolIncrBrushW.png"], None, None, GuiCanvasInterface.canvasIncrBrushWidth] - CID_DECRW_BRUSH = [0x020d, TID_COMMAND, "Decrease brush width", "Decrease brush width", ["toolDecrBrushW.png"], None, None, GuiCanvasInterface.canvasDecrBrushWidth] - CID_INCRH_BRUSH = [0x020e, TID_COMMAND, "Increase brush height", "Increase brush height", ["toolIncrBrushH.png"], None, None, GuiCanvasInterface.canvasIncrBrushHeight] - CID_DECRH_BRUSH = [0x020f, TID_COMMAND, "Decrease brush height", "Decrease brush height", ["toolDecrBrushH.png"], None, None, GuiCanvasInterface.canvasDecrBrushHeight] - CID_INCRHW_BRUSH = [0x0210, TID_COMMAND, "Increase brush size", "Increase brush size", ["toolIncrBrushHW.png"], None, None, GuiCanvasInterface.canvasIncrBrushHeightWidth] - CID_DECRHW_BRUSH = [0x0211, TID_COMMAND, "Decrease brush size", "Decrease brush size", ["toolDecrBrushHW.png"], None, None, GuiCanvasInterface.canvasDecrBrushHeightWidth] - CID_SOLID_BRUSH = [0x0212, TID_SELECT, "Solid brush", "Solid brush", None, None, True, GuiCanvasInterface.canvasBrushSolid] - - # - # MID_TOOLS - # Id Type Id Labels Icon bitmap Accelerator [Initial state] - CID_RECT = [0x0300, TID_SELECT, "Rectangle", "&Rectangle", ["toolRect.png"], [wx.ACCEL_CTRL, ord("R")], True, GuiCanvasInterface.canvasToolRect] - CID_CIRCLE = [0x0301, TID_SELECT, "Circle", "&Circle", ["toolCircle.png"], [wx.ACCEL_CTRL, ord("C")], False, GuiCanvasInterface.canvasToolCircle] - CID_FILL = [0x0302, TID_SELECT, "Fill", "&Fill", ["toolFill.png"], [wx.ACCEL_CTRL, ord("F")], False, GuiCanvasInterface.canvasToolFill] - CID_LINE = [0x0303, TID_SELECT, "Line", "&Line", ["toolLine.png"], [wx.ACCEL_CTRL, ord("L")], False, GuiCanvasInterface.canvasToolLine] - CID_TEXT = [0x0304, TID_SELECT, "Text", "&Text", ["toolText.png"], [wx.ACCEL_CTRL, ord("T")], False, GuiCanvasInterface.canvasToolText] - CID_CLONE_SELECT = [0x0305, TID_SELECT, "Clone", "Cl&one", ["toolClone.png"], [wx.ACCEL_CTRL, ord("E")], False, GuiCanvasInterface.canvasToolSelectClone] - CID_MOVE_SELECT = [0x0306, TID_SELECT, "Move", "&Move", ["toolMove.png"], [wx.ACCEL_CTRL, ord("M")], False, GuiCanvasInterface.canvasToolSelectMove] - - # - # BID_TOOLBAR - # Id Type Id Labels Icon bitmap Accelerator [Initial state] - CID_COLOUR00 = [0x0400, TID_SELECT, "Colour #00", "Colour #00", None, None, False, GuiCanvasInterface.canvasColour] - CID_COLOUR01 = [0x0401, TID_SELECT, "Colour #01", "Colour #01", None, None, False, GuiCanvasInterface.canvasColour] - CID_COLOUR02 = [0x0402, TID_SELECT, "Colour #02", "Colour #02", None, None, False, GuiCanvasInterface.canvasColour] - CID_COLOUR03 = [0x0403, TID_SELECT, "Colour #03", "Colour #03", None, None, False, GuiCanvasInterface.canvasColour] - CID_COLOUR04 = [0x0404, TID_SELECT, "Colour #04", "Colour #04", None, None, True, GuiCanvasInterface.canvasColour] - CID_COLOUR05 = [0x0405, TID_SELECT, "Colour #05", "Colour #05", None, None, False, GuiCanvasInterface.canvasColour] - CID_COLOUR06 = [0x0406, TID_SELECT, "Colour #06", "Colour #06", None, None, False, GuiCanvasInterface.canvasColour] - CID_COLOUR07 = [0x0407, TID_SELECT, "Colour #07", "Colour #07", None, None, False, GuiCanvasInterface.canvasColour] - CID_COLOUR08 = [0x0408, TID_SELECT, "Colour #08", "Colour #08", None, None, False, GuiCanvasInterface.canvasColour] - CID_COLOUR09 = [0x0409, TID_SELECT, "Colour #09", "Colour #09", None, None, False, GuiCanvasInterface.canvasColour] - CID_COLOUR10 = [0x040a, TID_SELECT, "Colour #10", "Colour #10", None, None, False, GuiCanvasInterface.canvasColour] - CID_COLOUR11 = [0x040b, TID_SELECT, "Colour #11", "Colour #11", None, None, False, GuiCanvasInterface.canvasColour] - CID_COLOUR12 = [0x040c, TID_SELECT, "Colour #12", "Colour #12", None, None, False, GuiCanvasInterface.canvasColour] - CID_COLOUR13 = [0x040d, TID_SELECT, "Colour #13", "Colour #13", None, None, False, GuiCanvasInterface.canvasColour] - CID_COLOUR14 = [0x040e, TID_SELECT, "Colour #14", "Colour #14", None, None, False, GuiCanvasInterface.canvasColour] - CID_COLOUR15 = [0x040f, TID_SELECT, "Colour #15", "Colour #15", None, None, False, GuiCanvasInterface.canvasColour] - - # - # MID_ABOUT - # Id Type Id Labels Icon bitmap Accelerator [Initial state] - CID_ABOUT = [0x0500, TID_COMMAND, "About", "&About", None, None, True, GuiCanvasInterface.canvasAbout] + # {{{ _initAccelTable(self, accels): XXX + def _initAccelTable(self, accels): + accelTableEntries = [] + for accel in accels: + if accel.attrDict["accel"] != None: + accelTableEntries += [wx.AcceleratorEntry()] + if accel.attrDict["id"] == None: + accel.attrDict["id"] = self.lastId; self.lastId += 1; + accelTableEntries[-1].Set(*accel.attrDict["accel"], accel.attrDict["id"]) + accel.attrDict["accelEntry"] = accelTableEntries[-1] + self.itemsById[accel.attrDict["id"]] = accel + self.Bind(wx.EVT_MENU, self.onInput, id=accel.attrDict["id"]) + self.SetAcceleratorTable(wx.AcceleratorTable(accelTableEntries)) # }}} - # {{{ Menus (0x1100-0x1fff) - MID_FILE = (0x1100, TID_MENU, "File", "&File", (CID_NEW, CID_OPEN, CID_SAVE, CID_SAVEAS, NID_MENU_SEP, CID_EXPORT_AS_ANSI, CID_EXPORT_CLIPB, CID_EXPORT_IMGUR, CID_EXPORT_PASTEBIN, CID_EXPORT_AS_PNG, NID_MENU_SEP, CID_IMPORT_ANSI, CID_IMPORT_CLIPB, CID_IMPORT_SAUCE, NID_MENU_SEP, CID_EXIT)) - MID_EDIT = (0x1101, TID_MENU, "Edit", "&Edit", (CID_UNDO, CID_REDO, NID_MENU_SEP, CID_CUT, CID_COPY, CID_PASTE, CID_DELETE, NID_MENU_SEP, CID_INCRW_CANVAS, CID_DECRW_CANVAS, CID_INCRH_CANVAS, CID_DECRH_CANVAS, NID_MENU_SEP, CID_INCRHW_CANVAS, CID_DECRHW_CANVAS, NID_MENU_SEP, CID_INCRW_BRUSH, CID_DECRW_BRUSH, CID_INCRH_BRUSH, CID_DECRH_BRUSH, NID_MENU_SEP, CID_INCRHW_BRUSH, CID_DECRHW_BRUSH, NID_MENU_SEP, CID_SOLID_BRUSH)) - MID_TOOLS = (0x1102, TID_MENU, "Tools", "&Tools", (CID_RECT, CID_CIRCLE, CID_FILL, CID_LINE, CID_TEXT, CID_CLONE_SELECT, CID_MOVE_SELECT)) - MID_HELP = (0x1103, TID_MENU, "Help", "&Help", (CID_ABOUT,)) - # }}} - # {{{ Toolbars (0x2100-0x2fff) - BID_TOOLBAR = (0x2100, TID_TOOLBAR, (CID_NEW, CID_OPEN, CID_SAVE, CID_SAVEAS, NID_TOOLBAR_HSEP, CID_UNDO, CID_REDO, NID_TOOLBAR_HSEP, CID_CUT, CID_COPY, CID_PASTE, CID_DELETE, NID_TOOLBAR_HSEP, CID_INCRW_CANVAS, CID_DECRW_CANVAS, CID_INCRH_CANVAS, CID_DECRH_CANVAS, NID_TOOLBAR_HSEP, CID_INCRHW_CANVAS, CID_DECRHW_CANVAS, NID_TOOLBAR_HSEP, CID_RECT, CID_CIRCLE, CID_FILL, CID_LINE, CID_TEXT, CID_CLONE_SELECT, CID_MOVE_SELECT, NID_TOOLBAR_VSEP, CID_COLOUR00, CID_COLOUR01, CID_COLOUR02, CID_COLOUR03, CID_COLOUR04, CID_COLOUR05, CID_COLOUR06, CID_COLOUR07, CID_COLOUR08, CID_COLOUR09, CID_COLOUR10, CID_COLOUR11, CID_COLOUR12, CID_COLOUR13, CID_COLOUR14, CID_COLOUR15, NID_TOOLBAR_HSEP, CID_INCRW_BRUSH, CID_DECRW_BRUSH, CID_INCRH_BRUSH, CID_DECRH_BRUSH, NID_TOOLBAR_HSEP, CID_INCRHW_BRUSH, CID_DECRHW_BRUSH)) - # }}} - # {{{ Accelerators (hotkeys) (0x3100-0x3fff) - AID_EDIT = (0x3100, TID_ACCELS, (CID_NEW, CID_OPEN, CID_SAVE, CID_EXIT, CID_UNDO, CID_REDO, CID_RECT, CID_CIRCLE, CID_FILL, CID_LINE, CID_TEXT, CID_CLONE_SELECT, CID_MOVE_SELECT)) - # }}} - # {{{ Lists (0x4100-0x4fff) - LID_ACCELS = (0x4100, TID_LIST, (AID_EDIT)) - LID_MENUS = (0x4101, TID_LIST, (MID_FILE, MID_EDIT, MID_TOOLS, MID_HELP)) - LID_TOOLBARS = (0x4102, TID_LIST, (BID_TOOLBAR)) - # }}} - # {{{ _initIcon(self): XXX def _initIcon(self): iconPathNames = glob(os.path.join("assets", "images", "logo*.bmp")) iconPathName = iconPathNames[random.randint(0, len(iconPathNames) - 1)] icon = wx.Icon(); icon.CopyFromBitmap(wx.Bitmap(iconPathName, wx.BITMAP_TYPE_ANY)); self.SetIcon(icon); # }}} - # {{{ _initPaletteToolBitmaps(self): XXX - def _initPaletteToolBitmaps(self): - paletteDescr = ( \ - self.CID_COLOUR00, self.CID_COLOUR01, self.CID_COLOUR02, self.CID_COLOUR03, self.CID_COLOUR04, \ - self.CID_COLOUR05, self.CID_COLOUR06, self.CID_COLOUR07, self.CID_COLOUR08, self.CID_COLOUR09, \ - self.CID_COLOUR10, self.CID_COLOUR11, self.CID_COLOUR12, self.CID_COLOUR13, self.CID_COLOUR14, \ - self.CID_COLOUR15) - for numColour in range(len(paletteDescr)): - toolBitmapColour = Colours[numColour][0:4] - toolBitmap = wx.Bitmap((16,16)) - toolBitmapDc = wx.MemoryDC(); toolBitmapDc.SelectObject(toolBitmap); - toolBitmapBrush = wx.Brush(wx.Colour(toolBitmapColour), wx.BRUSHSTYLE_SOLID) - toolBitmapDc.SetBrush(toolBitmapBrush) - toolBitmapDc.SetBackground(toolBitmapBrush) - toolBitmapDc.SetPen(wx.Pen(wx.Colour(toolBitmapColour), 1)) - toolBitmapDc.DrawRectangle(0, 0, 16, 16) - paletteDescr[numColour][4] = ["", None, toolBitmap] + # {{{ _initMenus(self, menus): XXX + def _initMenus(self, menus): + menuBar = wx.MenuBar() + for menu in menus: + menuWindow = wx.Menu() + for menuItem in menu[1:]: + if menuItem == NID_MENU_SEP: + menuWindow.AppendSeparator() + else: + if menuItem.attrDict["id"] == None: + menuItem.attrDict["id"] = self.lastId; self.lastId += 1; + self.itemsById[menuItem.attrDict["id"]] = menuItem + if hasattr(menuItem, "isSelect"): + menuItemWindow = menuWindow.AppendRadioItem(menuItem.attrDict["id"], menuItem.attrDict["label"], menuItem.attrDict["caption"]) + else: + menuItemWindow = menuWindow.Append(menuItem.attrDict["id"], menuItem.attrDict["label"], menuItem.attrDict["caption"]) + if menuItem.attrDict["accel"] != None: + menuItemWindow.SetAccel(menuItem.attrDict["accelEntry"]) + self.menuItemsById[menuItem.attrDict["id"]] = menuItemWindow + self.Bind(wx.EVT_MENU, self.onInput, menuItemWindow) + if menuItem.attrDict["initialState"] != None: + if hasattr(menuItem, "isSelect"): + menuItemWindow.Check(menuItem.attrDict["initialState"]) + else: + menuItemWindow.Enable(menuItem.attrDict["initialState"]) + menuBar.Append(menuWindow, menu[0]) + self.SetMenuBar(menuBar) + # }}} + # {{{ _initStatusBar(self): XXX + def _initStatusBar(self): + self.statusBar = self.CreateStatusBar() + # }}} + # {{{ _initToolBars(self, toolBars, panelSkin): XXX + def _initToolBars(self, toolBars, panelSkin): + for toolBar in toolBars: + self.toolBars.append(wx.ToolBar(panelSkin, -1, style=wx.TB_FLAT | wx.HORIZONTAL | wx.TB_NODIVIDER)) + self.toolBars[-1].SetToolBitmapSize((16, 16)) + for toolBarItem in toolBar: + if toolBarItem == NID_TOOLBAR_HSEP: + self.toolBars[-1].AddSeparator() + else: + if toolBarItem.attrDict["id"] == None: + toolBarItem.attrDict["id"] = self.lastId; self.lastId += 1; + self.itemsById[toolBarItem.attrDict["id"]] = toolBarItem + if hasattr(toolBarItem, "isSelect"): + toolBarItemWindow = self.toolBars[-1].AddRadioTool(toolBarItem.attrDict["id"], toolBarItem.attrDict["caption"], toolBarItem.attrDict["icon"][2], shortHelp=toolBarItem.attrDict["label"]) + else: + toolBarItemWindow = self.toolBars[-1].AddTool(toolBarItem.attrDict["id"], toolBarItem.attrDict["caption"], toolBarItem.attrDict["icon"][2], shortHelp=toolBarItem.attrDict["label"]) + self.toolBarItemsById[toolBarItem.attrDict["id"]] = toolBarItemWindow + self.Bind(wx.EVT_TOOL, self.onInput, toolBarItemWindow) + self.Bind(wx.EVT_TOOL_RCLICKED, self.onInput, toolBarItemWindow) + if toolBarItem.attrDict["initialState"] != None: + if hasattr(toolBarItem, "isSelect"): + toolBarItemWindow.Toggle(toolBarItem.attrDict["initialState"]) + else: + toolBarItemWindow.Enable(toolBarItem.attrDict["initialState"]) + for toolBar in self.toolBars: + self.sizerSkin.Add(toolBar, 0, wx.ALIGN_LEFT | wx.ALL, 3) + toolBar.Realize(); toolBar.Fit(); + # }}} + # {{{ _initToolBitmaps(self, toolBars): XXX + def _initToolBitmaps(self, toolBars): + for toolBar in toolBars: + for toolBarItem in toolBar: + if toolBarItem == NID_TOOLBAR_HSEP: + continue + elif toolBarItem.attrDict["icon"] == None: + toolBarItem.attrDict["icon"] = ["", None, wx.ArtProvider.GetBitmap(wx.ART_HELP, wx.ART_TOOLBAR, (16, 16))] + elif (toolBarItem.attrDict["icon"][0] == "") \ + and (toolBarItem.attrDict["icon"][1] != None): + toolBarItem.attrDict["icon"] = ["", None, wx.ArtProvider.GetBitmap(toolBarItem.attrDict["icon"][1], wx.ART_TOOLBAR, (16, 16))] + elif (toolBarItem.attrDict["icon"][0] == "") \ + and (toolBarItem.attrDict["icon"][1] == None): + toolBarItem.attrDict["icon"] = ["", None, toolBarItem.attrDict["icon"][2]] + elif toolBarItem.attrDict["icon"][0] != "": + toolBitmapPathName = os.path.dirname(sys.argv[0]) + toolBitmapPathName = os.path.join(toolBitmapPathName, "assets", "images", toolBarItem.attrDict["icon"][0]) + toolBitmap = wx.Bitmap((16, 16)) + toolBitmap.LoadFile(toolBitmapPathName, wx.BITMAP_TYPE_ANY) + toolBarItem.attrDict["icon"] = ["", None, toolBitmap] # }}} - # {{{ update(self, **kwargs): XXX - def update(self, **kwargs): - self.lastPanelState.update(kwargs); textItems = []; - if "cellPos" in self.lastPanelState: - textItems.append("X: {:03d} Y: {:03d}".format(*self.lastPanelState["cellPos"])) - if "size" in self.lastPanelState: - textItems.append("W: {:03d} H: {:03d}".format(*self.lastPanelState["size"])) - if "brushSize" in self.lastPanelState: - textItems.append("Brush: {:02d}x{:02d}".format(*self.lastPanelState["brushSize"])) - if "colours" in self.lastPanelState: - textItems.append("FG: {:02d}, BG: {:02d}".format(*self.lastPanelState["colours"])) - textItems.append("{} on {}".format(Colours[self.lastPanelState["colours"][0]][4], Colours[self.lastPanelState["colours"][1]][4])) - if "pathName" in self.lastPanelState: - if self.lastPanelState["pathName"] != "": - basePathName = os.path.basename(self.lastPanelState["pathName"]) - textItems.append("Current file: {}".format(basePathName)) - self.SetTitle("{} - roar".format(basePathName)) - else: - self.SetTitle("roar") - if "toolName" in self.lastPanelState: - textItems.append("Current tool: {}".format(self.lastPanelState["toolName"])) - self.statusBar.SetStatusText(" | ".join(textItems)) - if "undoLevel" in self.lastPanelState: - if self.lastPanelState["undoLevel"] >= 0: - self.menuItemsById[self.CID_UNDO[0]].Enable(True) - toolBar = self.toolBarItemsById[self.CID_UNDO[0]].GetToolBar() - toolBar.EnableTool(self.CID_UNDO[0], True) - else: - self.menuItemsById[self.CID_UNDO[0]].Enable(False) - toolBar = self.toolBarItemsById[self.CID_UNDO[0]].GetToolBar() - toolBar.EnableTool(self.CID_UNDO[0], False) - if self.lastPanelState["undoLevel"] > 0: - self.menuItemsById[self.CID_REDO[0]].Enable(True) - toolBar = self.toolBarItemsById[self.CID_REDO[0]].GetToolBar() - toolBar.EnableTool(self.CID_REDO[0], True) - else: - self.menuItemsById[self.CID_REDO[0]].Enable(False) - toolBar = self.toolBarItemsById[self.CID_REDO[0]].GetToolBar() - toolBar.EnableTool(self.CID_REDO[0], False) - # }}} # {{{ onInput(self, event): XXX def onInput(self, event): - eventId = event.GetId() - if eventId >= self.CID_COLOUR00[0] \ - and eventId <= self.CID_COLOUR15[0]: - numColour = eventId - self.CID_COLOUR00[0] - self.itemsById[eventId][7](self.canvasPanel.interface, event, numColour) - else: - self.itemsById[eventId][7](self.canvasPanel.interface, event) + eventId = event.GetId(); self.itemsById[eventId](self.canvasPanel.interface, event); # }}} # - # __init__(self, parent, appSize=(840, 630), defaultCanvasPos=(0, 75), defaultCanvasSize=(100, 30), defaultCellSize=(7, 14)): initialisation method - def __init__(self, parent, appSize=(840, 630), defaultCanvasPos=(0, 75), defaultCanvasSize=(100, 30), defaultCellSize=(7, 14)): - self._initPaletteToolBitmaps() - self.panelSkin = super().__init__(parent, wx.ID_ANY, "", size=appSize) - self.lastPanelState, self.canvasPanel = {}, None - self._initIcon() + # __init__(self, canvasInterface, parent, appSize=(840, 630), defaultCanvasPos=(0, 75), defaultCanvasSize=(100, 30), defaultCellSize=(7, 14)): initialisation method + def __init__(self, canvasInterface, parent, appSize=(840, 630), defaultCanvasPos=(0, 75), defaultCanvasSize=(100, 30), defaultCellSize=(7, 14)): + super().__init__(parent, wx.ID_ANY, "", size=appSize) + self.itemsById, self.menuItemsById, self.toolBarItemsById = {}, {}, {}; self.lastId = 0; + self.panelSkin, self.sizerSkin, self.toolBars = wx.Panel(self, wx.ID_ANY), wx.BoxSizer(wx.VERTICAL), [] - self.canvas = Canvas(defaultCanvasSize) - self.canvasPanel = GuiCanvasPanel(self.panelSkin, self, GuiCanvasWxBackend, self.canvas, defaultCanvasPos, defaultCanvasSize, defaultCellSize, GuiCanvasInterface) - self.canvasPanel.interface.canvasNew(None) + self.canvas, self.canvasPanel = Canvas(defaultCanvasSize), None + self.canvasPanel = GuiCanvasPanel(self.panelSkin, self, GuiCanvasWxBackend, self.canvas, defaultCanvasPos, defaultCanvasSize, defaultCellSize, canvasInterface) + + # Initialise accelerators (hotkeys) + # Initialise icon + # Initialise menu bar, menus & menu items + # Initialise status bar + # Initialise toolbar & toolbar items + self._initAccelTable(self.canvasPanel.interface.accels) + self._initIcon() + self._initMenus(self.canvasPanel.interface.menus) + self._initStatusBar() + self._initToolBitmaps(self.canvasPanel.interface.toolBars) + self._initToolBars(self.canvasPanel.interface.toolBars, self.panelSkin) self.sizerSkin.AddSpacer(5) - self.sizerSkin.Add(self.canvasPanel, 0, wx.ALL|wx.EXPAND, 14) + self.sizerSkin.Add(self.canvasPanel, 0, wx.ALL | wx.EXPAND, 14) self.panelSkin.SetSizer(self.sizerSkin) self.panelSkin.SetAutoLayout(1) self.sizerSkin.Fit(self.panelSkin) -# vim:expandtab foldmethod=marker sw=4 ts=4 tw=0 + self.canvasPanel.interface.canvasNew(None) + self.canvasPanel.interface.canvasTool(self.canvasPanel.interface.canvasTool, 5)(self.canvasPanel.interface, None) + self.canvasPanel.interface.update(brushSize=self.canvasPanel.brushSize, colours=self.canvasPanel.brushColours) + + # Set focus on & show window + self.SetFocus(); self.Show(True); + +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/libgui/GuiGeneralFrame.py b/libgui/GuiGeneralFrame.py deleted file mode 100644 index 163ad95..0000000 --- a/libgui/GuiGeneralFrame.py +++ /dev/null @@ -1,155 +0,0 @@ -#!/usr/bin/env python3 -# -# GuiGeneralFrame.py -- XXX -# Copyright (c) 2018, 2019 Lucio Andrés Illanes Albornoz -# - -import os, sys, wx - -# -# Types (0xe000-0xefff) -TID_ACCELS = (0xe000) -TID_COMMAND = (0xe001) -TID_LIST = (0xe002) -TID_MENU = (0xe003) -TID_NOTHING = (0xe004) -TID_SELECT = (0xe005) -TID_TOOLBAR = (0xe006) - -# -# Non-items (0xf000-0xffff) -NID_MENU_SEP = (0xf000, TID_NOTHING) -NID_TOOLBAR_HSEP = (0xf001, TID_NOTHING) -NID_TOOLBAR_VSEP = (0xf002, TID_NOTHING) - -class GuiGeneralFrame(wx.Frame): - """XXX""" - - # {{{ _initAccelTable(self, accelsDescr): XXX - def _initAccelTable(self, accelsDescr): - accelTableEntries = [wx.AcceleratorEntry() for n in range(len(accelsDescr[2]))] - self.accelItemsById = {} - for numAccel in range(len(accelsDescr[2])): - accelDescr = accelsDescr[2][numAccel] - if accelDescr[5] != None: - self.itemsById[accelDescr[0]] = accelDescr - accelTableEntries[numAccel].Set(*accelDescr[5], accelDescr[0]) - self.accelItemsById[accelDescr[0]] = accelTableEntries[numAccel] - self.Bind(wx.EVT_MENU, self.onInput, id=accelDescr[0]) - return accelTableEntries - # }}} - # {{{ _initMenus(self, menusDescr): XXX - def _initMenus(self, menusDescr): - self.menuItemsById = {}; menuBar = wx.MenuBar(); - for menuDescr in menusDescr: - menuWindow = wx.Menu() - for menuItem in menuDescr[4]: - if menuItem == NID_MENU_SEP: - menuWindow.AppendSeparator() - elif menuItem[1] == TID_SELECT: - self.itemsById[menuItem[0]] = menuItem - menuItemWindow = menuWindow.AppendRadioItem(menuItem[0], menuItem[3], menuItem[2]) - if menuItem[5] != None: - menuItemWindow.SetAccel(self.accelItemsById[menuItem[0]]) - self.menuItemsById[menuItem[0]] = menuItemWindow - self.Bind(wx.EVT_MENU, self.onInput, menuItemWindow) - if menuItem[6] != None: - menuItemWindow.Check(menuItem[6]) - else: - self.itemsById[menuItem[0]] = menuItem - menuItemWindow = menuWindow.Append(menuItem[0], menuItem[3], menuItem[2]) - if menuItem[5] != None: - menuItemWindow.SetAccel(self.accelItemsById[menuItem[0]]) - self.menuItemsById[menuItem[0]] = menuItemWindow - self.Bind(wx.EVT_MENU, self.onInput, menuItemWindow) - if menuItem[6] != None: - menuItemWindow.Enable(menuItem[6]) - menuBar.Append(menuWindow, menuDescr[3]) - return menuBar - # }}} - # {{{ _initToolBars(self, toolBarsDescr, panelSkin): XXX - def _initToolBars(self, toolBarsDescr, panelSkin): - self.toolBarItemsById = {} - self.sizerSkin = wx.BoxSizer(wx.VERTICAL) - self.toolBars = [None]; numToolBar = 0; - for toolBarItem in toolBarsDescr[2]: - if self.toolBars[numToolBar] == None: - self.toolBars[numToolBar] = wx.ToolBar(panelSkin, -1, style=wx.TB_FLAT | wx.HORIZONTAL | wx.TB_NODIVIDER) - self.toolBars[numToolBar].SetToolBitmapSize((16,16)) - if toolBarItem == NID_TOOLBAR_HSEP: - self.toolBars[numToolBar].AddSeparator() - elif toolBarItem == NID_TOOLBAR_VSEP: - numToolBar += 1; self.toolBars.append(None); - elif toolBarItem[1] == TID_SELECT: - self.itemsById[toolBarItem[0]] = toolBarItem - toolBarItemWindow = self.toolBars[numToolBar].AddRadioTool(toolBarItem[0], toolBarItem[2], toolBarItem[4][2], shortHelp=toolBarItem[2]) - self.toolBarItemsById[toolBarItem[0]] = toolBarItemWindow - if toolBarItem[6] != None: - toolBarItemWindow.Toggle(toolBarItem[6]) - self.Bind(wx.EVT_TOOL, self.onInput, toolBarItemWindow) - self.Bind(wx.EVT_TOOL_RCLICKED, self.onInput, toolBarItemWindow) - else: - self.itemsById[toolBarItem[0]] = toolBarItem - toolBarItemWindow = self.toolBars[numToolBar].AddTool(toolBarItem[0], toolBarItem[2], toolBarItem[4][2], toolBarItem[2]) - self.toolBarItemsById[toolBarItem[0]] = toolBarItemWindow - if toolBarItem[6] != None: - toolBarItemWindow.Enable(toolBarItem[6]) - self.Bind(wx.EVT_TOOL, self.onInput, toolBarItemWindow) - self.Bind(wx.EVT_TOOL_RCLICKED, self.onInput, toolBarItemWindow) - for numToolBar in range(len(self.toolBars)): - self.sizerSkin.Add(self.toolBars[numToolBar], 0, wx.ALL|wx.ALIGN_LEFT, 3) - self.toolBars[numToolBar].Realize() - self.toolBars[numToolBar].Fit() - # }}} - # {{{ _initToolBitmaps(self, toolBarsDescr): XXX - def _initToolBitmaps(self, toolBarsDescr): - for toolBarItem in toolBarsDescr[2]: - if toolBarItem == NID_TOOLBAR_HSEP \ - or toolBarItem == NID_TOOLBAR_VSEP: - continue - elif toolBarItem[4] == None: - toolBarItem[4] = ["", None, wx.ArtProvider.GetBitmap(wx.ART_HELP, wx.ART_TOOLBAR, (16,16))] - elif toolBarItem[4][0] == "" \ - and toolBarItem[4][1] != None: - toolBarItem[4] = ["", None, wx.ArtProvider.GetBitmap(toolBarItem[4][1], wx.ART_TOOLBAR, (16,16))] - elif toolBarItem[4][0] == "" \ - and toolBarItem[4][1] == None: - toolBarItem[4] = ["", None, toolBarItem[4][2]] - elif toolBarItem[4][0] != "": - toolBitmapPathName = os.path.dirname(sys.argv[0]) - toolBitmapPathName = os.path.join(toolBitmapPathName, "assets", "images", toolBarItem[4][0]) - toolBitmap = wx.Bitmap((16,16)) - toolBitmap.LoadFile(toolBitmapPathName, wx.BITMAP_TYPE_ANY) - toolBarItem[4] = ["", None, toolBitmap] - # }}} - # {{{ onInput(self, event): XXX - def onInput(self, event): - pass - # }}} - - # - # __init__(self, *args, **kwargs): initialisation method - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs); self.itemsById = {}; - panelSkin = wx.Panel(self, wx.ID_ANY) - - # Initialise accelerators (hotkeys) - accelTable = wx.AcceleratorTable(self._initAccelTable(self.LID_ACCELS[2])) - self.SetAcceleratorTable(accelTable) - - # Initialise menu bar, menus & menu items - # Initialise toolbar & toolbar items - menuBar = self._initMenus(self.LID_MENUS[2]) - self.SetMenuBar(menuBar) - self._initToolBitmaps(self.LID_TOOLBARS[2]) - toolBar = self._initToolBars(self.LID_TOOLBARS[2], panelSkin) - - # Initialise status bar - self.statusBar = self.CreateStatusBar() - - # Set focus on & show window - self.SetFocus(); self.Show(True); - - return panelSkin - -# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/libtools/ToolText.py b/libtools/ToolText.py index b34c282..bb2e227 100644 --- a/libtools/ToolText.py +++ b/libtools/ToolText.py @@ -19,11 +19,9 @@ class ToolText(Tool): and keyModifiers != wx.MOD_SHIFT: return True else: - if self.textColours == None: - self.textColours = brushColours.copy() if self.textPos == None: self.textPos = list(atPoint) - dispatchFn(eventDc, False, [*self.textPos, *self.textColours, 0, keyChar]) + dispatchFn(eventDc, False, [*self.textPos, *brushColours, 0, keyChar]) if self.textPos[0] < (self.parentCanvas.canvas.size[0] - 1): self.textPos[0] += 1 elif self.textPos[1] < (self.parentCanvas.canvas.size[1] - 1): @@ -35,15 +33,8 @@ class ToolText(Tool): # # onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): XXX def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): - if isLeftDown: - self.textColours, self.textPos = brushColours.copy(), list(atPoint) - elif isRightDown: - self.textColours, self.textPos = [brushColours[1], brushColours[0]], list(atPoint) - else: - if self.textColours == None: - self.textColours = brushColours.copy() - self.textPos = list(atPoint) - dispatchFn(eventDc, True, [*self.textPos, *self.textColours, 0, "_"]) + self.textPos = list(atPoint) + dispatchFn(eventDc, True, [*self.textPos, *brushColours, 0, "_"]) # __init__(self, *args): initialisation method def __init__(self, *args): diff --git a/roar.py b/roar.py index 1f81328..4dbabf4 100755 --- a/roar.py +++ b/roar.py @@ -8,21 +8,21 @@ import os, sys [sys.path.append(os.path.join(os.getcwd(), path)) for path in \ ["libcanvas", "libgui", "librtl", "libtools"]] +from GuiCanvasInterface import GuiCanvasInterface from GuiFrame import GuiFrame import wx # # Entry point def main(*argv): - wxApp = wx.App(False) - appFrame = GuiFrame(None) - if len(argv) > 1 \ + wxApp, appFrame = wx.App(False), GuiFrame(GuiCanvasInterface, None) + if len(argv) > 1 \ and len(argv[1]) > 0: appFrame.canvasPanel.interface.canvasPathName = argv[1] rc, error = appFrame.canvasPanel.canvas.importStore.importTextFile(argv[1]) if rc: appFrame.canvasPanel.update(appFrame.canvasPanel.canvas.importStore.inSize, False, appFrame.canvasPanel.canvas.importStore.outMap) - appFrame.update(pathName=argv[1], undoLevel=-1) + appFrame.canvasPanel.interface.update(pathName=argv[1], undoLevel=-1) else: print("error: {}".format(error), file=sys.stderr) wxApp.MainLoop()