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 ITouchID = uintptr_t;
79using MTLTexturePtr =
void*;
81using Milliseconds = std::chrono::duration<double, std::chrono::milliseconds::period>;
82using TimePoint = std::chrono::time_point<std::chrono::high_resolution_clock, Milliseconds>;
96 : mAPIBitmap(pAPIBitmap)
97 , mW(static_cast<int>(pAPIBitmap->GetWidth() / pAPIBitmap->
GetScale()))
98 , mH(static_cast<int>(pAPIBitmap->GetHeight() / pAPIBitmap->
GetScale()))
100 , mFramesAreHorizontal(framesAreHorizontal)
101 , mResourceName(name, static_cast<int>(strlen(name)))
106 : mAPIBitmap(nullptr)
110 , mFramesAreHorizontal(false)
115 int W()
const {
return mW; }
118 int H()
const {
return mH; }
121 int FW()
const {
return (mFramesAreHorizontal ? mW / mN : mW); }
124 int FH()
const {
return (mFramesAreHorizontal ? mH : mH / mN); }
127 int N()
const {
return mN; }
145 inline bool IsValid()
const {
return mAPIBitmap !=
nullptr; }
157 bool mFramesAreHorizontal;
159 WDL_String mResourceName;
168 ISVG(sk_sp<SkSVGDOM> svgDom)
177 return mSVGDom->containerSize().width();
184 return mSVGDom->containerSize().height();
188 inline bool IsValid()
const {
return mSVGDom !=
nullptr; }
190 sk_sp<SkSVGDOM> mSVGDom;
195 ISVG(NSVGimage* pImage)
204 return mImage->width;
211 return mImage->height;
215 inline bool IsValid()
const {
return mImage !=
nullptr; }
217 NSVGimage* mImage =
nullptr;
231 IColor(
int a = 255,
int r = 0,
int g = 0,
int b = 0) : A(a), R(r), G(g), B(b) {}
233 bool operator==(
const IColor& rhs) {
return (rhs.A == A && rhs.R == R && rhs.G == G && rhs.B == B); }
234 bool operator!=(
const IColor& rhs) {
return !operator==(rhs); }
241 void Set(
int a = 255,
int r = 0,
int g = 0,
int b = 0) { A = a; R = r; G = g; B = b; }
244 bool Empty()
const {
return A == 0 && R == 0 && G == 0 && B == 0; }
251 void Randomise(
int alpha = 255) { A = alpha; R = std::rand() % 255; G = std::rand() % 255; B = std::rand() % 255; }
257 A =
static_cast<int>(
Clip(alpha, 0.f, 1.f) * 255.f);
274 const int mod =
static_cast<int>(c * 255.f);
275 R =
Clip(R += mod, 0, 255);
276 G =
Clip(G += mod, 0, 255);
277 B =
Clip(B += mod, 0, 255);
303 rgbaf[0] = R / 255.f;
304 rgbaf[1] = G / 255.f;
305 rgbaf[2] = B / 255.f;
306 rgbaf[3] = A / 255.f;
314 void GetHSLA(
float& h,
float& s,
float& l,
float& a)
const
316 const float fR = R / 255.f;
317 const float fG = G / 255.f;
318 const float fB = B / 255.f;
321 const float fMin = std::min(fR, std::min(fG, fB));
322 const float fMax = std::max(fR, std::max(fG, fB));
323 const float fDiff = fMax - fMin;
324 const float fSum = fMax + fMin;
328 if (fMin == fMax) { s = 0.f; h = 0.f; l /= 100.f;
return; }
329 else if (l < 50.f) { s = 100.f * fDiff / fSum; }
330 else { s = 100.f * fDiff / (2.f - fDiff); }
332 if (fMax == fR) { h = 60.f * (fG - fB) / fDiff; }
333 if (fMax == fG) { h = 60.f * (fB - fR) / fDiff + 120.f; }
334 if (fMax == fB) { h = 60.f * (fR - fG) / fDiff + 240.f; }
336 if (h < 0.f) { h = h + 360.f; }
347 int min = R < G ? (R < B ? R : B) : (G < B ? G : B);
348 int max = R > G ? (R > B ? R : B) : (G > B ? G : B);
349 return (min + max) / 2;
357 int A = randomAlpha ? std::rand() & 0xFF : 255;
358 int R = std::rand() & 0xFF;
359 int G = std::rand() & 0xFF;
360 int B = std::rand() & 0xFF;
362 return IColor(A, R, G, B);
371 int R =
static_cast<int>(rgbf[0] * 255.f);
372 int G =
static_cast<int>(rgbf[1] * 255.f);
373 int B =
static_cast<int>(rgbf[2] * 255.f);
375 return IColor(A, R, G, B);
383 int R =
static_cast<int>(rgbaf[0] * 255.f);
384 int G =
static_cast<int>(rgbaf[1] * 255.f);
385 int B =
static_cast<int>(rgbaf[2] * 255.f);
386 int A =
static_cast<int>(rgbaf[3] * 255.f);
388 return IColor(A, R, G, B);
402 int R = (colorCode >> 16) & 0xFF;
403 int G = (colorCode >> 8) & 0xFF;
404 int B = colorCode & 0xFF;
406 return IColor(A, R, G, B);
414 WDL_String str(hexStr);
416 if ((str.GetLength() == 7 || str.GetLength() == 9) && str.Get()[0] ==
'#')
420 return FromColorCode(
static_cast<int>(std::stoul(str.Get(),
nullptr, 16)));
424 assert(0 &&
"Invalid color code str, returning black");
432 return (R << 16) | (G << 8) | B;
439 str.SetFormatted(32,
"#%02x%02x%02x%02x", R, G, B, A);
441 str.SetFormatted(32,
"#%02x%02x%02x", R, G, B);
452 auto hue = [](
float h,
float m1,
float m2) {
456 return m1 + (m2 - m1) * h * 6.0f;
457 else if (h < 3.0f / 6.0f)
459 else if (h < 4.0f / 6.0f)
460 return m1 + (m2 - m1) * (2.0f / 3.0f - h) * 6.0f;
465 h = std::fmodf(h, 1.0f);
466 if (h < 0.0f) h += 1.0f;
467 s =
Clip(s, 0.0f, 1.0f);
468 l =
Clip(l, 0.0f, 1.0f);
469 float m2 = l <= 0.5f ? (l * (1 + s)) : (l + s - l * s);
470 float m1 = 2 * l - m2;
471 col.R =
static_cast<int>(
Clip(hue(h + 1.0f / 3.0f, m1, m2), 0.0f, 1.0f) * 255.f);
472 col.G =
static_cast<int>(
Clip(hue(h, m1, m2), 0.0f, 1.0f) * 255.f);
473 col.B =
static_cast<int>(
Clip(hue(h - 1.0f / 3.0f, m1, m2), 0.0f, 1.0f) * 255.f);
474 col.A =
static_cast<int>(a * 255.f);
485 result.A = start.A +
static_cast<int>(progress *
static_cast<float>(dest.A - start.A));
486 result.R = start.R +
static_cast<int>(progress *
static_cast<float>(dest.R - start.R));
487 result.G = start.G +
static_cast<int>(progress *
static_cast<float>(dest.G - start.G));
488 result.B = start.B +
static_cast<int>(progress *
static_cast<float>(dest.B - start.B));
493const IColor COLOR_TRANSPARENT(0, 0, 0, 0);
494const IColor COLOR_TRANSLUCENT(10, 0, 0, 0);
495const IColor COLOR_BLACK(255, 0, 0, 0);
496const IColor COLOR_BLACK_DROP_SHADOW(128, 0, 0, 0);
497const IColor COLOR_GRAY(255, 127, 127, 127);
498const IColor COLOR_LIGHT_GRAY(255, 240, 240, 240);
499const IColor COLOR_MID_GRAY(255, 200, 200, 200);
500const IColor COLOR_DARK_GRAY(255, 70, 70, 70);
501const IColor COLOR_WHITE(255, 255, 255, 255);
502const IColor COLOR_RED(255, 255, 0, 0);
503const IColor COLOR_GREEN(255, 0, 255, 0);
504const IColor COLOR_BLUE(255, 0, 0, 255);
505const IColor COLOR_YELLOW(255, 255, 255, 0);
506const IColor COLOR_ORANGE(255, 255, 127, 0);
507const IColor COLOR_INDIGO(255, 75, 0, 130);
508const IColor COLOR_VIOLET(255, 148, 0, 211);
510static IColor GetRainbow(
int colorIdx)
513 case 0:
return COLOR_RED;
514 case 1:
return COLOR_ORANGE;
515 case 2:
return COLOR_YELLOW;
516 case 3:
return COLOR_GREEN;
517 case 4:
return COLOR_BLUE;
518 case 5:
return COLOR_INDIGO;
519 case 6:
return COLOR_VIOLET;
526const IColor DEFAULT_GRAPHICS_BGCOLOR = COLOR_GRAY;
527const IColor DEFAULT_BGCOLOR = COLOR_TRANSPARENT;
528const IColor DEFAULT_FGCOLOR = COLOR_MID_GRAY;
529const IColor DEFAULT_PRCOLOR = COLOR_LIGHT_GRAY;
531const IColor DEFAULT_FRCOLOR = COLOR_DARK_GRAY;
532const IColor DEFAULT_HLCOLOR = COLOR_TRANSLUCENT;
534const IColor DEFAULT_X1COLOR = COLOR_BLACK;
535const IColor DEFAULT_X2COLOR = COLOR_GREEN;
536const IColor DEFAULT_X3COLOR = COLOR_BLUE;
538const IColor DEFAULT_TEXT_FGCOLOR = COLOR_BLACK;
539const IColor DEFAULT_TEXTENTRY_BGCOLOR = COLOR_WHITE;
540const IColor DEFAULT_TEXTENTRY_FGCOLOR = COLOR_BLACK;
551 IBlend(EBlend type = EBlend::Default,
float weight = 1.0f)
553 , mWeight(
Clip(weight, 0.f, 1.f))
562 return (pBlend ? pBlend->mWeight : 1.0f);
572const IBlend BLEND_DST_OVER =
IBlend(EBlend::DstOver, 1.f);
577 EFillRule mFillRule { EFillRule::Winding };
578 bool mPreserve {
false };
580 IFillOptions(
bool preserve =
false, EFillRule fillRule = EFillRule::Winding)
581 : mFillRule(fillRule)
582 , mPreserve(preserve)
605 DashOptions(
float* array,
float offset,
int count)
607 SetDash(array, offset, count);
611 int GetCount()
const {
return mCount; }
614 float GetOffset()
const {
return mOffset; }
617 const float* GetArray()
const {
return mArray; }
623 void SetDash(
float* pArray,
float offset,
int count)
625 assert(count >= 0 && count <= 8);
630 for (
int i = 0; i < count; i++)
631 mArray[i] = pArray[i];
635 float mArray[8] = {};
640 float mMiterLimit = 10.f;
641 bool mPreserve =
false;
642 ELineCap mCapOption = ELineCap::Butt;
643 ELineJoin mJoinOption = ELineJoin::Miter;
652 case ETextStyle::Bold:
return "Bold";
653 case ETextStyle::Italic:
return "Italic";
654 case ETextStyle::Normal:
672 IText(
float size = DEFAULT_TEXT_SIZE,
673 const IColor& color = DEFAULT_TEXT_FGCOLOR,
674 const char* fontID =
nullptr,
675 EAlign align = EAlign::Center,
676 EVAlign valign = EVAlign::Middle,
678 const IColor& TEBGColor = DEFAULT_TEXTENTRY_BGCOLOR,
679 const IColor& TEFGColor = DEFAULT_TEXTENTRY_FGCOLOR)
682 , mTextEntryBGColor(TEBGColor)
683 , mTextEntryFGColor(TEFGColor)
688 strcpy(mFont, (fontID ? fontID : DEFAULT_FONT));
695 IText(
float size, EVAlign valign,
const IColor& color = DEFAULT_TEXT_FGCOLOR)
707 IText(
float size, EAlign align,
const IColor& color = DEFAULT_TEXT_FGCOLOR)
718 IText(
float size,
const char* fontID)
722 strcpy(mFont, (fontID ? fontID : DEFAULT_FONT));
725 IText WithFGColor(
const IColor& fgColor)
const {
IText newText = *
this; newText.mFGColor = fgColor;
return newText; }
726 IText WithTEColors(
const IColor& teBgColor,
const IColor& teFgColor)
const {
IText newText = *
this; newText.mTextEntryBGColor = teBgColor; newText.mTextEntryFGColor = teFgColor;
return newText; }
727 IText WithAlign(EAlign align)
const {
IText newText = *
this; newText.mAlign = align;
return newText; }
728 IText WithVAlign(EVAlign valign)
const {
IText newText = *
this; newText.mVAlign = valign;
return newText; }
729 IText WithSize(
float size)
const {
IText newText = *
this; newText.mSize = size;
return newText; }
730 IText WithAngle(
float v)
const {
IText newText = *
this; newText.mAngle = v;
return newText; }
731 IText WithFont(
const char* fontID)
const {
IText newText = *
this; strcpy(newText.mFont, (fontID ? fontID : DEFAULT_FONT));;
return newText; }
733 char mFont[FONT_LEN];
739 EAlign mAlign = EAlign::Near;
740 EVAlign mVAlign = EVAlign::Middle;
763 IRECT(
float l,
float t,
float r,
float b)
764 : L(l), T(t), R(r), B(b)
775 R = L + (float) bitmap.
FW();
776 B = T + (float) bitmap.
FH();
787 return IRECT(l, t, l+w, t+h);
793 return (L == 0.f && T == 0.f && R == 0.f && B == 0.f);
802 bool operator==(
const IRECT& rhs)
const
804 return (L == rhs.L && T == rhs.T && R == rhs.R && B == rhs.B);
807 bool operator!=(
const IRECT& rhs)
const
809 return !(*
this == rhs);
813 inline float W()
const {
return R - L; }
816 inline float H()
const {
return B - T; }
819 inline float MW()
const {
return 0.5f * (L + R); }
822 inline float MH()
const {
return 0.5f * (T + B); }
825 inline float Area()
const {
return W() *
H(); }
833 if (
Empty()) {
return rhs; }
834 if (rhs.
Empty()) {
return *
this; }
835 return IRECT(std::min(L, rhs.L), std::min(T, rhs.T), std::max(R, rhs.R), std::max(B, rhs.B));
845 return IRECT(std::max(L, rhs.L), std::max(T, rhs.T), std::min(R, rhs.R), std::min(B, rhs.B));
856 return (!
Empty() && !rhs.
Empty() && R >= rhs.L && L < rhs.R && B >= rhs.T && T < rhs.B);
865 return (!
Empty() && !rhs.
Empty() && rhs.L >= L && rhs.R <= R && rhs.T >= T && rhs.B <= B);
875 return (!
Empty() && x >= L && x < R && y >= T && y < B);
886 return (!
Empty() && x >= L && x <= R && y >= T && y <= B);
895 else if (x > R) x = R;
898 else if (y > B) y = B;
905 return IRECT(L + rhs.L, T + rhs.T, L + rhs.R, T + rhs.B);
917 if (L == rhs.L && R == rhs.R && ((T >= rhs.T && T <= rhs.B) || (rhs.T >= T && rhs.T <= B)))
919 return T == rhs.T && B == rhs.B && ((L >= rhs.L && L <= rhs.R) || (rhs.L >= L && rhs.L <= R));
928 inline IRECT FracRect(EDirection layoutDir,
float frac,
bool fromTopOrRight =
false)
const
930 if(layoutDir == EDirection::Vertical)
942 float widthOfSubRect =
W() * frac;
945 return IRECT(R - widthOfSubRect, T, R, B);
947 return IRECT(L, T, L + widthOfSubRect, B);
956 float heightOfSubRect =
H() * frac;
959 return IRECT(L, T, R, T + heightOfSubRect);
961 return IRECT(L, B - heightOfSubRect, R, B);
973 float heightOfSubRect =
H() / (float) numSlices;
974 float t = heightOfSubRect * (float) sliceIdx;
976 return IRECT(L, T + t, R, T + t + heightOfSubRect);
988 float widthOfSubRect =
W() / (float) numSlices;
989 float l = widthOfSubRect * (float) sliceIdx;
991 return IRECT(L + l, T, L + l + widthOfSubRect, B);
999 inline IRECT SubRect(EDirection layoutDir,
int numSlices,
int sliceIdx)
const
1001 if(layoutDir == EDirection::Vertical)
1099 assert(row * col <= nRows * nColumns);
1112 inline IRECT GetGridCell(
int cellIndex,
int nRows,
int nColumns, EDirection dir = EDirection::Horizontal,
int nCells = 1)
const
1114 assert(cellIndex <= nRows * nColumns);
1118 if(dir == EDirection::Horizontal)
1120 for(
int row = 0; row < nRows; row++)
1122 for(
int col = 0; col < nColumns; col++)
1124 if(cell == cellIndex)
1129 for (
int n = 1; n < nCells && (col + n) < nColumns; n++)
1142 for(
int col = 0; col < nColumns; col++)
1144 for(
int row = 0; row < nRows; row++)
1146 if(cell == cellIndex)
1151 for (
int n = 1; n < nCells && (row + n) < nRows; n++)
1171 auto isInteger = [](
float x){
return std::fabs(x - std::round(x)) <=
static_cast<float>(1e-3); };
1173 return isInteger(L) && isInteger(T) && isInteger(R) && isInteger(B);
1204 Scale(
static_cast<float>(1.0/
static_cast<double>(scale)));
1243 Scale(
static_cast<float>(1.0/
static_cast<double>(scale)));
1267 inline void Pad(
float padding)
1281 inline void Pad(
float padL,
float padT,
float padR,
float padB)
1311 const float mw =
MW();
1320 const float mh =
MH();
1331 return IRECT(L-padding, T-padding, R+padding, B+padding);
1343 return IRECT(L-padL, T-padT, R+padR, B+padB);
1352 return IRECT(L-padding, T, R+padding, B);
1361 return IRECT(L, T-padding, R, B+padding);
1369 return IRECT(
MW()-padding, T,
MW()+padding, B);
1377 return IRECT(L,
MH()-padding, R,
MH()+padding);
1387 return IRECT(R - w, T, R, B);
1389 return IRECT(L, T, L + w, B);
1399 return IRECT(L, B - h, R, B);
1401 return IRECT(L, T, R, T + h);
1410 R = std::min(rhs.R - 1, R + rhs.L - L);
1415 B = std::min(rhs.B - 1, B + rhs.T - T);
1420 L = std::max(rhs.L, L - (R - rhs.R + 1));
1425 T = std::max(rhs.T, T - (B - rhs.B + 1));
1446 float hw =
W() / 2.f;
1447 float hh =
H() / 2.f;
1448 L = x - (hw * scale);
1449 T = y - (hh * scale);
1450 R = x + (hw * scale);
1451 B = y + (hh * scale);
1482 result.L = start.L + progress * (dest.L - start.L);
1483 result.T = start.T + progress * (dest.T - start.T);
1484 result.R = start.R + progress * (dest.R - start.R);
1485 result.B = start.B + progress * (dest.B - start.B);
1494 const float r1 =
static_cast<float>(std::rand()/(
static_cast<float>(RAND_MAX)+1.f));
1495 const float r2 =
static_cast<float>(std::rand()/(
static_cast<float>(RAND_MAX)+1.f));
1509 return IRECT(l, t, r, b);
1517 void Offset(
float l,
float t,
float r,
float b)
1533 return IRECT(L + l, T + t, R + r, B + b);
1553 return IRECT(L + x, T + y, R + x, B + y);
1578 r.L =
MW() - sr.
W() / 2.f;
1579 r.T =
MH() - sr.
H() / 2.f;
1592 w = std::max(w, 1.f);
1598 r.L =
MW() - w / 2.f;
1599 r.T =
MH() - h / 2.f;
1612 r.L =
MW() - bitmap.
FW() / 2.f;
1613 r.T =
MH() - bitmap.
FH() / 2.f;
1614 r.R = r.L + (float) bitmap.
FW();
1615 r.B = r.T + (float) bitmap.
FH();
1625 const float height =
H();
1628 case EVAlign::Top: T = sr.T; B = sr.T + height;
break;
1629 case EVAlign::Bottom: T = sr.B - height; B = sr.B;
break;
1630 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;
1639 const float width =
W();
1642 case EAlign::Near: L = sr.L; R = sr.L + width;
break;
1643 case EAlign::Far: L = sr.R - width; R = sr.R;
break;
1644 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;
1654 IRECT result = *
this;
1674 IRECT result = *
this;
1680 void DBGPrint() { DBGMSG(
"L: %f, T: %f, R: %f, B: %f,: W: %f, H: %f\n", L, T, R, B,
W(),
H()); }
1687 ITouchID touchID = 0;
1688 float touchRadius = 0.f;
1697 IMouseMod(
bool l =
false,
bool r =
false,
bool s =
false,
bool c =
false,
bool a =
false, ITouchID touchID = 0)
1698 : L(l), R(r), S(s), C(c), A(a), touchID(touchID)
1705 void DBGPrint() { DBGMSG(
"L: %i, R: %i, S: %i, C: %i,: A: %i\n", L, R, S, C, A); }
1711 float x = 0.0, y = 0.0;
1712 float dX = 0.0, dY = 0.0;
1722 float velocity = 0.f;
1724 EGestureState state = EGestureState::Unknown;
1725 EGestureType type = EGestureType::Unknown;
1739 int Size()
const {
return mRects.GetSize(); }
1753 *(mRects.GetFast() + idx) = rect;
1761 return *(mRects.GetFast() + idx);
1775 for (
auto i = 1; i < mRects.GetSize(); i++)
1783 for (
auto i = 0; i <
Size(); i++)
1795 for (
auto i = 0; i <
Size(); i++)
1809 for (
auto i = 0; i <
Size(); i++)
1825 static bool GetFracGrid(
const IRECT& input,
IRECTList& rects,
const std::initializer_list<float>& rowFractions,
const std::initializer_list<float>& colFractions, EDirection layoutDir = EDirection::Horizontal)
1827 IRECT spaceLeft = input;
1831 if(std::accumulate(rowFractions.begin(), rowFractions.end(), 0.f) != 1.)
1834 if(std::accumulate(colFractions.begin(), colFractions.end(), 0.f) != 1.)
1837 if (layoutDir == EDirection::Horizontal)
1839 for (
auto& rowFrac : rowFractions)
1845 for (
auto& colFrac : colFractions)
1849 rects.
Add(thisCell);
1860 if (layoutDir == EDirection::Vertical)
1862 for (
auto& colFrac : colFractions)
1868 for (
auto& rowFrac : rowFractions)
1872 rects.
Add(thisCell);
1889 for (
int i = 0; i <
Size(); i++)
1891 for (
int j = i + 1; j <
Size(); j++)
1908 if (
Get(i).Mergeable(intersection))
1909 Set(i, Shrink(
Get(i), intersection));
1910 else if (
Get(j).Mergeable(intersection))
1911 Set(j, Shrink(
Get(j), intersection));
1912 else if (
Get(i).Area() <
Get(j).Area())
1913 Set(i, Split(
Get(i), intersection));
1915 Set(j, Split(
Get(j), intersection));
1920 for (
int i = 0; i <
Size(); i++)
1922 for (
int j = i + 1; j <
Size(); j++)
1943 return IRECT(r.L, r.T, i.L, r.B);
1945 return IRECT(r.L, r.T, r.R, i.T);
1947 return IRECT(i.R, r.T, r.R, r.B);
1948 return IRECT(r.L, i.B, r.R, r.B);
1962 return IRECT(r.L, i.B, r.R, r.B);
1967 return IRECT(i.R, i.T, r.R, r.B);
1974 return IRECT(r.L, i.B, r.R, r.B);
1979 return IRECT(r.L, i.T, i.L, r.B);
1983 WDL_TypedBuf<IRECT> mRects;
1996 IMatrix(
double xx,
double yx,
double xy,
double yy,
double tx,
double ty)
1997 : mXX(xx), mYX(yx), mXY(xy), mYY(yy), mTX(tx), mTY(ty)
2027 const double rad = DegToRad(a);
2028 const double c = std::cos(rad);
2029 const double s = std::sin(rad);
2040 return Transform(
IMatrix(1.0, std::tan(DegToRad(ya)), std::tan(DegToRad(xa)), 1.0, 0.0, 0.0));
2050 x = x0 * mXX + y0 * mXY + mTX;
2051 y = x0 * mYX + y0 * mYY + mTY;
2068 const double sx = after.
W() / before.
W();
2069 const double sy = after.
H() / before.
H();
2070 const double tx = after.L - before.L * sx;
2071 const double ty = after.T - before.T * sy;
2073 return *
this =
IMatrix(sx, 0.0, 0.0, sy, tx, ty);
2083 mXX = m.mXX * p.mXX + m.mYX * p.mXY;
2084 mYX = m.mXX * p.mYX + m.mYX * p.mYY;
2085 mXY = m.mXY * p.mXX + m.mYY * p.mXY;
2086 mYY = m.mXY * p.mYX + m.mYY * p.mYY;
2087 mTX = m.mTX * p.mXX + m.mTY * p.mXY + p.mTX;
2088 mTY = m.mTX * p.mYX + m.mTY * p.mYY + p.mTY;
2099 double d = 1.0 / (m.mXX * m.mYY - m.mYX * m.mXY);
2105 mTX = (-(m.mTX * mXX) - (m.mTY * mXY));
2106 mTY = (-(m.mTX * mYX) - (m.mTY * mYY));
2111 double mXX, mYX, mXY, mYY, mTX, mTY;
2128 assert(offset >= 0.0 && offset <= 1.0);
2139 EPatternExtend mExtend;
2147 : mType(type), mExtend(EPatternExtend::Pad), mNStops(0)
2153 : mType(EPatternType::Solid), mExtend(EPatternExtend::Pad), mNStops(1)
2167 IPattern pattern(EPatternType::Linear);
2170 const double xd = double(x2 - x1);
2171 const double yd = double(y2 - y1);
2172 const double d = sqrt(xd * xd + yd * yd);
2173 const double a = atan2(xd, yd);
2174 const double s = std::sin(a) / d;
2175 const double c = std::cos(a) / d;
2177 const double x0 = -(x1 * c - y1 * s);
2178 const double y0 = -(x1 * s + y1 * c);
2180 pattern.SetTransform(
static_cast<float>(c),
2181 static_cast<float>(s),
2182 static_cast<float>(-s),
2183 static_cast<float>(c),
2184 static_cast<float>(x0),
2185 static_cast<float>(y0));
2187 for (
auto& stop : stops)
2188 pattern.AddStop(stop.mColor, stop.mOffset);
2200 float x1, y1, x2, y2;
2202 if(direction == EDirection::Horizontal)
2204 y1 = bounds.
MH(); y2 = y1;
2210 x1 = bounds.
MW(); x2 = x1;
2226 IPattern pattern(EPatternType::Radial);
2228 const float s = 1.f / r;
2230 pattern.SetTransform(s, 0, 0, s, -(x1 * s), -(y1 * s));
2232 for (
auto& stop : stops)
2233 pattern.AddStop(stop.mColor, stop.mOffset);
2246 float angleStart = 0.f,
float angleEnd = 360.f)
2248 IPattern pattern(EPatternType::Sweep);
2250 #ifdef IGRAPHICS_SKIA
2255 float rad = DegToRad(angleStart);
2256 float c = std::cos(rad);
2257 float s = std::sin(rad);
2259 pattern.SetTransform(c, s, -s, c, -x1, -y1);
2261 for (
auto& stop : stops)
2263 pattern.AddStop(stop.mColor, stop.mOffset * (angleEnd - angleStart) / 360.f);
2287 assert(mType != EPatternType::Solid && mNStops < 16);
2288 assert(!mNStops ||
GetStop(mNStops - 1).mOffset < offset);
2290 mStops[mNStops++] =
IColorStop(color, offset);
2300 void SetTransform(
float xx,
float yx,
float xy,
float yy,
float tx,
float ty)
2302 mTransform =
IMatrix(xx, yx, xy, yy, tx, ty);
2309 mTransform = transform;
2329 , mControl(pControl)
2330 , mControlRECT(controlRect)
2351 std::unique_ptr<APIBitmap> mBitmap;
2373 IShadow(
const IPattern& pattern,
float blurSize,
float xOffset,
float yOffset,
float opacity,
bool drawForeground =
true)
2375 , mBlurSize(blurSize)
2379 , mDrawForeground(drawForeground)
2383 float mBlurSize = 0.f;
2384 float mXOffset = 0.f;
2385 float mYOffset = 0.f;
2386 float mOpacity = 1.f;
2387 bool mDrawForeground =
true;
2393 IColor mColors[kNumVColors];
2398 return mColors[(int) color];
2406 case kBG:
return DEFAULT_BGCOLOR;
2407 case kFG:
return DEFAULT_FGCOLOR;
2408 case kPR:
return DEFAULT_PRCOLOR;
2409 case kFR:
return DEFAULT_FRCOLOR;
2410 case kHL:
return DEFAULT_HLCOLOR;
2411 case kSH:
return DEFAULT_SHCOLOR;
2412 case kX1:
return DEFAULT_X1COLOR;
2413 case kX2:
return DEFAULT_X2COLOR;
2414 case kX3:
return DEFAULT_X3COLOR;
2416 return COLOR_TRANSPARENT;
2430 assert(colors.size() <= kNumVColors);
2434 for(
auto& c : colors)
2439 for(; i<kNumVColors; i++)
2448 for (
int i=0; i<kNumVColors; i++)
2457static constexpr bool DEFAULT_HIDE_CURSOR =
true;
2458static constexpr bool DEFAULT_SHOW_VALUE =
true;
2459static constexpr bool DEFAULT_SHOW_LABEL =
true;
2460static constexpr bool DEFAULT_DRAW_FRAME =
true;
2461static constexpr bool DEFAULT_DRAW_SHADOWS =
true;
2462static constexpr bool DEFAULT_EMBOSS =
false;
2463static constexpr float DEFAULT_ROUNDNESS = 0.f;
2464static constexpr float DEFAULT_FRAME_THICKNESS = 1.f;
2465static constexpr float DEFAULT_SHADOW_OFFSET = 3.f;
2466static constexpr float DEFAULT_WIDGET_FRAC = 1.f;
2467static constexpr float DEFAULT_WIDGET_ANGLE = 0.f;
2468static constexpr EOrientation DEFAULT_LABEL_ORIENTATION = EOrientation::North;
2469const IText DEFAULT_LABEL_TEXT {DEFAULT_TEXT_SIZE + 5.f, EVAlign::Top};
2470const IText DEFAULT_VALUE_TEXT {DEFAULT_TEXT_SIZE, EVAlign::Bottom};
2475 bool hideCursor = DEFAULT_HIDE_CURSOR;
2476 bool showLabel = DEFAULT_SHOW_LABEL;
2477 bool showValue = DEFAULT_SHOW_VALUE;
2478 bool drawFrame = DEFAULT_DRAW_FRAME;
2479 bool drawShadows = DEFAULT_DRAW_SHADOWS;
2480 bool emboss = DEFAULT_EMBOSS;
2481 float roundness = DEFAULT_ROUNDNESS;
2482 float frameThickness = DEFAULT_FRAME_THICKNESS;
2483 float shadowOffset = DEFAULT_SHADOW_OFFSET;
2484 float widgetFrac = DEFAULT_WIDGET_FRAC;
2485 float angle = DEFAULT_WIDGET_ANGLE;
2487 IText labelText = DEFAULT_LABEL_TEXT;
2488 IText valueText = DEFAULT_VALUE_TEXT;
2489 EOrientation labelOrientation = DEFAULT_LABEL_ORIENTATION;
2507 bool showValue = DEFAULT_SHOW_VALUE,
2508 const IVColorSpec& colors = {DEFAULT_BGCOLOR, DEFAULT_FGCOLOR, DEFAULT_PRCOLOR, DEFAULT_FRCOLOR, DEFAULT_HLCOLOR, DEFAULT_SHCOLOR, DEFAULT_X1COLOR, DEFAULT_X2COLOR, DEFAULT_X3COLOR},
2509 const IText& labelText = DEFAULT_LABEL_TEXT,
2510 const IText& valueText = DEFAULT_VALUE_TEXT,
2511 bool hideCursor = DEFAULT_HIDE_CURSOR,
2512 bool drawFrame = DEFAULT_DRAW_FRAME,
2513 bool drawShadows = DEFAULT_DRAW_SHADOWS,
2514 bool emboss = DEFAULT_EMBOSS,
2515 float roundness = DEFAULT_ROUNDNESS,
2516 float frameThickness = DEFAULT_FRAME_THICKNESS,
2517 float shadowOffset = DEFAULT_SHADOW_OFFSET,
2518 float widgetFrac = DEFAULT_WIDGET_FRAC,
2519 float angle = DEFAULT_WIDGET_ANGLE,
2520 EOrientation labelOrientation = DEFAULT_LABEL_ORIENTATION)
2521 : hideCursor(hideCursor)
2522 , showLabel(showLabel)
2523 , showValue(showValue)
2524 , drawFrame(drawFrame)
2525 , drawShadows(drawShadows)
2527 , roundness(roundness)
2528 , frameThickness(frameThickness)
2529 , shadowOffset(shadowOffset)
2530 , widgetFrac(widgetFrac)
2533 , labelText(labelText)
2534 , valueText(valueText)
2540 IVStyle(
const std::initializer_list<IColor>& colors)
2545 IVStyle WithShowLabel(
bool show =
true)
const {
IVStyle newStyle = *
this; newStyle.showLabel = show;
return newStyle; }
2546 IVStyle WithShowValue(
bool show =
true)
const {
IVStyle newStyle = *
this; newStyle.showValue = show;
return newStyle; }
2547 IVStyle WithLabelText(
const IText& text)
const {
IVStyle newStyle = *
this; newStyle.labelText = text;
return newStyle;}
2548 IVStyle WithValueText(
const IText& text)
const {
IVStyle newStyle = *
this; newStyle.valueText = text;
return newStyle; }
2549 IVStyle WithHideCursor(
bool hide =
true)
const {
IVStyle newStyle = *
this; newStyle.hideCursor = hide;
return newStyle; }
2550 IVStyle WithColor(EVColor idx,
IColor color)
const {
IVStyle newStyle = *
this; newStyle.colorSpec.mColors[idx] = color;
return newStyle; }
2551 IVStyle WithColors(
const IVColorSpec& spec)
const {
IVStyle newStyle = *
this; newStyle.colorSpec = spec;
return newStyle; }
2552 IVStyle WithRoundness(
float v)
const {
IVStyle newStyle = *
this; newStyle.roundness =
Clip(v, 0.f, 1.f);
return newStyle; }
2553 IVStyle WithFrameThickness(
float v)
const {
IVStyle newStyle = *
this; newStyle.frameThickness = v;
return newStyle; }
2554 IVStyle WithShadowOffset(
float v)
const {
IVStyle newStyle = *
this; newStyle.shadowOffset = v;
return newStyle; }
2555 IVStyle WithDrawShadows(
bool v =
true)
const {
IVStyle newStyle = *
this; newStyle.drawShadows = v;
return newStyle; }
2556 IVStyle WithDrawFrame(
bool v =
true)
const {
IVStyle newStyle = *
this; newStyle.drawFrame = v;
return newStyle; }
2557 IVStyle WithWidgetFrac(
float v)
const {
IVStyle newStyle = *
this; newStyle.widgetFrac =
Clip(v, 0.f, 1.f);
return newStyle; }
2558 IVStyle WithAngle(
float v)
const {
IVStyle newStyle = *
this; newStyle.angle =
Clip(v, 0.f, 360.f);
return newStyle; }
2559 IVStyle WithEmboss(
bool v =
true)
const {
IVStyle newStyle = *
this; newStyle.emboss = v;
return newStyle; }
2560 IVStyle WithLabelOrientation(EOrientation v)
const {
IVStyle newStyle = *
this; newStyle.labelOrientation = v;
return newStyle; }
2565END_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
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)
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 the point x, y.
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
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.