From d5935dfbbae6c16874a2d14cbaf5fe9897b7c63c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucio=20Andr=C3=A9s=20Illanes=20Albornoz?= Date: Fri, 27 Sep 2019 20:17:39 +0200 Subject: [PATCH] Various bugfixes & usability improvements. 1) Assets window: adds clear list context menu item. 2) Assets window: allow deleting multiple selected items. 3) Assets window: fix list view cursor key navigation. 4) Backend: correctly blend transparent background cursor cells with canvas character cells. 5) Backend: correctly determine cell size & set font size. 6) Backend: correctly unmask cursor. 7) Backend: disable font anti-aliasing on Windows. 8) Backend: render transparent background cells as RGBA #303030FF. 9) Canvas window: adds accelerator for `View melp?' menu item. 10) Canvas window: implement {dockable,floating} toolbars w/ wx' AUI framework. 11) Canvas window: separate tools toolbar from edit commands toolbar & dock both on right-hand side alongside each other. 12) Flip horizontally tool: flip characters, including some Unicode symbols. 13) Flip vertically tool: flip additional Unicode symbols. 14) Text tool: don't process keyboard events w/ either of <{Alt,AltGr,Ctrl}> modifiers. assets/images/roar.png: updated. --- assets/images/roar.png | Bin 41355 -> 41465 bytes assets/text/TODO | 10 +-- assets/text/hotkeys.txt | 1 + libgui/GuiCanvasWxBackend.py | 39 +++++----- libgui/GuiFrame.py | 20 ++--- libgui/GuiWindow.py | 10 +-- liboperators/OperatorFlipHorizontal.py | 17 ++++- liboperators/OperatorFlipVertical.py | 15 ++-- libroar/RoarAssetsWindow.py | 98 +++++++++++++++++-------- libroar/RoarCanvasCommands.py | 4 +- libroar/RoarCanvasCommandsHelp.py | 4 +- libroar/RoarCanvasWindow.py | 18 ++--- libroar/RoarClient.py | 13 ++-- libtools/ToolText.py | 2 +- 14 files changed, 152 insertions(+), 99 deletions(-) diff --git a/assets/images/roar.png b/assets/images/roar.png index 78291ac082b432f1a03f059e35d04a5e1ddb1450..9ad2fecea6d291b6dbc07922de9ad2a2c6b51735 100644 GIT binary patch literal 41465 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 literal 41355 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 S Save canvas as mIRC art file X Exit Y, Z Redo, undo last action + View melp? Break into Python debugger Canvas hotkeys: diff --git a/libgui/GuiCanvasWxBackend.py b/libgui/GuiCanvasWxBackend.py index e512090..7bf94c8 100644 --- a/libgui/GuiCanvasWxBackend.py +++ b/libgui/GuiCanvasWxBackend.py @@ -83,7 +83,7 @@ class GuiCanvasWxBackend(): def _initBrushesAndPens(self): self._brushes, self._brushesBlend, self._lastBrush, self._lastPen, self._pens, self._pensBlend = [], {}, None, None, [], {} - self._brushAlpha, self._penAlpha = wx.Brush(wx.Colour(Colours[14][:4]), wx.BRUSHSTYLE_SOLID), wx.Pen(wx.Colour(Colours[14][:4]), 1) + self._brushAlpha, self._penAlpha = wx.Brush(wx.Colour(48, 48, 48, 255), wx.BRUSHSTYLE_SOLID), wx.Pen(wx.Colour(48, 48, 48, 255), 1) for mircColour in range(len(Colours)): self._brushes += [wx.Brush(wx.Colour(Colours[mircColour][:4]), wx.BRUSHSTYLE_SOLID)]; self._brushesBlend[mircColour] = {}; self._pens += [wx.Pen(wx.Colour(Colours[mircColour][:4]), 1)]; self._pensBlend[mircColour] = {}; @@ -148,7 +148,7 @@ class GuiCanvasWxBackend(): def drawCursorMaskWithJournal(self, canvas, canvasJournal, eventDc): eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0); - self.drawPatches(canvas, eventDc, canvasJournal.popCursor(), True) + self.drawPatches(canvas, eventDc, canvasJournal.popCursor(), False) eventDc.SetDeviceOrigin(*eventDcOrigin) def drawPatches(self, canvas, eventDc, patches, isCursor=False): @@ -164,14 +164,12 @@ class GuiCanvasWxBackend(): for patchRender in patchesRender: absPoint, charFlag = [a * b for a, b in zip(self.cellSize, patchRender[:2])], False if (patchRender[5] == " ") and (patchRender[3] == -1): - charFlag, patchRender = True, [*patchRender[:-1], "░"] - textBg, textFg = wx.Colour(Colours[patchRender[3]][:4]), wx.Colour(Colours[patchRender[2]][:4]) - if isCursor and (patchRender[5] == " ") and ((canvas.map[patchRender[1]][patchRender[0]][3] != " ") or (canvas.map[patchRender[1]][patchRender[0]][2] & self._CellState.CS_UNDERLINE)): + charFlag, patchRender, textFg = True, [*patchRender[:-1], "░"], wx.Colour(0, 0, 0, 255) + elif isCursor and (patchRender[5] == " ") and ((canvas.map[patchRender[1]][patchRender[0]][3] != " ") or (canvas.map[patchRender[1]][patchRender[0]][2] & self._CellState.CS_UNDERLINE)): charFlag, patchRender = True, [*patchRender[:-2], *canvas.map[patchRender[1]][patchRender[0]][2:]] - textFg = wx.Colour(self._blendColours(canvas.map[patchRender[1]][patchRender[0]][0], patchRender[2])) + textFg = wx.Colour(self._blendColours(canvas.map[patchRender[1]][patchRender[0]][0], patchRender[3])) elif (patchRender[5] != " ") or (patchRender[4] & self._CellState.CS_UNDERLINE): - charFlag = True - textBg, textFg = wx.Colour(Colours[patchRender[3]][:4]), wx.Colour(Colours[patchRender[2]][:4]) + charFlag, textFg = True, wx.Colour(Colours[patchRender[2]][:4]) brush, pen = self._setBrushColours(eventDc, isCursor, patchRender[2:], canvas.map[patchRender[1]][patchRender[0]]) eventDc.DrawRectangle(*absPoint, *self.cellSize) if charFlag: @@ -208,8 +206,17 @@ class GuiCanvasWxBackend(): else: eventDc = GuiBufferedDC(self, self.canvasBitmap, clientSize, wx.PaintDC(panelWindow), viewRect) - def resize(self, canvasSize, cellSize): - winSize = [a * b for a, b in zip(canvasSize, cellSize)] + def resize(self, canvasSize): + if platform.system() == "Windows": + self._font = wx.TheFontList.FindOrCreateFont(self.fontSize, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, self.fontName) + fontInfoDesc = self._font.GetNativeFontInfoDesc().split(";"); fontInfoDesc[12] = "3"; + self._font.SetNativeFontInfo(";".join(fontInfoDesc)) + dc = wx.MemoryDC() + dc.SetFont(self._font); self.cellSize = dc.GetTextExtent("_"); + dc.Destroy() + else: + self._font = wx.Font(self.cellSize[0] + 1, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) + winSize = [a * b for a, b in zip(canvasSize, self.cellSize)] if self.canvasBitmap == None: self.canvasBitmap = wx.Bitmap(winSize) else: @@ -218,11 +225,7 @@ class GuiCanvasWxBackend(): newDc.Blit(0, 0, *self.canvasBitmap.GetSize(), oldDc, 0, 0) oldDc.SelectObject(wx.NullBitmap) self.canvasBitmap.Destroy(); self.canvasBitmap = newBitmap; - self.canvasSize, self.cellSize = canvasSize, cellSize - if platform.system() == "Windows": - self._font = wx.TheFontList.FindOrCreateFont(cellSize[0] + 1, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, self.fontName) - else: - self._font = wx.Font(cellSize[0] + 1, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) + self.canvasSize = canvasSize def xlateEventPoint(self, event, eventDc, viewRect): eventPoint = event.GetLogicalPosition(eventDc) @@ -235,11 +238,11 @@ class GuiCanvasWxBackend(): self.canvasBitmap.Destroy(); self.canvasBitmap = None; self._finiBrushesAndPens() - def __init__(self, canvasSize, cellSize, fontName="Dejavu Sans Mono", fontPathName=os.path.join("assets", "fonts", "DejaVuSansMono.ttf")): + def __init__(self, canvasSize, fontName="Dejavu Sans Mono", fontPathName=os.path.join("assets", "fonts", "DejaVuSansMono.ttf"), fontSize=8): self._brushes, self._font, self._lastBrush, self._lastPen, self._pens = None, None, None, None, None - self.canvasBitmap, self.cellSize, self.fontName, self.fontPathName = None, None, fontName, fontPathName + self.canvasBitmap, self.cellSize, self.fontName, self.fontPathName, self.fontSize = None, None, fontName, fontPathName, fontSize if platform.system() == "Windows": WinDLL("gdi32.dll").AddFontResourceW(self.fontPathName.encode("utf16")) - self._initBrushesAndPens(); self.resize(canvasSize, cellSize); + self._initBrushesAndPens(); self.resize(canvasSize); # vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/libgui/GuiFrame.py b/libgui/GuiFrame.py index c33011f..c62227e 100644 --- a/libgui/GuiFrame.py +++ b/libgui/GuiFrame.py @@ -146,7 +146,7 @@ class GuiFrame(wx.Frame): def loadToolBars(self, toolBars): for toolBar in toolBars: - self.toolBars.append(wx.lib.agw.aui.AuiToolBar(self.panelSkin, -1)) + self.toolBars.append(wx.lib.agw.aui.AuiToolBar(self, -1)) self.toolBars[-1].SetArtProvider(GuiToolBarArtProvider()) self.toolBars[-1].SetToolBitmapSize((16, 16)) for toolBarItem in toolBar: @@ -170,13 +170,16 @@ class GuiFrame(wx.Frame): else: self.toolBars[-1].EnableTool(toolBarItem.attrDict["id"], toolBarItem.attrDict["initialState"]) self.toolBars[-1].Refresh() + self.toolBarPanes, row = [], 0 for toolBar in self.toolBars: - self.sizerSkin.Add(toolBar, 0, wx.ALIGN_LEFT | wx.ALL, 3) toolBar.Realize(); toolBar.Fit(); + self.toolBarPanes += [wx.lib.agw.aui.AuiPaneInfo().ToolbarPane().CaptionVisible(False).CloseButton(False).Dockable(True).Floatable(True).Gripper(True).Row(row).Top()] + self.auiManager.AddPane(toolBar, self.toolBarPanes[-1]); row += 1; + self.auiManager.Update() - def addWindow(self, window, border=14, expand=False): - flags = wx.ALL; flags = flags | wx.EXPAND if expand else flags; - self.sizerSkin.Add(window, 0, flags, border); self.sizerSkin.Fit(self.panelSkin); + def addWindow(self, window): + self.auiManager.AddPane(window, wx.lib.agw.aui.AuiPaneInfo().CaptionVisible(False).Centre().CloseButton(False).Dockable(False).Floatable(False).Gripper(False)) + self.auiManager.Update() def onChar(self, event): event.Skip() @@ -193,11 +196,10 @@ class GuiFrame(wx.Frame): def __init__(self, iconPathName, size, parent=None, title=""): super().__init__(parent, wx.ID_ANY, title, size=size) - self.itemsById, self.menuItemsById, self.toolBarItemsById = {}, {}, {} - self.panelSkin, self.sizerSkin, self.toolBars = wx.Panel(self, wx.ID_ANY), wx.BoxSizer(wx.VERTICAL), [] - self.sizerSkin.AddSpacer(5); self.panelSkin.SetSizer(self.sizerSkin); self.panelSkin.SetAutoLayout(1); + self.auiManager = wx.lib.agw.aui.AuiManager(); self.auiManager.SetManagedWindow(self); + self.itemsById, self.menuItemsById, self.toolBarItemsById, self.toolBars = {}, {}, {}, [] self._initIcon(iconPathName); self.statusBar = self.CreateStatusBar(); - self.sizerSkin.Fit(self.panelSkin); self.SetFocus(); self.Show(True); + self.SetFocus(); self.Show(True); for event, f in ((wx.EVT_CHAR, self.onChar), (wx.EVT_MENU, self.onMenu), (wx.EVT_MOUSEWHEEL, self.onMouseWheel)): self.Bind(event, f) diff --git a/libgui/GuiWindow.py b/libgui/GuiWindow.py index bed0f4b..5dcbae6 100644 --- a/libgui/GuiWindow.py +++ b/libgui/GuiWindow.py @@ -8,8 +8,8 @@ import wx class GuiWindow(wx.ScrolledWindow): def _updateScrollBars(self): - if self.size != None: - clientSize = self.GetClientSize() + if (self.scrollStep != None) and (self.size != None): + self.SetScrollRate(*self.scrollStep); clientSize = self.GetClientSize(); if (self.size[0] > clientSize[0]) or (self.size[1] > clientSize[1]): self.scrollFlag = True; super().SetVirtualSize(self.size); elif self.scrollFlag \ @@ -48,16 +48,16 @@ class GuiWindow(wx.ScrolledWindow): while curWindow != None: curWindow.Layout(); curWindow = curWindow.GetParent(); - def __init__(self, parent, pos, scrollStep, style=0): + def __init__(self, parent, pos, style=0): super().__init__(parent, pos=pos, style=style) if style != 0 else super().__init__(parent, pos=pos) self.parent = parent - self.pos, self.scrollFlag, self.scrollStep, self.size = pos, False, scrollStep, None + self.pos, self.scrollFlag, self.scrollStep, self.size = pos, False, None, None for eventType, f in ( (wx.EVT_CHAR, self.onKeyboardInput), (wx.EVT_CLOSE, self.onClose), (wx.EVT_ENTER_WINDOW, self.onEnterWindow), (wx.EVT_LEAVE_WINDOW, self.onLeaveWindow), (wx.EVT_LEFT_DOWN, self.onMouseInput), (wx.EVT_MOTION, self.onMouseInput), (wx.EVT_PAINT, self.onPaint), (wx.EVT_RIGHT_DOWN, self.onMouseInput), (wx.EVT_SCROLLWIN_LINEDOWN, self.onScroll), (wx.EVT_SCROLLWIN_LINEUP, self.onScroll), (wx.EVT_SIZE, self.onSize)): self.Bind(eventType, f) - self.SetScrollRate(*self.scrollStep); self._updateScrollBars(); + self._updateScrollBars() # vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/liboperators/OperatorFlipHorizontal.py b/liboperators/OperatorFlipHorizontal.py index eb821c3..da19f7e 100644 --- a/liboperators/OperatorFlipHorizontal.py +++ b/liboperators/OperatorFlipHorizontal.py @@ -6,13 +6,26 @@ from Operator import Operator +# TODO + class OperatorFlipHorizontal(Operator): name = "Flip horizontally" + flipPairs = { + "/":"\\", "╱":"╲", + "▀":"▄", "▁":"▔", "▖":"▘", "▗":"▝", + "▙":"▛", "▚":"▞", "▜":"▟", + } def apply(self, region): - region.reverse(); return region; + region.reverse() + for numRow in range(len(region)): + for numCol in range(len(region[numRow])): + if region[numRow][numCol][3] in self.flipPairs: + region[numRow][numCol][3] = self.flipPairs[region[numRow][numCol][3]] + return region def __init__(self, *args): - pass + for flipPairKey in list(self.flipPairs.keys()): + self.flipPairs[self.flipPairs[flipPairKey]] = flipPairKey # vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/liboperators/OperatorFlipVertical.py b/liboperators/OperatorFlipVertical.py index 17752d0..1b42047 100644 --- a/liboperators/OperatorFlipVertical.py +++ b/liboperators/OperatorFlipVertical.py @@ -6,15 +6,15 @@ from Operator import Operator +# TODO + class OperatorFlipVertical(Operator): name = "Flip" flipPairs = { - "(":")", ")":"(", - "/":"\\", "\\":"/", - "\[":"]", "]":"\[", - "\{":"\}", "\}":"\{", - "<":">", ">":"<", - "`":"'", + "(":")", "/":"\\", "╱":"╲", "[":"]", "{":"}", "<":">", "`":"'", + "▌":"▐", "▏":"▕", + "▖":"▗", "▘":"▝", + "▟":"▙", "▛":"▜", "▚":"▞", } def apply(self, region): @@ -26,6 +26,7 @@ class OperatorFlipVertical(Operator): return region def __init__(self, *args): - pass + for flipPairKey in list(self.flipPairs.keys()): + self.flipPairs[self.flipPairs[flipPairKey]] = flipPairKey # vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/libroar/RoarAssetsWindow.py b/libroar/RoarAssetsWindow.py index a22069b..8905997 100644 --- a/libroar/RoarAssetsWindow.py +++ b/libroar/RoarAssetsWindow.py @@ -86,6 +86,28 @@ class RoarAssetsWindow(GuiMiniFrame): with open(localConfFileName, "r", encoding="utf-8") as inFile: self.lastDir = inFile.read().rstrip("\r\n") + def _removeAsset(self, idx): + del self.canvasList[idx]; self.listView.DeleteItem(idx); + itemCount = self.listView.GetItemCount() + if itemCount > 0: + self.listView.Select(self.currentIndex, on=0) + for numCanvas in [n for n in sorted(self.canvasList.keys()) if n >= idx]: + self.canvasList[numCanvas - 1] = self.canvasList[numCanvas]; del self.canvasList[numCanvas]; + [self.listView.SetColumnWidth(col, wx.LIST_AUTOSIZE) for col in (0, 1)] + if (idx == 0) or (idx >= itemCount): + idx = 0 if itemCount > 0 else None + else: + idx = idx if idx < itemCount else None + self.currentIndex = idx + if self.currentIndex != None: + self.listView.Select(self.currentIndex, on=1) + self.drawCanvas(self.canvasList[self.currentIndex][0]) + else: + self.currentIndex = None + [self.listView.SetColumnWidth(col, wx.LIST_AUTOSIZE_USEHEADER) for col in (0, 1)] + self.drawCanvas(Canvas((0, 0))) + return self.currentIndex + def _storeLastDir(self, pathName): localConfFileName = getLocalConfPathName("RecentAssetsDir.txt") with open(localConfFileName, "w", encoding="utf-8") as outFile: @@ -106,12 +128,12 @@ class RoarAssetsWindow(GuiMiniFrame): self.scrollFlag = False; super(wx.ScrolledWindow, self.panelCanvas).SetVirtualSize((0, 0)); def drawCanvas(self, canvas): - panelSize = [a * b for a, b in zip(canvas.size, self.cellSize)] + panelSize = [a * b for a, b in zip(canvas.size, self.backend.cellSize)] self.panelCanvas.SetMinSize(panelSize); self.panelCanvas.SetSize(wx.DefaultCoord, wx.DefaultCoord, *panelSize); curWindow = self.panelCanvas while curWindow != None: curWindow.Layout(); curWindow = curWindow.GetParent(); - self.backend.resize(canvas.size, self.cellSize) + self.backend.resize(canvas.size) eventDc = self.backend.getDeviceContext(self.panelCanvas.GetClientSize(), self.panelCanvas) eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0); patches = [] @@ -144,12 +166,12 @@ class RoarAssetsWindow(GuiMiniFrame): oldSize = [0, 0] if canvas.map == None else canvas.size deltaSize = [b - a for a, b in zip(oldSize, newSize)] if canvas.resize(newSize, False): - panelSize = [a * b for a, b in zip(canvas.size, self.cellSize)] + panelSize = [a * b for a, b in zip(canvas.size, self.backend.cellSize)] self.panelCanvas.SetMinSize(panelSize); self.panelCanvas.SetSize(wx.DefaultCoord, wx.DefaultCoord, *panelSize); curWindow = self.panelCanvas while curWindow != None: curWindow.Layout(); curWindow = curWindow.GetParent(); - self.backend.resize(newSize, self.cellSize) + self.backend.resize(newSize) eventDc = self.backend.getDeviceContext(self.panelCanvas.GetClientSize(), self.panelCanvas) eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0); patches = [] @@ -193,14 +215,27 @@ class RoarAssetsWindow(GuiMiniFrame): else: event.Skip() + def onClearList(self, event): + while len(self.canvasList): + self._removeAsset(list(self.canvasList.keys())[0]) + def onListViewChar(self, event): - index, rc = self.listView.GetFirstSelected(), False - if index != -1: - keyChar, keyModifiers = event.GetKeyCode(), event.GetModifiers() - if (keyChar, keyModifiers) == (wx.WXK_DELETE, wx.MOD_NONE): - self.currentIndex, rc = index, True; self.onRemove(None); - if not rc: - event.Skip() + keyCode = event.GetKeyCode() + if (event.GetModifiers() == wx.MOD_NONE) \ + and (keyCode in (wx.WXK_DOWN, wx.WXK_UP)) \ + and (self.currentIndex != None): + self.listView.Select(self.currentIndex, on=0) + id = +1 if keyCode == wx.WXK_DOWN else -1 + self.currentIndex = (self.currentIndex + id) % len(self.canvasList) + self.listView.Select(self.currentIndex, on=1) + else: + index, rc = self.listView.GetFirstSelected(), False + if index != -1: + keyChar, keyModifiers = event.GetKeyCode(), event.GetModifiers() + if (keyChar, keyModifiers) == (wx.WXK_DELETE, wx.MOD_NONE): + self.currentIndex, rc = index, True; self.onRemove(None); + if not rc: + event.Skip() def onListViewItemSelected(self, event): self.currentIndex = event.GetItem().GetId() @@ -217,6 +252,10 @@ class RoarAssetsWindow(GuiMiniFrame): self.contextMenuItems[4].Enable(False) else: self.contextMenuItems[4].Enable(True) + if len(self.canvasList) == 0: + self.contextMenuItems[7].Enable(False) + else: + self.contextMenuItems[7].Enable(True) self.PopupMenu(self.contextMenu, eventPoint) def onLoad(self, event): @@ -256,23 +295,15 @@ class RoarAssetsWindow(GuiMiniFrame): self._load_list(pathName) def onRemove(self, event): - del self.canvasList[self.currentIndex]; self.listView.DeleteItem(self.currentIndex); - itemCount = self.listView.GetItemCount() - if itemCount > 0: - for numCanvas in [n for n in sorted(self.canvasList.keys()) if n >= self.currentIndex]: - self.canvasList[numCanvas - 1] = self.canvasList[numCanvas]; del self.canvasList[numCanvas]; - [self.listView.SetColumnWidth(col, wx.LIST_AUTOSIZE) for col in (0, 1)] - if (self.currentIndex == 0) or (self.currentIndex >= itemCount): - self.currentIndex = 0 if itemCount > 0 else None + items = [self.listView.GetFirstSelected()] + while True: + item = self.listView.GetNextSelected(items[-1]) + if item != -1: + items += [item] else: - self.currentIndex = self.currentIndex if self.currentIndex < itemCount else None - if self.currentIndex != None: - self.listView.Select(self.currentIndex, on=1) - self.drawCanvas(self.canvasList[self.currentIndex][0]) - else: - self.currentIndex = None - [self.listView.SetColumnWidth(col, wx.LIST_AUTOSIZE_USEHEADER) for col in (0, 1)] - self.drawCanvas(Canvas((0, 0))) + break + while len(items): + self._removeAsset(items[0]); del items[0]; items = [i - 1 for i in items]; def onSaveList(self, event): rc = True @@ -293,12 +324,12 @@ class RoarAssetsWindow(GuiMiniFrame): with wx.MessageDialog(self, "Error: {}".format(error), "", wx.OK | wx.OK_DEFAULT) as dialog: dialogChoice = dialog.ShowModal() - def __init__(self, backend, cellSize, parent, pos=None, size=(400, 400), title="Assets"): + def __init__(self, backend, parent, pos=None, size=(400, 400), title="Assets"): if pos == None: parentRect = parent.GetScreenRect(); pos = (parentRect.x + parentRect.width, parentRect.y); super().__init__(parent, size, title, pos=pos) - self.backend, self.canvasList, self.lastDir = backend((0, 0), cellSize), {}, None - self.cellSize, self.currentIndex, self.leftDown, self.parent, self.scrollFlag = cellSize, None, False, parent, False + self.backend, self.canvasList, self.lastDir = backend((0, 0)), {}, None + self.currentIndex, self.leftDown, self.parent, self.scrollFlag = None, False, parent, False self.Bind(wx.EVT_CHAR, self.onChar) self._loadLastDir() @@ -311,7 +342,9 @@ class RoarAssetsWindow(GuiMiniFrame): ("&Remove", self.onRemove), (None, None), ("Load from l&ist...", self.onLoadList), - ("Sa&ve as list...", self.onSaveList),): + ("Sa&ve as list...", self.onSaveList), + (None, None), + ("Cl&ear list", self.onClearList),): if (text, f) == (None, None): self.contextMenu.AppendSeparator() else: @@ -325,7 +358,8 @@ class RoarAssetsWindow(GuiMiniFrame): self.listView.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onListViewItemSelected) self.listView.Bind(wx.EVT_RIGHT_DOWN, self.onListViewRightDown) - self.panelCanvas = GuiWindow(self, (0, 0), cellSize, wx.BORDER_SUNKEN) + self.panelCanvas = GuiWindow(self, (0, 0), wx.BORDER_SUNKEN) + self.panelCanvas.Bind(wx.EVT_CHAR, self.onChar) self.panelCanvas.Bind(wx.EVT_LEFT_DOWN, self.onPanelLeftDown) self.panelCanvas.Bind(wx.EVT_PAINT, self.onPanelPaint) self.panelCanvas.Bind(wx.EVT_SIZE, self.onPanelSize) diff --git a/libroar/RoarCanvasCommands.py b/libroar/RoarCanvasCommands.py index e3c09f1..df5ad17 100644 --- a/libroar/RoarCanvasCommands.py +++ b/libroar/RoarCanvasCommands.py @@ -123,7 +123,9 @@ class RoarCanvasCommands(RoarCanvasCommandsFile, RoarCanvasCommandsEdit, RoarCan self.canvasUndo, self.canvasRedo, NID_TOOLBAR_HSEP, self.canvasCut, self.canvasCopy, self.canvasPaste, self.canvasDelete, NID_TOOLBAR_HSEP, self.canvasAssetsWindowHide, self.canvasAssetsWindowShow, NID_TOOLBAR_HSEP, - self.canvasTool(self.canvasTool, 1), self.canvasTool(self.canvasTool, 7), self.canvasTool(self.canvasTool, 0), self.canvasTool(self.canvasTool, 3), self.canvasTool(self.canvasTool, 4), self.canvasTool(self.canvasTool, 8), self.canvasTool(self.canvasTool, 5), self.canvasTool(self.canvasTool, 2), self.canvasTool(self.canvasTool, 6), + ]) + toolBars.append( + [self.canvasTool(self.canvasTool, 1), self.canvasTool(self.canvasTool, 7), self.canvasTool(self.canvasTool, 0), self.canvasTool(self.canvasTool, 3), self.canvasTool(self.canvasTool, 4), self.canvasTool(self.canvasTool, 8), self.canvasTool(self.canvasTool, 5), self.canvasTool(self.canvasTool, 2), self.canvasTool(self.canvasTool, 6), ]) toolBars.append( [self.canvasColour(self.canvasColour, 0), self.canvasColour(self.canvasColour, 1), self.canvasColour(self.canvasColour, 2), self.canvasColour(self.canvasColour, 3), diff --git a/libroar/RoarCanvasCommandsHelp.py b/libroar/RoarCanvasCommandsHelp.py index f64718b..435c458 100644 --- a/libroar/RoarCanvasCommandsHelp.py +++ b/libroar/RoarCanvasCommandsHelp.py @@ -7,14 +7,14 @@ from GuiFrame import GuiCommandDecorator, NID_MENU_SEP from RoarWindowAbout import RoarWindowAbout from RoarWindowMelp import RoarWindowMelp -import webbrowser +import webbrowser, wx class RoarCanvasCommandsHelp(): @GuiCommandDecorator("About roar", "&About roar", None, None, True) def canvasAbout(self, event): RoarWindowAbout(self.parentFrame) - @GuiCommandDecorator("View melp?", "View &melp?", None, None, True) + @GuiCommandDecorator("View melp?", "View &melp?", None, [wx.MOD_NONE, wx.WXK_F1], True) def canvasMelp(self, event): RoarWindowMelp(self.parentFrame) diff --git a/libroar/RoarCanvasWindow.py b/libroar/RoarCanvasWindow.py index df97bfa..33cbd81 100644 --- a/libroar/RoarCanvasWindow.py +++ b/libroar/RoarCanvasWindow.py @@ -212,12 +212,12 @@ class RoarCanvasWindow(GuiWindow): def onMouseWheel(self, event): if event.GetModifiers() == wx.MOD_CONTROL: - cd = +1 if event.GetWheelRotation() >= event.GetWheelDelta() else -1 - newCellSize = [cs + cd for cs in self.backend.cellSize] - if (newCellSize[0] > 0) and (newCellSize[1] > 0): - self.backend.cellSize = newCellSize + fd = +1 if event.GetWheelRotation() >= event.GetWheelDelta() else -1 + newFontSize = self.backend.fontSize + fd + if newFontSize > 0: + self.backend.fontSize = newFontSize + self.backend.resize(self.canvas.size) super().resize([a * b for a, b in zip(self.canvas.size, self.backend.cellSize)]) - self.backend.resize(self.canvas.size, self.backend.cellSize) eventDc = self.backend.getDeviceContext(self.GetClientSize(), self) eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0); patches = [] @@ -239,8 +239,8 @@ class RoarCanvasWindow(GuiWindow): oldSize = [0, 0] if self.canvas.map == None else self.canvas.size deltaSize = [b - a for a, b in zip(oldSize, newSize)] if self.canvas.resize(newSize, commitUndo): + self.backend.resize(newSize); self.scrollStep = self.backend.cellSize; super().resize([a * b for a, b in zip(newSize, self.backend.cellSize)]) - self.backend.resize(newSize, self.backend.cellSize) eventDc = self.backend.getDeviceContext(self.GetClientSize(), self) eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0); patches = [] @@ -268,10 +268,10 @@ class RoarCanvasWindow(GuiWindow): self.backend.drawPatches(self.canvas, eventDc, patches, isCursor=False) eventDc.SetDeviceOrigin(*eventDcOrigin) - def __init__(self, backend, canvas, cellSize, commands, parent, parentFrame, pos, scrollStep, size): - super().__init__(parent, pos, scrollStep) + def __init__(self, backend, canvas, commands, parent, pos, size): + super().__init__(parent, pos) self.size = size - self.backend, self.canvas, self.cellSize, self.commands, self.parentFrame = backend(self.size, cellSize), canvas, cellSize, commands(self, parentFrame), parentFrame + self.backend, self.canvas, self.commands, self.parentFrame = backend(self.size), canvas, commands(self, parent), parent self.brushColours, self.brushPos, self.brushSize, self.dirty, self.lastCellState = [4, 1], [0, 0], [1, 1], False, None self.popupEventDc = None self.dropTarget = RoarCanvasWindowDropTarget(self) diff --git a/libroar/RoarClient.py b/libroar/RoarClient.py index c4d61a1..a034150 100644 --- a/libroar/RoarClient.py +++ b/libroar/RoarClient.py @@ -39,13 +39,10 @@ class RoarClient(GuiFrame): if closeFlag: event.Skip(); - def onSize(self, event): - self.canvasPanel.SetMinSize(self.GetSize()); self.canvasPanel.SetSize(wx.DefaultCoord, wx.DefaultCoord, *self.GetSize()); event.Skip(); - - def __init__(self, parent, defaultCanvasPos=(0, 75), defaultCanvasSize=(100, 30), defaultCellSize=(7, 14), size=(840, 640), title=""): + def __init__(self, parent, defaultCanvasPos=(0, 75), defaultCanvasSize=(100, 30), size=(840, 640), title=""): super().__init__(self._getIconPathName(), size, parent, title) self.canvas = Canvas(defaultCanvasSize) - self.canvasPanel = RoarCanvasWindow(GuiCanvasWxBackend, self.canvas, defaultCellSize, RoarCanvasCommands, self.panelSkin, self, defaultCanvasPos, defaultCellSize, defaultCanvasSize) + self.canvasPanel = RoarCanvasWindow(GuiCanvasWxBackend, self.canvas, RoarCanvasCommands, self, defaultCanvasPos, defaultCanvasSize) self.loadAccels(self.canvasPanel.commands.accels, self.canvasPanel.commands.menus, self.canvasPanel.commands.toolBars) self.loadMenus(self.canvasPanel.commands.menus) self._initToolBitmaps(self.canvasPanel.commands.toolBars) @@ -54,8 +51,8 @@ class RoarClient(GuiFrame): self.canvasPanel.commands.canvasNew(None) self.canvasPanel.commands.canvasTool(self.canvasPanel.commands.canvasTool, 1)(None) self.canvasPanel.commands.update(brushSize=self.canvasPanel.brushSize, colours=self.canvasPanel.brushColours) - self.addWindow(self.canvasPanel, expand=True) - self.assetsWindow = RoarAssetsWindow(GuiCanvasWxBackend, defaultCellSize, self) + self.addWindow(self.canvasPanel) + self.assetsWindow = RoarAssetsWindow(GuiCanvasWxBackend, self) self.canvasPanel.commands.canvasAssetsWindowShow(None) self.canvasPanel.operatorsMenu = wx.Menu() @@ -67,6 +64,6 @@ class RoarClient(GuiFrame): menuItemWindow = self.canvasPanel.commands.canvasOpenRecent.attrDict["menu"].Append(self.canvasPanel.commands.canvasClearRecent.attrDict["id"], self.canvasPanel.commands.canvasClearRecent.attrDict["label"], self.canvasPanel.commands.canvasClearRecent.attrDict["caption"]) self.canvasPanel.commands.canvasOpenRecent.attrDict["menu"].Bind(wx.EVT_MENU, self.canvasPanel.commands.canvasClearRecent, menuItemWindow) self.Bind(wx.EVT_CLOSE, self.onClose) - self.Bind(wx.EVT_SIZE, self.onSize) + self.toolBarPanes[0].BestSize(0, 0).Right(); self.toolBarPanes[1].BestSize(0, 0).Right(); self.auiManager.Update(); # vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/libtools/ToolText.py b/libtools/ToolText.py index a47f809..47c833e 100644 --- a/libtools/ToolText.py +++ b/libtools/ToolText.py @@ -111,7 +111,7 @@ class ToolText(Tool): else: brushPos[0], brushPos[1] = 0, 0 rc = True; patchesCursor += [[*brushPos, *brushColours, 0, "_"]]; - else: + elif not (keyModifiers in (wx.MOD_ALT, wx.MOD_ALTGR, wx.MOD_CONTROL)): rc, patches_ = self._processKeyChar(brushColours, brushPos, canvas, keyChar, keyModifiers) patches += patches_ if rc: