1 /*!
2 	@file
3 	@author		Generate utility by Albert Semenov
4 	@date		01/2009
5 	@module
6 */
7 #pragma once
8 
9 #include <MyGUI.h>
10 #include "Config.h"
11 #include "NativePtrHolder.h"
12 #include "WidgetHolder.h"
13 #include "Types.h"
14 #include "Delegates.h"
15 
16 namespace MyGUI
17 {
18 	namespace Managed
19 	{
20 
21 		public ref class BaseWidget abstract
22 		{
23 
24 		public:
BaseWidget()25 			BaseWidget() : mNative(0), mIsWrap(true) { }
26 
27 		internal:
BaseWidget(MyGUI::Widget * _native)28 			BaseWidget( MyGUI::Widget* _native )
29 			{
30 				if (_native == nullptr) return;
31 				mNative = _native;
32 				mParent = getMangedParent(mNative);
33 				if (mParent == nullptr) mRoots.Add(this);
34 				else mParent->mChilds.Add(this);
35 				WidgetHolder sender = this;
36 				mNative->setUserData(sender);
37 				mIsWrap = true;
38 			}
39 
~BaseWidget()40 			~BaseWidget()
41 			{
42 				if (mNative != 0)
43 				{
44 					DestroyChilds();
45 					if (mParent == nullptr)
46 					{
47 						mRoots.Remove(this);
48 					}
49 					else
50 					{
51 						mParent->mChilds.Remove(this);
52 						mParent = nullptr;
53 					}
54 					if ( ! mIsWrap )
55 						MyGUI::WidgetManager::getInstance().destroyWidget(mNative);
56 					mNative = 0;
57 				}
58 			}
59 
60 		internal:
61 			void CreateWidget( BaseWidget ^ _parent, MyGUI::WidgetStyle _style, const std::string& _skin, const MyGUI::IntCoord& _coord, MyGUI::Align _align, const std::string& _layer, const std::string& _name )
62 			{
63 				if (_parent == nullptr)
64 				{
65 					mNative = MyGUI::Gui::getInstance().createWidgetT(
66 						getClassTypeName(),
67 						_skin,
68 						_coord,
69 						_align,
70 						_layer,
71 						_name);
72 					mRoots.Add(this);
73 				}
74 				else
75 				{
76 					mNative = _parent->mNative->createWidgetT(
77 						getClassTypeName(),
78 						_skin,
79 						_coord,
80 						_align,
81 						_name);
82 					mParent = _parent;
83 					mParent->mChilds.Add(this);
84 				}
85 				WidgetHolder sender = this;
86 				mNative->setUserData(sender);
87 				mIsWrap = false;
88 			}
89 
DestroyChilds()90 			void DestroyChilds()
91 			{
92 				while (mChilds.Count > 0)
93 				{
94 					BaseWidget ^ child = mChilds[0];
95 					delete child;
96 					child = nullptr;
97 				}
98 			}
99 
100 			BaseWidget ^ getMangedParent(MyGUI::Widget* _widget)
101 			{
102 				MyGUI::Widget* parent = _widget->getParent();
103 				while (parent != nullptr)
104 				{
105 					WidgetHolder* obj = parent->getUserData< WidgetHolder >(false);
106 					if (obj != nullptr) return obj->toObject();
107 					parent = parent->getParent();
108 				}
109 				return nullptr;
110 			}
111 
112 		public:
113 			generic <typename WidgetType> where WidgetType : ref class
114 			WidgetType CreateWidget(System::String ^ _skin, IntCoord _coord, Align _align, System::String ^ _name)
115 			{
116 				BaseWidget ^ child = (BaseWidget ^ )(System::Activator::CreateInstance<WidgetType>());
117 				child->CreateWidget(this, MyGUI::WidgetStyle::Child, Convert<const std::string&>::From(_skin), Convert<const MyGUI::IntCoord&>::From(_coord), Convert<MyGUI::Align>::From(_align), "", Convert<const std::string&>::From(_name));
118 				return (WidgetType)child;
119 			}
120 
121 			generic <typename WidgetType> where WidgetType : ref class
122 			WidgetType CreateWidget(System::String ^ _skin, IntCoord _coord, Align _align)
123 			{
124 				BaseWidget ^ child = (BaseWidget ^ )(System::Activator::CreateInstance<WidgetType>());
125 				child->CreateWidget(this, MyGUI::WidgetStyle::Child, Convert<const std::string&>::From(_skin), Convert<const MyGUI::IntCoord&>::From(_coord), Convert<MyGUI::Align>::From(_align), "", "");
126 				return (WidgetType)child;
127 			}
128 
129 			generic <typename WidgetType> where WidgetType : ref class
130 			WidgetType CreateWidget(WidgetStyle _style, System::String ^ _skin, IntCoord _coord, Align _align, System::String ^ _layer, System::String ^ _name)
131 			{
132 				BaseWidget ^ child = (BaseWidget ^ )(System::Activator::CreateInstance<WidgetType>());
133 				child->CreateWidget(this, Convert<MyGUI::WidgetStyle>::From(_style), Convert<const std::string&>::From(_skin), Convert<const MyGUI::IntCoord&>::From(_coord), Convert<MyGUI::Align>::From(_align), Convert<const std::string&>::From(_layer), Convert<const std::string&>::From(_name));
134 				return (WidgetType)child;
135 			}
136 
137 			BaseWidget ^ CreateWidgetT(System::Type ^ _type, WidgetStyle _style, System::String ^ _skin, IntCoord _coord, Align _align, System::String ^ _layer, System::String ^ _name)
138 			{
139 				System::Reflection::ConstructorInfo ^ ci = _type->GetConstructor(gcnew cli::array < System::Type ^ > (0));
140 				BaseWidget ^ child = (BaseWidget ^ )ci->Invoke(nullptr);
141 				child->CreateWidget(this, Convert<MyGUI::WidgetStyle>::From(_style), Convert<const std::string&>::From(_skin), Convert<const MyGUI::IntCoord&>::From(_coord), Convert<MyGUI::Align>::From(_align), Convert<const std::string&>::From(_layer), Convert<const std::string&>::From(_name));
142 				return child;
143 			}
144 
145 		internal:
146 			virtual const std::string& getClassTypeName() = 0;
GetNativePtr()147 			MyGUI::Widget* GetNativePtr()
148 			{
149 				return mNative;
150 			}
151 
152 		public:
GetNativeIntPtr()153 			System::IntPtr GetNativeIntPtr()
154 			{
155 				return System::IntPtr(mNative);
156 			}
157 
158 			property System::Object ^ UserData
159 			{
160 				System::Object ^ get( )
161 				{
162 					MMYGUI_CHECK_NATIVE(mNative);
163 					return mUserData;
164 				}
165 				void set(System::Object ^ _value)
166 				{
167 					MMYGUI_CHECK_NATIVE(mNative);
168 					mUserData = _value;
169 				}
170 			}
171 
172 		internal:
173 			MyGUI::Widget* mNative;
174 
175 		private:
176 			bool mIsWrap;
177 			BaseWidget ^ mParent;
178 			System::Collections::Generic::List < BaseWidget ^ > mChilds;
179 			System::Object ^ mUserData;
180 			static System::Collections::Generic::List < BaseWidget ^ > mRoots;
181 
182 		};
183 
184 	} // namespace Managed
185 } // namespace MyGUI
186