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/>.
26 #include "nel/misc/common.h"
28 #include "nel/3d/u_driver.h"
37 using namespace NLMISC
;
45 extern UDriver
*Driver
;
51 //////////////////////
52 // CRosaceComponent //
53 //////////////////////
54 //-----------------------------------------------
57 //-----------------------------------------------
58 CRosaceComponent::CRosaceComponent()
60 // No callback function at the beginning.
62 // No texture at the beginning.
68 }// CRosaceComponent //
70 //-----------------------------------------------
72 // Display the component.
73 //-----------------------------------------------
74 void CRosaceComponent::display(bool selected
)
76 // If there is a texture to display.
80 Driver
->drawBitmap(_X
, _Y
, _W
, _H
, *_Texture
, true, CRGBA(255, 0, 0, 255));
82 Driver
->drawBitmap(_X
, _Y
, _W
, _H
, *_Texture
, true, CRGBA(255, 255, 255, 255));
86 //-----------------------------------------------
88 // Execute the callback associated to the component.
89 //-----------------------------------------------
90 void CRosaceComponent::execute()
92 // If there is a callback -> execute it.
97 //-----------------------------------------------
99 // Set the texture for the component.
100 //-----------------------------------------------
101 void CRosaceComponent::texture(const string
&filename
)
103 _Texture
= Driver
->createTextureFile(filename
);
106 //-----------------------------------------------
108 // Return true if the position (x,y) is inside the rosace.
109 //-----------------------------------------------
110 bool CRosaceComponent::inside(float x
, float y
)
112 if(x
>=_X
&& x
<_X
+_W
&& y
>=_Y
&& y
<_Y
+_H
)
123 //-----------------------------------------------
126 //-----------------------------------------------
127 CRosacePage::CRosacePage()
135 //-----------------------------------------------
137 // Constructor. Create some components at the beginning.
138 //-----------------------------------------------
139 CRosacePage::CRosacePage(sint nb
)
143 _Components
.resize(nb
);
145 }// CRosaceContext //
147 //-----------------------------------------------
149 // Display all the components in the page.
150 //-----------------------------------------------
151 void CRosacePage::display()
153 for(uint i
= 0; i
<size(); ++i
)
155 if(_Selected
== (sint
)i
)
156 _Components
[i
].display(true);
158 _Components
[i
].display(false);
162 //-----------------------------------------------
164 // Execute the callback associated to the selected component.
165 //-----------------------------------------------
166 void CRosacePage::execute()
168 // If there is no component selected -> return.
169 if(_Selected
<0 || _Selected
>=(sint
)size())
171 // Else execute the callback associated to the selected component.
172 _Components
[_Selected
].execute();
175 //-----------------------------------------------
177 // Select the next valide component.
178 //-----------------------------------------------
179 void CRosacePage::next()
190 //-----------------------------------------------
192 // Select the previous valide component.
193 //-----------------------------------------------
194 void CRosacePage::previous()
197 // If the selected component is not valide selected the last 1 (-1 is no component).
199 _Selected
= (sint
)size()-1;
202 //-----------------------------------------------
204 // Generate the rosace (all components).
205 //-----------------------------------------------
206 void CRosacePage::generate()
211 double ang
= 2*Pi
/(float)size();
212 double r1
= _W
/(2*sin(ang
/2)); // r = opp/tan @
213 double r2
= _H
/(2*sin(ang
/2));
214 for(uint i
=0; i
<size(); ++i
)
216 double x
= r1
*cos(i
*ang
);
217 double y
= r2
*sin(i
*ang
);
218 _Components
[i
].setPos((float)(0.5f
+x
-_W
/2), (float)(0.5f
+y
-_H
/2));
222 //-----------------------------------------------
225 //-----------------------------------------------
226 void CRosacePage::update(float x
, float y
, TMode mode
)
234 case CursorAngleMode
:
235 cursorAngleMode(x
, y
);
246 nlwarning("Rosace Mode reached.");
253 //-----------------------------------------------
256 //-----------------------------------------------
257 void CRosacePage::select(double ang
)
259 double angTmp
= 2*Pi
/(float)size();
263 _Selected
= (sint
)(ang
/angTmp
);
268 _Selected
= size()-(sint
)(ang
/angTmp
);
271 if(_Selected
>= (sint
)size() || _Selected
<0)
275 //-----------------------------------------------
277 // Select the component under the position (x,y) or unselect all if nothing at this position.
278 //-----------------------------------------------
279 void CRosacePage::cursorMode(float x
, float y
)
281 for(uint i
=0; i
<size(); ++i
)
283 if(_Components
[i
].inside(x
, y
))
294 //-----------------------------------------------
296 // Select elements of the rosace according to the angle generated by mouse position and screen center.
297 //-----------------------------------------------
298 void CRosacePage::cursorAngleMode(float x
, float y
)
300 // If the mouse is near center -> unselect all.
301 if(x
>=0.5f
-0.01f
&& x
<0.5f
+0.01f
&& y
>=0.5f
-0.01f
&& y
<0.5f
+0.01f
)
303 // Select the right element of the rosace according to the angle.
306 uint32 width
, height
;
307 Driver
->getWindowSize(width
, height
);
310 x1
= (double)width
/2.0;
311 x1
= (x
*(double)width
) - x1
;
313 y1
= (double)height
/2.0;
314 y1
= (y
*(double)height
) - y1
;
316 select(atan2(y1
, x1
));
318 }// CursorAngleMode //
320 //-----------------------------------------------
323 //-----------------------------------------------
324 void CRosacePage::directMode(float x
, float y
)
326 float difX
= x
-_OldX
;
327 float difY
= y
-_OldY
;
329 if(fabs(difX
)<0.01f
&& fabs(difY
)<0.01f
)
332 uint32 width
, height
;
333 Driver
->getWindowSize(width
, height
);
335 double x1
= (difX
*(double)width
);
336 double y1
= (difY
*(double)height
);
338 select(atan2(y1
, x1
));
340 // Backup the x and y.
345 //-----------------------------------------------
348 //-----------------------------------------------
349 void CRosacePage::relativeMode(float x
, float /* y */)
351 float difX
= x
-_OldX
;
360 // Backup the x and y.
370 //-----------------------------------------------
373 //-----------------------------------------------
374 CRosaceContext::CRosaceContext()
380 //-----------------------------------------------
382 // Constructor. Create some pages at the beginning.
383 //-----------------------------------------------
384 CRosaceContext::CRosaceContext(sint nb
)
391 //-----------------------------------------------
393 // Display all the pages in the context.
394 //-----------------------------------------------
395 void CRosaceContext::display()
397 // If there is no page selected -> return.
400 // Else display the right page.
401 _Pages
[_Selected
].display();
404 //-----------------------------------------------
406 // Execute the callback associated to the selected component in the selected page.
407 //-----------------------------------------------
408 void CRosaceContext::execute()
410 // If there is no page selected -> return.
413 // Else execute the callback associated to the selected component.
414 _Pages
[_Selected
].execute();
417 //-----------------------------------------------
420 //-----------------------------------------------
421 void CRosaceContext::add(const CRosacePage
&page
)
423 _Pages
.push_back(page
);
426 //-----------------------------------------------
428 // Update the context.
429 //-----------------------------------------------
430 void CRosaceContext::update(float x
, float y
, CRosacePage::TMode mode
)
432 // If there is no page selected -> return.
435 // Update the selected page.
436 _Pages
[_Selected
].update(x
, y
, mode
);
439 //-----------------------------------------------
441 // Select the next valide page.
442 //-----------------------------------------------
443 void CRosaceContext::next()
454 //-----------------------------------------------
456 // Select the previous valide page.
457 //-----------------------------------------------
458 void CRosaceContext::previous()
461 // If the selected component is not valide selected the last 1 (-1 is no component).
463 _Selected
= (sint
)size()-1;
472 //-----------------------------------------------
475 //-----------------------------------------------
481 //-----------------------------------------------
484 //-----------------------------------------------
489 //-----------------------------------------------
491 // Initialize the rosace.
492 //-----------------------------------------------
495 _Mode
= CRosacePage::CursorAngleMode
;
499 //-----------------------------------------------
501 // Add a page. ("" is not valide name).
502 //-----------------------------------------------
503 void CRosace::add(const string
&name
, const CRosaceContext
&context
)
505 // If the name is not empty.
507 _Contexts
.insert(TContexts::value_type (name
, context
));
510 //-----------------------------------------------
512 // Is the current context valide.
513 //-----------------------------------------------
514 bool CRosace::valide()
516 // Check if the Selected context is valide.
517 TContexts::iterator it
= _Contexts
.find(_Selected
);
518 if(it
!= _Contexts
.end())
523 //-----------------------------------------------
525 // Display the rosace.
526 //-----------------------------------------------
527 void CRosace::display()
530 _Contexts
[_Selected
].display();
533 //-----------------------------------------------
536 //-----------------------------------------------
537 void CRosace::update(float x
, float y
)
540 _Contexts
[_Selected
].update(x
, y
, _Mode
);
543 //-----------------------------------------------
545 // Execute the callback function corresponding to the selected component.
546 //-----------------------------------------------
547 void CRosace::execute()
550 _Contexts
[_Selected
].execute();
553 //-----------------------------------------------
555 // Swap to next rosace page.
556 //-----------------------------------------------
560 _Contexts
[_Selected
].next();