paintset.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. #include <precomp.h>
  2. #include <wasabicfg.h>
  3. #include "paintset.h"
  4. using namespace Paintset;
  5. #include <tataki/canvas/bltcanvas.h>
  6. #include <tataki/bitmap/autobitmap.h>
  7. #include <tataki/color/skinclr.h>
  8. #include <api/font/font.h>
  9. #include <api/service/svcs/svc_font.h>
  10. #ifndef WASABI_COMPILE_IMGLDR
  11. #error This module requires image loading capabilities (WASABI_COMPILE_IMGLDR)
  12. #endif
  13. #define TITLE_PADDING 4 // SKINME
  14. #ifdef WASABI_COMPILE_SKIN
  15. static SkinColor title_fg(L"wasabi.component.title.foreground");
  16. static SkinColor title_border(L"wasabi.component.title.border");
  17. #endif
  18. class NOVTABLE PaintSet
  19. {
  20. protected:
  21. PaintSet()
  22. {}
  23. public:
  24. virtual ~PaintSet()
  25. {}
  26. virtual void render(ifc_canvas *canvas, const RECT *r, int alpha) = 0;
  27. };
  28. static PaintSet *sets[NUM_PAINTSETS];
  29. class PaintSetButtonDisabled : public PaintSet
  30. {
  31. public:
  32. PaintSetButtonDisabled();
  33. virtual void render(ifc_canvas *canvas, const RECT *r, int alpha);
  34. private:
  35. AutoSkinBitmap mid;
  36. };
  37. PaintSetButtonDisabled::PaintSetButtonDisabled()
  38. {
  39. mid = L"wasabi.label.middle";
  40. }
  41. void PaintSetButtonDisabled::render(ifc_canvas *canvasbase, const RECT *_r, int alpha)
  42. {
  43. BaseCloneCanvas canvas;
  44. int ret = canvas.clone(canvasbase);
  45. ASSERT(ret);
  46. RECT r = *_r;
  47. mid.stretchToRectAlpha(&canvas, &r, alpha);
  48. }
  49. //----
  50. class PaintSetButtonUp : public PaintSet
  51. {
  52. public:
  53. PaintSetButtonUp();
  54. virtual void render(ifc_canvas *canvas, const RECT *r, int alpha);
  55. protected:
  56. AutoSkinBitmap ul, u, ur;
  57. AutoSkinBitmap l, mid, right;
  58. AutoSkinBitmap ll, bot, lr;
  59. };
  60. PaintSetButtonUp::PaintSetButtonUp()
  61. {
  62. ul = L"wasabi.button.top.left";
  63. u = L"wasabi.button.top";
  64. ur = L"wasabi.button.top.right";
  65. l = L"wasabi.button.left";
  66. mid = L"wasabi.button.middle";
  67. right = L"wasabi.button.right";
  68. ll = L"wasabi.button.bottom.left";
  69. bot = L"wasabi.button.bottom";
  70. lr = L"wasabi.button.bottom.right";
  71. }
  72. void PaintSetButtonUp::render(ifc_canvas *canvasbase, const RECT *_r, int alpha)
  73. {
  74. BaseCloneCanvas canvas;
  75. int ret = canvas.clone(canvasbase);
  76. if (!ret) return;
  77. RECT r = *_r, br;
  78. // upper left
  79. br.left = r.left;
  80. br.top = r.top;
  81. br.right = r.left + ul.getWidth();
  82. br.bottom = r.top + ul.getHeight();
  83. ul.stretchToRectAlpha(&canvas, &br, alpha);
  84. // top
  85. br.left = br.right;
  86. br.right = r.right - ur.getWidth();
  87. u.stretchToRectAlpha(&canvas, &br, alpha);
  88. // upper right
  89. br.left = br.right;
  90. br.right = r.right;
  91. ur.stretchToRectAlpha(&canvas, &br, alpha);
  92. // left
  93. br.left = r.left;
  94. br.right = r.left + l.getWidth();
  95. br.top = r.top + ul.getHeight();
  96. br.bottom = r.bottom - ll.getHeight();
  97. l.stretchToRectAlpha(&canvas, &br, alpha);
  98. // middle
  99. br.top = r.top + ul.getHeight();
  100. br.bottom = r.bottom - ll.getHeight();
  101. br.left = r.left + ul.getWidth();
  102. br.right = r.right - ur.getWidth();
  103. mid.stretchToRectAlpha(&canvas, &br, alpha);
  104. // right
  105. br.left = r.right - right.getWidth();
  106. br.right = r.right;
  107. br.top = r.top + ur.getHeight();
  108. br.bottom = r.bottom - lr.getHeight();
  109. right.stretchToRectAlpha(&canvas, &br, alpha);
  110. // lower left
  111. br.left = r.left;
  112. br.right = r.left + ll.getWidth();
  113. br.top = r.bottom - ll.getHeight();
  114. br.bottom = r.bottom;
  115. ll.stretchToRectAlpha(&canvas, &br, alpha);
  116. // bot
  117. br.left = r.left + ll.getWidth();
  118. br.right = r.right - lr.getWidth();
  119. br.top = r.bottom - bot.getHeight();
  120. br.bottom = r.bottom;
  121. bot.stretchToRectAlpha(&canvas, &br, alpha);
  122. // lower right
  123. br.left = r.right - lr.getWidth();
  124. br.right = r.right;
  125. br.top = r.bottom - lr.getHeight();
  126. br.bottom = r.bottom;
  127. lr.stretchToRectAlpha(&canvas, &br, alpha);
  128. }
  129. class PaintSetLabel : public PaintSetButtonUp
  130. {
  131. public:
  132. PaintSetLabel()
  133. {
  134. ul = L"wasabi.label.top.left";
  135. u = L"wasabi.label.top";
  136. ur = L"wasabi.label.top.right";
  137. l = L"wasabi.label.left";
  138. mid = L"wasabi.label.middle";
  139. right = L"wasabi.label.right";
  140. ll = L"wasabi.label.bottom.left";
  141. bot = L"wasabi.label.bottom";
  142. lr = L"wasabi.label.bottom.right";
  143. }
  144. };
  145. //----
  146. class PaintSetButtonDown : public PaintSet
  147. {
  148. public:
  149. PaintSetButtonDown();
  150. virtual void render(ifc_canvas *canvas, const RECT *r, int alpha);
  151. private:
  152. AutoSkinBitmap ul, u, ur;
  153. AutoSkinBitmap l, mid, right;
  154. AutoSkinBitmap ll, bot, lr;
  155. };
  156. PaintSetButtonDown::PaintSetButtonDown()
  157. {
  158. ul = L"wasabi.button.pressed.top.left";
  159. u = L"wasabi.button.pressed.top";
  160. ur = L"wasabi.button.pressed.top.right";
  161. l = L"wasabi.button.pressed.left";
  162. mid = L"wasabi.button.pressed.middle";
  163. right = L"wasabi.button.pressed.right";
  164. ll = L"wasabi.button.pressed.bottom.left";
  165. bot = L"wasabi.button.pressed.bottom";
  166. lr = L"wasabi.button.pressed.bottom.right";
  167. }
  168. void PaintSetButtonDown::render(ifc_canvas *canvasbase, const RECT *_r, int alpha)
  169. {
  170. BaseCloneCanvas canvas;
  171. int ret = canvas.clone(canvasbase);
  172. ASSERT(ret);
  173. RECT r = *_r, br;
  174. // upper left
  175. br.left = r.left;
  176. br.top = r.top;
  177. br.right = r.left + ul.getWidth();
  178. br.bottom = r.top + ul.getHeight();
  179. ul.stretchToRectAlpha(&canvas, &br, alpha);
  180. // top
  181. br.left = br.right;
  182. br.right = r.right - ur.getWidth();
  183. u.stretchToRectAlpha(&canvas, &br, alpha);
  184. // upper right
  185. br.left = br.right;
  186. br.right = r.right;
  187. ur.stretchToRectAlpha(&canvas, &br, alpha);
  188. // left
  189. br.left = r.left;
  190. br.right = r.left + l.getWidth();
  191. br.top = r.top + ul.getHeight();
  192. br.bottom = r.bottom - ll.getHeight();
  193. l.stretchToRectAlpha(&canvas, &br, alpha);
  194. // middle
  195. br.top = r.top + ul.getHeight();
  196. br.bottom = r.bottom - ll.getHeight();
  197. br.left = r.left + ul.getWidth();
  198. br.right = r.right - ur.getWidth();
  199. mid.stretchToRectAlpha(&canvas, &br, alpha);
  200. // right
  201. br.left = r.right - right.getWidth();
  202. br.right = r.right;
  203. br.top = r.top + ur.getHeight();
  204. br.bottom = r.bottom - lr.getHeight();
  205. right.stretchToRectAlpha(&canvas, &br, alpha);
  206. // lower left
  207. br.left = r.left;
  208. br.right = r.left + ll.getWidth();
  209. br.top = r.bottom - ll.getHeight();
  210. br.bottom = r.bottom;
  211. ll.stretchToRectAlpha(&canvas, &br, alpha);
  212. // bot
  213. br.left = r.left + ll.getWidth();
  214. br.right = r.right - lr.getWidth();
  215. br.top = r.bottom - bot.getHeight();
  216. br.bottom = r.bottom;
  217. bot.stretchToRectAlpha(&canvas, &br, alpha);
  218. // lower right
  219. br.left = r.right - lr.getWidth();
  220. br.right = r.right;
  221. br.top = r.bottom - lr.getHeight();
  222. br.bottom = r.bottom;
  223. lr.stretchToRectAlpha(&canvas, &br, alpha);
  224. }
  225. //--
  226. class PaintSetAppFrame : public PaintSet
  227. {
  228. public:
  229. PaintSetAppFrame();
  230. virtual ~PaintSetAppFrame();
  231. virtual void render(ifc_canvas *canvas, const RECT *r, int alpha);
  232. private:
  233. SkinBitmap *ul, *up, *ur;
  234. SkinBitmap *left, *right;
  235. SkinBitmap *ll, *bot, *lr;
  236. };
  237. PaintSetAppFrame::PaintSetAppFrame()
  238. {
  239. ul = new SkinBitmap(L"studio.border.upperLeft");
  240. up = new SkinBitmap(L"studio.border.top");
  241. ur = new SkinBitmap(L"studio.border.upperRight");
  242. left = new SkinBitmap(L"studio.border.left");
  243. right = new SkinBitmap(L"studio.border.right");
  244. ll = new SkinBitmap(L"studio.border.lowerLeft");
  245. bot = new SkinBitmap(L"studio.border.bottom");
  246. lr = new SkinBitmap(L"studio.border.lowerRight");
  247. }
  248. PaintSetAppFrame::~PaintSetAppFrame()
  249. {
  250. delete ul; delete up; delete ur;
  251. delete left; delete right;
  252. delete ll; delete bot; delete lr;
  253. }
  254. void PaintSetAppFrame::render(ifc_canvas *canvasbase, const RECT *_r, int alpha)
  255. {
  256. BaseCloneCanvas canvas;
  257. int ret = canvas.clone(canvasbase);
  258. ASSERT(ret);
  259. RECT r = *_r;
  260. RECT br;
  261. // upper left
  262. br = r;
  263. br.right = br.left + 2;
  264. br.bottom = br.top + 2;
  265. ul->stretchToRectAlpha(&canvas, &br, alpha);
  266. // top
  267. br = r;
  268. br.left += 2;
  269. br.right -= 2;
  270. br.bottom = br.top + 2;
  271. up->stretchToRectAlpha(&canvas, &br, alpha);
  272. // upper right
  273. br = r;
  274. br.left = br.right - 2;
  275. br.bottom = br.top + 2;
  276. ur->stretchToRectAlpha(&canvas, &br, alpha);
  277. // left
  278. br = r;
  279. br.right = br.left + 2;
  280. br.top += 2;
  281. br.bottom -= 2;
  282. left->stretchToRectAlpha(&canvas, &br, alpha);
  283. // right
  284. br = r;
  285. br.left = br.right - 2;
  286. br.top += 2;
  287. br.bottom -= 2;
  288. right->stretchToRectAlpha(&canvas, &br, alpha);
  289. // lower left
  290. br = r;
  291. br.right = br.left + 2;
  292. br.top = br.bottom - 2;
  293. ll->stretchToRectAlpha(&canvas, &br, alpha);
  294. // bottom
  295. br = r;
  296. br.left += 2;
  297. br.right -= 2;
  298. br.top = br.bottom - 2;
  299. bot->stretchToRectAlpha(&canvas, &br, alpha);
  300. // lower right
  301. br = r;
  302. br.left = br.right - 2;
  303. br.top = br.bottom - 2;
  304. lr->stretchToRectAlpha(&canvas, &br, alpha);
  305. }
  306. // -----
  307. class PaintSetTitleStreak : public PaintSet
  308. {
  309. public:
  310. PaintSetTitleStreak();
  311. virtual void render(ifc_canvas *canvas, const RECT *r, int alpha);
  312. private:
  313. AutoSkinBitmap title_left, title_middle, title_right;
  314. };
  315. PaintSetTitleStreak::PaintSetTitleStreak()
  316. {
  317. title_left = L"wasabi.titlebar.left.active";
  318. title_middle = L"wasabi.titlebar.center.active";
  319. title_right = L"wasabi.titlebar.right.active";
  320. }
  321. void PaintSetTitleStreak::render(ifc_canvas *canvasbase, const RECT *_r, int alpha)
  322. {
  323. BaseCloneCanvas canvas;
  324. int ret = canvas.clone(canvasbase);
  325. if (!ret) return;
  326. RECT r = *_r;
  327. RECT lr = r;
  328. lr.right = lr.left + title_left.getWidth();
  329. lr.top += ((lr.bottom - lr.top) - title_left.getHeight()) / 2;
  330. lr.bottom = lr.top + title_left.getHeight();
  331. if (lr.right <= lr.left) return;
  332. title_left.stretchToRectAlpha(&canvas, &lr, alpha);
  333. RECT rr = r;
  334. rr.left = rr.right - title_right.getWidth();
  335. rr.top += ((rr.bottom - rr.top) - title_left.getHeight()) / 2;
  336. rr.bottom = rr.top + title_left.getHeight();
  337. if (rr.right <= rr.left) return;
  338. title_right.stretchToRectAlpha(&canvas, &rr, alpha);
  339. RECT cr = r;
  340. cr.left = lr.right;
  341. cr.right = rr.left;
  342. cr.top += ((cr.bottom - cr.top) - title_left.getHeight()) / 2;
  343. cr.bottom = cr.top + title_left.getHeight();
  344. if (cr.right <= cr.left) return;
  345. title_middle.stretchToRectAlpha(&canvas, &cr, alpha);
  346. }
  347. class PaintSetFocusRect : public PaintSet
  348. {
  349. public:
  350. virtual void render(ifc_canvas *canvas, const RECT *r, int alpha)
  351. {
  352. BaseCloneCanvas c;
  353. c.clone(canvas);
  354. c.drawRect(r, 0, 0xFFFFFF, alpha);
  355. }
  356. };
  357. // -----
  358. int paintset_present(int set)
  359. {
  360. return paintset_renderPaintSet(set, NULL, NULL, 255, TRUE);
  361. }
  362. int paintset_renderPaintSet(int type, ifc_canvas *c, const RECT *r, int alpha, int checkonly)
  363. {
  364. PaintSet *ret = NULL;
  365. switch (type)
  366. {
  367. case BUTTONUP:
  368. ret = sets[BUTTONUP];
  369. if (ret == NULL) ret = new PaintSetButtonUp();
  370. sets[BUTTONUP] = ret;
  371. break;
  372. case BUTTONDOWN:
  373. ret = sets[BUTTONDOWN];
  374. if (ret == NULL) ret = new PaintSetButtonDown();
  375. sets[BUTTONDOWN] = ret;
  376. break;
  377. case TRAY:
  378. ret = sets[BUTTONDOWN];
  379. if (ret == NULL) ret = new PaintSetButtonDown();
  380. sets[BUTTONDOWN] = ret;
  381. break;
  382. case APPFRAME:
  383. ret = sets[APPFRAME];
  384. if (ret == NULL) ret = new PaintSetAppFrame();
  385. sets[APPFRAME] = ret;
  386. break;
  387. case BUTTONDISABLED:
  388. ret = sets[BUTTONDISABLED];
  389. if (ret == NULL) ret = new PaintSetButtonDisabled();
  390. sets[BUTTONDISABLED] = ret;
  391. break;
  392. case TITLESTREAK:
  393. ret = sets[TITLESTREAK];
  394. if (ret == NULL) ret = new PaintSetTitleStreak();
  395. sets[TITLESTREAK] = ret;
  396. break;
  397. case LABEL:
  398. ret = sets[LABEL];
  399. if (ret == NULL) ret = new PaintSetLabel();
  400. sets[LABEL] = ret;
  401. break;
  402. case FOCUSRECT:
  403. ret = sets[FOCUSRECT];
  404. if (ret == NULL) ret = new PaintSetFocusRect();
  405. sets[FOCUSRECT] = ret;
  406. break;
  407. }
  408. if (ret != NULL)
  409. {
  410. if (!checkonly) ret->render(c, r, alpha);
  411. return TRUE;
  412. }
  413. return FALSE;
  414. }
  415. #ifdef WASABI_COMPILE_FONTS
  416. #define VERTPAD 2
  417. #define AAFACTOR 2
  418. #define FONTNAME "studio.component.title"
  419. #define FONTNAMEW L"studio.component.title"
  420. void paintset_renderTitle(const wchar_t *title, ifc_canvas *canvasbase, const RECT *_r, int alpha, int dostreaks, int doborder)
  421. {
  422. BaseCloneCanvas canvas;
  423. int ret = canvas.clone(canvasbase);
  424. if (!ret) return;
  425. RECT r = *_r;
  426. int w = r.right - r.left;
  427. int h = (r.bottom - r.top) - VERTPAD;
  428. svc_font *f = Font::requestSkinFont(FONTNAMEW);
  429. if (f->isBitmap() || !doborder)
  430. {
  431. Wasabi::FontInfo fontInfo;
  432. int tw, th;
  433. fontInfo.pointSize = h;
  434. fontInfo.face = FONTNAMEW;
  435. fontInfo.color = title_fg;
  436. canvas.getTextExtent(title, &tw, &th, &fontInfo);
  437. w -= (tw + TITLE_PADDING * 2);
  438. w /= 2;
  439. int x = r.left + w + TITLE_PADDING;
  440. int y = r.top + VERTPAD / 2;
  441. canvas.textOut(x, y, title, &fontInfo);
  442. }
  443. else
  444. {
  445. Wasabi::FontInfo fontInfo;
  446. int tw, th;
  447. fontInfo.pointSize = h*AAFACTOR;
  448. fontInfo.face = FONTNAMEW;
  449. canvas.getTextExtent(title, &tw, &th, &fontInfo);
  450. tw /= AAFACTOR;
  451. th /= AAFACTOR;
  452. tw += 2;
  453. th += 2;
  454. BltCanvas bc(tw*AAFACTOR, th*AAFACTOR + 1);
  455. bc.fillBits(RGB(0, 0, 0)); // not skinned
  456. fontInfo.opaque=false;
  457. fontInfo.color = title_border;
  458. bc.textOut(-AAFACTOR, AAFACTOR / 2, title, &fontInfo);
  459. bc.textOut(AAFACTOR, AAFACTOR / 2, title, &fontInfo);
  460. bc.textOut(AAFACTOR / 2, -AAFACTOR, title, &fontInfo);
  461. bc.textOut(AAFACTOR / 2, AAFACTOR, title, &fontInfo);
  462. fontInfo.color = title_fg;
  463. bc.textOut(AAFACTOR / 2, AAFACTOR / 2, title, &fontInfo);
  464. // mask it
  465. bc.maskColor(RGB(0, 0, 0), RGB(0, 0, 0));
  466. BltCanvas tc(tw, th);
  467. bc.antiAliasTo(&tc, tw, th, AAFACTOR);
  468. //int cw = tw + TITLE_PADDING * 2;
  469. // if (cw > w || th > h) return;
  470. w -= (tw + TITLE_PADDING * 2);
  471. w /= 2;
  472. int x = r.left + w + TITLE_PADDING;
  473. int y = r.top + VERTPAD / 2;
  474. //FG>?? tc.vflip();
  475. tc.blitAlpha(&canvas, x, y, alpha);
  476. //SkinBitmap splef0(tc.getBitmap(), tc.getHDC(), TRUE, tc.getBits());
  477. // splef0.blitAlpha(&canvas, x, y, alpha);
  478. }
  479. if (dostreaks)
  480. {
  481. RECT pr = r;
  482. pr.right = pr.left + w;
  483. paintset_renderPaintSet(TITLESTREAK, &canvas, &pr, alpha);
  484. pr.right = r.right;
  485. pr.left = r.right - w;
  486. paintset_renderPaintSet(TITLESTREAK, &canvas, &pr, alpha);
  487. }
  488. }
  489. #endif
  490. void paintset_reset()
  491. {
  492. for (int i = 0; i < NUM_PAINTSETS; i++)
  493. {
  494. delete sets[i];
  495. sets[i] = NULL;
  496. }
  497. }