1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "nel/gui/widget_manager.h"
20 #include "nel/gui/action_handler.h"
21 #include "nel/gui/interface_group.h"
22 #include "nel/gui/view_renderer.h"
23 #include "nel/gui/ctrl_scroll.h"
24 #include "nel/misc/xml_auto_ptr.h"
25 #include "nel/gui/group_submenu_base.h"
26 #include "nel/gui/lua_ihm.h"
28 using namespace NLMISC
;
35 NLMISC_REGISTER_OBJECT(CViewBase
, CCtrlScroll
, std::string
, "scroll");
40 // ------------------------------------------------------------------------------------------------
41 CCtrlScroll::CCtrlScroll(const TCtorParam
¶m
)
42 : CCtrlScrollBase(param
)
48 _TrackSize
= _TrackSizeMin
= 16;
60 _LastTargetMaxHReal
= 0;
62 _LastTargetMaxWReal
= 0;
73 // ------------------------------------------------------------------------------------------------
74 void CCtrlScroll::runAH(const std::string
&name
, const std::string
¶ms
)
76 if (name
.empty()) return;
77 if (_CallingAH
) return; // avoid infinite loop
79 CAHManager::getInstance()->runActionHandler(name
, this, params
);
83 // ------------------------------------------------------------------------------------------------
84 CCtrlScroll::~CCtrlScroll()
88 ICDBNode::CTextId textId
;
89 _DBLink
.getNodePtr()->removeObserver(this, textId
);
93 std::string
CCtrlScroll::getProperty( const std::string
&name
) const
96 if( name
== "tx_bottomleft" )
98 return getTextureBottomOrLeft();
101 if( name
== "tx_middle" )
103 return getTextureMiddle();
106 if( name
== "tx_topright" )
108 return getTextureTopOrRight();
111 if( name
== "vertical" )
113 return toString( _Vertical
);
116 if( name
== "align" )
139 return toString( _Min
);
144 return toString( _Max
);
147 if( name
== "value" )
150 return _DBLink
.getNodePtr()->getFullName();
152 return toString( _Value
);
155 if( name
== "tracksize" )
157 return toString( _TrackSize
);
160 if( name
== "onscroll" )
165 if( name
== "params" )
167 return _AHOnScrollParams
;
170 if( name
== "onscrollend" )
172 return _AHOnScrollEnd
;
175 if( name
== "end_params" )
177 return _AHOnScrollEndParams
;
180 if( name
== "onscrollcancel" )
182 return _AHOnScrollCancel
;
185 if( name
== "cancel_params" )
187 return _AHOnScrollCancelParams
;
190 if( name
== "target" )
192 if( _Target
!= NULL
)
193 return _Target
->getId();
198 if( name
== "target_stepx" )
200 return toString( _TargetStepX
);
203 if( name
== "target_stepy" )
205 return toString( _TargetStepY
);
208 if( name
== "step_value" )
210 return toString( _StepValue
);
213 if( name
== "cancelable" )
215 return toString( _Cancelable
);
218 if( name
== "frozen" )
220 return toString( _Frozen
);
223 return CCtrlBase::getProperty( name
);
227 void CCtrlScroll::setProperty( const std::string
&name
, const std::string
&value
)
229 if( name
== "tx_bottomleft" )
231 setTextureBottomOrLeft( value
);
235 if( name
== "tx_middle" )
237 setTextureMiddle( value
);
241 if( name
== "tx_topright" )
243 setTextureTopOrRight( value
);
247 if( name
== "vertical" )
250 if( fromString( value
, b
) )
255 if( name
== "align" )
275 if( fromString( value
, i
) )
283 if( fromString( value
, i
) )
288 if( name
== "value" )
291 if( fromString( value
, i
) )
299 _DBLink
.link( value
.c_str() );
300 ICDBNode::CTextId dummy
;
301 _DBLink
.getNodePtr()->addObserver( this, dummy
);
306 if( name
== "tracksize" )
309 if( fromString( value
, i
) )
314 if( name
== "onscroll" )
320 if( name
== "params" )
322 _AHOnScrollParams
= value
;
326 if( name
== "onscrollend" )
328 _AHOnScrollEnd
= value
;
332 if( name
== "end_params" )
334 _AHOnScrollEndParams
= value
;
338 if( name
== "onscrollcancel" )
340 _AHOnScrollCancel
= value
;
344 if( name
== "cancel_params" )
346 _AHOnScrollCancelParams
= value
;
350 if( name
== "target" )
352 _Target
= dynamic_cast< CInterfaceGroup
* >(
353 CWidgetManager::getInstance()->getElementFromId( value
)
358 if( name
== "target_stepx" )
361 if( fromString( value
, i
) )
366 if( name
== "target_stepy" )
369 if( fromString( value
, i
) )
374 if( name
== "step_value" )
377 if( fromString( value
, i
) )
382 if( name
== "cancelable" )
385 if( fromString( value
, b
) )
390 if( name
== "frozen" )
393 if( fromString( value
, b
) )
398 CCtrlBase::setProperty( name
, value
);
401 xmlNodePtr
CCtrlScroll::serialize( xmlNodePtr parentNode
, const char *type
) const
403 xmlNodePtr node
= CCtrlBase::serialize( parentNode
, type
);
407 xmlSetProp( node
, BAD_CAST
"type", BAD_CAST
"scroll" );
408 xmlSetProp( node
, BAD_CAST
"tx_bottomleft", BAD_CAST
getTextureBottomOrLeft().c_str() );
409 xmlSetProp( node
, BAD_CAST
"tx_middle", BAD_CAST
getTextureMiddle().c_str() );
410 xmlSetProp( node
, BAD_CAST
"tx_topright", BAD_CAST
getTextureTopOrRight().c_str() );
411 xmlSetProp( node
, BAD_CAST
"vertical", BAD_CAST
toString( _Vertical
).c_str() );
433 xmlSetProp( node
, BAD_CAST
"align", BAD_CAST align
.c_str() );
435 xmlSetProp( node
, BAD_CAST
"min", BAD_CAST
toString( _Min
).c_str() );
436 xmlSetProp( node
, BAD_CAST
"max", BAD_CAST
toString( _Max
).c_str() );
439 xmlSetProp( node
, BAD_CAST
"value", BAD_CAST _DBLink
.getNodePtr()->getFullName().c_str() );
441 xmlSetProp( node
, BAD_CAST
"tracksize", BAD_CAST
toString( _TrackSize
).c_str() );
442 xmlSetProp( node
, BAD_CAST
"onscroll", BAD_CAST _AHOnScroll
.c_str() );
443 xmlSetProp( node
, BAD_CAST
"params", BAD_CAST _AHOnScrollParams
.c_str() );
444 xmlSetProp( node
, BAD_CAST
"onscrollend", BAD_CAST _AHOnScrollEnd
.c_str() );
445 xmlSetProp( node
, BAD_CAST
"end_params", BAD_CAST _AHOnScrollEndParams
.c_str() );
446 xmlSetProp( node
, BAD_CAST
"onscrollcancel", BAD_CAST _AHOnScrollCancel
.c_str() );
447 xmlSetProp( node
, BAD_CAST
"cancel_params", BAD_CAST _AHOnScrollCancelParams
.c_str() );
449 if( _Target
!= NULL
)
450 xmlSetProp( node
, BAD_CAST
"target", BAD_CAST _Target
->getId().c_str() );
452 xmlSetProp( node
, BAD_CAST
"target", BAD_CAST
"" );
454 xmlSetProp( node
, BAD_CAST
"target_stepx", BAD_CAST
toString( _TargetStepX
).c_str() );
455 xmlSetProp( node
, BAD_CAST
"target_stepy", BAD_CAST
toString( _TargetStepY
).c_str() );
456 xmlSetProp( node
, BAD_CAST
"step_value", BAD_CAST
toString( _StepValue
).c_str() );
457 xmlSetProp( node
, BAD_CAST
"cancelable", BAD_CAST
toString( _Cancelable
).c_str() );
458 xmlSetProp( node
, BAD_CAST
"frozen", BAD_CAST
toString( _Frozen
).c_str() );
463 // ------------------------------------------------------------------------------------------------
464 bool CCtrlScroll::parse(xmlNodePtr node
, CInterfaceGroup
* parentGroup
)
466 if (!CCtrlBase::parse(node
, parentGroup
))
471 prop
= (char*) xmlGetProp( node
, (xmlChar
*)"tx_bottomleft" );
472 if(prop
) setTextureBottomOrLeft(string((const char*)prop
));
473 else setTextureBottomOrLeft ("w_scroll_l0_b.tga");
475 prop
= (char*) xmlGetProp( node
, (xmlChar
*)"tx_middle" );
476 if(prop
) setTextureMiddle(string((const char*)prop
));
477 else setTextureMiddle ("w_scroll_l0_m.tga");
479 prop
= (char*) xmlGetProp( node
, (xmlChar
*)"tx_topright" );
480 if(prop
) setTextureTopOrRight(string((const char*)prop
));
481 else setTextureTopOrRight ("w_scroll_l0_t.tga");
484 prop
= (char*) xmlGetProp( node
, (xmlChar
*)"vertical" );
485 if (prop
) _Vertical
= convertBool((const char*)prop
);
487 prop
= (char*) xmlGetProp (node
, (xmlChar
*)"align");
491 if (stricmp(prop
, "T") == 0) _Aligned
= 0;
492 else if (stricmp(prop
, "B") == 0) _Aligned
= 1;
493 else if (stricmp(prop
, "L") == 0) _Aligned
= 2;
494 else if (stricmp(prop
, "R") == 0) _Aligned
= 3;
497 prop
= (char*) xmlGetProp( node
, (xmlChar
*)"min" );
498 if (prop
) fromString((const char*)prop
, _Min
);
500 prop
= (char*) xmlGetProp( node
, (xmlChar
*)"max" );
501 if (prop
) fromString((const char*)prop
, _Max
);
503 prop
= (char*) xmlGetProp( node
, (xmlChar
*)"value" );
506 if ( isdigit(*prop
) || *prop
=='-')
509 fromString((const char*)prop
, _Value
);
515 ICDBNode::CTextId textId
;
516 _DBLink
.getNodePtr()->addObserver(this, textId
);
521 prop
= (char*) xmlGetProp( node
, (xmlChar
*)"tracksize" );
522 if (prop
) fromString((const char*)prop
, _TrackSize
);
524 // Read Action handlers
525 prop
= (char*) xmlGetProp( node
, (xmlChar
*)"onscroll" );
526 if (prop
) _AHOnScroll
= NLMISC::toLower(prop
.str());
527 prop
= (char*) xmlGetProp( node
, (xmlChar
*)"params" );
528 if (prop
) _AHOnScrollParams
= string((const char*)prop
);
530 prop
= (char*) xmlGetProp( node
, (xmlChar
*)"onscrollend" );
531 if (prop
) _AHOnScrollEnd
= NLMISC::toLower(prop
.str());
532 prop
= (char*) xmlGetProp( node
, (xmlChar
*)"end_params" );
533 if (prop
) _AHOnScrollEndParams
= string((const char*)prop
);
535 prop
= (char*) xmlGetProp( node
, (xmlChar
*)"onscrollcancel" );
536 if (prop
) _AHOnScrollCancel
= NLMISC::toLower(prop
.str());
537 prop
= (char*) xmlGetProp( node
, (xmlChar
*)"cancel_params" );
538 if (prop
) _AHOnScrollCancelParams
= string((const char*)prop
);
542 prop
= (char*) xmlGetProp( node
, (xmlChar
*)"target" );
545 CInterfaceGroup
*group
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId(prop
.str()));
547 group
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId(this->getId(), prop
.str()));
555 prop
= (char*) xmlGetProp( node
, (xmlChar
*)"target_stepx" );
556 if(prop
) fromString((const char*)prop
, _TargetStepX
);
557 prop
= (char*) xmlGetProp( node
, (xmlChar
*)"target_stepy" );
558 if(prop
) fromString((const char*)prop
, _TargetStepY
);
559 _TargetStepX
= max((sint32
)1, _TargetStepX
);
560 _TargetStepY
= max((sint32
)1, _TargetStepY
);
563 prop
= (char*) xmlGetProp( node
, (xmlChar
*)"step_value" );
564 if(prop
) fromString((const char*)prop
, _StepValue
);
566 prop
= (char*) xmlGetProp( node
, (xmlChar
*)"cancelable" );
567 if (prop
) _Cancelable
= convertBool(prop
);
569 prop
= (char*) xmlGetProp (node
, (xmlChar
*)"frozen");
572 _Frozen
= convertBool(prop
);
578 // ------------------------------------------------------------------------------------------------
580 int CCtrlScroll::luaSetTarget(CLuaState
&ls
)
582 const char *funcName
= "setTarget";
583 CLuaIHM::checkArgCount(ls
, funcName
, 1);
584 CLuaIHM::checkArgType(ls
, funcName
, 1, LUA_TSTRING
);
585 std::string targetId
= ls
.toString(1);
587 CInterfaceGroup
*group
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId(targetId
));
596 void CCtrlScroll::updateCoords()
600 // update only if visible
601 if (_Target
->getActive())
603 CViewRenderer
&rVR
= *CViewRenderer::getInstance();
605 rVR
.getTextureSizeFromId (_TxIdB
, w
, h
);
610 _H
= _Target
->getMaxHReal();
614 _W
= _Target
->getMaxWReal();
618 CCtrlBase::updateCoords ();
621 if(_Target
->getHReal()!=_LastTargetHReal
|| _Target
->getMaxHReal()!=_LastTargetMaxHReal
||
622 _Target
->getOfsY() != _LastTargetOfsY
625 _LastTargetHReal
= _Target
->getHReal();
626 _LastTargetMaxHReal
= _Target
->getMaxHReal();
627 _LastTargetOfsY
= _Target
->getOfsY();
629 // Activate only if needed
630 setActive(_Target
->getHReal() > _Target
->getMaxHReal());
631 CCtrlBase::updateCoords();
633 // Calculate size of the track button
634 if ((_Target
->getHReal() <= _Target
->getMaxHReal()) || (_Target
->getHReal() == 0))
636 _TrackSize
= _Target
->getMaxHReal();
640 float factor
= (float)_Target
->getMaxHReal() / (float)_Target
->getHReal();
641 factor
= _TrackSizeMin
+ factor
* (this->getHReal() - _TrackSizeMin
);
642 _TrackSize
= (sint32
)factor
;
644 // Calculate pos of the track button
645 if (_Target
->getHReal() <= _Target
->getMaxHReal())
647 if (_Aligned
== 1) // BOTTOM
650 _TrackPos
= getHReal()-_TrackSize
;
654 if (_Aligned
== 1) // BOTTOM
656 float factor
= ((float)_Target
->getHReal() - (float)_Target
->getMaxHReal());
657 factor
= -(float)_Target
->getOfsY() / factor
;
658 if (factor
< 0.0f
) factor
= 0.0f
;
659 if (factor
> 1.0f
) factor
= 1.0f
;
660 _TrackPos
= factor
* (getHReal()-_TrackSize
);
664 float factor
= ((float)_Target
->getHReal() - (float)_Target
->getMaxHReal());
665 factor
= (float)_Target
->getOfsY() / factor
;
666 if (factor
< 0.0f
) factor
= 0.0f
;
667 if (factor
> 1.0f
) factor
= 1.0f
;
668 sint32 hreal
= getHReal();
669 _TrackPos
= (1.0f
-factor
) * (hreal
- _TrackSize
);
673 // invalidate coords.
674 computeTargetOfsFromPos();
677 else // Horizontal Tracker
679 if(_Target
->getWReal()!=_LastTargetWReal
|| _Target
->getMaxWReal()!=_LastTargetMaxWReal
||
680 _Target
->getOfsX() != _LastTargetOfsX
)
682 _LastTargetWReal
= _Target
->getWReal();
683 _LastTargetMaxWReal
= _Target
->getMaxWReal();
684 _LastTargetOfsX
= _Target
->getOfsX();
686 // Activate only if needed
687 setActive(_Target
->getWReal() > _Target
->getMaxWReal());
688 CCtrlBase::updateCoords();
690 // Calculate size of the track button
691 if ((_Target
->getWReal() <= _Target
->getMaxWReal()) || (_Target
->getWReal() == 0))
693 _TrackSize
= _Target
->getMaxWReal();
697 float factor
= (float)_Target
->getMaxWReal() / (float)_Target
->getWReal();
698 factor
= _TrackSizeMin
+ factor
* (this->getWReal() - _TrackSizeMin
);
699 _TrackSize
= (sint32
)factor
;
701 // Calculate pos of the track button
702 if (_Target
->getWReal() <= _Target
->getMaxWReal())
704 if (_Aligned
== 2) // LEFT
707 _TrackPos
= getWReal()-_TrackSize
;
711 if (_Aligned
== 2) // LEFT
713 float factor
= ((float)_Target
->getWReal() - (float)_Target
->getMaxWReal());
714 factor
= -(float)_Target
->getOfsX() / factor
;
715 if (factor
< 0.0f
) factor
= 0.0f
;
716 if (factor
> 1.0f
) factor
= 1.0f
;
717 _TrackPos
= factor
* (getWReal()-_TrackSize
);
721 float factor
= ((float)_Target
->getWReal() - (float)_Target
->getMaxWReal());
722 factor
= (float)_Target
->getOfsX() / factor
;
723 if (factor
< 0.0f
) factor
= 0.0f
;
724 if (factor
> 1.0f
) factor
= 1.0f
;
725 sint32 hreal
= getWReal();
726 _TrackPos
= (1.0f
-factor
) * (hreal
- _TrackSize
);
730 // invalidate coords.
731 computeTargetOfsFromPos();
739 _LastTargetMaxHReal
= 0;
741 _LastTargetMaxWReal
= 0;
749 CCtrlBase::updateCoords ();
751 _Value
= _DBLink
.getSInt32();
755 if (_Aligned
== 1) // BOTTOM
756 factor
= ((float)_Value
-_Min
) / (_Max
-_Min
);
758 factor
= 1.0f
- ((float)_Value
-_Min
) / (_Max
-_Min
);
759 factor
*= (this->getHReal() - _TrackSize
);
761 _TrackDispPos
= (sint32
)factor
;
766 if (_Aligned
== 2) // LEFT
767 factor
= ((float)_Value
-_Min
) / (_Max
-_Min
);
769 factor
= 1.0f
- ((float)_Value
-_Min
) / (_Max
-_Min
);
770 factor
*= (this->getWReal() - _TrackSize
);
772 _TrackDispPos
= (sint32
)factor
;
775 CCtrlBase::updateCoords ();
778 // ------------------------------------------------------------------------------------------------
779 void CCtrlScroll::draw()
781 CViewRenderer
&rVR
= *CViewRenderer::getInstance();
782 CRGBA col
= CWidgetManager::getInstance()->getGlobalColorForContent();
788 rVR
.drawRotFlipBitmap (_RenderLayer
, _XReal
, _YReal
+_TrackPos
, _WReal
, 4, 0, false, _TxIdB
, col
);
790 rVR
.drawRotFlipBitmap (_RenderLayer
, _XReal
, _YReal
+_TrackPos
+4, _WReal
, _TrackSize
-8, 0, false, _TxIdM
, col
);
792 rVR
.drawRotFlipBitmapTiled (_RenderLayer
, _XReal
, _YReal
+_TrackPos
+4, _WReal
, _TrackSize
-8, 0, false, _TxIdM
, _TileM
-1, col
);
793 rVR
.drawRotFlipBitmap (_RenderLayer
, _XReal
, _YReal
+_TrackPos
+_TrackSize
-4, _WReal
, 4, 0, false, _TxIdT
, col
);
797 rVR
.drawRotFlipBitmap (_RenderLayer
, _XReal
+_TrackPos
, _YReal
, 4, _HReal
, 0, false, _TxIdB
, col
);
799 rVR
.drawRotFlipBitmap (_RenderLayer
, _XReal
+_TrackPos
+4, _YReal
, _TrackSize
-8, _HReal
, 0, false, _TxIdM
, col
);
801 rVR
.drawRotFlipBitmapTiled (_RenderLayer
, _XReal
+_TrackPos
+4, _YReal
, _TrackSize
-8, _HReal
, 0, false, _TxIdM
, _TileM
-1, col
);
802 rVR
.drawRotFlipBitmap (_RenderLayer
, _XReal
+_TrackPos
+_TrackSize
-4, _YReal
, 4, _HReal
, 0, false, _TxIdT
, col
);
809 rVR
.drawRotFlipBitmap (_RenderLayer
, _XReal
, _YReal
+_TrackDispPos
, _WReal
, 4, 0, false, _TxIdB
, col
);
811 rVR
.drawRotFlipBitmap (_RenderLayer
, _XReal
, _YReal
+_TrackDispPos
+4, _WReal
, _TrackSize
-8, 0, false, _TxIdM
, col
);
813 rVR
.drawRotFlipBitmapTiled (_RenderLayer
, _XReal
, _YReal
+_TrackDispPos
+4, _WReal
, _TrackSize
-8, 0, false, _TxIdM
, _TileM
-1, col
);
814 rVR
.drawRotFlipBitmap (_RenderLayer
, _XReal
, _YReal
+_TrackDispPos
+_TrackSize
-4, _WReal
, 4, 0, false, _TxIdT
, col
);
818 rVR
.drawRotFlipBitmap (_RenderLayer
, _XReal
+_TrackDispPos
, _YReal
, 4, _HReal
, 0, false, _TxIdB
, col
);
820 rVR
.drawRotFlipBitmap (_RenderLayer
, _XReal
+_TrackDispPos
+4, _YReal
, _TrackSize
-8, _HReal
, 0, false, _TxIdM
, col
);
822 rVR
.drawRotFlipBitmapTiled (_RenderLayer
, _XReal
+_TrackDispPos
+4, _YReal
, _TrackSize
-8, _HReal
, 0, false, _TxIdM
, _TileM
-1, col
);
823 rVR
.drawRotFlipBitmap (_RenderLayer
, _XReal
+_TrackDispPos
+_TrackSize
-4, _YReal
, 4, _HReal
, 0, false, _TxIdT
, col
);
828 // ------------------------------------------------------------------------------------------------
829 bool CCtrlScroll::handleEvent (const NLGUI::CEventDescriptor
&event
)
831 if (CCtrlBase::handleEvent(event
)) return true;
832 if (!_Active
|| _Frozen
)
834 if (event
.getType() == NLGUI::CEventDescriptor::mouse
)
836 const NLGUI::CEventDescriptorMouse
&eventDesc
= (const NLGUI::CEventDescriptorMouse
&)event
;
837 if ((CWidgetManager::getInstance()->getCapturePointerLeft() != this) &&
838 (!((eventDesc
.getX() >= _XReal
) &&
839 (eventDesc
.getX() < (_XReal
+ _WReal
))&&
840 (eventDesc
.getY() > _YReal
) &&
841 (eventDesc
.getY() <= (_YReal
+ _HReal
)))))
844 if (eventDesc
.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown
)
847 _InitialValue
= getValue();
849 _TrackPos
= _TrackDispPos
;
850 _MouseDownOffsetX
= eventDesc
.getX() - (getXReal() + (_Vertical
? 0 : _TrackPos
));
851 _MouseDownOffsetY
= eventDesc
.getY() - (getYReal() + (_Vertical
? _TrackPos
: 0));
853 // if target is a menu, hidde its sub menus
854 if(_Target
&& _Target
->getParent())
856 CGroupSubMenuBase
*menu
= dynamic_cast<CGroupSubMenuBase
*>(_Target
->getParent());
858 menu
->hideSubMenus();
862 if (eventDesc
.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup
)
865 runAH(_AHOnScrollEnd
, _AHOnScrollEndParams
.empty() ? _AHOnScrollParams
: _AHOnScrollEndParams
); // backward compatibility
868 if (eventDesc
.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightdown
&& _MouseDown
&& _Cancelable
)
871 setValue(_InitialValue
);
872 runAH(_AHOnScrollCancel
, _AHOnScrollCancelParams
); // backward compatibility
875 if (eventDesc
.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mousemove
)
879 sint32 dx
= eventDesc
.getX() - (getXReal() + (_Vertical
? 0 : _TrackPos
) + _MouseDownOffsetX
);
880 sint32 dy
= eventDesc
.getY() - (getYReal() + (_Vertical
? _TrackPos
: 0 ) + _MouseDownOffsetY
);
881 if (dx
!= 0) moveTrackX (dx
);
882 if (dy
!= 0) moveTrackY (dy
);
886 if (eventDesc
.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mousewheel
&& _Vertical
)
888 moveTargetY (-(eventDesc
.getWheel() * 12));
895 // ------------------------------------------------------------------------------------------------
896 void CCtrlScroll::setTarget (CInterfaceGroup
*pIG
)
902 if (_Target
->getPosRef()&Hotspot_Tx
)
907 if (_Target
->getPosRef()&Hotspot_Tx
)
914 if (_Target
->getPosRef()&Hotspot_xL
)
919 if (_Target
->getPosRef()&Hotspot_xL
)
925 // ------------------------------------------------------------------------------------------------
926 sint32
CCtrlScroll::moveTrackX (sint32 dx
)
930 if ((getWReal()-_TrackSize
) <= 0)
934 float tpos
= _TrackPos
;
935 sint32 tsize
= _TrackSize
;
937 // Limit the scroller to the defined area
939 if (newtpos
< 0) newtpos
= 0;
940 if (newtpos
> (getWReal()-tsize
)) newtpos
= (getWReal()-tsize
);
947 computeTargetOfsFromPos();
949 else // This is a number scroller
951 float factor
= (float)(_Max
- _Min
);
953 if (_Aligned
== 2) // LEFT
954 factor
= -factor
* newtpos
/ (float)(getWReal()-tsize
) - _Min
;
956 factor
= factor
* (1.0f
-(newtpos
/ (float)(getWReal()-tsize
))) + _Min
;
960 if (_Aligned
== 2) // LEFT
961 _Value
= (sint32
) (_Inverted
? factor
: -factor
);
963 _Value
= (sint32
) (_Inverted
? factor
: -factor
);
965 // step and clamp value
966 normalizeValue(_Value
);
970 if (_Aligned
== 2) // LEFT
971 factor
= ((float)_Value
-_Min
) / (_Max
-_Min
);
973 factor
= 1.0f
- ((float)_Value
-_Min
) / (_Max
-_Min
);
974 factor
*= (this->getWReal() - _TrackSize
);
976 _TrackDispPos
= (sint32
)factor
;
982 _DBLink
.setSInt32 (_Value
);
987 // Launch the scroller event if any
988 runAH(_AHOnScroll
, _AHOnScrollParams
);
993 // ------------------------------------------------------------------------------------------------
994 sint32
CCtrlScroll::moveTrackY (sint32 dy
)
998 if ((getHReal()-_TrackSize
) <= 0)
1002 float tpos
= _TrackPos
;
1003 sint32 tsize
= _TrackSize
;
1005 // Limit the scroller to the defined area
1006 newtpos
= tpos
+ dy
;
1007 if (newtpos
< 0) newtpos
= 0;
1008 if (newtpos
> (getHReal()-tsize
)) newtpos
= (getHReal()-tsize
);
1009 dy
= newtpos
- tpos
;
1013 _TrackPos
= newtpos
;
1015 computeTargetOfsFromPos();
1017 else // This is a number scroller
1019 float factor
= (float)(_Max
- _Min
);
1021 if (_Aligned
== 1) // BOTTOM
1022 factor
= -factor
* newtpos
/ (float)(getHReal()-tsize
) - _Min
;
1024 factor
= factor
* (1.0f
-(newtpos
/ (float)(getHReal()-tsize
))) + _Min
;
1026 _TrackPos
= newtpos
;
1028 if (_Aligned
== 1) // BOTTOM
1029 _Value
= (sint32
) (_Inverted
? factor
: -factor
);
1031 _Value
= (sint32
) (_Inverted
? factor
: -factor
);
1033 // step and clamp value
1034 normalizeValue(_Value
);
1038 if (_Aligned
== 1) // BOTTOM
1039 factor
= ((float)_Value
-_Min
) / (_Max
-_Min
);
1041 factor
= 1.0f
- ((float)_Value
-_Min
) / (_Max
-_Min
);
1042 factor
*= (this->getHReal() - _TrackSize
);
1044 _TrackDispPos
= (sint32
)factor
;
1049 _ObserverOn
= false;
1050 _DBLink
.setSInt32 (_Value
);
1055 // Launch the scroller event if any
1056 runAH(_AHOnScroll
, _AHOnScrollParams
);
1061 // ------------------------------------------------------------------------------------------------
1062 void CCtrlScroll::setTextureBottomOrLeft (const std::string
&txName
)
1064 CViewRenderer
&rVR
= *CViewRenderer::getInstance();
1065 _TxIdB
= rVR
.getTextureIdFromName(txName
);
1068 // ------------------------------------------------------------------------------------------------
1069 void CCtrlScroll::setTextureMiddle (const std::string
&txName
)
1071 CViewRenderer
&rVR
= *CViewRenderer::getInstance();
1072 _TxIdM
= rVR
.getTextureIdFromName(txName
);
1075 // ------------------------------------------------------------------------------------------------
1076 void CCtrlScroll::setTextureTopOrRight (const std::string
&txName
)
1078 CViewRenderer
&rVR
= *CViewRenderer::getInstance();
1079 _TxIdT
= rVR
.getTextureIdFromName(txName
);
1082 std::string
CCtrlScroll::getTextureBottomOrLeft() const
1084 return CViewRenderer::getInstance()->getTextureNameFromId( _TxIdB
);
1087 std::string
CCtrlScroll::getTextureMiddle() const
1089 return CViewRenderer::getInstance()->getTextureNameFromId( _TxIdM
);
1092 std::string
CCtrlScroll::getTextureTopOrRight() const
1094 return CViewRenderer::getInstance()->getTextureNameFromId( _TxIdT
);
1097 // ------------------------------------------------------------------------------------------------
1098 void CCtrlScroll::setValue(sint32 value
)
1100 normalizeValue(value
);
1104 _ObserverOn
= false;
1105 _DBLink
.setSInt32(value
);
1115 // ------------------------------------------------------------------------------------------------
1116 void CCtrlScroll::setTrackPos(sint32 pos
)
1120 moveTrackY(pos
- _TrackPos
);
1124 moveTrackX(pos
- _TrackPos
);
1129 // ------------------------------------------------------------------------------------------------
1130 void CCtrlScroll::computeTargetOfsFromPos()
1134 float factor
= ((float)_Target
->getHReal() - (float)_Target
->getMaxHReal());
1136 if (_Aligned
== 1) // BOTTOM
1137 factor
= -factor
* _TrackPos
/ favoid0((float)(getHReal()-_TrackSize
));
1139 factor
= factor
* (1.0f
-(_TrackPos
/ favoid0((float)(getHReal()-_TrackSize
))));
1141 // Compute Steped target
1142 sint32 nexOfsY
= (sint32
) floorf(0.5+(_Inverted
? factor
: -factor
));
1144 nexOfsY
= ((nexOfsY
+_TargetStepY
/2)/_TargetStepY
) * _TargetStepY
;
1145 _Target
->setOfsY (nexOfsY
);
1146 _LastTargetOfsY
= nexOfsY
;
1148 // invalidate only XReal/YReal, doing only 1 pass
1149 _Target
->invalidateCoords(1);
1153 float factor
= ((float)_Target
->getWReal() - (float)_Target
->getMaxWReal());
1155 if (_Aligned
== 2) // LEFT
1156 factor
= -factor
* _TrackPos
/ favoid0((float)(getWReal()-_TrackSize
));
1158 factor
= factor
* (1.0f
-(_TrackPos
/ favoid0((float)(getWReal()-_TrackSize
))));
1160 // Compute Steped target
1161 sint32 nexOfsX
= (sint32
) floorf(0.5+(_Inverted
? factor
: -factor
));
1163 nexOfsX
= ((nexOfsX
+_TargetStepX
/2)/_TargetStepX
) * _TargetStepX
;
1164 _Target
->setOfsX (nexOfsX
);
1165 _LastTargetOfsX
= nexOfsX
;
1167 // invalidate only XReal/YReal, doing only 1 pass
1168 _Target
->invalidateCoords(1);
1172 // ------------------------------------------------------------------------------------------------
1173 void CCtrlScroll::update(ICDBNode
* /* node */)
1175 if (!_ObserverOn
) return;
1176 _Value
= _DBLink
.getSInt32();
1177 // the value in the db changed
1178 invalidateCoords(1);
1179 if (_Target
) _Target
->invalidateCoords(1);
1183 // ***************************************************************************
1184 void CCtrlScroll::moveTargetX (sint32 dx
)
1188 sint32 maxWReal
= _Target
->getMaxWReal();
1189 sint32 wReal
= _Target
->getWReal();
1190 if(wReal
<= maxWReal
)
1193 // compute the new ofsX.
1194 sint32 ofsX
= _Target
->getOfsX();
1196 clamp(ofsX
, 0, wReal
-maxWReal
);
1197 _Target
->setOfsX(ofsX
);
1199 // compute new trackPos.
1200 if (_Aligned
== 2) // LEFT
1202 float factor
= (float)(wReal
-maxWReal
);
1203 factor
= -(float)ofsX
/ factor
;
1204 clamp(factor
, 0.f
, 1.f
);
1205 _TrackPos
= factor
* (getWReal()-_TrackSize
);
1209 float factor
= (float)(wReal
-maxWReal
);
1210 factor
= (float)ofsX
/ factor
;
1211 clamp(factor
, 0.f
, 1.f
);
1212 _TrackPos
= (1.0f
-factor
) * (getWReal() - _TrackSize
);
1215 // invalidate only position. 1 pass is sufficient
1216 invalidateCoords(1);
1219 // ***************************************************************************
1220 void CCtrlScroll::moveTargetY (sint32 dy
)
1224 sint32 maxHReal
= _Target
->getMaxHReal();
1225 sint32 hReal
= _Target
->getHReal();
1226 if(hReal
<= maxHReal
)
1229 if (_TargetStepY
> 1)
1231 sint sign
= (0 < dy
) - (dy
< 0);
1232 dy
= sign
* max(1, (dy
/ _TargetStepY
)) * _TargetStepY
;
1235 // compute the new ofsY.
1236 sint32 ofsY
= _Target
->getOfsY();
1239 // compute new trackPos.
1240 if (_Aligned
== 1) // BOTTOM
1242 clamp(ofsY
, maxHReal
- hReal
, 0);
1243 _Target
->setOfsY(ofsY
);
1244 float factor
= (float)(hReal
-maxHReal
);
1245 factor
= -(float)ofsY
/ factor
;
1246 clamp(factor
, 0.f
, 1.f
);
1247 _TrackPos
= factor
* (getHReal()-_TrackSize
);
1251 clamp(ofsY
, 0, hReal
-maxHReal
);
1252 _Target
->setOfsY(ofsY
);
1253 float factor
= (float)(hReal
-maxHReal
);
1254 factor
= (float)ofsY
/ factor
;
1255 clamp(factor
, 0.f
, 1.f
);
1256 _TrackPos
= (1.0f
-factor
) * (getHReal() - _TrackSize
);
1259 // invalidate only position. 1 pass is sufficient
1260 invalidateCoords(1);
1263 // ***************************************************************************
1264 void CCtrlScroll::normalizeValue(sint32
&value
)
1267 if(_StepValue
==0 || _StepValue
==1)
1269 // if interval is null, force min!
1276 // get range of possible position
1277 // sint32 size= _Max - _Min;
1280 sint32 val
= (value
+ (_StepValue
/2) -_Min
) / _StepValue
;
1281 val
= _Min
+ val
* _StepValue
;
1282 clamp(val
, _Min
, _Max
);
1286 // ***************************************************************************
1287 void CCtrlScroll::setFrozen (bool state
)
1297 // ------------------------------------------------------------------------------------------------
1298 int CCtrlScroll::luaEnsureVisible(CLuaState
&ls
)
1300 const char *funcName
= "ensureVisible";
1301 CLuaIHM::checkArgCount(ls
, funcName
, 3);
1302 CLuaIHM::checkArgTypeUIElement(ls
, funcName
, 1);
1303 CLuaIHM::checkArgType(ls
, funcName
, 2, LUA_TSTRING
);
1304 CLuaIHM::checkArgType(ls
, funcName
, 3, LUA_TSTRING
);
1306 std::string hsStr
[] = { ls
.toString(2), ls
.toString(3) };
1308 for (uint hsIndex
= 0; hsIndex
< 2; ++ hsIndex
)
1312 if (NLMISC::nlstricmp(hsStr
[hsIndex
], "T") == 0)
1314 hs
[hsIndex
] = Hotspot_Tx
;
1317 if (NLMISC::nlstricmp(hsStr
[hsIndex
], "M") == 0)
1319 hs
[hsIndex
] = Hotspot_Mx
;
1322 if (NLMISC::nlstricmp(hsStr
[hsIndex
], "B") == 0)
1324 hs
[hsIndex
] = Hotspot_Bx
;
1328 CLuaIHM::fails(ls
, "%s : couldn't parse hotspot for vertical scrollbar", funcName
);
1333 if (NLMISC::nlstricmp(hsStr
[hsIndex
], "L") == 0)
1335 hs
[hsIndex
] = Hotspot_xL
;
1338 if (NLMISC::nlstricmp(hsStr
[hsIndex
], "M") == 0)
1340 hs
[hsIndex
] = Hotspot_xM
;
1343 if (NLMISC::nlstricmp(hsStr
[hsIndex
], "R") == 0)
1345 hs
[hsIndex
] = Hotspot_xR
;
1349 CLuaIHM::fails(ls
, "%s : couldn't parse hotspot for horizontal scrollbar", funcName
);
1353 ensureVisible(CLuaIHM::getUIOnStack(ls
, 1), hs
[0], hs
[1]);
1358 // ------------------------------------------------------------------------------------------------
1359 void CCtrlScroll::ensureVisible(CInterfaceElement
*childElement
, THotSpot childHotSpot
, THotSpot parentHotSpot
)
1361 if (!_Target
) return; // not connected to a target yet
1362 if (!childElement
) return;
1363 // compute corners of interest for enclosed element & enclosing group
1364 sint32 childX
, childY
;
1365 childElement
->getCorner(childX
, childY
, childHotSpot
);
1368 sint32 maxHReal
= _Target
->getMaxHReal();
1369 sint32 hReal
= _Target
->getHReal();
1370 if(hReal
> maxHReal
)
1373 switch (parentHotSpot
)
1376 enclosingDY
= maxHReal
;
1379 enclosingDY
= maxHReal
/ 2;
1391 sint32 offsetY
= (_Target
->getYReal() + _Target
->getHReal() - childY
) - enclosingDY
;
1392 NLMISC::clamp(offsetY
, 0, hReal
- maxHReal
);
1393 _Target
->setOfsY(offsetY
);
1394 _Target
->invalidateCoords();
1396 else if (_Aligned
== 1)
1398 // Bottom aligned case
1399 sint32 offsetY
= (maxHReal
- enclosingDY
) - (childY
- _Target
->getYReal());
1400 NLMISC::clamp(offsetY
, maxHReal
- hReal
, 0);
1401 _Target
->setOfsY(offsetY
);
1402 _Target
->invalidateCoords();
1405 // else, ... fully visible (not occluded by parent group)
1409 sint32 maxWReal
= _Target
->getMaxWReal();
1410 sint32 wReal
= _Target
->getWReal();
1411 if(wReal
> maxWReal
)
1414 switch (parentHotSpot
)
1417 enclosingDX
= maxWReal
;
1420 enclosingDX
= maxWReal
/ 2;
1431 // right aligned case
1432 sint32 offsetX
= (_Target
->getXReal() + _Target
->getWReal() - childX
) - enclosingDX
;
1433 NLMISC::clamp(offsetX
, 0, wReal
- maxWReal
);
1434 _Target
->setOfsX(offsetX
);
1435 _Target
->invalidateCoords();
1437 else if (_Aligned
== 2)
1439 // Left aligned case
1440 sint32 offsetX
= (maxWReal
- enclosingDX
) - (childX
- _Target
->getXReal());
1441 NLMISC::clamp(offsetX
, maxWReal
- wReal
, 0);
1442 _Target
->setOfsX(offsetX
);
1443 _Target
->invalidateCoords();
1446 // else, ... fully visible (not occluded by parent group)