summaryrefslogtreecommitdiff
path: root/src/editorui.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/editorui.py')
-rw-r--r--src/editorui.py281
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'''