aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIContextMenu.cpp
diff options
context:
space:
mode:
authorDavid Walter Seikel2016-03-28 22:28:34 +1000
committerDavid Walter Seikel2016-03-28 22:28:34 +1000
commit7028cbe09c688437910a25623098762bf0fa592d (patch)
tree10b5af58277d9880380c2251f109325542c4e6eb /src/others/irrlicht-1.8.1/source/Irrlicht/CGUIContextMenu.cpp
parentMove lemon to the src/others directory. (diff)
downloadSledjHamr-7028cbe09c688437910a25623098762bf0fa592d.zip
SledjHamr-7028cbe09c688437910a25623098762bf0fa592d.tar.gz
SledjHamr-7028cbe09c688437910a25623098762bf0fa592d.tar.bz2
SledjHamr-7028cbe09c688437910a25623098762bf0fa592d.tar.xz
Move Irrlicht to src/others.
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CGUIContextMenu.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CGUIContextMenu.cpp869
1 files changed, 869 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIContextMenu.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIContextMenu.cpp
new file mode 100644
index 0000000..67631e7
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIContextMenu.cpp
@@ -0,0 +1,869 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h
4
5#include "CGUIContextMenu.h"
6
7#ifdef _IRR_COMPILE_WITH_GUI_
8
9#include "IGUISkin.h"
10#include "IGUIEnvironment.h"
11#include "IVideoDriver.h"
12#include "IGUIFont.h"
13#include "IGUISpriteBank.h"
14#include "os.h"
15
16namespace irr
17{
18namespace gui
19{
20
21
22//! constructor
23CGUIContextMenu::CGUIContextMenu(IGUIEnvironment* environment,
24 IGUIElement* parent, s32 id,
25 core::rect<s32> rectangle, bool getFocus, bool allowFocus)
26 : IGUIContextMenu(environment, parent, id, rectangle), EventParent(0), LastFont(0),
27 CloseHandling(ECMC_REMOVE), HighLighted(-1), ChangeTime(0), AllowFocus(allowFocus)
28{
29 #ifdef _DEBUG
30 setDebugName("CGUIContextMenu");
31 #endif
32
33 Pos = rectangle.UpperLeftCorner;
34 recalculateSize();
35
36 if (getFocus)
37 Environment->setFocus(this);
38
39 setNotClipped(true);
40}
41
42
43//! destructor
44CGUIContextMenu::~CGUIContextMenu()
45{
46 for (u32 i=0; i<Items.size(); ++i)
47 if (Items[i].SubMenu)
48 Items[i].SubMenu->drop();
49
50 if (LastFont)
51 LastFont->drop();
52}
53
54//! set behavior when menus are closed
55void CGUIContextMenu::setCloseHandling(ECONTEXT_MENU_CLOSE onClose)
56{
57 CloseHandling = onClose;
58}
59
60//! get current behavior when the menue will be closed
61ECONTEXT_MENU_CLOSE CGUIContextMenu::getCloseHandling() const
62{
63 return CloseHandling;
64}
65
66//! Returns amount of menu items
67u32 CGUIContextMenu::getItemCount() const
68{
69 return Items.size();
70}
71
72
73//! Adds a menu item.
74u32 CGUIContextMenu::addItem(const wchar_t* text, s32 commandId, bool enabled, bool hasSubMenu, bool checked, bool autoChecking)
75{
76 return insertItem(Items.size(), text, commandId, enabled, hasSubMenu, checked, autoChecking);
77}
78
79//! Insert a menu item at specified position.
80u32 CGUIContextMenu::insertItem(u32 idx, const wchar_t* text, s32 commandId, bool enabled,
81 bool hasSubMenu, bool checked, bool autoChecking)
82{
83 SItem s;
84 s.Enabled = enabled;
85 s.Checked = checked;
86 s.AutoChecking = autoChecking;
87 s.Text = text;
88 s.IsSeparator = (text == 0);
89 s.SubMenu = 0;
90 s.CommandId = commandId;
91
92 if (hasSubMenu)
93 {
94 s.SubMenu = new CGUIContextMenu(Environment, this, commandId,
95 core::rect<s32>(0,0,100,100), false, false);
96 s.SubMenu->setVisible(false);
97 }
98
99 u32 result = idx;
100 if ( idx < Items.size() )
101 {
102 Items.insert(s, idx);
103 }
104 else
105 {
106 Items.push_back(s);
107 result = Items.size() - 1;
108 }
109
110 recalculateSize();
111 return result;
112}
113
114s32 CGUIContextMenu::findItemWithCommandId(s32 commandId, u32 idxStartSearch) const
115{
116 for ( u32 i=idxStartSearch; i<Items.size(); ++i )
117 {
118 if ( Items[i].CommandId == commandId )
119 {
120 return (s32)i;
121 }
122 }
123 return -1;
124}
125
126//! Adds a sub menu from an element that already exists.
127void CGUIContextMenu::setSubMenu(u32 index, CGUIContextMenu* menu)
128{
129 if (index >= Items.size())
130 return;
131
132 if (menu)
133 menu->grab();
134 if (Items[index].SubMenu)
135 Items[index].SubMenu->drop();
136
137 Items[index].SubMenu = menu;
138 menu->setVisible(false);
139
140 if (Items[index].SubMenu)
141 {
142 menu->AllowFocus = false;
143 if ( Environment->getFocus() == menu )
144 {
145 Environment->setFocus( this );
146 }
147 }
148
149 recalculateSize();
150}
151
152
153//! Adds a separator item to the menu
154void CGUIContextMenu::addSeparator()
155{
156 addItem(0, -1, true, false, false, false);
157}
158
159
160//! Returns text of the menu item.
161const wchar_t* CGUIContextMenu::getItemText(u32 idx) const
162{
163 if (idx >= Items.size())
164 return 0;
165
166 return Items[idx].Text.c_str();
167}
168
169
170//! Sets text of the menu item.
171void CGUIContextMenu::setItemText(u32 idx, const wchar_t* text)
172{
173 if (idx >= Items.size())
174 return;
175
176 Items[idx].Text = text;
177 recalculateSize();
178}
179
180//! should the element change the checked status on clicking
181void CGUIContextMenu::setItemAutoChecking(u32 idx, bool autoChecking)
182{
183 if ( idx >= Items.size())
184 return;
185
186 Items[idx].AutoChecking = autoChecking;
187}
188
189//! does the element change the checked status on clicking
190bool CGUIContextMenu::getItemAutoChecking(u32 idx) const
191{
192 if (idx >= Items.size())
193 return false;
194
195 return Items[idx].AutoChecking;
196}
197
198
199//! Returns if a menu item is enabled
200bool CGUIContextMenu::isItemEnabled(u32 idx) const
201{
202 if (idx >= Items.size())
203 {
204 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
205 return false;
206 }
207
208 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
209 return Items[idx].Enabled;
210}
211
212
213//! Returns if a menu item is checked
214bool CGUIContextMenu::isItemChecked(u32 idx) const
215{
216 if (idx >= Items.size())
217 {
218 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
219 return false;
220 }
221
222 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
223 return Items[idx].Checked;
224}
225
226
227//! Sets if the menu item should be enabled.
228void CGUIContextMenu::setItemEnabled(u32 idx, bool enabled)
229{
230 if (idx >= Items.size())
231 return;
232
233 Items[idx].Enabled = enabled;
234}
235
236
237//! Sets if the menu item should be checked.
238void CGUIContextMenu::setItemChecked(u32 idx, bool checked )
239{
240 if (idx >= Items.size())
241 return;
242
243 Items[idx].Checked = checked;
244}
245
246
247//! Removes a menu item
248void CGUIContextMenu::removeItem(u32 idx)
249{
250 if (idx >= Items.size())
251 return;
252
253 if (Items[idx].SubMenu)
254 {
255 Items[idx].SubMenu->drop();
256 Items[idx].SubMenu = 0;
257 }
258
259 Items.erase(idx);
260 recalculateSize();
261}
262
263
264//! Removes all menu items
265void CGUIContextMenu::removeAllItems()
266{
267 for (u32 i=0; i<Items.size(); ++i)
268 if (Items[i].SubMenu)
269 Items[i].SubMenu->drop();
270
271 Items.clear();
272 recalculateSize();
273}
274
275
276//! called if an event happened.
277bool CGUIContextMenu::OnEvent(const SEvent& event)
278{
279 if (isEnabled())
280 {
281
282 switch(event.EventType)
283 {
284 case EET_GUI_EVENT:
285 switch(event.GUIEvent.EventType)
286 {
287 case EGET_ELEMENT_FOCUS_LOST:
288 if (event.GUIEvent.Caller == this && !isMyChild(event.GUIEvent.Element) && AllowFocus)
289 {
290 // set event parent of submenus
291 IGUIElement * p = EventParent ? EventParent : Parent;
292 setEventParent(p);
293
294 SEvent event;
295 event.EventType = EET_GUI_EVENT;
296 event.GUIEvent.Caller = this;
297 event.GUIEvent.Element = 0;
298 event.GUIEvent.EventType = EGET_ELEMENT_CLOSED;
299 if ( !p->OnEvent(event) )
300 {
301 if ( CloseHandling & ECMC_HIDE )
302 {
303 setVisible(false);
304 }
305 if ( CloseHandling & ECMC_REMOVE )
306 {
307 remove();
308 }
309 }
310
311 return false;
312 }
313 break;
314 case EGET_ELEMENT_FOCUSED:
315 if (event.GUIEvent.Caller == this && !AllowFocus)
316 {
317 return true;
318 }
319 break;
320 default:
321 break;
322 }
323 break;
324 case EET_MOUSE_INPUT_EVENT:
325 switch(event.MouseInput.Event)
326 {
327 case EMIE_LMOUSE_LEFT_UP:
328 {
329 // menu might be removed if it loses focus in sendClick, so grab a reference
330 grab();
331 const u32 t = sendClick(core::position2d<s32>(event.MouseInput.X, event.MouseInput.Y));
332 if ((t==0 || t==1) && Environment->hasFocus(this))
333 Environment->removeFocus(this);
334 drop();
335 }
336 return true;
337 case EMIE_LMOUSE_PRESSED_DOWN:
338 return true;
339 case EMIE_MOUSE_MOVED:
340 if (Environment->hasFocus(this))
341 highlight(core::position2d<s32>(event.MouseInput.X, event.MouseInput.Y), true);
342 return true;
343 default:
344 break;
345 }
346 break;
347 default:
348 break;
349 }
350 }
351
352 return IGUIElement::OnEvent(event);
353}
354
355
356//! Sets the visible state of this element.
357void CGUIContextMenu::setVisible(bool visible)
358{
359 HighLighted = -1;
360 ChangeTime = os::Timer::getTime();
361 for (u32 j=0; j<Items.size(); ++j)
362 if (Items[j].SubMenu)
363 Items[j].SubMenu->setVisible(false);
364
365 IGUIElement::setVisible(visible);
366}
367
368
369//! sends a click Returns:
370//! 0 if click went outside of the element,
371//! 1 if a valid button was clicked,
372//! 2 if a nonclickable element was clicked
373u32 CGUIContextMenu::sendClick(const core::position2d<s32>& p)
374{
375 u32 t = 0;
376
377 // get number of open submenu
378 s32 openmenu = -1;
379 s32 j;
380 for (j=0; j<(s32)Items.size(); ++j)
381 if (Items[j].SubMenu && Items[j].SubMenu->isVisible())
382 {
383 openmenu = j;
384 break;
385 }
386
387 // delegate click operation to submenu
388 if (openmenu != -1)
389 {
390 t = Items[j].SubMenu->sendClick(p);
391 if (t != 0)
392 return t; // clicked something
393 }
394
395 // check click on myself
396 if (isPointInside(p) &&
397 (u32)HighLighted < Items.size())
398 {
399 if (!Items[HighLighted].Enabled ||
400 Items[HighLighted].IsSeparator ||
401 Items[HighLighted].SubMenu)
402 return 2;
403
404 if ( Items[HighLighted].AutoChecking )
405 {
406 Items[HighLighted].Checked = Items[HighLighted].Checked ? false : true;
407 }
408
409 SEvent event;
410 event.EventType = EET_GUI_EVENT;
411 event.GUIEvent.Caller = this;
412 event.GUIEvent.Element = 0;
413 event.GUIEvent.EventType = EGET_MENU_ITEM_SELECTED;
414 if (EventParent)
415 EventParent->OnEvent(event);
416 else if (Parent)
417 Parent->OnEvent(event);
418
419 return 1;
420 }
421
422 return 0;
423}
424
425
426//! returns true, if an element was highligted
427bool CGUIContextMenu::highlight(const core::position2d<s32>& p, bool canOpenSubMenu)
428{
429 if (!isEnabled())
430 {
431 return false;
432 }
433
434 // get number of open submenu
435 s32 openmenu = -1;
436 s32 i;
437 for (i=0; i<(s32)Items.size(); ++i)
438 if (Items[i].Enabled && Items[i].SubMenu && Items[i].SubMenu->isVisible())
439 {
440 openmenu = i;
441 break;
442 }
443
444 // delegate highlight operation to submenu
445 if (openmenu != -1)
446 {
447 if (Items[openmenu].Enabled && Items[openmenu].SubMenu->highlight(p, canOpenSubMenu))
448 {
449 HighLighted = openmenu;
450 ChangeTime = os::Timer::getTime();
451 return true;
452 }
453 }
454
455 // highlight myself
456 for (i=0; i<(s32)Items.size(); ++i)
457 {
458 if (Items[i].Enabled && getHRect(Items[i], AbsoluteRect).isPointInside(p))
459 {
460 HighLighted = i;
461 ChangeTime = os::Timer::getTime();
462
463 // make submenus visible/invisible
464 for (s32 j=0; j<(s32)Items.size(); ++j)
465 if (Items[j].SubMenu)
466 {
467 if ( j == i && canOpenSubMenu && Items[j].Enabled )
468 Items[j].SubMenu->setVisible(true);
469 else if ( j != i )
470 Items[j].SubMenu->setVisible(false);
471 }
472 return true;
473 }
474 }
475
476 HighLighted = openmenu;
477 return false;
478}
479
480
481//! returns the item highlight-area
482core::rect<s32> CGUIContextMenu::getHRect(const SItem& i, const core::rect<s32>& absolute) const
483{
484 core::rect<s32> r = absolute;
485 r.UpperLeftCorner.Y += i.PosY;
486 r.LowerRightCorner.Y = r.UpperLeftCorner.Y + i.Dim.Height;
487 return r;
488}
489
490
491//! Gets drawing rect of Item
492core::rect<s32> CGUIContextMenu::getRect(const SItem& i, const core::rect<s32>& absolute) const
493{
494 core::rect<s32> r = absolute;
495 r.UpperLeftCorner.Y += i.PosY;
496 r.LowerRightCorner.Y = r.UpperLeftCorner.Y + i.Dim.Height;
497 r.UpperLeftCorner.X += 20;
498 return r;
499}
500
501
502//! draws the element and its children
503void CGUIContextMenu::draw()
504{
505 if (!IsVisible)
506 return;
507
508 IGUISkin* skin = Environment->getSkin();
509
510 if (!skin)
511 return;
512
513 IGUIFont* font = skin->getFont(EGDF_MENU);
514 if (font != LastFont)
515 {
516 if (LastFont)
517 LastFont->drop();
518 LastFont = font;
519 if (LastFont)
520 LastFont->grab();
521
522 recalculateSize();
523 }
524
525 IGUISpriteBank* sprites = skin->getSpriteBank();
526
527 core::rect<s32> rect = AbsoluteRect;
528 core::rect<s32>* clip = 0;
529
530 // draw frame
531 skin->draw3DMenuPane(this, AbsoluteRect, clip);
532
533 // loop through all menu items
534
535 rect = AbsoluteRect;
536 s32 y = AbsoluteRect.UpperLeftCorner.Y;
537
538 for (s32 i=0; i<(s32)Items.size(); ++i)
539 {
540 if (Items[i].IsSeparator)
541 {
542 // draw separator
543 rect = AbsoluteRect;
544 rect.UpperLeftCorner.Y += Items[i].PosY + 3;
545 rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1;
546 rect.UpperLeftCorner.X += 5;
547 rect.LowerRightCorner.X -= 5;
548 skin->draw2DRectangle(this, skin->getColor(EGDC_3D_SHADOW), rect, clip);
549
550 rect.LowerRightCorner.Y += 1;
551 rect.UpperLeftCorner.Y += 1;
552 skin->draw2DRectangle(this, skin->getColor(EGDC_3D_HIGH_LIGHT), rect, clip);
553
554 y += 10;
555 }
556 else
557 {
558 rect = getRect(Items[i], AbsoluteRect);
559
560 // draw highlighted
561
562 if (i == HighLighted && Items[i].Enabled)
563 {
564 core::rect<s32> r = AbsoluteRect;
565 r.LowerRightCorner.Y = rect.LowerRightCorner.Y;
566 r.UpperLeftCorner.Y = rect.UpperLeftCorner.Y;
567 r.LowerRightCorner.X -= 5;
568 r.UpperLeftCorner.X += 5;
569 skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), r, clip);
570 }
571
572 // draw text
573
574 EGUI_DEFAULT_COLOR c = EGDC_BUTTON_TEXT;
575
576 if (i == HighLighted)
577 c = EGDC_HIGH_LIGHT_TEXT;
578
579 if (!Items[i].Enabled)
580 c = EGDC_GRAY_TEXT;
581
582 if (font)
583 font->draw(Items[i].Text.c_str(), rect,
584 skin->getColor(c), false, true, clip);
585
586 // draw submenu symbol
587 if (Items[i].SubMenu && sprites)
588 {
589 core::rect<s32> r = rect;
590 r.UpperLeftCorner.X = r.LowerRightCorner.X - 15;
591
592 sprites->draw2DSprite(skin->getIcon(EGDI_CURSOR_RIGHT),
593 r.getCenter(), clip, skin->getColor(c),
594 (i == HighLighted) ? ChangeTime : 0,
595 (i == HighLighted) ? os::Timer::getTime() : 0,
596 (i == HighLighted), true);
597 }
598
599 // draw checked symbol
600 if (Items[i].Checked && sprites)
601 {
602 core::rect<s32> r = rect;
603 r.LowerRightCorner.X = r.UpperLeftCorner.X - 15;
604 r.UpperLeftCorner.X = r.LowerRightCorner.X + 15;
605 sprites->draw2DSprite(skin->getIcon(EGDI_CHECK_BOX_CHECKED),
606 r.getCenter(), clip, skin->getColor(c),
607 (i == HighLighted) ? ChangeTime : 0,
608 (i == HighLighted) ? os::Timer::getTime() : 0,
609 (i == HighLighted), true);
610 }
611 }
612 }
613
614 IGUIElement::draw();
615}
616
617
618void CGUIContextMenu::recalculateSize()
619{
620 IGUIFont* font = Environment->getSkin()->getFont(EGDF_MENU);
621
622 if (!font)
623 return;
624
625 core::rect<s32> rect;
626 rect.UpperLeftCorner = RelativeRect.UpperLeftCorner;
627 u32 width = 100;
628 u32 height = 3;
629
630 u32 i;
631 for (i=0; i<Items.size(); ++i)
632 {
633 if (Items[i].IsSeparator)
634 {
635 Items[i].Dim.Width = 100;
636 Items[i].Dim.Height = 10;
637 }
638 else
639 {
640 Items[i].Dim = font->getDimension(Items[i].Text.c_str());
641 Items[i].Dim.Width += 40;
642
643 if (Items[i].Dim.Width > width)
644 width = Items[i].Dim.Width;
645 }
646
647 Items[i].PosY = height;
648 height += Items[i].Dim.Height;
649 }
650
651 height += 5;
652
653 if (height < 10)
654 height = 10;
655
656 rect.LowerRightCorner.X = RelativeRect.UpperLeftCorner.X + width;
657 rect.LowerRightCorner.Y = RelativeRect.UpperLeftCorner.Y + height;
658
659 setRelativePosition(rect);
660
661 // recalculate submenus
662 for (i=0; i<Items.size(); ++i)
663 {
664 if (Items[i].SubMenu)
665 {
666 // move submenu
667 const s32 w = Items[i].SubMenu->getAbsolutePosition().getWidth();
668 const s32 h = Items[i].SubMenu->getAbsolutePosition().getHeight();
669
670 core::rect<s32> subRect(width-5, Items[i].PosY, width+w-5, Items[i].PosY+h);
671
672 // if it would be drawn beyond the right border, then add it to the left side
673 gui::IGUIElement * root = Environment->getRootGUIElement();
674 if ( root )
675 {
676 core::rect<s32> rectRoot( root->getAbsolutePosition() );
677 if ( getAbsolutePosition().UpperLeftCorner.X+subRect.LowerRightCorner.X > rectRoot.LowerRightCorner.X )
678 {
679 subRect.UpperLeftCorner.X = -w;
680 subRect.LowerRightCorner.X = 0;
681 }
682 }
683
684 Items[i].SubMenu->setRelativePosition(subRect);
685 }
686 }
687}
688
689
690//! Returns the selected item in the menu
691s32 CGUIContextMenu::getSelectedItem() const
692{
693 return HighLighted;
694}
695
696
697//! \return Returns a pointer to the submenu of an item.
698IGUIContextMenu* CGUIContextMenu::getSubMenu(u32 idx) const
699{
700 if (idx >= Items.size())
701 return 0;
702
703 return Items[idx].SubMenu;
704}
705
706
707//! Returns command id of a menu item
708s32 CGUIContextMenu::getItemCommandId(u32 idx) const
709{
710 if (idx >= Items.size())
711 return -1;
712
713 return Items[idx].CommandId;
714}
715
716
717//! Sets the command id of a menu item
718void CGUIContextMenu::setItemCommandId(u32 idx, s32 id)
719{
720 if (idx >= Items.size())
721 return;
722
723 Items[idx].CommandId = id;
724}
725
726
727//! Writes attributes of the element.
728void CGUIContextMenu::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const
729{
730 IGUIElement::serializeAttributes(out,options);
731 out->addPosition2d("Position", Pos);
732
733 if (Parent->getType() == EGUIET_CONTEXT_MENU || Parent->getType() == EGUIET_MENU )
734 {
735 const IGUIContextMenu* const ptr = (const IGUIContextMenu*)Parent;
736 // find the position of this item in its parent's list
737 u32 i;
738 // VC6 needs the cast for this
739 for (i=0; (i<ptr->getItemCount()) && (ptr->getSubMenu(i) != (const IGUIContextMenu*)this); ++i)
740 ; // do nothing
741
742 out->addInt("ParentItem", i);
743 }
744
745 out->addInt("CloseHandling", (s32)CloseHandling);
746
747 // write out the item list
748 out->addInt("ItemCount", Items.size());
749
750 core::stringc tmp;
751
752 for (u32 i=0; i < Items.size(); ++i)
753 {
754 tmp = "IsSeparator"; tmp += i;
755 out->addBool(tmp.c_str(), Items[i].IsSeparator);
756
757 if (!Items[i].IsSeparator)
758 {
759 tmp = "Text"; tmp += i;
760 out->addString(tmp.c_str(), Items[i].Text.c_str());
761 tmp = "CommandID"; tmp += i;
762 out->addInt(tmp.c_str(), Items[i].CommandId);
763 tmp = "Enabled"; tmp += i;
764 out->addBool(tmp.c_str(), Items[i].Enabled);
765 tmp = "Checked"; tmp += i;
766 out->addBool(tmp.c_str(), Items[i].Checked);
767 tmp = "AutoChecking"; tmp += i;
768 out->addBool(tmp.c_str(), Items[i].AutoChecking);
769 }
770 }
771}
772
773
774//! Reads attributes of the element
775void CGUIContextMenu::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0)
776{
777 IGUIElement::deserializeAttributes(in,options);
778
779 Pos = in->getAttributeAsPosition2d("Position");
780
781 // link to this item's parent
782 if (Parent && ( Parent->getType() == EGUIET_CONTEXT_MENU || Parent->getType() == EGUIET_MENU ) )
783 ((CGUIContextMenu*)Parent)->setSubMenu(in->getAttributeAsInt("ParentItem"),this);
784
785 CloseHandling = (ECONTEXT_MENU_CLOSE)in->getAttributeAsInt("CloseHandling");
786
787 removeAllItems();
788
789 // read the item list
790 const s32 count = in->getAttributeAsInt("ItemCount");
791
792 for (s32 i=0; i<count; ++i)
793 {
794 core::stringc tmp;
795 core::stringw txt;
796 s32 commandid=-1;
797 bool enabled=true;
798 bool checked=false;
799 bool autochecking=false;
800
801 tmp = "IsSeparator"; tmp += i;
802 if ( in->existsAttribute(tmp.c_str()) && in->getAttributeAsBool(tmp.c_str()) )
803 addSeparator();
804 else
805 {
806 tmp = "Text"; tmp += i;
807 if ( in->existsAttribute(tmp.c_str()) )
808 txt = in->getAttributeAsStringW(tmp.c_str());
809
810 tmp = "CommandID"; tmp += i;
811 if ( in->existsAttribute(tmp.c_str()) )
812 commandid = in->getAttributeAsInt(tmp.c_str());
813
814 tmp = "Enabled"; tmp += i;
815 if ( in->existsAttribute(tmp.c_str()) )
816 enabled = in->getAttributeAsBool(tmp.c_str());
817
818 tmp = "Checked"; tmp += i;
819 if ( in->existsAttribute(tmp.c_str()) )
820 checked = in->getAttributeAsBool(tmp.c_str());
821
822 tmp = "AutoChecking"; tmp += i;
823 if ( in->existsAttribute(tmp.c_str()) )
824 autochecking = in->getAttributeAsBool(tmp.c_str());
825
826 addItem(core::stringw(txt.c_str()).c_str(), commandid, enabled, false, checked, autochecking);
827 }
828 }
829
830 recalculateSize();
831}
832
833
834// because sometimes the element has no parent at click time
835void CGUIContextMenu::setEventParent(IGUIElement *parent)
836{
837 EventParent = parent;
838
839 for (u32 i=0; i<Items.size(); ++i)
840 if (Items[i].SubMenu)
841 Items[i].SubMenu->setEventParent(parent);
842}
843
844
845bool CGUIContextMenu::hasOpenSubMenu() const
846{
847 for (u32 i=0; i<Items.size(); ++i)
848 if (Items[i].SubMenu && Items[i].SubMenu->isVisible())
849 return true;
850
851 return false;
852}
853
854
855void CGUIContextMenu::closeAllSubMenus()
856{
857 for (u32 i=0; i<Items.size(); ++i)
858 if (Items[i].SubMenu)
859 Items[i].SubMenu->setVisible(false);
860
861 //HighLighted = -1;
862}
863
864
865} // end namespace
866} // end namespace
867
868#endif // _IRR_COMPILE_WITH_GUI_
869