1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2020 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 // Copyright (C) 2014-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as
10 // published by the Free Software Foundation, either version 3 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "nel/gui/interface_options.h"
23 #include "nel/gui/interface_expr.h"
24 #include "nel/gui/group_menu.h"
25 #include "nel/misc/xml_auto_ptr.h"
26 #include "nel/gui/view_bitmap.h"
27 #include "nel/gui/action_handler.h" // Just for getAllParams
28 #include "nel/gui/lua_ihm.h"
29 #include "nel/misc/i18n.h"
30 #include "nel/gui/widget_manager.h"
31 #include "nel/gui/group_list.h"
32 #include "nel/gui/ctrl_scroll.h"
33 #include "nel/gui/view_pointer_base.h"
36 using namespace NLMISC
;
45 const std::string ID_MENU_CHECKBOX
= "menu_cb";
46 const std::string ID_MENU_SEPARATOR
= "menu_separator";
47 const std::string ID_MENU_SUBMENU
= "menu_sb";
48 const uint MENU_WIDGET_X
= 2;
49 const uint LEFT_MENU_WIDGET_X
= 4;
55 // ------------------------------------------------------------------------------------------------
57 // ------------------------------------------------------------------------------------------------
59 // ------------------------------------------------------------------------------------------------
60 bool CViewTextMenu::getGrayed() const
65 // ------------------------------------------------------------------------------------------------
66 void CViewTextMenu::setGrayed (bool g
)
71 // ------------------------------------------------------------------------------------------------
72 void CViewTextMenu::setCheckable(bool c
)
85 // ------------------------------------------------------------------------------------------------
86 void CViewTextMenu::setChecked(bool c
)
90 CInterfaceOptions
*pIO
= CWidgetManager::getInstance()->getOptions("menu_checkbox");
92 _CheckBox
->setTexture(pIO
->getValStr(c
? "checked_bitmap" : "unchecked_bitmap"));
97 // ------------------------------------------------------------------------------------------------
98 sint32
CViewTextMenu::getAlpha() const
102 return OldColorGrayed
.A
;
107 return OldColorOver
.A
;
113 // ------------------------------------------------------------------------------------------------
114 void CViewTextMenu::setAlpha (sint32 a
)
116 OldShadowColor
.A
= OldColor
.A
= (uint8
)a
;
117 OldShadowColorOver
.A
= OldColorOver
.A
= (uint8
)a
;
118 OldShadowColorGrayed
.A
= OldColorGrayed
.A
= (uint8
)a
;
121 // ------------------------------------------------------------------------------------------------
123 // ------------------------------------------------------------------------------------------------
125 // ------------------------------------------------------------------------------------------------
126 CGroupSubMenu::CGroupSubMenu(const TCtorParam
¶m
)
127 : CGroupSubMenuBase(param
)
129 _SelectionView
= NULL
;
133 _MaxVisibleLine
= -1;
137 // ------------------------------------------------------------------------------------------------
138 CGroupSubMenu::~CGroupSubMenu()
140 removeAllUserGroups();
143 // ------------------------------------------------------------------------------------------------
144 sint
CGroupSubMenu::getLineFromId(const std::string
&id
)
146 for (uint k
= 0; k
< _Lines
.size(); ++k
)
148 if (_Lines
[k
].Id
== id
)
156 // ------------------------------------------------------------------------------------------------
157 CGroupSubMenu
*CGroupSubMenu::getSubMenu(uint index
) const
159 if (index
>= _SubMenus
.size())
161 nlassert("bad index");
164 return _SubMenus
[index
];
167 // ------------------------------------------------------------------------------------------------
168 void CGroupSubMenu::setSubMenu(uint index
, CGroupSubMenu
*sub
)
170 nlassert(sub
!= NULL
);
171 nlassert(index
< _SubMenus
.size());
172 sub
->setSerializable( false );
174 if (_SubMenus
[index
] != NULL
)
176 // must delete from the group menu (if not found, just delete)
177 if( !_GroupMenu
|| !_GroupMenu
->delGroup(_SubMenus
[index
]) )
178 delete _SubMenus
[index
];
179 _SubMenus
[index
] = NULL
;
180 delView(_Lines
[index
].RightArrow
);
183 if (_Lines
[index
].CheckBox
)
184 _Lines
[index
].RightArrow
= createRightArrow(_Lines
[index
].CheckBox
, true);
186 _Lines
[index
].RightArrow
= createRightArrow(_GroupList
, false);
188 sub
->_GroupMenu
= _GroupMenu
;
189 sub
->initOptions(this);
190 _GroupMenu
->addGroup (sub
);
191 sub
->_DispType
= _GroupMenu
->_DispType
;
192 _SubMenus
[index
] = sub
;
195 // ------------------------------------------------------------------------------------------------
196 void CGroupSubMenu::initOptions(CInterfaceGroup
*parent
)
200 _Parent
= _GroupMenu
;
203 setParentPos (_GroupMenu
);
204 setParentPosRef (Hotspot_TL
);
205 setPosRef (Hotspot_TL
);
209 setParentPos (parent
);
210 setParentPosRef (Hotspot_BR
);
211 setPosRef (Hotspot_BL
);
213 _DisplayFrame
= true;
214 _ResizeFromChildH
= true;
215 _ResizeFromChildW
= true;
216 _ResizeFromChildHMargin
= 8;
217 _ResizeFromChildWMargin
= 8;
218 _ModulateGlobalColor
= _GroupMenu
->_ModulateGlobalColor
;
220 if (_SelectionView
== NULL
)
222 _SelectionView
= new CViewBitmap(CViewBase::TCtorParam());
223 // CInterfaceManager *pIM = CInterfaceManager::getInstance();
224 // CViewRenderer &rVR = *CViewRenderer::getInstance();
225 _SelectionView
->setId( getId() + ":selection" );
226 _SelectionView
->setParent (this);
227 _SelectionView
->setActive (false);
228 _SelectionView
->setTexture ("blank.tga");
229 _SelectionView
->setScale (true);
230 _SelectionView
->setX (4);
231 _SelectionView
->setSizeRef(1); // sizeref on W
232 _SelectionView
->setW (-8);
233 _SelectionView
->setSerializable( false );
234 addView (_SelectionView
, 0);
237 if (_GroupList
== NULL
)
239 _GroupList
= new CGroupList(CViewBase::TCtorParam());
240 _GroupList
->setId( getId() + ":list" );
241 _GroupList
->setParent (this);
242 _GroupList
->setParentPos (this);
243 _GroupList
->setX (4);
244 _GroupList
->setY (4);
245 _GroupList
->setSpace (_GroupMenu
->_Space
);
246 _GroupList
->setSerializable( false );
247 _GroupList
->setResizeFromChildW(true);
248 addGroup (_GroupList
);
252 // ------------------------------------------------------------------------------------------------
253 bool CGroupSubMenu::parse (xmlNodePtr cur
, CInterfaceGroup
*parent
)
259 CViewTextMenu
*pV
= NULL
;
261 CXMLAutoPtr
id((const char*) xmlGetProp (cur
, (xmlChar
*)"id"));
263 if (stricmp((char*)cur
->name
, "separator") == 0)
267 addSeparator((const char *) id
);
275 if (stricmp((char*)cur
->name
, "action") == 0)
277 string strId
, strAh
, strParams
, strCond
, strTexture
;
280 if (id
) strId
= (const char*)id
;
281 CXMLAutoPtr
name((const char*) xmlGetProp (cur
, (xmlChar
*)"name"));
285 const char *ptrName
= (const char*)name
;
286 if (NLMISC::startsWith(ptrName
, "ui"))
287 ucstrName
= CI18N::get(ptrName
);
292 CXMLAutoPtr
ah((const char*) xmlGetProp (cur
, (xmlChar
*)"handler"));
293 if (ah
) strAh
= (const char*)ah
;
294 CXMLAutoPtr
cond((const char*) xmlGetProp (cur
, (xmlChar
*)"cond"));
295 if (cond
) strCond
= (const char*)cond
;
296 CXMLAutoPtr
params((const char*) xmlGetProp (cur
, (xmlChar
*)"params"));
297 if (params
) strParams
= (const char*)params
;
298 CXMLAutoPtr
strCheckable((const char*) xmlGetProp (cur
, (xmlChar
*)"checkable"));
299 bool bCheckable
= false;
300 if (strCheckable
) bCheckable
= convertBool (strCheckable
);
301 CXMLAutoPtr
strChecked((const char*) xmlGetProp (cur
, (xmlChar
*)"checked"));
302 bool bChecked
= false;
303 if (strChecked
) bChecked
= convertBool (strChecked
);
304 bool bFormatted
= false;
305 CXMLAutoPtr
strFormatted((const char*) xmlGetProp (cur
, (xmlChar
*)"formatted"));
306 if (strFormatted
) bFormatted
= convertBool (strFormatted
);
308 pV
= addLine (ucstrName
, strAh
, strParams
, strId
, strCond
, strTexture
, bCheckable
, bChecked
, bFormatted
);
309 pV
->setSerializable( false );
311 CXMLAutoPtr
strSelectable((const char*) xmlGetProp (cur
, (xmlChar
*)"selectable"));
312 bool bSelectable
= true;
313 if (strSelectable
) bSelectable
= convertBool (strSelectable
);
314 _Lines
.back().Selectable
= bSelectable
;
317 CXMLAutoPtr
grayed((const char*) xmlGetProp (cur
, (xmlChar
*)"grayed"));
318 bool bGrayed
= false;
319 if (grayed
) bGrayed
= convertBool (grayed
);
320 pV
->setGrayed(bGrayed
);
322 // Is this line has a sub menu ?
323 xmlNodePtr child
= cur
->children
;
326 if (_Lines
.back().CheckBox
)
328 _Lines
.back().RightArrow
= createRightArrow(_Lines
.back().CheckBox
, true);
332 _Lines
.back().RightArrow
= createRightArrow(_GroupList
, false);
334 // and create the sub menu
335 CGroupSubMenu
*childMenu
= new CGroupSubMenu(CViewText::TCtorParam());
336 childMenu
->_GroupMenu
= _GroupMenu
;
337 childMenu
->setSerializable( false );
338 childMenu
->parse (child
, this);
340 CXMLAutoPtr
MVL((const char*) xmlGetProp(cur
, (xmlChar
*)"max_visible_line"));
343 sint32 maxVisibleLine
;
344 fromString((const char*)MVL
, maxVisibleLine
);
345 childMenu
->setMaxVisibleLine(maxVisibleLine
);
348 _SubMenus
.back() = childMenu
;
353 CXMLAutoPtr
usergroup((const char*) xmlGetProp (cur
, (xmlChar
*)"usergroup_l"));
356 vector
< pair
<string
,string
> > vparams
;
357 CXMLAutoPtr
ugparams((const char*) xmlGetProp (cur
, (xmlChar
*)"usergroup_params_l"));
360 IActionHandler::getAllParams((const char*)ugparams
, vparams
);
363 string completeId
= _Parent
->getId() + ":" + _Lines
[_Lines
.size()-1].Id
;
364 CInterfaceGroup
*pUGLeft
= CWidgetManager::getInstance()->getParser()->createGroupInstance((const char*)usergroup
, completeId
, vparams
);
366 setUserGroupLeft((uint
)_Lines
.size()-1, pUGLeft
, true);
368 usergroup
= (char*) xmlGetProp (cur
, (xmlChar
*)"usergroup_r");
371 vector
< pair
<string
,string
> > vparams
;
372 CXMLAutoPtr
ugparams((const char*) xmlGetProp (cur
, (xmlChar
*)"usergroup_params_r"));
375 IActionHandler::getAllParams((const char*)ugparams
, vparams
);
378 string completeId
= _Parent
->getId() + ":" + _Lines
[_Lines
.size()-1].Id
;
379 CInterfaceGroup
*pUG
= CWidgetManager::getInstance()->getParser()->createGroupInstance((const char*)usergroup
, completeId
, vparams
);
381 setUserGroupRight((uint
)_Lines
.size()-1, pUG
, true);
383 // usergroup from simple icon
384 CXMLAutoPtr
icon((const char*) xmlGetProp (cur
, (xmlChar
*)"icon"));
387 typedef std::pair
<std::string
, std::string
> TTmplParams
;
388 std::vector
<TTmplParams
> vparams
;
389 uint lineIndex
= _Lines
.size()-1;
390 vparams
.push_back(TTmplParams("id", toString("icon%d", lineIndex
)));
391 vparams
.push_back(TTmplParams("sizeref", ""));
392 vparams
.push_back(TTmplParams("icon_texture", (const char*)icon
));
393 //vparams.push_back(TTmplParams("icon_color", options.ColorNormal.toString()));
394 string lineId
= toString("%s:icon", pV
->getId().c_str());
396 CInterfaceGroup
*pUG
= CWidgetManager::getInstance()->getParser()->createGroupInstance("menu_row_icon", lineId
, vparams
);
398 setUserGroupLeft((uint
)_Lines
.size()-1, pUG
, true);
404 _GroupMenu
->addGroup (this);
405 this->_DispType
= _GroupMenu
->_DispType
;
410 // ------------------------------------------------------------------------------------------------
411 CViewBitmap
*CGroupSubMenu::createIcon(CInterfaceElement
*parentPos
, const string
&texture
)
413 // Add an icon to the line
414 CViewBitmap
*pVB
= new CViewBitmap(CViewBase::TCtorParam());
415 pVB
->setSerializable( false );
416 pVB
->setParent (this);
417 pVB
->setParentPos (parentPos
);
418 pVB
->setParentPosRef (Hotspot_ML
);
419 pVB
->setPosRef (Hotspot_MR
);
420 pVB
->setTexture(texture
);
421 pVB
->setModulateGlobalColor(false);
427 // ------------------------------------------------------------------------------------------------
428 CViewBitmap
*CGroupSubMenu::createCheckBox(bool checked
)
430 // Put the left arrow to the line
431 CViewBitmap
*pVB
= new CViewBitmap(CViewBase::TCtorParam());
432 pVB
->setSerializable( false );
433 pVB
->setParent (this);
434 pVB
->setParentPos (_GroupList
);
435 pVB
->setParentPosRef (Hotspot_BR
);
436 pVB
->setPosRef (Hotspot_BL
);
437 CInterfaceOptions
*pIO
= CWidgetManager::getInstance()->getOptions("menu_checkbox");
440 pVB
->setTexture(pIO
->getValStr(checked
? "checked_bitmap" : "unchecked_bitmap"));
442 pVB
->setX (MENU_WIDGET_X
);
443 pVB
->setId (ID_MENU_CHECKBOX
); // always rescale to parent in update coords
449 // ------------------------------------------------------------------------------------------------
450 CViewBitmap
*CGroupSubMenu::createRightArrow(CInterfaceElement
*parentPos
, bool center
)
452 // Put the left arrow to the line
453 CViewBitmap
*pVB
= new CViewBitmap(CViewBase::TCtorParam());
454 pVB
->setSerializable( false );
455 pVB
->setParent (this);
456 pVB
->setParentPos (parentPos
);
459 pVB
->setParentPosRef (Hotspot_BR
);
460 pVB
->setPosRef (Hotspot_BL
);
464 pVB
->setParentPosRef (Hotspot_MR
);
465 pVB
->setPosRef (Hotspot_ML
);
467 pVB
->setTexture("w_arrow_right_3.tga");
468 pVB
->setX (MENU_WIDGET_X
);
469 pVB
->setId (ID_MENU_SUBMENU
); // rescale to parent in update coords if asked (not needed if there's already on the left a checkbox)
474 // ------------------------------------------------------------------------------------------------
475 #define GET_REF_ELM(__index__) \
476 CInterfaceElement *refElm; \
477 sint32 refElmYReal= 0; \
478 sint32 refElmHReal= 0; \
479 refElm = _Lines[__index__].ViewText; \
482 refElmYReal= refElm->getYReal() - _Lines[__index__].TextDY; \
483 refElmHReal= _Lines[__index__].HReal; \
486 void CGroupSubMenu::updateCoords ()
488 if (_ParentPos
== _GroupMenu
)
491 setX(_GroupMenu
->SpawnMouseX
);
492 setY(_GroupMenu
->SpawnMouseY
);
493 CGroupFrame::updateCoords();
495 CViewRenderer
&rVR
= *CViewRenderer::getInstance();
496 uint32 screenW
, screenH
;
497 rVR
.getScreenSize(screenW
, screenH
);
498 if ((_XReal
+_WReal
) > (sint32
)screenW
)
499 setX(screenW
-_WReal
);
504 // The sub menu may go outside the screen in Y. => clamp it as possible
506 /* X/Y coords have normally been updated before by "parent" sub menus
507 Why? because setSubMenu() is typically called in "parent first" order (or it is exactly what is done in ::parse())
508 => Parent CGroupSubMenu::updateCoords() are called before their sons in CGroupMenu::updateCoords() !!!
509 => No Need to call _SubMenus[RALineNb]->updateCoords() below ! (else would call too much time because of recursion!!)
512 // must udpate correct Real coords
513 CGroupFrame::updateCoords();
516 CViewRenderer
&rVR
= *CViewRenderer::getInstance();
517 uint32 screenW
, screenH
;
518 rVR
.getScreenSize(screenW
, screenH
);
520 sint32 hReal
= getHReal();
521 // If the H is too big, abort.. can't do anything
522 if(hReal
<=(sint32
)screenH
)
524 sint32 yReal
= getYReal();
526 // compute the shift to apply to the Y of the sub menu, to respect (as possible) the screen
530 if(yReal
+hReal
>(sint32
)screenH
)
531 dyClamp
= screenH
- (yReal
+hReal
);
535 setY(getY()+dyClamp
);
536 CGroupFrame::updateCoords();
542 if (!_GroupList
) return;
544 // get text dy position
546 textDYPos
= -(1+_GroupList
->getSpace())/2;
548 // Set the arrows at the right positions (in _Views we have selection and the right arrows)
549 sint32 CBLineNb
= 0; // check box
550 sint32 RALineNb
= 0; // right arrow
553 sint32 maxUserGroupWidth
= 0;
554 // compute max width of user groups, & adapt max height for each line
557 // update all left user groups to get their width
558 sint32 maxLeftUGWidth
= 0;
559 for(k
= 0; k
< _Lines
.size(); ++k
)
561 if (_Lines
[k
].UserGroupLeft
)
563 _Lines
[k
].UserGroupLeft
->updateCoords();
564 maxLeftUGWidth
= std::max(_Lines
[k
].UserGroupLeft
->getWReal(), maxLeftUGWidth
);
568 _GroupList
->setX(LEFT_MENU_WIDGET_X
+ maxLeftUGWidth
);
570 // active separators when needed
571 bool activeLineSeen
= false;
572 for (i
= 0; i
< _Lines
.size(); ++i
)
574 if (_Lines
[i
].Separator
!= NULL
)
576 if (i
== _Lines
.size() - 1)
578 _Lines
[i
].Separator
->setActive(false);
581 _Lines
[i
].Separator
->setActive(activeLineSeen
);
582 activeLineSeen
= false;
586 if (_Lines
[i
].ViewText
&& _Lines
[i
].ViewText
->getActive()) activeLineSeen
= true;
590 CGroupFrame::updateCoords();
592 if (_MaxVisibleLine
> 0 && sint32(_Lines
.size())>_MaxVisibleLine
)
594 for(k
= 0; k
< _Lines
.size(); ++k
)
595 if (_Lines
[k
].ViewText
)
597 // compute max height of widgets on the left of text
598 sint32 widgetMaxH
= 0;
599 if (_Lines
[k
].UserGroupRight
) widgetMaxH
= _Lines
[k
].UserGroupRight
->getHReal();
600 if (_Lines
[k
].UserGroupLeft
) widgetMaxH
= std::max(widgetMaxH
, _Lines
[k
].UserGroupLeft
->getHReal());
601 if (_Lines
[k
].CheckBox
) widgetMaxH
= std::max(widgetMaxH
, _Lines
[k
].CheckBox
->getHReal());
602 if (_Lines
[k
].RightArrow
) widgetMaxH
= std::max(widgetMaxH
, _Lines
[k
].RightArrow
->getHReal());
603 widgetMaxH
= std::max(widgetMaxH
, _Lines
[k
].ViewText
->getHReal());
604 _GroupList
->setMaxH(widgetMaxH
*_MaxVisibleLine
+_GroupList
->getSpace()*(_MaxVisibleLine
-1));
605 if (_ScrollBar
== NULL
)
607 _ScrollBar
= new CCtrlScroll(CViewBase::TCtorParam());
608 _ScrollBar
->setParent (this);
609 _ScrollBar
->setParentPos (_GroupList
);
610 _ScrollBar
->setPosRef (Hotspot_BL
);
611 _ScrollBar
->setParentPosRef (Hotspot_BR
);
612 _ScrollBar
->setX (4);
613 _ScrollBar
->setY (0);
614 _ScrollBar
->setW (8);
615 _ScrollBar
->setTextureBottomOrLeft ("w_scroll_l123_b.tga");
616 _ScrollBar
->setTextureMiddle ("w_scroll_l123_m.tga");
617 _ScrollBar
->setTextureTopOrRight ("w_scroll_l123_t.tga");
618 _ScrollBar
->setTarget(_GroupList
);
619 _SelectionView
->setW (-8-8-2);
620 _ScrollBar
->setSerializable( false );
628 _SelectionView
->setW(-8);
633 for(k
= 0; k
< _Lines
.size(); ++k
)
635 CInterfaceGroup
*ig
= _Lines
[k
].UserGroupRight
;
639 maxUserGroupWidth
= std::max(maxUserGroupWidth
, ig
->getWReal());
641 if (_Lines
[k
].ViewText
)
643 // compute max height of widgets on the left of text
644 sint32 widgetMaxH
= 0;
645 if (_Lines
[k
].UserGroupRight
) widgetMaxH
= _Lines
[k
].UserGroupRight
->getHReal();
646 if (_Lines
[k
].UserGroupLeft
) widgetMaxH
= std::max(widgetMaxH
, _Lines
[k
].UserGroupLeft
->getHReal());
647 if (_Lines
[k
].CheckBox
) widgetMaxH
= std::max(widgetMaxH
, _Lines
[k
].CheckBox
->getHReal());
648 if (_Lines
[k
].RightArrow
) widgetMaxH
= std::max(widgetMaxH
, _Lines
[k
].RightArrow
->getHReal());
650 sint32 textHReal
= _Lines
[k
].ViewText
->getHReal();
651 _Lines
[k
].HReal
= max(widgetMaxH
, textHReal
);
652 _Lines
[k
].TextDY
= textDYPos
;
653 if(widgetMaxH
>textHReal
)
654 _Lines
[k
].TextDY
+= (widgetMaxH
-textHReal
) / 2;
659 // *** Update Text Positions
661 for(k
= 0; k
< _Lines
.size(); ++k
)
663 if (_Lines
[k
].ViewText
)
666 _Lines
[k
].ViewText
->setY(_Lines
[k
].TextDY
);
670 CGroupFrame::updateCoords();
672 // *** Setup SubMenus and CheckBoxes Positions
674 for (i
= 1; i
< _Views
.size(); ++i
)
676 CViewBitmap
*pVB
= dynamic_cast<CViewBitmap
*>(_Views
[i
]);
677 if (pVB
== NULL
) continue;
678 if (pVB
->getId() == ID_MENU_SUBMENU
)
680 // Look for the next line of the menu that contains a sub menu
683 nlassert (RALineNb
< (sint32
)_SubMenus
.size());
684 if (_SubMenus
[RALineNb
] != NULL
) // has a check box or an arrow to indicate submenu ?
691 // get refElm and refElmYReal
692 GET_REF_ELM(RALineNb
)
694 // if there is a check box, y is 0
695 if (_Lines
[RALineNb
].CheckBox
|| _Lines
[RALineNb
].UserGroupRight
)
698 pVB
->setX(MENU_WIDGET_X
);
702 sint32 limY
= refElmYReal
+ refElmHReal
/2 - _GroupList
->getYReal();
703 // Setup the arrow at the right pos
704 if(_GroupList
->getMaxH()>=limY
&& limY
>=0)
706 pVB
->setY(refElmYReal
+ (refElmHReal
- pVB
->getHReal()) / 2 - _GroupList
->getYReal());
707 pVB
->setColor(_Lines
[RALineNb
].ViewText
->getColor());
708 pVB
->setActive(_Lines
[RALineNb
].ViewText
->getActive());
709 pVB
->setX(maxUserGroupWidth
+ MENU_WIDGET_X
);
714 pVB
->setActive(false);
718 if (_GroupMenu
->SpawnOnMousePos
)
720 _SubMenus
[RALineNb
]->setParentPos (this);
722 // According to mouse position, set the sub menu on the left or right, begin at top or bottom
723 CViewRenderer
&rVR
= *CViewRenderer::getInstance();
724 uint32 screenW
, screenH
;
725 rVR
.getScreenSize(screenW
, screenH
);
726 if ((_GroupMenu
->SpawnMouseX
<= ((sint32
)screenW
/2)) && (_GroupMenu
->SpawnMouseY
<= ((sint32
)screenH
/2)))
728 _SubMenus
[RALineNb
]->setParentPosRef(Hotspot_BR
);
729 _SubMenus
[RALineNb
]->setPosRef(Hotspot_BL
);
730 _SubMenus
[RALineNb
]->setY (refElmYReal
- _GroupList
->getYReal());
732 if ((_GroupMenu
->SpawnMouseX
<= ((sint32
)screenW
/2)) && (_GroupMenu
->SpawnMouseY
> ((sint32
)screenH
/2)))
734 _SubMenus
[RALineNb
]->setParentPosRef(Hotspot_TR
);
735 _SubMenus
[RALineNb
]->setPosRef(Hotspot_TL
);
736 _SubMenus
[RALineNb
]->setY (refElmHReal
+(refElmYReal
- _GroupList
->getYReal()) - _GroupList
->getHReal());
738 if ((_GroupMenu
->SpawnMouseX
> ((sint32
)screenW
/2)) && (_GroupMenu
->SpawnMouseY
<= ((sint32
)screenH
/2)))
740 _SubMenus
[RALineNb
]->setParentPosRef(Hotspot_BL
);
741 _SubMenus
[RALineNb
]->setPosRef(Hotspot_BR
);
742 _SubMenus
[RALineNb
]->setY (refElmYReal
- _GroupList
->getYReal());
744 if ((_GroupMenu
->SpawnMouseX
> ((sint32
)screenW
/2)) && (_GroupMenu
->SpawnMouseY
> ((sint32
)screenH
/2)))
746 _SubMenus
[RALineNb
]->setParentPosRef(Hotspot_TL
);
747 _SubMenus
[RALineNb
]->setPosRef(Hotspot_TR
);
748 _SubMenus
[RALineNb
]->setY (refElmHReal
+(refElmYReal
- _GroupList
->getYReal()) - _GroupList
->getHReal());
750 _SubMenus
[RALineNb
]->setX(0);
755 _SubMenus
[RALineNb
]->setParentPos (this);
756 _SubMenus
[RALineNb
]->setParentPosRef (Hotspot_BR
);
757 _SubMenus
[RALineNb
]->setPosRef (Hotspot_BL
);
758 _SubMenus
[RALineNb
]->setY (16+refElmYReal
- _GroupList
->getYReal() - _SubMenus
[RALineNb
]->getHReal());
763 else if (pVB
->getId() == ID_MENU_CHECKBOX
)
767 nlassert (CBLineNb
< (sint32
)_SubMenus
.size());
768 if (_Lines
[CBLineNb
].CheckBox
!= NULL
) // has a check box or an arrow to indicate submenu ?
774 // Setup the arrow at the right pos
775 if (!_Lines
[CBLineNb
].UserGroupRight
)
777 // get refElm and refElmYReal
778 GET_REF_ELM(CBLineNb
)
780 pVB
->setX(maxUserGroupWidth
+ 2 * MENU_WIDGET_X
);
782 sint32 limY
= refElmYReal
+ refElmHReal
/2 - _GroupList
->getYReal();
783 // Setup the arrow at the right pos
784 if(_GroupList
->getMaxH()>=limY
&& limY
>=0)
786 pVB
->setY(refElmYReal
+ (refElmHReal
- pVB
->getHReal()) / 2 - _GroupList
->getYReal());
787 pVB
->setActive(_Lines
[CBLineNb
].ViewText
->getActive());
792 pVB
->setActive(false);
798 pVB
->setX(MENU_WIDGET_X
);
800 pVB
->setColor (_Lines
[CBLineNb
].ViewText
->getColor());
805 if (maxViewW
<(pVB
->getWReal()+pVB
->getX())) maxViewW
= pVB
->getWReal()+pVB
->getX();
808 // setup scrollbar position in function of views width
809 if(maxViewW
>0 && _ScrollBar
)
810 _ScrollBar
->setX(4 + maxViewW
);
812 // *** Setup user groups positions
813 for(k
= 0; k
< _Lines
.size(); ++k
)
815 CInterfaceGroup
*igr
= _Lines
[k
].UserGroupRight
;
816 CInterfaceGroup
*igl
= _Lines
[k
].UserGroupLeft
;
819 // get refElm and refElmYReal
826 igr
->setX(MENU_WIDGET_X
+ maxUserGroupWidth
- igr
->getWReal());
828 sint32 limY
= refElmYReal
+ refElmHReal
/2 - _GroupList
->getYReal();
829 if(_GroupList
->getMaxH()>=limY
&& limY
>=0)
831 igr
->setY(refElmYReal
+ (refElmHReal
- igr
->getHReal()) / 2 - _GroupList
->getYReal());
832 igr
->setActive (refElm
->getActive());
837 igr
->setActive(false);
843 sint32 limY
= refElmYReal
+ refElmHReal
/2 - _GroupList
->getYReal();
844 if(_GroupList
->getMaxH()>=limY
&& limY
>=0)
846 igl
->setY(refElmYReal
+ (refElmHReal
- igl
->getHReal()) / 2 - this->getYReal());
847 igl
->setActive(refElm
->getActive());
852 igl
->setActive(false);
860 sint32 SepLineNb
= 0;
861 // set separator at the right position
862 for (i
= 0; i
< _ChildrenGroups
.size(); ++i
)
864 CInterfaceGroup
*pIG
= dynamic_cast<CInterfaceGroup
*>(_ChildrenGroups
[i
]);
865 if (pIG
== NULL
) continue;
866 if (pIG
->getId() != ID_MENU_SEPARATOR
) continue; // is it a separator ?
869 /*sint32 sw = getW() - _LeftBorder - _RightBorder;
870 sw = std::max(sw, (sint32) 0);
873 // Look for the next line of the menu that contains a separator
874 CInterfaceGroup
*sep
= NULL
;
877 nlassert (SepLineNb
< (sint32
)_Lines
.size());
878 sep
= _Lines
[SepLineNb
].Separator
;
883 // Setup the arrow at the right pos
884 pIG
->setY (sep
->getYReal() - getYReal());
885 pIG
->setActive(sep
->getActive());
887 CGroupFrame::updateCoords();
889 //_SelectionView->setW (this->getW());
890 _SelectionView
->setH (8);
891 _SelectionView
->setY (4);
894 if (_Selected
!= -1 && _Lines
[_Selected
].ViewText
!= NULL
)
896 CRGBA col
= _GroupMenu
->_HighLightOver
;
898 _SelectionView
->setColor (col
);
899 _SelectionView
->setModulateGlobalColor(getModulateGlobalColor());
901 // get refElm and refElmYReal
902 GET_REF_ELM(_Selected
)
904 _SelectionView
->setH (refElmHReal
);
905 _SelectionView
->setY (refElmYReal
- this->getYReal());
909 // ------------------------------------------------------------------------------------------------
910 void CGroupSubMenu::checkCoords()
912 if (!_Active
) return;
913 if (_GroupMenu
== NULL
) return;
915 // if the mouse goes out the window, unselect all (because handleEvent may not be called)
916 sint xMouse
= CWidgetManager::getInstance()->getPointer()->getX();
917 sint yMouse
= CWidgetManager::getInstance()->getPointer()->getY();
918 if (!((xMouse
>= _XReal
) &&
919 (xMouse
< (_XReal
+ _WReal
))&&
921 (yMouse
<= (_YReal
+ _HReal
))))
924 // CViewRenderer &rVR = *CViewRenderer::getInstance();
926 // Highlight (background under the selection)
929 // display hightlight
930 if(_GroupMenu
->_HighLightOver
.A
> 0)
932 _SelectionView
->setActive (true);
933 _SelectionView
->invalidateCoords();
937 _SelectionView
->setActive (false);
942 _SelectionView
->setActive (false);
945 // Text color if grayed or not
946 for (sint32 i
= 0; i
< (sint32
)_Lines
.size(); ++i
)
948 if (_Lines
[i
].ViewText
)
950 if (_Lines
[i
].ViewText
->getGrayed()) // Colors when the text is grayed
952 _Lines
[i
].ViewText
->setColor (_Lines
[i
].ViewText
->OldColorGrayed
);
953 _Lines
[i
].ViewText
->setShadowColor (_Lines
[i
].ViewText
->OldShadowColorGrayed
);
957 if (i
== _Selected
) // Colors when the text is selected
959 _Lines
[i
].ViewText
->Over
= true;
960 _Lines
[i
].ViewText
->setColor (_Lines
[i
].ViewText
->OldColorOver
);
961 _Lines
[i
].ViewText
->setShadowColor (_Lines
[i
].ViewText
->OldShadowColorOver
);
963 else // Or finally normal colors
965 _Lines
[i
].ViewText
->Over
= false;
966 _Lines
[i
].ViewText
->setColor (_Lines
[i
].ViewText
->OldColor
);
967 _Lines
[i
].ViewText
->setShadowColor (_Lines
[i
].ViewText
->OldShadowColor
);
974 // ------------------------------------------------------------------------------------------------
975 void CGroupSubMenu::draw()
977 if (!_Active
) return;
978 if (_GroupMenu
== NULL
) return;
982 // ------------------------------------------------------------------------------------------------
983 bool CGroupSubMenu::handleEvent (const NLGUI::CEventDescriptor
&event
)
990 textDYPos
= -(1+_GroupList
->getSpace())/2;
992 if (event
.getType() == NLGUI::CEventDescriptor::mouse
)
994 const NLGUI::CEventDescriptorMouse
&eventDesc
= (const NLGUI::CEventDescriptorMouse
&)event
;
997 // TODO First check sub menus that can be not in the area of this menu
999 if (!((eventDesc
.getX() >= _XReal
) &&
1000 (eventDesc
.getX() < (_XReal
+ _WReal
))&&
1001 (eventDesc
.getY() > _YReal
) &&
1002 (eventDesc
.getY() <= (_YReal
+ _HReal
))))
1006 for (i
= 0; i
< _Lines
.size(); ++i
)
1008 if (_Lines
[i
].Selectable
)
1010 // get refElm and refElmYReal
1015 if (refElm
->getActive() == true)
1016 if ((eventDesc
.getY() > refElmYReal
) &&
1017 (eventDesc
.getY() <= (refElmYReal
+ refElmHReal
+ _GroupList
->getSpace())))
1026 if (eventDesc
.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup
)
1028 // If a line is selected and the line is not grayed
1029 if ((_Selected
!= -1) && (!_Lines
[i
].ViewText
->getGrayed()))
1032 CAHManager::getInstance()->runActionHandler ( _Lines
[_Selected
].AHName
,
1033 CWidgetManager::getInstance()->getCtrlLaunchingModal(),
1034 _Lines
[_Selected
].AHParams
);
1036 if (_SubMenus
[_Selected
] != NULL
)
1038 openSubMenu (_Selected
);
1042 // if the menu hasn't triggered a new modal window, disable it
1043 if (CWidgetManager::getInstance()->getModalWindow() == _GroupMenu
)
1045 if(_GroupMenu
&& _GroupMenu
->getCloseSubMenuUsingPopModal())
1046 CWidgetManager::getInstance()->popModalWindow();
1048 CWidgetManager::getInstance()->disableModalWindow ();
1054 if (eventDesc
.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightup
)
1056 // If a line is selected and the line is not grayed and has right click action handler
1057 if ((_Selected
!= -1) && (!_Lines
[i
].ViewText
->getGrayed()) && !_Lines
[_Selected
].AHRightClick
.empty())
1059 CAHManager::getInstance()->runActionHandler ( _Lines
[_Selected
].AHRightClick
,
1060 CWidgetManager::getInstance()->getCtrlLaunchingModal(),
1061 _Lines
[_Selected
].AHRightClickParams
);
1066 if (event
.getType() == NLGUI::CEventDescriptor::mouse
)
1068 const NLGUI::CEventDescriptorMouse
&eventDesc
= (const NLGUI::CEventDescriptorMouse
&)event
;
1070 if (_GroupList
&& _ScrollBar
)
1072 if (eventDesc
.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mousewheel
)
1074 if (isIn(eventDesc
.getX(), eventDesc
.getY()))
1077 for (uint32 k
= 0; k
< _Lines
.size(); ++k
)
1078 if (_Lines
[k
].ViewText
)
1080 // compute max height of widgets on the left of text
1081 sint32 widgetMaxH
= 0;
1082 if (_Lines
[k
].UserGroupRight
) widgetMaxH
= _Lines
[k
].UserGroupRight
->getHReal();
1083 if (_Lines
[k
].UserGroupLeft
) widgetMaxH
= std::max(widgetMaxH
, _Lines
[k
].UserGroupLeft
->getHReal());
1084 if (_Lines
[k
].CheckBox
) widgetMaxH
= std::max(widgetMaxH
, _Lines
[k
].CheckBox
->getHReal());
1085 if (_Lines
[k
].RightArrow
) widgetMaxH
= std::max(widgetMaxH
, _Lines
[k
].RightArrow
->getHReal());
1086 widgetMaxH
= std::max(widgetMaxH
, _Lines
[k
].ViewText
->getHReal());
1087 h
= widgetMaxH
+_GroupList
->getSpace();
1090 _ScrollBar
->moveTargetY(- eventDesc
.getWheel() * h
);
1105 // ------------------------------------------------------------------------------------------------
1106 CInterfaceElement
* CGroupSubMenu::getElement (const std::string
&id
)
1108 string sTmp
= id
.substr(0, _GroupMenu
->getId().size());
1109 if (sTmp
!= _GroupMenu
->getId()) return NULL
;
1111 string sRest
= id
.substr(_GroupMenu
->getId().size()+1, id
.size());
1113 // Iterate through the tree to see if sRest is present
1114 CGroupSubMenu
*pCurGSM
= this;
1115 while (!sRest
.empty())
1117 // Get the first element of the sRest
1118 string::size_type posid
= sRest
.find (":");
1120 if (posid
== string::npos
) // Is there just one token to test ?
1122 for (uint32 i
= 0; i
< pCurGSM
->_Lines
.size(); ++i
)
1123 if (sRest
== pCurGSM
->_Lines
[i
].Id
)
1124 return pCurGSM
->_Lines
[i
].ViewText
;
1127 else // no a lot of token left
1129 string sTok
= sRest
.substr (0, posid
);
1131 for (i
= 0; i
< pCurGSM
->_Lines
.size(); ++i
)
1132 if (sTok
== pCurGSM
->_Lines
[i
].Id
)
1134 if (i
== pCurGSM
->_Lines
.size())
1138 if (pCurGSM
->_SubMenus
[i
] == NULL
)
1141 sRest
= sRest
.substr (posid
+1);
1142 posid
= sRest
.find (":");
1143 if (posid
== string::npos
)
1146 sTok
= sRest
.substr (0, posid
);
1147 // Do we want left or right user group ?
1148 if (pCurGSM
->_Lines
[i
].UserGroupRight
)
1150 string sUGid
= pCurGSM
->_Lines
[i
].UserGroupRight
->getId();
1151 sUGid
= sUGid
.substr(sUGid
.rfind(':')+1,sUGid
.size());
1154 CInterfaceElement
*pIE
= pCurGSM
->_Lines
[i
].UserGroupRight
->getElement(id
);
1158 if (pCurGSM
->_Lines
[i
].UserGroupLeft
)
1160 string sUGid
= pCurGSM
->_Lines
[i
].UserGroupLeft
->getId();
1161 sUGid
= sUGid
.substr(sUGid
.rfind(':')+1,sUGid
.size());
1164 CInterfaceElement
*pIE
= pCurGSM
->_Lines
[i
].UserGroupLeft
->getElement(id
);
1173 pCurGSM
= pCurGSM
->_SubMenus
[i
];
1176 sRest
= sRest
.substr (posid
+1);
1182 // ------------------------------------------------------------------------------------------------
1183 void CGroupSubMenu::addSeparator(const std::string
&id
)
1185 addSeparatorAtIndex((uint
)_Lines
.size(), id
);
1188 // ------------------------------------------------------------------------------------------------
1189 void CGroupSubMenu::addSeparatorAtIndex(uint index
, const std::string
&id
)
1191 if (index
> _Lines
.size())
1193 nlwarning("Bad index");
1197 // create the real separator. It may be larger than the group list, this is why we create a separate group
1198 CInterfaceGroup
*separator
= CWidgetManager::getInstance()->getParser()->createGroupInstance("menu_separator", "", NULL
, 0);
1199 if (!separator
) return;
1200 separator
->setSerializable( false );
1201 separator
->setId(ID_MENU_SEPARATOR
);
1202 separator
->setSerializable( false );
1203 addGroup(separator
);
1204 separator
->setParent(this);
1205 // create place holder group
1206 CInterfaceGroup
*ph
= CWidgetManager::getInstance()->getParser()->createGroupInstance("menu_separator_empty", "", NULL
, 0);
1209 delGroup(separator
);
1212 _GroupList
->addChildAtIndex(ph
, index
);
1216 tmp
.ViewText
= NULL
;
1217 tmp
.CheckBox
= NULL
;
1218 tmp
.RightArrow
= NULL
;
1219 _Lines
.insert(_Lines
.begin() + index
, tmp
);
1220 _SubMenus
.insert(_SubMenus
.begin() + index
, (CGroupSubMenu
*)NULL
);
1221 _GroupMenu
->invalidateCoords();
1225 // ------------------------------------------------------------------------------------------------
1226 CViewTextMenu
* CGroupSubMenu::addLine (const std::string
&name
, const std::string
&ah
,
1227 const std::string
¶ms
, const std::string
&id
,
1228 const std::string
&cond
, const std::string
&texture
,
1229 bool checkable
/*= false*/, bool checked
/*= false*/, bool formatted
/*= false */
1234 CViewTextMenu
*pV
= new CViewTextMenu(CViewBase::TCtorParam());
1237 pV
->setCaseMode(_GroupMenu
->getCaseMode());
1240 pV
->setMultiLine (true);
1241 pV
->setMultiLineMaxWOnly (true);
1242 pV
->setTextFormatTaged (name
);
1248 pV
->setColor (_GroupMenu
->_Color
);
1249 pV
->setFontSize (_GroupMenu
->_FontSize
, _GroupMenu
->_FontSizeCoef
);
1250 pV
->setShadow (_GroupMenu
->_Shadow
);
1251 pV
->setShadowOutline (_GroupMenu
->_ShadowOutline
);
1252 pV
->setCheckable(checkable
);
1253 pV
->setChecked(checked
);
1254 pV
->setModulateGlobalColor(_GroupMenu
->_ModulateGlobalColor
);
1256 pV
->OldColor
= _GroupMenu
->_Color
;
1257 pV
->OldShadowColor
= _GroupMenu
->_ShadowColor
;
1258 pV
->OldColorOver
= _GroupMenu
->_ColorOver
;
1259 pV
->OldShadowColorOver
= _GroupMenu
->_ShadowColorOver
;
1260 pV
->OldColorGrayed
= _GroupMenu
->_ColorGrayed
;
1261 pV
->OldShadowColorGrayed
= _GroupMenu
->_ShadowColorGrayed
;
1263 _GroupList
->addChild (pV
);
1265 CViewBitmap
*checkBox
= NULL
;
1269 checkBox
= createCheckBox(checked
);
1270 checkBox
->setTexture(texture
);
1271 pV
->setCheckBox(checkBox
);
1274 CViewBitmap
*icon
= NULL
;
1275 if (!texture
.empty())
1277 if (_GroupList
->getNumChildren() == 1)
1279 icon
= createIcon(pV
, texture
);
1284 tmp
.Separator
= NULL
;
1286 tmp
.AHParams
= params
;
1288 tmp
.CheckBox
= checkBox
;
1289 tmp
.RightArrow
= icon
;
1291 tmp
.Id
= NLMISC::toString (_Lines
.size());
1295 pV
->setId(_GroupMenu
->getId()+":"+tmp
.Id
);
1297 _Lines
.push_back (tmp
);
1299 // Add an empty sub menu by default
1300 _SubMenus
.push_back (NULL
);
1302 _GroupMenu
->invalidateCoords();
1307 CViewTextMenu
* CGroupSubMenu::addLineAtIndex(uint index
, const std::string
&name
, const std::string
&ah
,
1308 const std::string
¶ms
, const std::string
&id
/*=""*/,
1309 const std::string
&cond
/*=std::string()*/, const std::string
&texture
,
1310 bool checkable
/*= false*/, bool checked
/*= false*/, bool formatted
/*= false */
1313 if (index
> _Lines
.size())
1315 nlwarning("Bad index");
1319 CViewTextMenu
*pV
= new CViewTextMenu(CViewBase::TCtorParam());
1320 pV
->setSerializable( false );
1323 pV
->setCaseMode(_GroupMenu
->getCaseMode());
1328 pV
->setMultiLine (true);
1329 pV
->setMultiLineMaxWOnly (true);
1330 pV
->setTextFormatTaged (name
);
1337 pV
->setColor (_GroupMenu
->_Color
);
1338 pV
->setFontSize (_GroupMenu
->_FontSize
, _GroupMenu
->_FontSizeCoef
);
1339 pV
->setShadow (_GroupMenu
->_Shadow
);
1340 pV
->setShadowOutline (_GroupMenu
->_ShadowOutline
);
1341 pV
->setCheckable(checkable
);
1342 pV
->setChecked(checked
);
1343 pV
->setModulateGlobalColor(_GroupMenu
->_ModulateGlobalColor
);
1345 pV
->OldColor
= _GroupMenu
->_Color
;
1346 pV
->OldShadowColor
= _GroupMenu
->_ShadowColor
;
1347 pV
->OldColorOver
= _GroupMenu
->_ColorOver
;
1348 pV
->OldShadowColorOver
= _GroupMenu
->_ShadowColorOver
;
1349 pV
->OldColorGrayed
= _GroupMenu
->_ColorGrayed
;
1350 pV
->OldShadowColorGrayed
= _GroupMenu
->_ShadowColorGrayed
;
1352 _GroupList
->addChildAtIndex(pV
, index
);
1354 CViewBitmap
*checkBox
= NULL
;
1357 checkBox
= createCheckBox(checked
);
1358 checkBox
->setTexture(texture
);
1359 pV
->setCheckBox(checkBox
);
1363 tmp
.Separator
= NULL
;
1365 tmp
.AHParams
= params
;
1367 tmp
.CheckBox
= checkBox
;
1368 tmp
.RightArrow
= NULL
;
1371 tmp
.Id
= NLMISC::toString (_Lines
.size());
1375 pV
->setId(getId()+":"+tmp
.Id
);
1377 _Lines
.insert(_Lines
.begin() + index
, tmp
);
1379 // Add an empty sub menu by default
1380 _SubMenus
.insert(_SubMenus
.begin() + index
, (CGroupSubMenu
*)NULL
);
1382 _GroupMenu
->invalidateCoords();
1388 // ------------------------------------------------------------------------------------------------
1389 void CGroupSubMenu::removeLine(uint index
)
1391 if (index
>= _Lines
.size())
1393 nlwarning("Bad index");
1396 setUserGroupRight(index
, NULL
, false); // remove user group
1397 setUserGroupLeft(index
, NULL
, false); // remove user group
1398 // remove view (right arrow & checkbox)
1399 if (_Lines
[index
].RightArrow
) delView(_Lines
[index
].RightArrow
);
1400 if (_Lines
[index
].CheckBox
) delView(_Lines
[index
].CheckBox
);
1401 if (_Lines
[index
].Separator
)
1403 // remove one separator group
1404 for(uint k
= 0; k
< _ChildrenGroups
.size(); ++k
)
1406 if (_ChildrenGroups
[k
]->getId() == ID_MENU_SEPARATOR
)
1408 delGroup(_ChildrenGroups
[k
]);
1414 _GroupList
->setDelOnRemove(index
, true);
1415 _GroupList
->delChild(index
);
1416 _Lines
.erase(_Lines
.begin() + index
);
1418 //invalidate selection
1421 if(_SubMenus
[index
])
1423 // reset it and his sons (recurs)
1424 _SubMenus
[index
]->reset();
1426 _GroupMenu
->delGroup(_SubMenus
[index
]);
1428 _SubMenus
.erase(_SubMenus
.begin() + index
);
1429 _GroupMenu
->invalidateCoords();
1432 // ------------------------------------------------------------------------------------------------
1433 void CGroupSubMenu::openSubMenu (sint32 nb
)
1436 _SubMenus
[nb
]->setActive (true);
1439 // ------------------------------------------------------------------------------------------------
1440 void CGroupSubMenu::hideSubMenus ()
1442 for (uint32 i
= 0; i
< _SubMenus
.size(); ++i
)
1443 if (_SubMenus
[i
] != NULL
)
1445 _SubMenus
[i
]->setActive (false);
1446 _SubMenus
[i
]->hideSubMenus ();
1450 // ------------------------------------------------------------------------------------------------
1451 void CGroupSubMenu::reset()
1453 uint lineCount
= (uint
)_Lines
.size();
1454 for(sint k
= lineCount
- 1; k
>= 0; --k
)
1461 // ------------------------------------------------------------------------------------------------
1462 void CGroupSubMenu::removeAllUserGroups()
1464 for(uint k
= 0; k
< _Lines
.size(); ++k
)
1466 setUserGroupRight(k
, NULL
, false);
1467 setUserGroupLeft(k
, NULL
, false);
1471 // ------------------------------------------------------------------------------------------------
1472 CInterfaceGroup
*CGroupSubMenu::getUserGroupRight(uint line
) const
1474 if (line
>= _Lines
.size())
1476 nlwarning("bad index");
1479 return _Lines
[line
].UserGroupRight
;
1482 // ------------------------------------------------------------------------------------------------
1483 CInterfaceGroup
*CGroupSubMenu::getUserGroupLeft(uint line
) const
1485 if (line
>= _Lines
.size())
1487 nlwarning("bad index");
1490 return _Lines
[line
].UserGroupLeft
;
1493 // ------------------------------------------------------------------------------------------------
1494 void CGroupSubMenu::setUserGroupRight(uint line
, CInterfaceGroup
*group
, bool ownership
)
1496 if (line
>= _Lines
.size())
1498 nlwarning("bad index");
1501 if (group
&& isChildGroup(group
))
1503 nlwarning("Group inserted twice");
1506 if (_Lines
[line
].UserGroupRight
)
1508 delGroup(_Lines
[line
].UserGroupRight
, !_Lines
[line
].UserGroupRightOwnership
);
1510 _Lines
[line
].UserGroupRight
= group
;
1511 _Lines
[line
].UserGroupRightOwnership
= ownership
;
1514 CViewBase
*prevElem
= _Lines
[line
].CheckBox
? _Lines
[line
].CheckBox
: _Lines
[line
].RightArrow
;
1517 prevElem
->setParentPosRef (Hotspot_MR
);
1518 prevElem
->setPosRef (Hotspot_ML
);
1519 prevElem
->setParentPos(group
);
1520 prevElem
->setX(MENU_WIDGET_X
);
1523 sint insertionOrder
;
1526 insertionOrder
= getInsertionOrder(prevElem
);
1530 insertionOrder
= -1;
1532 addGroup(group
, insertionOrder
);
1533 group
->setParent(this);
1534 group
->setParentPos(_GroupList
);
1535 group
->setParentPosRef (Hotspot_BR
);
1536 group
->setPosRef (Hotspot_BL
);
1540 // restore all posref..
1541 CViewBase
*prevElem
= _Lines
[line
].CheckBox
? _Lines
[line
].CheckBox
: _Lines
[line
].RightArrow
;
1544 prevElem
->setParent (this);
1545 prevElem
->setParentPos (_GroupList
);
1546 prevElem
->setParentPosRef (Hotspot_BR
);
1547 prevElem
->setPosRef (Hotspot_BL
);
1548 prevElem
->setX (MENU_WIDGET_X
);
1551 _GroupMenu
->invalidateCoords();
1555 // ------------------------------------------------------------------------------------------------
1556 void CGroupSubMenu::setUserGroupLeft(uint line
, CInterfaceGroup
*group
, bool ownership
)
1558 if (line
>= _Lines
.size())
1560 nlwarning("bad index");
1563 if (group
&& isChildGroup(group
))
1565 nlwarning("Group inserted twice");
1568 if (_Lines
[line
].UserGroupLeft
)
1570 delGroup(_Lines
[line
].UserGroupLeft
, !_Lines
[line
].UserGroupLeftOwnership
);
1572 _Lines
[line
].UserGroupLeft
= group
;
1573 _Lines
[line
].UserGroupLeftOwnership
= ownership
;
1577 group
->setParent(this);
1578 group
->setParentPos(this);
1579 group
->setParentPosRef (Hotspot_BL
);
1580 group
->setPosRef (Hotspot_BL
);
1581 group
->setX(LEFT_MENU_WIDGET_X
);
1584 _GroupMenu
->invalidateCoords();
1588 // ------------------------------------------------------------------------------------------------
1589 CGroupSubMenu
*CGroupSubMenu::cloneMenu(CGroupSubMenu
*appendToMenu
, CGroupMenu
*newFather
, CInterfaceGroup
*initGroup
/* = NULL */) const
1591 CGroupSubMenu
*copyMenu
= appendToMenu
? appendToMenu
: new CGroupSubMenu(CViewText::TCtorParam());
1592 uint startSize
= (uint
)copyMenu
->_Lines
.size();
1593 copyMenu
->setSerializable( false );
1594 copyMenu
->_GroupMenu
= newFather
;
1595 copyMenu
->initOptions(initGroup
);
1596 copyMenu
->_Lines
.reserve(_Lines
.size() + startSize
);
1597 copyMenu
->_SubMenus
.reserve(_SubMenus
.size() + startSize
);
1599 for(uint k
= 0; k
< _Lines
.size(); ++k
)
1601 if (_Lines
[k
].Separator
)
1603 copyMenu
->addSeparator(_Lines
[k
].Id
);
1607 std::string texture
= std::string();
1608 if(_Lines
[k
].ViewText
->getCheckBox())
1610 texture
= _Lines
[k
].ViewText
->getCheckBox()->getTexture();
1612 CViewTextMenu
*pV
= NULL
;
1613 pV
= copyMenu
->addLine (_Lines
[k
].ViewText
->getText(), _Lines
[k
].AHName
, _Lines
[k
].AHParams
, _Lines
[k
].Id
, _Lines
[k
].Cond
,
1614 texture
, _Lines
[k
].ViewText
->getCheckable(), _Lines
[k
].ViewText
->getChecked(), _Lines
[k
].ViewText
->getFormatted ());
1615 copyMenu
->_Lines
[k
].Selectable
= _Lines
[k
].Selectable
;
1616 pV
->setGrayed(_Lines
[k
].ViewText
->getGrayed());
1619 // sub menu copy if there's one
1620 if (_SubMenus
[k
] != NULL
)
1623 if (copyMenu
->_Lines
.back().CheckBox
)
1625 copyMenu
->_Lines
.back().RightArrow
= copyMenu
->createRightArrow(copyMenu
->_Lines
.back().CheckBox
, true);
1629 copyMenu
->_Lines
.back().RightArrow
= copyMenu
->createRightArrow(copyMenu
->_GroupList
, false);
1633 // and create the sub menu
1634 copyMenu
->_SubMenus
[k
+ startSize
] = _SubMenus
[k
]->cloneMenu(NULL
, newFather
, copyMenu
);
1639 newFather
->addGroup(copyMenu
);
1644 // ------------------------------------------------------------------------------------------------
1645 void CGroupSubMenu::setActive(bool state
)
1648 for(uint k
= 0; k
< _Lines
.size(); ++k
)
1650 if (!_Lines
[k
].Cond
.empty())
1652 CInterfaceExprValue result
;
1653 if (CInterfaceExpr::eval(_Lines
[k
].Cond
, result
))
1655 if (result
.toBool())
1657 _Lines
[k
].ViewText
->setGrayed(!result
.getBool());
1663 if(_ScrollBar
&& _GroupList
)
1664 _ScrollBar
->setTrackPos(_GroupList
->getHReal());
1666 CGroupFrame::setActive(state
);
1669 // ------------------------------------------------------------------------------------------------
1670 const std::string
CGroupSubMenu::getActionHandler(uint lineIndex
) const
1672 if (lineIndex
> _Lines
.size())
1674 nlwarning("Bad index");
1677 return _Lines
[lineIndex
].AHName
;
1680 // ------------------------------------------------------------------------------------------------
1681 const std::string
CGroupSubMenu::getActionHandlerParam(uint lineIndex
) const
1683 if (lineIndex
> _Lines
.size())
1685 nlwarning("Bad index");
1688 return _Lines
[lineIndex
].AHParams
;
1691 // ------------------------------------------------------------------------------------------------
1692 void CGroupSubMenu::setActionHandler(uint lineIndex
, const std::string
&ah
)
1694 if (lineIndex
> _Lines
.size())
1696 nlwarning("Bad index");
1699 _Lines
[lineIndex
].AHName
= ah
;
1702 // ------------------------------------------------------------------------------------------------
1703 void CGroupSubMenu::setActionHandlerParam(uint lineIndex
, const std::string
¶ms
)
1705 if (lineIndex
> _Lines
.size())
1707 nlwarning("Bad index");
1710 _Lines
[lineIndex
].AHParams
= params
;
1713 // ------------------------------------------------------------------------------------------------
1714 void CGroupSubMenu::setRightClickHandler(uint lineIndex
, const std::string
&ah
)
1716 if (lineIndex
> _Lines
.size())
1718 nlwarning("Bad index");
1721 _Lines
[lineIndex
].AHRightClick
= ah
;
1724 // ------------------------------------------------------------------------------------------------
1725 void CGroupSubMenu::setRightClickHandlerParam(uint lineIndex
, const std::string
¶ms
)
1727 if (lineIndex
> _Lines
.size())
1729 nlwarning("Bad index");
1732 _Lines
[lineIndex
].AHRightClickParams
= params
;
1735 // ------------------------------------------------------------------------------------------------
1736 void CGroupSubMenu::setSelectable(uint lineIndex
, bool selectable
)
1738 if (lineIndex
> _Lines
.size())
1740 nlwarning("Bad index");
1743 _Lines
[lineIndex
].Selectable
= selectable
;
1746 // ------------------------------------------------------------------------------------------------
1747 bool CGroupSubMenu::getSelectable(uint lineIndex
) const
1749 if (lineIndex
> _Lines
.size())
1751 nlwarning("Bad index");
1754 return _Lines
[lineIndex
].Selectable
;
1757 // ------------------------------------------------------------------------------------------------
1758 void CGroupSubMenu::setMaxVisibleLine(sint32 mvl
)
1760 _MaxVisibleLine
= mvl
;
1763 // ------------------------------------------------------------------------------------------------
1764 const std::string
&CGroupSubMenu::getLineId(uint index
)
1766 if(index
>=_Lines
.size())
1768 static string nullString
;
1772 return _Lines
[index
].Id
;
1775 // ------------------------------------------------------------------------------------------------
1776 void CGroupSubMenu::setGrayedLine(uint line
, bool g
)
1778 if(line
<_Lines
.size())
1780 if (_Lines
[line
].ViewText
)
1782 _Lines
[line
].ViewText
->setGrayed(g
);
1787 // ------------------------------------------------------------------------------------------------
1788 void CGroupSubMenu::setHiddenLine(uint line
, bool h
)
1790 if(line
<_Lines
.size())
1792 if (_Lines
[line
].ViewText
)
1794 _Lines
[line
].ViewText
->setActive(!h
);
1799 // ------------------------------------------------------------------------------------------------
1800 int CGroupSubMenu::luaGetNumLine(CLuaState
&ls
)
1802 CLuaIHM::checkArgCount(ls
, "getNumLine", 0);
1803 ls
.push(getNumLine());
1807 // ------------------------------------------------------------------------------------------------
1808 int CGroupSubMenu::luaGetSubMenu(CLuaState
&ls
)
1810 const char *funcName
= "getSubMenu";
1811 CLuaIHM::checkArgCount(ls
, funcName
, 1);
1812 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
1813 CLuaIHM::pushUIOnStack(ls
, getSubMenu((uint
) ls
.toInteger(1)));
1817 // ------------------------------------------------------------------------------------------------
1818 int CGroupSubMenu::luaAddSubMenu(CLuaState
&ls
)
1820 const char *funcName
= "addSubMenu";
1821 CLuaIHM::checkArgCount(ls
, funcName
, 1);
1822 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
1823 setSubMenu((uint
) ls
.toInteger(1), new CGroupSubMenu(CViewText::TCtorParam()));
1824 CLuaIHM::pushUIOnStack(ls
, getSubMenu((uint
) ls
.toInteger(1)));
1828 // ------------------------------------------------------------------------------------------------
1829 int CGroupSubMenu::luaGetLineId(CLuaState
&ls
)
1831 const char *funcName
= "getLineId";
1832 CLuaIHM::checkArgCount(ls
, funcName
, 1);
1833 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
1834 #ifdef RYZOM_LUA_UCSTRING
1835 ucstring id
= getLineId((uint
) ls
.toInteger(1)); // Compatibility
1836 CLuaIHM::push(ls
, id
);
1838 std::string id
= getLineId((uint
)ls
.toInteger(1));
1844 // ------------------------------------------------------------------------------------------------
1845 int CGroupSubMenu::luaGetLineFromId(CLuaState
&ls
)
1847 const char *funcName
= "getLineFromId";
1848 CLuaIHM::checkArgCount(ls
, funcName
, 1);
1849 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TSTRING
);
1850 ls
.push(getLineFromId(ls
.toString(1)));
1854 // ------------------------------------------------------------------------------------------------
1855 int CGroupSubMenu::luaIsSeparator(CLuaState
&ls
)
1857 const char *funcName
= "isSeparator";
1858 CLuaIHM::checkArgCount(ls
, funcName
, 1);
1859 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
1860 ls
.push(isSeparator((uint
) ls
.toInteger(1)));
1864 // ------------------------------------------------------------------------------------------------
1865 int CGroupSubMenu::luaAddLine(CLuaState
&ls
)
1867 const char *funcName
= "addLine";
1868 CLuaIHM::checkArgCount(ls
, funcName
, 4);
1869 #ifdef RYZOM_LUA_UCSTRING
1870 CLuaIHM::checkArgTypeUCString(ls
, funcName
, 1);
1872 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TSTRING
);
1874 CLuaIHM::checkArgType(ls
, funcName
, 2, LUA_TSTRING
);
1875 CLuaIHM::checkArgType(ls
, funcName
, 3, LUA_TSTRING
);
1876 CLuaIHM::checkArgType(ls
, funcName
, 4, LUA_TSTRING
);
1877 #ifdef RYZOM_LUA_UCSTRING
1878 ucstring arg1
; // Compatibility
1879 nlverify(CLuaIHM::getUCStringOnStack(ls
, 1, arg1
));
1880 addLine(arg1
.toUtf8(), ls
.toString(2), ls
.toString(3), ls
.toString(4));
1882 addLine(ls
.toString(1), ls
.toString(2), ls
.toString(3), ls
.toString(4));
1887 // ------------------------------------------------------------------------------------------------
1888 int CGroupSubMenu::luaAddIconLine(CLuaState
&ls
)
1890 const char *funcName
= "addIconLine";
1891 CLuaIHM::checkArgCount(ls
, funcName
, 5);
1892 #ifdef RYZOM_LUA_UCSTRING
1893 CLuaIHM::checkArgTypeUCString(ls
, funcName
, 1);
1895 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TSTRING
);
1897 CLuaIHM::checkArgType(ls
, funcName
, 2, LUA_TSTRING
);
1898 CLuaIHM::checkArgType(ls
, funcName
, 3, LUA_TSTRING
);
1899 CLuaIHM::checkArgType(ls
, funcName
, 4, LUA_TSTRING
);
1900 CLuaIHM::checkArgType(ls
, funcName
, 5, LUA_TSTRING
);
1901 #ifdef RYZOM_LUA_UCSTRING
1902 ucstring arg1
; // Compatibility
1903 nlverify(CLuaIHM::getUCStringOnStack(ls
, 1, arg1
));
1904 addLine(arg1
.toUtf8(), ls
.toString(2), ls
.toString(3), ls
.toString(4), string(), ls
.toString(5));
1906 addLine(ls
.toString(1), ls
.toString(2), ls
.toString(3), ls
.toString(4), string(), ls
.toString(5));
1911 // ------------------------------------------------------------------------------------------------
1912 int CGroupSubMenu::luaAddLineAtIndex(CLuaState
&ls
)
1914 const char *funcName
= "addLineAtIndex";
1915 CLuaIHM::checkArgCount(ls
, funcName
, 5);
1916 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
1917 #ifdef RYZOM_LUA_UCSTRING
1918 CLuaIHM::checkArgTypeUCString(ls
, funcName
, 2);
1920 CLuaIHM::checkArgType(ls
, funcName
, 2, LUA_TSTRING
);
1922 CLuaIHM::checkArgType(ls
, funcName
, 3, LUA_TSTRING
);
1923 CLuaIHM::checkArgType(ls
, funcName
, 4, LUA_TSTRING
);
1924 CLuaIHM::checkArgType(ls
, funcName
, 5, LUA_TSTRING
);
1925 #ifdef RYZOM_LUA_UCSTRING
1927 nlverify(CLuaIHM::getUCStringOnStack(ls
, 2, arg2
));
1928 addLineAtIndex((uint
) ls
.toInteger(1), arg2
.toUtf8(), ls
.toString(3), ls
.toString(4), ls
.toString(5));
1930 addLineAtIndex((uint
)ls
.toInteger(1), ls
.toString(2), ls
.toString(3), ls
.toString(4), ls
.toString(5));
1935 // ------------------------------------------------------------------------------------------------
1936 int CGroupSubMenu::luaAddSeparator(CLuaState
&ls
)
1938 CLuaIHM::checkArgCount(ls
, "addSeparator", 0);
1943 // ------------------------------------------------------------------------------------------------
1944 int CGroupSubMenu::luaAddSeparatorAtIndex(CLuaState
&ls
)
1946 const char *funcName
= "addSeparatorAtIndex";
1947 CLuaIHM::checkArgCount(ls
, funcName
, 1);
1948 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
1949 addSeparatorAtIndex((uint
) ls
.toInteger(1));
1953 // ------------------------------------------------------------------------------------------------
1954 int CGroupSubMenu::luaRemoveLine(CLuaState
&ls
)
1956 const char *funcName
= "removeLine";
1957 CLuaIHM::checkArgCount(ls
, funcName
, 1);
1958 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
1959 removeLine((uint
) ls
.toInteger(1));
1963 // ------------------------------------------------------------------------------------------------
1964 int CGroupSubMenu::luaSetUserGroupRight(CLuaState
&ls
)
1966 const char *funcName
= "setUserGroupRight";
1967 CLuaIHM::checkArgCount(ls
, funcName
, 2);
1968 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
1969 if (!(CLuaIHM::isUIOnStack(ls
, 2) || ls
.isNil(2)))
1971 CLuaIHM::fails(ls
, "%s : Group required as argument 2", funcName
);
1973 CInterfaceElement
*el
= CLuaIHM::getUIOnStack(ls
, 2);
1974 CInterfaceGroup
*group
= dynamic_cast<CInterfaceGroup
*>(el
);
1977 CLuaIHM::fails(ls
, "%s : Group required as argument 2", funcName
);
1979 setUserGroupRight((uint
) ls
.toInteger(1), group
, true);
1983 // ------------------------------------------------------------------------------------------------
1984 int CGroupSubMenu::luaSetUserGroupLeft(CLuaState
&ls
)
1986 const char *funcName
= "setUserGroupLeft";
1987 CLuaIHM::checkArgCount(ls
, funcName
, 2);
1988 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
1989 if (!(CLuaIHM::isUIOnStack(ls
, 2) || ls
.isNil(2)))
1991 CLuaIHM::fails(ls
, "%s : Group required as argument 2", funcName
);
1993 CInterfaceElement
*el
= CLuaIHM::getUIOnStack(ls
, 2);
1994 CInterfaceGroup
*group
= dynamic_cast<CInterfaceGroup
*>(el
);
1997 CLuaIHM::fails(ls
, "%s : Group required as argument 2", funcName
);
1999 setUserGroupLeft((uint
) ls
.toInteger(1), group
, true);
2004 // ------------------------------------------------------------------------------------------------
2005 int CGroupSubMenu::luaGetUserGroupRight(CLuaState
&ls
)
2007 const char *funcName
= "getUserGroupRight";
2008 CLuaIHM::checkArgCount(ls
, funcName
, 1);
2009 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
2010 CLuaIHM::pushUIOnStack(ls
, getUserGroupRight((uint
) ls
.toInteger(1)));
2015 // ------------------------------------------------------------------------------------------------
2016 int CGroupSubMenu::luaGetUserGroupLeft(CLuaState
&ls
)
2018 const char *funcName
= "getUserGroupLeft";
2019 CLuaIHM::checkArgCount(ls
, funcName
, 1);
2020 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
2021 CInterfaceElement
*pIE
= getUserGroupLeft((uint
) ls
.toInteger(1));
2024 CLuaIHM::pushUIOnStack(ls
, pIE
);
2030 // ------------------------------------------------------------------------------------------------
2031 int CGroupSubMenu::luaSetMaxVisibleLine(CLuaState
&ls
)
2033 const char *funcName
= "setMaxVisibleLine";
2034 CLuaIHM::checkArgCount(ls
, funcName
, 1);
2035 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
2036 setMaxVisibleLine((uint
) ls
.toInteger(1));
2040 // ------------------------------------------------------------------------------------------------
2041 int CGroupSubMenu::luaReset(CLuaState
&ls
)
2043 const char *funcName
= "reset";
2044 CLuaIHM::checkArgCount(ls
, funcName
, 0);
2050 // ------------------------------------------------------------------------------------------------
2052 // ------------------------------------------------------------------------------------------------
2054 NLMISC_REGISTER_OBJECT(CViewBase
, CGroupMenu
, std::string
, "menu");
2056 // ------------------------------------------------------------------------------------------------
2057 CGroupMenu::CGroupMenu(const TCtorParam
¶m
)
2061 _Color
= CRGBA::White
;
2062 _ColorOver
= CRGBA::White
;
2063 _ColorGrayed
= CRGBA(128, 128, 128, 255);
2064 _ShadowColor
= CRGBA::Black
;
2065 _ShadowColorOver
= CRGBA::Black
;
2066 _ShadowColorGrayed
= CRGBA::Black
;
2067 _HighLightOver
.set(128, 0, 0, 255);
2069 _FontSizeCoef
= true;
2071 _ShadowOutline
= false;
2072 _ResizeFromChildH
= _ResizeFromChildW
= true;
2073 _DisplayFrame
= false;
2076 _CaseMode
= CaseUpper
;
2080 // ------------------------------------------------------------------------------------------------
2081 CGroupMenu::~CGroupMenu()
2085 std::string
CGroupMenu::getProperty( const std::string
&name
) const
2087 if( name
== "extends" )
2092 if( name
== "case_mode" )
2094 uint32 cm
= _CaseMode
;
2095 return toString( cm
);
2098 if( name
== "color" )
2100 return toString( _Color
);
2103 if( name
== "shadow_color" )
2105 return toString( _ShadowColor
);
2108 if( name
== "color_over" )
2110 return toString( _ColorOver
);
2113 if( name
== "shadow_color_over" )
2115 return toString( _ShadowColorOver
);
2118 if( name
== "highlight_over" )
2120 return toString( _HighLightOver
);
2123 if( name
== "color_grayed" )
2125 return toString( _ColorGrayed
);
2128 if( name
== "shadow_color_grayed" )
2130 return toString( _ShadowColorGrayed
);
2133 if( name
== "space" )
2135 return toString( _Space
);
2138 if( name
== "fontsize" )
2140 return toString( _FontSize
);
2143 if( name
== "shadow" )
2145 return toString( _Shadow
);
2148 if( name
== "shadow_outline" )
2150 return toString( _ShadowOutline
);
2153 if( name
== "formatted" )
2155 return toString( _Formatted
);
2158 if( name
== "max_visible_line" )
2160 if( _RootMenu
== NULL
)
2163 return toString( _RootMenu
->getMaxVisibleLine() );
2166 return CGroupModal::getProperty( name
);
2169 void CGroupMenu::setProperty( const std::string
&name
, const std::string
&value
)
2171 if( name
== "extends" )
2177 if( name
== "case_mode" )
2180 if( fromString( value
, cm
) )
2181 _CaseMode
= (TCaseMode
)cm
;
2185 if( name
== "color" )
2188 if( fromString( value
, c
) )
2193 if( name
== "shadow_color" )
2196 if( fromString( value
, c
) )
2201 if( name
== "color_over" )
2204 if( fromString( value
, c
) )
2209 if( name
== "shadow_color_over" )
2212 if( fromString( value
, c
) )
2213 _ShadowColorOver
= c
;
2217 if( name
== "highlight_over" )
2220 if( fromString( value
, c
) )
2225 if( name
== "color_grayed" )
2228 if( fromString( value
, c
) )
2233 if( name
== "shadow_color_grayed" )
2236 if( fromString( value
, c
) )
2237 _ShadowColorGrayed
= c
;
2241 if( name
== "space" )
2244 if( fromString( value
, i
) )
2249 if( name
== "fontsize" )
2252 if( fromString( value
, i
) )
2257 if( name
== "shadow" )
2260 if( fromString( value
, b
) )
2265 if( name
== "shadow_outline" )
2268 if( fromString( value
, b
) )
2273 if( name
== "formatted" )
2276 if( fromString( value
, b
) )
2281 if( name
== "max_visible_line" )
2283 if( _RootMenu
!= NULL
)
2286 if( fromString( value
, i
) )
2287 _RootMenu
->setMaxVisibleLine( i
);
2292 CGroupModal::setProperty( name
, value
);
2296 xmlNodePtr
CGroupMenu::serialize( xmlNodePtr parentNode
, const char *type
) const
2298 xmlNodePtr node
= CGroupModal::serialize( parentNode
, type
);
2302 xmlSetProp( node
, BAD_CAST
"type", BAD_CAST
"menu" );
2303 xmlSetProp( node
, BAD_CAST
"extends", BAD_CAST _Extends
.c_str() );
2304 xmlSetProp( node
, BAD_CAST
"case_mode", BAD_CAST
toString( uint32( _CaseMode
) ).c_str() );
2305 xmlSetProp( node
, BAD_CAST
"color", BAD_CAST
toString( _Color
).c_str() );
2306 xmlSetProp( node
, BAD_CAST
"shadow_color", BAD_CAST
toString( _ShadowColor
).c_str() );
2307 xmlSetProp( node
, BAD_CAST
"color_over", BAD_CAST
toString( _ColorOver
).c_str() );
2308 xmlSetProp( node
, BAD_CAST
"shadow_color_over", BAD_CAST
toString( _ShadowColorOver
).c_str() );
2309 xmlSetProp( node
, BAD_CAST
"highlight_over", BAD_CAST
toString( _HighLightOver
).c_str() );
2310 xmlSetProp( node
, BAD_CAST
"color_grayed", BAD_CAST
toString( _ColorGrayed
).c_str() );
2311 xmlSetProp( node
, BAD_CAST
"shadow_color_grayed", BAD_CAST
toString( _ShadowColorGrayed
).c_str() );
2312 xmlSetProp( node
, BAD_CAST
"space", BAD_CAST
toString( _Space
).c_str() );
2313 xmlSetProp( node
, BAD_CAST
"fontsize", BAD_CAST
toString( _FontSize
).c_str() );
2314 xmlSetProp( node
, BAD_CAST
"shadow", BAD_CAST
toString( _Shadow
).c_str() );
2315 xmlSetProp( node
, BAD_CAST
"shadow_outline", BAD_CAST
toString( _ShadowOutline
).c_str() );
2316 xmlSetProp( node
, BAD_CAST
"formatted", BAD_CAST
toString( _Formatted
).c_str() );
2318 if( _RootMenu
== NULL
)
2319 xmlSetProp( node
, BAD_CAST
"max_visible_line", BAD_CAST
"0" );
2321 xmlSetProp( node
, BAD_CAST
"max_visible_line",
2322 BAD_CAST
toString( _RootMenu
->getMaxVisibleLine() ).c_str() );
2327 // ------------------------------------------------------------------------------------------------
2328 bool CGroupMenu::parse (xmlNodePtr in
, CInterfaceGroup
*parentGroup
)
2334 // override source menu options (if there's one)
2335 if (!CGroupModal::parse(in
, parentGroup
))
2339 // see if this menu extends another menu
2340 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"extends" );
2341 CGroupSubMenu
*gmExtended
= NULL
;
2345 _Extends
= std::string( (const char*)prop
);
2347 CGroupMenu
*gm
= dynamic_cast<CGroupMenu
*>(CWidgetManager::getInstance()->getElementFromId(prop
.str()));
2350 gm
= dynamic_cast<CGroupMenu
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:" + std::string((const char*)prop
)));
2354 gmExtended
= gm
->_RootMenu
;
2355 // copy group frame parameters
2356 CGroupFrame::copyOptionFrom(*gm
);
2358 _Color
= gm
->_Color
;
2359 _ShadowColor
= gm
->_ShadowColor
;
2360 _Shadow
= gm
->_Shadow
;
2361 _ShadowOutline
= gm
->_ShadowOutline
;
2362 _FontSize
= gm
->_FontSize
;
2363 _ColorOver
= gm
->_ColorOver
;
2364 _ShadowColorOver
= gm
->_ShadowColorOver
;
2365 _HighLightOver
= gm
->_HighLightOver
;
2366 _ColorGrayed
= gm
->_ColorGrayed
;
2367 _ShadowColorGrayed
= gm
->_ShadowColorGrayed
;
2368 _Priority
= gm
->_Priority
;
2369 _ModulateGlobalColor
= gm
->_ModulateGlobalColor
;
2370 _Space
= gm
->_Space
;
2371 _CaseMode
= gm
->_CaseMode
;
2375 nlwarning("Can't get menu %s or bad type", (const char *) prop
);
2380 // Override the modal behaviour because of sub menus
2381 ExitClickOut
= true;
2384 ExitKeyPushed
= true;
2385 _ResizeFromChildH
= _ResizeFromChildW
= true;
2386 _DisplayFrame
= false;
2391 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"color" );
2392 if (prop
) _Color
= convertColor(prop
);
2394 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"case_mode" );
2398 fromString((const char*)prop
, caseMode
);
2399 _CaseMode
= (TCaseMode
)caseMode
;
2402 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"shadow_color" );
2403 if (prop
) _ShadowColor
= convertColor(prop
);
2405 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"color_over" );
2406 if (prop
) _ColorOver
= convertColor(prop
);
2408 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"shadow_color_over" );
2409 if (prop
) _ShadowColorOver
= convertColor(prop
);
2411 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"highlight_over" );
2412 if (prop
) _HighLightOver
= convertColor(prop
);
2414 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"color_grayed" );
2415 if (prop
) _ColorGrayed
= convertColor(prop
);
2417 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"shadow_color_grayed" );
2418 if (prop
) _ShadowColorGrayed
= convertColor(prop
);
2420 prop
= (char*) xmlGetProp (in
, (xmlChar
*)"space");
2421 if (prop
) fromString((const char*)prop
, _Space
);
2424 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"fontsize" );
2425 if (prop
) fromString((const char*)prop
, _FontSize
);
2427 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"shadow" );
2429 _Shadow
= convertBool(prop
);
2431 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"shadow_outline" );
2433 _ShadowOutline
= convertBool(prop
);
2435 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"formatted" );
2437 _Formatted
= convertBool(prop
);
2443 if (_RootMenu
!= NULL
) delete _RootMenu
;
2444 _RootMenu
= new CGroupSubMenu(CViewText::TCtorParam());
2445 _RootMenu
->setId( getId() + ":header" );
2446 _RootMenu
->setSerializable( false );
2447 _RootMenu
->_GroupMenu
= this;
2448 _RootMenu
->parse (cur
);
2450 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"max_visible_line" );
2453 sint32 maxVisibleLine
;
2454 fromString((const char*)prop
, maxVisibleLine
);
2455 _RootMenu
->setMaxVisibleLine(maxVisibleLine
);
2460 gmExtended
->cloneMenu(_RootMenu
, this);
2465 // ------------------------------------------------------------------------------------------------
2466 void CGroupMenu::recurseDraw(CGroupSubMenu
*pSubMenu
)
2470 // const vector<CInterfaceGroup*> &rGroups = pSubMenu->getGroups();
2472 for (uint32 i
= 0; i
< pSubMenu
->getNumLines(); i
++)
2474 CGroupSubMenu
*pGSM
= pSubMenu
->getSubMenu(i
);
2478 CViewRenderer::getInstance()->flush();
2483 // ------------------------------------------------------------------------------------------------
2484 void CGroupMenu::draw ()
2486 if (!_Active
) return;
2489 //CViewRenderer &rVR = *CViewRenderer::getInstance();
2490 //rVR.drawRotFlipBitmap _RenderLayer, (_XReal, _YReal, _WReal, _HReal, 0, false, rVR.getBlankTextureId(), CRGBA(255, 0, 0, 255) );
2492 _RootMenu
->_Active
= true;
2494 if (SpawnOnMousePos
)
2495 recurseDraw(_RootMenu
);
2497 CGroupModal::draw();
2500 // ------------------------------------------------------------------------------------------------
2501 bool CGroupMenu::handleEvent (const NLGUI::CEventDescriptor
&event
)
2505 return CGroupModal::handleEvent (event
);
2508 // ------------------------------------------------------------------------------------------------
2509 CInterfaceElement
* CGroupMenu::getElement (const std::string
&id
)
2511 if (id
== getId()) return this;
2512 CInterfaceElement
*pIE
= _RootMenu
->getElement(id
);
2515 return CGroupModal::getElement(id
);
2518 // ------------------------------------------------------------------------------------------------
2519 void CGroupMenu::setActive (bool state
)
2521 if (SpawnOnMousePos
)
2523 CViewRenderer
&rVR
= *CViewRenderer::getInstance();
2525 rVR
.getScreenSize(w
,h
);
2530 _ResizeFromChildH
= _ResizeFromChildW
= false;
2531 _RootMenu
->_PosRef
= Hotspot_TL
;
2532 _RootMenu
->_ParentPosRef
= Hotspot_BL
;
2535 CGroupFrame::setActive (state
);
2537 // must recompute now the pos of the menu
2539 for (i
= 0; i
< _ChildrenGroups
.size(); ++i
)
2541 _ChildrenGroups
[i
]->setActive (true);
2544 CGroupModal::updateCoords();
2547 _RootMenu
->hideSubMenus();
2550 // ------------------------------------------------------------------------------------------------
2551 bool CGroupSubMenu::isSeparator(uint i
) const
2553 if (i
>= _SubMenus
.size())
2555 nlassert("bad index");
2558 return _Lines
[i
].Separator
!= NULL
;
2560 // ------------------------------------------------------------------------------------------------
2561 bool CGroupMenu::isWindowUnder (sint32 x
, sint32 y
)
2563 for (uint32 i
= 0; i
< _ChildrenGroups
.size(); ++i
)
2564 if (_ChildrenGroups
[i
]->getActive ())
2565 if (_ChildrenGroups
[i
]->isWindowUnder(x
, y
))
2571 // ------------------------------------------------------------------------------------------------
2572 void CGroupMenu::addLine(const std::string
&name
, const std::string
&ah
, const std::string
¶ms
,
2573 const std::string
&id
/* = std::string()*/,
2574 const std::string
&cond
/*= std::string()*/, const std::string
&texture
,
2575 bool checkable
/*= false*/, bool checked
/*= false*/
2578 if (_RootMenu
== NULL
)
2580 _RootMenu
= new CGroupSubMenu(CViewText::TCtorParam());
2581 _RootMenu
->_GroupMenu
= this;
2582 _RootMenu
->setSerializable( false );
2583 addGroup (_RootMenu
);
2585 _RootMenu
->addLine (name
, ah
, params
, id
, cond
, texture
, checkable
, checked
, _Formatted
);
2587 // ------------------------------------------------------------------------------------------------
2588 void CGroupMenu::addLineAtIndex(uint index
, const std::string
&name
, const std::string
&ah
,
2589 const std::string
¶ms
, const std::string
&id
/*=std::string()*/,
2590 const std::string
&cond
/*=std::string()*/, const std::string
&texture
,
2591 bool checkable
/*=false*/, bool checked
/*=false*/)
2593 if (_RootMenu
== NULL
)
2595 _RootMenu
= new CGroupSubMenu(CViewText::TCtorParam());
2596 _RootMenu
->_GroupMenu
= this;
2597 _RootMenu
->setSerializable( false );
2598 addGroup (_RootMenu
);
2600 _RootMenu
->addLineAtIndex(index
, name
, ah
, params
, id
, cond
, texture
, checkable
, checked
, _Formatted
);
2604 // ------------------------------------------------------------------------------------------------
2605 void CGroupMenu::reset ()
2614 // ------------------------------------------------------------------------------------------------
2615 void CGroupMenu::setMinW(sint32 minW
)
2619 _RootMenu
->_GroupList
->setMinW(minW
-_RootMenu
->getResizeFromChildWMargin());
2620 _RootMenu
->_GroupList
->setW(minW
-_RootMenu
->getResizeFromChildWMargin());
2621 _RootMenu
->setW(minW
-_RootMenu
->getResizeFromChildWMargin());
2625 // ------------------------------------------------------------------------------------------------
2626 void CGroupMenu::setMinH(sint32 minH
)
2630 _RootMenu
->_GroupList
->setMinH(minH
-_RootMenu
->getResizeFromChildHMargin());
2631 _RootMenu
->_GroupList
->setH(minH
-_RootMenu
->getResizeFromChildHMargin());
2632 _RootMenu
->setH(minH
-_RootMenu
->getResizeFromChildHMargin());
2636 // ------------------------------------------------------------------------------------------------
2637 void CGroupMenu::setGrayedLine(uint line
, bool g
)
2641 _RootMenu
->setGrayedLine(line
, g
);
2645 // ------------------------------------------------------------------------------------------------
2646 void CGroupMenu::setFontSize(uint fontSize
, bool coef
)
2648 _FontSize
= fontSize
;
2649 _FontSizeCoef
= coef
;
2652 // ------------------------------------------------------------------------------------------------
2653 uint
CGroupMenu::getNumLine() const
2655 return _RootMenu
? _RootMenu
->getNumLine() : 0;
2658 // ------------------------------------------------------------------------------------------------
2659 void CGroupMenu::deleteLine(uint index
)
2661 if (index
> getNumLine())
2663 nlwarning("bad index");
2666 _RootMenu
->removeLine(index
);
2669 // ------------------------------------------------------------------------------------------------
2670 const std::string
CGroupMenu::getActionHandler(uint lineIndex
) const
2672 return _RootMenu
? _RootMenu
->getActionHandler(lineIndex
) : "";
2675 // ------------------------------------------------------------------------------------------------
2676 const std::string
CGroupMenu::getActionHandlerParam(uint lineIndex
) const
2678 return _RootMenu
? _RootMenu
->getActionHandlerParam(lineIndex
) : "";
2681 // ------------------------------------------------------------------------------------------------
2682 void CGroupMenu::setActionHandler(uint lineIndex
, const std::string
&ah
)
2685 _RootMenu
->setActionHandler(lineIndex
, ah
);
2688 // ------------------------------------------------------------------------------------------------
2689 void CGroupMenu::setActionHandlerParam(uint lineIndex
, const std::string
¶ms
)
2692 _RootMenu
->setActionHandlerParam(lineIndex
, params
);
2695 // ------------------------------------------------------------------------------------------------
2696 void CGroupMenu::setRightClickHandler(uint lineIndex
, const std::string
&ah
)
2699 _RootMenu
->setRightClickHandler(lineIndex
, ah
);
2702 // ------------------------------------------------------------------------------------------------
2703 void CGroupMenu::setRightClickHandlerParam(uint lineIndex
, const std::string
¶ms
)
2706 _RootMenu
->setRightClickHandlerParam(lineIndex
, params
);
2709 // ------------------------------------------------------------------------------------------------
2710 void CGroupMenu::setUserGroupRight(uint line
, CInterfaceGroup
*gr
, bool ownerShip
/*=true*/)
2714 _RootMenu
->setUserGroupRight(line
, gr
, ownerShip
);
2718 // ------------------------------------------------------------------------------------------------
2719 void CGroupMenu::setUserGroupLeft(uint line
, CInterfaceGroup
*gr
, bool ownerShip
/*=true*/)
2723 _RootMenu
->setUserGroupLeft(line
, gr
, ownerShip
);
2727 // ------------------------------------------------------------------------------------------------
2728 int CGroupMenu::luaGetRootMenu(CLuaState
&ls
)
2730 CLuaIHM::checkArgCount(ls
, "getRootMenu", 0);
2731 CLuaIHM::pushUIOnStack(ls
, getRootMenu());
2735 // ------------------------------------------------------------------------------------------------
2736 int CGroupMenu::luaSetMinW(CLuaState
&ls
)
2738 const char *funcName
= "setMinW";
2739 CLuaIHM::checkArgCount(ls
, funcName
, 1);
2740 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
2741 setMinW((sint32
) ls
.toInteger(1));