mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-18 12:43:44 -04:00
Added [WIP] ProtoPalette
This commit is contained in:
parent
cb35e4d8f9
commit
821656be00
@ -14,6 +14,7 @@ base = ShowBase(False)
|
|||||||
|
|
||||||
from ObjectMgr import *
|
from ObjectMgr import *
|
||||||
from FileMgr import *
|
from FileMgr import *
|
||||||
|
from ProtoPalette import *
|
||||||
|
|
||||||
class LevelEditorBase(DirectObject):
|
class LevelEditorBase(DirectObject):
|
||||||
""" Base Class for Panda3D LevelEditor """
|
""" Base Class for Panda3D LevelEditor """
|
||||||
@ -23,6 +24,7 @@ class LevelEditorBase(DirectObject):
|
|||||||
self.actionEvents = []
|
self.actionEvents = []
|
||||||
self.objectMgr = ObjectMgr(self)
|
self.objectMgr = ObjectMgr(self)
|
||||||
self.fileMgr = FileMgr(self)
|
self.fileMgr = FileMgr(self)
|
||||||
|
self.protoPalette = ProtoPalette()
|
||||||
|
|
||||||
# define your own config file in inherited class
|
# define your own config file in inherited class
|
||||||
self.settingsFile = None
|
self.settingsFile = None
|
||||||
|
@ -11,6 +11,7 @@ from ObjectPropertyUI import *
|
|||||||
from SceneGraphUI import *
|
from SceneGraphUI import *
|
||||||
from LayerEditorUI import *
|
from LayerEditorUI import *
|
||||||
from HotKeyUI import *
|
from HotKeyUI import *
|
||||||
|
from ProtoPaletteUI import *
|
||||||
|
|
||||||
class PandaTextDropTarget(wx.TextDropTarget):
|
class PandaTextDropTarget(wx.TextDropTarget):
|
||||||
def __init__(self, editor):
|
def __init__(self, editor):
|
||||||
@ -95,12 +96,15 @@ class LevelEditorUI(WxAppShell):
|
|||||||
self.perspView = Viewport.makePerspective(self.viewFrame)
|
self.perspView = Viewport.makePerspective(self.viewFrame)
|
||||||
self.viewFrame.AppendWindow(self.perspView)
|
self.viewFrame.AppendWindow(self.perspView)
|
||||||
|
|
||||||
self.leftBarUpPane = wx.Panel(self.leftFrame)
|
self.leftBarUpFrame = wx.SplitterWindow(self.leftFrame, wx.SP_3D | wx.SP_BORDER)
|
||||||
|
self.leftBarUpPane = wx.Panel(self.leftBarUpFrame)
|
||||||
|
self.leftBarMidPane = wx.Panel(self.leftBarUpFrame)
|
||||||
self.leftBarDownPane = wx.Panel(self.leftFrame)
|
self.leftBarDownPane = wx.Panel(self.leftFrame)
|
||||||
self.rightBarUpPane = wx.Panel(self.rightFrame)
|
self.rightBarUpPane = wx.Panel(self.rightFrame)
|
||||||
self.rightBarDownPane = wx.Panel(self.rightFrame)
|
self.rightBarDownPane = wx.Panel(self.rightFrame)
|
||||||
|
|
||||||
self.leftFrame.SplitHorizontally(self.leftBarUpPane, self.leftBarDownPane)
|
self.leftFrame.SplitHorizontally(self.leftBarUpFrame, self.leftBarDownPane)
|
||||||
|
self.leftBarUpFrame.SplitHorizontally(self.leftBarUpPane, self.leftBarMidPane)
|
||||||
self.rightFrame.SplitHorizontally(self.rightBarUpPane, self.rightBarDownPane)
|
self.rightFrame.SplitHorizontally(self.rightBarUpPane, self.rightBarDownPane)
|
||||||
self.mainFrame.SplitVertically(self.leftFrame, self.baseFrame, 200)
|
self.mainFrame.SplitVertically(self.leftFrame, self.baseFrame, 200)
|
||||||
self.baseFrame.SplitVertically(self.viewFrame, self.rightFrame, 600)
|
self.baseFrame.SplitVertically(self.viewFrame, self.rightFrame, 600)
|
||||||
@ -108,6 +112,7 @@ class LevelEditorUI(WxAppShell):
|
|||||||
self.viewFrame.SetDropTarget(PandaTextDropTarget(self.editor))
|
self.viewFrame.SetDropTarget(PandaTextDropTarget(self.editor))
|
||||||
|
|
||||||
self.leftFrame.SetSashGravity(0.5)
|
self.leftFrame.SetSashGravity(0.5)
|
||||||
|
self.leftBarUpFrame.SetSashGravity(0.5)
|
||||||
self.rightFrame.SetSashGravity(0.5)
|
self.rightFrame.SetSashGravity(0.5)
|
||||||
self.baseFrame.SetSashGravity(1.0)
|
self.baseFrame.SetSashGravity(1.0)
|
||||||
|
|
||||||
@ -116,6 +121,7 @@ class LevelEditorUI(WxAppShell):
|
|||||||
self.SetSizer(sizer); self.Layout()
|
self.SetSizer(sizer); self.Layout()
|
||||||
|
|
||||||
self.objectPaletteUI = ObjectPaletteUI(self.leftBarUpPane, self.editor)
|
self.objectPaletteUI = ObjectPaletteUI(self.leftBarUpPane, self.editor)
|
||||||
|
self.protoPaletteUI = ProtoPaletteUI(self.leftBarMidPane, self.editor)
|
||||||
self.objectPropertyUI = ObjectPropertyUI(self.rightBarUpPane, self.editor)
|
self.objectPropertyUI = ObjectPropertyUI(self.rightBarUpPane, self.editor)
|
||||||
self.sceneGraphUI = SceneGraphUI(self.leftBarDownPane, self.editor)
|
self.sceneGraphUI = SceneGraphUI(self.leftBarDownPane, self.editor)
|
||||||
self.layerEditorUI = LayerEditorUI(self.rightBarDownPane, self.editor)
|
self.layerEditorUI = LayerEditorUI(self.rightBarDownPane, self.editor)
|
||||||
@ -190,6 +196,7 @@ class LevelEditorUI(WxAppShell):
|
|||||||
self.sceneGraphUI.showPandaObjectChildren()
|
self.sceneGraphUI.showPandaObjectChildren()
|
||||||
|
|
||||||
def onDestroy(self, evt):
|
def onDestroy(self, evt):
|
||||||
|
self.editor.protoPalette.saveToFile()
|
||||||
self.editor.saveSettings()
|
self.editor.saveSettings()
|
||||||
|
|
||||||
def updateGrids(self, newSize, newSpacing):
|
def updateGrids(self, newSize, newSpacing):
|
||||||
|
@ -7,7 +7,8 @@ OBJ_UID = 0
|
|||||||
OBJ_NP = 1
|
OBJ_NP = 1
|
||||||
OBJ_DEF = 2
|
OBJ_DEF = 2
|
||||||
OBJ_MODEL = 3
|
OBJ_MODEL = 3
|
||||||
OBJ_PROP = 4
|
OBJ_ANIM = 4
|
||||||
|
OBJ_PROP = 5
|
||||||
|
|
||||||
# supported UI types
|
# supported UI types
|
||||||
PROP_UI_ENTRY = '_PropUIEntry'
|
PROP_UI_ENTRY = '_PropUIEntry'
|
||||||
|
@ -68,8 +68,8 @@ class ObjectHandler:
|
|||||||
|
|
||||||
class PandaActor(Actor.Actor):
|
class PandaActor(Actor.Actor):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Actor.Actor.__init__(self, "models/panda-model.egg",{"walk":"models/panda-walk4.egg"})
|
Actor.Actor.__init__(self, "models/panda-model.egg")
|
||||||
self.setScale(0.005)
|
self.setScale(0.005)
|
||||||
self.loop("walk")
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ Defines ObjectMgr
|
|||||||
import os, time, wx
|
import os, time, wx
|
||||||
|
|
||||||
from direct.task import Task
|
from direct.task import Task
|
||||||
|
from direct.actor.Actor import Actor
|
||||||
from pandac.PandaModules import *
|
from pandac.PandaModules import *
|
||||||
|
|
||||||
import ObjectGlobals as OG
|
import ObjectGlobals as OG
|
||||||
@ -63,6 +64,8 @@ class ObjectMgr:
|
|||||||
parent = render
|
parent = render
|
||||||
|
|
||||||
objDef = self.editor.objectPalette.findItem(typeName)
|
objDef = self.editor.objectPalette.findItem(typeName)
|
||||||
|
if objDef is None:
|
||||||
|
objDef = self.editor.protoPalette.findItem(typeName)
|
||||||
newobj = None
|
newobj = None
|
||||||
if objDef and type(objDef) != dict:
|
if objDef and type(objDef) != dict:
|
||||||
if objDef.createFunction:
|
if objDef.createFunction:
|
||||||
@ -78,12 +81,29 @@ class ObjectMgr:
|
|||||||
|
|
||||||
# create new obj using function and keyword arguments defined in ObjectPalette
|
# create new obj using function and keyword arguments defined in ObjectPalette
|
||||||
newobj = func(**funcArgs)
|
newobj = func(**funcArgs)
|
||||||
|
elif objDef.actor:
|
||||||
|
if model is None:
|
||||||
|
model = objDef.model
|
||||||
|
try:
|
||||||
|
newobj = Actor(model)
|
||||||
|
except:
|
||||||
|
newobj = Actor(Filename.fromOsSpecific(model).getFullpath())
|
||||||
elif objDef.model is not None:
|
elif objDef.model is not None:
|
||||||
# since this obj is simple model let's load the model
|
# since this obj is simple model let's load the model
|
||||||
if model is None:
|
if model is None:
|
||||||
model = objDef.model
|
model = objDef.model
|
||||||
|
try:
|
||||||
newobj = loader.loadModel(model)
|
newobj = loader.loadModel(model)
|
||||||
|
except:
|
||||||
|
newobj = loader.loadModel(Filename.fromOsSpecific(model).getFullpath())
|
||||||
|
|
||||||
|
anim = ''
|
||||||
|
if len(objDef.anims) > 0:
|
||||||
|
anim = objDef.anims[0]
|
||||||
|
# load new anim
|
||||||
|
animName = os.path.basename(anim)
|
||||||
|
newAnim = newobj.loadAnims({animName:anim})
|
||||||
|
newobj.loop(animName)
|
||||||
|
|
||||||
if newobj is None:
|
if newobj is None:
|
||||||
return None
|
return None
|
||||||
@ -102,7 +122,7 @@ class ObjectMgr:
|
|||||||
properties[key] = objDef.properties[key][OG.PROP_DEFAULT]
|
properties[key] = objDef.properties[key][OG.PROP_DEFAULT]
|
||||||
|
|
||||||
# insert obj data to main repository
|
# insert obj data to main repository
|
||||||
self.objects[uid] = [uid, newobj, objDef, model, properties]
|
self.objects[uid] = [uid, newobj, objDef, model, anim, properties]
|
||||||
self.npIndex[NodePath(newobj)] = uid
|
self.npIndex[NodePath(newobj)] = uid
|
||||||
|
|
||||||
if fSelectObject:
|
if fSelectObject:
|
||||||
@ -270,6 +290,19 @@ class ObjectMgr:
|
|||||||
if fSelectObject:
|
if fSelectObject:
|
||||||
base.direct.select(newobj)
|
base.direct.select(newobj)
|
||||||
|
|
||||||
|
def updateObjectAnim(self, anim, obj, fSelectObject=True):
|
||||||
|
""" replace object's anim """
|
||||||
|
if obj[OG.OBJ_ANIM] != anim:
|
||||||
|
base.direct.deselectAll()
|
||||||
|
objNP = obj[OG.OBJ_NP]
|
||||||
|
|
||||||
|
# load new anim
|
||||||
|
animName = os.path.basename(anim)
|
||||||
|
newAnim = objNP.loadAnims({animName:anim})
|
||||||
|
objNP.loop(animName)
|
||||||
|
obj[OG.OBJ_ANIM] = anim
|
||||||
|
if fSelectObject:
|
||||||
|
base.direct.select(objNP)
|
||||||
|
|
||||||
def updateObjectModelFromUI(self, event, obj):
|
def updateObjectModelFromUI(self, event, obj):
|
||||||
""" replace object's model with one selected from UI """
|
""" replace object's model with one selected from UI """
|
||||||
@ -277,6 +310,12 @@ class ObjectMgr:
|
|||||||
if model is not None:
|
if model is not None:
|
||||||
self.updateObjectModel(model, obj)
|
self.updateObjectModel(model, obj)
|
||||||
|
|
||||||
|
def updateObjectAnimFromUI(self, event, obj):
|
||||||
|
""" replace object's anim with one selected from UI """
|
||||||
|
anim = event.GetString()
|
||||||
|
if anim is not None:
|
||||||
|
self.updateObjectAnim(anim, obj)
|
||||||
|
|
||||||
def updateObjectProperty(self, event, obj, propName):
|
def updateObjectProperty(self, event, obj, propName):
|
||||||
"""
|
"""
|
||||||
When an obj's property is updated in UI,
|
When an obj's property is updated in UI,
|
||||||
|
@ -101,6 +101,7 @@ class ObjectPalette(ObjectPaletteBase):
|
|||||||
self.add('Animal')
|
self.add('Animal')
|
||||||
self.add(ObjectBase(name='Panda',
|
self.add(ObjectBase(name='Panda',
|
||||||
createFunction = ('.createPanda', {}),
|
createFunction = ('.createPanda', {}),
|
||||||
|
anims = ['models/panda-walk4.egg',],
|
||||||
properties = {}),
|
properties = {}),
|
||||||
'Animal')
|
'Animal')
|
||||||
|
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
|
import copy
|
||||||
import ObjectGlobals as OG
|
import ObjectGlobals as OG
|
||||||
|
|
||||||
class ObjectBase:
|
class ObjectBase:
|
||||||
""" Base class for obj definitions """
|
""" Base class for obj definitions """
|
||||||
|
|
||||||
def __init__(self, name='', createFunction = None, model = None, models= [], properties={},
|
def __init__(self, name='', createFunction = None, model = None, models= [], anims = [], properties={},
|
||||||
movable = True):
|
movable = True, actor = False):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.createFunction = createFunction
|
self.createFunction = createFunction
|
||||||
self.model = model
|
self.model = model
|
||||||
self.models = models
|
self.models = models[:]
|
||||||
self.properties = properties
|
self.anims = anims[:]
|
||||||
|
self.properties = copy.deepcopy(properties)
|
||||||
self.movable = movable
|
self.movable = movable
|
||||||
|
self.actor = actor
|
||||||
|
|
||||||
class ObjectPaletteBase:
|
class ObjectPaletteBase:
|
||||||
"""
|
"""
|
||||||
|
@ -2,12 +2,39 @@
|
|||||||
UI for object property control
|
UI for object property control
|
||||||
"""
|
"""
|
||||||
import wx
|
import wx
|
||||||
|
import os
|
||||||
|
|
||||||
from wx.lib.scrolledpanel import ScrolledPanel
|
from wx.lib.scrolledpanel import ScrolledPanel
|
||||||
|
|
||||||
from direct.wxwidgets.WxSlider import *
|
from direct.wxwidgets.WxSlider import *
|
||||||
|
from pandac.PandaModules import *
|
||||||
import ObjectGlobals as OG
|
import ObjectGlobals as OG
|
||||||
|
|
||||||
|
class AnimFileDrop(wx.FileDropTarget):
|
||||||
|
def __init__(self, editor):
|
||||||
|
wx.FileDropTarget.__init__(self)
|
||||||
|
self.editor = editor
|
||||||
|
|
||||||
|
def OnDropFiles(self, x, y, filenames):
|
||||||
|
obj = self.editor.objectMgr.findObjectByNodePath(base.direct.selected.last)
|
||||||
|
if obj is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
objDef = obj[OG.OBJ_DEF]
|
||||||
|
if not objDef.actor:
|
||||||
|
return
|
||||||
|
|
||||||
|
objNP = obj[OG.OBJ_NP]
|
||||||
|
|
||||||
|
for filename in filenames:
|
||||||
|
name = os.path.basename(filename)
|
||||||
|
animName = Filename.fromOsSpecific(filename).getFullpath()
|
||||||
|
if animName not in objDef.anims:
|
||||||
|
objDef.anims.append(animName)
|
||||||
|
|
||||||
|
objNP.loadAnims({name:animName})
|
||||||
|
objNP.loop(name)
|
||||||
|
obj[OG.OBJ_ANIM] = animName
|
||||||
|
self.editor.ui.objectPropertyUI.updateProps(obj)
|
||||||
|
|
||||||
class ObjectPropUI(wx.Panel):
|
class ObjectPropUI(wx.Panel):
|
||||||
"""
|
"""
|
||||||
@ -124,6 +151,8 @@ class ObjectPropertyUI(ScrolledPanel):
|
|||||||
parentSizer.Add(self, 1, wx.EXPAND, 0)
|
parentSizer.Add(self, 1, wx.EXPAND, 0)
|
||||||
parent.SetSizer(parentSizer); parent.Layout()
|
parent.SetSizer(parentSizer); parent.Layout()
|
||||||
|
|
||||||
|
self.SetDropTarget(AnimFileDrop(self.editor))
|
||||||
|
|
||||||
def clearPropUI(self):
|
def clearPropUI(self):
|
||||||
sizer = self.GetSizer()
|
sizer = self.GetSizer()
|
||||||
if sizer is not None:
|
if sizer is not None:
|
||||||
@ -175,6 +204,14 @@ class ObjectPropertyUI(ScrolledPanel):
|
|||||||
self.editor.objectMgr.onLeaveObjectPropUI,
|
self.editor.objectMgr.onLeaveObjectPropUI,
|
||||||
lambda p0=None, p1=obj: self.editor.objectMgr.updateObjectModelFromUI(p0, p1))
|
lambda p0=None, p1=obj: self.editor.objectMgr.updateObjectModelFromUI(p0, p1))
|
||||||
|
|
||||||
|
if len(objDef.anims) > 0:
|
||||||
|
propUI = ObjectPropUICombo(self.propPane, 'anim', obj[OG.OBJ_ANIM], objDef.anims)
|
||||||
|
sizer.Add(propUI)
|
||||||
|
|
||||||
|
propUI.bindFunc(self.editor.objectMgr.onEnterObjectPropUI,
|
||||||
|
self.editor.objectMgr.onLeaveObjectPropUI,
|
||||||
|
lambda p0=None, p1=obj: self.editor.objectMgr.updateObjectAnimFromUI(p0, p1))
|
||||||
|
|
||||||
for key in objDef.properties.keys():
|
for key in objDef.properties.keys():
|
||||||
propDef = objDef.properties[key]
|
propDef = objDef.properties[key]
|
||||||
propType = propDef[OG.PROP_TYPE]
|
propType = propDef[OG.PROP_TYPE]
|
||||||
|
58
direct/src/leveleditor/ProtoPalette.py
Executable file
58
direct/src/leveleditor/ProtoPalette.py
Executable file
@ -0,0 +1,58 @@
|
|||||||
|
"""
|
||||||
|
Palette for Prototyping
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import imp
|
||||||
|
import types
|
||||||
|
|
||||||
|
from ObjectPaletteBase import *
|
||||||
|
|
||||||
|
class ProtoPalette(ObjectPaletteBase):
|
||||||
|
def __init__(self):
|
||||||
|
ObjectPaletteBase.__init__(self)
|
||||||
|
|
||||||
|
def addItems(self, protoData, parent=None):
|
||||||
|
if type(protoData) == types.DictType:
|
||||||
|
for key in protoData.keys():
|
||||||
|
if type(protoData[key]) == types.DictType:
|
||||||
|
self.add(key, parent)
|
||||||
|
self.addItems(protoData[key], key)
|
||||||
|
else:
|
||||||
|
self.add(protoData[key], parent)
|
||||||
|
|
||||||
|
def populate(self):
|
||||||
|
dirname = os.path.dirname(__file__)
|
||||||
|
moduleName = 'protoPaletteData'
|
||||||
|
try:
|
||||||
|
file, pathname, description = imp.find_module(moduleName, [dirname])
|
||||||
|
module = imp.load_module(moduleName, file, pathname, description)
|
||||||
|
except:
|
||||||
|
print "protoPaletteData doesn't exist"
|
||||||
|
return
|
||||||
|
|
||||||
|
self.addItems(module.protoData)
|
||||||
|
|
||||||
|
def saveProtoData(self, f, protoData, depth):
|
||||||
|
tab = ' '*4*depth
|
||||||
|
if not f:
|
||||||
|
return
|
||||||
|
|
||||||
|
for key in protoData.keys():
|
||||||
|
f.write("%s'%s' : "%(tab, key))
|
||||||
|
if type(protoData[key]) == types.DictType:
|
||||||
|
f.write("{\n")
|
||||||
|
self.saveProtoData(f, protoData[key], depth + 1)
|
||||||
|
f.write("%s},\n"%tab)
|
||||||
|
else:
|
||||||
|
f.write("ObjectBase(name='%s', model='%s', anims=%s, actor=True),\n"%(protoData[key].name, protoData[key].model, protoData[key].anims))
|
||||||
|
|
||||||
|
def saveToFile(self):
|
||||||
|
try:
|
||||||
|
f = open(os.path.dirname(__file__) + '/protoPaletteData.py', 'w')
|
||||||
|
f.write("from direct.leveleditor.ObjectPaletteBase import *\n\n")
|
||||||
|
f.write("protoData = {\n")
|
||||||
|
self.saveProtoData(f, self.data, 1)
|
||||||
|
f.write("}\n")
|
||||||
|
f.close()
|
||||||
|
except:
|
||||||
|
pass
|
71
direct/src/leveleditor/ProtoPaletteUI.py
Executable file
71
direct/src/leveleditor/ProtoPaletteUI.py
Executable file
@ -0,0 +1,71 @@
|
|||||||
|
"""
|
||||||
|
Defines ProtoPalette tree UI
|
||||||
|
"""
|
||||||
|
import wx
|
||||||
|
import os
|
||||||
|
import cPickle as pickl
|
||||||
|
from pandac.PandaModules import *
|
||||||
|
from ObjectPaletteBase import *
|
||||||
|
|
||||||
|
class FileDrop(wx.FileDropTarget):
|
||||||
|
def __init__(self, editor):
|
||||||
|
wx.FileDropTarget.__init__(self)
|
||||||
|
self.editor = editor
|
||||||
|
|
||||||
|
def OnDropFiles(self, x, y, filenames):
|
||||||
|
for filename in filenames:
|
||||||
|
name = os.path.basename(filename)
|
||||||
|
modelname = Filename.fromOsSpecific(filename).getFullpath()
|
||||||
|
itemData = ObjectBase(name=name, model=modelname, actor=True)
|
||||||
|
base.le.protoPalette.add(itemData)
|
||||||
|
newItem = self.editor.ui.protoPaletteUI.tree.AppendItem(self.editor.ui.protoPaletteUI.root, name)
|
||||||
|
self.editor.ui.protoPaletteUI.tree.SetItemPyData(newItem, itemData)
|
||||||
|
self.editor.ui.protoPaletteUI.tree.ScrollTo(newItem)
|
||||||
|
|
||||||
|
class ProtoPaletteUI(wx.Panel):
|
||||||
|
def __init__(self, parent, editor):
|
||||||
|
wx.Panel.__init__(self, parent)
|
||||||
|
|
||||||
|
self.editor = editor
|
||||||
|
self.palette = self.editor.protoPalette
|
||||||
|
self.tree = wx.TreeCtrl(self)
|
||||||
|
self.root = self.tree.AddRoot('Proto Objects')
|
||||||
|
self.addTreeNodes(self.root, self.palette.data)
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.onSelected)
|
||||||
|
self.tree.Bind(wx.EVT_TREE_BEGIN_DRAG, self.onBeginDrag)
|
||||||
|
|
||||||
|
self.SetDropTarget(FileDrop(self.editor))
|
||||||
|
|
||||||
|
def addTreeNodes(self, parentItem, items):
|
||||||
|
for key in items.keys():
|
||||||
|
newItem = self.tree.AppendItem(parentItem, key)
|
||||||
|
if type(items[key]) == dict:
|
||||||
|
self.addTreeNodes(newItem, items[key])
|
||||||
|
else:
|
||||||
|
self.tree.SetItemPyData(newItem, items[key])
|
||||||
|
|
||||||
|
def onSelected(self, event):
|
||||||
|
data = self.tree.GetItemPyData(event.GetItem())
|
||||||
|
if data:
|
||||||
|
print data.properties
|
||||||
|
|
||||||
|
def onBeginDrag(self, event):
|
||||||
|
item = event.GetItem()
|
||||||
|
|
||||||
|
if item != self.tree.GetRootItem(): # prevent dragging root item
|
||||||
|
text = self.tree.GetItemText(item)
|
||||||
|
print "Starting drag'n'drop with %s..." % repr(text)
|
||||||
|
|
||||||
|
tdo = wx.TextDataObject(text)
|
||||||
|
tds = wx.DropSource(self.tree)
|
||||||
|
tds.SetData(tdo)
|
||||||
|
tds.DoDragDrop(True)
|
Loading…
x
Reference in New Issue
Block a user