22BEGIN_IGRAPHICS_NAMESPACE
51 IBubbleControl(
const IText& text = DEFAULT_TEXT.WithAlign(EAlign::Center),
const IColor& fillColor = COLOR_WHITE,
const IColor& strokeColor = COLOR_BLACK,
float roundness = 5.f)
53 , mRoundness(roundness)
54 , mFillColor(fillColor)
55 , mStrokeColor(strokeColor)
61 auto animationFunc = [&](
IControl* pCaller) {
62 auto progress = pCaller->GetAnimationProgress();
65 if(mState == kExpanding)
67 mBlend.mWeight = mOpacity;
70 else if(mState == kExpanded)
79 mBlend.mWeight = mOpacity;
86 else if(mState == kCollapsing)
95 pCaller->OnEndAnimation();
100 case kExpanding: mBlend.mWeight = (float) progress * mOpacity;
break;
101 case kExpanded: mBlend.mWeight = mOpacity;
break;
102 case kCollapsing: mBlend.mWeight = (float) (1.-progress) * mOpacity;
break;
113 if(mState == kExpanded) {
127 DrawDropShadow(g, r);
136 mBubbleBounds = mRECT;
152 g.
DrawText(mText, mStr.Get(), r, &mBlend);
157 float halfCalloutSize = mCalloutSize/2.f;
160 g.
PathArc(r.L + mRoundness, r.T + mRoundness, mRoundness, 270.f, 360.f);
162 if(mArrowDir == kWest)
164 g.
PathArc(r.R - mRoundness, r.T + mRoundness, mRoundness, 0.f, 90.f);
165 g.
PathArc(r.R - mRoundness, r.B - mRoundness, mRoundness, 90.f, 180.f);
166 g.
PathArc(r.L + mRoundness, r.B - mRoundness, mRoundness, 180.f, 270.f);
171 else if(mArrowDir == kEast)
173 g.
PathArc(r.R - mRoundness, r.T + mRoundness, mRoundness, 0.f, 90.f);
177 g.
PathArc(r.R - mRoundness, r.B - mRoundness, mRoundness, 90.f, 180.f);
178 g.
PathArc(r.L + mRoundness, r.B - mRoundness, mRoundness, 180.f, 270.f);
180 else if(mArrowDir == kNorth)
185 g.
PathArc(r.R - mRoundness, r.T + mRoundness, mRoundness, 0.f, 90.f);
186 g.
PathArc(r.R - mRoundness, r.B - mRoundness, mRoundness, 90.f, 180.f);
187 g.
PathArc(r.L + mRoundness, r.B - mRoundness, mRoundness, 180.f, 270.f);
189 else if(mArrowDir == kSouth)
191 g.
PathArc(r.R - mRoundness, r.T + mRoundness, mRoundness, 0.f, 90.f);
192 g.
PathArc(r.R - mRoundness, r.B - mRoundness, mRoundness, 90.f, 180.f);
196 g.
PathArc(r.L + mRoundness, r.B - mRoundness, mRoundness, 180.f, 270.f);
200 g.
PathFill(mFillColor,
true, &mBlend);
209 virtual void MeasureText(
const char* str,
IRECT& contentBounds)
214 void ShowBubble(
IControl* pCaller,
float x,
float y,
const char* str, EDirection dir,
IRECT minimumContentBounds, ITouchID touchID = 0)
216 if(mMaxBounds.
W() == 0)
224 MeasureText(str, contentBounds);
226 if (!minimumContentBounds.
Empty())
228 if(minimumContentBounds.
W() > contentBounds.
W())
230 contentBounds.R = contentBounds.L + minimumContentBounds.
W();
233 if(minimumContentBounds.
H() > contentBounds.
H())
235 contentBounds.B = contentBounds.T + minimumContentBounds.
H();
239 contentBounds.
HPad(mHorizontalPadding);
240 contentBounds.
Pad(mDropShadowSize);
241 const float halfHeight = contentBounds.
H() / 2.f;
242 const float halfWidth = contentBounds.
W() / 2.f;
244 mBubbleBounds =
IRECT(x, y - halfHeight, x + contentBounds.
W(), y + halfHeight);
247 if(mDirection == EDirection::Horizontal)
249 const float maxR = mMaxBounds.R - mHorizontalPadding - mDropShadowSize;
252 if(mBubbleBounds.R > maxR)
254 const float shiftLeft = mBubbleBounds.R-controlBounds.L;
255 mBubbleBounds.
Translate(-shiftLeft, 0.f);
256 mArrowDir = EArrowDir::kEast;
259 mArrowDir = EArrowDir::kWest;
263 mBubbleBounds.
Translate(-halfWidth, -halfHeight);
266 if(mBubbleBounds.T < mMaxBounds.T)
268 mArrowDir = EArrowDir::kNorth;
269 const float shiftDown = mBubbleBounds.
H() + controlBounds.
H();
273 mArrowDir = EArrowDir::kSouth;
278 if(mState == kCollapsed)
285 if(pCaller != mCaller)
287 mRECT = mBubbleBounds;
294 bool GetActive()
const
296 return mState > EPopupState::kCollapsed;
299 ITouchID GetTouchID()
const
307 ITouchID mTouchId = 0;
308 EDirection mDirection = EDirection::Horizontal;
312 EArrowDir mArrowDir = EArrowDir::kWest;
314 IBlend mBlend = { EBlend::Default, 0.f };
315 float mRoundness = 5.f;
316 float mDropShadowSize = 10.f;
317 float mCalloutSize = 10.f;
318 float mOpacity = 0.95f;
319 float mStrokeThickness = 2.f;
320 float mHorizontalPadding = 5.f;
321 IColor mFillColor = COLOR_WHITE;
322 IColor mStrokeColor = COLOR_BLACK;
326END_IGRAPHICS_NAMESPACE
This file contains the base IControl implementation, along with some base classes for specific types ...
A special control to draw contextual info as a slider etc is moved If used in the main IControl stack...
void ResetBounds()
If controls get moved, you may need to call this to avoid the wrong regions getting dirtied.
IBubbleControl(const IText &text=DEFAULT_TEXT.WithAlign(EAlign::Center), const IColor &fillColor=COLOR_WHITE, const IColor &strokeColor=COLOR_BLACK, float roundness=5.f)
Create a new IBubbleControl.
void SetStrokeColor(const IColor &color)
Set the stroke color for the bubble.
EPopupState
An enumerated list, that is used to determine the state of the menu, mainly for animations.
void SetMaxBounds(const IRECT &bounds)
Set the bounds that the menu can potentially occupy, if not the full graphics context.
void Draw(IGraphics &g) override
Draw the control to the graphics context.
void SetFillColor(const IColor &color)
Set the background color for the bubble.
The lowest level base class of an IGraphics control.
virtual void Hide(bool hide)
Shows or hides the IControl.
const IRECT & GetRECT() const
Get the rectangular draw area for this control, within the graphics context.
IControl * SetAnimationEndActionFunction(IActionFunction actionFunc)
Set an Action Function to be called at the end of an animation.
void SetRECT(const IRECT &bounds)
Set the rectangular draw area for this control, within the graphics context.
void SetTargetAndDrawRECTs(const IRECT &bounds)
Set BOTH the draw rect and the target area, within the graphics context for this control.
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.
bool ControlIsCaptured() const
Check to see if any control is captured.
virtual void PathFill(const IPattern &pattern, const IFillOptions &options=IFillOptions(), const IBlend *pBlend=0)=0
Fill the current current path.
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.
virtual void PathClose()=0
Close the path that is being specified.
virtual void PathStroke(const IPattern &pattern, float thickness, const IStrokeOptions &options=IStrokeOptions(), const IBlend *pBlend=0)=0
Stroke the current current path.
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.
void SetAllControlsDirty()
Calls SetDirty() on every control.
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.
virtual void PathLineTo(float x, float y)=0
Add a line to the current path from the current point to the specified location.
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 stroke behaviour for path based drawing back ends.
Used to manage composite/blend operations, independent of draw class/platform.
Used to manage color data, independent of draw class/platform.
Used to manage a rectangular area, independent of draw class/platform.
void Pad(float padding)
Pad this IRECT N.B.
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.
void Translate(float x, float y)
Translate this rectangle.
IRECT GetPadded(float padding) const
Get a copy of this IRECT with each value padded by padding N.B.
IText is used to manage font and text/text entry style for a piece of text on the UI,...