25#include "IPlugStructs.h"
27#include "IGraphicsPrivate.h"
28#include "IGraphicsUtilities.h"
29#include "IGraphicsConstants.h"
32BEGIN_IGRAPHICS_NAMESPACE
44using IActionFunction = std::function<void(
IControl*)>;
45using IAnimationFunction = std::function<void(
IControl*)>;
46using IControlFunction = std::function<void(
IControl*)>;
48using IKeyHandlerFunc = std::function<bool(
const IKeyPress& key,
bool isUp)>;
49using IMsgBoxCompletionHandlerFunc = std::function<void(EMsgBoxResult result)>;
50using IFileDialogCompletionHandlerFunc = std::function<void(
const WDL_String& fileName,
const WDL_String& path)>;
51using IColorPickerHandlerFunc = std::function<void(
const IColor& result)>;
53using IPopupFunction = std::function<void(
IPopupMenu* pMenu)>;
54using IDisplayTickFunc = std::function<void()>;
55using IUIAppearanceChangedFunc = std::function<void(EUIAppearance appearance)>;
56using ILiveEditEventFunc = std::function<void(
const char* eventJson)>;
57using ITouchID = uintptr_t;
80using MTLTexturePtr =
void*;
82using Milliseconds = std::chrono::duration<double, std::chrono::milliseconds::period>;
83using TimePoint = std::chrono::time_point<std::chrono::high_resolution_clock, Milliseconds>;
97 : mAPIBitmap(pAPIBitmap)
98 , mW(static_cast<int>(pAPIBitmap->GetWidth() / pAPIBitmap->
GetScale()))
99 , mH(static_cast<int>(pAPIBitmap->GetHeight() / pAPIBitmap->
GetScale()))
101 , mFramesAreHorizontal(framesAreHorizontal)
102 , mResourceName(name, static_cast<int>(strlen(name)))
107 : mAPIBitmap(nullptr)
111 , mFramesAreHorizontal(false)
116 int W()
const {
return mW; }
119 int H()
const {
return mH; }
122 int FW()
const {
return (mFramesAreHorizontal ? mW / mN : mW); }
125 int FH()
const {
return (mFramesAreHorizontal ? mH : mH / mN); }
128 int N()
const {
return mN; }
146 inline bool IsValid()
const {
return mAPIBitmap !=
nullptr; }
158 bool mFramesAreHorizontal;
160 WDL_String mResourceName;
169 ISVG(sk_sp<SkSVGDOM> svgDom)
178 return mSVGDom->containerSize().width();
185 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;
212 return mImage->height;
216 inline bool IsValid()
const {
return mImage !=
nullptr; }
218 NSVGimage* mImage =
nullptr;
232 IColor(
int a = 255,
int r = 0,
int g = 0,
int b = 0) : A(a), R(r), G(g), B(b) {}
234 bool operator==(
const IColor& rhs) {
return (rhs.A == A && rhs.R == R && rhs.G == G && rhs.B == B); }
235 bool operator!=(
const IColor& rhs) {
return !operator==(rhs); }
242 void Set(
int a = 255,
int r = 0,
int g = 0,
int b = 0) { A = a; R = r; G = g; B = b; }
245 bool Empty()
const {
return A == 0 && R == 0 && G == 0 && B == 0; }
252 void Randomise(
int alpha = 255) { A = alpha; R = std::rand() % 255; G = std::rand() % 255; B = std::rand() % 255; }
258 A =
static_cast<int>(
Clip(alpha, 0.f, 1.f) * 255.f);
275 const int mod =
static_cast<int>(c * 255.f);
276 R =
Clip(R += mod, 0, 255);
277 G =
Clip(G += mod, 0, 255);
278 B =
Clip(B += mod, 0, 255);
304 rgbaf[0] = R / 255.f;
305 rgbaf[1] = G / 255.f;
306 rgbaf[2] = B / 255.f;
307 rgbaf[3] = A / 255.f;
315 void GetHSLA(
float& h,
float& s,
float& l,
float& a)
const
317 const float fR = R / 255.f;
318 const float fG = G / 255.f;
319 const float fB = B / 255.f;
322 const float fMin = std::min(fR, std::min(fG, fB));
323 const float fMax = std::max(fR, std::max(fG, fB));
324 const float fDiff = fMax - fMin;
325 const float fSum = fMax + fMin;
329 if (fMin == fMax) { s = 0.f; h = 0.f; l /= 100.f;
return; }
330 else if (l < 50.f) { s = 100.f * fDiff / fSum; }
331 else { s = 100.f * fDiff / (2.f - fDiff); }
333 if (fMax == fR) { h = 60.f * (fG - fB) / fDiff; }
334 if (fMax == fG) { h = 60.f * (fB - fR) / fDiff + 120.f; }
335 if (fMax == fB) { h = 60.f * (fR - fG) / fDiff + 240.f; }
337 if (h < 0.f) { h = h + 360.f; }
348 int min = R < G ? (R < B ? R : B) : (G < B ? G : B);
349 int max = R > G ? (R > B ? R : B) : (G > B ? G : B);
350 return (min + max) / 2;
358 int A = randomAlpha ? std::rand() & 0xFF : 255;
359 int R = std::rand() & 0xFF;
360 int G = std::rand() & 0xFF;
361 int B = std::rand() & 0xFF;
363 return IColor(A, R, G, B);
372 int R =
static_cast<int>(rgbf[0] * 255.f);
373 int G =
static_cast<int>(rgbf[1] * 255.f);
374 int B =
static_cast<int>(rgbf[2] * 255.f);
376 return IColor(A, R, G, B);
384 int R =
static_cast<int>(rgbaf[0] * 255.f);
385 int G =
static_cast<int>(rgbaf[1] * 255.f);
386 int B =
static_cast<int>(rgbaf[2] * 255.f);
387 int A =
static_cast<int>(rgbaf[3] * 255.f);
389 return IColor(A, R, G, B);
403 int R = (colorCode >> 16) & 0xFF;
404 int G = (colorCode >> 8) & 0xFF;
405 int B = colorCode & 0xFF;
407 return IColor(A, R, G, B);
415 WDL_String str(hexStr);
417 if ((str.GetLength() == 7 || str.GetLength() == 9) && str.Get()[0] ==
'#')
421 return FromColorCode(
static_cast<int>(std::stoul(str.Get(),
nullptr, 16)));
425 assert(0 &&
"Invalid color code str, returning black");
433 return (R << 16) | (G << 8) | B;
440 str.SetFormatted(32,
"#%02x%02x%02x%02x", R, G, B, A);
442 str.SetFormatted(32,
"#%02x%02x%02x", R, G, B);
453 auto hue = [](
float h,
float m1,
float m2) {
457 return m1 + (m2 - m1) * h * 6.0f;
458 else if (h < 3.0f / 6.0f)
460 else if (h < 4.0f / 6.0f)
461 return m1 + (m2 - m1) * (2.0f / 3.0f - h) * 6.0f;
466 h = std::fmodf(h, 1.0f);
467 if (h < 0.0f) h += 1.0f;
468 s =
Clip(s, 0.0f, 1.0f);
469 l =
Clip(l, 0.0f, 1.0f);
470 float m2 = l <= 0.5f ? (l * (1 + s)) : (l + s - l * s);
471 float m1 = 2 * l - m2;
472 col.R =
static_cast<int>(
Clip(hue(h + 1.0f / 3.0f, m1, m2), 0.0f, 1.0f) * 255.f);
473 col.G =
static_cast<int>(
Clip(hue(h, m1, m2), 0.0f, 1.0f) * 255.f);
474 col.B =
static_cast<int>(
Clip(hue(h - 1.0f / 3.0f, m1, m2), 0.0f, 1.0f) * 255.f);
475 col.A =
static_cast<int>(a * 255.f);
486 result.A = start.A +
static_cast<int>(progress *
static_cast<float>(dest.A - start.A));
487 result.R = start.R +
static_cast<int>(progress *
static_cast<float>(dest.R - start.R));
488 result.G = start.G +
static_cast<int>(progress *
static_cast<float>(dest.G - start.G));
489 result.B = start.B +
static_cast<int>(progress *
static_cast<float>(dest.B - start.B));
494const IColor COLOR_TRANSPARENT(0, 0, 0, 0);
495const IColor COLOR_TRANSLUCENT(10, 0, 0, 0);
496const IColor COLOR_BLACK(255, 0, 0, 0);
497const IColor COLOR_BLACK_DROP_SHADOW(128, 0, 0, 0);
498const IColor COLOR_GRAY(255, 127, 127, 127);
499const IColor COLOR_LIGHT_GRAY(255, 240, 240, 240);
500const IColor COLOR_MID_GRAY(255, 200, 200, 200);
501const IColor COLOR_DARK_GRAY(255, 70, 70, 70);
502const IColor COLOR_WHITE(255, 255, 255, 255);
503const IColor COLOR_RED(255, 255, 0, 0);
504const IColor COLOR_GREEN(255, 0, 255, 0);
505const IColor COLOR_BLUE(255, 0, 0, 255);
506const IColor COLOR_YELLOW(255, 255, 255, 0);
507const IColor COLOR_ORANGE(255, 255, 127, 0);
508const IColor COLOR_INDIGO(255, 75, 0, 130);
509const IColor COLOR_VIOLET(255, 148, 0, 211);
511static IColor GetRainbow(
int colorIdx)
514 case 0:
return COLOR_RED;
515 case 1:
return COLOR_ORANGE;
516 case 2:
return COLOR_YELLOW;
517 case 3:
return COLOR_GREEN;
518 case 4:
return COLOR_BLUE;
519 case 5:
return COLOR_INDIGO;
520 case 6:
return COLOR_VIOLET;
527const IColor DEFAULT_GRAPHICS_BGCOLOR = COLOR_GRAY;
528const IColor DEFAULT_BGCOLOR = COLOR_TRANSPARENT;
529const IColor DEFAULT_FGCOLOR = COLOR_MID_GRAY;
530const IColor DEFAULT_PRCOLOR = COLOR_LIGHT_GRAY;
532const IColor DEFAULT_FRCOLOR = COLOR_DARK_GRAY;
533const IColor DEFAULT_HLCOLOR = COLOR_TRANSLUCENT;
535const IColor DEFAULT_X1COLOR = COLOR_BLACK;
536const IColor DEFAULT_X2COLOR = COLOR_GREEN;
537const IColor DEFAULT_X3COLOR = COLOR_BLUE;
539const IColor DEFAULT_TEXT_FGCOLOR = COLOR_BLACK;
540const IColor DEFAULT_TEXTENTRY_BGCOLOR = COLOR_WHITE;
541const IColor DEFAULT_TEXTENTRY_FGCOLOR = COLOR_BLACK;
552 IBlend(EBlend type = EBlend::Default,
float weight = 1.0f)
554 , mWeight(
Clip(weight, 0.f, 1.f))
563 return (pBlend ? pBlend->mWeight : 1.0f);
573const IBlend BLEND_DST_OVER =
IBlend(EBlend::DstOver, 1.f);
578 EFillRule mFillRule { EFillRule::Winding };
579 bool mPreserve {
false };
581 IFillOptions(
bool preserve =
false, EFillRule fillRule = EFillRule::Winding)
582 : mFillRule(fillRule)
583 , mPreserve(preserve)
606 DashOptions(
float* array,
float offset,
int count)
608 SetDash(array, offset, count);
612 int GetCount()
const {
return mCount; }
615 float GetOffset()
const {
return mOffset; }
618 const float* GetArray()
const {
return mArray; }
624 void SetDash(
float* pArray,
float offset,
int count)
626 assert(count >= 0 && count <= 8);
631 for (
int i = 0; i < count; i++)
632 mArray[i] = pArray[i];
636 float mArray[8] = {};
641 float mMiterLimit = 10.f;
642 bool mPreserve =
false;
643 ELineCap mCapOption = ELineCap::Butt;
644 ELineJoin mJoinOption = ELineJoin::Miter;
653 case ETextStyle::Bold:
return "Bold";
654 case ETextStyle::Italic:
return "Italic";
655 case ETextStyle::Normal:
673 IText(
float size = DEFAULT_TEXT_SIZE,
674 const IColor& color = DEFAULT_TEXT_FGCOLOR,
675 const char* fontID =
nullptr,
676 EAlign align = EAlign::Center,
677 EVAlign valign = EVAlign::Middle,
679 const IColor& TEBGColor = DEFAULT_TEXTENTRY_BGCOLOR,
680 const IColor& TEFGColor = DEFAULT_TEXTENTRY_FGCOLOR)
683 , mTextEntryBGColor(TEBGColor)
684 , mTextEntryFGColor(TEFGColor)
689 strcpy(mFont, (fontID ? fontID : DEFAULT_FONT));
696 IText(
float size, EVAlign valign,
const IColor& color = DEFAULT_TEXT_FGCOLOR)
708 IText(
float size, EAlign align,
const IColor& color = DEFAULT_TEXT_FGCOLOR)
719 IText(
float size,
const char* fontID)
723 strcpy(mFont, (fontID ? fontID : DEFAULT_FONT));
726 IText WithFGColor(
const IColor& fgColor)
const {
IText newText = *
this; newText.mFGColor = fgColor;
return newText; }
727 IText WithTEColors(
const IColor& teBgColor,
const IColor& teFgColor)
const {
IText newText = *
this; newText.mTextEntryBGColor = teBgColor; newText.mTextEntryFGColor = teFgColor;
return newText; }
728 IText WithAlign(EAlign align)
const {
IText newText = *
this; newText.mAlign = align;
return newText; }
729 IText WithVAlign(EVAlign valign)
const {
IText newText = *
this; newText.mVAlign = valign;
return newText; }
730 IText WithSize(
float size)
const {
IText newText = *
this; newText.mSize = size;
return newText; }
731 IText WithAngle(
float v)
const {
IText newText = *
this; newText.mAngle = v;
return newText; }
732 IText WithFont(
const char* fontID)
const {
IText newText = *
this; strcpy(newText.mFont, (fontID ? fontID : DEFAULT_FONT));;
return newText; }
734 char mFont[FONT_LEN];
740 EAlign mAlign = EAlign::Near;
741 EVAlign mVAlign = EVAlign::Middle;
764 IRECT(
float l,
float t,
float r,
float b)
765 : L(l), T(t), R(r), B(b)
776 R = L + (float) bitmap.
FW();
777 B = T + (float) bitmap.
FH();
788 return IRECT(l, t, l+w, t+h);
799 return IRECT(x-(w/2.0f), y-(h/2.0f), x+(w/2.0f), y+(h/2.0f));
805 return (L == 0.f && T == 0.f && R == 0.f && B == 0.f);
814 bool operator==(
const IRECT& rhs)
const
816 return (L == rhs.L && T == rhs.T && R == rhs.R && B == rhs.B);
819 bool operator!=(
const IRECT& rhs)
const
821 return !(*
this == rhs);
825 inline float W()
const {
return R - L; }
828 inline float H()
const {
return B - T; }
831 inline float MW()
const {
return 0.5f * (L + R); }
834 inline float MH()
const {
return 0.5f * (T + B); }
837 inline float Area()
const {
return W() *
H(); }
845 if (
Empty()) {
return rhs; }
846 if (rhs.
Empty()) {
return *
this; }
847 return IRECT(std::min(L, rhs.L), std::min(T, rhs.T), std::max(R, rhs.R), std::max(B, rhs.B));
857 return IRECT(std::max(L, rhs.L), std::max(T, rhs.T), std::min(R, rhs.R), std::min(B, rhs.B));
868 return (!
Empty() && !rhs.
Empty() && R >= rhs.L && L < rhs.R && B >= rhs.T && T < rhs.B);
877 return (!
Empty() && !rhs.
Empty() && rhs.L >= L && rhs.R <= R && rhs.T >= T && rhs.B <= B);
887 return (!
Empty() && x >= L && x < R && y >= T && y < B);
898 return (!
Empty() && x >= L && x <= R && y >= T && y <= B);
907 else if (x > R) x = R;
910 else if (y > B) y = B;
917 return IRECT(L + rhs.L, T + rhs.T, L + rhs.R, T + rhs.B);
929 if (L == rhs.L && R == rhs.R && ((T >= rhs.T && T <= rhs.B) || (rhs.T >= T && rhs.T <= B)))
931 return T == rhs.T && B == rhs.B && ((L >= rhs.L && L <= rhs.R) || (rhs.L >= L && rhs.L <= R));
940 inline IRECT FracRect(EDirection layoutDir,
float frac,
bool fromTopOrRight =
false)
const
942 if(layoutDir == EDirection::Vertical)
954 float widthOfSubRect =
W() * frac;
957 return IRECT(R - widthOfSubRect, T, R, B);
959 return IRECT(L, T, L + widthOfSubRect, B);
968 float heightOfSubRect =
H() * frac;
971 return IRECT(L, T, R, T + heightOfSubRect);
973 return IRECT(L, B - heightOfSubRect, R, B);
985 float heightOfSubRect =
H() / (float) numSlices;
986 float t = heightOfSubRect * (float) sliceIdx;
988 return IRECT(L, T + t, R, T + t + heightOfSubRect);
1000 float widthOfSubRect =
W() / (float) numSlices;
1001 float l = widthOfSubRect * (float) sliceIdx;
1003 return IRECT(L + l, T, L + l + widthOfSubRect, B);
1011 inline IRECT SubRect(EDirection layoutDir,
int numSlices,
int sliceIdx)
const
1013 if(layoutDir == EDirection::Vertical)
1111 assert(row * col <= nRows * nColumns);
1124 inline IRECT GetGridCell(
int cellIndex,
int nRows,
int nColumns, EDirection dir = EDirection::Horizontal,
int nCells = 1)
const
1126 assert(cellIndex <= nRows * nColumns);
1130 if(dir == EDirection::Horizontal)
1132 for(
int row = 0; row < nRows; row++)
1134 for(
int col = 0; col < nColumns; col++)
1136 if(cell == cellIndex)
1141 for (
int n = 1; n < nCells && (col + n) < nColumns; n++)
1154 for(
int col = 0; col < nColumns; col++)
1156 for(
int row = 0; row < nRows; row++)
1158 if(cell == cellIndex)
1163 for (
int n = 1; n < nCells && (row + n) < nRows; n++)
1183 auto isInteger = [](
float x){
return std::fabs(x - std::round(x)) <=
static_cast<float>(1e-3); };
1185 return isInteger(L) && isInteger(T) && isInteger(R) && isInteger(B);
1216 Scale(
static_cast<float>(1.0/
static_cast<double>(scale)));
1255 Scale(
static_cast<float>(1.0/
static_cast<double>(scale)));
1279 inline void Pad(
float padding)
1293 inline void Pad(
float padL,
float padT,
float padR,
float padB)
1323 const float mw =
MW();
1332 const float mh =
MH();
1343 return IRECT(L-padding, T-padding, R+padding, B+padding);
1355 return IRECT(L-padL, T-padT, R+padR, B+padB);
1364 return IRECT(L-padding, T, R+padding, B);
1373 return IRECT(L, T-padding, R, B+padding);
1381 return IRECT(
MW()-padding, T,
MW()+padding, B);
1389 return IRECT(L,
MH()-padding, R,
MH()+padding);
1399 return IRECT(R - w, T, R, B);
1401 return IRECT(L, T, L + w, B);
1411 return IRECT(L, B - h, R, B);
1413 return IRECT(L, T, R, T + h);
1422 R = std::min(rhs.R - 1, R + rhs.L - L);
1427 B = std::min(rhs.B - 1, B + rhs.T - T);
1432 L = std::max(rhs.L, L - (R - rhs.R + 1));
1437 T = std::max(rhs.T, T - (B - rhs.B + 1));
1458 float hw =
W() / 2.f;
1459 float hh =
H() / 2.f;
1460 L = x - (hw * scale);
1461 T = y - (hh * scale);
1462 R = x + (hw * scale);
1463 B = y + (hh * scale);
1494 result.L = start.L + progress * (dest.L - start.L);
1495 result.T = start.T + progress * (dest.T - start.T);
1496 result.R = start.R + progress * (dest.R - start.R);
1497 result.B = start.B + progress * (dest.B - start.B);
1506 const float r1 =
static_cast<float>(std::rand()/(
static_cast<float>(RAND_MAX)+1.f));
1507 const float r2 =
static_cast<float>(std::rand()/(
static_cast<float>(RAND_MAX)+1.f));
1521 return IRECT(l, t, r, b);
1529 void Offset(
float l,
float t,
float r,
float b)
1545 return IRECT(L + l, T + t, R + r, B + b);
1565 return IRECT(L + x, T + y, R + x, B + y);
1590 r.L =
MW() - sr.
W() / 2.f;
1591 r.T =
MH() - sr.
H() / 2.f;
1604 w = std::max(w, 1.f);
1610 r.L =
MW() - w / 2.f;
1611 r.T =
MH() - h / 2.f;
1624 r.L =
MW() - bitmap.
FW() / 2.f;
1625 r.T =
MH() - bitmap.
FH() / 2.f;
1626 r.R = r.L + (float) bitmap.
FW();
1627 r.B = r.T + (float) bitmap.
FH();
1637 const float height =
H();
1640 case EVAlign::Top: T = sr.T; B = sr.T + height;
break;
1641 case EVAlign::Bottom: T = sr.B - height; B = sr.B;
break;
1642 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;
1651 const float width =
W();
1654 case EAlign::Near: L = sr.L; R = sr.L + width;
break;
1655 case EAlign::Far: L = sr.R - width; R = sr.R;
break;
1656 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;
1666 IRECT result = *
this;
1686 IRECT result = *
this;
1692 void DBGPrint() { DBGMSG(
"L: %f, T: %f, R: %f, B: %f,: W: %f, H: %f\n", L, T, R, B,
W(),
H()); }
1699 ITouchID touchID = 0;
1700 float touchRadius = 0.f;
1709 IMouseMod(
bool l =
false,
bool r =
false,
bool s =
false,
bool c =
false,
bool a =
false, ITouchID touchID = 0)
1710 : L(l), R(r), S(s), C(c), A(a), touchID(touchID)
1717 void DBGPrint() { DBGMSG(
"L: %i, R: %i, S: %i, C: %i,: A: %i\n", L, R, S, C, A); }
1723 float x = 0.0, y = 0.0;
1724 float dX = 0.0, dY = 0.0;
1734 float velocity = 0.f;
1736 EGestureState state = EGestureState::Unknown;
1737 EGestureType type = EGestureType::Unknown;
1751 int Size()
const {
return mRects.GetSize(); }
1765 *(mRects.GetFast() + idx) = rect;
1773 return *(mRects.GetFast() + idx);
1787 for (
auto i = 1; i < mRects.GetSize(); i++)
1795 for (
auto i = 0; i <
Size(); i++)
1807 for (
auto i = 0; i <
Size(); i++)
1821 for (
auto i = 0; i <
Size(); i++)
1837 static bool GetFracGrid(
const IRECT& input,
IRECTList& rects,
const std::initializer_list<float>& rowFractions,
const std::initializer_list<float>& colFractions, EDirection layoutDir = EDirection::Horizontal)
1839 IRECT spaceLeft = input;
1843 if(std::accumulate(rowFractions.begin(), rowFractions.end(), 0.f) != 1.)
1846 if(std::accumulate(colFractions.begin(), colFractions.end(), 0.f) != 1.)
1849 if (layoutDir == EDirection::Horizontal)
1851 for (
auto& rowFrac : rowFractions)
1857 for (
auto& colFrac : colFractions)
1861 rects.
Add(thisCell);
1872 if (layoutDir == EDirection::Vertical)
1874 for (
auto& colFrac : colFractions)
1880 for (
auto& rowFrac : rowFractions)
1884 rects.
Add(thisCell);
1901 for (
int i = 0; i <
Size(); i++)
1903 for (
int j = i + 1; j <
Size(); j++)
1920 if (
Get(i).Mergeable(intersection))
1921 Set(i, Shrink(
Get(i), intersection));
1922 else if (
Get(j).Mergeable(intersection))
1923 Set(j, Shrink(
Get(j), intersection));
1924 else if (
Get(i).Area() <
Get(j).Area())
1925 Set(i, Split(
Get(i), intersection));
1927 Set(j, Split(
Get(j), intersection));
1932 for (
int i = 0; i <
Size(); i++)
1934 for (
int j = i + 1; j <
Size(); j++)
1955 return IRECT(r.L, r.T, i.L, r.B);
1957 return IRECT(r.L, r.T, r.R, i.T);
1959 return IRECT(i.R, r.T, r.R, r.B);
1960 return IRECT(r.L, i.B, r.R, r.B);
1974 return IRECT(r.L, i.B, r.R, r.B);
1979 return IRECT(i.R, i.T, r.R, r.B);
1986 return IRECT(r.L, i.B, r.R, r.B);
1991 return IRECT(r.L, i.T, i.L, r.B);
1995 WDL_TypedBuf<IRECT> mRects;
2008 IMatrix(
double xx,
double yx,
double xy,
double yy,
double tx,
double ty)
2009 : mXX(xx), mYX(yx), mXY(xy), mYY(yy), mTX(tx), mTY(ty)
2039 const double rad = DegToRad(a);
2040 const double c = std::cos(rad);
2041 const double s = std::sin(rad);
2052 return Transform(
IMatrix(1.0, std::tan(DegToRad(ya)), std::tan(DegToRad(xa)), 1.0, 0.0, 0.0));
2062 x = x0 * mXX + y0 * mXY + mTX;
2063 y = x0 * mYX + y0 * mYY + mTY;
2080 const double sx = after.
W() / before.
W();
2081 const double sy = after.
H() / before.
H();
2082 const double tx = after.L - before.L * sx;
2083 const double ty = after.T - before.T * sy;
2085 return *
this =
IMatrix(sx, 0.0, 0.0, sy, tx, ty);
2095 mXX = m.mXX * p.mXX + m.mYX * p.mXY;
2096 mYX = m.mXX * p.mYX + m.mYX * p.mYY;
2097 mXY = m.mXY * p.mXX + m.mYY * p.mXY;
2098 mYY = m.mXY * p.mYX + m.mYY * p.mYY;
2099 mTX = m.mTX * p.mXX + m.mTY * p.mXY + p.mTX;
2100 mTY = m.mTX * p.mYX + m.mTY * p.mYY + p.mTY;
2111 double d = 1.0 / (m.mXX * m.mYY - m.mYX * m.mXY);
2117 mTX = (-(m.mTX * mXX) - (m.mTY * mXY));
2118 mTY = (-(m.mTX * mYX) - (m.mTY * mYY));
2123 double mXX, mYX, mXY, mYY, mTX, mTY;
2140 assert(offset >= 0.0 && offset <= 1.0);
2151 EPatternExtend mExtend;
2159 : mType(type), mExtend(EPatternExtend::Pad), mNStops(0)
2165 : mType(EPatternType::Solid), mExtend(EPatternExtend::Pad), mNStops(1)
2179 IPattern pattern(EPatternType::Linear);
2182 const double xd = double(x2 - x1);
2183 const double yd = double(y2 - y1);
2184 const double d = sqrt(xd * xd + yd * yd);
2185 const double a = atan2(xd, yd);
2186 const double s = std::sin(a) / d;
2187 const double c = std::cos(a) / d;
2189 const double x0 = -(x1 * c - y1 * s);
2190 const double y0 = -(x1 * s + y1 * c);
2192 pattern.SetTransform(
static_cast<float>(c),
2193 static_cast<float>(s),
2194 static_cast<float>(-s),
2195 static_cast<float>(c),
2196 static_cast<float>(x0),
2197 static_cast<float>(y0));
2199 for (
auto& stop : stops)
2200 pattern.AddStop(stop.mColor, stop.mOffset);
2212 float x1, y1, x2, y2;
2214 if(direction == EDirection::Horizontal)
2216 y1 = bounds.
MH(); y2 = y1;
2222 x1 = bounds.
MW(); x2 = x1;
2238 IPattern pattern(EPatternType::Radial);
2240 const float s = 1.f / r;
2242 pattern.SetTransform(s, 0, 0, s, -(x1 * s), -(y1 * s));
2244 for (
auto& stop : stops)
2245 pattern.AddStop(stop.mColor, stop.mOffset);
2258 float angleStart = 0.f,
float angleEnd = 360.f)
2260 IPattern pattern(EPatternType::Sweep);
2262 #ifdef IGRAPHICS_SKIA
2267 float rad = DegToRad(angleStart);
2268 float c = std::cos(rad);
2269 float s = std::sin(rad);
2271 pattern.SetTransform(c, s, -s, c, -x1, -y1);
2273 for (
auto& stop : stops)
2275 pattern.AddStop(stop.mColor, stop.mOffset * (angleEnd - angleStart) / 360.f);
2299 assert(mType != EPatternType::Solid && mNStops < 16);
2300 assert(!mNStops ||
GetStop(mNStops - 1).mOffset < offset);
2302 mStops[mNStops++] =
IColorStop(color, offset);
2312 void SetTransform(
float xx,
float yx,
float xy,
float yy,
float tx,
float ty)
2314 mTransform =
IMatrix(xx, yx, xy, yy, tx, ty);
2321 mTransform = transform;
2341 , mControl(pControl)
2342 , mControlRECT(controlRect)
2363 std::unique_ptr<APIBitmap> mBitmap;
2385 IShadow(
const IPattern& pattern,
float blurSize,
float xOffset,
float yOffset,
float opacity,
bool drawForeground =
true)
2387 , mBlurSize(blurSize)
2391 , mDrawForeground(drawForeground)
2395 float mBlurSize = 0.f;
2396 float mXOffset = 0.f;
2397 float mYOffset = 0.f;
2398 float mOpacity = 1.f;
2399 bool mDrawForeground =
true;
2405 IColor mColors[kNumVColors];
2410 return mColors[(int) color];
2418 case kBG:
return DEFAULT_BGCOLOR;
2419 case kFG:
return DEFAULT_FGCOLOR;
2420 case kPR:
return DEFAULT_PRCOLOR;
2421 case kFR:
return DEFAULT_FRCOLOR;
2422 case kHL:
return DEFAULT_HLCOLOR;
2423 case kSH:
return DEFAULT_SHCOLOR;
2424 case kX1:
return DEFAULT_X1COLOR;
2425 case kX2:
return DEFAULT_X2COLOR;
2426 case kX3:
return DEFAULT_X3COLOR;
2428 return COLOR_TRANSPARENT;
2442 assert(colors.size() <= kNumVColors);
2446 for(
auto& c : colors)
2451 for(; i<kNumVColors; i++)
2460 for (
int i=0; i<kNumVColors; i++)
2469static constexpr bool DEFAULT_HIDE_CURSOR =
true;
2470static constexpr bool DEFAULT_SHOW_VALUE =
true;
2471static constexpr bool DEFAULT_SHOW_LABEL =
true;
2472static constexpr bool DEFAULT_DRAW_FRAME =
true;
2473static constexpr bool DEFAULT_DRAW_SHADOWS =
true;
2474static constexpr bool DEFAULT_EMBOSS =
false;
2475static constexpr float DEFAULT_ROUNDNESS = 0.f;
2476static constexpr float DEFAULT_FRAME_THICKNESS = 1.f;
2477static constexpr float DEFAULT_SHADOW_OFFSET = 3.f;
2478static constexpr float DEFAULT_WIDGET_FRAC = 1.f;
2479static constexpr float DEFAULT_WIDGET_ANGLE = 0.f;
2480static constexpr EOrientation DEFAULT_LABEL_ORIENTATION = EOrientation::North;
2481const IText DEFAULT_LABEL_TEXT {DEFAULT_TEXT_SIZE + 5.f, EVAlign::Top};
2482const IText DEFAULT_VALUE_TEXT {DEFAULT_TEXT_SIZE, EVAlign::Bottom};
2487 bool hideCursor = DEFAULT_HIDE_CURSOR;
2488 bool showLabel = DEFAULT_SHOW_LABEL;
2489 bool showValue = DEFAULT_SHOW_VALUE;
2490 bool drawFrame = DEFAULT_DRAW_FRAME;
2491 bool drawShadows = DEFAULT_DRAW_SHADOWS;
2492 bool emboss = DEFAULT_EMBOSS;
2493 float roundness = DEFAULT_ROUNDNESS;
2494 float frameThickness = DEFAULT_FRAME_THICKNESS;
2495 float shadowOffset = DEFAULT_SHADOW_OFFSET;
2496 float widgetFrac = DEFAULT_WIDGET_FRAC;
2497 float angle = DEFAULT_WIDGET_ANGLE;
2499 IText labelText = DEFAULT_LABEL_TEXT;
2500 IText valueText = DEFAULT_VALUE_TEXT;
2501 EOrientation labelOrientation = DEFAULT_LABEL_ORIENTATION;
2519 bool showValue = DEFAULT_SHOW_VALUE,
2520 const IVColorSpec& colors = {DEFAULT_BGCOLOR, DEFAULT_FGCOLOR, DEFAULT_PRCOLOR, DEFAULT_FRCOLOR, DEFAULT_HLCOLOR, DEFAULT_SHCOLOR, DEFAULT_X1COLOR, DEFAULT_X2COLOR, DEFAULT_X3COLOR},
2521 const IText& labelText = DEFAULT_LABEL_TEXT,
2522 const IText& valueText = DEFAULT_VALUE_TEXT,
2523 bool hideCursor = DEFAULT_HIDE_CURSOR,
2524 bool drawFrame = DEFAULT_DRAW_FRAME,
2525 bool drawShadows = DEFAULT_DRAW_SHADOWS,
2526 bool emboss = DEFAULT_EMBOSS,
2527 float roundness = DEFAULT_ROUNDNESS,
2528 float frameThickness = DEFAULT_FRAME_THICKNESS,
2529 float shadowOffset = DEFAULT_SHADOW_OFFSET,
2530 float widgetFrac = DEFAULT_WIDGET_FRAC,
2531 float angle = DEFAULT_WIDGET_ANGLE,
2532 EOrientation labelOrientation = DEFAULT_LABEL_ORIENTATION)
2533 : hideCursor(hideCursor)
2534 , showLabel(showLabel)
2535 , showValue(showValue)
2536 , drawFrame(drawFrame)
2537 , drawShadows(drawShadows)
2539 , roundness(roundness)
2540 , frameThickness(frameThickness)
2541 , shadowOffset(shadowOffset)
2542 , widgetFrac(widgetFrac)
2545 , labelText(labelText)
2546 , valueText(valueText)
2552 IVStyle(
const std::initializer_list<IColor>& colors)
2557 IVStyle WithShowLabel(
bool show =
true)
const {
IVStyle newStyle = *
this; newStyle.showLabel = show;
return newStyle; }
2558 IVStyle WithShowValue(
bool show =
true)
const {
IVStyle newStyle = *
this; newStyle.showValue = show;
return newStyle; }
2559 IVStyle WithLabelText(
const IText& text)
const {
IVStyle newStyle = *
this; newStyle.labelText = text;
return newStyle;}
2560 IVStyle WithValueText(
const IText& text)
const {
IVStyle newStyle = *
this; newStyle.valueText = text;
return newStyle; }
2561 IVStyle WithHideCursor(
bool hide =
true)
const {
IVStyle newStyle = *
this; newStyle.hideCursor = hide;
return newStyle; }
2562 IVStyle WithColor(EVColor idx,
IColor color)
const {
IVStyle newStyle = *
this; newStyle.colorSpec.mColors[idx] = color;
return newStyle; }
2563 IVStyle WithColors(
const IVColorSpec& spec)
const {
IVStyle newStyle = *
this; newStyle.colorSpec = spec;
return newStyle; }
2564 IVStyle WithRoundness(
float v)
const {
IVStyle newStyle = *
this; newStyle.roundness =
Clip(v, 0.f, 1.f);
return newStyle; }
2565 IVStyle WithFrameThickness(
float v)
const {
IVStyle newStyle = *
this; newStyle.frameThickness = v;
return newStyle; }
2566 IVStyle WithShadowOffset(
float v)
const {
IVStyle newStyle = *
this; newStyle.shadowOffset = v;
return newStyle; }
2567 IVStyle WithDrawShadows(
bool v =
true)
const {
IVStyle newStyle = *
this; newStyle.drawShadows = v;
return newStyle; }
2568 IVStyle WithDrawFrame(
bool v =
true)
const {
IVStyle newStyle = *
this; newStyle.drawFrame = v;
return newStyle; }
2569 IVStyle WithWidgetFrac(
float v)
const {
IVStyle newStyle = *
this; newStyle.widgetFrac =
Clip(v, 0.f, 1.f);
return newStyle; }
2570 IVStyle WithAngle(
float v)
const {
IVStyle newStyle = *
this; newStyle.angle =
Clip(v, 0.f, 360.f);
return newStyle; }
2571 IVStyle WithEmboss(
bool v =
true)
const {
IVStyle newStyle = *
this; newStyle.emboss = v;
return newStyle; }
2572 IVStyle WithLabelOrientation(EOrientation v)
const {
IVStyle newStyle = *
this; newStyle.labelOrientation = v;
return newStyle; }
2577END_IGRAPHICS_NAMESPACE
IPlug logging a.k.a tracing functionality.
Utility functions and macros.
A base class interface for a bitmap abstraction around the different drawing back end bitmap represen...
float GetDrawScale() const
User-facing bitmap abstraction that you use to manage bitmap data, independant of draw class/platform...
bool GetFramesAreHorizontal() const
const WDL_String & GetResourceName() const
float GetDrawScale() const
APIBitmap * GetAPIBitmap() const
IBitmap(APIBitmap *pAPIBitmap, int n, bool framesAreHorizontal, const char *name="")
IBitmap Constructor.
The lowest level base class of an IGraphics control.
The lowest level base class of an IGraphics context.
A control that can be specialised with a lambda function, for quick experiments without making a cust...
An abstraction that is used to store a temporary raster image/framebuffer.
const APIBitmap * GetAPIBitmap() const
ILayer(APIBitmap *pBitmap, const IRECT &layerRect, IControl *pControl, const IRECT &controlRect)
Create a layer/offscreen context (used internally)
const IRECT & Bounds() const
void Invalidate()
Mark the layer as needing its contents redrawn
IBitmap GetBitmap() const
Used to manage a list of rectangular areas and optimize them for drawing to the screen.
void Clear()
Clear the list.
void Set(int idx, const IRECT &rect)
Set a specific rectangle in the list (will crash if idx is invalid)
IRECT Bounds()
Get a union of all rectangles in the list.
void Add(const IRECT &rect)
Add a rectangle to the list.
void PixelAlign(float scale)
Pixel-align the IRECTs at the given scale factor then scale them back down.
void PixelAlign()
Align the rectangles to pixel boundaries.
void Optimize()
Remove rects that are contained by other rects and intersections and merge any rects that can be merg...
int Find(float x, float y) const
Find the first index of the rect that contains point x, y, if it exists.
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.
const IRECT & Get(int idx) const
Get an IRECT from the list (will crash if idx is invalid)
void DefaultAnimationFunc(IControl *pCaller)
An animation function that just calls the caller control's OnEndAnimation() method at the end of the ...
void EmptyClickActionFunc(IControl *pCaller)
A click action function that does nothing.
static const char * TextStyleString(ETextStyle style)
Helper to get a CString based on ETextStyle.
void DefaultClickActionFunc(IControl *pCaller)
A click action function that triggers the default animation function for DEFAULT_ANIMATION_DURATION.
void SplashClickActionFunc(IControl *pCaller)
The splash click action function is used by IVControls to start SplashAnimationFunc.
void SplashAnimationFunc(IControl *pCaller)
The splash animation function is used by IVControls to animate the splash.
std::unique_ptr< ILayer > ILayerPtr
ILayerPtr is a managed pointer for transferring the ownership of layers.
float BlendWeight(const IBlend *pBlend)
Helper function to extract the blend weight value from an IBlend ptr if it is valid.
void ShowBubbleVerticalActionFunc(IControl *pCaller)
Use with a param-linked control to popup the bubble control vertically.
void ShowBubbleHorizontalActionFunc(IControl *pCaller)
Use with a param-linked control to popup the bubble control horizontally.
Used to describe a particular gesture.
Used to group mouse coordinates with mouse modifier information.
Used to manage stroke behaviour for path based drawing back ends.
BEGIN_IPLUG_NAMESPACE T Clip(T x, T lo, T hi)
Clips the value x between lo and hi.
Used to manage composite/blend operations, independent of draw class/platform.
IBlend(EBlend type=EBlend::Default, float weight=1.0f)
Creates a new IBlend.
Used to manage color data, independent of draw class/platform.
IColor(int a=255, int r=0, int g=0, int b=0)
Create an IColor from ARGB values.
void SetOpacity(float alpha)
Set the color's opacity/alpha component with a float.
static IColor FromColorCode(int colorCode, int A=0xFF)
Create an IColor from a color code.
static IColor FromRGBAf(float *rgbaf)
Create an IColor from a 4 float RGBA array.
void GetRGBAf(float *rgbaf) const
Get the color as a 4 float array.
void Set(int a=255, int r=0, int g=0, int b=0)
Set the color parts.
IColor WithContrast(float c) const
Returns a new contrasted IColor based on this one.
void Randomise(int alpha=255)
Randomise the color parts, with optional alpha.
static IColor FromHSLA(float h, float s, float l, float a=1.f)
Create an IColor from Hue Saturation and Luminance values.
void GetRGBf(float *rgbf) const
Get the color as a 3 float array.
int ToColorCode() const
Convert the IColor to a single int (no alpha)
IColor WithOpacity(float alpha) const
Returns a new IColor with a different opacity.
int GetLuminosity() const
Gets the lightness of the color (HSL lightness component)
static IColor FromColorCodeStr(const char *hexStr)
Create an IColor from a color code in a CString.
static IColor FromRGBf(float *rgbf)
Create an IColor from a 3 float RGB array.
static IColor LinearInterpolateBetween(const IColor &start, const IColor &dest, float progress)
Helper function to linear interpolate between two IColors.
void GetHSLA(float &h, float &s, float &l, float &a) const
Get the Hue, Saturation and Luminance of the color.
void Contrast(float c)
Contrast the color.
void ToColorCodeStr(WDL_String &str, bool withAlpha=true) const
Convert the IColor to a hex string e.g.
static IColor GetRandomColor(bool randomAlpha=false)
Get a random IColor.
void Clamp()
Keep the member int variables within the range 0-255.
Used to represent a point/stop in a gradient.
IColorStop(IColor color, float offset)
Create an IColor stop.
Used to manage fill behaviour.
Used for key press info, such as ASCII representation, virtual key (mapped to win32 codes) and modifi...
Used to store transformation matrices.
IMatrix(double xx, double yx, double xy, double yy, double tx, double ty)
Create an IMatrix, specifying the values.
IMatrix & Rotate(float a)
Set the matrix for a rotation transform.
IMatrix & Scale(float x, float y)
Set the matrix for a scale transform.
IMatrix()
Create an identity matrix.
IMatrix & Transform(const IMatrix &m)
Transform this matrix with another.
IMatrix & Invert()
Changes the matrix to be the inverse of its original value.
void TransformPoint(double &x, double &y) const
Transforms the point x, y with the matrix.
IMatrix & Transform(const IRECT &before, const IRECT &after)
Sets up a transformation matrix to map one rectangle to another.
IMatrix & Translate(float x, float y)
Set the matrix for a translation transform.
IMatrix & Skew(float xa, float ya)
Set the matrix for a skew transform.
void TransformPoint(double &x, double &y, double x0, double y0) const
Transforms a point using this matrix.
Used to manage mouse modifiers i.e.
bool IsTouch() const
true if this IMouseMod is linked to a touch event
IMouseMod(bool l=false, bool r=false, bool s=false, bool c=false, bool a=false, ITouchID touchID=0)
Create an IMouseMod.
void DBGPrint()
Print the mouse modifier values to the console in Debug builds.
Used to store pattern information for gradients.
const IColorStop & GetStop(int idx) const
Get the IColorStop at a particular index (will crash if out of bounds)
IPattern(const IColor &color)
Create an IPattern with a solid color fill.
void AddStop(IColor color, float offset)
Add an IColorStop to the IPattern.
static IPattern CreateLinearGradient(float x1, float y1, float x2, float y2, const std::initializer_list< IColorStop > &stops={})
Create a linear gradient IPattern.
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)
static IPattern CreateLinearGradient(const IRECT &bounds, EDirection direction, const std::initializer_list< IColorStop > &stops={})
Create a linear gradient IPattern across a rectangular area.
static IPattern CreateRadialGradient(float x1, float y1, float r, const std::initializer_list< IColorStop > &stops={})
Create a radial gradient IPattern.
void SetTransform(float xx, float yx, float xy, float yy, float tx, float ty)
Set the affine transform for the IPattern with values.
IPattern(EPatternType type)
Create an IPattern.
void SetTransform(const IMatrix &transform)
Set the affine transform for the IPattern with an IMatrix.
Used to manage a rectangular area, independent of draw class/platform.
IRECT ReduceFromRight(float amount)
Reduce in width from the right edge by 'amount' and return the removed region.
IRECT GetCentredInside(const IBitmap &bitmap) const
Get a rectangle with the same center point as this rectangle and the size of the bitmap.
IRECT GetReducedFromTop(float amount) const
Get a subrect of this IRECT reduced in height from the top edge by 'amount'.
IRECT GetFromTRHC(float w, float h) const
Get a subrect of this IRECT expanding from the top-right corner.
void VPad(float padding)
Pad this IRECT in the Y-axis N.B.
void MidHPad(float padding)
Set the width of this IRECT to 2*padding without changing it's center point on the X-axis.
IRECT GetReducedFromLeft(float amount) const
Get a subrect of this IRECT reduced in width from the left edge by 'amount'.
void Clear()
Set all fields of this IRECT to 0.
IRECT GetReducedFromRight(float amount) const
Get a subrect of this IRECT reduced in width from the right edge by 'amount'.
IRECT ReduceFromLeft(float amount)
Reduce in width from the left edge by 'amount' and return the removed region.
IRECT GetCentredInside(float w, float h=0.f) const
Get a rectangle with the same center point as this rectangle and the given size.
IRECT(float l, float t, float r, float b)
Construct a new IRECT with dimensions.
bool Contains(float x, float y) const
Returns true if this IRECT completely contains the point (x,y).
IRECT Intersect(const IRECT &rhs) const
Create a new IRECT that is the intersection of this IRECT and rhs.
void Pad(float padding)
Pad this IRECT N.B.
IRECT GetFromTLHC(float w, float h) const
Get a subrect of this IRECT expanding from the top-left corner.
IRECT GetFromRight(float amount) const
Get a subrect of this IRECT bounded in X by 'amount' and the right edge.
IRECT GetFromBottom(float amount) const
Get a subrect of this IRECT bounded in Y by 'amount' and the bottom edge.
IRECT GetCentredInside(const IRECT &sr) const
Get a rectangle the size of sr but with the same center point as this rectangle.
bool IsPixelAligned() const
IRECT GetPixelAligned() const
Get a copy of this IRECT with PixelAlign() called.
IRECT Inset(const IRECT &rhs) const
Offsets the input IRECT based on the parent.
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)
bool Mergeable(const IRECT &rhs) const
Return if this IRECT and rhs may be merged.
float GetLengthOfShortestSide() const
void Pad(float padL, float padT, float padR, float padB)
Pad this IRECT N.B.
IRECT()
Construct an empty IRECT
void GetRandomPoint(float &x, float &y) const
Get a random point within this rectangle.
IRECT ReduceFromTop(float amount)
Reduce in height from the top edge by 'amount' and return the removed region.
IRECT GetTranslated(float x, float y) const
Get a translated copy of this rectangle.
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 PixelSnap()
Pixel aligns to nearest pixels This may make the IRECT smaller, unlike PixelAlign().
void VAlignTo(const IRECT &sr, EVAlign align)
Vertically align this rect to the reference IRECT.
bool ContainsEdge(float x, float y) const
Returns true if the point (x,y) is either contained in this IRECT or on an edge.
IRECT GetVSliced(float h, bool bot=false) const
Get a copy of this IRECT with a new height.
IRECT GetFromBLHC(float w, float h) const
Get a subrect of this IRECT expanding from the bottom-left corner.
IRECT GetReducedFromBottom(float amount) const
Get a subrect of this IRECT reduced in height from the bottom edge by 'amount'.
IRECT FracRectVertical(float frac, bool fromTop=false) const
Returns a new IRECT with a height that is multiplied by frac.
void Offset(float l, float t, float r, float b)
Offset each field of the rectangle.
void MidVPad(float padding)
Set the height of this IRECT to 2*padding without changing it's center point on the Y-axis.
IRECT SubRect(EDirection layoutDir, int numSlices, int sliceIdx) const
Get a new rectangle which is a "slice" of this rectangle.
IRECT GetPixelSnapped() const
static IRECT MakeMidXYWH(float x, float y, float w, float h)
Create a new IRECT of size (y,h) centred at the given position (x,y)
void HAlignTo(const IRECT &sr, EAlign align)
Horizontally align this rect to the reference IRECT.
IRECT SubRectHorizontal(int numSlices, int sliceIdx) const
Returns a new IRECT which is a vertical "slice" of this IRECT.
IRECT GetScaled(float scale) const
Get a copy of this IRECT with all values multiplied by scale.
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 GetVPadded(float padding) const
Get a copy of this IRECT padded in the Y-axis N.B.
IRECT FracRect(EDirection layoutDir, float frac, bool fromTopOrRight=false) const
Get a new rectangle which is a fraction of this rectangle.
IRECT ReduceFromBottom(float amount)
Reduce in height from the bottom edge by 'amount' and return the removed region.
static IRECT LinearInterpolateBetween(const IRECT &start, const IRECT &dest, float progress)
Get a rectangle that is a linear interpolation between start and dest
void Clank(const IRECT &rhs)
Clank will limit this IRECT's bounds based on the boundaries of the IRECT passed in as an argument.
void Scale(float scale)
Multiply each field of this IRECT by scale.
IRECT FracRectHorizontal(float frac, bool rhs=false) const
Returns a new IRECT with a width that is multiplied by frac.
void PixelAlign(float scale)
Pixel-align this IRECT at the given scale factor then scale it back down When scaling this mutliples ...
void HPad(float padding)
Pad this IRECT in the X-axis N.B.
IRECT Union(const IRECT &rhs) const
Create a new IRECT that is a union of this IRECT and rhs.
IRECT GetVShifted(float y) const
Get a copy of this rectangle translated on the Y axis.
void Constrain(float &x, float &y) const
Ensure the point (x,y) is inside this IRECT.
IRECT GetPixelAligned(float scale) const
Get a copy of this IRECT with PixelAlign(scale) called.
bool Intersects(const IRECT &rhs) const
Returns true if this IRECT shares any common pixels with rhs, false otherwise.
IRECT GetRandomSubRect() const
IRECT SubRectVertical(int numSlices, int sliceIdx) const
Returns a new IRECT which is a horizontal "slice" of this IRECT.
IRECT GetFromLeft(float amount) const
Get a subrect of this IRECT bounded in X by the left edge and 'amount'.
bool IsPixelAligned(float scale) const
Return true if, when scaled by scale, this IRECT is pixel aligned When scaling this mutliples each va...
IRECT GetFromTop(float amount) const
Get a subrect of this IRECT bounded in Y by the top edge and 'amount'.
void Translate(float x, float y)
Translate this rectangle.
IRECT GetFromBRHC(float w, float h) const
Get a subrect of this IRECT expanding from the bottom-right corner.
IRECT(float x, float y, const IBitmap &bitmap)
Construct a new IRECT at the given position and with the same size as the bitmap.
IRECT GetHShifted(float x) const
Get a copy of this rectangle translated on the X axis.
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...
IRECT GetHAlignedTo(const IRECT &sr, EAlign align) const
Get a rectangle the same dimensions as this one, horizontally aligned to the reference IRECT.
void ScaleAboutCentre(float scale)
Scale the width and height of this IRECT by scale without changing the center point.
bool Contains(const IRECT &rhs) const
Returns true if this IRECT completely contains rhs.
void PixelSnap(float scale)
Pixel align a scaled version of this IRECT.
IRECT GetPadded(float padding) const
Get a copy of this IRECT with each value padded by padding N.B.
IRECT GetHPadded(float padding) const
Get a copy of this IRECT padded in the X-axis N.B.
IRECT GetPixelSnapped(float scale) const
Get a copy of this IRECT with PixelSnap(scale) called.
void DBGPrint()
Print the IRECT's details to the console in Debug builds.
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.
IRECT GetVAlignedTo(const IRECT &sr, EVAlign align) const
Get a rectangle the same dimensions as this one, vertically aligned to the reference IRECT.
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...
IRECT GetPadded(float padL, float padT, float padR, float padB) const
Get a copy of this IRECT with the values padded N.B.
IRECT GetHSliced(float w, bool rhs=false) const
Get a copy of this IRECT with a new width.
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...
User-facing SVG abstraction that you use to manage SVG data ISVG doesn't actually own the image data.
Used to specify properties of a drop-shadow to a layer.
IShadow(const IPattern &pattern, float blurSize, float xOffset, float yOffset, float opacity, bool drawForeground=true)
Create an IShadow.
IText is used to manage font and text/text entry style for a piece of text on the UI,...
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 ...
IText(float size, const char *fontID)
Create a new IText with size and fontID.
IText(float size, EVAlign valign, const IColor &color=DEFAULT_TEXT_FGCOLOR)
Create a new IText with size, vertical align, color.
IText(float size, EAlign align, const IColor &color=DEFAULT_TEXT_FGCOLOR)
Create a new IText with size, horizontal align, color.
Contains a set of 9 colors used to theme IVControls.
IVColorSpec(const std::initializer_list< IColor > &colors)
Create a new IVColorSpec object specifying the colors.
static const IColor & GetDefaultColor(EVColor idx)
void ResetColors()
Reset the colors to the defaults.
const IColor & GetColor(EVColor color) const
IVColorSpec()
Create a new IVColorSpec object with default colors.
A struct encapsulating a set of properties used to configure IVControls.
IVStyle(const std::initializer_list< IColor > &colors)
Create a new IVStyle based on a list of colors, and defaults for the other elements.
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, EOrientation labelOrientation=DEFAULT_LABEL_ORIENTATION)
Create a new IVStyle to configure common styling for IVControls.
Encapsulate an xy point in one struct.