mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
Added popup menu to sceneGraphUI
This commit is contained in:
parent
1df1eb4f3e
commit
5f662a84ef
@ -173,6 +173,79 @@ class ActionDeleteObj(ActionBase):
|
||||
self.hierarchy = {}
|
||||
self.objInfos = {}
|
||||
|
||||
class ActionDeleteObjById(ActionBase):
|
||||
""" Action class for deleting object """
|
||||
|
||||
def __init__(self, editor, uid):
|
||||
self.editor = editor
|
||||
function = self.editor.objectMgr.removeObjectById
|
||||
self.uid = uid
|
||||
ActionBase.__init__(self, function, self.uid)
|
||||
self.hierarchy = {}
|
||||
self.objInfos = {}
|
||||
self.objTransforms = {}
|
||||
|
||||
def saveStatus(self):
|
||||
def saveObjStatus(uid_np, isUID=False):
|
||||
if isUID:
|
||||
obj = self.editor.objectMgr.findObjectById(uid_np)
|
||||
else:
|
||||
obj = self.editor.objectMgr.findObjectByNodePath(uid_np)
|
||||
if obj:
|
||||
uid = obj[OG.OBJ_UID]
|
||||
objNP = obj[OG.OBJ_NP]
|
||||
self.objInfos[uid] = obj
|
||||
self.objTransforms[uid] = objNP.getMat()
|
||||
parentNP = objNP.getParent()
|
||||
if parentNP == render:
|
||||
self.hierarchy[uid] = None
|
||||
else:
|
||||
parentObj = self.editor.objectMgr.findObjectByNodePath(parentNP)
|
||||
if parentObj:
|
||||
self.hierarchy[uid] = parentObj[OG.OBJ_UID]
|
||||
|
||||
for child in objNP.getChildren():
|
||||
if child.hasTag('OBJRoot'):
|
||||
saveObjStatus(child)
|
||||
|
||||
saveObjStatus(self.uid, True)
|
||||
|
||||
def undo(self):
|
||||
if len(self.hierarchy.keys()) == 0 or\
|
||||
len(self.objInfos.keys()) == 0:
|
||||
print "Can't undo this deletion"
|
||||
else:
|
||||
print "Undo: deleteObjectById"
|
||||
def restoreObject(uid, parentNP):
|
||||
obj = self.objInfos[uid]
|
||||
objDef = obj[OG.OBJ_DEF]
|
||||
objModel = obj[OG.OBJ_MODEL]
|
||||
objProp = obj[OG.OBJ_PROP]
|
||||
objRGBA = obj[OG.OBJ_RGBA]
|
||||
objNP = self.editor.objectMgr.addNewObject(objDef.name,
|
||||
uid,
|
||||
obj[OG.OBJ_MODEL],
|
||||
parentNP)
|
||||
self.editor.objectMgr.updateObjectColor(objRGBA[0], objRGBA[1], objRGBA[2], objRGBA[3], uid)
|
||||
self.editor.objectMgr.updateObjectProperties(uid, objProp)
|
||||
objNP.setMat(self.objTransforms[uid])
|
||||
|
||||
while (len(self.hierarchy.keys()) > 0):
|
||||
for uid in self.hierarchy.keys():
|
||||
if self.hierarchy[uid] is None:
|
||||
parentNP = None
|
||||
restoreObject(uid, parentNP)
|
||||
del self.hierarchy[uid]
|
||||
else:
|
||||
parentObj = self.editor.objectMgr.findObjectById(self.hierarchy[uid])
|
||||
if parentObj:
|
||||
parentNP = parentObj[OG.OBJ_NP]
|
||||
restoreObject(uid, parentNP)
|
||||
del self.hierarchy[uid]
|
||||
|
||||
self.hierarchy = {}
|
||||
self.objInfos = {}
|
||||
|
||||
class ActionChangeHierarchy(ActionBase):
|
||||
""" Action class for changing Scene Graph Hierarchy """
|
||||
|
||||
|
@ -153,6 +153,20 @@ class ObjectMgr:
|
||||
self.editor.fNeedToSave = True
|
||||
return newobj
|
||||
|
||||
def removeObjectById(self, uid):
|
||||
obj = self.findObjectById(uid)
|
||||
nodePath = obj[OG.OBJ_NP]
|
||||
del self.objects[uid]
|
||||
del self.npIndex[nodePath]
|
||||
|
||||
# remove children also
|
||||
for child in nodePath.getChildren():
|
||||
if child.hasTag('OBJRoot'):
|
||||
self.removeObjectByNodePath(child)
|
||||
nodePath.remove()
|
||||
|
||||
self.editor.fNeedToSave = True
|
||||
|
||||
def removeObjectByNodePath(self, nodePath):
|
||||
uid = self.npIndex.get(nodePath)
|
||||
if uid:
|
||||
|
@ -1,283 +1,11 @@
|
||||
"""
|
||||
Defines Scene Graph tree UI
|
||||
"""
|
||||
import wx
|
||||
import cPickle as pickle
|
||||
from pandac.PandaModules import *
|
||||
from ActionMgr import *
|
||||
|
||||
import ObjectGlobals as OG
|
||||
|
||||
class SceneGraphUIDropTarget(wx.TextDropTarget):
|
||||
def __init__(self, editor):
|
||||
print "in SceneGraphUIDropTarget::init..."
|
||||
wx.TextDropTarget.__init__(self)
|
||||
self.editor = editor
|
||||
|
||||
def OnDropText(self, x, y, text):
|
||||
print "in SceneGraphUIDropTarget::OnDropText..."
|
||||
self.editor.ui.sceneGraphUI.changeHierarchy(text, x, y)
|
||||
from SceneGraphUIBase import *
|
||||
|
||||
class SceneGraphUI(wx.Panel):
|
||||
class SceneGraphUI(SceneGraphUIBase):
|
||||
def __init__(self, parent, editor):
|
||||
wx.Panel.__init__(self, parent)
|
||||
SceneGraphUIBase.__init__(self, parent, editor)
|
||||
|
||||
self.editor = editor
|
||||
self.tree = wx.TreeCtrl(self, id=-1, pos=wx.DefaultPosition,
|
||||
size=wx.DefaultSize, style=wx.TR_MULTIPLE|wx.TR_DEFAULT_STYLE,
|
||||
validator=wx.DefaultValidator, name="treeCtrl")
|
||||
self.root = self.tree.AddRoot('render')
|
||||
self.tree.SetItemPyData(self.root, "render")
|
||||
|
||||
self.shouldShowPandaObjChildren = False
|
||||
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
sizer.Add(self.tree, 1, wx.EXPAND, 0)
|
||||
self.SetSizer(sizer); self.Layout()
|
||||
|
||||
parentSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
parentSizer.Add(self, 1, wx.EXPAND, 0)
|
||||
parent.SetSizer(parentSizer); parent.Layout()
|
||||
|
||||
parent.SetDropTarget(SceneGraphUIDropTarget(self.editor))
|
||||
|
||||
self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.onSelected)
|
||||
self.tree.Bind(wx.EVT_TREE_BEGIN_DRAG, self.onBeginDrag)
|
||||
|
||||
def reset(self):
|
||||
#import pdb;set_trace()
|
||||
itemList = list()
|
||||
item, cookie = self.tree.GetFirstChild(self.root)
|
||||
while item:
|
||||
itemList.append(item)
|
||||
item, cookie = self.tree.GetNextChild(self.root, cookie)
|
||||
|
||||
for item in itemList:
|
||||
self.tree.Delete(item)
|
||||
|
||||
def traversePandaObjects(self, parent, objNodePath):
|
||||
itemId = self.tree.GetItemPyData(parent)
|
||||
i = 0
|
||||
for child in objNodePath.getChildren():
|
||||
namestr = "%s.%s"%(child.node().getType(), child.node().getName())
|
||||
newItem = self.tree.PrependItem(parent, namestr)
|
||||
newItemId = "%s.%s"%(itemId, i)
|
||||
self.tree.SetItemPyData(newItem, newItemId)
|
||||
|
||||
# recursing...
|
||||
self.traversePandaObjects(newItem, child)
|
||||
i = i + 1
|
||||
|
||||
def addPandaObjectChildren(self, parent):
|
||||
# first, find Panda Object's NodePath of the item
|
||||
itemId = self.tree.GetItemPyData(parent)
|
||||
if itemId == "render":
|
||||
return
|
||||
obj = self.editor.objectMgr.findObjectById(itemId)
|
||||
if obj is None:
|
||||
return
|
||||
|
||||
objNodePath = obj[OG.OBJ_NP]
|
||||
self.traversePandaObjects(parent, objNodePath)
|
||||
|
||||
item, cookie = self.tree.GetFirstChild(parent)
|
||||
while item:
|
||||
# recursing...
|
||||
self.addPandaObjectChildren(item)
|
||||
item, cookie = self.tree.GetNextChild(parent, cookie)
|
||||
|
||||
def removePandaObjectChildren(self, parent):
|
||||
# first, find Panda Object's NodePath of the item
|
||||
itemId = self.tree.GetItemPyData(parent)
|
||||
if itemId == "render":
|
||||
return
|
||||
obj = self.editor.objectMgr.findObjectById(itemId)
|
||||
if obj is None:
|
||||
self.tree.Delete(parent)
|
||||
return
|
||||
item, cookie = self.tree.GetFirstChild(parent)
|
||||
while item:
|
||||
# recurse...
|
||||
itemToRemove = item
|
||||
# continue iteration to the next child
|
||||
item, cookie = self.tree.GetNextChild(parent, cookie)
|
||||
self.removePandaObjectChildren(itemToRemove)
|
||||
|
||||
def add(self, item):
|
||||
#import pdb;pdb.set_trace()
|
||||
if item is None:
|
||||
return
|
||||
obj = self.editor.objectMgr.findObjectByNodePath(NodePath(item))
|
||||
if obj is None:
|
||||
return
|
||||
|
||||
parentNodePath = obj[OG.OBJ_NP].getParent()
|
||||
parentObj = self.editor.objectMgr.findObjectByNodePath(parentNodePath)
|
||||
|
||||
#import pdb;pdb.set_trace()
|
||||
if parentObj is None:
|
||||
parent = self.root
|
||||
else:
|
||||
parent = self.traverse(self.root, parentObj[OG.OBJ_UID])
|
||||
|
||||
namestr = "%s_%s"%(obj[OG.OBJ_DEF].name, obj[OG.OBJ_UID])
|
||||
newItem = self.tree.AppendItem(parent, namestr)
|
||||
self.tree.SetItemPyData(newItem, obj[OG.OBJ_UID])
|
||||
|
||||
# adding children of PandaObj
|
||||
if self.shouldShowPandaObjChildren:
|
||||
self.addPandaObjectChildren(newItem)
|
||||
self.tree.Expand(self.root)
|
||||
|
||||
def traverse(self, parent, itemId):
|
||||
# prevent from traversing into self
|
||||
if itemId == self.tree.GetItemPyData(parent):
|
||||
return None
|
||||
|
||||
# main loop - serching for an item with an itemId
|
||||
item, cookie = self.tree.GetFirstChild(parent)
|
||||
while item:
|
||||
# if the item was found - return it
|
||||
if itemId == self.tree.GetItemPyData(item):
|
||||
return item
|
||||
|
||||
# the tem was not found - checking if it has children
|
||||
if self.tree.ItemHasChildren(item):
|
||||
# item has children - delving into it
|
||||
child = self.traverse(item, itemId)
|
||||
if child is not None:
|
||||
return child
|
||||
|
||||
# continue iteration to the next child
|
||||
item, cookie = self.tree.GetNextChild(parent, cookie)
|
||||
return None
|
||||
|
||||
def reParentTree(self, parent, newParent):
|
||||
# main loop - iterating over item's children
|
||||
item, cookie = self.tree.GetFirstChild(parent)
|
||||
while item:
|
||||
data = self.tree.GetItemText(item)
|
||||
itemId = self.tree.GetItemPyData(item)
|
||||
newItem = self.tree.AppendItem(newParent, data)
|
||||
self.tree.SetItemPyData(newItem, itemId)
|
||||
|
||||
# if an item had children, we need to re-parent them as well
|
||||
if self.tree.ItemHasChildren(item):
|
||||
# recursing...
|
||||
self.reParentTree(item, newItem)
|
||||
|
||||
# continue iteration to the next child
|
||||
item, cookie = self.tree.GetNextChild(parent, cookie)
|
||||
|
||||
def reParentData(self, parent, child):
|
||||
child.wrtReparentTo(parent)
|
||||
|
||||
def reParent(self, oldParent, newParent, child):
|
||||
if newParent is None:
|
||||
newParent = self.root
|
||||
itemId = self.tree.GetItemPyData(oldParent)
|
||||
newItem = self.tree.AppendItem(newParent, child)
|
||||
self.tree.SetItemPyData(newItem, itemId)
|
||||
self.reParentTree(oldParent, newItem)
|
||||
|
||||
obj = self.editor.objectMgr.findObjectById(itemId)
|
||||
itemId = self.tree.GetItemPyData(newParent)
|
||||
if itemId != "render":
|
||||
newParentObj = self.editor.objectMgr.findObjectById(itemId)
|
||||
self.reParentData(newParentObj[OG.OBJ_NP], obj[OG.OBJ_NP])
|
||||
else:
|
||||
self.reParentData(render, obj[OG.OBJ_NP])
|
||||
|
||||
self.tree.Delete(oldParent)
|
||||
if self.shouldShowPandaObjChildren:
|
||||
self.removePandaObjectChildren(oldParent)
|
||||
self.addPandaObjectChildren(oldParent)
|
||||
self.removePandaObjectChildren(newParent)
|
||||
self.addPandaObjectChildren(newpParent)
|
||||
|
||||
def isChildOrGrandChild(self, parent, child):
|
||||
childId = self.tree.GetItemPyData(child)
|
||||
return self.traverse(parent, childId)
|
||||
|
||||
def changeHierarchy(self, data, x, y):
|
||||
itemText = data.split('_')
|
||||
itemId = itemText[-1] # uid is the last token
|
||||
item = self.traverse(self.tree.GetRootItem(), itemId)
|
||||
if item is None:
|
||||
return
|
||||
|
||||
dragToItem, flags = self.tree.HitTest(wx.Point(x, y))
|
||||
if dragToItem.IsOk():
|
||||
# prevent draging into itself
|
||||
if dragToItem == item:
|
||||
return
|
||||
if self.isChildOrGrandChild(item, dragToItem):
|
||||
return
|
||||
|
||||
# undo function setup...
|
||||
action = ActionChangeHierarchy(self.editor, self.tree.GetItemPyData(self.tree.GetItemParent(item)), self.tree.GetItemPyData(item), self.tree.GetItemPyData(dragToItem), data)
|
||||
self.editor.actionMgr.push(action)
|
||||
action()
|
||||
|
||||
def parent(self, oldParentId, newParentId, childName):
|
||||
oldParent = self.traverse(self.tree.GetRootItem(), oldParentId)
|
||||
newParent = self.traverse(self.tree.GetRootItem(), newParentId)
|
||||
self.reParent(oldParent, newParent, childName)
|
||||
|
||||
def showPandaObjectChildren(self):
|
||||
itemList = list()
|
||||
self.shouldShowPandaObjChildren = not self.shouldShowPandaObjChildren
|
||||
|
||||
item, cookie = self.tree.GetFirstChild(self.root)
|
||||
while item:
|
||||
itemList.append(item)
|
||||
item, cookie = self.tree.GetNextChild(self.root, cookie)
|
||||
|
||||
#import pdb;set_trace()
|
||||
for item in itemList:
|
||||
if self.shouldShowPandaObjChildren:
|
||||
self.addPandaObjectChildren(item)
|
||||
else:
|
||||
self.removePandaObjectChildren(item)
|
||||
# continue iteration to the next child
|
||||
|
||||
def delete(self, itemId):
|
||||
item = self.traverse(self.root, itemId)
|
||||
if item:
|
||||
self.tree.Delete(item)
|
||||
|
||||
def select(self, itemId):
|
||||
item = self.traverse(self.root, itemId)
|
||||
if item:
|
||||
if not self.tree.IsSelected(item):
|
||||
self.tree.SelectItem(item)
|
||||
|
||||
def deSelect(self, itemId):
|
||||
item = self.traverse(self.root, itemId)
|
||||
if item is not None:
|
||||
self.tree.UnselectItem(item)
|
||||
|
||||
def onSelected(self, event):
|
||||
item = event.GetItem();
|
||||
if item:
|
||||
itemId = self.tree.GetItemPyData(item)
|
||||
if itemId:
|
||||
obj = self.editor.objectMgr.findObjectById(itemId);
|
||||
if obj:
|
||||
selections = self.tree.GetSelections()
|
||||
if len(selections) > 1:
|
||||
base.direct.select(obj[OG.OBJ_NP], fMultiSelect = 1, fLEPane = 0)
|
||||
else:
|
||||
base.direct.select(obj[OG.OBJ_NP], fMultiSelect = 0, fLEPane = 0)
|
||||
|
||||
def onBeginDrag(self, event):
|
||||
item = event.GetItem()
|
||||
|
||||
if item != self.tree.GetRootItem(): # prevent dragging root item
|
||||
text = self.tree.GetItemText(item)
|
||||
print "Starting SceneGraphUI drag'n'drop with %s..." % repr(text)
|
||||
|
||||
tdo = wx.TextDataObject(text)
|
||||
tds = wx.DropSource(self.tree)
|
||||
tds.SetData(tdo)
|
||||
tds.DoDragDrop(True)
|
||||
def populateExtraMenu(self):
|
||||
pass
|
||||
|
321
direct/src/leveleditor/SceneGraphUIBase.py
Executable file
321
direct/src/leveleditor/SceneGraphUIBase.py
Executable file
@ -0,0 +1,321 @@
|
||||
"""
|
||||
Defines Scene Graph tree UI Base
|
||||
"""
|
||||
import wx
|
||||
import cPickle as pickle
|
||||
from pandac.PandaModules import *
|
||||
from ActionMgr import *
|
||||
|
||||
import ObjectGlobals as OG
|
||||
|
||||
class SceneGraphUIDropTarget(wx.TextDropTarget):
|
||||
def __init__(self, editor):
|
||||
print "in SceneGraphUIDropTarget::init..."
|
||||
wx.TextDropTarget.__init__(self)
|
||||
self.editor = editor
|
||||
|
||||
def OnDropText(self, x, y, text):
|
||||
print "in SceneGraphUIDropTarget::OnDropText..."
|
||||
self.editor.ui.sceneGraphUI.changeHierarchy(text, x, y)
|
||||
|
||||
class SceneGraphUIBase(wx.Panel):
|
||||
def __init__(self, parent, editor):
|
||||
wx.Panel.__init__(self, parent)
|
||||
|
||||
self.editor = editor
|
||||
self.tree = wx.TreeCtrl(self, id=-1, pos=wx.DefaultPosition,
|
||||
size=wx.DefaultSize, style=wx.TR_MULTIPLE|wx.TR_DEFAULT_STYLE,
|
||||
validator=wx.DefaultValidator, name="treeCtrl")
|
||||
self.root = self.tree.AddRoot('render')
|
||||
self.tree.SetItemPyData(self.root, "render")
|
||||
|
||||
self.shouldShowPandaObjChildren = False
|
||||
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
sizer.Add(self.tree, 1, wx.EXPAND, 0)
|
||||
self.SetSizer(sizer); self.Layout()
|
||||
|
||||
parentSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
parentSizer.Add(self, 1, wx.EXPAND, 0)
|
||||
parent.SetSizer(parentSizer); parent.Layout()
|
||||
|
||||
parent.SetDropTarget(SceneGraphUIDropTarget(self.editor))
|
||||
|
||||
self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.onSelected)
|
||||
self.tree.Bind(wx.EVT_TREE_BEGIN_DRAG, self.onBeginDrag)
|
||||
|
||||
self.currObj = None
|
||||
self.menu = wx.Menu()
|
||||
self.populateMenu()
|
||||
self.Bind(wx.EVT_CONTEXT_MENU, self.onShowPopup)
|
||||
|
||||
def reset(self):
|
||||
#import pdb;set_trace()
|
||||
itemList = list()
|
||||
item, cookie = self.tree.GetFirstChild(self.root)
|
||||
while item:
|
||||
itemList.append(item)
|
||||
item, cookie = self.tree.GetNextChild(self.root, cookie)
|
||||
|
||||
for item in itemList:
|
||||
self.tree.Delete(item)
|
||||
|
||||
def traversePandaObjects(self, parent, objNodePath):
|
||||
itemId = self.tree.GetItemPyData(parent)
|
||||
i = 0
|
||||
for child in objNodePath.getChildren():
|
||||
namestr = "%s.%s"%(child.node().getType(), child.node().getName())
|
||||
newItem = self.tree.PrependItem(parent, namestr)
|
||||
newItemId = "%s.%s"%(itemId, i)
|
||||
self.tree.SetItemPyData(newItem, newItemId)
|
||||
|
||||
# recursing...
|
||||
self.traversePandaObjects(newItem, child)
|
||||
i = i + 1
|
||||
|
||||
def addPandaObjectChildren(self, parent):
|
||||
# first, find Panda Object's NodePath of the item
|
||||
itemId = self.tree.GetItemPyData(parent)
|
||||
if itemId == "render":
|
||||
return
|
||||
obj = self.editor.objectMgr.findObjectById(itemId)
|
||||
if obj is None:
|
||||
return
|
||||
|
||||
objNodePath = obj[OG.OBJ_NP]
|
||||
self.traversePandaObjects(parent, objNodePath)
|
||||
|
||||
item, cookie = self.tree.GetFirstChild(parent)
|
||||
while item:
|
||||
# recursing...
|
||||
self.addPandaObjectChildren(item)
|
||||
item, cookie = self.tree.GetNextChild(parent, cookie)
|
||||
|
||||
def removePandaObjectChildren(self, parent):
|
||||
# first, find Panda Object's NodePath of the item
|
||||
itemId = self.tree.GetItemPyData(parent)
|
||||
if itemId == "render":
|
||||
return
|
||||
obj = self.editor.objectMgr.findObjectById(itemId)
|
||||
if obj is None:
|
||||
self.tree.Delete(parent)
|
||||
return
|
||||
item, cookie = self.tree.GetFirstChild(parent)
|
||||
while item:
|
||||
# recurse...
|
||||
itemToRemove = item
|
||||
# continue iteration to the next child
|
||||
item, cookie = self.tree.GetNextChild(parent, cookie)
|
||||
self.removePandaObjectChildren(itemToRemove)
|
||||
|
||||
def add(self, item):
|
||||
#import pdb;pdb.set_trace()
|
||||
if item is None:
|
||||
return
|
||||
obj = self.editor.objectMgr.findObjectByNodePath(NodePath(item))
|
||||
if obj is None:
|
||||
return
|
||||
|
||||
parentNodePath = obj[OG.OBJ_NP].getParent()
|
||||
parentObj = self.editor.objectMgr.findObjectByNodePath(parentNodePath)
|
||||
|
||||
#import pdb;pdb.set_trace()
|
||||
if parentObj is None:
|
||||
parent = self.root
|
||||
else:
|
||||
parent = self.traverse(self.root, parentObj[OG.OBJ_UID])
|
||||
|
||||
namestr = "%s_%s"%(obj[OG.OBJ_DEF].name, obj[OG.OBJ_UID])
|
||||
newItem = self.tree.AppendItem(parent, namestr)
|
||||
self.tree.SetItemPyData(newItem, obj[OG.OBJ_UID])
|
||||
|
||||
# adding children of PandaObj
|
||||
if self.shouldShowPandaObjChildren:
|
||||
self.addPandaObjectChildren(newItem)
|
||||
self.tree.Expand(self.root)
|
||||
|
||||
def traverse(self, parent, itemId):
|
||||
# prevent from traversing into self
|
||||
if itemId == self.tree.GetItemPyData(parent):
|
||||
return None
|
||||
|
||||
# main loop - serching for an item with an itemId
|
||||
item, cookie = self.tree.GetFirstChild(parent)
|
||||
while item:
|
||||
# if the item was found - return it
|
||||
if itemId == self.tree.GetItemPyData(item):
|
||||
return item
|
||||
|
||||
# the tem was not found - checking if it has children
|
||||
if self.tree.ItemHasChildren(item):
|
||||
# item has children - delving into it
|
||||
child = self.traverse(item, itemId)
|
||||
if child is not None:
|
||||
return child
|
||||
|
||||
# continue iteration to the next child
|
||||
item, cookie = self.tree.GetNextChild(parent, cookie)
|
||||
return None
|
||||
|
||||
def reParentTree(self, parent, newParent):
|
||||
# main loop - iterating over item's children
|
||||
item, cookie = self.tree.GetFirstChild(parent)
|
||||
while item:
|
||||
data = self.tree.GetItemText(item)
|
||||
itemId = self.tree.GetItemPyData(item)
|
||||
newItem = self.tree.AppendItem(newParent, data)
|
||||
self.tree.SetItemPyData(newItem, itemId)
|
||||
|
||||
# if an item had children, we need to re-parent them as well
|
||||
if self.tree.ItemHasChildren(item):
|
||||
# recursing...
|
||||
self.reParentTree(item, newItem)
|
||||
|
||||
# continue iteration to the next child
|
||||
item, cookie = self.tree.GetNextChild(parent, cookie)
|
||||
|
||||
def reParentData(self, parent, child):
|
||||
child.wrtReparentTo(parent)
|
||||
|
||||
def reParent(self, oldParent, newParent, child):
|
||||
if newParent is None:
|
||||
newParent = self.root
|
||||
itemId = self.tree.GetItemPyData(oldParent)
|
||||
newItem = self.tree.AppendItem(newParent, child)
|
||||
self.tree.SetItemPyData(newItem, itemId)
|
||||
self.reParentTree(oldParent, newItem)
|
||||
|
||||
obj = self.editor.objectMgr.findObjectById(itemId)
|
||||
itemId = self.tree.GetItemPyData(newParent)
|
||||
if itemId != "render":
|
||||
newParentObj = self.editor.objectMgr.findObjectById(itemId)
|
||||
self.reParentData(newParentObj[OG.OBJ_NP], obj[OG.OBJ_NP])
|
||||
else:
|
||||
self.reParentData(render, obj[OG.OBJ_NP])
|
||||
|
||||
self.tree.Delete(oldParent)
|
||||
if self.shouldShowPandaObjChildren:
|
||||
self.removePandaObjectChildren(oldParent)
|
||||
self.addPandaObjectChildren(oldParent)
|
||||
self.removePandaObjectChildren(newParent)
|
||||
self.addPandaObjectChildren(newpParent)
|
||||
|
||||
def isChildOrGrandChild(self, parent, child):
|
||||
childId = self.tree.GetItemPyData(child)
|
||||
return self.traverse(parent, childId)
|
||||
|
||||
def changeHierarchy(self, data, x, y):
|
||||
itemText = data.split('_')
|
||||
itemId = itemText[-1] # uid is the last token
|
||||
item = self.traverse(self.tree.GetRootItem(), itemId)
|
||||
if item is None:
|
||||
return
|
||||
|
||||
dragToItem, flags = self.tree.HitTest(wx.Point(x, y))
|
||||
if dragToItem.IsOk():
|
||||
# prevent draging into itself
|
||||
if dragToItem == item:
|
||||
return
|
||||
if self.isChildOrGrandChild(item, dragToItem):
|
||||
return
|
||||
|
||||
# undo function setup...
|
||||
action = ActionChangeHierarchy(self.editor, self.tree.GetItemPyData(self.tree.GetItemParent(item)), self.tree.GetItemPyData(item), self.tree.GetItemPyData(dragToItem), data)
|
||||
self.editor.actionMgr.push(action)
|
||||
action()
|
||||
|
||||
def parent(self, oldParentId, newParentId, childName):
|
||||
oldParent = self.traverse(self.tree.GetRootItem(), oldParentId)
|
||||
newParent = self.traverse(self.tree.GetRootItem(), newParentId)
|
||||
self.reParent(oldParent, newParent, childName)
|
||||
|
||||
def showPandaObjectChildren(self):
|
||||
itemList = list()
|
||||
self.shouldShowPandaObjChildren = not self.shouldShowPandaObjChildren
|
||||
|
||||
item, cookie = self.tree.GetFirstChild(self.root)
|
||||
while item:
|
||||
itemList.append(item)
|
||||
item, cookie = self.tree.GetNextChild(self.root, cookie)
|
||||
|
||||
#import pdb;set_trace()
|
||||
for item in itemList:
|
||||
if self.shouldShowPandaObjChildren:
|
||||
self.addPandaObjectChildren(item)
|
||||
else:
|
||||
self.removePandaObjectChildren(item)
|
||||
# continue iteration to the next child
|
||||
|
||||
def delete(self, itemId):
|
||||
item = self.traverse(self.root, itemId)
|
||||
if item:
|
||||
self.tree.Delete(item)
|
||||
|
||||
def select(self, itemId):
|
||||
item = self.traverse(self.root, itemId)
|
||||
if item:
|
||||
if not self.tree.IsSelected(item):
|
||||
self.tree.SelectItem(item)
|
||||
|
||||
def deSelect(self, itemId):
|
||||
item = self.traverse(self.root, itemId)
|
||||
if item is not None:
|
||||
self.tree.UnselectItem(item)
|
||||
|
||||
def onSelected(self, event):
|
||||
item = event.GetItem();
|
||||
if item:
|
||||
itemId = self.tree.GetItemPyData(item)
|
||||
if itemId:
|
||||
obj = self.editor.objectMgr.findObjectById(itemId);
|
||||
if obj:
|
||||
selections = self.tree.GetSelections()
|
||||
if len(selections) > 1:
|
||||
base.direct.select(obj[OG.OBJ_NP], fMultiSelect = 1, fLEPane = 0)
|
||||
else:
|
||||
base.direct.select(obj[OG.OBJ_NP], fMultiSelect = 0, fLEPane = 0)
|
||||
|
||||
def onBeginDrag(self, event):
|
||||
item = event.GetItem()
|
||||
|
||||
if item != self.tree.GetRootItem(): # prevent dragging root item
|
||||
text = self.tree.GetItemText(item)
|
||||
print "Starting SceneGraphUI drag'n'drop with %s..." % repr(text)
|
||||
|
||||
tdo = wx.TextDataObject(text)
|
||||
tds = wx.DropSource(self.tree)
|
||||
tds.SetData(tdo)
|
||||
tds.DoDragDrop(True)
|
||||
|
||||
def onShowPopup(self, event):
|
||||
pos = event.GetPosition()
|
||||
pos = self.ScreenToClient(pos)
|
||||
|
||||
item, flags = self.tree.HitTest(pos)
|
||||
if not item.IsOk():
|
||||
return
|
||||
itemId = self.tree.GetItemPyData(item)
|
||||
if not itemId:
|
||||
return
|
||||
self.currObj = self.editor.objectMgr.findObjectById(itemId);
|
||||
if self.currObj:
|
||||
self.PopupMenu(self.menu, pos)
|
||||
|
||||
def populateMenu(self):
|
||||
menuitem = self.menu.Append(-1, 'Delete')
|
||||
self.Bind(wx.EVT_MENU, self.onDelete, menuitem)
|
||||
self.populateExtraMenu()
|
||||
|
||||
def populateExtraMenu(self):
|
||||
# You should implement this in subclass
|
||||
raise NotImplementedError('populateExtraMenu() must be implemented in subclass')
|
||||
|
||||
def onDelete(self, evt=None):
|
||||
if self.currObj is None:
|
||||
return
|
||||
|
||||
uid = self.currObj[OG.OBJ_UID]
|
||||
action = ActionDeleteObjById(self.editor, uid)
|
||||
self.editor.actionMgr.push(action)
|
||||
action()
|
||||
self.delete(uid)
|
Loading…
x
Reference in New Issue
Block a user