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);
 
  798    return IRECT(x-(w/2.0f), y-(h/2.0f), x+(w/2.0f), y+(h/2.0f));
 
  804    return (L == 0.f && T == 0.f && R == 0.f && B == 0.f);
 
  813  bool operator==(
const IRECT& rhs)
 const 
  815    return (L == rhs.L && T == rhs.T && R == rhs.R && B == rhs.B);
 
  818  bool operator!=(
const IRECT& rhs)
 const 
  820    return !(*
this == rhs);
 
  824  inline float W()
 const { 
return R - L; }
 
  827  inline float H()
 const { 
return B - T; }
 
  830  inline float MW()
 const { 
return 0.5f * (L + R); }
 
  833  inline float MH()
 const { 
return 0.5f * (T + B); }
 
  836  inline float Area()
 const { 
return W() * 
H(); }
 
  844    if (
Empty()) { 
return rhs; }
 
  845    if (rhs.
Empty()) { 
return *
this; }
 
  846    return IRECT(std::min(L, rhs.L), std::min(T, rhs.T), std::max(R, rhs.R), std::max(B, rhs.B));
 
  856      return IRECT(std::max(L, rhs.L), std::max(T, rhs.T), std::min(R, rhs.R), std::min(B, rhs.B));
 
  867    return (!
Empty() && !rhs.
Empty() && R >= rhs.L && L < rhs.R && B >= rhs.T && T < rhs.B);
 
  876    return (!
Empty() && !rhs.
Empty() && rhs.L >= L && rhs.R <= R && rhs.T >= T && rhs.B <= B);
 
  886    return (!
Empty() && x >= L && x < R && y >= T && y < B);
 
  897    return (!
Empty() && x >= L && x <= R && y >= T && y <= B);
 
  906    else if (x > R) x = R;
 
  909    else if (y > B) y = B;
 
  916    return IRECT(L + rhs.L, T + rhs.T, L + rhs.R, T + rhs.B);
 
  928    if (L == rhs.L && R == rhs.R && ((T >= rhs.T && T <= rhs.B) || (rhs.T >= T && rhs.T <= B)))
 
  930    return T == rhs.T && B == rhs.B && ((L >= rhs.L && L <= rhs.R) || (rhs.L >= L && rhs.L <= R));
 
  939  inline IRECT FracRect(EDirection layoutDir, 
float frac, 
bool fromTopOrRight = 
false)
 const 
  941    if(layoutDir == EDirection::Vertical)
 
  953    float widthOfSubRect = 
W() * frac;
 
  956      return IRECT(R - widthOfSubRect, T, R, B);
 
  958      return IRECT(L, T, L + widthOfSubRect, B);
 
  967    float heightOfSubRect = 
H() * frac;
 
  970      return IRECT(L, T, R, T + heightOfSubRect);
 
  972      return IRECT(L, B - heightOfSubRect, R, B);
 
  984    float heightOfSubRect = 
H() / (float) numSlices;
 
  985    float t = heightOfSubRect * (float) sliceIdx;
 
  987    return IRECT(L, T + t, R, T + t + heightOfSubRect);
 
  999    float widthOfSubRect = 
W() / (float) numSlices;
 
 1000    float l = widthOfSubRect * (float) sliceIdx;
 
 1002    return IRECT(L + l, T, L + l + widthOfSubRect, B);
 
 1010  inline IRECT SubRect(EDirection layoutDir, 
int numSlices, 
int sliceIdx)
 const 
 1012    if(layoutDir == EDirection::Vertical)
 
 1110    assert(row * col <= nRows * nColumns); 
 
 1123  inline IRECT GetGridCell(
int cellIndex, 
int nRows, 
int nColumns, EDirection dir = EDirection::Horizontal, 
int nCells = 1)
 const 
 1125    assert(cellIndex <= nRows * nColumns); 
 
 1129    if(dir == EDirection::Horizontal)
 
 1131      for(
int row = 0; row < nRows; row++)
 
 1133        for(
int col = 0; col < nColumns; col++)
 
 1135          if(cell == cellIndex)
 
 1140            for (
int n = 1; n < nCells && (col + n) < nColumns; n++)
 
 1153      for(
int col = 0; col < nColumns; col++)
 
 1155        for(
int row = 0; row < nRows; row++)
 
 1157          if(cell == cellIndex)
 
 1162            for (
int n = 1; n < nCells && (row + n) < nRows; n++)
 
 1182    auto isInteger = [](
float x){ 
return std::fabs(x - std::round(x)) <= 
static_cast<float>(1e-3); };
 
 1184    return isInteger(L) && isInteger(T) && isInteger(R) && isInteger(B);
 
 1215    Scale(
static_cast<float>(1.0/
static_cast<double>(scale)));
 
 1254    Scale(
static_cast<float>(1.0/
static_cast<double>(scale)));
 
 1278  inline void Pad(
float padding)
 
 1292  inline void Pad(
float padL, 
float padT, 
float padR, 
float padB)
 
 1322    const float mw = 
MW();
 
 1331    const float mh = 
MH();
 
 1342    return IRECT(L-padding, T-padding, R+padding, B+padding);
 
 1354    return IRECT(L-padL, T-padT, R+padR, B+padB);
 
 1363    return IRECT(L-padding, T, R+padding, B);
 
 1372    return IRECT(L, T-padding, R, B+padding);
 
 1380    return IRECT(
MW()-padding, T, 
MW()+padding, B);
 
 1388    return IRECT(L, 
MH()-padding, R, 
MH()+padding);
 
 1398      return IRECT(R - w, T, R, B);
 
 1400      return IRECT(L, T, L + w, B);
 
 1410      return IRECT(L, B - h, R, B);
 
 1412      return IRECT(L, T, R, T + h);
 
 1421      R = std::min(rhs.R - 1, R + rhs.L - L);
 
 1426      B = std::min(rhs.B - 1, B + rhs.T - T);
 
 1431      L = std::max(rhs.L, L - (R - rhs.R + 1));
 
 1436      T = std::max(rhs.T, T - (B - rhs.B + 1));
 
 1457    float hw = 
W() / 2.f;
 
 1458    float hh = 
H() / 2.f;
 
 1459    L = x - (hw * scale);
 
 1460    T = y - (hh * scale);
 
 1461    R = x + (hw * scale);
 
 1462    B = y + (hh * scale);
 
 1493    result.L = start.L + progress * (dest.L -  start.L);
 
 1494    result.T = start.T + progress * (dest.T -  start.T);
 
 1495    result.R = start.R + progress * (dest.R -  start.R);
 
 1496    result.B = start.B + progress * (dest.B -  start.B);
 
 1505    const float r1 = 
static_cast<float>(std::rand()/(
static_cast<float>(RAND_MAX)+1.f));
 
 1506    const float r2 = 
static_cast<float>(std::rand()/(
static_cast<float>(RAND_MAX)+1.f));
 
 1520    return IRECT(l, t, r, b);
 
 1528  void Offset(
float l, 
float t, 
float r, 
float b)
 
 1544    return IRECT(L + l, T + t, R + r, B + b);
 
 1564    return IRECT(L + x, T + y, R + x, B + y);
 
 1589    r.L = 
MW() - sr.
W() / 2.f;
 
 1590    r.T = 
MH() - sr.
H() / 2.f;
 
 1603    w = std::max(w, 1.f);
 
 1609    r.L = 
MW() - w / 2.f;
 
 1610    r.T = 
MH() - h / 2.f;
 
 1623    r.L = 
MW() - bitmap.
FW() / 2.f;
 
 1624    r.T = 
MH() - bitmap.
FH() / 2.f;
 
 1625    r.R = r.L + (float) bitmap.
FW();
 
 1626    r.B = r.T + (float) bitmap.
FH();
 
 1636    const float height = 
H();
 
 1639      case EVAlign::Top: T = sr.T; B = sr.T + height; 
break;
 
 1640      case EVAlign::Bottom: T = sr.B - height; B = sr.B; 
break;
 
 1641      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;
 
 1650    const float width = 
W();
 
 1653      case EAlign::Near: L = sr.L; R = sr.L + width; 
break;
 
 1654      case EAlign::Far: L = sr.R - width; R = sr.R; 
break;
 
 1655      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;
 
 1665    IRECT result = *
this;
 
 1685    IRECT result = *
this;
 
 1691  void DBGPrint() { DBGMSG(
"L: %f, T: %f, R: %f, B: %f,: W: %f, H: %f\n", L, T, R, B, 
W(), 
H()); }
 
 1698  ITouchID touchID = 0;
 
 1699  float touchRadius = 0.f;
 
 1708  IMouseMod(
bool l = 
false, 
bool r = 
false, 
bool s = 
false, 
bool c = 
false, 
bool a = 
false, ITouchID touchID = 0)
 
 1709  : L(l), R(r), S(s), C(c), A(a), touchID(touchID)
 
 1716  void DBGPrint() { DBGMSG(
"L: %i, R: %i, S: %i, C: %i,: A: %i\n", L, R, S, C, A); }
 
 1722  float x = 0.0, y = 0.0;
 
 1723  float dX = 0.0, dY = 0.0;
 
 1733  float velocity = 0.f; 
 
 1735  EGestureState state = EGestureState::Unknown;
 
 1736  EGestureType type = EGestureType::Unknown;
 
 1750  int Size()
 const { 
return mRects.GetSize(); }
 
 1764    *(mRects.GetFast() + idx) = rect;
 
 1772    return *(mRects.GetFast() + idx);
 
 1786    for (
auto i = 1; i < mRects.GetSize(); i++)
 
 1794    for (
auto i = 0; i < 
Size(); i++)
 
 1806    for (
auto i = 0; i < 
Size(); i++)
 
 1820    for (
auto i = 0; i < 
Size(); i++)
 
 1836  static bool GetFracGrid(
const IRECT& input, 
IRECTList& rects, 
const std::initializer_list<float>& rowFractions, 
const std::initializer_list<float>& colFractions, EDirection layoutDir = EDirection::Horizontal)
 
 1838    IRECT spaceLeft = input;
 
 1842    if(std::accumulate(rowFractions.begin(), rowFractions.end(), 0.f) != 1.)
 
 1845    if(std::accumulate(colFractions.begin(), colFractions.end(), 0.f) != 1.)
 
 1848    if (layoutDir == EDirection::Horizontal)
 
 1850      for (
auto& rowFrac : rowFractions)
 
 1856        for (
auto& colFrac : colFractions)
 
 1860          rects.
Add(thisCell);
 
 1871    if (layoutDir == EDirection::Vertical)
 
 1873      for (
auto& colFrac : colFractions)
 
 1879        for (
auto& rowFrac : rowFractions)
 
 1883          rects.
Add(thisCell);
 
 1900    for (
int i = 0; i < 
Size(); i++)
 
 1902      for (
int j = i + 1; j < 
Size(); j++)
 
 1919          if (
Get(i).Mergeable(intersection))
 
 1920            Set(i, Shrink(
Get(i), intersection));
 
 1921          else if (
Get(j).Mergeable(intersection))
 
 1922            Set(j, Shrink(
Get(j), intersection));
 
 1923          else if (
Get(i).Area() < 
Get(j).Area())
 
 1924            Set(i, Split(
Get(i), intersection));
 
 1926            Set(j, Split(
Get(j), intersection));
 
 1931    for (
int i = 0; i < 
Size(); i++)
 
 1933      for (
int j = i + 1; j < 
Size(); j++)
 
 1954      return IRECT(r.L, r.T, i.L, r.B);
 
 1956      return IRECT(r.L, r.T, r.R, i.T);
 
 1958      return IRECT(i.R, r.T, r.R, r.B);
 
 1959    return IRECT(r.L, i.B, r.R, r.B);
 
 1973        return IRECT(r.L, i.B, r.R, r.B);
 
 1978        return IRECT(i.R, i.T, r.R, r.B);
 
 1985      return IRECT(r.L, i.B, r.R, r.B);
 
 1990      return IRECT(r.L, i.T, i.L, r.B);
 
 1994  WDL_TypedBuf<IRECT> mRects;
 
 2007  IMatrix(
double xx, 
double yx, 
double xy, 
double yy, 
double tx, 
double ty)
 
 2008  : mXX(xx), mYX(yx), mXY(xy), mYY(yy), mTX(tx), mTY(ty)
 
 2038    const double rad = DegToRad(a);
 
 2039    const double c = std::cos(rad);
 
 2040    const double s = std::sin(rad);
 
 2051    return Transform(
IMatrix(1.0, std::tan(DegToRad(ya)), std::tan(DegToRad(xa)), 1.0, 0.0, 0.0));
 
 2061    x = x0 * mXX + y0 * mXY + mTX;
 
 2062    y = x0 * mYX + y0 * mYY + mTY;
 
 2079    const double sx = after.
W() / before.
W();
 
 2080    const double sy = after.
H() / before.
H();
 
 2081    const double tx = after.L - before.L * sx;
 
 2082    const double ty = after.T - before.T * sy;
 
 2084    return *
this = 
IMatrix(sx, 0.0, 0.0, sy, tx, ty);
 
 2094    mXX = m.mXX * p.mXX + m.mYX * p.mXY;
 
 2095    mYX = m.mXX * p.mYX + m.mYX * p.mYY;
 
 2096    mXY = m.mXY * p.mXX + m.mYY * p.mXY;
 
 2097    mYY = m.mXY * p.mYX + m.mYY * p.mYY;
 
 2098    mTX = m.mTX * p.mXX + m.mTY * p.mXY + p.mTX;
 
 2099    mTY = m.mTX * p.mYX + m.mTY * p.mYY + p.mTY;
 
 2110    double d = 1.0 / (m.mXX * m.mYY - m.mYX * m.mXY);
 
 2116    mTX = (-(m.mTX * mXX) - (m.mTY * mXY));
 
 2117    mTY = (-(m.mTX * mYX) - (m.mTY * mYY));
 
 2122  double mXX, mYX, mXY, mYY, mTX, mTY;
 
 2139    assert(offset >= 0.0 && offset <= 1.0);
 
 2150  EPatternExtend mExtend;
 
 2158  : mType(type), mExtend(EPatternExtend::Pad), mNStops(0)
 
 2164  : mType(EPatternType::Solid), mExtend(EPatternExtend::Pad), mNStops(1)
 
 2178    IPattern pattern(EPatternType::Linear);
 
 2181    const double xd = double(x2 - x1);
 
 2182    const double yd = double(y2 - y1);
 
 2183    const double d = sqrt(xd * xd + yd * yd);
 
 2184    const double a = atan2(xd, yd);
 
 2185    const double s = std::sin(a) / d;
 
 2186    const double c = std::cos(a) / d;
 
 2188    const double x0 = -(x1 * c - y1 * s);
 
 2189    const double y0 = -(x1 * s + y1 * c);
 
 2191    pattern.SetTransform(
static_cast<float>(c),
 
 2192                         static_cast<float>(s),
 
 2193                         static_cast<float>(-s),
 
 2194                         static_cast<float>(c),
 
 2195                         static_cast<float>(x0),
 
 2196                         static_cast<float>(y0));
 
 2198    for (
auto& stop : stops)
 
 2199      pattern.AddStop(stop.mColor, stop.mOffset);
 
 2211    float x1, y1, x2, y2;
 
 2213    if(direction == EDirection::Horizontal)
 
 2215      y1 = bounds.
MH(); y2 = y1;
 
 2221      x1 = bounds.
MW(); x2 = x1;
 
 2237    IPattern pattern(EPatternType::Radial);
 
 2239    const float s = 1.f / r;
 
 2241    pattern.SetTransform(s, 0, 0, s, -(x1 * s), -(y1 * s));
 
 2243    for (
auto& stop : stops)
 
 2244      pattern.AddStop(stop.mColor, stop.mOffset);
 
 2257    float angleStart = 0.f, 
float angleEnd = 360.f)
 
 2259    IPattern pattern(EPatternType::Sweep);
 
 2261    #ifdef IGRAPHICS_SKIA 
 2266    float rad = DegToRad(angleStart);
 
 2267    float c = std::cos(rad);
 
 2268    float s = std::sin(rad);
 
 2270    pattern.SetTransform(c, s, -s, c, -x1, -y1);
 
 2272    for (
auto& stop : stops)
 
 2274      pattern.AddStop(stop.mColor, stop.mOffset * (angleEnd - angleStart) / 360.f);
 
 2298    assert(mType != EPatternType::Solid && mNStops < 16);
 
 2299    assert(!mNStops || 
GetStop(mNStops - 1).mOffset < offset);
 
 2301      mStops[mNStops++] = 
IColorStop(color, offset);
 
 2311  void SetTransform(
float xx, 
float yx, 
float xy, 
float yy, 
float tx, 
float ty)
 
 2313    mTransform = 
IMatrix(xx, yx, xy, yy, tx, ty);
 
 2320    mTransform = transform;
 
 2340  , mControl(pControl)
 
 2341  , mControlRECT(controlRect)
 
 2362  std::unique_ptr<APIBitmap> mBitmap;
 
 2384  IShadow(
const IPattern& pattern, 
float blurSize, 
float xOffset, 
float yOffset, 
float opacity, 
bool drawForeground = 
true)
 
 2386  , mBlurSize(blurSize)
 
 2390  , mDrawForeground(drawForeground)
 
 2394  float mBlurSize = 0.f;
 
 2395  float mXOffset = 0.f;
 
 2396  float mYOffset = 0.f;
 
 2397  float mOpacity = 1.f;
 
 2398  bool mDrawForeground = 
true;
 
 2404  IColor mColors[kNumVColors];
 
 2409    return mColors[(int) color];
 
 2417      case kBG: 
return DEFAULT_BGCOLOR; 
 
 2418      case kFG: 
return DEFAULT_FGCOLOR; 
 
 2419      case kPR: 
return DEFAULT_PRCOLOR; 
 
 2420      case kFR: 
return DEFAULT_FRCOLOR; 
 
 2421      case kHL: 
return DEFAULT_HLCOLOR; 
 
 2422      case kSH: 
return DEFAULT_SHCOLOR; 
 
 2423      case kX1: 
return DEFAULT_X1COLOR; 
 
 2424      case kX2: 
return DEFAULT_X2COLOR; 
 
 2425      case kX3: 
return DEFAULT_X3COLOR; 
 
 2427        return COLOR_TRANSPARENT;
 
 2441    assert(colors.size() <= kNumVColors);
 
 2445    for(
auto& c : colors)
 
 2450    for(; i<kNumVColors; i++)
 
 2459    for (
int i=0; i<kNumVColors; i++)
 
 2468static constexpr bool DEFAULT_HIDE_CURSOR = 
true;
 
 2469static constexpr bool DEFAULT_SHOW_VALUE = 
true;
 
 2470static constexpr bool DEFAULT_SHOW_LABEL = 
true;
 
 2471static constexpr bool DEFAULT_DRAW_FRAME = 
true;
 
 2472static constexpr bool DEFAULT_DRAW_SHADOWS = 
true;
 
 2473static constexpr bool DEFAULT_EMBOSS = 
false;
 
 2474static constexpr float DEFAULT_ROUNDNESS = 0.f;
 
 2475static constexpr float DEFAULT_FRAME_THICKNESS = 1.f;
 
 2476static constexpr float DEFAULT_SHADOW_OFFSET = 3.f;
 
 2477static constexpr float DEFAULT_WIDGET_FRAC = 1.f;
 
 2478static constexpr float DEFAULT_WIDGET_ANGLE = 0.f;
 
 2479static constexpr EOrientation DEFAULT_LABEL_ORIENTATION = EOrientation::North;
 
 2480const IText DEFAULT_LABEL_TEXT {DEFAULT_TEXT_SIZE + 5.f, EVAlign::Top};
 
 2481const IText DEFAULT_VALUE_TEXT {DEFAULT_TEXT_SIZE, EVAlign::Bottom};
 
 2486  bool hideCursor = DEFAULT_HIDE_CURSOR;
 
 2487  bool showLabel = DEFAULT_SHOW_LABEL;
 
 2488  bool showValue = DEFAULT_SHOW_VALUE;
 
 2489  bool drawFrame = DEFAULT_DRAW_FRAME;
 
 2490  bool drawShadows = DEFAULT_DRAW_SHADOWS;
 
 2491  bool emboss = DEFAULT_EMBOSS;
 
 2492  float roundness = DEFAULT_ROUNDNESS;
 
 2493  float frameThickness = DEFAULT_FRAME_THICKNESS;
 
 2494  float shadowOffset = DEFAULT_SHADOW_OFFSET;
 
 2495  float widgetFrac = DEFAULT_WIDGET_FRAC;
 
 2496  float angle = DEFAULT_WIDGET_ANGLE;
 
 2498  IText labelText = DEFAULT_LABEL_TEXT;
 
 2499  IText valueText = DEFAULT_VALUE_TEXT;
 
 2500  EOrientation labelOrientation = DEFAULT_LABEL_ORIENTATION;
 
 2518          bool showValue = DEFAULT_SHOW_VALUE,
 
 2519          const IVColorSpec& colors = {DEFAULT_BGCOLOR, DEFAULT_FGCOLOR, DEFAULT_PRCOLOR, DEFAULT_FRCOLOR, DEFAULT_HLCOLOR, DEFAULT_SHCOLOR, DEFAULT_X1COLOR, DEFAULT_X2COLOR, DEFAULT_X3COLOR},
 
 2520          const IText& labelText = DEFAULT_LABEL_TEXT,
 
 2521          const IText& valueText = DEFAULT_VALUE_TEXT,
 
 2522          bool hideCursor = DEFAULT_HIDE_CURSOR,
 
 2523          bool drawFrame = DEFAULT_DRAW_FRAME,
 
 2524          bool drawShadows = DEFAULT_DRAW_SHADOWS,
 
 2525          bool emboss = DEFAULT_EMBOSS,
 
 2526          float roundness = DEFAULT_ROUNDNESS,
 
 2527          float frameThickness = DEFAULT_FRAME_THICKNESS,
 
 2528          float shadowOffset = DEFAULT_SHADOW_OFFSET,
 
 2529          float widgetFrac = DEFAULT_WIDGET_FRAC,
 
 2530          float angle = DEFAULT_WIDGET_ANGLE,
 
 2531          EOrientation labelOrientation = DEFAULT_LABEL_ORIENTATION)
 
 2532  : hideCursor(hideCursor)
 
 2533  , showLabel(showLabel)
 
 2534  , showValue(showValue)
 
 2535  , drawFrame(drawFrame)
 
 2536  , drawShadows(drawShadows)
 
 2538  , roundness(roundness)
 
 2539  , frameThickness(frameThickness)
 
 2540  , shadowOffset(shadowOffset)
 
 2541  , widgetFrac(widgetFrac)
 
 2544  , labelText(labelText)
 
 2545  , valueText(valueText)
 
 2551  IVStyle(
const std::initializer_list<IColor>& colors)
 
 2556  IVStyle WithShowLabel(
bool show = 
true)
 const { 
IVStyle newStyle = *
this; newStyle.showLabel = show; 
return newStyle; }
 
 2557  IVStyle WithShowValue(
bool show = 
true)
 const { 
IVStyle newStyle = *
this; newStyle.showValue = show; 
return newStyle; }
 
 2558  IVStyle WithLabelText(
const IText& text)
 const { 
IVStyle newStyle = *
this; newStyle.labelText = text; 
return newStyle;}
 
 2559  IVStyle WithValueText(
const IText& text)
 const { 
IVStyle newStyle = *
this; newStyle.valueText = text; 
return newStyle; }
 
 2560  IVStyle WithHideCursor(
bool hide = 
true)
 const { 
IVStyle newStyle = *
this; newStyle.hideCursor = hide; 
return newStyle; }
 
 2561  IVStyle WithColor(EVColor idx, 
IColor color)
 const { 
IVStyle newStyle = *
this; newStyle.colorSpec.mColors[idx] = color; 
return newStyle; }
 
 2562  IVStyle WithColors(
const IVColorSpec& spec)
 const { 
IVStyle newStyle = *
this; newStyle.colorSpec = spec; 
return newStyle; }
 
 2563  IVStyle WithRoundness(
float v)
 const { 
IVStyle newStyle = *
this; newStyle.roundness = 
Clip(v, 0.f, 1.f); 
return newStyle; }
 
 2564  IVStyle WithFrameThickness(
float v)
 const { 
IVStyle newStyle = *
this; newStyle.frameThickness = v; 
return newStyle; }
 
 2565  IVStyle WithShadowOffset(
float v)
 const { 
IVStyle newStyle = *
this; newStyle.shadowOffset = v; 
return newStyle; }
 
 2566  IVStyle WithDrawShadows(
bool v = 
true)
 const { 
IVStyle newStyle = *
this; newStyle.drawShadows = v; 
return newStyle; }
 
 2567  IVStyle WithDrawFrame(
bool v = 
true)
 const { 
IVStyle newStyle = *
this; newStyle.drawFrame = v; 
return newStyle; }
 
 2568  IVStyle WithWidgetFrac(
float v)
 const { 
IVStyle newStyle = *
this; newStyle.widgetFrac = 
Clip(v, 0.f, 1.f); 
return newStyle; }
 
 2569  IVStyle WithAngle(
float v)
 const { 
IVStyle newStyle = *
this; newStyle.angle = 
Clip(v, 0.f, 360.f); 
return newStyle; }
 
 2570  IVStyle WithEmboss(
bool v = 
true)
 const { 
IVStyle newStyle = *
this; newStyle.emboss = v; 
return newStyle; }
 
 2571  IVStyle WithLabelOrientation(EOrientation v)
 const { 
IVStyle newStyle = *
this; newStyle.labelOrientation = v; 
return newStyle; }
 
 2576END_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
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.