1 // Copyright (C) 2002-2012 Nikolaus Gebhardt
\r
2 // Copyright (C) 2019 Irrlick
\r
4 // This file is part of the "Irrlicht Engine".
\r
5 // For conditions of distribution and use, see copyright notice in irrlicht.h
\r
9 #include "IGUIFont.h"
\r
10 #include "IGUISpriteBank.h"
\r
11 #include "IGUIElement.h"
\r
12 #include "IVideoDriver.h"
\r
13 #include "IAttributes.h"
\r
20 GUISkin::GUISkin(EGUI_SKIN_TYPE type, video::IVideoDriver* driver)
\r
21 : SpriteBank(0), Driver(driver), Type(type)
\r
24 setDebugName("GUISkin");
\r
27 if ((Type == EGST_WINDOWS_CLASSIC) || (Type == EGST_WINDOWS_METALLIC))
\r
29 Colors[EGDC_3D_DARK_SHADOW] = video::SColor(101,50,50,50);
\r
30 Colors[EGDC_3D_SHADOW] = video::SColor(101,130,130,130);
\r
31 Colors[EGDC_3D_FACE] = video::SColor(220,100,100,100);
\r
32 Colors[EGDC_3D_HIGH_LIGHT] = video::SColor(101,255,255,255);
\r
33 Colors[EGDC_3D_LIGHT] = video::SColor(101,210,210,210);
\r
34 Colors[EGDC_ACTIVE_BORDER] = video::SColor(101,16,14,115);
\r
35 Colors[EGDC_ACTIVE_CAPTION] = video::SColor(255,255,255,255);
\r
36 Colors[EGDC_APP_WORKSPACE] = video::SColor(101,100,100,100);
\r
37 Colors[EGDC_BUTTON_TEXT] = video::SColor(240,10,10,10);
\r
38 Colors[EGDC_GRAY_TEXT] = video::SColor(240,130,130,130);
\r
39 Colors[EGDC_HIGH_LIGHT] = video::SColor(101,8,36,107);
\r
40 Colors[EGDC_HIGH_LIGHT_TEXT] = video::SColor(240,255,255,255);
\r
41 Colors[EGDC_INACTIVE_BORDER] = video::SColor(101,165,165,165);
\r
42 Colors[EGDC_INACTIVE_CAPTION] = video::SColor(255,30,30,30);
\r
43 Colors[EGDC_TOOLTIP] = video::SColor(200,0,0,0);
\r
44 Colors[EGDC_TOOLTIP_BACKGROUND] = video::SColor(200,255,255,225);
\r
45 Colors[EGDC_SCROLLBAR] = video::SColor(101,230,230,230);
\r
46 Colors[EGDC_WINDOW] = video::SColor(101,255,255,255);
\r
47 Colors[EGDC_WINDOW_SYMBOL] = video::SColor(200,10,10,10);
\r
48 Colors[EGDC_ICON] = video::SColor(200,255,255,255);
\r
49 Colors[EGDC_ICON_HIGH_LIGHT] = video::SColor(200,8,36,107);
\r
50 Colors[EGDC_GRAY_WINDOW_SYMBOL] = video::SColor(240,100,100,100);
\r
51 Colors[EGDC_EDITABLE] = video::SColor(255,255,255,255);
\r
52 Colors[EGDC_GRAY_EDITABLE] = video::SColor(255,120,120,120);
\r
53 Colors[EGDC_FOCUSED_EDITABLE] = video::SColor(255,240,240,255);
\r
56 Sizes[EGDS_SCROLLBAR_SIZE] = 14;
\r
57 Sizes[EGDS_MENU_HEIGHT] = 30;
\r
58 Sizes[EGDS_WINDOW_BUTTON_WIDTH] = 15;
\r
59 Sizes[EGDS_CHECK_BOX_WIDTH] = 18;
\r
60 Sizes[EGDS_MESSAGE_BOX_WIDTH] = 500;
\r
61 Sizes[EGDS_MESSAGE_BOX_HEIGHT] = 200;
\r
62 Sizes[EGDS_BUTTON_WIDTH] = 80;
\r
63 Sizes[EGDS_BUTTON_HEIGHT] = 30;
\r
65 Sizes[EGDS_TEXT_DISTANCE_X] = 2;
\r
66 Sizes[EGDS_TEXT_DISTANCE_Y] = 0;
\r
68 Sizes[EGDS_TITLEBARTEXT_DISTANCE_X] = 2;
\r
69 Sizes[EGDS_TITLEBARTEXT_DISTANCE_Y] = 0;
\r
74 Colors[EGDC_3D_DARK_SHADOW] = 0x60767982;
\r
75 //Colors[EGDC_3D_FACE] = 0xc0c9ccd4; // tab background
\r
76 Colors[EGDC_3D_FACE] = 0xc0cbd2d9; // tab background
\r
77 Colors[EGDC_3D_SHADOW] = 0x50e4e8f1; // tab background, and left-top highlight
\r
78 Colors[EGDC_3D_HIGH_LIGHT] = 0x40c7ccdc;
\r
79 Colors[EGDC_3D_LIGHT] = 0x802e313a;
\r
80 Colors[EGDC_ACTIVE_BORDER] = 0x80404040; // window title
\r
81 Colors[EGDC_ACTIVE_CAPTION] = 0xffd0d0d0;
\r
82 Colors[EGDC_APP_WORKSPACE] = 0xc0646464; // unused
\r
83 Colors[EGDC_BUTTON_TEXT] = 0xd0161616;
\r
84 Colors[EGDC_GRAY_TEXT] = 0x3c141414;
\r
85 Colors[EGDC_HIGH_LIGHT] = 0x6c606060;
\r
86 Colors[EGDC_HIGH_LIGHT_TEXT] = 0xd0e0e0e0;
\r
87 Colors[EGDC_INACTIVE_BORDER] = 0xf0a5a5a5;
\r
88 Colors[EGDC_INACTIVE_CAPTION] = 0xffd2d2d2;
\r
89 Colors[EGDC_TOOLTIP] = 0xf00f2033;
\r
90 Colors[EGDC_TOOLTIP_BACKGROUND] = 0xc0cbd2d9;
\r
91 Colors[EGDC_SCROLLBAR] = 0xf0e0e0e0;
\r
92 Colors[EGDC_WINDOW] = 0xf0f0f0f0;
\r
93 Colors[EGDC_WINDOW_SYMBOL] = 0xd0161616;
\r
94 Colors[EGDC_ICON] = 0xd0161616;
\r
95 Colors[EGDC_ICON_HIGH_LIGHT] = 0xd0606060;
\r
96 Colors[EGDC_GRAY_WINDOW_SYMBOL] = 0x3c101010;
\r
97 Colors[EGDC_EDITABLE] = 0xf0ffffff;
\r
98 Colors[EGDC_GRAY_EDITABLE] = 0xf0cccccc;
\r
99 Colors[EGDC_FOCUSED_EDITABLE] = 0xf0fffff0;
\r
101 Sizes[EGDS_SCROLLBAR_SIZE] = 14;
\r
102 Sizes[EGDS_MENU_HEIGHT] = 48;
\r
103 Sizes[EGDS_WINDOW_BUTTON_WIDTH] = 15;
\r
104 Sizes[EGDS_CHECK_BOX_WIDTH] = 18;
\r
105 Sizes[EGDS_MESSAGE_BOX_WIDTH] = 500;
\r
106 Sizes[EGDS_MESSAGE_BOX_HEIGHT] = 200;
\r
107 Sizes[EGDS_BUTTON_WIDTH] = 80;
\r
108 Sizes[EGDS_BUTTON_HEIGHT] = 30;
\r
110 Sizes[EGDS_TEXT_DISTANCE_X] = 3;
\r
111 Sizes[EGDS_TEXT_DISTANCE_Y] = 2;
\r
113 Sizes[EGDS_TITLEBARTEXT_DISTANCE_X] = 3;
\r
114 Sizes[EGDS_TITLEBARTEXT_DISTANCE_Y] = 2;
\r
117 Sizes[EGDS_MESSAGE_BOX_GAP_SPACE] = 15;
\r
118 Sizes[EGDS_MESSAGE_BOX_MIN_TEXT_WIDTH] = 0;
\r
119 Sizes[EGDS_MESSAGE_BOX_MAX_TEXT_WIDTH] = 500;
\r
120 Sizes[EGDS_MESSAGE_BOX_MIN_TEXT_HEIGHT] = 0;
\r
121 Sizes[EGDS_MESSAGE_BOX_MAX_TEXT_HEIGHT] = 99999;
\r
123 Sizes[EGDS_BUTTON_PRESSED_IMAGE_OFFSET_X] = 1;
\r
124 Sizes[EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y] = 1;
\r
125 Sizes[EGDS_BUTTON_PRESSED_TEXT_OFFSET_X] = 0;
\r
126 Sizes[EGDS_BUTTON_PRESSED_TEXT_OFFSET_Y] = 2;
\r
128 Texts[EGDT_MSG_BOX_OK] = L"OK";
\r
129 Texts[EGDT_MSG_BOX_CANCEL] = L"Cancel";
\r
130 Texts[EGDT_MSG_BOX_YES] = L"Yes";
\r
131 Texts[EGDT_MSG_BOX_NO] = L"No";
\r
132 Texts[EGDT_WINDOW_CLOSE] = L"Close";
\r
133 Texts[EGDT_WINDOW_RESTORE] = L"Restore";
\r
134 Texts[EGDT_WINDOW_MINIMIZE] = L"Minimize";
\r
135 Texts[EGDT_WINDOW_MAXIMIZE] = L"Maximize";
\r
137 Icons[EGDI_WINDOW_MAXIMIZE] = 225;
\r
138 Icons[EGDI_WINDOW_RESTORE] = 226;
\r
139 Icons[EGDI_WINDOW_CLOSE] = 227;
\r
140 Icons[EGDI_WINDOW_MINIMIZE] = 228;
\r
141 Icons[EGDI_CURSOR_UP] = 229;
\r
142 Icons[EGDI_CURSOR_DOWN] = 230;
\r
143 Icons[EGDI_CURSOR_LEFT] = 231;
\r
144 Icons[EGDI_CURSOR_RIGHT] = 232;
\r
145 Icons[EGDI_MENU_MORE] = 232;
\r
146 Icons[EGDI_CHECK_BOX_CHECKED] = 233;
\r
147 Icons[EGDI_DROP_DOWN] = 234;
\r
148 Icons[EGDI_SMALL_CURSOR_UP] = 235;
\r
149 Icons[EGDI_SMALL_CURSOR_DOWN] = 236;
\r
150 Icons[EGDI_RADIO_BUTTON_CHECKED] = 237;
\r
151 Icons[EGDI_MORE_LEFT] = 238;
\r
152 Icons[EGDI_MORE_RIGHT] = 239;
\r
153 Icons[EGDI_MORE_UP] = 240;
\r
154 Icons[EGDI_MORE_DOWN] = 241;
\r
155 Icons[EGDI_WINDOW_RESIZE] = 242;
\r
156 Icons[EGDI_EXPAND] = 243;
\r
157 Icons[EGDI_COLLAPSE] = 244;
\r
159 Icons[EGDI_FILE] = 245;
\r
160 Icons[EGDI_DIRECTORY] = 246;
\r
162 for (u32 i=0; i<EGDF_COUNT; ++i)
\r
165 UseGradient = (Type == EGST_WINDOWS_METALLIC) || (Type == EGST_BURNING_SKIN) ;
\r
170 GUISkin::~GUISkin()
\r
172 for (u32 i=0; i<EGDF_COUNT; ++i)
\r
179 SpriteBank->drop();
\r
183 //! returns default color
\r
184 video::SColor GUISkin::getColor(EGUI_DEFAULT_COLOR color) const
\r
186 if ((u32)color < EGDC_COUNT)
\r
187 return Colors[color];
\r
189 return video::SColor();
\r
193 //! sets a default color
\r
194 void GUISkin::setColor(EGUI_DEFAULT_COLOR which, video::SColor newColor)
\r
196 if ((u32)which < EGDC_COUNT)
\r
197 Colors[which] = newColor;
\r
201 //! returns size for the given size type
\r
202 s32 GUISkin::getSize(EGUI_DEFAULT_SIZE size) const
\r
204 if ((u32)size < EGDS_COUNT)
\r
205 return Sizes[size];
\r
211 //! sets a default size
\r
212 void GUISkin::setSize(EGUI_DEFAULT_SIZE which, s32 size)
\r
214 if ((u32)which < EGDS_COUNT)
\r
215 Sizes[which] = size;
\r
219 //! returns the default font
\r
220 IGUIFont* GUISkin::getFont(EGUI_DEFAULT_FONT which) const
\r
222 if (((u32)which < EGDF_COUNT) && Fonts[which])
\r
223 return Fonts[which];
\r
225 return Fonts[EGDF_DEFAULT];
\r
229 //! sets a default font
\r
230 void GUISkin::setFont(IGUIFont* font, EGUI_DEFAULT_FONT which)
\r
232 if ((u32)which >= EGDF_COUNT)
\r
239 Fonts[which]->drop();
\r
241 Fonts[which] = font;
\r
246 //! gets the sprite bank stored
\r
247 IGUISpriteBank* GUISkin::getSpriteBank() const
\r
253 //! set a new sprite bank or remove one by passing 0
\r
254 void GUISkin::setSpriteBank(IGUISpriteBank* bank)
\r
260 SpriteBank->drop();
\r
266 //! Returns a default icon
\r
267 u32 GUISkin::getIcon(EGUI_DEFAULT_ICON icon) const
\r
269 if ((u32)icon < EGDI_COUNT)
\r
270 return Icons[icon];
\r
276 //! Sets a default icon
\r
277 void GUISkin::setIcon(EGUI_DEFAULT_ICON icon, u32 index)
\r
279 if ((u32)icon < EGDI_COUNT)
\r
280 Icons[icon] = index;
\r
284 //! Returns a default text. For example for Message box button captions:
\r
285 //! "OK", "Cancel", "Yes", "No" and so on.
\r
286 const wchar_t* GUISkin::getDefaultText(EGUI_DEFAULT_TEXT text) const
\r
288 if ((u32)text < EGDT_COUNT)
\r
289 return Texts[text].c_str();
\r
291 return Texts[0].c_str();
\r
295 //! Sets a default text. For example for Message box button captions:
\r
296 //! "OK", "Cancel", "Yes", "No" and so on.
\r
297 void GUISkin::setDefaultText(EGUI_DEFAULT_TEXT which, const wchar_t* newText)
\r
299 if ((u32)which < EGDT_COUNT)
\r
300 Texts[which] = newText;
\r
304 //! draws a standard 3d button pane
\r
305 /** Used for drawing for example buttons in normal state.
\r
306 It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and
\r
307 EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details.
\r
308 \param rect: Defining area where to draw.
\r
309 \param clip: Clip area.
\r
310 \param element: Pointer to the element which wishes to draw this. This parameter
\r
311 is usually not used by ISkin, but can be used for example by more complex
\r
312 implementations to find out how to draw the part exactly. */
\r
314 void GUISkin::drawColored3DButtonPaneStandard(IGUIElement* element,
\r
315 const core::rect<s32>& r,
\r
316 const core::rect<s32>* clip,
\r
317 const video::SColor* colors)
\r
325 core::rect<s32> rect = r;
\r
327 if ( Type == EGST_BURNING_SKIN )
\r
329 rect.UpperLeftCorner.X -= 1;
\r
330 rect.UpperLeftCorner.Y -= 1;
\r
331 rect.LowerRightCorner.X += 1;
\r
332 rect.LowerRightCorner.Y += 1;
\r
333 draw3DSunkenPane(element,
\r
334 colors[ EGDC_WINDOW ].getInterpolated( 0xFFFFFFFF, 0.9f )
\r
335 ,false, true, rect, clip);
\r
339 Driver->draw2DRectangle(colors[EGDC_3D_DARK_SHADOW], rect, clip);
\r
341 rect.LowerRightCorner.X -= 1;
\r
342 rect.LowerRightCorner.Y -= 1;
\r
343 Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], rect, clip);
\r
345 rect.UpperLeftCorner.X += 1;
\r
346 rect.UpperLeftCorner.Y += 1;
\r
347 Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], rect, clip);
\r
349 rect.LowerRightCorner.X -= 1;
\r
350 rect.LowerRightCorner.Y -= 1;
\r
354 Driver->draw2DRectangle(colors[EGDC_3D_FACE], rect, clip);
\r
358 const video::SColor c1 = colors[EGDC_3D_FACE];
\r
359 const video::SColor c2 = c1.getInterpolated(colors[EGDC_3D_DARK_SHADOW], 0.4f);
\r
360 Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip);
\r
366 //! draws a pressed 3d button pane
\r
367 /** Used for drawing for example buttons in pressed state.
\r
368 It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and
\r
369 EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details.
\r
370 \param rect: Defining area where to draw.
\r
371 \param clip: Clip area.
\r
372 \param element: Pointer to the element which wishes to draw this. This parameter
\r
373 is usually not used by ISkin, but can be used for example by more complex
\r
374 implementations to find out how to draw the part exactly. */
\r
376 void GUISkin::drawColored3DButtonPanePressed(IGUIElement* element,
\r
377 const core::rect<s32>& r,
\r
378 const core::rect<s32>* clip,
\r
379 const video::SColor* colors)
\r
387 core::rect<s32> rect = r;
\r
388 Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], rect, clip);
\r
390 rect.LowerRightCorner.X -= 1;
\r
391 rect.LowerRightCorner.Y -= 1;
\r
392 Driver->draw2DRectangle(colors[EGDC_3D_DARK_SHADOW], rect, clip);
\r
394 rect.UpperLeftCorner.X += 1;
\r
395 rect.UpperLeftCorner.Y += 1;
\r
396 Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], rect, clip);
\r
398 rect.UpperLeftCorner.X += 1;
\r
399 rect.UpperLeftCorner.Y += 1;
\r
403 Driver->draw2DRectangle(colors[EGDC_3D_FACE], rect, clip);
\r
407 const video::SColor c1 = colors[EGDC_3D_FACE];
\r
408 const video::SColor c2 = c1.getInterpolated(colors[EGDC_3D_DARK_SHADOW], 0.4f);
\r
409 Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip);
\r
415 //! draws a sunken 3d pane
\r
416 /** Used for drawing the background of edit, combo or check boxes.
\r
417 \param element: Pointer to the element which wishes to draw this. This parameter
\r
418 is usually not used by ISkin, but can be used for example by more complex
\r
419 implementations to find out how to draw the part exactly.
\r
420 \param bgcolor: Background color.
\r
421 \param flat: Specifies if the sunken pane should be flat or displayed as sunken
\r
422 deep into the ground.
\r
423 \param rect: Defining area where to draw.
\r
424 \param clip: Clip area. */
\r
426 void GUISkin::drawColored3DSunkenPane(IGUIElement* element, video::SColor bgcolor,
\r
427 bool flat, bool fillBackGround,
\r
428 const core::rect<s32>& r,
\r
429 const core::rect<s32>* clip,
\r
430 const video::SColor* colors)
\r
438 core::rect<s32> rect = r;
\r
440 if (fillBackGround)
\r
441 Driver->draw2DRectangle(bgcolor, rect, clip);
\r
445 // draw flat sunken pane
\r
447 rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1;
\r
448 Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], rect, clip); // top
\r
450 ++rect.UpperLeftCorner.Y;
\r
451 rect.LowerRightCorner.Y = r.LowerRightCorner.Y;
\r
452 rect.LowerRightCorner.X = rect.UpperLeftCorner.X + 1;
\r
453 Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], rect, clip); // left
\r
456 ++rect.UpperLeftCorner.Y;
\r
457 rect.UpperLeftCorner.X = rect.LowerRightCorner.X - 1;
\r
458 Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], rect, clip); // right
\r
461 ++rect.UpperLeftCorner.X;
\r
462 rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1;
\r
463 --rect.LowerRightCorner.X;
\r
464 Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], rect, clip); // bottom
\r
468 // draw deep sunken pane
\r
469 rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1;
\r
470 Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], rect, clip); // top
\r
471 ++rect.UpperLeftCorner.X;
\r
472 ++rect.UpperLeftCorner.Y;
\r
473 --rect.LowerRightCorner.X;
\r
474 ++rect.LowerRightCorner.Y;
\r
475 Driver->draw2DRectangle(colors[EGDC_3D_DARK_SHADOW], rect, clip);
\r
477 rect.UpperLeftCorner.X = r.UpperLeftCorner.X;
\r
478 rect.UpperLeftCorner.Y = r.UpperLeftCorner.Y+1;
\r
479 rect.LowerRightCorner.X = rect.UpperLeftCorner.X + 1;
\r
480 rect.LowerRightCorner.Y = r.LowerRightCorner.Y;
\r
481 Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], rect, clip); // left
\r
482 ++rect.UpperLeftCorner.X;
\r
483 ++rect.UpperLeftCorner.Y;
\r
484 ++rect.LowerRightCorner.X;
\r
485 --rect.LowerRightCorner.Y;
\r
486 Driver->draw2DRectangle(colors[EGDC_3D_DARK_SHADOW], rect, clip);
\r
489 rect.UpperLeftCorner.X = rect.LowerRightCorner.X - 1;
\r
490 ++rect.UpperLeftCorner.Y;
\r
491 Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], rect, clip); // right
\r
492 --rect.UpperLeftCorner.X;
\r
493 ++rect.UpperLeftCorner.Y;
\r
494 --rect.LowerRightCorner.X;
\r
495 --rect.LowerRightCorner.Y;
\r
496 Driver->draw2DRectangle(colors[EGDC_3D_LIGHT], rect, clip);
\r
499 ++rect.UpperLeftCorner.X;
\r
500 rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1;
\r
501 --rect.LowerRightCorner.X;
\r
502 Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], rect, clip); // bottom
\r
503 ++rect.UpperLeftCorner.X;
\r
504 --rect.UpperLeftCorner.Y;
\r
505 --rect.LowerRightCorner.X;
\r
506 --rect.LowerRightCorner.Y;
\r
507 Driver->draw2DRectangle(colors[EGDC_3D_LIGHT], rect, clip);
\r
512 //! draws a window background
\r
513 // return where to draw title bar text.
\r
515 core::rect<s32> GUISkin::drawColored3DWindowBackground(IGUIElement* element,
\r
516 bool drawTitleBar, video::SColor titleBarColor,
\r
517 const core::rect<s32>& r,
\r
518 const core::rect<s32>* clip,
\r
519 core::rect<s32>* checkClientArea,
\r
520 const video::SColor* colors)
\r
524 if ( checkClientArea )
\r
526 *checkClientArea = r;
\r
534 core::rect<s32> rect = r;
\r
537 rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1;
\r
538 if ( !checkClientArea )
\r
540 Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], rect, clip);
\r
544 rect.LowerRightCorner.Y = r.LowerRightCorner.Y;
\r
545 rect.LowerRightCorner.X = rect.UpperLeftCorner.X + 1;
\r
546 if ( !checkClientArea )
\r
548 Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], rect, clip);
\r
551 // right border dark outer line
\r
552 rect.UpperLeftCorner.X = r.LowerRightCorner.X - 1;
\r
553 rect.LowerRightCorner.X = r.LowerRightCorner.X;
\r
554 rect.UpperLeftCorner.Y = r.UpperLeftCorner.Y;
\r
555 rect.LowerRightCorner.Y = r.LowerRightCorner.Y;
\r
556 if ( !checkClientArea )
\r
558 Driver->draw2DRectangle(colors[EGDC_3D_DARK_SHADOW], rect, clip);
\r
561 // right border bright innner line
\r
562 rect.UpperLeftCorner.X -= 1;
\r
563 rect.LowerRightCorner.X -= 1;
\r
564 rect.UpperLeftCorner.Y += 1;
\r
565 rect.LowerRightCorner.Y -= 1;
\r
566 if ( !checkClientArea )
\r
568 Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], rect, clip);
\r
571 // bottom border dark outer line
\r
572 rect.UpperLeftCorner.X = r.UpperLeftCorner.X;
\r
573 rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1;
\r
574 rect.LowerRightCorner.Y = r.LowerRightCorner.Y;
\r
575 rect.LowerRightCorner.X = r.LowerRightCorner.X;
\r
576 if ( !checkClientArea )
\r
578 Driver->draw2DRectangle(colors[EGDC_3D_DARK_SHADOW], rect, clip);
\r
581 // bottom border bright inner line
\r
582 rect.UpperLeftCorner.X += 1;
\r
583 rect.LowerRightCorner.X -= 1;
\r
584 rect.UpperLeftCorner.Y -= 1;
\r
585 rect.LowerRightCorner.Y -= 1;
\r
586 if ( !checkClientArea )
\r
588 Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], rect, clip);
\r
591 // client area for background
\r
593 rect.UpperLeftCorner.X +=1;
\r
594 rect.UpperLeftCorner.Y +=1;
\r
595 rect.LowerRightCorner.X -= 2;
\r
596 rect.LowerRightCorner.Y -= 2;
\r
597 if (checkClientArea)
\r
599 *checkClientArea = rect;
\r
602 if ( !checkClientArea )
\r
606 Driver->draw2DRectangle(colors[EGDC_3D_FACE], rect, clip);
\r
608 else if ( Type == EGST_BURNING_SKIN )
\r
610 const video::SColor c1 = colors[EGDC_WINDOW].getInterpolated ( 0xFFFFFFFF, 0.9f );
\r
611 const video::SColor c2 = colors[EGDC_WINDOW].getInterpolated ( 0xFFFFFFFF, 0.8f );
\r
613 Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip);
\r
617 const video::SColor c2 = colors[EGDC_3D_SHADOW];
\r
618 const video::SColor c1 = colors[EGDC_3D_FACE];
\r
619 Driver->draw2DRectangle(rect, c1, c1, c1, c2, clip);
\r
625 rect.UpperLeftCorner.X += 2;
\r
626 rect.UpperLeftCorner.Y += 2;
\r
627 rect.LowerRightCorner.X -= 2;
\r
628 rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + getSize(EGDS_WINDOW_BUTTON_WIDTH) + 2;
\r
632 if (checkClientArea)
\r
634 (*checkClientArea).UpperLeftCorner.Y = rect.LowerRightCorner.Y;
\r
639 //if (!UseGradient)
\r
640 // Driver->draw2DRectangle(titleBarColor, rect, clip);
\r
642 if ( Type == EGST_BURNING_SKIN )
\r
644 const video::SColor c = titleBarColor.getInterpolated( video::SColor(titleBarColor.getAlpha(),255,255,255), 0.8f);
\r
645 Driver->draw2DRectangle(rect, titleBarColor, titleBarColor, c, c, clip);
\r
649 const video::SColor c = titleBarColor.getInterpolated(video::SColor(titleBarColor.getAlpha(),0,0,0), 0.2f);
\r
650 Driver->draw2DRectangle(rect, titleBarColor, c, titleBarColor, c, clip);
\r
660 //! draws a standard 3d menu pane
\r
661 /** Used for drawing for menus and context menus.
\r
662 It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and
\r
663 EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details.
\r
664 \param element: Pointer to the element which wishes to draw this. This parameter
\r
665 is usually not used by ISkin, but can be used for example by more complex
\r
666 implementations to find out how to draw the part exactly.
\r
667 \param rect: Defining area where to draw.
\r
668 \param clip: Clip area. */
\r
670 void GUISkin::drawColored3DMenuPane(IGUIElement* element,
\r
671 const core::rect<s32>& r, const core::rect<s32>* clip,
\r
672 const video::SColor* colors)
\r
680 core::rect<s32> rect = r;
\r
682 if ( Type == EGST_BURNING_SKIN )
\r
684 rect.UpperLeftCorner.Y -= 3;
\r
685 draw3DButtonPaneStandard(element, rect, clip);
\r
689 // in this skin, this is exactly what non pressed buttons look like,
\r
690 // so we could simply call
\r
691 // draw3DButtonPaneStandard(element, rect, clip);
\r
693 // but if the skin is transparent, this doesn't look that nice. So
\r
694 // We draw it a little bit better, with some more draw2DRectangle calls,
\r
695 // but there aren't that much menus visible anyway.
\r
697 rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1;
\r
698 Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], rect, clip);
\r
700 rect.LowerRightCorner.Y = r.LowerRightCorner.Y;
\r
701 rect.LowerRightCorner.X = rect.UpperLeftCorner.X + 1;
\r
702 Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], rect, clip);
\r
704 rect.UpperLeftCorner.X = r.LowerRightCorner.X - 1;
\r
705 rect.LowerRightCorner.X = r.LowerRightCorner.X;
\r
706 rect.UpperLeftCorner.Y = r.UpperLeftCorner.Y;
\r
707 rect.LowerRightCorner.Y = r.LowerRightCorner.Y;
\r
708 Driver->draw2DRectangle(colors[EGDC_3D_DARK_SHADOW], rect, clip);
\r
710 rect.UpperLeftCorner.X -= 1;
\r
711 rect.LowerRightCorner.X -= 1;
\r
712 rect.UpperLeftCorner.Y += 1;
\r
713 rect.LowerRightCorner.Y -= 1;
\r
714 Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], rect, clip);
\r
716 rect.UpperLeftCorner.X = r.UpperLeftCorner.X;
\r
717 rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1;
\r
718 rect.LowerRightCorner.Y = r.LowerRightCorner.Y;
\r
719 rect.LowerRightCorner.X = r.LowerRightCorner.X;
\r
720 Driver->draw2DRectangle(colors[EGDC_3D_DARK_SHADOW], rect, clip);
\r
722 rect.UpperLeftCorner.X += 1;
\r
723 rect.LowerRightCorner.X -= 1;
\r
724 rect.UpperLeftCorner.Y -= 1;
\r
725 rect.LowerRightCorner.Y -= 1;
\r
726 Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], rect, clip);
\r
729 rect.UpperLeftCorner.X +=1;
\r
730 rect.UpperLeftCorner.Y +=1;
\r
731 rect.LowerRightCorner.X -= 2;
\r
732 rect.LowerRightCorner.Y -= 2;
\r
735 Driver->draw2DRectangle(colors[EGDC_3D_FACE], rect, clip);
\r
738 const video::SColor c1 = colors[EGDC_3D_FACE];
\r
739 const video::SColor c2 = colors[EGDC_3D_SHADOW];
\r
740 Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip);
\r
746 //! draws a standard 3d tool bar
\r
747 /** Used for drawing for toolbars and menus.
\r
748 \param element: Pointer to the element which wishes to draw this. This parameter
\r
749 is usually not used by ISkin, but can be used for example by more complex
\r
750 implementations to find out how to draw the part exactly.
\r
751 \param rect: Defining area where to draw.
\r
752 \param clip: Clip area. */
\r
754 void GUISkin::drawColored3DToolBar(IGUIElement* element,
\r
755 const core::rect<s32>& r,
\r
756 const core::rect<s32>* clip,
\r
757 const video::SColor* colors)
\r
765 core::rect<s32> rect = r;
\r
767 rect.UpperLeftCorner.X = r.UpperLeftCorner.X;
\r
768 rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1;
\r
769 rect.LowerRightCorner.Y = r.LowerRightCorner.Y;
\r
770 rect.LowerRightCorner.X = r.LowerRightCorner.X;
\r
771 Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], rect, clip);
\r
774 rect.LowerRightCorner.Y -= 1;
\r
778 Driver->draw2DRectangle(colors[EGDC_3D_FACE], rect, clip);
\r
781 if ( Type == EGST_BURNING_SKIN )
\r
783 const video::SColor c1 = 0xF0000000 | colors[EGDC_3D_FACE].color;
\r
784 const video::SColor c2 = 0xF0000000 | colors[EGDC_3D_SHADOW].color;
\r
786 rect.LowerRightCorner.Y += 1;
\r
787 Driver->draw2DRectangle(rect, c1, c2, c1, c2, clip);
\r
791 const video::SColor c1 = colors[EGDC_3D_FACE];
\r
792 const video::SColor c2 = colors[EGDC_3D_SHADOW];
\r
793 Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip);
\r
798 //! draws a tab button
\r
799 /** Used for drawing for tab buttons on top of tabs.
\r
800 \param element: Pointer to the element which wishes to draw this. This parameter
\r
801 is usually not used by ISkin, but can be used for example by more complex
\r
802 implementations to find out how to draw the part exactly.
\r
803 \param active: Specifies if the tab is currently active.
\r
804 \param rect: Defining area where to draw.
\r
805 \param clip: Clip area. */
\r
807 void GUISkin::drawColored3DTabButton(IGUIElement* element, bool active,
\r
808 const core::rect<s32>& frameRect, const core::rect<s32>* clip, EGUI_ALIGNMENT alignment,
\r
809 const video::SColor* colors)
\r
817 core::rect<s32> tr = frameRect;
\r
819 if ( alignment == EGUIA_UPPERLEFT )
\r
821 tr.LowerRightCorner.X -= 2;
\r
822 tr.LowerRightCorner.Y = tr.UpperLeftCorner.Y + 1;
\r
823 tr.UpperLeftCorner.X += 1;
\r
824 Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], tr, clip);
\r
826 // draw left highlight
\r
828 tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1;
\r
829 tr.UpperLeftCorner.Y += 1;
\r
830 Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], tr, clip);
\r
832 // draw grey background
\r
834 tr.UpperLeftCorner.X += 1;
\r
835 tr.UpperLeftCorner.Y += 1;
\r
836 tr.LowerRightCorner.X -= 2;
\r
837 Driver->draw2DRectangle(colors[EGDC_3D_FACE], tr, clip);
\r
839 // draw right middle gray shadow
\r
840 tr.LowerRightCorner.X += 1;
\r
841 tr.UpperLeftCorner.X = tr.LowerRightCorner.X - 1;
\r
842 Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], tr, clip);
\r
844 tr.LowerRightCorner.X += 1;
\r
845 tr.UpperLeftCorner.X += 1;
\r
846 tr.UpperLeftCorner.Y += 1;
\r
847 Driver->draw2DRectangle(colors[EGDC_3D_DARK_SHADOW], tr, clip);
\r
851 tr.LowerRightCorner.X -= 2;
\r
852 tr.UpperLeftCorner.Y = tr.LowerRightCorner.Y - 1;
\r
853 tr.UpperLeftCorner.X += 1;
\r
854 Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], tr, clip);
\r
856 // draw left highlight
\r
858 tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1;
\r
859 tr.LowerRightCorner.Y -= 1;
\r
860 Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], tr, clip);
\r
862 // draw grey background
\r
864 tr.UpperLeftCorner.X += 1;
\r
865 tr.UpperLeftCorner.Y -= 1;
\r
866 tr.LowerRightCorner.X -= 2;
\r
867 tr.LowerRightCorner.Y -= 1;
\r
868 Driver->draw2DRectangle(colors[EGDC_3D_FACE], tr, clip);
\r
870 // draw right middle gray shadow
\r
871 tr.LowerRightCorner.X += 1;
\r
872 tr.UpperLeftCorner.X = tr.LowerRightCorner.X - 1;
\r
873 //tr.LowerRightCorner.Y -= 1;
\r
874 Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], tr, clip);
\r
876 tr.LowerRightCorner.X += 1;
\r
877 tr.UpperLeftCorner.X += 1;
\r
878 tr.LowerRightCorner.Y -= 1;
\r
879 Driver->draw2DRectangle(colors[EGDC_3D_DARK_SHADOW], tr, clip);
\r
885 //! draws a tab control body
\r
886 /** \param element: Pointer to the element which wishes to draw this. This parameter
\r
887 is usually not used by ISkin, but can be used for example by more complex
\r
888 implementations to find out how to draw the part exactly.
\r
889 \param border: Specifies if the border should be drawn.
\r
890 \param background: Specifies if the background should be drawn.
\r
891 \param rect: Defining area where to draw.
\r
892 \param clip: Clip area. */
\r
894 void GUISkin::drawColored3DTabBody(IGUIElement* element, bool border, bool background,
\r
895 const core::rect<s32>& rect, const core::rect<s32>* clip, s32 tabHeight, EGUI_ALIGNMENT alignment,
\r
896 const video::SColor* colors)
\r
904 core::rect<s32> tr = rect;
\r
906 if ( tabHeight == -1 )
\r
907 tabHeight = getSize(gui::EGDS_BUTTON_HEIGHT);
\r
912 if ( alignment == EGUIA_UPPERLEFT )
\r
914 // draw left hightlight
\r
915 tr.UpperLeftCorner.Y += tabHeight + 2;
\r
916 tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1;
\r
917 Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], tr, clip);
\r
919 // draw right shadow
\r
920 tr.UpperLeftCorner.X = rect.LowerRightCorner.X - 1;
\r
921 tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1;
\r
922 Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], tr, clip);
\r
924 // draw lower shadow
\r
926 tr.UpperLeftCorner.Y = tr.LowerRightCorner.Y - 1;
\r
927 Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], tr, clip);
\r
931 // draw left hightlight
\r
932 tr.LowerRightCorner.Y -= tabHeight + 2;
\r
933 tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1;
\r
934 Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], tr, clip);
\r
936 // draw right shadow
\r
937 tr.UpperLeftCorner.X = rect.LowerRightCorner.X - 1;
\r
938 tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1;
\r
939 Driver->draw2DRectangle(colors[EGDC_3D_SHADOW], tr, clip);
\r
941 // draw lower shadow
\r
943 tr.LowerRightCorner.Y = tr.UpperLeftCorner.Y + 1;
\r
944 Driver->draw2DRectangle(colors[EGDC_3D_HIGH_LIGHT], tr, clip);
\r
950 if ( alignment == EGUIA_UPPERLEFT )
\r
953 tr.UpperLeftCorner.Y += tabHeight + 2;
\r
954 tr.LowerRightCorner.X -= 1;
\r
955 tr.UpperLeftCorner.X += 1;
\r
956 tr.LowerRightCorner.Y -= 1;
\r
961 tr.UpperLeftCorner.X += 1;
\r
962 tr.UpperLeftCorner.Y -= 1;
\r
963 tr.LowerRightCorner.X -= 1;
\r
964 tr.LowerRightCorner.Y -= tabHeight + 2;
\r
965 //tr.UpperLeftCorner.X += 1;
\r
969 Driver->draw2DRectangle(colors[EGDC_3D_FACE], tr, clip);
\r
972 video::SColor c1 = colors[EGDC_3D_FACE];
\r
973 video::SColor c2 = colors[EGDC_3D_SHADOW];
\r
974 Driver->draw2DRectangle(tr, c1, c1, c2, c2, clip);
\r
981 //! draws an icon, usually from the skin's sprite bank
\r
982 /** \param parent: Pointer to the element which wishes to draw this icon.
\r
983 This parameter is usually not used by IGUISkin, but can be used for example
\r
984 by more complex implementations to find out how to draw the part exactly.
\r
985 \param icon: Specifies the icon to be drawn.
\r
986 \param position: The position to draw the icon
\r
987 \param starttime: The time at the start of the animation
\r
988 \param currenttime: The present time, used to calculate the frame number
\r
989 \param loop: Whether the animation should loop or not
\r
990 \param clip: Clip area. */
\r
992 void GUISkin::drawColoredIcon(IGUIElement* element, EGUI_DEFAULT_ICON icon,
\r
993 const core::position2di position,
\r
994 u32 starttime, u32 currenttime,
\r
995 bool loop, const core::rect<s32>* clip,
\r
996 const video::SColor* colors)
\r
1004 bool gray = element && !element->isEnabled();
\r
1005 SpriteBank->draw2DSprite(Icons[icon], position, clip,
\r
1006 colors[gray? EGDC_GRAY_WINDOW_SYMBOL : EGDC_WINDOW_SYMBOL], starttime, currenttime, loop, true);
\r
1011 EGUI_SKIN_TYPE GUISkin::getType() const
\r
1017 //! draws a 2d rectangle.
\r
1018 void GUISkin::draw2DRectangle(IGUIElement* element,
\r
1019 const video::SColor &color, const core::rect<s32>& pos,
\r
1020 const core::rect<s32>* clip)
\r
1022 Driver->draw2DRectangle(color, pos, clip);
\r
1026 //! gets the colors
\r
1028 void GUISkin::getColors(video::SColor* colors)
\r
1031 for (i=0; i<EGDC_COUNT; ++i)
\r
1032 colors[i] = Colors[i];
\r
1036 } // end namespace gui
\r
1037 } // end namespace irr
\r