Merge branch 'main/rendor-staging' into fixes
[ryzomcore.git] / nel / src / gui / group_scrolltext.cpp
blob8f6b471bc5dfda661e5504bff843e54e9a0169f6
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2015 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 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "stdpch.h"
22 #include "nel/gui/group_scrolltext.h"
23 #include "nel/gui/group_list.h"
24 #include "nel/gui/view_text.h"
25 #include "nel/gui/ctrl_scroll.h"
26 #include "nel/gui/ctrl_button.h"
27 #include "nel/gui/action_handler.h"
28 #include "nel/misc/i18n.h"
29 #include "nel/gui/widget_manager.h"
31 #ifdef DEBUG_NEW
32 #define new DEBUG_NEW
33 #endif
35 NLMISC_REGISTER_OBJECT(CViewBase, CGroupScrollText, std::string, "scroll_text");
37 namespace NLGUI
40 //========================================================================
41 CGroupScrollText::CGroupScrollText(const TCtorParam &param) :
42 CInterfaceGroup(param),
43 _List(NULL),
44 _ScrollBar(NULL),
45 _ButtonAdd(NULL),
46 _ButtonSub(NULL),
47 _Settuped(false),
48 _InvertScrollBar(true),
49 _ListHeight(0),
50 _Scrolling(false),
51 _ScrollDistance(0),
52 _ClockMsgEventRegistered(false),
53 _StartHeight(0),
54 _EllapsedTime(0)
56 _IsGroupScrollText = true;
59 //========================================================================
60 CGroupScrollText::~CGroupScrollText()
64 std::string CGroupScrollText::getProperty( const std::string &name ) const
66 if( name == "invert_scroll_bar" )
67 return NLMISC::toString( _InvertScrollBar );
68 else
69 return CInterfaceGroup::getProperty( name );
72 void CGroupScrollText::setProperty( const std::string &name, const std::string &value )
74 if( name == "invert_scroll_bar" )
76 bool b;
77 if( NLMISC::fromString( value, b ) )
78 _InvertScrollBar = b;
79 return;
81 else
82 CInterfaceGroup::setProperty( name, value );
86 xmlNodePtr CGroupScrollText::serialize( xmlNodePtr parentNode, const char *type ) const
88 xmlNodePtr node = CInterfaceGroup::serialize( parentNode, type );
89 if( node == NULL )
90 return NULL;
92 xmlSetProp( node, BAD_CAST "type", BAD_CAST "scroll_text" );
93 xmlSetProp( node, BAD_CAST "invert_scroll_bar", BAD_CAST NLMISC::toString( _InvertScrollBar ).c_str() );
95 return node;
98 //========================================================================
99 bool CGroupScrollText::parse(xmlNodePtr cur,CInterfaceGroup *parentGroup)
101 if(!CInterfaceGroup::parse(cur, parentGroup))
102 return false;
103 CXMLAutoPtr ptr;
105 // invert scroll bar?
106 ptr = xmlGetProp (cur, (xmlChar*)"invert_scroll_bar");
107 if(ptr) _InvertScrollBar= convertBool(ptr);
109 return true;
112 //========================================================================
113 void CGroupScrollText::updateCoords()
115 CInterfaceGroup::updateCoords();
116 if (!_Settuped) setup();
117 updateScrollBar();
118 // re-update of scrollbar
119 if(_ScrollBar)
120 _ScrollBar->updateCoords();
123 //========================================================================
124 void CGroupScrollText::updateScrollBar()
126 if (_List && _ScrollBar)
128 if (_List->getHReal() < _List->getMaxHReal())
130 _ScrollBar->setActive(false);
132 else
134 _ScrollBar->setActive(true);
139 //========================================================================
140 void CGroupScrollText::checkCoords ()
142 // update scrollbar if necessary
143 if (_List)
145 if (_List->getH() != _ListHeight) // see if the scrollbar should be updated
147 invalidateCoords();
148 _ListHeight = _List->getH();
151 CInterfaceGroup::checkCoords();
154 //========================================================================
155 void CGroupScrollText::draw()
157 CInterfaceGroup::draw();
160 //========================================================================
161 void CGroupScrollText::clearViews()
163 CInterfaceGroup::clearViews();
166 //========================================================================
167 bool CGroupScrollText::handleEvent(const NLGUI::CEventDescriptor &event)
169 if (event.getType() == NLGUI::CEventDescriptor::mouse)
171 const NLGUI::CEventDescriptorMouse &eventDesc = (const NLGUI::CEventDescriptorMouse &)event;
173 if (_List && _ScrollBar)
175 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mousewheel)
177 if (isIn(eventDesc.getX(), eventDesc.getY()))
179 // limit scroll to 100px with single wheel event
180 sint32 h = std::min(100, _List->getMaxHReal() / 2);
181 if (h == 0) h = 1;
183 smoothScrollY(- eventDesc.getWheel() * h);
184 return true;
190 if (event.getType() == NLGUI::CEventDescriptor::system)
192 if (_Scrolling && _ScrollBar)
194 float dy = _ScrollDistance / 4;
195 if ((sint32) dy != 0)
197 _ScrollBar->moveTargetY(dy);
198 _ScrollDistance -= dy;
200 else
202 _Scrolling = false;
203 if (_ClockMsgEventRegistered)
205 _ClockMsgEventRegistered = false;
206 CWidgetManager::getInstance()->unregisterClockMsgTarget(this);
212 if (CInterfaceGroup::handleEvent(event)) return true;
213 return false;
216 //========================================================================
217 void CGroupScrollText::smoothScrollY(sint32 dy)
219 if (!_Scrolling)
221 _Scrolling = true;
222 _ScrollDistance = 0;
224 // register for clock tick event if not already done
225 CWidgetManager *pWM = CWidgetManager::getInstance();
226 if (!pWM->isClockMsgTarget(this))
228 pWM->registerClockMsgTarget(this);
229 _ClockMsgEventRegistered = true;
233 _ScrollDistance += dy;
236 //========================================================================
237 void CGroupScrollText::setup()
239 // bind to the controls
240 _ScrollBar = dynamic_cast<CCtrlScroll *>(CInterfaceGroup::getCtrl("scroll_bar"));
241 _ButtonAdd = dynamic_cast<CCtrlBaseButton *>(CInterfaceGroup::getCtrl("button_add"));
242 _ButtonSub = dynamic_cast<CCtrlBaseButton *>(CInterfaceGroup::getCtrl("button_sub"));
243 _List = dynamic_cast<CGroupList *>(CInterfaceGroup::getGroup("text_list"));
245 if(_ScrollBar == NULL)
246 nlwarning("<setup> scroll bar 'scroll_bar' missing or bad type.(%s)",this->_Id.c_str());
247 // Add and sub button are not required
249 if(buttonAdd == NULL)
250 nlwarning("Interface: CGroupScrollText: button 'button_add' missing or bad type");
251 if(buttonSub == NULL)
252 nlwarning("Interface: CGroupScrollText: button 'button_sub' missing or bad type");
254 if(_List == NULL)
255 nlwarning("<setup> group list 'text_list' missing or bad type");
257 // actions
258 if (_ButtonAdd) _ButtonAdd->setActionOnClockTick("gst_add");
259 if (_ButtonSub) _ButtonSub->setActionOnClockTick("gst_sub");
261 // bind the scrollbar to the list
262 if (_ScrollBar)
264 _ScrollBar->setTarget(_List);
265 //_ScrollBar->setInverted(_InvertScrollBar);
267 _Settuped = true;
270 //========================================================================
271 void CGroupScrollText::elementCaptured(CCtrlBase *capturedElement)
273 if (capturedElement == _ButtonAdd || capturedElement == _ButtonSub)
275 // reset the counters for increase
276 _EllapsedTime = 0;
277 _StartHeight = getH();
281 // ***************************************************************************
282 // ***************************************************************************
283 // Actions Handlers
284 // ***************************************************************************
285 // ***************************************************************************
288 // ***************************************************************************
289 class CSTUp : public IActionHandler
291 public:
292 virtual void execute (CCtrlBase *pCaller, const std::string &/* Params */)
294 const CWidgetManager::SInterfaceTimes &times = CWidgetManager::getInstance()->getInterfaceTimes();
296 CGroupScrollText *pST = dynamic_cast<CGroupScrollText*>(pCaller->getParent());
297 if (pST == NULL) return;
298 if (pST->getList() == NULL) return;
299 // get the font height from the text template of the list
300 const CViewText *vt = pST->getList()->getTextTemplatePtr();
301 if (!vt) return;
302 pST->_EllapsedTime += times.frameDiffMs;
303 // pST->setH(std::min((sint32) pST->getMaxHeight(), (sint32) (pST->_StartHeight + pST->_EllapsedTime / 9)));
304 pST->setH((sint32) (pST->_StartHeight + pST->_EllapsedTime / 9));
305 pST->invalidateCoords();
308 REGISTER_ACTION_HANDLER (CSTUp, "gst_add");
310 // ***************************************************************************
311 class CSTDown : public IActionHandler
313 public:
314 virtual void execute (CCtrlBase *pCaller, const std::string &/* Params */)
316 const CWidgetManager::SInterfaceTimes &times = CWidgetManager::getInstance()->getInterfaceTimes();
318 CGroupScrollText *pST = dynamic_cast<CGroupScrollText*>(pCaller->getParent());
319 if (pST == NULL) return;
320 if (pST->getList() == NULL) return;
321 // get the font height from the text template of the list
322 const CViewText *vt = pST->getList()->getTextTemplatePtr();
323 if (!vt) return;
324 pST->_EllapsedTime += times.frameDiffMs;
325 // pST->setH(std::max((sint32) pST->getMinHeight(), (sint32) (pST->_StartHeight - pST->_EllapsedTime / 9)));
326 pST->setH((sint32) (pST->_StartHeight - pST->_EllapsedTime / 9));
327 pST->invalidateCoords();
330 REGISTER_ACTION_HANDLER (CSTDown, "gst_sub");