guiSkin.cpp 30 KB

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