Merge branch 'main/rendor-staging' into fixes
[ryzomcore.git] / nel / src / gui / ctrl_button.cpp
blob15bf33897778466f172d9c6cbb94d5fc696740aa
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2016 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_button.h"
24 #include "nel/misc/xml_auto_ptr.h"
25 #include "nel/gui/widget_manager.h"
26 #include "nel/gui/interface_group.h"
28 // ----------------------------------------------------------------------------
29 using namespace std;
30 using namespace NLMISC;
31 using namespace NL3D;
33 #ifdef DEBUG_NEW
34 #define new DEBUG_NEW
35 #endif
37 NLMISC_REGISTER_OBJECT(CViewBase, CCtrlButton, std::string, "button");
39 namespace NLGUI
42 void CCtrlButton::setAlignFromString( const std::string &s )
44 _Align = 0;
46 std::string::size_type i;
47 for( i = 0; i < s.size(); i++ )
49 char c = toLower( s[ i ] );
51 switch( c )
53 case 'l':
54 _Align &= ~1;
55 break;
57 case 'r':
58 _Align |= 1;
59 break;
61 case 'b':
62 _Align &= ~2;
63 break;
65 case 't':
66 _Align |= 2;
67 break;
72 std::string CCtrlButton::getProperty( const std::string &name ) const
74 if( name == "tx_normal" )
76 return CViewRenderer::getInstance()->getTextureNameFromId( _TextureIdNormal );
78 else
79 if( name == "tx_pushed" )
81 return CViewRenderer::getInstance()->getTextureNameFromId( _TextureIdPushed );
83 else
84 if( name == "tx_over" )
86 return CViewRenderer::getInstance()->getTextureNameFromId( _TextureIdOver );
88 else
89 if( name == "scale" )
91 return toString( _Scale );
93 else
94 if( name == "align" )
96 std::string align;
97 if( ( _Align & 1 ) != 0 )
98 align = "r";
99 else
100 align = "l";
101 if( ( _Align & 2 ) != 0 )
102 align += "t";
103 else
104 align += "b";
105 return align;
107 else
108 return CCtrlBaseButton::getProperty( name );
111 void CCtrlButton::setProperty( const std::string &name, const std::string &value )
113 if( name == "tx_normal" )
115 std::string s = CViewRenderer::getInstance()->getTextureNameFromId( _TextureIdNormal );
116 if( !_TextureIdNormal.setTexture( value.c_str() ) )
118 _TextureIdNormal.setTexture( s.c_str() );
120 return;
122 else
123 if( name == "tx_pushed" )
125 std::string s = CViewRenderer::getInstance()->getTextureNameFromId( _TextureIdPushed );
126 if( !_TextureIdPushed.setTexture( value.c_str() ) )
128 _TextureIdPushed.setTexture( s.c_str() );
130 return;
132 else
133 if( name == "tx_over" )
135 std::string s = CViewRenderer::getInstance()->getTextureNameFromId( _TextureIdOver );
136 if( !_TextureIdOver.setTexture( value.c_str() ) )
138 _TextureIdOver.setTexture( s.c_str() );
140 return;
142 else
143 if( name == "scale" )
145 bool b;
146 if( fromString( value, b ) )
147 _Scale = b;
148 return;
150 else
151 if( name == "align" )
153 setAlignFromString( value );
154 return;
156 else
157 CCtrlBaseButton::setProperty( name, value );
161 xmlNodePtr CCtrlButton::serialize( xmlNodePtr parentNode, const char *type ) const
163 xmlNodePtr node = CCtrlBaseButton::serialize( parentNode, type );
164 if( node == NULL )
165 return NULL;
167 xmlSetProp( node, BAD_CAST "type", BAD_CAST "button" );
169 xmlNewProp( node, BAD_CAST "tx_normal",
170 BAD_CAST CViewRenderer::getInstance()->getTextureNameFromId( _TextureIdNormal ).c_str() );
172 xmlNewProp( node, BAD_CAST "tx_pushed",
173 BAD_CAST CViewRenderer::getInstance()->getTextureNameFromId( _TextureIdPushed ).c_str() );
175 xmlNewProp( node, BAD_CAST "tx_over",
176 BAD_CAST CViewRenderer::getInstance()->getTextureNameFromId( _TextureIdOver ).c_str() );
178 xmlNewProp( node, BAD_CAST "scale", BAD_CAST toString( _Scale ).c_str() );
180 std::string align;
181 if( ( _Align & 1 ) != 0 )
182 align = "r";
183 else
184 align = "l";
185 if( ( _Align & 2 ) != 0 )
186 align += "t";
187 else
188 align += "b";
190 xmlNewProp( node, BAD_CAST "align", BAD_CAST align.c_str() );
192 return node;
195 // ----------------------------------------------------------------------------
196 bool CCtrlButton::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup)
198 CXMLAutoPtr prop;
199 //try to get props that can be inherited from groups
200 //if a property is not defined, try to find it in the parent group.
201 //if it is undefined, set it to zero
202 if (! CCtrlBaseButton::parse(cur,parentGroup) )
204 string tmp = "cannot parse view:"+getId()+", parent:"+parentGroup->getId();
205 nlinfo(tmp.c_str());
206 return false;
210 // *** Read Textures
211 prop = (char*) xmlGetProp( cur, (xmlChar*)"tx_normal" );
212 if (prop)
214 string TxName = NLMISC::toLowerAscii((const char *) prop);
215 _TextureIdNormal.setTexture(TxName.c_str());
218 prop = (char*) xmlGetProp( cur, (xmlChar*)"tx_pushed" );
219 if (prop)
221 string TxName = NLMISC::toLowerAscii((const char *) prop);
222 _TextureIdPushed.setTexture(TxName.c_str());
225 prop = (char*) xmlGetProp( cur, (xmlChar*)"tx_over" );
226 if (prop)
228 string TxName = NLMISC::toLowerAscii((const char *) prop);
229 _TextureIdOver.setTexture(TxName.c_str());
232 // *** Misc.
233 prop = (char*) xmlGetProp( cur, (xmlChar*)"scale" );
234 _Scale = false;
235 if (prop)
236 _Scale = convertBool(prop);
239 prop = (char*) xmlGetProp (cur, (xmlChar*)"align");
240 if (prop)
242 setAlignFromString( std::string( (const char*)prop ) );
246 return true;
249 // ----------------------------------------------------------------------------
250 void CCtrlButton::draw ()
252 sint32 nTxId = -1;
253 CRGBA color;
255 CViewRenderer &rVR = *CViewRenderer::getInstance();
256 CRGBA globalColor= CWidgetManager::getInstance()->getGlobalColorForContent();
258 // *** Detect Over
259 bool lastOver = false;
261 updateOver(lastOver);
264 sint32 x = _XReal;
265 sint32 y = _YReal;
266 sint32 txw, txh;
267 // the pointer is over the button
268 if (_Scale)
270 x = _XReal;
271 y = _YReal;
272 txw = _WReal;
273 txh = _HReal;
275 else
277 x = _XReal;
278 y = _YReal;
281 switch(_Type)
283 case ToggleButton:
285 if (_Pushed && !editorMode )
287 nTxId = _TextureIdPushed;
288 color = getCurrentColorPushed(globalColor);
290 else
292 nTxId = _TextureIdNormal;
293 color = getCurrentColorNormal(globalColor);
296 break;
297 case RadioButton:
299 // CViewPointer &rIP = *CInterfaceManager::getInstance()->getPointer();
300 // Init the radio button
301 initRBRef();
303 if (*_RBRef == this)
305 // if it is equal to the ref value, then the button must appear pushed
306 nTxId = _TextureIdPushed;
307 color = getCurrentColorPushed(globalColor);
309 else
311 if ( (_Over) && (CWidgetManager::getInstance()->getCapturePointerLeft() == this) && !editorMode )
313 nTxId = _TextureIdPushed;
314 color = getCurrentColorPushed(globalColor);
316 else
318 nTxId = _TextureIdNormal;
319 color = getCurrentColorNormal(globalColor);
320 _Pushed = false;
324 break;
325 case PushButton:
327 if ( _Over && (CWidgetManager::getInstance()->getCapturePointerLeft() == this) && !editorMode )
329 nTxId = _TextureIdPushed;
330 color = getCurrentColorPushed(globalColor);
332 else
334 nTxId = _TextureIdNormal;
335 color = getCurrentColorNormal(globalColor);
336 _Pushed = false;
339 break;
340 default:
341 break;
344 color.A = (uint8)(((sint32)color.A*((sint32)globalColor.A+1))>>8);
346 // Fromzen ?
347 if (getFrozen() && getFrozenHalfTone())
348 color.A >>= 2;
350 if (!_Scale)
352 CViewRenderer::getInstance()->getTextureSizeFromId (nTxId, txw, txh);
353 if (_Align&1)
354 x = x + _WReal - txw;
355 if (_Align&2)
356 y = y + _HReal - txh;
358 rVR.drawRotFlipBitmap ( _RenderLayer, x, y, txw, txh,
359 0, false,
360 nTxId,
361 color );
363 if ((_OverWhenPushed == false) && (_Pushed == true || (CWidgetManager::getInstance()->getCapturePointerLeft() == this)))
364 return;
368 if ( ( _Over && !editorMode ) )
371 if( !editorMode && (lastOver == false) && (_AHOnOver != NULL))
372 CAHManager::getInstance()->runActionHandler (_AHOnOver, this, _AHOverParams);
374 // the pointer is over the button
375 color= getCurrentColorOver(globalColor);
376 color.A = (uint8)(((sint32)color.A*((sint32)globalColor.A+1))>>8);
378 // Frozen ?
379 if (getFrozen())
380 color.A >>= 2;
382 // draw the over. force upper layer to avoid problem with DXTC/tga
383 rVR.drawRotFlipBitmap ( _RenderLayer+1, x, y, txw, txh,
384 0, false,
385 _TextureIdOver,
386 color );
391 // ----------------------------------------------------------------------------
392 void CCtrlButton::updateCoords()
394 if (!_Scale)
396 CViewRenderer &rVR = *CViewRenderer::getInstance();
397 sint32 txw, txh;
398 rVR.getTextureSizeFromId (_TextureIdNormal, txw, txh);
399 _W = txw;
400 _H = txh;
402 CViewBase::updateCoords();
405 // ----------------------------------------------------------------------------
406 void CCtrlButton::setTexture(const std::string&name)
408 // CInterfaceManager *pIM = CInterfaceManager::getInstance();
409 // CViewRenderer &rVR = *CViewRenderer::getInstance();
410 _TextureIdNormal.setTexture(name.c_str (), 0, 0, -1, -1, false);
413 // ----------------------------------------------------------------------------
414 void CCtrlButton::setTexturePushed(const std::string&name)
416 // CInterfaceManager *pIM = CInterfaceManager::getInstance();
417 // CViewRenderer &rVR = *CViewRenderer::getInstance();
418 _TextureIdPushed.setTexture(name.c_str (), 0, 0, -1, -1, false);
421 // ----------------------------------------------------------------------------
422 void CCtrlButton::setTextureOver(const std::string&name)
424 // CInterfaceManager *pIM = CInterfaceManager::getInstance();
425 // CViewRenderer &rVR = *CViewRenderer::getInstance();
426 _TextureIdOver.setTexture(name.c_str (), 0, 0, -1, -1, false);
429 // ----------------------------------------------------------------------------
430 std::string CCtrlButton::getTexture() const
432 CViewRenderer &rVR = *CViewRenderer::getInstance();
433 return rVR.getTextureNameFromId(_TextureIdNormal);
436 // ----------------------------------------------------------------------------
437 std::string CCtrlButton::getTexturePushed() const
439 CViewRenderer &rVR = *CViewRenderer::getInstance();
440 return rVR.getTextureNameFromId(_TextureIdPushed);
443 // ----------------------------------------------------------------------------
444 std::string CCtrlButton::getTextureOver() const
446 CViewRenderer &rVR = *CViewRenderer::getInstance();
447 return rVR.getTextureNameFromId(_TextureIdOver);
450 // ***************************************************************************
451 sint32 CCtrlButton::getMaxUsedW() const
453 if (_Scale)
454 return _WReal;
456 sint32 txw, txh;
457 CViewRenderer &rVR = *CViewRenderer::getInstance();
458 rVR.getTextureSizeFromId (_TextureIdNormal, txw, txh);
459 return txw;
462 // ***************************************************************************
463 sint32 CCtrlButton::getMinUsedW() const
465 return getMaxUsedW();
468 // ***************************************************************************
469 void CCtrlButton::fitTexture()
471 CViewRenderer &rVR = *CViewRenderer::getInstance();
472 sint32 w, h;
473 rVR.getTextureSizeFromId(_TextureIdNormal, w, h);
474 setW(w);
475 setH(h);
478 // ***************************************************************************
479 bool CCtrlButton::getMouseOverShape(string &texName, uint8 &rot, CRGBA &col)
481 if (_AHOnLeftClickString == "browse")
483 if (!_AHOnLeftClickStringParams.empty())
485 texName = "@curs_pick.tga@"+_AHOnLeftClickStringParams;
487 else
489 texName = "curs_pick.tga";
491 rot= 0;
492 col = CRGBA::White;
493 return true;
496 return false;