diff options
-rw-r--r-- | src/editorui/editormain.py | 85 | ||||
-rw-r--r-- | src/mapdata.py | 8 | ||||
-rw-r--r-- | 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) @@ -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 + ######################## + + + + |