diff options
Diffstat (limited to 'src/editorui.py')
-rw-r--r-- | src/editorui.py | 281 |
1 files changed, 258 insertions, 23 deletions
diff --git a/src/editorui.py b/src/editorui.py index c7da106..3b9b74e 100644 --- a/src/editorui.py +++ b/src/editorui.py @@ -1,6 +1,7 @@ from common import * from math import floor, ceil import weakref +import math class KPEditorItem(QtGui.QGraphicsItem): @@ -236,33 +237,36 @@ class KPEditorObject(KPEditorItem): self._layerRef().updateCache() -class KPEditorDoodad(KPEditorItem): +class KPEditorDoodad(QtGui.QGraphicsPixmapItem): def __init__(self, doodad, layer): - KPEditorItem.__init__(self) - obj.qtItem = self + QtGui.QGraphicsPixmapItem.__init__(self) + self.setFlags( + self.ItemSendsGeometryChanges | + self.ItemIsSelectable | + self.ItemIsMovable + ) + + doodad.qtItem = self self._doodadRef = weakref.ref(doodad) self._layerRef = weakref.ref(layer) - self._updatePosition() - self._updateSize() + + self.resizing = None + self.rotating = None self.setAcceptHoverEvents(True) + self.setTransformationMode(1) - def _updatePosition(self): - self.setPos(*self._doodadRef().position) - - def _updateSize(self): - self.prepareGeometryChange() - - w,h = self._doodadRef().size + + def paint(self, painter, option, widget): - self._boundingRect = QtCore.QRectF(0, 0, w, h) - self._selectionRect = QtCore.QRectF(0, 0, w, h) - + try: + QtGui.QGraphicsPixmapItem.paint(self, painter, option, widget) + except: + pass - def paint(self, painter, option, widget): if self.isSelected(): painter.setPen(QtGui.QPen(Qt.white, 1, Qt.DotLine)) - painter.drawRect(self._selectionRect) + painter.drawRect(self.boundingRect().adjusted(-1,-1,1,1)) def _itemMoved(self, oldX, oldY, newX, newY): @@ -270,6 +274,207 @@ class KPEditorDoodad(KPEditorItem): doodad.position = (newX, newY) + def itemChange(self, change, value): + + return QtGui.QGraphicsItem.itemChange(self, change, value) + + + def resizerPortionAt(self, x, y): + + rightBound = self.boundingRect().right() - 5 + bottomBound = self.boundingRect().bottom() - 5 + + if y < 5: + if x < 5: return 1 # TOP_LEFT + elif x >= rightBound: return 2 # TOP_RIGHT + else: return 5 # TOP + + elif y >= bottomBound: + if x < 5: return 3 # BOTTOM_LEFT + elif x >= rightBound: return 4 # BOTTOM_RIGHT + else: return 6 # BOTTOM + + else: + if x < 5: return 7 # LEFT + elif x >= rightBound: return 8 # RIGHT + else: return None + + + def hoverMoveEvent(self, event): + if self._layerRef() != KP.mapScene.currentLayer: + self.setCursor(Qt.ArrowCursor) + return + + pos = event.pos() + bit = self.resizerPortionAt(pos.x(), pos.y()) + + + if (event.modifiers() == Qt.AltModifier): + + if bit: + self.setCursor(Qt.OpenHandCursor) + else: + self.setCursor(Qt.ArrowCursor) + + else: + + if bit == 1 or bit == 4: + self.setCursor(Qt.SizeFDiagCursor) + elif bit == 2 or bit == 3: + self.setCursor(Qt.SizeBDiagCursor) + elif bit == 7 or bit == 8: + self.setCursor(Qt.SizeHorCursor) + elif bit == 5 or bit == 6: + self.setCursor(Qt.SizeVerCursor) + else: + self.setCursor(Qt.ArrowCursor) + + + def mousePressEvent(self, event): + if event.button() == Qt.LeftButton: + pos = event.pos() + bit = self.resizerPortionAt(pos.x(), pos.y()) + + if self._layerRef() == KP.mapScene.currentLayer and bit: + event.accept() + + if (event.modifiers() == Qt.AltModifier): + self.rotating = self.mapToScene(pos), self._doodadRef().angle + self.setCursor(Qt.ClosedHandCursor) + return + + else: + self.resizing = bit + return + + + KPEditorItem.mousePressEvent(self, event) + + + def _tryAndResize(self, bit, mousePosition, modifiers): + + itemPos = self.mapFromScene(mousePosition) + + x2 = self.boundingRect().right() + 5.0 + y2 = self.boundingRect().bottom() + 5.0 + + + if bit == 1: + relativeScale = min([(x2 - itemPos.x()) / x2, (y2 - itemPos.y()) / y2]) + elif bit == 2: + relativeScale = min([itemPos.x() / x2, (y2 - itemPos.y()) / y2]) + elif bit == 3: + relativeScale = min([(x2 - itemPos.x()) / x2, itemPos.y() / y2]) + elif bit == 4: + relativeScale = min([itemPos.x() / x2, itemPos.y() / y2]) + elif bit == 5: + relativeScale = (y2 - itemPos.y()) / y2 + elif bit == 6: + relativeScale = itemPos.y() / y2 + elif bit == 7: + relativeScale = (x2 - itemPos.x()) / x2 + elif bit == 8: + relativeScale = itemPos.x() / x2 + else: + return False, 0 + + + if relativeScale > 1.0: + relativeScale = 1.0 + + if relativeScale < 0.1: + relativeScale = 0.1 + + self.setTransformOriginPoint(self.boundingRect().center()) + + return True, relativeScale + + + def _tryAndRotate(self, obj, mouseX, mouseY, originalPos, oldAngle, modifiers): + center = self.mapToScene(self.boundingRect().center()) + + objX = center.x() + objY = center.y() + + + origX = originalPos.x() + origY = originalPos.y() + + dy = origY - objY + dx = origX - objX + rads = math.atan2(dy, dx) + + origAngle = math.degrees(rads) + + + + + dy = mouseY - objY + dx = mouseX - objX + rads = math.atan2(dy, dx) + + angle = math.degrees(rads) + + + # Move this to ItemChange() or something at some point. + # + # if (modifiers == Qt.ShiftModifier): + # if int(angle / 45.0) == int(oldAngle / 45.0): + # return False, 0 + # else: + # angle = int(angle / 45.0) * 45.0 + + return True, angle - origAngle + oldAngle + + + def mouseMoveEvent(self, event): + + # Fucking Transform can't do independent transforms with doing matrix math directly. + # And before anyone asks, using QTransform.scale() is no good. + + if self.resizing: + obj = self._doodadRef() + scenePos = event.scenePos() + + hasChanged = False + bit = self.resizing + + hasChanged, scale = self._tryAndResize(bit, scenePos, event.modifiers()) + + if hasChanged: + obj.scale = scale + + self.setScale(scale) + + + elif self.rotating: + obj = self._doodadRef() + scenePos = event.scenePos() + + hasChanged = False + + hasChanged, angle = self._tryAndRotate(obj, scenePos.x(), scenePos.y(), self.rotating[0], self.rotating[1], event.modifiers()) + + if hasChanged: + obj.angle = angle + self.setRotation(angle) + + + else: + KPEditorItem.mouseMoveEvent(self, event) + + + def mouseReleaseEvent(self, event): + if self.resizing and event.button() == Qt.LeftButton: + self.resizing = None + elif self.rotating and event.button() == Qt.LeftButton: + self.rotating = None + + else: + KPEditorItem.mouseReleaseEvent(self, event) + + + class KPMapScene(QtGui.QGraphicsScene): def __init__(self): QtGui.QGraphicsScene.__init__(self, 0, 0, 512*24, 512*24) @@ -282,7 +487,7 @@ class KPMapScene(QtGui.QGraphicsScene): def drawBackground(self, painter, rect): - painter.fillRect(rect, Qt.white) + painter.fillRect(rect, QtGui.QColor(209, 218, 236)) areaLeft, areaTop = rect.x(), rect.y() areaWidth, areaHeight = rect.width(), rect.height() @@ -320,10 +525,9 @@ class KPMapScene(QtGui.QGraphicsScene): continue for item in toDraw: - painter.save() - painter.setWorldTransform(item.transform(), True) - painter.drawPixmap(0, 0, item.pixmap) - painter.restore() + item.paint(painter, QtGui.QStyleOptionGraphicsItem(), self) + # painter.setWorldTransform(item.transform(), True) + # painter.drawPixmap(0, 0, item.pixmap) elif isinstance(layer, KPTileLayer): left, top = layer.cacheBasePos @@ -419,8 +623,8 @@ class KPEditorWidget(QtGui.QGraphicsView): '''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() @@ -432,6 +636,7 @@ class KPEditorWidget(QtGui.QGraphicsView): layer = self.scene().currentLayer if not layer.visible: return + if not isinstance(layer, KPTileLayer): return obj = KPObject() obj.position = (x,y) @@ -448,6 +653,36 @@ class KPEditorWidget(QtGui.QGraphicsView): self.painting = obj self.paintingItem = item self.paintBeginPosition = (x, y) + + if isinstance(paint, QtGui.QListWidgetItem): + clicked = self.mapToScene(event.x(), event.y()) + x, y = clicked.x(), clicked.y() + if x < 0: x = 0 + if y < 0: y = 0 + + layer = self.scene().currentLayer + if not layer.visible: return + if not isinstance(layer, KPDoodadLayer): return + + size = paint.icon().availableSizes()[0] + + obj = KPDoodad() + obj.position = (x,y) + obj.size = (size.width(), size.height()) + obj.index = self.paintNextID + layer.objects.append(obj) + + item = KPEditorDoodad(obj, layer) + item.setPixmap(paint.icon().pixmap(size)) + item.setTransformOriginPoint(item.boundingRect().center()) + item.setPos(x, y) + self.scene().addItem(item) + + self.painting = obj + self.paintingItem = item + self.paintBeginPosition = (x, y) + + def _movedWhilePainting(self, event): '''Called when the mouse is moved while painting something''' |