瀏覽代碼

update the datamodel structure

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

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

@@ -1,12 +1,16 @@
 import copy
 import copy
 import ObjectGlobals as OG
 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 """
     """ Base class for obj definitions """
-    
     def __init__(self, name='', createFunction = None, model = None, models= [], anims = [], animNames = [], properties={},
     def __init__(self, name='', createFunction = None, model = None, models= [], anims = [], animNames = [], properties={},
                  movable = True, actor = False):
                  movable = True, actor = False):
-        self.name = name
+        ObjectGen.__init__(self, name)
         self.createFunction = createFunction
         self.createFunction = createFunction
         self.model = model
         self.model = model
         self.models = models[:]
         self.models = models[:]
@@ -23,12 +27,14 @@ class ObjectPaletteBase:
     You should write your own ObjectPalette class inheriting this.
     You should write your own ObjectPalette class inheriting this.
     Refer ObjectPalette.py for example.
     Refer ObjectPalette.py for example.
     """
     """
-    
+
     def __init__(self):
     def __init__(self):
+        self.rootName = '_root'
         self.data = {}
         self.data = {}
+        self.dataStruct = {}
         self.populate()
         self.populate()
 
 
-    def insertItem(self, item, parentName, data, obj=None):
+    def insertItem(self, item, parentName):
         """
         """
         You can insert item to obj palette tree.
         You can insert item to obj palette tree.
 
 
@@ -36,53 +42,56 @@ class ObjectPaletteBase:
         If item is a group 'obj' will be None.
         If item is a group 'obj' will be None.
         'parentName' is the name of parent under where this item will be inserted.
         'parentName' is the name of parent under where this item will be inserted.
         'data' is used in recursive searching.
         'data' is used in recursive searching.
-        
-        """
 
 
-        if type(data) != dict:
-            return
+        """
+        if type(self.data) != dict:
+           return None
 
 
         if parentName is 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):
     def add(self, item, parentName = None):
         if type(item) == str:
         if type(item) == str:
-            self.insertItem(item, parentName, self.data, None)
+           self.insertItem(ObjectGen(name = item), parentName)
         else:
         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):
     def populate(self):
         # You should implement this in subclass
         # You should implement this in subclass
         raise NotImplementedError('populate() must be implemented in ObjectPalette.py')
         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.palette = self.editor.objectPalette
         self.tree = wx.TreeCtrl(self)
         self.tree = wx.TreeCtrl(self)
         root = self.tree.AddRoot('Objects')
         root = self.tree.AddRoot('Objects')
-        self.addTreeNodes(root, self.palette.data)
+        self.addTreeNodes(root, self.palette.dataStruct)
 
 
         sizer = wx.BoxSizer(wx.VERTICAL)
         sizer = wx.BoxSizer(wx.VERTICAL)
         sizer.Add(self.tree, 1, wx.EXPAND, 0)
         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_SEL_CHANGED, self.onSelected)
         self.tree.Bind(wx.EVT_TREE_BEGIN_DRAG, self.onBeginDrag)
         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):
     def addTreeNodes(self, parentItem, items):
+        #import pdb;set_trace()
         for key in items.keys():
         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):
     def onSelected(self, event):
         data = self.tree.GetItemPyData(event.GetItem())
         data = self.tree.GetItemPyData(event.GetItem())

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

@@ -11,7 +11,7 @@ class ProtoPalette(ObjectPaletteBase):
     def __init__(self):
     def __init__(self):
         ObjectPaletteBase.__init__(self)
         ObjectPaletteBase.__init__(self)
 
 
-    def addItems(self, protoData, parent=None):
+    def addItems(self):
         if type(protoData) == types.DictType:
         if type(protoData) == types.DictType:
             for key in protoData.keys():
             for key in protoData.keys():
                 if type(protoData[key]) == types.DictType:
                 if type(protoData[key]) == types.DictType:
@@ -19,39 +19,47 @@ class ProtoPalette(ObjectPaletteBase):
                     self.addItems(protoData[key], key)
                     self.addItems(protoData[key], key)
                 else:
                 else:
                     self.add(protoData[key], parent)
                     self.add(protoData[key], parent)
-                    
+
     def populate(self):
     def populate(self):
         dirname = os.path.dirname(__file__)
         dirname = os.path.dirname(__file__)
         moduleName = 'protoPaletteData'
         moduleName = 'protoPaletteData'
         try:
         try:
             file, pathname, description = imp.find_module(moduleName, [dirname])
             file, pathname, description = imp.find_module(moduleName, [dirname])
             module = imp.load_module(moduleName, file, pathname, description)
             module = imp.load_module(moduleName, file, pathname, description)
+            self.data = module.protoData
+            self.dataStruct = module.protoDataStruct
         except:
         except:
-            print "protoPaletteData doesn't exist"        
+            print "protoPaletteData doesn't exist"
             return
             return
 
 
-        self.addItems(module.protoData)
+        #self.addItems()
 
 
-    def saveProtoData(self, f, protoData, depth):
-        tab = ' '*4*depth
+    def saveProtoDataStruct(self, f):
         if not f:
         if not f:
             return
             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:
             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):
     def saveToFile(self):
         try:
         try:
             f = open(os.path.dirname(__file__) + '/protoPaletteData.py', 'w')
             f = open(os.path.dirname(__file__) + '/protoPaletteData.py', 'w')
             f.write("from direct.leveleditor.ObjectPaletteBase import *\n\n")
             f.write("from direct.leveleditor.ObjectPaletteBase import *\n\n")
             f.write("protoData = {\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.write("}\n")
             f.close()
             f.close()
         except:
         except:

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

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