Marko Pintera 10 лет назад
Родитель
Сommit
f6c1d83ca6

+ 9 - 1
BansheeEngine/Include/BsGUIElement.h

@@ -55,6 +55,12 @@ namespace BansheeEngine
 		 */
 		 */
 		void setStyle(const String& styleName);
 		void setStyle(const String& styleName);
 
 
+		/**
+		 * @brief	Assigns a new context menu that will be opened when the element is right clicked.
+		 *			Null is allowed in case no context menu is wanted.
+		 */
+		void setContextMenu(const GUIContextMenuPtr& menu) { mContextMenu = menu; }
+
 		/**
 		/**
 		 * @copydoc	GUIElementBase::getVisibleBounds
 		 * @copydoc	GUIElementBase::getVisibleBounds
 		 */
 		 */
@@ -302,7 +308,7 @@ namespace BansheeEngine
 		 *
 		 *
 		 * @note	Internal method.
 		 * @note	Internal method.
 		 */
 		 */
-		virtual GUIContextMenu* _getContextMenu() const { return nullptr; }
+		virtual GUIContextMenuPtr _getContextMenu() const { return mContextMenu; }
 
 
 		/**
 		/**
 		 * @brief	Returns a clip rectangle relative to the element, used for offsetting
 		 * @brief	Returns a clip rectangle relative to the element, used for offsetting
@@ -383,5 +389,7 @@ namespace BansheeEngine
 	private:
 	private:
 		const GUIElementStyle* mStyle;
 		const GUIElementStyle* mStyle;
 		String mStyleName;
 		String mStyleName;
+
+		GUIContextMenuPtr mContextMenu;
 	};
 	};
 }
 }

+ 1 - 1
BansheeEngine/Include/BsGUIInputBox.h

@@ -198,7 +198,7 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @copydoc	GUIElement::getContextMenu
 		 * @copydoc	GUIElement::getContextMenu
 		 */
 		 */
-		virtual GUIContextMenu* _getContextMenu() const;
+		virtual GUIContextMenuPtr _getContextMenu() const override;
 	private:
 	private:
 		/**
 		/**
 		 * @brief	Retrieves a sprite from a render element index, and a local render element index
 		 * @brief	Retrieves a sprite from a render element index, and a local render element index

+ 1 - 0
BansheeEngine/Include/BsPrerequisites.h

@@ -117,6 +117,7 @@ namespace BansheeEngine
 	typedef std::shared_ptr<PlainText> PlainTextPtr;
 	typedef std::shared_ptr<PlainText> PlainTextPtr;
 	typedef std::shared_ptr<ScriptCode> ScriptCodePtr;
 	typedef std::shared_ptr<ScriptCode> ScriptCodePtr;
 	typedef std::shared_ptr<GUISkin> GUISkinPtr;
 	typedef std::shared_ptr<GUISkin> GUISkinPtr;
+	typedef std::shared_ptr<GUIContextMenu> GUIContextMenuPtr;
 	typedef std::shared_ptr<DefaultMeshData> DefaultMeshDataPtr;
 	typedef std::shared_ptr<DefaultMeshData> DefaultMeshDataPtr;
 
 
 	typedef GameObjectHandle<GUIWidget> HGUIWidget;
 	typedef GameObjectHandle<GUIWidget> HGUIWidget;

+ 11 - 12
BansheeEngine/Source/BsGUIInputBox.cpp

@@ -1097,25 +1097,24 @@ namespace BansheeEngine
 		return _getStyle()->normal.textColor;
 		return _getStyle()->normal.textColor;
 	}
 	}
 
 
-	GUIContextMenu* GUIInputBox::_getContextMenu() const
+	GUIContextMenuPtr GUIInputBox::_getContextMenu() const
 	{
 	{
-		static bool initialized = false;
-		static GUIContextMenu mContextMenu;
+		static GUIContextMenuPtr contextMenu;
 
 
-		if(!initialized)
+		if (contextMenu == nullptr)
 		{
 		{
-			mContextMenu.addMenuItem(L"Cut", std::bind(&GUIInputBox::cutText, const_cast<GUIInputBox*>(this)), 0);
-			mContextMenu.addMenuItem(L"Copy", std::bind(&GUIInputBox::copyText, const_cast<GUIInputBox*>(this)), 0);
-			mContextMenu.addMenuItem(L"Paste", std::bind(&GUIInputBox::pasteText, const_cast<GUIInputBox*>(this)), 0);
+			contextMenu = bs_shared_ptr<GUIContextMenu>();
 
 
-			mContextMenu.setLocalizedName(L"Cut", HString(L"Cut"));
-			mContextMenu.setLocalizedName(L"Copy", HString(L"Copy"));
-			mContextMenu.setLocalizedName(L"Paste", HString(L"Paste"));
+			contextMenu->addMenuItem(L"Cut", std::bind(&GUIInputBox::cutText, const_cast<GUIInputBox*>(this)), 0);
+			contextMenu->addMenuItem(L"Copy", std::bind(&GUIInputBox::copyText, const_cast<GUIInputBox*>(this)), 0);
+			contextMenu->addMenuItem(L"Paste", std::bind(&GUIInputBox::pasteText, const_cast<GUIInputBox*>(this)), 0);
 
 
-			initialized = true;
+			contextMenu->setLocalizedName(L"Cut", HString(L"Cut"));
+			contextMenu->setLocalizedName(L"Copy", HString(L"Copy"));
+			contextMenu->setLocalizedName(L"Paste", HString(L"Paste"));
 		}
 		}
 
 
-		return &mContextMenu;
+		return contextMenu;
 	}
 	}
 
 
 	void GUIInputBox::cutText()
 	void GUIInputBox::cutText()

+ 1 - 1
BansheeEngine/Source/BsGUIManager.cpp

@@ -984,7 +984,7 @@ namespace BansheeEngine
 		{
 		{
 			for(auto& elementInfo : mElementsUnderPointer)
 			for(auto& elementInfo : mElementsUnderPointer)
 			{
 			{
-				GUIContextMenu* menu = elementInfo.element->_getContextMenu();
+				GUIContextMenuPtr menu = elementInfo.element->_getContextMenu();
 
 
 				if(menu != nullptr)
 				if(menu != nullptr)
 				{
 				{

+ 0 - 1
MBansheeEditor/MBansheeEditor.csproj

@@ -120,7 +120,6 @@
     <Compile Include="Scene\ScaleHandle.cs" />
     <Compile Include="Scene\ScaleHandle.cs" />
     <Compile Include="ScriptCompiler.cs" />
     <Compile Include="ScriptCompiler.cs" />
     <Compile Include="Selection.cs" />
     <Compile Include="Selection.cs" />
-    <Compile Include="ShortcutKey.cs" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\MBansheeEngine\MBansheeEngine.csproj">
     <ProjectReference Include="..\MBansheeEngine\MBansheeEngine.csproj">

+ 76 - 0
MBansheeEngine/ContextMenu.cs

@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+
+namespace BansheeEngine
+{
+    public class ContextMenu : ScriptObject
+    {
+        private List<Action> callbacks; 
+
+        public ContextMenu()
+        {
+            Internal_CreateInstance(this);
+        }
+
+        public void AddItem(string path, Action callback)
+        {
+            Internal_AddItem(mCachedPtr, path, callbacks.Count, ShortcutKey.None);
+            callbacks.Add(callback);
+        }
+
+        public void AddItem(string path, Action callback, ShortcutKey shortcut)
+        {
+            Internal_AddItem(mCachedPtr, path, callbacks.Count, shortcut);
+            callbacks.Add(callback);
+        }
+
+        public void AddItem(string path, Action callback, LocString name)
+        {
+            Internal_AddItem(mCachedPtr, path, callbacks.Count, ShortcutKey.None);
+            callbacks.Add(callback);
+        }
+
+        public void AddItem(string path, Action callback, ShortcutKey shortcut, LocString name)
+        {
+            Internal_AddItem(mCachedPtr, path, callbacks.Count, shortcut);
+            callbacks.Add(callback);
+        }
+
+        public void AddSeparator(string path)
+        {
+            Internal_AddSeparator(mCachedPtr, path);
+        }
+
+        public void SetLocalizedName(string label, LocString name)
+        {
+            IntPtr namePtr = IntPtr.Zero;
+            if (name != null)
+                namePtr = name.GetCachedPtr();
+
+            Internal_SetLocalizedName(mCachedPtr, label, namePtr);
+        }
+
+        private void InternalDoOnEntryTriggered(int callbackIdx)
+        {
+            if (callbackIdx < 0 || callbackIdx >= callbacks.Count)
+                return;
+
+            Action callback = callbacks[callbackIdx];
+            if (callback != null)
+                callback();
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_CreateInstance(ContextMenu instance);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_AddItem(IntPtr instance, string path, int callbackIdx, ShortcutKey shortcut);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_AddSeparator(IntPtr instance, string path);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetLocalizedName(IntPtr instance, string label, IntPtr name);
+    }
+}

+ 12 - 0
MBansheeEngine/GUI/GUIElement.cs

@@ -76,6 +76,15 @@ namespace BansheeEngine
             Internal_ResetDimensions(mCachedPtr);
             Internal_ResetDimensions(mCachedPtr);
         }
         }
 
 
+        public void SetContextMenu(ContextMenu menu)
+        {
+            IntPtr menuPtr = IntPtr.Zero;
+            if (menu != null)
+                menuPtr = menu.GetCachedPtr();
+
+            Internal_SetContextMenu(mCachedPtr, menuPtr);
+        }
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetVisible(IntPtr nativeInstance, bool visible);
         private static extern void Internal_SetVisible(IntPtr nativeInstance, bool visible);
 
 
@@ -106,6 +115,9 @@ namespace BansheeEngine
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern Rect2I Internal_GetVisualBounds(IntPtr nativeInstance);
         private static extern Rect2I Internal_GetVisualBounds(IntPtr nativeInstance);
 
 
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetContextMenu(IntPtr nativeInstance, IntPtr contextMenu);
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_Destroy(IntPtr nativeInstance);
         private static extern void Internal_Destroy(IntPtr nativeInstance);
     }
     }

+ 2 - 0
MBansheeEngine/MBansheeEngine.csproj

@@ -47,6 +47,7 @@
     <Compile Include="Builtin.cs" />
     <Compile Include="Builtin.cs" />
     <Compile Include="Camera.cs" />
     <Compile Include="Camera.cs" />
     <Compile Include="CameraHandler.cs" />
     <Compile Include="CameraHandler.cs" />
+    <Compile Include="ContextMenu.cs" />
     <Compile Include="Cursor.cs" />
     <Compile Include="Cursor.cs" />
     <Compile Include="Debug.cs" />
     <Compile Include="Debug.cs" />
     <Compile Include="Color.cs" />
     <Compile Include="Color.cs" />
@@ -125,6 +126,7 @@
     <Compile Include="SerializeObject.cs" />
     <Compile Include="SerializeObject.cs" />
     <Compile Include="SerializeField.cs" />
     <Compile Include="SerializeField.cs" />
     <Compile Include="Shader.cs" />
     <Compile Include="Shader.cs" />
+    <Compile Include="ShortcutKey.cs" />
     <Compile Include="Sphere.cs" />
     <Compile Include="Sphere.cs" />
     <Compile Include="SpriteTexture.cs" />
     <Compile Include="SpriteTexture.cs" />
     <Compile Include="StringTable.cs" />
     <Compile Include="StringTable.cs" />

+ 1 - 2
MBansheeEditor/ShortcutKey.cs → MBansheeEngine/ShortcutKey.cs

@@ -1,7 +1,6 @@
 using System.Runtime.InteropServices;
 using System.Runtime.InteropServices;
-using BansheeEngine;
 
 
-namespace BansheeEditor
+namespace BansheeEngine
 {
 {
     [StructLayout(LayoutKind.Sequential)]
     [StructLayout(LayoutKind.Sequential)]
     public struct ShortcutKey
     public struct ShortcutKey

+ 31 - 0
SBansheeEngine/Include/BsScriptContextMenu.h

@@ -0,0 +1,31 @@
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "BsScriptObject.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BE_EXPORT ScriptContextMenu : public ScriptObject < ScriptContextMenu >
+	{
+	public:
+		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "ContextMenu")
+
+		GUIContextMenuPtr getInternal() const { return mContextMenu; }
+
+	private:
+		static void internal_CreateInstance(MonoObject* instance);
+		static void internal_AddItem(ScriptContextMenu* instance, MonoString* path, UINT32 callbackIdx, ShortcutKey shortcut);
+		static void internal_AddSeparator(ScriptContextMenu* instance, MonoString* path);
+		static void internal_SetLocalizedName(ScriptContextMenu* instance, MonoString* label, ScriptHString* name);
+
+		ScriptContextMenu(MonoObject* instance);
+
+		void onContextMenuItemTriggered(UINT32 idx);
+
+		GUIContextMenuPtr mContextMenu;
+
+		typedef void(__stdcall *OnEntryTriggeredThunkDef) (MonoObject*, UINT32 callbackIdx, MonoException**);
+
+		static OnEntryTriggeredThunkDef onEntryTriggered;
+	};
+}

+ 2 - 0
SBansheeEngine/Include/BsScriptEnginePrerequisites.h

@@ -66,6 +66,8 @@ namespace BansheeEngine
 	class ManagedResource;
 	class ManagedResource;
 	class ManagedResourceMetaData;
 	class ManagedResourceMetaData;
 	class ScriptAssemblyManager;
 	class ScriptAssemblyManager;
+	class ScriptHString;
+	class ScriptContextMenu;
 
 
 	typedef GameObjectHandle<ManagedComponent> HManagedComponent;
 	typedef GameObjectHandle<ManagedComponent> HManagedComponent;
 	typedef ResourceHandle<ManagedResource> HManagedResource;
 	typedef ResourceHandle<ManagedResource> HManagedResource;

+ 1 - 0
SBansheeEngine/Include/BsScriptGUIElement.h

@@ -97,6 +97,7 @@ namespace BansheeEngine
 		static void internal_SetFlexibleWidth(ScriptGUIElementBaseTBase* nativeInstance, UINT32 minWidth, UINT32 maxWidth);
 		static void internal_SetFlexibleWidth(ScriptGUIElementBaseTBase* nativeInstance, UINT32 minWidth, UINT32 maxWidth);
 		static void internal_SetHeight(ScriptGUIElementBaseTBase* nativeInstance, UINT32 height);
 		static void internal_SetHeight(ScriptGUIElementBaseTBase* nativeInstance, UINT32 height);
 		static void internal_SetFlexibleHeight(ScriptGUIElementBaseTBase* nativeInstance, UINT32 minHeight, UINT32 maxHeight);
 		static void internal_SetFlexibleHeight(ScriptGUIElementBaseTBase* nativeInstance, UINT32 minHeight, UINT32 maxHeight);
+		static void internal_SetContextMenu(ScriptGUIElementBaseTBase* nativeInstance, ScriptContextMenu* contextMenu);
 		static void internal_ResetDimensions(ScriptGUIElementBaseTBase* nativeInstance);
 		static void internal_ResetDimensions(ScriptGUIElementBaseTBase* nativeInstance);
 
 
 		ScriptGUIElement(MonoObject* instance);
 		ScriptGUIElement(MonoObject* instance);

+ 2 - 0
SBansheeEngine/SBansheeEngine.vcxproj

@@ -257,6 +257,7 @@
     <ClInclude Include="Include\BsScriptCameraHandler.h" />
     <ClInclude Include="Include\BsScriptCameraHandler.h" />
     <ClInclude Include="Include\BsScriptColor.h" />
     <ClInclude Include="Include\BsScriptColor.h" />
     <ClInclude Include="Include\BsScriptComponent.h" />
     <ClInclude Include="Include\BsScriptComponent.h" />
+    <ClInclude Include="Include\BsScriptContextMenu.h" />
     <ClInclude Include="Include\BsScriptCursor.h" />
     <ClInclude Include="Include\BsScriptCursor.h" />
     <ClInclude Include="Include\BsScriptDebug.h" />
     <ClInclude Include="Include\BsScriptDebug.h" />
     <ClInclude Include="Include\BsScriptEnginePrerequisites.h" />
     <ClInclude Include="Include\BsScriptEnginePrerequisites.h" />
@@ -339,6 +340,7 @@
     <ClCompile Include="Source\BsScriptCameraHandler.cpp" />
     <ClCompile Include="Source\BsScriptCameraHandler.cpp" />
     <ClCompile Include="Source\BsScriptColor.cpp" />
     <ClCompile Include="Source\BsScriptColor.cpp" />
     <ClCompile Include="Source\BsScriptComponent.cpp" />
     <ClCompile Include="Source\BsScriptComponent.cpp" />
+    <ClCompile Include="Source\BsScriptContextMenu.cpp" />
     <ClCompile Include="Source\BsScriptCursor.cpp" />
     <ClCompile Include="Source\BsScriptCursor.cpp" />
     <ClCompile Include="Source\BsScriptDebug.cpp" />
     <ClCompile Include="Source\BsScriptDebug.cpp" />
     <ClCompile Include="Source\BsScriptEnginePlugin.cpp" />
     <ClCompile Include="Source\BsScriptEnginePlugin.cpp" />

+ 6 - 0
SBansheeEngine/SBansheeEngine.vcxproj.filters

@@ -312,6 +312,9 @@
     <ClInclude Include="Include\BsScriptRenderableHandler.h">
     <ClInclude Include="Include\BsScriptRenderableHandler.h">
       <Filter>Header Files</Filter>
       <Filter>Header Files</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\BsScriptContextMenu.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsScriptTexture2D.cpp">
     <ClCompile Include="Source\BsScriptTexture2D.cpp">
@@ -560,5 +563,8 @@
     <ClCompile Include="Source\BsScriptRenderableHandler.cpp">
     <ClCompile Include="Source\BsScriptRenderableHandler.cpp">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="Source\BsScriptContextMenu.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 71 - 0
SBansheeEngine/Source/BsScriptContextMenu.cpp

@@ -0,0 +1,71 @@
+#include "BsScriptContextMenu.h"
+#include "BsScriptMeta.h"
+#include "BsMonoField.h"
+#include "BsMonoClass.h"
+#include "BsMonoManager.h"
+#include "BsMonoMethod.h"
+#include "BsMonoUtil.h"
+#include "BsGUIContextMenu.h"
+#include "BsScriptHString.h"
+
+using namespace std::placeholders;
+
+namespace BansheeEngine
+{
+	ScriptContextMenu::ScriptContextMenu(MonoObject* instance)
+		: ScriptObject(instance)
+	{
+		mContextMenu = bs_shared_ptr<GUIContextMenu>();
+	}
+
+	void ScriptContextMenu::initRuntimeData()
+	{
+		metaData.scriptClass->addInternalCall("internal_CreateInstance", &ScriptContextMenu::internal_CreateInstance);
+		metaData.scriptClass->addInternalCall("internal_AddItem", &ScriptContextMenu::internal_AddItem);
+		metaData.scriptClass->addInternalCall("internal_AddSeparator", &ScriptContextMenu::internal_AddSeparator);
+		metaData.scriptClass->addInternalCall("internal_SetLocalizedName", &ScriptContextMenu::internal_SetLocalizedName);
+
+		onEntryTriggered = (OnEntryTriggeredThunkDef)metaData.scriptClass->getMethod("InternalDoOnEntryTriggered", 1)->getThunk();
+	}
+
+	void ScriptContextMenu::internal_CreateInstance(MonoObject* instance)
+	{
+		ScriptContextMenu* nativeInstance = new (bs_alloc<ScriptContextMenu>()) ScriptContextMenu(instance);
+	}
+
+	void ScriptContextMenu::internal_AddItem(ScriptContextMenu* instance, MonoString* path, UINT32 callbackIdx,
+		ShortcutKey shortcut)
+	{
+		WString nativePath = MonoUtil::monoToWString(path);
+
+		GUIContextMenuPtr contextMenu = instance->getInternal();
+		contextMenu->addMenuItem(nativePath, std::bind(&ScriptContextMenu::onContextMenuItemTriggered,
+			instance, callbackIdx), 0, shortcut);
+	}
+
+	void ScriptContextMenu::internal_AddSeparator(ScriptContextMenu* instance, MonoString* path)
+	{
+		WString nativePath = MonoUtil::monoToWString(path);
+
+		GUIContextMenuPtr contextMenu = instance->getInternal();
+		contextMenu->addSeparator(nativePath, 0);
+	}
+
+	void ScriptContextMenu::internal_SetLocalizedName(ScriptContextMenu* instance, MonoString* label, ScriptHString* name)
+	{
+		if (label == nullptr || name == nullptr)
+			return;
+
+		WString nativeLabel = MonoUtil::monoToWString(label);
+		GUIContextMenuPtr contextMenu = instance->getInternal();
+		contextMenu->setLocalizedName(nativeLabel, name->getInternalValue());
+	}
+
+	void ScriptContextMenu::onContextMenuItemTriggered(UINT32 idx)
+	{
+		MonoException* exception = nullptr;
+		onEntryTriggered(getManagedInstance(), idx, &exception);
+
+		MonoUtil::throwIfException(exception);
+	}
+}

+ 17 - 0
SBansheeEngine/Source/BsScriptGUIElement.cpp

@@ -7,6 +7,7 @@
 #include "BsMonoUtil.h"
 #include "BsMonoUtil.h"
 #include "BsGUIElement.h"
 #include "BsGUIElement.h"
 #include "BsScriptGUILayout.h"
 #include "BsScriptGUILayout.h"
+#include "BsScriptContextMenu.h"
 #include "BsGUILayout.h"
 #include "BsGUILayout.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
@@ -61,6 +62,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_SetHeight", &ScriptGUIElement::internal_SetHeight);
 		metaData.scriptClass->addInternalCall("Internal_SetHeight", &ScriptGUIElement::internal_SetHeight);
 		metaData.scriptClass->addInternalCall("Internal_SetFlexibleHeight", &ScriptGUIElement::internal_SetFlexibleHeight);
 		metaData.scriptClass->addInternalCall("Internal_SetFlexibleHeight", &ScriptGUIElement::internal_SetFlexibleHeight);
 		metaData.scriptClass->addInternalCall("Internal_ResetDimensions", &ScriptGUIElement::internal_ResetDimensions);
 		metaData.scriptClass->addInternalCall("Internal_ResetDimensions", &ScriptGUIElement::internal_ResetDimensions);
+		metaData.scriptClass->addInternalCall("Internal_SetContextMenu", &ScriptGUIElement::internal_SetContextMenu);
 	}
 	}
 
 
 	void ScriptGUIElement::internal_destroy(ScriptGUIElementBaseTBase* nativeInstance)
 	void ScriptGUIElement::internal_destroy(ScriptGUIElementBaseTBase* nativeInstance)
@@ -122,4 +124,19 @@ namespace BansheeEngine
 	{
 	{
 		nativeInstance->getGUIElement()->resetDimensions();
 		nativeInstance->getGUIElement()->resetDimensions();
 	}
 	}
+
+	void ScriptGUIElement::internal_SetContextMenu(ScriptGUIElementBaseTBase* nativeInstance, ScriptContextMenu* contextMenu)
+	{
+		GUIElementBase* guiElemBase = nativeInstance->getGUIElement();
+		if (guiElemBase->_getType() == GUIElementBase::Type::Element)
+		{
+			GUIElement* guiElem = static_cast<GUIElement*>(guiElemBase);
+
+			GUIContextMenuPtr nativeContextMenu;
+			if (contextMenu != nullptr)
+				nativeContextMenu = contextMenu->getInternal();
+
+			guiElem->setContextMenu(nativeContextMenu);
+		}
+	}
 }
 }