diff options
Diffstat (limited to 'Src/Wasabi/api/wnd/paintset.cpp')
-rw-r--r-- | Src/Wasabi/api/wnd/paintset.cpp | 603 |
1 files changed, 603 insertions, 0 deletions
diff --git a/Src/Wasabi/api/wnd/paintset.cpp b/Src/Wasabi/api/wnd/paintset.cpp new file mode 100644 index 00000000..b6ea8343 --- /dev/null +++ b/Src/Wasabi/api/wnd/paintset.cpp @@ -0,0 +1,603 @@ +#include <precomp.h> +#include <wasabicfg.h> +#include "paintset.h" + +using namespace Paintset; +#include <tataki/canvas/bltcanvas.h> + +#include <tataki/bitmap/autobitmap.h> +#include <tataki/color/skinclr.h> +#include <api/font/font.h> +#include <api/service/svcs/svc_font.h> + +#ifndef WASABI_COMPILE_IMGLDR +#error This module requires image loading capabilities (WASABI_COMPILE_IMGLDR) +#endif + +#define TITLE_PADDING 4 // SKINME + +#ifdef WASABI_COMPILE_SKIN +static SkinColor title_fg(L"wasabi.component.title.foreground"); +static SkinColor title_border(L"wasabi.component.title.border"); +#endif + +class NOVTABLE PaintSet +{ +protected: + PaintSet() + {} +public: + virtual ~PaintSet() + {} + + virtual void render(ifc_canvas *canvas, const RECT *r, int alpha) = 0; +}; + +static PaintSet *sets[NUM_PAINTSETS]; + +class PaintSetButtonDisabled : public PaintSet +{ +public: + PaintSetButtonDisabled(); + + virtual void render(ifc_canvas *canvas, const RECT *r, int alpha); + +private: + AutoSkinBitmap mid; +}; + +PaintSetButtonDisabled::PaintSetButtonDisabled() +{ + mid = L"wasabi.label.middle"; +} + +void PaintSetButtonDisabled::render(ifc_canvas *canvasbase, const RECT *_r, int alpha) +{ + BaseCloneCanvas canvas; + int ret = canvas.clone(canvasbase); + ASSERT(ret); + + RECT r = *_r; + + mid.stretchToRectAlpha(&canvas, &r, alpha); +} + +//---- + +class PaintSetButtonUp : public PaintSet +{ +public: + PaintSetButtonUp(); + + virtual void render(ifc_canvas *canvas, const RECT *r, int alpha); + +protected: + AutoSkinBitmap ul, u, ur; + AutoSkinBitmap l, mid, right; + AutoSkinBitmap ll, bot, lr; +}; + +PaintSetButtonUp::PaintSetButtonUp() +{ + ul = L"wasabi.button.top.left"; + u = L"wasabi.button.top"; + ur = L"wasabi.button.top.right"; + + l = L"wasabi.button.left"; + mid = L"wasabi.button.middle"; + right = L"wasabi.button.right"; + + ll = L"wasabi.button.bottom.left"; + bot = L"wasabi.button.bottom"; + lr = L"wasabi.button.bottom.right"; +} + +void PaintSetButtonUp::render(ifc_canvas *canvasbase, const RECT *_r, int alpha) +{ + BaseCloneCanvas canvas; + int ret = canvas.clone(canvasbase); + if (!ret) return; + + RECT r = *_r, br; + + // upper left + br.left = r.left; + br.top = r.top; + br.right = r.left + ul.getWidth(); + br.bottom = r.top + ul.getHeight(); + ul.stretchToRectAlpha(&canvas, &br, alpha); + + // top + br.left = br.right; + br.right = r.right - ur.getWidth(); + u.stretchToRectAlpha(&canvas, &br, alpha); + + // upper right + br.left = br.right; + br.right = r.right; + ur.stretchToRectAlpha(&canvas, &br, alpha); + + // left + br.left = r.left; + br.right = r.left + l.getWidth(); + br.top = r.top + ul.getHeight(); + br.bottom = r.bottom - ll.getHeight(); + l.stretchToRectAlpha(&canvas, &br, alpha); + + // middle + br.top = r.top + ul.getHeight(); + br.bottom = r.bottom - ll.getHeight(); + br.left = r.left + ul.getWidth(); + br.right = r.right - ur.getWidth(); + mid.stretchToRectAlpha(&canvas, &br, alpha); + + // right + br.left = r.right - right.getWidth(); + br.right = r.right; + br.top = r.top + ur.getHeight(); + br.bottom = r.bottom - lr.getHeight(); + right.stretchToRectAlpha(&canvas, &br, alpha); + + // lower left + br.left = r.left; + br.right = r.left + ll.getWidth(); + br.top = r.bottom - ll.getHeight(); + br.bottom = r.bottom; + ll.stretchToRectAlpha(&canvas, &br, alpha); + + // bot + br.left = r.left + ll.getWidth(); + br.right = r.right - lr.getWidth(); + br.top = r.bottom - bot.getHeight(); + br.bottom = r.bottom; + bot.stretchToRectAlpha(&canvas, &br, alpha); + + // lower right + br.left = r.right - lr.getWidth(); + br.right = r.right; + br.top = r.bottom - lr.getHeight(); + br.bottom = r.bottom; + lr.stretchToRectAlpha(&canvas, &br, alpha); +} + +class PaintSetLabel : public PaintSetButtonUp +{ +public: + PaintSetLabel() + { + ul = L"wasabi.label.top.left"; + u = L"wasabi.label.top"; + ur = L"wasabi.label.top.right"; + + l = L"wasabi.label.left"; + mid = L"wasabi.label.middle"; + right = L"wasabi.label.right"; + + ll = L"wasabi.label.bottom.left"; + bot = L"wasabi.label.bottom"; + lr = L"wasabi.label.bottom.right"; + } +}; + +//---- + +class PaintSetButtonDown : public PaintSet +{ +public: + PaintSetButtonDown(); + + virtual void render(ifc_canvas *canvas, const RECT *r, int alpha); + +private: + AutoSkinBitmap ul, u, ur; + AutoSkinBitmap l, mid, right; + AutoSkinBitmap ll, bot, lr; +}; + +PaintSetButtonDown::PaintSetButtonDown() +{ + ul = L"wasabi.button.pressed.top.left"; + u = L"wasabi.button.pressed.top"; + ur = L"wasabi.button.pressed.top.right"; + + l = L"wasabi.button.pressed.left"; + mid = L"wasabi.button.pressed.middle"; + right = L"wasabi.button.pressed.right"; + + ll = L"wasabi.button.pressed.bottom.left"; + bot = L"wasabi.button.pressed.bottom"; + lr = L"wasabi.button.pressed.bottom.right"; +} + +void PaintSetButtonDown::render(ifc_canvas *canvasbase, const RECT *_r, int alpha) +{ + BaseCloneCanvas canvas; + int ret = canvas.clone(canvasbase); + ASSERT(ret); + + RECT r = *_r, br; + + // upper left + br.left = r.left; + br.top = r.top; + br.right = r.left + ul.getWidth(); + br.bottom = r.top + ul.getHeight(); + ul.stretchToRectAlpha(&canvas, &br, alpha); + + // top + br.left = br.right; + br.right = r.right - ur.getWidth(); + u.stretchToRectAlpha(&canvas, &br, alpha); + + // upper right + br.left = br.right; + br.right = r.right; + ur.stretchToRectAlpha(&canvas, &br, alpha); + + // left + br.left = r.left; + br.right = r.left + l.getWidth(); + br.top = r.top + ul.getHeight(); + br.bottom = r.bottom - ll.getHeight(); + l.stretchToRectAlpha(&canvas, &br, alpha); + + // middle + br.top = r.top + ul.getHeight(); + br.bottom = r.bottom - ll.getHeight(); + br.left = r.left + ul.getWidth(); + br.right = r.right - ur.getWidth(); + mid.stretchToRectAlpha(&canvas, &br, alpha); + + // right + br.left = r.right - right.getWidth(); + br.right = r.right; + br.top = r.top + ur.getHeight(); + br.bottom = r.bottom - lr.getHeight(); + right.stretchToRectAlpha(&canvas, &br, alpha); + + // lower left + br.left = r.left; + br.right = r.left + ll.getWidth(); + br.top = r.bottom - ll.getHeight(); + br.bottom = r.bottom; + ll.stretchToRectAlpha(&canvas, &br, alpha); + + // bot + br.left = r.left + ll.getWidth(); + br.right = r.right - lr.getWidth(); + br.top = r.bottom - bot.getHeight(); + br.bottom = r.bottom; + bot.stretchToRectAlpha(&canvas, &br, alpha); + + // lower right + br.left = r.right - lr.getWidth(); + br.right = r.right; + br.top = r.bottom - lr.getHeight(); + br.bottom = r.bottom; + lr.stretchToRectAlpha(&canvas, &br, alpha); +} +//-- + +class PaintSetAppFrame : public PaintSet +{ +public: + PaintSetAppFrame(); + virtual ~PaintSetAppFrame(); + + virtual void render(ifc_canvas *canvas, const RECT *r, int alpha); + +private: + SkinBitmap *ul, *up, *ur; + SkinBitmap *left, *right; + SkinBitmap *ll, *bot, *lr; +}; + +PaintSetAppFrame::PaintSetAppFrame() +{ + ul = new SkinBitmap(L"studio.border.upperLeft"); + up = new SkinBitmap(L"studio.border.top"); + ur = new SkinBitmap(L"studio.border.upperRight"); + + left = new SkinBitmap(L"studio.border.left"); + right = new SkinBitmap(L"studio.border.right"); + + ll = new SkinBitmap(L"studio.border.lowerLeft"); + bot = new SkinBitmap(L"studio.border.bottom"); + lr = new SkinBitmap(L"studio.border.lowerRight"); +} + +PaintSetAppFrame::~PaintSetAppFrame() +{ + delete ul; delete up; delete ur; + delete left; delete right; + delete ll; delete bot; delete lr; +} + +void PaintSetAppFrame::render(ifc_canvas *canvasbase, const RECT *_r, int alpha) +{ + BaseCloneCanvas canvas; + int ret = canvas.clone(canvasbase); + ASSERT(ret); + + RECT r = *_r; + RECT br; + + // upper left + br = r; + br.right = br.left + 2; + br.bottom = br.top + 2; + ul->stretchToRectAlpha(&canvas, &br, alpha); + + // top + br = r; + br.left += 2; + br.right -= 2; + br.bottom = br.top + 2; + up->stretchToRectAlpha(&canvas, &br, alpha); + + // upper right + br = r; + br.left = br.right - 2; + br.bottom = br.top + 2; + ur->stretchToRectAlpha(&canvas, &br, alpha); + + // left + br = r; + br.right = br.left + 2; + br.top += 2; + br.bottom -= 2; + left->stretchToRectAlpha(&canvas, &br, alpha); + + // right + br = r; + br.left = br.right - 2; + br.top += 2; + br.bottom -= 2; + right->stretchToRectAlpha(&canvas, &br, alpha); + + // lower left + br = r; + br.right = br.left + 2; + br.top = br.bottom - 2; + ll->stretchToRectAlpha(&canvas, &br, alpha); + + // bottom + br = r; + br.left += 2; + br.right -= 2; + br.top = br.bottom - 2; + bot->stretchToRectAlpha(&canvas, &br, alpha); + + // lower right + br = r; + br.left = br.right - 2; + br.top = br.bottom - 2; + lr->stretchToRectAlpha(&canvas, &br, alpha); +} + +// ----- + +class PaintSetTitleStreak : public PaintSet +{ +public: + PaintSetTitleStreak(); + + virtual void render(ifc_canvas *canvas, const RECT *r, int alpha); + +private: + AutoSkinBitmap title_left, title_middle, title_right; +}; + +PaintSetTitleStreak::PaintSetTitleStreak() +{ + title_left = L"wasabi.titlebar.left.active"; + title_middle = L"wasabi.titlebar.center.active"; + title_right = L"wasabi.titlebar.right.active"; +} + +void PaintSetTitleStreak::render(ifc_canvas *canvasbase, const RECT *_r, int alpha) +{ + BaseCloneCanvas canvas; + int ret = canvas.clone(canvasbase); + if (!ret) return; + + RECT r = *_r; + + RECT lr = r; + lr.right = lr.left + title_left.getWidth(); + lr.top += ((lr.bottom - lr.top) - title_left.getHeight()) / 2; + lr.bottom = lr.top + title_left.getHeight(); + if (lr.right <= lr.left) return; + title_left.stretchToRectAlpha(&canvas, &lr, alpha); + + RECT rr = r; + rr.left = rr.right - title_right.getWidth(); + rr.top += ((rr.bottom - rr.top) - title_left.getHeight()) / 2; + rr.bottom = rr.top + title_left.getHeight(); + if (rr.right <= rr.left) return; + title_right.stretchToRectAlpha(&canvas, &rr, alpha); + + RECT cr = r; + cr.left = lr.right; + cr.right = rr.left; + cr.top += ((cr.bottom - cr.top) - title_left.getHeight()) / 2; + cr.bottom = cr.top + title_left.getHeight(); + if (cr.right <= cr.left) return; + title_middle.stretchToRectAlpha(&canvas, &cr, alpha); +} + +class PaintSetFocusRect : public PaintSet +{ +public: + virtual void render(ifc_canvas *canvas, const RECT *r, int alpha) + { + BaseCloneCanvas c; + c.clone(canvas); + c.drawRect(r, 0, 0xFFFFFF, alpha); + } +}; + +// ----- + +int paintset_present(int set) +{ + return paintset_renderPaintSet(set, NULL, NULL, 255, TRUE); +} + +int paintset_renderPaintSet(int type, ifc_canvas *c, const RECT *r, int alpha, int checkonly) +{ + PaintSet *ret = NULL; + switch (type) + { + case BUTTONUP: + ret = sets[BUTTONUP]; + if (ret == NULL) ret = new PaintSetButtonUp(); + sets[BUTTONUP] = ret; + break; + case BUTTONDOWN: + ret = sets[BUTTONDOWN]; + if (ret == NULL) ret = new PaintSetButtonDown(); + sets[BUTTONDOWN] = ret; + break; + case TRAY: + ret = sets[BUTTONDOWN]; + if (ret == NULL) ret = new PaintSetButtonDown(); + sets[BUTTONDOWN] = ret; + break; + case APPFRAME: + ret = sets[APPFRAME]; + if (ret == NULL) ret = new PaintSetAppFrame(); + sets[APPFRAME] = ret; + break; + case BUTTONDISABLED: + ret = sets[BUTTONDISABLED]; + if (ret == NULL) ret = new PaintSetButtonDisabled(); + sets[BUTTONDISABLED] = ret; + break; + case TITLESTREAK: + ret = sets[TITLESTREAK]; + if (ret == NULL) ret = new PaintSetTitleStreak(); + sets[TITLESTREAK] = ret; + break; + case LABEL: + ret = sets[LABEL]; + if (ret == NULL) ret = new PaintSetLabel(); + sets[LABEL] = ret; + break; + case FOCUSRECT: + ret = sets[FOCUSRECT]; + if (ret == NULL) ret = new PaintSetFocusRect(); + sets[FOCUSRECT] = ret; + break; + } + + if (ret != NULL) + { + if (!checkonly) ret->render(c, r, alpha); + return TRUE; + } + return FALSE; +} + +#ifdef WASABI_COMPILE_FONTS + +#define VERTPAD 2 +#define AAFACTOR 2 +#define FONTNAME "studio.component.title" +#define FONTNAMEW L"studio.component.title" + +void paintset_renderTitle(const wchar_t *title, ifc_canvas *canvasbase, const RECT *_r, int alpha, int dostreaks, int doborder) +{ + BaseCloneCanvas canvas; + int ret = canvas.clone(canvasbase); + if (!ret) return; + + RECT r = *_r; + int w = r.right - r.left; + int h = (r.bottom - r.top) - VERTPAD; + + svc_font *f = Font::requestSkinFont(FONTNAMEW); + if (f->isBitmap() || !doborder) + { + Wasabi::FontInfo fontInfo; + int tw, th; + fontInfo.pointSize = h; + fontInfo.face = FONTNAMEW; + fontInfo.color = title_fg; + canvas.getTextExtent(title, &tw, &th, &fontInfo); + w -= (tw + TITLE_PADDING * 2); + w /= 2; + int x = r.left + w + TITLE_PADDING; + int y = r.top + VERTPAD / 2; + canvas.textOut(x, y, title, &fontInfo); + } + else + { + Wasabi::FontInfo fontInfo; + int tw, th; + fontInfo.pointSize = h*AAFACTOR; + fontInfo.face = FONTNAMEW; + canvas.getTextExtent(title, &tw, &th, &fontInfo); + tw /= AAFACTOR; + th /= AAFACTOR; + tw += 2; + th += 2; + + BltCanvas bc(tw*AAFACTOR, th*AAFACTOR + 1); + bc.fillBits(RGB(0, 0, 0)); // not skinned + fontInfo.opaque=false; + fontInfo.color = title_border; + bc.textOut(-AAFACTOR, AAFACTOR / 2, title, &fontInfo); + bc.textOut(AAFACTOR, AAFACTOR / 2, title, &fontInfo); + bc.textOut(AAFACTOR / 2, -AAFACTOR, title, &fontInfo); + bc.textOut(AAFACTOR / 2, AAFACTOR, title, &fontInfo); + + fontInfo.color = title_fg; + bc.textOut(AAFACTOR / 2, AAFACTOR / 2, title, &fontInfo); + + // mask it + bc.maskColor(RGB(0, 0, 0), RGB(0, 0, 0)); + BltCanvas tc(tw, th); + bc.antiAliasTo(&tc, tw, th, AAFACTOR); + + + //int cw = tw + TITLE_PADDING * 2; + // if (cw > w || th > h) return; + w -= (tw + TITLE_PADDING * 2); + w /= 2; + + int x = r.left + w + TITLE_PADDING; + int y = r.top + VERTPAD / 2; +//FG>?? tc.vflip(); + tc.blitAlpha(&canvas, x, y, alpha); + + //SkinBitmap splef0(tc.getBitmap(), tc.getHDC(), TRUE, tc.getBits()); +// splef0.blitAlpha(&canvas, x, y, alpha); + + + + } + + if (dostreaks) + { + RECT pr = r; + pr.right = pr.left + w; + paintset_renderPaintSet(TITLESTREAK, &canvas, &pr, alpha); + + pr.right = r.right; + pr.left = r.right - w; + paintset_renderPaintSet(TITLESTREAK, &canvas, &pr, alpha); + } +} + +#endif + +void paintset_reset() +{ + for (int i = 0; i < NUM_PAINTSETS; i++) + { + delete sets[i]; + sets[i] = NULL; + } +} + |