1 
2 #include "CGUIEditWindow.h"
3 #include "IGUISkin.h"
4 #include "IGUIEnvironment.h"
5 #include "IGUIElementFactory.h"
6 #include "IAttributes.h"
7 #include "IGUIFont.h"
8 #include "IGUITabControl.h"
9 #include "IGUITreeView.h"
10 #include "CGUIEditWorkspace.h"
11 
12 using namespace irr;
13 using namespace gui;
14 
15 //! constructor
CGUIEditWindow(IGUIEnvironment * environment,core::rect<s32> rectangle,IGUIElement * parent)16 CGUIEditWindow::CGUIEditWindow(IGUIEnvironment* environment, core::rect<s32> rectangle, IGUIElement *parent)
17 		: IGUIWindow(environment, parent, -1, rectangle),
18 		Dragging(false), IsDraggable(true), Resizing(false), SelectedElement(0),
19 		AttribEditor(0), OptionEditor(0), EnvEditor(0)
20 {
21 	#ifdef _DEBUG
22 	setDebugName("CGUIEditWindow");
23 	#endif
24 
25 	// we can't tab out of this window
26 	setTabGroup(true);
27 	// we can ctrl+tab to it
28 	setTabStop(true);
29 	// the tab order number is auto-assigned
30 	setTabOrder(-1);
31 
32 	// set window text
33 	setText(L"GUI Editor");
34 
35 	// return if we have no skin.
36 	IGUISkin *skin = environment->getSkin();
37 	if (!skin)
38 		return;
39 
40 	s32 th = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH);
41 
42 	setRelativePosition(core::rect<s32>(50,50,250,500));
43 	setMinSize(core::dimension2du(200,200));
44 
45 	IGUITabControl *TabControl = environment->addTabControl(core::rect<s32>(1,th+5,199,449), this, false, true);
46 	TabControl->setSubElement(true);
47 	TabControl->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
48 
49 	TabControl->addTab(L"Tools");
50 	//L"Texture Cache Browser"
51 	//L"Font Browser"
52 	//L"Font Generator"
53 	//L"Sprite Editor"
54 	//Environment->addGUIElement("textureCacheBrowser", this);
55 
56 	IGUITab* EditorTab = TabControl->addTab(L"Editor");
57 	OptionEditor = (CGUIAttributeEditor*) environment->addGUIElement("attributeEditor", EditorTab);
58 	OptionEditor->grab();
59 	OptionEditor->setID(EGUIEDCE_OPTION_EDITOR);
60 	OptionEditor->setRelativePositionProportional(core::rect<f32>(0.0f, 0.0f, 1.0f, 1.0f));
61 	OptionEditor->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
62 
63 	if (Parent && Parent->getParent() == Environment->getRootGUIElement())
64 	{
65 		IGUITab* EnvTab = TabControl->addTab(L"Env");
66 		EnvEditor = (CGUIAttributeEditor*) environment->addGUIElement("attributeEditor", EnvTab);
67 		EnvEditor->grab();
68 		EnvEditor->setID(EGUIEDCE_ENV_EDITOR);
69 		EnvEditor->setRelativePositionProportional(core::rect<f32>(0.0f, 0.0f, 1.0f, 1.0f));
70 		EnvEditor->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
71 	}
72 	IGUITab* ElementTab = TabControl->addTab(L"Element");
73 
74 	AttribEditor = (CGUIAttributeEditor*) environment->addGUIElement("attributeEditor", ElementTab);
75 	AttribEditor->grab();
76 	AttribEditor->setID(EGUIEDCE_ATTRIB_EDITOR);
77 	AttribEditor->setRelativePositionProportional(core::rect<f32>(0.0f, 0.0f, 1.0f, 1.0f));
78 	AttribEditor->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
79 
80 	IGUITab* TreeTab = TabControl->addTab(L"Tree");
81 	TreeView = environment->addTreeView(core::rect<s32>(0,0,0,0), TreeTab);
82 	TreeView->setRelativePositionProportional(core::rect<f32>(0.0f, 0.0f, 1.0f, 1.0f));
83 	TreeView->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
84 	IGUITreeViewNode* treenode = TreeView->getRoot();
85 	//treenode->addChildFront(L"Elements");
86 	ResizeButton = environment->addButton(core::rect<s32>(199-th,449-th,199,449), this);
87 	ResizeButton->setDrawBorder(false);
88 	ResizeButton->setEnabled(false);
89 	ResizeButton->setSpriteBank(skin->getSpriteBank());
90 	ResizeButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_RESIZE), skin->getColor(EGDC_WINDOW_SYMBOL));
91 	ResizeButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_RESIZE), skin->getColor(EGDC_WINDOW_SYMBOL));
92 	ResizeButton->grab();
93 	ResizeButton->setSubElement(true);
94 	ResizeButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT);
95 	updateTree();
96 }
97 
98 
99 //! destructor
~CGUIEditWindow()100 CGUIEditWindow::~CGUIEditWindow()
101 {
102 	// drop everything
103 	if (AttribEditor)
104 		AttribEditor->drop();
105 	if (EnvEditor)
106 		EnvEditor->drop();
107 	if (OptionEditor)
108 		OptionEditor->drop();
109 	if (ResizeButton)
110 		ResizeButton->drop();
111 }
112 
getTreeView() const113 IGUITreeView* CGUIEditWindow::getTreeView() const
114 {
115 	return TreeView;
116 }
getEnvironmentEditor() const117 CGUIAttributeEditor* CGUIEditWindow::getEnvironmentEditor() const
118 {
119 	return EnvEditor;
120 }
121 
getAttributeEditor() const122 CGUIAttributeEditor* CGUIEditWindow::getAttributeEditor() const
123 {
124 	return AttribEditor;
125 }
126 
getOptionEditor() const127 CGUIAttributeEditor* CGUIEditWindow::getOptionEditor() const
128 {
129 	return OptionEditor;
130 }
131 
getTreeNode(IGUIElement * element,IGUITreeViewNode * searchnode)132 IGUITreeViewNode* CGUIEditWindow::getTreeNode(IGUIElement* element, IGUITreeViewNode* searchnode)
133 {
134 	IGUITreeViewNode* child = searchnode->getFirstChild();
135 	while (child)
136 	{
137 		if (((IGUIElement*) child->getData()) == element)
138 			return child;
139 
140 		if (child->hasChildren())
141 		{
142 			IGUITreeViewNode* foundnode = getTreeNode(element, child);
143 			if (foundnode)
144 				return foundnode;
145 		}
146 		child = child->getNextSibling();
147 	}
148 	return 0;
149 }
150 
addChildrenToTree(IGUIElement * parentElement,IGUITreeViewNode * treenode)151 void CGUIEditWindow::addChildrenToTree(IGUIElement* parentElement, IGUITreeViewNode* treenode)
152 {
153 	core::stringw name = core::stringw(parentElement->getTypeName());
154 	if (parentElement->getID() != -1)
155 		name += core::stringw(L" [") + core::stringw(parentElement->getID()) + core::stringw(L"]");
156 
157 	IGUITreeViewNode* newnode = treenode->addChildBack(name.c_str());
158 	newnode->setData((void*)parentElement);
159 	core::list<IGUIElement*> children = parentElement->getChildren();
160 
161 	for (core::list<IGUIElement*>::Iterator i = children.begin(); i != children.end(); i++ )
162 	{
163 		if(core::stringc((*i)->getTypeName()) != "GUIEditor" && !(*i)->isSubElement())
164 			addChildrenToTree(*i, newnode);
165 	}
166 }
167 
updateTree()168 void CGUIEditWindow::updateTree()
169 {
170 	TreeView->getRoot()->clearChildren();
171 	IGUIElement* root = Environment->getRootGUIElement();
172 	addChildrenToTree(root, TreeView->getRoot());
173 	TreeView->getRoot()->getFirstChild()->setExpanded(true);
174 }
175 
setSelectedElement(IGUIElement * sel)176 void CGUIEditWindow::setSelectedElement(IGUIElement *sel)
177 {
178 	// save changes
179 	AttribEditor->updateAttribs();
180 	IGUITreeViewNode* elementTreeNode = getTreeNode(sel, TreeView->getRoot());
181 
182 	if (elementTreeNode)
183 	{
184 		elementTreeNode->setSelected(true);
185 		while (elementTreeNode)
186 		{
187 			elementTreeNode->setExpanded(true);
188 			elementTreeNode = elementTreeNode->getParent();
189 		}
190 	}
191 
192 	io::IAttributes* Attribs = AttribEditor->getAttribs();
193 
194 	if (SelectedElement && sel != SelectedElement)
195 	{
196 		// deserialize attributes
197 		SelectedElement->deserializeAttributes(Attribs);
198 	}
199 	// clear the attributes list
200 	Attribs->clear();
201 	SelectedElement = sel;
202 
203 	// get the new attributes
204 	if (SelectedElement)
205 		SelectedElement->serializeAttributes(Attribs);
206 
207 	AttribEditor->refreshAttribs();
208 }
209 
210 //! draws the element and its children.
211 //! same code as for a window
draw()212 void CGUIEditWindow::draw()
213 {
214 	if (!IsVisible)
215 		return;
216 
217 	IGUISkin* skin = Environment->getSkin();
218 
219 	core::rect<s32> rect = AbsoluteRect;
220 
221 	// draw body fast
222 	rect = skin->draw3DWindowBackground(this, true, skin->getColor(EGDC_ACTIVE_BORDER),
223 		AbsoluteRect, &AbsoluteClippingRect);
224 
225 	if (Text.size())
226 	{
227 		rect.UpperLeftCorner.X += skin->getSize(EGDS_TEXT_DISTANCE_X);
228 		rect.UpperLeftCorner.Y += skin->getSize(EGDS_TEXT_DISTANCE_Y);
229 		rect.LowerRightCorner.X -= skin->getSize(EGDS_WINDOW_BUTTON_WIDTH) + 5;
230 
231 		IGUIFont* font = skin->getFont();
232 		if (font)
233 			font->draw(Text.c_str(), rect, skin->getColor(EGDC_ACTIVE_CAPTION), false, true, &AbsoluteClippingRect);
234 	}
235 
236 	IGUIElement::draw();
237 }
238 
239 
240 //! called if an event happened.
OnEvent(const SEvent & event)241 bool CGUIEditWindow::OnEvent(const SEvent &event)
242 {
243 	switch(event.EventType)
244 	{
245 	case EET_GUI_EVENT:
246 		switch(event.GUIEvent.EventType)
247 		{
248 		case EGET_ELEMENT_FOCUS_LOST:
249 			if (event.GUIEvent.Caller == this ||
250 				event.GUIEvent.Caller == ResizeButton)
251 			{
252 				Dragging = false;
253 				Resizing = false;
254 			}
255 			break;
256 		default:
257 			break;
258 		}
259 
260 		break;
261 	case EET_MOUSE_INPUT_EVENT:
262 		switch(event.MouseInput.Event)
263 		{
264 		case EMIE_LMOUSE_PRESSED_DOWN:
265 		{
266 			DragStart.X = event.MouseInput.X;
267 			DragStart.Y = event.MouseInput.Y;
268 
269 			IGUIElement* clickedElement = getElementFromPoint(DragStart);
270 
271 			if (clickedElement == this)
272 			{
273 				Dragging = IsDraggable;
274 				//Environment->setFocus(this);
275 				if (Parent)
276 					Parent->bringToFront(this);
277 				return true;
278 			}
279 			else if (clickedElement == ResizeButton)
280 			{
281 				Resizing = true;
282 				//Environment->setFocus(this);
283 				if (Parent)
284 					Parent->bringToFront(this);
285 				return true;
286 			}
287 			break;
288 		}
289 		case EMIE_LMOUSE_LEFT_UP:
290 			if (Dragging || Resizing)
291 			{
292 				Dragging = false;
293 				Resizing = false;
294 				return true;
295 			}
296 			break;
297 		case EMIE_MOUSE_MOVED:
298 			if (Dragging || Resizing)
299 			{
300 				// gui window should not be dragged outside of its parent
301 				if (Parent)
302 					if (event.MouseInput.X < Parent->getAbsolutePosition().UpperLeftCorner.X +1 ||
303 						event.MouseInput.Y < Parent->getAbsolutePosition().UpperLeftCorner.Y +1 ||
304 						event.MouseInput.X > Parent->getAbsolutePosition().LowerRightCorner.X -1 ||
305 						event.MouseInput.Y > Parent->getAbsolutePosition().LowerRightCorner.Y -1)
306 
307 						return true;
308 				core::position2di diff(event.MouseInput.X - DragStart.X, event.MouseInput.Y - DragStart.Y);
309 				if (Dragging)
310 				{
311 					move(diff);
312 					DragStart.X = event.MouseInput.X;
313 					DragStart.Y = event.MouseInput.Y;
314 				}
315 				else if (Resizing)
316 				{
317 					core::position2di dp = RelativeRect.LowerRightCorner + diff;
318 					setRelativePosition(core::rect<s32>(RelativeRect.UpperLeftCorner, dp));
319 					DragStart += dp - RelativeRect.LowerRightCorner + diff;
320 				}
321 
322 				return true;
323 			}
324 			break;
325 		default:
326 			break;
327 		}
328 	default:
329 		break;
330 	}
331 
332 	return Parent ? Parent->OnEvent(event) : false;
333 }
334 
isDraggable() const335 bool CGUIEditWindow::isDraggable() const
336 {
337 	return IsDraggable;
338 }
339 
setDraggable(bool draggable)340 void CGUIEditWindow::setDraggable(bool draggable)
341 {
342 	IsDraggable = draggable;
343 
344 	if (Dragging && !IsDraggable)
345 		Dragging = false;
346 }
347 
348 
349 // we're supposed to supply these if we're creating an IGUIWindow
350 // but we don't need them so we'll just return null
351 
352 //! Returns the rectangle of the drawable area (without border, without titlebar and without scrollbars)
getClientRect() const353 core::rect<s32> CGUIEditWindow::getClientRect() const  {return core::recti();}
getCloseButton() const354 IGUIButton* CGUIEditWindow::getCloseButton()    const  {return 0;}
getMinimizeButton() const355 IGUIButton* CGUIEditWindow::getMinimizeButton() const  {return 0;}
getMaximizeButton() const356 IGUIButton* CGUIEditWindow::getMaximizeButton() const  {return 0;}
357