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