Encapsulate pending import info, preparing for multiple imports

This commit is contained in:
David Vierra 2015-01-21 15:35:04 -10:00
parent b4de6e2ac9
commit f57196537b
2 changed files with 82 additions and 78 deletions

View File

@ -39,6 +39,14 @@ selection box, the editor tab containing its viewports, its command history, a s
tool (why?), and the ChunkLoader that coordinates loading chunks into its viewports.
"""
class PendingImport(object):
def __init__(self, schematic, pos):
self.pos = pos
self.schematic = schematic
def __repr__(self):
return "%s(%r, %r)" % (self.__class__.__name__, self.schematic, self.pos)
class EditorSession(QtCore.QObject):
def __init__(self, filename, versionInfo, readonly=False):
QtCore.QObject.__init__(self)
@ -52,6 +60,9 @@ class EditorSession(QtCore.QObject):
self.copiedSchematic = None
""":type : WorldEditor"""
self.pendingImports = []
self.versionInfo = versionInfo
# --- Open world editor ---
@ -250,13 +261,7 @@ class EditorSession(QtCore.QObject):
if self.copiedSchematic is None:
return
moveTool = self.tools["Move"]
ray = self.editorTab.currentView().rayAtCenter()
point = ray.point + ray.vector * (self.copiedSchematic.getDimension().bounds.size.length() * 2)
point = Vector(*[int(i) for i in point])
moveTool.pasteSchematic(self.copiedSchematic, point)
self.chooseTool("Move")
self.beginImport(self.copiedSchematic, self.currentSelection.origin)
def pasteBlocks(self):
NotImplementedYet()
@ -271,15 +276,32 @@ class EditorSession(QtCore.QObject):
def importSchematic(self, filename):
schematic = WorldEditor(filename, readonly=True)
self.beginImport(schematic)
# --- Import ---
def beginImport(self, schematic, pos=None):
moveTool = self.tools["Move"]
ray = self.editorTab.currentView().rayAtCenter()
point, face = rayCastInBounds(ray, self.currentDimension)
if point is None:
point = ray.point
moveTool.pasteSchematic(schematic, point)
if pos is None:
ray = self.editorTab.currentView().rayAtCenter()
pos, face = rayCastInBounds(ray, self.currentDimension)
if pos is None:
pos = ray.point
imp = PendingImport(schematic, pos)
self.pendingImports.append(imp)
moveTool.currentImport = imp
self.chooseTool("Move")
def addPendingImport(self, pendingImport):
self.pendingImports.append(pendingImport)
def removePendingImport(self, pendingImport):
self.pendingImports.remove(pendingImport)
# --- Undo support ---
def undoIndexChanged(self, index):

View File

@ -5,6 +5,7 @@ from __future__ import absolute_import, division, print_function
import logging
from PySide import QtGui, QtCore
from mcedit2.editorsession import PendingImport
from mcedit2.editortools import EditorTool
from mcedit2.command import SimpleRevisionCommand
@ -24,25 +25,22 @@ from mceditlib.selection import BoundingBox
log = logging.getLogger(__name__)
class MoveSelectionCommand(SimpleRevisionCommand):
def __init__(self, moveTool, movingSchematic, movePosition=None, text=None, *args, **kwargs):
def __init__(self, moveTool, pendingImport, text=None, *args, **kwargs):
if text is None:
text = moveTool.tr("Move Selected Things")
if movePosition is None:
movePosition = moveTool.editorSession.currentSelection.origin
text = moveTool.tr("Move Selected Object")
super(MoveSelectionCommand, self).__init__(moveTool.editorSession, text, *args, **kwargs)
self.currentImport = pendingImport
self.moveTool = moveTool
self.movingSchematic = movingSchematic
self.movePosition = movePosition
def undo(self):
super(MoveSelectionCommand, self).undo()
self.moveTool.movingSchematic = None
self.moveTool.movePosition = None
self.moveTool.currentImport = None
self.editorSession.removePendingImport(self.currentImport)
self.moveTool.editorSession.chooseTool("Select")
def redo(self):
self.moveTool.movingSchematic = self.movingSchematic
self.moveTool.movePosition = self.movePosition
self.moveTool.currentImport = self.currentImport
self.editorSession.addPendingImport(self.currentImport)
self.moveTool.editorSession.chooseTool("Move")
super(MoveSelectionCommand, self).redo()
@ -51,7 +49,7 @@ class MoveOffsetCommand(QtGui.QUndoCommand):
def __init__(self, moveTool, oldPoint, newPoint):
super(MoveOffsetCommand, self).__init__()
self.setText(moveTool.tr("Move Things"))
self.setText(moveTool.tr("Move Object"))
self.newPoint = newPoint
self.oldPoint = oldPoint
self.moveTool = moveTool
@ -63,24 +61,24 @@ class MoveOffsetCommand(QtGui.QUndoCommand):
self.moveTool.movePosition = self.newPoint
class MoveFinishCommand(SimpleRevisionCommand):
def __init__(self, moveTool, movingSchematic, *args, **kwargs):
super(MoveFinishCommand, self).__init__(moveTool.editorSession, moveTool.tr("Finish Moving Things"), *args, **kwargs)
self.movingSchematic = movingSchematic
def __init__(self, moveTool, pendingImport, *args, **kwargs):
super(MoveFinishCommand, self).__init__(moveTool.editorSession, moveTool.tr("Finish Move"), *args, **kwargs)
self.currentImport = pendingImport
self.moveTool = moveTool
def undo(self):
super(MoveFinishCommand, self).undo()
self.moveTool.movingSchematic = self.movingSchematic
self.moveTool.movePosition = self.movePosition
self.moveTool.pendingImport = self.currentImport
self.editorSession.currentSelection = self.previousSelection
self.editorSession.chooseTool("Move")
def redo(self):
super(MoveFinishCommand, self).redo()
self.previousSelection = self.editorSession.currentSelection
self.movePosition = self.moveTool.movePosition
self.editorSession.currentSelection = BoundingBox(self.movePosition, self.previousSelection.size)
self.moveTool.movingSchematic = None
self.currentImport = self.moveTool.currentImport
self.editorSession.currentSelection = BoundingBox(self.pendingImport.pos, self.previousSelection.size)
self.moveTool.currentImport = None
self.editorSession.removePendingImport(self.currentImport)
class CoordinateWidget(QtGui.QWidget):
@ -154,18 +152,15 @@ class MoveTool(EditorTool):
self.pointInput = CoordinateWidget()
self.pointInput.pointChanged.connect(self.pointInputChanged)
confirmButton = QtGui.QPushButton("Confirm") # xxxx should be in worldview
confirmButton.clicked.connect(self.completeMove)
confirmButton.clicked.connect(self.confirmImport)
self.toolWidget.setLayout(Column(self.pointInput,
confirmButton,
None))
self.movePosition = None
_movePosition = None
@property
def movePosition(self):
return self._movePosition
return None if self.currentImport is None else self.currentImport.pos
@movePosition.setter
def movePosition(self, value):
@ -179,35 +174,33 @@ class MoveTool(EditorTool):
def doMoveOffsetCommand(self, oldPoint, newPoint):
if newPoint != oldPoint:
command = MoveOffsetCommand(self, oldPoint, newPoint)
self.editorSession.removeUndoBlock(self.moveUndoBlock)
self.editorSession.pushCommand(command)
self.editorSession.setUndoBlock(self.moveUndoBlock)
def pointInputChanged(self, value):
self._movePosition = value
if value is not None:
self.currentImport.pos = value
self.translateNode.visible = True
self.translateNode.translateOffset = value
else:
self.translateNode.visible = False
_movingSchematic = None
_currentImport = None
@property
def movingSchematic(self):
return self._movingSchematic
def currentImport(self):
return self._currentImport
@movingSchematic.setter
def movingSchematic(self, value):
oldVal = self._movingSchematic
self._movingSchematic = value
@currentImport.setter
def currentImport(self, value):
oldVal = self._currentImport
self._currentImport = value
if oldVal is not value:
self.updateOverlay()
self.pointInput.setEnabled(value is not None)
def updateOverlay(self):
if self.movingSchematic is None:
if self.currentImport is None:
log.info("updateOverlay: Nothing to display")
if self.movingWorldScene:
self.sceneHolderNode.removeChild(self.movingWorldScene)
@ -215,12 +208,12 @@ class MoveTool(EditorTool):
self.outlineNode.visible = False
log.info("Updating move schematic scene: %s", self.movingSchematic)
log.info("Updating move schematic scene: %s", self.currentImport)
if self.movingWorldScene:
self.loader.timer.stop()
self.sceneHolderNode.removeChild(self.movingWorldScene)
if self.movingSchematic:
dim = self.movingSchematic.getDimension()
if self.currentImport:
dim = self.currentImport.schematic.getDimension()
self.movingWorldScene = WorldScene(dim, self.editorSession.textureAtlas)
# xxx assumes import is same blocktypes as world, find atlas for imported object
self.outlineNode.selectionBox = dim.bounds
@ -234,7 +227,7 @@ class MoveTool(EditorTool):
@property
def schematicBox(self):
box = self.movingSchematic.getDimension().bounds
box = self.currentImport.schematic.getDimension().bounds
return BoundingBox(self.movePosition, box.size)
# --- Mouse events ---
@ -252,7 +245,7 @@ class MoveTool(EditorTool):
def mouseMove(self, event):
# Hilite face cursor is over
if self.movingSchematic is None or self.movePosition is None:
if self.currentImport is None:
return
point, face = boxFaceUnderCursor(self.schematicBox, event.ray)
@ -261,7 +254,7 @@ class MoveTool(EditorTool):
self.faceHoverNode.visible = True
self.faceHoverNode.face = face
self.faceHoverNode.selectionBox = self.movingSchematic.getDimension().bounds
self.faceHoverNode.selectionBox = self.currentImport.schematic.getDimension().bounds
else:
self.faceHoverNode.visible = False
@ -270,7 +263,7 @@ class MoveTool(EditorTool):
def mouseDrag(self, event):
# Move box using face or axis pointers
if self.movingSchematic is None:
if self.currentImport is None:
return
if self.dragStartFace is None:
return
@ -286,7 +279,7 @@ class MoveTool(EditorTool):
# begin drag
if self.movingSchematic is not None:
if self.currentImport is not None:
point, face = boxFaceUnderCursor(self.schematicBox, event.ray)
self.dragStartFace = face
self.dragStartPoint = point
@ -296,55 +289,44 @@ class MoveTool(EditorTool):
# Don't paste cut selection in yet. Wait for tool switch or "Confirm" button press. Begin new revision
# for paste operation, paste stored world, store revision after paste (should be previously stored revision
# +2), commit MoveCommand to undo history.
if self.movingSchematic is not None:
if self.currentImport is not None:
self.doMoveOffsetCommand(self.dragStartMovePosition, self.movePosition)
def toolActive(self):
self.editorSession.selectionTool.hideSelectionWalls = True
if self.movingSchematic is None:
if self.currentImport is None:
# Need to cut out selection
# xxxx for huge selections, don't cut, just do everything at the end?
if self.editorSession.currentSelection is None:
return
export = self.editorSession.currentDimension.exportSchematicIter(self.editorSession.currentSelection)
self.movingSchematic = showProgress("Lifting...", export)
moveCommand = MoveSelectionCommand(self, self.movingSchematic)
schematic = showProgress("Copying...", export)
pos = self.editorSession.currentSelection.origin
pendingImport = PendingImport(schematic, pos)
moveCommand = MoveSelectionCommand(self, pendingImport)
with moveCommand.begin():
fill = self.editorSession.currentDimension.fillBlocksIter(self.editorSession.currentSelection, "air")
showProgress("Lifting...", fill)
showProgress("Clearing...", fill)
self.editorSession.pushCommand(moveCommand)
self.editorSession.setUndoBlock(self.moveUndoBlock)
def moveUndoBlock(self):
self.completeMove()
self.movingSchematic = None
self.outlineNode.visible = True
def toolInactive(self):
self.editorSession.selectionTool.hideSelectionWalls = False
if self.movingSchematic is not None:
self.completeMove()
self.movingSchematic = None
self.outlineNode.visible = False
self.faceHoverNode.visible = False
def completeMove(self):
if self.movingSchematic is None:
def confirmImport(self):
if self.currentImport is None:
return
self.editorSession.removeUndoBlock(self.moveUndoBlock)
command = MoveFinishCommand(self, self.movingSchematic)
command = MoveFinishCommand(self, self.currentImport)
with command.begin():
task = self.editorSession.currentDimension.importSchematicIter(self.movingSchematic, self.movePosition)
task = self.editorSession.currentDimension.importSchematicIter(self.currentImport.schematic, self.currentImport.pos)
showProgress(self.tr("Pasting..."), task)
self.editorSession.pushCommand(command)
def pasteSchematic(self, copiedSchematic, position):
command = MoveSelectionCommand(self, copiedSchematic, position, self.tr("Paste"))
self.editorSession.pushCommand(command)
self.editorSession.setUndoBlock(self.moveUndoBlock)