13#define NANOSVG_IMPLEMENTATION
14#pragma warning(disable:4244)
18#include "pluginterfaces/base/ustring.h"
20using VST3_API_BASE = iplug::IPlugVST3;
21#elif defined VST3C_API
22#include "pluginterfaces/base/ustring.h"
24#include "IPlugVST3_View.h"
25using VST3_API_BASE = iplug::IPlugVST3Controller;
41using namespace igraphics;
43static StaticStorage<APIBitmap> sBitmapCache;
44static StaticStorage<SVGHolder> sSVGCache;
46IGraphics::IGraphics(
IGEditorDelegate& dlg,
int w,
int h,
int fps,
float scale)
51, mMinScale(DEFAULT_MIN_DRAW_SCALE)
52, mMaxScale(DEFAULT_MAX_DRAW_SCALE)
55 StaticStorage<APIBitmap>::Accessor bitmapStorage(sBitmapCache);
56 bitmapStorage.Retain();
57 StaticStorage<SVGHolder>::Accessor svgStorage(sSVGCache);
61IGraphics::~IGraphics()
66 mCursorHidden =
false;
69 StaticStorage<APIBitmap>::Accessor bitmapStorage(sBitmapCache);
70 bitmapStorage.Release();
71 StaticStorage<SVGHolder>::Accessor svgStorage(sSVGCache);
81 assert(windowWidth > 0 && windowHeight > 0 &&
"Window dimensions invalid");
84 PlatformResize(parentResized);
94 scale =
Clip(scale, mMinScale, mMaxScale);
106 mCornerResizer->OnRescale();
112 PlatformResize(parentResized);
123void IGraphics::SetLayoutOnResize(
bool layoutOnResize)
125 mLayoutOnResize = layoutOnResize;
130 mMinScale = std::min(lo, hi);
131 mMaxScale = std::max(lo, hi);
137 mCtrlTags.erase(ctrlTag);
144 while (idx >= fromIdx)
151 if(pControl == mMouseOver)
154 if(pControl == mInTextEntry)
157 if(pControl == mInPopupMenu)
158 mInPopupMenu =
nullptr;
160 if(pControl->
GetTag() > kNoTag)
161 mCtrlTags.erase(pControl->
GetTag());
163 mControls.Delete(idx--,
true);
179 if(pControl == mMouseOver)
182 if(pControl == mInTextEntry)
185 if(pControl == mInPopupMenu)
186 mInPopupMenu =
nullptr;
188 if(pControl->
GetTag() > kNoTag)
189 mCtrlTags.erase(pControl->
GetTag());
191 mControls.DeletePtr(pControl,
true);
201 mPopupControl =
nullptr;
202 mTextEntryControl =
nullptr;
203 mCornerResizer =
nullptr;
204 mPerfDisplay =
nullptr;
210 mBubbleControls.Empty(
true);
213 mControls.Empty(
true);
242 const IParam* pParam = mTextEntryValIdx > kNoValIdx ? mInTextEntry->
GetParam(mTextEntryValIdx) :
nullptr;
265 mInPopupMenu->
OnPopupMenuSelection(!pMenu || pMenu->GetChosenItemIdx() == -1 ?
nullptr : pMenu, mPopupMenuValIdx);
267 int nVals = mInPopupMenu->
NVals();
269 for (
int v = 0; v < nVals; v++)
273 if (paramIdx > kNoParameter)
279 mInPopupMenu =
nullptr;
294 mControls.Insert(0, pBG);
301 mControls.Insert(0, pBG);
308 mControls.Insert(0, pBG);
315 auto result = mCtrlTags.insert(std::make_pair(ctrlTag, pControl));
316 assert(result.second &&
"AttachControl failed: ctrl tags must be unique");
324 mControls.Add(pControl);
338 assert(!mCornerResizer);
340 std::unique_ptr<ICornerResizerControl> control(pControl);
344 mCornerResizer.swap(control);
345 mGUISizeMode = sizeMode;
346 mLayoutOnResize = layoutOnResize;
350DBGMSG(
"AttachCornerResizer() is disabled for AUv3");
363 mBubbleControls.Add(pControl);
370 mPopupControl = std::make_unique<IPopupMenuControl>(kNoParameter, text,
IRECT(), bounds);
377 mPopupControl =
nullptr;
382 if (!mTextEntryControl)
384 mTextEntryControl = std::make_unique<ITextEntryControl>();
391 mTextEntryControl =
nullptr;
394void IGraphics::ShowBubbleControl(
IControl* pCaller,
float x,
float y,
const char* str, EDirection dir,
IRECT minimumContentBounds)
396 assert(mBubbleControls.GetSize() &&
"No bubble controls attached");
400 std::vector<ITouchID> touchIDsForCaller;
402 std::vector<IBubbleControl*> availableBubbleControls;
403 int nBubbleControls = mBubbleControls.GetSize();
405 if(touchIDsForCaller.size() == 1)
407 ITouchID touchID = touchIDsForCaller[0];
410 for(
int i=0;i<nBubbleControls;i++)
413 if(pBubbleControl->GetTouchID() == touchID)
415 pBubbleControl->ShowBubble(pCaller, x, y, str, dir, minimumContentBounds, touchID);
419 availableBubbleControls.push_back(pBubbleControl);
422 if(availableBubbleControls.size())
425 static int whichBubbleControl = 0;
426 availableBubbleControls[whichBubbleControl++]->ShowBubble(pCaller, x, y, str, dir, minimumContentBounds, touchID);
427 whichBubbleControl %= nBubbleControls;
436 mBubbleControls.Get(0)->ShowBubble(pCaller, x, y, str, dir, minimumContentBounds);
445 if (mPerfDisplayBounds.
Empty())
450 mPerfDisplay = std::make_unique<IFPSDisplayControl>(mPerfDisplayBounds);
456 mPerfDisplay =
nullptr;
465 const auto it = mCtrlTags.find(ctrlTag);
467 if (it != mCtrlTags.end())
473 assert(
"There is no control attached with this tag");
523 for (
auto param : params)
540 if (CStringHasContents(pControl->
GetGroup()))
542 if (strcmp(pControl->
GetGroup(), group) == 0)
560 func(mPerfDisplay.get());
564 func(mLiveEdit.get());
568 func(mCornerResizer.get());
570 if (mTextEntryControl)
571 func(mTextEntryControl.get());
574 func(mPopupControl.get());
576 if (mBubbleControls.GetSize())
578 for(
int i = 0;i<mBubbleControls.GetSize();i++)
580 func(mBubbleControls.Get(i));
585template<
typename T,
typename... Args>
591template<
typename T,
typename... Args>
611 if (pControl->GetParamIdx() > kNoParameter)
612 pControl->SetTooltip(pControl->GetParam()->GetName());
620 double value = pCaller->
GetValue(callerValIdx);
623 auto func = [pCaller, paramIdx, value](
IControl* pControl)
625 int valIdx = pControl->LinkedToParam(paramIdx);
628 if ((valIdx > kNoValIdx) && (pControl != pCaller))
630 pControl->SetValueFromDelegate(value, valIdx);
639 assert(valIdx > kNoValIdx);
647 WDL_String currentText;
649 if ( type == IParam::kTypeEnum || (type == IParam::kTypeBool && nDisplayTexts))
652 mPromptPopupMenu.Clear();
655 for (
int i = 0; i < nDisplayTexts; ++i)
659 if (!strcmp(str, currentText.Get()))
660 mPromptPopupMenu.AddItem(
new IPopupMenu::Item(str, IPopupMenu::Item::kChecked), -1 );
664 mPromptPopupMenu.SetRootTitle(pParam->
GetName());
676 currentText.Append(
" ");
677 currentText.Append(pParam->
GetLabel());
687 if (!str || str[0] ==
'\0')
695 if (!str || str[0] ==
'\0')
703 IRECT bounds = { x, y, x, y };
704 DrawText(text, str, bounds, pBlend);
712 bmpState =
Clip(bmpState, 1, bitmap.
N());
714 if (bitmap.
N() > 1 && bmpState > 1)
718 srcX = bitmap.
W() * (bmpState - 1) / bitmap.
N();
722 srcY = bitmap.
H() * (bmpState - 1) / bitmap.
N();
726 return DrawBitmap(bitmap, bounds, srcX, srcY, pBlend);
731 if (CStringHasContents(str))
733 int stringLength = (int) strlen(str);
735 float basicYOffset = 0.;
736 float basicXOffset = 0.;
739 basicYOffset = bounds.T + ((bounds.
H() - charHeight) / 2.f);
741 basicYOffset = bounds.T;
743 if (text.mAlign == EAlign::Center)
744 basicXOffset = bounds.L + ((bounds.
W() - (stringLength * charWidth)) / 2.f);
745 else if (text.mAlign == EAlign::Near)
746 basicXOffset = bounds.L;
747 else if (text.mAlign == EAlign::Far)
748 basicXOffset = bounds.R - (stringLength * charWidth);
750 int widthAsOneLine = charWidth * stringLength;
755 int nCharsThatFitIntoLine;
759 if (widthAsOneLine > bounds.
W())
761 nCharsThatFitIntoLine = int(bounds.
W() / (
float)charWidth);
762 nLines = int(
float(widthAsOneLine) / bounds.
W()) + 1;
766 nCharsThatFitIntoLine = stringLength;
772 nCharsThatFitIntoLine = int(bounds.
W() / (
float) charWidth);
776 for (
int line=0; line<nLines; line++)
778 float yOffset = basicYOffset + line * charHeight;
780 for (
int linepos=0; linepos<nCharsThatFitIntoLine; linepos++)
782 if (str[stridx] ==
'\0')
return;
784 int frameOffset = (int) str[stridx++] - 31;
786 float xOffset = ((float) linepos * ((
float) charWidth + (float) charOffset)) + basicXOffset;
787 IRECT charRect =
IRECT(xOffset, yOffset, xOffset + charWidth, yOffset + charHeight);
788 DrawBitmap(bitmap, charRect, frameOffset, pBlend);
796 if (dir == EDirection::Horizontal)
804 x =
Clip(x, 0.0f, 1.0f);
805 float xi = bounds.L + int(x * (bounds.R - bounds.L));
811 y =
Clip(y, 0.0f, 1.0f);
812 float yi = bounds.B - (y * (float) (bounds.B - bounds.T));
818 DrawLine(color, xi, yLo, xi, yHi, pBlend, thickness);
823 DrawLine(color, xLo, yi, xHi, yi, pBlend, thickness);
829 RadialPoints(angle, cx, cy, rMin, rMax, 2, data);
830 DrawLine(color, data[0][0], data[0][1], data[1][0], data[1][1], pBlend, thickness);
836 RadialPoints(angle, cx, cy, rMin, rMax, 2, data);
837 PathLine(data[0][0], data[0][1], data[1][0], data[1][1]);
842 if (mDisplayTickFunc)
849 auto func = [&dirty, &rects](
IControl* pControl) {
860 rects.
Add(rectToAdd);
872 else if (++mIdleTicks > IDLE_TICKS)
886 const double timestamp = GetTimestamp();
887 const double timeDiff = timestamp - mPrevTimestamp;
888 mPerfDisplay->Update((
float) timeDiff);
889 mPrevTimestamp = timestamp;
894void IGraphics::DrawControl(
IControl* pControl,
const IRECT& bounds,
float scale)
902 if (clipBounds.
W() <= 0.0 || clipBounds.
H() <= 0)
914 clipBounds.
Clank(parentBounds);
919 PrepareRegion(clipBounds);
920 pControl->
Draw(*
this);
926 if (mShowControlBounds)
928 PrepareRegion(clipBounds);
933 CompleteRegion(clipBounds);
944 PrepareRegion(bounds);
948 CompleteRegion(bounds);
973 for (
auto i = 0; i < rects.
Size(); i++)
990 bool singlePoint = points.size() == 1;
994 mMouseDownX = points[0].x;
995 mMouseDownY = points[0].y;
998 for (
auto& point : points)
1004 IControl* pCapturedControl = GetMouseControl(x, y,
true,
false, mod.touchID);
1006 if (pCapturedControl)
1008 int nVals = pCapturedControl->
NVals();
1009#if defined AAX_API || !defined IGRAPHICS_NO_CONTEXT_MENU
1011 int paramIdx = pCapturedControl->
GetParamIdx((valIdx > kNoValIdx) ? valIdx : 0);
1015 if (mAAXViewContainer && paramIdx > kNoParameter)
1017 auto GetAAXModifiersFromIMouseMod = [](
const IMouseMod& mod) {
1018 uint32_t modifiers = 0;
1020 if (mod.A) modifiers |= AAX_eModifiers_Option;
1023 if (mod.C) modifiers |= AAX_eModifiers_Command;
1025 if (mod.C) modifiers |= AAX_eModifiers_Control;
1026 if (mod.R) modifiers |= AAX_eModifiers_Command;
1028 if (mod.S) modifiers |= AAX_eModifiers_Shift;
1029 if (mod.R) modifiers |= AAX_eModifiers_SecondaryButton;
1034 uint32_t aaxModifiersForPT = GetAAXModifiersFromIMouseMod(mod);
1037 uint32_t aaxModifiersFromPT = 0;
1038 mAAXViewContainer->GetModifiers(&aaxModifiersFromPT);
1039 aaxModifiersForPT |= aaxModifiersFromPT;
1042 paramID.SetFormatted(32,
"%i", paramIdx+1);
1044 if (mAAXViewContainer->HandleParameterMouseDown(paramID.Get(), aaxModifiersForPT) == AAX_SUCCESS)
1052#ifndef IGRAPHICS_NO_CONTEXT_MENU
1053 if (mod.R && paramIdx > kNoParameter)
1061 for (
int v = 0; v < nVals; v++)
1063 if (pCapturedControl->
GetParamIdx(v) > kNoParameter)
1078 for (
auto& point : points)
1083 auto itr = mCapturedMap.find(mod.touchID);
1085 if(itr != mCapturedMap.end())
1087 IControl* pCapturedControl = itr->second;
1091 int nVals = pCapturedControl->
NVals();
1093 for (
int v = 0; v < nVals; v++)
1095 if (pCapturedControl->
GetParamIdx(v) > kNoParameter)
1099 mCapturedMap.erase(mod.touchID);
1104 if (mResizingInProcess)
1109 if (points.size() == 1 && !points[0].ms.IsTouch())
1110 OnMouseOver(points[0].x, points[0].y, points[0].ms);
1118 for (
auto& point : points)
1124 auto itr = mCapturedMap.find(mod.touchID);
1126 if(itr != mCapturedMap.end())
1128 IControl* pCapturedControl = itr->second;
1130 mCapturedMap.erase(mod.touchID);
1140 Trace(
"IGraphics::OnMouseOver", __LINE__,
"x:%0.2f, y:%0.2f, mod:LRSCA: %i%i%i%i%i",
1141 x, y, mod.L, mod.R, mod.S, mod.C, mod.A);
1144 IControl* pControl = GetMouseControl(x, y,
false,
true);
1146 if (pControl != mMouseOver)
1151 mMouseOver = pControl;
1162 Trace(
"IGraphics::OnMouseOut", __LINE__,
"");
1172 Trace(
"IGraphics::OnMouseDrag:", __LINE__,
"x:%0.2f, y:%0.2f, dX:%0.2f, dY:%0.2f, mod:LRSCA: %i%i%i%i%i",
1173 points[0].x, points[0].y, points[0].dX, points[0].dY, points[0].ms.L, points[0].ms.R, points[0].ms.S, points[0].ms.C, points[0].ms.A);
1175 if (mResizingInProcess && points.size() == 1)
1182 textEntry = mTextEntryControl.get();
1184 for (
auto& point : points)
1188 float dX = point.dX;
1189 float dY = point.dY;
1192 auto itr = mCapturedMap.find(mod.touchID);
1194 if (itr != mCapturedMap.end())
1196 IControl* pCapturedControl = itr->second;
1198 if (textEntry && pCapturedControl != textEntry)
1199 pCapturedControl =
nullptr;
1201 if (pCapturedControl && (dX != 0 || dY != 0))
1212 Trace(
"IGraphics::OnMouseDblClick", __LINE__,
"x:%0.2f, y:%0.2f, mod:LRSCA: %i%i%i%i%i",
1213 x, y, mod.L, mod.R, mod.S, mod.C, mod.A);
1215 IControl* pControl = GetMouseControl(x, y,
true);
1225 std::vector<IMouseInfo> list {info};
1240 IControl* pControl = GetMouseControl(x, y,
false);
1250 Trace(
"IGraphics::OnKeyDown", __LINE__,
"x:%0.2f, y:%0.2f, key:%s",
1253 bool handled =
false;
1255 IControl* pControl = GetMouseControl(x, y,
false);
1258 handled = pControl->
OnKeyDown(x, y, key);
1261 handled = mKeyHandlerFunc ? mKeyHandlerFunc(key,
false) :
false;
1268 Trace(
"IGraphics::OnKeyUp", __LINE__,
"x:%0.2f, y:%0.2f, key:%s",
1271 bool handled =
false;
1273 IControl* pControl = GetMouseControl(x, y,
false);
1276 handled = pControl->
OnKeyUp(x, y, key);
1279 handled = mKeyHandlerFunc ? mKeyHandlerFunc(key,
true) :
false;
1286 IControl* pControl = GetMouseControl(x, y,
false);
1287 if (pControl) pControl->
OnDrop(str);
1292 IControl* pControl = GetMouseControl(x, y,
false);
1298 mCapturedMap.clear();
1303int IGraphics::GetMouseControlIdx(
float x,
float y,
bool mouseOver)
1305 if (!mouseOver || mEnableMouseOver)
1308 for (
auto c =
NControls() - 1; c >= (mouseOver ? 1 : 0); --c)
1320 if (pControl->
IsHit(x, y))
1339IControl* IGraphics::GetMouseControl(
float x,
float y,
bool capture,
bool mouseOver, ITouchID touchID)
1343 auto itr = mCapturedMap.find(touchID);
1347 pControl = itr->second;
1353 int controlIdx = -1;
1355 if (!pControl && mPopupControl && mPopupControl->GetExpanded())
1356 pControl = mPopupControl.get();
1358 if (!pControl && mTextEntryControl && mTextEntryControl->EditInProgress())
1359 pControl = mTextEntryControl.get();
1363 if (!pControl && mLiveEdit)
1364 pControl = mLiveEdit.get();
1367 if (!pControl && mCornerResizer && mCornerResizer->GetRECT().Contains(x, y))
1368 pControl = mCornerResizer.get();
1370 if (!pControl && mPerfDisplay && mPerfDisplay->GetRECT().Contains(x, y))
1371 pControl = mPerfDisplay.get();
1375 controlIdx = GetMouseControlIdx(x, y, mouseOver);
1376 pControl = (controlIdx >= 0) ?
GetControl(controlIdx) :
nullptr;
1379 if (capture && pControl)
1389 mCapturedMap.insert(std::make_pair(touchID, pControl));
1395 mMouseOverIdx = controlIdx;
1402 IControl* pControl = GetMouseControl(x, y,
false);
1403 int idx = mLastClickedParam = pControl ? pControl->
GetParamIdx() : -1;
1409 const int idx = mLastClickedParam;
1410 mLastClickedParam = kNoParameter;
1422 contextMenu.Clear();
1428#if defined VST3_API || defined VST3C_API
1429 VST3_API_BASE* pVST3 =
dynamic_cast<VST3_API_BASE*
>(
GetDelegate());
1431 if (!pVST3->GetComponentHandler() || !pVST3->GetView())
1434 Steinberg::FUnknownPtr<Steinberg::Vst::IComponentHandler3>handler(pVST3->GetComponentHandler() );
1439 Steinberg::Vst::ParamID p = paramIdx;
1441 Steinberg::Vst::IContextMenu* pVST3ContextMenu = handler->createContextMenu(pVST3->GetView(), &p);
1443 if (pVST3ContextMenu)
1445 std::function<void(
IPopupMenu* pCurrentMenu)> populateFunc;
1446 Steinberg::int32 tag = 0;
1448 populateFunc = [&populateFunc, &tag, pVST3ContextMenu, pControl](
IPopupMenu* pCurrentMenu) {
1449 Steinberg::Vst::IContextMenu::Item item = {0};
1451 for (
int i = 0; i < pCurrentMenu->NItems(); i++)
1453 Steinberg::UString128 (pCurrentMenu->GetItemText(i)).copyTo (item.name, 128);
1457 if (pCurrentMenu->GetItem(i)->GetIsSeparator())
1459 item.flags = Steinberg::Vst::IContextMenu::Item::kIsSeparator;
1461 else if (
auto pSubMenu = pCurrentMenu->GetItem(i)->GetSubmenu())
1463 item.flags = Steinberg::Vst::IContextMenu::Item::kIsGroupStart;
1464 pVST3ContextMenu->addItem(item, pControl);
1465 populateFunc(pSubMenu);
1467 item.flags = Steinberg::Vst::IContextMenu::Item::kIsGroupEnd;
1468 pVST3ContextMenu->addItem(item, pControl);
1473 if (!pCurrentMenu->GetItem(i)->GetEnabled())
1474 item.flags |= Steinberg::Vst::IContextMenu::Item::kIsDisabled;
1476 if (pCurrentMenu->GetItem(i)->GetChecked())
1477 item.flags |= Steinberg::Vst::IContextMenu::Item::kIsChecked;
1480 pVST3ContextMenu->addItem(item, pControl);
1484 populateFunc(&contextMenu);
1493 pVST3ContextMenu->popup((Steinberg::UCoord) x, (Steinberg::UCoord) y);
1494 pVST3ContextMenu->release();
1498 if(!contextMenu.NItems())
1501 DoCreatePopupMenu(*pControl, contextMenu,
IRECT(x, y, x, y), kNoValIdx,
true);
1519 if(mGUISizeMode == EUIResizerMode::Scale)
1534 if (mAppearanceChangedFunc)
1535 mAppearanceChangedFunc(appearance);
1547 mEnableTooltips = enable;
1548 if (enable) mEnableMouseOver =
true;
1558 mLiveEdit = std::make_unique<IGraphicsLiveEdit>(mEnableMouseOver);
1564 mLiveEdit =
nullptr;
1578 StaticStorage<SVGHolder>::Accessor storage(sSVGCache);
1579 SVGHolder* pHolder = storage.Find(fileName);
1583 WDL_TypedBuf<uint8_t> svgData =
LoadResource(fileName,
"svg");
1584 if (svgData.GetSize() == 0)
1586 return ISVG(
nullptr);
1590 return LoadSVG(fileName, svgData.Get(), svgData.GetSize(), units, dpi);
1594 return ISVG(pHolder->mSVGDom);
1599 StaticStorage<SVGHolder>::Accessor storage(sSVGCache);
1600 SVGHolder* pHolder = storage.Find(name);
1604 sk_sp<SkSVGDOM> svgDOM;
1607 SkMemoryStream svgStream(pData, dataSize);
1608 svgDOM = SkSVGDOM::MakeFromStream(svgStream);
1611 return ISVG(
nullptr);
1615 if (svgDOM->containerSize().width() == 0)
1617 NSVGimage* pImage =
nullptr;
1620 svgStr.Set((
const char*)pData, dataSize);
1621 pImage = nsvgParse(svgStr.Get(), units, dpi);
1625 svgDOM->setContainerSize(SkSize::Make(pImage->width, pImage->height));
1630 pHolder =
new SVGHolder(svgDOM);
1631 storage.Add(pHolder, name);
1634 return ISVG(pHolder->mSVGDom);
1640 StaticStorage<SVGHolder>::Accessor storage(sSVGCache);
1641 SVGHolder* pHolder = storage.Find(fileName);
1645 WDL_TypedBuf<uint8_t> svgData =
LoadResource(fileName,
"svg");
1646 if (svgData.GetSize() == 0)
1648 return ISVG(
nullptr);
1652 return LoadSVG(fileName, svgData.Get(), svgData.GetSize(), units, dpi);
1656 return ISVG(pHolder->mImage);
1661 StaticStorage<SVGHolder>::Accessor storage(sSVGCache);
1662 SVGHolder* pHolder = storage.Find(name);
1666 NSVGimage* pImage =
nullptr;
1669 svgStr.Set(
reinterpret_cast<const char*
>(pData), dataSize);
1670 pImage = nsvgParse(svgStr.Get(), units, dpi);
1673 return ISVG(
nullptr);
1675 pHolder =
new SVGHolder(pImage);
1677 storage.Add(pHolder, name);
1680 return ISVG(pHolder->mImage);
1686 WDL_TypedBuf<uint8_t> result;
1691 if (resourceFound == EResourceLocation::kNotFound)
1695 if (resourceFound == EResourceLocation::kWinBinary)
1699 result.Resize(size);
1700 result.Set((
const uint8_t*)pResData, size);
1703 if (resourceFound == EResourceLocation::kAbsolutePath)
1705 FILE* fd = fopen(path.Get(),
"rb");
1711 if (fseek(fd, 0, SEEK_END))
1716 long size = ftell(fd);
1719 if (fseek(fd, 0, SEEK_SET))
1725 result.Resize((
int)size);
1726 size_t bytesRead = fread(result.Get(), 1, (
size_t)size, fd);
1727 if (bytesRead != (
size_t)size)
1730 result.Resize(0,
true);
1741 if (targetScale == 0)
1744 StaticStorage<APIBitmap>::Accessor storage(sBitmapCache);
1745 APIBitmap* pAPIBitmap = storage.Find(name, targetScale);
1750 WDL_String fullPath;
1751 std::unique_ptr<APIBitmap> loadedBitmap;
1752 int sourceScale = 0;
1754 const char* ext = name + strlen(name) - 1;
1755 while (ext >= name && *ext !=
'.') --ext;
1760 if (!bitmapTypeSupported)
1763 EResourceLocation resourceLocation =
SearchImageResource(name, ext, fullPath, targetScale, sourceScale);
1765 if (resourceLocation == EResourceLocation::kNotFound)
1773 if (sourceScale != targetScale)
1774 pAPIBitmap = storage.Find(name, sourceScale);
1779 loadedBitmap = std::unique_ptr<APIBitmap>(
LoadAPIBitmap(fullPath.Get(), sourceScale, resourceLocation, ext));
1780 pAPIBitmap= loadedBitmap.get();
1785 assert(pAPIBitmap &&
"Bitmap not found");
1788 if (pAPIBitmap->
GetScale() != targetScale)
1790 return ScaleBitmap(
IBitmap(pAPIBitmap, nStates, framesAreHorizontal, name), name, targetScale);
1792 else if (loadedBitmap)
1798 return IBitmap(pAPIBitmap, nStates, framesAreHorizontal, name);
1803 if (targetScale == 0)
1806 StaticStorage<APIBitmap>::Accessor storage(sBitmapCache);
1807 APIBitmap* pAPIBitmap = storage.Find(name, targetScale);
1812 WDL_String fullPath;
1813 std::unique_ptr<APIBitmap> loadedBitmap;
1814 int sourceScale = 0;
1816 const char* ext = name + strlen(name) - 1;
1817 while (ext >= name && *ext !=
'.') --ext;
1822 if (!bitmapTypeSupported)
1830 loadedBitmap = std::unique_ptr<APIBitmap>(
LoadAPIBitmap(name, pData, dataSize, 1));
1831 pAPIBitmap= loadedBitmap.get();
1836 assert(pAPIBitmap &&
"Bitmap not found");
1839 if (pAPIBitmap->
GetScale() != targetScale)
1841 return ScaleBitmap(
IBitmap(pAPIBitmap, nStates, framesAreHorizontal, name), name, targetScale);
1843 else if (loadedBitmap)
1849 return IBitmap(pAPIBitmap, nStates, framesAreHorizontal, name);
1854 StaticStorage<APIBitmap>::Accessor storage(sBitmapCache);
1860 StaticStorage<APIBitmap>::Accessor storage(sBitmapCache);
1869 mScreenScale = scale;
1879 mScreenScale = screenScale;
1880 mDrawScale = drawScale;
1885auto SearchNextScale = [](
int& sourceScale,
int targetScale) {
1886 if (sourceScale == targetScale && (targetScale != MAX_IMG_SCALE))
1887 sourceScale = MAX_IMG_SCALE;
1888 else if (sourceScale == targetScale + 1)
1889 sourceScale = targetScale - 1;
1896 for (sourceScale = targetScale ; sourceScale > 0; SearchNextScale(sourceScale, targetScale))
1898 WDL_String fullName(name);
1900 if (sourceScale != 1)
1902 WDL_String baseName(name); baseName.remove_fileext();
1903 WDL_String ext(fullName.get_fileext());
1904 fullName.SetFormatted((
int) (strlen(name) + strlen(
"@2x")),
"%s@%dx%s", baseName.Get(), sourceScale, ext.Get());
1909 if (found > EResourceLocation::kNotFound)
1913 return EResourceLocation::kNotFound;
1918 StaticStorage<APIBitmap>::Accessor storage(sBitmapCache);
1920 for (sourceScale = targetScale; sourceScale > 0; SearchNextScale(sourceScale, targetScale))
1922 APIBitmap* pBitmap = storage.Find(name, sourceScale);
1943 mInTextEntry = &control;
1944 mTextEntryValIdx = valIdx;
1946 int paramIdx = valIdx > kNoValIdx ? control.
GetParamIdx(valIdx) : kNoParameter;
1948 if (mTextEntryControl)
1949 mTextEntryControl->CreateTextEntry(paramIdx, text, bounds, control.
GetTextEntryLength(), str);
1956void IGraphics::DoCreatePopupMenu(
IControl& control,
IPopupMenu& menu,
const IRECT& bounds,
int valIdx,
bool isContext)
1960 mInPopupMenu = &control;
1961 mPopupMenuValIdx = valIdx;
1962 mIsContextMenu = isContext;
1966 mPopupControl->CreatePopupMenu(menu, bounds);
1970 bool isAsync =
false;
1980 DoCreatePopupMenu(control, menu, bounds, valIdx,
false);
1983void IGraphics::EndDragResize()
1985 mResizingInProcess =
false;
1993 else if (mCornerResizer)
1994 mCornerResizer->SetDirty(
false);
2001 const int w =
static_cast<int>(std::ceil(pixelBackingScale * std::ceil(alignedBounds.
W())));
2002 const int h =
static_cast<int>(std::ceil(pixelBackingScale * std::ceil(alignedBounds.
H())));
2011 ownedLayer.swap(layer);
2012 ILayer* pOwnerlessLayer = ownedLayer.release();
2014 if (pOwnerlessLayer)
2027 mLayers.push(pLayer);
2036 ILayer* pLayer =
nullptr;
2038 if (!mLayers.empty())
2040 pLayer = mLayers.top();
2054 const APIBitmap* pBitmap = layer ? layer->GetAPIBitmap() :
nullptr;
2056 if (pBitmap && layer->mControl && layer->mControlRECT != layer->mControl->GetRECT())
2058 layer->mControlRECT = layer->mControl->GetRECT();
2059 layer->Invalidate();
2069 DrawBitmap(layer->GetBitmap(), layer->Bounds(), 0, 0, pBlend);
2075 IBitmap bitmap = layer->GetBitmap();
2076 IRECT layerBounds = layer->Bounds();
2079 IRECT newBounds(0., 0., layerBounds.
W(), layerBounds.
H());
2089 IBitmap bitmap = layer->GetBitmap();
2090 IRECT bounds = layer->Bounds();
2097 auto GaussianBlurSwap = [](uint8_t* out, uint8_t* in, uint8_t* kernel,
int width,
int height,
2098 int outStride,
int inStride,
int kernelSize, uint32_t norm)
2101 int fullKernelSize = kernelSize * 2 + 1;
2104 auto RepeatCheck = [&](
int idx)
2106 repeats = last == in[idx * 4] ? std::min(repeats + 1, fullKernelSize) : 1;
2109 return repeats == fullKernelSize;
2112 for (
int i = 0; i < height; i++, in += inStride)
2114 for (
int j = 0; j < kernelSize - 1; j++)
2116 uint32_t accum = in[j * 4] * kernel[0];
2117 for (
int k = 1; k < j + 1; k++)
2118 accum += kernel[k] * in[(j - k) * 4];
2119 for (
int k = 1; k < kernelSize; k++)
2120 accum += kernel[k] * in[(j + k) * 4];
2121 out[j * outStride + (i * 4)] =
static_cast<uint8_t
>(std::min(
static_cast<uint32_t
>(255), accum / norm));
2123 for (
int j = 0; j < kernelSize * 2 - 2; j++)
2125 for (
int j = kernelSize - 1; j < (width - kernelSize) + 1; j++)
2127 if (RepeatCheck(j + kernelSize - 1))
2129 out[j * outStride + (i * 4)] =
static_cast<uint8_t
>(last);
2133 uint32_t accum = in[j * 4] * kernel[0];
2134 for (
int k = 1; k < kernelSize; k++)
2135 accum += kernel[k] * (in[(j - k) * 4] + in[(j + k) * 4]);
2136 out[j * outStride + (i * 4)] =
static_cast<uint8_t
>(std::min(
static_cast<uint32_t
>(255), accum / norm));
2138 for (
int j = (width - kernelSize) + 1; j < width; j++)
2140 uint32_t accum = in[j * 4] * kernel[0];
2141 for (
int k = 1; k < kernelSize; k++)
2142 accum += kernel[k] * in[(j - k) * 4];
2143 for (
int k = 1; k < width - j; k++)
2144 accum += kernel[k] * in[(j + k) * 4];
2145 out[j * outStride + (i * 4)] =
static_cast<uint8_t
>(std::min(
static_cast<uint32_t
>(255), accum / norm));
2150 RawBitmapData temp1;
2151 RawBitmapData temp2;
2152 RawBitmapData kernel;
2157 if (!temp1.GetSize())
2159 temp2.Resize(temp1.GetSize());
2163 float scale = layer->GetAPIBitmap()->GetScale() * layer->GetAPIBitmap()->GetDrawScale();
2164 float blurSize = std::max(1.f, (shadow.mBlurSize * scale) + 1.f);
2165 float blurConst = 4.5f / (blurSize * blurSize);
2166 int iSize =
static_cast<int>(ceil(blurSize));
2167 int width = layer->GetAPIBitmap()->GetWidth();
2168 int height = layer->GetAPIBitmap()->GetHeight();
2169 int stride1 = temp1.GetSize() / width;
2170 int stride2 = flipped ? -temp1.GetSize() / height : temp1.GetSize() / height;
2171 int stride3 = flipped ? -stride2 : stride2;
2173 kernel.Resize(iSize);
2175 for (
int i = 0; i < iSize; i++)
2176 kernel.Get()[i] =
static_cast<uint8_t
>(std::round(255.f * std::expf(-(i * i) * blurConst)));
2179 int normFactor = kernel.Get()[0];
2181 for (
int i = 1; i < iSize; i++)
2182 normFactor += kernel.Get()[i] + kernel.Get()[i];
2186 uint8_t* inRows = flipped ? asRows + stride3 * (height - 1) : asRows;
2189 GaussianBlurSwap(asCols, inRows, kernel.Get(), width, height, stride1, stride2, iSize, normFactor);
2190 GaussianBlurSwap(asRows, asCols, kernel.Get(), height, width, stride3, stride1, iSize, normFactor);
2209 DBGMSG(
"Could not locate font %s\n", fileNameOrResID);
2226 DBGMSG(
"Could not load font %s\n", fontID);
2243 DBGMSG(
"Could not locate font %s\n", fontID);
2249 double tx = 0.0, ty = 0.0;
2252 rect.
Translate(
static_cast<float>(tx),
static_cast<float>(ty));
2276 IRECT r1(
static_cast<float>(std::min(x0, x3)),
static_cast<float>(std::min(y0, y3)),
static_cast<float>(std::max(x0, x3)),
static_cast<float>(std::max(y0, y3)));
2277 IRECT r2(
static_cast<float>(std::min(x1, x2)),
static_cast<float>(std::min(y1, y2)),
static_cast<float>(std::max(x1, x2)),
static_cast<float>(std::max(y1, y2)));
2278 rect = r1.
Union(r2);
2280 switch (text.mAlign)
2282 case EAlign::Near: tx = bounds.L - rect.L;
break;
2283 case EAlign::Center: tx = bounds.
MW() - rect.
MW();
break;
2284 case EAlign::Far: tx = bounds.R - rect.R;
break;
2287 switch (text.mVAlign)
2289 case EVAlign::Top: ty = bounds.T - rect.T;
break;
2290 case EVAlign::Middle: ty = bounds.
MH() - rect.
MH();
break;
2291 case EVAlign::Bottom: ty = bounds.B - rect.B;
break;
2301 static int base = 48;
2302 static bool keysDown[128] = {};
2304 auto onOctSwitch = [&]() {
2305 base =
Clip(base, 24, 96);
2307 for(
auto i=0;i<128;i++) {
2318 case kVK_A: note = 0;
break;
2319 case kVK_W: note = 1;
break;
2320 case kVK_S: note = 2;
break;
2321 case kVK_E: note = 3;
break;
2322 case kVK_D: note = 4;
break;
2323 case kVK_F: note = 5;
break;
2324 case kVK_T: note = 6;
break;
2325 case kVK_G: note = 7;
break;
2326 case kVK_Y: note = 8;
break;
2327 case kVK_H: note = 9;
break;
2328 case kVK_U: note = 10;
break;
2329 case kVK_J: note = 11;
break;
2330 case kVK_K: note = 12;
break;
2331 case kVK_O: note = 13;
break;
2332 case kVK_L: note = 14;
break;
2333 case kVK_Z:
if(!isUp) { base -= 12; onOctSwitch(); }
return true;
2334 case kVK_X:
if(!isUp) { base += 12; onOctSwitch(); }
return true;
2335 default:
return true;
2338 int pitch = base + note;
2341 if(keysDown[pitch] ==
false) {
2343 keysDown[pitch] =
true;
2350 if(keysDown[pitch] ==
true) {
2352 keysDown[pitch] =
false;
2365 IControl* pControl = GetMouseControl(x, y,
false,
false);
2370 if(mGestureRegions.
Size() == 0)
2374 int regionIdx = mGestureRegions.
Find(x, y);
2385 IControl* pControl = GetMouseControl(info.x, info.y,
false,
false);
2391 int regionIdx = mGestureRegions.
Find(info.x, info.y);
2394 mGestureRegionFuncs.find(regionIdx)->second(
nullptr, info);
2400 if (std::find(std::begin(mRegisteredGestures), std::end(mRegisteredGestures), type) != std::end(mRegisteredGestures))
2402 mRegisteredGestures.push_back(type);
2408 mGestureRegions.
Add(bounds);
2410 mGestureRegionFuncs.insert(std::make_pair(mGestureRegions.
Size()-1, func));
2415 mGestureRegions.
Clear();
2416 mGestureRegionFuncs.clear();
2427 DrawBitmap(bitmap,
IRECT(-width * 0.5f, - height * 0.5f, width * 0.5f, height * 0.5f), 0, 0, pBlend);
2449 if (gridSizeH > 1.f)
2451 for (
float x = bounds.L + gridSizeH; x < bounds.R; x += gridSizeH)
2458 if (gridSizeV > 1.f)
2460 for (
float y = bounds.T + gridSizeV; y < bounds.B; y += gridSizeV)
2477 float xPos = bounds.L;
2479 PathMoveTo(xPos, bounds.B - (bounds.
H() * normYPoints[0]));
2481 for (
auto i = 1; i < nPoints; i++)
2484 xPos = bounds.L + (bounds.
W() * normXPoints[i]);
2486 xPos = bounds.L + ((bounds.
W() / (float) (nPoints - 1) * i));
2488 PathLineTo(xPos, bounds.B - (bounds.
H() * normYPoints[i]));
2504 options.mDash.SetDash(&dashLen, 0.0, 1);
2507 PathStroke(color, thickness, options, pBlend);
2563 options.mDash.SetDash(&dashLen, 0., 1);
2565 PathStroke(color, thickness, options, pBlend);
2666 if (ctl <= 0.f && ctr <= 0.f && cbl <= 0.f && cbr <= 0.f)
2672 const float y = bounds.B - bounds.
H();
2674 PathArc(bounds.L + ctl, y + ctl, ctl, 270.f, 360.f);
2675 PathArc(bounds.L + bounds.
W() - ctr, y + ctr, ctr, 0.f, 90.f);
2676 PathArc(bounds.L + bounds.
W() - cbr, y + bounds.
H() - cbr, cbr, 90.f, 180.f);
2677 PathArc(bounds.L + cbl, y + bounds.
H() - cbl, cbl, 180.f, 270.f);
2691 if (r1 <= 0.0 || r2 <= 0.0)
2711 PathArc(cx, cy, r, 0.f, 360.f);
2718 for(
int i = 1; i < nPoints; i++)
2725 mTransformStates.push(mTransform);
2730 if (!mTransformStates.empty())
2732 mTransform = mTransformStates.top();
2733 mTransformStates.pop();
2734 PathTransformSetMatrix(mTransform);
2742 std::stack<IMatrix> newStack;
2743 mTransformStates.swap(newStack);
2747 PathTransformSetMatrix(mTransform);
2753 PathTransformSetMatrix(mTransform);
2758 mTransform.
Scale(scaleX, scaleY);
2759 PathTransformSetMatrix(mTransform);
2769 mTransform.
Rotate(angle);
2770 PathTransformSetMatrix(mTransform);
2775 mTransform.
Skew(xAngle, yAngle);
2776 PathTransformSetMatrix(mTransform);
2782 PathTransformSetMatrix(mTransform);
2787 IRECT drawArea = mLayers.empty() ? mClipRECT : mLayers.top()->Bounds();
2789 PathTransformSetMatrix(
IMatrix());
2790 SetClipRegion(clip);
2791 PathTransformSetMatrix(mTransform);
2798 IRECT newBounds(0., 0.,
static_cast<float>(bitmap.
W()),
static_cast<float>(bitmap.
H()));
2799 PathTransformScale(bounds.
W() /
static_cast<float>(bitmap.
W()), bounds.
H() /
static_cast<float>(bitmap.
H()));
2806 float xScale = dest.
W() / svg.
W();
2807 float yScale = dest.
H() / svg.
H();
2808 float scale = xScale < yScale ? xScale : yScale;
2813 DoDrawSVG(svg, pBlend, pStrokeColor, pFillColor);
2822 DrawSVG(svg,
IRECT(-width * 0.5f, - height * 0.5f, width * 0.5f, height * 0.5f), pBlend);
2826IPattern IGraphics::GetSVGPattern(
const NSVGpaint& paint,
float opacity)
2828 int alpha = std::min(255, std::max(
int(roundf(opacity * 255.f)), 0));
2832 case NSVG_PAINT_COLOR:
2833 return IColor(alpha, (paint.color >> 0) & 0xFF, (paint.color >> 8) & 0xFF, (paint.color >> 16) & 0xFF);
2835 case NSVG_PAINT_LINEAR_GRADIENT:
2836 case NSVG_PAINT_RADIAL_GRADIENT:
2838 NSVGgradient* pGrad = paint.gradient;
2840 IPattern pattern(paint.type == NSVG_PAINT_LINEAR_GRADIENT ? EPatternType::Linear : EPatternType::Radial);
2843 switch (pGrad->spread)
2845 case NSVG_SPREAD_PAD: pattern.mExtend = EPatternExtend::Pad;
break;
2846 case NSVG_SPREAD_REFLECT: pattern.mExtend = EPatternExtend::Reflect;
break;
2847 case NSVG_SPREAD_REPEAT: pattern.mExtend = EPatternExtend::Repeat;
break;
2851 for (
int i = 0; i < pGrad->nstops; i++)
2853 unsigned int color = pGrad->stops[i].color;
2854 pattern.AddStop(
IColor(255, (color >> 0) & 0xFF, (color >> 8) & 0xFF, (color >> 16) & 0xFF), pGrad->stops[i].offset);
2858 pattern.SetTransform(pGrad->xform[0], pGrad->xform[1], pGrad->xform[2], pGrad->xform[3], pGrad->xform[4], pGrad->xform[5]);
2863 return IColor(alpha, 0, 0, 0);
2867void IGraphics::DoDrawSVG(
const ISVG& svg,
const IBlend* pBlend,
const IColor* pStrokeColor,
const IColor* pFillColor)
2871 svg.mSVGDom->render(canvas);
2873 NSVGimage* pImage = svg.mImage;
2875 assert(pImage !=
nullptr);
2877 for (NSVGshape* pShape = pImage->shapes; pShape; pShape = pShape->next)
2879 if (!(pShape->flags & NSVG_FLAGS_VISIBLE))
2886 for (NSVGpath* pPath = pShape->paths; pPath; pPath = pPath->next)
2890 for (
int i = 1; i < pPath->npts; i += 3)
2892 float *p = &pPath->pts[i*2];
2901 IVec2 p0{pPath->pts[0], pPath->pts[1]};
2902 IVec2 p1{pPath->bounds[0] - 1.0f, pPath->bounds[1] - 1.0f};
2904 for (NSVGpath *pPath2 = pShape->paths; pPath2; pPath2 = pPath2->next)
2906 if (pPath2 == pPath)
2909 if (pPath2->npts < 4)
2911 for (
int i = 1; i < pPath2->npts + 3; i += 3)
2913 float *p = &pPath2->pts[2*i];
2915 IVec2 p2 {p[-2], p[-1]};
2917 IVec2 p3 = (i < pPath2->npts) ?
IVec2{p[4], p[5]} :
IVec2{pPath2->pts[0], pPath2->pts[1]};
2918 float crossing = GetLineCrossing(p0, p1, p2, p3);
2919 float crossing2 = GetLineCrossing(p2, p3, p0, p1);
2920 if (0.0 <= crossing && crossing < 1.0 && 0.0 <= crossing2)
2930 if (pShape->fill.type != NSVG_PAINT_NONE)
2933 options.mFillRule = EFillRule::Preserve;
2935 options.mPreserve = pShape->stroke.type != NSVG_PAINT_NONE;
2936 PathFill(pFillColor ?
IPattern(*pFillColor) : GetSVGPattern(pShape->fill, pShape->opacity), options, pBlend);
2940 if (pShape->stroke.type != NSVG_PAINT_NONE)
2944 options.mMiterLimit = pShape->miterLimit;
2946 switch (pShape->strokeLineCap)
2948 case NSVG_CAP_BUTT: options.mCapOption = ELineCap::Butt;
break;
2949 case NSVG_CAP_ROUND: options.mCapOption = ELineCap::Round;
break;
2950 case NSVG_CAP_SQUARE: options.mCapOption = ELineCap::Square;
break;
2953 switch (pShape->strokeLineJoin)
2955 case NSVG_JOIN_MITER: options.mJoinOption = ELineJoin::Miter;
break;
2956 case NSVG_JOIN_ROUND: options.mJoinOption = ELineJoin::Round;
break;
2957 case NSVG_JOIN_BEVEL: options.mJoinOption = ELineJoin::Bevel;
break;
2960 options.mDash.SetDash(pShape->strokeDashArray, pShape->strokeDashOffset, pShape->strokeDashCount);
2962 PathStroke(pStrokeColor ?
IPattern(*pStrokeColor) : GetSVGPattern(pShape->stroke, pShape->opacity), pShape->strokeWidth, options, pBlend);
This file contains the base IControl implementation, along with some base classes for specific types ...
A collection of IControls for common UI widgets, such as knobs, sliders, switches.
const void * LoadWinResource(const char *resID, const char *type, int &sizeInBytes, void *pHInstance)
Load a resource from the binary (windows only).
EResourceLocation LocateResource(const char *fileNameOrResID, const char *type, WDL_String &result, const char *bundleID, void *pHInstance, const char *sharedResourcesSubPath)
Find the absolute path of a resource based on it's file name (e.g.
A Text entry widget drawn by IGraphics to optionally override platform text entries.
A base class interface for a bitmap abstraction around the different drawing back end bitmap represen...
float GetDrawScale() const
A basic control to draw a bitmap, or one frame of a stacked bitmap depending on the current value.
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
A special control to draw contextual info as a slider etc is moved If used in the main IControl stack...
The lowest level base class of an IGraphics control.
virtual bool GetWantsGestures() const
virtual void OnResize()
Called when IControl is constructed or resized using SetRect().
const char * GetGroup() const
Get the group that the control belongs to, if any.
int GetTextEntryLength() const
Get the max number of characters that are allowed in text entry.
virtual void OnDropMultiple(const std::vector< const char * > &paths)
Implement to handle multiple items drag 'n dropped onto this control.
virtual bool OnKeyUp(float x, float y, const IKeyPress &key)
Implement this method to respond to a key up event on this control.
virtual void OnMouseOut()
Implement this method to respond to a mouseout event on this control.
bool GetWantsMultiTouch() const
virtual void OnGUIIdle()
This is an idle timer tick call on the GUI thread, only active if USE_IDLE_CALLS is defined.
bool GetMouseEventsWhenDisabled() const
bool GetMouseOverWhenDisabled() const
virtual void OnMouseOver(float x, float y, const IMouseMod &mod)
Implement this method to respond to a mouseover event on this control.
virtual void SetPosition(float x, float y)
Set the position of the control, preserving the width and height.
void SetGroup(const char *groupName)
Assign the control to a control group.
virtual void OnPopupMenuSelection(IPopupMenu *pSelectedMenu, int valIdx)
Implement this method to handle popup menu selection after IGraphics::CreatePopupMenu/IControlPromptU...
virtual void OnMouseDown(float x, float y, const IMouseMod &mod)
Implement this method to respond to a mouse down event on this control.
virtual void SetValueFromUserInput(double value, int valIdx=0)
Set the control's value after user input.
virtual bool IsDirty()
Called at each display refresh by the IGraphics draw loop, after IControl::Animate(),...
virtual bool IsHit(float x, float y) const
Hit test the control.
virtual void Hide(bool hide)
Shows or hides the IControl.
virtual void OnRescale()
Implement to do something when graphics is scaled globally (e.g.
void SetDelegate(IGEditorDelegate &dlg)
Used internally to set the mDelegate (and mGraphics) variables.
virtual void OnDeleteFromPopupMenu(IPopupMenu *pMenu, int itemIdx)
Implement this method to handle popup menu deletion interactions (on IOS) after IGraphics::CreatePopu...
virtual void OnTouchCancelled(float x, float y, const IMouseMod &mod)
Implement this method to respond to a touch cancel event on this control.
virtual void OnDrop(const char *str)
Implement to do something when something was drag 'n dropped onto this control.
int GetParamIdx(int valIdx=0) const
Get the index of a parameter that the control is linked to Normaly controls are either linked to a si...
const IRECT & GetRECT() const
Get the rectangular draw area for this control, within the graphics context.
virtual bool OnKeyDown(float x, float y, const IKeyPress &key)
Implement this method to respond to a key down event on this control.
int LinkedToParam(int paramIdx) const
Check if the control is linked to a particular parameter.
bool GetIgnoreMouse() const
virtual void OnMouseDblClick(float x, float y, const IMouseMod &mod)
Implement this method to respond to a mouse double click event on this control.
int GetTag() const
Get the control's tag.
virtual void OnMouseUp(float x, float y, const IMouseMod &mod)
Implement this method to respond to a mouse up event on this control.
virtual void DrawPTHighlight(IGraphics &g)
Implement this to customise how a colored highlight is drawn on the control in ProTools (AAX format o...
virtual void CreateContextMenu(IPopupMenu &contextMenu)
Called by default when the user right clicks a control.
virtual void OnAttached()
Called after the control has been attached, and its delegate and graphics member variable set.
virtual bool OnGesture(const IGestureInfo &info)
virtual void OnMouseDrag(float x, float y, float dX, float dY, const IMouseMod &mod)
Implement this method to respond to a mouse drag event on this control.
virtual void OnMouseWheel(float x, float y, const IMouseMod &mod, float d)
Implement this method to respond to a mouse wheel event on this control.
virtual void Draw(IGraphics &g)=0
Draw the control to the graphics context.
const IParam * GetParam(int valIdx=0) const
Get a const pointer to the IParam object (owned by the editor delegate class), associated with this c...
const IText & GetText() const
Get the Text object for the control.
bool GetMouseDblAsSingleClick() const
Get double click as single click By default, mouse double click has its own handler.
virtual void SetSize(float w, float h)
Set the size of the control, preserving the current position.
void SetPTParameterHighlight(bool isHighlighted, int color)
Used internally by the AAX wrapper view interface to set the control parmeter highlight.
virtual void OnTextEntryCompletion(const char *str, int valIdx)
Implement this method to handle text input after IGraphics::CreateTextEntry/IControlPromptUserInput.
virtual void SetDisabled(bool disable)
Sets disabled mode for the control, the default implementation modifies the mBlend member.
double GetValue(int valIdx=0) const
Get the control's value.
void SetTargetAndDrawRECTs(const IRECT &bounds)
Set BOTH the draw rect and the target area, within the graphics context for this control.
virtual void OnContextSelection(int itemSelected)
Implement this to respond to a menu selection from CreateContextMenu();.
virtual int GetValIdxForPos(float x, float y) const
Check to see which of the control's values relates to this x and y coordinate.
IContainerBase * GetParent() const
virtual void SetDirty(bool triggerAction=true, int valIdx=kNoValIdx)
Mark the control as dirty, i.e.
bool GetPromptShowsParamLabel() const
A control for resizing the plug-in window by clicking and dragging in the bottom right-hand corner Th...
virtual void BeginInformHostOfParamChangeFromUI(int paramIdx)=0
Called by the UI at the beginning of a parameter change gesture, in order to notify the host (via a c...
virtual void EndInformHostOfParamChangeFromUI(int paramIdx)=0
Called by the user interface at the end of a parameter change gesture, in order to notify the host (v...
virtual void SendMidiMsgFromUI(const IMidiMsg &msg)
SendMidiMsgFromUI (Abbreviation: SMMFUI) This method should be used when sending a MIDI message from ...
virtual bool ConstrainEditorResize(int &w, int &h) const
Constrain the incoming editor width and height values based on the minimum and maximum.
virtual bool EditorResizeFromUI(int viewWidth, int viewHeight, bool needsPlatformResize)
If the editor changes UI dimensions, e.g.
An editor delegate base class that uses IGraphics for the UI.
virtual void LayoutUI(IGraphics *pGraphics)
Called to layout controls when the GUI is initially opened and again if the UI size changes.
bool ControlIsCaptured() const
Check to see if any control is captured.
void EnableTooltips(bool enable)
virtual float DoMeasureText(const IText &text, const char *str, IRECT &bounds) const =0
Internal method to measure text dimensions.
void Resize(int w, int h, float scale, bool needsPlatformResize=true)
Resizes the graphics context to new dimensions and scale.
virtual void DrawRotatedSVG(const ISVG &svg, float destCentreX, float destCentreY, float width, float height, double angle, const IBlend *pBlend=0)
Draw an SVG image to the graphics context with rotation.
virtual void DrawRect(const IColor &color, const IRECT &bounds, const IBlend *pBlend=0, float thickness=1.f)
Draw a rectangle to the graphics context.
virtual void FillEllipse(const IColor &color, const IRECT &bounds, const IBlend *pBlend=0)
Fill an ellipse within a rectangular region of the graphics context.
ILayer * PopLayer()
Pop a layer off the stack.
virtual void DrawConvexPolygon(const IColor &color, float *x, float *y, int nPoints, const IBlend *pBlend=0, float thickness=1.f)
Draw a convex polygon to the graphics context.
virtual void DrawEllipse(const IColor &color, const IRECT &bounds, const IBlend *pBlend=0, float thickness=1.f)
Draw an ellipse within a rectangular region of the graphics context.
virtual void DrawFittedBitmap(const IBitmap &bitmap, const IRECT &bounds, const IBlend *pBlend=0)
Draw a bitmap (raster) image to the graphics context, scaling the image to fit the bounds.
void DrawBitmapedText(const IBitmap &bitmap, const IRECT &bounds, IText &text, IBlend *pBlend, const char *str, bool vCenter=true, bool multiline=false, int charWidth=6, int charHeight=12, int charOffset=0)
Draws mono spaced bitmap text.
void AttachPopupMenuControl(const IText &text=DEFAULT_TEXT, const IRECT &bounds=IRECT())
Attach a control for pop-up menus, to override platform style menus.
virtual void DrawPoint(const IColor &color, float x, float y, const IBlend *pBlend=0)
Fill a rectangle corresponding to a pixel on a 1:1 screen with a color.
void RemoveControl(int idx)
Remove a control at a particular index, (frees memory).
void DeleteFromPopupMenu(IPopupMenu *pMenu, int itemIdx)
Called by IOS platform (or other supported platforms) in order to update a control with a deletion in...
virtual const char * GetBundleID() const
Get the bundle ID on macOS and iOS, returns emtpy string on other OSs.
void PathConvexPolygon(float *x, float *y, int nPoints)
Add a convex polygon to the current path.
virtual void PathFill(const IPattern &pattern, const IFillOptions &options=IFillOptions(), const IBlend *pBlend=0)=0
Fill the current current path.
virtual float GetPlatformWindowScale() const
Returns a scaling factor for resizing parent windows via the host/plugin API.
void DrawText(const IText &text, const char *str, const IRECT &bounds, const IBlend *pBlend=0)
Draw some text to the graphics context in a specific rectangle.
float GetTotalScale() const
Gets the combined draw and screen/display scaling factor.
int GetParamIdxForPTAutomation(float x, float y)
[AAX only] This can be called by the ProTools API class (e.g.
void CreatePopupMenu(IControl &control, IPopupMenu &menu, const IRECT &bounds, int valIdx=0)
Shows a pop up/contextual menu in relation to a rectangular region of the graphics context.
void CreateTextEntry(IControl &control, const IText &text, const IRECT &bounds, const char *str="", int valIdx=0)
Create a text entry box.
virtual void PathClear()=0
Clear the stack of path drawing commands.
virtual void * GetDrawContext()=0
Gets a void pointer to underlying drawing context, for the IGraphics backend See draw class implement...
void PathRoundRect(const IRECT &bounds, float ctl, float ctr, float cbl, float cbr)
Add a rounded rectangle to the current path, with independent corner roundness.
void SetPTParameterHighlight(int paramIdx, bool isHighlighted, int color)
[AAX only] See AAX_CEffectGUI::SetControlHighlightInfo()
virtual void PathClose()=0
Close the path that is being specified.
void PathTransformTranslate(float x, float y)
Apply a translation transform to the current path.
void ClearInTextEntryControl()
Called when the text entry is dismissed, to reset mInTextEntry.
void DrawRadialLine(const IColor &color, float cx, float cy, float angle, float rMin, float rMax, const IBlend *pBlend=0, float thickness=1.f)
Draw a radial line to the graphics context, useful for pointers on dials.
void PathRect(const IRECT &bounds)
Add a rectangle to the current path.
virtual void RetainBitmap(const IBitmap &bitmap, const char *cacheName)
Adds an IBitmap to the cache/static storage.
void ForMatchingControls(T method, int paramIdx, Args... args)
For all standard controls in the main control stack that are linked to a specific parameter,...
virtual void CreatePlatformTextEntry(int paramIdx, const IText &text, const IRECT &bounds, int length, const char *str)=0
Creates a platform native text entry field.
void ResumeLayer(ILayerPtr &layer)
If a layer already exists, continue drawing to it.
void PathTransformMatrix(const IMatrix &matrix)
Apply an arbitary affine transform matrix to the current path.
void DrawRotatedLayer(const ILayerPtr &layer, double angle)
Draw a layer to the main IGraphics context, with rotation.
void PathTransformScale(float x, float y)
Apply a scale transform to the current path, with independant x, y scales.
virtual ECursor SetMouseCursor(ECursor cursorType=ECursor::ARROW)
Sets the mouse cursor to one of ECursor (implementations should return the result of the base impleme...
void PathLine(float x1, float y1, float x2, float y2)
Add a line to the current path.
virtual void DrawDottedRect(const IColor &color, const IRECT &bounds, const IBlend *pBlend=0, float thickness=1.f, float dashLen=2.f)
Draw a dotted rectangle to the graphics context.
IControl * GetControlWithTag(int ctrlTag) const
Get the control with a particular tag.
virtual void PathSetWinding(bool clockwise)
NanoVG only.
void OnMouseDrag(const std::vector< IMouseInfo > &points)
Called when the platform class sends drag events.
virtual void ReleaseBitmap(const IBitmap &bitmap)
Releases an IBitmap from the cache/static storage.
virtual void DrawRoundRect(const IColor &color, const IRECT &bounds, float cornerRadius=5.f, const IBlend *pBlend=0, float thickness=1.f)
Draw a rounded rectangle to the graphics context.
void OnMouseOut()
Called when the mouse leaves the graphics context.
void UpdatePeers(IControl *pCaller, int callerValIdx)
This method is called after interacting with a control, so that any other controls linked to the same...
void RemovePopupMenuControl()
Remove the IGraphics popup menu, use platform popup menu if available.
virtual float GetBackingPixelScale() const
virtual void DrawRotatedBitmap(const IBitmap &bitmap, float destCentreX, float destCentreY, double angle, const IBlend *pBlend=0)
Draw a bitmap (raster) image to the graphics context with rotation.
bool OnKeyDown(float x, float y, const IKeyPress &key)
virtual int AlphaChannel() const =0
void AttachGestureRecognizerToRegion(const IRECT &bounds, EGestureType type, IGestureFunc func)
Attach a gesture recognizer to a rectangular region of the GUI, i.e.
bool MultiTouchEnabled() const
int Width() const
Gets the width of the graphics context.
virtual void EndFrame()
Called by some drawing API classes to finally blit the draw bitmap onto the screen or perform other c...
void DisableControl(int paramIdx, bool diable)
Disable or enable controls linked to a specific parameter.
void SetControlBounds(IControl *pControl, const IRECT &r)
Set a controls target and draw rect to r, redrawing the interface correctly.
void PathTriangle(float x1, float y1, float x2, float y2, float x3, float y3)
Add a triangle to the current path.
void DoMeasureTextRotation(const IText &text, const IRECT &bounds, IRECT &rect) const
Measures text bounds accounting for rotation.
void AttachTextEntryControl()
Attach a control for text entry, to override platform text entry.
void AttachCornerResizer(EUIResizerMode sizeMode=EUIResizerMode::Scale, bool layoutOnResize=false, const IColor &color=COLOR_TRANSLUCENT, const IColor &mouseOverColor=COLOR_BLACK, const IColor &dragColor=COLOR_BLACK, float size=20.f)
Attach the default control to scale or increase the UI size by dragging the plug-in bottom right-hand...
virtual void AttachGestureRecognizer(EGestureType type)
Registers a gesture recognizer with the graphics context.
virtual APIBitmap * CreateAPIBitmap(int width, int height, float scale, double drawScale, bool cacheable=false)=0
Creates a new API bitmap, either in memory or as a GPU texture.
void OnMouseUp(const std::vector< IMouseInfo > &points)
Called when the platform class sends mouse up events.
void PathTransformReset(bool clearStates=false)
Reset the affine transform of the current path, to the default state.
void OnAppearanceChanged(EUIAppearance appearance)
Called by the platform class if the view changes to dark/light mode.
void CalculateTextRotation(const IText &text, const IRECT &bounds, IRECT &rect, double &tx, double &ty) const
Calculates rotation parameters for text drawing.
bool IsInPlatformTextEntry()
virtual void PathStroke(const IPattern &pattern, float thickness, const IStrokeOptions &options=IStrokeOptions(), const IBlend *pBlend=0)=0
Stroke the current current path.
bool CheckLayer(const ILayerPtr &layer)
Test to see if a layer needs drawing, for instance if the control's bounds were changed.
int WindowWidth() const
Gets the width of the graphics context including draw scaling.
void Draw(IRECTList &rects)
Called by the platform class indicating a number of rectangles in the UI that need to redraw.
EResourceLocation SearchImageResource(const char *fileName, const char *type, WDL_String &result, int targetScale, int &sourceScale)
Search for a bitmap image resource matching the target scale.
IControl * GetControlWithParamIdx(int paramIdx)
Get the first control with a parameter index that matches paramIdx.
virtual void ApplyShadowMask(ILayerPtr &layer, RawBitmapData &mask, const IShadow &shadow)=0
Implemented by a graphics backend to apply a calculated shadow mask to a layer, according to the shad...
void EnableLiveEdit(bool enable)
Live edit mode allows you to relocate controls at runtime in debug builds.
void PathTransformRestore()
Restore the affine transform of the current path, to the previously saved state.
void SetControlValueAfterPopupMenu(IPopupMenu *pMenu)
Called by PopupMenuControl in order to update a control with a new value after returning from the non...
void DrawLayer(const ILayerPtr &layer, const IBlend *pBlend=nullptr)
Draw a layer to the main IGraphics context.
void PushLayer(ILayer *pLayer)
Push a layer on to the stack.
void ReleaseMouseCapture()
Used to tell the graphics context to stop tracking mouse interaction with a control.
int GetLastClickedParamForPTAutomation()
[AAX only]
void ForControlWithParam(int paramIdx, IControlFunction func)
For all standard controls in the main control stack that are linked to a specific parameter,...
void AttachBubbleControl(const IText &text=DEFAULT_TEXT)
Attach the default control to show text as a control changes.
EUIResizerMode GetResizerMode() const
virtual void FillRect(const IColor &color, const IRECT &bounds, const IBlend *pBlend=0)
Fill a rectangular region of the graphics context with a color.
int GetRoundedScreenScale() const
Gets the screen/display scaling factor, rounded up.
APIBitmap * SearchBitmapInCache(const char *fileName, int targetScale, int &sourceScale)
Search the static storage cache for a bitmap image resource matching the target scale.
virtual void DrawLine(const IColor &color, float x1, float y1, float x2, float y2, const IBlend *pBlend=0, float thickness=1.f)
Draw a line to the graphics context.
virtual void DrawArc(const IColor &color, float cx, float cy, float r, float a1, float a2, const IBlend *pBlend=0, float thickness=1.f)
Draw an arc to the graphics context.
void OnTouchCancelled(const std::vector< IMouseInfo > &points)
Called when the platform class sends touch cancel events.
bool OnMouseOver(float x, float y, const IMouseMod &mod)
void OnDragResize(float x, float y)
Called by ICornerResizerControl as the corner is dragged to resize.
virtual PlatformFontPtr LoadPlatformFont(const char *fontID, const char *fileNameOrResID)=0
Load a font from disk or resource in a platform format.
void ForAllControlsFunc(IControlFunction func)
For all controls, including the "special controls" call a method.
void HideControl(int paramIdx, bool hide)
Hide controls linked to a specific parameter.
virtual bool LoadFont(const char *fontID, const char *fileNameOrResID)
Load a font to be used by the graphics context.
virtual bool BitmapExtSupported(const char *ext)=0
Checks a file extension and reports whether this drawing API supports loading that extension.
void RemoveAllControls()
Removes all regular IControls from the control list, as well as special controls (frees memory).
virtual void DrawCircle(const IColor &color, float cx, float cy, float r, const IBlend *pBlend=0, float thickness=1.f)
Draw a circle to the graphics context.
void OnMouseDown(const std::vector< IMouseInfo > &points)
Called when the platform class sends mouse down events.
int Height() const
Gets the height of the graphics context.
void PathClipRegion(const IRECT r=IRECT())
Clip the current path to a particular region.
void PathCircle(float cx, float cy, float r)
Add a circle to the current path.
void PathRadialLine(float cx, float cy, float angle, float rMin, float rMax)
Add a radial line to the current path.
void PathTransformRotate(float angle)
Apply a rotation transform to the current path.
bool OnKeyUp(float x, float y, const IKeyPress &key)
bool IsDirty(IRECTList &rects)
Called repeatedly at frame rate by the platform class to check what the graphics context says is dirt...
virtual void FillRoundRect(const IColor &color, const IRECT &bounds, float cornerRadius=5.f, const IBlend *pBlend=0)
Fill a rounded rectangle with a color.
virtual void GetLayerBitmapData(const ILayerPtr &layer, RawBitmapData &data)=0
Get the contents of a layer as Raw RGBA bitmap data NOTE: you should only call this within IControl::...
bool RespondsToGesture(float x, float y)
Called by platform class to see if the point at x, y is linked to a gesture recognizer.
void ForAllControls(T method, Args... args)
For all controls, including the "special controls" call a method.
void ClearGestureRegions()
Remove all gesture recognizers linked to regions.
void SetControlValueAfterTextEdit(const char *str)
Called by the platform class after returning from a text entry in order to update a control with a ne...
virtual void * GetWinModuleHandle()
virtual void UpdateLayer()
Implemented by a graphics backend to prepare for drawing to the layer at the top of the stack.
virtual void DrawData(const IColor &color, const IRECT &bounds, float *normYPoints, int nPoints, float *normXPoints=nullptr, const IBlend *pBlend=0, float thickness=1.f, const IColor *pFillColor=nullptr)
Draw a line between a collection of normalized points.
void SetQwertyMidiKeyHandlerFunc(std::function< void(const IMidiMsg &msg)> func=nullptr)
A helper to set the IGraphics KeyHandlerFunc in order to make an instrument playable via QWERTY keys.
void AttachSVGBackground(const char *fileName)
Attach an ISVGControl as the lowest IControl in the control stack to be the background for the graphi...
virtual void FillTriangle(const IColor &color, float x1, float y1, float x2, float y2, float x3, float y3, const IBlend *pBlend=0)
Fill a triangle with a color.
virtual void ApplyLayerDropShadow(ILayerPtr &layer, const IShadow &shadow)
Applies a drop shadow directly onto a layer.
virtual void DrawGrid(const IColor &color, const IRECT &bounds, float gridSizeH, float gridSizeV, const IBlend *pBlend=0, float thickness=1.f)
Draw a grid to the graphics context.
void SetAllControlsDirty()
Calls SetDirty() on every control.
virtual IBitmap ScaleBitmap(const IBitmap &inBitmap, const char *cacheName, int targetScale)
Returns a new IBitmap, an integer scaled version of the input, and adds it to the cache.
IControl * GetControlInTextEntry()
IBitmap GetScaledBitmap(IBitmap &inBitmap)
Get a version of the input bitmap from the cache that corresponds to the current screen scale For exa...
void AttachPanelBackground(const IPattern &color)
Attach an IPanelControl as the lowest IControl in the control stack to fill the background with a sol...
virtual void FillConvexPolygon(const IColor &color, float *x, float *y, int nPoints, const IBlend *pBlend=0)
Fill a convex polygon with a color.
bool OnMouseWheel(float x, float y, const IMouseMod &mod, float delta)
void SetAllControlsClean()
Calls SetClean() on every control.
void StyleAllVectorControls(const IVStyle &style)
Helper method to style all of the controls which inherit IVectorBase.
virtual IPopupMenu * CreatePlatformPopupMenu(IPopupMenu &menu, const IRECT bounds, bool &isAsync)=0
Calls the platform backend to create the platform popup menu.
void RemoveControlWithTag(int ctrlTag)
Remove controls from the control list with a particular tag.
void GetTouches(IControl *pControl, std::vector< ITouchID > &touchesOnThisControl) const
Populate a vector with the touchIDs active on pControl.
void DrawVerticalLine(const IColor &color, const IRECT &bounds, float x, const IBlend *pBlend=0, float thickness=1.f)
Draw a vertical line, within a rectangular region of the graphics context.
virtual void PathMoveTo(float x, float y)=0
Move the current point in the current path.
virtual void PathArc(float cx, float cy, float r, float a1, float a2, EWinding winding=EWinding::CW)=0
Add an arc to the current path.
void PopupHostContextMenuForParam(int controlIdx, int paramIdx, float x, float y)
[VST3 primarily] In VST3 plug-ins this enable support for the IContextMenu interface,...
virtual bool FlippedBitmap() const =0
void PromptUserInput(IControl &control, const IRECT &bounds, int valIdx=0)
Prompt for user input either using a text entry or pop up menu.
void SetControlSize(IControl *pControl, float w, float h)
Resize a control, redrawing the interface correctly.
float GetScreenScale() const
Gets the screen/display scaling factor, e.g.
virtual bool LoadAPIFont(const char *fontID, const PlatformFontPtr &font)=0
Drawing API method to load a font from a PlatformFontPtr, called internally.
void OnDropMultiple(const std::vector< const char * > &paths, float x, float y)
void AssignParamNameToolTips()
Call this method in order to create tool tips for every IControl that show the associated parameter's...
virtual ISVG LoadSVG(const char *fileNameOrResID, const char *units="px", float dpi=72.f)
Load an SVG from disk or from windows resource.
virtual APIBitmap * LoadAPIBitmap(const char *fileNameOrResID, int scale, EResourceLocation location, const char *ext)=0
Drawing API method to load a bitmap, called internally.
virtual void HideMouseCursor(bool hide=true, bool lock=true)=0
Call to hide/show the mouse cursor.
void SetScaleConstraints(float lo, float hi)
Sets the minimum and maximum (draw) scaling values.
void DrawHorizontalLine(const IColor &color, const IRECT &bounds, float y, const IBlend *pBlend=0, float thickness=1.f)
Draw a horizontal line, within a rectangular region of the graphics context.
void ForControlInGroup(const char *group, IControlFunction func)
For all standard controls in the main control stack that are linked to a group, execute a function.
virtual void DoDrawText(const IText &text, const char *str, const IRECT &bounds, const IBlend *pBlend=nullptr)=0
Internal method to draw text.
void PathTransformSave()
Save the current affine transform of the current path.
virtual void FillArc(const IColor &color, float cx, float cy, float r, float a1, float a2, const IBlend *pBlend=0)
Fill an arc segment with a color.
void SetKeyHandlerFunc(IKeyHandlerFunc func)
Set a function that is called when key presses are not intercepted by any controls.
virtual void DrawDottedLine(const IColor &color, float x1, float y1, float x2, float y2, const IBlend *pBlend=0, float thickness=1.f, float dashLen=2.f)
Draw a dotted line to the graphics context.
void RemoveTextEntryControl()
Remove the IGraphics text entry, use platform text entry if available.
void ShowFPSDisplay(bool enable)
Shows a control to display the frame rate of drawing.
virtual void PathLineTo(float x, float y)=0
Add a line to the current path from the current point to the specified location.
void DrawLineAcross(const IColor &color, const IRECT &bounds, EDirection dir, float pos, const IBlend *pBlend=0, float thickness=1.f)
Draw a horzional or vertical line, within a rectangular region of the graphics context.
const char * GetSharedResourcesSubPath() const
Gets the name of the shared resources subpath.
void PathTransformSkew(float xAngle, float yAngle)
Apply a skew transform to the current path.
float GetDrawScale() const
Gets the graphics context scaling factor.
void DrawFittedLayer(const ILayerPtr &layer, const IRECT &bounds, const IBlend *pBlend)
Draw a layer to the main IGraphics context, fitting it to a rectangle that is different to the layer'...
void RemoveControls(int fromIdx)
Remove controls from the control list above a particular index, (frees memory).
void AttachBackground(const char *fileName)
Attach an IBitmapControl as the lowest IControl in the control stack to be the background for the gra...
void SetStrictDrawing(bool strict)
Enables strict drawing mode.
void OnGUIIdle()
This is an idle timer tick call on the GUI thread, only active if USE_IDLE_CALLS is defined.
IGEditorDelegate * GetDelegate()
Gets a pointer to the delegate class that handles communication to and from this graphics context.
IControl * GetControl(int idx)
Get the control at a certain index in the control stack.
void StartLayer(IControl *pOwner, const IRECT &r, bool cacheable=false)
Create an IGraphics layer.
void OnGestureRecognized(const IGestureInfo &info)
Called by platform class when a gesture is recognized.
virtual void CachePlatformFont(const char *fontID, const PlatformFontPtr &font)=0
Called to indicate that the platform should cache data about the platform font if needed.
bool OnMouseDblClick(float x, float y, const IMouseMod &mod)
virtual void DrawSVG(const ISVG &svg, const IRECT &bounds, const IBlend *pBlend=0, const IColor *pStrokeColor=nullptr, const IColor *pFillColor=nullptr)
Draw an SVG image to the graphics context.
void ForStandardControlsFunc(IControlFunction func)
For all standard controls in the main control stack perform a function.
virtual void DrawTriangle(const IColor &color, float x1, float y1, float x2, float y2, float x3, float y3, const IBlend *pBlend=0, float thickness=1.f)
Draw a triangle to the graphics context.
virtual void PathCubicBezierTo(float c1x, float c1y, float c2x, float c2y, float x2, float y2)=0
Add a cubic bezier to the current path from the current point to the specified location.
int WindowHeight() const
Gets the height of the graphics context including draw scaling.
void PathEllipse(const IRECT &bounds)
Add an ellipse to the current path, specifying the rectangular region.
virtual IBitmap LoadBitmap(const char *fileNameOrResID, int nStates=1, bool framesAreHorizontal=false, int targetScale=0)
Load a bitmap image from disk or from windows resource.
virtual void BeginFrame()
Called at the beginning of drawing.
virtual void FillCircle(const IColor &color, float cx, float cy, float r, const IBlend *pBlend=0)
Fill a circle with a color.
void SetControlPosition(IControl *pControl, float x, float y)
Reposition a control, redrawing the interface correctly.
void SetScreenScale(float scale)
Called by the platform IGraphics class when moving to a new screen to set DPI.
ILayerPtr EndLayer()
End an IGraphics layer.
virtual WDL_TypedBuf< uint8_t > LoadResource(const char *fileNameOrResID, const char *fileType)
Load a resource from the file system, the bundle, or a Windows resource, and returns its data.
void OnDrop(const char *str, float x, float y)
IRECT GetBounds() const
Returns an IRECT that represents the entire UI bounds This is useful for programatically arranging UI...
IControl * AttachControl(IControl *pControl, int ctrlTag=kNoTag, const char *group="")
Attach an IControl to the graphics context and add it to the top of the control stack.
virtual void DrawBitmap(const IBitmap &bitmap, const IRECT &bounds, int srcX, int srcY, const IBlend *pBlend=0)=0
Draw a bitmap (raster) image to the graphics context.
virtual float MeasureText(const IText &text, const char *str, IRECT &bounds) const
Measure the rectangular region that some text will occupy.
An abstraction that is used to store a temporary raster image/framebuffer.
const IRECT & Bounds() const
A basic control to fill a rectangle with a color or gradient.
EParamType Type() const
Get the parameter's type.
double ToNormalized(double nonNormalizedValue) const
Convert a real value to normalized value for this parameter.
void GetDisplay(WDL_String &display, bool withDisplayText=true) const
Get the current textual display for the current parameter value.
const char * GetLabel() const
Returns the parameter's label.
double StringToValue(const char *str) const
Convert a textual representation of the parameter value to a double (real value)
const char * GetName() const
Returns the parameter's name.
const char * GetDisplayText(double value) const
Get the display text for a particular value.
int NDisplayTexts() const
Get the number of display texts for the parameter.
EParamType
Defines types or parameter.
Used to manage a list of rectangular areas and optimize them for drawing to the screen.
void Clear()
Clear the list.
IRECT Bounds()
Get a union of all rectangles in the list.
void Add(const IRECT &rect)
Add a rectangle to the list.
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.
const IRECT & Get(int idx) const
Get an IRECT from the list (will crash if idx is invalid)
A basic control to draw an SVG image to the screen.
A base interface to be combined with IControl for vectorial controls "IVControls",...
virtual void SetStyle(const IVStyle &style)
Set the Style of this IVControl.
std::unique_ptr< ILayer > ILayerPtr
ILayerPtr is a managed pointer for transferring the ownership of layers.
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.
Used to manage color data, independent of draw class/platform.
void Randomise(int alpha=255)
Randomise the color parts, with optional alpha.
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 & Rotate(float a)
Set the matrix for a rotation transform.
IMatrix & Scale(float x, float y)
Set the matrix for a scale transform.
IMatrix & Transform(const IRECT &before, const IRECT &after)
Sets up a transformation matrix to map one rectangle to another.
IMatrix & Translate(float x, float y)
Set the matrix for a translation transform.
IMatrix & Skew(float xa, float ya)
Set the matrix for a skew transform.
void TransformPoint(double &x, double &y, double x0, double y0) const
Transforms a point using this matrix.
Encapsulates a MIDI message and provides helper functions.
void MakeNoteOnMsg(int noteNumber, int velocity, int offset, int channel=0)
Make a Note On message.
void MakeNoteOffMsg(int noteNumber, int offset, int channel=0)
Make a Note Off message.
Used to manage mouse modifiers i.e.
Used to store pattern information for gradients.
Used to manage a rectangular area, independent of draw class/platform.
IRECT Intersect(const IRECT &rhs) const
Create a new IRECT that is the intersection of this IRECT and rhs.
IRECT GetFromTLHC(float w, float h) const
Get a subrect of this IRECT expanding from the top-left corner.
IRECT GetPixelAligned() const
Get a copy of this IRECT with PixelAlign() called.
void PixelAlign()
Pixel aligns the rect in an inclusive manner (moves all points outwards)
void Clank(const IRECT &rhs)
Clank will limit this IRECT's bounds based on the boundaries of the IRECT passed in as an argument.
IRECT Union(const IRECT &rhs) const
Create a new IRECT that is a union of this IRECT and rhs.
bool Intersects(const IRECT &rhs) const
Returns true if this IRECT shares any common pixels with rhs, false otherwise.
void Translate(float x, float y)
Translate this rectangle.
bool Contains(const IRECT &rhs) const
Returns true if this IRECT completely contains rhs.
IRECT GetPadded(float padding) const
Get a copy of this IRECT with each value padded by padding N.B.
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.
IText is used to manage font and text/text entry style for a piece of text on the UI,...
A struct encapsulating a set of properties used to configure IVControls.
Encapsulate an xy point in one struct.