Initial release

This commit is contained in:
civ
2026-08-16 18:24:52 +07:00
commit 876886a39a
13244 changed files with 2353959 additions and 0 deletions
@@ -0,0 +1,504 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "cparamdisplay.h"
#include "../cbitmap.h"
#include "../cframe.h"
#include "../cstring.h"
#include "../cgraphicspath.h"
#include "../cdrawcontext.h"
#include <string>
namespace VSTGUI {
//------------------------------------------------------------------------
// CParamDisplay
//------------------------------------------------------------------------
/*! @class CParamDisplay
Define a rectangle view where a text-value can be displayed with a given font and color.
The user can specify its convert function (from float to char) by default the string format is "%2.2f".
The text-value is centered in the given rect.
*/
CParamDisplay::CParamDisplay (const CRect& size, CBitmap* background, int32_t inStyle)
: CControl (size, nullptr, -1, background)
, horiTxtAlign (kCenterText)
, style (inStyle)
, valuePrecision (2)
, roundRectRadius (6.)
, frameWidth (1.)
, textRotation (0.)
{
setBit (style, kAntialias, true);
backOffset (0, 0);
fontID = kNormalFont; fontID->remember ();
fontColor = kWhiteCColor;
backColor = kBlackCColor;
frameColor = kBlackCColor;
shadowColor = kRedCColor;
if (hasBit (style, kNoDrawStyle))
setDirty (false);
}
//------------------------------------------------------------------------
CParamDisplay::CParamDisplay (const CParamDisplay& v)
: CControl (v)
, valueToStringFunction (v.valueToStringFunction)
, horiTxtAlign (v.horiTxtAlign)
, style (v.style)
, valuePrecision (v.valuePrecision)
, fontID (v.fontID)
, fontColor (v.fontColor)
, backColor (v.backColor)
, frameColor (v.frameColor)
, shadowColor (v.shadowColor)
, textInset (v.textInset)
, backOffset (v.backOffset)
, roundRectRadius (v.roundRectRadius)
, frameWidth (v.frameWidth)
, textRotation (v.textRotation)
{
fontID->remember ();
}
//------------------------------------------------------------------------
CParamDisplay::~CParamDisplay () noexcept
{
if (fontID)
fontID->forget ();
}
//------------------------------------------------------------------------
bool CParamDisplay::removed (CView* parent)
{
return CControl::removed (parent);
}
//------------------------------------------------------------------------
void CParamDisplay::setStyle (int32_t val)
{
setBit (val, kAntialias, hasBit (style, kAntialias));
if (style != val)
{
style = val;
drawStyleChanged ();
}
}
//------------------------------------------------------------------------
int32_t CParamDisplay::getStyle () const
{
auto tmp = style;
setBit (tmp, kAntialias, false);
return tmp;
}
//------------------------------------------------------------------------
void CParamDisplay::setPrecision (uint8_t precision)
{
if (valuePrecision != precision)
{
valuePrecision = precision;
drawStyleChanged ();
}
}
//------------------------------------------------------------------------
void CParamDisplay::setValueToStringFunction2 (const ValueToStringFunction2& valueToStringFunc)
{
valueToStringFunction = valueToStringFunc;
}
//------------------------------------------------------------------------
void CParamDisplay::setValueToStringFunction2 (ValueToStringFunction2&& valueToStringFunc)
{
valueToStringFunction = std::move (valueToStringFunc);
}
//------------------------------------------------------------------------
void CParamDisplay::setValueToStringFunction (const ValueToStringFunction& func)
{
if (!func)
{
setValueToStringFunction2 (nullptr);
return;
}
setValueToStringFunction2 ([=] (float value, std::string& str, CParamDisplay* display) {
char string[256];
string[0] = 0;
if (func (value, string, display))
{
str = string;
return true;
}
return false;
});
}
//------------------------------------------------------------------------
void CParamDisplay::setValueToStringFunction (ValueToStringFunction&& func)
{
setValueToStringFunction (func);
}
//------------------------------------------------------------------------
bool CParamDisplay::getFocusPath (CGraphicsPath& outPath)
{
if (wantsFocus ())
{
auto lineWidth = getFrameWidth ();
if (lineWidth < 0.)
lineWidth = 1.;
CCoord focusWidth = getFrame ()->getFocusWidth ();
CRect r (getViewSize ());
if (hasBit (style, kRoundRectStyle))
{
r.inset (lineWidth / 2., lineWidth / 2.);
outPath.addRoundRect (r, roundRectRadius);
outPath.closeSubpath ();
r.extend (focusWidth, focusWidth);
outPath.addRoundRect (r, roundRectRadius);
}
else
{
r.inset (lineWidth / 2., lineWidth / 2.);
outPath.addRect (r);
r.extend (focusWidth, focusWidth);
outPath.addRect (r);
}
}
return true;
}
//------------------------------------------------------------------------
void CParamDisplay::draw (CDrawContext *pContext)
{
if (hasBit (style, kNoDrawStyle))
return;
std::string string;
bool converted = false;
if (valueToStringFunction)
converted = valueToStringFunction (value, string, this);
if (!converted)
{
char tmp[255];
char precisionStr[10];
snprintf (precisionStr, 10, "%%.%hhuf", valuePrecision);
snprintf (tmp, 255, precisionStr, value);
string = tmp;
}
drawBack (pContext);
drawPlatformText (pContext, UTF8String (string));
setDirty (false);
}
//------------------------------------------------------------------------
void CParamDisplay::drawBack (CDrawContext* pContext, CBitmap* newBack)
{
pContext->setDrawMode (kAliasing);
auto lineWidth = getFrameWidth ();
if (lineWidth < 0.)
lineWidth = pContext->getHairlineSize ();
if (newBack)
{
newBack->draw (pContext, getViewSize (), backOffset);
}
else if (getDrawBackground ())
{
getDrawBackground ()->draw (pContext, getViewSize (), backOffset);
}
else
{
if (!getTransparency ())
{
bool strokePath = !(hasBit (style, (k3DIn|k3DOut|kNoFrame)));
pContext->setFillColor (backColor);
if (hasBit (style, kRoundRectStyle))
{
CRect pathRect = getViewSize ();
pathRect.inset (lineWidth/2., lineWidth/2.);
SharedPointer<CGraphicsPath> path = owned (pContext->createRoundRectGraphicsPath (pathRect, roundRectRadius));
if (path)
{
pContext->setDrawMode (kAntiAliasing);
pContext->drawGraphicsPath (path, CDrawContext::kPathFilled);
if (strokePath)
{
pContext->setLineStyle (kLineSolid);
pContext->setLineWidth (lineWidth);
pContext->setFrameColor (frameColor);
pContext->drawGraphicsPath (path, CDrawContext::kPathStroked);
}
}
}
else
{
pContext->setDrawMode (kAntiAliasing);
SharedPointer<CGraphicsPath> path = owned (pContext->createGraphicsPath ());
if (path)
{
CRect frameRect = getViewSize ();
if (strokePath)
frameRect.inset (lineWidth/2., lineWidth/2.);
path->addRect (frameRect);
pContext->drawGraphicsPath (path, CDrawContext::kPathFilled);
if (strokePath)
{
pContext->setLineStyle (kLineSolid);
pContext->setLineWidth (lineWidth);
pContext->setFrameColor (frameColor);
pContext->drawGraphicsPath (path, CDrawContext::kPathStroked);
}
}
else
{
pContext->drawRect (getViewSize (), kDrawFilled);
if (strokePath)
{
CRect frameRect = getViewSize ();
frameRect.inset (lineWidth/2., lineWidth/2.);
pContext->setLineStyle (kLineSolid);
pContext->setLineWidth (lineWidth);
pContext->setFrameColor (frameColor);
pContext->drawRect (frameRect);
}
}
}
}
}
// draw the frame for the 3D effect
if (hasBit (style, (k3DIn|k3DOut)))
{
CRect r (getViewSize ());
r.inset (lineWidth/2., lineWidth/2.);
pContext->setDrawMode (kAliasing);
pContext->setLineWidth (lineWidth);
pContext->setLineStyle (kLineSolid);
if (hasBit (style, k3DIn))
pContext->setFrameColor (backColor);
else
pContext->setFrameColor (frameColor);
CPoint p;
SharedPointer<CGraphicsPath> path = owned (pContext->createGraphicsPath ());
if (path)
{
path->beginSubpath (p (r.left, r.bottom));
path->addLine (p (r.left, r.top));
path->addLine (p (r.right, r.top));
pContext->drawGraphicsPath (path, CDrawContext::kPathStroked);
}
else
{
pContext->drawLine (CPoint (r.left, r.bottom), CPoint (r.left, r.top));
pContext->drawLine (CPoint (r.left, r.top), CPoint (r.right, r.top));
}
if (hasBit (style, k3DIn))
pContext->setFrameColor (frameColor);
else
pContext->setFrameColor (backColor);
path = owned (pContext->createGraphicsPath ());
if (path)
{
path->beginSubpath (p (r.right, r.top));
path->addLine (p (r.right, r.bottom));
path->addLine (p (r.left, r.bottom));
pContext->drawGraphicsPath (path, CDrawContext::kPathStroked);
}
else
{
pContext->drawLine (CPoint (r.right, r.top), CPoint (r.right, r.bottom));
pContext->drawLine (CPoint (r.right, r.bottom), CPoint (r.left, r.bottom));
}
}
}
//------------------------------------------------------------------------
void CParamDisplay::drawPlatformText (CDrawContext* pContext, const UTF8String& string)
{
drawPlatformText (pContext, string, getViewSize ());
}
//------------------------------------------------------------------------
void CParamDisplay::drawPlatformText (CDrawContext* pContext, const UTF8String& string,
const CRect& size)
{
if (!hasBit (style, kNoTextStyle))
{
pContext->saveGlobalState ();
CRect textRect (size);
textRect.inset (textInset.x, textInset.y);
drawClipped (pContext, textRect, [&] () {
CPoint center (textRect.getCenter ());
CGraphicsTransform transform;
transform.rotate (textRotation, center);
CDrawContext::Transform ctxTransform (*pContext, transform);
pContext->setDrawMode (kAntiAliasing);
pContext->setFont (fontID);
// draw darker text (as shadow)
if (hasBit (style, kShadowText))
{
CRect newSize (textRect);
newSize.offset (shadowTextOffset);
pContext->setFontColor (shadowColor);
pContext->drawString (string.getPlatformString (), newSize, horiTxtAlign,
hasBit (style, kAntialias));
}
pContext->setFontColor (fontColor);
pContext->drawString (string.getPlatformString (), textRect, horiTxtAlign,
hasBit (style, kAntialias));
});
pContext->restoreGlobalState ();
}
}
//------------------------------------------------------------------------
void CParamDisplay::setFont (CFontRef inFontID)
{
if (fontID)
fontID->forget ();
fontID = inFontID;
if (fontID)
fontID->remember ();
drawStyleChanged ();
}
//------------------------------------------------------------------------
void CParamDisplay::setFontColor (CColor color)
{
// to force the redraw
if (fontColor != color)
{
fontColor = color;
drawStyleChanged ();
}
}
//------------------------------------------------------------------------
void CParamDisplay::setBackColor (CColor color)
{
// to force the redraw
if (backColor != color)
{
backColor = color;
drawStyleChanged ();
}
}
//------------------------------------------------------------------------
void CParamDisplay::setFrameColor (CColor color)
{
// to force the redraw
if (frameColor != color)
{
frameColor = color;
drawStyleChanged ();
}
}
//------------------------------------------------------------------------
void CParamDisplay::setShadowColor (CColor color)
{
// to force the redraw
if (shadowColor != color)
{
shadowColor = color;
drawStyleChanged ();
}
}
//------------------------------------------------------------------------
void CParamDisplay::setShadowTextOffset (const CPoint& offset)
{
if (shadowTextOffset != offset)
{
shadowTextOffset = offset;
drawStyleChanged ();
}
}
//------------------------------------------------------------------------
void CParamDisplay::setHoriAlign (CHoriTxtAlign hAlign)
{
// to force the redraw
if (horiTxtAlign != hAlign)
{
horiTxtAlign = hAlign;
drawStyleChanged ();
}
}
//------------------------------------------------------------------------
void CParamDisplay::setTextInset (const CPoint& p)
{
if (textInset != p)
{
textInset = p;
drawStyleChanged ();
}
}
//------------------------------------------------------------------------
void CParamDisplay::setTextRotation (double angle)
{
while (angle < 0.)
angle += 360.;
while (angle > 360.)
angle -= 360.;
if (textRotation != angle)
{
textRotation = angle;
drawStyleChanged ();
}
}
//------------------------------------------------------------------------
void CParamDisplay::setRoundRectRadius (const CCoord& radius)
{
if (roundRectRadius != radius)
{
roundRectRadius = radius;
drawStyleChanged ();
}
}
//------------------------------------------------------------------------
void CParamDisplay::setFrameWidth (const CCoord& width)
{
if (frameWidth != width)
{
frameWidth = width;
drawStyleChanged ();
}
}
//------------------------------------------------------------------------
void CParamDisplay::drawStyleChanged ()
{
setDirty ();
}
//------------------------------------------------------------------------
void CParamDisplay::setBackOffset (const CPoint &offset)
{
backOffset = offset;
}
//-----------------------------------------------------------------------------
void CParamDisplay::copyBackOffset ()
{
backOffset (getViewSize ().left, getViewSize ().top);
}
} // VSTGUI