25 #include "IPlugStructs.h" 27 #include "IGraphicsPrivate.h" 28 #include "IGraphicsUtilities.h" 29 #include "IGraphicsConstants.h" 32 BEGIN_IGRAPHICS_NAMESPACE
44 using IActionFunction = std::function<void(IControl*)>;
45 using IAnimationFunction = std::function<void(IControl*)>;
46 using ILambdaDrawFunction = std::function<void(ILambdaControl*, IGraphics&, IRECT&)>;
47 using IKeyHandlerFunc = std::function<bool(const IKeyPress& key, bool isUp)>;
48 using IMsgBoxCompletionHanderFunc = std::function<void(EMsgBoxResult result)>;
49 using IColorPickerHandlerFunc = std::function<void(const IColor& result)>;
50 using IGestureFunc = std::function<void(IControl*, const IGestureInfo&)>;
51 using IPopupFunction = std::function<void(IPopupMenu* pMenu)>;
52 using IDisplayTickFunc = std::function<void()>;
53 using ITouchID = uintptr_t;
76 using MTLTexturePtr =
void*;
78 using Milliseconds = std::chrono::duration<double, std::chrono::milliseconds::period>;
79 using TimePoint = std::chrono::time_point<std::chrono::high_resolution_clock, Milliseconds>;
93 : mAPIBitmap(pAPIBitmap)
94 , mW(pAPIBitmap->GetWidth() / pAPIBitmap->
GetScale())
95 , mH(pAPIBitmap->GetHeight() / pAPIBitmap->
GetScale())
97 , mFramesAreHorizontal(framesAreHorizontal)
98 , mResourceName(name, static_cast<int>(strlen(name)))
103 : mAPIBitmap(
nullptr)
107 , mFramesAreHorizontal(
false)
112 int W()
const {
return mW; }
115 int H()
const {
return mH; }
118 int FW()
const {
return (mFramesAreHorizontal ? mW / mN : mW); }
121 int FH()
const {
return (mFramesAreHorizontal ? mH : mH / mN); }
124 int N()
const {
return mN; }
142 inline bool IsValid()
const {
return mAPIBitmap !=
nullptr; }
154 bool mFramesAreHorizontal;
156 WDL_String mResourceName;
162 #ifdef IGRAPHICS_SKIA 165 ISVG(sk_sp<SkSVGDOM> svgDom)
174 return mSVGDom->containerSize().width();
183 return mSVGDom->containerSize().height();
189 inline bool IsValid()
const {
return mSVGDom !=
nullptr; }
191 sk_sp<SkSVGDOM> mSVGDom;
196 ISVG(NSVGimage* pImage)
205 return mImage->width;
214 return mImage->height;
220 inline bool IsValid()
const {
return mImage !=
nullptr; }
222 NSVGimage* mImage =
nullptr;
236 IColor(
int a = 255,
int r = 0,
int g = 0,
int b = 0) : A(a), R(r), G(g), B(b) {}
238 bool operator==(
const IColor& rhs) {
return (rhs.A == A && rhs.R == R && rhs.G == G && rhs.B == B); }
239 bool operator!=(
const IColor& rhs) {
return !operator==(rhs); }
246 void Set(
int a = 255,
int r = 0,
int g = 0,
int b = 0) { A = a; R = r; G = g; B = b; }
249 bool Empty()
const {
return A == 0 && R == 0 && G == 0 && B == 0; }
256 void Randomise(
int alpha = 255) { A = alpha; R = std::rand() % 255; G = std::rand() % 255; B = std::rand() % 255; }
262 A =
static_cast<int>(
Clip(alpha, 0.f, 1.f) * 255.f);
279 const int mod =
static_cast<int>(c * 255.f);
280 R =
Clip(R += mod, 0, 255);
281 G =
Clip(G += mod, 0, 255);
282 B =
Clip(B += mod, 0, 255);
308 rgbaf[0] = R / 255.f;
309 rgbaf[1] = G / 255.f;
310 rgbaf[2] = B / 255.f;
311 rgbaf[3] = A / 255.f;
319 void GetHSLA(
float& h,
float& s,
float& l,
float& a)
const 321 const float fR = R / 255.f;
322 const float fG = G / 255.f;
323 const float fB = B / 255.f;
326 const float fMin = std::min(fR, std::min(fG, fB));
327 const float fMax = std::max(fR, std::max(fG, fB));
328 const float fDiff = fMax - fMin;
329 const float fSum = fMax + fMin;
333 if (fMin == fMax) { s = 0.f; h = 0.f; l /= 100.f;
return; }
334 else if (l < 50.f) { s = 100.f * fDiff / fSum; }
335 else { s = 100.f * fDiff / (2.f - fDiff); }
337 if (fMax == fR) { h = 60.f * (fG - fB) / fDiff; }
338 if (fMax == fG) { h = 60.f * (fB - fR) / fDiff + 120.f; }
339 if (fMax == fB) { h = 60.f * (fR - fG) / fDiff + 240.f; }
341 if (h < 0.f) { h = h + 360.f; }
352 int min = R < G ? (R < B ? R : B) : (G < B ? G : B);
353 int max = R > G ? (R > B ? R : B) : (G > B ? G : B);
354 return (min + max) / 2;
362 int A = randomAlpha ? std::rand() & 0xFF : 255;
363 int R = std::rand() & 0xFF;
364 int G = std::rand() & 0xFF;
365 int B = std::rand() & 0xFF;
367 return IColor(A, R, G, B);
376 int R =
static_cast<int>(rgbf[0] * 255.f);
377 int G =
static_cast<int>(rgbf[1] * 255.f);
378 int B =
static_cast<int>(rgbf[2] * 255.f);
380 return IColor(A, R, G, B);
388 int R =
static_cast<int>(rgbaf[0] * 255.f);
389 int G =
static_cast<int>(rgbaf[1] * 255.f);
390 int B =
static_cast<int>(rgbaf[2] * 255.f);
391 int A =
static_cast<int>(rgbaf[3] * 255.f);
393 return IColor(A, R, G, B);
407 int R = (colorCode >> 16) & 0xFF;
408 int G = (colorCode >> 8) & 0xFF;
409 int B = colorCode & 0xFF;
411 return IColor(A, R, G, B);
419 WDL_String str(hexStr);
421 if(str.GetLength() == 7 && str.Get()[0] ==
'#')
425 return FromColorCode(static_cast<int>(std::stoul(str.Get(),
nullptr, 16)));
429 assert(0 &&
"Invalid color code str, returning black");
437 return (R << 16) | (G << 8) | B;
443 str.SetFormatted(32,
"#%02x%02x%02x%02x", R, G, B, A);
454 auto hue = [](
float h,
float m1,
float m2) {
458 return m1 + (m2 - m1) * h * 6.0f;
459 else if (h < 3.0f / 6.0f)
461 else if (h < 4.0f / 6.0f)
462 return m1 + (m2 - m1) * (2.0f / 3.0f - h) * 6.0f;
467 h = std::fmodf(h, 1.0f);
468 if (h < 0.0f) h += 1.0f;
469 s =
Clip(s, 0.0f, 1.0f);
470 l =
Clip(l, 0.0f, 1.0f);
471 float m2 = l <= 0.5f ? (l * (1 + s)) : (l + s - l * s);
472 float m1 = 2 * l - m2;
473 col.R =
static_cast<int>(
Clip(hue(h + 1.0f / 3.0f, m1, m2), 0.0f, 1.0f) * 255.f);
474 col.G =
static_cast<int>(
Clip(hue(h, m1, m2), 0.0f, 1.0f) * 255.f);
475 col.B =
static_cast<int>(
Clip(hue(h - 1.0f / 3.0f, m1, m2), 0.0f, 1.0f) * 255.f);
476 col.A =
static_cast<int>(a * 255.f);
487 result.A = start.A +
static_cast<int>(progress *
static_cast<float>(dest.A - start.A));
488 result.R = start.R +
static_cast<int>(progress *
static_cast<float>(dest.R - start.R));
489 result.G = start.G +
static_cast<int>(progress *
static_cast<float>(dest.G - start.G));
490 result.B = start.B +
static_cast<int>(progress *
static_cast<float>(dest.B - start.B));
495 const IColor COLOR_TRANSPARENT(0, 0, 0, 0);
496 const IColor COLOR_TRANSLUCENT(10, 0, 0, 0);
497 const IColor COLOR_BLACK(255, 0, 0, 0);
498 const IColor COLOR_BLACK_DROP_SHADOW(128, 0, 0, 0);
499 const IColor COLOR_GRAY(255, 127, 127, 127);
500 const IColor COLOR_LIGHT_GRAY(255, 240, 240, 240);
501 const IColor COLOR_MID_GRAY(255, 200, 200, 200);
502 const IColor COLOR_DARK_GRAY(255, 70, 70, 70);
503 const IColor COLOR_WHITE(255, 255, 255, 255);
504 const IColor COLOR_RED(255, 255, 0, 0);
505 const IColor COLOR_GREEN(255, 0, 255, 0);
506 const IColor COLOR_BLUE(255, 0, 0, 255);
507 const IColor COLOR_YELLOW(255, 255, 255, 0);
508 const IColor COLOR_ORANGE(255, 255, 127, 0);
509 const IColor COLOR_INDIGO(255, 75, 0, 130);
510 const IColor COLOR_VIOLET(255, 148, 0, 211);
512 static IColor GetRainbow(
int colorIdx)
515 case 0:
return COLOR_RED;
516 case 1:
return COLOR_ORANGE;
517 case 2:
return COLOR_YELLOW;
518 case 3:
return COLOR_GREEN;
519 case 4:
return COLOR_BLUE;
520 case 5:
return COLOR_INDIGO;
521 case 6:
return COLOR_VIOLET;
528 const IColor DEFAULT_GRAPHICS_BGCOLOR = COLOR_GRAY;
529 const IColor DEFAULT_BGCOLOR = COLOR_TRANSPARENT;
530 const IColor DEFAULT_FGCOLOR = COLOR_MID_GRAY;
531 const IColor DEFAULT_PRCOLOR = COLOR_LIGHT_GRAY;
533 const IColor DEFAULT_FRCOLOR = COLOR_DARK_GRAY;
534 const IColor DEFAULT_HLCOLOR = COLOR_TRANSLUCENT;
536 const IColor DEFAULT_X1COLOR = COLOR_BLACK;
537 const IColor DEFAULT_X2COLOR = COLOR_GREEN;
538 const IColor DEFAULT_X3COLOR = COLOR_BLUE;
540 const IColor DEFAULT_TEXT_FGCOLOR = COLOR_BLACK;
541 const IColor DEFAULT_TEXTENTRY_BGCOLOR = COLOR_WHITE;
542 const IColor DEFAULT_TEXTENTRY_FGCOLOR = COLOR_BLACK;
553 IBlend(EBlend type = EBlend::Default,
float weight = 1.0f)
555 , mWeight(
Clip(weight, 0.f, 1.f))
564 return (pBlend ? pBlend->mWeight : 1.0f);
574 const IBlend BLEND_DST_OVER =
IBlend(EBlend::DstOver, 1.f);
579 EFillRule mFillRule { EFillRule::Winding };
580 bool mPreserve {
false };
582 IFillOptions(
bool preserve =
false, EFillRule fillRule = EFillRule::Winding)
583 : mFillRule(fillRule)
584 , mPreserve(preserve)
607 DashOptions(
float* array,
float offset,
int count)
609 SetDash(array, offset, count);
613 int GetCount()
const {
return mCount; }
616 float GetOffset()
const {
return mOffset; }
619 const float* GetArray()
const {
return mArray; }
625 void SetDash(
float* pArray,
float offset,
int count)
627 assert(count >= 0 && count <= 8);
632 for (
int i = 0; i < count; i++)
633 mArray[i] = pArray[i];
637 float mArray[8] = {};
642 float mMiterLimit = 10.f;
643 bool mPreserve =
false;
644 ELineCap mCapOption = ELineCap::Butt;
645 ELineJoin mJoinOption = ELineJoin::Miter;
654 case ETextStyle::Bold:
return "Bold";
655 case ETextStyle::Italic:
return "Italic";
656 case ETextStyle::Normal:
674 IText(
float size = DEFAULT_TEXT_SIZE,
675 const IColor& color = DEFAULT_TEXT_FGCOLOR,
676 const char* fontID =
nullptr,
677 EAlign align = EAlign::Center,
678 EVAlign valign = EVAlign::Middle,
680 const IColor& TEBGColor = DEFAULT_TEXTENTRY_BGCOLOR,
681 const IColor& TEFGColor = DEFAULT_TEXTENTRY_FGCOLOR)
684 , mTextEntryBGColor(TEBGColor)
685 , mTextEntryFGColor(TEFGColor)
690 strcpy(mFont, (fontID ? fontID : DEFAULT_FONT));
697 IText(
float size, EVAlign valign,
const IColor& color = DEFAULT_TEXT_FGCOLOR)
709 IText(
float size, EAlign align,
const IColor& color = DEFAULT_TEXT_FGCOLOR)
720 IText(
float size,
const char* fontID)
724 strcpy(mFont, (fontID ? fontID : DEFAULT_FONT));
727 IText WithFGColor(
const IColor& fgColor)
const {
IText newText = *
this; newText.mFGColor = fgColor;
return newText; }
728 IText WithTEColors(
const IColor& teBgColor,
const IColor& teFgColor)
const {
IText newText = *
this; newText.mTextEntryBGColor = teBgColor; newText.mTextEntryFGColor = teFgColor;
return newText; }
729 IText WithAlign(EAlign align)
const {
IText newText = *
this; newText.mAlign = align;
return newText; }
730 IText WithVAlign(EVAlign valign)
const {
IText newText = *
this; newText.mVAlign = valign;
return newText; }
731 IText WithSize(
float size)
const {
IText newText = *
this; newText.mSize = size;
return newText; }
732 IText WithAngle(
float v)
const {
IText newText = *
this; newText.mAngle = v;
return newText; }
733 IText WithFont(
const char* fontID)
const {
IText newText = *
this; strcpy(newText.mFont, (fontID ? fontID : DEFAULT_FONT));;
return newText; }
735 char mFont[FONT_LEN];
741 EAlign mAlign = EAlign::Near;
742 EVAlign mVAlign = EVAlign::Middle;
772 IRECT(
float l,
float t,
float r,
float b)
773 : L(l), T(t), R(r), B(b)
784 R = L + (float) bitmap.
FW();
785 B = T + (float) bitmap.
FH();
796 return IRECT(l, t, l+w, t+h);
802 return (L == 0.f && T == 0.f && R == 0.f && B == 0.f);
811 bool operator==(
const IRECT& rhs)
const 813 return (L == rhs.
L && T == rhs.
T && R == rhs.
R && B == rhs.
B);
816 bool operator!=(
const IRECT& rhs)
const 818 return !(*
this == rhs);
822 inline float W()
const {
return R - L; }
825 inline float H()
const {
return B - T; }
828 inline float MW()
const {
return 0.5f * (L + R); }
831 inline float MH()
const {
return 0.5f * (T + B); }
834 inline float Area()
const {
return W() *
H(); }
842 if (Empty()) {
return rhs; }
843 if (rhs.
Empty()) {
return *
this; }
844 return IRECT(std::min(L, rhs.
L), std::min(T, rhs.
T), std::max(R, rhs.
R), std::max(B, rhs.
B));
854 return IRECT(std::max(L, rhs.
L), std::max(T, rhs.
T), std::min(R, rhs.
R), std::min(B, rhs.
B));
865 return (!Empty() && !rhs.
Empty() && R >= rhs.
L && L < rhs.
R && B >= rhs.
T && T < rhs.
B);
874 return (!Empty() && !rhs.
Empty() && rhs.
L >= L && rhs.
R <= R && rhs.
T >= T && rhs.
B <= B);
884 return (!Empty() && x >= L && x < R && y >= T && y < B);
895 return (!Empty() && x >= L && x <= R && y >= T && y <= B);
904 else if (x > R) x = R;
907 else if (y > B) y = B;
914 return IRECT(L + rhs.
L, T + rhs.
T, L + rhs.
R, T + rhs.
B);
924 if (Empty() || rhs.
Empty())
926 if (L == rhs.
L && R == rhs.
R && ((T >= rhs.
T && T <= rhs.
B) || (rhs.
T >= T && rhs.
T <= B)))
928 return T == rhs.
T && B == rhs.
B && ((L >= rhs.
L && L <= rhs.
R) || (rhs.
L >= L && rhs.
L <= R));
937 inline IRECT FracRect(EDirection layoutDir,
float frac,
bool fromTopOrRight =
false)
const 939 if(layoutDir == EDirection::Vertical)
940 return FracRectVertical(frac, fromTopOrRight);
942 return FracRectHorizontal(frac, fromTopOrRight);
951 float widthOfSubRect =
W() * frac;
954 return IRECT(R - widthOfSubRect, T, R, B);
956 return IRECT(L, T, L + widthOfSubRect, B);
965 float heightOfSubRect =
H() * frac;
968 return IRECT(L, T, R, T + heightOfSubRect);
970 return IRECT(L, B - heightOfSubRect, R, B);
982 float heightOfSubRect =
H() / (float) numSlices;
983 float t = heightOfSubRect * (float) sliceIdx;
985 return IRECT(L, T + t, R, T + t + heightOfSubRect);
997 float widthOfSubRect =
W() / (float) numSlices;
998 float l = widthOfSubRect * (float) sliceIdx;
1000 return IRECT(L + l, T, L + l + widthOfSubRect, B);
1008 inline IRECT SubRect(EDirection layoutDir,
int numSlices,
int sliceIdx)
const 1010 if(layoutDir == EDirection::Vertical)
1011 return SubRectVertical(numSlices, sliceIdx);
1013 return SubRectHorizontal(numSlices, sliceIdx);
1108 assert(row * col <= nRows * nColumns);
1110 const IRECT vrect = SubRectVertical(nRows, row);
1121 inline IRECT GetGridCell(
int cellIndex,
int nRows,
int nColumns, EDirection dir = EDirection::Horizontal,
int nCells = 1)
const 1123 assert(cellIndex <= nRows * nColumns);
1127 if(dir == EDirection::Horizontal)
1129 for(
int row = 0; row < nRows; row++)
1131 for(
int col = 0; col < nColumns; col++)
1133 if(cell == cellIndex)
1135 const IRECT vrect = SubRectVertical(nRows, row);
1138 for (
int n = 1; n < nCells && (col + n) < nColumns; n++)
1151 for(
int col = 0; col < nColumns; col++)
1153 for(
int row = 0; row < nRows; row++)
1155 if(cell == cellIndex)
1157 const IRECT hrect = SubRectHorizontal(nColumns, col);
1160 for (
int n = 1; n < nCells && (row + n) < nRows; n++)
1180 auto isInteger = [](
float x){
return std::fabs(x - std::round(x)) <=
static_cast<float>(1e-3); };
1182 return isInteger(L) && isInteger(T) && isInteger(R) && isInteger(B);
1213 Scale(static_cast<float>(1.0/static_cast<double>(scale)));
1252 Scale(static_cast<float>(1.0/static_cast<double>(scale)));
1276 inline void Pad(
float padding)
1290 inline void Pad(
float padL,
float padT,
float padR,
float padB)
1320 const float mw = MW();
1329 const float mh = MH();
1340 return IRECT(L-padding, T-padding, R+padding, B+padding);
1352 return IRECT(L-padL, T-padT, R+padR, B+padB);
1361 return IRECT(L-padding, T, R+padding, B);
1370 return IRECT(L, T-padding, R, B+padding);
1378 return IRECT(MW()-padding, T, MW()+padding, B);
1386 return IRECT(L, MH()-padding, R, MH()+padding);
1396 return IRECT(R - w, T, R, B);
1398 return IRECT(L, T, L + w, B);
1408 return IRECT(L, B - h, R, B);
1410 return IRECT(L, T, R, T + h);
1419 R = std::min(rhs.
R - 1, R + rhs.
L - L);
1424 B = std::min(rhs.
B - 1, B + rhs.
T - T);
1429 L = std::max(rhs.
L, L - (R - rhs.
R + 1));
1434 T = std::max(rhs.
T, T - (B - rhs.
B + 1));
1455 float hw =
W() / 2.f;
1456 float hh =
H() / 2.f;
1457 L = x - (hw * scale);
1458 T = y - (hh * scale);
1459 R = x + (hw * scale);
1460 B = y + (hh * scale);
1491 result.
L = start.
L + progress * (dest.
L - start.
L);
1492 result.
T = start.
T + progress * (dest.
T - start.
T);
1493 result.
R = start.
R + progress * (dest.
R - start.
R);
1494 result.
B = start.
B + progress * (dest.
B - start.
B);
1503 const float r1 =
static_cast<float>(std::rand()/(
static_cast<float>(RAND_MAX)+1.f));
1504 const float r2 =
static_cast<float>(std::rand()/(
static_cast<float>(RAND_MAX)+1.f));
1514 GetRandomPoint(l, t);
1518 return IRECT(l, t, r, b);
1526 void Offset(
float l,
float t,
float r,
float b)
1542 return IRECT(L + l, T + t, R + r, B + b);
1562 return IRECT(L + x, T + y, R + x, B + y);
1570 return GetTranslated(x, 0.f);
1578 return GetTranslated(0.f, y);
1587 r.
L = MW() - sr.
W() / 2.f;
1588 r.
T = MH() - sr.
H() / 2.f;
1601 w = std::max(w, 1.f);
1607 r.
L = MW() - w / 2.f;
1608 r.
T = MH() - h / 2.f;
1621 r.
L = MW() - bitmap.
FW() / 2.f;
1622 r.
T = MH() - bitmap.
FH() / 2.f;
1623 r.
R = r.
L + (float) bitmap.
FW();
1624 r.
B = r.
T + (float) bitmap.
FH();
1634 const float height =
H();
1637 case EVAlign::Top: T = sr.
T; B = sr.
T + height;
break;
1638 case EVAlign::Bottom: T = sr.
B - height; B = sr.
B;
break;
1639 case EVAlign::Middle: T = sr.
T + (sr.
H() * 0.5f) - (height * 0.5f); B = sr.
T + (sr.
H() * 0.5f) - (height * 0.5f) + height;
break;
1648 const float width =
W();
1651 case EAlign::Near: L = sr.
L; R = sr.
L + width;
break;
1652 case EAlign::Far: L = sr.
R - width; R = sr.
R;
break;
1653 case EAlign::Center: L = sr.
L + (sr.
W() * 0.5f) - (width * 0.5f); R = sr.
L + (sr.
W() * 0.5f) - (width * 0.5f) + width;
break;
1663 IRECT result = *
this;
1683 IRECT result = *
this;
1689 void DBGPrint() { DBGMSG(
"L: %f, T: %f, R: %f, B: %f,: W: %f, H: %f\n", L, T, R, B,
W(),
H()); }
1696 ITouchID touchID = 0;
1697 float touchRadius = 0.f;
1706 IMouseMod(
bool l =
false,
bool r =
false,
bool s =
false,
bool c =
false,
bool a =
false, ITouchID touchID = 0)
1707 : L(l), R(r), S(s), C(c), A(a), touchID(touchID)
1714 void DBGPrint() { DBGMSG(
"L: %i, R: %i, S: %i, C: %i,: A: %i\n", L, R, S, C, A); }
1731 float velocity = 0.f;
1733 EGestureState state = EGestureState::Unknown;
1734 EGestureType type = EGestureType::Unknown;
1748 int Size()
const {
return mRects.GetSize(); }
1762 *(mRects.GetFast() + idx) = rect;
1770 return *(mRects.GetFast() + idx);
1784 for (
auto i = 1; i < mRects.GetSize(); i++)
1785 r = r.
Union(Get(i));
1792 for (
auto i = 0; i < Size(); i++)
1804 for (
auto i = 0; i < Size(); i++)
1818 for (
auto i = 0; i < Size(); i++)
1820 if(Get(i).Contains(x, y))
1834 static bool GetFracGrid(
const IRECT& input,
IRECTList& rects,
const std::initializer_list<float>& rowFractions,
const std::initializer_list<float>& colFractions, EDirection layoutDir = EDirection::Horizontal)
1836 IRECT spaceLeft = input;
1840 if(std::accumulate(rowFractions.begin(), rowFractions.end(), 0.f) != 1.)
1843 if(std::accumulate(colFractions.begin(), colFractions.end(), 0.f) != 1.)
1846 if (layoutDir == EDirection::Horizontal)
1848 for (
auto& rowFrac : rowFractions)
1854 for (
auto& colFrac : colFractions)
1858 rects.
Add(thisCell);
1869 if (layoutDir == EDirection::Vertical)
1871 for (
auto& colFrac : colFractions)
1877 for (
auto& rowFrac : rowFractions)
1881 rects.
Add(thisCell);
1898 for (
int i = 0; i < Size(); i++)
1900 for (
int j = i + 1; j < Size(); j++)
1902 if (Get(i).Contains(Get(j)))
1907 else if (Get(j).Contains(Get(i)))
1913 else if (Get(i).Intersects(Get(j)))
1917 if (Get(i).Mergeable(intersection))
1918 Set(i, Shrink(Get(i), intersection));
1919 else if (Get(j).Mergeable(intersection))
1920 Set(j, Shrink(Get(j), intersection));
1921 else if (Get(i).Area() < Get(j).Area())
1922 Set(i, Split(Get(i), intersection));
1924 Set(j, Split(Get(j), intersection));
1929 for (
int i = 0; i < Size(); i++)
1931 for (
int j = i + 1; j < Size(); j++)
1933 if (Get(i).Mergeable(Get(j)))
1935 Set(j, Get(i).Union(Get(j)));
1992 WDL_TypedBuf<IRECT> mRects;
2005 IMatrix(
double xx,
double yx,
double xy,
double yy,
double tx,
double ty)
2006 : mXX(xx), mYX(yx), mXY(xy), mYY(yy), mTX(tx), mTY(ty)
2019 return Transform(
IMatrix(1.0, 0.0, 0.0, 1.0, x, y));
2028 return Transform(
IMatrix(x, 0.0, 0.0, y, 0.0, 0.0));
2036 const double rad = DegToRad(a);
2037 const double c = std::cos(rad);
2038 const double s = std::sin(rad);
2040 return Transform(
IMatrix(c, s, -s, c, 0.0, 0.0));
2049 return Transform(
IMatrix(1.0, std::tan(DegToRad(ya)), std::tan(DegToRad(xa)), 1.0, 0.0, 0.0));
2059 x = x0 * mXX + y0 * mXY + mTX;
2060 y = x0 * mYX + y0 * mYY + mTY;
2068 TransformPoint(x, y, x, y);
2077 const double sx = after.
W() / before.
W();
2078 const double sy = after.
H() / before.
H();
2079 const double tx = after.
L - before.
L * sx;
2080 const double ty = after.
T - before.
T * sy;
2082 return *
this =
IMatrix(sx, 0.0, 0.0, sy, tx, ty);
2092 mXX = m.mXX * p.mXX + m.mYX * p.mXY;
2093 mYX = m.mXX * p.mYX + m.mYX * p.mYY;
2094 mXY = m.mXY * p.mXX + m.mYY * p.mXY;
2095 mYY = m.mXY * p.mYX + m.mYY * p.mYY;
2096 mTX = m.mTX * p.mXX + m.mTY * p.mXY + p.mTX;
2097 mTY = m.mTX * p.mYX + m.mTY * p.mYY + p.mTY;
2108 double d = 1.0 / (m.mXX * m.mYY - m.mYX * m.mXY);
2114 mTX = (-(m.mTX * mXX) - (m.mTY * mXY));
2115 mTY = (-(m.mTX * mYX) - (m.mTY * mYY));
2120 double mXX, mYX, mXY, mYY, mTX, mTY;
2137 assert(offset >= 0.0 && offset <= 1.0);
2148 EPatternExtend mExtend;
2156 : mType(type), mExtend(EPatternExtend::Pad), mNStops(0)
2162 : mType(EPatternType::Solid), mExtend(EPatternExtend::Pad), mNStops(1)
2176 IPattern pattern(EPatternType::Linear);
2179 const double xd = x2 - x1;
2180 const double yd = y2 - y1;
2181 const double d = sqrt(xd * xd + yd * yd);
2182 const double a = atan2(xd, yd);
2183 const double s = std::sin(a) / d;
2184 const double c = std::cos(a) / d;
2186 const double x0 = -(x1 * c - y1 * s);
2187 const double y0 = -(x1 * s + y1 * c);
2190 static_cast<float>(s),
2191 static_cast<float>(-s),
2192 static_cast<float>(c),
2193 static_cast<float>(x0),
2194 static_cast<float>(y0));
2196 for (
auto& stop : stops)
2197 pattern.
AddStop(stop.mColor, stop.mOffset);
2209 float x1, y1, x2, y2;
2211 if(direction == EDirection::Horizontal)
2213 y1 = bounds.
MH(); y2 = y1;
2219 x1 = bounds.
MW(); x2 = x1;
2224 return CreateLinearGradient(x1, y1, x2, y2, stops);
2235 IPattern pattern(EPatternType::Radial);
2237 const float s = 1.f / r;
2239 pattern.
SetTransform(s, 0, 0, s, -(x1 * s), -(y1 * s));
2241 for (
auto& stop : stops)
2242 pattern.
AddStop(stop.mColor, stop.mOffset);
2255 float angleStart = 0.f,
float angleEnd = 360.f)
2257 IPattern pattern(EPatternType::Sweep);
2259 #ifdef IGRAPHICS_SKIA 2264 float rad = DegToRad(angleStart);
2265 float c = std::cos(rad);
2266 float s = std::sin(rad);
2270 for (
auto& stop : stops)
2272 pattern.
AddStop(stop.mColor, stop.mOffset * (angleEnd - angleStart) / 360.f);
2296 assert(mType != EPatternType::Solid && mNStops < 16);
2297 assert(!mNStops || GetStop(mNStops - 1).mOffset < offset);
2299 mStops[mNStops++] =
IColorStop(color, offset);
2309 void SetTransform(
float xx,
float yx,
float xy,
float yy,
float tx,
float ty)
2311 mTransform =
IMatrix(xx, yx, xy, yy, tx, ty);
2318 mTransform = transform;
2338 , mControl(pControl)
2339 , mControlRECT(controlRect)
2360 std::unique_ptr<APIBitmap> mBitmap;
2382 IShadow(
const IPattern& pattern,
float blurSize,
float xOffset,
float yOffset,
float opacity,
bool drawForeground =
true)
2384 , mBlurSize(blurSize)
2388 , mDrawForeground(drawForeground)
2392 float mBlurSize = 0.f;
2393 float mXOffset = 0.f;
2394 float mYOffset = 0.f;
2395 float mOpacity = 1.f;
2396 bool mDrawForeground =
true;
2402 IColor mColors[kNumVColors];
2407 return mColors[(int) color];
2415 case kBG:
return DEFAULT_BGCOLOR;
2416 case kFG:
return DEFAULT_FGCOLOR;
2417 case kPR:
return DEFAULT_PRCOLOR;
2418 case kFR:
return DEFAULT_FRCOLOR;
2419 case kHL:
return DEFAULT_HLCOLOR;
2420 case kSH:
return DEFAULT_SHCOLOR;
2421 case kX1:
return DEFAULT_X1COLOR;
2422 case kX2:
return DEFAULT_X2COLOR;
2423 case kX3:
return DEFAULT_X3COLOR;
2425 return COLOR_TRANSPARENT;
2439 assert(colors.size() <= kNumVColors);
2443 for(
auto& c : colors)
2448 for(; i<kNumVColors; i++)
2450 mColors[i] = GetDefaultColor((EVColor) i);
2457 for (
int i=0; i<kNumVColors; i++)
2459 mColors[i] = GetDefaultColor((EVColor) i);
2466 static constexpr
bool DEFAULT_HIDE_CURSOR =
true;
2467 static constexpr
bool DEFAULT_SHOW_VALUE =
true;
2468 static constexpr
bool DEFAULT_SHOW_LABEL =
true;
2469 static constexpr
bool DEFAULT_DRAW_FRAME =
true;
2470 static constexpr
bool DEFAULT_DRAW_SHADOWS =
true;
2471 static constexpr
bool DEFAULT_EMBOSS =
false;
2472 static constexpr
float DEFAULT_ROUNDNESS = 0.f;
2473 static constexpr
float DEFAULT_FRAME_THICKNESS = 1.f;
2474 static constexpr
float DEFAULT_SHADOW_OFFSET = 3.f;
2475 static constexpr
float DEFAULT_WIDGET_FRAC = 1.f;
2476 static constexpr
float DEFAULT_WIDGET_ANGLE = 0.f;
2477 const IText DEFAULT_LABEL_TEXT {DEFAULT_TEXT_SIZE + 5.f, EVAlign::Top};
2478 const IText DEFAULT_VALUE_TEXT {DEFAULT_TEXT_SIZE, EVAlign::Bottom};
2483 bool hideCursor = DEFAULT_HIDE_CURSOR;
2484 bool showLabel = DEFAULT_SHOW_LABEL;
2485 bool showValue = DEFAULT_SHOW_VALUE;
2486 bool drawFrame = DEFAULT_DRAW_FRAME;
2487 bool drawShadows = DEFAULT_DRAW_SHADOWS;
2488 bool emboss = DEFAULT_EMBOSS;
2489 float roundness = DEFAULT_ROUNDNESS;
2490 float frameThickness = DEFAULT_FRAME_THICKNESS;
2491 float shadowOffset = DEFAULT_SHADOW_OFFSET;
2492 float widgetFrac = DEFAULT_WIDGET_FRAC;
2493 float angle = DEFAULT_WIDGET_ANGLE;
2495 IText labelText = DEFAULT_LABEL_TEXT;
2496 IText valueText = DEFAULT_VALUE_TEXT;
2514 bool showValue = DEFAULT_SHOW_VALUE,
2515 const IVColorSpec& colors = {DEFAULT_BGCOLOR, DEFAULT_FGCOLOR, DEFAULT_PRCOLOR, DEFAULT_FRCOLOR, DEFAULT_HLCOLOR, DEFAULT_SHCOLOR, DEFAULT_X1COLOR, DEFAULT_X2COLOR, DEFAULT_X3COLOR},
2516 const IText& labelText = DEFAULT_LABEL_TEXT,
2517 const IText& valueText = DEFAULT_VALUE_TEXT,
2518 bool hideCursor = DEFAULT_HIDE_CURSOR,
2519 bool drawFrame = DEFAULT_DRAW_FRAME,
2520 bool drawShadows = DEFAULT_DRAW_SHADOWS,
2521 bool emboss = DEFAULT_EMBOSS,
2522 float roundness = DEFAULT_ROUNDNESS,
2523 float frameThickness = DEFAULT_FRAME_THICKNESS,
2524 float shadowOffset = DEFAULT_SHADOW_OFFSET,
2525 float widgetFrac = DEFAULT_WIDGET_FRAC,
2526 float angle = DEFAULT_WIDGET_ANGLE)
2527 : hideCursor(hideCursor)
2528 , showLabel(showLabel)
2529 , showValue(showValue)
2530 , drawFrame(drawFrame)
2531 , drawShadows(drawShadows)
2533 , roundness(roundness)
2534 , frameThickness(frameThickness)
2535 , shadowOffset(shadowOffset)
2536 , widgetFrac(widgetFrac)
2539 , labelText(labelText)
2540 , valueText(valueText)
2546 IVStyle(
const std::initializer_list<IColor>& colors)
2551 IVStyle WithShowLabel(
bool show =
true)
const {
IVStyle newStyle = *
this; newStyle.showLabel = show;
return newStyle; }
2552 IVStyle WithShowValue(
bool show =
true)
const {
IVStyle newStyle = *
this; newStyle.showValue = show;
return newStyle; }
2553 IVStyle WithLabelText(
const IText& text)
const {
IVStyle newStyle = *
this; newStyle.labelText = text;
return newStyle;}
2554 IVStyle WithValueText(
const IText& text)
const {
IVStyle newStyle = *
this; newStyle.valueText = text;
return newStyle; }
2555 IVStyle WithHideCursor(
bool hide =
true)
const {
IVStyle newStyle = *
this; newStyle.hideCursor = hide;
return newStyle; }
2556 IVStyle WithColor(EVColor idx,
IColor color)
const {
IVStyle newStyle = *
this; newStyle.colorSpec.mColors[idx] = color;
return newStyle; }
2558 IVStyle WithRoundness(
float v)
const {
IVStyle newStyle = *
this; newStyle.roundness =
Clip(v, 0.f, 1.f);
return newStyle; }
2559 IVStyle WithFrameThickness(
float v)
const {
IVStyle newStyle = *
this; newStyle.frameThickness = v;
return newStyle; }
2560 IVStyle WithShadowOffset(
float v)
const {
IVStyle newStyle = *
this; newStyle.shadowOffset = v;
return newStyle; }
2561 IVStyle WithDrawShadows(
bool v =
true)
const {
IVStyle newStyle = *
this; newStyle.drawShadows = v;
return newStyle; }
2562 IVStyle WithDrawFrame(
bool v =
true)
const {
IVStyle newStyle = *
this; newStyle.drawFrame = v;
return newStyle; }
2563 IVStyle WithWidgetFrac(
float v)
const {
IVStyle newStyle = *
this; newStyle.widgetFrac =
Clip(v, 0.f, 1.f);
return newStyle; }
2564 IVStyle WithAngle(
float v)
const {
IVStyle newStyle = *
this; newStyle.angle =
Clip(v, 0.f, 360.f);
return newStyle; }
2565 IVStyle WithEmboss(
bool v =
true)
const {
IVStyle newStyle = *
this; newStyle.emboss = v;
return newStyle; }
2570 END_IGRAPHICS_NAMESPACE
Encapsulate an xy point in one struct.
static IColor FromColorCodeStr(const char *hexStr)
Create an IColor from a color code in a CString.
static IPattern CreateSweepGradient(float x1, float y1, const std::initializer_list< IColorStop > &stops={}, float angleStart=0.f, float angleEnd=360.f)
Create a sweep gradient IPattern (SKIA only)
void Scale(float scale)
Multiply each field of this IRECT by scale.
Contains a set of 9 colors used to theme IVControls.
IRECT Inset(const IRECT &rhs) const
Offsets the input IRECT based on the parent.
IRECT GetPixelSnapped() const
bool Contains(const IRECT &rhs) const
Returns true if this IRECT completely contains rhs.
const IRECT & Get(int idx) const
Get an IRECT from the list (will crash if idx is invalid)
Utility functions and macros.
void Optimize()
Remove rects that are contained by other rects and intersections and merge any rects that can be merg...
IRECT(float x, float y, const IBitmap &bitmap)
Construct a new IRECT at the given position and with the same size as the bitmap. ...
static IColor FromColorCode(int colorCode, int A=0xFF)
Create an IColor from a color code.
IRECT SubRect(EDirection layoutDir, int numSlices, int sliceIdx) const
Get a new rectangle which is a "slice" of this rectangle.
Used to manage a list of rectangular areas and optimize them for drawing to the screen.
The lowest level base class of an IGraphics control.
Used to manage a rectangular area, independent of draw class/platform.
IRECT GetFromBLHC(float w, float h) const
Get a subrect of this IRECT expanding from the bottom-left corner.
void PixelSnap(float scale)
Pixel align a scaled version of this IRECT.
IVColorSpec(const std::initializer_list< IColor > &colors)
Create a new IVColorSpec object specifying the colors.
Used to manage composite/blend operations, independent of draw class/platform.
IRECT GetOffset(float l, float t, float r, float b) const
Get a copy of this rectangle where each field is offset by a specified amount.
User-facing bitmap abstraction that you use to manage bitmap data, independant of draw class/platform...
void VPad(float padding)
Pad this IRECT in the Y-axis N.B.
const APIBitmap * GetAPIBitmap() const
IRECT Bounds()
Get a union of all rectangles in the list.
Used to manage fill behaviour for path based drawing back ends.
IMatrix & Invert()
Changes the matrix to be the inverse of its original value.
IShadow(const IPattern &pattern, float blurSize, float xOffset, float yOffset, float opacity, bool drawForeground=true)
Create an IShadow.
IBitmap(APIBitmap *pAPIBitmap, int n, bool framesAreHorizontal, const char *name="")
IBitmap Constructor.
Used to manage mouse modifiers i.e.
void PixelAlign(float scale)
Pixel-align the IRECTs at the given scale factor then scale them back down.
IRECT GetHAlignedTo(const IRECT &sr, EAlign align) const
Get a rectangle the same dimensions as this one, horizontally aligned to the reference IRECT...
IRECT FracRectHorizontal(float frac, bool rhs=false) const
Returns a new IRECT with a width that is multiplied by frac.
IRECT GetVSliced(float h, bool bot=false) const
Get a copy of this IRECT with a new height.
float GetLengthOfShortestSide() const
void Pad(float padL, float padT, float padR, float padB)
Pad this IRECT N.B.
void EmptyClickActionFunc(IControl *pCaller)
A click action function that does nothing.
void Clank(const IRECT &rhs)
void Translate(float x, float y)
Translate this rectangle.
IRECT FracRect(EDirection layoutDir, float frac, bool fromTopOrRight=false) const
Get a new rectangle which is a fraction of this rectangle.
IRECT ReduceFromTop(float amount)
Reduce in height from the top edge by 'amount' and return the removed region.
static IColor FromRGBf(float *rgbf)
Create an IColor from a 3 float RGB array.
static IRECT MakeXYWH(float l, float t, float w, float h)
Create a new IRECT with the given position and size.
void PixelAlign()
Pixel aligns the rect in an inclusive manner (moves all points outwards)
IRECT GetFromTLHC(float w, float h) const
Get a subrect of this IRECT expanding from the top-left corner.
IBitmap GetBitmap() const
IRECT GetVPadded(float padding) const
Get a copy of this IRECT padded in the Y-axis N.B.
IColor WithContrast(float c) const
Returns a new contrasted IColor based on this one.
IMouseMod(bool l=false, bool r=false, bool s=false, bool c=false, bool a=false, ITouchID touchID=0)
Create an IMouseMod.
Used to manage color data, independent of draw class/platform.
IRECT GetTranslated(float x, float y) const
Get a translated copy of this rectangle.
bool IsPixelAligned(float scale) const
Return true if, when scaled by scale, this IRECT is pixel aligned When scaling this mutliples each va...
void GetRGBAf(float *rgbaf) const
Get the color as a 4 float array.
void HPad(float padding)
Pad this IRECT in the X-axis N.B.
Used to describe a particular gesture.
static bool GetFracGrid(const IRECT &input, IRECTList &rects, const std::initializer_list< float > &rowFractions, const std::initializer_list< float > &colFractions, EDirection layoutDir=EDirection::Horizontal)
Fill an IRECTList with divisons of an input IRECT.
IRECT FracRectVertical(float frac, bool fromTop=false) const
Returns a new IRECT with a height that is multiplied by frac.
void ResetColors()
Reset the colors to the defaults.
void DefaultClickActionFunc(IControl *pCaller)
A click action function that triggers the default animation function for DEFAULT_ANIMATION_DURATION.
IRECT ReduceFromBottom(float amount)
Reduce in height from the bottom edge by 'amount' and return the removed region.
Used to manage stroke behaviour for path based drawing back ends.
IRECT ReduceFromRight(float amount)
Reduce in width from the right edge by 'amount' and return the removed region.
User-facing SVG abstraction that you use to manage SVG data ISVG doesn't actually own the image data...
IText(float size=DEFAULT_TEXT_SIZE, const IColor &color=DEFAULT_TEXT_FGCOLOR, const char *fontID=nullptr, EAlign align=EAlign::Center, EVAlign valign=EVAlign::Middle, float angle=0, const IColor &TEBGColor=DEFAULT_TEXTENTRY_BGCOLOR, const IColor &TEFGColor=DEFAULT_TEXTENTRY_FGCOLOR)
Create a new IText with size, color, fontID ...
IRECT SubRectVertical(int numSlices, int sliceIdx) const
Returns a new IRECT which is a horizontal "slice" of this IRECT.
IRECT GetPadded(float padL, float padT, float padR, float padB) const
Get a copy of this IRECT with the values padded N.B.
void VAlignTo(const IRECT &sr, EVAlign align)
Vertically align this rect to the reference IRECT.
void GetHSLA(float &h, float &s, float &l, float &a) const
Get the Hue, Saturation and Luminance of the color.
IMatrix()
Create an identity matrix.
IRECT GetFromLeft(float amount) const
Get a subrect of this IRECT bounded in X by the left edge and 'amount'.
float R
Right side of the rectangle (X + W)
void Randomise(int alpha=255)
Randomise the color parts, with optional alpha.
IRECT GetScaled(float scale) const
Get a copy of this IRECT with all values multiplied by scale.
IPlug logging a.k.a tracing functionality.
void SetTransform(float xx, float yx, float xy, float yy, float tx, float ty)
Set the affine transform for the IPattern with values.
IRECT GetVAlignedTo(const IRECT &sr, EVAlign align) const
Get a rectangle the same dimensions as this one, vertically aligned to the reference IRECT...
static IPattern CreateRadialGradient(float x1, float y1, float r, const std::initializer_list< IColorStop > &stops={})
Create a radial gradient IPattern.
IRECT GetGridCell(int cellIndex, int nRows, int nColumns, EDirection dir=EDirection::Horizontal, int nCells=1) const
Get a subrect (by index) of this IRECT which is a cell (or union of nCells sequential cells on same r...
IBlend(EBlend type=EBlend::Default, float weight=1.0f)
Creates a new IBlend.
IRECT Intersect(const IRECT &rhs) const
Create a new IRECT that is the intersection of this IRECT and rhs.
void ShowBubbleHorizontalActionFunc(IControl *pCaller)
Use with a param-linked control to popup the bubble control horizontally.
void ShowBubbleVerticalActionFunc(IControl *pCaller)
Use with a param-linked control to popup the bubble control vertically.
bool Intersects(const IRECT &rhs) const
Returns true if this IRECT shares any common pixels with rhs, false otherwise.
IRECT GetVShifted(float y) const
Get a copy of this rectangle translated on the Y axis.
IColor WithOpacity(float alpha) const
Returns a new IColor with a different opacity.
IRECT GetMidHPadded(float padding) const
Get a copy of this IRECT where its width = 2 * padding but the center point on the X-axis has not cha...
IText is used to manage font and text/text entry style for a piece of text on the UI...
IRECT GetScaledAboutCentre(float scale) const
Get a copy of this IRECT where the width and height are multiplied by scale without changing the cent...
void Offset(float l, float t, float r, float b)
Offset each field of the rectangle.
IMatrix & Translate(float x, float y)
Set the matrix for a translation transform.
const IColor & GetColor(EVColor color) const
void DBGPrint()
Print the IRECT's detailes to the console in Debug builds.
void Clamp()
Keep the member int variables within the range 0-255.
ILayer(APIBitmap *pBitmap, const IRECT &layerRect, IControl *pControl, const IRECT &controlRect)
Create a layer/offscreen context (used internally)
IRECT GetReducedFromBottom(float amount) const
Get a subrect of this IRECT reduced in height from the bottom edge by 'amount'.
Used to group mouse coordinates with mouse modifier information.
void SetOpacity(float alpha)
Set the color's opacity/alpha component with a float.
const IColorStop & GetStop(int idx) const
Get the IColorStop at a particular index (will crash if out of bounds)
void ScaleAboutCentre(float scale)
Scale the width and height of this IRECT by scale without changing the center point.
void MidVPad(float padding)
Set the height of this IRECT to 2*padding without changing it's center point on the Y-axis...
static IRECT LinearInterpolateBetween(const IRECT &start, const IRECT &dest, float progress)
Get a rectangle that is a linear interpolation between start and dest
float GetDrawScale() const
const WDL_String & GetResourceName() const
IMatrix & Scale(float x, float y)
Set the matrix for a scale transform.
IRECT(float l, float t, float r, float b)
Construct a new IRECT with dimensions.
The lowest level base class of an IGraphics context.
float BlendWeight(const IBlend *pBlend)
Helper function to extract the blend weight value from an IBlend ptr if it is valid.
Used to specify properties of a drop-shadow to a layer.
void PixelAlign()
Align the rectangles to pixel boundaries.
void SetTransform(const IMatrix &transform)
Set the affine transform for the IPattern with an IMatrix.
IMatrix & Transform(const IRECT &before, const IRECT &after)
static IColor LinearInterpolateBetween(const IColor &start, const IColor &dest, float progress)
Helper function to linear interpolate between two IColors.
IText(float size, const char *fontID)
Create a new IText with size and fontID.
int ToColorCode() const
Convert the IColor to a single int (no alpha)
void DBGPrint()
Print the mouse modifier values to the console in Debug builds.
static const char * TextStyleString(ETextStyle style)
Helper to get a CString based on ETextStyle.
IRECT ReduceFromLeft(float amount)
Reduce in width from the left edge by 'amount' and return the removed region.
Used to represent a point/stop in a gradient.
IRECT GetPixelAligned() const
Get a copy of this IRECT with PixelAlign() called.
void Clear()
Set all fields of this IRECT to 0.
BEGIN_IPLUG_NAMESPACE T Clip(T x, T lo, T hi)
Clips the value x between lo and hi.
const IRECT & Bounds() const
void TransformPoint(double &x, double &y, double x0, double y0) const
Transforms the point x, y.
A control that can be specialised with a lambda function, for quick experiments without making a cust...
void DefaultAnimationFunc(IControl *pCaller)
An animation function that just calls the caller control's OnEndAnimation() method at the end of the ...
void Constrain(float &x, float &y) const
Ensure the point (x,y) is inside this IRECT.
void SplashAnimationFunc(IControl *pCaller)
The splash animation function is used by IVControls to animate the splash.
IRECT GetHSliced(float w, bool rhs=false) const
Get a copy of this IRECT with a new width.
void SplashClickActionFunc(IControl *pCaller)
The splash click action function is used by IVControls to start SplashAnimationFunc.
IColor(int a=255, int r=0, int g=0, int b=0)
Create an IColor.
IRECT Union(const IRECT &rhs) const
Create a new IRECT that is a union of this IRECT and rhs.
IVStyle(bool showLabel=DEFAULT_SHOW_LABEL, bool showValue=DEFAULT_SHOW_VALUE, const IVColorSpec &colors={DEFAULT_BGCOLOR, DEFAULT_FGCOLOR, DEFAULT_PRCOLOR, DEFAULT_FRCOLOR, DEFAULT_HLCOLOR, DEFAULT_SHCOLOR, DEFAULT_X1COLOR, DEFAULT_X2COLOR, DEFAULT_X3COLOR}, const IText &labelText=DEFAULT_LABEL_TEXT, const IText &valueText=DEFAULT_VALUE_TEXT, bool hideCursor=DEFAULT_HIDE_CURSOR, bool drawFrame=DEFAULT_DRAW_FRAME, bool drawShadows=DEFAULT_DRAW_SHADOWS, bool emboss=DEFAULT_EMBOSS, float roundness=DEFAULT_ROUNDNESS, float frameThickness=DEFAULT_FRAME_THICKNESS, float shadowOffset=DEFAULT_SHADOW_OFFSET, float widgetFrac=DEFAULT_WIDGET_FRAC, float angle=DEFAULT_WIDGET_ANGLE)
Create a new IVStyle to configure common styling for IVControls.
IMatrix & Skew(float xa, float ya)
Set the matrix for a skew transform.
IRECT GetFromRight(float amount) const
Get a subrect of this IRECT bounded in X by 'amount' and the right edge.
bool Mergeable(const IRECT &rhs) const
Return if this IRECT and rhs may be merged.
void Pad(float padding)
Pad this IRECT N.B.
bool Contains(float x, float y) const
Returns true if this IRECT completely contains the point (x,y).
void TransformPoint(double &x, double &y) const
Transforms the point x, y with the matrix.
void Set(int a=255, int r=0, int g=0, int b=0)
Set the color parts.
IRECT GetGridCell(int row, int col, int nRows, int nColumns) const
Get a subrect (by row, column) of this IRECT which is a cell in a grid of size (nRows * nColumns) ...
IRECT GetCentredInside(const IBitmap &bitmap) const
Get a rectangle with the same center point as this rectangle and the size of the bitmap.
A base class interface for a bitmap abstraction around the different drawing back end bitmap represen...
static IColor GetRandomColor(bool randomAlpha=false)
Get a random IColor.
float GetDrawScale() const
void Contrast(float c)
Contrast the color.
IText(float size, EVAlign valign, const IColor &color=DEFAULT_TEXT_FGCOLOR)
Create a new IText with size, vertical align, color.
static IColor FromHSLA(float h, float s, float l, float a=1.f)
Create an IColor from Hue Saturation and Luminance values.
float L
Left side of the rectangle (X)
IRECT GetPixelAligned(float scale) const
Get a copy of this IRECT with PixelAlign(scale) called.
IRECT GetFromTRHC(float w, float h) const
Get a subrect of this IRECT expanding from the top-right corner.
IRECT()
Construct an empty IRECT.
IRECT GetPixelSnapped(float scale) const
Get a copy of this IRECT with PixelSnap(scale) called.
IRECT GetHPadded(float padding) const
Get a copy of this IRECT padded in the X-axis N.B.
IRECT GetReducedFromLeft(float amount) const
Get a subrect of this IRECT reduced in width from the left edge by 'amount'.
IRECT GetCentredInside(const IRECT &sr) const
Get a rectangle the size of sr but with the same center point as this rectangle.
void Set(int idx, const IRECT &rect)
Set a specific rectangle in the list (will crash if idx is invalid)
IMatrix & Transform(const IMatrix &m)
Transform this matrix with another.
static const IColor & GetDefaultColor(EVColor idx)
void AddStop(IColor color, float offset)
Add an IColorStop to the IPattern.
IPattern(EPatternType type)
Create an IPattern.
static IPattern CreateLinearGradient(const IRECT &bounds, EDirection direction, const std::initializer_list< IColorStop > &stops={})
Create a linear gradient IPattern across a rectangular area.
void HAlignTo(const IRECT &sr, EAlign align)
Horizontally align this rect to the reference IRECT.
IRECT GetRandomSubRect() const
static IPattern CreateLinearGradient(float x1, float y1, float x2, float y2, const std::initializer_list< IColorStop > &stops={})
Create a linear gradient IPattern.
IRECT GetPadded(float padding) const
Get a copy of this IRECT with each value padded by padding N.B.
IRECT GetFromBRHC(float w, float h) const
Get a subrect of this IRECT expanding from the bottom-right corner.
IRECT GetCentredInside(float w, float h=0.f) const
Get a rectangle with the same center point as this rectangle and the given size.
void MidHPad(float padding)
Set the width of this IRECT to 2*padding without changing it's center point on the X-axis...
IVColorSpec()
Create a new IVColorSpec object with default colors.
IColorStop(IColor color, float offset)
Create an IColor stop.
void GetRGBf(float *rgbf) const
Get the color as a 3 float array.
int Find(float x, float y) const
Find the first index of the rect that contains point x, y, if it exists.
APIBitmap * GetAPIBitmap() const
IText(float size, EAlign align, const IColor &color=DEFAULT_TEXT_FGCOLOR)
Create a new IText with size, horizontal align, color.
int GetLuminosity() const
IMatrix & Rotate(float a)
Set the matrix for a rotation transform.
bool IsPixelAligned() const
void Add(const IRECT &rect)
Add a rectangle to the list.
std::unique_ptr< ILayer > ILayerPtr
ILayerPtr is a managed pointer for transferring the ownership of layers.
IPattern(const IColor &color)
Create an IPattern with a solid color fill.
void ToColorCodeStr(WDL_String &str) const
Convert the IColor to a hex string e.g.
Used to store pattern information for gradients.
IRECT GetFromBottom(float amount) const
Get a subrect of this IRECT bounded in Y by 'amount' and the bottom edge.
void Clear()
Clear the list.
IVStyle(const std::initializer_list< IColor > &colors)
Create a new IVStyle based on a list of colors, and defaults for the other elements.
static IColor FromRGBAf(float *rgbaf)
Create an IColor from a 4 float RGBA array.
IRECT GetFromTop(float amount) const
Get a subrect of this IRECT bounded in Y by the top edge and 'amount'.
Used to store transformation matrices.
bool IsTouch() const
true if this IMouseMod is linked to a touch event
IRECT SubRectHorizontal(int numSlices, int sliceIdx) const
Returns a new IRECT which is a vertical "slice" of this IRECT.
IMatrix(double xx, double yx, double xy, double yy, double tx, double ty)
Create an IMatrix, specifying the values.
bool GetFramesAreHorizontal() const
bool ContainsEdge(float x, float y) const
Returns true if the point (x,y) is either contained in this IRECT or on an edge.
void Invalidate()
Mark the layer as needing its contents redrawn.
float T
Top of the rectangle (Y)
void PixelAlign(float scale)
Pixel-align this IRECT at the given scale factor then scale it back down When scaling this mutliples ...
void PixelSnap()
Pixel aligns to nearest pixels This may make the IRECT smaller, unlike PixelAlign().
A struct encapsulating a set of properties used to configure IVControls.
IRECT GetReducedFromRight(float amount) const
Get a subrect of this IRECT reduced in width from the right edge by 'amount'.
void GetRandomPoint(float &x, float &y) const
Get a random point within this rectangle.
IRECT GetReducedFromTop(float amount) const
Get a subrect of this IRECT reduced in height from the top edge by 'amount'.
IRECT GetHShifted(float x) const
Get a copy of this rectangle translated on the X axis.
float B
Bottom of the rectangle (Y + H)
An abstraction that is used to store a temporary raster image/framebuffer.
IRECT GetMidVPadded(float padding) const
Get a copy of this IRECT where its height = 2 * padding but the center point on the Y-axis has not ch...