19 #ifdef IGRAPHICS_NANOVG 23 using namespace iplug;
24 using namespace igraphics;
27 :
IControl(collapsedBounds, paramIdx)
28 , mSpecifiedCollapsedBounds(collapsedBounds)
29 , mSpecifiedExpandedBounds(expandedBounds)
33 int duration = DEFAULT_ANIMATION_DURATION;
35 if(mState == kSubMenuAppearing)
36 duration = DEFAULT_ANIMATION_DURATION * 2;
38 #pragma mark animations 43 pCaller->OnEndAnimation();
47 if(mState == kExpanding)
49 if(mAppearingMenuPanel !=
nullptr)
50 mAppearingMenuPanel->mBlend.mWeight = (float) progress * mOpacity;
52 else if(mState == kSubMenuAppearing)
54 if(mAppearingMenuPanel !=
nullptr)
55 mAppearingMenuPanel->mBlend.mWeight = (float) (progress > 0.9) * mOpacity;
57 else if(mState == kCollapsing)
59 for (
auto i = 0; i < mMenuPanels.GetSize(); i++) {
60 mMenuPanels.Get(i)->mBlend.mWeight = (float) (1.-progress) * mOpacity;
63 else if(mState == kIdling)
65 for (
auto i = 0; i < mMenuPanels.GetSize(); i++) {
66 mMenuPanels.Get(i)->mBlend.mWeight = 0.f;
77 IPopupMenuControl::~IPopupMenuControl()
79 mMenuPanels.Empty(
true);
84 assert(mMenu !=
nullptr);
86 for (
auto mr = 0; mr < mMenuPanels.GetSize(); mr++)
88 MenuPanel* pMenuPanel = mMenuPanels.Get(mr);
90 if(pMenuPanel->mShouldDraw)
95 int nItems = pMenuPanel->mMenu.NItems();
96 int nCells = pMenuPanel->mCellBounds.GetSize();
98 int endCell = nCells-1;
103 if(pMenuPanel->mScrollItemOffset > 0)
105 IRECT* pCellRect = pMenuPanel->mCellBounds.Get(0);
106 bool sel = mMouseCellBounds == pCellRect || pCellRect == pMenuPanel->mHighlightedCell;
109 DrawUpArrow(g, *pCellRect, sel, &pMenuPanel->mBlend);
114 if(pMenuPanel->mScrollItemOffset < nItems-nCells)
116 IRECT* pCellRect = pMenuPanel->mCellBounds.Get(nCells-1);
117 bool sel = mMouseCellBounds == pCellRect || pCellRect == pMenuPanel->mHighlightedCell;
126 for(
auto i = startCell; i <= endCell; i++)
128 IRECT* pCellRect = pMenuPanel->mCellBounds.Get(i);
129 IPopupMenu::Item* pMenuItem = pMenuPanel->mMenu.GetItem(startCell + pMenuPanel->mScrollItemOffset + cellOffset++);
134 if(pMenuItem->GetIsSeparator())
138 bool sel = mMouseCellBounds == pCellRect || pCellRect == pMenuPanel->mHighlightedCell;
140 if(pMenuPanel->mClickedCell)
142 if(mState != kFlickering)
149 DrawCellText(g, *pCellRect, pMenuItem, sel, &pMenuPanel->mBlend);
151 if(pMenuItem->GetChecked())
152 DrawTick(g, *pCellRect, pMenuItem, sel, &pMenuPanel->mBlend);
154 if(pMenuItem->GetSubmenu())
161 if(mCallOut && mMenuPanels.GetSize())
164 if (mMenuHasSubmenu && mSubMenuOpened)
175 mMouseCellBounds = mActiveMenuPanel->HitTestCells(x, y);
176 CollapseEverything();
186 mMouseCellBounds = mActiveMenuPanel->HitTestCells(x, y);
193 mMouseCellBounds = mActiveMenuPanel->HitTestCells(x, y);
196 if(mMouseCellBounds ==
nullptr)
198 MenuPanel* pMousedMenuPanel =
nullptr;
200 const int nPanels = mMenuPanels.GetSize();
202 for (
auto p = nPanels-1; p >= 0; p--)
204 MenuPanel* pMenuPanel = mMenuPanels.Get(p);
206 if(pMenuPanel->mShouldDraw && pMenuPanel->mRECT.Contains(x, y))
208 pMousedMenuPanel = pMenuPanel;
213 if(pMousedMenuPanel !=
nullptr)
215 mActiveMenuPanel = pMousedMenuPanel;
216 mMouseCellBounds = mActiveMenuPanel->HitTestCells(x, y);
222 if(mActiveMenuPanel->mScroller)
224 if(mMouseCellBounds == mActiveMenuPanel->mCellBounds.Get(0))
226 mActiveMenuPanel->ScrollUp();
228 else if (mMouseCellBounds == mActiveMenuPanel->mCellBounds.Get((mActiveMenuPanel->mCellBounds.GetSize()-1)))
230 mActiveMenuPanel->ScrollDown();
239 mMouseCellBounds =
nullptr;
261 float trisize = bounds.
H();
262 float halftri = trisize * 0.5f;
263 float ax, ay, bx, by, cx, cy;
265 switch (mCalloutArrowDir) {
267 ax = bounds.
MW() - halftri;
268 ay = bounds.
MH() - halftri;
275 ax = bounds.
MW() + halftri;
276 ay = bounds.
MH() + halftri;
283 ax = bounds.
MW() - halftri;
284 ay = bounds.
MH() + halftri;
291 ax = bounds.
MW() - halftri;
292 ay = bounds.
MH() + halftri;
301 g.
FillTriangle(mPanelBackgroundColor, ax, ay, bx, by, cx, cy, pBlend);
306 float trisize = bounds.
H();
307 float halftri = trisize * 0.5f;
308 float ax, ay, bx, by, cx, cy;
312 ax = bounds.
MW() + halftri;
313 ay = bounds.
MH() + halftri;
321 ax = bounds.
MW() - halftri;
322 ay = bounds.
MH() + halftri;
328 g.
FillTriangle(mPanelBackgroundColor, ax, ay, bx, by, cx, cy, pBlend);
334 g.
FillRoundRect(mPanelBackgroundColor, panel->mTargetRECT, mRoundness, &panel->mBlend);
352 IRECT textRect =
IRECT(tickRect.
R + TEXT_HPAD, bounds.
T, bounds.
R - TEXT_HPAD, bounds.
B);
355 mText.mFGColor = mItemMouseoverColor;
358 if(pItem->GetEnabled())
359 mText.mFGColor = mItemColor;
361 mText.mFGColor = mDisabledItemColor;
364 mText.mAlign = EAlign::Near;
365 g.
DrawText(mText, pItem->GetText(), textRect, pBlend);
376 float trisize, halftri, ax, ay, bx, by, cx, cy;
380 IRECT tri =
IRECT(bounds.
R + (PAD * 0.5f) - bounds.
H(), bounds.
T, bounds.
R + (PAD * 0.5f), bounds.
B);
381 trisize = (tri.
R - tri.
L) * 0.5f;
382 halftri = trisize * 0.5f;
383 ax = tri.
R - trisize;
384 ay = tri.
MH() + halftri;
392 IRECT tri =
IRECT(bounds.
L - (PAD * 0.5f), bounds.
T, bounds.
L - (PAD * 0.5f) + bounds.
H(), bounds.
B);
393 trisize = (tri.
R - tri.
L) * 0.5f;
394 halftri = trisize * 0.5f;
395 ax = tri.
L + trisize;
396 ay = tri.
MH() + halftri;
402 g.
FillTriangle(sel ? mItemMouseoverColor : mItemColor, ax, ay, bx, by, cx, cy, pBlend);
407 IRECT tri =
IRECT(bounds.
MW() - (bounds.
H() * 0.5f), bounds.
T, bounds.
MW() + (bounds.
H() * 0.5f), bounds.
B);
408 float trisize = (tri.
R - tri.
L) * 0.6f;
409 float halftri = trisize * 0.5f;
410 float ax = tri.
MW() - halftri;
411 float ay = tri.
MH() + halftri;
412 float bx = ax + trisize;
415 float cy = ay - trisize;
416 g.
FillTriangle(sel ? mItemMouseoverColor : mItemColor, ax, ay, bx, by, cx, cy, pBlend);
421 IRECT tri =
IRECT(bounds.
MW() - (bounds.
H() * 0.5f), bounds.
T, bounds.
MW() + (bounds.
H() * 0.5f), bounds.
B);
422 float trisize = (tri.
R - tri.
L) * 0.6f;
423 float halftri = trisize * 0.5f;
424 float ax = tri.
MW() - halftri;
425 float ay = tri.
MH() - halftri;
426 float bx = ax + trisize;
429 float cy = ay + trisize;
430 g.
FillTriangle(sel ? mItemMouseoverColor : mItemColor, ax, ay, bx, by, cx, cy, pBlend);
435 if(pBlend->mWeight > 0.9)
436 g.
FillRect(mSeparatorColor, bounds, &BLEND_25);
443 for (
int i = 0; i< mMenu->NItems(); i++)
445 if (mMenu->GetItem(i)->GetSubmenu())
447 mMenuHasSubmenu =
true;
450 else mMenuHasSubmenu =
false;
453 if(mMaxBounds.
W() == 0)
460 IRECT IPopupMenuControl::GetLargestCellRectForMenu(
IPopupMenu& menu,
float x,
float y)
const 464 for (
auto i = 0; i < menu.NItems(); ++i)
471 pGraphics->
MeasureText(mText, pItem->GetText(), textBounds);
472 span = span.
Union(textBounds);
475 span.
HPad(TEXT_HPAD);
476 span.
Pad(TICK_SIZE, 0, ARROW_SIZE, 0);
478 return IRECT(x, y, x + span.
W(), y + span.
H());
481 void IPopupMenuControl::GetPanelDimensions(
IPopupMenu&menu,
float& width,
float& height)
const 483 IRECT maxCell = GetLargestCellRectForMenu(menu, 0, 0);
485 int numItems = menu.NItems();
486 int numSeparators = 0;
487 float panelHeight = 0.f;
489 for (
auto i = 0; i < numItems; ++i)
492 if (pItem->GetIsSeparator())
497 float numCells = float(numItems - numSeparators);
498 panelHeight = (numCells * maxCell.
H()) + (numSeparators * mSeparatorSize) + ((numItems - 1) * mCellGap);
501 height = panelHeight;
506 float calloutSpace =0.f;
510 calloutSpace = CALLOUT_SPACE;
513 for(
auto i = 0; i < mActiveMenuPanel->mCellBounds.GetSize(); i++)
515 IRECT* pCellRect = mActiveMenuPanel->mCellBounds.Get(i);
517 IPopupMenu* pSubMenu = pMenuItem->GetSubmenu();
519 if(pCellRect == mMouseCellBounds)
521 if(pSubMenu !=
nullptr)
523 MenuPanel* pMenuPanelForThisMenu =
nullptr;
525 for (
auto mr = 0; mr < mMenuPanels.GetSize(); mr++)
527 MenuPanel* pMenuPanel = mMenuPanels.Get(mr);
529 if(&pMenuPanel->mMenu == pSubMenu)
531 pMenuPanelForThisMenu = pMenuPanel;
532 pMenuPanel->mShouldDraw =
true;
535 pMenuPanel->mShouldDraw =
false;
538 if(pMenuItem->GetEnabled())
539 mActiveMenuPanel->mHighlightedCell = pCellRect;
541 mActiveMenuPanel->mHighlightedCell =
nullptr;
544 if(pMenuPanelForThisMenu ==
nullptr) {
546 float panelWidth = 0.f;
547 float panelHeight = 0.f;
549 GetPanelDimensions(*pSubMenu, panelWidth, panelHeight);
551 float minT = mMaxBounds.
T + mDropShadowSize;
552 float maxB = mMaxBounds.
B - panelHeight - (mDropShadowSize * 2.f);
553 float maxR = mMaxBounds.
R - panelWidth - (mDropShadowSize * 2.f);
554 float minL = mMaxBounds.
L + mDropShadowSize;
559 if (mCalloutArrowDir == kSouth)
561 y = pCellRect->
T - PAD;
562 if (y > maxB) y = maxB;
563 if ( y <= minT) y = minT;
566 if (mCalloutArrowDir == kNorth)
568 y = (pCellRect->
T - (PAD / 2.f) - panelHeight) + (mCellGap * 2.f) + mDropShadowSize;
569 if ( y <= minT) y = minT;
570 if (y > maxB) y = maxB;
573 if (mSubmenuOnRight) x = pCellRect->
R + PAD + calloutSpace;
574 else x = pCellRect->
L - PAD - calloutSpace - panelWidth - mDropShadowSize;
575 if ( x <= minL ) x = minL;
576 if ( x > maxR ) x = maxR;
578 pMenuPanelForThisMenu = mMenuPanels.Add(
new MenuPanel(*
this, *pSubMenu, x, y, mMenuPanels.Find(mActiveMenuPanel)));
581 for (
auto mr = 0; mr < mMenuPanels.GetSize(); mr++)
583 MenuPanel* pMenuPanel = mMenuPanels.Get(mr);
585 if(pMenuPanel->mShouldDraw)
587 IRECT drawRECT = pMenuPanel->mRECT;
588 IRECT targetRECT = pMenuPanel->mTargetRECT;
590 MenuPanel* pParentMenuPanel = mMenuPanels.Get(pMenuPanel->mParentIdx);
592 while (pParentMenuPanel !=
nullptr)
594 pParentMenuPanel->mShouldDraw =
true;
595 drawRECT = drawRECT.
Union(pParentMenuPanel->mTargetRECT);
596 targetRECT = targetRECT.
Union(pParentMenuPanel->mRECT);
597 pParentMenuPanel = mMenuPanels.Get(pParentMenuPanel->mParentIdx);
598 mSubMenuOpened =
true;
600 if (mSubmenuOnRight) mSubMenuCalloutArrowBounds =
IRECT(pCellRect->
R + PAD , pCellRect->
MH() - (calloutSpace / 2.f) , pCellRect->
R + PAD + calloutSpace, pCellRect->
MH() + (calloutSpace / 2.f));
601 else mSubMenuCalloutArrowBounds =
IRECT(pCellRect->
L - PAD - calloutSpace, pCellRect->
MH() - (calloutSpace / 2.f), pCellRect->
L - PAD, pCellRect->
MH() + (calloutSpace / 2.f));
607 if(mAppearingMenuPanel != pMenuPanel)
609 mState = kSubMenuAppearing;
610 mAppearingMenuPanel = pMenuPanelForThisMenu;
621 for (
auto mr = 0; mr < mMenuPanels.GetSize(); mr++)
623 MenuPanel* pMenuPanel = mMenuPanels.Get(mr);
625 if(pMenuPanel->mParentIdx == mMenuPanels.Find(mActiveMenuPanel))
627 mActiveMenuPanel->mHighlightedCell =
nullptr;
628 pMenuPanel->mShouldDraw =
false;
629 mSubMenuOpened =
false;
639 void IPopupMenuControl::Expand(
const IRECT& anchorArea)
645 mMenuPanels.Empty(
true);
647 mAnchorArea = anchorArea;
649 float panelWidth = 0.f;
650 float panelHeight = 0.f;
652 GetPanelDimensions(*mMenu, panelWidth, panelHeight);
654 float minT = mMaxBounds.
T + mDropShadowSize;
655 float maxB = mMaxBounds.
B - panelHeight - (mDropShadowSize * 2.f);
656 float maxR = mMaxBounds.
R - panelWidth - (mDropShadowSize * 2.f);
657 float minL = mMaxBounds.
L + mDropShadowSize;
662 float calloutSpace =0.f;
665 calloutSpace = CALLOUT_SPACE;
668 if ( anchorArea.
MH() <= mMaxBounds.
MH())
670 y = anchorArea.
MH() - (calloutSpace + mText.mSize);
672 else y = (anchorArea.
MH() - panelHeight) + (calloutSpace + mText.mSize);
674 if ( anchorArea.
MW() <= mMaxBounds.
MW() )
676 x = anchorArea.
R + calloutSpace;
677 mCalloutArrowBounds =
IRECT( anchorArea.
R, anchorArea.
MH() - (calloutSpace / 2.f), x, anchorArea.
MH() + (calloutSpace / 2.f) );
678 mCalloutArrowDir = kEast;
682 x = anchorArea.
L - calloutSpace - panelWidth - mDropShadowSize;
683 mCalloutArrowBounds =
IRECT( anchorArea.
L - calloutSpace, anchorArea.
MH() - (calloutSpace / 2.f), anchorArea.
L, anchorArea.
MH() + (calloutSpace / 2.f) );
684 mCalloutArrowDir = kWest;
687 if( y <= minT || y > maxB || x <= minL || x > maxR )
689 if ( (y <= minT || x <= minL || x > maxR) && anchorArea.
MH() <= mMaxBounds.
MH() )
691 x = anchorArea.
MW() - (panelWidth / 2.f);
692 y = anchorArea.
B + calloutSpace;
693 mCalloutArrowBounds =
IRECT(anchorArea.
MW() - (calloutSpace/2.f), anchorArea.
B, anchorArea.
MW() + (calloutSpace/2.f), anchorArea.
B + calloutSpace);
694 mCalloutArrowDir = kSouth;
698 if ( anchorArea.
MW() <= mMaxBounds.
MW() )
700 x = anchorArea.
R + calloutSpace;
701 mCalloutArrowBounds =
IRECT( anchorArea.
R, anchorArea.
MH() - (calloutSpace / 2.f), x, anchorArea.
MH() + (calloutSpace / 2.f) );
702 mCalloutArrowDir = kEast;
706 x = anchorArea.
L - calloutSpace - panelWidth - mDropShadowSize;
707 mCalloutArrowBounds =
IRECT( anchorArea.
L - calloutSpace, anchorArea.
MH() - (calloutSpace / 2.f), anchorArea.
L, anchorArea.
MH() + (calloutSpace / 2.f) );
708 mCalloutArrowDir = kWest;
714 if ( (y > maxB || x <= minL || x > maxR) && anchorArea.
MH() > mMaxBounds.
MH() )
716 x = anchorArea.
MW() - (panelWidth / 2.f);
717 y = anchorArea.
T - calloutSpace - panelHeight - mDropShadowSize;
718 mCalloutArrowBounds =
IRECT(anchorArea.
MW() - (calloutSpace/2.f), anchorArea.
T - calloutSpace, anchorArea.
MW() + (calloutSpace/2.f), anchorArea.
T);
719 mCalloutArrowDir = kNorth;
723 if ( anchorArea.
MW() <= mMaxBounds.
MW() )
725 x = anchorArea.
R + calloutSpace;
726 mCalloutArrowBounds =
IRECT( anchorArea.
R, anchorArea.
MH() - (calloutSpace / 2.f), x, anchorArea.
MH() + (calloutSpace / 2.f) );
727 mCalloutArrowDir = kEast;
731 x = anchorArea.
L - calloutSpace - panelWidth - mDropShadowSize;
732 mCalloutArrowBounds =
IRECT( anchorArea.
L - calloutSpace, anchorArea.
MH() - (calloutSpace / 2.f), anchorArea.
L, anchorArea.
MH() + (calloutSpace / 2.f) );
733 mCalloutArrowDir = kWest;
739 if ( x <= minL ) x = minL;
740 if ( x > maxR ) x = maxR;
741 if ( y <= minT ) y = minT;
742 if ( y > maxB ) y = maxB;
747 if (anchorArea.
B + calloutSpace <= maxB)
749 x = anchorArea.
MW() - (panelWidth / 2.f);
750 y = anchorArea.
B + calloutSpace;
751 mCalloutArrowBounds =
IRECT(anchorArea.
MW() - (calloutSpace/2.f), anchorArea.
B, anchorArea.
MW() + (calloutSpace/2.f), anchorArea.
B + calloutSpace);
752 mCalloutArrowDir = kSouth;
754 if ( x <= minL ) x = minL;
755 if ( x > maxR ) x = maxR;
761 if ( anchorArea.
MW() <= mMaxBounds.
MW() )
763 mSubmenuOnRight =
true;
768 mSubmenuOnRight =
false;
771 x = (anchorArea.
MW() - (panelWidth / 2.f)) + (mMenuShift * shiftfactor);
772 if ( x <= minL ) x = minL;
773 if ( x > maxR ) x = maxR;
775 if (anchorArea.
T - mMaxBounds.
T <= mMaxBounds.
B - anchorArea.
B)
777 y = anchorArea.
B + calloutSpace;
778 if ( y > maxB ) y = maxB;
779 if ( y <= minT ) y = minT;
780 mCalloutArrowBounds =
IRECT(anchorArea.
MW() - (calloutSpace/2.f), anchorArea.
B, anchorArea.
MW() + (calloutSpace/2.f), anchorArea.
B + calloutSpace);
781 mCalloutArrowDir = kSouth;
785 y = anchorArea.
T - calloutSpace - panelHeight - mDropShadowSize;
786 if ( y <= minT ) y = minT;
787 if ( y > maxB ) y = maxB;
788 mCalloutArrowBounds =
IRECT(anchorArea.
MW() - (calloutSpace/2.f), anchorArea.
T - calloutSpace, anchorArea.
MW() + (calloutSpace/2.f), anchorArea.
T);
789 mCalloutArrowDir = kNorth;
793 mActiveMenuPanel = mAppearingMenuPanel = mMenuPanels.Add(
new MenuPanel(*
this, *mMenu, x, y, -1));
796 SetRECT(mActiveMenuPanel->mRECT);
801 void IPopupMenuControl::CollapseEverything()
803 IPopupMenu* pClickedMenu = &mActiveMenuPanel->mMenu;
805 pClickedMenu->SetChosenItemIdx(-1);
807 for(
auto i = 0; i < mActiveMenuPanel->mCellBounds.GetSize(); i++)
809 IRECT* pR = mActiveMenuPanel->mCellBounds.Get(i);
811 if(mMouseCellBounds == pR)
813 int itemChosen = mActiveMenuPanel->mScrollItemOffset + i;
816 if(pItem->GetIsChoosable())
818 pClickedMenu->SetChosenItemIdx(itemChosen);
819 mActiveMenuPanel->mClickedCell = pR;
824 if(pClickedMenu->GetFunction())
825 pClickedMenu->ExecFunction();
829 mSubMenuOpened =
false;
830 mActiveMenuPanel =
nullptr;
832 mState = kFlickering;
837 void IPopupMenuControl::OnEndAnimation()
841 if(mState == kExpanding)
843 for (
auto i = 0; i < mMenuPanels.GetSize(); i++) {
844 mMenuPanels.Get(i)->mBlend.mWeight = mOpacity;
849 else if (mState == kFlickering)
851 mState = kCollapsing;
855 else if (mState == kSubMenuAppearing)
857 for (
auto i = 0; i < mMenuPanels.GetSize(); i++) {
858 mMenuPanels.Get(i)->mBlend.mWeight = mOpacity;
863 else if(mState == kCollapsing)
865 mTargetRECT = mSpecifiedCollapsedBounds;
867 for (
auto i = 0; i < mMenuPanels.GetSize(); i++) {
868 mMenuPanels.Get(i)->mBlend.mWeight = 0.;
872 mMouseCellBounds =
nullptr;
873 mAnchorArea =
IRECT();
878 else if(mState == kIdling)
882 mMenuPanels.Empty(
true);
883 mRECT = mSpecifiedCollapsedBounds;
887 IControl::OnEndAnimation();
892 , mParentIdx(parentIdx)
894 mSingleCellBounds = control.GetLargestCellRectForMenu(menu, x, y);
896 float left = x + control.PAD;
897 float top = y + control.PAD;
900 auto GetIncrements = [&](
IPopupMenu::Item* pMenuItem,
float& incX,
float& incY)
904 if (pMenuItem->GetIsSeparator())
905 incY = control.mSeparatorSize;
910 for (
auto i = 0; i < menu.NItems(); ++i)
914 float toAddX, toAddY;
915 bool newColumn =
false;
917 GetIncrements(pMenuItem, toAddX, toAddY);
919 if(control.mMaxColumnItems > 0 && i > 1)
920 newColumn = !(i % control.mMaxColumnItems);
922 if((top + toAddY + control.PAD) > control.mMaxBounds.
B || newColumn)
924 if(control.mScrollIfTooBig)
926 const float maxTop = control.mMaxBounds.
T + control.PAD + control.mDropShadowSize;
927 const float maxBottom = control.mMaxBounds.
B - control.PAD;
928 const float maxH = (maxBottom - maxTop);
929 mScrollMaxRows =
static_cast<int>(maxH / (CellHeight() + control.mCellGap));
932 mCellBounds.Empty(
true);
933 GetIncrements(menu.GetItem(0), toAddX, toAddY);
935 if(menu.NItems() < mScrollMaxRows)
937 top = (y + control.PAD + CellHeight()) - (menu.NItems() * CellHeight());
939 for (
auto r = 0; r < menu.NItems(); r++)
941 GetIncrements(menu.GetItem(r), toAddX, toAddY);
942 bottom = top + toAddY;
943 right = left + toAddX;
944 mCellBounds.Add(
new IRECT(left, top, right, bottom));
945 top = bottom + control.mCellGap;
946 bottom = top + toAddY;
954 for (
auto r = 0; r < mScrollMaxRows; r++)
956 GetIncrements(menu.GetItem(r), toAddX, toAddY);
957 bottom = top + toAddY;
958 right = left + toAddX;
959 mCellBounds.Add(
new IRECT(left, top, right, bottom));
960 top = bottom + control.mCellGap;
961 bottom = top + toAddY;
968 left += mSingleCellBounds.W() + control.mCellGap;
969 top = mSingleCellBounds.T + control.PAD;
973 right = left + toAddX;
974 bottom = top + toAddY;
976 mCellBounds.Add(
new IRECT(left, top, right, bottom));
977 top = bottom + control.mCellGap;
982 if(mCellBounds.GetSize())
984 span = *mCellBounds.Get(0);
986 for(
auto i = 1; i < mCellBounds.GetSize(); i++)
988 span = span.
Union(*mCellBounds.Get(i));
992 if (control.mSpecifiedExpandedBounds.
W())
994 mTargetRECT = control.mSpecifiedExpandedBounds.
GetPadded(control.PAD);
995 mRECT = control.mSpecifiedExpandedBounds.
GetPadded(control.mDropShadowSize + control.PAD);
999 mTargetRECT = span.
GetPadded(control.PAD);
1000 mRECT = span.
GetPadded(control.mDropShadowSize + control.PAD);
1004 IPopupMenuControl::MenuPanel::~MenuPanel()
1006 mCellBounds.
Empty(
true);
1009 IRECT* IPopupMenuControl::MenuPanel::HitTestCells(
float x,
float y)
const 1011 for(
auto i = 0; i < mCellBounds.GetSize(); i++)
1013 IRECT* pR = mCellBounds.Get(i);
1014 if(pR->
Contains(x, y) && mMenu.GetItem(i)->GetEnabled())
bool Contains(const IRECT &rhs) const
Returns true if this IRECT completely contains rhs.
The lowest level base class of an IGraphics control.
Used to manage a rectangular area, independent of draw class/platform.
virtual void OnMouseDown(float x, float y, const IMouseMod &mod)
Implement this method to respond to a mouse down event on this control.
Used to manage composite/blend operations, independent of draw class/platform.
Used to manage mouse modifiers i.e.
virtual void Hide(bool hide)
Shows or hides the IControl.
IControl * SetActionFunction(IActionFunction actionFunc)
Set an Action Function for this control.
void HPad(float padding)
Pad this IRECT in the X-axis N.B.
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 R
Right side of the rectangle (X + W)
void SetRECT(const IRECT &bounds)
Set the rectangular draw area for this control, within the graphics context.
double GetAnimationProgress() const
Get the progress in a control's animation, in the range 0-1.
IText is used to manage font and text/text entry style for a piece of text on the UI...
virtual void DrawFastDropShadow(const IRECT &innerBounds, const IRECT &outerBounds, float xyDrop=5.f, float roundness=0.f, float blur=10.f, IBlend *pBlend=nullptr)
NanoVG only.
The lowest level base class of an IGraphics context.
void SetAnimation(IAnimationFunction func)
Set the animation function.
IRECT GetBounds() const
Returns an IRECT that represents the entire UI bounds This is useful for programatically arranging UI...
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 FillRect(const IColor &color, const IRECT &bounds, const IBlend *pBlend=0)
Fill a rectangular region of the graphics context with a color.
IRECT Union(const IRECT &rhs) const
Create a new IRECT that is a union of this IRECT and rhs.
void Pad(float padding)
Pad this IRECT N.B.
void SetTargetRECT(const IRECT &bounds)
Set the rectangular mouse tracking target area, within the graphics context for this control...
float L
Left side of the rectangle (X)
IRECT GetHPadded(float padding) const
Get a copy of this IRECT padded in the X-axis N.B.
IRECT GetCentredInside(const IRECT &sr) const
Get a rectangle the size of sr but with the same center point as this rectangle.
IRECT GetPadded(float padding) const
Get a copy of this IRECT with each value padded by padding N.B.
void SetControlValueAfterPopupMenu(IPopupMenu *pMenu)
Called by PopupMenuControl in order to update a control with a new value after returning from the non...
float T
Top of the rectangle (Y)
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 float MeasureText(const IText &text, const char *str, IRECT &bounds) const
Measure the rectangular region that some text will occupy.
virtual void SetDirty(bool triggerAction=true, int valIdx=kNoValIdx)
Mark the control as dirty, i.e.
float B
Bottom of the rectangle (Y + H)
virtual void UpdateTooltips()=0
Call this if you modify control tool tips at runtime.