1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2019 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);
387 _GroupMenu
->addGroup (this);
388 this->_DispType
= _GroupMenu
->_DispType
;
393 // ------------------------------------------------------------------------------------------------
394 CViewBitmap
*CGroupSubMenu::createIcon(CInterfaceElement
*parentPos
, const string
&texture
)
396 // Add an icon to the line
397 CViewBitmap
*pVB
= new CViewBitmap(CViewBase::TCtorParam());
398 pVB
->setSerializable( false );
399 pVB
->setParent (this);
400 pVB
->setParentPos (parentPos
);
401 pVB
->setParentPosRef (Hotspot_ML
);
402 pVB
->setPosRef (Hotspot_MR
);
403 pVB
->setTexture(texture
);
404 pVB
->setModulateGlobalColor(false);
410 // ------------------------------------------------------------------------------------------------
411 CViewBitmap
*CGroupSubMenu::createCheckBox(bool checked
)
413 // Put the left arrow to the line
414 CViewBitmap
*pVB
= new CViewBitmap(CViewBase::TCtorParam());
415 pVB
->setSerializable( false );
416 pVB
->setParent (this);
417 pVB
->setParentPos (_GroupList
);
418 pVB
->setParentPosRef (Hotspot_BR
);
419 pVB
->setPosRef (Hotspot_BL
);
420 CInterfaceOptions
*pIO
= CWidgetManager::getInstance()->getOptions("menu_checkbox");
423 pVB
->setTexture(pIO
->getValStr(checked
? "checked_bitmap" : "unchecked_bitmap"));
425 pVB
->setX (MENU_WIDGET_X
);
426 pVB
->setId (ID_MENU_CHECKBOX
); // always rescale to parent in update coords
432 // ------------------------------------------------------------------------------------------------
433 CViewBitmap
*CGroupSubMenu::createRightArrow(CInterfaceElement
*parentPos
, bool center
)
435 // Put the left arrow to the line
436 CViewBitmap
*pVB
= new CViewBitmap(CViewBase::TCtorParam());
437 pVB
->setSerializable( false );
438 pVB
->setParent (this);
439 pVB
->setParentPos (parentPos
);
442 pVB
->setParentPosRef (Hotspot_BR
);
443 pVB
->setPosRef (Hotspot_BL
);
447 pVB
->setParentPosRef (Hotspot_MR
);
448 pVB
->setPosRef (Hotspot_ML
);
450 pVB
->setTexture("w_arrow_right_3.tga");
451 pVB
->setX (MENU_WIDGET_X
);
452 pVB
->setId (ID_MENU_SUBMENU
); // rescale to parent in update coords if asked (not needed if there's already on the left a checkbox)
457 // ------------------------------------------------------------------------------------------------
458 #define GET_REF_ELM(__index__) \
459 CInterfaceElement *refElm; \
460 sint32 refElmYReal= 0; \
461 sint32 refElmHReal= 0; \
462 refElm = _Lines[__index__].ViewText; \
465 refElmYReal= refElm->getYReal() - _Lines[__index__].TextDY; \
466 refElmHReal= _Lines[__index__].HReal; \
469 void CGroupSubMenu::updateCoords ()
471 if (_ParentPos
== _GroupMenu
)
474 setX(_GroupMenu
->SpawnMouseX
);
475 setY(_GroupMenu
->SpawnMouseY
);
476 CGroupFrame::updateCoords();
478 CViewRenderer
&rVR
= *CViewRenderer::getInstance();
479 uint32 screenW
, screenH
;
480 rVR
.getScreenSize(screenW
, screenH
);
481 if ((_XReal
+_WReal
) > (sint32
)screenW
)
482 setX(screenW
-_WReal
);
487 // The sub menu may go outside the screen in Y. => clamp it as possible
489 /* X/Y coords have normally been updated before by "parent" sub menus
490 Why? because setSubMenu() is typically called in "parent first" order (or it is exactly what is done in ::parse())
491 => Parent CGroupSubMenu::updateCoords() are called before their sons in CGroupMenu::updateCoords() !!!
492 => No Need to call _SubMenus[RALineNb]->updateCoords() below ! (else would call too much time because of recursion!!)
495 // must udpate correct Real coords
496 CGroupFrame::updateCoords();
499 CViewRenderer
&rVR
= *CViewRenderer::getInstance();
500 uint32 screenW
, screenH
;
501 rVR
.getScreenSize(screenW
, screenH
);
503 sint32 hReal
= getHReal();
504 // If the H is too big, abort.. can't do anything
505 if(hReal
<=(sint32
)screenH
)
507 sint32 yReal
= getYReal();
509 // compute the shift to apply to the Y of the sub menu, to respect (as possible) the screen
513 if(yReal
+hReal
>(sint32
)screenH
)
514 dyClamp
= screenH
- (yReal
+hReal
);
518 setY(getY()+dyClamp
);
519 CGroupFrame::updateCoords();
525 if (!_GroupList
) return;
527 // get text dy position
529 textDYPos
= -(1+_GroupList
->getSpace())/2;
531 // Set the arrows at the right positions (in _Views we have selection and the right arrows)
532 sint32 CBLineNb
= 0; // check box
533 sint32 RALineNb
= 0; // right arrow
536 sint32 maxUserGroupWidth
= 0;
537 // compute max width of user groups, & adapt max height for each line
540 // update all left user groups to get their width
541 sint32 maxLeftUGWidth
= 0;
542 for(k
= 0; k
< _Lines
.size(); ++k
)
544 if (_Lines
[k
].UserGroupLeft
)
546 _Lines
[k
].UserGroupLeft
->updateCoords();
547 maxLeftUGWidth
= std::max(_Lines
[k
].UserGroupLeft
->getWReal(), maxLeftUGWidth
);
551 _GroupList
->setX(LEFT_MENU_WIDGET_X
+ maxLeftUGWidth
);
553 // active separators when needed
554 bool activeLineSeen
= false;
555 for (i
= 0; i
< _Lines
.size(); ++i
)
557 if (_Lines
[i
].Separator
!= NULL
)
559 if (i
== _Lines
.size() - 1)
561 _Lines
[i
].Separator
->setActive(false);
564 _Lines
[i
].Separator
->setActive(activeLineSeen
);
565 activeLineSeen
= false;
569 if (_Lines
[i
].ViewText
&& _Lines
[i
].ViewText
->getActive()) activeLineSeen
= true;
573 CGroupFrame::updateCoords();
575 bool mustUpdate
= false;
577 if (_MaxVisibleLine
> 0 && sint32(_Lines
.size())>_MaxVisibleLine
)
579 for(k
= 0; k
< _Lines
.size(); ++k
)
580 if (_Lines
[k
].ViewText
)
582 // compute max height of widgets on the left of text
583 sint32 widgetMaxH
= 0;
584 if (_Lines
[k
].UserGroupRight
) widgetMaxH
= _Lines
[k
].UserGroupRight
->getHReal();
585 if (_Lines
[k
].UserGroupLeft
) widgetMaxH
= std::max(widgetMaxH
, _Lines
[k
].UserGroupLeft
->getHReal());
586 if (_Lines
[k
].CheckBox
) widgetMaxH
= std::max(widgetMaxH
, _Lines
[k
].CheckBox
->getHReal());
587 if (_Lines
[k
].RightArrow
) widgetMaxH
= std::max(widgetMaxH
, _Lines
[k
].RightArrow
->getHReal());
588 widgetMaxH
= std::max(widgetMaxH
, _Lines
[k
].ViewText
->getHReal());
589 _GroupList
->setMaxH(widgetMaxH
*_MaxVisibleLine
+_GroupList
->getSpace()*(_MaxVisibleLine
-1));
590 if (_ScrollBar
== NULL
)
592 _ScrollBar
= new CCtrlScroll(CViewBase::TCtorParam());
593 _ScrollBar
->setParent (this);
594 _ScrollBar
->setParentPos (_GroupList
);
595 _ScrollBar
->setPosRef (Hotspot_BL
);
596 _ScrollBar
->setParentPosRef (Hotspot_BR
);
597 _ScrollBar
->setX (4);
598 _ScrollBar
->setY (0);
599 _ScrollBar
->setW (8);
600 _ScrollBar
->setTextureBottomOrLeft ("w_scroll_l123_b.tga");
601 _ScrollBar
->setTextureMiddle ("w_scroll_l123_m.tga");
602 _ScrollBar
->setTextureTopOrRight ("w_scroll_l123_t.tga");
603 _ScrollBar
->setTarget(_GroupList
);
604 _SelectionView
->setW (-8-8-2);
605 _ScrollBar
->setSerializable( false );
614 _SelectionView
->setW(-8);
619 for(k
= 0; k
< _Lines
.size(); ++k
)
621 CInterfaceGroup
*ig
= _Lines
[k
].UserGroupRight
;
625 maxUserGroupWidth
= std::max(maxUserGroupWidth
, ig
->getWReal());
627 if (_Lines
[k
].ViewText
)
629 // compute max height of widgets on the left of text
630 sint32 widgetMaxH
= 0;
631 if (_Lines
[k
].UserGroupRight
) widgetMaxH
= _Lines
[k
].UserGroupRight
->getHReal();
632 if (_Lines
[k
].UserGroupLeft
) widgetMaxH
= std::max(widgetMaxH
, _Lines
[k
].UserGroupLeft
->getHReal());
633 if (_Lines
[k
].CheckBox
) widgetMaxH
= std::max(widgetMaxH
, _Lines
[k
].CheckBox
->getHReal());
634 if (_Lines
[k
].RightArrow
) widgetMaxH
= std::max(widgetMaxH
, _Lines
[k
].RightArrow
->getHReal());
636 sint32 textHReal
= _Lines
[k
].ViewText
->getHReal();
637 _Lines
[k
].HReal
= max(widgetMaxH
, textHReal
);
638 _Lines
[k
].TextDY
= textDYPos
;
639 if(widgetMaxH
>textHReal
)
640 _Lines
[k
].TextDY
+= (widgetMaxH
-textHReal
) / 2;
645 // *** Update Text Positions
647 for(k
= 0; k
< _Lines
.size(); ++k
)
649 if (_Lines
[k
].ViewText
)
652 _Lines
[k
].ViewText
->setY(_Lines
[k
].TextDY
);
660 CGroupFrame::updateCoords();
664 // *** Setup SubMenus and CheckBoxes Positions
666 for (i
= 1; i
< _Views
.size(); ++i
)
668 CViewBitmap
*pVB
= dynamic_cast<CViewBitmap
*>(_Views
[i
]);
669 if (pVB
== NULL
) continue;
670 if (pVB
->getId() == ID_MENU_SUBMENU
)
672 // Look for the next line of the menu that contains a sub menu
675 nlassert (RALineNb
< (sint32
)_SubMenus
.size());
676 if (_SubMenus
[RALineNb
] != NULL
) // has a check box or an arrow to indicate submenu ?
683 // get refElm and refElmYReal
684 GET_REF_ELM(RALineNb
)
686 // if there is a check box, y is 0
687 if (_Lines
[RALineNb
].CheckBox
|| _Lines
[RALineNb
].UserGroupRight
)
690 pVB
->setX(MENU_WIDGET_X
);
694 sint32 limY
= refElmYReal
+ refElmHReal
/2 - _GroupList
->getYReal();
695 // Setup the arrow at the right pos
696 if(_GroupList
->getMaxH()>=limY
&& limY
>=0)
698 pVB
->setY(refElmYReal
+ (refElmHReal
- pVB
->getHReal()) / 2 - _GroupList
->getYReal());
699 pVB
->setColor(_Lines
[RALineNb
].ViewText
->getColor());
700 pVB
->setActive(_Lines
[RALineNb
].ViewText
->getActive());
701 pVB
->setX(maxUserGroupWidth
+ MENU_WIDGET_X
);
706 pVB
->setActive(false);
710 if (_GroupMenu
->SpawnOnMousePos
)
712 _SubMenus
[RALineNb
]->setParentPos (this);
714 // According to mouse position, set the sub menu on the left or right, begin at top or bottom
715 CViewRenderer
&rVR
= *CViewRenderer::getInstance();
716 uint32 screenW
, screenH
;
717 rVR
.getScreenSize(screenW
, screenH
);
718 if ((_GroupMenu
->SpawnMouseX
<= ((sint32
)screenW
/2)) && (_GroupMenu
->SpawnMouseY
<= ((sint32
)screenH
/2)))
720 _SubMenus
[RALineNb
]->setParentPosRef(Hotspot_BR
);
721 _SubMenus
[RALineNb
]->setPosRef(Hotspot_BL
);
722 _SubMenus
[RALineNb
]->setY (refElmYReal
- _GroupList
->getYReal());
724 if ((_GroupMenu
->SpawnMouseX
<= ((sint32
)screenW
/2)) && (_GroupMenu
->SpawnMouseY
> ((sint32
)screenH
/2)))
726 _SubMenus
[RALineNb
]->setParentPosRef(Hotspot_TR
);
727 _SubMenus
[RALineNb
]->setPosRef(Hotspot_TL
);
728 _SubMenus
[RALineNb
]->setY (refElmHReal
+(refElmYReal
- _GroupList
->getYReal()) - _GroupList
->getHReal());
730 if ((_GroupMenu
->SpawnMouseX
> ((sint32
)screenW
/2)) && (_GroupMenu
->SpawnMouseY
<= ((sint32
)screenH
/2)))
732 _SubMenus
[RALineNb
]->setParentPosRef(Hotspot_BL
);
733 _SubMenus
[RALineNb
]->setPosRef(Hotspot_BR
);
734 _SubMenus
[RALineNb
]->setY (refElmYReal
- _GroupList
->getYReal());
736 if ((_GroupMenu
->SpawnMouseX
> ((sint32
)screenW
/2)) && (_GroupMenu
->SpawnMouseY
> ((sint32
)screenH
/2)))
738 _SubMenus
[RALineNb
]->setParentPosRef(Hotspot_TL
);
739 _SubMenus
[RALineNb
]->setPosRef(Hotspot_TR
);
740 _SubMenus
[RALineNb
]->setY (refElmHReal
+(refElmYReal
- _GroupList
->getYReal()) - _GroupList
->getHReal());
742 _SubMenus
[RALineNb
]->setX(0);
747 _SubMenus
[RALineNb
]->setParentPos (this);
748 _SubMenus
[RALineNb
]->setParentPosRef (Hotspot_BR
);
749 _SubMenus
[RALineNb
]->setPosRef (Hotspot_BL
);
750 _SubMenus
[RALineNb
]->setY (16+refElmYReal
- _GroupList
->getYReal() - _SubMenus
[RALineNb
]->getHReal());
755 else if (pVB
->getId() == ID_MENU_CHECKBOX
)
759 nlassert (CBLineNb
< (sint32
)_SubMenus
.size());
760 if (_Lines
[CBLineNb
].CheckBox
!= NULL
) // has a check box or an arrow to indicate submenu ?
766 // Setup the arrow at the right pos
767 if (!_Lines
[CBLineNb
].UserGroupRight
)
769 // get refElm and refElmYReal
770 GET_REF_ELM(CBLineNb
)
772 pVB
->setX(maxUserGroupWidth
+ 2 * MENU_WIDGET_X
);
774 sint32 limY
= refElmYReal
+ refElmHReal
/2 - _GroupList
->getYReal();
775 // Setup the arrow at the right pos
776 if(_GroupList
->getMaxH()>=limY
&& limY
>=0)
778 pVB
->setY(refElmYReal
+ (refElmHReal
- pVB
->getHReal()) / 2 - _GroupList
->getYReal());
779 pVB
->setActive(_Lines
[CBLineNb
].ViewText
->getActive());
784 pVB
->setActive(false);
790 pVB
->setX(MENU_WIDGET_X
);
792 pVB
->setColor (_Lines
[CBLineNb
].ViewText
->getColor());
797 if (maxViewW
<(pVB
->getWReal()+pVB
->getX())) maxViewW
= pVB
->getWReal()+pVB
->getX();
800 // setup scrollbar position in function of views width
801 if(maxViewW
>0 && _ScrollBar
)
802 _ScrollBar
->setX(4 + maxViewW
);
804 // *** Setup user groups positions
805 for(k
= 0; k
< _Lines
.size(); ++k
)
807 CInterfaceGroup
*igr
= _Lines
[k
].UserGroupRight
;
808 CInterfaceGroup
*igl
= _Lines
[k
].UserGroupLeft
;
811 // get refElm and refElmYReal
818 igr
->setX(MENU_WIDGET_X
+ maxUserGroupWidth
- igr
->getWReal());
820 sint32 limY
= refElmYReal
+ refElmHReal
/2 - _GroupList
->getYReal();
821 if(_GroupList
->getMaxH()>=limY
&& limY
>=0)
823 igr
->setY(refElmYReal
+ (refElmHReal
- igr
->getHReal()) / 2 - _GroupList
->getYReal());
824 igr
->setActive (refElm
->getActive());
829 igr
->setActive(false);
835 sint32 limY
= refElmYReal
+ refElmHReal
/2 - _GroupList
->getYReal();
836 if(_GroupList
->getMaxH()>=limY
&& limY
>=0)
838 igl
->setY(refElmYReal
+ (refElmHReal
- igl
->getHReal()) / 2 - this->getYReal());
839 igl
->setActive(refElm
->getActive());
844 igl
->setActive(false);
852 sint32 SepLineNb
= 0;
853 // set separator at the right position
854 for (i
= 0; i
< _ChildrenGroups
.size(); ++i
)
856 CInterfaceGroup
*pIG
= dynamic_cast<CInterfaceGroup
*>(_ChildrenGroups
[i
]);
857 if (pIG
== NULL
) continue;
858 if (pIG
->getId() != ID_MENU_SEPARATOR
) continue; // is it a separator ?
861 /*sint32 sw = getW() - _LeftBorder - _RightBorder;
862 sw = std::max(sw, (sint32) 0);
865 // Look for the next line of the menu that contains a separator
866 CInterfaceGroup
*sep
= NULL
;
869 nlassert (SepLineNb
< (sint32
)_Lines
.size());
870 sep
= _Lines
[SepLineNb
].Separator
;
875 // Setup the arrow at the right pos
876 pIG
->setY (sep
->getYReal() - getYReal());
877 pIG
->setActive(sep
->getActive());
879 CGroupFrame::updateCoords();
881 //_SelectionView->setW (this->getW());
882 _SelectionView
->setH (8);
883 _SelectionView
->setY (4);
886 if (_Selected
!= -1 && _Lines
[_Selected
].ViewText
!= NULL
)
888 CRGBA col
= _GroupMenu
->_HighLightOver
;
890 _SelectionView
->setColor (col
);
891 _SelectionView
->setModulateGlobalColor(getModulateGlobalColor());
893 // get refElm and refElmYReal
894 GET_REF_ELM(_Selected
)
896 _SelectionView
->setH (refElmHReal
);
897 _SelectionView
->setY (refElmYReal
- this->getYReal());
901 // ------------------------------------------------------------------------------------------------
902 void CGroupSubMenu::checkCoords()
904 if (!_Active
) return;
905 if (_GroupMenu
== NULL
) return;
907 // if the mouse goes out the window, unselect all (because handleEvent may not be called)
908 sint xMouse
= CWidgetManager::getInstance()->getPointer()->getX();
909 sint yMouse
= CWidgetManager::getInstance()->getPointer()->getY();
910 if (!((xMouse
>= _XReal
) &&
911 (xMouse
< (_XReal
+ _WReal
))&&
913 (yMouse
<= (_YReal
+ _HReal
))))
916 // CViewRenderer &rVR = *CViewRenderer::getInstance();
918 // Highlight (background under the selection)
921 // display hightlight
922 if(_GroupMenu
->_HighLightOver
.A
> 0)
924 _SelectionView
->setActive (true);
925 _SelectionView
->invalidateCoords();
929 _SelectionView
->setActive (false);
934 _SelectionView
->setActive (false);
937 // Text color if grayed or not
938 for (sint32 i
= 0; i
< (sint32
)_Lines
.size(); ++i
)
940 if (_Lines
[i
].ViewText
)
942 if (_Lines
[i
].ViewText
->getGrayed()) // Colors when the text is grayed
944 _Lines
[i
].ViewText
->setColor (_Lines
[i
].ViewText
->OldColorGrayed
);
945 _Lines
[i
].ViewText
->setShadowColor (_Lines
[i
].ViewText
->OldShadowColorGrayed
);
949 if (i
== _Selected
) // Colors when the text is selected
951 _Lines
[i
].ViewText
->Over
= true;
952 _Lines
[i
].ViewText
->setColor (_Lines
[i
].ViewText
->OldColorOver
);
953 _Lines
[i
].ViewText
->setShadowColor (_Lines
[i
].ViewText
->OldShadowColorOver
);
955 else // Or finally normal colors
957 _Lines
[i
].ViewText
->Over
= false;
958 _Lines
[i
].ViewText
->setColor (_Lines
[i
].ViewText
->OldColor
);
959 _Lines
[i
].ViewText
->setShadowColor (_Lines
[i
].ViewText
->OldShadowColor
);
966 // ------------------------------------------------------------------------------------------------
967 void CGroupSubMenu::draw()
969 if (!_Active
) return;
970 if (_GroupMenu
== NULL
) return;
974 // ------------------------------------------------------------------------------------------------
975 bool CGroupSubMenu::handleEvent (const NLGUI::CEventDescriptor
&event
)
982 textDYPos
= -(1+_GroupList
->getSpace())/2;
984 if (event
.getType() == NLGUI::CEventDescriptor::mouse
)
986 const NLGUI::CEventDescriptorMouse
&eventDesc
= (const NLGUI::CEventDescriptorMouse
&)event
;
989 // TODO First check sub menus that can be not in the area of this menu
991 if (!((eventDesc
.getX() >= _XReal
) &&
992 (eventDesc
.getX() < (_XReal
+ _WReal
))&&
993 (eventDesc
.getY() > _YReal
) &&
994 (eventDesc
.getY() <= (_YReal
+ _HReal
))))
998 for (i
= 0; i
< _Lines
.size(); ++i
)
1000 if (_Lines
[i
].Selectable
)
1002 // get refElm and refElmYReal
1007 if (refElm
->getActive() == true)
1008 if ((eventDesc
.getY() > refElmYReal
) &&
1009 (eventDesc
.getY() <= (refElmYReal
+ refElmHReal
+ _GroupList
->getSpace())))
1018 if (eventDesc
.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup
)
1020 // If a line is selected and the line is not grayed
1021 if ((_Selected
!= -1) && (!_Lines
[i
].ViewText
->getGrayed()))
1024 CAHManager::getInstance()->runActionHandler ( _Lines
[_Selected
].AHName
,
1025 CWidgetManager::getInstance()->getCtrlLaunchingModal(),
1026 _Lines
[_Selected
].AHParams
);
1028 if (_SubMenus
[_Selected
] != NULL
)
1030 openSubMenu (_Selected
);
1034 // if the menu hasn't triggered a new modal window, disable it
1035 if (CWidgetManager::getInstance()->getModalWindow() == _GroupMenu
)
1037 if(_GroupMenu
&& _GroupMenu
->getCloseSubMenuUsingPopModal())
1038 CWidgetManager::getInstance()->popModalWindow();
1040 CWidgetManager::getInstance()->disableModalWindow ();
1046 if (eventDesc
.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightup
)
1048 // If a line is selected and the line is not grayed and has right click action handler
1049 if ((_Selected
!= -1) && (!_Lines
[i
].ViewText
->getGrayed()) && !_Lines
[_Selected
].AHRightClick
.empty())
1051 CAHManager::getInstance()->runActionHandler ( _Lines
[_Selected
].AHRightClick
,
1052 CWidgetManager::getInstance()->getCtrlLaunchingModal(),
1053 _Lines
[_Selected
].AHRightClickParams
);
1058 if (event
.getType() == NLGUI::CEventDescriptor::mouse
)
1060 const NLGUI::CEventDescriptorMouse
&eventDesc
= (const NLGUI::CEventDescriptorMouse
&)event
;
1062 if (_GroupList
&& _ScrollBar
)
1064 if (eventDesc
.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mousewheel
)
1066 if (isIn(eventDesc
.getX(), eventDesc
.getY()))
1069 for (uint32 k
= 0; k
< _Lines
.size(); ++k
)
1070 if (_Lines
[k
].ViewText
)
1072 // compute max height of widgets on the left of text
1073 sint32 widgetMaxH
= 0;
1074 if (_Lines
[k
].UserGroupRight
) widgetMaxH
= _Lines
[k
].UserGroupRight
->getHReal();
1075 if (_Lines
[k
].UserGroupLeft
) widgetMaxH
= std::max(widgetMaxH
, _Lines
[k
].UserGroupLeft
->getHReal());
1076 if (_Lines
[k
].CheckBox
) widgetMaxH
= std::max(widgetMaxH
, _Lines
[k
].CheckBox
->getHReal());
1077 if (_Lines
[k
].RightArrow
) widgetMaxH
= std::max(widgetMaxH
, _Lines
[k
].RightArrow
->getHReal());
1078 widgetMaxH
= std::max(widgetMaxH
, _Lines
[k
].ViewText
->getHReal());
1079 h
= widgetMaxH
+_GroupList
->getSpace();
1082 _ScrollBar
->moveTargetY(- eventDesc
.getWheel() * h
);
1097 // ------------------------------------------------------------------------------------------------
1098 CInterfaceElement
* CGroupSubMenu::getElement (const std::string
&id
)
1100 string sTmp
= id
.substr(0, _GroupMenu
->getId().size());
1101 if (sTmp
!= _GroupMenu
->getId()) return NULL
;
1103 string sRest
= id
.substr(_GroupMenu
->getId().size()+1, id
.size());
1105 // Iterate through the tree to see if sRest is present
1106 CGroupSubMenu
*pCurGSM
= this;
1107 while (!sRest
.empty())
1109 // Get the first element of the sRest
1110 string::size_type posid
= sRest
.find (":");
1112 if (posid
== string::npos
) // Is there just one token to test ?
1114 for (uint32 i
= 0; i
< pCurGSM
->_Lines
.size(); ++i
)
1115 if (sRest
== pCurGSM
->_Lines
[i
].Id
)
1116 return pCurGSM
->_Lines
[i
].ViewText
;
1119 else // no a lot of token left
1121 string sTok
= sRest
.substr (0, posid
);
1123 for (i
= 0; i
< pCurGSM
->_Lines
.size(); ++i
)
1124 if (sTok
== pCurGSM
->_Lines
[i
].Id
)
1126 if (i
== pCurGSM
->_Lines
.size())
1130 if (pCurGSM
->_SubMenus
[i
] == NULL
)
1133 sRest
= sRest
.substr (posid
+1);
1134 posid
= sRest
.find (":");
1135 if (posid
== string::npos
)
1138 sTok
= sRest
.substr (0, posid
);
1139 // Do we want left or right user group ?
1140 if (pCurGSM
->_Lines
[i
].UserGroupRight
)
1142 string sUGid
= pCurGSM
->_Lines
[i
].UserGroupRight
->getId();
1143 sUGid
= sUGid
.substr(sUGid
.rfind(':')+1,sUGid
.size());
1146 CInterfaceElement
*pIE
= pCurGSM
->_Lines
[i
].UserGroupRight
->getElement(id
);
1150 if (pCurGSM
->_Lines
[i
].UserGroupLeft
)
1152 string sUGid
= pCurGSM
->_Lines
[i
].UserGroupLeft
->getId();
1153 sUGid
= sUGid
.substr(sUGid
.rfind(':')+1,sUGid
.size());
1156 CInterfaceElement
*pIE
= pCurGSM
->_Lines
[i
].UserGroupLeft
->getElement(id
);
1165 pCurGSM
= pCurGSM
->_SubMenus
[i
];
1168 sRest
= sRest
.substr (posid
+1);
1174 // ------------------------------------------------------------------------------------------------
1175 void CGroupSubMenu::addSeparator(const std::string
&id
)
1177 addSeparatorAtIndex((uint
)_Lines
.size(), id
);
1180 // ------------------------------------------------------------------------------------------------
1181 void CGroupSubMenu::addSeparatorAtIndex(uint index
, const std::string
&id
)
1183 if (index
> _Lines
.size())
1185 nlwarning("Bad index");
1189 // create the real separator. It may be larger than the group list, this is why we create a separate group
1190 CInterfaceGroup
*separator
= CWidgetManager::getInstance()->getParser()->createGroupInstance("menu_separator", "", NULL
, 0);
1191 if (!separator
) return;
1192 separator
->setSerializable( false );
1193 separator
->setId(ID_MENU_SEPARATOR
);
1194 separator
->setSerializable( false );
1195 addGroup(separator
);
1196 separator
->setParent(this);
1197 // create place holder group
1198 CInterfaceGroup
*ph
= CWidgetManager::getInstance()->getParser()->createGroupInstance("menu_separator_empty", "", NULL
, 0);
1201 delGroup(separator
);
1204 _GroupList
->addChildAtIndex(ph
, index
);
1208 tmp
.ViewText
= NULL
;
1209 tmp
.CheckBox
= NULL
;
1210 tmp
.RightArrow
= NULL
;
1211 _Lines
.insert(_Lines
.begin() + index
, tmp
);
1212 _SubMenus
.insert(_SubMenus
.begin() + index
, (CGroupSubMenu
*)NULL
);
1213 _GroupMenu
->invalidateCoords();
1217 // ------------------------------------------------------------------------------------------------
1218 CViewTextMenu
* CGroupSubMenu::addLine (const std::string
&name
, const std::string
&ah
,
1219 const std::string
¶ms
, const std::string
&id
,
1220 const std::string
&cond
, const std::string
&texture
,
1221 bool checkable
/*= false*/, bool checked
/*= false*/, bool formatted
/*= false */
1226 CViewTextMenu
*pV
= new CViewTextMenu(CViewBase::TCtorParam());
1229 pV
->setCaseMode(_GroupMenu
->getCaseMode());
1232 pV
->setMultiLine (true);
1233 pV
->setMultiLineMaxWOnly (true);
1234 pV
->setTextFormatTaged (name
);
1240 pV
->setColor (_GroupMenu
->_Color
);
1241 pV
->setFontSize (_GroupMenu
->_FontSize
, _GroupMenu
->_FontSizeCoef
);
1242 pV
->setShadow (_GroupMenu
->_Shadow
);
1243 pV
->setShadowOutline (_GroupMenu
->_ShadowOutline
);
1244 pV
->setCheckable(checkable
);
1245 pV
->setChecked(checked
);
1246 pV
->setModulateGlobalColor(_GroupMenu
->_ModulateGlobalColor
);
1248 pV
->OldColor
= _GroupMenu
->_Color
;
1249 pV
->OldShadowColor
= _GroupMenu
->_ShadowColor
;
1250 pV
->OldColorOver
= _GroupMenu
->_ColorOver
;
1251 pV
->OldShadowColorOver
= _GroupMenu
->_ShadowColorOver
;
1252 pV
->OldColorGrayed
= _GroupMenu
->_ColorGrayed
;
1253 pV
->OldShadowColorGrayed
= _GroupMenu
->_ShadowColorGrayed
;
1255 _GroupList
->addChild (pV
);
1257 CViewBitmap
*checkBox
= NULL
;
1261 checkBox
= createCheckBox(checked
);
1262 checkBox
->setTexture(texture
);
1263 pV
->setCheckBox(checkBox
);
1266 CViewBitmap
*icon
= NULL
;
1267 if (!texture
.empty())
1269 if (_GroupList
->getNumChildren() == 1)
1271 icon
= createIcon(pV
, texture
);
1276 tmp
.Separator
= NULL
;
1278 tmp
.AHParams
= params
;
1280 tmp
.CheckBox
= checkBox
;
1281 tmp
.RightArrow
= icon
;
1283 tmp
.Id
= NLMISC::toString (_Lines
.size());
1287 pV
->setId(_GroupMenu
->getId()+":"+tmp
.Id
);
1289 _Lines
.push_back (tmp
);
1291 // Add an empty sub menu by default
1292 _SubMenus
.push_back (NULL
);
1294 _GroupMenu
->invalidateCoords();
1299 CViewTextMenu
* CGroupSubMenu::addLineAtIndex(uint index
, const std::string
&name
, const std::string
&ah
,
1300 const std::string
¶ms
, const std::string
&id
/*=""*/,
1301 const std::string
&cond
/*=std::string()*/, const std::string
&texture
,
1302 bool checkable
/*= false*/, bool checked
/*= false*/, bool formatted
/*= false */
1305 if (index
> _Lines
.size())
1307 nlwarning("Bad index");
1311 CViewTextMenu
*pV
= new CViewTextMenu(CViewBase::TCtorParam());
1312 pV
->setSerializable( false );
1315 pV
->setCaseMode(_GroupMenu
->getCaseMode());
1320 pV
->setMultiLine (true);
1321 pV
->setMultiLineMaxWOnly (true);
1322 pV
->setTextFormatTaged (name
);
1329 pV
->setColor (_GroupMenu
->_Color
);
1330 pV
->setFontSize (_GroupMenu
->_FontSize
, _GroupMenu
->_FontSizeCoef
);
1331 pV
->setShadow (_GroupMenu
->_Shadow
);
1332 pV
->setShadowOutline (_GroupMenu
->_ShadowOutline
);
1333 pV
->setCheckable(checkable
);
1334 pV
->setChecked(checked
);
1335 pV
->setModulateGlobalColor(_GroupMenu
->_ModulateGlobalColor
);
1337 pV
->OldColor
= _GroupMenu
->_Color
;
1338 pV
->OldShadowColor
= _GroupMenu
->_ShadowColor
;
1339 pV
->OldColorOver
= _GroupMenu
->_ColorOver
;
1340 pV
->OldShadowColorOver
= _GroupMenu
->_ShadowColorOver
;
1341 pV
->OldColorGrayed
= _GroupMenu
->_ColorGrayed
;
1342 pV
->OldShadowColorGrayed
= _GroupMenu
->_ShadowColorGrayed
;
1344 _GroupList
->addChildAtIndex(pV
, index
);
1346 CViewBitmap
*checkBox
= NULL
;
1349 checkBox
= createCheckBox(checked
);
1350 checkBox
->setTexture(texture
);
1351 pV
->setCheckBox(checkBox
);
1355 tmp
.Separator
= NULL
;
1357 tmp
.AHParams
= params
;
1359 tmp
.CheckBox
= checkBox
;
1360 tmp
.RightArrow
= NULL
;
1363 tmp
.Id
= NLMISC::toString (_Lines
.size());
1367 pV
->setId(getId()+":"+tmp
.Id
);
1369 _Lines
.insert(_Lines
.begin() + index
, tmp
);
1371 // Add an empty sub menu by default
1372 _SubMenus
.insert(_SubMenus
.begin() + index
, (CGroupSubMenu
*)NULL
);
1374 _GroupMenu
->invalidateCoords();
1380 // ------------------------------------------------------------------------------------------------
1381 void CGroupSubMenu::removeLine(uint index
)
1383 if (index
>= _Lines
.size())
1385 nlwarning("Bad index");
1388 setUserGroupRight(index
, NULL
, false); // remove user group
1389 setUserGroupLeft(index
, NULL
, false); // remove user group
1390 // remove view (right arrow & checkbox)
1391 if (_Lines
[index
].RightArrow
) delView(_Lines
[index
].RightArrow
);
1392 if (_Lines
[index
].CheckBox
) delView(_Lines
[index
].CheckBox
);
1393 if (_Lines
[index
].Separator
)
1395 // remove one separator group
1396 for(uint k
= 0; k
< _ChildrenGroups
.size(); ++k
)
1398 if (_ChildrenGroups
[k
]->getId() == ID_MENU_SEPARATOR
)
1400 delGroup(_ChildrenGroups
[k
]);
1406 _GroupList
->setDelOnRemove(index
, true);
1407 _GroupList
->delChild(index
);
1408 _Lines
.erase(_Lines
.begin() + index
);
1410 //invalidate selection
1413 if(_SubMenus
[index
])
1415 // reset it and his sons (recurs)
1416 _SubMenus
[index
]->reset();
1418 _GroupMenu
->delGroup(_SubMenus
[index
]);
1420 _SubMenus
.erase(_SubMenus
.begin() + index
);
1421 _GroupMenu
->invalidateCoords();
1424 // ------------------------------------------------------------------------------------------------
1425 void CGroupSubMenu::openSubMenu (sint32 nb
)
1428 _SubMenus
[nb
]->setActive (true);
1431 // ------------------------------------------------------------------------------------------------
1432 void CGroupSubMenu::hideSubMenus ()
1434 for (uint32 i
= 0; i
< _SubMenus
.size(); ++i
)
1435 if (_SubMenus
[i
] != NULL
)
1437 _SubMenus
[i
]->setActive (false);
1438 _SubMenus
[i
]->hideSubMenus ();
1442 // ------------------------------------------------------------------------------------------------
1443 void CGroupSubMenu::reset()
1445 uint lineCount
= (uint
)_Lines
.size();
1446 for(sint k
= lineCount
- 1; k
>= 0; --k
)
1453 // ------------------------------------------------------------------------------------------------
1454 void CGroupSubMenu::removeAllUserGroups()
1456 for(uint k
= 0; k
< _Lines
.size(); ++k
)
1458 setUserGroupRight(k
, NULL
, false);
1459 setUserGroupLeft(k
, NULL
, false);
1463 // ------------------------------------------------------------------------------------------------
1464 CInterfaceGroup
*CGroupSubMenu::getUserGroupRight(uint line
) const
1466 if (line
>= _Lines
.size())
1468 nlwarning("bad index");
1471 return _Lines
[line
].UserGroupRight
;
1474 // ------------------------------------------------------------------------------------------------
1475 CInterfaceGroup
*CGroupSubMenu::getUserGroupLeft(uint line
) const
1477 if (line
>= _Lines
.size())
1479 nlwarning("bad index");
1482 return _Lines
[line
].UserGroupLeft
;
1485 // ------------------------------------------------------------------------------------------------
1486 void CGroupSubMenu::setUserGroupRight(uint line
, CInterfaceGroup
*group
, bool ownership
)
1488 if (line
>= _Lines
.size())
1490 nlwarning("bad index");
1493 if (group
&& isChildGroup(group
))
1495 nlwarning("Group inserted twice");
1498 if (_Lines
[line
].UserGroupRight
)
1500 delGroup(_Lines
[line
].UserGroupRight
, !_Lines
[line
].UserGroupRightOwnership
);
1502 _Lines
[line
].UserGroupRight
= group
;
1503 _Lines
[line
].UserGroupRightOwnership
= ownership
;
1506 CViewBase
*prevElem
= _Lines
[line
].CheckBox
? _Lines
[line
].CheckBox
: _Lines
[line
].RightArrow
;
1509 prevElem
->setParentPosRef (Hotspot_MR
);
1510 prevElem
->setPosRef (Hotspot_ML
);
1511 prevElem
->setParentPos(group
);
1512 prevElem
->setX(MENU_WIDGET_X
);
1515 sint insertionOrder
;
1518 insertionOrder
= getInsertionOrder(prevElem
);
1522 insertionOrder
= -1;
1524 addGroup(group
, insertionOrder
);
1525 group
->setParent(this);
1526 group
->setParentPos(_GroupList
);
1527 group
->setParentPosRef (Hotspot_BR
);
1528 group
->setPosRef (Hotspot_BL
);
1532 // restore all posref..
1533 CViewBase
*prevElem
= _Lines
[line
].CheckBox
? _Lines
[line
].CheckBox
: _Lines
[line
].RightArrow
;
1536 prevElem
->setParent (this);
1537 prevElem
->setParentPos (_GroupList
);
1538 prevElem
->setParentPosRef (Hotspot_BR
);
1539 prevElem
->setPosRef (Hotspot_BL
);
1540 prevElem
->setX (MENU_WIDGET_X
);
1543 _GroupMenu
->invalidateCoords();
1547 // ------------------------------------------------------------------------------------------------
1548 void CGroupSubMenu::setUserGroupLeft(uint line
, CInterfaceGroup
*group
, bool ownership
)
1550 if (line
>= _Lines
.size())
1552 nlwarning("bad index");
1555 if (group
&& isChildGroup(group
))
1557 nlwarning("Group inserted twice");
1560 if (_Lines
[line
].UserGroupLeft
)
1562 delGroup(_Lines
[line
].UserGroupLeft
, !_Lines
[line
].UserGroupLeftOwnership
);
1564 _Lines
[line
].UserGroupLeft
= group
;
1565 _Lines
[line
].UserGroupLeftOwnership
= ownership
;
1569 group
->setParent(this);
1570 group
->setParentPos(this);
1571 group
->setParentPosRef (Hotspot_BL
);
1572 group
->setPosRef (Hotspot_BL
);
1573 group
->setX(LEFT_MENU_WIDGET_X
);
1576 _GroupMenu
->invalidateCoords();
1580 // ------------------------------------------------------------------------------------------------
1581 CGroupSubMenu
*CGroupSubMenu::cloneMenu(CGroupSubMenu
*appendToMenu
, CGroupMenu
*newFather
, CInterfaceGroup
*initGroup
/* = NULL */) const
1583 CGroupSubMenu
*copyMenu
= appendToMenu
? appendToMenu
: new CGroupSubMenu(CViewText::TCtorParam());
1584 uint startSize
= (uint
)copyMenu
->_Lines
.size();
1585 copyMenu
->setSerializable( false );
1586 copyMenu
->_GroupMenu
= newFather
;
1587 copyMenu
->initOptions(initGroup
);
1588 copyMenu
->_Lines
.reserve(_Lines
.size() + startSize
);
1589 copyMenu
->_SubMenus
.reserve(_SubMenus
.size() + startSize
);
1591 for(uint k
= 0; k
< _Lines
.size(); ++k
)
1593 if (_Lines
[k
].Separator
)
1595 copyMenu
->addSeparator(_Lines
[k
].Id
);
1599 std::string texture
= std::string();
1600 if(_Lines
[k
].ViewText
->getCheckBox())
1602 texture
= _Lines
[k
].ViewText
->getCheckBox()->getTexture();
1604 CViewTextMenu
*pV
= NULL
;
1605 pV
= copyMenu
->addLine (_Lines
[k
].ViewText
->getText(), _Lines
[k
].AHName
, _Lines
[k
].AHParams
, _Lines
[k
].Id
, _Lines
[k
].Cond
,
1606 texture
, _Lines
[k
].ViewText
->getCheckable(), _Lines
[k
].ViewText
->getChecked(), _Lines
[k
].ViewText
->getFormatted ());
1607 copyMenu
->_Lines
[k
].Selectable
= _Lines
[k
].Selectable
;
1608 pV
->setGrayed(_Lines
[k
].ViewText
->getGrayed());
1611 // sub menu copy if there's one
1612 if (_SubMenus
[k
] != NULL
)
1615 if (copyMenu
->_Lines
.back().CheckBox
)
1617 copyMenu
->_Lines
.back().RightArrow
= copyMenu
->createRightArrow(copyMenu
->_Lines
.back().CheckBox
, true);
1621 copyMenu
->_Lines
.back().RightArrow
= copyMenu
->createRightArrow(copyMenu
->_GroupList
, false);
1625 // and create the sub menu
1626 copyMenu
->_SubMenus
[k
+ startSize
] = _SubMenus
[k
]->cloneMenu(NULL
, newFather
, copyMenu
);
1631 newFather
->addGroup(copyMenu
);
1636 // ------------------------------------------------------------------------------------------------
1637 void CGroupSubMenu::setActive(bool state
)
1640 for(uint k
= 0; k
< _Lines
.size(); ++k
)
1642 if (!_Lines
[k
].Cond
.empty())
1644 CInterfaceExprValue result
;
1645 if (CInterfaceExpr::eval(_Lines
[k
].Cond
, result
))
1647 if (result
.toBool())
1649 _Lines
[k
].ViewText
->setGrayed(!result
.getBool());
1655 if(_ScrollBar
&& _GroupList
)
1656 _ScrollBar
->setTrackPos(_GroupList
->getHReal());
1658 CGroupFrame::setActive(state
);
1661 // ------------------------------------------------------------------------------------------------
1662 const std::string
CGroupSubMenu::getActionHandler(uint lineIndex
) const
1664 if (lineIndex
> _Lines
.size())
1666 nlwarning("Bad index");
1669 return _Lines
[lineIndex
].AHName
;
1672 // ------------------------------------------------------------------------------------------------
1673 const std::string
CGroupSubMenu::getActionHandlerParam(uint lineIndex
) const
1675 if (lineIndex
> _Lines
.size())
1677 nlwarning("Bad index");
1680 return _Lines
[lineIndex
].AHParams
;
1683 // ------------------------------------------------------------------------------------------------
1684 void CGroupSubMenu::setActionHandler(uint lineIndex
, const std::string
&ah
)
1686 if (lineIndex
> _Lines
.size())
1688 nlwarning("Bad index");
1691 _Lines
[lineIndex
].AHName
= ah
;
1694 // ------------------------------------------------------------------------------------------------
1695 void CGroupSubMenu::setActionHandlerParam(uint lineIndex
, const std::string
¶ms
)
1697 if (lineIndex
> _Lines
.size())
1699 nlwarning("Bad index");
1702 _Lines
[lineIndex
].AHParams
= params
;
1705 // ------------------------------------------------------------------------------------------------
1706 void CGroupSubMenu::setRightClickHandler(uint lineIndex
, const std::string
&ah
)
1708 if (lineIndex
> _Lines
.size())
1710 nlwarning("Bad index");
1713 _Lines
[lineIndex
].AHRightClick
= ah
;
1716 // ------------------------------------------------------------------------------------------------
1717 void CGroupSubMenu::setRightClickHandlerParam(uint lineIndex
, const std::string
¶ms
)
1719 if (lineIndex
> _Lines
.size())
1721 nlwarning("Bad index");
1724 _Lines
[lineIndex
].AHRightClickParams
= params
;
1727 // ------------------------------------------------------------------------------------------------
1728 void CGroupSubMenu::setSelectable(uint lineIndex
, bool selectable
)
1730 if (lineIndex
> _Lines
.size())
1732 nlwarning("Bad index");
1735 _Lines
[lineIndex
].Selectable
= selectable
;
1738 // ------------------------------------------------------------------------------------------------
1739 bool CGroupSubMenu::getSelectable(uint lineIndex
) const
1741 if (lineIndex
> _Lines
.size())
1743 nlwarning("Bad index");
1746 return _Lines
[lineIndex
].Selectable
;
1749 // ------------------------------------------------------------------------------------------------
1750 void CGroupSubMenu::setMaxVisibleLine(sint32 mvl
)
1752 _MaxVisibleLine
= mvl
;
1755 // ------------------------------------------------------------------------------------------------
1756 const std::string
&CGroupSubMenu::getLineId(uint index
)
1758 if(index
>=_Lines
.size())
1760 static string nullString
;
1764 return _Lines
[index
].Id
;
1767 // ------------------------------------------------------------------------------------------------
1768 void CGroupSubMenu::setGrayedLine(uint line
, bool g
)
1770 if(line
<_Lines
.size())
1772 if (_Lines
[line
].ViewText
)
1774 _Lines
[line
].ViewText
->setGrayed(g
);
1779 // ------------------------------------------------------------------------------------------------
1780 void CGroupSubMenu::setHiddenLine(uint line
, bool h
)
1782 if(line
<_Lines
.size())
1784 if (_Lines
[line
].ViewText
)
1786 _Lines
[line
].ViewText
->setActive(!h
);
1791 // ------------------------------------------------------------------------------------------------
1792 int CGroupSubMenu::luaGetNumLine(CLuaState
&ls
)
1794 CLuaIHM::checkArgCount(ls
, "getNumLine", 0);
1795 ls
.push(getNumLine());
1799 // ------------------------------------------------------------------------------------------------
1800 int CGroupSubMenu::luaGetSubMenu(CLuaState
&ls
)
1802 const char *funcName
= "getSubMenu";
1803 CLuaIHM::checkArgCount(ls
, funcName
, 1);
1804 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
1805 CLuaIHM::pushUIOnStack(ls
, getSubMenu((uint
) ls
.toInteger(1)));
1809 // ------------------------------------------------------------------------------------------------
1810 int CGroupSubMenu::luaAddSubMenu(CLuaState
&ls
)
1812 const char *funcName
= "addSubMenu";
1813 CLuaIHM::checkArgCount(ls
, funcName
, 1);
1814 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
1815 setSubMenu((uint
) ls
.toInteger(1), new CGroupSubMenu(CViewText::TCtorParam()));
1816 CLuaIHM::pushUIOnStack(ls
, getSubMenu((uint
) ls
.toInteger(1)));
1820 // ------------------------------------------------------------------------------------------------
1821 int CGroupSubMenu::luaGetLineId(CLuaState
&ls
)
1823 const char *funcName
= "getLineId";
1824 CLuaIHM::checkArgCount(ls
, funcName
, 1);
1825 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
1826 #ifdef RYZOM_LUA_UCSTRING
1827 ucstring id
= getLineId((uint
) ls
.toInteger(1)); // Compatibility
1828 CLuaIHM::push(ls
, id
);
1830 std::string id
= getLineId((uint
)ls
.toInteger(1));
1836 // ------------------------------------------------------------------------------------------------
1837 int CGroupSubMenu::luaGetLineFromId(CLuaState
&ls
)
1839 const char *funcName
= "getLineFromId";
1840 CLuaIHM::checkArgCount(ls
, funcName
, 1);
1841 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TSTRING
);
1842 ls
.push(getLineFromId(ls
.toString(1)));
1846 // ------------------------------------------------------------------------------------------------
1847 int CGroupSubMenu::luaIsSeparator(CLuaState
&ls
)
1849 const char *funcName
= "isSeparator";
1850 CLuaIHM::checkArgCount(ls
, funcName
, 1);
1851 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
1852 ls
.push(isSeparator((uint
) ls
.toInteger(1)));
1856 // ------------------------------------------------------------------------------------------------
1857 int CGroupSubMenu::luaAddLine(CLuaState
&ls
)
1859 const char *funcName
= "addLine";
1860 CLuaIHM::checkArgCount(ls
, funcName
, 4);
1861 #ifdef RYZOM_LUA_UCSTRING
1862 CLuaIHM::checkArgTypeUCString(ls
, funcName
, 1);
1864 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TSTRING
);
1866 CLuaIHM::checkArgType(ls
, funcName
, 2, LUA_TSTRING
);
1867 CLuaIHM::checkArgType(ls
, funcName
, 3, LUA_TSTRING
);
1868 CLuaIHM::checkArgType(ls
, funcName
, 4, LUA_TSTRING
);
1869 #ifdef RYZOM_LUA_UCSTRING
1870 ucstring arg1
; // Compatibility
1871 nlverify(CLuaIHM::getUCStringOnStack(ls
, 1, arg1
));
1872 addLine(arg1
.toUtf8(), ls
.toString(2), ls
.toString(3), ls
.toString(4));
1874 addLine(ls
.toString(1), ls
.toString(2), ls
.toString(3), ls
.toString(4));
1879 // ------------------------------------------------------------------------------------------------
1880 int CGroupSubMenu::luaAddIconLine(CLuaState
&ls
)
1882 const char *funcName
= "addIconLine";
1883 CLuaIHM::checkArgCount(ls
, funcName
, 5);
1884 #ifdef RYZOM_LUA_UCSTRING
1885 CLuaIHM::checkArgTypeUCString(ls
, funcName
, 1);
1887 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TSTRING
);
1889 CLuaIHM::checkArgType(ls
, funcName
, 2, LUA_TSTRING
);
1890 CLuaIHM::checkArgType(ls
, funcName
, 3, LUA_TSTRING
);
1891 CLuaIHM::checkArgType(ls
, funcName
, 4, LUA_TSTRING
);
1892 CLuaIHM::checkArgType(ls
, funcName
, 5, LUA_TSTRING
);
1893 #ifdef RYZOM_LUA_UCSTRING
1894 ucstring arg1
; // Compatibility
1895 nlverify(CLuaIHM::getUCStringOnStack(ls
, 1, arg1
));
1896 addLine(arg1
.toUtf8(), ls
.toString(2), ls
.toString(3), ls
.toString(4), string(), ls
.toString(5));
1898 addLine(ls
.toString(1), ls
.toString(2), ls
.toString(3), ls
.toString(4), string(), ls
.toString(5));
1903 // ------------------------------------------------------------------------------------------------
1904 int CGroupSubMenu::luaAddLineAtIndex(CLuaState
&ls
)
1906 const char *funcName
= "addLineAtIndex";
1907 CLuaIHM::checkArgCount(ls
, funcName
, 5);
1908 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
1909 #ifdef RYZOM_LUA_UCSTRING
1910 CLuaIHM::checkArgTypeUCString(ls
, funcName
, 2);
1912 CLuaIHM::checkArgType(ls
, funcName
, 2, LUA_TSTRING
);
1914 CLuaIHM::checkArgType(ls
, funcName
, 3, LUA_TSTRING
);
1915 CLuaIHM::checkArgType(ls
, funcName
, 4, LUA_TSTRING
);
1916 CLuaIHM::checkArgType(ls
, funcName
, 5, LUA_TSTRING
);
1917 #ifdef RYZOM_LUA_UCSTRING
1919 nlverify(CLuaIHM::getUCStringOnStack(ls
, 2, arg2
));
1920 addLineAtIndex((uint
) ls
.toInteger(1), arg2
.toUtf8(), ls
.toString(3), ls
.toString(4), ls
.toString(5));
1922 addLineAtIndex((uint
)ls
.toInteger(1), ls
.toString(2), ls
.toString(3), ls
.toString(4), ls
.toString(5));
1927 // ------------------------------------------------------------------------------------------------
1928 int CGroupSubMenu::luaAddSeparator(CLuaState
&ls
)
1930 CLuaIHM::checkArgCount(ls
, "addSeparator", 0);
1935 // ------------------------------------------------------------------------------------------------
1936 int CGroupSubMenu::luaAddSeparatorAtIndex(CLuaState
&ls
)
1938 const char *funcName
= "addSeparatorAtIndex";
1939 CLuaIHM::checkArgCount(ls
, funcName
, 1);
1940 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
1941 addSeparatorAtIndex((uint
) ls
.toInteger(1));
1945 // ------------------------------------------------------------------------------------------------
1946 int CGroupSubMenu::luaRemoveLine(CLuaState
&ls
)
1948 const char *funcName
= "removeLine";
1949 CLuaIHM::checkArgCount(ls
, funcName
, 1);
1950 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
1951 removeLine((uint
) ls
.toInteger(1));
1955 // ------------------------------------------------------------------------------------------------
1956 int CGroupSubMenu::luaSetUserGroupRight(CLuaState
&ls
)
1958 const char *funcName
= "setUserGroupRight";
1959 CLuaIHM::checkArgCount(ls
, funcName
, 2);
1960 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
1961 if (!(CLuaIHM::isUIOnStack(ls
, 2) || ls
.isNil(2)))
1963 CLuaIHM::fails(ls
, "%s : Group required as argument 2", funcName
);
1965 CInterfaceElement
*el
= CLuaIHM::getUIOnStack(ls
, 2);
1966 CInterfaceGroup
*group
= dynamic_cast<CInterfaceGroup
*>(el
);
1969 CLuaIHM::fails(ls
, "%s : Group required as argument 2", funcName
);
1971 setUserGroupRight((uint
) ls
.toInteger(1), group
, true);
1975 // ------------------------------------------------------------------------------------------------
1976 int CGroupSubMenu::luaSetUserGroupLeft(CLuaState
&ls
)
1978 const char *funcName
= "setUserGroupLeft";
1979 CLuaIHM::checkArgCount(ls
, funcName
, 2);
1980 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
1981 if (!(CLuaIHM::isUIOnStack(ls
, 2) || ls
.isNil(2)))
1983 CLuaIHM::fails(ls
, "%s : Group required as argument 2", funcName
);
1985 CInterfaceElement
*el
= CLuaIHM::getUIOnStack(ls
, 2);
1986 CInterfaceGroup
*group
= dynamic_cast<CInterfaceGroup
*>(el
);
1989 CLuaIHM::fails(ls
, "%s : Group required as argument 2", funcName
);
1991 setUserGroupLeft((uint
) ls
.toInteger(1), group
, true);
1996 // ------------------------------------------------------------------------------------------------
1997 int CGroupSubMenu::luaGetUserGroupRight(CLuaState
&ls
)
1999 const char *funcName
= "getUserGroupRight";
2000 CLuaIHM::checkArgCount(ls
, funcName
, 1);
2001 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
2002 CLuaIHM::pushUIOnStack(ls
, getUserGroupRight((uint
) ls
.toInteger(1)));
2007 // ------------------------------------------------------------------------------------------------
2008 int CGroupSubMenu::luaGetUserGroupLeft(CLuaState
&ls
)
2010 const char *funcName
= "getUserGroupLeft";
2011 CLuaIHM::checkArgCount(ls
, funcName
, 1);
2012 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
2013 CInterfaceElement
*pIE
= getUserGroupLeft((uint
) ls
.toInteger(1));
2016 CLuaIHM::pushUIOnStack(ls
, pIE
);
2022 // ------------------------------------------------------------------------------------------------
2023 int CGroupSubMenu::luaSetMaxVisibleLine(CLuaState
&ls
)
2025 const char *funcName
= "setMaxVisibleLine";
2026 CLuaIHM::checkArgCount(ls
, funcName
, 1);
2027 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
2028 setMaxVisibleLine((uint
) ls
.toInteger(1));
2032 // ------------------------------------------------------------------------------------------------
2033 int CGroupSubMenu::luaReset(CLuaState
&ls
)
2035 const char *funcName
= "reset";
2036 CLuaIHM::checkArgCount(ls
, funcName
, 0);
2042 // ------------------------------------------------------------------------------------------------
2044 // ------------------------------------------------------------------------------------------------
2046 NLMISC_REGISTER_OBJECT(CViewBase
, CGroupMenu
, std::string
, "menu");
2048 // ------------------------------------------------------------------------------------------------
2049 CGroupMenu::CGroupMenu(const TCtorParam
¶m
)
2053 _Color
= CRGBA::White
;
2054 _ColorOver
= CRGBA::White
;
2055 _ColorGrayed
= CRGBA(128, 128, 128, 255);
2056 _ShadowColor
= CRGBA::Black
;
2057 _ShadowColorOver
= CRGBA::Black
;
2058 _ShadowColorGrayed
= CRGBA::Black
;
2059 _HighLightOver
.set(128, 0, 0, 255);
2061 _FontSizeCoef
= true;
2063 _ShadowOutline
= false;
2064 _ResizeFromChildH
= _ResizeFromChildW
= true;
2065 _DisplayFrame
= false;
2068 _CaseMode
= CaseUpper
;
2072 // ------------------------------------------------------------------------------------------------
2073 CGroupMenu::~CGroupMenu()
2077 std::string
CGroupMenu::getProperty( const std::string
&name
) const
2079 if( name
== "extends" )
2084 if( name
== "case_mode" )
2086 uint32 cm
= _CaseMode
;
2087 return toString( cm
);
2090 if( name
== "color" )
2092 return toString( _Color
);
2095 if( name
== "shadow_color" )
2097 return toString( _ShadowColor
);
2100 if( name
== "color_over" )
2102 return toString( _ColorOver
);
2105 if( name
== "shadow_color_over" )
2107 return toString( _ShadowColorOver
);
2110 if( name
== "highlight_over" )
2112 return toString( _HighLightOver
);
2115 if( name
== "color_grayed" )
2117 return toString( _ColorGrayed
);
2120 if( name
== "shadow_color_grayed" )
2122 return toString( _ShadowColorGrayed
);
2125 if( name
== "space" )
2127 return toString( _Space
);
2130 if( name
== "fontsize" )
2132 return toString( _FontSize
);
2135 if( name
== "shadow" )
2137 return toString( _Shadow
);
2140 if( name
== "shadow_outline" )
2142 return toString( _ShadowOutline
);
2145 if( name
== "formatted" )
2147 return toString( _Formatted
);
2150 if( name
== "max_visible_line" )
2152 if( _RootMenu
== NULL
)
2155 return toString( _RootMenu
->getMaxVisibleLine() );
2158 return CGroupModal::getProperty( name
);
2161 void CGroupMenu::setProperty( const std::string
&name
, const std::string
&value
)
2163 if( name
== "extends" )
2169 if( name
== "case_mode" )
2172 if( fromString( value
, cm
) )
2173 _CaseMode
= (TCaseMode
)cm
;
2177 if( name
== "color" )
2180 if( fromString( value
, c
) )
2185 if( name
== "shadow_color" )
2188 if( fromString( value
, c
) )
2193 if( name
== "color_over" )
2196 if( fromString( value
, c
) )
2201 if( name
== "shadow_color_over" )
2204 if( fromString( value
, c
) )
2205 _ShadowColorOver
= c
;
2209 if( name
== "highlight_over" )
2212 if( fromString( value
, c
) )
2217 if( name
== "color_grayed" )
2220 if( fromString( value
, c
) )
2225 if( name
== "shadow_color_grayed" )
2228 if( fromString( value
, c
) )
2229 _ShadowColorGrayed
= c
;
2233 if( name
== "space" )
2236 if( fromString( value
, i
) )
2241 if( name
== "fontsize" )
2244 if( fromString( value
, i
) )
2249 if( name
== "shadow" )
2252 if( fromString( value
, b
) )
2257 if( name
== "shadow_outline" )
2260 if( fromString( value
, b
) )
2265 if( name
== "formatted" )
2268 if( fromString( value
, b
) )
2273 if( name
== "max_visible_line" )
2275 if( _RootMenu
!= NULL
)
2278 if( fromString( value
, i
) )
2279 _RootMenu
->setMaxVisibleLine( i
);
2284 CGroupModal::setProperty( name
, value
);
2288 xmlNodePtr
CGroupMenu::serialize( xmlNodePtr parentNode
, const char *type
) const
2290 xmlNodePtr node
= CGroupModal::serialize( parentNode
, type
);
2294 xmlSetProp( node
, BAD_CAST
"type", BAD_CAST
"menu" );
2295 xmlSetProp( node
, BAD_CAST
"extends", BAD_CAST _Extends
.c_str() );
2296 xmlSetProp( node
, BAD_CAST
"case_mode", BAD_CAST
toString( uint32( _CaseMode
) ).c_str() );
2297 xmlSetProp( node
, BAD_CAST
"color", BAD_CAST
toString( _Color
).c_str() );
2298 xmlSetProp( node
, BAD_CAST
"shadow_color", BAD_CAST
toString( _ShadowColor
).c_str() );
2299 xmlSetProp( node
, BAD_CAST
"color_over", BAD_CAST
toString( _ColorOver
).c_str() );
2300 xmlSetProp( node
, BAD_CAST
"shadow_color_over", BAD_CAST
toString( _ShadowColorOver
).c_str() );
2301 xmlSetProp( node
, BAD_CAST
"highlight_over", BAD_CAST
toString( _HighLightOver
).c_str() );
2302 xmlSetProp( node
, BAD_CAST
"color_grayed", BAD_CAST
toString( _ColorGrayed
).c_str() );
2303 xmlSetProp( node
, BAD_CAST
"shadow_color_grayed", BAD_CAST
toString( _ShadowColorGrayed
).c_str() );
2304 xmlSetProp( node
, BAD_CAST
"space", BAD_CAST
toString( _Space
).c_str() );
2305 xmlSetProp( node
, BAD_CAST
"fontsize", BAD_CAST
toString( _FontSize
).c_str() );
2306 xmlSetProp( node
, BAD_CAST
"shadow", BAD_CAST
toString( _Shadow
).c_str() );
2307 xmlSetProp( node
, BAD_CAST
"shadow_outline", BAD_CAST
toString( _ShadowOutline
).c_str() );
2308 xmlSetProp( node
, BAD_CAST
"formatted", BAD_CAST
toString( _Formatted
).c_str() );
2310 if( _RootMenu
== NULL
)
2311 xmlSetProp( node
, BAD_CAST
"max_visible_line", BAD_CAST
"0" );
2313 xmlSetProp( node
, BAD_CAST
"max_visible_line",
2314 BAD_CAST
toString( _RootMenu
->getMaxVisibleLine() ).c_str() );
2319 // ------------------------------------------------------------------------------------------------
2320 bool CGroupMenu::parse (xmlNodePtr in
, CInterfaceGroup
*parentGroup
)
2326 // override source menu options (if there's one)
2327 if (!CGroupModal::parse(in
, parentGroup
))
2331 // see if this menu extends another menu
2332 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"extends" );
2333 CGroupSubMenu
*gmExtended
= NULL
;
2337 _Extends
= std::string( (const char*)prop
);
2339 CGroupMenu
*gm
= dynamic_cast<CGroupMenu
*>(CWidgetManager::getInstance()->getElementFromId(prop
.str()));
2342 gm
= dynamic_cast<CGroupMenu
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:" + std::string((const char*)prop
)));
2346 gmExtended
= gm
->_RootMenu
;
2347 // copy group frame parameters
2348 CGroupFrame::copyOptionFrom(*gm
);
2350 _Color
= gm
->_Color
;
2351 _ShadowColor
= gm
->_ShadowColor
;
2352 _Shadow
= gm
->_Shadow
;
2353 _ShadowOutline
= gm
->_ShadowOutline
;
2354 _FontSize
= gm
->_FontSize
;
2355 _ColorOver
= gm
->_ColorOver
;
2356 _ShadowColorOver
= gm
->_ShadowColorOver
;
2357 _HighLightOver
= gm
->_HighLightOver
;
2358 _ColorGrayed
= gm
->_ColorGrayed
;
2359 _ShadowColorGrayed
= gm
->_ShadowColorGrayed
;
2360 _Priority
= gm
->_Priority
;
2361 _ModulateGlobalColor
= gm
->_ModulateGlobalColor
;
2362 _Space
= gm
->_Space
;
2363 _CaseMode
= gm
->_CaseMode
;
2367 nlwarning("Can't get menu %s or bad type", (const char *) prop
);
2372 // Override the modal behaviour because of sub menus
2373 ExitClickOut
= true;
2376 ExitKeyPushed
= true;
2377 _ResizeFromChildH
= _ResizeFromChildW
= true;
2378 _DisplayFrame
= false;
2383 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"color" );
2384 if (prop
) _Color
= convertColor(prop
);
2386 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"case_mode" );
2390 fromString((const char*)prop
, caseMode
);
2391 _CaseMode
= (TCaseMode
)caseMode
;
2394 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"shadow_color" );
2395 if (prop
) _ShadowColor
= convertColor(prop
);
2397 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"color_over" );
2398 if (prop
) _ColorOver
= convertColor(prop
);
2400 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"shadow_color_over" );
2401 if (prop
) _ShadowColorOver
= convertColor(prop
);
2403 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"highlight_over" );
2404 if (prop
) _HighLightOver
= convertColor(prop
);
2406 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"color_grayed" );
2407 if (prop
) _ColorGrayed
= convertColor(prop
);
2409 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"shadow_color_grayed" );
2410 if (prop
) _ShadowColorGrayed
= convertColor(prop
);
2412 prop
= (char*) xmlGetProp (in
, (xmlChar
*)"space");
2413 if (prop
) fromString((const char*)prop
, _Space
);
2416 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"fontsize" );
2417 if (prop
) fromString((const char*)prop
, _FontSize
);
2419 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"shadow" );
2421 _Shadow
= convertBool(prop
);
2423 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"shadow_outline" );
2425 _ShadowOutline
= convertBool(prop
);
2427 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"formatted" );
2429 _Formatted
= convertBool(prop
);
2435 if (_RootMenu
!= NULL
) delete _RootMenu
;
2436 _RootMenu
= new CGroupSubMenu(CViewText::TCtorParam());
2437 _RootMenu
->setId( getId() + ":header" );
2438 _RootMenu
->setSerializable( false );
2439 _RootMenu
->_GroupMenu
= this;
2440 _RootMenu
->parse (cur
);
2442 prop
= (char*) xmlGetProp( in
, (xmlChar
*)"max_visible_line" );
2445 sint32 maxVisibleLine
;
2446 fromString((const char*)prop
, maxVisibleLine
);
2447 _RootMenu
->setMaxVisibleLine(maxVisibleLine
);
2452 gmExtended
->cloneMenu(_RootMenu
, this);
2457 // ------------------------------------------------------------------------------------------------
2458 void CGroupMenu::recurseDraw(CGroupSubMenu
*pSubMenu
)
2462 // const vector<CInterfaceGroup*> &rGroups = pSubMenu->getGroups();
2464 for (uint32 i
= 0; i
< pSubMenu
->getNumLines(); i
++)
2466 CGroupSubMenu
*pGSM
= pSubMenu
->getSubMenu(i
);
2470 CViewRenderer::getInstance()->flush();
2475 // ------------------------------------------------------------------------------------------------
2476 void CGroupMenu::draw ()
2478 if (!_Active
) return;
2481 //CViewRenderer &rVR = *CViewRenderer::getInstance();
2482 //rVR.drawRotFlipBitmap _RenderLayer, (_XReal, _YReal, _WReal, _HReal, 0, false, rVR.getBlankTextureId(), CRGBA(255, 0, 0, 255) );
2484 _RootMenu
->_Active
= true;
2486 if (SpawnOnMousePos
)
2487 recurseDraw(_RootMenu
);
2489 CGroupModal::draw();
2492 // ------------------------------------------------------------------------------------------------
2493 bool CGroupMenu::handleEvent (const NLGUI::CEventDescriptor
&event
)
2497 return CGroupModal::handleEvent (event
);
2500 // ------------------------------------------------------------------------------------------------
2501 CInterfaceElement
* CGroupMenu::getElement (const std::string
&id
)
2503 if (id
== getId()) return this;
2504 CInterfaceElement
*pIE
= _RootMenu
->getElement(id
);
2507 return CGroupModal::getElement(id
);
2510 // ------------------------------------------------------------------------------------------------
2511 void CGroupMenu::setActive (bool state
)
2513 if (SpawnOnMousePos
)
2515 CViewRenderer
&rVR
= *CViewRenderer::getInstance();
2517 rVR
.getScreenSize(w
,h
);
2522 _ResizeFromChildH
= _ResizeFromChildW
= false;
2523 _RootMenu
->_PosRef
= Hotspot_TL
;
2524 _RootMenu
->_ParentPosRef
= Hotspot_BL
;
2527 CGroupFrame::setActive (state
);
2529 // must recompute now the pos of the menu
2531 for (i
= 0; i
< _ChildrenGroups
.size(); ++i
)
2533 _ChildrenGroups
[i
]->setActive (true);
2536 CGroupModal::updateCoords();
2539 _RootMenu
->hideSubMenus();
2542 // ------------------------------------------------------------------------------------------------
2543 bool CGroupSubMenu::isSeparator(uint i
) const
2545 if (i
>= _SubMenus
.size())
2547 nlassert("bad index");
2550 return _Lines
[i
].Separator
!= NULL
;
2552 // ------------------------------------------------------------------------------------------------
2553 bool CGroupMenu::isWindowUnder (sint32 x
, sint32 y
)
2555 for (uint32 i
= 0; i
< _ChildrenGroups
.size(); ++i
)
2556 if (_ChildrenGroups
[i
]->getActive ())
2557 if (_ChildrenGroups
[i
]->isWindowUnder(x
, y
))
2563 // ------------------------------------------------------------------------------------------------
2564 void CGroupMenu::addLine(const std::string
&name
, const std::string
&ah
, const std::string
¶ms
,
2565 const std::string
&id
/* = std::string()*/,
2566 const std::string
&cond
/*= std::string()*/, const std::string
&texture
,
2567 bool checkable
/*= false*/, bool checked
/*= false*/
2570 if (_RootMenu
== NULL
)
2572 _RootMenu
= new CGroupSubMenu(CViewText::TCtorParam());
2573 _RootMenu
->_GroupMenu
= this;
2574 _RootMenu
->setSerializable( false );
2575 addGroup (_RootMenu
);
2577 _RootMenu
->addLine (name
, ah
, params
, id
, cond
, texture
, checkable
, checked
, _Formatted
);
2579 // ------------------------------------------------------------------------------------------------
2580 void CGroupMenu::addLineAtIndex(uint index
, const std::string
&name
, const std::string
&ah
,
2581 const std::string
¶ms
, const std::string
&id
/*=std::string()*/,
2582 const std::string
&cond
/*=std::string()*/, const std::string
&texture
,
2583 bool checkable
/*=false*/, bool checked
/*=false*/)
2585 if (_RootMenu
== NULL
)
2587 _RootMenu
= new CGroupSubMenu(CViewText::TCtorParam());
2588 _RootMenu
->_GroupMenu
= this;
2589 _RootMenu
->setSerializable( false );
2590 addGroup (_RootMenu
);
2592 _RootMenu
->addLineAtIndex(index
, name
, ah
, params
, id
, cond
, texture
, checkable
, checked
, _Formatted
);
2596 // ------------------------------------------------------------------------------------------------
2597 void CGroupMenu::reset ()
2606 // ------------------------------------------------------------------------------------------------
2607 void CGroupMenu::setMinW(sint32 minW
)
2611 _RootMenu
->_GroupList
->setMinW(minW
-_RootMenu
->getResizeFromChildWMargin());
2612 _RootMenu
->_GroupList
->setW(minW
-_RootMenu
->getResizeFromChildWMargin());
2613 _RootMenu
->setW(minW
-_RootMenu
->getResizeFromChildWMargin());
2617 // ------------------------------------------------------------------------------------------------
2618 void CGroupMenu::setMinH(sint32 minH
)
2622 _RootMenu
->_GroupList
->setMinH(minH
-_RootMenu
->getResizeFromChildHMargin());
2623 _RootMenu
->_GroupList
->setH(minH
-_RootMenu
->getResizeFromChildHMargin());
2624 _RootMenu
->setH(minH
-_RootMenu
->getResizeFromChildHMargin());
2628 // ------------------------------------------------------------------------------------------------
2629 void CGroupMenu::setGrayedLine(uint line
, bool g
)
2633 _RootMenu
->setGrayedLine(line
, g
);
2637 // ------------------------------------------------------------------------------------------------
2638 void CGroupMenu::setFontSize(uint fontSize
, bool coef
)
2640 _FontSize
= fontSize
;
2641 _FontSizeCoef
= coef
;
2644 // ------------------------------------------------------------------------------------------------
2645 uint
CGroupMenu::getNumLine() const
2647 return _RootMenu
? _RootMenu
->getNumLine() : 0;
2650 // ------------------------------------------------------------------------------------------------
2651 void CGroupMenu::deleteLine(uint index
)
2653 if (index
> getNumLine())
2655 nlwarning("bad index");
2658 _RootMenu
->removeLine(index
);
2661 // ------------------------------------------------------------------------------------------------
2662 const std::string
CGroupMenu::getActionHandler(uint lineIndex
) const
2664 return _RootMenu
? _RootMenu
->getActionHandler(lineIndex
) : "";
2667 // ------------------------------------------------------------------------------------------------
2668 const std::string
CGroupMenu::getActionHandlerParam(uint lineIndex
) const
2670 return _RootMenu
? _RootMenu
->getActionHandlerParam(lineIndex
) : "";
2673 // ------------------------------------------------------------------------------------------------
2674 void CGroupMenu::setActionHandler(uint lineIndex
, const std::string
&ah
)
2677 _RootMenu
->setActionHandler(lineIndex
, ah
);
2680 // ------------------------------------------------------------------------------------------------
2681 void CGroupMenu::setActionHandlerParam(uint lineIndex
, const std::string
¶ms
)
2684 _RootMenu
->setActionHandlerParam(lineIndex
, params
);
2687 // ------------------------------------------------------------------------------------------------
2688 void CGroupMenu::setRightClickHandler(uint lineIndex
, const std::string
&ah
)
2691 _RootMenu
->setRightClickHandler(lineIndex
, ah
);
2694 // ------------------------------------------------------------------------------------------------
2695 void CGroupMenu::setRightClickHandlerParam(uint lineIndex
, const std::string
¶ms
)
2698 _RootMenu
->setRightClickHandlerParam(lineIndex
, params
);
2701 // ------------------------------------------------------------------------------------------------
2702 void CGroupMenu::setUserGroupRight(uint line
, CInterfaceGroup
*gr
, bool ownerShip
/*=true*/)
2706 _RootMenu
->setUserGroupRight(line
, gr
, ownerShip
);
2710 // ------------------------------------------------------------------------------------------------
2711 void CGroupMenu::setUserGroupLeft(uint line
, CInterfaceGroup
*gr
, bool ownerShip
/*=true*/)
2715 _RootMenu
->setUserGroupLeft(line
, gr
, ownerShip
);
2719 // ------------------------------------------------------------------------------------------------
2720 int CGroupMenu::luaGetRootMenu(CLuaState
&ls
)
2722 CLuaIHM::checkArgCount(ls
, "getRootMenu", 0);
2723 CLuaIHM::pushUIOnStack(ls
, getRootMenu());
2727 // ------------------------------------------------------------------------------------------------
2728 int CGroupMenu::luaSetMinW(CLuaState
&ls
)
2730 const char *funcName
= "setMinW";
2731 CLuaIHM::checkArgCount(ls
, funcName
, 1);
2732 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TNUMBER
);
2733 setMinW((sint32
) ls
.toInteger(1));