WorldView now accepts dropped map items dragged from Library panel
Map items are placed immediately with no "movable" intermediate. xxx still need placement preview! and xxx should allow URLs/schematic files/etc to be dropped from Library's Schematic panel, file explorer, etc!
This commit is contained in:
parent
31aec2a932
commit
fd76076689
@ -17,6 +17,7 @@ from mcedit2.panels.map import MapPanel
|
||||
from mcedit2.panels.worldinfo import WorldInfoPanel
|
||||
from mcedit2.util.dialogs import NotImplementedYet
|
||||
from mcedit2.util.directories import getUserSchematicsDirectory
|
||||
from mcedit2.util.mimeformats import MimeFormats
|
||||
from mceditlib.util import exhaust
|
||||
from mceditlib.util.lazyprop import weakrefprop
|
||||
from mcedit2.util.raycast import rayCastInBounds
|
||||
@ -33,13 +34,13 @@ from mcedit2.worldview.camera import CameraWorldViewFrame
|
||||
from mcedit2.worldview.cutaway import CutawayWorldViewFrame
|
||||
from mcedit2.worldview.minimap import MinimapWorldView
|
||||
from mcedit2.worldview.overhead import OverheadWorldViewFrame
|
||||
from mceditlib import util
|
||||
from mceditlib import util, nbt, faces
|
||||
from mceditlib.anvil.biome_types import BiomeTypes
|
||||
from mceditlib.geometry import Vector
|
||||
from mceditlib.operations import ComposeOperations
|
||||
from mceditlib.operations.entity import RemoveEntitiesOperation
|
||||
from mceditlib.selection import BoundingBox
|
||||
from mceditlib.exceptions import PlayerNotFound
|
||||
from mceditlib.exceptions import PlayerNotFound, ChunkNotPresent
|
||||
from mceditlib.revisionhistory import UndoFolderExists, RevisionChanges
|
||||
from mceditlib.worldeditor import WorldEditor
|
||||
from mceditlib.blocktypes import BlockType
|
||||
@ -367,6 +368,9 @@ class EditorSession(QtCore.QObject):
|
||||
self.editorTab = EditorTab(self)
|
||||
self.toolChanged.connect(self.toolDidChange)
|
||||
|
||||
self.editorTab.urlsDropped.connect(self.urlsWereDropped)
|
||||
self.editorTab.mapItemDropped.connect(self.mapItemWasDropped)
|
||||
|
||||
self.undoStack.indexChanged.connect(self.undoIndexChanged)
|
||||
|
||||
self.findReplaceDialog = FindReplaceDialog(self)
|
||||
@ -668,6 +672,52 @@ class EditorSession(QtCore.QObject):
|
||||
schematic = showProgress("Copying...", task)
|
||||
schematic.saveToFile(filename)
|
||||
|
||||
# --- Drag-and-drop ---
|
||||
|
||||
def urlsWereDropped(self, mimeData, position, face):
|
||||
log.info("URLs dropped:\n%s", mimeData.urls())
|
||||
|
||||
def mapItemWasDropped(self, mimeData, position, face):
|
||||
log.info("Map item dropped.")
|
||||
assert mimeData.hasFormat(MimeFormats.MapItem)
|
||||
mapIDString = mimeData.data(MimeFormats.MapItem).data()
|
||||
mapIDs = mapIDString.split(", ")
|
||||
mapIDs = [int(m) for m in mapIDs]
|
||||
mapID = mapIDs[0] # xxx only one at a time for now
|
||||
|
||||
position = position + face.vector
|
||||
x, y, z = position
|
||||
cx = x >> 4
|
||||
cz = z >> 4
|
||||
try:
|
||||
chunk = self.currentDimension.getChunk(cx, cz)
|
||||
except ChunkNotPresent:
|
||||
log.info("Refusing to import map into non-existent chunk %s", (cx, cz))
|
||||
return
|
||||
|
||||
ref = self.worldEditor.createEntity("ItemFrame")
|
||||
if ref is None:
|
||||
return
|
||||
|
||||
facing = ref.facingForMCEditFace(face)
|
||||
if facing is None:
|
||||
# xxx by camera vector?
|
||||
facing = ref.SouthFacing
|
||||
|
||||
ref.Item.Damage = mapID
|
||||
ref.Item.id = "minecraft:filled_map"
|
||||
ref.Position = position + (0.5, 0.5, 0.5)
|
||||
ref.TilePos = position # 1.7/1.8 issues should be handled by ref...
|
||||
ref.Facing = facing
|
||||
|
||||
log.info("Created map ItemFrame with ID %s, importing...", mapID)
|
||||
|
||||
command = SimpleRevisionCommand(self, self.tr("Import map %(mapID)s") % {"mapID": mapID})
|
||||
with command.begin():
|
||||
chunk.addEntity(ref)
|
||||
log.info(nbt.nested_string(ref.rootTag))
|
||||
self.pushCommand(command)
|
||||
|
||||
# --- Library support ---
|
||||
|
||||
def importSchematic(self, filename):
|
||||
@ -1000,6 +1050,9 @@ class EditorTab(QtGui.QWidget):
|
||||
|
||||
editorSession = weakrefprop()
|
||||
|
||||
urlsDropped = QtCore.Signal(QtCore.QMimeData, Vector, faces.Face)
|
||||
mapItemDropped = QtCore.Signal(QtCore.QMimeData, Vector, faces.Face)
|
||||
|
||||
def configuredBlocksDidChange(self):
|
||||
for view in self.views:
|
||||
view.setTextureAtlas(self.editorSession.textureAtlas)
|
||||
@ -1057,6 +1110,8 @@ class EditorTab(QtGui.QWidget):
|
||||
UseToolMouseAction(self),
|
||||
TrackingMouseAction(self)
|
||||
])
|
||||
frame.worldView.urlsDropped.connect(self.urlsDropped.emit)
|
||||
frame.worldView.mapItemDropped.connect(self.mapItemDropped.emit)
|
||||
|
||||
def currentView(self):
|
||||
"""
|
||||
|
@ -23,6 +23,7 @@ from mcedit2.rendering.textureatlas import TextureAtlas
|
||||
from mcedit2.rendering.vertexarraybuffer import VertexArrayBuffer
|
||||
from mcedit2.rendering import scenegraph, rendergraph
|
||||
from mcedit2.util import profiler, raycast
|
||||
from mcedit2.util.mimeformats import MimeFormats
|
||||
from mcedit2.util.qglcontext import validateQGLContext
|
||||
from mcedit2.util.settings import Settings
|
||||
from mcedit2.widgets.infopanel import InfoPanel
|
||||
@ -72,6 +73,9 @@ class WorldView(QGLWidget):
|
||||
viewportMoved = QtCore.Signal(QtGui.QWidget)
|
||||
cursorMoved = QtCore.Signal(QtGui.QMouseEvent)
|
||||
|
||||
urlsDropped = QtCore.Signal(QtCore.QMimeData, Vector, faces.Face)
|
||||
mapItemDropped = QtCore.Signal(QtCore.QMimeData, Vector, faces.Face)
|
||||
|
||||
mouseBlockPos = Vector(0, 0, 0)
|
||||
mouseBlockFace = faces.FaceYIncreasing
|
||||
|
||||
@ -92,6 +96,7 @@ class WorldView(QGLWidget):
|
||||
QGLWidget.__init__(self, shareWidget=sharedGLWidget)
|
||||
validateQGLContext(self.context())
|
||||
|
||||
self.setAcceptDrops(True)
|
||||
self.setSizePolicy(QtGui.QSizePolicy.Policy.Expanding, QtGui.QSizePolicy.Policy.Expanding)
|
||||
self.setFocusPolicy(Qt.ClickFocus)
|
||||
|
||||
@ -138,6 +143,32 @@ class WorldView(QGLWidget):
|
||||
|
||||
self.setDimension(dimension)
|
||||
|
||||
acceptableMimeTypes = [
|
||||
MimeFormats.MapItem,
|
||||
]
|
||||
|
||||
def dragEnterEvent(self, event):
|
||||
# xxx show drop preview as scene node
|
||||
print("DRAG ENTER. FORMATS:\n%s" % event.mimeData().formats())
|
||||
for mimeType in self.acceptableMimeTypes:
|
||||
if event.mimeData().hasFormat(mimeType):
|
||||
event.acceptProposedAction()
|
||||
return
|
||||
if event.mimeData().hasUrls():
|
||||
event.acceptProposedAction()
|
||||
|
||||
def dropEvent(self, event):
|
||||
mimeData = event.mimeData()
|
||||
x = event.pos().x()
|
||||
y = event.pos().y()
|
||||
ray = self.rayAtPosition(x, y)
|
||||
dropPosition, face = self.rayCastInView(ray)
|
||||
|
||||
if mimeData.hasFormat(MimeFormats.MapItem):
|
||||
self.mapItemDropped.emit(mimeData, dropPosition, face)
|
||||
elif mimeData.hasUrls:
|
||||
self.urlsDropped.emit(mimeData, dropPosition, face)
|
||||
|
||||
def setDimension(self, dimension):
|
||||
"""
|
||||
|
||||
@ -456,6 +487,13 @@ class WorldView(QGLWidget):
|
||||
event.ray = ray
|
||||
event.view = self
|
||||
|
||||
position, face = self.rayCastInView(ray)
|
||||
|
||||
self.mouseBlockPos = event.blockPosition = position
|
||||
self.mouseBlockFace = event.blockFace = face
|
||||
self.mouseRay = ray
|
||||
|
||||
def rayCastInView(self, ray):
|
||||
try:
|
||||
result = raycast.rayCastInBounds(ray, self.dimension, maxDistance=2000)
|
||||
position, face = result
|
||||
@ -472,9 +510,7 @@ class WorldView(QGLWidget):
|
||||
position = (ray.point + ray.vector * defaultDistance).intfloor()
|
||||
face = faces.FaceUp
|
||||
|
||||
self.mouseBlockPos = event.blockPosition = position
|
||||
self.mouseBlockFace = event.blockFace = face
|
||||
self.mouseRay = ray
|
||||
return position, face
|
||||
|
||||
maxFPS = 30
|
||||
|
||||
|
Reference in New Issue
Block a user