Move PendingImport and PendingImportNode to imports.py, disable multi-imports (for now)
Rewrite much of them for clarity.
This commit is contained in:
parent
df25824820
commit
2557df5e58
@ -33,29 +33,44 @@ class MoveSelectionCommand(SimpleRevisionCommand):
|
|||||||
def undo(self):
|
def undo(self):
|
||||||
super(MoveSelectionCommand, self).undo()
|
super(MoveSelectionCommand, self).undo()
|
||||||
self.moveTool.currentImport = None
|
self.moveTool.currentImport = None
|
||||||
self.moveTool.removePendingImport(self.pendingImport)
|
#self.moveTool.removePendingImport(self.pendingImport)
|
||||||
self.moveTool.editorSession.chooseTool("Select")
|
self.moveTool.editorSession.chooseTool("Select")
|
||||||
|
|
||||||
def redo(self):
|
def redo(self):
|
||||||
self.moveTool.currentImport = self.pendingImport
|
self.moveTool.currentImport = self.pendingImport
|
||||||
self.moveTool.addPendingImport(self.pendingImport)
|
#self.moveTool.addPendingImport(self.pendingImport)
|
||||||
self.moveTool.editorSession.chooseTool("Move")
|
self.moveTool.editorSession.chooseTool("Move")
|
||||||
super(MoveSelectionCommand, self).redo()
|
super(MoveSelectionCommand, self).redo()
|
||||||
|
|
||||||
|
|
||||||
class MoveOffsetCommand(QtGui.QUndoCommand):
|
class MoveOffsetCommand(QtGui.QUndoCommand):
|
||||||
def __init__(self, moveTool, oldPoint, newPoint):
|
def __init__(self, oldPoint, newPoint, pendingImport):
|
||||||
super(MoveOffsetCommand, self).__init__()
|
super(MoveOffsetCommand, self).__init__()
|
||||||
self.setText(moveTool.tr("Move Object"))
|
self.pendingImport = pendingImport
|
||||||
|
self.setText(QtGui.qApp.tr("Move Object"))
|
||||||
self.newPoint = newPoint
|
self.newPoint = newPoint
|
||||||
self.oldPoint = oldPoint
|
self.oldPoint = oldPoint
|
||||||
self.moveTool = moveTool
|
|
||||||
|
|
||||||
def undo(self):
|
def undo(self):
|
||||||
self.moveTool.movePosition = self.oldPoint
|
self.pendingImport.basePosition = self.oldPoint
|
||||||
|
|
||||||
def redo(self):
|
def redo(self):
|
||||||
self.moveTool.movePosition = self.newPoint
|
self.pendingImport.basePosition = self.newPoint
|
||||||
|
|
||||||
|
|
||||||
|
class MoveRotateCommand(QtGui.QUndoCommand):
|
||||||
|
def __init__(self, oldRotation, newRotation, pendingImport):
|
||||||
|
super(MoveRotateCommand, self).__init__()
|
||||||
|
self.pendingImport = pendingImport
|
||||||
|
self.setText(QtGui.qApp.tr("Rotate Object"))
|
||||||
|
self.newRotation = newRotation
|
||||||
|
self.oldRotation = oldRotation
|
||||||
|
|
||||||
|
def undo(self):
|
||||||
|
self.pendingImport.rotation = self.oldRotation
|
||||||
|
|
||||||
|
def redo(self):
|
||||||
|
self.pendingImport.rotation = self.newRotation
|
||||||
|
|
||||||
|
|
||||||
class MoveFinishCommand(SimpleRevisionCommand):
|
class MoveFinishCommand(SimpleRevisionCommand):
|
||||||
@ -63,10 +78,12 @@ class MoveFinishCommand(SimpleRevisionCommand):
|
|||||||
super(MoveFinishCommand, self).__init__(moveTool.editorSession, moveTool.tr("Finish Move"), *args, **kwargs)
|
super(MoveFinishCommand, self).__init__(moveTool.editorSession, moveTool.tr("Finish Move"), *args, **kwargs)
|
||||||
self.pendingImport = pendingImport
|
self.pendingImport = pendingImport
|
||||||
self.moveTool = moveTool
|
self.moveTool = moveTool
|
||||||
|
self.previousSelection = None
|
||||||
|
|
||||||
def undo(self):
|
def undo(self):
|
||||||
super(MoveFinishCommand, self).undo()
|
super(MoveFinishCommand, self).undo()
|
||||||
self.moveTool.addPendingImport(self.pendingImport)
|
#self.moveTool.addPendingImport(self.pendingImport)
|
||||||
|
self.moveTool.currentImport = self.pendingImport
|
||||||
self.editorSession.currentSelection = self.previousSelection
|
self.editorSession.currentSelection = self.previousSelection
|
||||||
self.editorSession.chooseTool("Move")
|
self.editorSession.chooseTool("Move")
|
||||||
|
|
||||||
@ -74,7 +91,8 @@ class MoveFinishCommand(SimpleRevisionCommand):
|
|||||||
super(MoveFinishCommand, self).redo()
|
super(MoveFinishCommand, self).redo()
|
||||||
self.previousSelection = self.editorSession.currentSelection
|
self.previousSelection = self.editorSession.currentSelection
|
||||||
self.editorSession.currentSelection = self.pendingImport.importBounds
|
self.editorSession.currentSelection = self.pendingImport.importBounds
|
||||||
self.moveTool.removePendingImport(self.pendingImport)
|
self.moveTool.currentImport = None
|
||||||
|
#self.moveTool.removePendingImport(self.pendingImport)
|
||||||
|
|
||||||
|
|
||||||
class RotationWidget(QtGui.QWidget):
|
class RotationWidget(QtGui.QWidget):
|
||||||
@ -98,6 +116,19 @@ class RotationWidget(QtGui.QWidget):
|
|||||||
|
|
||||||
rotationChanged = QtCore.Signal(object, bool)
|
rotationChanged = QtCore.Signal(object, bool)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def rotation(self):
|
||||||
|
return self.xRot, self.yRot, self.zRot
|
||||||
|
|
||||||
|
@rotation.setter
|
||||||
|
def rotation(self, value):
|
||||||
|
if value == self.rotation:
|
||||||
|
return
|
||||||
|
xRot, yRot, zRot = value
|
||||||
|
self.setXRot(xRot)
|
||||||
|
self.setYRot(yRot)
|
||||||
|
self.setZRot(zRot)
|
||||||
|
|
||||||
def emitRotationChanged(self, live):
|
def emitRotationChanged(self, live):
|
||||||
self.rotationChanged.emit((self.xRot, self.yRot, self.zRot), live)
|
self.rotationChanged.emit((self.xRot, self.yRot, self.zRot), live)
|
||||||
|
|
||||||
@ -142,22 +173,11 @@ class MoveTool(EditorTool):
|
|||||||
def __init__(self, editorSession, *args, **kwargs):
|
def __init__(self, editorSession, *args, **kwargs):
|
||||||
super(MoveTool, self).__init__(editorSession, *args, **kwargs)
|
super(MoveTool, self).__init__(editorSession, *args, **kwargs)
|
||||||
self.overlayNode = scenenode.Node()
|
self.overlayNode = scenenode.Node()
|
||||||
|
self._currentImport = None
|
||||||
self.dragStartFace = None
|
self._currentImportNode = None
|
||||||
self.dragStartPoint = None
|
|
||||||
|
|
||||||
self.pendingImports = []
|
|
||||||
|
|
||||||
self.pendingImportNodes = {}
|
|
||||||
|
|
||||||
self.toolWidget = QtGui.QWidget()
|
self.toolWidget = QtGui.QWidget()
|
||||||
|
|
||||||
self.importsListWidget = QtGui.QListView()
|
|
||||||
self.importsListModel = QtGui.QStandardItemModel()
|
|
||||||
self.importsListWidget.setModel(self.importsListModel)
|
|
||||||
self.importsListWidget.clicked.connect(self.listClicked)
|
|
||||||
self.importsListWidget.doubleClicked.connect(self.listDoubleClicked)
|
|
||||||
|
|
||||||
self.pointInput = CoordinateWidget()
|
self.pointInput = CoordinateWidget()
|
||||||
self.pointInput.pointChanged.connect(self.pointInputChanged)
|
self.pointInput.pointChanged.connect(self.pointInputChanged)
|
||||||
|
|
||||||
@ -171,8 +191,7 @@ class MoveTool(EditorTool):
|
|||||||
|
|
||||||
confirmButton = QtGui.QPushButton("Confirm") # xxxx should be in worldview
|
confirmButton = QtGui.QPushButton("Confirm") # xxxx should be in worldview
|
||||||
confirmButton.clicked.connect(self.confirmImport)
|
confirmButton.clicked.connect(self.confirmImport)
|
||||||
self.toolWidget.setLayout(Column(self.importsListWidget,
|
self.toolWidget.setLayout(Column(self.pointInput,
|
||||||
self.pointInput,
|
|
||||||
self.rotationInput,
|
self.rotationInput,
|
||||||
self.copyOptionsWidget,
|
self.copyOptionsWidget,
|
||||||
confirmButton,
|
confirmButton,
|
||||||
@ -183,86 +202,46 @@ class MoveTool(EditorTool):
|
|||||||
if live:
|
if live:
|
||||||
self.currentImportNode.setPreviewRotation(rots)
|
self.currentImportNode.setPreviewRotation(rots)
|
||||||
else:
|
else:
|
||||||
self.currentImportNode.setRotation(rots)
|
command = MoveRotateCommand(self.currentImport.rotation, rots, self.currentImport)
|
||||||
|
self.editorSession.pushCommand(command)
|
||||||
|
|
||||||
self.editorSession.updateView()
|
self.editorSession.updateView()
|
||||||
|
|
||||||
@property
|
|
||||||
def movePosition(self):
|
|
||||||
return None if self.currentImport is None else self.currentImport.pos
|
|
||||||
|
|
||||||
@movePosition.setter
|
|
||||||
def movePosition(self, value):
|
|
||||||
"""
|
|
||||||
|
|
||||||
:type value: Vector
|
|
||||||
"""
|
|
||||||
self.pointInput.point = value
|
|
||||||
self.pointInputChanged(value)
|
|
||||||
|
|
||||||
def pointInputChanged(self, value):
|
def pointInputChanged(self, value):
|
||||||
if value is not None:
|
if value is not None:
|
||||||
self.currentImport.pos = value
|
self.currentImport.basePosition = value
|
||||||
self.currentImportNode.pos = value
|
|
||||||
|
|
||||||
# --- Pending imports ---
|
# --- Pending imports ---
|
||||||
|
|
||||||
def addPendingImport(self, pendingImport):
|
|
||||||
log.info("Added import: %s", pendingImport)
|
|
||||||
self.pendingImports.append(pendingImport)
|
|
||||||
item = QtGui.QStandardItem()
|
|
||||||
item.setEditable(False)
|
|
||||||
item.setText(pendingImport.text)
|
|
||||||
item.setData(pendingImport, Qt.UserRole)
|
|
||||||
self.importsListModel.appendRow(item)
|
|
||||||
self.importsListWidget.setCurrentIndex(self.importsListModel.index(self.importsListModel.rowCount()-1, 0))
|
|
||||||
node = self.pendingImportNodes[pendingImport] = PendingImportNode(pendingImport, self.editorSession.textureAtlas)
|
|
||||||
node.importMoved.connect(self.importDidMove)
|
|
||||||
|
|
||||||
self.overlayNode.addChild(node)
|
|
||||||
self.currentImport = pendingImport
|
|
||||||
|
|
||||||
def removePendingImport(self, pendingImport):
|
|
||||||
index = self.pendingImports.index(pendingImport)
|
|
||||||
self.pendingImports.remove(pendingImport)
|
|
||||||
self.importsListModel.removeRows(index, 1)
|
|
||||||
self.currentImport = self.pendingImports[-1] if len(self.pendingImports) else None
|
|
||||||
node = self.pendingImportNodes.pop(pendingImport)
|
|
||||||
if node:
|
|
||||||
self.overlayNode.removeChild(node)
|
|
||||||
|
|
||||||
def importDidMove(self, newPoint, oldPoint):
|
def importDidMove(self, newPoint, oldPoint):
|
||||||
if newPoint != oldPoint:
|
if newPoint != oldPoint:
|
||||||
command = MoveOffsetCommand(self, oldPoint, newPoint)
|
command = MoveOffsetCommand(oldPoint, newPoint, self.currentImport)
|
||||||
self.editorSession.pushCommand(command)
|
self.editorSession.pushCommand(command)
|
||||||
|
|
||||||
def listClicked(self, index):
|
|
||||||
item = self.importsListModel.itemFromIndex(index)
|
|
||||||
pendingImport = item.data(Qt.UserRole)
|
|
||||||
self.currentImport = pendingImport
|
|
||||||
|
|
||||||
def listDoubleClicked(self, index):
|
|
||||||
item = self.importsListModel.itemFromIndex(index)
|
|
||||||
pendingImport = item.data(Qt.UserRole)
|
|
||||||
self.editorSession.editorTab.currentView().centerOnPoint(pendingImport.bounds.center)
|
|
||||||
|
|
||||||
_currentImport = None
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def currentImport(self):
|
def currentImport(self):
|
||||||
return self._currentImport
|
return self._currentImport
|
||||||
|
|
||||||
@currentImport.setter
|
@currentImport.setter
|
||||||
def currentImport(self, value):
|
def currentImport(self, pendingImport):
|
||||||
self._currentImport = value
|
self._currentImport = pendingImport
|
||||||
self.pointInput.setEnabled(value is not None)
|
self.pointInput.setEnabled(pendingImport is not None)
|
||||||
# Set current import to different color?
|
# Set current import to different color?
|
||||||
# for node in self.pendingImportNodes.itervalues():
|
# for node in self.pendingImportNodes.itervalues():
|
||||||
# node.outlineNode.wireColor = (.2, 1., .2, .5) if node.pendingImport is value else (1, 1, 1, .3)
|
# node.outlineNode.wireColor = (.2, 1., .2, .5) if node.pendingImport is value else (1, 1, 1, .3)
|
||||||
|
if pendingImport is None:
|
||||||
|
if self._currentImportNode is not None:
|
||||||
|
self.overlayNode.removeChild(self._currentImportNode)
|
||||||
|
self._currentImportNode = None
|
||||||
|
else:
|
||||||
|
node = PendingImportNode(pendingImport, self.editorSession.textureAtlas)
|
||||||
|
node.importMoved.connect(self.importDidMove)
|
||||||
|
self._currentImportNode = node
|
||||||
|
self.overlayNode.addChild(node)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def currentImportNode(self):
|
def currentImportNode(self):
|
||||||
return self.pendingImportNodes.get(self.currentImport)
|
return self._currentImportNode
|
||||||
|
|
||||||
# --- Mouse events ---
|
# --- Mouse events ---
|
||||||
|
|
||||||
@ -289,6 +268,7 @@ class MoveTool(EditorTool):
|
|||||||
def toolActive(self):
|
def toolActive(self):
|
||||||
self.editorSession.selectionTool.hideSelectionWalls = True
|
self.editorSession.selectionTool.hideSelectionWalls = True
|
||||||
if self.currentImport is None:
|
if self.currentImport is None:
|
||||||
|
self.rotationInput.rotation = (0, 0, 0)
|
||||||
if self.editorSession.currentSelection is None:
|
if self.editorSession.currentSelection is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -315,12 +295,14 @@ class MoveTool(EditorTool):
|
|||||||
command = MoveFinishCommand(self, self.currentImport)
|
command = MoveFinishCommand(self, self.currentImport)
|
||||||
destDim = self.editorSession.currentDimension
|
destDim = self.editorSession.currentDimension
|
||||||
with command.begin():
|
with command.begin():
|
||||||
|
log.info("Move: starting")
|
||||||
if self.currentImport.isMove:
|
if self.currentImport.isMove:
|
||||||
sourceDim = self.currentImport.importDim
|
sourceDim = self.currentImport.importDim
|
||||||
destBox = BoundingBox(self.currentImport.importPos, sourceDim.bounds.size)
|
destBox = BoundingBox(self.currentImport.importPos, sourceDim.bounds.size)
|
||||||
|
|
||||||
# Use intermediate schematic only if source and destination overlap.
|
# Use intermediate schematic only if source and destination overlap.
|
||||||
if sourceDim.bounds.intersect(destBox).volume:
|
if sourceDim.bounds.intersect(destBox).volume:
|
||||||
|
log.info("Move: using temporary")
|
||||||
export = extractSchematicFromIter(sourceDim, self.currentImport.selection)
|
export = extractSchematicFromIter(sourceDim, self.currentImport.selection)
|
||||||
schematic = showProgress(self.tr("Copying..."), export)
|
schematic = showProgress(self.tr("Copying..."), export)
|
||||||
sourceDim = schematic.getDimension()
|
sourceDim = schematic.getDimension()
|
||||||
@ -330,6 +312,7 @@ class MoveTool(EditorTool):
|
|||||||
sourceDim = self.currentImport.importDim
|
sourceDim = self.currentImport.importDim
|
||||||
|
|
||||||
# Copy to destination
|
# Copy to destination
|
||||||
|
log.info("Move: copying")
|
||||||
task = destDim.copyBlocksIter(sourceDim, sourceDim.bounds,
|
task = destDim.copyBlocksIter(sourceDim, sourceDim.bounds,
|
||||||
self.currentImport.importPos,
|
self.currentImport.importPos,
|
||||||
biomes=True, create=True,
|
biomes=True, create=True,
|
||||||
@ -337,6 +320,7 @@ class MoveTool(EditorTool):
|
|||||||
|
|
||||||
showProgress(self.tr("Pasting..."), task)
|
showProgress(self.tr("Pasting..."), task)
|
||||||
|
|
||||||
|
log.info("Move: clearing")
|
||||||
# Clear source
|
# Clear source
|
||||||
if self.currentImport.isMove:
|
if self.currentImport.isMove:
|
||||||
fill = destDim.fillBlocksIter(self.currentImport.selection, "air")
|
fill = destDim.fillBlocksIter(self.currentImport.selection, "air")
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
"""
|
"""
|
||||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
import logging
|
import logging
|
||||||
from PySide import QtCore
|
from PySide import QtCore, QtGui
|
||||||
|
from PySide.QtCore import Qt
|
||||||
from mcedit2.handles.boxhandle import BoxHandle
|
from mcedit2.handles.boxhandle import BoxHandle
|
||||||
from mcedit2.rendering.depths import DepthOffset
|
from mcedit2.rendering.depths import DepthOffset
|
||||||
from mcedit2.rendering.scenegraph.matrix import TranslateNode, RotateNode
|
from mcedit2.rendering.scenegraph.matrix import TranslateNode, RotateNode
|
||||||
@ -16,14 +17,80 @@ from mceditlib.transform import SelectionTransform, DimensionTransform
|
|||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class PendingImportsGroup(QtCore.QObject):
|
||||||
|
def __init__(self):
|
||||||
|
super(PendingImportsGroup, self).__init__()
|
||||||
|
|
||||||
|
self.pendingImports = []
|
||||||
|
|
||||||
|
self.pendingImportNodes = {}
|
||||||
|
|
||||||
|
def addPendingImport(self, pendingImport):
|
||||||
|
log.info("Added import: %s", pendingImport)
|
||||||
|
self.pendingImports.append(pendingImport)
|
||||||
|
item = QtGui.QStandardItem()
|
||||||
|
item.setEditable(False)
|
||||||
|
item.setText(pendingImport.text)
|
||||||
|
item.setData(pendingImport, Qt.UserRole)
|
||||||
|
self.importsListModel.appendRow(item)
|
||||||
|
self.importsListWidget.setCurrentIndex(self.importsListModel.index(self.importsListModel.rowCount()-1, 0))
|
||||||
|
node = self.pendingImportNodes[pendingImport] = PendingImportNode(pendingImport, self.editorSession.textureAtlas)
|
||||||
|
node.importMoved.connect(self.importDidMove)
|
||||||
|
|
||||||
|
self.overlayNode.addChild(node)
|
||||||
|
self.currentImport = pendingImport
|
||||||
|
|
||||||
|
def removePendingImport(self, pendingImport):
|
||||||
|
index = self.pendingImports.index(pendingImport)
|
||||||
|
self.pendingImports.remove(pendingImport)
|
||||||
|
self.importsListModel.removeRows(index, 1)
|
||||||
|
self.currentImport = self.pendingImports[-1] if len(self.pendingImports) else None
|
||||||
|
node = self.pendingImportNodes.pop(pendingImport)
|
||||||
|
if node:
|
||||||
|
self.overlayNode.removeChild(node)
|
||||||
|
#
|
||||||
|
# def listClicked(self, index):
|
||||||
|
# item = self.importsListModel.itemFromIndex(index)
|
||||||
|
# pendingImport = item.data(Qt.UserRole)
|
||||||
|
# self.currentImport = pendingImport
|
||||||
|
|
||||||
|
def listDoubleClicked(self, index):
|
||||||
|
item = self.importsListModel.itemFromIndex(index)
|
||||||
|
pendingImport = item.data(Qt.UserRole)
|
||||||
|
self.editorSession.editorTab.currentView().centerOnPoint(pendingImport.bounds.center)
|
||||||
|
|
||||||
|
|
||||||
class PendingImportNode(Node, QtCore.QObject):
|
class PendingImportNode(Node, QtCore.QObject):
|
||||||
__node_id_counter = 0
|
__node_id_counter = 0
|
||||||
|
|
||||||
def __init__(self, pendingImport, textureAtlas):
|
def __init__(self, pendingImport, textureAtlas):
|
||||||
|
"""
|
||||||
|
A scenegraph node displaying an object that will be imported later, including
|
||||||
|
live and deferred views of the object with transformed items, and a BoxHandle
|
||||||
|
for moving the item.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
|
||||||
|
pendingImport: PendingImport
|
||||||
|
The object to be imported. The PendingImportNode responds to changes in this
|
||||||
|
object's position, rotation, and scale.
|
||||||
|
textureAtlas: TextureAtlas
|
||||||
|
The textures and block models used to render the preview of the object.
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
----------
|
||||||
|
|
||||||
|
basePosition: Vector
|
||||||
|
The pre-transform position of the pending import. This is equal to
|
||||||
|
`self.pendingImport.basePosition` except when the node is currently being
|
||||||
|
dragged.
|
||||||
|
transformedPosition: Vector
|
||||||
|
The post-transform position of the pending import. This is equal to
|
||||||
|
`self.pendingImport.importPos` except when the node is currently being
|
||||||
|
dragged, scaled, or rotated.
|
||||||
|
"""
|
||||||
super(PendingImportNode, self).__init__()
|
super(PendingImportNode, self).__init__()
|
||||||
PendingImportNode.__node_id_counter += 1
|
|
||||||
self.id = PendingImportNode.__node_id_counter
|
|
||||||
|
|
||||||
self.textureAtlas = textureAtlas
|
self.textureAtlas = textureAtlas
|
||||||
self.pendingImport = pendingImport
|
self.pendingImport = pendingImport
|
||||||
@ -38,7 +105,7 @@ class PendingImportNode(Node, QtCore.QObject):
|
|||||||
self.addChild(self.positionTranslateNode)
|
self.addChild(self.positionTranslateNode)
|
||||||
self.positionTranslateNode.addChild(self.rotateNode)
|
self.positionTranslateNode.addChild(self.rotateNode)
|
||||||
|
|
||||||
self.rotateNode.setAnchor(self.pendingImport.bounds.size * 0.5)
|
self.rotateNode.setAnchor(self.pendingImport.selection.size * 0.5)
|
||||||
|
|
||||||
# worldSceneTranslateNode is contained by positionTranslateNode, and
|
# worldSceneTranslateNode is contained by positionTranslateNode, and
|
||||||
# serves to translate the world scene back to 0, 0, 0 so the positionTranslateNode
|
# serves to translate the world scene back to 0, 0, 0 so the positionTranslateNode
|
||||||
@ -70,7 +137,7 @@ class PendingImportNode(Node, QtCore.QObject):
|
|||||||
self.handleNode.resizable = False
|
self.handleNode.resizable = False
|
||||||
|
|
||||||
self.updateTransformedScene()
|
self.updateTransformedScene()
|
||||||
self.pos = pendingImport.pos
|
self.basePosition = pendingImport.basePosition
|
||||||
|
|
||||||
self.handleNode.boundsChanged.connect(self.handleBoundsChanged)
|
self.handleNode.boundsChanged.connect(self.handleBoundsChanged)
|
||||||
self.handleNode.boundsChangedDone.connect(self.handleBoundsChangedDone)
|
self.handleNode.boundsChangedDone.connect(self.handleBoundsChangedDone)
|
||||||
@ -82,23 +149,26 @@ class PendingImportNode(Node, QtCore.QObject):
|
|||||||
list(pendingImport.selection.chunkPositions()))
|
list(pendingImport.selection.chunkPositions()))
|
||||||
self.loader.startLoader()
|
self.loader.startLoader()
|
||||||
|
|
||||||
|
self.pendingImport.positionChanged.connect(self.setPosition)
|
||||||
|
self.pendingImport.rotationChanged.connect(self.setRotation)
|
||||||
|
|
||||||
# Emitted when the user finishes dragging the box handle and releases the mouse
|
# Emitted when the user finishes dragging the box handle and releases the mouse
|
||||||
# button. Arguments are (newPosition, oldPosition).
|
# button. Arguments are (newPosition, oldPosition).
|
||||||
importMoved = QtCore.Signal(object, object)
|
importMoved = QtCore.Signal(object, object)
|
||||||
|
|
||||||
def handleBoundsChangedDone(self, bounds, oldBounds):
|
def handleBoundsChangedDone(self, bounds, oldBounds):
|
||||||
point = self.getPosFromBox(bounds.origin)
|
point = self.getBaseFromTransformed(bounds.origin)
|
||||||
oldPoint = self.getPosFromBox(oldBounds.origin)
|
oldPoint = self.getBaseFromTransformed(oldBounds.origin)
|
||||||
if point != oldPoint:
|
if point != oldPoint:
|
||||||
self.importMoved.emit(point, oldPoint)
|
self.importMoved.emit(point, oldPoint)
|
||||||
|
|
||||||
def handleBoundsChanged(self, bounds):
|
def handleBoundsChanged(self, bounds):
|
||||||
point = self.getPosFromBox(bounds.origin)
|
point = self.getBaseFromTransformed(bounds.origin)
|
||||||
if self.pos != point:
|
if self.basePosition != point:
|
||||||
self.pos = point
|
self.basePosition = point
|
||||||
|
|
||||||
def getPosFromBox(self, point):
|
def getBaseFromTransformed(self, point):
|
||||||
offset = self.pendingImport.pos - self.pendingImport.importPos
|
offset = self.pendingImport.basePosition - self.pendingImport.importPos
|
||||||
return point + offset
|
return point + offset
|
||||||
|
|
||||||
def setPreviewRotation(self, rots):
|
def setPreviewRotation(self, rots):
|
||||||
@ -108,7 +178,6 @@ class PendingImportNode(Node, QtCore.QObject):
|
|||||||
self.rotateNode.setRotation(rots)
|
self.rotateNode.setRotation(rots)
|
||||||
|
|
||||||
def setRotation(self, rots):
|
def setRotation(self, rots):
|
||||||
self.pendingImport.rotation = rots
|
|
||||||
self.updateTransformedScene()
|
self.updateTransformedScene()
|
||||||
self.updateBoxHandle()
|
self.updateBoxHandle()
|
||||||
|
|
||||||
@ -144,14 +213,18 @@ class PendingImportNode(Node, QtCore.QObject):
|
|||||||
self.transformedWorldScene = None
|
self.transformedWorldScene = None
|
||||||
|
|
||||||
def updateTransformedSceneOffset(self):
|
def updateTransformedSceneOffset(self):
|
||||||
self.transformedWorldTranslateNode.translateOffset = self.pos - self.pendingImport.rotateAnchor + self.pendingImport.bounds.size * 0.5
|
self.transformedWorldTranslateNode.translateOffset = self.transformedPosition - self.pendingImport.importDim.bounds.origin
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def pos(self):
|
def transformedPosition(self):
|
||||||
|
return self.basePosition + self.pendingImport.importPos - self.pendingImport.basePosition
|
||||||
|
|
||||||
|
@property
|
||||||
|
def basePosition(self):
|
||||||
return self.positionTranslateNode.translateOffset
|
return self.positionTranslateNode.translateOffset
|
||||||
|
|
||||||
@pos.setter
|
@basePosition.setter
|
||||||
def pos(self, value):
|
def basePosition(self, value):
|
||||||
if value == self.positionTranslateNode.translateOffset:
|
if value == self.positionTranslateNode.translateOffset:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -159,11 +232,14 @@ class PendingImportNode(Node, QtCore.QObject):
|
|||||||
self.updateTransformedSceneOffset()
|
self.updateTransformedSceneOffset()
|
||||||
self.updateBoxHandle()
|
self.updateBoxHandle()
|
||||||
|
|
||||||
|
def setPosition(self, pos):
|
||||||
|
self.basePosition = pos
|
||||||
|
|
||||||
def updateBoxHandle(self):
|
def updateBoxHandle(self):
|
||||||
if self.transformedWorldScene is None:
|
if self.transformedWorldScene is None:
|
||||||
bounds = BoundingBox(self.pos, self.pendingImport.bounds.size)
|
bounds = BoundingBox(self.basePosition, self.pendingImport.bounds.size)
|
||||||
else:
|
else:
|
||||||
origin = self.pos - self.pendingImport.pos + self.pendingImport.importPos
|
origin = self.transformedPosition
|
||||||
bounds = BoundingBox(origin, self.pendingImport.importBounds.size)
|
bounds = BoundingBox(origin, self.pendingImport.importBounds.size)
|
||||||
#if self.handleNode.bounds.size != bounds.size:
|
#if self.handleNode.bounds.size != bounds.size:
|
||||||
self.handleNode.bounds = bounds
|
self.handleNode.bounds = bounds
|
||||||
@ -181,7 +257,7 @@ class PendingImportNode(Node, QtCore.QObject):
|
|||||||
self.handleNode.mouseRelease(event)
|
self.handleNode.mouseRelease(event)
|
||||||
|
|
||||||
|
|
||||||
class PendingImport(object):
|
class PendingImport(QtCore.QObject):
|
||||||
"""
|
"""
|
||||||
An object representing a schematic, etc that is currently being imported and can be
|
An object representing a schematic, etc that is currently being imported and can be
|
||||||
moved/rotated/scaled by the user.
|
moved/rotated/scaled by the user.
|
||||||
@ -191,7 +267,7 @@ class PendingImport(object):
|
|||||||
|
|
||||||
sourceDim: WorldEditorDimension
|
sourceDim: WorldEditorDimension
|
||||||
The object that will be imported.
|
The object that will be imported.
|
||||||
pos: Vector
|
basePosition: Vector
|
||||||
The position in the currently edited world where the object will be imported.
|
The position in the currently edited world where the object will be imported.
|
||||||
selection: SelectionBox
|
selection: SelectionBox
|
||||||
Defines the portion of sourceDim that will be imported. For importing
|
Defines the portion of sourceDim that will be imported. For importing
|
||||||
@ -212,8 +288,8 @@ class PendingImport(object):
|
|||||||
importPos: Vector
|
importPos: Vector
|
||||||
The effective position where the object is to be imported. When the
|
The effective position where the object is to be imported. When the
|
||||||
PendingImport's rotation or scale is the default, this will be the
|
PendingImport's rotation or scale is the default, this will be the
|
||||||
same as `self.pos`, otherwise it will be the position where the transformed
|
same as `self.basePosition`, otherwise it will be the position where the transformed
|
||||||
object will be imported. Changing this attribute will also change `self.pos`
|
object will be imported. Changing this attribute will also change `self.basePosition`
|
||||||
to the pre-transform position accordingly.
|
to the pre-transform position accordingly.
|
||||||
|
|
||||||
importDim: WorldEditorDimension
|
importDim: WorldEditorDimension
|
||||||
@ -239,7 +315,7 @@ class PendingImport(object):
|
|||||||
|
|
||||||
bounds: BoundingBox
|
bounds: BoundingBox
|
||||||
The axis-aligned bounding box that completely encloses `self.selection`, moved
|
The axis-aligned bounding box that completely encloses `self.selection`, moved
|
||||||
to the position given by `self.pos`, in destination coordinates.
|
to the position given by `self.basePosition`, in destination coordinates.
|
||||||
|
|
||||||
importBounds: BoundingBox
|
importBounds: BoundingBox
|
||||||
The axis-aligned bounding box that completely encloses the transformed dimension
|
The axis-aligned bounding box that completely encloses the transformed dimension
|
||||||
@ -247,9 +323,11 @@ class PendingImport(object):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, sourceDim, pos, selection, text, isMove=False):
|
def __init__(self, sourceDim, pos, selection, text, isMove=False):
|
||||||
|
super(PendingImport, self).__init__()
|
||||||
|
|
||||||
self.selection = selection
|
self.selection = selection
|
||||||
self.text = text
|
self.text = text
|
||||||
self.pos = pos
|
self._pos = pos
|
||||||
self.sourceDim = sourceDim
|
self.sourceDim = sourceDim
|
||||||
self.isMove = isMove
|
self.isMove = isMove
|
||||||
self._rotation = (0, 0, 0)
|
self._rotation = (0, 0, 0)
|
||||||
@ -259,18 +337,34 @@ class PendingImport(object):
|
|||||||
bounds = self.selection
|
bounds = self.selection
|
||||||
self.rotateAnchor = bounds.origin + bounds.size * 0.5
|
self.rotateAnchor = bounds.origin + bounds.size * 0.5
|
||||||
|
|
||||||
|
positionChanged = QtCore.Signal(object)
|
||||||
|
rotationChanged = QtCore.Signal(object)
|
||||||
|
scaleChanged = QtCore.Signal(object)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def basePosition(self):
|
||||||
|
return self._pos
|
||||||
|
|
||||||
|
@basePosition.setter
|
||||||
|
def basePosition(self, value):
|
||||||
|
if value == self._pos:
|
||||||
|
return
|
||||||
|
|
||||||
|
self._pos = Vector(*value)
|
||||||
|
self.positionChanged.emit(self._pos)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def importPos(self):
|
def importPos(self):
|
||||||
if self.transformedDim is None:
|
if self.transformedDim is None:
|
||||||
return self.pos
|
return self.basePosition
|
||||||
return self.pos + self.transformedDim.bounds.origin - self.selection.origin
|
return self.basePosition + self.transformedDim.bounds.origin - self.selection.origin
|
||||||
|
|
||||||
@importPos.setter
|
@importPos.setter
|
||||||
def importPos(self, pos):
|
def importPos(self, pos):
|
||||||
if self.transformedDim is None:
|
if self.transformedDim is None:
|
||||||
self.pos = pos
|
self.basePosition = pos
|
||||||
else:
|
else:
|
||||||
self.pos = pos - self.transformedDim.bounds.origin + self.selection.origin
|
self.basePosition = pos - self.transformedDim.bounds.origin + self.selection.origin
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def importDim(self):
|
def importDim(self):
|
||||||
@ -285,8 +379,11 @@ class PendingImport(object):
|
|||||||
|
|
||||||
@rotation.setter
|
@rotation.setter
|
||||||
def rotation(self, value):
|
def rotation(self, value):
|
||||||
self._rotation = value
|
if self._rotation == value:
|
||||||
|
return
|
||||||
|
self._rotation = Vector(*value)
|
||||||
self.updateTransform()
|
self.updateTransform()
|
||||||
|
self.rotationChanged.emit(self._rotation)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def scale(self):
|
def scale(self):
|
||||||
@ -294,7 +391,10 @@ class PendingImport(object):
|
|||||||
|
|
||||||
@scale.setter
|
@scale.setter
|
||||||
def scale(self, value):
|
def scale(self, value):
|
||||||
self._rotation = value
|
if self._scale == value:
|
||||||
|
return
|
||||||
|
self._scale = Vector(*value)
|
||||||
|
self.scaleChanged.emit(self._scale)
|
||||||
self.updateTransform()
|
self.updateTransform()
|
||||||
|
|
||||||
def updateTransform(self):
|
def updateTransform(self):
|
||||||
@ -305,11 +405,12 @@ class PendingImport(object):
|
|||||||
self.transformedDim = DimensionTransform(selectionDim, self.rotateAnchor, *self.rotation)
|
self.transformedDim = DimensionTransform(selectionDim, self.rotateAnchor, *self.rotation)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "%s(%r, %r, %r)" % (self.__class__.__name__, self.sourceDim, self.selection, self.pos)
|
return "%s(%r, %r, %r)" % (
|
||||||
|
self.__class__.__name__, self.sourceDim, self.selection, self.basePosition)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def bounds(self):
|
def bounds(self):
|
||||||
return BoundingBox(self.pos, self.selection.size)
|
return BoundingBox(self.basePosition, self.selection.size)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def importBounds(self):
|
def importBounds(self):
|
||||||
@ -330,10 +431,10 @@ class Rotate3DNode(Node):
|
|||||||
self.recenterNode = TranslateNode()
|
self.recenterNode = TranslateNode()
|
||||||
|
|
||||||
super(Rotate3DNode, self).addChild(self.anchorNode)
|
super(Rotate3DNode, self).addChild(self.anchorNode)
|
||||||
self.anchorNode.addChild(self.rotXNode)
|
self.anchorNode.addChild(self.rotZNode)
|
||||||
self.rotXNode.addChild(self.rotYNode)
|
self.rotZNode.addChild(self.rotYNode)
|
||||||
self.rotYNode.addChild(self.rotZNode)
|
self.rotYNode.addChild(self.rotXNode)
|
||||||
self.rotZNode.addChild(self.recenterNode)
|
self.rotXNode.addChild(self.recenterNode)
|
||||||
|
|
||||||
def addChild(self, node):
|
def addChild(self, node):
|
||||||
self.recenterNode.addChild(node)
|
self.recenterNode.addChild(node)
|
||||||
|
17
src/mcedit2/panels/pending_imports.py
Normal file
17
src/mcedit2/panels/pending_imports.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
"""
|
||||||
|
pending_imports
|
||||||
|
"""
|
||||||
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
from PySide import QtGui
|
||||||
|
import logging
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class PendingImportsWidget(QtGui.QWidget):
|
||||||
|
def __init__(self):
|
||||||
|
super(PendingImportsWidget, self).__init__()
|
||||||
|
self.importsListWidget = QtGui.QListView()
|
||||||
|
self.importsListModel = QtGui.QStandardItemModel()
|
||||||
|
self.importsListWidget.setModel(self.importsListModel)
|
||||||
|
self.importsListWidget.clicked.connect(self.listClicked)
|
||||||
|
self.importsListWidget.doubleClicked.connect(self.listDoubleClicked)
|
Reference in New Issue
Block a user