summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common.py3
-rw-r--r--src/editorui.py169
-rw-r--r--src/main.py1
-rw-r--r--src/mapdata.py29
-rw-r--r--src/tileset.py8
-rw-r--r--src/ui.py15
6 files changed, 196 insertions, 29 deletions
diff --git a/src/common.py b/src/common.py
index 2b965d7..cc68e99 100644
--- a/src/common.py
+++ b/src/common.py
@@ -2,8 +2,9 @@ import sys
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import Qt
+from main import KP
+
from tileset import *
from mapdata import *
-from main import KP
diff --git a/src/editorui.py b/src/editorui.py
index 4eeca1d..557fe54 100644
--- a/src/editorui.py
+++ b/src/editorui.py
@@ -1,8 +1,92 @@
from common import *
+from math import floor, ceil
+import weakref
+
+
+class KPEditorItem(QtGui.QGraphicsItem):
+ def __init__(self):
+ QtGui.QGraphicsItem.__init__(self)
+ self.setFlags(
+ self.ItemSendsGeometryChanges |
+ self.ItemIsSelectable |
+ self.ItemIsMovable
+ )
+
+ def itemChange(self, change, value):
+ if change == self.ItemPositionChange:
+ currentX, currentY = self.x(), self.y()
+
+ # snap the item to 24x24
+ newpos = value.toPyObject()
+
+ x, y = newpos.x(), newpos.y()
+
+ x = int((x + 12) / 24) * 24
+ y = int((y + 12) / 24) * 24
+
+ if x < 0: x = 0
+ if x > 12264: x = 12264
+ if y < 0: y = 0
+ if y > 12264: y = 12264
+
+ if x != currentX or y != currentY:
+ print "Position change"
+ self._itemMoved(currentX, currentY, x, y)
+
+ newpos.setX(x)
+ newpos.setY(y)
+ return newpos
+
+ return QtGui.QGraphicsItem.itemChange(self, change, value)
+
+ def boundingRect(self):
+ return self._boundingRect
+
+ def _itemMoved(self, oldX, oldY, newX, newY):
+ pass
+
+
+class KPEditorObject(KPEditorItem):
+ def __init__(self, obj, layer):
+ KPEditorItem.__init__(self)
+ obj.qtItem = self
+ self._objRef = weakref.ref(obj)
+ self._layerRef = weakref.ref(layer)
+ self._updatePosition()
+ self._updateSize()
+
+ def _updatePosition(self):
+ obj = self._objRef()
+ x,y = obj.position
+
+ self.setPos(x*24, y*24)
+
+ def _updateSize(self):
+ self.prepareGeometryChange()
+
+ obj = self._objRef()
+ w,h = obj.size
+
+ self._boundingRect = QtCore.QRectF(0, 0, w*24, h*24)
+ self._selectionRect = QtCore.QRectF(0, 0, w*24-1, h*24-1)
+
+ def paint(self, painter, option, widget):
+ if self.isSelected():
+ painter.setPen(QtGui.QPen(Qt.white, 1, Qt.DotLine))
+ painter.drawRect(self._selectionRect)
+
+ def _itemMoved(self, oldX, oldY, newX, newY):
+ obj = self._objRef()
+ obj.position = (newX/24, newY/24)
+ self._layerRef().updateCache()
+
class KPMapScene(QtGui.QGraphicsScene):
def __init__(self):
- QtGui.QGraphicsScene.__init__(self)
+ QtGui.QGraphicsScene.__init__(self, 0, 0, 512*24, 512*24)
+
+ # todo: handle selectionChanged
+ # todo: look up why I used setItemIndexMethod(self.NoIndex) in Reggie
self.currentLayer = None
@@ -14,10 +98,10 @@ class KPMapScene(QtGui.QGraphicsScene):
areaWidth, areaHeight = rect.width(), rect.height()
areaRight, areaBottom = areaLeft+areaWidth, areaTop+areaHeight
- areaLeftT = areaLeft / 24
- areaTopT = areaTop / 24
- areaRightT = areaRight / 24
- areaBottomT = areaBottom / 24
+ areaLeftT = floor(areaLeft / 24)
+ areaTopT = floor(areaTop / 24)
+ areaRightT = ceil(areaRight / 24)
+ areaBottomT = ceil(areaBottom / 24)
for layer in KP.map.layers:
left, top = layer.cacheBasePos
@@ -33,11 +117,11 @@ class KPMapScene(QtGui.QGraphicsScene):
if top > areaBottomT: continue
# decide how much of the layer we'll actually draw
- drawLeft = max(areaLeftT, left)
- drawRight = min(areaRightT, right)
+ drawLeft = int(max(areaLeftT, left))
+ drawRight = int(min(areaRightT, right))
- drawTop = max(areaTopT, top)
- drawBottom = min(areaBottomT, bottom)
+ drawTop = int(max(areaTopT, top))
+ drawBottom = int(min(areaBottomT, bottom))
srcY = drawTop - top
destY = drawTop * 24
@@ -80,8 +164,73 @@ class KPMapScene(QtGui.QGraphicsScene):
if item:
item.setFlag(flag, value)
+
+
class KPEditorWidget(QtGui.QGraphicsView):
- pass
+ def __init__(self, scene, parent=None):
+ QtGui.QGraphicsView.__init__(self, scene, parent)
+
+ self.setAlignment(Qt.AlignLeft | Qt.AlignTop)
+ self.setDragMode(self.RubberBandDrag)
+
+ self.xScrollBar = QtGui.QScrollBar(Qt.Horizontal, parent)
+ self.setHorizontalScrollBar(self.xScrollBar)
+
+ self.yScrollBar = QtGui.QScrollBar(Qt.Vertical, parent)
+ self.setVerticalScrollBar(self.yScrollBar)
+
+ self.centerOn(0,0)
+
+ # set up stuff for painting
+ self.paintNext = None
+ self.paintNextID = None
+ self._resetPaintVars()
+
+ def _resetPaintVars(self):
+ self.painting = None
+ self.paintingItem = None
+
+ def _tryToPaint(self, event):
+ '''Called when a paint attempt is initiated'''
+
+ if self.paintNext is None: return
+
+ paint = self.paintNext
+ if isinstance(paint, KPTileObject):
+ clicked = self.mapToScene(event.x(), event.y())
+ x, y = clicked.x(), clicked.y()
+ if x < 0: x = 0
+ if y < 0: y = 0
+
+ x = int(x / 24)
+ y = int(y / 24)
+
+ layer = self.scene().currentLayer
+
+ obj = KPObject()
+ obj.position = (x,y)
+ obj.size = (1,1)
+ obj.tileset = layer.tileset
+ obj.kind = self.paintNextID
+ obj.updateCache()
+ layer.objects.append(obj)
+ layer.updateCache()
+
+ item = KPEditorObject(obj, layer)
+ self.scene().addItem(item)
+
+ self.painting = obj
+ self.paintingItem = item
+
+
+
+ def mousePressEvent(self, event):
+ if event.button() == Qt.RightButton:
+ self._tryToPaint(event)
+ event.accept()
+
+ else:
+ QtGui.QGraphicsView.mousePressEvent(self, event)
diff --git a/src/main.py b/src/main.py
index ebf762f..1d53521 100644
--- a/src/main.py
+++ b/src/main.py
@@ -3,6 +3,7 @@ from common import *
class KP:
@staticmethod
def newMap():
+ from mapdata import KPMap
KP.map = KPMap()
@staticmethod
diff --git a/src/mapdata.py b/src/mapdata.py
index 3938047..f8ededd 100644
--- a/src/mapdata.py
+++ b/src/mapdata.py
@@ -14,7 +14,7 @@ class KPObject(object):
self.qtItem = None
def updateCache(self):
- self.cache = KP.map.tilesets[self.tileset].objects[self.kind].render(self.size)
+ self.cache = KP.map.loadedTilesets[self.tileset].objects[self.kind].render(self.size)
class KPLayer(object):
@@ -41,22 +41,24 @@ class KPLayer(object):
y1, y2 = MAP_SIZE_IN_TILES[1] - 1, 0
for obj in self.objects:
- pos, size = obj.position, obj.size
+ x, y = obj.position
+ w, h = obj.size
+ right, bottom = (x+w-1), (y+h-1)
- if pos[0] < x1:
- x1 = pos[0]
- if pos[1] < y1:
- y1 = pos[1]
- if (pos[0] + size[0]) > x2:
- x2 = pos[0] + size[0]
- if (pos[1] + size[1]) > y2:
- y2 = pos[1] + size[1]
+ if x < x1:
+ x1 = x
+ if y < y1:
+ y1 = y
+ if right > x2:
+ x2 = right
+ if bottom > y2:
+ y2 = bottom
# create the cache
# I was going to just resize it, but setting every tile to -1
# in Python would probably be slower than creating a new one ...
- size = (x2 - x1, y2 - y1)
+ size = (x2 - x1 + 1, y2 - y1 + 1)
width, height = size
cache = [[-1 for i in xrange(width)] for j in xrange(height)]
@@ -118,7 +120,7 @@ class KPMap(object):
def __init__(self):
self.nextLayerNumber = 1
- self.layers = [self.createNewLayer() for x in range(4)]
+ self.layers = [self.createNewLayer('Test') for x in range(4)]
self.layerModel = KPMap.LayerModel(self.layers)
self.nodes = []
self.paths = []
@@ -189,10 +191,11 @@ class KPMap(object):
return False
- def createNewLayer(self):
+ def createNewLayer(self, tilesetName):
layer = KPLayer()
layer.name = "Layer %d" % self.nextLayerNumber
self.nextLayerNumber += 1
+ layer.tileset = tilesetName
return layer
def appendLayer(self, layer):
diff --git a/src/tileset.py b/src/tileset.py
index 8d4bbb6..763c197 100644
--- a/src/tileset.py
+++ b/src/tileset.py
@@ -49,7 +49,7 @@ class KPTileObject(object):
buf = []
beforeRepeat = []
- inRepeat = self.tiles.copy()
+ inRepeat = self.tiles[:]
afterRepeat = []
if (self.wrap == 1) or (self.wrap == 3) or (self.wrap == 5):
@@ -99,11 +99,11 @@ class KPTileObject(object):
for x in xrange(width):
if x < bC:
- buf[x] = beforeRepeat[y]
+ buf[x] = beforeRepeat[x]
elif x < middleUntil:
- buf[x] = inRepeat[(y - bC) % iC]
+ buf[x] = inRepeat[(x - bC) % iC]
else:
- buf[x] = afterRepeat[y - bC - iC]
+ buf[x] = afterRepeat[x - bC - iC]
return buf
diff --git a/src/ui.py b/src/ui.py
index d2ac143..0a126c3 100644
--- a/src/ui.py
+++ b/src/ui.py
@@ -112,6 +112,7 @@ class KPObjectSelector(QtGui.QWidget):
# Borrowed the signals and junk from Reggie, figure we'll need em'
+ # Some more signals are set in setModel
self.listView.clicked.connect(self.handleObjReplace)
self.sorterMenu.aboutToShow.connect(self.fixUpMenuSize)
self.sorterMenu.triggered.connect(self.toggleTopLevel)
@@ -154,6 +155,9 @@ class KPObjectSelector(QtGui.QWidget):
# a Quick Fix
self.listView.setRowHidden(0, True)
+ # set up signals
+ self.listView.selectionModel().currentRowChanged.connect(self.handleRowChanged)
+
def toggleTopLevel(self, action):
"""Changes the top level group in the list view."""
@@ -175,7 +179,7 @@ class KPObjectSelector(QtGui.QWidget):
@QtCore.pyqtSlot(QtCore.QModelIndex, QtCore.QModelIndex)
- def currentChanged(self, current, previous):
+ def handleRowChanged(self, current, previous):
"""Throws a signal emitting the current object when changed"""
i = current.row()
object, depth = self.model.groupItem().getItem(i)
@@ -230,7 +234,9 @@ class KPMainWindow(QtGui.QMainWindow):
self.layerList.selectedLayerChanged.connect(self.scene.setCurrentLayer)
self.objectSelector = KPObjectSelector()
+ self.objectSelector.objChanged.connect(self.handleSelectedObjectChanged)
self.updateObjectSelector()
+
self.objectSelectorDock = QtGui.QDockWidget('Objects')
self.objectSelectorDock.setWidget(self.objectSelector)
@@ -246,6 +252,13 @@ class KPMainWindow(QtGui.QMainWindow):
except IOError:
tileset = KPTileset.loadFromArc('/home/me/Dropbox/NEWERsmbw/Test3.arc')
self.objectSelector.setModel(tileset.getModel())
+
+
+ @QtCore.pyqtSlot(int, KPTileObject)
+ def handleSelectedObjectChanged(self, index, obj):
+ print("New obj: %d, %r" % (index, obj))
+ self.editor.paintNext = obj
+ self.editor.paintNextID = index