Merge branch 'fixes' into main/rendor-staging
[ryzomcore.git] / nel / src / gui / ctrl_base_button.cpp
blobf306c8b528a0099da923978cf29790082cf477f0
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2018 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) 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/ctrl_base_button.h"
24 #include "nel/misc/xml_auto_ptr.h"
25 #include "nel/gui/interface_group.h"
26 #include "nel/gui/lua_ihm.h"
27 #include "nel/gui/widget_manager.h"
28 #include "nel/gui/db_manager.h"
31 using namespace std;
32 using namespace NLMISC;
34 #ifdef DEBUG_NEW
35 #define new DEBUG_NEW
36 #endif
38 namespace
40 const uint KEY_REPEAT_MIN = 100;
41 const uint KEY_REPEAT_MAX = 750;
44 namespace NLGUI
47 sint64 CCtrlBaseButton::_LastLeftClickDate = 0;
48 NLMISC::CRefPtr<CCtrlBaseButton> CCtrlBaseButton::_LastLeftClickButton;
51 // ***************************************************************************
52 CCtrlBaseButton::CCtrlBaseButton(const TCtorParam &param) : CCtrlBase(param), _Type(ToggleButton)
54 _Pushed = _Over = false;
55 _Frozen = false;
56 _FrozenHalfTone = true;
57 _OverWhenPushed = true;
58 _ColorOver = _ColorPushed = _ColorNormal = NLMISC::CRGBA(255,255,255,255);
59 _ModulateGlobalColorNormal= _ModulateGlobalColorPushed= _ModulateGlobalColorOver= true;
60 _LeftLongClickHandled = true;
61 _LeftDblClickHandled = false;
62 _ClickWhenPushed = false;
63 _RBRefBut = NULL;
64 _RBRef = NULL;
66 _AHOnOver = NULL;
67 _AHOnLeftClick = NULL;
68 _AHOnRightClick = NULL;
69 _AHOnClockTick = NULL;
70 _AHOnLeftLongClick = NULL;
71 _AHOnLeftDblClick = NULL;
74 std::string CCtrlBaseButton::getProperty( const std::string &name ) const
76 if( name == "button_type" )
78 return getTypeString();
80 else
81 if( name == "pushed" )
83 return toString( _Pushed );
85 else
86 if( name == "over_when_pushed" )
88 return toString( _OverWhenPushed );
90 else
91 if( name == "clicked_when_pushed" )
93 return toString( _ClickWhenPushed );
95 else
96 if( name == "color" )
98 return getColorAsString();
100 else
101 if( name == "col_pushed" )
103 return getColorPushedAsString();
105 else
106 if( name == "col_over" )
108 return getColorOverAsString();
110 else
111 if( name == "global_color_normal" )
113 return toString( _ModulateGlobalColorNormal );
115 else
116 if( name == "global_color_pushed" )
118 return toString( _ModulateGlobalColorPushed );
120 else
121 if( name == "global_color_over" )
123 return toString( _ModulateGlobalColorOver );
125 else
126 if( name == "onover" )
128 return getAHString( "onover" );
130 else
131 if( name == "params_over" )
133 return _getParamsOnOver();
135 else
136 if( name == "onclick_l" )
138 return getAHString( "onclick_l" );
140 else
141 if( name == "params_l" )
143 return _getParamsOnLeftClick();
145 else
146 if( name == "ondblclick_l" )
148 return getAHString( "ondblclick_l" );
150 else
151 if( name == "params_dblclick_l" )
153 return _AHLeftDblClickParams.toString();
155 else
156 if( name == "onlongclick_l" )
158 return getAHString( "onlongclick_l" );
160 else
161 if( name == "params_longclick_l" )
163 return _AHLeftLongClickParams.toString();
165 else
166 if( name == "onclick_r" )
168 return getAHString( "onclick_r" );
170 else
171 if( name == "params_r" )
173 return _AHRightClickParams.toString();
175 else
176 if( name == "onclock_tick" )
178 return getAHString( "onclock_tick" );
180 else
181 if( name == "params_clock_tick" )
183 return _AHClockTickParams.toString();
185 else
186 if( name == "menu_l" )
188 return _ListMenuLeft.toString();
190 else
191 if( name == "menu_r" )
193 return _ListMenuRight.toString();
195 else
196 if( name == "menu_b" )
198 if( _ListMenuLeft.toString() == _ListMenuRight.toString() )
199 return _ListMenuLeft.toString();
200 else
201 return "";
203 else
204 if( name == "frozen" )
206 return toString( _Frozen );
208 else
209 if( name == "frozen_half_tone" )
211 return toString( _FrozenHalfTone );
213 else
214 return CCtrlBase::getProperty( name );
217 void CCtrlBaseButton::setProperty( const std::string &name, const std::string &value )
219 if( name == "button_type" )
221 setTypeFromString( value );
222 return;
224 else
225 if( name == "pushed" )
227 bool b;
228 if( fromString( value, b ) )
229 _Pushed = b;
230 return;
232 else
233 if( name == "over_when_pushed" )
235 bool b;
236 if( fromString( value, b ) )
237 _OverWhenPushed = b;
238 return;
240 else
241 if( name == "clicked_when_pushed" )
243 bool b;
244 if( fromString( value, b ) )
245 _ClickWhenPushed = b;
246 return;
248 else
249 if( name == "color" )
251 setColorAsString( value );
252 return;
254 else
255 if( name == "col_pushed" )
257 setColorPushedAsString( value );
258 return;
260 else
261 if( name == "col_over" )
263 setColorOverAsString( value );
264 return;
266 else
267 if( name == "global_color_normal" )
269 bool b;
270 if( fromString( value, b ) )
271 _ModulateGlobalColorNormal = b;
272 return;
274 else
275 if( name == "global_color_pushed" )
277 bool b;
278 if( fromString( value, b ) )
279 _ModulateGlobalColorPushed = b;
280 return;
283 else
284 if( name == "global_color_over" )
286 bool b;
287 if( fromString( value, b ) )
288 _ModulateGlobalColorOver = b;
289 return;
291 else
292 if( name == "onover" )
294 std::string dummy;
295 _AHOnOver = CAHManager::getInstance()->getAH( value, dummy );
296 mapAHString( "onover", value );
297 return;
299 else
300 if( name == "params_over" )
302 _AHOverParams = value;
303 return;
305 else
306 if( name == "onclick_l" )
308 std::string dummy;
309 _AHOnLeftClick = CAHManager::getInstance()->getAH( value, dummy );
310 mapAHString( "onclick_l", value );
311 return;
313 else
314 if( name == "params_l" )
316 _AHLeftClickParams = value;
317 return;
319 else
320 if( name == "ondblclick_l" )
322 std::string dummy;
323 _AHOnLeftDblClick = CAHManager::getInstance()->getAH( value, dummy );
324 mapAHString( "ondblclick_l", value );
325 return;
327 else
328 if( name == "params_dblclick_l" )
330 _AHLeftDblClickParams = value;
331 return;
333 else
334 if( name == "onlongclick_l" )
336 std::string dummy;
337 _AHOnLeftLongClick = CAHManager::getInstance()->getAH( value, dummy );
338 mapAHString( "onlongclick_l", value );
339 return;
341 else
342 if( name == "params_longclick_l" )
344 _AHLeftLongClickParams = value;
345 return;
347 else
348 if( name == "onclick_r" )
350 std::string dummy;
351 _AHOnRightClick = CAHManager::getInstance()->getAH( value, dummy );
352 mapAHString( "onclick_r", value );
353 return;
355 else
356 if( name == "params_r" )
358 _AHRightClickParams = value;
359 return;
361 else
362 if( name == "onclock_tick" )
364 std::string dummy;
365 _AHOnClockTick = CAHManager::getInstance()->getAH( value, dummy );
366 mapAHString( "onclock_tick", value );
367 return;
369 else
370 if( name == "params_clock_tick" )
372 _AHClockTickParams = value;
373 return;
375 else
376 if( name == "menu_l" )
378 _ListMenuLeft = value;
379 return;
381 else
382 if( name == "menu_r" )
384 _ListMenuRight = value;
385 return;
387 else
388 if( name == "menu_b" )
390 _ListMenuLeft = _ListMenuRight = value;
391 return;
393 else
394 if( name == "frozen" )
396 bool b;
397 if( fromString( value, b ) )
398 _Frozen = b;
399 return;
401 else
402 if( name == "frozen_half_tone" )
404 bool b;
405 if( fromString( value, b ) )
406 _FrozenHalfTone = b;
407 return;
409 else
410 CCtrlBase::setProperty( name, value );
414 xmlNodePtr CCtrlBaseButton::serialize( xmlNodePtr parentNode, const char *type ) const
416 xmlNodePtr node = CCtrlBase::serialize( parentNode, type );
417 if( node == NULL )
418 return NULL;
420 xmlSetProp( node, BAD_CAST "type", BAD_CAST "button" );
421 xmlNewProp( node, BAD_CAST "button_type", BAD_CAST getTypeString().c_str() );
422 xmlNewProp( node, BAD_CAST "pushed", BAD_CAST toString( _Pushed ).c_str() );
423 xmlNewProp( node, BAD_CAST "over_when_pushed", BAD_CAST toString( _OverWhenPushed ).c_str() );
424 xmlNewProp( node, BAD_CAST "clicked_when_pushed", BAD_CAST toString( _ClickWhenPushed ).c_str() );
425 xmlNewProp( node, BAD_CAST "color", BAD_CAST getColorAsString().c_str() );
426 xmlNewProp( node, BAD_CAST "col_pushed", BAD_CAST getColorPushedAsString().c_str() );
427 xmlNewProp( node, BAD_CAST "col_over", BAD_CAST getColorOverAsString().c_str() );
428 xmlNewProp( node, BAD_CAST "global_color_normal", BAD_CAST toString( _ModulateGlobalColorNormal ).c_str() );
429 xmlNewProp( node, BAD_CAST "global_color_pushed", BAD_CAST toString( _ModulateGlobalColorPushed ).c_str() );
430 xmlNewProp( node, BAD_CAST "global_color_over", BAD_CAST toString( _ModulateGlobalColorOver ).c_str() );
432 xmlNewProp( node, BAD_CAST "onover", BAD_CAST getAHString( "onover" ).c_str() );
433 xmlNewProp( node, BAD_CAST "params_over", BAD_CAST _getParamsOnOver().c_str() );
434 xmlNewProp( node, BAD_CAST "onclick_l", BAD_CAST getAHString( "onclick_l" ).c_str() );
435 xmlNewProp( node, BAD_CAST "params_l", BAD_CAST _getParamsOnLeftClick().c_str() );
436 xmlNewProp( node, BAD_CAST "ondblclick_l", BAD_CAST getAHString( "ondblclick_l" ).c_str() );
437 xmlNewProp( node, BAD_CAST "params_dblclick_l", BAD_CAST _AHLeftDblClickParams.toString().c_str() );
438 xmlNewProp( node, BAD_CAST "onlongclick_l", BAD_CAST getAHString( "onlongclick_l" ).c_str() );
439 xmlNewProp( node, BAD_CAST "params_longclick_l", BAD_CAST _AHLeftLongClickParams.toString().c_str() );
440 xmlNewProp( node, BAD_CAST "onclick_r", BAD_CAST getAHString( "onclick_r" ).c_str() );
441 xmlNewProp( node, BAD_CAST "params_r", BAD_CAST _AHRightClickParams.toString().c_str() );
442 xmlNewProp( node, BAD_CAST "onclock_tick", BAD_CAST getAHString( "onclock_tick" ).c_str() );
443 xmlNewProp( node, BAD_CAST "params_clock_tick", BAD_CAST _AHClockTickParams.toString().c_str() );
446 xmlNewProp( node, BAD_CAST "menu_l", BAD_CAST _ListMenuLeft.toString().c_str() );
447 xmlNewProp( node, BAD_CAST "menu_r", BAD_CAST _ListMenuRight.toString().c_str() );
449 if( _ListMenuLeft.toString() == _ListMenuRight.toString() )
450 xmlNewProp( node, BAD_CAST "menu_b", BAD_CAST _ListMenuLeft.toString().c_str() );
451 else
452 xmlNewProp( node, BAD_CAST "menu_b", BAD_CAST "" );
454 xmlNewProp( node, BAD_CAST "frozen", BAD_CAST toString( _Frozen ).c_str() );
455 xmlNewProp( node, BAD_CAST "frozen_half_tone", BAD_CAST toString( _FrozenHalfTone ).c_str() );
457 return node;
461 // ***************************************************************************
462 bool CCtrlBaseButton::parse (xmlNodePtr cur,CInterfaceGroup * parentGroup)
464 CXMLAutoPtr prop;
466 //try to get props that can be inherited from groups
467 //if a property is not defined, try to find it in the parent group.
468 //if it is undefined, set it to zero
469 if (! CCtrlBase::parse(cur,parentGroup) )
470 return false;
472 _Over = false;
474 // *** try to get the NEEDED specific props
475 prop = xmlGetProp (cur, (xmlChar*)"button_type");
476 string type;
477 if (prop)
479 type = (const char*) prop;
482 if (type.empty() || type == "toggle_button")
484 _Type = ToggleButton;
486 else if (type == "push_button")
488 _Type = PushButton;
490 else if (type == "radio_button")
492 _Type = RadioButton;
494 initRBRef();
495 if (_Pushed)
496 *_RBRef = this;
498 else
500 nlinfo(("cannot parse button type for button " + getId()).c_str());
503 prop= (char*) xmlGetProp (cur, (xmlChar*)"pushed");
504 _Pushed = false;
505 if (prop)
506 _Pushed = convertBool(prop);
508 prop= (char*) xmlGetProp (cur, (xmlChar*)"over_when_pushed");
509 _OverWhenPushed = true;
510 if (prop)
511 _OverWhenPushed = convertBool(prop);
513 prop= (char*) xmlGetProp (cur, (xmlChar*)"click_when_pushed");
514 _ClickWhenPushed = false;
515 if (prop)
516 _ClickWhenPushed = convertBool(prop);
518 // *** Read Colors
519 // get color normal
520 prop= (char*) xmlGetProp( cur, (xmlChar*)"color" );
521 _ColorNormal = CRGBA(255,255,255,255);
522 if (prop)
523 _ColorNormal = convertColor (prop);
525 // Get ColorPushed
526 prop= (char*) xmlGetProp( cur, (xmlChar*)"col_pushed" );
527 _ColorPushed = CRGBA(255,255,255,255);
528 if (prop)
529 _ColorPushed = convertColor(prop);
531 // Get ColorOver
532 prop= (char*) xmlGetProp( cur, (xmlChar*)"col_over" );
533 _ColorOver = CRGBA(255,255,255,255);
534 if (prop)
535 _ColorOver = convertColor(prop);
537 // Default: take "global_color" param interface_element option.
538 _ModulateGlobalColorNormal= _ModulateGlobalColorPushed= _ModulateGlobalColorOver= getModulateGlobalColor();
540 // Read special global_color for each state
541 prop = (char*) xmlGetProp( cur, (xmlChar*)"global_color_normal" );
542 if (prop) _ModulateGlobalColorNormal= convertBool(prop);
543 prop = (char*) xmlGetProp( cur, (xmlChar*)"global_color_pushed" );
544 if (prop) _ModulateGlobalColorPushed= convertBool(prop);
545 prop = (char*) xmlGetProp( cur, (xmlChar*)"global_color_over" );
546 if (prop) _ModulateGlobalColorOver= convertBool(prop);
549 // *** Read Action handlers
550 CAHManager::getInstance()->parseAH(cur, "onover", "params_over", _AHOnOver, _AHOverParams);
551 CAHManager::getInstance()->parseAH(cur, "onclick_l", "params_l", _AHOnLeftClick, _AHLeftClickParams);
552 CAHManager::getInstance()->parseAH(cur, "ondblclick_l", "params_dblclick_l", _AHOnLeftDblClick, _AHLeftDblClickParams);
553 CAHManager::getInstance()->parseAH(cur, "onclick_r", "params_r", _AHOnRightClick, _AHRightClickParams);
554 CAHManager::getInstance()->parseAH(cur, "onlongclick_l", "params_longclick_l", _AHOnLeftLongClick, _AHLeftLongClickParams);
555 CAHManager::getInstance()->parseAH(cur, "onclock_tick", "params_clock_tick", _AHOnClockTick, _AHClockTickParams);
557 if( editorMode )
559 prop = (char*) xmlGetProp( cur, BAD_CAST "onover" );
560 if (prop)
561 mapAHString( "onover", std::string( (const char*)prop ) );
563 prop = (char*) xmlGetProp( cur, BAD_CAST "onclick_l" );
564 if (prop)
565 mapAHString( "onclick_l", std::string( (const char*)prop ) );
567 prop = (char*) xmlGetProp( cur, BAD_CAST "ondblclick_l" );
568 if (prop)
569 mapAHString( "ondblclick_l", std::string( (const char*)prop ) );
571 prop = (char*) xmlGetProp( cur, BAD_CAST "onclick_r" );
572 if (prop)
573 mapAHString( "onclick_r", std::string( (const char*)prop ) );
575 prop = (char*) xmlGetProp( cur, BAD_CAST "onlongclick_l" );
576 if (prop)
577 mapAHString( "onlongclick_l", std::string( (const char*)prop ) );
579 prop = (char*) xmlGetProp( cur, BAD_CAST "onclock_tick" );
580 if (prop)
581 mapAHString( "onclock_tick", std::string( (const char*)prop ) );
584 // Context menu association
585 prop = (char*) xmlGetProp( cur, (xmlChar*)"menu_l" );
586 if (prop)
588 _ListMenuLeft = NLMISC::toLowerAscii(std::string((const char *) prop));
590 prop = (char*) xmlGetProp( cur, (xmlChar*)"menu_r" );
591 if (prop)
593 _ListMenuRight = NLMISC::toLowerAscii(std::string((const char *) prop));
595 // list menu on both clicks
596 prop = (char*) xmlGetProp( cur, (xmlChar*)"menu_b" );
597 if (prop)
599 setListMenuBoth(NLMISC::toLowerAscii(std::string((const char *) prop)));
602 prop= (char*) xmlGetProp (cur, (xmlChar*)"frozen");
603 _Frozen = false;
604 if (prop)
605 _Frozen = convertBool(prop);
607 prop= (char*) xmlGetProp (cur, (xmlChar*)"frozen_half_tone");
608 _FrozenHalfTone = true;
609 if (prop)
610 _FrozenHalfTone = convertBool(prop);
612 return true;
616 // ***************************************************************************
617 void CCtrlBaseButton::setModulateGlobalColorAll(bool state)
619 setModulateGlobalColor(state);
620 setModulateGlobalColorNormal(state);
621 setModulateGlobalColorPushed(state);
622 setModulateGlobalColorOver(state);
626 // ***************************************************************************
627 bool CCtrlBaseButton::handleEvent (const NLGUI::CEventDescriptor& event)
629 if (CCtrlBase::handleEvent(event)) return true;
630 if (!_Active || _Frozen)
631 return false;
633 sint64 T1 = NLMISC::CTime::getLocalTime();
635 if (event.getType() == NLGUI::CEventDescriptor::mouse)
637 const NLGUI::CEventDescriptorMouse &eventDesc = (const NLGUI::CEventDescriptorMouse &)event;
639 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup)
641 if (CWidgetManager::getInstance()->getCapturePointerLeft() != this)
642 return false;
643 _LeftLongClickHandled = true;
646 if (!((eventDesc.getX() >= _XReal) &&
647 (eventDesc.getX() < (_XReal + _WReal))&&
648 (eventDesc.getY() > _YReal) &&
649 (eventDesc.getY() <= (_YReal+ _HReal))))
650 return false;
652 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown)
654 if (_AHOnLeftDblClick)
656 if ((CCtrlBaseButton *) _LastLeftClickButton == this && (T1 - _LastLeftClickDate) < CWidgetManager::getInstance()->getUserDblClickDelay())
658 CAHManager::getInstance()->runActionHandler (_AHOnLeftDblClick, this, _AHLeftDblClickParams);
659 _LeftDblClickHandled = true;
660 _LastLeftClickButton = NULL;
661 return true;
665 if (_AHOnLeftLongClick != NULL)
667 _LeftLongClickHandled = false;
668 _LeftLongClickDate = T1;
670 _LeftDblClickHandled = false;
671 _LastLeftClickButton = NULL;
672 return true;
675 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup)
677 if (CWidgetManager::getInstance()->getCapturePointerLeft() != this)
678 return false;
680 if (_LeftDblClickHandled) // no effect on mouse up after double click has been handled
682 _LeftDblClickHandled = false;
683 return true;
686 // Do not launch 2 times action handler if we are already pushed ! except if we want.
687 if (!_ClickWhenPushed)
689 if ((_Type == RadioButton) && _RBRef && (*_RBRef == this))
690 return true;
693 if (_Type == RadioButton)
695 _Pushed = true;
696 if(_RBRef) *_RBRef = this;
699 if (_Type == ToggleButton)
700 _Pushed = !_Pushed;
703 // RunAction
704 if(_AHOnLeftClick != NULL)
706 //nlinfo("clicked on %s", _Id.c_str());
707 pIM->submitEvent ("button_click:"+getId());//TEMP
708 CAHManager::getInstance()->runActionHandler (_AHOnLeftClick, this, _AHLeftClickParams);
709 //pIM->submitEvent ("button_click:"+getId());
713 // top-right corner is EventX=0, EventY=0
714 _EventX = eventDesc.getX() - _XReal;
715 _EventY = (_YReal + _HReal) - eventDesc.getY();
717 runLeftClickAction();
718 if (CWidgetManager::getInstance()->getCapturePointerLeft() == NULL) return true; // event handler may release cpature from this object (if it is removed for example)
720 // Run Menu
721 if (!_ListMenuLeft.empty())
722 CWidgetManager::getInstance()->enableModalWindow (this, _ListMenuLeft);
724 if (_AHOnLeftDblClick != NULL)
726 _LastLeftClickDate = T1;
727 _LastLeftClickButton = this;
730 // Always return true on LeftClick.
731 return true;
733 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightdown)
735 _LastLeftClickButton = NULL;
736 return true;
738 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightup)
740 _LastLeftClickButton = NULL;
741 bool handled= false;
742 if (CWidgetManager::getInstance()->getCapturePointerRight() != this)
743 return false;
745 // RunAction
746 if(_AHOnRightClick != NULL)
748 handled= true;
749 CAHManager::getInstance()->runActionHandler (_AHOnRightClick, this, _AHRightClickParams);
751 if (CWidgetManager::getInstance()->getCapturePointerRight() == NULL) return true; // if this become NULL, this ctrl has been deleted
752 // Run Menu
753 if (!_ListMenuRight .empty())
755 handled= true;
756 CWidgetManager::getInstance()->enableModalWindow (this, _ListMenuRight);
758 // If not handled here, ret to parent
759 return handled;
764 else if (event.getType() == NLGUI::CEventDescriptor::system)
766 const NLGUI::CEventDescriptorSystem &systemEvent = (const NLGUI::CEventDescriptorSystem &) event;
767 if (systemEvent.getEventTypeExtended() == NLGUI::CEventDescriptorSystem::clocktick)
769 if (_AHOnClockTick != NULL)
771 CAHManager::getInstance()->runActionHandler(_AHOnClockTick, this, _AHClockTickParams);
774 if (CWidgetManager::getInstance()->getCapturePointerLeft() == this)
776 if (!_LeftLongClickHandled)
778 uint nVal = 50;
779 CCDBNodeLeaf *pNL = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:KEY_REPEAT_SPEED");
780 if (pNL != NULL)
781 nVal = pNL->getValue32();
782 uint repeatDelay = (uint)(KEY_REPEAT_MIN + (KEY_REPEAT_MAX-KEY_REPEAT_MIN) * (float)nVal / 100.0f);
783 if ((T1 - _LeftLongClickDate) > repeatDelay)
785 _LeftLongClickHandled = true;
786 CAHManager::getInstance()->runActionHandler(_AHOnLeftLongClick, this, _AHLeftLongClickParams);
792 return false;
795 std::string CCtrlBaseButton::getTypeString() const
797 switch( _Type )
799 case PushButton:
800 return "push_button";
801 break;
803 case ToggleButton:
804 return "toggle_button";
805 break;
807 case RadioButton:
808 return "radio_button";
809 break;
811 default:
812 break;
815 return "";
818 void CCtrlBaseButton::setTypeFromString( const std::string &type )
820 if( type.empty() || type == "toggle_button" )
822 _Type = ToggleButton;
823 return;
825 else
826 if( type == "push_button" )
828 _Type = PushButton;
829 return;
831 else
832 if( type == "radio_button" )
834 _Type = RadioButton;
836 initRBRef();
837 if( _Pushed )
838 *_RBRef = this;
840 return;
842 else
844 _Type = ToggleButton;
845 nlinfo( ( "cannot parse button type for button " + getId() ).c_str() );
849 // ***************************************************************************
850 void CCtrlBaseButton::initRBRef()
852 if (_RBRef != NULL) return;
853 nlassert(_Parent);
854 const vector<CCtrlBase*> &vCB = _Parent->getControls();
855 uint i = 0;
856 for (i = 0; i < vCB.size(); ++i)
858 CCtrlBaseButton *pBut = dynamic_cast<CCtrlBaseButton*>(vCB[i]);
859 if (pBut && pBut->_Type == RadioButton)
861 _RBRef = &pBut->_RBRefBut;
862 break;
865 // If we are the first radio button of the group and not added
866 if (i == vCB.size())
867 _RBRef = &this->_RBRefBut;
870 // ***************************************************************************
871 void CCtrlBaseButton::initRBRefFromRadioButton(CCtrlBaseButton * pBut)
873 if(pBut && pBut->_Type == RadioButton)
875 _RBRef = &(pBut->_RBRefBut);
876 _RBRefBut=NULL;
881 // ***************************************************************************
882 void CCtrlBaseButton::setPushed (bool state)
884 _Pushed = state;
886 if (_Type == RadioButton && _RBRef)
888 if (state == true)
890 *_RBRef = this;
892 else
894 if (*_RBRef == this) // I have to be pushed to unpush me
895 *_RBRef = NULL; // After that : All radio buttons are NOT pushed
900 // ***************************************************************************
901 void CCtrlBaseButton::setFrozen (bool state)
903 _Frozen = state;
904 if (_Frozen)
906 _Pushed = false;
907 _Over = false;
911 // ***************************************************************************
912 void CCtrlBaseButton::setFrozenHalfTone(bool enabled)
914 _FrozenHalfTone = enabled;
917 // ***************************************************************************
918 void CCtrlBaseButton::unselect()
920 if (_Type == RadioButton)
922 if (_RBRef) *_RBRef = NULL;
927 // ***************************************************************************
928 void CCtrlBaseButton::updateOver(bool &lastOver)
930 if (!CWidgetManager::getInstance()->isMouseHandlingEnabled())
932 _Over = false;
933 return;
936 if (CWidgetManager::getInstance()->getCapturePointerLeft() != NULL)
938 if (CWidgetManager::getInstance()->getCapturePointerLeft() != this)
940 _Over = false;
942 return;
945 const vector<CCtrlBase*> &rVB = CWidgetManager::getInstance()->getCtrlsUnderPointer ();
947 if (!_Frozen)
949 uint32 i;
950 lastOver = _Over;
951 // show over if it is the last control that has the same father
952 CCtrlBase *candidate = NULL;
953 for (i = 0; i < rVB.size(); ++i)
955 if (rVB[i]->getParent() == this->getParent())
957 candidate = rVB[i];
960 _Over = (candidate == this);
962 else
963 _Over = false;
968 // ***************************************************************************
969 void CCtrlBaseButton::elementCaptured(CCtrlBase *capturedElement)
971 // if not me, then reset my '_Over'
972 if (capturedElement != this)
974 _Over = false;
979 // ***************************************************************************
980 void CCtrlBaseButton::runLeftClickAction()
982 if(_AHOnLeftClick != NULL)
985 //nlinfo("clicked on %s", _Id.c_str());
986 CAHManager::getInstance()->submitEvent( "button_click:" + getId() );
987 CAHManager::getInstance()->runActionHandler (_AHOnLeftClick, this, _AHLeftClickParams);
988 //pIM->submitEvent ("button_click:"+getId());
992 // ***************************************************************************
993 int CCtrlBaseButton::luaRunLeftClickAction(CLuaState &ls)
995 const char *funcName = "onLeftClick";
996 CLuaIHM::checkArgCount(ls, funcName, 0);
998 runLeftClickAction();
1000 return 0;
1003 // ***************************************************************************
1004 void CCtrlBaseButton::runRightClickAction()
1006 if(_AHOnRightClick != NULL)
1009 CAHManager::getInstance()->submitEvent( "button_click:" + getId() );
1010 CAHManager::getInstance()->runActionHandler (_AHOnRightClick, this, _AHRightClickParams);
1014 // ***************************************************************************
1015 int CCtrlBaseButton::luaRunRightClickAction(CLuaState &ls)
1017 const char *funcName = "onRightClick";
1018 CLuaIHM::checkArgCount(ls, funcName, 0);
1020 runRightClickAction();
1022 return 0;