aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CGUISkin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CGUISkin.cpp')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/CGUISkin.cpp1019
1 files changed, 1019 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CGUISkin.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CGUISkin.cpp
new file mode 100644
index 0000000..b0b2b39
--- /dev/null
+++ b/libraries/irrlicht-1.8/source/Irrlicht/CGUISkin.cpp
@@ -0,0 +1,1019 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h
4
5#include "CGUISkin.h"
6#ifdef _IRR_COMPILE_WITH_GUI_
7
8#include "IGUIFont.h"
9#include "IGUISpriteBank.h"
10#include "IGUIElement.h"
11#include "IVideoDriver.h"
12#include "IAttributes.h"
13
14namespace irr
15{
16namespace gui
17{
18
19CGUISkin::CGUISkin(EGUI_SKIN_TYPE type, video::IVideoDriver* driver)
20: SpriteBank(0), Driver(driver), Type(type)
21{
22 #ifdef _DEBUG
23 setDebugName("CGUISkin");
24 #endif
25
26 if ((Type == EGST_WINDOWS_CLASSIC) || (Type == EGST_WINDOWS_METALLIC))
27 {
28 Colors[EGDC_3D_DARK_SHADOW] = video::SColor(101,50,50,50);
29 Colors[EGDC_3D_SHADOW] = video::SColor(101,130,130,130);
30 Colors[EGDC_3D_FACE] = video::SColor(101,210,210,210);
31 Colors[EGDC_3D_HIGH_LIGHT] = video::SColor(101,255,255,255);
32 Colors[EGDC_3D_LIGHT] = video::SColor(101,210,210,210);
33 Colors[EGDC_ACTIVE_BORDER] = video::SColor(101,16,14,115);
34 Colors[EGDC_ACTIVE_CAPTION] = video::SColor(255,255,255,255);
35 Colors[EGDC_APP_WORKSPACE] = video::SColor(101,100,100,100);
36 Colors[EGDC_BUTTON_TEXT] = video::SColor(240,10,10,10);
37 Colors[EGDC_GRAY_TEXT] = video::SColor(240,130,130,130);
38 Colors[EGDC_HIGH_LIGHT] = video::SColor(101,8,36,107);
39 Colors[EGDC_HIGH_LIGHT_TEXT] = video::SColor(240,255,255,255);
40 Colors[EGDC_INACTIVE_BORDER] = video::SColor(101,165,165,165);
41 Colors[EGDC_INACTIVE_CAPTION] = video::SColor(255,30,30,30);
42 Colors[EGDC_TOOLTIP] = video::SColor(200,0,0,0);
43 Colors[EGDC_TOOLTIP_BACKGROUND] = video::SColor(200,255,255,225);
44 Colors[EGDC_SCROLLBAR] = video::SColor(101,230,230,230);
45 Colors[EGDC_WINDOW] = video::SColor(101,255,255,255);
46 Colors[EGDC_WINDOW_SYMBOL] = video::SColor(200,10,10,10);
47 Colors[EGDC_ICON] = video::SColor(200,255,255,255);
48 Colors[EGDC_ICON_HIGH_LIGHT] = video::SColor(200,8,36,107);
49 Colors[EGDC_GRAY_WINDOW_SYMBOL] = video::SColor(240,100,100,100);
50 Colors[EGDC_EDITABLE] = video::SColor(255,255,255,255);
51 Colors[EGDC_GRAY_EDITABLE] = video::SColor(255,120,120,120);
52 Colors[EGDC_FOCUSED_EDITABLE] = video::SColor(255,240,240,255);
53
54
55 Sizes[EGDS_SCROLLBAR_SIZE] = 14;
56 Sizes[EGDS_MENU_HEIGHT] = 30;
57 Sizes[EGDS_WINDOW_BUTTON_WIDTH] = 15;
58 Sizes[EGDS_CHECK_BOX_WIDTH] = 18;
59 Sizes[EGDS_MESSAGE_BOX_WIDTH] = 500;
60 Sizes[EGDS_MESSAGE_BOX_HEIGHT] = 200;
61 Sizes[EGDS_BUTTON_WIDTH] = 80;
62 Sizes[EGDS_BUTTON_HEIGHT] = 30;
63
64 Sizes[EGDS_TEXT_DISTANCE_X] = 2;
65 Sizes[EGDS_TEXT_DISTANCE_Y] = 0;
66
67 Sizes[EGDS_TITLEBARTEXT_DISTANCE_X] = 2;
68 Sizes[EGDS_TITLEBARTEXT_DISTANCE_Y] = 0;
69 }
70 else
71 {
72 //0x80a6a8af
73 Colors[EGDC_3D_DARK_SHADOW] = 0x60767982;
74 //Colors[EGDC_3D_FACE] = 0xc0c9ccd4; // tab background
75 Colors[EGDC_3D_FACE] = 0xc0cbd2d9; // tab background
76 Colors[EGDC_3D_SHADOW] = 0x50e4e8f1; // tab background, and left-top highlight
77 Colors[EGDC_3D_HIGH_LIGHT] = 0x40c7ccdc;
78 Colors[EGDC_3D_LIGHT] = 0x802e313a;
79 Colors[EGDC_ACTIVE_BORDER] = 0x80404040; // window title
80 Colors[EGDC_ACTIVE_CAPTION] = 0xffd0d0d0;
81 Colors[EGDC_APP_WORKSPACE] = 0xc0646464; // unused
82 Colors[EGDC_BUTTON_TEXT] = 0xd0161616;
83 Colors[EGDC_GRAY_TEXT] = 0x3c141414;
84 Colors[EGDC_HIGH_LIGHT] = 0x6c606060;
85 Colors[EGDC_HIGH_LIGHT_TEXT] = 0xd0e0e0e0;
86 Colors[EGDC_INACTIVE_BORDER] = 0xf0a5a5a5;
87 Colors[EGDC_INACTIVE_CAPTION] = 0xffd2d2d2;
88 Colors[EGDC_TOOLTIP] = 0xf00f2033;
89 Colors[EGDC_TOOLTIP_BACKGROUND] = 0xc0cbd2d9;
90 Colors[EGDC_SCROLLBAR] = 0xf0e0e0e0;
91 Colors[EGDC_WINDOW] = 0xf0f0f0f0;
92 Colors[EGDC_WINDOW_SYMBOL] = 0xd0161616;
93 Colors[EGDC_ICON] = 0xd0161616;
94 Colors[EGDC_ICON_HIGH_LIGHT] = 0xd0606060;
95 Colors[EGDC_GRAY_WINDOW_SYMBOL] = 0x3c101010;
96 Colors[EGDC_EDITABLE] = 0xf0ffffff;
97 Colors[EGDC_GRAY_EDITABLE] = 0xf0cccccc;
98 Colors[EGDC_FOCUSED_EDITABLE] = 0xf0fffff0;
99
100 Sizes[EGDS_SCROLLBAR_SIZE] = 14;
101 Sizes[EGDS_MENU_HEIGHT] = 48;
102 Sizes[EGDS_WINDOW_BUTTON_WIDTH] = 15;
103 Sizes[EGDS_CHECK_BOX_WIDTH] = 18;
104 Sizes[EGDS_MESSAGE_BOX_WIDTH] = 500;
105 Sizes[EGDS_MESSAGE_BOX_HEIGHT] = 200;
106 Sizes[EGDS_BUTTON_WIDTH] = 80;
107 Sizes[EGDS_BUTTON_HEIGHT] = 30;
108
109 Sizes[EGDS_TEXT_DISTANCE_X] = 3;
110 Sizes[EGDS_TEXT_DISTANCE_Y] = 2;
111
112 Sizes[EGDS_TITLEBARTEXT_DISTANCE_X] = 3;
113 Sizes[EGDS_TITLEBARTEXT_DISTANCE_Y] = 2;
114 }
115
116 Sizes[EGDS_MESSAGE_BOX_GAP_SPACE] = 15;
117 Sizes[EGDS_MESSAGE_BOX_MIN_TEXT_WIDTH] = 0;
118 Sizes[EGDS_MESSAGE_BOX_MAX_TEXT_WIDTH] = 500;
119 Sizes[EGDS_MESSAGE_BOX_MIN_TEXT_HEIGHT] = 0;
120 Sizes[EGDS_MESSAGE_BOX_MAX_TEXT_HEIGHT] = 99999;
121
122 Sizes[EGDS_BUTTON_PRESSED_IMAGE_OFFSET_X] = 1;
123 Sizes[EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y] = 1;
124 Sizes[EGDS_BUTTON_PRESSED_TEXT_OFFSET_X] = 0;
125 Sizes[EGDS_BUTTON_PRESSED_TEXT_OFFSET_Y] = 2;
126
127 Texts[EGDT_MSG_BOX_OK] = L"OK";
128 Texts[EGDT_MSG_BOX_CANCEL] = L"Cancel";
129 Texts[EGDT_MSG_BOX_YES] = L"Yes";
130 Texts[EGDT_MSG_BOX_NO] = L"No";
131 Texts[EGDT_WINDOW_CLOSE] = L"Close";
132 Texts[EGDT_WINDOW_RESTORE] = L"Restore";
133 Texts[EGDT_WINDOW_MINIMIZE] = L"Minimize";
134 Texts[EGDT_WINDOW_MAXIMIZE] = L"Maximize";
135
136 Icons[EGDI_WINDOW_MAXIMIZE] = 225;
137 Icons[EGDI_WINDOW_RESTORE] = 226;
138 Icons[EGDI_WINDOW_CLOSE] = 227;
139 Icons[EGDI_WINDOW_MINIMIZE] = 228;
140 Icons[EGDI_CURSOR_UP] = 229;
141 Icons[EGDI_CURSOR_DOWN] = 230;
142 Icons[EGDI_CURSOR_LEFT] = 231;
143 Icons[EGDI_CURSOR_RIGHT] = 232;
144 Icons[EGDI_MENU_MORE] = 232;
145 Icons[EGDI_CHECK_BOX_CHECKED] = 233;
146 Icons[EGDI_DROP_DOWN] = 234;
147 Icons[EGDI_SMALL_CURSOR_UP] = 235;
148 Icons[EGDI_SMALL_CURSOR_DOWN] = 236;
149 Icons[EGDI_RADIO_BUTTON_CHECKED] = 237;
150 Icons[EGDI_MORE_LEFT] = 238;
151 Icons[EGDI_MORE_RIGHT] = 239;
152 Icons[EGDI_MORE_UP] = 240;
153 Icons[EGDI_MORE_DOWN] = 241;
154 Icons[EGDI_WINDOW_RESIZE] = 242;
155 Icons[EGDI_EXPAND] = 243;
156 Icons[EGDI_COLLAPSE] = 244;
157
158 Icons[EGDI_FILE] = 245;
159 Icons[EGDI_DIRECTORY] = 246;
160
161 for (u32 i=0; i<EGDF_COUNT; ++i)
162 Fonts[i] = 0;
163
164 UseGradient = (Type == EGST_WINDOWS_METALLIC) || (Type == EGST_BURNING_SKIN) ;
165}
166
167
168//! destructor
169CGUISkin::~CGUISkin()
170{
171 for (u32 i=0; i<EGDF_COUNT; ++i)
172 {
173 if (Fonts[i])
174 Fonts[i]->drop();
175 }
176
177 if (SpriteBank)
178 SpriteBank->drop();
179}
180
181
182//! returns default color
183video::SColor CGUISkin::getColor(EGUI_DEFAULT_COLOR color) const
184{
185 if ((u32)color < EGDC_COUNT)
186 return Colors[color];
187 else
188 return video::SColor();
189}
190
191
192//! sets a default color
193void CGUISkin::setColor(EGUI_DEFAULT_COLOR which, video::SColor newColor)
194{
195 if ((u32)which < EGDC_COUNT)
196 Colors[which] = newColor;
197}
198
199
200//! returns size for the given size type
201s32 CGUISkin::getSize(EGUI_DEFAULT_SIZE size) const
202{
203 if ((u32)size < EGDS_COUNT)
204 return Sizes[size];
205 else
206 return 0;
207}
208
209
210//! sets a default size
211void CGUISkin::setSize(EGUI_DEFAULT_SIZE which, s32 size)
212{
213 if ((u32)which < EGDS_COUNT)
214 Sizes[which] = size;
215}
216
217
218//! returns the default font
219IGUIFont* CGUISkin::getFont(EGUI_DEFAULT_FONT which) const
220{
221 if (((u32)which < EGDF_COUNT) && Fonts[which])
222 return Fonts[which];
223 else
224 return Fonts[EGDF_DEFAULT];
225}
226
227
228//! sets a default font
229void CGUISkin::setFont(IGUIFont* font, EGUI_DEFAULT_FONT which)
230{
231 if ((u32)which >= EGDF_COUNT)
232 return;
233
234 if (font)
235 {
236 font->grab();
237 if (Fonts[which])
238 Fonts[which]->drop();
239
240 Fonts[which] = font;
241 }
242}
243
244
245//! gets the sprite bank stored
246IGUISpriteBank* CGUISkin::getSpriteBank() const
247{
248 return SpriteBank;
249}
250
251
252//! set a new sprite bank or remove one by passing 0
253void CGUISkin::setSpriteBank(IGUISpriteBank* bank)
254{
255 if (bank)
256 bank->grab();
257
258 if (SpriteBank)
259 SpriteBank->drop();
260
261 SpriteBank = bank;
262}
263
264
265//! Returns a default icon
266u32 CGUISkin::getIcon(EGUI_DEFAULT_ICON icon) const
267{
268 if ((u32)icon < EGDI_COUNT)
269 return Icons[icon];
270 else
271 return 0;
272}
273
274
275//! Sets a default icon
276void CGUISkin::setIcon(EGUI_DEFAULT_ICON icon, u32 index)
277{
278 if ((u32)icon < EGDI_COUNT)
279 Icons[icon] = index;
280}
281
282
283//! Returns a default text. For example for Message box button captions:
284//! "OK", "Cancel", "Yes", "No" and so on.
285const wchar_t* CGUISkin::getDefaultText(EGUI_DEFAULT_TEXT text) const
286{
287 if ((u32)text < EGDT_COUNT)
288 return Texts[text].c_str();
289 else
290 return Texts[0].c_str();
291}
292
293
294//! Sets a default text. For example for Message box button captions:
295//! "OK", "Cancel", "Yes", "No" and so on.
296void CGUISkin::setDefaultText(EGUI_DEFAULT_TEXT which, const wchar_t* newText)
297{
298 if ((u32)which < EGDT_COUNT)
299 Texts[which] = newText;
300}
301
302
303//! draws a standard 3d button pane
304/** Used for drawing for example buttons in normal state.
305It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and
306EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details.
307\param rect: Defining area where to draw.
308\param clip: Clip area.
309\param element: Pointer to the element which wishes to draw this. This parameter
310is usually not used by ISkin, but can be used for example by more complex
311implementations to find out how to draw the part exactly. */
312void CGUISkin::draw3DButtonPaneStandard(IGUIElement* element,
313 const core::rect<s32>& r,
314 const core::rect<s32>* clip)
315{
316 if (!Driver)
317 return;
318
319 core::rect<s32> rect = r;
320
321 if ( Type == EGST_BURNING_SKIN )
322 {
323 rect.UpperLeftCorner.X -= 1;
324 rect.UpperLeftCorner.Y -= 1;
325 rect.LowerRightCorner.X += 1;
326 rect.LowerRightCorner.Y += 1;
327 draw3DSunkenPane(element,
328 getColor( EGDC_WINDOW ).getInterpolated( 0xFFFFFFFF, 0.9f )
329 ,false, true, rect, clip);
330 return;
331 }
332
333 Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, clip);
334
335 rect.LowerRightCorner.X -= 1;
336 rect.LowerRightCorner.Y -= 1;
337 Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip);
338
339 rect.UpperLeftCorner.X += 1;
340 rect.UpperLeftCorner.Y += 1;
341 Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip);
342
343 rect.LowerRightCorner.X -= 1;
344 rect.LowerRightCorner.Y -= 1;
345
346 if (!UseGradient)
347 {
348 Driver->draw2DRectangle(getColor(EGDC_3D_FACE), rect, clip);
349 }
350 else
351 {
352 const video::SColor c1 = getColor(EGDC_3D_FACE);
353 const video::SColor c2 = c1.getInterpolated(getColor(EGDC_3D_DARK_SHADOW), 0.4f);
354 Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip);
355 }
356}
357
358
359//! draws a pressed 3d button pane
360/** Used for drawing for example buttons in pressed state.
361It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and
362EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details.
363\param rect: Defining area where to draw.
364\param clip: Clip area.
365\param element: Pointer to the element which wishes to draw this. This parameter
366is usually not used by ISkin, but can be used for example by more complex
367implementations to find out how to draw the part exactly. */
368void CGUISkin::draw3DButtonPanePressed(IGUIElement* element,
369 const core::rect<s32>& r,
370 const core::rect<s32>* clip)
371{
372 if (!Driver)
373 return;
374
375 core::rect<s32> rect = r;
376 Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip);
377
378 rect.LowerRightCorner.X -= 1;
379 rect.LowerRightCorner.Y -= 1;
380 Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, clip);
381
382 rect.UpperLeftCorner.X += 1;
383 rect.UpperLeftCorner.Y += 1;
384 Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip);
385
386 rect.UpperLeftCorner.X += 1;
387 rect.UpperLeftCorner.Y += 1;
388
389 if (!UseGradient)
390 {
391 Driver->draw2DRectangle(getColor(EGDC_3D_FACE), rect, clip);
392 }
393 else
394 {
395 const video::SColor c1 = getColor(EGDC_3D_FACE);
396 const video::SColor c2 = c1.getInterpolated(getColor(EGDC_3D_DARK_SHADOW), 0.4f);
397 Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip);
398 }
399}
400
401
402//! draws a sunken 3d pane
403/** Used for drawing the background of edit, combo or check boxes.
404\param element: Pointer to the element which wishes to draw this. This parameter
405is usually not used by ISkin, but can be used for example by more complex
406implementations to find out how to draw the part exactly.
407\param bgcolor: Background color.
408\param flat: Specifies if the sunken pane should be flat or displayed as sunken
409deep into the ground.
410\param rect: Defining area where to draw.
411\param clip: Clip area. */
412void CGUISkin::draw3DSunkenPane(IGUIElement* element, video::SColor bgcolor,
413 bool flat, bool fillBackGround,
414 const core::rect<s32>& r,
415 const core::rect<s32>* clip)
416{
417 if (!Driver)
418 return;
419
420 core::rect<s32> rect = r;
421
422 if (fillBackGround)
423 Driver->draw2DRectangle(bgcolor, rect, clip);
424
425 if (flat)
426 {
427 // draw flat sunken pane
428
429 rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1;
430 Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip); // top
431
432 ++rect.UpperLeftCorner.Y;
433 rect.LowerRightCorner.Y = r.LowerRightCorner.Y;
434 rect.LowerRightCorner.X = rect.UpperLeftCorner.X + 1;
435 Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip); // left
436
437 rect = r;
438 ++rect.UpperLeftCorner.Y;
439 rect.UpperLeftCorner.X = rect.LowerRightCorner.X - 1;
440 Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip); // right
441
442 rect = r;
443 ++rect.UpperLeftCorner.X;
444 rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1;
445 --rect.LowerRightCorner.X;
446 Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip); // bottom
447 }
448 else
449 {
450 // draw deep sunken pane
451 rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1;
452 Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip); // top
453 ++rect.UpperLeftCorner.X;
454 ++rect.UpperLeftCorner.Y;
455 --rect.LowerRightCorner.X;
456 ++rect.LowerRightCorner.Y;
457 Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, clip);
458
459 rect.UpperLeftCorner.X = r.UpperLeftCorner.X;
460 rect.UpperLeftCorner.Y = r.UpperLeftCorner.Y+1;
461 rect.LowerRightCorner.X = rect.UpperLeftCorner.X + 1;
462 rect.LowerRightCorner.Y = r.LowerRightCorner.Y;
463 Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip); // left
464 ++rect.UpperLeftCorner.X;
465 ++rect.UpperLeftCorner.Y;
466 ++rect.LowerRightCorner.X;
467 --rect.LowerRightCorner.Y;
468 Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, clip);
469
470 rect = r;
471 rect.UpperLeftCorner.X = rect.LowerRightCorner.X - 1;
472 ++rect.UpperLeftCorner.Y;
473 Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip); // right
474 --rect.UpperLeftCorner.X;
475 ++rect.UpperLeftCorner.Y;
476 --rect.LowerRightCorner.X;
477 --rect.LowerRightCorner.Y;
478 Driver->draw2DRectangle(getColor(EGDC_3D_LIGHT), rect, clip);
479
480 rect = r;
481 ++rect.UpperLeftCorner.X;
482 rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1;
483 --rect.LowerRightCorner.X;
484 Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip); // bottom
485 ++rect.UpperLeftCorner.X;
486 --rect.UpperLeftCorner.Y;
487 --rect.LowerRightCorner.X;
488 --rect.LowerRightCorner.Y;
489 Driver->draw2DRectangle(getColor(EGDC_3D_LIGHT), rect, clip);
490 }
491}
492
493
494//! draws a window background
495// return where to draw title bar text.
496core::rect<s32> CGUISkin::draw3DWindowBackground(IGUIElement* element,
497 bool drawTitleBar, video::SColor titleBarColor,
498 const core::rect<s32>& r,
499 const core::rect<s32>* clip,
500 core::rect<s32>* checkClientArea)
501{
502 if (!Driver)
503 {
504 if ( checkClientArea )
505 {
506 *checkClientArea = r;
507 }
508 return r;
509 }
510
511 core::rect<s32> rect = r;
512
513 // top border
514 rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1;
515 if ( !checkClientArea )
516 {
517 Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip);
518 }
519
520 // left border
521 rect.LowerRightCorner.Y = r.LowerRightCorner.Y;
522 rect.LowerRightCorner.X = rect.UpperLeftCorner.X + 1;
523 if ( !checkClientArea )
524 {
525 Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip);
526 }
527
528 // right border dark outer line
529 rect.UpperLeftCorner.X = r.LowerRightCorner.X - 1;
530 rect.LowerRightCorner.X = r.LowerRightCorner.X;
531 rect.UpperLeftCorner.Y = r.UpperLeftCorner.Y;
532 rect.LowerRightCorner.Y = r.LowerRightCorner.Y;
533 if ( !checkClientArea )
534 {
535 Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, clip);
536 }
537
538 // right border bright innner line
539 rect.UpperLeftCorner.X -= 1;
540 rect.LowerRightCorner.X -= 1;
541 rect.UpperLeftCorner.Y += 1;
542 rect.LowerRightCorner.Y -= 1;
543 if ( !checkClientArea )
544 {
545 Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip);
546 }
547
548 // bottom border dark outer line
549 rect.UpperLeftCorner.X = r.UpperLeftCorner.X;
550 rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1;
551 rect.LowerRightCorner.Y = r.LowerRightCorner.Y;
552 rect.LowerRightCorner.X = r.LowerRightCorner.X;
553 if ( !checkClientArea )
554 {
555 Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, clip);
556 }
557
558 // bottom border bright inner line
559 rect.UpperLeftCorner.X += 1;
560 rect.LowerRightCorner.X -= 1;
561 rect.UpperLeftCorner.Y -= 1;
562 rect.LowerRightCorner.Y -= 1;
563 if ( !checkClientArea )
564 {
565 Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip);
566 }
567
568 // client area for background
569 rect = r;
570 rect.UpperLeftCorner.X +=1;
571 rect.UpperLeftCorner.Y +=1;
572 rect.LowerRightCorner.X -= 2;
573 rect.LowerRightCorner.Y -= 2;
574 if (checkClientArea)
575 {
576 *checkClientArea = rect;
577 }
578
579 if ( !checkClientArea )
580 {
581 if (!UseGradient)
582 {
583 Driver->draw2DRectangle(getColor(EGDC_3D_FACE), rect, clip);
584 }
585 else if ( Type == EGST_BURNING_SKIN )
586 {
587 const video::SColor c1 = getColor(EGDC_WINDOW).getInterpolated ( 0xFFFFFFFF, 0.9f );
588 const video::SColor c2 = getColor(EGDC_WINDOW).getInterpolated ( 0xFFFFFFFF, 0.8f );
589
590 Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip);
591 }
592 else
593 {
594 const video::SColor c2 = getColor(EGDC_3D_SHADOW);
595 const video::SColor c1 = getColor(EGDC_3D_FACE);
596 Driver->draw2DRectangle(rect, c1, c1, c1, c2, clip);
597 }
598 }
599
600 // title bar
601 rect = r;
602 rect.UpperLeftCorner.X += 2;
603 rect.UpperLeftCorner.Y += 2;
604 rect.LowerRightCorner.X -= 2;
605 rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + getSize(EGDS_WINDOW_BUTTON_WIDTH) + 2;
606
607 if (drawTitleBar )
608 {
609 if (checkClientArea)
610 {
611 (*checkClientArea).UpperLeftCorner.Y = rect.LowerRightCorner.Y;
612 }
613 else
614 {
615 // draw title bar
616 //if (!UseGradient)
617 // Driver->draw2DRectangle(titleBarColor, rect, clip);
618 //else
619 if ( Type == EGST_BURNING_SKIN )
620 {
621 const video::SColor c = titleBarColor.getInterpolated( video::SColor(titleBarColor.getAlpha(),255,255,255), 0.8f);
622 Driver->draw2DRectangle(rect, titleBarColor, titleBarColor, c, c, clip);
623 }
624 else
625 {
626 const video::SColor c = titleBarColor.getInterpolated(video::SColor(titleBarColor.getAlpha(),0,0,0), 0.2f);
627 Driver->draw2DRectangle(rect, titleBarColor, c, titleBarColor, c, clip);
628 }
629 }
630 }
631
632 return rect;
633}
634
635
636//! draws a standard 3d menu pane
637/** Used for drawing for menus and context menus.
638It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and
639EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details.
640\param element: Pointer to the element which wishes to draw this. This parameter
641is usually not used by ISkin, but can be used for example by more complex
642implementations to find out how to draw the part exactly.
643\param rect: Defining area where to draw.
644\param clip: Clip area. */
645void CGUISkin::draw3DMenuPane(IGUIElement* element,
646 const core::rect<s32>& r, const core::rect<s32>* clip)
647{
648 if (!Driver)
649 return;
650
651 core::rect<s32> rect = r;
652
653 if ( Type == EGST_BURNING_SKIN )
654 {
655 rect.UpperLeftCorner.Y -= 3;
656 draw3DButtonPaneStandard(element, rect, clip);
657 return;
658 }
659
660 // in this skin, this is exactly what non pressed buttons look like,
661 // so we could simply call
662 // draw3DButtonPaneStandard(element, rect, clip);
663 // here.
664 // but if the skin is transparent, this doesn't look that nice. So
665 // We draw it a little bit better, with some more draw2DRectangle calls,
666 // but there aren't that much menus visible anyway.
667
668 rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1;
669 Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip);
670
671 rect.LowerRightCorner.Y = r.LowerRightCorner.Y;
672 rect.LowerRightCorner.X = rect.UpperLeftCorner.X + 1;
673 Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip);
674
675 rect.UpperLeftCorner.X = r.LowerRightCorner.X - 1;
676 rect.LowerRightCorner.X = r.LowerRightCorner.X;
677 rect.UpperLeftCorner.Y = r.UpperLeftCorner.Y;
678 rect.LowerRightCorner.Y = r.LowerRightCorner.Y;
679 Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, clip);
680
681 rect.UpperLeftCorner.X -= 1;
682 rect.LowerRightCorner.X -= 1;
683 rect.UpperLeftCorner.Y += 1;
684 rect.LowerRightCorner.Y -= 1;
685 Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip);
686
687 rect.UpperLeftCorner.X = r.UpperLeftCorner.X;
688 rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1;
689 rect.LowerRightCorner.Y = r.LowerRightCorner.Y;
690 rect.LowerRightCorner.X = r.LowerRightCorner.X;
691 Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, clip);
692
693 rect.UpperLeftCorner.X += 1;
694 rect.LowerRightCorner.X -= 1;
695 rect.UpperLeftCorner.Y -= 1;
696 rect.LowerRightCorner.Y -= 1;
697 Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip);
698
699 rect = r;
700 rect.UpperLeftCorner.X +=1;
701 rect.UpperLeftCorner.Y +=1;
702 rect.LowerRightCorner.X -= 2;
703 rect.LowerRightCorner.Y -= 2;
704
705 if (!UseGradient)
706 Driver->draw2DRectangle(getColor(EGDC_3D_FACE), rect, clip);
707 else
708 {
709 const video::SColor c1 = getColor(EGDC_3D_FACE);
710 const video::SColor c2 = getColor(EGDC_3D_SHADOW);
711 Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip);
712 }
713}
714
715
716//! draws a standard 3d tool bar
717/** Used for drawing for toolbars and menus.
718\param element: Pointer to the element which wishes to draw this. This parameter
719is usually not used by ISkin, but can be used for example by more complex
720implementations to find out how to draw the part exactly.
721\param rect: Defining area where to draw.
722\param clip: Clip area. */
723void CGUISkin::draw3DToolBar(IGUIElement* element,
724 const core::rect<s32>& r,
725 const core::rect<s32>* clip)
726{
727 if (!Driver)
728 return;
729
730 core::rect<s32> rect = r;
731
732 rect.UpperLeftCorner.X = r.UpperLeftCorner.X;
733 rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1;
734 rect.LowerRightCorner.Y = r.LowerRightCorner.Y;
735 rect.LowerRightCorner.X = r.LowerRightCorner.X;
736 Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip);
737
738 rect = r;
739 rect.LowerRightCorner.Y -= 1;
740
741 if (!UseGradient)
742 {
743 Driver->draw2DRectangle(getColor(EGDC_3D_FACE), rect, clip);
744 }
745 else
746 if ( Type == EGST_BURNING_SKIN )
747 {
748 const video::SColor c1 = 0xF0000000 | getColor(EGDC_3D_FACE).color;
749 const video::SColor c2 = 0xF0000000 | getColor(EGDC_3D_SHADOW).color;
750
751 rect.LowerRightCorner.Y += 1;
752 Driver->draw2DRectangle(rect, c1, c2, c1, c2, clip);
753 }
754 else
755 {
756 const video::SColor c1 = getColor(EGDC_3D_FACE);
757 const video::SColor c2 = getColor(EGDC_3D_SHADOW);
758 Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip);
759 }
760}
761
762
763//! draws a tab button
764/** Used for drawing for tab buttons on top of tabs.
765\param element: Pointer to the element which wishes to draw this. This parameter
766is usually not used by ISkin, but can be used for example by more complex
767implementations to find out how to draw the part exactly.
768\param active: Specifies if the tab is currently active.
769\param rect: Defining area where to draw.
770\param clip: Clip area. */
771void CGUISkin::draw3DTabButton(IGUIElement* element, bool active,
772 const core::rect<s32>& frameRect, const core::rect<s32>* clip, EGUI_ALIGNMENT alignment)
773{
774 if (!Driver)
775 return;
776
777 core::rect<s32> tr = frameRect;
778
779 if ( alignment == EGUIA_UPPERLEFT )
780 {
781 tr.LowerRightCorner.X -= 2;
782 tr.LowerRightCorner.Y = tr.UpperLeftCorner.Y + 1;
783 tr.UpperLeftCorner.X += 1;
784 Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), tr, clip);
785
786 // draw left highlight
787 tr = frameRect;
788 tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1;
789 tr.UpperLeftCorner.Y += 1;
790 Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), tr, clip);
791
792 // draw grey background
793 tr = frameRect;
794 tr.UpperLeftCorner.X += 1;
795 tr.UpperLeftCorner.Y += 1;
796 tr.LowerRightCorner.X -= 2;
797 Driver->draw2DRectangle(getColor(EGDC_3D_FACE), tr, clip);
798
799 // draw right middle gray shadow
800 tr.LowerRightCorner.X += 1;
801 tr.UpperLeftCorner.X = tr.LowerRightCorner.X - 1;
802 Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), tr, clip);
803
804 tr.LowerRightCorner.X += 1;
805 tr.UpperLeftCorner.X += 1;
806 tr.UpperLeftCorner.Y += 1;
807 Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), tr, clip);
808 }
809 else
810 {
811 tr.LowerRightCorner.X -= 2;
812 tr.UpperLeftCorner.Y = tr.LowerRightCorner.Y - 1;
813 tr.UpperLeftCorner.X += 1;
814 Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), tr, clip);
815
816 // draw left highlight
817 tr = frameRect;
818 tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1;
819 tr.LowerRightCorner.Y -= 1;
820 Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), tr, clip);
821
822 // draw grey background
823 tr = frameRect;
824 tr.UpperLeftCorner.X += 1;
825 tr.UpperLeftCorner.Y -= 1;
826 tr.LowerRightCorner.X -= 2;
827 tr.LowerRightCorner.Y -= 1;
828 Driver->draw2DRectangle(getColor(EGDC_3D_FACE), tr, clip);
829
830 // draw right middle gray shadow
831 tr.LowerRightCorner.X += 1;
832 tr.UpperLeftCorner.X = tr.LowerRightCorner.X - 1;
833 //tr.LowerRightCorner.Y -= 1;
834 Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), tr, clip);
835
836 tr.LowerRightCorner.X += 1;
837 tr.UpperLeftCorner.X += 1;
838 tr.LowerRightCorner.Y -= 1;
839 Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), tr, clip);
840 }
841}
842
843
844//! draws a tab control body
845/** \param element: Pointer to the element which wishes to draw this. This parameter
846is usually not used by ISkin, but can be used for example by more complex
847implementations to find out how to draw the part exactly.
848\param border: Specifies if the border should be drawn.
849\param background: Specifies if the background should be drawn.
850\param rect: Defining area where to draw.
851\param clip: Clip area. */
852void CGUISkin::draw3DTabBody(IGUIElement* element, bool border, bool background,
853 const core::rect<s32>& rect, const core::rect<s32>* clip, s32 tabHeight, EGUI_ALIGNMENT alignment)
854{
855 if (!Driver)
856 return;
857
858 core::rect<s32> tr = rect;
859
860 if ( tabHeight == -1 )
861 tabHeight = getSize(gui::EGDS_BUTTON_HEIGHT);
862
863 // draw border.
864 if (border)
865 {
866 if ( alignment == EGUIA_UPPERLEFT )
867 {
868 // draw left hightlight
869 tr.UpperLeftCorner.Y += tabHeight + 2;
870 tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1;
871 Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), tr, clip);
872
873 // draw right shadow
874 tr.UpperLeftCorner.X = rect.LowerRightCorner.X - 1;
875 tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1;
876 Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), tr, clip);
877
878 // draw lower shadow
879 tr = rect;
880 tr.UpperLeftCorner.Y = tr.LowerRightCorner.Y - 1;
881 Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), tr, clip);
882 }
883 else
884 {
885 // draw left hightlight
886 tr.LowerRightCorner.Y -= tabHeight + 2;
887 tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1;
888 Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), tr, clip);
889
890 // draw right shadow
891 tr.UpperLeftCorner.X = rect.LowerRightCorner.X - 1;
892 tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1;
893 Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), tr, clip);
894
895 // draw lower shadow
896 tr = rect;
897 tr.LowerRightCorner.Y = tr.UpperLeftCorner.Y + 1;
898 Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), tr, clip);
899 }
900 }
901
902 if (background)
903 {
904 if ( alignment == EGUIA_UPPERLEFT )
905 {
906 tr = rect;
907 tr.UpperLeftCorner.Y += tabHeight + 2;
908 tr.LowerRightCorner.X -= 1;
909 tr.UpperLeftCorner.X += 1;
910 tr.LowerRightCorner.Y -= 1;
911 }
912 else
913 {
914 tr = rect;
915 tr.UpperLeftCorner.X += 1;
916 tr.UpperLeftCorner.Y -= 1;
917 tr.LowerRightCorner.X -= 1;
918 tr.LowerRightCorner.Y -= tabHeight + 2;
919 //tr.UpperLeftCorner.X += 1;
920 }
921
922 if (!UseGradient)
923 Driver->draw2DRectangle(getColor(EGDC_3D_FACE), tr, clip);
924 else
925 {
926 video::SColor c1 = getColor(EGDC_3D_FACE);
927 video::SColor c2 = getColor(EGDC_3D_SHADOW);
928 Driver->draw2DRectangle(tr, c1, c1, c2, c2, clip);
929 }
930 }
931}
932
933
934//! draws an icon, usually from the skin's sprite bank
935/** \param parent: Pointer to the element which wishes to draw this icon.
936This parameter is usually not used by IGUISkin, but can be used for example
937by more complex implementations to find out how to draw the part exactly.
938\param icon: Specifies the icon to be drawn.
939\param position: The position to draw the icon
940\param starttime: The time at the start of the animation
941\param currenttime: The present time, used to calculate the frame number
942\param loop: Whether the animation should loop or not
943\param clip: Clip area. */
944void CGUISkin::drawIcon(IGUIElement* element, EGUI_DEFAULT_ICON icon,
945 const core::position2di position,
946 u32 starttime, u32 currenttime,
947 bool loop, const core::rect<s32>* clip)
948{
949 if (!SpriteBank)
950 return;
951
952 bool gray = element && !element->isEnabled();
953 SpriteBank->draw2DSprite(Icons[icon], position, clip,
954 Colors[gray? EGDC_GRAY_WINDOW_SYMBOL : EGDC_WINDOW_SYMBOL], starttime, currenttime, loop, true);
955}
956
957
958EGUI_SKIN_TYPE CGUISkin::getType() const
959{
960 return Type;
961}
962
963
964//! draws a 2d rectangle.
965void CGUISkin::draw2DRectangle(IGUIElement* element,
966 const video::SColor &color, const core::rect<s32>& pos,
967 const core::rect<s32>* clip)
968{
969 Driver->draw2DRectangle(color, pos, clip);
970}
971
972
973//! Writes attributes of the object.
974//! Implement this to expose the attributes of your scene node animator for
975//! scripting languages, editors, debuggers or xml serialization purposes.
976void CGUISkin::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
977{
978 u32 i;
979 for (i=0; i<EGDC_COUNT; ++i)
980 out->addColor(GUISkinColorNames[i], Colors[i]);
981
982 for (i=0; i<EGDS_COUNT; ++i)
983 out->addInt(GUISkinSizeNames[i], Sizes[i]);
984
985 for (i=0; i<EGDT_COUNT; ++i)
986 out->addString(GUISkinTextNames[i], Texts[i].c_str());
987
988 for (i=0; i<EGDI_COUNT; ++i)
989 out->addInt(GUISkinIconNames[i], Icons[i]);
990}
991
992
993//! Reads attributes of the object.
994//! Implement this to set the attributes of your scene node animator for
995//! scripting languages, editors, debuggers or xml deserialization purposes.
996void CGUISkin::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
997{
998 // TODO: This is not nice code for downward compatibility, whenever new values are added and users
999 // load an old skin the corresponding values will be set to 0.
1000 u32 i;
1001 for (i=0; i<EGDC_COUNT; ++i)
1002 Colors[i] = in->getAttributeAsColor(GUISkinColorNames[i]);
1003
1004 for (i=0; i<EGDS_COUNT; ++i)
1005 Sizes[i] = in->getAttributeAsInt(GUISkinSizeNames[i]);
1006
1007 for (i=0; i<EGDT_COUNT; ++i)
1008 Texts[i] = in->getAttributeAsStringW(GUISkinTextNames[i]);
1009
1010 for (i=0; i<EGDI_COUNT; ++i)
1011 Icons[i] = in->getAttributeAsInt(GUISkinIconNames[i]);
1012}
1013
1014
1015} // end namespace gui
1016} // end namespace irr
1017
1018#endif // _IRR_COMPILE_WITH_GUI_
1019