iPlug 2: IPopupMenuControl.cpp Source File
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;
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;
65 for (auto i = 0; i < mMenuPanels.GetSize(); i++) {
66 mMenuPanels.Get(i)->mBlend.mWeight = 0.f;
77IPopupMenuControl::~IPopupMenuControl()
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();
103 if(pMenuPanel->mScrollItemOffset > 0)
105 IRECT* pCellRect = pMenuPanel->mCellBounds.Get(0);
106 bool sel = mMouseCellBounds == pCellRect || pCellRect == pMenuPanel->mHighlightedCell;
108 DrawCellBackground(g, *pCellRect, nullptr, sel, &pMenuPanel->mBlend);
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;
119 DrawCellBackground(g, *pCellRect, nullptr, sel, &pMenuPanel->mBlend);
120 DrawDownArrow(g, *pCellRect, sel, &pMenuPanel->mBlend);
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())
135 DrawSeparator(g, *pCellRect, &pMenuPanel->mBlend);
138 bool sel = mMouseCellBounds == pCellRect || pCellRect == pMenuPanel->mHighlightedCell;
140 if(pMenuPanel->mClickedCell)
143 DrawCellBackground(g, *pCellRect, pMenuItem, sel, &pMenuPanel->mBlend);
146 DrawCellBackground(g, *pCellRect, pMenuItem, sel, &pMenuPanel->mBlend);
149 DrawCellText(g, *pCellRect, pMenuItem, sel, &pMenuPanel->mBlend);
151 if(pMenuItem->GetChecked())
152 DrawTick(g, *pCellRect, pMenuItem, sel, &pMenuPanel->mBlend);
154 if(pMenuItem->GetSubmenu())
155 DrawSubMenuArrow(g, *pCellRect, pMenuItem, sel, &pMenuPanel->mBlend);
161 if(mCallOut && mMenuPanels.GetSize())
163 DrawCalloutArrow(g, mCalloutArrowBounds, &mMenuPanels.Get(0)->mBlend);
164 if (mMenuHasSubmenu && mSubMenuOpened)
175 mMouseCellBounds = mActiveMenuPanel->HitTestCells(x, y);
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;
271 cx = bounds.MW();
275 ax = bounds.MW() + halftri;
276 ay = bounds.MH() + halftri;
280 cy = bounds.MH();
283 ax = bounds.MW() - halftri;
284 ay = bounds.MH() + halftri;
287 cx = bounds.MW();
291 ax = bounds.MW() - halftri;
292 ay = bounds.MH() + halftri;
296 cy = bounds.MH();
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;
317 cy = bounds.MH();
321 ax = bounds.MW() - halftri;
322 ay = bounds.MH() + halftri;
326 cy = bounds.MH();
328 g.FillTriangle(mPanelBackgroundColor, ax, ay, bx, by, cx, cy, pBlend);
334 g.FillRoundRect(mPanelBackgroundColor, panel->mTargetRECT, mRoundness, &panel->mBlend);
339 IRECT inner = panel->mRECT.GetPadded(-mDropShadowSize);
340 g.DrawFastDropShadow(inner, panel->mRECT, 2.0, mRoundness, 10.f, &panel->mBlend);
351 IRECT tickRect = IRECT(bounds.L, bounds.T, bounds.L + TICK_SIZE, bounds.B).GetCentredInside(TICK_SIZE);
352 IRECT textRect = IRECT(tickRect.R + TEXT_HPAD, bounds.T, bounds.R - TEXT_HPAD, bounds.B);
355 mText.mFGColor = mItemMouseoverColor;
359 mText.mFGColor = mItemColor;
361 mText.mFGColor = mDisabledItemColor;
364 mText.mAlign = EAlign::Near;
365 g.DrawText(mText, pItem->GetText(), textRect, pBlend);
370 IRECT tickRect = IRECT(bounds.L, bounds.T, bounds.L + TICK_SIZE, bounds.B).GetCentredInside(TICK_SIZE);
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;
384 ay = tri.MH() + halftri;
388 cy = tri.MH();
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;
396 ay = tri.MH() + halftri;
400 cy = tri.MH();
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;
414 float cx = tri.MW();
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;
428 float cx = tri.MW();
430 g.FillTriangle(sel ? mItemMouseoverColor : mItemColor, ax, ay, bx, by, cx, cy, pBlend);
436 g.FillRect(mSeparatorColor, bounds, &BLEND_25);
443 for (int i = 0; i< mMenu->NItems(); i++)
445 if (mMenu->GetItem(i)->GetSubmenu())
450 else mMenuHasSubmenu = false;
453 if(mMaxBounds.W() == 0)
460IRECT IPopupMenuControl::GetLargestCellRectForMenu(IPopupMenu& menu, float x, float y) const
464 for (auto i = 0; i < menu.NItems(); ++i)
467 IRECT textBounds;
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());
481void IPopupMenuControl::GetPanelDimensions(IPopupMenu&menu, float& width, float& height) const
483 IRECT maxCell = GetLargestCellRectForMenu(menu, 0, 0);
485 int numItems = menu.NItems();
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);
500 width = maxCell.W();
510 calloutSpace = CALLOUT_SPACE;
513 for(auto i = 0; i < mActiveMenuPanel->mCellBounds.GetSize(); i++)
515 IRECT* pCellRect = mActiveMenuPanel->mCellBounds.Get(i);
516 IPopupMenu::Item* pMenuItem = mActiveMenuPanel->mMenu.GetItem(i);
517 IPopupMenu* pSubMenu = pMenuItem->GetSubmenu();
519 if(pCellRect == mMouseCellBounds)
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) {
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)
566 if (mCalloutArrowDir == kNorth)
568 y = (pCellRect->T - (PAD / 2.f) - panelHeight) + (mCellGap * 2.f) + mDropShadowSize;
573 if (mSubmenuOnRight) x = pCellRect->R + PAD + calloutSpace;
574 else x = pCellRect->L - PAD - calloutSpace - panelWidth - mDropShadowSize;
575 if ( x <= minL ) x = minL;
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);
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;
639void IPopupMenuControl::Expand(const IRECT& anchorArea)
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;
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) );
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) );
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) );
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) );
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) );
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) );
739 if ( x <= minL ) x = minL;
741 if ( y <= minT ) y = minT;
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;
761 if ( anchorArea.MW() <= mMaxBounds.MW() )
771 x = (anchorArea.MW() - (panelWidth / 2.f)) + (mMenuShift * shiftfactor);
772 if ( x <= minL ) x = minL;
775 if (anchorArea.T - mMaxBounds.T <= mMaxBounds.B - anchorArea.B)
777 y = anchorArea.B + calloutSpace;
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;
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);
798 SetDirty(true);
801void 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();
830 mActiveMenuPanel = nullptr;
834 SetDirty(true);
837void IPopupMenuControl::OnEndAnimation()
843 for (auto i = 0; i < mMenuPanels.GetSize(); i++) {
844 mMenuPanels.Get(i)->mBlend.mWeight = mOpacity;
849 else if (mState == kFlickering)
852 SetDirty(true);
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();
875 SetDirty(true);
878 else if(mState == kIdling)
883 mRECT = mSpecifiedCollapsedBounds;
887 IControl::OnEndAnimation();
890IPopupMenuControl::MenuPanel::MenuPanel(IPopupMenuControl& control, IPopupMenu& menu, float x, float y, int 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)
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));
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);
944 mCellBounds.Add(new IRECT(left, top, right, bottom));
945 top = bottom + control.mCellGap;
954 for (auto r = 0; r < mScrollMaxRows; r++)
956 GetIncrements(menu.GetItem(r), toAddX, toAddY);
959 mCellBounds.Add(new IRECT(left, top, right, bottom));
960 top = bottom + control.mCellGap;
968 left += mSingleCellBounds.W() + control.mCellGap;
969 top = mSingleCellBounds.T + control.PAD;
976 mCellBounds.Add(new IRECT(left, top, right, bottom));
977 top = bottom + control.mCellGap;
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);
1004IPopupMenuControl::MenuPanel::~MenuPanel()
1006 mCellBounds.Empty(true);
1009IRECT* 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())
The lowest level base class of an IGraphics control.
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 Hide(bool hide)
Shows or hides the IControl.
void SetTargetRECT(const IRECT &bounds)
Set the rectangular mouse tracking target area, within the graphics context for this control.
double GetAnimationProgress() const
Get the progress in a control's animation, in the range 0-1.
void SetRECT(const IRECT &bounds)
Set the rectangular draw area for this control, within the graphics context.
virtual void SetDirty(bool triggerAction=true, int valIdx=kNoValIdx)
Mark the control as dirty, i.e.
IControl * SetActionFunction(IActionFunction actionFunc)
Set an Action Function for this control.
void SetAnimation(IAnimationFunction func)
Set the animation function.
The lowest level base class of an IGraphics context.
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.
void SetControlValueAfterPopupMenu(IPopupMenu *pMenu)
Called by PopupMenuControl in order to update a control with a new value after returning from the non...
virtual void FillRect(const IColor &color, const IRECT &bounds, const IBlend *pBlend=0)
Fill a rectangular region of the graphics context with a color.
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.
virtual void UpdateTooltips()=0
Call this if you modify control tool tips at runtime to refresh the platform tooltip state.
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 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.
IRECT GetBounds() const
Returns an IRECT that represents the entire UI bounds This is useful for programatically arranging UI...
virtual float MeasureText(const IText &text, const char *str, IRECT &bounds) const
Measure the rectangular region that some text will occupy.
Used to manage composite/blend operations, independent of draw class/platform.
Used to manage mouse modifiers i.e.
Used to manage a rectangular area, independent of draw class/platform.
void Pad(float padding)
Pad this IRECT N.B.
IRECT GetCentredInside(const IRECT &sr) const
Get a rectangle the size of sr but with the same center point as this rectangle.
void HPad(float padding)
Pad this IRECT in the X-axis N.B.
IRECT Union(const IRECT &rhs) const
Create a new IRECT that is a union of this IRECT and rhs.
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.
IRECT GetHPadded(float padding) const
Get a copy of this IRECT padded in the X-axis N.B.
IText is used to manage font and text/text entry style for a piece of text on the UI,...