Panel.cpp 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. /******************************************************************************
  5. windows aero colors
  6. on black background - R 21, G 46, B 71
  7. on white background - R 199, G 224, B 249
  8. panel_window.back_color.set(178, 178, 178);
  9. panel_window.blur_color.set( 21, 46, 71);
  10. /******************************************************************************/
  11. #define CC4_GSTL CC4('G','S','T','L')
  12. #define DEFAULT_SIZE 0.1f
  13. /******************************************************************************/
  14. DEFINE_CACHE(Panel, Panels, PanelPtr, "Panel");
  15. /******************************************************************************/
  16. void Panel::extendedRect(C Rect &rect, Rect &extended)C
  17. {
  18. Rect r; if(panel_image)panel_image->extendedRect(rect, r);else r=rect;
  19. if(shadow_opacity)r|=(rect+Vec2(shadow_offset, -shadow_offset)).extend(shadow_radius);
  20. if(border_color.a)
  21. {
  22. Flt border=-border_size;
  23. if( border>0)r.extend(border);
  24. }
  25. if(side_stretch)
  26. {
  27. Flt y[]={rect.min.y+bottom_offset, rect.max.y+top_offset};
  28. Flt x[3][2]= // [y][x]
  29. {
  30. {rect.min.x- top_corner_offset.x, rect.max.x+ top_corner_offset.x},
  31. {rect.min.x- left_right_offset.x, rect.max.x+ left_right_offset.x},
  32. {rect.min.x-bottom_corner_offset.x, rect.max.x+bottom_corner_offset.x},
  33. };
  34. if( top_image)r.includeY(y[1] + top_size);
  35. if( bottom_image)r.includeY(y[0] - bottom_size);
  36. if(left_right_image)r.includeX(x[1][0]-left_right_size, x[1][1]+left_right_size);
  37. if(top_corner_image)
  38. {
  39. Flt w=top_corner_size*top_corner_image->aspect(),
  40. h=top_corner_size;
  41. r.includeY(y[1]+h).includeX(x[0][0]-w, x[0][1]+w);
  42. }
  43. if(bottom_corner_image)
  44. {
  45. Flt w=bottom_corner_size*bottom_corner_image->aspect(),
  46. h=bottom_corner_size;
  47. r.includeY(y[0]-h).includeX(x[2][0]-w, x[2][1]+w);
  48. }
  49. }else
  50. {
  51. if( top_image)r|=Rect_C(rect.centerX()/*+ top_offset.x*/, rect.max.y+ top_offset, top_size* top_image->aspect(), top_size);
  52. if( bottom_image)r|=Rect_C(rect.centerX()/*+bottom_offset.x*/, rect.min.y+bottom_offset, bottom_size*bottom_image->aspect(), bottom_size);
  53. if(left_right_image)
  54. {
  55. Flt w=left_right_size*left_right_image->aspect(),
  56. h=left_right_size,
  57. y=rect.centerY()+left_right_offset.y;
  58. r|=Rect_C(rect.min.x-left_right_offset.x, y, w, h);
  59. r|=Rect_C(rect.max.x+left_right_offset.x, y, w, h);
  60. }
  61. if(top_corner_image)
  62. {
  63. Flt w=top_corner_size*top_corner_image->aspect(),
  64. h=top_corner_size,
  65. y=rect.max.y+top_corner_offset.y;
  66. r|=Rect_C(rect.min.x-top_corner_offset.x, y, w, h);
  67. r|=Rect_C(rect.max.x+top_corner_offset.x, y, w, h);
  68. }
  69. if(bottom_corner_image)
  70. {
  71. Flt w=bottom_corner_size*bottom_corner_image->aspect(),
  72. h=bottom_corner_size,
  73. y=rect.min.y+bottom_corner_offset.y;
  74. r|=Rect_C(rect.min.x-bottom_corner_offset.x, y, w, h);
  75. r|=Rect_C(rect.max.x+bottom_corner_offset.x, y, w, h);
  76. }
  77. }
  78. extended=r; // modify at the end in case 'extended' is 'rect'
  79. }
  80. void Panel::defaultInnerPadding(Rect &padding)C
  81. {
  82. if(panel_image)padding=panel_image->defaultInnerPadding();else padding.zero();
  83. #if 0 // border is not included
  84. if(border_color.a && border_size>0)
  85. {
  86. MAX(padding.min.x, border_size);
  87. MAX(padding.min.y, border_size);
  88. MAX(padding.max.x, border_size);
  89. MAX(padding.max.y, border_size);
  90. }
  91. #endif
  92. if(side_stretch)
  93. {
  94. if( top_image) MAX(padding.max.y, -top_offset); // 'top_offset' moves up
  95. if( bottom_image) MAX(padding.min.y, bottom_offset); // 'bottom_offset' moves up
  96. if(left_right_image){MAX(padding.min.x, -left_right_offset.x); MAX(padding.max.x, -left_right_offset.x);} // 'left_right_offset.x' moves right
  97. }
  98. }
  99. void Panel::innerPadding(C Rect &rect, Rect &padding)C
  100. {
  101. if(panel_image)panel_image->innerPadding(rect, padding);else padding.zero();
  102. #if 0 // border is not included
  103. if(border_color.a && border_size>0)
  104. {
  105. MAX(padding.min.x, border_size);
  106. MAX(padding.min.y, border_size);
  107. MAX(padding.max.x, border_size);
  108. MAX(padding.max.y, border_size);
  109. }
  110. #endif
  111. if(side_stretch)
  112. {
  113. if( top_image) MAX(padding.max.y, -top_offset); // 'top_offset' moves up
  114. if( bottom_image) MAX(padding.min.y, bottom_offset); // 'bottom_offset' moves up
  115. if(left_right_image){MAX(padding.min.x, -left_right_offset.x); MAX(padding.max.x, -left_right_offset.x);} // 'left_right_offset.x' moves right
  116. }
  117. }
  118. void Panel::defaultInnerPaddingSize(Vec2 &padd_size)C
  119. {
  120. Rect padding; defaultInnerPadding(padding);
  121. padd_size.set(padding.min.x+padding.max.x, padding.min.y+padding.max.y);
  122. }
  123. /******************************************************************************/
  124. void Panel::reset()
  125. {
  126. center_stretch=side_stretch=false;
  127. center_color=WHITE;
  128. border_color=WHITE;
  129. side_color=WHITE;
  130. blur_color=TRANSPARENT;
  131. center_shadow =false;
  132. shadow_opacity=170;
  133. shadow_radius =0.035f;
  134. shadow_offset =0;
  135. border_size =0;
  136. center_scale =1;
  137. top_size=bottom_size=left_right_size=top_corner_size=bottom_corner_size=DEFAULT_SIZE;
  138. top_offset=bottom_offset=0;
  139. left_right_offset=top_corner_offset=bottom_corner_offset.zero();
  140. center_image=border_image=top_image=bottom_image=left_right_image=top_corner_image=bottom_corner_image.clear();
  141. panel_image.clear();
  142. }
  143. /******************************************************************************/
  144. Bool Panel::pixelBorder()C
  145. {
  146. return border_color.a && !border_image && !border_size;
  147. }
  148. Bool Panel::getSideScale(C Rect &rect, Flt &scale)C
  149. {
  150. if(panel_image)return panel_image->getSideScale(rect, scale);
  151. return false;
  152. }
  153. void Panel::scaleBorder(Flt scale)
  154. {
  155. border_size*=scale;
  156. top_size*=scale; top_offset*=scale;
  157. bottom_size*=scale; bottom_offset*=scale;
  158. left_right_size*=scale; left_right_offset*=scale;
  159. top_corner_size*=scale; top_corner_offset*=scale;
  160. bottom_corner_size*=scale; bottom_corner_offset*=scale;
  161. }
  162. /******************************************************************************/
  163. void Panel::draw(C Rect &rect)C
  164. {
  165. Rect r=rect; if(side_stretch)
  166. {
  167. r.min.x-=left_right_offset.x; r.min.y+=bottom_offset;
  168. r.max.x+=left_right_offset.x; r.max.y+= top_offset;
  169. }
  170. #if !MOBILE // too slow
  171. if(blur_color.a)
  172. {
  173. const Bool hi =true;
  174. const Int shift=(hi ? 1 : 2);
  175. ImageRTPtrRef rt0(hi ? Renderer._h0 : Renderer._q0); rt0.get(ImageRTDesc(Renderer._gui->w()>>shift, Renderer._gui->h()>>shift, IMAGERT_RGB));
  176. ImageRTPtrRef rt1(hi ? Renderer._h1 : Renderer._q1); rt1.get(ImageRTDesc(Renderer._gui->w()>>shift, Renderer._gui->h()>>shift, IMAGERT_RGB));
  177. Image *cur =Renderer._cur[0], *ds=Renderer._cur_ds;
  178. Rect re =r; re.extend(D.pixelToScreenSize(SHADER_BLUR_RANGE<<shift));
  179. Bool secondary=(Renderer._gui!=cur); // required when "window.fade && blur" is used
  180. Renderer._gui->copyHw(*rt0, false, re); // use 'Renderer.gui' instead of 'Renderer.cur[0]' in case we're drawing transparent Window and we're inside 'D.fxBegin' but need to access default gui RT
  181. if(secondary)Renderer._gui->copyHw(*cur, false, r ); // set background to be a copy
  182. ALPHA_MODE alpha=D.alpha(ALPHA_NONE); Renderer.set(rt1(), null, false); Sh.h_BlurX[true]->draw(rt0(), &re);
  183. Renderer.set(rt0(), null, false); Sh.h_BlurY[true]->draw(rt1(), &re);
  184. Renderer.set(cur , ds , true );
  185. if(shadow_opacity)
  186. {
  187. D.alpha(ALPHA_BLEND);
  188. if(shadow_opacity)
  189. {
  190. if(center_shadow)D.drawShadow (shadow_opacity, rect+Vec2(shadow_offset, -shadow_offset), shadow_radius);
  191. else D.drawShadowBorders(shadow_opacity, rect , shadow_radius);
  192. }
  193. }
  194. if(secondary) // for secondary we need to force rt.alpha to 1.0
  195. {
  196. D.alphaFactor(Color(blur_color.a, blur_color.a, blur_color.a, 255));
  197. D.alpha(ALPHA_FACTOR); Sh.h_Color[0]->set(Color(center_color.r, center_color.g, center_color.b, 0)); Sh.h_Color[1]->set(Color(blur_color.r, blur_color.g, blur_color.b, 255)); Sh.h_DrawC->draw(rt0(), &r);
  198. }else
  199. {
  200. D.alpha(ALPHA_BLEND ); Sh.h_Color[0]->set(Color(center_color.r, center_color.g, center_color.b, 0)); Sh.h_Color[1]->set(blur_color); Sh.h_DrawC->draw(rt0(), &r);
  201. }
  202. D.alpha(alpha );
  203. }else
  204. #endif
  205. {
  206. if(shadow_opacity)
  207. {
  208. if(center_shadow)D.drawShadow (shadow_opacity, rect+Vec2(shadow_offset, -shadow_offset), shadow_radius);
  209. else D.drawShadowBorders(shadow_opacity, rect , shadow_radius);
  210. }
  211. if(center_color.a)
  212. {
  213. if( panel_image )panel_image ->draw (center_color, TRANSPARENT, r);else
  214. if(!center_image )r . draw (center_color );else
  215. if(!center_stretch)center_image->drawTile(center_color, TRANSPARENT, r, center_scale);else
  216. center_image->draw (center_color, TRANSPARENT, r);
  217. }
  218. }
  219. if(border_color.a)
  220. {
  221. if(border_image)border_image->drawBorder(border_color, TRANSPARENT, r, border_size);else
  222. if(border_size )r . drawBorder(border_color, border_size);else
  223. r . draw (border_color, false);
  224. }
  225. if(side_color.a)
  226. {
  227. if(side_stretch)
  228. {
  229. Flt y[]={r.min.y, r.max.y};
  230. Flt x[3][2]= // [y][x]
  231. {
  232. {rect.min.x- top_corner_offset.x, rect.max.x+ top_corner_offset.x},
  233. {r .min.x , r .max.x },
  234. {rect.min.x-bottom_corner_offset.x, rect.max.x+bottom_corner_offset.x},
  235. };
  236. if( top_image)top_image->draw(side_color, TRANSPARENT, Rect(x[0][0], y[1], x[0][1], y[1]+top_size));
  237. if(bottom_image)
  238. {
  239. Rect r(x[2][0], y[0]-bottom_size, x[2][1], y[0]);
  240. if(bottom_image==top_image)r.swapY(); // mirror vertically if it's the same as top
  241. bottom_image->draw(side_color, TRANSPARENT, r);
  242. }
  243. if(left_right_image)
  244. {
  245. left_right_image->draw(side_color, TRANSPARENT, Rect(x[1][0], y[0], x[1][0]-left_right_size, y[1])); // mirror horizontally
  246. left_right_image->draw(side_color, TRANSPARENT, Rect(x[1][1], y[0], x[1][1]+left_right_size, y[1]));
  247. }
  248. if(top_corner_image)
  249. {
  250. Flt w=top_corner_size*top_corner_image->aspect(),
  251. h=top_corner_size,
  252. y1=y[1]+h;
  253. top_corner_image->draw(side_color, TRANSPARENT, Rect(x[0][0], y[1], x[0][0]-w, y1)); // mirror horizontally
  254. top_corner_image->draw(side_color, TRANSPARENT, Rect(x[0][1], y[1], x[0][1]+w, y1));
  255. }
  256. if(bottom_corner_image)
  257. {
  258. Flt w=bottom_corner_size*bottom_corner_image->aspect(),
  259. h=bottom_corner_size,
  260. y0=y[0]-h, y1=y[0];
  261. if(bottom_corner_image==top_corner_image)Swap(y0, y1); // mirror vertically if it's the same as top
  262. bottom_corner_image->draw(side_color, TRANSPARENT, Rect(x[2][0], y0, x[2][0]-w, y1)); // mirror horizontally
  263. bottom_corner_image->draw(side_color, TRANSPARENT, Rect(x[2][1], y0, x[2][1]+w, y1));
  264. }
  265. }else
  266. {
  267. if( top_image)top_image->draw(side_color, TRANSPARENT, Rect_C(rect.centerX()/*+top_offset.x*/, rect.max.y+top_offset, top_size*top_image->aspect(), top_size));
  268. if(bottom_image)
  269. {
  270. Flt h=bottom_size;
  271. if(bottom_image==top_image)CHS(h); // mirror vertically if it's the same as top
  272. bottom_image->draw(side_color, TRANSPARENT, Rect_C(rect.centerX()/*+bottom_offset.x*/, rect.min.y+bottom_offset, bottom_size*bottom_image->aspect(), h));
  273. }
  274. if(left_right_image)
  275. {
  276. Flt w=left_right_size*left_right_image->aspect(),
  277. h=left_right_size,
  278. y=rect.centerY()+left_right_offset.y;
  279. left_right_image->draw(side_color, TRANSPARENT, Rect_C(rect.min.x-left_right_offset.x, y, -w, h));
  280. left_right_image->draw(side_color, TRANSPARENT, Rect_C(rect.max.x+left_right_offset.x, y, w, h));
  281. }
  282. if(top_corner_image)
  283. {
  284. Flt w=top_corner_size*top_corner_image->aspect(),
  285. h=top_corner_size,
  286. y=rect.max.y+top_corner_offset.y;
  287. top_corner_image->draw(side_color, TRANSPARENT, Rect_C(rect.min.x-top_corner_offset.x, y, -w, h));
  288. top_corner_image->draw(side_color, TRANSPARENT, Rect_C(rect.max.x+top_corner_offset.x, y, w, h));
  289. }
  290. if(bottom_corner_image)
  291. {
  292. Flt w=bottom_corner_size*bottom_corner_image->aspect(),
  293. h=bottom_corner_size,
  294. y=rect.min.y+bottom_corner_offset.y;
  295. if(bottom_corner_image==top_corner_image)CHS(h); // mirror vertically if it's the same as top
  296. bottom_corner_image->draw(side_color, TRANSPARENT, Rect_C(rect.min.x-bottom_corner_offset.x, y, -w, h));
  297. bottom_corner_image->draw(side_color, TRANSPARENT, Rect_C(rect.max.x+bottom_corner_offset.x, y, w, h));
  298. }
  299. }
  300. }
  301. }
  302. void Panel::draw(C Color &color, C Rect &rect)C
  303. {
  304. Byte shadow_opacity= (T.shadow_opacity* color.a+128)/255;
  305. Color center_color =ColorMul(T.center_color , color),
  306. border_color =ColorMul(T.border_color , color),
  307. side_color =ColorMul(T. side_color , color),
  308. blur_color =ColorMul(T. blur_color , color);
  309. Rect r=rect; if(side_stretch)
  310. {
  311. r.min.x-=left_right_offset.x; r.min.y+=bottom_offset;
  312. r.max.x+=left_right_offset.x; r.max.y+= top_offset;
  313. }
  314. #if !MOBILE // too slow
  315. if(blur_color.a)
  316. {
  317. const Bool hi =true;
  318. const Int shift=(hi ? 1 : 2);
  319. ImageRTPtrRef rt0(hi ? Renderer._h0 : Renderer._q0); rt0.get(ImageRTDesc(Renderer._gui->w()>>shift, Renderer._gui->h()>>shift, IMAGERT_RGB));
  320. ImageRTPtrRef rt1(hi ? Renderer._h1 : Renderer._q1); rt1.get(ImageRTDesc(Renderer._gui->w()>>shift, Renderer._gui->h()>>shift, IMAGERT_RGB));
  321. Image *cur =Renderer._cur[0], *ds=Renderer._cur_ds;
  322. Rect re =r; re.extend(D.pixelToScreenSize(SHADER_BLUR_RANGE<<shift));
  323. Bool secondary=(Renderer._gui!=cur); // required when "window.fade && blur" is used
  324. Renderer._gui->copyHw(*rt0, false, re); // use 'Renderer.gui' instead of 'Renderer.cur[0]' in case we're drawing transparent Window and we're inside 'D.fxBegin' but need to access default gui RT
  325. if(secondary)Renderer._gui->copyHw(*cur, false, r ); // set background to be a copy
  326. ALPHA_MODE alpha=D.alpha(ALPHA_NONE); Renderer.set(rt1(), null, false); Sh.h_BlurX[true]->draw(rt0(), &re);
  327. Renderer.set(rt0(), null, false); Sh.h_BlurY[true]->draw(rt1(), &re);
  328. Renderer.set(cur , ds , true );
  329. if(shadow_opacity)
  330. {
  331. D.alpha(ALPHA_BLEND);
  332. if(shadow_opacity)
  333. {
  334. if(center_shadow)D.drawShadow (shadow_opacity, rect+Vec2(shadow_offset, -shadow_offset), shadow_radius);
  335. else D.drawShadowBorders(shadow_opacity, rect , shadow_radius);
  336. }
  337. }
  338. if(secondary) // for secondary we need to force rt.alpha to 1.0
  339. {
  340. D.alphaFactor(Color(blur_color.a, blur_color.a, blur_color.a, 255));
  341. D.alpha(ALPHA_FACTOR); Sh.h_Color[0]->set(Color(center_color.r, center_color.g, center_color.b, 0)); Sh.h_Color[1]->set(Color(blur_color.r, blur_color.g, blur_color.b, 255)); Sh.h_DrawC->draw(rt0(), &r);
  342. }else
  343. {
  344. D.alpha(ALPHA_BLEND ); Sh.h_Color[0]->set(Color(center_color.r, center_color.g, center_color.b, 0)); Sh.h_Color[1]->set(blur_color); Sh.h_DrawC->draw(rt0(), &r);
  345. }
  346. D.alpha(alpha );
  347. }else
  348. #endif
  349. {
  350. if(shadow_opacity)
  351. {
  352. if(center_shadow)D.drawShadow (shadow_opacity, rect+Vec2(shadow_offset, -shadow_offset), shadow_radius);
  353. else D.drawShadowBorders(shadow_opacity, rect , shadow_radius);
  354. }
  355. if(center_color.a)
  356. {
  357. if( panel_image )panel_image ->draw (center_color, TRANSPARENT, r);else
  358. if(!center_image )r . draw (center_color );else
  359. if(!center_stretch)center_image->drawTile(center_color, TRANSPARENT, r, center_scale);else
  360. center_image->draw (center_color, TRANSPARENT, r);
  361. }
  362. }
  363. if(border_color.a)
  364. {
  365. if(border_image)border_image->drawBorder(border_color, TRANSPARENT, r, border_size);else
  366. if(border_size )r . drawBorder(border_color, border_size);else
  367. r . draw (border_color, false);
  368. }
  369. if(side_color.a)
  370. {
  371. if(side_stretch)
  372. {
  373. Flt y[]={r.min.y, r.max.y};
  374. Flt x[3][2]= // [y][x]
  375. {
  376. {rect.min.x- top_corner_offset.x, rect.max.x+ top_corner_offset.x},
  377. {r .min.x , r .max.x },
  378. {rect.min.x-bottom_corner_offset.x, rect.max.x+bottom_corner_offset.x},
  379. };
  380. if( top_image)top_image->draw(side_color, TRANSPARENT, Rect(x[0][0], y[1], x[0][1], y[1]+top_size));
  381. if(bottom_image)
  382. {
  383. Rect r(x[2][0], y[0]-bottom_size, x[2][1], y[0]);
  384. if(bottom_image==top_image)r.swapY(); // mirror vertically if it's the same as top
  385. bottom_image->draw(side_color, TRANSPARENT, r);
  386. }
  387. if(left_right_image)
  388. {
  389. left_right_image->draw(side_color, TRANSPARENT, Rect(x[1][0], y[0], x[1][0]-left_right_size, y[1])); // mirror horizontally
  390. left_right_image->draw(side_color, TRANSPARENT, Rect(x[1][1], y[0], x[1][1]+left_right_size, y[1]));
  391. }
  392. if(top_corner_image)
  393. {
  394. Flt w=top_corner_size*top_corner_image->aspect(),
  395. h=top_corner_size,
  396. y1=y[1]+h;
  397. top_corner_image->draw(side_color, TRANSPARENT, Rect(x[0][0], y[1], x[0][0]-w, y1)); // mirror horizontally
  398. top_corner_image->draw(side_color, TRANSPARENT, Rect(x[0][1], y[1], x[0][1]+w, y1));
  399. }
  400. if(bottom_corner_image)
  401. {
  402. Flt w=bottom_corner_size*bottom_corner_image->aspect(),
  403. h=bottom_corner_size,
  404. y0=y[0]-h, y1=y[0];
  405. if(bottom_corner_image==top_corner_image)Swap(y0, y1); // mirror vertically if it's the same as top
  406. bottom_corner_image->draw(side_color, TRANSPARENT, Rect(x[2][0], y0, x[2][0]-w, y1)); // mirror horizontally
  407. bottom_corner_image->draw(side_color, TRANSPARENT, Rect(x[2][1], y0, x[2][1]+w, y1));
  408. }
  409. }else
  410. {
  411. if( top_image)top_image->draw(side_color, TRANSPARENT, Rect_C(rect.centerX()/*+top_offset.x*/, rect.max.y+top_offset, top_size*top_image->aspect(), top_size));
  412. if(bottom_image)
  413. {
  414. Flt h=bottom_size;
  415. if(bottom_image==top_image)CHS(h); // mirror vertically if it's the same as top
  416. bottom_image->draw(side_color, TRANSPARENT, Rect_C(rect.centerX()/*+bottom_offset.x*/, rect.min.y+bottom_offset, bottom_size*bottom_image->aspect(), h));
  417. }
  418. if(left_right_image)
  419. {
  420. Flt w=left_right_size*left_right_image->aspect(),
  421. h=left_right_size,
  422. y=rect.centerY()+left_right_offset.y;
  423. left_right_image->draw(side_color, TRANSPARENT, Rect_C(rect.min.x-left_right_offset.x, y, -w, h));
  424. left_right_image->draw(side_color, TRANSPARENT, Rect_C(rect.max.x+left_right_offset.x, y, w, h));
  425. }
  426. if(top_corner_image)
  427. {
  428. Flt w=top_corner_size*top_corner_image->aspect(),
  429. h=top_corner_size,
  430. y=rect.max.y+top_corner_offset.y;
  431. top_corner_image->draw(side_color, TRANSPARENT, Rect_C(rect.min.x-top_corner_offset.x, y, -w, h));
  432. top_corner_image->draw(side_color, TRANSPARENT, Rect_C(rect.max.x+top_corner_offset.x, y, w, h));
  433. }
  434. if(bottom_corner_image)
  435. {
  436. Flt w=bottom_corner_size*bottom_corner_image->aspect(),
  437. h=bottom_corner_size,
  438. y=rect.min.y+bottom_corner_offset.y;
  439. if(bottom_corner_image==top_corner_image)CHS(h); // mirror vertically if it's the same as top
  440. bottom_corner_image->draw(side_color, TRANSPARENT, Rect_C(rect.min.x-bottom_corner_offset.x, y, -w, h));
  441. bottom_corner_image->draw(side_color, TRANSPARENT, Rect_C(rect.max.x+bottom_corner_offset.x, y, w, h));
  442. }
  443. }
  444. }
  445. }
  446. /******************************************************************************/
  447. void Panel::drawLines(C Color &line_color, C Rect &rect)C
  448. {
  449. rect.draw(line_color, false);
  450. if(side_stretch)
  451. {
  452. Flt y[]={rect.min.y+bottom_offset, rect.max.y+top_offset};
  453. Flt x[3][2]= // [y][x]
  454. {
  455. {rect.min.x- top_corner_offset.x, rect.max.x+ top_corner_offset.x},
  456. {rect.min.x- left_right_offset.x, rect.max.x+ left_right_offset.x},
  457. {rect.min.x-bottom_corner_offset.x, rect.max.x+bottom_corner_offset.x},
  458. };
  459. if( top_image)Rect(x[0][0], y[1] , x[0][1], y[1]+top_size).draw(line_color, false);
  460. if(bottom_image)Rect(x[2][0], y[0]-bottom_size, x[2][1], y[0] ).draw(line_color, false);
  461. if(left_right_image)
  462. {
  463. Rect(x[1][0], y[0], x[1][0]-left_right_size, y[1]).draw(line_color, false);
  464. Rect(x[1][1], y[0], x[1][1]+left_right_size, y[1]).draw(line_color, false);
  465. }
  466. if(top_corner_image)
  467. {
  468. Flt w =top_corner_size*top_corner_image->aspect(),
  469. h =top_corner_size,
  470. y1=y[1]+h;
  471. Rect(x[0][0], y[1], x[0][0]-w, y1).draw(line_color, false);
  472. Rect(x[0][1], y[1], x[0][1]+w, y1).draw(line_color, false);
  473. }
  474. if(bottom_corner_image)
  475. {
  476. Flt w=bottom_corner_size*bottom_corner_image->aspect(),
  477. h=bottom_corner_size,
  478. y0=y[0]-h, y1=y[0];
  479. Rect(x[2][0], y0, x[2][0]-w, y1).draw(line_color, false);
  480. Rect(x[2][1], y0, x[2][1]+w, y1).draw(line_color, false);
  481. }
  482. }else
  483. {
  484. if( top_image)Rect_C(rect.centerX()/*+top_offset.x*/, rect.max.y+top_offset, top_size*top_image->aspect(), top_size).draw(line_color, false);
  485. if(bottom_image)
  486. {
  487. Flt h=bottom_size;
  488. Rect_C(rect.centerX()/*+bottom_offset.x*/, rect.min.y+bottom_offset, bottom_size*bottom_image->aspect(), h).draw(line_color, false);
  489. }
  490. if(left_right_image)
  491. {
  492. Flt w=left_right_size*left_right_image->aspect(),
  493. h=left_right_size,
  494. y=rect.centerY()+left_right_offset.y;
  495. Rect_C(rect.min.x-left_right_offset.x, y, -w, h).draw(line_color, false);
  496. Rect_C(rect.max.x+left_right_offset.x, y, w, h).draw(line_color, false);
  497. }
  498. if(top_corner_image)
  499. {
  500. Flt w=top_corner_size*top_corner_image->aspect(),
  501. h=top_corner_size,
  502. y=rect.max.y+top_corner_offset.y;
  503. Rect_C(rect.min.x-top_corner_offset.x, y, -w, h).draw(line_color, false);
  504. Rect_C(rect.max.x+top_corner_offset.x, y, w, h).draw(line_color, false);
  505. }
  506. if(bottom_corner_image)
  507. {
  508. Flt w=bottom_corner_size*bottom_corner_image->aspect(),
  509. h=bottom_corner_size,
  510. y=rect.min.y+bottom_corner_offset.y;
  511. Rect_C(rect.min.x-bottom_corner_offset.x, y, -w, h).draw(line_color, false);
  512. Rect_C(rect.max.x+bottom_corner_offset.x, y, w, h).draw(line_color, false);
  513. }
  514. }
  515. }
  516. /******************************************************************************/
  517. #pragma pack(push, 1)
  518. struct PanelDesc
  519. {
  520. Bool center_stretch, side_stretch, center_shadow;
  521. Byte shadow_opacity;
  522. Color center_color, border_color, side_color, blur_color;
  523. Flt shadow_radius, shadow_offset,
  524. border_size, center_scale, top_size, bottom_size, left_right_size, top_corner_size, bottom_corner_size,
  525. top_offset, bottom_offset;
  526. Vec2 left_right_offset, top_corner_offset, bottom_corner_offset;
  527. };
  528. struct PanelDesc2
  529. {
  530. Byte center_stretch, shadow_opacity;
  531. Color center_color, border_color, blur_color;
  532. Flt shadow_offset, shadow_radius, border_size, center_scale, corner_size, top_size;
  533. Vec2 corner_offset, top_offset;
  534. };
  535. #pragma pack(pop)
  536. Bool Panel::save(File &f, CChar *path)C
  537. {
  538. f.putUInt (CC4_GSTL);
  539. f.cmpUIntV(6 ); // version
  540. PanelDesc desc;
  541. Unaligned(desc. center_stretch, center_stretch);
  542. Unaligned(desc. side_stretch, side_stretch);
  543. Unaligned(desc. center_shadow , center_shadow );
  544. Unaligned(desc. shadow_opacity, shadow_opacity);
  545. Unaligned(desc. center_color , center_color );
  546. Unaligned(desc. border_color , border_color );
  547. Unaligned(desc. side_color , side_color );
  548. Unaligned(desc. blur_color , blur_color );
  549. Unaligned(desc. shadow_radius , shadow_radius );
  550. Unaligned(desc. shadow_offset , shadow_offset );
  551. Unaligned(desc. border_size , border_size );
  552. Unaligned(desc. center_scale , center_scale );
  553. Unaligned(desc. top_size , top_size );
  554. Unaligned(desc. bottom_size , bottom_size );
  555. Unaligned(desc. left_right_size , left_right_size );
  556. Unaligned(desc. top_corner_size , top_corner_size );
  557. Unaligned(desc.bottom_corner_size , bottom_corner_size );
  558. Unaligned(desc. top_offset , top_offset );
  559. Unaligned(desc. bottom_offset , bottom_offset );
  560. Unaligned(desc. left_right_offset , left_right_offset );
  561. Unaligned(desc. top_corner_offset , top_corner_offset );
  562. Unaligned(desc.bottom_corner_offset , bottom_corner_offset );
  563. f<<desc;
  564. f.putAsset( center_image.id());
  565. f.putAsset( border_image.id());
  566. f.putAsset( top_image.id());
  567. f.putAsset( bottom_image.id());
  568. f.putAsset( left_right_image.id());
  569. f.putAsset( top_corner_image.id());
  570. f.putAsset(bottom_corner_image.id());
  571. f.putAsset( panel_image.id());
  572. return f.ok();
  573. }
  574. Bool Panel::load(File &f, CChar *path)
  575. {
  576. if(f.getUInt()==CC4_GSTL)switch(f.decUIntV()) // version
  577. {
  578. case 6:
  579. {
  580. PanelDesc desc; if(f.get(desc))
  581. {
  582. Unaligned( center_stretch, desc. center_stretch);
  583. Unaligned( side_stretch, desc. side_stretch);
  584. Unaligned( center_shadow, desc. center_shadow );
  585. Unaligned( shadow_opacity, desc. shadow_opacity);
  586. Unaligned( center_color , desc. center_color );
  587. Unaligned( border_color , desc. border_color );
  588. Unaligned( side_color , desc. side_color );
  589. Unaligned( blur_color , desc. blur_color );
  590. Unaligned( shadow_radius , desc. shadow_radius );
  591. Unaligned( shadow_offset , desc. shadow_offset );
  592. Unaligned( border_size , desc. border_size );
  593. Unaligned( center_scale , desc. center_scale );
  594. Unaligned( top_size , desc. top_size );
  595. Unaligned( bottom_size , desc. bottom_size );
  596. Unaligned( left_right_size , desc. left_right_size );
  597. Unaligned( top_corner_size , desc. top_corner_size );
  598. Unaligned(bottom_corner_size , desc.bottom_corner_size );
  599. Unaligned( top_offset , desc. top_offset );
  600. Unaligned( bottom_offset , desc. bottom_offset );
  601. Unaligned( left_right_offset , desc. left_right_offset );
  602. Unaligned( top_corner_offset , desc. top_corner_offset );
  603. Unaligned(bottom_corner_offset , desc.bottom_corner_offset );
  604. center_image.require(f.getAssetID(), path);
  605. border_image.require(f.getAssetID(), path);
  606. top_image.require(f.getAssetID(), path);
  607. bottom_image.require(f.getAssetID(), path);
  608. left_right_image.require(f.getAssetID(), path);
  609. top_corner_image.require(f.getAssetID(), path);
  610. bottom_corner_image.require(f.getAssetID(), path);
  611. panel_image.require(f.getAssetID(), path);
  612. if(f.ok())return true;
  613. }
  614. }break;
  615. case 5:
  616. {
  617. PanelDesc desc; if(f.get(desc))
  618. {
  619. Unaligned( center_stretch, desc. center_stretch);
  620. Unaligned( side_stretch, desc. side_stretch);
  621. Unaligned( center_shadow, desc. center_shadow );
  622. Unaligned( shadow_opacity, desc. shadow_opacity);
  623. Unaligned( center_color , desc. center_color );
  624. Unaligned( border_color , desc. border_color );
  625. Unaligned( side_color , desc. side_color );
  626. Unaligned( blur_color , desc. blur_color );
  627. Unaligned( shadow_radius , desc. shadow_radius );
  628. Unaligned( shadow_offset , desc. shadow_offset );
  629. Unaligned( border_size , desc. border_size );
  630. Unaligned( center_scale , desc. center_scale );
  631. Unaligned( top_size , desc. top_size );
  632. Unaligned( bottom_size , desc. bottom_size );
  633. Unaligned( left_right_size , desc. left_right_size );
  634. Unaligned( top_corner_size , desc. top_corner_size );
  635. Unaligned(bottom_corner_size , desc.bottom_corner_size );
  636. Unaligned( top_offset , desc. top_offset );
  637. Unaligned( bottom_offset , desc. bottom_offset );
  638. Unaligned( left_right_offset , desc. left_right_offset );
  639. Unaligned( top_corner_offset , desc. top_corner_offset );
  640. Unaligned(bottom_corner_offset , desc.bottom_corner_offset );
  641. center_image.require(f._getAsset(), path);
  642. border_image.require(f._getAsset(), path);
  643. top_image.require(f._getAsset(), path);
  644. bottom_image.require(f._getAsset(), path);
  645. left_right_image.require(f._getAsset(), path);
  646. top_corner_image.require(f._getAsset(), path);
  647. bottom_corner_image.require(f._getAsset(), path);
  648. panel_image.require(f._getAsset(), path);
  649. if(f.ok())return true;
  650. }
  651. }break;
  652. case 4:
  653. {
  654. #pragma pack(push, 1)
  655. struct PanelDesc4
  656. {
  657. Byte center_stretch, shadow_opacity;
  658. Color center_color, border_color, blur_color;
  659. Flt shadow_offset, shadow_radius, border_size, center_scale, corner_size, top_size, bottom_size, left_right_size;
  660. Vec2 corner_offset, top_offset, bottom_offset, left_right_offset;
  661. }desc;
  662. #pragma pack(pop)
  663. if(f.get(desc))
  664. {
  665. center_stretch=(Unaligned(desc.center_stretch)!=0);
  666. Unaligned( shadow_opacity, desc. shadow_opacity );
  667. Unaligned( center_color , desc. center_color );
  668. Unaligned( border_color , desc. border_color );
  669. Unaligned( blur_color , desc. blur_color );
  670. Unaligned( shadow_offset , desc. shadow_offset );
  671. Unaligned( shadow_radius , desc. shadow_radius );
  672. Unaligned( border_size , desc. border_size );
  673. Unaligned( center_scale , desc. center_scale );
  674. Unaligned(top_corner_size , desc. corner_size );
  675. Unaligned( top_size , desc. top_size );
  676. Unaligned( bottom_size , desc. bottom_size );
  677. Unaligned(left_right_size , desc.left_right_size );
  678. Unaligned(top_corner_offset , desc. corner_offset );
  679. Unaligned( top_offset , desc. top_offset.y);
  680. Unaligned( bottom_offset , desc. bottom_offset.y);
  681. Unaligned(left_right_offset , desc.left_right_offset );
  682. top_image.require(f._getStr2(), path);
  683. center_image.require(f._getStr2(), path);
  684. border_image.require(f._getStr2(), path);
  685. top_corner_image.require(f._getStr2(), path);
  686. bottom_image.require(f._getStr2(), path);
  687. left_right_image.require(f._getStr2(), path);
  688. side_stretch =false;
  689. side_color =border_color;
  690. shadow_offset *=shadow_radius;
  691. bottom_corner_size =top_corner_size;
  692. bottom_corner_image =top_corner_image;
  693. bottom_corner_offset.set(top_corner_offset.x, -top_corner_offset.y);
  694. panel_image .clear();
  695. center_shadow=!Equal(shadow_offset, 0);
  696. if(f.ok())return true;
  697. }
  698. }break;
  699. case 3:
  700. {
  701. PanelDesc2 desc; if(f.get(desc))
  702. {
  703. center_stretch=(Unaligned(desc.center_stretch)!=0);
  704. Unaligned( shadow_opacity, desc.shadow_opacity);
  705. Unaligned( center_color , desc.center_color );
  706. Unaligned( border_color , desc.border_color );
  707. Unaligned( blur_color , desc. blur_color );
  708. Unaligned( shadow_offset , desc.shadow_offset );
  709. Unaligned( shadow_radius , desc.shadow_radius );
  710. Unaligned( border_size , desc.border_size );
  711. Unaligned( center_scale , desc.center_scale );
  712. Unaligned(top_corner_size , desc.corner_size );
  713. Unaligned( top_size , desc. top_size );
  714. Unaligned(top_corner_offset , desc.corner_offset );
  715. Unaligned( top_offset , desc. top_offset.y);
  716. top_image.require(f._getStr(), path);
  717. center_image.require(f._getStr(), path);
  718. border_image.require(f._getStr(), path);
  719. top_corner_image.require(f._getStr(), path);
  720. side_stretch =false;
  721. side_color =border_color;
  722. shadow_offset *=shadow_radius;
  723. bottom_corner_size =top_corner_size;
  724. bottom_corner_image =top_corner_image;
  725. bottom_corner_offset.set(top_corner_offset.x, -top_corner_offset.y);
  726. panel_image .clear();
  727. bottom_image.clear(); left_right_image.clear(); bottom_size=left_right_size=DEFAULT_SIZE; left_right_offset=bottom_offset=0;
  728. center_shadow=!Equal(shadow_offset, 0);
  729. if(f.ok())return true;
  730. }
  731. }break;
  732. case 2:
  733. {
  734. PanelDesc2 desc; if(f.get(desc))
  735. {
  736. center_stretch=(Unaligned(desc.center_stretch)!=0);
  737. Unaligned( shadow_opacity, desc.shadow_opacity);
  738. Unaligned( center_color , desc.center_color ); Swap(center_color.r, center_color.b);
  739. Unaligned( border_color , desc.border_color ); Swap(border_color.r, border_color.b);
  740. Unaligned( blur_color , desc. blur_color ); Swap( blur_color.r, blur_color.b);
  741. Unaligned( shadow_offset , desc.shadow_offset );
  742. Unaligned( shadow_radius , desc.shadow_radius );
  743. Unaligned( border_size , desc.border_size );
  744. Unaligned( center_scale , desc.center_scale );
  745. Unaligned(top_corner_size , desc.corner_size );
  746. Unaligned( top_size , desc. top_size );
  747. Unaligned(top_corner_offset , desc.corner_offset );
  748. Unaligned( top_offset , desc. top_offset.y);
  749. top_image.require(f._getStr(), path);
  750. center_image.require(f._getStr(), path);
  751. border_image.require(f._getStr(), path);
  752. top_corner_image.require(f._getStr(), path);
  753. side_stretch =false;
  754. side_color =border_color;
  755. shadow_offset *=shadow_radius;
  756. bottom_corner_size =top_corner_size;
  757. bottom_corner_image =top_corner_image;
  758. bottom_corner_offset.set(top_corner_offset.x, -top_corner_offset.y);
  759. panel_image .clear();
  760. bottom_image.clear(); left_right_image.clear(); bottom_size=left_right_size=DEFAULT_SIZE; left_right_offset=bottom_offset=0;
  761. center_shadow=!Equal(shadow_offset, 0);
  762. if(f.ok())return true;
  763. }
  764. }break;
  765. case 1:
  766. {
  767. #pragma pack(push, 4)
  768. struct PanelDesc1
  769. {
  770. Byte shadow_opacity, center_stretch;
  771. VecB4 center_color, border_color, blur_color;
  772. Flt center_scale, border_size, shadow_radius, shadow_offset;
  773. }desc;
  774. #pragma pack(pop)
  775. if(f.get(desc))
  776. {
  777. center_stretch=(Unaligned(desc.center_stretch)!=0);
  778. Unaligned( shadow_opacity, desc.shadow_opacity);
  779. center_color .set(Unaligned(desc.center_color.z), Unaligned(desc.center_color.y), Unaligned(desc.center_color.x), Unaligned(desc.center_color.w));
  780. border_color .set(Unaligned(desc.border_color.z), Unaligned(desc.border_color.y), Unaligned(desc.border_color.x), Unaligned(desc.border_color.w));
  781. blur_color .set(Unaligned(desc. blur_color.z), Unaligned(desc. blur_color.y), Unaligned(desc. blur_color.x), Unaligned(desc. blur_color.w));
  782. Unaligned( shadow_offset , desc.shadow_offset);
  783. Unaligned( shadow_radius , desc.shadow_radius);
  784. Unaligned( border_size , desc.border_size );
  785. Unaligned( center_scale , desc.center_scale );
  786. Unaligned(top_corner_size , desc.border_size );
  787. Unaligned( top_size , desc.border_size );
  788. top_corner_offset =0;
  789. top_offset =0;
  790. top_image.require(f._getStr8(), path);
  791. center_image.require(f._getStr8(), path);
  792. border_image.require(f._getStr8(), path);
  793. top_corner_image.require(f._getStr8(), path);
  794. side_stretch =false;
  795. side_color =border_color;
  796. shadow_offset *=shadow_radius;
  797. bottom_corner_size =top_corner_size;
  798. bottom_corner_image =top_corner_image;
  799. bottom_corner_offset.set(top_corner_offset.x, -top_corner_offset.y);
  800. panel_image .clear();
  801. bottom_image.clear(); left_right_image.clear(); bottom_size=left_right_size=DEFAULT_SIZE; left_right_offset=bottom_offset=0;
  802. center_shadow=!Equal(shadow_offset, 0);
  803. if(f.ok())return true;
  804. }
  805. }break;
  806. case 0:
  807. {
  808. #pragma pack(push, 4)
  809. struct PanelDesc0
  810. {
  811. Byte shadow_opacity, center_stretch;
  812. VecB4 center_color, border_color;
  813. Flt center_scale, border_size, shadow_radius, shadow_offset;
  814. }desc;
  815. #pragma pack(pop)
  816. if(f.get(desc))
  817. {
  818. center_stretch=(Unaligned(desc.center_stretch)!=0);
  819. Unaligned( shadow_opacity, desc.shadow_opacity);
  820. center_color .set(Unaligned(desc.center_color.z), Unaligned(desc.center_color.y), Unaligned(desc.center_color.x), Unaligned(desc.center_color.w));
  821. border_color .set(Unaligned(desc.border_color.z), Unaligned(desc.border_color.y), Unaligned(desc.border_color.x), Unaligned(desc.border_color.w));
  822. blur_color .zero();
  823. Unaligned( shadow_offset , desc.shadow_offset);
  824. Unaligned( shadow_radius , desc.shadow_radius);
  825. Unaligned( border_size , desc.border_size );
  826. Unaligned( center_scale , desc.center_scale );
  827. Unaligned(top_corner_size , desc.border_size );
  828. Unaligned( top_size , desc.border_size );
  829. top_corner_offset =0;
  830. top_offset =0;
  831. top_image.require(f._getStr8(), path);
  832. center_image.require(f._getStr8(), path);
  833. border_image.require(f._getStr8(), path);
  834. top_corner_image.require(f._getStr8(), path);
  835. side_stretch =false;
  836. side_color =border_color;
  837. shadow_offset *=shadow_radius;
  838. bottom_corner_size =top_corner_size;
  839. bottom_corner_image =top_corner_image;
  840. bottom_corner_offset.set(top_corner_offset.x, -top_corner_offset.y);
  841. panel_image .clear();
  842. bottom_image.clear(); left_right_image.clear(); bottom_size=left_right_size=DEFAULT_SIZE; left_right_offset=bottom_offset=0;
  843. center_shadow=!Equal(shadow_offset, 0);
  844. if(f.ok())return true;
  845. }
  846. }break;
  847. }
  848. reset(); return false;
  849. }
  850. Bool Panel::save(C Str &name)C
  851. {
  852. File f; if(f.writeTry(name)){if(save(f, _GetPath(name)) && f.flush())return true; f.del(); FDelFile(name);}
  853. return false;
  854. }
  855. Bool Panel::load(C Str &name)
  856. {
  857. File f; if(f.readTry(name))return load(f, _GetPath(name));
  858. reset(); return false;
  859. }
  860. void Panel::operator=(C Str &name)
  861. {
  862. if(!load(name))Exit(MLT(S+"Can't load Panel \"" +name+"\"",
  863. PL,S+u"Nie można wczytać Panel \""+name+"\""));
  864. }
  865. /******************************************************************************/
  866. }
  867. /******************************************************************************/