Linux multi-monitor fullscreen support
[ryzomcore.git] / nel / src / gui / group_container.cpp
blob916e95b13c90c60af1026775c7e5f0d3cbce0542
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2020 Winch Gate Property Limited
3 //
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>
7 //
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 "stdpch.h"
23 #include "nel/gui/group_container.h"
24 #include "nel/gui/interface_options.h"
25 #include "nel/misc/xml_auto_ptr.h"
26 #include "nel/gui/action_handler.h"
27 #include "nel/gui/group_editbox.h"
28 #include "nel/gui/view_text_formated.h"
29 #include "nel/gui/view_text_id.h"
30 #include "nel/gui/lua_ihm.h"
31 #include "nel/gui/group_list.h"
32 #include "nel/gui/ctrl_button.h"
33 #include "nel/gui/ctrl_scroll.h"
34 #include "nel/gui/view_text.h"
35 #include "nel/gui/view_bitmap.h"
36 #include "nel/gui/view_renderer.h"
37 #include "nel/gui/widget_manager.h"
38 #include "nel/gui/view_pointer_base.h"
39 #include "nel/misc/i18n.h"
40 #include "nel/misc/algo.h"
42 using namespace std;
43 using namespace NL3D;
44 using namespace NLMISC;
46 #ifdef DEBUG_NEW
47 #define new DEBUG_NEW
48 #endif
50 namespace
52 const sint SIZE_W_LEFT = 16;
53 const sint DELTA_BEFORE_POPUP = 32;
54 const sint DELTA_BEFORE_MOVING_IN_PARENT_LIST = 16;
57 namespace NLGUI
60 bool CGroupContainer::_ValidateCanDeactivate = true;
62 //#define DRAW_GC_TEST_QUADS
65 #ifdef DRAW_GC_TEST_QUADS
66 static void drawGCTestQuad(sint renderLayer, sint32 xreal, sint32 yreal, sint32 wreal, sint32 hreal, CRGBA color)
68 CViewRenderer &rVR = *CViewRenderer::getInstance();
69 if(rVR.isMinimized())
70 return;
71 sint32 x, y, w, h;
72 rVR.getClipWindow(x, y, w, h);
73 uint32 sw, sh;
74 rVR.getScreenSize(sw, sh);
75 rVR.setClipWindow(0, 0, (sint32)sw, (sint32)sh);
76 rVR.drawRotFlipBitmap (renderLayer, xreal, yreal, wreal, hreal, 0, false, rVR.getBlankTextureId(), color );
77 rVR.setClipWindow(x, y, w ,h);
79 #endif
82 // ***************************************************************************
83 const string CGroupContainer::_OptionLayerName[CGroupContainer::NumLayerName]=
85 "layer0",
86 "layer1",
87 "layer2",
88 "layer3",
89 "layer4",
90 "layer5",
91 "layer6",
92 "layer7",
93 "layer8",
94 "layer9",
98 // ***************************************************************************
99 // CCtrlResizer
100 // ***************************************************************************
102 // ***************************************************************************
103 CCtrlResizer::CCtrlResizer(const TCtorParam &param)
104 : CCtrlBase(param)
106 WMin = WMax = 0;
107 HMin = HMax = 0;
108 _ResizerPos = Hotspot_BR;
109 IsMaxH = false;
110 _MouseDown = false;
111 _XBias = 0;
112 _YBias = 0;
113 resizer = true;
117 // ***************************************************************************
118 THotSpot CCtrlResizer::getRealResizerPos() const
120 CGroupContainer *parent = dynamic_cast<CGroupContainer *>(getParent());
121 if (parent)
123 THotSpot resizerPos = _ResizerPos;
124 if (!IsMaxH && parent->getPopupMinH() == parent->getPopupMaxH())
126 resizerPos = (THotSpot) (resizerPos & ~(Hotspot_Bx | Hotspot_Mx | Hotspot_Tx));
128 if (parent->getPopupMinW() == parent->getPopupMaxW())
130 resizerPos = (THotSpot) (resizerPos & ~(Hotspot_xR | Hotspot_xM | Hotspot_xL));
132 return resizerPos;
134 return _ResizerPos;
137 // ***************************************************************************
138 void CCtrlResizer::draw ()
140 #ifdef DRAW_GC_TEST_QUADS
141 CRGBA col;
142 switch(ResizerPos)
144 case Hotspot_TR: col = CRGBA::Yellow; break;
145 case Hotspot_MR: col = CRGBA::Blue; break;
146 case Hotspot_BR: col = CRGBA::Yellow; break;
147 case Hotspot_BM: col = CRGBA::Blue; break;
148 case Hotspot_BL: col = CRGBA::Yellow; break;
149 case Hotspot_ML: col = CRGBA::Blue; break;
150 case Hotspot_TL: col = CRGBA::Yellow; break;
151 case Hotspot_TM: col = CRGBA::Blue; break;
154 drawGCTestQuad(_RenderLayer, _XReal, _YReal, _WReal, _HReal, col);
155 #endif
158 // ***************************************************************************
159 bool CCtrlResizer::handleEvent (const NLGUI::CEventDescriptor &event)
161 if (CCtrlBase::handleEvent(event)) return true;
162 if (!_Active || !_Parent)
163 return false;
165 if (event.getType() == NLGUI::CEventDescriptor::system)
167 const NLGUI::CEventDescriptorSystem &eds = (const NLGUI::CEventDescriptorSystem &) event;
168 if (eds.getEventTypeExtended() == NLGUI::CEventDescriptorSystem::setfocus)
170 const NLGUI::CEventDescriptorSetFocus &edsf = (const NLGUI::CEventDescriptorSetFocus &) eds;
171 if (edsf.hasFocus() == false && _MouseDown)
173 _MouseDown = false;
174 _Parent->invalidateCoords();
175 return true;
180 if (event.getType() == NLGUI::CEventDescriptor::mouse)
182 const NLGUI::CEventDescriptorMouse &eventDesc = (const NLGUI::CEventDescriptorMouse &)event;
183 if ((CWidgetManager::getInstance()->getCapturePointerLeft() != this) && !isIn(eventDesc.getX(), eventDesc.getY()))
184 return false;
186 CGroupContainer *gc = dynamic_cast<CGroupContainer *>(_Parent);
188 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown)
190 // must check that parent isn't closed
191 if (gc)
194 if (!gc->isOpen()) return false;
195 if (gc->getLayerSetup() != 0) return false;
196 if (gc->isLocked()) return true;
197 if (IsMaxH)
198 gc->setPopupMaxH(gc->getH());
200 _MouseDown = true;
201 _MouseDownX = eventDesc.getX();
202 _MouseDownY = eventDesc.getY();
203 _XBias = 0;
204 _YBias = 0;
205 return true;
208 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup)
210 _MouseDown = false;
211 _Parent->invalidateCoords();
212 return true;
214 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mousemove)
216 if (_MouseDown)
218 //nlinfo("x = %d, y = %d", eventDesc.getX() + _XReal, eventDesc.getY() + _YReal);
219 sint32 dx = eventDesc.getX() - _MouseDownX;
220 sint32 dy = eventDesc.getY() - _MouseDownY;
223 THotSpot resizerPos = getRealResizerPos();
225 // horizontal resize
226 if (dx != 0)
228 if (_XBias > 0)
230 _XBias += dx;
231 if (_XBias < 0)
233 dx = _XBias;
234 _XBias = 0;
236 else
238 dx = 0;
241 else if (_XBias < 0)
243 _XBias += dx;
244 if (_XBias > 0)
246 dx = _XBias;
247 _XBias = 0;
249 else
251 dx = 0;
254 if (resizerPos & Hotspot_xR)
256 sint32 effectiveDX = resizeW (dx);
257 if (effectiveDX != 0 && gc) gc->touch();
258 if (_Parent->getPosRef() & Hotspot_xR)
260 _Parent->setX(_Parent->getX() + effectiveDX);
262 _XBias += dx - effectiveDX;
264 else if (resizerPos & Hotspot_xL)
266 sint32 effectiveDX = resizeW (- dx);
267 if (effectiveDX != 0 && gc) gc->touch();
268 if (_Parent->getPosRef() & Hotspot_xL)
270 _Parent->setX(_Parent->getX() - effectiveDX);
272 _XBias += dx + effectiveDX;
276 // vertical resize
277 if (dy != 0)
279 if (_YBias > 0)
281 _YBias += dy;
282 if (_YBias < 0)
284 dy = _YBias;
285 _YBias = 0;
287 else
289 dy = 0;
292 else if (_YBias < 0)
294 _YBias += dy;
295 if (_YBias > 0)
297 dy = _YBias;
298 _YBias = 0;
300 else
302 dy = 0;
305 if (resizerPos & Hotspot_Tx)
307 sint32 effectiveDY = resizeH (dy);
308 if (effectiveDY != 0 && gc) gc->touch();
309 if (_Parent->getPosRef() & Hotspot_Tx)
311 _Parent->setY(_Parent->getY() + effectiveDY);
313 _YBias += dy - effectiveDY;
315 else if (resizerPos & Hotspot_Bx)
317 sint32 effectiveDY = resizeH (- dy);
318 if (effectiveDY != 0 && gc) gc->touch();
319 if (_Parent->getPosRef() & Hotspot_Bx)
321 _Parent->setY(_Parent->getY() + effectiveDY);
323 _YBias += dy + effectiveDY;
327 _Parent->invalidateCoords();
329 // update pos
330 _MouseDownX = eventDesc.getX();
331 _MouseDownY = eventDesc.getY();
334 // call resize handler of parent container if any
335 if (gc && gc->getAHOnResizePtr() != NULL)
337 CAHManager::getInstance()->runActionHandler(gc->getAHOnResize(), gc, gc->getAHOnResizeParams());
340 return true;
343 return false;
346 // ***************************************************************************
347 sint32 CCtrlResizer::resizeW (sint32 dx)
349 sint32 newW = _Parent->getW();
350 newW += dx;
351 sint32 clippedNewW = newW;
352 NLMISC::clamp(clippedNewW, WMin, WMax);
353 // clip by screen
354 uint32 sw, sh;
355 CViewRenderer &vr = *CViewRenderer::getInstance();
356 vr.getScreenSize(sw, sh);
357 if (_Parent->getPosRef() & Hotspot_xR)
359 if (_ResizerPos & Hotspot_xR)
361 clippedNewW = std::min((sint32)sw + _Parent->getW() - _Parent->getXReal(), clippedNewW);
363 else
365 clippedNewW = std::min(clippedNewW, _Parent->getXReal());
368 else
370 if (_ResizerPos & Hotspot_xL)
372 clippedNewW = std::min(clippedNewW, _Parent->getXReal() + _Parent->getW());
374 else
376 clippedNewW = std::min((sint32)sw - _Parent->getXReal(), clippedNewW);
380 dx = clippedNewW - _Parent->getW();
381 _Parent->setW (clippedNewW);
382 return dx;
385 // ***************************************************************************
386 sint32 CCtrlResizer::resizeH (sint32 dy)
388 // if the owner is a container, special resize applied
389 CGroupContainer *gc = NULL;
390 gc = dynamic_cast<CGroupContainer *>(_Parent);
391 if (gc == NULL)
392 return 0;
394 // resize popupmaxh or h, according to IsMaxH.
395 sint32 oldH;
396 if (IsMaxH)
397 oldH= gc->getPopupMaxH();
398 else
399 oldH= _Parent->getH();
401 // new H
402 sint32 clippedNewH= oldH + dy;
403 // if IsMaxH, don't clamp by HMax
404 if (IsMaxH)
405 clippedNewH = std::max(clippedNewH, HMin);
406 else
407 NLMISC::clamp(clippedNewH, HMin, HMax);
410 // clip by screen
411 uint32 sw, sh;
412 CViewRenderer &vr = *CViewRenderer::getInstance();
413 vr.getScreenSize(sw, sh);
414 if (_Parent->getPosRef() & Hotspot_Tx)
416 if (_ResizerPos & Hotspot_Tx)
418 clippedNewH = std::min((sint32) sh + oldH - _Parent->getY(), clippedNewH);
420 else
422 clippedNewH = std::min(clippedNewH, _Parent->getY());
425 else
427 if (_ResizerPos & Hotspot_Tx)
429 clippedNewH = std::min((sint32) sh - _Parent->getY(), clippedNewH);
431 else
433 clippedNewH = std::min(clippedNewH, _Parent->getY() + oldH);
437 // set final result
438 dy = clippedNewH - oldH;
439 if (IsMaxH)
440 gc->setPopupMaxH(clippedNewH);
441 else
442 gc->setH(clippedNewH);
443 return dy;
447 // ***************************************************************************
448 // CCtrlMover
449 // ***************************************************************************
451 // ***************************************************************************
452 CCtrlMover::CCtrlMover(const TCtorParam &param, bool canMove, bool canOpen)
453 : CCtrlBase(param)
455 _Moving= false;
456 _CanMove = canMove;
457 _CanOpen = canOpen;
458 _HasMoved = false;
459 _MovingInParentList = false;
460 _ParentScrollingUp = false;
461 _ParentScrollingDown = false;
462 _WaitToOpenClose = false;
465 // ***************************************************************************
466 CCtrlMover::~CCtrlMover()
470 // ***************************************************************************
471 COptionsContainerInsertion *CCtrlMover::getInsertionOptions()
473 static NLMISC::CRefPtr<COptionsContainerInsertion> insertionOptions;
474 if (insertionOptions) return insertionOptions;
475 insertionOptions = (COptionsContainerInsertion *) CWidgetManager::getInstance()->getOptions("container_insertion_opt");
476 return insertionOptions;
480 // ***************************************************************************
481 void CCtrlMover::draw ()
483 #ifdef DRAW_GC_TEST_QUADS
484 drawGCTestQuad(_RenderLayer, _XReal, _YReal, _WReal, _HReal, CRGBA(255, 0, 0, 127));
485 #endif
487 // No Op if window is minimized
488 if(CViewRenderer::getInstance()->isMinimized())
489 return;
491 // draw insertion position if moving in parent list
492 if (_MovingInParentList)
494 COptionsContainerInsertion *options = getInsertionOptions();
495 if (!options) return;
496 CViewRenderer &rVR = *CViewRenderer::getInstance();
497 sint32 oldSciX, oldSciY, oldSciW, oldSciH;
498 rVR.getClipWindow (oldSciX, oldSciY, oldSciW, oldSciH);
499 uint32 sw, sh;
500 rVR.getScreenSize(sw, sh);
501 rVR.setClipWindow (0, 0, (sint32) sw, (sint32) sh);
502 CViewRenderer &vr = *CViewRenderer::getInstance();
504 CGroupContainer *gc = dynamic_cast<CGroupContainer *>(_Parent);
505 if (!gc) return;
506 CGroupList *gl = gc->getPreviousParentList();
507 if (!gl) return;
509 sint32 arrowWidth, arrowHeight;
511 if (_ParentScrollingUp)
513 sint32 topPosY = gl->getChild(0)->getYReal();
514 if (gc->getYReal() < topPosY)
516 vr.getTextureSizeFromId(options->TxId_T_Arrow, arrowWidth, arrowHeight);
517 // insertion position is too high, just draw an arrow pointing to top
518 sint32 px = gl->getXReal() + (gl->getWReal() >> 1) - (arrowWidth >> 1);
519 vr.drawRotFlipBitmap(gc->getRenderLayer(), px, _ParentListTop - arrowHeight - 2, arrowWidth, arrowHeight, 0, 0, options->TxId_T_Arrow);
523 if (_ParentScrollingDown)
525 sint32 bottomPosY = gl->getChild(gl->getNumChildren() - 1)->getYReal() - gl->getChild(gl->getNumChildren() - 1)->getHReal();
526 if (gc->getYReal() - gc->getHReal() > bottomPosY)
528 vr.getTextureSizeFromId(options->TxId_B_Arrow, arrowWidth, arrowHeight);
529 // draw an arrow pointing at bottom
530 // insertion position is too high, just draw an arrow pointing to top
531 sint32 px = gl->getXReal() + (gl->getWReal() >> 1) - (arrowWidth >> 1);
532 vr.drawRotFlipBitmap(gc->getRenderLayer(), px, _ParentListBottom + 2, arrowWidth, arrowHeight, 0, 0, options->TxId_B_Arrow);
537 if (!_ParentScrollingUp && !_ParentScrollingDown)
539 sint32 posY;
540 if (_InsertionIndex == (sint32) gl->getNumChildren())
542 posY = gl->getChild(_InsertionIndex - 1)->getYReal();
544 else
546 posY = gl->getChild(_InsertionIndex)->getYReal() + gl->getChild(_InsertionIndex)->getHReal();
549 // draw insertion bar
551 sint32 barWidth, barHeight;
552 vr.getTextureSizeFromId(options->TxId_InsertionBar, barWidth, barHeight);
553 if (posY >= _ParentListBottom && posY <= _ParentListTop)
555 sint32 py = posY - (barHeight >> 1) - 3;
556 vr.drawRotFlipBitmap(gc->getRenderLayer(), gl->getXReal(), py, gl->getWReal(), barHeight, 0, 0, options->TxId_InsertionBar);
559 rVR.setClipWindow(oldSciX, oldSciY, oldSciW, oldSciH);
563 // ***************************************************************************
564 bool CCtrlMover::handleEvent (const NLGUI::CEventDescriptor &event)
566 if (CCtrlBase::handleEvent(event)) return true;
567 if (!_Active)
568 return false;
570 const CWidgetManager::SInterfaceTimes &times = CWidgetManager::getInstance()->getInterfaceTimes();
572 if (event.getType() == NLGUI::CEventDescriptor::system)
574 const NLGUI::CEventDescriptorSystem &eds = (const NLGUI::CEventDescriptorSystem &) event;
575 if (eds.getEventTypeExtended() == NLGUI::CEventDescriptorSystem::setfocus)
577 const NLGUI::CEventDescriptorSetFocus &edsf = (const NLGUI::CEventDescriptorSetFocus &) eds;
578 if (edsf.hasFocus() == false && _Moving)
580 stopMove();
581 return true;
586 if (event.getType() == NLGUI::CEventDescriptor::mouse)
588 const NLGUI::CEventDescriptorMouse &eventDesc = (const NLGUI::CEventDescriptorMouse &)event;
589 // the ctrl must have been captured
590 if (CWidgetManager::getInstance()->getCapturePointerLeft() != this)
591 return false;
593 CGroupContainer *gc = dynamic_cast<CGroupContainer *>(_Parent);
594 if (!gc) return false;
595 if (gc->isLockable())
597 if (gc->isLocked())
599 return false; // do nothing
603 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown && _WaitToOpenClose)
605 if (_WaitToOpenClose)
607 _WaitToOpenClose = false;
608 CWidgetManager::getInstance()->unregisterClockMsgTarget(this);
609 // _WaitToOpen can only be set if the container is popable
610 if (gc)
612 // A double click has been made
613 gc->setHighLighted(false);
614 if (gc->isPopuped())
616 // pop in the window
617 gc->setPopupX(gc->getX());
618 gc->setPopupY(gc->getY());
619 gc->setPopupW(gc->getW());
620 //sint32 currH, minH, maxH;
621 //gc->getResizableChildrenH(currH, minH, maxH);
622 //gc->setPopupChildrenH(currH);
624 gc->popin();
626 else
628 // pop the window
629 gc->popupCurrentPos();
630 gc->forceRolloverAlpha();
631 if (gc->getPopupW() != -1)
633 gc->setX(gc->getPopupX());
634 gc->setY(gc->getPopupY());
635 gc->setW(gc->getPopupW());
636 // must resize the children to get correct height
637 //gc->setChildrenH(gc->getPopupChildrenH());
639 else
641 gc->setW(gc->getRefW());
644 gc->invalidateCoords(2);
646 CWidgetManager::getInstance()->setCapturePointerLeft(NULL);
647 CWidgetManager::getInstance()->setCapturePointerRight(NULL);
649 return true;
653 if (_WaitToOpenClose)
655 _WaitToOpenClose = false;
656 CWidgetManager::getInstance()->unregisterClockMsgTarget(this);
659 if (_CanOpen || gc->isOpenWhenPopup())
661 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup)
663 if (!_Parent) return false;
664 gc->setHighLighted(false);
665 if (_HasMoved || _MovingInParentList)
667 stopMove();
668 return true;
670 if (isIn(eventDesc.getX(), eventDesc.getY()))
673 if (gc->isPopable())
675 _WaitToOpenClose = true;
676 CWidgetManager::getInstance()->registerClockMsgTarget(this);
677 _WaitToOpenCloseDate = times.thisFrameMs;
679 else
681 _Moving = false;
682 if (gc->isOpenable() && !gc->isOpenWhenPopup())
684 gc->setOpen(!gc->isOpen());
686 else
688 return runTitleActionHandler();
691 _Moving = false;
692 return true;
694 else
696 return false;
702 // Move Window Mgt.
703 if(!_Moving && !_MovingInParentList)
705 if (_CanMove)
707 // Enter Moving?
708 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown )
710 _MoveStartX= _Parent->getX()-eventDesc.getX();
711 _MoveStartY= _Parent->getY()-eventDesc.getY();
712 _MoveDeltaXReal= _Parent->getXReal() - _Parent->getX();
713 _MoveDeltaYReal= _Parent->getYReal() - _Parent->getY();
714 _Moving= true;
715 // set the window at top.
716 CWidgetManager::getInstance()->setTopWindow(_Parent);
717 if (gc->getAHOnBeginMovePtr())
719 CAHManager::getInstance()->runActionHandler(gc->getAHOnBeginMove(), gc, gc->getAHOnBeginMoveParams());
721 return true;
725 else
727 // Leave Moving?
728 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup )
730 stopMove();
731 return true;
733 // Move
734 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mousemove )
736 _HasMoved = true;
737 if (gc) gc->touch();
738 // new coords
739 sint32 x= eventDesc.getX() + _MoveStartX;
740 sint32 y= eventDesc.getY() + _MoveStartY;
742 // if the father is a container and is popable (but not poped), move it only if the user has moved the mouse enough
743 if (_Parent && !_MovingInParentList)
745 if (gc && gc->getLayerSetup() != 0)
747 if (gc->isMovableInParentList() && !gc->isPopable())
749 if (abs(y - _Parent->getY()) > DELTA_BEFORE_MOVING_IN_PARENT_LIST)
751 // There should be at least one other entry in the parent list
752 CGroupList *parentList = dynamic_cast<CGroupList *>(gc->getParent());
753 if (!parentList) return false;
754 if (parentList->getNbElement() == 1) return false;
755 setMovingInParent(gc, x, y, eventDesc);
756 updateInsertionIndex(parentList, eventDesc.getY());
757 return true;
761 if (gc->isPopable())
763 if (!gc->isMovableInParentList())
765 if (abs(x - _Parent->getX()) > DELTA_BEFORE_POPUP || abs(y - _Parent->getY()) > DELTA_BEFORE_POPUP)
767 setPoped(gc, x, y, eventDesc);
768 return true;
771 else
773 if (abs(y - _Parent->getY()) > DELTA_BEFORE_MOVING_IN_PARENT_LIST)
775 // There should be at least one other entry in the parent list
776 CGroupList *parentList = dynamic_cast<CGroupList *>(gc->getParent());
777 if (!parentList) return false;
778 if (parentList->getNbElement() == 1) return false;
779 setMovingInParent(gc, x, y, eventDesc);
780 updateInsertionIndex(parentList, eventDesc.getY());
781 return true;
783 else // the mouse should move on the side of the container to turn it into a popup
784 //if (_Parent->getX() - x > DELTA_BEFORE_POPUP || x - (_Parent->getX() + _Parent->getWReal()) > DELTA_BEFORE_POPUP)
785 if (abs(x - _Parent->getX()) > DELTA_BEFORE_POPUP)
787 setPoped(gc, x, y, eventDesc);
788 return true;
793 if (abs(x - _Parent->getX()) > 1 || abs(y - _Parent->getY()) > 1)
795 gc->setHighLighted(true);
796 return true;
798 else
800 gc->setHighLighted(false);
801 return true; // mouse has not moved enough
806 if (!_MovingInParentList)
808 // clip, in real coords space
809 uint32 wScreen, hScreen;
810 CViewRenderer::getInstance()->getScreenSize(wScreen, hScreen);
811 x+= _MoveDeltaXReal;
812 y+= _MoveDeltaYReal;
814 clamp(x, 0, (sint32)wScreen-_Parent->getWReal());
815 clamp(y, 0, (sint32)hScreen-_Parent->getHReal());
816 x-= _MoveDeltaXReal;
817 y-= _MoveDeltaYReal;
818 // move window
819 _Parent->setX(x);
820 _Parent->setY(y);
822 CWidgetManager::getInstance()->snapIfClose(_Parent);
824 // if some action handler to call when moving
825 if(gc->getAHOnMovePtr())
827 // udpate XReal/YReal coords only of the container
828 gc->CInterfaceElement::updateCoords();
829 // execute the AH
830 CAHManager::getInstance()->runActionHandler(gc->getAHOnMovePtr(), this, gc->getAHOnMoveParams());
833 else
835 if (!gc) return false;
836 const CGroupList *gl = gc->getPreviousParentList();
837 if (gl)
839 updateInsertionIndex(gl, eventDesc.getY());
840 // compute visible portion of list
841 sint32 glSciX, glSciY, glSciW, glSciH;
842 gl->getClip(glSciX, glSciY, glSciW, glSciH);
843 _ParentListTop = glSciY + glSciH;
844 _ParentListBottom = glSciY;
845 // the control is moving in its parent list, so the x coordinate doesn't change
846 y += _MoveDeltaYReal;
847 // if the group is at the bottom of screen or at the bottom of the list, must clamp & scroll down
848 if (y < _ParentListBottom)
850 if (_ParentScrollingUp)
852 _ParentScrollingUp = false;
853 CWidgetManager::getInstance()->registerClockMsgTarget(this); // want to now when time pass
855 if (glSciY > gl->getYReal()) // is there need for scroll ?
857 if (!_ParentScrollingDown)
859 _ParentScrollingDown = true;
860 CWidgetManager::getInstance()->registerClockMsgTarget(this); // want to now when time pass
861 _ScrollTime = 0;
864 else
866 if (_ParentScrollingDown)
868 _ParentScrollingDown = false;
869 CWidgetManager::getInstance()->unregisterClockMsgTarget(this); // want to now when time pass
872 y = _ParentListBottom;
874 else
876 if (_ParentScrollingDown)
878 _ParentScrollingDown = false;
879 CWidgetManager::getInstance()->registerClockMsgTarget(this); // want to now when time pass
881 sint32 topY = y + _Parent->getHReal();
882 if (topY > _ParentListTop)
884 // idem for top
885 if (glSciY + glSciH < gl->getYReal() + gl->getHReal()) // is there need for scroll ?
887 if (!_ParentScrollingUp)
889 _ParentScrollingUp = true;
890 CWidgetManager::getInstance()->registerClockMsgTarget(this); // want to now when time pass
891 _ScrollTime = 0;
894 else
896 if (_ParentScrollingUp)
898 _ParentScrollingDown = false;
899 CWidgetManager::getInstance()->unregisterClockMsgTarget(this); // want to now when time pass
902 y = _ParentListTop - _Parent->getHReal();
905 y -= _MoveDeltaYReal;
906 // move window
907 _Parent->setY(y);
910 // just invalidate position (1 pass)
911 _Parent->invalidateCoords(1);
912 return true;
916 if (event.getType() == NLGUI::CEventDescriptor::system)
918 const NLGUI::CEventDescriptorSystem &systemEvent = (const NLGUI::CEventDescriptorSystem &) event;
919 if (systemEvent.getEventTypeExtended() == NLGUI::CEventDescriptorSystem::clocktick)
921 if (_WaitToOpenClose)
923 uint dbclickDelay = CWidgetManager::getInstance()->getUserDblClickDelay();
924 if ((times.thisFrameMs - _WaitToOpenCloseDate) > dbclickDelay)
926 CGroupContainer *gc = dynamic_cast<CGroupContainer *>(_Parent);
927 if (!gc) return false;
928 _WaitToOpenClose = false;
929 CWidgetManager::getInstance()->unregisterClockMsgTarget(this);
930 // do the open action
931 if (gc->isOpenable() && !gc->isOpenWhenPopup())
933 gc->setOpen(!gc->isOpen());
935 else
937 // if can't open, just call the action handler
938 return runTitleActionHandler();
942 else if (_ParentScrollingDown || _ParentScrollingUp)
944 handleScrolling();
948 return false;
951 // ***************************************************************************
952 void CCtrlMover::handleScrolling()
954 const uint pixPerMS = 7; // the number of millisecond to move of one pixel in the parent scrollbar
955 CGroupContainer *gc = dynamic_cast<CGroupContainer *>(_Parent);
956 if (!gc) return;
957 CGroupList *gl = gc->getPreviousParentList();
958 if (!gl) return;
960 const CWidgetManager::SInterfaceTimes &times = CWidgetManager::getInstance()->getInterfaceTimes();
962 if (_ParentScrollingUp)
964 sint32 topPosY = gl->getChild(0)->getYReal();
965 // check if we are really at the end of the list, if this is not the case, we should perform scroll on parent container with a scroll bar
966 if (gc->getYReal() < topPosY)
968 _ScrollTime += times.frameDiffMs;
969 sint32 deltaY = (sint32) (_ScrollTime / pixPerMS);
970 if (deltaY != 0)
972 CGroupContainer *currGC = gc->getPreviousContainer();
973 while (currGC)
975 CCtrlScroll *cs = currGC->getScroll();
976 if (cs)
978 sint32 dy = cs->moveTrackY(deltaY);
979 if (dy != 0) break;
981 currGC = currGC->getFatherContainer();
983 gl->invalidateCoords();
984 gc->invalidateCoords();
985 _ScrollTime = _ScrollTime % (sint64) pixPerMS;
988 else
990 _ParentScrollingUp = false;
991 CWidgetManager::getInstance()->unregisterClockMsgTarget(this);
992 _InsertionIndex = 0;
996 if (_ParentScrollingDown)
998 // check if we are really at the end of the list, if this is not the case, we should perform scroll on parent container with a scroll bar
999 sint32 bottomPosY = gl->getChild(gl->getNumChildren() - 1)->getYReal() - gl->getChild(gl->getNumChildren() - 1)->getHReal();
1000 if (gc->getYReal() - gc->getHReal() > bottomPosY)
1002 _ScrollTime += times.frameDiffMs;
1003 sint32 deltaY = - (sint32) (_ScrollTime / pixPerMS);
1004 if (deltaY != 0)
1006 CGroupContainer *currGC = gc->getPreviousContainer();
1007 while (currGC)
1009 CCtrlScroll *cs = currGC->getScroll();
1010 if (cs)
1012 sint32 dy = cs->moveTrackY(deltaY);
1013 if (dy != 0) break;
1015 currGC = currGC->getFatherContainer();
1017 gl->invalidateCoords();
1018 gc->invalidateCoords();
1019 _ScrollTime = _ScrollTime % pixPerMS;
1022 else
1024 _ParentScrollingDown = false;
1025 CWidgetManager::getInstance()->unregisterClockMsgTarget(this);
1026 _InsertionIndex = gl->getNumChildren();
1031 // ***************************************************************************
1032 bool CCtrlMover::runTitleActionHandler()
1034 CGroupContainer *gc = dynamic_cast<CGroupContainer *>(_Parent);
1035 if (!gc) return false;
1036 CInterfaceGroup *gr = gc->isOpen() ? gc->getHeaderOpened() : gc->getHeaderClosed();
1037 if (gr && !gr->getLeftClickHandler().empty())
1039 CAHManager::getInstance()->runActionHandler(gr->getLeftClickHandler(), this, gr->getLeftClickHandlerParams());
1040 return true;
1042 // try with the main group
1043 if (!gc->getLeftClickHandler().empty())
1045 CAHManager::getInstance()->runActionHandler(gc->getLeftClickHandler(), this, gc->getLeftClickHandlerParams());
1046 return true;
1048 return false;
1051 // ***************************************************************************
1052 void CCtrlMover::setPoped(CGroupContainer *gc, sint32 x, sint32 y, const NLGUI::CEventDescriptorMouse &eventDesc)
1054 gc->setHighLighted(false);
1055 sint32 deltaX = x - _Parent->getX();
1056 sint32 deltaY = y - _Parent->getY();
1057 // pop up the window
1058 gc->popupCurrentPos(); // NB : this has the side effect of destroying this object during the call to CGroupContainer::update(), because the mover is recreated during the setup !
1059 // So from now we shouldn't use anything that use the 'this' pointer
1060 // TODO : maybe there a more clean way to do that ? (except that we may not call update() in popupCurrentPos() )
1061 if (gc->isLockable())
1063 gc->setLocked(false);
1065 gc->setW(gc->getRefW());
1066 gc->updateCoords();
1067 gc->updateCoords();
1068 gc->updateCoords();
1069 // now the window is in screen coordinates
1070 sint32 newX = gc->getXReal() + deltaX;
1071 sint32 newY = gc->getYReal() + deltaY;
1072 uint32 wScreen, hScreen;
1073 CViewRenderer::getInstance()->getScreenSize(wScreen, hScreen);
1074 clamp(newX, 0, (sint32)wScreen - gc->getWReal());
1075 clamp(newY, 0, (sint32)hScreen - gc->getHReal());
1076 // move window
1077 gc->setX(newX);
1078 gc->setY(newY + gc->getHReal());
1079 // just invalidate position (1 pass)
1080 gc->updateCoords();
1082 // delegate to the new created control mover
1083 CCtrlMover *cm = gc->getCtrlMover();
1084 cm->_MoveStartX= gc->getX()-eventDesc.getX();
1085 cm->_MoveStartY= gc->getY()-eventDesc.getY();
1086 cm->_MoveDeltaXReal= gc->getXReal() - gc->getX();
1087 cm->_MoveDeltaYReal= gc->getYReal() - gc->getY();
1088 cm->_Moving= true;
1089 CWidgetManager::getInstance()->setCapturePointerLeft(cm);
1090 CWidgetManager::getInstance()->setCapturePointerRight(NULL);
1093 // ***************************************************************************
1094 void CCtrlMover::setMovingInParent(CGroupContainer *gc, sint32 /* x */, sint32 y, const NLGUI::CEventDescriptorMouse &eventDesc)
1096 if (!gc) return;
1097 sint32 deltaY = y - gc->getY();
1098 CGroupList *parentList = dynamic_cast<CGroupList *>(gc->getParent());
1099 if (!parentList) return;
1100 // sint32 startIndex = parentList->getElementIndex(gc);
1101 gc->setHighLighted(false);
1102 sint32 oldX = _Parent->getXReal();
1103 gc->setMovingInParentList(true);
1104 sint32 gcWidth = gc->getWReal();
1105 // pop up the window
1106 gc->popupCurrentPos(); // this doesn't change the order in setup
1107 gc->setSizeRef(0);
1108 gc->setW(gcWidth);
1109 gc->setX(oldX);
1110 gc->updateCoords();
1111 gc->updateCoords();
1112 gc->updateCoords();
1113 // now the window is in screen coordinates
1114 sint32 newY = gc->getYReal() + deltaY;
1116 parentList->updateCoords();
1117 // get clip rect from parent list
1118 sint32 glSciX, glSciY, glSciW, glSciH;
1119 parentList->getClip(glSciX, glSciY, glSciW, glSciH);
1120 _ParentListTop = glSciY + glSciH;
1121 _ParentListBottom = glSciY;
1122 // clip by parent list coords
1123 clamp(newY, _ParentListBottom, _ParentListTop - gc->getHReal());
1124 // move window
1125 gc->setY(newY + gc->getHReal());
1126 // just invalidate position (1 pass)
1127 gc->updateCoords();
1129 // reupdate pos
1130 _MoveStartY= gc->getY()-eventDesc.getY();
1131 _MoveDeltaYReal= gc->getYReal() - gc->getY();
1133 CWidgetManager::getInstance()->setCapturePointerLeft(this);
1134 CWidgetManager::getInstance()->setCapturePointerRight(NULL);
1135 _Moving = false;
1136 _MovingInParentList = true;
1138 // register to get time events
1141 // ***************************************************************************
1142 void CCtrlMover::updateInsertionIndex(const CGroupList *gl, sint32 posY)
1144 if (!gl) return;
1145 for(uint k = 0; k < gl->getNumChildren(); ++k)
1147 CViewBase *child = gl->getChild(k);
1148 if (child->getYReal() <= posY)
1150 if (posY < child->getYReal() + (child->getHReal() >> 1))
1152 _InsertionIndex = k + 1;
1153 return;
1155 else
1157 _InsertionIndex = k;
1158 return;
1162 _InsertionIndex = gl->getNumChildren();
1165 // ***************************************************************************
1166 void CCtrlMover::stopMove()
1168 _ParentScrollingUp = false;
1169 _ParentScrollingDown = false;
1170 CWidgetManager::getInstance()->setCapturePointerLeft(NULL);
1171 _HasMoved = false;
1172 if (_Moving)
1174 _Moving = false;
1176 else
1178 _MovingInParentList = false;
1179 // insert at good position in the parent list
1180 CGroupContainer *gc = dynamic_cast<CGroupContainer *>(_Parent);
1181 if (!gc) return;
1182 gc->popin(_InsertionIndex);
1183 if (gc->getChildrenObs())
1185 gc->getChildrenObs()->childrenMoved(_StartIndex, _InsertionIndex, gc);
1191 // ***************************************************************************
1192 // CGroupContainer
1193 // ***************************************************************************
1195 NLMISC_REGISTER_OBJECT(CViewBase, CGroupContainer, std::string, "container");
1197 // ***************************************************************************
1198 CGroupContainer::CGroupContainer(const TCtorParam &param)
1199 : CGroupContainerBase(param)
1201 // faster than a virual call
1202 _IsGroupContainer = true;
1204 _CurrentRolloverAlphaContainer = 0.f;
1205 _CurrentRolloverAlphaContent = 0.f;
1207 _LayerSetup = -1;
1208 _Localize = true;
1209 _Content = NULL;
1210 _HeaderOpened = NULL;
1211 _HeaderClosed = NULL;
1212 _TitleOpened = NULL;
1213 _TitleClosed = NULL;
1214 _TitleDeltaMaxW = 0;
1215 _ViewOpenState = NULL;
1216 _RightButton = NULL;
1217 _HelpButton = NULL;
1218 _List = NULL;
1219 _ScrollBar = NULL;
1220 _Mover= NULL;
1221 _OldFatherContainer = NULL;
1222 _InsertionOrder = 0;
1223 _MinW = 222;
1224 _MaxW = 320;
1225 _BackupX = 0;
1226 _BackupY = 0;
1227 _PopupMinW = 222;
1228 _PopupMaxW = 500;
1229 _PopupMinH = 48;
1230 _PopupMaxH = 500;
1232 _BlinkDT = 0;
1233 _ChildrenObs = NULL;
1234 _NumBlinks = 0;
1236 _PopupX = -1;
1237 _PopupY = -1;
1238 _PopupW = -1;
1240 _RefW = 0;
1242 _Openable = true;
1243 _Opened = false;
1244 _OpenWhenPopup = false;
1245 _OpenAtStart = false;
1246 _OpenedBeforePopup = false;
1248 _Lockable = true;
1250 _EnabledResizer = true;
1251 _ResizerTopSize = -1;
1252 _Movable = false;
1253 _MovableInParentList = false;
1254 _Popable = false;
1255 _Poped = false;
1256 _HighLighted = false;
1257 _Blinking = false;
1258 _BlinkState = false;
1259 _MovingInParentList = false;
1260 _ActiveSavable = true;
1261 _Savable = true;
1262 _TitleClass = TitleText;
1263 _TouchFlag = false;
1264 _PositionBackuped = false;
1265 _Modal = false;
1267 _HeaderActive = true;
1268 _EnabledRightButton = true;
1269 _EnabledHelpButton = true;
1270 _TitleOverExtendViewText = false;
1273 // action handler
1274 _AHOnOpen = NULL;
1275 _AHOnClose = NULL;
1276 _AHOnCloseButton = NULL;
1277 _AHOnMove = NULL;
1278 _AHOnDeactiveCheck = NULL;
1279 _AHOnResize = NULL;
1280 _AHOnAlphaSettingsChanged = NULL;
1281 _AHOnBeginMove = NULL;
1283 std::fill(_Resizer, _Resizer + NumResizers, (CCtrlResizer *) 0);
1285 _ContentYOffset = 0;
1288 // ***************************************************************************
1289 CGroupContainer::~CGroupContainer()
1293 // ***************************************************************************
1294 CGroupContainer::TTileClass CGroupContainer::convertTitleClass(const char *ptr)
1296 if(nlstricmp(ptr, "formated")==0)
1297 return TitleTextFormated;
1298 if(nlstricmp(ptr, "text_id")==0)
1299 return TitleTextId;
1300 if(nlstricmp(ptr, "text_dyn_string")==0)
1301 return TitleTextDynString;
1302 // default
1303 return TitleText;
1306 std::string CGroupContainer::getProperty( const std::string &name ) const
1308 if( name == "localize" )
1310 return toString( _Localize );
1312 else
1313 if( name == "title_class" )
1315 switch( _TitleClass )
1317 case TitleTextFormated:
1318 return "formated";
1319 break;
1321 case TitleTextId:
1322 return "text_id";
1323 break;
1325 case TitleTextDynString:
1326 return "text_dyn_string";
1327 break;
1330 return "text";
1332 else
1333 if( name == "content_y_offset" )
1335 return toString( _ContentYOffset );
1337 else
1338 if( name == "title" )
1340 if( _TitleTextOpened == _TitleTextClosed )
1341 return _TitleTextOpened;
1342 else
1343 return "";
1345 else
1346 if( name == "title_opened" )
1348 return _TitleTextOpened;
1350 else
1351 if( name == "title_closed" )
1353 return _TitleTextClosed;
1355 else
1356 if( name == "header_active" )
1358 return toString( _HeaderActive );
1360 else
1361 if( name == "header_color" )
1363 if( _HeaderColor.getNodePtr() != NULL )
1364 return _HeaderColor.getNodePtr()->getFullName();
1365 else
1366 return "";
1368 else
1369 if( name == "right_button" )
1371 return toString( _EnabledRightButton );
1373 else
1374 if( name == "help_button" )
1376 return toString( _EnabledHelpButton );
1378 else
1379 if( name == "movable" )
1381 return toString( _Movable );
1383 else
1384 if( name == "popable" )
1386 return toString( _Popable );
1388 else
1389 if( name == "lockable" )
1391 return toString( _Lockable );
1393 else
1394 if( name == "locked" )
1396 return toString( _Locked );
1398 else
1399 if( name == "openable" )
1401 return toString( _Openable );
1403 else
1404 if( name == "opened" )
1406 return toString( _Opened );
1408 else
1409 if( name == "modal" )
1411 return toString( _Modal );
1413 else
1414 if( name == "open_when_popup" )
1416 return toString( _OpenWhenPopup );
1418 else
1419 if( name == "resizer" )
1421 return toString( _EnabledResizer );
1423 else
1424 if( name == "resizer_top_size" )
1426 return toString( _ResizerTopSize );
1428 else
1429 if( name == "on_open" )
1431 return getAHString( name );
1433 else
1434 if( name == "on_open_params" )
1436 return _AHOnOpenParams.toString();
1438 else
1439 if( name == "on_close" )
1441 return getAHString( name );
1443 else
1444 if( name == "on_close_params" )
1446 return _AHOnCloseParams.toString();
1448 else
1449 if( name == "on_close_button" )
1451 return getAHString( name );
1453 else
1454 if( name == "on_close_button_params" )
1456 return _AHOnCloseButtonParams.toString();
1458 else
1459 if( name == "on_move" )
1461 return getAHString( name );
1463 else
1464 if( name == "on_move_params" )
1466 return _AHOnMoveParams.toString();
1468 else
1469 if( name == "on_deactive_check" )
1471 return getAHString( name );
1473 else
1474 if( name == "on_deactive_check_params" )
1476 return _AHOnDeactiveCheckParams.toString();
1478 else
1479 if( name == "on_resize" )
1481 return getAHString( name );
1483 else
1484 if( name == "on_resize_params" )
1486 return _AHOnResizeParams.toString();
1488 else
1489 if( name == "on_alpha_settings_changed" )
1491 return getAHString( name );
1493 else
1494 if( name == "on_alpha_settings_changed_params" )
1496 return _AHOnAlphaSettingsChangedParams.toString();
1498 else
1499 if( name == "on_begin_move" )
1501 return getAHString( name );
1503 else
1504 if( name == "on_begin_move_params" )
1506 return _AHOnBeginMoveParams.toString();
1508 else
1509 if( name == "max_w" )
1511 return toString( _MaxW );
1513 else
1514 if( name == "min_w" )
1516 return toString( _MinW );
1518 else
1519 if( name == "pop_max_w" )
1521 return toString( _PopupMaxW );
1523 else
1524 if( name == "pop_min_w" )
1526 return toString( _PopupMinW );
1528 else
1529 if( name == "pop_max_h" )
1531 return toString( _PopupMaxH );
1533 else
1534 if( name == "pop_min_h" )
1536 return toString( _PopupMinH );
1538 else
1539 if( name == "movable_in_parent_list" )
1541 return toString( _MovableInParentList );
1543 else
1544 if( name == "savable" )
1546 return toString( _Savable );
1548 else
1549 if( name == "active_savable" )
1551 return toString( _ActiveSavable );
1553 else
1554 if( name == "modal_parent" )
1556 return _ModalParentNames;
1558 else
1559 if( name == "options" )
1561 return _OptionsName;
1563 else
1564 if( name == "title_delta_max_w" )
1566 return toString( _TitleDeltaMaxW );
1568 else
1569 if( name == "title_over_extend_view_text" )
1571 return toString( _TitleOverExtendViewText );
1573 else
1574 if( name == "help_page" )
1576 return _HelpPage.toString();
1578 else
1579 return CInterfaceGroup::getProperty( name );
1583 void CGroupContainer::setProperty( const std::string &name, const std::string &value )
1585 if( name == "localize" )
1587 bool b;
1588 if( fromString( value, b ) )
1589 _Localize = b;
1590 return;
1592 else
1593 if( name == "title_class" )
1595 if( value == "formated" )
1596 _TitleClass = TitleTextFormated;
1597 else
1598 if( value == "text_id" )
1599 _TitleClass = TitleTextId;
1600 else
1601 if( value == "text_dyn_string" )
1602 _TitleClass = TitleTextDynString;
1603 else
1604 _TitleClass = TitleText;
1606 return;
1609 else
1610 if( name == "content_y_offset" )
1612 sint8 i;
1613 if( fromString( value, i ) )
1614 _ContentYOffset = i;
1615 return;
1617 else
1618 if( name == "title" )
1620 _TitleTextOpened = _TitleTextClosed = value;
1621 return;
1623 else
1624 if( name == "title_opened" )
1626 _TitleTextOpened = value;
1627 return;
1629 else
1630 if( name == "title_closed" )
1632 _TitleTextClosed = value;
1633 return;
1635 else
1636 if( name == "header_active" )
1638 bool b;
1639 if( fromString( value, b ) )
1640 _HeaderActive = b;
1641 return;
1643 else
1644 if( name == "header_color" )
1646 _HeaderColor.link( value.c_str() );
1647 return;
1649 else
1650 if( name == "right_button" )
1652 bool b;
1653 if( fromString( value, b ) )
1654 _EnabledRightButton = b;
1655 return;
1657 else
1658 if( name == "help_button" )
1660 bool b;
1661 if( fromString( value, b ) )
1662 _EnabledHelpButton = b;
1663 return;
1665 else
1666 if( name == "movable" )
1668 bool b;
1669 if( fromString( value, b ) )
1670 _Movable = b;
1671 return;
1673 else
1674 if( name == "popable" )
1676 bool b;
1677 if( fromString( value, b ) )
1678 _Popable = b;
1679 return;
1681 else
1682 if( name == "lockable" )
1684 bool b;
1685 if( fromString( value, b ) )
1686 _Lockable = b;
1687 return;
1689 else
1690 if( name == "locked" )
1692 bool b;
1693 if( fromString( value, b ) )
1694 _Locked = b;
1695 return;
1697 else
1698 if( name == "openable" )
1700 bool b;
1701 if( fromString( value, b ) )
1702 _Openable = b;
1703 return;
1705 else
1706 if( name == "opened" )
1708 bool b;
1709 if( fromString( value, b ) )
1710 _Opened = b;
1711 return;
1713 else
1714 if( name == "modal" )
1716 bool b;
1717 if( fromString( value, b ) )
1718 _Modal = b;
1719 return;
1721 else
1722 if( name == "open_when_popup" )
1724 bool b;
1725 if( fromString( value, b ) )
1726 _OpenWhenPopup = b;
1727 return;
1729 else
1730 if( name == "resizer" )
1732 bool b;
1733 if( fromString( value, b ) )
1734 _EnabledResizer = b;
1735 return;
1737 else
1738 if( name == "resizer_top_size" )
1740 sint8 i;
1741 if( fromString( value, i ) )
1742 _ResizerTopSize = i;
1743 return;
1745 else
1746 if( name == "on_open" )
1748 std::string dummy;
1749 _AHOnOpen = CAHManager::getInstance()->getAH( value, dummy );
1750 mapAHString( name, value );
1751 return;
1753 else
1754 if( name == "on_open_params" )
1756 _AHOnOpenParams = value;
1757 return;
1759 else
1760 if( name == "on_close" )
1762 std::string dummy;
1763 _AHOnClose = CAHManager::getInstance()->getAH( value, dummy );
1764 mapAHString( name, value );
1765 return;
1767 else
1768 if( name == "on_close_params" )
1770 _AHOnCloseParams = value;
1771 return;
1773 else
1774 if( name == "on_close_button" )
1776 std::string dummy;
1777 _AHOnCloseButton = CAHManager::getInstance()->getAH( value, dummy );
1778 mapAHString( name, value );
1779 return;
1781 else
1782 if( name == "on_close_button_params" )
1784 _AHOnCloseButtonParams = value;
1785 return;
1787 else
1788 if( name == "on_move" )
1790 std::string dummy;
1791 _AHOnMove = CAHManager::getInstance()->getAH( value, dummy );
1792 mapAHString( name, value );
1793 return;
1795 else
1796 if( name == "on_move_params" )
1798 _AHOnMoveParams = value;
1799 return;
1801 else
1802 if( name == "on_deactive_check" )
1804 std::string dummy;
1805 _AHOnDeactiveCheck = CAHManager::getInstance()->getAH( value, dummy );
1806 mapAHString( name, value );
1807 return;
1809 else
1810 if( name == "on_deactive_check_params" )
1812 _AHOnDeactiveCheckParams = value;
1813 return;
1815 else
1816 if( name == "on_resize" )
1818 std::string dummy;
1819 _AHOnResize = CAHManager::getInstance()->getAH( value, dummy );
1820 mapAHString( name, value );
1821 return;
1823 else
1824 if( name == "on_resize_params" )
1826 _AHOnResizeParams = value;
1827 return;
1829 else
1830 if( name == "on_alpha_settings_changed" )
1832 std::string dummy;
1833 _AHOnAlphaSettingsChanged = CAHManager::getInstance()->getAH( value, dummy );
1834 mapAHString( name, value );
1835 return;
1837 else
1838 if( name == "on_alpha_settings_changed_params" )
1840 _AHOnAlphaSettingsChangedParams = value;
1841 return;
1843 else
1844 if( name == "on_begin_move" )
1846 std::string dummy;
1847 _AHOnBeginMove = CAHManager::getInstance()->getAH( value, dummy );
1848 mapAHString( name, value );
1849 return;
1851 else
1852 if( name == "on_begin_move_params" )
1854 _AHOnBeginMoveParams = value;
1855 return;
1857 else
1858 if( name == "max_w" )
1860 sint32 i;
1861 if( fromString( value, i ) )
1862 _MaxW = i;
1863 return;
1865 else
1866 if( name == "min_w" )
1868 sint32 i;
1869 if( fromString( value, i ) )
1870 _MinW = i;
1871 return;
1873 else
1874 if( name == "pop_max_w" )
1876 sint32 i;
1877 if( fromString( value, i ) )
1878 _PopupMaxW = i;
1879 return;
1881 else
1882 if( name == "pop_min_w" )
1884 sint32 i;
1885 if( fromString( value, i ) )
1886 _PopupMinW = i;
1887 return;
1889 else
1890 if( name == "pop_max_h" )
1892 sint32 i;
1893 if( fromString( value, i ) )
1894 _PopupMaxH = i;
1895 return;
1897 else
1898 if( name == "pop_min_h" )
1900 sint32 i;
1901 if( fromString( value, i ) )
1902 _PopupMinH = i;
1903 return;
1905 else
1906 if( name == "movable_in_parent_list" )
1908 bool b;
1909 if( fromString( value, b ) )
1910 _MovableInParentList = b;
1911 return;
1913 else
1914 if( name == "savable" )
1916 bool b;
1917 if( fromString( value, b ) )
1918 _Savable = b;
1919 return;
1921 else
1922 if( name == "active_savable" )
1924 bool b;
1925 if( fromString( value, b ) )
1926 _ActiveSavable = b;
1927 return;
1929 else
1930 if( name == "modal_parent" )
1932 _ModalParentNames = value;
1933 return;
1935 else
1936 if( name == "options" )
1938 _OptionsName = value;
1939 return;
1941 else
1942 if( name == "title_delta_max_w" )
1944 sint32 i;
1945 if( fromString( value, i ) )
1946 _TitleDeltaMaxW = i;
1947 return;
1949 else
1950 if( name == "title_over_extend_view_text" )
1952 bool b;
1953 if( fromString( value, b ) )
1954 _TitleOverExtendViewText = b;
1955 return;
1957 else
1958 if( name == "help_page" )
1960 _HelpPage = value;
1961 return;
1963 else
1964 CInterfaceGroup::setProperty( name, value );
1967 xmlNodePtr CGroupContainer::serialize( xmlNodePtr parentNode, const char *type ) const
1969 xmlNodePtr node = CInterfaceGroup::serialize( parentNode, type );
1970 if( node == NULL )
1971 return NULL;
1973 xmlSetProp( node, BAD_CAST "type", BAD_CAST "container" );
1974 xmlSetProp( node, BAD_CAST "localize", BAD_CAST toString( _Localize ).c_str() );
1976 std::string titleClass;
1977 switch( _TitleClass )
1979 case TitleTextFormated:
1980 titleClass = "formated";
1981 break;
1983 case TitleTextId:
1984 titleClass = "text_id";
1985 break;
1987 case TitleTextDynString:
1988 titleClass = "text_dyn_string";
1989 break;
1991 default:
1992 titleClass = "text";
1993 break;
1996 xmlSetProp( node, BAD_CAST "title_class", BAD_CAST titleClass.c_str() );
1997 xmlSetProp( node, BAD_CAST "content_y_offset", BAD_CAST toString( _ContentYOffset ).c_str() );
1999 if( _TitleTextOpened == _TitleTextClosed )
2000 xmlSetProp( node, BAD_CAST "title", BAD_CAST _TitleTextOpened.c_str() );
2001 else
2002 xmlSetProp( node, BAD_CAST "title", BAD_CAST "" );
2004 xmlSetProp( node, BAD_CAST "title_opened", BAD_CAST _TitleTextOpened.c_str() );
2005 xmlSetProp( node, BAD_CAST "title_closed", BAD_CAST _TitleTextClosed.c_str() );
2006 xmlSetProp( node, BAD_CAST "header_active", BAD_CAST toString( _HeaderActive ).c_str() );
2008 if( _HeaderColor.getNodePtr() != NULL )
2009 xmlSetProp( node, BAD_CAST "header_color", BAD_CAST _HeaderColor.getNodePtr()->getFullName().c_str() );
2010 else
2011 xmlSetProp( node, BAD_CAST "header_color", BAD_CAST "" );
2013 xmlSetProp( node, BAD_CAST "right_button", BAD_CAST toString( _EnabledRightButton ).c_str() );
2014 xmlSetProp( node, BAD_CAST "help_button", BAD_CAST toString( _EnabledHelpButton ).c_str() );
2015 xmlSetProp( node, BAD_CAST "movable", BAD_CAST toString( _Movable ).c_str() );
2016 xmlSetProp( node, BAD_CAST "popable", BAD_CAST toString( _Popable ).c_str() );
2017 xmlSetProp( node, BAD_CAST "lockable", BAD_CAST toString( _Lockable ).c_str() );
2018 xmlSetProp( node, BAD_CAST "locked", BAD_CAST toString( _Locked ).c_str() );
2019 xmlSetProp( node, BAD_CAST "openable", BAD_CAST toString( _Openable ).c_str() );
2020 xmlSetProp( node, BAD_CAST "opened", BAD_CAST toString( _Opened ).c_str() );
2021 xmlSetProp( node, BAD_CAST "modal", BAD_CAST toString( _Modal ).c_str() );
2022 xmlSetProp( node, BAD_CAST "open_when_popup", BAD_CAST toString( _OpenWhenPopup ).c_str() );
2023 xmlSetProp( node, BAD_CAST "resizer", BAD_CAST toString( _EnabledResizer ).c_str() );
2024 xmlSetProp( node, BAD_CAST "resizer_top_size", BAD_CAST toString( _ResizerTopSize ).c_str() );
2026 xmlSetProp( node, BAD_CAST "on_open",
2027 BAD_CAST getAHString( "on_open" ).c_str() );
2029 xmlSetProp( node, BAD_CAST "on_open_params",
2030 BAD_CAST _AHOnOpenParams.toString().c_str() );
2032 xmlSetProp( node, BAD_CAST "on_close",
2033 BAD_CAST getAHString( "on_close" ).c_str() );
2035 xmlSetProp( node, BAD_CAST "on_close_params",
2036 BAD_CAST _AHOnCloseParams.toString().c_str() );
2038 xmlSetProp( node, BAD_CAST "on_close_button",
2039 BAD_CAST getAHString( "on_close_button" ).c_str() );
2041 xmlSetProp( node, BAD_CAST "on_close_button_params",
2042 BAD_CAST _AHOnCloseButtonParams.toString().c_str() );
2044 xmlSetProp( node, BAD_CAST "on_move",
2045 BAD_CAST getAHString( "on_move" ).c_str() );
2047 xmlSetProp( node, BAD_CAST "on_close_params",
2048 BAD_CAST _AHOnMoveParams.toString().c_str() );
2050 xmlSetProp( node, BAD_CAST "on_deactive_check",
2051 BAD_CAST getAHString( "on_deactive_check" ).c_str() );
2053 xmlSetProp( node, BAD_CAST "on_deactive_check_params",
2054 BAD_CAST _AHOnDeactiveCheckParams.toString().c_str() );
2056 xmlSetProp( node, BAD_CAST "on_resize",
2057 BAD_CAST getAHString( "on_resize" ).c_str() );
2059 xmlSetProp( node, BAD_CAST "on_resize_params",
2060 BAD_CAST _AHOnResizeParams.toString().c_str() );
2062 xmlSetProp( node, BAD_CAST "on_alpha_settings_changed",
2063 BAD_CAST getAHString( "on_alpha_settings_changed" ).c_str() );
2065 xmlSetProp( node, BAD_CAST "on_alpha_settings_changed_params",
2066 BAD_CAST _AHOnAlphaSettingsChangedParams.toString().c_str() );
2068 xmlSetProp( node, BAD_CAST "on_begin_move",
2069 BAD_CAST getAHString( "on_begin_move" ).c_str() );
2071 xmlSetProp( node, BAD_CAST "on_begin_move_params",
2072 BAD_CAST _AHOnBeginMoveParams.toString().c_str() );
2074 xmlSetProp( node, BAD_CAST "max_w", BAD_CAST toString( _MaxW ).c_str() );
2075 xmlSetProp( node, BAD_CAST "min_w", BAD_CAST toString( _MinW ).c_str() );
2076 xmlSetProp( node, BAD_CAST "pop_max_w", BAD_CAST toString( _PopupMaxW ).c_str() );
2077 xmlSetProp( node, BAD_CAST "pop_min_w", BAD_CAST toString( _PopupMinW ).c_str() );
2078 xmlSetProp( node, BAD_CAST "pop_max_h", BAD_CAST toString( _PopupMaxH ).c_str() );
2079 xmlSetProp( node, BAD_CAST "pop_min_h", BAD_CAST toString( _PopupMinH ).c_str() );
2080 xmlSetProp( node, BAD_CAST "movable_in_parent_list", BAD_CAST toString( _MovableInParentList ).c_str() );
2081 xmlSetProp( node, BAD_CAST "savable", BAD_CAST toString( _Savable ).c_str() );
2082 xmlSetProp( node, BAD_CAST "active_savable", BAD_CAST toString( _ActiveSavable ).c_str() );
2083 xmlSetProp( node, BAD_CAST "modal_parents", BAD_CAST _ModalParentNames.c_str() );
2084 xmlSetProp( node, BAD_CAST "options", BAD_CAST _OptionsName.toString().c_str() );
2085 xmlSetProp( node, BAD_CAST "title_delta_max_w", BAD_CAST toString( _TitleDeltaMaxW ).c_str() );
2086 xmlSetProp( node, BAD_CAST "title_over_extend_view_text", BAD_CAST toString( _TitleOverExtendViewText ).c_str() );
2087 xmlSetProp( node, BAD_CAST "help_page", BAD_CAST _HelpPage.toString().c_str() );
2089 return node;
2093 xmlNodePtr CGroupContainer::serializeTreeData( xmlNodePtr parentNode ) const
2095 xmlNodePtr node = CInterfaceGroup::serializeTreeData( parentNode );
2096 if( node == NULL )
2097 return NULL;
2099 if( _List == NULL )
2100 return NULL;
2102 CInterfaceGroup *g = NULL;
2103 for( sint32 i = 0; i < _List->getChildrenNb(); i++ )
2105 g = dynamic_cast< CInterfaceGroup* >( _List->getChild( i ) );
2106 if( g == NULL )
2107 continue;
2109 if( g->serializeTreeData( node ) == NULL )
2110 return NULL;
2113 return node;
2116 // ***************************************************************************
2117 bool CGroupContainer::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup)
2119 if (!CInterfaceGroup::parse(cur,parentGroup))
2120 return false;
2121 CXMLAutoPtr ptr;
2123 ptr = xmlGetProp (cur, (xmlChar*)"localize");
2124 if (ptr) _Localize = convertBool((const char*)ptr);
2126 // Type of the view text of the title
2127 ptr = xmlGetProp (cur, (xmlChar*)"title_class");
2128 if (ptr)
2130 _TitleClass = convertTitleClass((const char*)ptr);
2131 // if textid, don't localize, because the title is a DB path
2132 if(_TitleClass==TitleTextId || _TitleClass==TitleTextDynString)
2133 _Localize= false;
2136 // y offset for content
2137 ptr = xmlGetProp (cur, (xmlChar*)"content_y_offset");
2138 if (ptr)
2140 fromString((const char*)ptr, _ContentYOffset);
2143 // text of the title
2144 ptr = xmlGetProp (cur, (xmlChar*)"title");
2145 if (ptr)
2147 _TitleTextOpened = (const char *)ptr;
2148 _TitleTextClosed = (const char *)ptr;
2151 ptr = xmlGetProp (cur, (xmlChar*)"title_opened");
2152 if (ptr)
2154 _TitleTextOpened = (const char*)ptr;
2157 ptr = xmlGetProp (cur, (xmlChar*)"title_closed");
2158 if (ptr)
2160 _TitleTextClosed = (const char *)ptr;
2163 ptr = xmlGetProp (cur, (xmlChar*)"header_active");
2164 if (ptr)
2165 _HeaderActive = convertBool(ptr);
2167 ptr = xmlGetProp (cur, (xmlChar*)"header_color");
2168 if (ptr)
2169 _HeaderColor.link(ptr);
2171 ptr = xmlGetProp (cur, (xmlChar*)"right_button");
2172 if (ptr)
2174 _EnabledRightButton = convertBool(ptr);
2175 // Default; take same state than the right button
2176 _EnabledHelpButton = _EnabledRightButton;
2179 // but user may ovveride this case
2180 ptr = xmlGetProp (cur, (xmlChar*)"help_button");
2181 if (ptr)
2182 _EnabledHelpButton = convertBool(ptr);
2184 ptr = xmlGetProp (cur, (xmlChar*)"movable");
2185 if (ptr)
2186 _Movable = convertBool(ptr);
2188 ptr = xmlGetProp (cur, (xmlChar*)"popable");
2189 if (ptr)
2190 _Popable = convertBool(ptr);
2192 ptr = xmlGetProp (cur, (xmlChar*)"lockable");
2193 if (ptr)
2194 _Lockable = convertBool(ptr);
2196 ptr = xmlGetProp (cur, (xmlChar*)"locked");
2197 if (ptr)
2198 _Locked = convertBool(ptr);
2200 ptr = xmlGetProp (cur, (xmlChar*)"openable");
2201 if (ptr)
2202 _Openable = convertBool(ptr);
2204 ptr = xmlGetProp (cur, (xmlChar*)"opened");
2205 if (ptr)
2206 _OpenAtStart = convertBool(ptr);
2208 ptr = xmlGetProp (cur, (xmlChar*)"modal");
2209 if (ptr)
2210 _Modal = convertBool(ptr);
2212 ptr = xmlGetProp (cur, (xmlChar*)"open_when_popup");
2213 if (ptr)
2215 _OpenWhenPopup = convertBool(ptr);
2216 if (_OpenWhenPopup)
2217 _OpenAtStart = false;
2220 ptr = xmlGetProp (cur, (xmlChar*)"resizer");
2221 if (ptr)
2222 _EnabledResizer = convertBool(ptr);
2224 ptr = xmlGetProp (cur, (xmlChar*)"resizer_top_size");
2225 _ResizerTopSize= -1;
2226 if (ptr)
2227 fromString((const char*)ptr, _ResizerTopSize);
2229 CAHManager::getInstance()->parseAH(cur, "on_open", "on_open_params", _AHOnOpen, _AHOnOpenParams);
2230 CAHManager::getInstance()->parseAH(cur, "on_close", "on_close_params", _AHOnClose, _AHOnCloseParams);
2231 CAHManager::getInstance()->parseAH(cur, "on_close_button", "on_close_button_params", _AHOnCloseButton, _AHOnCloseButtonParams);
2232 CAHManager::getInstance()->parseAH(cur, "on_move", "on_move_params", _AHOnMove, _AHOnMoveParams);
2233 CAHManager::getInstance()->parseAH(cur, "on_deactive_check", "on_deactive_check_params", _AHOnDeactiveCheck, _AHOnDeactiveCheckParams);
2234 CAHManager::getInstance()->parseAH(cur, "on_resize", "on_resize_params", _AHOnResize, _AHOnResizeParams);
2235 CAHManager::getInstance()->parseAH(cur, "on_alpha_settings_changed", "on_alpha_settings_changed_params", _AHOnAlphaSettingsChanged, _AHOnAlphaSettingsChangedParams);
2236 CAHManager::getInstance()->parseAH(cur, "on_begin_move", "on_begin_move_params", _AHOnBeginMove, _AHOnBeginMoveParams);
2239 if( editorMode )
2241 ptr = xmlGetProp( cur, BAD_CAST "on_open" );
2242 if( ptr )
2243 mapAHString( "on_open", std::string( (const char*)ptr ) );
2245 ptr = xmlGetProp( cur, BAD_CAST "on_close" );
2246 if( ptr )
2247 mapAHString( "on_close", std::string( (const char*)ptr ) );
2249 ptr = xmlGetProp( cur, BAD_CAST "on_close_button" );
2250 if( ptr )
2251 mapAHString( "on_close_button", std::string( (const char*)ptr ) );
2253 ptr = xmlGetProp( cur, BAD_CAST "on_move" );
2254 if( ptr )
2255 mapAHString( "on_move", std::string( (const char*)ptr ) );
2257 ptr = xmlGetProp( cur, BAD_CAST "on_deactive_check" );
2258 if( ptr )
2259 mapAHString( "on_deactive_check", std::string( (const char*)ptr ) );
2261 ptr = xmlGetProp( cur, BAD_CAST "on_resize" );
2262 if( ptr )
2263 mapAHString( "on_resize", std::string( (const char*)ptr ) );
2265 ptr = xmlGetProp( cur, BAD_CAST "on_alpha_settings_changed" );
2266 if( ptr )
2267 mapAHString( "on_alpha_settings_changed", std::string( (const char*)ptr ) );
2269 ptr = xmlGetProp( cur, BAD_CAST "on_begin_move" );
2270 if( ptr )
2271 mapAHString( "on_begin_move", std::string( (const char*)ptr ) );
2274 ptr = xmlGetProp (cur, (xmlChar*)"max_w");
2275 if (ptr)
2276 fromString((const char*)ptr, _MaxW);
2277 ptr = xmlGetProp (cur, (xmlChar*)"min_w");
2278 if (ptr)
2279 fromString((const char*)ptr, _MinW);
2281 ptr = xmlGetProp (cur, (xmlChar*)"pop_max_w");
2282 if (ptr)
2283 fromString((const char*)ptr, _PopupMaxW);
2284 ptr = xmlGetProp (cur, (xmlChar*)"pop_min_w");
2285 if (ptr)
2286 fromString((const char*)ptr, _PopupMinW);
2288 ptr = xmlGetProp (cur, (xmlChar*)"pop_max_h");
2289 if (ptr)
2290 fromString((const char*)ptr, _PopupMaxH);
2291 ptr = xmlGetProp (cur, (xmlChar*)"pop_min_h");
2292 if (ptr)
2293 fromString((const char*)ptr, _PopupMinH);
2295 ptr = xmlGetProp (cur, (xmlChar*)"movable_in_parent_list");
2296 if (ptr) _MovableInParentList = convertBool(ptr);
2298 ptr = xmlGetProp (cur, (xmlChar*)"savable");
2299 if (ptr) _Savable = convertBool(ptr);
2301 ptr = xmlGetProp (cur, (xmlChar*)"active_savable");
2302 if (ptr) _ActiveSavable = convertBool(ptr);
2304 ptr = xmlGetProp (cur, (xmlChar*)"modal_parent");
2305 if (ptr) _ModalParentNames = (const char*)ptr;
2307 ptr = xmlGetProp (cur, (xmlChar*)"options");
2308 if (ptr) _OptionsName = (const char*)ptr;
2310 ptr = xmlGetProp (cur, (xmlChar*)"title_delta_max_w");
2311 if (ptr) fromString((const char*)ptr, _TitleDeltaMaxW);
2313 ptr = xmlGetProp (cur, (xmlChar*)"title_over_extend_view_text");
2314 _TitleOverExtendViewText= false;
2315 if (ptr) _TitleOverExtendViewText = convertBool(ptr);
2318 ptr = xmlGetProp (cur, (xmlChar*)"help_page");
2319 if (ptr) _HelpPage = (const char*)ptr;
2321 _RefW = _W;
2322 return true;
2325 // ***************************************************************************
2326 void CGroupContainer::updateCoords()
2328 if (_Mover && _Mover->isMovingInParentList())
2330 // must clamp by parent coords, now it has been updated
2331 CGroupList *gl = getPreviousParentList();
2332 if (gl)
2334 sint32 cx, cy, cw, ch;
2335 gl->getClip(cx, cy, cw, ch);
2336 sint32 currYReal = getYReal();
2337 clamp(currYReal, cy, cy + ch - getHReal());
2338 if (currYReal != getYReal())
2340 setY(getY() + currYReal - getYReal());
2345 setup();
2347 bool bHasChild = (_List->getNbElement() > 0);
2349 // clamp popupmaxh if resizemax mode
2350 if ((_LayerSetup == 0) && bHasChild && _EnabledResizer)
2352 // Clip by screen
2353 uint32 sw, sh;
2354 CViewRenderer &vr = *CViewRenderer::getInstance();
2355 vr.getScreenSize(sw, sh);
2356 // ensure the maxH is > minH and < sh (prioritary > minH, in case of sh<minh)
2357 _PopupMaxH= min(_PopupMaxH, (sint32)sh);
2358 _PopupMaxH= max(_PopupMaxH, _PopupMinH);
2361 // clamp w/h if standard resizer
2362 if ((_LayerSetup == 0) && (!bHasChild) && _EnabledResizer)
2364 clamp(_W, _PopupMinW, _PopupMaxW);
2365 clamp(_H, _PopupMinH, _PopupMaxH);
2366 // Clip by screen (but minw/minh is prioritary)
2367 uint32 sw, sh;
2368 CViewRenderer &vr = *CViewRenderer::getInstance();
2369 vr.getScreenSize(sw, sh);
2370 if((sint32)sw>_PopupMinW && _W>(sint32)sw) _W= sw;
2371 if((sint32)sh>_PopupMinH && _H>(sint32)sh) _H= sh;
2374 COptionsLayer *pLayer = getContainerOptions();
2375 sint32 newH = 0;
2377 // Get base header size
2378 if (_LayerSetup == 0)
2380 setMaxH(_PopupMaxH);
2381 // _W is given by scripter-man
2382 newH = (pLayer->H_T - pLayer->InsetT);
2384 else
2386 if (_SizeRef & 1)
2388 _W = _Parent->getW();
2390 setMaxH (std::numeric_limits<sint32>::max()); // No scrollbar for container of layer > 0
2391 newH = (pLayer->H_T - pLayer->InsetT);
2394 if (_Opened)
2396 if (_HeaderOpened != NULL)
2398 if (_HeaderOpened->getPosRef()&Hotspot_xR)
2399 _HeaderOpened->setX (-pLayer->W_R);
2400 if (_HeaderOpened->getPosRef()&Hotspot_xL)
2401 _HeaderOpened->setX (pLayer->W_L);
2402 _HeaderOpened->setY (- newH);
2403 _HeaderOpened->setW (_W-(pLayer->W_L+pLayer->W_R));
2404 _HeaderOpened->updateCoords();
2405 newH += max (_HeaderOpened->getHReal(), pLayer->HeaderH);
2407 else
2409 newH += pLayer->HeaderH;
2412 newH -= (sint32) _ContentYOffset;
2414 // Calculate content size part
2415 if (_Content != NULL)
2417 if (_Content->getPosRef()&Hotspot_xR)
2418 _Content->setX (-pLayer->W_R);
2419 else if (_Content->getPosRef()&Hotspot_xL)
2420 _Content->setX (pLayer->W_L);
2421 _Content->setY (-newH);
2422 _Content->setW (-(pLayer->W_L+pLayer->W_R));
2423 if ((bHasChild) || (!_EnabledResizer) || (_LayerSetup>0)) // Content is constant in H
2425 _Content->setSizeRef (1); // w
2426 _Content->updateCoords();
2427 newH += _Content->getHReal();
2429 else
2431 _Content->setSizeRef (3); // wh
2432 _Content->setH (-newH - pLayer->H_B); // Sub header and top, bottom bitmaps
2436 if (bHasChild)
2437 newH += pLayer->H_B_Open;
2438 else
2439 newH += pLayer->H_B;
2441 if (_LayerSetup == 0)
2443 _List->setX (pLayer->W_M_Open);
2444 _ScrollBar->setX (pLayer->Scrollbar_Offset_X);
2445 _ScrollBar->setY(-newH);
2447 else
2449 _List->setX (0);
2451 _List->setY (-newH);
2453 // Calculate list max height if top container
2454 if (_LayerSetup == 0)
2456 // zeH is the height to substract to total height of the container to obtain height of the list
2457 sint32 zeH = (pLayer->H_T - pLayer->InsetT) + pLayer->H_B_Open + pLayer->H_EM_Open;
2459 if (_HeaderOpened != NULL)
2460 zeH += max (_HeaderOpened->getHReal(), pLayer->HeaderH);
2461 else
2462 zeH += pLayer->HeaderH;
2464 if (_Content != NULL)
2465 zeH += _Content->getHReal();
2467 if (_List != NULL)
2468 _List->setMaxH (max((sint32)0, _MaxH-zeH));
2470 else
2472 if (_List != NULL)
2473 _List->setMaxH (std::numeric_limits<sint32>::max());
2476 if (_LayerSetup == 0)
2478 _List->forceSizeW(_W - (pLayer->W_M_Open + pLayer->W_R) );
2480 else
2482 _List->forceSizeW(_W);
2486 //CInterfaceElement::updateCoords();
2487 CInterfaceGroup::updateCoords();
2489 newH += ((_List->getHReal() < _List->getMaxH()) ? _List->getHReal() : _List->getMaxH());
2491 if (_LayerSetup == 0)
2493 if ((!bHasChild) || (_List->getHReal() < _List->getMaxH()))
2494 _ScrollBar->setActive (false);
2495 else
2496 _ScrollBar->setActive (true);
2499 if (_LayerSetup == 0)
2501 if (_List->getNbElement() > 0)
2503 newH += pLayer->H_EM_Open;
2507 if ((bHasChild) || (!_EnabledResizer) || (_LayerSetup>0)) // H is depending on the header and content and list
2508 _H = newH;
2511 else // Closed
2513 if (_HeaderClosed != NULL)
2515 if (_HeaderClosed->getPosRef()&Hotspot_xR)
2516 _HeaderClosed->setX (-pLayer->W_R);
2517 else if (_HeaderClosed->getPosRef()&Hotspot_xL)
2518 _HeaderClosed->setX (pLayer->W_L);
2519 _HeaderClosed->setY (-newH);
2520 _HeaderClosed->setW (_W-(pLayer->W_L+pLayer->W_R));
2521 _HeaderClosed->updateCoords();
2522 newH += max (_HeaderClosed->getHReal(), pLayer->HeaderH);
2524 else
2526 newH += pLayer->HeaderH;
2528 newH += pLayer->H_B;
2530 if ((bHasChild) || (!_EnabledResizer) || (_LayerSetup>0)) // H is depending on the header and content and list
2531 _H = newH;
2533 CInterfaceGroup::updateCoords();
2537 if (_Mover != NULL)
2539 _Mover->setW (_W+_MoverDeltaW);
2540 _Mover->updateCoords();
2543 // Set MaxW for title according to current Container Width
2544 _TitleOpened->setLineMaxW(_W + _TitleDeltaMaxW);
2545 _TitleClosed->setLineMaxW(_W + _TitleDeltaMaxW);
2547 _TitleOpened->updateCoords();
2548 _TitleClosed->updateCoords();
2549 if (_ViewOpenState != NULL) _ViewOpenState->updateCoords();
2550 if (_RightButton != NULL) _RightButton->updateCoords();
2551 if (_HelpButton != NULL) _HelpButton->updateCoords();
2552 if (_ScrollBar != NULL) _ScrollBar->updateCoords();
2553 if (_Content != NULL) _Content->updateCoords();
2554 if (_HeaderClosed != NULL) _HeaderClosed->updateCoords();
2555 if (_HeaderOpened != NULL) _HeaderOpened->updateCoords();
2557 CInterfaceElement::updateCoords();
2559 if (_LayerSetup == 0)
2561 // test if must clip
2562 uint32 wScreen, hScreen;
2563 CViewRenderer::getInstance()->getScreenSize(wScreen, hScreen);
2564 if (_WReal <= (sint32) wScreen && _HReal <= (sint32) hScreen)
2566 sint32 newX = _XReal;
2567 sint32 newY = _YReal;
2568 clamp(newX, 0, (sint32)wScreen - _WReal);
2569 clamp(newY, 0, (sint32)hScreen - _HReal);
2570 if (newX != _XReal || newY != _YReal)
2572 setX(_X + newX - _XReal);
2573 setY(_Y + newY - _YReal);
2574 CInterfaceGroup::updateCoords();
2579 // resizers
2580 for(uint k = 0; k < NumResizers; ++k)
2582 if (_Resizer[k]) updateResizerSize(_Resizer[k]);
2586 // ***************************************************************************
2587 void CGroupContainer::updateResizerSize(CCtrlResizer *cr)
2589 COptionsContainerMove *options = getMoveOptions();
2590 if (!options) return;
2592 // Yoyo: The +1 stuff is important, maybe because of the HotSpot MiddleMiddle style...
2594 // Choose H
2595 if (!(cr->getResizerPos() & Hotspot_Tx) && !(cr->getResizerPos() & Hotspot_Bx))
2597 // if no special topH size
2598 if(_ResizerTopSize<0)
2599 cr->setH (_H - 2 * options->ResizerSize + 1); // Bottom and Top same value
2600 else
2601 cr->setH (_H - options->ResizerSize - _ResizerTopSize + 1); // Top different from bottom
2603 else
2605 // if no special topH size, or if the resizer is not the top one
2606 if(_ResizerTopSize<0 || !(cr->getResizerPos() & Hotspot_Tx))
2607 cr->setH(options->ResizerSize + 1);
2608 else
2609 cr->setH(_ResizerTopSize + 1);
2612 // Choose W
2613 if (!(cr->getResizerPos() & Hotspot_xR) && !(cr->getResizerPos() & Hotspot_xL))
2615 cr->setW (_W - 2 * options->ResizerSize + 1);
2617 else
2619 cr->setW(options->ResizerSize + 1);
2622 // update coordinate
2623 cr->updateCoords();
2626 // ***************************************************************************
2627 void CGroupContainer::draw ()
2629 H_AUTO( RZ_Interface_CGroupContainer_draw )
2631 if (_LayerSetup == -1) return;
2633 float speed = CWidgetManager::getInstance()->getAlphaRolloverSpeed();
2634 const CWidgetManager::SInterfaceTimes &times = CWidgetManager::getInstance()->getInterfaceTimes();
2636 CRGBA oldGlobalColor = CWidgetManager::getInstance()->getGlobalColor();
2637 CRGBA oldGColForGrayed = CWidgetManager::getInstance()->getGlobalColor();
2638 if (_Blinking)
2640 const uint blinkDuration = 300;
2641 if (((_BlinkDT / 300) & 1) == 0)
2643 CRGBA newCol = oldGlobalColor;
2644 clamp(newCol.R, 64, 192);
2645 clamp(newCol.G, 64, 192);
2646 clamp(newCol.B, 64, 192);
2647 newCol.R = ~newCol.R;
2648 newCol.G = ~newCol.G;
2649 newCol.B = ~newCol.B;
2650 if (abs(newCol.R - oldGlobalColor.R) < 64) newCol.R = 192;
2651 if (abs(newCol.G - oldGlobalColor.G) < 64) newCol.G = 192;
2652 if (abs(newCol.B - oldGlobalColor.B) < 64) newCol.B = 192;
2653 CWidgetManager::getInstance()->setGlobalColor(newCol);
2654 _BlinkState = true;
2656 else
2658 if (_BlinkState) // was previously on ?
2660 if (_NumBlinks != 0) // if dont blink for ever
2662 -- _NumBlinks;
2663 if (_NumBlinks == 0)
2665 disableBlink();
2669 _BlinkState = false;
2671 _BlinkDT += std::min((uint) times.frameDiffMs, blinkDuration);
2674 CGroupContainer *parentGC = NULL;
2675 if (getParent() && getParent()->getParent())
2677 if (getParent()->getParent()->isGroupContainer())
2679 parentGC = static_cast<CGroupContainer *>(getParent()->getParent());
2683 sint32 oldSciX, oldSciY, oldSciW, oldSciH;
2684 makeNewClip (oldSciX, oldSciY, oldSciW, oldSciH);
2686 // Draw the container
2687 CViewRenderer &rVR = *CViewRenderer::getInstance();
2688 CRGBA col = CWidgetManager::getInstance()->getGlobalColor();
2690 bool bGrayed = isGrayed();
2691 if (bGrayed)
2693 col.R = col.R / 2;
2694 col.G = col.G / 2;
2695 col.B = col.B / 2;
2696 CWidgetManager::getInstance()->setGlobalColor(col);
2697 oldGlobalColor.R = oldGlobalColor.R / 2;
2698 oldGlobalColor.G = oldGlobalColor.G / 2;
2699 oldGlobalColor.B = oldGlobalColor.B / 2;
2702 if (_MovingInParentList)
2704 // display half tone when moving in parent
2705 col.A >>= 1;
2707 // if the father is a group container, do modulation too
2708 if (parentGC)
2710 // _CurrentContainerAlpha = (uint8) (((uint16) parentGC->getCurrentContainerAlpha() * (uint16) _ContainerAlpha) >> 8);
2711 _CurrentContainerAlpha = parentGC->getCurrentContainerAlpha();
2713 else
2715 _CurrentContainerAlpha = _UseGlobalAlpha ? CWidgetManager::getInstance()->getGlobalContainerAlpha() : _ContainerAlpha;
2717 // modulate by container alpha color
2718 col.A = (uint8) (((uint16) _CurrentContainerAlpha * (uint16) col.A) >> 8);
2719 // Modulate by parent rollover
2720 if (parentGC)
2722 // _ICurrentRolloverAlpha = (uint8) (((uint16) parentGC->_ICurrentRolloverAlpha * (uint16) _ICurrentRolloverAlpha) >> 8);
2723 _ICurrentRolloverAlphaContent = parentGC->_ICurrentRolloverAlphaContent;
2724 _ICurrentRolloverAlphaContainer = parentGC->_ICurrentRolloverAlphaContainer;
2726 else
2728 uint8 rolloverFactorContent = _UseGlobalAlpha ? (255 - CWidgetManager::getInstance()->getGlobalRolloverFactorContent()) : _RolloverAlphaContent;
2729 _ICurrentRolloverAlphaContent = (uint8) (255 - rolloverFactorContent + rolloverFactorContent * _CurrentRolloverAlphaContent);
2730 uint8 rolloverFactorContainer = _UseGlobalAlpha ? (255 - CWidgetManager::getInstance()->getGlobalRolloverFactorContainer()) : _RolloverAlphaContainer;
2731 _ICurrentRolloverAlphaContainer = (uint8) (255 - rolloverFactorContainer + rolloverFactorContainer * _CurrentRolloverAlphaContainer);
2733 // Modulate alpha by rollover alpha
2734 col.A = (uint8) (((uint16) _ICurrentRolloverAlphaContainer * (uint16) col.A) >> 8);
2736 COptionsLayer *pLayer = getContainerOptions();
2737 // h is the size of what is on top of the child list
2738 sint32 x, y, w, h;
2740 bool bHasChild = (_List->getNbElement() > 0);
2741 h = (pLayer->H_T - pLayer->InsetT) + (((!_Opened) || (!bHasChild)) ? pLayer->H_B : pLayer->H_B_Open);
2743 if (_Opened)
2745 if (_HeaderOpened != NULL)
2746 h += max (_HeaderOpened->getHReal(), pLayer->HeaderH);
2747 else
2748 h += pLayer->HeaderH;
2750 if (_Content != NULL)
2751 h += _Content->getHReal();
2753 if (_List != NULL)
2754 h += _List->getHReal();
2756 h -= _ContentYOffset;
2758 else
2760 h = _HReal;
2763 x = _XReal;
2764 y = _YReal+_HReal-h;
2765 w = _WReal;
2766 sint8 rl = _RenderLayer;
2767 if (_LayerSetup == 0)
2769 // Top Left
2770 rVR.drawRotFlipBitmap (rl, x, y+h-pLayer->H_TL, pLayer->W_TL, pLayer->H_TL, 0, false, pLayer->TxId_TL, col);
2771 // Top
2772 if (pLayer->Tile_T == 0) // Tiling ?
2773 rVR.drawRotFlipBitmap (rl, x+pLayer->W_TL, y+h-pLayer->H_T, w-(pLayer->W_TL+pLayer->W_TR), pLayer->H_T, 0, false, pLayer->TxId_T, col);
2774 else
2775 rVR.drawRotFlipBitmapTiled (rl, x+pLayer->W_TL, y+h-pLayer->H_T, w-(pLayer->W_TL+pLayer->W_TR), pLayer->H_T, 0, false, pLayer->TxId_T, pLayer->Tile_T-1, col);
2776 // Top Right
2777 rVR.drawRotFlipBitmap (rl, x+w-pLayer->W_TR, y+h-pLayer->H_TR, pLayer->W_TR, pLayer->H_TR, 0, false, pLayer->TxId_TR, col);
2779 if ((!_Opened) || (!bHasChild))
2780 { // Not opened
2781 // Left
2782 if (pLayer->Tile_L == 0) // Tiling ?
2783 rVR.drawRotFlipBitmap (rl, x, y+pLayer->H_BL, pLayer->W_L, h-(pLayer->H_BL+pLayer->H_TL), 0, false, pLayer->TxId_L, col);
2784 else
2785 rVR.drawRotFlipBitmapTiled (rl, x, y+pLayer->H_BL, pLayer->W_L, h-(pLayer->H_BL+pLayer->H_TL), 0, false, pLayer->TxId_L, pLayer->Tile_L-1, col);
2786 // Right
2787 if (pLayer->Tile_R == 0) // Tiling ?
2788 rVR.drawRotFlipBitmap (rl, x+w-pLayer->W_R, y+pLayer->H_BR, pLayer->W_R, h-(pLayer->H_TR+pLayer->H_BR), 0, false, pLayer->TxId_R, col);
2789 else
2790 rVR.drawRotFlipBitmapTiled (rl, x+w-pLayer->W_R, y+pLayer->H_BR, pLayer->W_R, h-(pLayer->H_TR+pLayer->H_BR), 0, false, pLayer->TxId_R, pLayer->Tile_R-1, col);
2791 // Bottom Left
2792 rVR.drawRotFlipBitmap (rl, x, y, pLayer->W_BL, pLayer->H_BL, 0, false, pLayer->TxId_BL, col);
2793 // Bottom
2794 if (pLayer->Tile_B == 0) // Tiling ?
2795 rVR.drawRotFlipBitmap (rl, x+pLayer->W_BL, y, w-(pLayer->W_BL+pLayer->W_BR), pLayer->H_B, 0, false, pLayer->TxId_B, col);
2796 else
2797 rVR.drawRotFlipBitmapTiled (rl, x+pLayer->W_BL, y, w-(pLayer->W_BL+pLayer->W_BR), pLayer->H_B, 0, false, pLayer->TxId_B, pLayer->Tile_B-1, col);
2798 // Bottom Right
2799 rVR.drawRotFlipBitmap (rl, x+w-pLayer->W_BR, y, pLayer->W_BR, pLayer->H_BR, 0, false, pLayer->TxId_BR, col);
2800 // Content
2801 if (pLayer->Tile_Blank == 0) // Tiling ?
2802 rVR.drawRotFlipBitmap (rl, x+pLayer->W_L, y+pLayer->H_B, w-(pLayer->W_R+pLayer->W_L), h-(pLayer->H_B+pLayer->H_T), 0, false, pLayer->TxId_Blank, col);
2803 else
2804 rVR.drawRotFlipBitmapTiled (rl, x+pLayer->W_L, y+pLayer->H_B, w-(pLayer->W_R+pLayer->W_L), h-(pLayer->H_B+pLayer->H_T), 0, false, pLayer->TxId_Blank, pLayer->Tile_Blank-1, col);
2806 else
2807 { // Opened
2808 // Left
2809 if (pLayer->Tile_L == 0) // Tiling ?
2810 rVR.drawRotFlipBitmap (rl, x, y+pLayer->H_BL_Open, pLayer->W_L, h-(pLayer->H_BL_Open+pLayer->H_TL), 0, false, pLayer->TxId_L, col);
2811 else
2812 rVR.drawRotFlipBitmapTiled (rl, x, y+pLayer->H_BL_Open, pLayer->W_L, h-(pLayer->H_BL_Open+pLayer->H_TL), 0, false, pLayer->TxId_L, pLayer->Tile_L-1, col);
2813 // Right
2814 if (pLayer->Tile_R == 0) // Tiling ?
2815 rVR.drawRotFlipBitmap (rl, x+w-pLayer->W_R, y+pLayer->H_BR_Open, pLayer->W_R, h-(pLayer->H_TR+pLayer->H_BR_Open), 0, false, pLayer->TxId_R, col);
2816 else
2817 rVR.drawRotFlipBitmapTiled (rl, x+w-pLayer->W_R, y+pLayer->H_BR_Open, pLayer->W_R, h-(pLayer->H_TR+pLayer->H_BR_Open), 0, false, pLayer->TxId_R, pLayer->Tile_R-1, col);
2818 // Bottom Left
2819 rVR.drawRotFlipBitmap (rl, x, y, pLayer->W_BL_Open, pLayer->H_BL_Open, 0, false, pLayer->TxId_BL_Open, col);
2820 // Bottom
2821 if (pLayer->Tile_B_Open == 0) // Tiling ?
2822 rVR.drawRotFlipBitmap (rl, x+pLayer->W_BL_Open, y, w-(pLayer->W_BL_Open+pLayer->W_BR_Open), pLayer->H_B_Open, 0, false, pLayer->TxId_B_Open, col);
2823 else
2824 rVR.drawRotFlipBitmapTiled (rl, x+pLayer->W_BL_Open, y, w-(pLayer->W_BL_Open+pLayer->W_BR_Open), pLayer->H_B_Open, 0, false, pLayer->TxId_B_Open, pLayer->Tile_B_Open-1, col);
2825 // Bottom Right
2826 rVR.drawRotFlipBitmap (rl, x+w-pLayer->W_BR_Open, y, pLayer->W_BR_Open, pLayer->H_BR_Open, 0, false, pLayer->TxId_BR_Open, col);
2827 // Content
2828 if (pLayer->Tile_Blank == 0) // Tiling ?
2829 rVR.drawRotFlipBitmap (rl, x+pLayer->W_L, y+pLayer->H_B_Open, w-(pLayer->W_R+pLayer->W_L), h-(pLayer->H_B_Open+pLayer->H_T), 0, false, pLayer->TxId_Blank, col);
2830 else
2831 rVR.drawRotFlipBitmapTiled (rl, x+pLayer->W_L, y+pLayer->H_B_Open, w-(pLayer->W_R+pLayer->W_L), h-(pLayer->H_B_Open+pLayer->H_T), 0, false, pLayer->TxId_Blank, pLayer->Tile_Blank-1, col);
2832 // ScrollBar Placement
2833 if (pLayer->Tile_M_Open == 0) // Tiling ?
2834 rVR.drawRotFlipBitmap (rl, x, _YReal+pLayer->H_EL_Open, pLayer->W_M_Open, _HReal-h-pLayer->H_EL_Open, 0, false, pLayer->TxId_M_Open, col);
2835 else
2836 rVR.drawRotFlipBitmapTiled (rl, x, _YReal+pLayer->H_EL_Open, pLayer->W_M_Open, _HReal-h-pLayer->H_EL_Open, 0, false, pLayer->TxId_M_Open, pLayer->Tile_M_Open-1, col);
2837 // Ending Left
2838 rVR.drawRotFlipBitmap (rl, x, _YReal, pLayer->W_EL_Open, pLayer->H_EL_Open, 0, false, pLayer->TxId_EL_Open, col);
2839 // Ending Middle
2840 if (pLayer->Tile_EM_Open == 0) // Tiling ?
2841 rVR.drawRotFlipBitmap (rl, x+pLayer->W_EL_Open, _YReal, w-(pLayer->W_EL_Open+pLayer->W_ER_Open), pLayer->H_EM_Open, 0, false, pLayer->TxId_EM_Open, col);
2842 else
2843 rVR.drawRotFlipBitmapTiled (rl, x+pLayer->W_EL_Open, _YReal, w-(pLayer->W_EL_Open+pLayer->W_ER_Open), pLayer->H_EM_Open, 0, false, pLayer->TxId_EM_Open, pLayer->Tile_EM_Open-1, col);
2844 // Ending Right
2845 rVR.drawRotFlipBitmap (rl, x+w-pLayer->W_ER_Open, _YReal, pLayer->W_ER_Open, pLayer->H_ER_Open, 0, false, pLayer->TxId_ER_Open, col);
2848 else // Version for layer 1,2,3
2850 // Top Left
2851 rVR.drawRotFlipBitmap (rl, x, y+h-pLayer->H_TL, pLayer->W_TL, pLayer->H_TL, 0, false, pLayer->TxId_TL, col);
2852 // Top
2853 if (pLayer->Tile_T == 0) // Tiling ?
2854 rVR.drawRotFlipBitmap (rl, x+pLayer->W_TL, y+h-pLayer->H_T, w-(pLayer->W_TL+pLayer->W_TR), pLayer->H_T, 0, false, pLayer->TxId_T, col);
2855 else
2856 rVR.drawRotFlipBitmapTiled (rl, x+pLayer->W_TL, y+h-pLayer->H_T, w-(pLayer->W_TL+pLayer->W_TR), pLayer->H_T, 0, false, pLayer->TxId_T, pLayer->Tile_T-1, col);
2857 // Top Right
2858 rVR.drawRotFlipBitmap (rl, x+w-pLayer->W_TR, y+h-pLayer->H_TR, pLayer->W_TR, pLayer->H_TR, 0, false, pLayer->TxId_TR, col);
2860 if ((!_Opened) || (!bHasChild))
2862 // Left
2863 if (pLayer->Tile_L == 0) // Tiling ?
2864 rVR.drawRotFlipBitmap (rl, x, y+pLayer->H_BL, pLayer->W_L, h-(pLayer->H_BL+pLayer->H_TL), 0, false, pLayer->TxId_L, col);
2865 else
2866 rVR.drawRotFlipBitmapTiled (rl, x, y+pLayer->H_BL, pLayer->W_L, h-(pLayer->H_BL+pLayer->H_TL), 0, false, pLayer->TxId_L, pLayer->Tile_L-1, col);
2867 // Right
2868 if (pLayer->Tile_R == 0) // Tiling ?
2869 rVR.drawRotFlipBitmap (rl, x+w-pLayer->W_R, y+pLayer->H_BR, pLayer->W_R, h-(pLayer->H_BL+pLayer->H_TL), 0, false, pLayer->TxId_R, col);
2870 else
2871 rVR.drawRotFlipBitmapTiled (rl, x+w-pLayer->W_R, y+pLayer->H_BR, pLayer->W_R, h-(pLayer->H_BL+pLayer->H_TL), 0, false, pLayer->TxId_R, pLayer->Tile_R-1, col);
2872 // Bottom Left
2873 rVR.drawRotFlipBitmap (rl, x, y, pLayer->W_BL, pLayer->H_BL, 0, false, pLayer->TxId_BL, col);
2874 // Bottom
2875 if (pLayer->Tile_B == 0) // Tiling ?
2876 rVR.drawRotFlipBitmap (rl, x+pLayer->W_BL, y, w-(pLayer->W_BL+pLayer->W_BR), pLayer->H_B, 0, false, pLayer->TxId_B, col);
2877 else
2878 rVR.drawRotFlipBitmapTiled (rl, x+pLayer->W_BL, y, w-(pLayer->W_BL+pLayer->W_BR), pLayer->H_B, 0, false, pLayer->TxId_B, pLayer->Tile_B-1, col);
2879 // Bottom Right
2880 rVR.drawRotFlipBitmap (rl, x+w-pLayer->W_BR, y, pLayer->W_BR, pLayer->H_BR, 0, false, pLayer->TxId_BR, col);
2881 // Content
2882 if (pLayer->Tile_Blank == 0) // Tiling ?
2883 rVR.drawRotFlipBitmap (rl, x+pLayer->W_L, y+pLayer->H_B, w-(pLayer->W_L+pLayer->W_R), h-(pLayer->H_B+pLayer->H_T), 0, false, pLayer->TxId_Blank, col);
2884 else
2885 rVR.drawRotFlipBitmapTiled (rl, x+pLayer->W_L, y+pLayer->H_B, w-(pLayer->W_L+pLayer->W_R), h-(pLayer->H_B+pLayer->H_T), 0, false, pLayer->TxId_Blank, pLayer->Tile_Blank-1, col);
2887 else
2889 // Left
2890 if (pLayer->Tile_L == 0) // Tiling ?
2891 rVR.drawRotFlipBitmap (rl, x, y+pLayer->H_BL_Open, pLayer->W_L, h-(pLayer->H_BL_Open+pLayer->H_TL), 0, false, pLayer->TxId_L, col);
2892 else
2893 rVR.drawRotFlipBitmapTiled (rl, x, y+pLayer->H_BL_Open, pLayer->W_L, h-(pLayer->H_BL_Open+pLayer->H_TL), 0, false, pLayer->TxId_L, pLayer->Tile_L-1, col);
2894 // Right
2895 if (pLayer->Tile_R == 0) // Tiling ?
2896 rVR.drawRotFlipBitmap (rl, x+w-pLayer->W_R, y+pLayer->H_BR_Open, pLayer->W_R, h-(pLayer->H_TR+pLayer->H_BR_Open), 0, false, pLayer->TxId_R, col);
2897 else
2898 rVR.drawRotFlipBitmapTiled (rl, x+w-pLayer->W_R, y+pLayer->H_BR_Open, pLayer->W_R, h-(pLayer->H_TR+pLayer->H_BR_Open), 0, false, pLayer->TxId_R, pLayer->Tile_R-1, col);
2899 // Bottom Left
2900 rVR.drawRotFlipBitmap (rl, x, y, pLayer->W_BL_Open, pLayer->H_BL_Open, 0, false, pLayer->TxId_BL_Open, col);
2901 // Bottom
2902 if (pLayer->Tile_B_Open == 0) // Tiling ?
2903 rVR.drawRotFlipBitmap (rl, x+pLayer->W_BL_Open, y, w-(pLayer->W_BL_Open+pLayer->W_BR_Open), pLayer->H_B_Open, 0, false, pLayer->TxId_B_Open, col);
2904 else
2905 rVR.drawRotFlipBitmapTiled (rl, x+pLayer->W_BL_Open, y, w-(pLayer->W_BL_Open+pLayer->W_BR_Open), pLayer->H_B_Open, 0, false, pLayer->TxId_B_Open, pLayer->Tile_B_Open-1, col);
2906 // Bottom Right
2907 rVR.drawRotFlipBitmap (rl, x+w-pLayer->W_BR_Open, y, pLayer->W_BR_Open, pLayer->H_BR_Open, 0, false, pLayer->TxId_BR_Open, col);
2908 // Content
2909 if (pLayer->Tile_Blank == 0)
2910 rVR.drawRotFlipBitmap (rl, x+pLayer->W_L, y+pLayer->H_B_Open, w-(pLayer->W_L+pLayer->W_R), h-(pLayer->H_B_Open+pLayer->H_T), 0, false, pLayer->TxId_Blank, col);
2911 else
2912 rVR.drawRotFlipBitmapTiled (rl, x+pLayer->W_L, y+pLayer->H_B_Open, w-(pLayer->W_L+pLayer->W_R), h-(pLayer->H_B_Open+pLayer->H_T), 0, false, pLayer->TxId_Blank, pLayer->Tile_Blank-1, col);
2917 if (_Blinking)
2919 CWidgetManager::getInstance()->setGlobalColor(oldGlobalColor);
2922 // Top window : title is highlighted
2923 if (_LayerSetup == 0)
2925 CRGBA c = CRGBA(255,255,255,255);
2926 // Display the header in white if we are the last clicked window
2927 if (CWidgetManager::getInstance()->getTopWindow(CWidgetManager::getInstance()->getLastTopWindowPriority()) != this)
2929 if (_HeaderColor.getNodePtr() != NULL)
2930 c = _HeaderColor.getRGBA();
2931 if (bGrayed)
2933 c.R = c.R / 2;
2934 c.G = c.G / 2;
2935 c.B = c.B / 2;
2937 c.A = 255;
2939 if (_TitleClosed != NULL) _TitleClosed->setColor(c);
2940 if (_TitleOpened != NULL) _TitleOpened->setColor(c);
2941 if (_ViewOpenState != NULL) _ViewOpenState->setColor(c);
2942 if (_RightButton != NULL)
2944 _RightButton->setColor(c);
2945 _RightButton->setColorPushed(c);
2946 _RightButton->setColorOver(c);
2948 if (_HelpButton != NULL)
2950 _HelpButton->setColor(c);
2951 _HelpButton->setColorPushed(c);
2952 _HelpButton->setColorOver(c);
2956 // Render inside window
2958 uint8 oldAlphaContent = CWidgetManager::getInstance()->getContentAlpha();
2959 uint8 oldAlphaContainer = _CurrentContainerAlpha;
2960 if (parentGC)
2962 // _CurrentContentAlpha = (uint8) (((uint16) _ContentAlpha * (uint16) parentGC->getCurrentContentAlpha()) >> 8);
2963 _CurrentContentAlpha = parentGC->getCurrentContentAlpha();
2964 _CurrentContainerAlpha = parentGC->getCurrentContainerAlpha();
2966 else
2968 _CurrentContentAlpha = _UseGlobalAlpha ? CWidgetManager::getInstance()->getGlobalContentAlpha() : _ContentAlpha;
2969 _CurrentContainerAlpha = _UseGlobalAlpha ? CWidgetManager::getInstance()->getGlobalContainerAlpha() : _ContainerAlpha;
2971 // set content alpha multiplied by rollover alpha
2972 CWidgetManager::getInstance()->setContentAlpha((uint8) (((uint16) _CurrentContentAlpha * (uint16) _ICurrentRolloverAlphaContent) >> 8));
2973 // set content alpha multiplied by rollover alpha
2974 _CurrentContainerAlpha = (uint8) (((uint16) _CurrentContainerAlpha * (uint16) _ICurrentRolloverAlphaContainer) >> 8);
2976 // Display the color title bar (if the header is active)
2977 if (_LayerSetup == 0)
2979 if (_HeaderActive)
2981 CRGBA c(255,255,255,255);
2982 if (_HeaderColor.getNodePtr() != NULL)
2983 c = _HeaderColor.getRGBA();
2984 if (bGrayed)
2986 c.R = c.R / 2;
2987 c.G = c.G / 2;
2988 c.B = c.B / 2;
2990 c.A = (uint8) (((uint16) _CurrentContentAlpha * (uint16) _ICurrentRolloverAlphaContent) >> 8);
2991 // Left
2992 rVR.drawRotFlipBitmap (rl, x, y+h-pLayer->H_L_Header, pLayer->W_L_Header, pLayer->H_L_Header, 0, false, pLayer->TxId_L_Header, c);
2993 // Middle
2994 if (pLayer->Tile_M_Header == 0) // Tiling ?
2995 rVR.drawRotFlipBitmap (rl, x+pLayer->W_L_Header, y+h-pLayer->H_M_Header, w-(pLayer->W_L_Header+pLayer->W_R_Header), pLayer->H_M_Header, 0, false, pLayer->TxId_M_Header, c);
2996 else
2997 rVR.drawRotFlipBitmapTiled (rl, x+pLayer->W_L_Header, y+h-pLayer->H_M_Header, w-(pLayer->W_L_Header+pLayer->W_R_Header), pLayer->H_M_Header, 0, false, pLayer->TxId_M_Header, pLayer->Tile_M_Header-1, c);
2998 // Right
2999 rVR.drawRotFlipBitmap (rl, x+w-pLayer->W_R_Header, y+h-pLayer->H_R_Header, pLayer->W_R_Header, pLayer->H_R_Header, 0, false, pLayer->TxId_R_Header, c);
3004 CInterfaceGroup::draw();
3007 if (_LayerSetup == 0)
3008 if ((_HighLighted) || (_CurrentContainerAlpha <= 128))
3010 uint8 nInverted = (128-_CurrentContainerAlpha)/2;
3011 if (!_HighLighted)
3012 col.A = nInverted;
3013 else
3014 col.A = max(_HighLightedAlpha, nInverted);
3015 // corners
3016 rVR.drawRotFlipBitmap (_RenderLayer, x, y + h - pLayer->H_T_HighLight, pLayer->W_TL_HighLight, pLayer->H_TL_HighLight, 0, false, pLayer->TxId_TL_HighLight, col);
3017 rVR.drawRotFlipBitmap (_RenderLayer, x + _WReal - pLayer->W_TR_HighLight, y + h - pLayer->H_T_HighLight, pLayer->W_TR_HighLight, pLayer->H_TR_HighLight, 0, false, pLayer->TxId_TR_HighLight, col);
3018 rVR.drawRotFlipBitmap (_RenderLayer, x, _YReal, pLayer->W_BL_HighLight, pLayer->H_BL_HighLight, 0, false, pLayer->TxId_BL_HighLight, col);
3019 rVR.drawRotFlipBitmap (_RenderLayer, x + _WReal - pLayer->W_BR_HighLight, _YReal, pLayer->W_BR_HighLight, pLayer->H_BR_HighLight, 0, false, pLayer->TxId_BR_HighLight, col);
3020 // border
3021 rVR.drawRotFlipBitmap (_RenderLayer, x + pLayer->W_TL_HighLight, y + h - pLayer->H_T_HighLight, _WReal - pLayer->W_TL_HighLight - pLayer->W_TR_HighLight, pLayer->H_T_HighLight, 0, false, pLayer->TxId_T_HighLight, col);
3022 rVR.drawRotFlipBitmap (_RenderLayer, x + pLayer->W_BL_HighLight, _YReal, _WReal - pLayer->W_BL_HighLight - pLayer->W_BR_HighLight, pLayer->H_B_HighLight, 0, false, pLayer->TxId_B_HighLight, col);
3023 rVR.drawRotFlipBitmap (_RenderLayer, x, _YReal + pLayer->H_B_HighLight, pLayer->W_L_HighLight, _HReal - pLayer->H_T_HighLight - pLayer->H_B_HighLight, 0, false, pLayer->TxId_L_HighLight, col);
3024 rVR.drawRotFlipBitmap (_RenderLayer, x + _WReal - pLayer->W_R_HighLight, _YReal + pLayer->H_B_HighLight, pLayer->W_R_HighLight, _HReal - pLayer->H_T_HighLight - pLayer->H_B_HighLight, 0, false, pLayer->TxId_R_HighLight, col);
3028 CWidgetManager::getInstance()->setContentAlpha(oldAlphaContent);
3029 _CurrentContainerAlpha = oldAlphaContainer;
3032 // manage rollover
3033 CViewPointerBase *mousePointer = CWidgetManager::getInstance()->getPointer();
3034 if (mousePointer)
3036 bool dontFade = false;
3037 // bool alphaUp = false;
3038 // should not applied if the container is being resized
3039 if (CWidgetManager::getInstance()->getCapturePointerLeft() != NULL)
3041 CInterfaceGroup *ig = CWidgetManager::getInstance()->getCapturePointerLeft()->getParent();
3042 while (ig)
3044 if (ig == this)
3046 dontFade = true;
3047 break;
3049 ig = ig->getParent();
3053 if (hasKeyboardFocus()) dontFade =true;
3055 bool isOver = false;
3057 if (CWidgetManager::getInstance()->getCapturePointerLeft() == NULL)
3058 if (isIn(mousePointer->getX(), mousePointer->getY()))
3060 CInterfaceGroup *ig = CWidgetManager::getInstance()->getCurrentWindowUnder();
3061 while (ig)
3063 if (ig == this)
3065 isOver = true;
3066 break;
3068 ig = ig->getParent();
3071 if (dontFade || isOver)
3073 _CurrentRolloverAlphaContent += (float) (speed * times.frameDiffMs);
3074 _CurrentRolloverAlphaContent = std::min(1.f, _CurrentRolloverAlphaContent);
3076 _CurrentRolloverAlphaContainer += (float) (speed * times.frameDiffMs);
3077 _CurrentRolloverAlphaContainer = std::min(1.f, _CurrentRolloverAlphaContainer);
3079 else
3081 _CurrentRolloverAlphaContent -= (float) (speed * times.frameDiffMs);
3082 _CurrentRolloverAlphaContent = std::max(0.f, _CurrentRolloverAlphaContent);
3084 _CurrentRolloverAlphaContainer -= (float) (speed * times.frameDiffMs);
3085 _CurrentRolloverAlphaContainer = std::max(0.f, _CurrentRolloverAlphaContainer);
3089 if (bGrayed)
3091 CWidgetManager::getInstance()->setGlobalColor(oldGColForGrayed);
3095 // Restore the old clip window
3096 restoreClip (oldSciX, oldSciY, oldSciW, oldSciH);
3099 // ***************************************************************************
3100 void CGroupContainer::clearViews()
3102 CInterfaceGroup::clearViews();
3105 // ***************************************************************************
3106 bool CGroupContainer::handleEvent (const NLGUI::CEventDescriptor& event)
3108 if (!_Active)
3109 return false;
3111 if (_MovingInParentList)
3113 return true;
3116 if (!checkIfModal(event))
3117 return false;
3119 if (!CInterfaceGroup::handleEvent(event))
3121 if (event.getType() == NLGUI::CEventDescriptor::mouse)
3123 const NLGUI::CEventDescriptorMouse &eventDesc = (const NLGUI::CEventDescriptorMouse &)event;
3124 // MouseWheel mgt
3125 if ((_LayerSetup == 0) && (isIn(eventDesc.getX(), eventDesc.getY())))
3127 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mousewheel)
3129 if (_ScrollBar != NULL)
3130 _ScrollBar->moveTrackY (eventDesc.getWheel()*12);
3131 return true;
3135 return false;
3138 return true;
3141 // ***************************************************************************
3142 void CGroupContainer::open()
3144 disableBlink();
3145 _Opened = true;
3146 _OpenAtStart = true;
3147 if (_TitleOpened != NULL) _TitleOpened->setActive(true);
3148 if (_TitleClosed != NULL) _TitleClosed->setActive(false);
3150 if ((_Openable) && (_LayerSetup >= 0))
3152 COptionsLayer *pLayer = getContainerOptions();
3153 if (_ViewOpenState != NULL) _ViewOpenState->setTexture(pLayer->getValStr ("open_state_tx_opened"));
3156 if (_List != NULL) _List->setActive(true);
3158 if (_ScrollBar != NULL) _ScrollBar->setActive(true);
3159 if (_Content != NULL) _Content->setActive(true);
3160 if (_HeaderClosed != NULL) _HeaderClosed->setActive(false);
3161 if (_HeaderOpened != NULL) _HeaderOpened->setActive(true);
3163 invalidateCoords();
3165 // call action handler if any
3166 if (_AHOnOpen != NULL)
3168 CAHManager::getInstance()->runActionHandler(_AHOnOpen, this, _AHOnOpenParams);
3173 // ***************************************************************************
3174 void CGroupContainer::close()
3176 _Opened = false;
3177 if (_TitleOpened != NULL) _TitleOpened->setActive(false);
3178 if (_TitleClosed != NULL) _TitleClosed->setActive(true);
3179 if ((_Openable) && (_LayerSetup >= 0))
3181 COptionsLayer *pLayer = getContainerOptions();
3182 if (_ViewOpenState != NULL) _ViewOpenState->setTexture(pLayer->getValStr ("open_state_tx_closed"));
3184 if (_List != NULL) _List->setActive(false);
3186 if (_ScrollBar != NULL) _ScrollBar->setActive(false);
3187 if (_Content != NULL) _Content->setActive(false);
3188 if (_HeaderClosed != NULL) _HeaderClosed->setActive(true);
3189 if (_HeaderOpened != NULL) _HeaderOpened->setActive(false);
3190 invalidateCoords();
3192 // call action handler if any
3193 if (_AHOnClose != NULL)
3195 CAHManager::getInstance()->runActionHandler(_AHOnClose, this, _AHOnCloseParams);
3199 // ***************************************************************************
3200 void CGroupContainer::attachContainer (CGroupContainer *pIC, sint insertionOrder /* = -1 */)
3202 if (_List == NULL)
3204 _List = new CGroupList(CViewBase::TCtorParam());
3205 _List->setId (_Id+":list");
3206 _List->setParent (this);
3209 // Remove from the list if already inserted
3210 _List->delChild (pIC, true);
3211 if (insertionOrder == -1)
3213 _List->addChild (pIC, false); // Do not delete it on remove !
3215 else
3217 uint k = 0;
3218 for(k = 0; k < (uint) _List->getNbElement(); ++k)
3220 if (_List->getOrder(k) > (uint) insertionOrder) break;
3222 _List->addChildAtIndex(pIC, k, false);
3223 _List->setOrder(k, insertionOrder);
3226 // Create MaxH Resizer if not already created
3227 createResizerMaxH();
3231 // ***************************************************************************
3232 bool CGroupContainer::attachContainerAtIndex(CGroupContainer *pIC, uint index)
3234 if (_List == NULL)
3236 _List = new CGroupList(CViewBase::TCtorParam());
3237 _List->setId (_Id+":list");
3238 _List->setParent (this);
3240 if (index > (uint) _List->getNbElement())
3242 nlwarning("Bad index");
3243 return false;
3245 uint eltOrder;
3246 if (index == (uint) _List->getNbElement())
3248 if (_List->getNbElement() == 0)
3250 eltOrder = 0;
3252 else
3254 eltOrder = _List->getOrder(index - 1);
3257 else
3259 eltOrder = _List->getOrder(index);
3261 uint k;
3262 for(k = index; k < (uint) _List->getNbElement(); ++k)
3264 _List->setOrder(k, _List->getOrder(k) + 1);
3266 // change insertion order of poped containers
3267 for(k = 0; k < _PopedCont.size(); ++k)
3269 if (_PopedCont[k]->_InsertionOrder >= eltOrder)
3271 ++ _PopedCont[k]->_InsertionOrder;
3274 attachContainer(pIC, eltOrder);
3275 return true;
3279 // ***************************************************************************
3280 void CGroupContainer::detachContainer (CGroupContainer *pIC)
3282 if (!pIC) return;
3283 nlassert(_List != NULL);
3284 nlassert(pIC->getProprietaryContainer() == this); // should be a son of that container
3285 nlassert(!pIC->isPopuped()); // if the container is poped, should pop it in before detaching it!
3286 _List->delChild (pIC);
3287 _List->invalidateCoords(2);
3289 // Remove MaxH Resizer if exist
3290 if (_List->getNumChildren() == 0)
3292 removeResizerMaxH();
3297 // ***************************************************************************
3298 void CGroupContainer::removeAllContainers()
3300 if (!_List) return;
3301 _List->deleteAllChildren();
3304 // ***************************************************************************
3305 void CGroupContainer::setMovable(bool b)
3307 if (_Movable != b)
3309 _Movable = b;
3310 if (_LayerSetup != -1)
3312 updateMover();
3317 // Make from layer
3318 // ***************************************************************************
3319 void CGroupContainer::setup()
3321 sint32 nNewLayer = getLayer();
3322 if (_LayerSetup == nNewLayer)
3323 return;
3325 _LayerSetup = nNewLayer;
3327 if ((_LayerSetup == 0) && _Popable)
3329 _Poped = true;
3331 else
3333 _Poped = false;
3337 COptionsLayer *pLayer = getContainerOptions(_LayerSetup);
3339 if (_LayerSetup == 0)
3341 setParentPosRef(Hotspot_BL);
3342 setPosRef(Hotspot_TL);
3344 else
3346 setParentPosRef(Hotspot_TL);
3347 setPosRef(Hotspot_TL);
3350 // At start, consider all closed.
3352 // Title when the container is opened
3353 updateTitle();
3355 // Opened state view (tells the user if the container is openable (if the view appears) and if its opened/closed
3356 updateViewOpenState();
3358 // Multi usage button
3359 updateRightButton();
3361 // Help button
3362 updateHelpButton();
3364 // if the window is popable,
3366 if (_List == NULL)
3367 _List = new CGroupList(CViewBase::TCtorParam());
3368 _List->setId(_Id+":list");
3369 _List->setParent (this);
3370 _List->setParentPos (this);
3371 _List->setParentPosRef (Hotspot_TL);
3372 _List->setPosRef (Hotspot_TL);
3373 _List->setActive (_Opened);
3375 if (_LayerSetup == 0)
3377 _ScrollBar = new CCtrlScroll(CViewBase::TCtorParam());
3378 _ScrollBar->setId (_Id+":sb");
3379 _ScrollBar->setParent (this);
3380 _ScrollBar->setParentPos (this);
3381 _ScrollBar->setParentPosRef (Hotspot_TL);
3382 _ScrollBar->setPosRef (Hotspot_TL);
3383 _ScrollBar->setTarget(_List);
3384 _ScrollBar->setW (pLayer->Scrollbar_W); // TODO read this from somewhere
3385 _ScrollBar->setAlign (3); // Top
3386 _ScrollBar->setTextureBottomOrLeft (pLayer->TxId_B_Scrollbar);
3387 _ScrollBar->setTextureMiddle (pLayer->TxId_M_Scrollbar);
3388 _ScrollBar->setTextureTopOrRight (pLayer->TxId_T_Scrollbar);
3389 _ScrollBar->setTextureMiddleTile ((uint8)pLayer->Tile_M_Scrollbar);
3390 _ScrollBar->setActive (false);
3392 else
3394 _ScrollBar = NULL;
3398 // del all previous resizers
3399 uint k;
3400 for(k = 0; k < NumResizers; ++k)
3402 if (_Resizer[k])
3404 delCtrl (toString("rz%d", (int) k));
3405 _Resizer[k] = NULL;
3409 // Create Mover
3410 updateMover();
3412 // Remove previous controls / views
3414 delGroup ("list", true);
3415 delCtrl ("sb");
3417 COptionsContainerMove *options = getMoveOptions();
3419 // create resizer?
3420 if ((_LayerSetup == 0) && (_EnabledResizer))
3422 if (options)
3424 sint yOffset;
3425 // if no specific top Size specified
3426 if(_ResizerTopSize<0)
3427 yOffset= -options->ResizerSize;
3428 else
3429 yOffset= -_ResizerTopSize;
3430 // create the resizers
3431 createResizer(0, Hotspot_TL, Hotspot_TM, options->ResizerSize, 0, false);
3432 createResizer(1, Hotspot_TR, Hotspot_TR, 0, 0, false);
3433 createResizer(2, Hotspot_TR, Hotspot_MR, 0, yOffset, false);
3434 createResizer(3, Hotspot_BR, Hotspot_BR, 0, 0, false);
3435 createResizer(4, Hotspot_BR, Hotspot_BM, -options->ResizerSize, 0, false);
3436 createResizer(5, Hotspot_BL, Hotspot_BL, 0, 0, false);
3437 createResizer(6, Hotspot_TL, Hotspot_ML, 0, yOffset, false);
3438 createResizer(7, Hotspot_TL, Hotspot_TL, 0, 0, false);
3442 if ((_LayerSetup == 0) && (options))
3444 createResizerMaxH();
3447 addGroup (_List);
3448 if (_ScrollBar != NULL) addCtrl (_ScrollBar);
3450 // Link with script
3452 _Content = getGroup ("content");
3453 if (_Content != NULL)
3455 // Content must be (TL TL), (TR TR) or (TM TM)
3456 _Content->setPosRef( (THotSpot)((_Content->getPosRef() & (Hotspot_xL|Hotspot_xM|Hotspot_xR)) | Hotspot_Tx) );
3457 _Content->setParentPosRef(_Content->getPosRef());
3458 _Content->setActive (false);
3461 _HeaderOpened = getGroup ("header_opened");
3462 if (_HeaderOpened != NULL)
3464 // Header opened must be (TL TL), (TR TR) or (TM TM)
3465 _HeaderOpened->setPosRef( (THotSpot)((_HeaderOpened->getPosRef() & (Hotspot_xL|Hotspot_xM|Hotspot_xR)) | Hotspot_Tx) );
3466 _HeaderOpened->setParentPosRef(_HeaderOpened->getPosRef());
3467 _HeaderOpened->setActive (_Opened);
3470 _HeaderClosed = getGroup ("header_closed");
3471 if (_HeaderClosed != NULL)
3473 // Header closed must be (TL TL), (TR TR) or (TM TM)
3474 _HeaderClosed->setPosRef( (THotSpot)((_HeaderClosed->getPosRef() & (Hotspot_xL|Hotspot_xM|Hotspot_xR)) | Hotspot_Tx) );
3475 _HeaderClosed->setParentPosRef(_HeaderClosed->getPosRef());
3476 _HeaderClosed->setActive (!_Opened);
3479 _List->setActive(_Opened);
3480 if (_ScrollBar != NULL) _ScrollBar->setActive(_Opened);
3481 if (_Content != NULL) _Content->setActive(_Opened);
3483 if (!_ModalParentNames.empty())
3485 // reassign the first setup time
3486 setModalParentList(_ModalParentNames);
3489 invalidateCoords ();
3493 // ***************************************************************************
3494 // Update right button depending on pop, popable, layer and locked
3495 void CGroupContainer::updateRightButton()
3497 if ((_EnabledRightButton) && (!((_LayerSetup>0)&&(!_Popable))))
3499 COptionsLayer *pLayer = getContainerOptions();
3501 // Create right button
3502 if (_RightButton == NULL)
3504 _RightButton = new CCtrlButton(CViewBase::TCtorParam());
3505 _RightButton->setId(_Id+":rightbut");
3506 _RightButton->setType(CCtrlBaseButton::PushButton);
3507 _RightButton->setParent (this);
3508 _RightButton->setParentPos (this);
3509 _RightButton->setParentPosRef (Hotspot_TR);
3510 _RightButton->setPosRef (Hotspot_TR);
3511 _RightButton->setModulateGlobalColorAll (getModulateGlobalColor());
3512 _RightButton->setModulateGlobalColorOver (true);
3513 addCtrl (_RightButton);
3515 _RightButton->setX(pLayer->getValSInt32 ("right_button_offset_x"));
3516 _RightButton->setY(pLayer->getValSInt32 ("right_button_offset_y"));
3518 if (_LayerSetup == 0)
3520 if (_Locked)
3522 _RightButton->setTexture (pLayer->getValStr ("right_button_tx_locked"));
3523 _RightButton->setTexturePushed (pLayer->getValStr ("right_button_tx_locked"));
3524 _RightButton->setTextureOver ("");
3525 _RightButton->setActionOnLeftClick ("");
3526 _RightButton->setDefaultContextHelp(string(""));
3528 else
3530 // If the container is normally a layer>0 and is poped ? popin button
3531 if (_OldFatherContainer != NULL)
3533 _RightButton->setTexture (pLayer->getValStr ("right_button_tx_popin"));
3534 _RightButton->setTexturePushed (pLayer->getValStr ("right_button_tx_popin"));
3535 _RightButton->setTextureOver (pLayer->getValStr ("right_button_tx_over"));
3536 _RightButton->setActionOnLeftClick ("ic_popin");
3537 _RightButton->setDefaultContextHelp(CI18N::get("uiPopinWindow"));
3539 else // else the container can be deactivated ? deactivate button
3541 _RightButton->setTexture (pLayer->getValStr ("right_button_tx_deactive"));
3542 _RightButton->setTexturePushed (pLayer->getValStr ("right_button_tx_deactive"));
3543 _RightButton->setTextureOver (pLayer->getValStr ("right_button_tx_over"));
3544 _RightButton->setActionOnLeftClick ("ic_deactive");
3545 _RightButton->setDefaultContextHelp(CI18N::get("uiClose"));
3549 else
3551 // If the container can be a popup ? popup button
3552 if (_Popable)
3554 _RightButton->setTexture (pLayer->getValStr ("right_button_tx_popup"));
3555 _RightButton->setTexturePushed (pLayer->getValStr ("right_button_tx_popup"));
3556 _RightButton->setTextureOver (pLayer->getValStr ("right_button_tx_over"));
3557 _RightButton->setActionOnLeftClick ("ic_popup");
3558 _RightButton->setDefaultContextHelp(CI18N::get("uiPopupWindow"));
3560 _RightButton->setActive(!_Locked);
3563 else
3565 // Delete right button
3566 delCtrl ("rightbut");
3567 _RightButton = NULL;
3572 // ***************************************************************************
3573 void CGroupContainer::updateHelpButton()
3575 // enable the help button only if has some help page
3576 if ( _EnabledHelpButton && !_HelpPage.empty() )
3578 COptionsLayer *pLayer = getContainerOptions();
3580 // Create Help button
3581 if (_HelpButton == NULL)
3583 _HelpButton = new CCtrlButton(CViewBase::TCtorParam());
3584 _HelpButton->setId(_Id+":helpbut");
3585 _HelpButton->setType(CCtrlBaseButton::PushButton);
3586 _HelpButton->setParent (this);
3587 _HelpButton->setParentPos (this);
3588 _HelpButton->setParentPosRef (Hotspot_TR);
3589 _HelpButton->setPosRef (Hotspot_TR);
3590 _HelpButton->setModulateGlobalColorAll (getModulateGlobalColor());
3591 _HelpButton->setModulateGlobalColorOver (true);
3592 addCtrl (_HelpButton);
3594 _HelpButton->setX(pLayer->getValSInt32 ("help_button_offset_x"));
3595 _HelpButton->setY(pLayer->getValSInt32 ("help_button_offset_y"));
3597 _HelpButton->setTexture (pLayer->getValStr ("help_button_tx"));
3598 _HelpButton->setTexturePushed (pLayer->getValStr ("help_button_tx"));
3599 _HelpButton->setTextureOver (pLayer->getValStr ("help_button_tx_over"));
3600 _HelpButton->setActionOnLeftClick ("ic_help");
3601 _HelpButton->setDefaultContextHelp(CI18N::get("uiHelp"));
3604 // if not layer 0
3605 if (_LayerSetup > 0)
3607 // if locked, the right button is not displayed => take its pos instead
3608 if(_Locked)
3610 _HelpButton->setX(pLayer->getValSInt32 ("help_button_offset_x"));
3611 _HelpButton->setY(pLayer->getValSInt32 ("help_button_offset_y"));
3613 else
3615 _HelpButton->setX(pLayer->getValSInt32 ("right_button_offset_x"));
3616 _HelpButton->setY(pLayer->getValSInt32 ("right_button_offset_y"));
3620 else
3622 // Delete help button
3623 delCtrl ("helpbut");
3624 _HelpButton = NULL;
3629 // ***************************************************************************
3630 void CGroupContainer::updateMover()
3632 if (_Movable || _Popable || _Openable)
3634 COptionsContainerMove *options = getMoveOptions();
3635 _Mover = new CCtrlMover(CViewText::TCtorParam(), _Movable || _Popable || _MovableInParentList, _Openable);
3636 _Mover->setId (_Id+":mover");
3637 _Mover->setParent (this);
3638 _Mover->setParentPos (this);
3639 _Mover->setParentPosRef (Hotspot_TM);
3640 _Mover->setPosRef (Hotspot_TM);
3641 if (_Poped && _EnabledResizer)
3642 _Mover->setY (options->TrackYWithTopResizer);
3643 else
3644 _Mover->setY (options->TrackY);
3645 _Mover->setH (options->TrackH);
3646 _MoverDeltaW= options->TrackW;
3648 else
3650 _Mover = NULL;
3652 delCtrl ("mover");
3653 if (_Mover != NULL)
3654 addCtrl (_Mover, 0);
3655 invalidateCoords();
3658 // ***************************************************************************
3659 void CGroupContainer::updateViewOpenState()
3661 if (_Openable)
3663 COptionsLayer *pLayer = getContainerOptions();
3664 if (_ViewOpenState == NULL)
3666 _ViewOpenState = new CViewBitmap(CViewBase::TCtorParam());
3667 _ViewOpenState->setId(_Id+":open_state");
3668 _ViewOpenState->setParent (this);
3669 _ViewOpenState->setParentPos (this);
3670 _ViewOpenState->setParentPosRef (Hotspot_TL);
3671 _ViewOpenState->setPosRef (Hotspot_TL);
3672 _ViewOpenState->setModulateGlobalColor (getModulateGlobalColor());
3673 addView (_ViewOpenState);
3675 _ViewOpenState->setX(pLayer->getValSInt32 ("open_state_offset_x"));
3676 _ViewOpenState->setY(pLayer->getValSInt32 ("open_state_offset_y"));
3678 if (_Opened)
3679 _ViewOpenState->setTexture (pLayer->getValStr ("open_state_tx_opened"));
3680 else
3681 _ViewOpenState->setTexture (pLayer->getValStr ("open_state_tx_closed"));
3682 _ViewOpenState->setActive(!_Locked);
3684 else
3686 _ViewOpenState = NULL;
3687 delView ("open_state");
3691 // ***************************************************************************
3692 void CGroupContainer::updateTitle()
3694 COptionsLayer *pLayer = getContainerOptions();
3695 if (_TitleOpened == NULL)
3697 switch(_TitleClass)
3699 case TitleTextFormated:
3701 CViewTextFormated *vtf = new CViewTextFormated(CViewBase::TCtorParam());
3702 vtf->setFormatString(_TitleTextOpened);
3703 _TitleOpened = vtf;
3705 break;
3706 case TitleTextId:
3707 case TitleTextDynString:
3709 CViewTextID *vti= new CViewTextID(CViewBase::TCtorParam());
3710 // the title here is actually the DB path
3711 vti->setDBTextID(_TitleTextOpened);
3712 vti->setDynamicString(_TitleClass==TitleTextDynString);
3713 _TitleOpened = vti;
3715 break;
3716 default:
3717 _TitleOpened = new CViewText(CViewBase::TCtorParam());
3719 _TitleOpened->setId(_Id+":titopen");
3720 _TitleOpened->setParent (this);
3721 _TitleOpened->setParentPos (this);
3722 _TitleOpened->setParentPosRef (Hotspot_TL);
3723 _TitleOpened->setPosRef (Hotspot_TL);
3724 _TitleOpened->setShadow (true);
3725 _TitleOpened->setShadowOutline (false);
3726 _TitleOpened->setColor (CRGBA(255,255,255,255));
3727 _TitleOpened->setModulateGlobalColor(getModulateGlobalColor());
3728 _TitleOpened->setOverExtendViewText(_TitleOverExtendViewText);
3729 addView (_TitleOpened);
3732 if (_Openable)
3734 _TitleOpened->setX (pLayer->getValSInt32 ("title_offset_openable_x"));
3735 _TitleOpened->setY (pLayer->getValSInt32 ("title_offset_openable_y"));
3737 else
3739 _TitleOpened->setX (pLayer->getValSInt32 ("title_offset_x"));
3740 _TitleOpened->setY (pLayer->getValSInt32 ("title_offset_y"));
3742 _TitleOpened->setFontSize (pLayer->getValSInt32 ("title_font_size"));
3743 if (_TitleClass == TitleText) setTitledOpenedViewText();
3744 _TitleOpened->setActive (_Opened);
3746 // Title when the container is closed
3747 if (_TitleClosed == NULL)
3749 switch(_TitleClass)
3751 case TitleTextFormated:
3753 CViewTextFormated *vtf = new CViewTextFormated(CViewBase::TCtorParam());
3754 vtf->setFormatString(_TitleTextClosed);
3755 _TitleClosed = vtf;
3757 break;
3758 case TitleTextId:
3759 case TitleTextDynString:
3761 CViewTextID *vti= new CViewTextID(CViewBase::TCtorParam());
3762 // the title here is actually the DB path
3763 vti->setDBTextID(_TitleTextClosed);
3764 vti->setDynamicString(_TitleClass==TitleTextDynString);
3765 _TitleClosed = vti;
3767 break;
3768 default:
3769 _TitleClosed = new CViewText(CViewBase::TCtorParam());
3771 _TitleClosed->setId(_Id+":titclose");
3772 _TitleClosed->setParent (this);
3773 _TitleClosed->setParentPos (this);
3774 _TitleClosed->setParentPosRef (Hotspot_TL);
3775 _TitleClosed->setPosRef (Hotspot_TL);
3776 _TitleClosed->setShadow (true);
3777 _TitleClosed->setShadowOutline (false);
3778 _TitleClosed->setColor (CRGBA(255,255,255,255));
3779 _TitleClosed->setModulateGlobalColor(getModulateGlobalColor());
3780 _TitleClosed->setOverExtendViewText(_TitleOverExtendViewText);
3781 addView (_TitleClosed);
3784 if (_Openable)
3786 _TitleClosed->setX (pLayer->getValSInt32 ("title_offset_openable_x"));
3787 _TitleClosed->setY (pLayer->getValSInt32 ("title_offset_openable_y"));
3789 else
3791 _TitleClosed->setX (pLayer->getValSInt32 ("title_offset_x"));
3792 _TitleClosed->setY (pLayer->getValSInt32 ("title_offset_y"));
3794 _TitleClosed->setFontSize (pLayer->getValSInt32 ("title_font_size"));
3795 if (_TitleClass == TitleText) setTitledClosedViewText();
3796 _TitleClosed->setActive(!_Opened);
3801 // ***************************************************************************
3802 // bMaxH is a boolean to know if the resizer act on the content or on the child list
3803 void CGroupContainer::createResizer(uint index, THotSpot posRef, THotSpot type, sint32 offsetX, sint32 offsetY, bool bMaxH)
3805 CCtrlResizer *cr = new CCtrlResizer(CViewText::TCtorParam());
3806 cr->setId (_Id+toString(":rz%d", (int) index));
3807 cr->setParent (this);
3808 cr->setParentPos (this);
3809 cr->setResizerPos(type);
3811 if (_LayerSetup != 0)
3813 cr->WMin = _MinW;
3814 cr->WMax = _MaxW;
3816 else
3818 cr->WMin = _PopupMinW;
3819 cr->WMax = _PopupMaxW;
3820 cr->HMin = _PopupMinH;
3821 cr->HMax = _PopupMaxH;
3824 cr->setParentPosRef (posRef);
3825 cr->setPosRef (posRef);
3827 cr->setX(offsetX);
3828 cr->setY(offsetY);
3830 cr->IsMaxH = bMaxH;
3832 updateResizerSize(cr);
3833 _Resizer[index] = cr;
3834 addCtrl (_Resizer[index], 0);
3837 // ***************************************************************************
3838 void CGroupContainer::createResizerMaxH()
3840 if (_LayerSetup != 0) return;
3841 if (_List == NULL) return;
3842 if (_List->getNumChildren() == 0) return;
3844 COptionsContainerMove *options = getMoveOptions();
3846 // Create corner resizer if we asked for all resizer
3847 if (_EnabledResizer)
3849 if (_Resizer[1] == NULL) createResizer(1, Hotspot_TR, Hotspot_TR, 0, 0, true);
3850 if (_Resizer[3] == NULL) createResizer(3, Hotspot_BR, Hotspot_BR, 0, 0, true);
3851 if (_Resizer[5] == NULL) createResizer(5, Hotspot_BL, Hotspot_BL, 0, 0, true);
3852 if (_Resizer[7] == NULL) createResizer(7, Hotspot_TL, Hotspot_TL, 0, 0, true);
3853 _Resizer[1]->IsMaxH = true;
3854 _Resizer[3]->IsMaxH = true;
3855 _Resizer[5]->IsMaxH = true;
3856 _Resizer[7]->IsMaxH = true;
3859 if (_Resizer[0] == NULL) createResizer(0, Hotspot_TL, Hotspot_TM, options->ResizerSize, 0, true);
3860 if (_Resizer[4] == NULL) createResizer(4, Hotspot_BR, Hotspot_BM, -options->ResizerSize, 0, true);
3861 _Resizer[0]->IsMaxH = true;
3862 _Resizer[4]->IsMaxH = true;
3865 // ***************************************************************************
3866 void CGroupContainer::removeResizerMaxH()
3868 if (_LayerSetup != 0) return;
3869 if (_List == NULL) return;
3870 if (_List->getNumChildren() != 0) return;
3872 for (uint i = 0; i < NumResizers; ++i)
3873 if ((i != 6) && (i != 2)) // 6 == right and 2 == left
3874 if (_Resizer[i] != NULL)
3876 delCtrl ( toString(":rz%d", (int) i) );
3877 _Resizer[i] = NULL;
3881 // ***************************************************************************
3882 sint32 CGroupContainer::getLayer()
3884 if (_MovingInParentList)
3886 // keep the previous layer
3887 return _LayerSetup;
3889 else
3891 // Count Nb of Parent
3892 CInterfaceGroup *pIG = this;
3893 sint32 nNbParent = 0;
3894 while (pIG != NULL)
3896 pIG = pIG->getParent();
3897 if (pIG != NULL)
3898 nNbParent++;
3900 return (nNbParent-1)/2;
3904 // ***************************************************************************
3905 COptionsLayer *CGroupContainer::getContainerOptions(sint32 ls)
3907 if (ls == -1)
3908 ls = _LayerSetup;
3910 string sTmp;
3911 const string *sLayerName;
3912 if (_OptionsName.empty())
3914 nlassert((uint32)ls<NumLayerName);
3915 sLayerName = &_OptionLayerName[ls];
3917 else
3919 sTmp = _OptionsName;
3920 sLayerName = &sTmp;
3923 COptionsLayer *pLayer = (COptionsLayer*)CWidgetManager::getInstance()->getOptions(*sLayerName);
3924 nlassert(pLayer != NULL);
3925 return pLayer;
3928 // ***************************************************************************
3929 void CGroupContainer::setContent (CInterfaceGroup *pC)
3931 if (_Content != NULL)
3932 delGroup (_Content);
3933 _Content = pC;
3934 if (_Content)
3936 _Content->setId (_Id+":content");
3937 _Content->setActive (false);
3938 _Content->setParentPosRef (Hotspot_TL);
3939 _Content->setPosRef (Hotspot_TL);
3940 _Content->setParent (this);
3941 addGroup (_Content);
3945 // ***************************************************************************
3946 void CGroupContainer::setLocalize(bool localize)
3948 _Localize = localize;
3949 if (_TitleOpened)
3951 _TitleOpened->setLocalized(localize);
3953 if (_TitleClosed)
3955 _TitleClosed->setLocalized(localize);
3957 invalidateCoords();
3960 // ***************************************************************************
3961 std::string CGroupContainer::getTitle () const
3963 return _TitleTextOpened;
3966 // ***************************************************************************
3967 void CGroupContainer::setTitle (const std::string &title)
3969 setTitleOpened(title);
3970 setTitleClosed(title);
3973 // ***************************************************************************
3974 std::string CGroupContainer::getTitleOpened () const
3976 return _TitleTextOpened;
3979 // ***************************************************************************
3980 void CGroupContainer::setTitleOpened (const std::string &title)
3982 _TitleTextOpened = title;
3983 setTitledOpenedViewText();
3984 invalidateCoords();
3987 // ***************************************************************************
3988 std::string CGroupContainer::getTitleClosed () const
3990 return _TitleTextClosed;
3993 // ***************************************************************************
3994 void CGroupContainer::setTitleClosed (const std::string &title)
3996 _TitleTextClosed = title;
3997 setTitledClosedViewText();
3998 invalidateCoords();
4001 // ***************************************************************************
4002 void CGroupContainer::setTitledOpenedViewText()
4004 if (_TitleOpened != NULL)
4006 _TitleOpened->setTextLocalized(_TitleTextOpened, _Localize);
4010 // ***************************************************************************
4011 void CGroupContainer::setTitledClosedViewText()
4013 if (_TitleClosed != NULL)
4015 _TitleClosed->setTextLocalized(_TitleTextClosed, _Localize);
4019 #ifdef RYZOM_LUA_UCSTRING
4020 // ***************************************************************************
4021 void CGroupContainer::setUCTitleOpened(const ucstring &title)
4023 setTitleOpened(title.toUtf8());
4026 // ***************************************************************************
4027 void CGroupContainer::setUCTitleClosed(const ucstring &title)
4029 setTitleClosed(title.toUtf8());
4032 // ***************************************************************************
4033 void CGroupContainer::setUCTitle(const ucstring &title)
4035 setTitle(title.toUtf8());
4038 // ***************************************************************************
4039 ucstring CGroupContainer::getUCTitle () const
4041 return ucstring::makeFromUtf8(getTitle());
4044 // ***************************************************************************
4045 ucstring CGroupContainer::getUCTitleOpened () const
4047 return ucstring::makeFromUtf8(getTitleOpened());
4050 // ***************************************************************************
4051 ucstring CGroupContainer::getUCTitleClosed () const
4053 return ucstring::makeFromUtf8(getTitleClosed());
4055 #endif
4057 // ***************************************************************************
4058 void CGroupContainer::launch ()
4060 if (_OpenAtStart)
4061 open();
4063 CInterfaceGroup::launch();
4066 // ***************************************************************************
4067 void CGroupContainer::setActive (bool state)
4069 if(state != getActive() && getLayer()==0)
4071 if (state)
4072 CWidgetManager::getInstance()->setTopWindow(this);
4073 else
4074 CWidgetManager::getInstance()->setBackWindow(this);
4076 CAHManager::getInstance()->submitEvent((state?"show:":"hide:")+getId());
4078 CInterfaceGroup::setActive(state);
4081 // ***************************************************************************
4082 /*bool CGroupContainer::isWindowUnder (sint32 x, sint32 y)
4084 bool bGrayed = false;
4085 CGroupContainer *pSon = _ModalSon;
4086 if ((pSon != NULL) && pSon->getActive())
4087 bGrayed = true;
4089 if (bGrayed) return NULL;
4090 return CInterfaceGroup::isWindowUnder(x,y);
4093 // ***************************************************************************
4094 bool CGroupContainer::getViewsUnder (sint32 x, sint32 y, sint32 clipX, sint32 clipY, sint32 clipW, sint32 clipH, std::vector<CViewBase*> &vVB)
4096 bool bGrayed = isGrayed();
4097 if (bGrayed) return false;
4098 return CInterfaceGroup::getViewsUnder(x, y, clipX, clipY, clipW, clipH, vVB);
4101 // ***************************************************************************
4102 bool CGroupContainer::getCtrlsUnder (sint32 x, sint32 y, sint32 clipX, sint32 clipY, sint32 clipW, sint32 clipH, std::vector<CCtrlBase*> &vICL)
4104 bool bGrayed = isGrayed();
4105 if (bGrayed) return false;
4106 return CInterfaceGroup::getCtrlsUnder(x,y,clipX,clipY,clipW,clipH,vICL);
4109 // ***************************************************************************
4110 void CGroupContainer::popupCurrentPos()
4112 if (!_Popable && !_MovableInParentList)
4114 nlwarning("<CGroupContainer::popup> The window is not popable or cannot move in parent list.");
4115 return;
4117 if (_LayerSetup == 0)
4119 nlwarning("<CGroupContainer::popup> The window is already poped.");
4120 return;
4122 if (!_Parent || !_Parent->getParent())
4124 nlwarning("<CGroupContainer::popup> Window has not parent.");
4125 return;
4127 // remove the group from its father
4128 CGroupContainer *parentContainer = dynamic_cast<CGroupContainer *>(_Parent->getParent());
4129 if (!parentContainer)
4131 nlwarning("<CGroupContainer::popup> Container is not son of another container");
4132 return;
4134 _OldFatherContainer = parentContainer;
4135 sint32 eltIndex = parentContainer->_List->getElementIndex(this);
4136 if (eltIndex == -1)
4138 nlwarning("<CGroupContainer::popup> Can't get index in owner group");
4139 return;
4141 _InsertionOrder = parentContainer->_List->getOrder(eltIndex);
4142 parentContainer->detachContainer(this);
4144 parentContainer->_PopedCont.push_back(this);
4146 // put at the base of hierarchy
4147 CInterfaceGroup *parent = _Parent;
4148 if (!parent) return;
4149 while (parent->getParent())
4151 parent = parent->getParent();
4153 _Parent = parent;
4154 _ParentPos = parent;
4156 CWidgetManager::getInstance()->makeWindow(this);
4157 CWidgetManager::getInstance()->setTopWindow(this);
4158 CWidgetManager::getInstance()->clearViewUnders();
4159 CWidgetManager::getInstance()->clearCtrlsUnders();
4161 // update coords (put coords in world)
4162 setX(getXReal());
4163 setY(getYReal() + getHReal());
4164 setParentPosRef(Hotspot_BL);
4165 setPosRef(Hotspot_TL);
4167 // clamp coords
4168 // width
4169 sint32 w = getW();
4170 clamp(w, _PopupMinW, _PopupMaxW);
4171 setW(w);
4173 invalidateCoords();
4175 // setup the new controls
4176 _Poped = true;
4177 _OpenedBeforePopup = _Opened;
4178 _Opened = true;
4179 disableBlink();
4180 setup();
4183 // ***************************************************************************
4184 void CGroupContainer::popin(sint32 insertPos /* = -1 */, bool putBackInFatherContainer /*= true*/)
4186 if (!_OldFatherContainer)
4188 nlwarning("<popin> The window wasn't previously attached.(%s)",this->_Id.c_str());
4189 return;
4192 if (!_Popable && !_MovableInParentList)
4194 nlwarning("<popin> The window is not popable or cannot move in parent list.(%s)",this->_Id.c_str());
4195 return;
4197 if (!_MovingInParentList && _LayerSetup != 0)
4199 nlwarning("<popin> The window should be in layer 0.(%s)",this->_Id.c_str());
4200 return;
4202 if (!_Parent)
4204 nlwarning("<popin> The window has no parent.(%s)",this->_Id.c_str());
4205 return;
4208 touch();
4209 _List->setOfsY(0);
4211 _MovingInParentList = false;
4212 CWidgetManager::getInstance()->unMakeWindow(this);
4213 CWidgetManager::getInstance()->clearViewUnders();
4214 CWidgetManager::getInstance()->clearCtrlsUnders();
4215 _Parent = NULL;
4216 _ParentPos = NULL;
4217 std::vector<CGroupContainer *>::iterator it = std::find(_PopedCont.begin(), _PopedCont.end(), this);
4218 if (it != _PopedCont.end())
4220 // replace by last element
4221 *it = _PopedCont.back();
4222 _PopedCont.pop_back();
4224 if (putBackInFatherContainer)
4226 bool active = getActive();
4227 _Poped = false;
4228 if (insertPos == -1)
4230 _OldFatherContainer->attachContainer(this, _InsertionOrder);
4232 else
4234 if (!_OldFatherContainer->attachContainerAtIndex(this, insertPos))
4236 nlwarning("Couldn't attach to previous container");
4237 return;
4240 setActive(active);
4241 _OldFatherContainer = NULL;
4242 if (_OpenWhenPopup)
4244 setOpen(false);
4246 else
4248 setOpen(_OpenedBeforePopup);
4252 invalidateCoords();
4254 _OldFatherContainer = NULL;
4255 setup();
4258 // ***************************************************************************
4259 void CGroupContainer::enableBlink(uint numBlinks /*=0*/)
4261 _Blinking = true;
4262 _NumBlinks = numBlinks;
4263 _BlinkDT = 0;
4264 _BlinkState = true;
4267 // ***************************************************************************
4268 void CGroupContainer::disableBlink()
4270 _Blinking = false;
4271 _NumBlinks = 0;
4272 _BlinkDT = 0;
4273 _BlinkState = false;
4277 // ***************************************************************************
4278 void CGroupContainer::setMovingInParentList(bool enable)
4280 _MovingInParentList = enable;
4283 // ***************************************************************************
4284 void CGroupContainer::popup()
4286 if (_Poped) return;
4287 touch();
4288 setHighLighted(false);
4289 // pop the window
4290 popupCurrentPos();
4291 if (getPopupW() != -1)
4293 setX(getPopupX());
4294 setY(getPopupY());
4295 setW(getPopupW());
4296 setH(getPopupH());
4298 else
4300 setW(getRefW()); // Do not know what we need to do that ...
4302 invalidateCoords(2);
4305 // ***************************************************************************
4306 COptionsContainerMove *CGroupContainer::getMoveOptions()
4308 static NLMISC::CRefPtr<COptionsContainerMove> moveOptions;
4309 if (moveOptions) return moveOptions;
4310 moveOptions = (COptionsContainerMove *) CWidgetManager::getInstance()->getOptions("container_move_opt");
4311 return moveOptions;
4315 // ***************************************************************************
4316 // Actions Handlers
4317 // ***************************************************************************
4319 // ***************************************************************************
4320 class CICOpen : public IActionHandler
4322 public:
4323 virtual void execute (CCtrlBase *pCaller, const std::string &/* Params */)
4325 CInterfaceGroup *pIG = pCaller->getParent();
4326 if (pIG == NULL) return;
4327 CGroupContainer *pIC = dynamic_cast<CGroupContainer*>(pIG);
4328 if (pIC == NULL) return;
4329 pIC->open();
4332 REGISTER_ACTION_HANDLER (CICOpen, "ic_open");
4334 // ***************************************************************************
4335 class CICClose : public IActionHandler
4337 public:
4338 virtual void execute (CCtrlBase *pCaller, const std::string &/* Params */)
4340 CInterfaceGroup *pIG = pCaller->getParent();
4341 if (pIG == NULL) return;
4342 CGroupContainer *pIC = dynamic_cast<CGroupContainer*>(pIG);
4343 if (pIC == NULL) return;
4344 pIC->close();
4347 REGISTER_ACTION_HANDLER (CICClose, "ic_close");
4349 // ***************************************************************************
4350 class CICDeactive : public IActionHandler
4352 public:
4353 virtual void execute (CCtrlBase *pCaller, const std::string &/* Params */)
4355 CInterfaceGroup *pIG = pCaller->getParent();
4356 if (pIG == NULL) return;
4357 CGroupContainer *pIC = dynamic_cast<CGroupContainer*>(pIG);
4358 if (pIC == NULL) return;
4359 if (pIC->isLocked()) return;
4361 // check if the window can be really closed
4362 CGroupContainer::_ValidateCanDeactivate = true;
4363 if (!pIC->getAHOnDeactiveCheck().empty())
4365 CAHManager::getInstance()->runActionHandler(pIC->getAHOnDeactiveCheck(), pCaller, pIC->getAHOnDeactiveCheckParams());
4368 if (CGroupContainer::_ValidateCanDeactivate)
4370 // send close button msg
4371 if (!pIC->getAHOnCloseButton().empty())
4373 CAHManager::getInstance()->runActionHandler(pIC->getAHOnCloseButton(), pCaller, pIC->getAHOnCloseButtonParams());
4375 CWidgetManager::getInstance()->setBackWindow(pIC);
4376 pIC->setActive(false);
4380 REGISTER_ACTION_HANDLER (CICDeactive, "ic_deactive");
4382 // ***************************************************************************
4383 class CICPopup : public IActionHandler
4385 public:
4386 virtual void execute (CCtrlBase *pCaller, const std::string &/* Params */)
4388 CInterfaceGroup *pIG = pCaller->getParent();
4389 if (pIG == NULL) return;
4390 CGroupContainer *pIC = dynamic_cast<CGroupContainer*>(pIG);
4391 if (pIC == NULL) return;
4392 if (pIC->isLocked()) return;
4394 pIC->popup();
4397 CWidgetManager::getInstance()->setCapturePointerLeft(NULL);
4398 CWidgetManager::getInstance()->setCapturePointerRight(NULL);
4401 REGISTER_ACTION_HANDLER (CICPopup, "ic_popup");
4403 // ***************************************************************************
4404 class CICPopin : public IActionHandler
4406 public:
4407 virtual void execute (CCtrlBase *pCaller, const std::string &/* Params */)
4409 CInterfaceGroup *pIG = pCaller->getParent();
4410 if (pIG == NULL) return;
4411 CGroupContainer *pIC = dynamic_cast<CGroupContainer*>(pIG);
4412 if (pIC == NULL) return;
4413 if (pIC->isLocked()) return;
4414 // memorize popup position
4415 pIC->setPopupX(pIC->getX());
4416 pIC->setPopupY(pIC->getY());
4417 pIC->setPopupW(pIC->getW());
4418 pIC->setPopupH(pIC->getH());
4420 pIC->popin();
4422 CWidgetManager::getInstance()->setCapturePointerLeft(NULL);
4423 CWidgetManager::getInstance()->setCapturePointerRight(NULL);
4426 REGISTER_ACTION_HANDLER (CICPopin, "ic_popin");
4428 // ***************************************************************************
4429 class CICLock : public IActionHandler
4431 virtual void execute (CCtrlBase *pCaller, const std::string &/* Params */)
4433 CInterfaceGroup *pIG = pCaller->getParent();
4434 if (pIG == NULL) return;
4435 CGroupContainer *pIC = dynamic_cast<CGroupContainer*>(pIG);
4436 if (pIC == NULL) return;
4437 pIC->setLocked(!pIC->isLocked());
4440 REGISTER_ACTION_HANDLER(CICLock, "ic_lock");
4442 // ***************************************************************************
4443 class CICHelp : public IActionHandler
4445 virtual void execute (CCtrlBase *pCaller, const std::string &/* Params */)
4447 // get the container to get help
4448 if(!pCaller)
4449 return;
4450 CGroupContainer *pIC = dynamic_cast<CGroupContainer*>(pCaller->getRootWindow());
4451 if (pIC == NULL) return;
4453 // if found the help page
4454 const std::string &helpPage= pIC->getHelpPage();
4455 if(!helpPage.empty())
4458 // open the web browser, and point to the page
4459 CAHManager::getInstance()->runActionHandler("launch_help", NULL, "url=" + helpPage);
4463 REGISTER_ACTION_HANDLER(CICHelp, "ic_help");
4465 // ***************************************************************************
4466 CGroupContainer *CGroupContainer::getFatherContainer() const
4468 if (_Parent && _Parent->getParent())
4470 return dynamic_cast<CGroupContainer *>(_Parent->getParent());
4472 return NULL;
4475 // ***************************************************************************
4476 CGroupContainer *CGroupContainer::getProprietaryContainer() const
4478 if (_Parent && _Parent->getParent())
4480 return dynamic_cast<CGroupContainer *>(_Parent->getParent());
4482 else
4484 return _OldFatherContainer;
4488 // ***************************************************************************
4489 void CGroupContainer::setOpenable(bool openable)
4491 // COptionsLayer *pLayer = getContainerOptions();
4492 // COptionsContainerMove *options = getMoveOptions();
4493 _Openable = openable;
4495 updateTitle();
4496 updateViewOpenState();
4497 updateMover();
4500 // ***************************************************************************
4501 void CGroupContainer::rollOverAlphaUp()
4504 CViewPointerBase *vp = CWidgetManager::getInstance()->getPointer();
4505 float speed = CWidgetManager::getInstance()->getAlphaRolloverSpeed();
4506 if (!isIn(vp->getX(), vp->getY()))
4508 const CWidgetManager::SInterfaceTimes &times = CWidgetManager::getInstance()->getInterfaceTimes();
4510 _CurrentRolloverAlphaContainer += (float) (speed * times.frameDiffMs);
4511 _CurrentRolloverAlphaContainer = std::min(1.f, _CurrentRolloverAlphaContainer);
4513 _CurrentRolloverAlphaContent += (float) (speed * times.frameDiffMs);
4514 _CurrentRolloverAlphaContent = std::min(1.f, _CurrentRolloverAlphaContent);
4518 // ***************************************************************************
4519 void CGroupContainer::forceRolloverAlpha()
4521 _CurrentRolloverAlphaContent = hasKeyboardFocus() ? 1.0f : 0.f;
4522 _CurrentRolloverAlphaContainer = hasKeyboardFocus() ? 1.0f : 0.f;
4525 // ***************************************************************************
4526 bool CGroupContainer::hasKeyboardFocus() const
4529 if (CWidgetManager::getInstance()->getCaptureKeyboard() != NULL)
4531 const CGroupEditBox *geb = dynamic_cast<const CGroupEditBox *>(CWidgetManager::getInstance()->getCaptureKeyboard());
4532 if (geb)
4534 const CInterfaceGroup *gr = geb->getParent();
4535 while(gr)
4537 if (gr == this)
4539 return true;
4541 gr = gr->getParent();
4545 return false;
4548 // ***************************************************************************
4549 void CGroupContainer::setLockable(bool lockable)
4551 if (lockable == _Lockable) return;
4552 setup();
4555 // ***************************************************************************
4556 void CGroupContainer::setLocked(bool locked)
4558 if (!_Lockable)
4560 nlwarning("Container is not lockable");
4561 return;
4563 if (locked == _Locked) return;
4564 _Locked = locked;
4565 if (_LayerSetup == 0)
4567 updateRightButton();
4568 updateHelpButton();
4569 if (_ViewOpenState != NULL) _ViewOpenState->setActive(!_Locked);
4570 if (_Mover != NULL) _Mover->setActive(!_Locked);
4574 // ***************************************************************************
4575 std::string CGroupContainer::getTitleColorAsString() const
4577 // return one of the title opened....
4578 if(!_TitleOpened)
4579 return std::string();
4581 return _TitleOpened->getColorAsString();
4584 // ***************************************************************************
4585 void CGroupContainer::setTitleColorAsString(const std::string &col)
4587 // Set both colors
4588 if(_TitleOpened)
4589 _TitleOpened->setColorAsString(col);
4590 if(_TitleClosed)
4591 _TitleClosed->setColorAsString(col);
4594 // ***************************************************************************
4595 void CGroupContainer::setModalParentList (const std::string &name)
4597 _ModalParentNames = name;
4599 // can have multiple parent
4600 vector<string> modalParents;
4601 NLMISC::splitString(name, "|", modalParents);
4602 // add each of them (if possible)
4603 for(uint i=0;i<modalParents.size();i++)
4605 CGroupContainer *pGC = dynamic_cast<CGroupContainer*>(CWidgetManager::getInstance()->getElementFromId(modalParents[i]));
4606 if (pGC == NULL)
4607 pGC = dynamic_cast<CGroupContainer*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:"+modalParents[i]));
4608 if (pGC == NULL)
4609 nlwarning("<setModalParentList> not found %s",modalParents[i].c_str());
4610 else
4611 addModalParent (pGC);
4615 // ***************************************************************************
4616 void CGroupContainer::addModalParent (CGroupContainer *pParent)
4618 if(pParent==NULL) return;
4619 // Look if parent not already added
4620 for(uint i=0;i<_ModalParents.size();++i)
4621 if(_ModalParents[i] == pParent)
4622 return;
4623 // add me to the parent
4624 pParent->addModalSon(this);
4625 _ModalParents.push_back(pParent);
4628 // ***************************************************************************
4629 void CGroupContainer::addModalSon (CGroupContainer *pSon)
4631 if (pSon == NULL) return;
4632 // Look if the son not already added
4633 for (uint i = 0; i < _ModalSons.size(); ++i)
4634 if (_ModalSons[i] == pSon)
4635 return;
4636 _ModalSons.push_back(pSon);
4639 // ***************************************************************************
4640 bool CGroupContainer::checkIfModal(const NLGUI::CEventDescriptor& event)
4642 bool bRet = true;
4643 if (event.getType() == NLGUI::CEventDescriptor::mouse)
4645 const NLGUI::CEventDescriptorMouse &eventDesc = (const NLGUI::CEventDescriptorMouse &)event;
4646 if ((eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown) ||
4647 (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightdown))
4649 bRet = blinkAllSons();
4651 // Additionaly, if it is a UP, don't blink, but return false if some son active
4652 if (bRet && (
4653 (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup) ||
4654 (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightup))
4657 bRet= !isGrayed();
4660 return bRet;
4663 // ***************************************************************************
4664 bool CGroupContainer::isGrayed() const
4666 bool bGrayed = false;
4667 for (uint i = 0; i < _ModalSons.size(); ++i)
4669 CGroupContainer *pSon = _ModalSons[i];
4670 if (pSon->getActive())
4671 bGrayed = true;
4673 return bGrayed;
4676 // ***************************************************************************
4677 bool CGroupContainer::blinkAllSons()
4679 bool bRet = true;
4680 vector<CGroupContainer*> allSons = _ModalSons;
4681 uint i,j;
4682 // Recurs all sons (because allSons grow while sons are added). NB: if there is a graph, it will freeze....
4683 for (i = 0; i < allSons.size(); ++i)
4685 CGroupContainer *pSon = allSons[i];
4686 for (j = 0; j < pSon->_ModalSons.size(); ++j)
4687 allSons.push_back(pSon->_ModalSons[j]);
4689 // Then for all sons and descendants, blink
4690 for (i = 0; i < allSons.size(); ++i)
4692 CGroupContainer *pSon = allSons[i];
4693 if (pSon->getActive())
4695 pSon->enableBlink(3);
4696 bRet = false;
4699 return bRet;
4703 // ***************************************************************************
4704 void CGroupContainer::forceOpen()
4706 // Force open the container.
4707 open();
4708 // Ensure it is Active too
4709 setActive(true);
4712 // ***************************************************************************
4713 void CGroupContainer::backupPosition()
4715 _BackupX = getX();
4716 _BackupY = getY();
4717 _PositionBackuped = true;
4720 // ***************************************************************************
4721 void CGroupContainer::restorePosition()
4723 if (!_PositionBackuped) return;
4724 setX(_BackupX);
4725 setY(_BackupY);
4726 _PositionBackuped = false;
4729 // ***************************************************************************
4730 bool CGroupContainer::getTouchFlag(bool clearFlag) const
4732 bool touchFlag = _TouchFlag;
4733 if (clearFlag)
4735 _TouchFlag = false;
4737 return touchFlag;
4740 // ***************************************************************************
4741 void CGroupContainer::setBackupPosition(sint32 x, sint32 y)
4743 _BackupX = x;
4744 _BackupY = y;
4745 _PositionBackuped = true;
4748 // ***************************************************************************
4749 void CGroupContainer::setPopupMinW(sint32 minW)
4751 _PopupMinW = minW;
4752 // TODO : avoid this stupid copy (issue in CCtrResizer..)
4753 for(uint k = 0; k < NumResizers; ++k)
4755 if (_Resizer[k]) _Resizer[k]->WMin = minW;
4759 // ***************************************************************************
4760 void CGroupContainer::setPopupMaxW(sint32 maxW)
4762 _PopupMaxW = maxW;
4763 // TODO : avoid this stupid copy (issue in CCtrResizer..)
4764 for(uint k = 0; k < NumResizers; ++k)
4766 if (_Resizer[k]) _Resizer[k]->WMax = maxW;
4770 // ***************************************************************************
4771 void CGroupContainer::setPopupMinH(sint32 minH)
4773 _PopupMinH = minH;
4774 // TODO : avoid this stupid copy (issue in CCtrResizer..)
4775 for(uint k = 0; k < NumResizers; ++k)
4777 if (_Resizer[k]) _Resizer[k]->HMin = minH;
4781 // ***************************************************************************
4782 void CGroupContainer::setPopupMaxH(sint32 maxH)
4784 _PopupMaxH = maxH;
4785 // TODO : avoid this stupid copy (issue in CCtrResizer..)
4786 for(uint k = 0; k < NumResizers; ++k)
4788 if (_Resizer[k]) _Resizer[k]->HMax = maxH;
4792 // ***************************************************************************
4793 int CGroupContainer::luaSetHeaderColor(CLuaState &ls)
4795 const char *funcName = "setHeaderColor";
4796 CLuaIHM::checkArgCount(ls, funcName, 1);
4797 CLuaIHM::checkArgType(ls, funcName, 1, LUA_TSTRING);
4798 _HeaderColor.link(ls.toString(1));
4799 return 0;
4802 // ***************************************************************************
4803 int CGroupContainer::luaSetModalParentList(CLuaState &ls)
4805 const char *funcName = "setModalParentList";
4806 CLuaIHM::checkArgCount(ls, funcName, 1);
4807 CLuaIHM::checkArgType(ls, funcName, 1, LUA_TSTRING);
4808 setModalParentList(ls.toString(1));
4809 return 0;
4812 // ***************************************************************************
4813 CRGBA CGroupContainer::getDrawnHeaderColor () const
4815 CRGBA c = CRGBA(255,255,255,255);
4817 // Display the header in white if we are the last clicked window
4818 if (CWidgetManager::getInstance()->getTopWindow(CWidgetManager::getInstance()->getLastTopWindowPriority()) != static_cast<const CInterfaceGroup*>(this))
4820 if (_HeaderColor.getNodePtr() != NULL)
4821 c = _HeaderColor.getRGBA();
4822 if (isGrayed())
4824 c.R = c.R / 2;
4825 c.G = c.G / 2;
4826 c.B = c.B / 2;
4828 c.A = 255;
4831 return c;
4834 // ***************************************************************************
4835 void CGroupContainer::setHelpPage(const std::string &newPage)
4837 _HelpPage= newPage;
4840 // ***************************************************************************
4841 void CGroupContainer::requireAttention()
4843 if (getActive())
4845 // Window have headers opened => blink it if is not the top window
4846 if (isOpen())
4848 if (getId() != CWidgetManager::getInstance()->getTopWindow()->getId())
4850 enableBlink(3);
4853 // Window have headers closed => change color of header
4854 else
4856 setHeaderColor("UI:SAVE:WIN:COLORS:INFOS");
4859 else
4861 // Must open this window everytime someone tell something on it
4862 setActive(true);
4867 // ***************************************************************************
4868 int CGroupContainer::luaBlink(CLuaState &ls)
4870 const char *funcName = "blink";
4871 CLuaIHM::checkArgCount(ls, funcName, 1);
4872 CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
4873 enableBlink((uint) ls.toInteger(1));
4874 return 0;
4877 // ***************************************************************************
4878 void CGroupContainer::setRightButtonEnabled(bool enabled)
4880 if (_EnabledRightButton == enabled) return;
4881 _EnabledRightButton = enabled;
4882 updateRightButton();
4885 // ***************************************************************************
4886 void CGroupContainer::setContentYOffset(sint32 value)
4888 #ifdef NL_DEBUG
4889 nlassert(value <= 127 && value >= -128);
4890 #endif
4891 if (value > 127 || value < -128)
4893 // for lua exported value, let know the user that there was some problem
4894 throw NLMISC::Exception("y_offset must be in the [-128, 127] range");
4896 _ContentYOffset = (sint8) value;
4897 invalidateCoords();