from common import * from editorcommon import * import weakref class KPEditorNode(KPEditorItem): SNAP_TO = (12,12) class ToggleButton(QtGui.QPushButton): stateToggled = QtCore.pyqtSignal(int) def __init__(self): QtGui.QPushButton.__init__(self) self.setIconSize(QtCore.QSize(24, 24)) self.setFixedSize(24, 24) self.iconList = [QtGui.QIcon("Resources/Through.png"), QtGui.QIcon("Resources/Level.png"), QtGui.QIcon("Resources/Stop.png")] self.state = 0 self.setPalette(QtGui.QPalette(QtGui.QColor(0,0,0,0))) self.released.connect(self.toggle) def toggle(self): self.state += 1 if self.state == 3: self.state = 0 self.stateToggled.emit(self.state) def paintEvent(self, event): painter = QtGui.QPainter(self) painter.setBackgroundMode(Qt.TransparentMode) painter.setBrush(QtGui.QColor(0,0,0,0)) painter.setPen(QtGui.QColor(0,0,0,0)) if self.isDown(): self.iconList[self.state].paint(painter, self.contentsRect(), Qt.AlignCenter, QtGui.QIcon.Disabled) else: self.iconList[self.state].paint(painter, self.contentsRect()) painter.end() class HiddenProxy(QtGui.QGraphicsProxyWidget): def __init__(self, button, parent, x, y): QtGui.QGraphicsProxyWidget.__init__(self, parent) self.setWidget(button) self.setPos(x, y) self.setZValue(parent.zValue()+1000) self.hide() class LevelSlotSpinner(QtGui.QSpinBox): def __init__(self): QtGui.QSpinBox.__init__(self) self.setRange(1, 99) self.setPalette(QtGui.QPalette(QtGui.QColor(0,0,0,0))) def __init__(self, node): KPEditorItem.__init__(self) node.qtItem = self self._nodeRef = weakref.ref(node) self.setZValue(101) self._boundingRect = QtCore.QRectF(-24, -24, 48, 48) self._levelRect = self._boundingRect self._stopRect = QtCore.QRectF(-12, -12, 24, 24) self._tinyRect = QtCore.QRectF(-6, -6, 12, 12) if not hasattr(KPEditorNode, 'SELECTION_PEN'): KPEditorNode.SELECTION_PEN = QtGui.QPen(Qt.blue, 1, Qt.DotLine) self.button = self.ToggleButton() self.buttonProxy = self.HiddenProxy(self.button, self, 12, -24) self.button.stateToggled.connect(self.stateChange) self.world = self.LevelSlotSpinner() self.worldProxy = self.HiddenProxy(self.world, self, -42, 24) self.world.valueChanged.connect(self.worldChange) self.stage = self.LevelSlotSpinner() self.stageProxy = self.HiddenProxy(self.stage, self, 6, 24) self.stage.valueChanged.connect(self.stageChange) self._updatePosition() @QtCore.pyqtSlot(int) def stateChange(self, state): node = self._nodeRef() if state == 1: node.isStop = True node.level = [1, 1] self.world.setValue(node.level[0]) self.stage.setValue(node.level[1]) elif state == 2: node.isStop = True node.level = [0,0] else: node.isStop = False node.level = [0,0] self.update() @QtCore.pyqtSlot(int) def worldChange(self, world): node = self._nodeRef() node.level[0] = world @QtCore.pyqtSlot(int) def stageChange(self, stage): node = self._nodeRef() node.level[1] = stage def _updatePosition(self): node = self._nodeRef() x, y = node.position self.setPos(x+12, y+12) def _itemMoved(self, oldX, oldY, newX, newY): node = self._nodeRef() node.position = (newX-12, newY-12) for exit in node.exits: exit.qtItem.updatePosition() def paint(self, painter, option, widget): node = self._nodeRef() selectionRect = None if node.level != [0,0]: painter.setBrush(QtGui.QColor(0, 0, 0, 0)) painter.setPen(QtGui.QColor(0, 0, 0, 0)) painter.drawPixmap(self._boundingRect.topLeft(), QtGui.QPixmap("Resources/BlackLevel.png")) selectionRect = self._boundingRect.adjusted(1,5,-1,-5) elif node.isStop: brush = QtGui.QBrush(QtGui.QColor(255, 220, 220)) painter.setPen(QtGui.QColor(255, 255, 255)) painter.setBrush(brush) painter.drawEllipse(self._stopRect) selectionRect = self._stopRect.adjusted(-1,-1,1,1) else: brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) painter.setPen(QtGui.QColor(255, 255, 255)) painter.setBrush(brush) painter.drawEllipse(self._tinyRect) selectionRect = self._tinyRect.adjusted(-1,-1,1,1) if self.isSelected(): painter.setPen(self.SELECTION_PEN) painter.setBrush(QtGui.QColor(0,0,0,0)) painter.drawEllipse(selectionRect) self.buttonProxy.show() if node.level != [0,0]: self.worldProxy.show() self.stageProxy.show() else: self.worldProxy.hide() self.stageProxy.hide() else: self.buttonProxy.hide() self.worldProxy.hide() self.stageProxy.hide() def remove(self, withItem=False): node = self._nodeRef() layer = KP.map.pathLayer layer.nodes.remove(node) if len(node.exits) == 2: # let's try to join the two! pathOne, pathTwo = node.exits start1, end1 = pathOne._startNodeRef(), pathOne._endNodeRef() start2, end2 = pathTwo._startNodeRef(), pathTwo._endNodeRef() if start1 == node: start = end1 else: start = start1 if start2 == node: end = end2 else: end = start2 # make sure no path already exists between these nodes nope = False for pathToCheck in start.exits: if pathToCheck._startNodeRef() == end: nope = True elif pathToCheck._endNodeRef() == end: nope = True if not nope: joinedPath = KPPath(start, end, pathOne) layer.paths.append(joinedPath) item = KPEditorPath(joinedPath) self.scene().addItem(item) for path in (pathOne, pathTwo): path.qtItem.remove(True) else: # we can't join them so just nuke them for exit in node.exits[:]: exit.qtItem.remove(True) if withItem: self.scene().removeItem(self) class KPEditorPath(QtGui.QGraphicsLineItem): def __init__(self, path): QtGui.QGraphicsLineItem.__init__(self) self.setFlag(self.ItemIsSelectable, True) self.setZValue(100) startNode = path._startNodeRef().qtItem endNode = path._endNodeRef().qtItem self._startNodeRef = weakref.ref(startNode) self._endNodeRef = weakref.ref(endNode) self._pathRef = weakref.ref(path) path.qtItem = self self.updatePosition() if not hasattr(KPEditorPath, 'PEN'): KPEditorPath.BRUSH = QtGui.QBrush(QtGui.QColor(255, 255, 255, 140)) KPEditorPath.PEN = QtGui.QPen(KPEditorPath.BRUSH, 8, Qt.SolidLine, Qt.RoundCap) self.setPen(KPEditorPath.PEN) def updatePosition(self): path = self._pathRef() x1, y1 = path._startNodeRef().position x2, y2 = path._endNodeRef().position self.setLine(QtCore.QLineF(x1+12, y1+12, x2+12, y2+12)) def remove(self, withItem=False): path = self._pathRef() layer = KP.map.pathLayer layer.paths.remove(path) for ref in (self._startNodeRef, self._endNodeRef): node = ref()._nodeRef() try: node.exits.remove(path) except ValueError: pass if withItem: self.scene().removeItem(self)