diff --git a/assets/images/roar.png b/assets/images/roar.png index 78291ac..9ad2fec 100644 Binary files a/assets/images/roar.png and b/assets/images/roar.png differ diff --git a/assets/text/TODO b/assets/text/TODO index bb8664a..42e41ec 100644 --- a/assets/text/TODO +++ b/assets/text/TODO @@ -19,10 +19,10 @@ Release roadmap: 1) {copy,cut,delete,insert from,paste}, edit asset in new canvas, import from {canvas,object} -2) operators: crop, scale, shift, slice -3) tools: unicode block elements -4) floating/dockable toolbar https://wxpython.org/Phoenix/docs/html/wx.aui.AuiManager.html -5) reimplement cursor unmasking w/ simple list of points -6) auto{load,save} & {backup,restore} +2) reimplement cursor unmasking w/ simple list of points +3) operators: crop, scale, shift, slice +4) auto{load,save} & {backup,restore} +5) tools: unicode block elements +6) bugs: a) undock all toolbars & resize window b) increase cell size, scroll down vim:ff=dos tw=0 diff --git a/assets/text/hotkeys.txt b/assets/text/hotkeys.txt index 39d6a00..6b06225 100644 --- a/assets/text/hotkeys.txt +++ b/assets/text/hotkeys.txt @@ -12,6 +12,7 @@ Global hotkeys: 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: