guiSkin.cpp 30 KB

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