Ejemplo n.º 1
0
    def removeTiles(self):
        view = self.currentTilesetView()
        if (not view):
            return
        if (not view.selectionModel().hasSelection()):
            return
        indexes = view.selectionModel().selectedIndexes()
        model = view.tilesetModel()
        tileIds = RangeSet()
        tiles = QList()
        for index in indexes:
            tile = model.tileAt(index)
            if tile:
                tileIds.insert(tile.id())
                tiles.append(tile)

        def matchesAnyTile(cell):
            tile = cell.tile
            if tile:
                return tiles.contains(tile)
            return False

        inUse = self.hasTileReferences(self.mMapDocument, matchesAnyTile)
        # If the tileset is in use, warn the user and confirm removal
        if (inUse):
            warning = QMessageBox(
                QMessageBox.Warning, self.tr("Remove Tiles"),
                self.tr("One or more of the tiles to be removed are "
                        "still in use by the map!"),
                QMessageBox.Yes | QMessageBox.No, self)
            warning.setDefaultButton(QMessageBox.Yes)
            warning.setInformativeText(
                self.tr("Remove all references to these tiles?"))
            if (warning.exec() != QMessageBox.Yes):
                return

        undoStack = self.mMapDocument.undoStack()
        undoStack.beginMacro(self.tr("Remove Tiles"))
        removeTileReferences(self.mMapDocument, matchesAnyTile)
        # Iterate backwards over the ranges in order to keep the indexes valid
        firstRange = tileIds.begin()
        it = tileIds.end()
        if (it == firstRange):  # no range
            return
        tileset = view.tilesetModel().tileset()
        while (it != firstRange):
            it -= 1
            item = tileIds.item(it)
            length = item[1] - item[0] + 1
            undoStack.push(
                RemoveTiles(self.mMapDocument, tileset, item[0], length))

        undoStack.endMacro()
        # Clear the current tiles, will be referencing the removed tiles
        self.setCurrentTiles(None)
        self.setCurrentTile(None)
Ejemplo n.º 2
0
    def delete_(self):
        if (not self.mMapDocument or not self.mTile):
            return
        if (self.mTile.tileset().isExternal()):
            return
        selectionModel = self.mUi.frameList.selectionModel()
        indexes = selectionModel.selectedIndexes()
        if len(indexes) == 0:
            return
        undoStack = self.mMapDocument.undoStack()
        undoStack.beginMacro(self.tr("Delete Frames"))
        ranges = RangeSet()
        for index in indexes:
            ranges.insert(index.row())
        # Iterate backwards over the ranges in order to keep the indexes valid
        firstRange = ranges.begin()
        it = ranges.end()
        while (it != firstRange):
            it -= 1
            item = ranges.item(it)
            length = item[1] - item[0] + 1
            self.mFrameListModel.removeRows(item[0], length, QModelIndex())

        undoStack.endMacro()
Ejemplo n.º 3
0
class RaiseLowerHelper():
    def __init__(self, mapScene):
        self.mSelectionRanges = RangeSet()

        self.mMapDocument = mapScene.mapDocument()
        self.mMapScene = mapScene
        # Context
        self.mObjectGroup = None
        self.mRelatedObjects = QList()

    def raise_(self):
        if (not self.initContext()):
            return
        # Iterate backwards over the ranges in order to keep the indexes valid
        size = len(self.mSelectionRanges)
        if size <= 0:  # no range
            return
        firstRange = self.mSelectionRanges.begin()
        it = self.mSelectionRanges.end()
        if (it == firstRange):  # no range
            return
        # For each range of objects, only the first will move
        commands = QList()

        lastIndex = len(self.mRelatedObjects) - 1
        for i in range(size - 1, -1, -1):
            it = self.mSelectionRanges.item(i)
            value = it[1]
            # The last range may be already at the top of the related items
            if value == lastIndex:
                continue
            movingItem = self.mRelatedObjects.at(value)
            targetItem = self.mRelatedObjects.at(value + 1)
            _from = int(movingItem.zValue())
            to = int(targetItem.zValue() + 1)
            commands.append(
                ChangeMapObjectsOrder(self.mMapDocument, self.mObjectGroup,
                                      _from, to, 1))
        self.push(commands,
                  QCoreApplication.translate("Undo Commands", "Raise Object"))

    def lower(self):
        if (not self.initContext()):
            return

        # For each range of objects, only the first will move
        commands = QList()
        for it in self.mSelectionRanges:
            value = it[0]
            # The first range may be already at the bottom of the related items
            if (value == 0):
                continue
            movingItem = self.mRelatedObjects.at(value)
            targetItem = self.mRelatedObjects.at(value - 1)
            _from = int(movingItem.zValue())
            to = int(targetItem.zValue())
            commands.append(
                ChangeMapObjectsOrder(self.mMapDocument, self.mObjectGroup,
                                      _from, to, 1))

        self.push(commands,
                  QCoreApplication.translate("Undo Commands", "Lower Object"))

    def raiseToTop(self):
        selectedItems = self.mMapScene.selectedObjectItems()
        objectGroup = RaiseLowerHelper.sameObjectGroup(selectedItems)
        if (not objectGroup):
            return
        if (objectGroup.drawOrder() != ObjectGroup.DrawOrder.IndexOrder):
            return
        ranges = RangeSet()
        for item in selectedItems:
            ranges.insert(int(item.zValue()))

        # Iterate backwards over the ranges in order to keep the indexes valid
        size = len(ranges)
        if size <= 0:  # no range
            return

        commands = QList()
        to = objectGroup.objectCount()
        for i in range(size - 1, -1, -1):
            it = ranges.item(i)
            first = it[0]
            last = it[1]
            count = last - first + 1
            if (last + 1 == to):
                to -= count
                continue

            _from = first
            commands.append(
                ChangeMapObjectsOrder(self.mMapDocument, objectGroup, _from,
                                      to, count))
            to -= count

        self.push(
            commands,
            QCoreApplication.translate("Undo Commands", "Raise Object To Top"))

    def lowerToBottom(self):
        selectedItems = self.mMapScene.selectedObjectItems()
        objectGroup = RaiseLowerHelper.sameObjectGroup(selectedItems)
        if (not objectGroup):
            return
        if (objectGroup.drawOrder() != ObjectGroup.DrawOrder.IndexOrder):
            return
        ranges = RangeSet()
        for item in selectedItems:
            ranges.insert(int(item.zValue()))

        commands = QList()
        to = 0
        for it in ranges:
            first = it[0]
            _from = first
            count = it[1] - first + 1
            if (_from == to):
                to += count
                continue

            commands.append(
                ChangeMapObjectsOrder(self.mMapDocument, objectGroup, _from,
                                      to, count))
            to += count

        self.push(
            commands,
            QCoreApplication.translate("Undo Commands",
                                       "Lower Object To Bottom"))

    def sameObjectGroup(items):
        if (items.isEmpty()):
            return None
        # All selected objects need to be in the same group
        group = items.begin().mapObject().objectGroup()
        for item in items:
            if (item.mapObject().objectGroup() != group):
                return None
        return group

    ##
    # Initializes the context in which objects are being raised or lowered. Only
    # used for single-step raising and lowering, since the context is not relevant
    # when raising to the top or lowering to the bottom.
    #
    # Returns whether the operation can be performed.
    ##
    def initContext(self):
        self.mObjectGroup = None
        self.mRelatedObjects.clear()
        self.mSelectionRanges.clear()
        selectedItems = self.mMapScene.selectedObjectItems()
        if (selectedItems.isEmpty()):
            return False
        # All selected objects need to be in the same group
        self.mObjectGroup = selectedItems.begin().mapObject().objectGroup()
        if (self.mObjectGroup.drawOrder() != ObjectGroup.DrawOrder.IndexOrder):
            return False
        shape = QPainterPath()
        for item in selectedItems:
            if (item.mapObject().objectGroup() != self.mObjectGroup):
                return False
            shape |= item.mapToScene(item.shape())

        # The list of related items are all items from the same object group
        # that share space with the selected items.
        items = self.mMapScene.items(shape, Qt.IntersectsItemShape,
                                     Qt.AscendingOrder)
        for item in items:
            if type(item) == MapObjectItem:
                if (item.mapObject().objectGroup() == self.mObjectGroup):
                    self.mRelatedObjects.append(item)

        for item in selectedItems:
            index = self.mRelatedObjects.indexOf(item)
            self.mSelectionRanges.insert(index)

        return True

    def push(self, commands, text):
        if (commands.isEmpty()):
            return
        undoStack = self.mMapDocument.undoStack()
        undoStack.beginMacro(text)
        for command in commands:
            undoStack.push(command)
        undoStack.endMacro()