From cbadd29918da648190cd609130f808e11cf01a25 Mon Sep 17 00:00:00 2001 From: Colin Noga Date: Fri, 2 Dec 2011 00:33:09 -0600 Subject: Added a whackload of menu functions - screenshots, select all, deselect, add tileset layer add doodad layer, remoive layer, move layer up, down, to bottom or to top, add tileset (by copying it to the Tileset folder), add doodad, play animation, reset animation, grid, zoom in, zoom out, actual size, show/hide all the docks at will. Placeholders for other stuff also added. --- src/editorui/editormain.py | 85 ++++++++++++ src/mapdata.py | 8 +- src/ui.py | 315 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 398 insertions(+), 10 deletions(-) diff --git a/src/editorui/editormain.py b/src/editorui/editormain.py index b74967b..136eee1 100644 --- a/src/editorui/editormain.py +++ b/src/editorui/editormain.py @@ -23,6 +23,8 @@ class KPMapScene(QtGui.QGraphicsScene): self.ticker.valueChanged.connect(self.thing) self.ticker.setUpdateInterval(16.6666666666667) + self.grid = False + def playPause(self): if self.playing == False: @@ -49,6 +51,89 @@ class KPMapScene(QtGui.QGraphicsScene): self.views()[0].viewport().update() + def drawForeground(self, painter, rect): + if not self.grid: return + + Zoom = KP.mainWindow.ZoomLevel + drawLine = painter.drawLine + + if Zoom >= 4: + startx = rect.x() + startx -= (startx % 24) + endx = startx + rect.width() + 24 + + starty = rect.y() + starty -= (starty % 24) + endy = starty + rect.height() + 24 + + painter.setPen(QtGui.QPen(QtGui.QColor.fromRgb(255,255,255,100), 1, QtCore.Qt.DotLine)) + + x = startx + y1 = rect.top() + y2 = rect.bottom() + while x <= endx: + drawLine(x, starty, x, endy) + x += 24 + + y = starty + x1 = rect.left() + x2 = rect.right() + while y <= endy: + drawLine(startx, y, endx, y) + y += 24 + + + if Zoom >= 2: + startx = rect.x() + startx -= (startx % 96) + endx = startx + rect.width() + 96 + + starty = rect.y() + starty -= (starty % 96) + endy = starty + rect.height() + 96 + + painter.setPen(QtGui.QPen(QtGui.QColor.fromRgb(255,255,255,100), 1, QtCore.Qt.DashLine)) + + x = startx + y1 = rect.top() + y2 = rect.bottom() + while x <= endx: + drawLine(x, starty, x, endy) + x += 96 + + y = starty + x1 = rect.left() + x2 = rect.right() + while y <= endy: + drawLine(startx, y, endx, y) + y += 96 + + + startx = rect.x() + startx -= (startx % 192) + endx = startx + rect.width() + 192 + + starty = rect.y() + starty -= (starty % 192) + endy = starty + rect.height() + 192 + + painter.setPen(QtGui.QPen(QtGui.QColor.fromRgb(255,255,255,100), 2, QtCore.Qt.DashLine)) + + x = startx + y1 = rect.top() + y2 = rect.bottom() + while x <= endx: + drawLine(x, starty, x, endy) + x += 192 + + y = starty + x1 = rect.left() + x2 = rect.right() + while y <= endy: + drawLine(startx, y, endx, y) + y += 192 + + def drawBackground(self, painter, rect): painter.fillRect(rect, QtGui.QColor(209, 218, 236)) diff --git a/src/mapdata.py b/src/mapdata.py index d4bc571..de00b10 100644 --- a/src/mapdata.py +++ b/src/mapdata.py @@ -343,9 +343,11 @@ class KPMap(object): if fromIndex == toIndex: return if fromIndex < 0 or toIndex < 0: - raise ValueError + return if fromIndex >= len(self.layers) or toIndex > len(self.layers): - raise ValueError + return + if fromIndex == toIndex-1: + return self.layerModel.beginMoveRows( QtCore.QModelIndex(), fromIndex, fromIndex, @@ -363,7 +365,7 @@ class KPMap(object): def removeLayer(self, layer): if layer not in self.layers: - raise ValueError + return index = self.layers.index(layer) self.layerModel.beginRemoveRows(QtCore.QModelIndex(), index, index) diff --git a/src/ui.py b/src/ui.py index d5c5c2a..a0bbab7 100644 --- a/src/ui.py +++ b/src/ui.py @@ -94,6 +94,9 @@ class KPLayerList(QtGui.QWidget): layer = self.selectedLayer() scene = KP.mainWindow.scene + if isinstance(layer, KPPathLayer): + return + for obj in layer.objects: item = obj.qtItem if item: @@ -108,11 +111,19 @@ class KPLayerList(QtGui.QWidget): KP.mainWindow.editor.viewport().update() def moveDown(self): - index = self.selectedLayerIndex() + index = self.selectedLayerIndex() KP.map.moveLayer(index, index + 2) KP.mainWindow.editor.viewport().update() + def moveTop(self): + index = self.selectedLayerIndex() + KP.map.moveLayer(index, 0) + KP.mainWindow.editor.viewport().update() + def moveBottom(self): + index = self.selectedLayerIndex() + KP.map.moveLayer(index, len(KP.map.layers)) + KP.mainWindow.editor.viewport().update() class KPDoodadSelector(QtGui.QWidget): @@ -251,8 +262,6 @@ class KPDoodadSelector(QtGui.QWidget): self.objChanged.emit(current.data(32).toPyObject(), current) - - class KPObjectSelector(QtGui.QWidget): def __init__(self): """Initialises the widget. Remember to call setModel() on it with a KPGroupModel @@ -400,7 +409,6 @@ class KPObjectSelector(QtGui.QWidget): objReplaced = QtCore.pyqtSignal(int, KPTileObject) - class KPMainWindow(QtGui.QMainWindow): def __init__(self): QtGui.QMainWindow.__init__(self) @@ -410,37 +418,101 @@ class KPMainWindow(QtGui.QMainWindow): self.editor = KPEditorWidget(self.scene) self.setCentralWidget(self.editor) - self.setupMenuBar() + self.ZoomLevel = 5 self.setupDocks() + self.setupMenuBar() def setupMenuBar(self): mb = self.menuBar() - m = mb.addMenu('&File') - # ... + from PyQt4.QtGui import QKeySequence + + f = mb.addMenu('&File') + self.fa = f.addAction('New') # N + self.fb = f.addAction('Open...') # O + self.fc = f.addAction('Open Recent') # + f.addSeparator() + self.fd = f.addAction('Save') # S + self.fe = f.addAction('Save As...') # Shift S + self.ff = f.addAction('Export...') # E + f.addSeparator() + self.fg = f.addAction('Take Screenshot...', self.screenshot, QKeySequence("Ctrl+Alt+S")) + f.addSeparator() + # self.fi = f.addAction('Quit') + + e = mb.addMenu('Edit') + self.ea = e.addAction('Copy') # C + self.eb = e.addAction('Cut') # X + self.ec = e.addAction('Paste') # V + e.addSeparator() + self.ed = e.addAction('Select All', self.selectAll, QKeySequence.SelectAll) + self.ee = e.addAction('Deselect', self.deSelect, QKeySequence("Ctrl+D")) + + l = mb.addMenu('Layers') + self.la = l.addAction('Add Tileset Layer', self.layerList.addTileLayer, QKeySequence("Ctrl+T")) + self.lb = l.addAction('Add Doodad Layer', self.layerList.addDoodadLayer, QKeySequence("Ctrl+R")) + self.lc = l.addAction('Remove Layer', self.layerList.removeLayer, QKeySequence("Ctrl+Del")) + l.addSeparator() + self.ld = l.addAction('Move Layer Up', self.layerList.moveUp, QKeySequence("Ctrl+Up")) + self.le = l.addAction('Move Layer Down', self.layerList.moveDown, QKeySequence("Ctrl+Down")) + self.lf = l.addAction('Move Layer to Top', self.layerList.moveTop, QKeySequence("Ctrl+Shift+Up")) + self.lg = l.addAction('Move Layer to Bottom', self.layerList.moveBottom, QKeySequence("Ctrl+Shift+Down")) + l.addSeparator() + self.lh = l.addAction('Add Tileset...', self.moveTilesetToFolder, QKeySequence("Ctrl+Shift+T")) + self.li = l.addAction('Add Doodad...', self.doodadSelector.addDoodadfromFile, QKeySequence("Ctrl+Shift+R")) + + a = mb.addMenu('Animate') + self.aa = a.addAction('Play Animations', self.playAnim, QKeySequence("Ctrl+P")) + self.ac = a.addAction('Reset Animations', self.resetAnim, QKeySequence("Ctrl+Shift+P")) + a.addSeparator() + self.ad = a.addAction('Load Animation Presets...') + self.ae = a.addAction('Save Animation Presets...') + self.af = a.addAction('Clear Animation Presets') + + w = mb.addMenu('Window') + self.wa = w.addAction('Show Grid', self.showGrid, QKeySequence("Ctrl+G")) + w.addSeparator() + self.wb = w.addAction('Zoom In', self.ZoomIn, QKeySequence.ZoomIn) + self.wc = w.addAction('Zoom Out', self.ZoomOut, QKeySequence.ZoomOut) + self.wd = w.addAction('Actual Size', self.ZoomActual, QKeySequence("Ctrl+=")) + self.wh = w.addAction('Show Wii Zoom', self.showWiiZoom) + w.addSeparator() + self.we = w.addAction('Hide Layer Palette', self.showHideLayer, QKeySequence("Ctrl+1")) + self.wf = w.addAction('Show Object Palette', self.showHideObject, QKeySequence("Ctrl+2")) + self.wg = w.addAction('Show Doodad Palette', self.showHideDoodad, QKeySequence("Ctrl+3")) + + h = mb.addMenu('Help') + self.ha = h.addAction('About Koopatlas') + self.hb = h.addAction('Koopatlas Documentation') + self.hc = h.addAction('Keyboard Shortcuts') def setupDocks(self): self.layerList = KPLayerList() self.layerListDock = QtGui.QDockWidget('Layers') self.layerListDock.setWidget(self.layerList) + self.layerListDock.visibilityChanged.connect(self.showHideLayerDock) self.layerList.selectedLayerChanged.connect(self.handleSelectedLayerChanged) self.layerList.playPaused.connect(self.scene.playPause) + self.layerList.playPaused.connect(self.playButtonChanged) self.objectSelector = KPObjectSelector() self.objectSelector.objChanged.connect(self.handleSelectedObjectChanged) self.objectSelectorDock = QtGui.QDockWidget('Objects') self.objectSelectorDock.setWidget(self.objectSelector) + self.objectSelectorDock.visibilityChanged.connect(self.showHideObjectDock) + self.objectSelectorDock.hide() self.doodadSelector = KPDoodadSelector() self.doodadSelector.objChanged.connect(self.handleSelectedDoodadChanged) self.doodadSelectorDock = QtGui.QDockWidget('Doodads') self.doodadSelectorDock.setWidget(self.doodadSelector) + self.doodadSelectorDock.visibilityChanged.connect(self.showHideDoodadDock) self.doodadSelectorDock.hide() self.addDockWidget(Qt.RightDockWidgetArea, self.layerListDock) @@ -448,6 +520,10 @@ class KPMainWindow(QtGui.QMainWindow): self.addDockWidget(Qt.RightDockWidgetArea, self.doodadSelectorDock) + ##################### + # Slots for Widgets # + ##################### + @QtCore.pyqtSlot(KPLayer) def handleSelectedLayerChanged(self, layer): self.scene.setCurrentLayer(layer) @@ -464,6 +540,10 @@ class KPMainWindow(QtGui.QMainWindow): self.objectSelector.setModel(KP.map.loadedTilesets[layer.tileset].getModel()) + else: + self.objectSelectorDock.hide() + self.doodadSelectorDock.hide() + @QtCore.pyqtSlot(int, KPTileObject) def handleSelectedObjectChanged(self, index, obj): @@ -477,4 +557,225 @@ class KPMainWindow(QtGui.QMainWindow): self.editor.paintNextID = index + ######################## + # Slots for Menu Items # + ######################## + + # File + ######################## + + + @QtCore.pyqtSlot() + def screenshot(self): + items = ("Current Window", "Entire Map") + + item, ok = QtGui.QInputDialog.getItem(self, "QInputDialog.getItem()", + "Choose a Screenshot Source:", items, 0, False) + if ok and item: + fn = QtGui.QFileDialog.getSaveFileName(self, 'Choose a new filename', '/untitled.png', 'Portable Network Graphics (*.png)') + if fn == '': return + fn = unicode(fn) + + if item == "Current Window": + ScreenshotImage = QtGui.QImage(self.editor.width(), self.editor.height(), QtGui.QImage.Format_ARGB32) + ScreenshotImage.fill(QtCore.Qt.transparent) + + RenderPainter = QtGui.QPainter(ScreenshotImage) + self.editor.render(RenderPainter, QtCore.QRectF(0,0,self.editor.width(), self.editor.height()), QtCore.QRect(QtCore.QPoint(0,0), QtCore.QSize(self.editor.width(), self.editor.height()))) + RenderPainter.end() + + else: + + ScreenshotImage = QtGui.QImage(self.scene.itemsBoundingRect().width()+100, self.scene.itemsBoundingRect().height()+100, QtGui.QImage.Format_ARGB32) + ScreenshotImage.fill(QtCore.Qt.transparent) + + RenderPainter = QtGui.QPainter(ScreenshotImage) + self.scene.render(RenderPainter, QtCore.QRectF(ScreenshotImage.rect()), self.scene.itemsBoundingRect().adjusted(-50.0, -50.0, 50.0, 50.0)) + RenderPainter.end() + + ScreenshotImage.save(fn, 'PNG', 50) + + + # Edit + ######################## + + @QtCore.pyqtSlot() + def selectAll(self): + + path = QtGui.QPainterPath() + path.addRect(self.scene.sceneRect()) + self.scene.setSelectionArea(path) + + + @QtCore.pyqtSlot() + def deSelect(self): + self.scene.clearSelection() + + + # Layers + ######################## + + @QtCore.pyqtSlot() + def moveTilesetToFolder(self): + log = QtGui.QFileDialog() + + path = QtGui.QFileDialog.getOpenFileNames(self, + "Choose a tileset. Tileset will be copied to the Koopatlas Tilesets Folder.", "", + "Koopuzzle Tilesets (*.arc)") + if path: + import shutil + import os + from hashlib import sha256 as sha + + name = os.path.basename(path[:-4]) + shutil.copy(path, 'Tilesets') + + filehandler = open(path) + data = filehandler.read() + filehandler.close() + hash = sha(data).hexdigest() + + KP.map.tilesets[name] = {'path': path, 'hash': hash} + KP.map.loadedTilesets[name] = KPTileset.loadFromArc(path) + + + # Animate + ######################## + + @QtCore.pyqtSlot() + def playAnim(self): + self.scene.playPause() + self.playButtonChanged() + + + @QtCore.pyqtSlot() + def playButtonChanged(self): + if self.scene.playing == True: + self.aa.setText('Stop Animations') + self.layerList.actPlayPause.setIcon(KP.icon('AStop')) + self.layerList.actPlayPause.setText('Stop') + else: + self.aa.setText('Play Animations') + self.layerList.actPlayPause.setIcon(KP.icon('APlay')) + self.layerList.actPlayPause.setText('Play') + + + @QtCore.pyqtSlot() + def resetAnim(self): + if self.scene.playing == True: + self.scene.playPause() + self.scene.playPause() + + + # Window + ######################## + + @QtCore.pyqtSlot(bool) + def showHideLayerDock(self, visible): + if visible: + self.we.setText('Hide Layer Palette') + else: + self.we.setText('Show Layer Palette') + + + @QtCore.pyqtSlot(bool) + def showHideObjectDock(self, visible): + if visible: + self.wf.setText('Hide Object Palette') + else: + self.wf.setText('Show Object Palette') + + + @QtCore.pyqtSlot(bool) + def showHideDoodadDock(self, visible): + if visible: + self.wg.setText('Hide Doodad Palette') + else: + self.wg.setText('Show Doodad Palette') + + + @QtCore.pyqtSlot() + def showHideLayer(self): + if self.layerListDock.isVisible(): + self.layerListDock.hide() + else: + self.layerListDock.show() + + @QtCore.pyqtSlot() + def showHideObject(self): + if self.objectSelectorDock.isVisible(): + self.objectSelectorDock.hide() + else: + self.objectSelectorDock.show() + + @QtCore.pyqtSlot() + def showHideDoodad(self): + if self.doodadSelectorDock.isVisible(): + self.doodadSelectorDock.hide() + else: + self.doodadSelectorDock.show() + + + @QtCore.pyqtSlot() + def ZoomActual(self): + """Handle zooming to the editor size""" + self.ZoomLevel = 5 + self.ZoomTo() + + @QtCore.pyqtSlot() + def ZoomIn(self): + """Handle zooming in""" + self.ZoomLevel += 1 + self.ZoomTo() + + @QtCore.pyqtSlot() + def ZoomOut(self): + """Handle zooming out""" + self.ZoomLevel -= 1 + self.ZoomTo() + + def ZoomTo(self): + """Zoom to a specific level""" + tr = QtGui.QTransform() + + zooms = [5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 150.0, 200.0, 400.0] + scale = zooms[self.ZoomLevel] / 100.0 + + tr.scale(scale, scale) + + + self.editor.setTransform(tr) + + self.wb.setEnabled(self.ZoomLevel != 8) + self.wc.setEnabled(self.ZoomLevel != 0) + self.wd.setEnabled(self.ZoomLevel != 5) + + self.scene.update() + + + @QtCore.pyqtSlot() + def showGrid(self): + """Handle toggling of the grid being showed""" + # settings.setValue('GridEnabled', checked) + + if self.scene.grid == True: + self.scene.grid = False + else: + self.scene.grid = True + + print self.scene.grid + self.scene.update() + + + @QtCore.pyqtSlot(bool) + def showWiiZoom(self): + pass + + + # Help + ######################## + + + + -- cgit v1.2.3