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