Ver Fonte

More work on Inspector

Marko Pintera há 11 anos atrás
pai
commit
3540e822e7

+ 59 - 30
Inspector.txt

@@ -29,7 +29,6 @@ Get rid of the CamelotFramework namespace
 Undocking a window wont remove the tabbed title bar
 Undocking a window wont remove the tabbed title bar
 While dragging an undocked window, dropping it over the main window (not over dock overlays) will not restore it
 While dragging an undocked window, dropping it over the main window (not over dock overlays) will not restore it
 
 
-REFACTOR c++ GUI a bit:
  - GameObjectField
  - GameObjectField
    - When dragging over GameObjectField cursor needs to change depending whether drop will be accepted or not
    - When dragging over GameObjectField cursor needs to change depending whether drop will be accepted or not
    - How will I limit it to just certain component types?
    - How will I limit it to just certain component types?
@@ -40,30 +39,24 @@ Make a common class for ScriptGUIElement as they all share:
 Add InsertElement to GUILayout
 Add InsertElement to GUILayout
 
 
 -------------
 -------------
-Implementation order:
- - Component foldout
- - Color picker modular window
-   - Possibly a generic ModularWindow class
-   - EditorUtility::showColorPicker
- - GameObject/resource field
- - Matrix fields
- - Refactor C# GUI
- - Basic InspectableObject and basic Inspector that open Inspector window, display SceneManager base fields and a list of components
- - Per-component generic and custom inspectors
-
--------------
-IMPORTANT:
- - I should probably consider making each Component part of the inspector its own separate GUIWidget, otherwise I wont
-   be able to use multiple GUIAreas in the Inspectors, which is fairly limiting.
-     - Each has a separate EditorGUI instance?
-
-
-TOMORROW:
- - InspectableObject calls a C++ method which gets all SerializableFields, and C++ in turn
-   generates a list of InspectableFields
-     - They should have a type, name, and get/set methods
-
-Dont forget to implement SceneObject.GetComponents
+Get rid of EditorGUI and GUI classes and instead make them a single class GUIPanel
+ - IMPORANT. Consider replacing InspectorArea with GUIPanels (they internally in C++ are just clipped GUIAreas). This way I have a generic system
+
+IMPLEMENT:
+EditorWindow
+ WindowResized
+ Internal_GetWidth
+ Internal_GetHeight
+ Internal_CreateGUIPanel
+GUIPanel
+ Internal_SetArea
+ Internal_Destroy
+SceneObject
+ GetComponents
+GUIArea
+ SetArea
+Refactor existing ScriptGUI and ScriptEditorGUI and add support for GUIPanel instead
+Remove support for resizable areas
 
 
 Tab indexes
 Tab indexes
  - EditorFields should have SetNextField method that allow you to set tab order directly
  - EditorFields should have SetNextField method that allow you to set tab order directly
@@ -98,10 +91,46 @@ UndoRedo
     - but when I click outside maybe I just want to undo to the previous state before I even focused on that text field
     - but when I click outside maybe I just want to undo to the previous state before I even focused on that text field
       - plus it doesn't make sense for example to undo a text field if I'm currently focusing on something in scene
       - plus it doesn't make sense for example to undo a text field if I'm currently focusing on something in scene
 
 
-IMPLEMENTATION
- - Add a Foldout GUI type and its C# version
- - Attempt to display a list of Components on a SceneObject just by using the foldouts
+---------------------------
+
+SerializableObject(object obj)
+ - GetFields()
+
+SerializableField
+ - Type
+ - GetInt/SetInt
+ - GetString/SetString
+ - GetObject/SetObject
+ - GetArray/SetArray
+ - etc.
+
+SerializableArray
+ - GetInt(arrayIdx)/SetInt(arrayIdx)
+ - GetKVP(arrayIdx)/SetKVP(arrayIdx)
+ - etc.
+
+SerializableDictionary
+ - GetInt(key)/SetInt(key)
+ - GetKVP(key)/SetKVP(key)
+ - etc.
+
+----------------
+
+InspectableObject(SerializableObject)
+ - Internally creates a list of InspectorFields (does not initialize any GUI elements)
+ - CreateGUI(GUILayout) <- populates the GUI layout with every InspectorField
+     - For nested objects it creates child layouts and indents them appropriately
+
+InspectorField(SerializableField)
+ - CreateGUI(GUILayout) <- Inserts the corresponding GUI element into the layout
+
+-------------------
 
 
- - Add basic IntField and hook it up with InspectableField (get/set methods and everything)
+When creating a custom inspector, where will I store InspectorFields? Require user to store them?
+ - I guess. If user doesn't store them they get destructed and upon destruction they remove their GUI element from the layout.
+ - But what happens when Destroy is called? GUI elements get destroyed as normal and InspectorField will need to check for that, in which case it will essentially do nothing.
 
 
- - Add Multi-rank array, List & Dictionary types
+How do I refresh Inspector fields if source object changes?
+ - Keep all InspectorFields in InspectorManager class, which will call Update on it regularily
+ - If InspectorField GUI elements were destroyed then Update will show a warning
+ - Otherwise you are required to call destroy on an InspectorField to properly remove it

+ 0 - 17
MBansheeEditor/EditorGUI.cs

@@ -1,17 +0,0 @@
-using System.Runtime.CompilerServices;
-using BansheeEngine;
-
-namespace BansheeEditor
-{
-    public sealed class EditorGUI : GUIBase
-    {
-        internal EditorGUI(EditorWindow parentWindow)
-        {
-            Internal_CreateInstance(this, parentWindow);
-            Initialize();
-        }
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_CreateInstance(EditorGUI instance, EditorWindow parentWindow);
-    }
-}

+ 14 - 3
MBansheeEditor/EditorWindow.cs

@@ -9,7 +9,7 @@ namespace BansheeEditor
         internal int width { get { return Internal_GetWidth(); } }
         internal int width { get { return Internal_GetWidth(); } }
         internal int height { get { return Internal_GetHeight(); } }
         internal int height { get { return Internal_GetHeight(); } }
 
 
-        protected EditorGUI GUI;
+        protected GUIPanel GUI;
 
 
         public static EditorWindow OpenWindow<T>() where T : EditorWindow
         public static EditorWindow OpenWindow<T>() where T : EditorWindow
         {
         {
@@ -18,17 +18,28 @@ namespace BansheeEditor
 
 
         protected EditorWindow()
         protected EditorWindow()
         {
         {
-            GUI = new EditorGUI(this);
+            GUI = CreatePanel(0, 0, width, height);
         }
         }
 
 
         protected virtual void WindowResized(int width, int height)
         protected virtual void WindowResized(int width, int height)
         {
         {
-            
+            GUI.SetArea(0, 0, width, height);
+        }
+
+        internal GUIPanel CreatePanel(int x, int y, int width, int height)
+        {
+            GUIPanel newPanel = Internal_CreateGUIPanel(mCachedPtr);
+            newPanel.SetArea(x, y, width, height);
+
+            return newPanel;
         }
         }
 
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern EditorWindow Internal_CreateOrGetInstance(string ns, string typeName);
         private static extern EditorWindow Internal_CreateOrGetInstance(string ns, string typeName);
 
 
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern GUIPanel Internal_CreateGUIPanel(IntPtr nativeInstance);
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern int Internal_GetWidth();
         private static extern int Internal_GetWidth();
 
 

+ 0 - 11
MBansheeEditor/Inspector/EditorField.cs

@@ -1,11 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace BansheeEditor
-{
-    public class EditorField
-    {
-    }
-}

+ 3 - 1
MBansheeEditor/Inspector/GenericInspector.cs

@@ -10,7 +10,9 @@ namespace BansheeEditor
     {
     {
         internal override void Refresh()
         internal override void Refresh()
         {
         {
-            throw new NotImplementedException();
+            InspectableObject obj = new InspectableObject(serializableObject);
+
+            obj.CreateGUI(GUI.layout);
         }
         }
 
 
         internal override int GetOptimalHeight()
         internal override int GetOptimalHeight()

+ 0 - 15
MBansheeEditor/Inspector/InspectableArray.cs

@@ -1,15 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace BansheeEditor
-{
-    public class InspectableArray : InspectableObjectBase
-    {
-        public InspectableArray(Array array)
-        {
-            // TODO - Populate "fields" array
-        }
-    }
-}

+ 0 - 65
MBansheeEditor/Inspector/InspectableField.cs

@@ -1,65 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.CompilerServices;
-using System.Text;
-
-namespace BansheeEditor
-{
-    public class InspectableField
-    {
-        public enum Type
-        {
-            Int,
-            Float,
-            Bool,
-            String,
-            Color,
-            Vector2,
-            Vector3,
-            Vector4,
-            GameObjectRef,
-            ResourceRef,
-            Object,
-            Array,
-            List,
-            Dictionary
-        }
-
-        private EditorField guiField; // TODO - This will likely be a specific EditorField type, not a generic base one
-        private InspectableObjectBase parent;
-        private Type type;
-
-        // TODO - Add getters/setters for all fields
-        
-        // TODO - Make sure "guiField" is created properly
-
-        public void Refresh()
-        {
-            // TODO - Update "guiField" from the field value by calling "Internal_Get*" method
-        }
-
-        public void Destroy()
-        {
-            // TODO - Called by the parent
-            //  Release "guiField"
-        }
-
-        private void OnValueChangedInt32(Int32 newValue)
-        {
-            // TODO - Callback from "guiField"
-            //  Need separate methods for all types
-            //  Call "Internal_Set*" method to update the actual field
-            //  Register an "Undo" action
-        }
-
-        // TODO - I need a set of these methods for all possible "Type"s
-        //  Internally they should use SerializableField methods for setting/getting values
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_SetInt32(IntPtr nativeInstance, Int32 value);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern Int32 Internal_GetInt32(IntPtr nativeInstance);
-    }
-}

+ 97 - 3
MBansheeEditor/Inspector/InspectableObject.cs

@@ -2,14 +2,108 @@
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Text;
 using System.Text;
+using BansheeEngine;
 
 
 namespace BansheeEditor
 namespace BansheeEditor
 {
 {
-    public class InspectableObject : InspectableObjectBase
+    public sealed class InspectableObject
     {
     {
-        public InspectableObject(object obj)
+        private const int IndentAmount = 15;
+
+        private SerializableObject serializableObject;
+        private SerializableArray serializableArray;
+
+        public InspectableObject(SerializableObject serializableObject)
+        {
+            this.serializableObject = serializableObject;
+        }
+
+        public InspectableObject(SerializableArray serializableArray)
+        {
+            this.serializableArray = serializableArray;
+        }
+
+        public void CreateGUI(GUILayout layout)
+        {
+            if (serializableObject != null)
+            {
+                foreach (var field in serializableObject.fields)
+                {
+                    CreateGUI(layout, field.Name, field.Type, field.GetValue());
+                }
+            }
+            else if (serializableArray != null)
+            {
+                // TODO - Handle multi-rank arrays
+
+                int length = serializableArray.GetDimension(0);
+                for (int i = 0; i < length; i++)
+                {
+                    CreateGUI(layout, i.ToString(), serializableArray.ElementType, serializableArray.GetValue(i));
+                }
+            }
+
+            // TODO - Handle List & Dictionary
+        }
+
+        private void CreateGUI(GUILayout layout, string name, SerializableField.FieldType type, SerializableValue value)
+        {
+            switch (type)
+            {
+                case SerializableField.FieldType.Object:
+                    CreateComplexField(layout, name, type, value);
+                    break;
+                case SerializableField.FieldType.Array:
+                    goto case SerializableField.FieldType.Object;
+                case SerializableField.FieldType.List:
+                    goto case SerializableField.FieldType.Object;
+                case SerializableField.FieldType.Dictionary:
+                    goto case SerializableField.FieldType.Object;
+                default:
+                    CreatePrimitiveField(layout, name, type, value);
+                    break;
+            }
+        }
+
+        private void CreatePrimitiveField(GUILayout layout, string name, SerializableField.FieldType type, SerializableValue value)
         {
         {
-            // TODO - Populate "fields" array
+            layout.AddElement(new GUILabel(name)); // TODO - Use an IntEditorField, or others for other types
+        }
+
+        private void CreateComplexField(GUILayout layout, string name, SerializableField.FieldType type, SerializableValue value)
+        {
+            layout.AddElement(new GUILabel(name)); // TODO - Add foldout and hook up its callbacks
+
+            GUILayout childLayout = layout.AddLayoutX();
+            childLayout.AddSpace(IndentAmount);
+
+            GUILayout childContent = childLayout.AddLayoutY();
+
+            switch (type)
+            {
+                case SerializableField.FieldType.Object:
+                    {
+                        SerializableObject childObj = new SerializableObject(value.GetValue<object>());
+                        InspectableObject childInspectable = new InspectableObject(childObj);
+                        childInspectable.CreateGUI(childContent);
+                    }
+                    break;
+                case SerializableField.FieldType.Array:
+                    {
+                        SerializableArray childArr = new SerializableArray(value.GetValue<object>());
+                        InspectableObject childInspectable = new InspectableObject(childArr);
+                        childInspectable.CreateGUI(childContent);
+                    }
+                    break;
+                case SerializableField.FieldType.List:
+                    // TODO
+                    break;
+                case SerializableField.FieldType.Dictionary:
+                    // TODO
+                    break;
+                default:
+                    throw new Exception("Invalid complex field type.");
+            }
         }
         }
     }
     }
 }
 }

+ 0 - 44
MBansheeEditor/Inspector/InspectableObjectBase.cs

@@ -1,44 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace BansheeEditor
-{
-    public abstract class InspectableObjectBase
-    {
-        private bool _isExpanded = false;
-        private InspectableField[] _fields;
-
-        public bool isExpanded { get { return _isExpanded; } }
-        public InspectableField[] fields { get { return _fields; } }
-
-        public void Expand()
-        {
-            // TODO - Show all child "fields"
-            //  Reposition all visual child elements
-            //  Re-do tab indexes
-            _isExpanded = true;
-        }
-
-        public void Collapse()
-        {
-            // TODO - Hide all child "fields"
-            //  Reposition all visual child elements
-            //  Re-do tab indexes
-            _isExpanded = false;
-        }
-
-        public void Refresh()
-        {
-            for (int i = 0; i < fields.Length; i++)
-                fields[i].Refresh();
-        }
-
-        public void Destroy()
-        {
-            for (int i = 0; i < fields.Length; i++)
-                fields[i].Destroy();
-        }
-    }
-}

+ 0 - 76
MBansheeEditor/Inspector/InspectorArea.cs

@@ -1,76 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using BansheeEngine;
-
-namespace BansheeEditor
-{
-    public class InspectorArea
-    {
-        private GUIArea guiArea;
-        private Inspector owner;
-
-        private int parentX, parentY, parentWidth, parentHeight;
-        private int x, y, width, height;
-        private short depth;
-
-        public GUILayout layout
-        {
-            get { return guiArea.layout; }
-        }
-
-        internal InspectorArea(Inspector owner, EditorGUI parentGUI)
-        {
-            this.owner = owner;
-            guiArea = parentGUI.AddArea(0, 0, 0, 0);
-        }
-
-        public void Destroy()
-        {
-            owner.Remove(this);
-
-            guiArea.Destroy();
-        }
-
-        public void SetArea(int x, int y, int width, int height, short depth)
-        {
-            this.x = x;
-            this.y = y;
-            this.width = width;
-            this.height = height;
-            this.depth = depth;
-
-            UpdateGUIArea();
-        }
-
-        internal void SetParentArea(int x, int y, int width, int height)
-        {
-            parentX = x;
-            parentY = y;
-            parentWidth = width;
-            parentHeight = height;
-
-            UpdateGUIArea();
-        }
-
-        private void UpdateGUIArea()
-        {
-            int guiX = parentX + x;
-            int guiY = parentY + y;
-
-            int guiRight = guiX + width;
-            guiRight = MathEx.Min(guiRight, parentX + parentWidth);
-
-            int guiWidth = MathEx.Max(0, guiRight - guiX);
-
-            int guiBottom = guiY + height;
-            guiBottom = MathEx.Min(guiBottom, parentY + parentHeight);
-
-            int guiHeight = MathEx.Max(0, guiBottom - guiY);
-
-            guiArea.SetArea(guiX, guiY, guiWidth, guiHeight, depth);
-        }
-    }
-}

+ 44 - 0
MBansheeEditor/Inspector/SerializableArray.cs

@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BansheeEditor
+{
+    public sealed class SerializableArray
+    {
+        public SerializableArray(object obj)
+        {
+            // TODO - Initialize the array - handle it properly in case obj isn't a valid array
+        }
+
+        public SerializableField.FieldType ElementType;
+        private int[] dimensions;
+        private int rank;
+
+        public int GetDimension(int rank)
+        {
+            return dimensions[rank];
+        }
+
+        public int Rank
+        {
+            get { return rank;  }
+        }
+
+        public SerializableValue GetValue(int id)
+        {
+            return null; // TODO - Return actual SerializableValue
+        }
+
+        // TODO - Add getters/setters for all fields
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetInt32(IntPtr nativeInstance, int arrayIdx, Int32 value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern Int32 Internal_GetInt32(IntPtr nativeInstance, int arrayIdx);
+    }
+}

+ 23 - 0
MBansheeEditor/Inspector/SerializableObject.cs

@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BansheeEditor
+{
+    public sealed class SerializableObject
+    {
+        private SerializableField[] _fields;
+
+        public SerializableObject(object obj)
+        {
+            // TODO - Populate _fields
+        }
+
+        public SerializableField[] fields
+        {
+            get { return _fields; }
+        }
+    }
+}

+ 37 - 0
MBansheeEditor/Inspector/SerializableValue.cs

@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BansheeEditor
+{
+    public sealed class SerializableValue
+    {
+        internal delegate void Setter(object value);
+        internal delegate object Getter();
+
+        private Setter setter;
+        private Getter getter;
+
+        internal SerializableValue(Setter setter, Getter getter)
+        {
+            this.setter = setter;
+            this.getter = getter;
+        }
+
+        public T GetValue<T>()
+        {
+            // TODO - Check for valid type?
+
+            return (T) getter();
+        }
+
+        public void SetValue<T>(T value)
+        {
+            // TODO - Check for valid type?
+
+            setter(value);
+        }
+    }
+}

+ 4 - 6
MBansheeEditor/MBansheeEditor.csproj

@@ -42,18 +42,16 @@
     <Compile Include="DbgCustomInspector.cs" />
     <Compile Include="DbgCustomInspector.cs" />
     <Compile Include="DbgEditorWindow.cs" />
     <Compile Include="DbgEditorWindow.cs" />
     <Compile Include="EditorApplication.cs" />
     <Compile Include="EditorApplication.cs" />
-    <Compile Include="EditorGUI.cs" />
     <Compile Include="EditorWindow.cs" />
     <Compile Include="EditorWindow.cs" />
     <Compile Include="Inspector\CustomInspector.cs" />
     <Compile Include="Inspector\CustomInspector.cs" />
-    <Compile Include="Inspector\EditorField.cs" />
     <Compile Include="Inspector\GenericInspector.cs" />
     <Compile Include="Inspector\GenericInspector.cs" />
-    <Compile Include="Inspector\InspectableArray.cs" />
-    <Compile Include="Inspector\InspectableField.cs" />
+    <Compile Include="Inspector\SerializableArray.cs" />
+    <Compile Include="Inspector\SerializableField.cs" />
     <Compile Include="Inspector\InspectableObject.cs" />
     <Compile Include="Inspector\InspectableObject.cs" />
-    <Compile Include="Inspector\InspectableObjectBase.cs" />
     <Compile Include="Inspector\Inspector.cs" />
     <Compile Include="Inspector\Inspector.cs" />
-    <Compile Include="Inspector\InspectorArea.cs" />
     <Compile Include="Inspector\InspectorWindow.cs" />
     <Compile Include="Inspector\InspectorWindow.cs" />
+    <Compile Include="Inspector\SerializableObject.cs" />
+    <Compile Include="Inspector\SerializableValue.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
   </ItemGroup>

+ 0 - 38
MBansheeEngine/GUI/GUI.cs

@@ -1,38 +0,0 @@
-using System;
-using System.Runtime.CompilerServices;
-
-namespace BansheeEngine
-{
-    public sealed class GUI : GUIBase
-    {
-        private static GUI instance = new GUI();
-
-        internal GUI()
-        {
-            Internal_CreateInstance(this);
-        }
-
-        public new static GUIArea AddArea(int x, int y, int width = 0, int height = 0, short depth = 0)
-        {
-            return ((GUIBase)instance).AddArea(x, y, width, height, depth);
-        }
-
-        public new static GUIArea AddResizableAreaX(int offsetLeft, int offsetRight, int offsetTop, int height, short depth = 0)
-        {
-            return ((GUIBase)instance).AddResizableAreaX(offsetLeft, offsetRight, offsetTop, height, depth);
-        }
-
-        public new static GUIArea AddResizableAreaY(int offsetTop, int offsetBottom, int offsetLeft, int width, short depth = 0)
-        {
-            return ((GUIBase)instance).AddResizableAreaY(offsetTop, offsetBottom, offsetLeft, width, depth);
-        }
-
-        public new static GUIArea AddResizableAreaXY(int offsetLeft, int offsetRight, int offsetTop, int offsetBottom, short depth = 0)
-        {
-            return ((GUIBase)instance).AddResizableAreaXY(offsetLeft, offsetRight, offsetTop, offsetBottom, depth);
-        }
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_CreateInstance(GUI instance);
-    }
-}

+ 10 - 10
MBansheeEngine/GUI/GUIArea.cs

@@ -6,7 +6,7 @@ namespace BansheeEngine
     public sealed class GUIArea : ScriptObject
     public sealed class GUIArea : ScriptObject
     {
     {
         private GUILayout _layout;
         private GUILayout _layout;
-        private GUIBase parent;
+        private GUIPanel parent;
         private bool isDestroyed;
         private bool isDestroyed;
 
 
         public GUILayout layout
         public GUILayout layout
@@ -17,7 +17,7 @@ namespace BansheeEngine
         internal GUIArea()
         internal GUIArea()
         { }
         { }
 
 
-        internal void SetParent(GUIBase parent)
+        internal void SetParent(GUIPanel parent)
         {
         {
             if (this.parent != null)
             if (this.parent != null)
                 this.parent.childAreas.Remove(this);
                 this.parent.childAreas.Remove(this);
@@ -27,7 +27,7 @@ namespace BansheeEngine
             parent.childAreas.Add(this);
             parent.childAreas.Add(this);
         }
         }
 
 
-        internal static GUIArea Create(GUIBase parent, int x, int y, int width, int height, short depth)
+        internal static GUIArea Create(GUIPanel parent, int x, int y, int width, int height, short depth)
         {
         {
             GUIArea newArea = new GUIArea();
             GUIArea newArea = new GUIArea();
             Internal_CreateInstance(newArea, parent, x, y, width, height, depth);
             Internal_CreateInstance(newArea, parent, x, y, width, height, depth);
@@ -36,7 +36,7 @@ namespace BansheeEngine
             return newArea;
             return newArea;
         }
         }
 
 
-        internal static GUIArea CreateResizableX(GUIBase parent, int offsetLeft, int offsetRight, int offsetTop, int height, short depth)
+        internal static GUIArea CreateResizableX(GUIPanel parent, int offsetLeft, int offsetRight, int offsetTop, int height, short depth)
         {
         {
             GUIArea newArea = new GUIArea();
             GUIArea newArea = new GUIArea();
             Internal_CreateInstanceResizableX(newArea, parent, offsetLeft, offsetRight, offsetTop, height, depth);
             Internal_CreateInstanceResizableX(newArea, parent, offsetLeft, offsetRight, offsetTop, height, depth);
@@ -45,7 +45,7 @@ namespace BansheeEngine
             return newArea;
             return newArea;
         }
         }
 
 
-        internal static GUIArea CreateResizableY(GUIBase parent, int offsetTop, int offsetBottom, int offsetLeft, int width, short depth)
+        internal static GUIArea CreateResizableY(GUIPanel parent, int offsetTop, int offsetBottom, int offsetLeft, int width, short depth)
         {
         {
             GUIArea newArea = new GUIArea();
             GUIArea newArea = new GUIArea();
             Internal_CreateInstanceResizableY(newArea, parent, offsetTop, offsetBottom, offsetLeft, width, depth);
             Internal_CreateInstanceResizableY(newArea, parent, offsetTop, offsetBottom, offsetLeft, width, depth);
@@ -54,7 +54,7 @@ namespace BansheeEngine
             return newArea;
             return newArea;
         }
         }
 
 
-        internal static GUIArea CreateResizableXY(GUIBase parent, int offsetLeft, int offsetRight, int offsetTop, int offsetBottom, short depth)
+        internal static GUIArea CreateResizableXY(GUIPanel parent, int offsetLeft, int offsetRight, int offsetTop, int offsetBottom, short depth)
         {
         {
             GUIArea newArea = new GUIArea();
             GUIArea newArea = new GUIArea();
             Internal_CreateInstanceResizableXY(newArea, parent, offsetLeft, offsetRight, offsetTop, offsetBottom, depth);
             Internal_CreateInstanceResizableXY(newArea, parent, offsetLeft, offsetRight, offsetTop, offsetBottom, depth);
@@ -88,18 +88,18 @@ namespace BansheeEngine
         }
         }
 
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_CreateInstance(GUIArea instance, GUIBase parent, int x, int y, int width, int height, short depth);
+        private static extern void Internal_CreateInstance(GUIArea instance, GUIPanel parent, int x, int y, int width, int height, short depth);
 
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_CreateInstanceResizableX(GUIArea instance, GUIBase parent, int offsetLeft, int offsetRight, int offsetTop, 
+        private static extern void Internal_CreateInstanceResizableX(GUIArea instance, GUIPanel parent, int offsetLeft, int offsetRight, int offsetTop, 
             int height, short depth);
             int height, short depth);
 
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_CreateInstanceResizableY(GUIArea instance, GUIBase parent, int offsetTop, int offsetBottom, int offsetLeft,
+        private static extern void Internal_CreateInstanceResizableY(GUIArea instance, GUIPanel parent, int offsetTop, int offsetBottom, int offsetLeft,
             int width, short depth);
             int width, short depth);
 
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_CreateInstanceResizableXY(GUIArea instance, GUIBase parent, int offsetLeft, int offsetRight, int offsetTop,
+        private static extern void Internal_CreateInstanceResizableXY(GUIArea instance, GUIPanel parent, int offsetLeft, int offsetRight, int offsetTop,
             int offsetBottom, short depth);
             int offsetBottom, short depth);
 
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]

+ 0 - 71
MBansheeEngine/GUI/GUIBase.cs

@@ -1,71 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Runtime.CompilerServices;
-
-namespace BansheeEngine
-{
-    public abstract class GUIBase : ScriptObject
-    {
-        private GUIArea mainArea;
-        private GUILayout _mainLayout;
-
-        internal List<GUIArea> childAreas = new List<GUIArea>();
-
-        public GUILayout layout
-        {
-            get { return _mainLayout; }
-        }
-
-        public GUISkin skin; // TODO
-
-        internal GUIBase()
-        { }
-
-        ~GUIBase()
-        {
-            GUIArea[] childArray = childAreas.ToArray(); // Iterating over it will modify it so make a copy
-            for (int i = 0; i < childArray.Length; i++)
-                childArray[i].Destroy();
-
-            childAreas.Clear();
-        }
-
-        internal void Initialize()
-        {
-            mainArea = AddResizableAreaXY(0, 0, 0, 0);
-            _mainLayout = mainArea.layout;
-        }
-
-        public GUIArea AddArea(int x, int y, int width, int height, short depth = 0)
-        {
-            GUIArea area = GUIArea.Create(this, x, y, width, height, depth);
-            area.SetParent(this);
-
-            return area;
-        }
-
-        public GUIArea AddResizableAreaX(int offsetLeft, int offsetRight, int offsetTop, int height, short depth = 0)
-        {
-            GUIArea area = GUIArea.CreateResizableX(this, offsetLeft, offsetRight, offsetTop, height, depth);
-            area.SetParent(this);
-
-            return area;
-        }
-
-        public GUIArea AddResizableAreaY(int offsetTop, int offsetBottom, int offsetLeft, int width, short depth = 0)
-        {
-            GUIArea area = GUIArea.CreateResizableY(this, offsetTop, offsetBottom, offsetLeft, width, depth);
-            area.SetParent(this);
-
-            return area;
-        }
-
-        public GUIArea AddResizableAreaXY(int offsetLeft, int offsetRight, int offsetTop, int offsetBottom, short depth = 0)
-        {
-            GUIArea area = GUIArea.CreateResizableXY(this, offsetLeft, offsetRight, offsetTop, offsetBottom, depth);
-            area.SetParent(this);
-
-            return area;
-        }
-    }
-}

+ 5 - 0
MBansheeEngine/GUI/GUILabel.cs

@@ -10,6 +10,11 @@ namespace BansheeEngine
             Internal_CreateInstance(this, content, style, options);
             Internal_CreateInstance(this, content, style, options);
         }
         }
 
 
+        public GUILabel(GUIContent content, string style = "")
+        {
+            Internal_CreateInstance(this, content, style, new GUIOption[0]);
+        }
+
         public void SetContent(GUIContent content)
         public void SetContent(GUIContent content)
         {
         {
             Internal_SetContent(mCachedPtr, content);
             Internal_SetContent(mCachedPtr, content);

+ 76 - 0
MBansheeEngine/GUI/GUIPanel.cs

@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+
+namespace BansheeEngine
+{
+    public sealed class GUIPanel : ScriptObject
+    {
+        private GUIArea mainArea;
+        private GUILayout _mainLayout;
+
+        internal List<GUIArea> childAreas = new List<GUIArea>();
+
+        public GUILayout layout
+        {
+            get { return _mainLayout; }
+        }
+
+        public GUISkin skin; // TODO
+
+        internal GUIPanel()
+        {
+            Internal_CreateInstance(this);
+        }
+
+        ~GUIPanel()
+        {
+            GUIArea[] childArray = childAreas.ToArray(); // Iterating over it will modify it so make a copy
+            for (int i = 0; i < childArray.Length; i++)
+                childArray[i].Destroy();
+
+            childAreas.Clear();
+        }
+
+        internal void Initialize()
+        {
+            mainArea = AddArea(0, 0, 0, 0);
+            _mainLayout = mainArea.layout;
+        }
+
+        public GUIArea AddArea(int x, int y, int width, int height, short depth = 0)
+        {
+            GUIArea area = GUIArea.Create(this, x, y, width, height, depth);
+            area.SetParent(this);
+
+            return area;
+        }
+
+        internal void SetArea(int x, int y, int width, int height)
+        {
+            Internal_SetArea(x, y, width, height);
+
+            mainArea.SetArea(x, y, width, height);
+        }
+
+        internal void Destroy()
+        {
+            GUIArea[] tempAreas = childAreas.ToArray();
+            for (int i = 0; i < tempAreas.Length; i++)
+                tempAreas[i].Destroy();
+
+            childAreas.Clear();
+
+            Internal_Destroy(mCachedPtr);
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetArea(int x, int y, int width, int height);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_CreateInstance(GUIPanel instance);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_Destroy(IntPtr nativeInstance);
+    }
+}

+ 1 - 2
MBansheeEngine/MBansheeEngine.csproj

@@ -53,9 +53,8 @@
     <Compile Include="DontSerializeField.cs" />
     <Compile Include="DontSerializeField.cs" />
     <Compile Include="Font.cs" />
     <Compile Include="Font.cs" />
     <Compile Include="GameObject.cs" />
     <Compile Include="GameObject.cs" />
-    <Compile Include="GUI\GUI.cs" />
     <Compile Include="GUI\GUIArea.cs" />
     <Compile Include="GUI\GUIArea.cs" />
-    <Compile Include="GUI\GUIBase.cs" />
+    <Compile Include="GUI\GUIPanel.cs" />
     <Compile Include="GUI\GUIButton.cs" />
     <Compile Include="GUI\GUIButton.cs" />
     <Compile Include="GUI\GUIContent.cs" />
     <Compile Include="GUI\GUIContent.cs" />
     <Compile Include="GUI\GUIElement.cs" />
     <Compile Include="GUI\GUIElement.cs" />