Преглед изворни кода

Logic for new drop down box style
Fixed an issue where only one separator could be present per menu
Fixed an issue where GUI menu items were sorted by name rather than insertion order
Fixed an issue where C# menu item separators weren't being properly removed on assembly refresh

BearishSun пре 10 година
родитељ
комит
c5349658df
37 измењених фајлова са 452 додато и 461 уклоњено
  1. 16 3
      BansheeEditor/Include/BsBuiltinEditorResources.h
  2. 3 4
      BansheeEditor/Include/BsGUIComponentFoldout.h
  3. 8 3
      BansheeEditor/Include/BsGUIMenuBar.h
  4. 96 113
      BansheeEditor/Source/BsBuiltinEditorResources.cpp
  5. 9 28
      BansheeEditor/Source/BsGUIComponentFoldout.cpp
  6. 15 3
      BansheeEditor/Source/BsGUIMenuBar.cpp
  7. 5 4
      BansheeEngine/Include/BsBuiltinResources.h
  8. 6 4
      BansheeEngine/Include/BsGUIDropDownMenu.h
  9. 18 7
      BansheeEngine/Include/BsGUIMenu.h
  10. 109 134
      BansheeEngine/Source/BsBuiltinResources.cpp
  11. 63 66
      BansheeEngine/Source/BsGUIDropDownMenu.cpp
  12. 28 15
      BansheeEngine/Source/BsGUIMenu.cpp
  13. 5 0
      MBansheeEditor/EditorBuiltin.cs
  14. 0 7
      MBansheeEditor/GUI/GUIComponentFoldout.cs
  15. 1 1
      MBansheeEditor/Inspector/GenericInspector.cs
  16. 3 3
      MBansheeEditor/Inspector/InspectableArray.cs
  17. 2 2
      MBansheeEditor/Inspector/InspectableBool.cs
  18. 2 2
      MBansheeEditor/Inspector/InspectableColor.cs
  19. 18 16
      MBansheeEditor/Inspector/InspectableField.cs
  20. 2 2
      MBansheeEditor/Inspector/InspectableFloat.cs
  21. 2 2
      MBansheeEditor/Inspector/InspectableGameObjectRef.cs
  22. 2 2
      MBansheeEditor/Inspector/InspectableInt.cs
  23. 3 3
      MBansheeEditor/Inspector/InspectableList.cs
  24. 3 3
      MBansheeEditor/Inspector/InspectableObject.cs
  25. 2 2
      MBansheeEditor/Inspector/InspectableResourceRef.cs
  26. 2 2
      MBansheeEditor/Inspector/InspectableString.cs
  27. 2 2
      MBansheeEditor/Inspector/InspectableVector2.cs
  28. 2 2
      MBansheeEditor/Inspector/InspectableVector3.cs
  29. 2 2
      MBansheeEditor/Inspector/InspectableVector4.cs
  30. 8 2
      MBansheeEditor/Inspector/InspectorWindow.cs
  31. 1 1
      README.md
  32. 1 1
      SBansheeEditor/Include/BsMenuItemManager.h
  33. 1 0
      SBansheeEditor/Include/BsScriptEditorBuiltin.h
  34. 0 9
      SBansheeEditor/Include/BsScriptGUIComponentFoldout.h
  35. 4 3
      SBansheeEditor/Source/BsMenuItemManager.cpp
  36. 8 0
      SBansheeEditor/Source/BsScriptEditorBuiltin.cpp
  37. 0 8
      SBansheeEditor/Source/BsScriptGUIComponentFoldout.cpp

+ 16 - 3
BansheeEditor/Include/BsBuiltinEditorResources.h

@@ -15,6 +15,14 @@ namespace BansheeEngine
 		Folder, Mesh, Font, Texture, PlainText, ScriptCode, SpriteTexture, Shader, ShaderInclude, Material, Prefab
 	};
 
+	/**
+	 * @brief	Types of icons used in various areas throughout the editor.
+	 */
+	enum class EditorIcon
+	{
+		XBtn
+	};
+
 	/**
 	 * @brief	Types of icons to be used along with log messages depending on their severity.
 	 */
@@ -103,6 +111,11 @@ namespace BansheeEngine
 		 */
 		HSpriteTexture getLibraryIcon(ProjectIcon icon) const;
 
+		/**
+		 * @brief	Retrieves an icon that represents a specific generic editor icon.
+		 */
+		HSpriteTexture getIcon(EditorIcon icon) const;
+
 		/**
 		 * @brief	Retrieves an icon that represents a specific log message type.
 		 */
@@ -310,6 +323,9 @@ namespace BansheeEngine
 		static const WString DropDownBtnActiveTex;
 
 		static const WString DropDownBoxBgTex;
+		static const WString DropDownBoxSideBgTex;
+		static const WString DropDownBoxHandleTex;
+
 		static const WString DropDownBoxEntryNormalTex;
 		static const WString DropDownBoxEntryHoverTex;
 
@@ -324,9 +340,6 @@ namespace BansheeEngine
 
 		static const WString DropDownSeparatorTex;
 
-		static const WString DropDownBoxBtnUpArrowTex;
-		static const WString DropDownBoxBtnDownArrowTex;
-
 		static const WString MenuBarBgTex;
 		static const WString MenuBarBansheeLogoTex;
 

+ 3 - 4
BansheeEditor/Include/BsGUIComponentFoldout.h

@@ -28,9 +28,9 @@ namespace BansheeEngine
 		static const String& getFoldoutButtonStyleType();
 
 		/**
-		 * Returns the style type name of the internal toggle button that triggers component removal.
+		 * Returns the style type name of the background texture.
 		 */
-		static const String& getFoldoutRemoveButtonStyleType();
+		static const String& getFoldoutBgStyleType();
 
 		/**
 		 * @brief	Creates a new GUI component foldout element.
@@ -87,7 +87,6 @@ namespace BansheeEngine
 		Vector2I _getOptimalSize() const override;
 
 		Event<void(bool)> onStateChanged;
-		Event<void()> onRemoveClicked;
 	protected:
 		virtual ~GUIComponentFoldout();
 
@@ -108,7 +107,7 @@ namespace BansheeEngine
 		void styleUpdated() override;
 
 		GUIToggle* mToggle;
-		GUIButton* mRemove;
+		GUITexture* mBackground;
 		bool mIsExpanded;
 	};
 }

+ 8 - 3
BansheeEditor/Include/BsGUIMenuBar.h

@@ -99,7 +99,7 @@ namespace BansheeEngine
 		 * @param	shortcut	Keyboard shortcut key to display next to the interactable element, and register with the
 		 *						global shortcut manager.
 		 */
-		const GUIMenuItem* addMenuItem(const WString& path, std::function<void()> callback, INT32 priority = 0, const ShortcutKey& shortcut = ShortcutKey::NONE);
+		GUIMenuItem* addMenuItem(const WString& path, std::function<void()> callback, INT32 priority = 0, const ShortcutKey& shortcut = ShortcutKey::NONE);
 
 		/**
 		 * @brief	Adds a menu item separator element at the specified path. The separator is added as a child of the path.
@@ -108,18 +108,23 @@ namespace BansheeEngine
 		 * @param	priority	Determines where is the separator positioned compared to other elements in the same sub-menu.
 		 *						Higher priority elements get placed higher up in the sub-menu.
 		 */
-		const GUIMenuItem* addMenuItemSeparator(const WString& path, INT32 priority = 0);
+		GUIMenuItem* addMenuItemSeparator(const WString& path, INT32 priority = 0);
 
 		/**
 		 * @brief	Returns an existing menu item at the specified path, or null if one cannot be found.
 		 */
-		const GUIMenuItem* getMenuItem(const WString& path) const;
+		GUIMenuItem* getMenuItem(const WString& path);
 
 		/**
 		 * @brief	Removes a menu item from the specified path. If this path points to a sub-menu entire sub-menu will be removed.
 		 */
 		void removeMenuItem(const WString& path);
 
+		/**
+		 * @brief	Removes the specified menu item.
+		 */
+		void removeMenuItem(GUIMenuItem* item);
+
 		/**
 		 * @brief	Adds a new button to the tool bar.
 		 *

+ 96 - 113
BansheeEditor/Source/BsBuiltinEditorResources.cpp

@@ -139,17 +139,17 @@ namespace BansheeEngine
 	const WString BuiltinEditorResources::SliderHandleHoverTex = L"SliderHandleHover.png";
 	const WString BuiltinEditorResources::SliderHandleActiveTex = L"SliderHandleActive.png";
 
-	const WString BuiltinEditorResources::FoldoutOpenNormalTex = L"FoldoutOpenNormal.psd";
-	const WString BuiltinEditorResources::FoldoutOpenHoverTex = L"FoldoutOpenHover.psd";
-	const WString BuiltinEditorResources::FoldoutClosedNormalTex = L"FoldoutClosedNormal.psd";
-	const WString BuiltinEditorResources::FoldoutClosedHoverTex = L"FoldoutClosedHover.psd";
-
-	const WString BuiltinEditorResources::CmpFoldoutOpenNormalTex = L"CmpFoldoutOpenNormal.psd";
-	const WString BuiltinEditorResources::CmpFoldoutOpenHoverTex = L"CmpFoldoutOpenHover.psd";
-	const WString BuiltinEditorResources::CmpFoldoutOpenActiveTex = L"CmpFoldoutOpenActive.psd";
-	const WString BuiltinEditorResources::CmpFoldoutClosedNormalTex = L"CmpFoldoutClosedNormal.psd";
-	const WString BuiltinEditorResources::CmpFoldoutClosedHoverTex = L"CmpFoldoutClosedHover.psd";
-	const WString BuiltinEditorResources::CmpFoldoutClosedActiveTex = L"CmpFoldoutClosedActive.psd";
+	const WString BuiltinEditorResources::FoldoutOpenNormalTex = L"ExpandArrowNormalOn.png";
+	const WString BuiltinEditorResources::FoldoutOpenHoverTex = L"ExpandArrowHoverOn.png";
+	const WString BuiltinEditorResources::FoldoutClosedNormalTex = L"ExpandArrowNormalOff.png";
+	const WString BuiltinEditorResources::FoldoutClosedHoverTex = L"ExpandArrowHoverOff.png";
+
+	const WString BuiltinEditorResources::CmpFoldoutOpenNormalTex = L"ComponentExpandNormalOn.png";
+	const WString BuiltinEditorResources::CmpFoldoutOpenHoverTex = L"ComponentExpandHoverOn.png";
+	const WString BuiltinEditorResources::CmpFoldoutOpenActiveTex = L"ComponentExpandHoverOn.png";
+	const WString BuiltinEditorResources::CmpFoldoutClosedNormalTex = L"ComponentExpandNormalOff.png";
+	const WString BuiltinEditorResources::CmpFoldoutClosedHoverTex = L"ComponentExpandHoverOff.png";
+	const WString BuiltinEditorResources::CmpFoldoutClosedActiveTex = L"ComponentExpandHoverOff.png";
 
 	const WString BuiltinEditorResources::WindowBackgroundTex = L"WindowBackground.png";
 
@@ -201,23 +201,23 @@ namespace BansheeEngine
 	const WString BuiltinEditorResources::ScrollBarHBgTex = L"ScrollBarHBackground.png";
 	const WString BuiltinEditorResources::ScrollBarVBgTex = L"ScrollBarVBackground.png";
 
-	const WString BuiltinEditorResources::DropDownBoxBgTex = L"DropDownBoxBg.psd";
-	const WString BuiltinEditorResources::DropDownBoxEntryNormalTex = L"DropDownButtonNormal.psd";
-	const WString BuiltinEditorResources::DropDownBoxEntryHoverTex = L"DropDownButtonHover.psd";
+	const WString BuiltinEditorResources::DropDownBoxBgTex = L"DropDownBoxBg.png";
+	const WString BuiltinEditorResources::DropDownBoxSideBgTex = L"DropDownBoxSideBg.png";
+	const WString BuiltinEditorResources::DropDownBoxHandleTex = L"DropDownBoxScrollHandle.png";
 
-	const WString BuiltinEditorResources::DropDownBoxBtnUpNormalTex = L"DropDownBoxBtnUpNormal.psd";
-	const WString BuiltinEditorResources::DropDownBoxBtnUpHoverTex = L"DropDownBoxBtnUpHover.psd";
+	const WString BuiltinEditorResources::DropDownBoxEntryNormalTex = L"DropDownBoxEntryNormal.png";
+	const WString BuiltinEditorResources::DropDownBoxEntryHoverTex = L"DropDownBoxEntryHover.png";
 
-	const WString BuiltinEditorResources::DropDownBoxBtnDownNormalTex = L"DropDownBoxBtnDownNormal.psd";
-	const WString BuiltinEditorResources::DropDownBoxBtnDownHoverTex = L"DropDownBoxBtnDownHover.psd";
+	const WString BuiltinEditorResources::DropDownBoxBtnUpNormalTex = L"DropDownBoxArrowUpNormal.png";
+	const WString BuiltinEditorResources::DropDownBoxBtnUpHoverTex = L"DropDownBoxArrowUpHover.png";
 
-	const WString BuiltinEditorResources::DropDownBoxEntryExpNormalTex = L"DropDownExpNormal.psd";
-	const WString BuiltinEditorResources::DropDownBoxEntryExpHoverTex = L"DropDownExpHover.psd";
+	const WString BuiltinEditorResources::DropDownBoxBtnDownNormalTex = L"DropDownBoxArrowDownNormal.png";
+	const WString BuiltinEditorResources::DropDownBoxBtnDownHoverTex = L"DropDownBoxArrowDownHover.png";
 
-	const WString BuiltinEditorResources::DropDownSeparatorTex = L"DropDownSeparator.psd";
+	const WString BuiltinEditorResources::DropDownBoxEntryExpNormalTex = L"DropDownBoxExpandBtnNormal.png";
+	const WString BuiltinEditorResources::DropDownBoxEntryExpHoverTex = L"DropDownBoxExpandBtnHover.png";
 
-	const WString BuiltinEditorResources::DropDownBoxBtnUpArrowTex = L"DropDownBoxBtnUpArrow.psd";
-	const WString BuiltinEditorResources::DropDownBoxBtnDownArrowTex = L"DropDownBoxBtnDownArrow.psd";
+	const WString BuiltinEditorResources::DropDownSeparatorTex = L"DropDownBoxSeparator.png";
 
 	const WString BuiltinEditorResources::MenuBarBgTex = L"MenuBarBackground.png";
 	const WString BuiltinEditorResources::MenuBarBansheeLogoTex = L"MenuBarLog.png";
@@ -804,80 +804,61 @@ namespace BansheeEngine
 
 		skin->setStyle("ListBox", dropDownListStyle);
 
-		// DropDown scroll up button arrow
-		HSpriteTexture dropDownBtnScrollUpArrow = getGUITexture(DropDownBoxBtnUpArrowTex);
-
-		GUIElementStyle dropDownScrollUpBtnArrowStyle;
-		dropDownScrollUpBtnArrowStyle.normal.texture = getGUITexture(DropDownBoxBtnUpArrowTex);
-		dropDownScrollUpBtnArrowStyle.hover.texture = dropDownScrollUpBtnArrowStyle.normal.texture;
-		dropDownScrollUpBtnArrowStyle.active.texture = dropDownScrollUpBtnArrowStyle.hover.texture;
-		dropDownScrollUpBtnArrowStyle.fixedHeight = true;
-		dropDownScrollUpBtnArrowStyle.fixedWidth = false;
-		dropDownScrollUpBtnArrowStyle.height = 7;
-		dropDownScrollUpBtnArrowStyle.width = 30;
-		dropDownScrollUpBtnArrowStyle.border.left = 1;
-		dropDownScrollUpBtnArrowStyle.border.right = 1;
-		dropDownScrollUpBtnArrowStyle.border.top = 1;
-		dropDownScrollUpBtnArrowStyle.border.bottom = 1;
-
-		skin->setStyle("ListBoxScrollUpBtnArrow", dropDownScrollUpBtnArrowStyle);
-		skin->setStyle("MenuBarScrollUpBtnArrow", dropDownScrollUpBtnArrowStyle);
-		skin->setStyle("ContextMenuScrollUpBtnArrow", dropDownScrollUpBtnArrowStyle);
-
 		// DropDown scroll up button
 		GUIElementStyle dropDownScrollUpBtnStyle;
 		dropDownScrollUpBtnStyle.normal.texture = getGUITexture(DropDownBoxBtnUpNormalTex);
 		dropDownScrollUpBtnStyle.hover.texture = getGUITexture(DropDownBoxBtnUpHoverTex);
 		dropDownScrollUpBtnStyle.active.texture = dropDownScrollUpBtnStyle.hover.texture;
 		dropDownScrollUpBtnStyle.fixedHeight = true;
-		dropDownScrollUpBtnStyle.fixedWidth = false;
-		dropDownScrollUpBtnStyle.height = 7;
-		dropDownScrollUpBtnStyle.width = 30;
-		dropDownScrollUpBtnStyle.border.left = 1;
-		dropDownScrollUpBtnStyle.border.right = 1;
-		dropDownScrollUpBtnStyle.border.top = 1;
-		dropDownScrollUpBtnStyle.border.bottom = 1;
+		dropDownScrollUpBtnStyle.fixedWidth = true;
+		dropDownScrollUpBtnStyle.width = 8;
+		dropDownScrollUpBtnStyle.height = 12;
 
 		skin->setStyle("ListBoxScrollUpBtn", dropDownScrollUpBtnStyle);
 		skin->setStyle("MenuBarScrollUpBtn", dropDownScrollUpBtnStyle);
 		skin->setStyle("ContextMenuScrollUpBtn", dropDownScrollUpBtnStyle);
 
-		// DropDown scroll down button arrow
-		GUIElementStyle dropDownScrollDownBtnArrowStyle;
-		dropDownScrollDownBtnArrowStyle.normal.texture = getGUITexture(DropDownBoxBtnDownArrowTex);
-		dropDownScrollDownBtnArrowStyle.hover.texture = dropDownScrollDownBtnArrowStyle.normal.texture;
-		dropDownScrollDownBtnArrowStyle.active.texture = dropDownScrollDownBtnArrowStyle.hover.texture;
-		dropDownScrollDownBtnArrowStyle.fixedHeight = true;
-		dropDownScrollDownBtnArrowStyle.fixedWidth = false;
-		dropDownScrollDownBtnArrowStyle.height = 7;
-		dropDownScrollDownBtnArrowStyle.width = 30;
-		dropDownScrollDownBtnArrowStyle.border.left = 1;
-		dropDownScrollDownBtnArrowStyle.border.right = 1;
-		dropDownScrollDownBtnArrowStyle.border.top = 1;
-		dropDownScrollDownBtnArrowStyle.border.bottom = 1;
-
-		skin->setStyle("ListBoxScrollDownBtnArrow", dropDownScrollDownBtnArrowStyle);
-		skin->setStyle("MenuBarScrollDownBtnArrow", dropDownScrollDownBtnArrowStyle);
-		skin->setStyle("ContextMenuScrollDownBtnArrow", dropDownScrollDownBtnArrowStyle);
-
 		// DropDown scroll down button
 		GUIElementStyle dropDownScrollDownBtnStyle;
 		dropDownScrollDownBtnStyle.normal.texture = getGUITexture(DropDownBoxBtnDownNormalTex);
 		dropDownScrollDownBtnStyle.hover.texture = getGUITexture(DropDownBoxBtnDownHoverTex);
 		dropDownScrollDownBtnStyle.active.texture = dropDownScrollDownBtnStyle.hover.texture;
 		dropDownScrollDownBtnStyle.fixedHeight = true;
-		dropDownScrollDownBtnStyle.fixedWidth = false;
-		dropDownScrollDownBtnStyle.height = 7;
-		dropDownScrollDownBtnStyle.width = 30;
-		dropDownScrollDownBtnStyle.border.left = 1;
-		dropDownScrollDownBtnStyle.border.right = 1;
-		dropDownScrollDownBtnStyle.border.top = 1;
-		dropDownScrollDownBtnStyle.border.bottom = 1;
+		dropDownScrollDownBtnStyle.fixedWidth = true;
+		dropDownScrollDownBtnStyle.width = 8;
+		dropDownScrollDownBtnStyle.height = 12;
 
 		skin->setStyle("ListBoxScrollDownBtn", dropDownScrollDownBtnStyle);
 		skin->setStyle("MenuBarScrollDownBtn", dropDownScrollDownBtnStyle);
 		skin->setStyle("ContextMenuScrollDownBtn", dropDownScrollDownBtnStyle);
 
+		// DropDown handle
+		GUIElementStyle dropDownScrollHandleStyle;
+		dropDownScrollHandleStyle.normal.texture = getGUITexture(DropDownBoxHandleTex);
+		dropDownScrollHandleStyle.fixedHeight = false;
+		dropDownScrollHandleStyle.fixedWidth = true;
+		dropDownScrollHandleStyle.height = 8;
+		dropDownScrollHandleStyle.width = 8;
+
+		skin->setStyle("ListBoxHandle", dropDownScrollHandleStyle);
+		skin->setStyle("MenuBarHandle", dropDownScrollHandleStyle);
+		skin->setStyle("ContextMenuHandle", dropDownScrollHandleStyle);
+
+		// DropDown sidebar background
+		GUIElementStyle dropDownSidebarBg;
+		dropDownSidebarBg.normal.texture = getGUITexture(DropDownBoxSideBgTex);
+		dropDownSidebarBg.fixedHeight = false;
+		dropDownSidebarBg.fixedWidth = true;
+		dropDownSidebarBg.height = 8;
+		dropDownSidebarBg.width = 9;
+		dropDownSidebarBg.border.left = 1;
+		dropDownSidebarBg.border.top = 1;
+		dropDownSidebarBg.border.bottom = 1;
+
+		skin->setStyle("ListBoxSidebarBg", dropDownSidebarBg);
+		skin->setStyle("MenuBarSidebarBg", dropDownSidebarBg);
+		skin->setStyle("ContextMenuSidebarBg", dropDownSidebarBg);
+
 		// DropDown entry button
 		GUIElementStyle dropDownEntryBtnStyle;
 		dropDownEntryBtnStyle.normal.texture = getGUITexture(DropDownBoxEntryNormalTex);
@@ -894,16 +875,12 @@ namespace BansheeEngine
 		dropDownEntryBtnStyle.activeOn.textColor = TextNormalColor;
 		dropDownEntryBtnStyle.fixedHeight = true;
 		dropDownEntryBtnStyle.fixedWidth = false;
-		dropDownEntryBtnStyle.height = 14;
+		dropDownEntryBtnStyle.height = 16;
 		dropDownEntryBtnStyle.width = 30;
-		dropDownEntryBtnStyle.border.left = 1;
-		dropDownEntryBtnStyle.border.right = 1;
-		dropDownEntryBtnStyle.border.top = 1;
-		dropDownEntryBtnStyle.border.bottom = 1;
 		dropDownEntryBtnStyle.font = font;
 		dropDownEntryBtnStyle.fontSize = DefaultFontSize;
 		dropDownEntryBtnStyle.textHorzAlign = THA_Left;
-		dropDownEntryBtnStyle.textVertAlign = TVA_Top;
+		dropDownEntryBtnStyle.textVertAlign = TVA_Center;
 
 		skin->setStyle(GUIDropDownContent::ENTRY_STYLE_TYPE, dropDownEntryBtnStyle);
 
@@ -923,16 +900,13 @@ namespace BansheeEngine
 		dropDownEntryExpBtnStyle.activeOn.textColor = TextNormalColor;
 		dropDownEntryExpBtnStyle.fixedHeight = true;
 		dropDownEntryExpBtnStyle.fixedWidth = false;
-		dropDownEntryExpBtnStyle.height = 14;
+		dropDownEntryExpBtnStyle.height = 16;
 		dropDownEntryExpBtnStyle.width = 30;
-		dropDownEntryExpBtnStyle.border.left = 1;
-		dropDownEntryExpBtnStyle.border.right = 6;
-		dropDownEntryExpBtnStyle.border.top = 1;
-		dropDownEntryExpBtnStyle.border.bottom = 1;
+		dropDownEntryExpBtnStyle.border.right = 13;
 		dropDownEntryExpBtnStyle.font = font;
 		dropDownEntryExpBtnStyle.fontSize = DefaultFontSize;
 		dropDownEntryExpBtnStyle.textHorzAlign = THA_Left;
-		dropDownEntryExpBtnStyle.textVertAlign = TVA_Top;
+		dropDownEntryExpBtnStyle.textVertAlign = TVA_Center;
 
 		skin->setStyle(GUIDropDownContent::ENTRY_EXP_STYLE_TYPE, dropDownEntryExpBtnStyle);
 
@@ -943,10 +917,6 @@ namespace BansheeEngine
 		dropDownSeparatorStyle.fixedWidth = false;
 		dropDownSeparatorStyle.height = 3;
 		dropDownSeparatorStyle.width = 30;
-		dropDownSeparatorStyle.border.left = 1;
-		dropDownSeparatorStyle.border.right = 1;
-		dropDownSeparatorStyle.border.top = 1;
-		dropDownSeparatorStyle.border.bottom = 1;
 
 		skin->setStyle(GUIDropDownContent::SEPARATOR_STYLE_TYPE, dropDownSeparatorStyle);
 
@@ -965,18 +935,18 @@ namespace BansheeEngine
 		// DropDown box frame
 		GUIElementStyle dropDownBoxStyle;
 		dropDownBoxStyle.normal.texture = getGUITexture(DropDownBoxBgTex);
-		dropDownBoxStyle.hover.texture = dropDownEntryBtnStyle.normal.texture;
-		dropDownBoxStyle.active.texture = dropDownEntryBtnStyle.hover.texture;
+		dropDownBoxStyle.hover.texture = dropDownBoxStyle.normal.texture;
+		dropDownBoxStyle.active.texture = dropDownBoxStyle.hover.texture;
 		dropDownBoxStyle.fixedHeight = false;
 		dropDownBoxStyle.fixedWidth = false;
-		dropDownBoxStyle.border.left = 1;
-		dropDownBoxStyle.border.right = 1;
-		dropDownBoxStyle.border.top = 1;
-		dropDownBoxStyle.border.bottom = 1;
-		dropDownBoxStyle.margins.left = 1;
-		dropDownBoxStyle.margins.right = 1;
-		dropDownBoxStyle.margins.top = 1;
-		dropDownBoxStyle.margins.bottom = 1;
+		dropDownBoxStyle.border.left = 2;
+		dropDownBoxStyle.border.right = 2;
+		dropDownBoxStyle.border.top = 2;
+		dropDownBoxStyle.border.bottom = 4;
+		dropDownBoxStyle.margins.left = 6;
+		dropDownBoxStyle.margins.right = 6;
+		dropDownBoxStyle.margins.top = 4;
+		dropDownBoxStyle.margins.bottom = 6;
 
 		skin->setStyle("ListBoxFrame", dropDownBoxStyle);
 		skin->setStyle("MenuBarFrame", dropDownBoxStyle);
@@ -1398,23 +1368,25 @@ namespace BansheeEngine
 
 		skin->setStyle(GUIComponentFoldout::getFoldoutButtonStyleType(), cmpFoldoutBtnStyle);
 
-		GUIElementStyle cmpFoldoutRemoveBtnStyle;
-		cmpFoldoutRemoveBtnStyle.normal.texture = getGUITexture(XButtonNormalTex);
-		cmpFoldoutRemoveBtnStyle.hover.texture = getGUITexture(XButtonHoverTex);
-		cmpFoldoutRemoveBtnStyle.active.texture = cmpFoldoutRemoveBtnStyle.hover.texture;
-		cmpFoldoutRemoveBtnStyle.fixedHeight = true;
-		cmpFoldoutRemoveBtnStyle.fixedWidth = true;
-		cmpFoldoutRemoveBtnStyle.height = 11;
-		cmpFoldoutRemoveBtnStyle.width = 11;
+		// Component foldout background
+		GUIElementStyle cmpFoldoutBgStyle;
+		cmpFoldoutBgStyle.normal.texture = getGUITexture(ButtonNormalTex);
+		cmpFoldoutBgStyle.border.left = 2;
+		cmpFoldoutBgStyle.border.right = 2;
+		cmpFoldoutBgStyle.border.top = 2;
+		cmpFoldoutBgStyle.border.bottom = 4;
+		cmpFoldoutBgStyle.fixedHeight = true;
+		cmpFoldoutBgStyle.height = 21;
+		cmpFoldoutBgStyle.minWidth = 20;
 
-		skin->setStyle(GUIComponentFoldout::getFoldoutRemoveButtonStyleType(), cmpFoldoutRemoveBtnStyle);
+		skin->setStyle(GUIComponentFoldout::getFoldoutBgStyleType(), cmpFoldoutBgStyle);
 
 		GUIElementStyle cmpFoldoutStyle;
 		cmpFoldoutStyle.fixedHeight = true;
-		cmpFoldoutStyle.height = 12;
+		cmpFoldoutStyle.height = 21;
 		cmpFoldoutStyle.minWidth = 30;
 		cmpFoldoutStyle.subStyles[GUIComponentFoldout::getFoldoutButtonStyleType()] = GUIComponentFoldout::getFoldoutButtonStyleType();
-		cmpFoldoutStyle.subStyles[GUIComponentFoldout::getFoldoutRemoveButtonStyleType()] = GUIComponentFoldout::getFoldoutRemoveButtonStyleType();
+		cmpFoldoutStyle.subStyles[GUIComponentFoldout::getFoldoutBgStyleType()] = GUIComponentFoldout::getFoldoutBgStyleType();
 
 		skin->setStyle(GUIComponentFoldout::getGUITypeName(), cmpFoldoutStyle);
 
@@ -1431,7 +1403,7 @@ namespace BansheeEngine
 		foldoutBtnStyle.fixedHeight = true;
 		foldoutBtnStyle.fixedWidth = true;
 		foldoutBtnStyle.height = 10;
-		foldoutBtnStyle.width = 8;
+		foldoutBtnStyle.width = 10;
 
 		skin->setStyle(GUIFoldout::getFoldoutButtonStyleType(), foldoutBtnStyle);
 
@@ -1844,6 +1816,17 @@ namespace BansheeEngine
 		return HSpriteTexture();
 	}
 
+	HSpriteTexture BuiltinEditorResources::getIcon(EditorIcon icon) const
+	{
+		switch (icon)
+		{
+		case EditorIcon::XBtn:
+			return getGUIIcon(XButtonNormalTex);
+		}
+
+		return HSpriteTexture();
+	}
+
 	HSpriteTexture BuiltinEditorResources::getLogMessageIcon(LogMessageIcon icon) const
 	{
 		switch (icon)

+ 9 - 28
BansheeEditor/Source/BsGUIComponentFoldout.cpp

@@ -14,18 +14,16 @@ namespace BansheeEngine
 {
 	GUIComponentFoldout::GUIComponentFoldout(const PrivatelyConstruct& dummy, const HString& label, const String& style,
 		const GUIDimensions& dimensions)
-		:GUIElementContainer(dimensions, style), mToggle(nullptr), mRemove(nullptr), mIsExpanded(false)
+		:GUIElementContainer(dimensions, style), mToggle(nullptr), mBackground(nullptr), mIsExpanded(false)
 	{
 		mToggle = GUIToggle::create(label, getSubStyleName(getFoldoutButtonStyleType()));
-		mRemove = GUIButton::create(HEString(L""), getSubStyleName(getFoldoutRemoveButtonStyleType()));
+		mBackground = GUITexture::create(getSubStyleName(getFoldoutBgStyleType()));
 
 		_registerChildElement(mToggle);
-		_registerChildElement(mRemove);
+		_registerChildElement(mBackground);
 
 		mToggle->onToggled.connect(std::bind(&GUIComponentFoldout::toggleTriggered, this, _1));
-		mRemove->onClick.connect(std::bind(&GUIComponentFoldout::removeTriggered, this));
-
-		mToggle->_setElementDepth(1);
+		mBackground->_setElementDepth(1);
 	}
 
 	GUIComponentFoldout::~GUIComponentFoldout()
@@ -85,11 +83,6 @@ namespace BansheeEngine
 		onStateChanged(value);
 	}
 
-	void GUIComponentFoldout::removeTriggered()
-	{
-		onRemoveClicked();
-	}
-
 	void GUIComponentFoldout::_updateLayoutInternal(const GUILayoutData& data)
 	{
 		Vector2I toggleOptSize = mToggle->_getOptimalSize();
@@ -103,19 +96,7 @@ namespace BansheeEngine
 			mToggle->_setLayoutData(childData);
 		}
 
-		{
-			Vector2I optimalSize = mRemove->_getOptimalSize();
-
-			INT32 yOffset = Math::roundToInt(((INT32)data.area.height - optimalSize.y) * 0.5f);
-
-			GUILayoutData childData = data;
-			childData.area.x = data.area.x + data.area.width - optimalSize.x - 5; // 5 = arbitrary offset
-			childData.area.width = optimalSize.x;
-			childData.area.y += yOffset;
-			childData.area.height = optimalSize.y;
-
-			mRemove->_setLayoutData(childData);
-		}
+		mBackground->_setLayoutData(data);
 	}
 
 	Vector2I GUIComponentFoldout::_getOptimalSize() const
@@ -128,7 +109,7 @@ namespace BansheeEngine
 	void GUIComponentFoldout::styleUpdated()
 	{
 		mToggle->setStyle(getSubStyleName(getFoldoutButtonStyleType()));
-		mRemove->setStyle(getSubStyleName(getFoldoutRemoveButtonStyleType()));
+		mBackground->setStyle(getSubStyleName(getFoldoutBgStyleType()));
 	}
 
 	const String& GUIComponentFoldout::getGUITypeName()
@@ -143,9 +124,9 @@ namespace BansheeEngine
 		return FOLDOUT_BUTTON_STYLE;		
 	}
 
-	const String& GUIComponentFoldout::getFoldoutRemoveButtonStyleType()
+	const String& GUIComponentFoldout::getFoldoutBgStyleType()
 	{
-		static String FOLDOUT_REMOVE_BUTTON_STYLE = "ComponentFoldoutRemoveButton";
-		return FOLDOUT_REMOVE_BUTTON_STYLE;
+		static String FOLDOUT_BACKGROUND_STYLE = "ComponentFoldoutBg";
+		return FOLDOUT_BACKGROUND_STYLE;
 	}
 }

+ 15 - 3
BansheeEditor/Source/BsGUIMenuBar.cpp

@@ -149,7 +149,7 @@ namespace BansheeEngine
 		refreshNonClientAreas();
 	}
 
-	const GUIMenuItem* GUIMenuBar::addMenuItem(const WString& path, std::function<void()> callback, 
+	GUIMenuItem* GUIMenuBar::addMenuItem(const WString& path, std::function<void()> callback, 
 		INT32 priority, const ShortcutKey& shortcut)
 	{
 		WString strippedPath = path;
@@ -172,7 +172,7 @@ namespace BansheeEngine
 		return subMenu->menu->addMenuItem(strippedPath, callback, priority, shortcut);
 	}
 
-	const GUIMenuItem* GUIMenuBar::addMenuItemSeparator(const WString& path, INT32 priority)
+	GUIMenuItem* GUIMenuBar::addMenuItemSeparator(const WString& path, INT32 priority)
 	{
 		WString strippedPath = path;
 		WString rootName;
@@ -212,7 +212,7 @@ namespace BansheeEngine
 		return &newSubMenu;
 	}
 
-	const GUIMenuItem* GUIMenuBar::getMenuItem(const WString& path) const
+	GUIMenuItem* GUIMenuBar::getMenuItem(const WString& path)
 	{
 		WString strippedPath = path;
 		WString rootName;
@@ -276,6 +276,18 @@ namespace BansheeEngine
 		subMenu->menu->removeMenuItem(item);
 	}
 
+	void GUIMenuBar::removeMenuItem(GUIMenuItem* item)
+	{
+		if (item == nullptr)
+			return;
+
+		GUIMenuItem* parent = item->getParent();
+		if (parent != nullptr)
+		{
+			parent->removeChild(item);
+		}
+	}
+
 	const GUIMenuBar::GUIMenuBarData* GUIMenuBar::getSubMenu(const WString& name) const
 	{
 		for(auto& subMenu : mChildMenus)

+ 5 - 4
BansheeEngine/Include/BsBuiltinResources.h

@@ -225,13 +225,17 @@ namespace BansheeEngine
 		static const WString ScrollBarHandleVertHoverTex;
 		static const WString ScrollBarHandleVertActiveTex;
 
-		static const WString ScrollBarBgTex;
+		static const WString ScrollBarHBgTex;
+		static const WString ScrollBarVBgTex;
 
 		static const WString DropDownBtnNormalTex;
 		static const WString DropDownBtnHoverTex;
 		static const WString DropDownBtnActiveTex;
 
 		static const WString DropDownBoxBgTex;
+		static const WString DropDownBoxSideBgTex;
+		static const WString DropDownBoxHandleTex;
+
 		static const WString DropDownBoxEntryNormalTex;
 		static const WString DropDownBoxEntryHoverTex;
 
@@ -246,9 +250,6 @@ namespace BansheeEngine
 
 		static const WString DropDownSeparatorTex;
 
-		static const WString DropDownBoxBtnUpArrowTex;
-		static const WString DropDownBoxBtnDownArrowTex;
-
 		static const WString CursorArrowTex;
 		static const WString CursorArrowDragTex;
 		static const WString CursorArrowLeftRightTex;

+ 6 - 4
BansheeEngine/Include/BsGUIDropDownMenu.h

@@ -239,14 +239,16 @@ namespace BansheeEngine
 			UINT32 mDepthOffset;
 			bool mOpenedUpward;
 
-			GUIButton* mScrollUpBtn;
-			GUIButton* mScrollDownBtn;
 			GUIDropDownContent* mContent;
 			GUITexture* mBackgroundFrame;
+			GUIButton* mScrollUpBtn;
+			GUIButton* mScrollDownBtn;
+			GUITexture* mHandle;
 
 			GUIPanel* mBackgroundPanel;
 			GUIPanel* mContentPanel;
 			GUILayout* mContentLayout;
+			GUIPanel* mSidebarPanel;
 
 			DropDownSubMenu* mParent;
 			DropDownSubMenu* mSubMenu;
@@ -282,8 +284,8 @@ namespace BansheeEngine
 		String mScrollDownStyle;
 		String mBackgroundStyle;
 		String mContentStyle;
-		HSpriteTexture mScrollUpBtnArrow;
-		HSpriteTexture mScrollDownBtnArrow;
+		String mSideBackgroundStyle;
+		String mHandleStyle;
 
 		DropDownSubMenu* mRootMenu;
 		GUIDropDownHitBox* mFrontHitBox;

+ 18 - 7
BansheeEngine/Include/BsGUIMenu.h

@@ -30,18 +30,22 @@ namespace BansheeEngine
 		 * @param	name		Name of the item to be displayed.
 		 * @param	callback	Callback to be triggered when menu items is selected.
 		 * @param	priority	Priority that determines the order of this element compared to its siblings.
+		 * @param	seqIdx		Sequential index of the menu item that specifies in what order was it added to the menu
+		 * 						compared to other items.
 		 * @param	key			Keyboard shortcut that can be used for triggering the menu item.
 		 */
 		GUIMenuItem(GUIMenuItem* parent, const WString& name, std::function<void()> callback, 
-			INT32 priority, const ShortcutKey& key);
+			INT32 priority, UINT32 seqIdx, const ShortcutKey& key);
 
 		/**
 		 * @brief	Constructs a new separator menu item.
 		 *
 		 * @param	parent		Parent item, if any.
 		 * @param	priority	Priority that determines the order of this element compared to its siblings.
+		 * @param	seqIdx		Sequential index of the menu item that specifies in what order was it added to the menu
+		 * 						compared to other items.
 		 */
-		GUIMenuItem(GUIMenuItem* parent, INT32 priority);
+		GUIMenuItem(GUIMenuItem* parent, INT32 priority, UINT32 seqIdx);
 		~GUIMenuItem();
 
 		/**
@@ -57,7 +61,7 @@ namespace BansheeEngine
 		/**
 		 * @brief	Returns the parent menu item, or null if none.
 		 */
-		const GUIMenuItem* getParent() const { return mParent; }
+		GUIMenuItem* getParent() { return mParent; }
 
 		/**
 		 * @brief	Returns name of the menu item. Empty if separator.
@@ -90,6 +94,11 @@ namespace BansheeEngine
 		 */
 		void removeChild(const WString& name);
 
+		/**
+		 * @brief	Removes the specified child.
+		 */
+		void removeChild(const GUIMenuItem* item);
+
 	private:
 		friend class GUIMenu;
 		friend struct GUIMenuItemComparer;
@@ -105,6 +114,7 @@ namespace BansheeEngine
 		std::function<void()> mCallback;
 		INT32 mPriority;
 		ShortcutKey mShortcut;
+		UINT32 mSeqIdx;
 		Set<GUIMenuItem*, GUIMenuItemComparer> mChildren;
 	};
 
@@ -138,7 +148,7 @@ namespace BansheeEngine
 		 *
 		 * @returns	A menu item object that you may use for removing the menu item later. Its lifetime is managed internally.
 		 */
-		const GUIMenuItem* addMenuItem(const WString& path, std::function<void()> callback, INT32 priority, const ShortcutKey& key = ShortcutKey::NONE);
+		GUIMenuItem* addMenuItem(const WString& path, std::function<void()> callback, INT32 priority, const ShortcutKey& key = ShortcutKey::NONE);
 
 		/**
 		 * @brief	Adds a new separator menu item with the specified callback.
@@ -150,12 +160,12 @@ namespace BansheeEngine
 		 *
 		 * @returns	A menu item object that you may use for removing the menu item later. Its lifetime is managed internally.
 		 */
-		const GUIMenuItem* addSeparator(const WString& path, INT32 priority);
+		GUIMenuItem* addSeparator(const WString& path, INT32 priority);
 
 		/**
 		 * @brief	Returns a menu item at the specified path, or null if one is not found.
 		 */
-		const GUIMenuItem* getMenuItem(const WString& path) const;
+		GUIMenuItem* getMenuItem(const WString& path);
 
 		/**
 		 * @brief	Removes the specified menu item from the path. If the menu item has any sub-menus they will also be removed.
@@ -181,7 +191,7 @@ namespace BansheeEngine
 		/**
 		 * @brief	Adds a menu item at the specified path, as a normal button or as a separator.
 		 */
-		const GUIMenuItem* addMenuItemInternal(const WString& path, std::function<void()> callback, bool isSeparator, 
+		GUIMenuItem* addMenuItemInternal(const WString& path, std::function<void()> callback, bool isSeparator, 
 			INT32 priority, const ShortcutKey& key);
 
 		/**
@@ -191,5 +201,6 @@ namespace BansheeEngine
 
 		GUIMenuItem mRootElement;
 		UnorderedMap<WString, HString> mLocalizedEntryNames;
+		UINT32 mNextIdx;
 	};
 }

+ 109 - 134
BansheeEngine/Source/BsBuiltinResources.cpp

@@ -79,53 +79,54 @@ namespace BansheeEngine
 	const WString BuiltinResources::InputBoxHoverTex = L"InputBoxHover.png";
 	const WString BuiltinResources::InputBoxFocusedTex = L"InputBoxActive.png";
 
-	const WString BuiltinResources::ScrollBarUpNormalTex = L"ScrollBarUpNormal.psd";
-	const WString BuiltinResources::ScrollBarUpHoverTex = L"ScrollBarUpHover.psd";
-	const WString BuiltinResources::ScrollBarUpActiveTex = L"ScrollBarUpActive.psd";
+	const WString BuiltinResources::ScrollBarUpNormalTex = L"ScrollArrowUpNormal.png";
+	const WString BuiltinResources::ScrollBarUpHoverTex = L"ScrollArrowUpHover.png";
+	const WString BuiltinResources::ScrollBarUpActiveTex = L"ScrollArrowUpActive.png";
 
-	const WString BuiltinResources::ScrollBarDownNormalTex = L"ScrollBarDownNormal.psd";
-	const WString BuiltinResources::ScrollBarDownHoverTex = L"ScrollBarDownHover.psd";
-	const WString BuiltinResources::ScrollBarDownActiveTex = L"ScrollBarDownActive.psd";
+	const WString BuiltinResources::ScrollBarDownNormalTex = L"ScrollArrowDownNormal.png";
+	const WString BuiltinResources::ScrollBarDownHoverTex = L"ScrollArrowDownHover.png";
+	const WString BuiltinResources::ScrollBarDownActiveTex = L"ScrollArrowDownActive.png";
 
-	const WString BuiltinResources::ScrollBarLeftNormalTex = L"ScrollBarLeftNormal.psd";
-	const WString BuiltinResources::ScrollBarLeftHoverTex = L"ScrollBarLeftHover.psd";
-	const WString BuiltinResources::ScrollBarLeftActiveTex = L"ScrollBarLeftActive.psd";
+	const WString BuiltinResources::ScrollBarLeftNormalTex = L"ScrollArrowLeftNormal.png";
+	const WString BuiltinResources::ScrollBarLeftHoverTex = L"ScrollArrowLeftHover.png";
+	const WString BuiltinResources::ScrollBarLeftActiveTex = L"ScrollArrowLeftActive.png";
 
-	const WString BuiltinResources::ScrollBarRightNormalTex = L"ScrollBarRightNormal.psd";
-	const WString BuiltinResources::ScrollBarRightHoverTex = L"ScrollBarRightHover.psd";
-	const WString BuiltinResources::ScrollBarRightActiveTex = L"ScrollBarRightActive.psd";
+	const WString BuiltinResources::ScrollBarRightNormalTex = L"ScrollArrowRightNormal.png";
+	const WString BuiltinResources::ScrollBarRightHoverTex = L"ScrollArrowRightHover.png";
+	const WString BuiltinResources::ScrollBarRightActiveTex = L"ScrollArrowRightActive.png";
 
-	const WString BuiltinResources::ScrollBarHandleHorzNormalTex = L"ScrollBarHorzHandleNormal.psd";
-	const WString BuiltinResources::ScrollBarHandleHorzHoverTex = L"ScrollBarHorzHandleHover.psd";
-	const WString BuiltinResources::ScrollBarHandleHorzActiveTex = L"ScrollBarHorzHandleActive.psd";
+	const WString BuiltinResources::ScrollBarHandleHorzNormalTex = L"ScrollBarHHandleNormal.png";
+	const WString BuiltinResources::ScrollBarHandleHorzHoverTex = L"ScrollBarHHandleHover.png";
+	const WString BuiltinResources::ScrollBarHandleHorzActiveTex = L"ScrollBarHHandleActive.png";
 
-	const WString BuiltinResources::ScrollBarHandleVertNormalTex = L"ScrollBarVertHandleNormal.psd";
-	const WString BuiltinResources::ScrollBarHandleVertHoverTex = L"ScrollBarVertHandleHover.psd";
-	const WString BuiltinResources::ScrollBarHandleVertActiveTex = L"ScrollBarVertHandleActive.psd";
+	const WString BuiltinResources::ScrollBarHandleVertNormalTex = L"ScrollBarVHandleNormal.png";
+	const WString BuiltinResources::ScrollBarHandleVertHoverTex = L"ScrollBarVHandleHover.png";
+	const WString BuiltinResources::ScrollBarHandleVertActiveTex = L"ScrollBarVHandleActive.png";
+
+	const WString BuiltinResources::ScrollBarHBgTex = L"ScrollBarHBackground.png";
+	const WString BuiltinResources::ScrollBarVBgTex = L"ScrollBarVBackground.png";
 
 	const WString BuiltinResources::DropDownBtnNormalTex = L"DropDownButtonNormal.png";
 	const WString BuiltinResources::DropDownBtnHoverTex = L"DropDownButtonHover.png";
 	const WString BuiltinResources::DropDownBtnActiveTex = L"DropDownButtonActive.png";
 
-	const WString BuiltinResources::DropDownBoxBgTex = L"DropDownBoxBg.psd";
-	const WString BuiltinResources::DropDownBoxEntryNormalTex = L"DropDownButtonNormal.psd";
-	const WString BuiltinResources::DropDownBoxEntryHoverTex = L"DropDownButtonHover.psd";
-
-	const WString BuiltinResources::DropDownBoxBtnUpNormalTex = L"DropDownBoxBtnUpNormal.psd";
-	const WString BuiltinResources::DropDownBoxBtnUpHoverTex = L"DropDownBoxBtnUpHover.psd";
+	const WString BuiltinResources::DropDownBoxBgTex = L"DropDownBoxBg.png";
+	const WString BuiltinResources::DropDownBoxSideBgTex = L"DropDownBoxSideBg.png";
+	const WString BuiltinResources::DropDownBoxHandleTex = L"DropDownBoxScrollHandle.png";
 
-	const WString BuiltinResources::DropDownBoxBtnDownNormalTex = L"DropDownBoxBtnDownNormal.psd";
-	const WString BuiltinResources::DropDownBoxBtnDownHoverTex = L"DropDownBoxBtnDownHover.psd";
+	const WString BuiltinResources::DropDownBoxEntryNormalTex = L"DropDownBoxEntryNormal.png";
+	const WString BuiltinResources::DropDownBoxEntryHoverTex = L"DropDownBoxEntryHover.png";
 
-	const WString BuiltinResources::DropDownBoxEntryExpNormalTex = L"DropDownExpNormal.psd";
-	const WString BuiltinResources::DropDownBoxEntryExpHoverTex = L"DropDownExpHover.psd";
+	const WString BuiltinResources::DropDownBoxBtnUpNormalTex = L"DropDownBoxArrowUpNormal.png";
+	const WString BuiltinResources::DropDownBoxBtnUpHoverTex = L"DropDownBoxArrowUpHover.png";
 
-	const WString BuiltinResources::DropDownSeparatorTex = L"DropDownSeparator.psd";
+	const WString BuiltinResources::DropDownBoxBtnDownNormalTex = L"DropDownBoxArrowDownNormal.png";
+	const WString BuiltinResources::DropDownBoxBtnDownHoverTex = L"DropDownBoxArrowDownHover.png";
 
-	const WString BuiltinResources::DropDownBoxBtnUpArrowTex = L"DropDownBoxBtnUpArrow.psd";
-	const WString BuiltinResources::DropDownBoxBtnDownArrowTex = L"DropDownBoxBtnDownArrow.psd";
+	const WString BuiltinResources::DropDownBoxEntryExpNormalTex = L"DropDownBoxExpandBtnNormal.png";
+	const WString BuiltinResources::DropDownBoxEntryExpHoverTex = L"DropDownBoxExpandBtnHover.png";
 
-	const WString BuiltinResources::ScrollBarBgTex = L"ScrollBarBg.psd";
+	const WString BuiltinResources::DropDownSeparatorTex = L"DropDownBoxSeparator.png";
 
 	/************************************************************************/
 	/* 							CURSOR TEXTURES                      		*/
@@ -399,8 +400,8 @@ namespace BansheeEngine
 		scrollUpBtnStyle.active.texture = getSkinTexture(ScrollBarUpActiveTex);
 		scrollUpBtnStyle.fixedHeight = true;
 		scrollUpBtnStyle.fixedWidth = true;
-		scrollUpBtnStyle.height = 4;
-		scrollUpBtnStyle.width = 8;
+		scrollUpBtnStyle.height = 11;
+		scrollUpBtnStyle.width = 13;
 
 		skin->setStyle("ScrollUpBtn", scrollUpBtnStyle);
 
@@ -411,8 +412,8 @@ namespace BansheeEngine
 		scrollDownBtnStyle.active.texture = getSkinTexture(ScrollBarDownActiveTex);
 		scrollDownBtnStyle.fixedHeight = true;
 		scrollDownBtnStyle.fixedWidth = true;
-		scrollDownBtnStyle.height = 4;
-		scrollDownBtnStyle.width = 8;
+		scrollDownBtnStyle.height = 11;
+		scrollDownBtnStyle.width = 13;
 
 		skin->setStyle("ScrollDownBtn", scrollDownBtnStyle);
 
@@ -423,8 +424,8 @@ namespace BansheeEngine
 		scrollLeftBtnStyle.active.texture = getSkinTexture(ScrollBarLeftActiveTex);
 		scrollLeftBtnStyle.fixedHeight = true;
 		scrollLeftBtnStyle.fixedWidth = true;
-		scrollLeftBtnStyle.height = 8;
-		scrollLeftBtnStyle.width = 4;
+		scrollLeftBtnStyle.height = 13;
+		scrollLeftBtnStyle.width = 11;
 
 		skin->setStyle("ScrollLeftBtn", scrollLeftBtnStyle);
 
@@ -435,8 +436,8 @@ namespace BansheeEngine
 		scrollRightBtnStyle.active.texture = getSkinTexture(ScrollBarRightActiveTex);
 		scrollRightBtnStyle.fixedHeight = true;
 		scrollRightBtnStyle.fixedWidth = true;
-		scrollRightBtnStyle.height = 8;
-		scrollRightBtnStyle.width = 4;
+		scrollRightBtnStyle.height = 13;
+		scrollRightBtnStyle.width = 11;
 
 		skin->setStyle("ScrollRightBtn", scrollRightBtnStyle);
 
@@ -446,9 +447,11 @@ namespace BansheeEngine
 		scrollBarHorzBtnStyle.hover.texture = getSkinTexture(ScrollBarHandleHorzHoverTex);
 		scrollBarHorzBtnStyle.active.texture = getSkinTexture(ScrollBarHandleHorzActiveTex);
 		scrollBarHorzBtnStyle.fixedHeight = true;
-		scrollBarHorzBtnStyle.fixedWidth = true;
-		scrollBarHorzBtnStyle.height = 6;
-		scrollBarHorzBtnStyle.width = 4;
+		scrollBarHorzBtnStyle.fixedWidth = false;
+		scrollBarHorzBtnStyle.width = 10;
+		scrollBarHorzBtnStyle.height = 13;
+		scrollBarHorzBtnStyle.border.left = 4;
+		scrollBarHorzBtnStyle.border.right = 4;
 
 		skin->setStyle("ScrollBarHorzBtn", scrollBarHorzBtnStyle);
 
@@ -457,36 +460,36 @@ namespace BansheeEngine
 		scrollBarVertBtnStyle.normal.texture = getSkinTexture(ScrollBarHandleVertNormalTex);
 		scrollBarVertBtnStyle.hover.texture = getSkinTexture(ScrollBarHandleVertHoverTex);
 		scrollBarVertBtnStyle.active.texture = getSkinTexture(ScrollBarHandleVertActiveTex);
-		scrollBarVertBtnStyle.fixedHeight = true;
+		scrollBarVertBtnStyle.fixedHeight = false;
 		scrollBarVertBtnStyle.fixedWidth = true;
-		scrollBarVertBtnStyle.height = 4;
-		scrollBarVertBtnStyle.width = 6;
+		scrollBarVertBtnStyle.width = 13;
+		scrollBarVertBtnStyle.height = 10;
+		scrollBarVertBtnStyle.border.top = 4;
+		scrollBarVertBtnStyle.border.bottom = 4;
 
 		skin->setStyle("ScrollBarVertBtn", scrollBarVertBtnStyle);
 
-		HSpriteTexture scrollBarBgPtr = getSkinTexture(ScrollBarBgTex);
-
 		// Vertical scroll bar
 		GUIElementStyle vertScrollBarStyle;
-		vertScrollBarStyle.normal.texture = scrollBarBgPtr;
-		vertScrollBarStyle.hover.texture = scrollBarBgPtr;
-		vertScrollBarStyle.active.texture = scrollBarBgPtr;
+		vertScrollBarStyle.normal.texture = getSkinTexture(ScrollBarVBgTex);
+		vertScrollBarStyle.hover.texture = vertScrollBarStyle.normal.texture;
+		vertScrollBarStyle.active.texture = vertScrollBarStyle.normal.texture;
 		vertScrollBarStyle.fixedHeight = false;
 		vertScrollBarStyle.fixedWidth = true;
-		vertScrollBarStyle.minHeight = 16;
-		vertScrollBarStyle.width = 8;
+		vertScrollBarStyle.minHeight = 8;
+		vertScrollBarStyle.width = 16;
 
 		skin->setStyle("ScrollBarVert", vertScrollBarStyle);
 
 		// Horizontal scroll bar
 		GUIElementStyle horzScrollBarStyle;
-		horzScrollBarStyle.normal.texture = scrollBarBgPtr;
-		horzScrollBarStyle.hover.texture = scrollBarBgPtr;
-		horzScrollBarStyle.active.texture = scrollBarBgPtr;
+		horzScrollBarStyle.normal.texture = getSkinTexture(ScrollBarHBgTex);
+		horzScrollBarStyle.hover.texture = horzScrollBarStyle.normal.texture;
+		horzScrollBarStyle.active.texture = horzScrollBarStyle.normal.texture;
 		horzScrollBarStyle.fixedHeight = true;
 		horzScrollBarStyle.fixedWidth = false;
-		horzScrollBarStyle.minWidth = 16;
-		horzScrollBarStyle.height = 8;
+		horzScrollBarStyle.minWidth = 8;
+		horzScrollBarStyle.height = 16;
 
 		skin->setStyle("ScrollBarHorz", horzScrollBarStyle);
 
@@ -528,78 +531,61 @@ namespace BansheeEngine
 
 		skin->setStyle("ListBox", dropDownListStyle);
 
-		// DropDown scroll up button arrow
-		GUIElementStyle dropDownScrollUpBtnArrowStyle;
-		dropDownScrollUpBtnArrowStyle.normal.texture = getSkinTexture(DropDownBoxBtnUpArrowTex);
-		dropDownScrollUpBtnArrowStyle.hover.texture = dropDownScrollUpBtnArrowStyle.normal.texture;
-		dropDownScrollUpBtnArrowStyle.active.texture = dropDownScrollUpBtnArrowStyle.hover.texture;
-		dropDownScrollUpBtnArrowStyle.fixedHeight = true;
-		dropDownScrollUpBtnArrowStyle.fixedWidth = false;
-		dropDownScrollUpBtnArrowStyle.height = 7;
-		dropDownScrollUpBtnArrowStyle.width = 30;
-		dropDownScrollUpBtnArrowStyle.border.left = 1;
-		dropDownScrollUpBtnArrowStyle.border.right = 1;
-		dropDownScrollUpBtnArrowStyle.border.top = 1;
-		dropDownScrollUpBtnArrowStyle.border.bottom = 1;
-
-		skin->setStyle("ListBoxScrollUpBtnArrow", dropDownScrollUpBtnArrowStyle);
-		skin->setStyle("MenuBarScrollUpBtnArrow", dropDownScrollUpBtnArrowStyle);
-		skin->setStyle("ContextMenuScrollUpBtnArrow", dropDownScrollUpBtnArrowStyle);
-
 		// DropDown scroll up button
 		GUIElementStyle dropDownScrollUpBtnStyle;
 		dropDownScrollUpBtnStyle.normal.texture = getSkinTexture(DropDownBoxBtnUpNormalTex);
 		dropDownScrollUpBtnStyle.hover.texture = getSkinTexture(DropDownBoxBtnUpHoverTex);
 		dropDownScrollUpBtnStyle.active.texture = dropDownScrollUpBtnStyle.hover.texture;
 		dropDownScrollUpBtnStyle.fixedHeight = true;
-		dropDownScrollUpBtnStyle.fixedWidth = false;
-		dropDownScrollUpBtnStyle.height = 7;
-		dropDownScrollUpBtnStyle.width = 30;
-		dropDownScrollUpBtnStyle.border.left = 1;
-		dropDownScrollUpBtnStyle.border.right = 1;
-		dropDownScrollUpBtnStyle.border.top = 1;
-		dropDownScrollUpBtnStyle.border.bottom = 1;
+		dropDownScrollUpBtnStyle.fixedWidth = true;
+		dropDownScrollUpBtnStyle.width = 8;
+		dropDownScrollUpBtnStyle.height = 12;
 
 		skin->setStyle("ListBoxScrollUpBtn", dropDownScrollUpBtnStyle);
 		skin->setStyle("MenuBarScrollUpBtn", dropDownScrollUpBtnStyle);
 		skin->setStyle("ContextMenuScrollUpBtn", dropDownScrollUpBtnStyle);
 
-		// DropDown scroll down button arrow
-		GUIElementStyle dropDownScrollDownBtnArrowStyle;
-		dropDownScrollDownBtnArrowStyle.normal.texture = getSkinTexture(DropDownBoxBtnDownArrowTex);
-		dropDownScrollDownBtnArrowStyle.hover.texture = dropDownScrollDownBtnArrowStyle.normal.texture;
-		dropDownScrollDownBtnArrowStyle.active.texture = dropDownScrollDownBtnArrowStyle.hover.texture;
-		dropDownScrollDownBtnArrowStyle.fixedHeight = true;
-		dropDownScrollDownBtnArrowStyle.fixedWidth = false;
-		dropDownScrollDownBtnArrowStyle.height = 7;
-		dropDownScrollDownBtnArrowStyle.width = 30;
-		dropDownScrollDownBtnArrowStyle.border.left = 1;
-		dropDownScrollDownBtnArrowStyle.border.right = 1;
-		dropDownScrollDownBtnArrowStyle.border.top = 1;
-		dropDownScrollDownBtnArrowStyle.border.bottom = 1;
-
-		skin->setStyle("ListBoxScrollDownBtnArrow", dropDownScrollDownBtnArrowStyle);
-		skin->setStyle("MenuBarScrollDownBtnArrow", dropDownScrollDownBtnArrowStyle);
-		skin->setStyle("ContextMenuScrollDownBtnArrow", dropDownScrollDownBtnArrowStyle);
-
 		// DropDown scroll down button
 		GUIElementStyle dropDownScrollDownBtnStyle;
 		dropDownScrollDownBtnStyle.normal.texture = getSkinTexture(DropDownBoxBtnDownNormalTex);
 		dropDownScrollDownBtnStyle.hover.texture = getSkinTexture(DropDownBoxBtnDownHoverTex);
 		dropDownScrollDownBtnStyle.active.texture = dropDownScrollDownBtnStyle.hover.texture;
 		dropDownScrollDownBtnStyle.fixedHeight = true;
-		dropDownScrollDownBtnStyle.fixedWidth = false;
-		dropDownScrollDownBtnStyle.height = 7;
-		dropDownScrollDownBtnStyle.width = 30;
-		dropDownScrollDownBtnStyle.border.left = 1;
-		dropDownScrollDownBtnStyle.border.right = 1;
-		dropDownScrollDownBtnStyle.border.top = 1;
-		dropDownScrollDownBtnStyle.border.bottom = 1;
+		dropDownScrollDownBtnStyle.fixedWidth = true;
+		dropDownScrollDownBtnStyle.width = 8;
+		dropDownScrollDownBtnStyle.height = 12;
 
 		skin->setStyle("ListBoxScrollDownBtn", dropDownScrollDownBtnStyle);
 		skin->setStyle("MenuBarScrollDownBtn", dropDownScrollDownBtnStyle);
 		skin->setStyle("ContextMenuScrollDownBtn", dropDownScrollDownBtnStyle);
 
+		// DropDown handle
+		GUIElementStyle dropDownScrollHandleStyle;
+		dropDownScrollHandleStyle.normal.texture = getSkinTexture(DropDownBoxHandleTex);
+		dropDownScrollHandleStyle.fixedHeight = false;
+		dropDownScrollHandleStyle.fixedWidth = true;
+		dropDownScrollHandleStyle.height = 8;
+		dropDownScrollHandleStyle.width = 8;
+
+		skin->setStyle("ListBoxHandle", dropDownScrollHandleStyle);
+		skin->setStyle("MenuBarHandle", dropDownScrollHandleStyle);
+		skin->setStyle("ContextMenuHandle", dropDownScrollHandleStyle);
+
+		// DropDown sidebar background
+		GUIElementStyle dropDownSidebarBg;
+		dropDownSidebarBg.normal.texture = getSkinTexture(DropDownBoxSideBgTex);
+		dropDownSidebarBg.fixedHeight = false;
+		dropDownSidebarBg.fixedWidth = true;
+		dropDownSidebarBg.height = 8;
+		dropDownSidebarBg.width = 9;
+		dropDownSidebarBg.border.left = 1;
+		dropDownSidebarBg.border.top = 1;
+		dropDownSidebarBg.border.bottom = 1;
+
+		skin->setStyle("ListBoxSidebarBg", dropDownSidebarBg);
+		skin->setStyle("MenuBarSidebarBg", dropDownSidebarBg);
+		skin->setStyle("ContextMenuSidebarBg", dropDownSidebarBg);
+
 		// DropDown entry button
 		GUIElementStyle dropDownEntryBtnStyle;
 		dropDownEntryBtnStyle.normal.texture = getSkinTexture(DropDownBoxEntryNormalTex);
@@ -616,16 +602,12 @@ namespace BansheeEngine
 		dropDownEntryBtnStyle.activeOn.textColor = TextNormalColor;
 		dropDownEntryBtnStyle.fixedHeight = true;
 		dropDownEntryBtnStyle.fixedWidth = false;
-		dropDownEntryBtnStyle.height = 14;
+		dropDownEntryBtnStyle.height = 16;
 		dropDownEntryBtnStyle.width = 30;
-		dropDownEntryBtnStyle.border.left = 1;
-		dropDownEntryBtnStyle.border.right = 1;
-		dropDownEntryBtnStyle.border.top = 1;
-		dropDownEntryBtnStyle.border.bottom = 1;
 		dropDownEntryBtnStyle.font = font;
 		dropDownEntryBtnStyle.fontSize = DefaultFontSize;
 		dropDownEntryBtnStyle.textHorzAlign = THA_Left;
-		dropDownEntryBtnStyle.textVertAlign = TVA_Top;
+		dropDownEntryBtnStyle.textVertAlign = TVA_Center;
 
 		skin->setStyle(GUIDropDownContent::ENTRY_STYLE_TYPE, dropDownEntryBtnStyle);
 
@@ -645,16 +627,13 @@ namespace BansheeEngine
 		dropDownEntryExpBtnStyle.activeOn.textColor = TextNormalColor;
 		dropDownEntryExpBtnStyle.fixedHeight = true;
 		dropDownEntryExpBtnStyle.fixedWidth = false;
-		dropDownEntryExpBtnStyle.height = 14;
+		dropDownEntryExpBtnStyle.height = 16;
 		dropDownEntryExpBtnStyle.width = 30;
-		dropDownEntryExpBtnStyle.border.left = 1;
-		dropDownEntryExpBtnStyle.border.right = 6;
-		dropDownEntryExpBtnStyle.border.top = 1;
-		dropDownEntryExpBtnStyle.border.bottom = 1;
+		dropDownEntryExpBtnStyle.border.right = 13;
 		dropDownEntryExpBtnStyle.font = font;
 		dropDownEntryExpBtnStyle.fontSize = DefaultFontSize;
 		dropDownEntryExpBtnStyle.textHorzAlign = THA_Left;
-		dropDownEntryExpBtnStyle.textVertAlign = TVA_Top;
+		dropDownEntryExpBtnStyle.textVertAlign = TVA_Center;
 
 		skin->setStyle(GUIDropDownContent::ENTRY_EXP_STYLE_TYPE, dropDownEntryExpBtnStyle);
 
@@ -665,10 +644,6 @@ namespace BansheeEngine
 		dropDownSeparatorStyle.fixedWidth = false;
 		dropDownSeparatorStyle.height = 3;
 		dropDownSeparatorStyle.width = 30;
-		dropDownSeparatorStyle.border.left = 1;
-		dropDownSeparatorStyle.border.right = 1;
-		dropDownSeparatorStyle.border.top = 1;
-		dropDownSeparatorStyle.border.bottom = 1;
 
 		skin->setStyle(GUIDropDownContent::SEPARATOR_STYLE_TYPE, dropDownSeparatorStyle);
 
@@ -687,18 +662,18 @@ namespace BansheeEngine
 		// DropDown box frame
 		GUIElementStyle dropDownBoxStyle;
 		dropDownBoxStyle.normal.texture = getSkinTexture(DropDownBoxBgTex);
-		dropDownBoxStyle.hover.texture = dropDownEntryBtnStyle.normal.texture;
-		dropDownBoxStyle.active.texture = dropDownEntryBtnStyle.hover.texture;
+		dropDownBoxStyle.hover.texture = dropDownBoxStyle.normal.texture;
+		dropDownBoxStyle.active.texture = dropDownBoxStyle.hover.texture;
 		dropDownBoxStyle.fixedHeight = false;
 		dropDownBoxStyle.fixedWidth = false;
-		dropDownBoxStyle.border.left = 1;
-		dropDownBoxStyle.border.right = 1;
-		dropDownBoxStyle.border.top = 1;
-		dropDownBoxStyle.border.bottom = 1;
-		dropDownBoxStyle.margins.left = 1;
-		dropDownBoxStyle.margins.right = 1;
-		dropDownBoxStyle.margins.top = 1;
-		dropDownBoxStyle.margins.bottom = 1;
+		dropDownBoxStyle.border.left = 2;
+		dropDownBoxStyle.border.right = 2;
+		dropDownBoxStyle.border.top = 2;
+		dropDownBoxStyle.border.bottom = 4;
+		dropDownBoxStyle.margins.left = 6;
+		dropDownBoxStyle.margins.right = 6;
+		dropDownBoxStyle.margins.top = 4;
+		dropDownBoxStyle.margins.bottom = 6;
 
 		skin->setStyle("ListBoxFrame", dropDownBoxStyle);
 		skin->setStyle("MenuBarFrame", dropDownBoxStyle);

+ 63 - 66
BansheeEngine/Source/BsGUIDropDownMenu.cpp

@@ -74,9 +74,8 @@ namespace BansheeEngine
 		mScrollDownStyle = stylePrefix + "ScrollDownBtn";
 		mBackgroundStyle = stylePrefix + "Frame";
 		mContentStyle = stylePrefix + "Content";
-
-		mScrollUpBtnArrow = desc.skin->getStyle(stylePrefix + "ScrollUpBtnArrow")->normal.texture;
-		mScrollDownBtnArrow = desc.skin->getStyle(stylePrefix + "ScrollDownBtnArrow")->normal.texture;
+		mSideBackgroundStyle = stylePrefix + "SidebarBg";
+		mHandleStyle = stylePrefix + "Handle";
 
 		setDepth(0); // Needs to be in front of everything
 		setSkin(desc.skin);
@@ -182,14 +181,13 @@ namespace BansheeEngine
 	GUIDropDownMenu::DropDownSubMenu::DropDownSubMenu(GUIDropDownMenu* owner, DropDownSubMenu* parent, const DropDownAreaPlacement& placement,
 		const Rect2I& availableBounds, const GUIDropDownData& dropDownData, GUIDropDownType type, UINT32 depthOffset)
 		:mOwner(owner), mParent(parent), mPage(0), mBackgroundFrame(nullptr), mBackgroundPanel(nullptr), mContentPanel(nullptr),
-		mContentLayout(nullptr), mScrollUpBtn(nullptr), mScrollDownBtn(nullptr), x(0), y(0), width(0), height(0), 
-		mType(type), mSubMenu(nullptr), mData(dropDownData), mOpenedUpward(false), mDepthOffset(depthOffset), mContent(nullptr)
+		mContentLayout(nullptr), x(0), y(0), width(0), height(0), mSidebarPanel(nullptr), mType(type), mSubMenu(nullptr), 
+		mData(dropDownData), mOpenedUpward(false), mDepthOffset(depthOffset), mContent(nullptr)
 	{
 		mAvailableBounds = availableBounds;
 
-		const GUIElementStyle* scrollUpStyle = mOwner->getSkin().getStyle(mOwner->mScrollUpStyle);
-		const GUIElementStyle* scrollDownStyle = mOwner->getSkin().getStyle(mOwner->mScrollDownStyle);
 		const GUIElementStyle* backgroundStyle = mOwner->getSkin().getStyle(mOwner->mBackgroundStyle);
+		const GUIElementStyle* sideBarStyle = mOwner->getSkin().getStyle(mOwner->mSideBackgroundStyle);
 
 		// Create content GUI element
 		mContent = GUIDropDownContent::create(this, dropDownData, mOwner->mContentStyle);
@@ -216,17 +214,16 @@ namespace BansheeEngine
 		mContentLayout->addElement(mContent); // Note: It's important this is added to the layout before we 
 		// use it for size calculations, in order for its skin to be assigned
 
-		UINT32 helperElementHeight = scrollUpStyle->height + scrollDownStyle->height +
-			backgroundStyle->margins.top + backgroundStyle->margins.bottom;
+		UINT32 dropDownBoxWidth = DROP_DOWN_BOX_WIDTH + sideBarStyle->width;
 
-		UINT32 maxNeededHeight = helperElementHeight;
+		UINT32 maxNeededHeight = backgroundStyle->margins.top + backgroundStyle->margins.bottom;
 		UINT32 numElements = (UINT32)dropDownData.entries.size();
 		for (UINT32 i = 0; i < numElements; i++)
 			maxNeededHeight += mContent->getElementHeight(i);
 
 		DropDownAreaPlacement::HorzDir horzDir;
 		DropDownAreaPlacement::VertDir vertDir;
-		Rect2I placementBounds = placement.getOptimalBounds(DROP_DOWN_BOX_WIDTH, maxNeededHeight, availableBounds, horzDir, vertDir);
+		Rect2I placementBounds = placement.getOptimalBounds(dropDownBoxWidth, maxNeededHeight, availableBounds, horzDir, vertDir);
 
 		mOpenedUpward = vertDir == DropDownAreaPlacement::VertDir::Up;
 
@@ -256,22 +253,17 @@ namespace BansheeEngine
 
 		GUIElement::destroy(mContent);
 
-		if (mScrollUpBtn != nullptr)
-			GUIElement::destroy(mScrollUpBtn);
-
-		if (mScrollDownBtn != nullptr)
-			GUIElement::destroy(mScrollDownBtn);
-
 		GUIElement::destroy(mBackgroundFrame);
 
 		GUILayout::destroy(mBackgroundPanel);
 		GUILayout::destroy(mContentPanel);
+
+		if (mSidebarPanel != nullptr)
+			GUIPanel::destroy(mSidebarPanel);
 	}
 
 	Vector<GUIDropDownMenu::DropDownSubMenu::PageInfo> GUIDropDownMenu::DropDownSubMenu::getPageInfos() const
 	{
-		const GUIElementStyle* scrollUpStyle = mOwner->getSkin().getStyle(mOwner->mScrollUpStyle);
-		const GUIElementStyle* scrollDownStyle = mOwner->getSkin().getStyle(mOwner->mScrollDownStyle);
 		const GUIElementStyle* backgroundStyle = mOwner->getSkin().getStyle(mOwner->mBackgroundStyle);
 
 		INT32 numElements = (INT32)mData.entries.size();
@@ -290,8 +282,6 @@ namespace BansheeEngine
 
 			if (curPageInfo.height > height)
 			{
-				curPageInfo.height += scrollDownStyle->height;
-
 				// Remove last few elements until we fit again
 				while (curPageInfo.height > height && i >= 0)
 				{
@@ -309,7 +299,6 @@ namespace BansheeEngine
 
 				curPageInfo.start = curPageInfo.end;
 				curPageInfo.height = backgroundStyle->margins.top + backgroundStyle->margins.bottom;
-				curPageInfo.height += scrollUpStyle->height;
 
 				curPageInfo.idx++;
 			}
@@ -329,87 +318,95 @@ namespace BansheeEngine
 
 		mContentLayout->addElement(mContent); // Note: Needs to be added first so that size calculations have proper skin to work with
 
+		const GUIElementStyle* backgroundStyle = mOwner->getSkin().getStyle(mOwner->mBackgroundStyle);
+		const GUIElementStyle* sideBarStyle = mOwner->getSkin().getStyle(mOwner->mSideBackgroundStyle);
 		const GUIElementStyle* scrollUpStyle = mOwner->getSkin().getStyle(mOwner->mScrollUpStyle);
 		const GUIElementStyle* scrollDownStyle = mOwner->getSkin().getStyle(mOwner->mScrollDownStyle);
-		const GUIElementStyle* backgroundStyle = mOwner->getSkin().getStyle(mOwner->mBackgroundStyle);
+		const GUIElementStyle* handleStyle = mOwner->getSkin().getStyle(mOwner->mHandleStyle);
 
-		// Determine if we need scroll up and/or down buttons, number of visible elements and actual height
-		bool needsScrollUp = mPage > 0;
+		Vector<PageInfo> pageInfos = getPageInfos();
 
 		UINT32 pageStart = 0, pageEnd = 0;
 		UINT32 pageHeight = 0;
-		Vector<PageInfo> pageInfos = getPageInfos();
-
-		if (pageInfos.size() > mPage)
+		UINT32 pageCount = (UINT32)pageInfos.size();
+		if (pageCount > mPage)
 		{
 			pageStart = pageInfos[mPage].start;
 			pageEnd = pageInfos[mPage].end;
 			pageHeight = pageInfos[mPage].height;
 		}
 
-		UINT32 numElements = (UINT32)mData.entries.size();
-		bool needsScrollDown = pageEnd != numElements;
+		INT32 actualY = y;
 
-		// Add scroll up button
-		if(needsScrollUp)
-		{
-			if(mScrollUpBtn == nullptr)
-			{
-				mScrollUpBtn = GUIButton::create(GUIContent(HString(L""), mOwner->mScrollUpBtnArrow), mOwner->mScrollUpStyle);
-				mScrollUpBtn->onClick.connect(std::bind(&DropDownSubMenu::scrollUp, this));
-			}
+		if (mOpenedUpward)
+			actualY -= (INT32)pageHeight;
 
-			mContentLayout->insertElement(0, mScrollUpBtn);			
-		}
-		else
+		// Add sidebar if needed
+		UINT32 contentOffset = 0;
+		if (pageInfos.size() > 1)
 		{
-			if(mScrollUpBtn != nullptr)
+			UINT32 sidebarHeight = pageHeight - 2;
+			contentOffset = sideBarStyle->width;
+
+			if (mSidebarPanel == nullptr)
 			{
-				GUIElement::destroy(mScrollUpBtn);
-				mScrollUpBtn = nullptr;
-			}
-		}
+				mSidebarPanel = mOwner->getPanel()->addNewElement<GUIPanel>();
 
-		mContent->setRange(pageStart, pageEnd);
+				mScrollUpBtn = GUIButton::create(HString(L""), mOwner->mScrollUpStyle);
+				mScrollUpBtn->onClick.connect(std::bind(&DropDownSubMenu::scrollUp, this));
 
-		// Add scroll down button
-		if(needsScrollDown)
-		{
-			if(mScrollDownBtn == nullptr)
-			{
-				mScrollDownBtn = GUIButton::create(GUIContent(HString(L""), mOwner->mScrollDownBtnArrow), mOwner->mScrollDownStyle);
+				mScrollDownBtn = GUIButton::create(HString(L""), mOwner->mScrollDownStyle);
 				mScrollDownBtn->onClick.connect(std::bind(&DropDownSubMenu::scrollDown, this));
+
+				mHandle = GUITexture::create(mOwner->mHandleStyle);
+				GUITexture* background = GUITexture::create(mOwner->mSideBackgroundStyle);
+				background->_setElementDepth(2);
+
+				mSidebarPanel->addElement(background);
+				mSidebarPanel->addElement(mScrollUpBtn);
+				mSidebarPanel->addElement(mScrollDownBtn);
+				mSidebarPanel->addElement(mHandle);
 			}
 
-			mContentLayout->addElement(mScrollDownBtn);			
+			mScrollUpBtn->setPosition(1, 1);
+			mScrollDownBtn->setPosition(1, sidebarHeight - 1 - scrollDownStyle->height);
+
+			UINT32 maxHandleSize = std::max(0, (INT32)sidebarHeight - (INT32)scrollDownStyle->height - (INT32)scrollUpStyle->height - 2);
+			UINT32 handleSize = maxHandleSize / pageCount;
+
+			INT32 handlePos = 1 + scrollUpStyle->height + mPage * handleSize;
+
+			mHandle->setPosition(1, handlePos);
+			mHandle->setHeight(handleSize);
+
+			mSidebarPanel->setPosition(x, actualY);
+			mSidebarPanel->setWidth(sideBarStyle->width);
+			mSidebarPanel->setHeight(sidebarHeight);
 		}
 		else
 		{
-			if(mScrollDownBtn != nullptr)
+			if (mSidebarPanel != nullptr)
 			{
-				GUIElement::destroy(mScrollDownBtn);
-				mScrollDownBtn = nullptr;
+				GUIPanel::destroy(mSidebarPanel);
+				mSidebarPanel = nullptr;
 			}
 		}
-		
-		// Resize and reposition areas
-		INT32 actualY = y;
 
-		if(mOpenedUpward)	
-			actualY -= (INT32)pageHeight;
+		mContent->setRange(pageStart, pageEnd);
 
-		mBackgroundPanel->setWidth(width);
+		// Resize and reposition areas
+		mBackgroundPanel->setWidth(width - contentOffset);
 		mBackgroundPanel->setHeight(pageHeight);
-		mBackgroundPanel->setPosition(x, actualY);
+		mBackgroundPanel->setPosition(x + contentOffset, actualY);
 
 		mVisibleBounds = Rect2I(x, actualY, width, pageHeight);
 
-		UINT32 contentWidth = (UINT32)std::max(0, (INT32)width - (INT32)backgroundStyle->margins.left - (INT32)backgroundStyle->margins.right);
+		UINT32 contentWidth = (UINT32)std::max(0, (INT32)width - (INT32)backgroundStyle->margins.left - (INT32)backgroundStyle->margins.right - (INT32)contentOffset);
 		UINT32 contentHeight = (UINT32)std::max(0, (INT32)pageHeight - (INT32)backgroundStyle->margins.top - (INT32)backgroundStyle->margins.bottom);
 
 		mContentPanel->setWidth(contentWidth);
 		mContentPanel->setHeight(contentHeight);
-		mContentPanel->setPosition(x + backgroundStyle->margins.left, actualY + backgroundStyle->margins.top);
+		mContentPanel->setPosition(x + contentOffset + backgroundStyle->margins.left, actualY + backgroundStyle->margins.top);
 	}
 
 	void GUIDropDownMenu::DropDownSubMenu::scrollDown()

+ 28 - 15
BansheeEngine/Source/BsGUIMenu.cpp

@@ -5,17 +5,19 @@ namespace BansheeEngine
 {
 	bool GUIMenuItemComparer::operator() (const GUIMenuItem* const& a, const GUIMenuItem* const& b)
 	{
-		return a->mPriority > b->mPriority || (a->mPriority == b->mPriority && a->mName.compare(b->mName) < 0);
+		return a->mPriority > b->mPriority || (a->mPriority == b->mPriority && a->mSeqIdx < b->mSeqIdx);
 	}
 
-	GUIMenuItem::GUIMenuItem(GUIMenuItem* parent, const WString& name, std::function<void()> callback, INT32 priority, const ShortcutKey& key)
-		:mParent(parent), mName(name), mCallback(callback), mIsSeparator(false), mPriority(priority), mShortcut(key)
+	GUIMenuItem::GUIMenuItem(GUIMenuItem* parent, const WString& name, std::function<void()> callback, 
+		INT32 priority, UINT32 seqIdx, const ShortcutKey& key)
+		:mParent(parent), mName(name), mCallback(callback), mIsSeparator(false), mPriority(priority), 
+		mShortcut(key), mSeqIdx(seqIdx)
 	{
 
 	}
 
-	GUIMenuItem::GUIMenuItem(GUIMenuItem* parent, INT32 priority)
-		: mParent(parent), mCallback(nullptr), mIsSeparator(true), mPriority(priority)
+	GUIMenuItem::GUIMenuItem(GUIMenuItem* parent, INT32 priority, UINT32 seqIdx)
+		: mParent(parent), mCallback(nullptr), mIsSeparator(true), mPriority(priority), mSeqIdx(seqIdx)
 	{
 
 	}
@@ -57,8 +59,19 @@ namespace BansheeEngine
 		}
 	}
 
+	void GUIMenuItem::removeChild(const GUIMenuItem* item)
+	{
+		auto iterFind = std::find(begin(mChildren), end(mChildren), item);
+
+		if (iterFind != mChildren.end())
+		{
+			bs_delete(*iterFind);
+			mChildren.erase(iterFind);
+		}
+	}
+
 	GUIMenu::GUIMenu()
-		:mRootElement(nullptr, L"", nullptr, 0, ShortcutKey::NONE)
+		:mRootElement(nullptr, L"", nullptr, 0, 0, ShortcutKey::NONE), mNextIdx(0)
 	{
 
 	}
@@ -68,17 +81,17 @@ namespace BansheeEngine
 
 	}
 
-	const GUIMenuItem* GUIMenu::addMenuItem(const WString& path, std::function<void()> callback, INT32 priority, const ShortcutKey& key)
+	GUIMenuItem* GUIMenu::addMenuItem(const WString& path, std::function<void()> callback, INT32 priority, const ShortcutKey& key)
 	{
 		return addMenuItemInternal(path, callback, false, priority, key);
 	}
 
-	const GUIMenuItem* GUIMenu::addSeparator(const WString& path, INT32 priority)
+	GUIMenuItem* GUIMenu::addSeparator(const WString& path, INT32 priority)
 	{
 		return addMenuItemInternal(path, nullptr, true, priority, ShortcutKey::NONE);
 	}
 
-	const GUIMenuItem* GUIMenu::addMenuItemInternal(const WString& path, std::function<void()> callback, bool isSeparator, 
+	GUIMenuItem* GUIMenu::addMenuItemInternal(const WString& path, std::function<void()> callback, bool isSeparator, 
 		INT32 priority, const ShortcutKey& key)
 	{
 		Vector<WString> pathElements = StringUtil::split(path, L"/");
@@ -97,11 +110,11 @@ namespace BansheeEngine
 				bool isLastElem = i == (UINT32)(pathElements.size() - 1);
 
 				if(isLastElem)
-					existingItem = bs_new<GUIMenuItem>(curSubMenu, pathElem, callback, priority, key);
+					existingItem = bs_new<GUIMenuItem>(curSubMenu, pathElem, callback, priority, mNextIdx++, key);
 				else
 				{
 					existingItem = bs_alloc<GUIMenuItem>();
-					existingItem = new (existingItem)GUIMenuItem(curSubMenu, pathElem, nullptr, 0, ShortcutKey::NONE);
+					existingItem = new (existingItem)GUIMenuItem(curSubMenu, pathElem, nullptr, 0, mNextIdx++, ShortcutKey::NONE);
 				}
 
 				curSubMenu->addChild(existingItem);
@@ -112,7 +125,7 @@ namespace BansheeEngine
 
 		if(isSeparator)
 		{
-			GUIMenuItem* separatorItem = bs_new<GUIMenuItem>(curSubMenu, priority);
+			GUIMenuItem* separatorItem = bs_new<GUIMenuItem>(curSubMenu, priority, mNextIdx++);
 			curSubMenu->addChild(separatorItem);
 
 			return separatorItem;
@@ -121,15 +134,15 @@ namespace BansheeEngine
 		return curSubMenu;
 	}
 
-	const GUIMenuItem* GUIMenu::getMenuItem(const WString& path) const
+	GUIMenuItem* GUIMenu::getMenuItem(const WString& path)
 	{
 		Vector<WString> pathElements = StringUtil::split(path, L"/");
 
-		const GUIMenuItem* curSubMenu = &mRootElement;
+		GUIMenuItem* curSubMenu = &mRootElement;
 		for(UINT32 i = 0; i < (UINT32)pathElements.size(); i++)
 		{
 			const WString& pathElem = *(pathElements.begin() + i);
-			const GUIMenuItem* existingItem = curSubMenu->findChild(pathElem);
+			GUIMenuItem* existingItem = curSubMenu->findChild(pathElem);
 
 			if(existingItem == nullptr || existingItem->isSeparator())
 				return nullptr;

+ 5 - 0
MBansheeEditor/EditorBuiltin.cs

@@ -17,6 +17,8 @@ namespace BansheeEditor
         public static SpriteTexture SpriteTextureIcon { get { return Internal_GetSpriteTextureIcon(); } }
         public static SpriteTexture PrefabIcon { get { return Internal_GetPrefabIcon(); } }
 
+        public static SpriteTexture XBtnIcon { get { return Internal_GetXBtnIcon(); } }
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern SpriteTexture Internal_GetFolderIcon();
 
@@ -49,5 +51,8 @@ namespace BansheeEditor
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern SpriteTexture Internal_GetPrefabIcon();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern SpriteTexture Internal_GetXBtnIcon();
     }
 }

+ 0 - 7
MBansheeEditor/GUI/GUIComponentFoldout.cs

@@ -7,7 +7,6 @@ namespace BansheeEditor
     public sealed class GUIComponentFoldout : GUIElement
     {
         public event Action<bool> OnToggled;
-        public event Action OnRemoveClicked;
 
         public GUIComponentFoldout(GUIContent content, string style, params GUIOption[] options)
         {
@@ -52,12 +51,6 @@ namespace BansheeEditor
                 OnToggled(expanded);
         }
 
-        private void DoOnRemoveClicked()
-        {
-            if (OnRemoveClicked != null)
-                OnRemoveClicked();
-        }
-
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_CreateInstance(GUIComponentFoldout instance, GUIContent content, string style, GUIOption[] options);
 

+ 1 - 1
MBansheeEditor/Inspector/GenericInspector.cs

@@ -23,7 +23,7 @@ namespace BansheeEditor
                     if (!field.Inspectable)
                         continue;
 
-                    inspectableFields.Add(InspectableField.CreateInspectable(field.Name, new InspectableFieldLayout(layout), field.GetProperty()));
+                    inspectableFields.Add(InspectableField.CreateInspectable(field.Name, 0, new InspectableFieldLayout(layout), field.GetProperty()));
                 }
             }
 

+ 3 - 3
MBansheeEditor/Inspector/InspectableArray.cs

@@ -73,8 +73,8 @@ namespace BansheeEditor
 
         private bool forceUpdate = true;
 
-        public InspectableArray(string title, InspectableFieldLayout layout, SerializableProperty property)
-            : base(title, layout, property)
+        public InspectableArray(string title, int depth, InspectableFieldLayout layout, SerializableProperty property)
+            : base(title, depth, layout, property)
         {
 
         }
@@ -196,7 +196,7 @@ namespace BansheeEditor
                         EntryRow newRow = new EntryRow(guiContentLayout);
                         rows.Add(newRow);
 
-                        InspectableField childObj = CreateInspectable(i + ".", new InspectableFieldLayout(newRow.contentLayout), array.GetProperty(i));
+                        InspectableField childObj = CreateInspectable(i + ".", depth + 1, new InspectableFieldLayout(newRow.contentLayout), array.GetProperty(i));
                         AddChild(childObj);
 
                         childObj.Refresh(0);

+ 2 - 2
MBansheeEditor/Inspector/InspectableBool.cs

@@ -13,8 +13,8 @@ namespace BansheeEditor
         private GUIToggleField guiField;
         private bool isInitialized;
 
-        public InspectableBool(string title, InspectableFieldLayout layout, SerializableProperty property)
-            : base(title, layout, property)
+        public InspectableBool(string title, int depth, InspectableFieldLayout layout, SerializableProperty property)
+            : base(title, depth, layout, property)
         {
 
         }

+ 2 - 2
MBansheeEditor/Inspector/InspectableColor.cs

@@ -13,8 +13,8 @@ namespace BansheeEditor
         private GUIColorField guiField;
         private bool isInitialized;
 
-        public InspectableColor(string title, InspectableFieldLayout layout, SerializableProperty property)
-            : base(title, layout, property)
+        public InspectableColor(string title, int depth, InspectableFieldLayout layout, SerializableProperty property)
+            : base(title, depth, layout, property)
         {
 
         }

+ 18 - 16
MBansheeEditor/Inspector/InspectableField.cs

@@ -15,12 +15,14 @@ namespace BansheeEditor
         protected InspectableFieldLayout layout;
         protected SerializableProperty property;
         protected string title;
+        protected int depth;
 
-        public InspectableField(string title, InspectableFieldLayout layout, SerializableProperty property)
+        public InspectableField(string title, int depth, InspectableFieldLayout layout, SerializableProperty property)
         {
             this.layout = layout;
             this.title = title;
             this.property = property;
+            this.depth = depth;
         }
 
         protected void AddChild(InspectableField child)
@@ -112,42 +114,42 @@ namespace BansheeEditor
                 parent.RemoveChild(this);
         }
 
-        public static InspectableField CreateInspectable(string title, InspectableFieldLayout layout, SerializableProperty property)
+        public static InspectableField CreateInspectable(string title, int depth, InspectableFieldLayout layout, SerializableProperty property)
         {
             Type customInspectable = InspectorUtility.GetCustomInspectable(property.InternalType);
             if (customInspectable != null)
             {
-                return (InspectableField)Activator.CreateInstance(customInspectable, title, property);
+                return (InspectableField)Activator.CreateInstance(customInspectable, depth, title, property);
             }
 
             switch (property.Type)
             {
                 case SerializableProperty.FieldType.Int:
-                    return new InspectableInt(title, layout, property);
+                    return new InspectableInt(title, depth, layout, property);
                 case SerializableProperty.FieldType.Float:
-                    return new InspectableFloat(title, layout, property);
+                    return new InspectableFloat(title, depth, layout, property);
                 case SerializableProperty.FieldType.Bool:
-                    return new InspectableBool(title, layout, property);
+                    return new InspectableBool(title, depth, layout, property);
                 case SerializableProperty.FieldType.Color:
-                    return new InspectableColor(title, layout, property);
+                    return new InspectableColor(title, depth, layout, property);
                 case SerializableProperty.FieldType.String:
-                    return new InspectableString(title, layout, property);
+                    return new InspectableString(title, depth, layout, property);
                 case SerializableProperty.FieldType.Vector2:
-                    return new InspectableVector2(title, layout, property);
+                    return new InspectableVector2(title, depth, layout, property);
                 case SerializableProperty.FieldType.Vector3:
-                    return new InspectableVector3(title, layout, property);
+                    return new InspectableVector3(title, depth, layout, property);
                 case SerializableProperty.FieldType.Vector4:
-                    return new InspectableVector4(title, layout, property);
+                    return new InspectableVector4(title, depth, layout, property);
                 case SerializableProperty.FieldType.ResourceRef:
-                    return new InspectableResourceRef(title, layout, property);
+                    return new InspectableResourceRef(title, depth, layout, property);
                 case SerializableProperty.FieldType.GameObjectRef:
-                    return new InspectableGameObjectRef(title, layout, property);
+                    return new InspectableGameObjectRef(title, depth, layout, property);
                 case SerializableProperty.FieldType.Object:
-                    return new InspectableObject(title, layout, property);
+                    return new InspectableObject(title, depth, layout, property);
                 case SerializableProperty.FieldType.Array:
-                    return new InspectableArray(title, layout, property);
+                    return new InspectableArray(title, depth, layout, property);
                 case SerializableProperty.FieldType.List:
-                    return new InspectableList(title, layout, property);
+                    return new InspectableList(title, depth, layout, property);
             }
 
             throw new Exception("No inspector exists for the provided field type.");

+ 2 - 2
MBansheeEditor/Inspector/InspectableFloat.cs

@@ -13,8 +13,8 @@ namespace BansheeEditor
         private GUIFloatField guiFloatField;
         private bool isInitialized;
 
-        public InspectableFloat(string title, InspectableFieldLayout layout, SerializableProperty property)
-            : base(title, layout, property)
+        public InspectableFloat(string title, int depth, InspectableFieldLayout layout, SerializableProperty property)
+            : base(title, depth, layout, property)
         {
 
         }

+ 2 - 2
MBansheeEditor/Inspector/InspectableGameObjectRef.cs

@@ -13,8 +13,8 @@ namespace BansheeEditor
         private GUIGameObjectField guiField;
         private bool isInitialized;
 
-        public InspectableGameObjectRef(string title, InspectableFieldLayout layout, SerializableProperty property)
-            : base(title, layout, property)
+        public InspectableGameObjectRef(string title, int depth, InspectableFieldLayout layout, SerializableProperty property)
+            : base(title, depth, layout, property)
         {
 
         }

+ 2 - 2
MBansheeEditor/Inspector/InspectableInt.cs

@@ -13,8 +13,8 @@ namespace BansheeEditor
         private GUIIntField guiIntField;
         private bool isInitialized;
 
-        public InspectableInt(string title, InspectableFieldLayout layout, SerializableProperty property)
-            : base(title, layout, property)
+        public InspectableInt(string title, int depth, InspectableFieldLayout layout, SerializableProperty property)
+            : base(title, depth, layout, property)
         {
 
         }

+ 3 - 3
MBansheeEditor/Inspector/InspectableList.cs

@@ -73,8 +73,8 @@ namespace BansheeEditor
         private bool forceUpdate = true;
         private bool isExpanded;
 
-        public InspectableList(string title, InspectableFieldLayout layout, SerializableProperty property)
-            : base(title, layout, property)
+        public InspectableList(string title, int depth, InspectableFieldLayout layout, SerializableProperty property)
+            : base(title, depth, layout, property)
         {
 
         }
@@ -196,7 +196,7 @@ namespace BansheeEditor
                         EntryRow newRow = new EntryRow(guiContentLayout);
                         rows.Add(newRow);
 
-                        InspectableField childObj = CreateInspectable(i + ".", new InspectableFieldLayout(newRow.contentLayout), list.GetProperty(i));
+                        InspectableField childObj = CreateInspectable(i + ".", depth + 1, new InspectableFieldLayout(newRow.contentLayout), list.GetProperty(i));
                         AddChild(childObj);
 
                         childObj.Refresh(0);

+ 3 - 3
MBansheeEditor/Inspector/InspectableObject.cs

@@ -18,8 +18,8 @@ namespace BansheeEditor
         private bool isExpanded;
         private bool forceUpdate = true;
 
-        public InspectableObject(string title, InspectableFieldLayout layout, SerializableProperty property)
-            : base(title, layout, property)
+        public InspectableObject(string title, int depth, InspectableFieldLayout layout, SerializableProperty property)
+            : base(title, depth, layout, property)
         {
             
         }
@@ -99,7 +99,7 @@ namespace BansheeEditor
                         if (!field.Inspectable)
                             continue;
 
-                        AddChild(CreateInspectable(field.Name, new InspectableFieldLayout(guiContentLayout), field.GetProperty()));
+                        AddChild(CreateInspectable(field.Name, depth + 1, new InspectableFieldLayout(guiContentLayout), field.GetProperty()));
                     }
                 }
                 else

+ 2 - 2
MBansheeEditor/Inspector/InspectableResourceRef.cs

@@ -13,8 +13,8 @@ namespace BansheeEditor
         private GUIResourceField guiField;
         private bool isInitialized;
 
-        public InspectableResourceRef(string title, InspectableFieldLayout layout, SerializableProperty property)
-            : base(title, layout, property)
+        public InspectableResourceRef(string title, int depth, InspectableFieldLayout layout, SerializableProperty property)
+            : base(title, depth, layout, property)
         {
 
         }

+ 2 - 2
MBansheeEditor/Inspector/InspectableString.cs

@@ -13,8 +13,8 @@ namespace BansheeEditor
         private GUITextField guiField;
         private bool isInitialized;
 
-        public InspectableString(string title, InspectableFieldLayout layout, SerializableProperty property)
-            : base(title, layout, property)
+        public InspectableString(string title, int depth, InspectableFieldLayout layout, SerializableProperty property)
+            : base(title, depth, layout, property)
         {
 
         }

+ 2 - 2
MBansheeEditor/Inspector/InspectableVector2.cs

@@ -13,8 +13,8 @@ namespace BansheeEditor
         private GUIVector2Field guiField;
         private bool isInitialized;
 
-        public InspectableVector2(string title, InspectableFieldLayout layout, SerializableProperty property)
-            : base(title, layout, property)
+        public InspectableVector2(string title, int depth, InspectableFieldLayout layout, SerializableProperty property)
+            : base(title, depth, layout, property)
         {
 
         }

+ 2 - 2
MBansheeEditor/Inspector/InspectableVector3.cs

@@ -13,8 +13,8 @@ namespace BansheeEditor
         private GUIVector3Field guiField;
         private bool isInitialized;
 
-        public InspectableVector3(string title, InspectableFieldLayout layout, SerializableProperty property)
-            : base(title, layout, property)
+        public InspectableVector3(string title, int depth, InspectableFieldLayout layout, SerializableProperty property)
+            : base(title, depth, layout, property)
         {
 
         }

+ 2 - 2
MBansheeEditor/Inspector/InspectableVector4.cs

@@ -13,8 +13,8 @@ namespace BansheeEditor
         private GUIVector4Field guiField;
         private bool isInitialized;
 
-        public InspectableVector4(string title, InspectableFieldLayout layout, SerializableProperty property)
-            : base(title, layout, property)
+        public InspectableVector4(string title, int depth, InspectableFieldLayout layout, SerializableProperty property)
+            : base(title, depth, layout, property)
         {
 
         }

+ 8 - 2
MBansheeEditor/Inspector/InspectorWindow.cs

@@ -19,6 +19,7 @@ namespace BansheeEditor
         private class InspectorComponent
         {
             public GUIComponentFoldout foldout;
+            public GUIButton removeBtn;
             public GUIPanel panel;
             public Inspector inspector;
             public bool expanded = true;
@@ -124,7 +125,11 @@ namespace BansheeEditor
                 data.instanceId = allComponents[i].InstanceId;
 
                 data.foldout = new GUIComponentFoldout(allComponents[i].GetType().Name);
-                inspectorLayout.AddElement(data.foldout);
+                data.removeBtn = new GUIButton(new GUIContent(EditorBuiltin.XBtnIcon));
+
+                GUILayoutX horzLayout = inspectorLayout.AddLayoutX();
+                horzLayout.AddElement(data.foldout);
+                horzLayout.AddElement(data.removeBtn);
                 data.panel = inspectorLayout.AddPanel();
                 
                 data.inspector = InspectorUtility.GetInspector(allComponents[i].GetType());
@@ -134,7 +139,7 @@ namespace BansheeEditor
 
                 Type curComponentType = allComponents[i].GetType();
                 data.foldout.OnToggled += (bool expanded) => OnComponentFoldoutToggled(data, expanded);
-                data.foldout.OnRemoveClicked += () => OnComponentRemoveClicked(curComponentType);
+                data.removeBtn.OnClick += () => OnComponentRemoveClicked(curComponentType);
 
                 inspectorComponents.Add(data);
 
@@ -488,6 +493,7 @@ namespace BansheeEditor
             for (int i = 0; i < inspectorComponents.Count; i++)
             {
                 inspectorComponents[i].foldout.Destroy();
+                inspectorComponents[i].removeBtn.Destroy();
                 inspectorComponents[i].inspector.Destroy();
             }
 

+ 1 - 1
README.md

@@ -178,7 +178,7 @@ Easiest way to get started with Banshee is to check out the `ExampleProject` inc
 
 # License
 
-Banshee is offered completely free for personal or commercial use. Only requirement is that you include Banshee Logo in your application when using any part of Banshee. Read `BansheeLicense.rtf` included with the project for more details. 
+Banshee is offered completely free for personal or commercial use under the General Public License v3 (GPL v3). Read `BansheeLicense.txt` included in the License sub-directory for full license text. Licenses and credits for used third-party libraries and tools are included in the same directory.
 
 # Author
 

+ 1 - 1
SBansheeEditor/Include/BsMenuItemManager.h

@@ -58,6 +58,6 @@ namespace BansheeEngine
 		MonoField* mPriorityField;
 		MonoField* mSeparatorField;
 
-		Vector<WString> mMenuItems;
+		Vector<GUIMenuItem*> mMenuItems;
 	};
 }

+ 1 - 0
SBansheeEditor/Include/BsScriptEditorBuiltin.h

@@ -30,5 +30,6 @@ namespace BansheeEngine
 		static MonoObject* internal_getMaterialIcon();
 		static MonoObject* internal_getSpriteTextureIcon();
 		static MonoObject* internal_getPrefabIcon();
+		static MonoObject* internal_getXBtnIcon();
 	};
 }

+ 0 - 9
SBansheeEditor/Include/BsScriptGUIComponentFoldout.h

@@ -22,13 +22,6 @@ namespace BansheeEngine
 		 */
 		static void onToggled(MonoObject* instance, bool expanded);
 
-		/**
-		 * @brief	Triggered when the remove button on the foldout is clicked.
-		 *
-		 * @param	instance	Managed GUIComponentFoldout instance.
-		 */
-		static void onRemoveClicked(MonoObject* instance);
-
 		ScriptGUIComponentFoldout(MonoObject* instance, GUIComponentFoldout* foldout);
 
 		/************************************************************************/
@@ -41,9 +34,7 @@ namespace BansheeEngine
 		static void internal_setTint(ScriptGUIComponentFoldout* nativeInstance, Color color);
 
 		typedef void (__stdcall *OnToggledThunkDef) (MonoObject*, bool, MonoException**);
-		typedef void(__stdcall *OnRemoveClickedThunkDef) (MonoObject*, MonoException**);
 
 		static OnToggledThunkDef onToggledThunk;
-		static OnRemoveClickedThunkDef onRemoveClickedThunk;
 	};
 }

+ 4 - 3
SBansheeEditor/Source/BsMenuItemManager.cpp

@@ -85,11 +85,12 @@ namespace BansheeEngine
 								separatorPath.erase(path.size() - lastElem.size() - 1, lastElem.size() + 1);
 							}
 
-							mainWindow->getMenuBar().addMenuItemSeparator(separatorPath, priority);
+							GUIMenuItem* separatorItem = mainWindow->getMenuBar().addMenuItemSeparator(separatorPath, priority);
+							mMenuItems.push_back(separatorItem);
 						}
 
-						mainWindow->getMenuBar().addMenuItem(path, callback, priority, shortcutKey);
-						mMenuItems.push_back(path);
+						GUIMenuItem* menuItem = mainWindow->getMenuBar().addMenuItem(path, callback, priority, shortcutKey);
+						mMenuItems.push_back(menuItem);
 					}
 				}
 			}

+ 8 - 0
SBansheeEditor/Source/BsScriptEditorBuiltin.cpp

@@ -26,6 +26,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_GetMaterialIcon", &ScriptEditorBuiltin::internal_getMaterialIcon);
 		metaData.scriptClass->addInternalCall("Internal_GetSpriteTextureIcon", &ScriptEditorBuiltin::internal_getSpriteTextureIcon);
 		metaData.scriptClass->addInternalCall("Internal_GetPrefabIcon", &ScriptEditorBuiltin::internal_getPrefabIcon);
+		metaData.scriptClass->addInternalCall("Internal_GetXBtnIcon", &ScriptEditorBuiltin::internal_getXBtnIcon);
 	}
 
 	MonoObject* ScriptEditorBuiltin::internal_getFolderIcon()
@@ -104,4 +105,11 @@ namespace BansheeEngine
 
 		return ScriptSpriteTexture::toManaged(tex);
 	}
+
+	MonoObject* ScriptEditorBuiltin::internal_getXBtnIcon()
+	{
+		HSpriteTexture tex = BuiltinEditorResources::instance().getIcon(EditorIcon::XBtn);
+
+		return ScriptSpriteTexture::toManaged(tex);
+	}
 }

+ 0 - 8
SBansheeEditor/Source/BsScriptGUIComponentFoldout.cpp

@@ -20,7 +20,6 @@ using namespace std::placeholders;
 namespace BansheeEngine
 {
 	ScriptGUIComponentFoldout::OnToggledThunkDef ScriptGUIComponentFoldout::onToggledThunk;
-	ScriptGUIComponentFoldout::OnRemoveClickedThunkDef ScriptGUIComponentFoldout::onRemoveClickedThunk;
 
 	ScriptGUIComponentFoldout::ScriptGUIComponentFoldout(MonoObject* instance, GUIComponentFoldout* foldout)
 		:TScriptGUIElement(instance, foldout)
@@ -37,7 +36,6 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_SetTint", &ScriptGUIComponentFoldout::internal_setTint);
 
 		onToggledThunk = (OnToggledThunkDef)metaData.scriptClass->getMethod("DoOnToggled", 1)->getThunk();
-		onRemoveClickedThunk = (OnRemoveClickedThunkDef)metaData.scriptClass->getMethod("DoOnRemoveClicked")->getThunk();
 	}
 
 	void ScriptGUIComponentFoldout::internal_createInstance(MonoObject* instance, MonoObject* content, MonoString* style, MonoArray* guiOptions)
@@ -52,7 +50,6 @@ namespace BansheeEngine
 		GUIComponentFoldout* guiFoldout = GUIComponentFoldout::create(label);
 
 		guiFoldout->onStateChanged.connect(std::bind(&ScriptGUIComponentFoldout::onToggled, instance, _1));
-		guiFoldout->onRemoveClicked.connect(std::bind(&ScriptGUIComponentFoldout::onRemoveClicked, instance));
 
 		ScriptGUIComponentFoldout* nativeInstance = new (bs_alloc<ScriptGUIComponentFoldout>()) ScriptGUIComponentFoldout(instance, guiFoldout);
 	}
@@ -87,9 +84,4 @@ namespace BansheeEngine
 	{
 		MonoUtil::invokeThunk(onToggledThunk, instance, expanded);
 	}
-
-	void ScriptGUIComponentFoldout::onRemoveClicked(MonoObject* instance)
-	{
-		MonoUtil::invokeThunk(onRemoveClickedThunk, instance);
-	}
 }