瀏覽代碼

update the datamodel structure

Arkady Trestman 16 年之前
父節點
當前提交
c62725336f

+ 50 - 41
direct/src/leveleditor/ObjectPaletteBase.py

@@ -1,12 +1,16 @@
 import copy
 import ObjectGlobals as OG
 
-class ObjectBase:
+class ObjectGen:
+    """ Base class for obj definitions """
+    def __init__(self, name=''):
+       self.name = name
+
+class ObjectBase(ObjectGen):
     """ Base class for obj definitions """
-    
     def __init__(self, name='', createFunction = None, model = None, models= [], anims = [], animNames = [], properties={},
                  movable = True, actor = False):
-        self.name = name
+        ObjectGen.__init__(self, name)
         self.createFunction = createFunction
         self.model = model
         self.models = models[:]
@@ -23,12 +27,14 @@ class ObjectPaletteBase:
     You should write your own ObjectPalette class inheriting this.
     Refer ObjectPalette.py for example.
     """
-    
+
     def __init__(self):
+        self.rootName = '_root'
         self.data = {}
+        self.dataStruct = {}
         self.populate()
 
-    def insertItem(self, item, parentName, data, obj=None):
+    def insertItem(self, item, parentName):
         """
         You can insert item to obj palette tree.
 
@@ -36,53 +42,56 @@ class ObjectPaletteBase:
         If item is a group 'obj' will be None.
         'parentName' is the name of parent under where this item will be inserted.
         'data' is used in recursive searching.
-        
-        """
 
-        if type(data) != dict:
-            return
+        """
+        if type(self.data) != dict:
+           return None
 
         if parentName is None:
-            # when adding a group to the root
-            assert item not in data.keys()
+           parentName = self.rootName
 
-            if obj is None:
-                data[item] = {}
-            else:
-                data[item] = obj
-            return
+        self.dataStruct[item.name] = parentName
+        self.data[item.name] = item
 
-        if parentName in data.keys():
-            if obj is None:
-                data[parentName][item] = {}
-            else:
-                data[parentName][item] = obj
-        else:
-            for key in data.keys():
-                self.insertItem(item, parentName, data[key], obj)
-                
     def add(self, item, parentName = None):
         if type(item) == str:
-            self.insertItem(item, parentName, self.data, None)
+           self.insertItem(ObjectGen(name = item), parentName)
         else:
-            self.insertItem(item.name, parentName, self.data, item)
+           self.insertItem(item, parentName)
 
-    def findItem(self, name, data=None):
-        if data is None:
-            data = self.data
+    def deleteStruct(self, name, deleteItems):
+        try:
+           item = self.data.pop(name)
+           for key in self.dataStruct.keys():
+               if self.dataStruct[key] == name:
+                  node = self.deleteStruct(key, deleteItems)
+                  if node is not None:
+                     deleteItems[key] = node
+           return item
+        except:
+           return None
+        return None
 
-        if type(data) != dict:
-            return None
+    def delete(self, name):
+        try:
+           import pdb;set_trace()
+           deleteItems = {}
+           node = self.deleteStruct(name, deleteItems)
+           if node is not None:
+              deleteItems[name] = node 
+           for key in deleteItems.keys():
+               item = self.dataStruct.pop(key)
+        except:
+           return
+        return
+
+    def findItem(self, name):
+        try:
+            item = self.data[name]
+        except:
+            return None;
+        return item
 
-        if name in data.keys():
-            return data[name]
-        else:
-            for key in data.keys():
-                result = self.findItem(name, data[key])
-                if result:
-                    return result
-            return None
-        
     def populate(self):
         # You should implement this in subclass
         raise NotImplementedError('populate() must be implemented in ObjectPalette.py')

+ 41 - 6
direct/src/leveleditor/ObjectPaletteUI.py

@@ -14,7 +14,7 @@ class ObjectPaletteUI(wx.Panel):
         self.palette = self.editor.objectPalette
         self.tree = wx.TreeCtrl(self)
         root = self.tree.AddRoot('Objects')
-        self.addTreeNodes(root, self.palette.data)
+        self.addTreeNodes(root, self.palette.dataStruct)
 
         sizer = wx.BoxSizer(wx.VERTICAL)
         sizer.Add(self.tree, 1, wx.EXPAND, 0)
@@ -27,13 +27,48 @@ class ObjectPaletteUI(wx.Panel):
         self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.onSelected)
         self.tree.Bind(wx.EVT_TREE_BEGIN_DRAG, self.onBeginDrag)
 
+    def traverse(self, parent, itemText):
+        if itemText == self.tree.GetItemText(parent):
+           return parent
+        item, cookie = self.tree.GetFirstChild(parent)
+        while item:
+              # if the item was found - return it
+              if itemText == self.tree.GetItemText(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, itemText)
+                 if child is not None:
+                    return child
+
+              # continue iteration to the next child
+              item, cookie = self.tree.GetNextChild(parent, cookie)
+        return None
+
+    def addTreeNode(self, itemText, parentItem, items):
+        newItem = wx.TreeItemId
+        parentText = items[itemText]
+        if parentText == self.palette.rootName:
+           newItem = self.tree.AppendItem(parentItem, itemText)
+           self.tree.SetItemPyData(newItem, itemText)
+        else:
+           item = self.traverse(parentItem, parentText)
+           if item is None:
+              item = self.addTreeNode(parentText, parentItem, items)
+
+           newItem = self.tree.AppendItem(item, itemText)
+           self.tree.SetItemPyData(newItem, itemText)
+
+        return newItem
+
     def addTreeNodes(self, parentItem, items):
+        #import pdb;set_trace()
         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])
+            item = self.traverse(parentItem, key)
+            if item is None:
+               newItem = self.addTreeNode(key, parentItem, items)
 
     def onSelected(self, event):
         data = self.tree.GetItemPyData(event.GetItem())

+ 22 - 14
direct/src/leveleditor/ProtoPalette.py

@@ -11,7 +11,7 @@ class ProtoPalette(ObjectPaletteBase):
     def __init__(self):
         ObjectPaletteBase.__init__(self)
 
-    def addItems(self, protoData, parent=None):
+    def addItems(self):
         if type(protoData) == types.DictType:
             for key in protoData.keys():
                 if type(protoData[key]) == types.DictType:
@@ -19,39 +19,47 @@ class ProtoPalette(ObjectPaletteBase):
                     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)
+            self.data = module.protoData
+            self.dataStruct = module.protoDataStruct
         except:
-            print "protoPaletteData doesn't exist"        
+            print "protoPaletteData doesn't exist"
             return
 
-        self.addItems(module.protoData)
+        #self.addItems()
 
-    def saveProtoData(self, f, protoData, depth):
-        tab = ' '*4*depth
+    def saveProtoDataStruct(self, f):
         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)
+        for key in self.dataStruct.keys():
+            f.write("\t'%s':'%s',\n"%(key, self.dataStruct[key]))
+
+    def saveProtoData(self, f):
+        if not f:
+           return
+
+        for key in self.data.keys():
+            if isinstance(self.data[key], ObjectBase):
+               f.write("\t'%s':ObjectBase(name='%s', model='%s', anims=%s, actor=True),\n"%(key, self.data[key].name, self.data[key].model, self.data[key].anims))
             else:
-                f.write("ObjectBase(name='%s', model='%s', anims=%s, actor=True),\n"%(protoData[key].name, protoData[key].model, protoData[key].anims))
+               f.write("\t'%s':ObjectGen(name='%s'),\n"%(key, self.data[key].name))
 
     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)
+            self.saveProtoData(f)
+            f.write("}\n")
+            f.write("protoDataStruct = {\n")
+            self.saveProtoDataStruct(f)
             f.write("}\n")
             f.close()
         except:

+ 78 - 46
direct/src/leveleditor/ProtoPaletteUI.py

@@ -24,11 +24,7 @@ class FileDrop(wx.FileDropTarget):
             itemData = ObjectBase(name=name, model=modelname, actor=True)
             self.editor.protoPalette.add(itemData)
 
-            #import pdb;set_trace()
-            parent = self.editor.ui.protoPaletteUI.tree.GetSelection()
-            if parent is None:
-               parent = self.editor.ui.protoPaletteUI.root
-            newItem = self.editor.ui.protoPaletteUI.tree.AppendItem(parent, name)
+            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)
 
@@ -40,7 +36,6 @@ class ProtoPaletteUITextDrop(wx.TextDropTarget):
     def OnDropText(self, x, y, text):
         self.editor.ui.protoPaletteUI.ChangeHierarchy(text, x, y)
 
-
 class ProtoPaletteUI(wx.Panel):
     def __init__(self, parent, editor):
         wx.Panel.__init__(self, parent)
@@ -48,12 +43,12 @@ class ProtoPaletteUI(wx.Panel):
         self.editor = editor
         self.palette = self.editor.protoPalette
         #self.tree = wx.TreeCtrl(self)
-        self.tree = wx.TreeCtrl(self, id=-1, pos=wx.DefaultPosition, 
+        self.tree = wx.TreeCtrl(self, id=-1, pos=wx.DefaultPosition,
                   size=wx.DefaultSize, style=wx.TR_EDIT_LABELS|wx.TR_DEFAULT_STYLE,
                   validator=wx.DefaultValidator, name="treeCtrl")
         self.rootName = "Proto Objects"
         self.root = self.tree.AddRoot(self.rootName)
-        self.addTreeNodes(self.root, self.palette.data)
+        self.addTreeNodes(self.root, self.palette.dataStruct)
 
         self.opAdd    = "Add Group"
         self.opDelete = "Delete Group"
@@ -82,22 +77,58 @@ class ProtoPaletteUI(wx.Panel):
 
         self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.onSelected)
         self.tree.Bind(wx.EVT_TREE_BEGIN_DRAG, self.onBeginDrag)
+        self.tree.Bind(wx.EVT_KILL_FOCUS , self.OnKillFocus)
 
         self.SetDropTarget(FileDrop(self.editor))
-        self.SetDropTarget(ProtoPaletteUITextDrop(self.editor))
+
+    def traverse(self, parent, itemName):
+        # prevent from traversing into self
+        if itemName == self.tree.GetItemText(parent):
+           return parent
+
+        # 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 itemName == self.tree.GetItemText(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, itemName)
+                 if child is not None:
+                    return child
+
+              # continue iteration to the next child
+              item, cookie = self.tree.GetNextChild(parent, cookie)
+        return None
+
+    def addTreeNode(self, itemText, parentItem, items):
+        newItem = wx.TreeItemId
+        parentText = items[itemText]
+        if parentText == self.palette.rootName:
+           newItem = self.tree.AppendItem(parentItem, itemText)
+           self.tree.SetItemPyData(newItem, itemText)
+        else:
+           item = self.traverse(parentItem, parentText)
+           if item is None:
+              item = self.addTreeNode(parentText, parentItem, items)
+
+           newItem = self.tree.AppendItem(item, itemText)
+           self.tree.SetItemPyData(newItem, itemText)
+
+        return newItem
 
     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])
+            item = self.traverse(parentItem, key)
+            if item is None:
+               self.addTreeNode(key, parentItem, items)
 
     def onSelected(self, event):
         data = self.tree.GetItemPyData(event.GetItem())
-        if data:
-            print data.properties
+        self.SetDropTarget(ProtoPaletteUITextDrop(self.editor))
 
     def onBeginDrag(self, event):
         item = event.GetItem()
@@ -111,6 +142,10 @@ class ProtoPaletteUI(wx.Panel):
             tds.SetData(tdo)
             tds.DoDragDrop(True)
 
+    def OnKillFocus(self, event):
+        print "Leaving protoUI window..."
+        self.SetDropTarget(FileDrop(self.editor))
+
     def menuAppendGenItems(self):
         for item in self.menuItemsGen:
             menuItem = self.popupmenu.Append(-1, item)
@@ -124,7 +159,7 @@ class ProtoPaletteUI(wx.Panel):
     def onShowPopup(self, event):
         pos = event.GetPosition()
         pos = self.ScreenToClient(pos)
-        
+
         for menuItem in self.popupmenu.GetMenuItems():
             self.popupmenu.RemoveItem(menuItem)
 
@@ -156,60 +191,46 @@ class ProtoPaletteUI(wx.Panel):
 
         i = 1
         namestr = "Group%s"%(i)
-        found = self.Traverse(self.root, namestr)
+        found = self.traverse(self.root, namestr)
         while found:
               i = i + 1
               namestr = "Group%s"%(i)
-              found = self.Traverse(self.root, namestr)
+              found = self.traverse(self.root, namestr)
 
         newItem = self.tree.AppendItem(parent, namestr)
+        itemData = ObjectGen(name=namestr)
+        parentName = self.tree.GetItemText(parent)
+        if parentName == self.rootName:
+           self.editor.protoPalette.add(itemData)
+        else:
+           self.editor.protoPalette.add(itemData, parentName)
+        self.tree.SetItemPyData(newItem, itemData)
         #uid = self.editor.objectMgr.genUniqueId()
 
         self.tree.Expand(self.root)
+        self.tree.ScrollTo(newItem)
 
     def DeleteGroup(self):
         item = self.tree.GetSelection()
         itemText = self.tree.GetItemText(item)
         if item is not None and itemText != self.rootName:
            self.tree.Delete(item)
-
-    def Traverse(self, parent, itemName):
-        # prevent from traversing into self
-        if itemName == self.tree.GetItemText(parent):
-           return parent
-
-        # 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 itemName == self.tree.GetItemText(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, itemName)
-                 if child is not None:
-                    return child
-
-              # continue iteration to the next child
-              item, cookie = self.tree.GetNextChild(parent, cookie)
-        return None
+           self.editor.protoPalette.delete(itemText)
 
     def ReParent(self, parent, newParent):
-
         # main loop - iterating over item's children
         item, cookie = self.tree.GetFirstChild(parent)
         while item:
            itemName = self.tree.GetItemText(item)
            itemData = self.tree.GetItemPyData(item)
+
            newItem = self.tree.AppendItem(newParent, itemName)
            self.tree.SetItemPyData(newItem, itemData)
-           
+
            # if an item had children, we need to re-parent them as well
            if self.tree.ItemHasChildren(item):
               # recursing...
-              self.ReParent(item, newItem)
+              self.ReParent(item, newItem, )
 
            # continue iteration to the next child
            item, cookie = self.tree.GetNextChild(parent, cookie)
@@ -217,7 +238,7 @@ class ProtoPaletteUI(wx.Panel):
     def ChangeHierarchy(self, itemName, x, y):
         #import pdb;set_trace()
         parent = self.tree.GetRootItem()
-        item = self.Traverse(parent, itemName)
+        item = self.traverse(parent, itemName)
         if item is None:
            return
 
@@ -227,5 +248,16 @@ class ProtoPaletteUI(wx.Panel):
            if  dragToItem == item:
                return
            newItem = self.tree.AppendItem(dragToItem, itemName)
+
+           itemObj = self.editor.protoPalette.findItem(itemName)
+           if itemObj is not None:
+              dragToItemName = self.tree.GetItemText(dragToItem)
+              
+              # reparenting the data objects...
+              if dragToItemName == self.rootName:
+                 self.editor.protoPalette.add(itemObj)
+              else:
+                 self.editor.protoPalette.add(itemObj, dragToItemName)
+
            self.ReParent(item, newItem)
            self.tree.Delete(item)