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