Initial release
This commit is contained in:
+870
@@ -0,0 +1,870 @@
|
||||
// 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 "drawcontextobject.h"
|
||||
#include "converters.h"
|
||||
#include "../../lib/cdrawcontext.h"
|
||||
#include "../../lib/cgraphicspath.h"
|
||||
#include "../../lib/cgradient.h"
|
||||
#include "../../uidescription/uidescription.h"
|
||||
#include "../../uidescription/uiviewcreator.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace VSTGUI {
|
||||
namespace ScriptingInternal {
|
||||
|
||||
using namespace std::literals;
|
||||
using namespace TJS;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
static T getFromVar (CScriptVar* var, const string& exceptionString)
|
||||
{
|
||||
auto customData = var->getCustomData ();
|
||||
if (!customData.has_value ())
|
||||
throw CScriptException (exceptionString);
|
||||
try
|
||||
{
|
||||
auto result = std::any_cast<T> (customData);
|
||||
return result;
|
||||
}
|
||||
catch (const std::bad_any_cast&)
|
||||
{
|
||||
throw CScriptException (exceptionString);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static SharedPointer<CGraphicsPath> getGraphicsPath (CScriptVar* var, std::string_view varName,
|
||||
std::string_view signature)
|
||||
{
|
||||
auto pathVar = getArgument (var, varName, signature);
|
||||
return getFromVar<SharedPointer<CGraphicsPath>> (pathVar, "Variable is not a graphics path");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static SharedPointer<CGradient> getGradient (CScriptVar* var, std::string_view varName,
|
||||
std::string_view signature)
|
||||
{
|
||||
auto gradientVar = getArgument (var, varName, signature);
|
||||
return getFromVar<SharedPointer<CGradient>> (gradientVar, "Variable is not a gradient");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static std::shared_ptr<CGraphicsTransform> getTransformMatrix (CScriptVar* var,
|
||||
std::string_view varName,
|
||||
std::string_view signature)
|
||||
{
|
||||
auto tmVar = getArgument (var, varName, signature);
|
||||
return getFromVar<std::shared_ptr<CGraphicsTransform>> (tmVar,
|
||||
"Variable is not a transform matrix");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static std::shared_ptr<CGraphicsTransform> getOptionalTransformMatrix (CScriptVar* var,
|
||||
std::string_view varName,
|
||||
std::string_view signature)
|
||||
{
|
||||
if (auto tmVar = getOptionalArgument (var, varName))
|
||||
return getFromVar<std::shared_ptr<CGraphicsTransform>> (
|
||||
tmVar, "Variable is not a transform matrix");
|
||||
return {};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static CRect getRect (CScriptVar* var, std::string_view varName, std::string_view signature)
|
||||
{
|
||||
auto rectVar = getArgument (var, varName, signature);
|
||||
auto rect = fromScriptRect (*rectVar);
|
||||
return rect;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static CPoint getPoint (CScriptVar* var, std::string_view varName, std::string_view signature)
|
||||
{
|
||||
auto pointVar = getArgument (var, varName, signature);
|
||||
auto point = fromScriptPoint (*pointVar);
|
||||
return point;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static CPoint getOptionalPoint (CScriptVar* var, std::string_view varName,
|
||||
std::string_view signature, CPoint defaultPoint = {})
|
||||
{
|
||||
if (auto pointVar = getOptionalArgument (var, varName))
|
||||
return fromScriptPoint (*pointVar);
|
||||
return defaultPoint;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static double getDouble (CScriptVar* var, std::string_view varName, std::string_view signature)
|
||||
{
|
||||
auto doubleVar = getArgument (var, varName, signature);
|
||||
if (!doubleVar->isNumeric ())
|
||||
{
|
||||
TJS::string s ("'");
|
||||
s.append (varName);
|
||||
s.append ("' must be a number");
|
||||
throw CScriptException (s);
|
||||
}
|
||||
return doubleVar->getDouble ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static int64_t getInt (CScriptVar* var, std::string_view varName, std::string_view signature)
|
||||
{
|
||||
auto intVar = getArgument (var, varName, signature);
|
||||
if (!intVar->isNumeric ())
|
||||
{
|
||||
TJS::string s ("'");
|
||||
s.append (varName);
|
||||
s.append ("' must be numeric");
|
||||
throw CScriptException (s);
|
||||
}
|
||||
return intVar->getInt ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static int64_t getOptionalInt (CScriptVar* var, std::string_view varName,
|
||||
std::string_view signature, int64_t defaultInt = {})
|
||||
{
|
||||
if (auto intVar = getOptionalArgument (var, varName))
|
||||
{
|
||||
if (!intVar->isNumeric ())
|
||||
{
|
||||
TJS::string s ("'");
|
||||
s.append (varName);
|
||||
s.append ("' must be numeric");
|
||||
throw CScriptException (s);
|
||||
}
|
||||
return intVar->getInt ();
|
||||
}
|
||||
return defaultInt;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static CColor getColor (CScriptVar* var, const IUIDescription* uiDesc, std::string_view varName,
|
||||
std::string_view signature)
|
||||
{
|
||||
auto colorVar = getArgument (var, varName, signature);
|
||||
auto colorStr = colorVar->getString ();
|
||||
CColor color {};
|
||||
if (!UIViewCreator::stringToColor (colorStr, color, uiDesc))
|
||||
{
|
||||
string str ("'");
|
||||
str += colorStr;
|
||||
str += "' is not a color in a call to ";
|
||||
str += signature;
|
||||
throw CScriptException (str);
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
struct TransformMatrixScriptObject : ScriptObject
|
||||
{
|
||||
using TransformMatrixPtr = std::shared_ptr<CGraphicsTransform>;
|
||||
|
||||
TransformMatrixScriptObject (TransformMatrixPtr tm = std::make_shared<CGraphicsTransform> ())
|
||||
: ScriptObject (new CScriptVar ("", SCRIPTVAR_OBJECT))
|
||||
{
|
||||
scriptVar->setCustomData (tm);
|
||||
addFunc ("concat"sv, [tm] (auto var) { concat (tm, var); }, {"transformMatrix"sv});
|
||||
addFunc ("inverse"sv, [tm] (auto var) { inverse (tm, var); });
|
||||
addFunc ("rotate"sv, [tm] (auto var) { rotate (tm, var); }, {"angle"sv, "center?"sv});
|
||||
addFunc ("scale"sv, [tm] (auto var) { scale (tm, var); }, {"x"sv, "y"sv});
|
||||
addFunc ("skewX"sv, [tm] (auto var) { skewX (tm, var); }, {"angle"sv});
|
||||
addFunc ("skewY"sv, [tm] (auto var) { skewY (tm, var); }, {"angle"sv});
|
||||
addFunc ("translate"sv, [tm] (auto var) { translate (tm, var); }, {"x"sv, "y"sv});
|
||||
addFunc ("transform"sv, [tm] (auto var) { transform (tm, var); }, {"pointOrRect"sv});
|
||||
}
|
||||
|
||||
static void inverse (const TransformMatrixPtr& tm, CScriptVar* var)
|
||||
{
|
||||
static constexpr auto signature = "matrix.inverse();"sv;
|
||||
auto iTm = tm->inverse ();
|
||||
TransformMatrixScriptObject obj (std::make_shared<CGraphicsTransform> (iTm));
|
||||
var->setReturnVar (obj.take ());
|
||||
}
|
||||
|
||||
static void concat (const TransformMatrixPtr& tm, CScriptVar* var)
|
||||
{
|
||||
static constexpr auto signature = "matrix.concat(transformMatrix);"sv;
|
||||
auto other = getTransformMatrix (var, "transformMatrix"sv, signature);
|
||||
auto result = *(tm.get ()) * *(other.get ());
|
||||
*(tm.get ()) = result;
|
||||
}
|
||||
|
||||
static void translate (const TransformMatrixPtr& tm, CScriptVar* var)
|
||||
{
|
||||
static constexpr auto signature = "matrix.translate(x, y);"sv;
|
||||
auto x = getDouble (var, "x"sv, signature);
|
||||
auto y = getDouble (var, "y"sv, signature);
|
||||
tm->translate (x, y);
|
||||
}
|
||||
|
||||
static void scale (const TransformMatrixPtr& tm, CScriptVar* var)
|
||||
{
|
||||
static constexpr auto signature = "matrix.scale(x, y);"sv;
|
||||
auto x = getDouble (var, "x"sv, signature);
|
||||
auto y = getDouble (var, "y"sv, signature);
|
||||
tm->scale (x, y);
|
||||
}
|
||||
|
||||
static void rotate (const TransformMatrixPtr& tm, CScriptVar* var)
|
||||
{
|
||||
static constexpr auto signature = "matrix.rotate(angle, center?);"sv;
|
||||
auto angle = getDouble (var, "angle"sv, signature);
|
||||
if (auto centerVar = getOptionalArgument (var, "center?"sv))
|
||||
{
|
||||
auto center = fromScriptPoint (*centerVar);
|
||||
tm->rotate (angle, center);
|
||||
}
|
||||
else
|
||||
{
|
||||
tm->rotate (angle);
|
||||
}
|
||||
}
|
||||
|
||||
static void skewX (const TransformMatrixPtr& tm, CScriptVar* var)
|
||||
{
|
||||
static constexpr auto signature = "matrix.skewX(angle);"sv;
|
||||
auto angle = getDouble (var, "angle"sv, signature);
|
||||
tm->skewX (angle);
|
||||
}
|
||||
|
||||
static void skewY (const TransformMatrixPtr& tm, CScriptVar* var)
|
||||
{
|
||||
static constexpr auto signature = "matrix.skewY(angle);"sv;
|
||||
auto angle = getDouble (var, "angle"sv, signature);
|
||||
tm->skewY (angle);
|
||||
}
|
||||
|
||||
static void transform (const TransformMatrixPtr& tm, CScriptVar* var)
|
||||
{
|
||||
static constexpr auto signature = "matrix.transform(pointOrRect);"sv;
|
||||
auto pointOrRect = getArgument (var, "pointOrRect"sv, signature);
|
||||
auto xVar = getOptionalArgument (pointOrRect, "x"sv);
|
||||
auto yVar = getOptionalArgument (pointOrRect, "y"sv);
|
||||
if (xVar && yVar)
|
||||
{
|
||||
auto x = xVar->getDouble ();
|
||||
auto y = yVar->getDouble ();
|
||||
tm->transform (x, y);
|
||||
xVar->setDouble (x);
|
||||
yVar->setDouble (y);
|
||||
return;
|
||||
}
|
||||
auto leftVar = getOptionalArgument (pointOrRect, "left"sv);
|
||||
auto topVar = getOptionalArgument (pointOrRect, "top"sv);
|
||||
auto rightVar = getOptionalArgument (pointOrRect, "right"sv);
|
||||
auto bottomVar = getOptionalArgument (pointOrRect, "bottom"sv);
|
||||
if (leftVar && topVar && rightVar && bottomVar)
|
||||
{
|
||||
CRect r (leftVar->getDouble (), topVar->getDouble (), rightVar->getDouble (),
|
||||
bottomVar->getDouble ());
|
||||
tm->transform (r);
|
||||
leftVar->setDouble (r.left);
|
||||
topVar->setDouble (r.top);
|
||||
rightVar->setDouble (r.right);
|
||||
bottomVar->setDouble (r.bottom);
|
||||
return;
|
||||
}
|
||||
|
||||
string s ("Argument is not a point or a rect in ");
|
||||
s.append (signature);
|
||||
throw CScriptException (std::move (s));
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
TJS::CScriptVar* makeTransformMatrixObject ()
|
||||
{
|
||||
TransformMatrixScriptObject obj;
|
||||
return obj.take ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
struct GradientScriptObject : ScriptObject
|
||||
{
|
||||
GradientScriptObject (const SharedPointer<CGradient>& g, const IUIDescription* uiDesc)
|
||||
: ScriptObject (new CScriptVar ("", SCRIPTVAR_OBJECT))
|
||||
{
|
||||
scriptVar->setCustomData (g);
|
||||
|
||||
addFunc ("addColorStop"sv, [g, uiDesc] (auto var) { addColorStop (g, uiDesc, var); },
|
||||
{"position"sv, "color"sv});
|
||||
}
|
||||
|
||||
static void addColorStop (const SharedPointer<CGradient>& g, const IUIDescription* uiDesc,
|
||||
CScriptVar* var)
|
||||
{
|
||||
static constexpr auto signature = "gradient.addColorStop(position, color);"sv;
|
||||
auto position = getDouble (var, "position"sv, signature);
|
||||
auto color = getColor (var, uiDesc, "color"sv, signature);
|
||||
g->addColorStop (position, color);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
struct GraphicsPathScriptObject : ScriptObject
|
||||
{
|
||||
GraphicsPathScriptObject (const SharedPointer<CGraphicsPath>& p)
|
||||
: ScriptObject (new CScriptVar ("", SCRIPTVAR_OBJECT))
|
||||
{
|
||||
scriptVar->setCustomData (p);
|
||||
|
||||
addFunc ("addEllipse"sv, [p] (auto var) { addEllipse (p, var); }, {"rect"sv});
|
||||
addFunc ("addArc"sv, [p] (auto var) { addArc (p, var); },
|
||||
{"rect"sv, "startAngle"sv, "endAngle"sv, "clockwise"sv});
|
||||
addFunc ("addBezierCurve"sv, [p] (auto var) { addBezierCurve (p, var); },
|
||||
{"control1"sv, "control2"sv, "end"sv});
|
||||
addFunc ("addLine"sv, [p] (auto var) { addLine (p, var); }, {"to"sv});
|
||||
addFunc ("addPath"sv, [p] (auto var) { addPath (p, var); },
|
||||
{"path"sv, "transformMatrix?"sv});
|
||||
addFunc ("addRect"sv, [p] (auto var) { addRect (p, var); }, {"rect"sv});
|
||||
addFunc ("addRoundRect"sv, [p] (auto var) { addRoundRect (p, var); },
|
||||
{"rect"sv, "radius"sv});
|
||||
addFunc ("closeSubpath"sv, [p] (auto var) { closeSubpath (p); });
|
||||
addFunc ("beginSubpath"sv, [p] (auto var) { beginSubpath (p, var); }, {"start"sv});
|
||||
}
|
||||
|
||||
static void addPath (const SharedPointer<CGraphicsPath>& path, CScriptVar* var)
|
||||
{
|
||||
static constexpr auto signature = "path.addPath(path, transformMatrix?);"sv;
|
||||
auto otherPath = getGraphicsPath (var, "path"sv, signature);
|
||||
auto tm = getOptionalTransformMatrix (var, "transformMatrix?"sv, signature);
|
||||
path->addPath (*otherPath.get (), tm ? tm.get () : nullptr);
|
||||
}
|
||||
|
||||
static void addArc (const SharedPointer<CGraphicsPath>& path, CScriptVar* var)
|
||||
{
|
||||
static constexpr auto signature = "path.addArc(rect, startAngle, endAngle, clockwise);"sv;
|
||||
auto rect = getRect (var, "rect"sv, signature);
|
||||
auto startAngle = getDouble (var, "startAngle"sv, signature);
|
||||
auto endAngle = getDouble (var, "endAngle"sv, signature);
|
||||
auto clockwise = getInt (var, "clockwise"sv, signature);
|
||||
path->addArc (rect, startAngle, endAngle, clockwise != 0 ? true : false);
|
||||
}
|
||||
|
||||
static void addEllipse (const SharedPointer<CGraphicsPath>& path, CScriptVar* var)
|
||||
{
|
||||
static constexpr auto signature = "path.addEllipse(rect);"sv;
|
||||
auto rect = getRect (var, "rect"sv, signature);
|
||||
path->addEllipse (rect);
|
||||
}
|
||||
|
||||
static void addRect (const SharedPointer<CGraphicsPath>& path, CScriptVar* var)
|
||||
{
|
||||
static constexpr auto signature = "path.addRect(rect);"sv;
|
||||
auto rect = getRect (var, "rect"sv, signature);
|
||||
path->addRect (rect);
|
||||
}
|
||||
|
||||
static void addLine (const SharedPointer<CGraphicsPath>& path, CScriptVar* var)
|
||||
{
|
||||
static constexpr auto signature = "path.addLine(to);"sv;
|
||||
auto point = getPoint (var, "to"sv, signature);
|
||||
path->addLine (point);
|
||||
}
|
||||
|
||||
static void addBezierCurve (const SharedPointer<CGraphicsPath>& path, CScriptVar* var)
|
||||
{
|
||||
static constexpr auto signature = "path.addBezierCurve(control1, control2, end);"sv;
|
||||
auto control1 = getPoint (var, "control1"sv, signature);
|
||||
auto control2 = getPoint (var, "control2"sv, signature);
|
||||
auto end = getPoint (var, "end"sv, signature);
|
||||
path->addBezierCurve (control1, control2, end);
|
||||
}
|
||||
|
||||
static void beginSubpath (const SharedPointer<CGraphicsPath>& path, CScriptVar* var)
|
||||
{
|
||||
static constexpr auto signature = "path.beginSubpath(start);"sv;
|
||||
auto start = getPoint (var, "start"sv, signature);
|
||||
path->beginSubpath (start);
|
||||
}
|
||||
|
||||
static void closeSubpath (const SharedPointer<CGraphicsPath>& path)
|
||||
{
|
||||
static constexpr auto signature = "path.closeSubpath();"sv;
|
||||
path->closeSubpath ();
|
||||
}
|
||||
|
||||
static void addRoundRect (const SharedPointer<CGraphicsPath>& path, CScriptVar* var)
|
||||
{
|
||||
static constexpr auto signature = "path.addRoundRect(rect, radius);"sv;
|
||||
auto rect = getRect (var, "rect"sv, signature);
|
||||
auto radius = getDouble (var, "radius"sv, signature);
|
||||
path->addRoundRect (rect, radius);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
ScriptObject makeGraphicsPathScriptObject (const SharedPointer<CGraphicsPath>& p)
|
||||
{
|
||||
return GraphicsPathScriptObject (p);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
struct DrawContextObject::Impl
|
||||
{
|
||||
CDrawContext* context {nullptr};
|
||||
IUIDescription* uiDesc {nullptr};
|
||||
mutable int32_t globalStatesStored {0};
|
||||
|
||||
void setContext (CDrawContext* inContext, IUIDescription* inUIDesc)
|
||||
{
|
||||
if (context)
|
||||
{
|
||||
while (globalStatesStored > 0)
|
||||
{
|
||||
context->restoreGlobalState ();
|
||||
--globalStatesStored;
|
||||
}
|
||||
}
|
||||
context = inContext;
|
||||
uiDesc = inUIDesc;
|
||||
globalStatesStored = 0;
|
||||
}
|
||||
|
||||
void checkContextOrThrow () const
|
||||
{
|
||||
if (!context)
|
||||
throw CScriptException ("Native context is missing!");
|
||||
}
|
||||
|
||||
CDrawStyle getDrawStyle (CScriptVar* styleVar) const
|
||||
{
|
||||
CDrawStyle style {};
|
||||
auto string = styleVar->getString ();
|
||||
if (string == "stroked"sv)
|
||||
style = kDrawStroked;
|
||||
else if (string == "filled"sv)
|
||||
style = kDrawFilled;
|
||||
else if (string == "filledAndStroked"sv)
|
||||
style = kDrawFilledAndStroked;
|
||||
else
|
||||
throw CScriptException ("Unknown draw style: " + string);
|
||||
return style;
|
||||
}
|
||||
|
||||
CDrawContext::PathDrawMode getPathDrawMode (CScriptVar* var) const
|
||||
{
|
||||
CDrawContext::PathDrawMode mode {};
|
||||
auto string = var->getString ();
|
||||
if (string == "stroked"sv)
|
||||
mode = CDrawContext::PathDrawMode::kPathStroked;
|
||||
else if (string == "filled"sv)
|
||||
mode = CDrawContext::PathDrawMode::kPathFilled;
|
||||
else if (string == "filledEvenOdd"sv)
|
||||
mode = CDrawContext::PathDrawMode::kPathFilledEvenOdd;
|
||||
else
|
||||
throw CScriptException ("Unknown path draw mode: " + string);
|
||||
return mode;
|
||||
}
|
||||
|
||||
void createRoundGraphicsPath (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature = "drawContext.createRoundGraphicsPath(rect, radius);"sv;
|
||||
checkContextOrThrow ();
|
||||
auto rect = getRect (var, "rect"sv, signature);
|
||||
auto radius = getDouble (var, "radius"sv, signature);
|
||||
if (auto path = owned (context->createRoundRectGraphicsPath (rect, radius)))
|
||||
{
|
||||
GraphicsPathScriptObject obj (path);
|
||||
var->setReturnVar (obj);
|
||||
}
|
||||
}
|
||||
|
||||
void createGraphicsPath (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature = "drawContext.createGraphicsPath();"sv;
|
||||
checkContextOrThrow ();
|
||||
if (auto path = owned (context->createGraphicsPath ()))
|
||||
{
|
||||
GraphicsPathScriptObject obj (path);
|
||||
var->setReturnVar (obj);
|
||||
}
|
||||
}
|
||||
|
||||
void createGradient (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature =
|
||||
"drawContext.createGradient(startColorPosition, startColor, endColorPosition, endColor);"sv;
|
||||
auto startColorPosition = getDouble (var, "startColorPosition", signature);
|
||||
auto endColorPosition = getDouble (var, "endColorPosition", signature);
|
||||
auto startColor = getColor (var, uiDesc, "startColor"sv, signature);
|
||||
auto endColor = getColor (var, uiDesc, "endColor"sv, signature);
|
||||
if (auto gradient = owned (
|
||||
CGradient::create (startColorPosition, endColorPosition, startColor, endColor)))
|
||||
{
|
||||
GradientScriptObject obj (gradient, uiDesc);
|
||||
var->setReturnVar (obj);
|
||||
}
|
||||
}
|
||||
|
||||
void drawGraphicsPath (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature =
|
||||
"drawContext.drawGraphicsPath(path, mode?, transform?);"sv;
|
||||
checkContextOrThrow ();
|
||||
auto path = getGraphicsPath (var, "path"sv, signature);
|
||||
auto modeVar = getOptionalArgument (var, "mode?");
|
||||
auto mode = modeVar ? getPathDrawMode (modeVar) : CDrawContext::PathDrawMode::kPathFilled;
|
||||
auto tm = getOptionalTransformMatrix (var, "transform?"sv, signature);
|
||||
context->drawGraphicsPath (path, mode, tm ? tm.get () : nullptr);
|
||||
}
|
||||
|
||||
void fillLinearGradient (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature =
|
||||
"drawContext.fillLinearGradient(path, gradient, startPoint, endPoint, evenOdd?, transform?);"sv;
|
||||
checkContextOrThrow ();
|
||||
auto path = getGraphicsPath (var, "path"sv, signature);
|
||||
auto gradient = getGradient (var, "gradient"sv, signature);
|
||||
auto startPoint = getPoint (var, "startPoint"sv, signature);
|
||||
auto endPoint = getPoint (var, "endPoint"sv, signature);
|
||||
auto tm = getOptionalTransformMatrix (var, "transform?"sv, signature);
|
||||
auto evenOdd = getOptionalInt (var, "evenOdd?", signature);
|
||||
context->fillLinearGradient (path, *gradient, startPoint, endPoint, evenOdd > 0, tm.get ());
|
||||
}
|
||||
|
||||
void fillRadialGradient (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature =
|
||||
"drawContext.fillRadialGradient(path, gradient, centerPoint, radius, originOffsetPoint?, evenOdd?, transform?);"sv;
|
||||
checkContextOrThrow ();
|
||||
auto path = getGraphicsPath (var, "path"sv, signature);
|
||||
auto gradient = getGradient (var, "gradient"sv, signature);
|
||||
auto centerPoint = getPoint (var, "centerPoint"sv, signature);
|
||||
auto radius = getDouble (var, "radius"sv, signature);
|
||||
auto originOffsetPoint = getOptionalPoint (var, "originOffsetPoint?"sv, signature);
|
||||
auto evenOdd = getOptionalInt (var, "evenOdd?", signature);
|
||||
auto tm = getOptionalTransformMatrix (var, "transform?"sv, signature);
|
||||
context->fillRadialGradient (path, *gradient, centerPoint, radius, originOffsetPoint,
|
||||
evenOdd, tm.get ());
|
||||
}
|
||||
|
||||
void drawLine (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature = "drawContext.drawLine(from, to);"sv;
|
||||
checkContextOrThrow ();
|
||||
auto fromPoint = getArgument (var, "from"sv, signature);
|
||||
auto toPoint = getArgument (var, "to"sv, signature);
|
||||
auto from = fromScriptPoint (*fromPoint);
|
||||
auto to = fromScriptPoint (*toPoint);
|
||||
context->drawLine (from, to);
|
||||
}
|
||||
void drawRect (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature = "drawContext.drawRect(rect, style);"sv;
|
||||
checkContextOrThrow ();
|
||||
auto rect = getRect (var, "rect"sv, signature);
|
||||
auto styleVar = getArgument (var, "style"sv, signature);
|
||||
auto style = getDrawStyle (styleVar);
|
||||
context->drawRect (rect, style);
|
||||
}
|
||||
void drawEllipse (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature = "drawContext.drawEllipse(rect, style);"sv;
|
||||
checkContextOrThrow ();
|
||||
auto rect = getRect (var, "rect"sv, signature);
|
||||
auto styleVar = getArgument (var, "style"sv, signature);
|
||||
auto style = getDrawStyle (styleVar);
|
||||
context->drawEllipse (rect, style);
|
||||
}
|
||||
void drawArc (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature =
|
||||
"drawContext.drawArc(rect, startAngle, endAngle, style);"sv;
|
||||
checkContextOrThrow ();
|
||||
auto rect = getRect (var, "rect"sv, signature);
|
||||
auto startAngle = static_cast<float> (getDouble (var, "startAngle"sv, signature));
|
||||
auto endAngle = static_cast<float> (getDouble (var, "endAngle"sv, signature));
|
||||
auto styleVar = getArgument (var, "style"sv, signature);
|
||||
auto style = getDrawStyle (styleVar);
|
||||
context->drawArc (rect, startAngle, endAngle, style);
|
||||
}
|
||||
void clearRect (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature = "drawContext.clearRect(rect);"sv;
|
||||
checkContextOrThrow ();
|
||||
auto rect = getRect (var, "rect"sv, signature);
|
||||
context->clearRect (rect);
|
||||
}
|
||||
void drawPolygon (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature = "drawContext.drawPolygon(points, style);"sv;
|
||||
checkContextOrThrow ();
|
||||
auto pointsVar = getArgument (var, "points"sv, signature);
|
||||
auto styleVar = getArgument (var, "style"sv, signature);
|
||||
if (!pointsVar->isArray ())
|
||||
throw CScriptException ("`points` argument must be an array of points in "
|
||||
"drawContext.drawPolygon(points, style);");
|
||||
PointList points;
|
||||
auto numPoints = pointsVar->getArrayLength ();
|
||||
for (auto index = 0; index < numPoints; ++index)
|
||||
{
|
||||
auto pointVar = pointsVar->getArrayIndex (index);
|
||||
vstgui_assert (pointVar != nullptr);
|
||||
points.emplace_back (fromScriptPoint (*pointVar));
|
||||
}
|
||||
auto style = getDrawStyle (styleVar);
|
||||
context->drawPolygon (points, style);
|
||||
}
|
||||
void setClipRect (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature = "drawContext.setClipRect(rect);"sv;
|
||||
checkContextOrThrow ();
|
||||
auto rect = getRect (var, "rect"sv, signature);
|
||||
context->setClipRect (rect);
|
||||
}
|
||||
void drawBitmap (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature =
|
||||
"drawContext.drawBitmap(name, destRect, offsetPoint?, alpha?);"sv;
|
||||
checkContextOrThrow ();
|
||||
auto nameVar = getArgument (var, "name"sv, signature);
|
||||
auto destRect = getRect (var, "destRect"sv, signature);
|
||||
auto offsetPointVar = getOptionalArgument (var, "offsetPoint?"sv);
|
||||
auto alphaVar = getOptionalArgument (var, "alpha?"sv);
|
||||
auto bitmap = uiDesc->getBitmap (nameVar->getString ().data ());
|
||||
if (!bitmap)
|
||||
throw CScriptException ("bitmap not found in uiDescription");
|
||||
auto offset = offsetPointVar ? fromScriptPoint (*offsetPointVar) : CPoint (0, 0);
|
||||
auto alpha = static_cast<float> (alphaVar ? alphaVar->getDouble () : 1.);
|
||||
context->drawBitmap (bitmap, destRect, offset, alpha);
|
||||
}
|
||||
void drawString (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature = "drawContext.drawString(string, rect, align?);"sv;
|
||||
checkContextOrThrow ();
|
||||
auto stringVar = getArgument (var, "string"sv, signature);
|
||||
auto rect = getRect (var, "rect"sv, signature);
|
||||
auto alignVar = getOptionalArgument (var, "align?"sv);
|
||||
auto string = stringVar->getString ().data ();
|
||||
CHoriTxtAlign align = kCenterText;
|
||||
if (!alignVar || alignVar->isUndefined ())
|
||||
align = kCenterText;
|
||||
else if (alignVar->getString () == "left"sv)
|
||||
align = kLeftText;
|
||||
else if (alignVar->getString () == "center"sv)
|
||||
align = kCenterText;
|
||||
else if (alignVar->getString () == "right"sv)
|
||||
align = kRightText;
|
||||
else
|
||||
throw CScriptException (
|
||||
"wrong `align` argument. Expecting 'left', 'center' or 'right'");
|
||||
context->drawString (string, rect, align, true);
|
||||
}
|
||||
void setFont (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature = "drawContext.setFont(name);"sv;
|
||||
checkContextOrThrow ();
|
||||
auto fontVar = getArgument (var, "name"sv, signature);
|
||||
if (auto font = uiDesc->getFont (fontVar->getString ().data ()))
|
||||
context->setFont (font);
|
||||
}
|
||||
void setFontColor (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature = "drawContext.setFontColor(color);"sv;
|
||||
checkContextOrThrow ();
|
||||
auto colorVar = getArgument (var, "color"sv, signature);
|
||||
CColor color {};
|
||||
UIViewCreator::stringToColor (colorVar->getString (), color, uiDesc);
|
||||
context->setFontColor (color);
|
||||
}
|
||||
void setFillColor (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature = "drawContext.setFillColor(color);"sv;
|
||||
checkContextOrThrow ();
|
||||
auto color = getColor (var, uiDesc, "color"sv, signature);
|
||||
context->setFillColor (color);
|
||||
}
|
||||
void setFrameColor (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature = "drawContext.setFrameColor(color);"sv;
|
||||
checkContextOrThrow ();
|
||||
auto color = getColor (var, uiDesc, "color"sv, signature);
|
||||
context->setFrameColor (color);
|
||||
}
|
||||
void setLineWidth (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature = "drawContext.setLineWidth(width);"sv;
|
||||
checkContextOrThrow ();
|
||||
auto widthVar = getArgument (var, "width"sv, signature);
|
||||
context->setLineWidth (widthVar->getDouble ());
|
||||
}
|
||||
void setLineStyle (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature =
|
||||
"drawContext.setLineStyle(styleOrLineCap, lineJoin?, dashLengths?, dashPhase);"sv;
|
||||
checkContextOrThrow ();
|
||||
auto styleOrLineCapVar = getArgument (var, "styleOrLineCap"sv, signature);
|
||||
auto lineJoinVar = getOptionalArgument (var, "lineJoin?"sv);
|
||||
auto dashLengthsVar = getOptionalArgument (var, "dashLengths?"sv);
|
||||
auto dashPhaseVar = getOptionalArgument (var, "dashPhase?"sv);
|
||||
auto styleOrLineCap = styleOrLineCapVar->getString ();
|
||||
std::unique_ptr<CLineStyle> lineStyle;
|
||||
if (styleOrLineCap == "solid"sv)
|
||||
{
|
||||
lineStyle = std::make_unique<CLineStyle> (kLineSolid);
|
||||
}
|
||||
else if (styleOrLineCap == "dotted"sv)
|
||||
{
|
||||
lineStyle = std::make_unique<CLineStyle> (kLineOnOffDash);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (styleOrLineCap == "butt"sv)
|
||||
lineStyle = std::make_unique<CLineStyle> (CLineStyle::LineCap::kLineCapButt);
|
||||
else if (styleOrLineCap == "round"sv)
|
||||
lineStyle = std::make_unique<CLineStyle> (CLineStyle::LineCap::kLineCapRound);
|
||||
else if (styleOrLineCap == "square"sv)
|
||||
lineStyle = std::make_unique<CLineStyle> (CLineStyle::LineCap::kLineCapSquare);
|
||||
else
|
||||
throw CScriptException ("unknown `line cap` argument");
|
||||
if (lineJoinVar)
|
||||
{
|
||||
auto lineJoin = lineJoinVar->getString ();
|
||||
if (lineJoin == "miter"sv)
|
||||
lineStyle->setLineJoin (CLineStyle::LineJoin::kLineJoinMiter);
|
||||
else if (lineJoin == "round"sv)
|
||||
lineStyle->setLineJoin (CLineStyle::LineJoin::kLineJoinRound);
|
||||
else if (lineJoin == "bevel"sv)
|
||||
lineStyle->setLineJoin (CLineStyle::LineJoin::kLineJoinBevel);
|
||||
}
|
||||
if (dashLengthsVar)
|
||||
{
|
||||
if (!dashLengthsVar->isArray ())
|
||||
throw CScriptException ("`dashLengths` must be an array of numbers");
|
||||
CLineStyle::CoordVector lengths;
|
||||
auto numValues = dashLengthsVar->getArrayLength ();
|
||||
for (auto index = 0; index < numValues; ++index)
|
||||
{
|
||||
if (auto lengthVar = dashLengthsVar->getArrayIndex (index))
|
||||
lengths.push_back (lengthVar->getDouble ());
|
||||
}
|
||||
lineStyle->getDashLengths () = lengths;
|
||||
}
|
||||
if (dashPhaseVar)
|
||||
{
|
||||
lineStyle->setDashPhase (dashPhaseVar->getDouble ());
|
||||
}
|
||||
}
|
||||
if (lineStyle)
|
||||
context->setLineStyle (*lineStyle.get ());
|
||||
}
|
||||
void setGlobalAlpha (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature = "drawContext.setGlobalAlpha(alpha);"sv;
|
||||
checkContextOrThrow ();
|
||||
auto alpha = static_cast<float> (getDouble (var, "alpha"sv, signature));
|
||||
context->setGlobalAlpha (alpha);
|
||||
}
|
||||
void saveGlobalState () const
|
||||
{
|
||||
checkContextOrThrow ();
|
||||
context->saveGlobalState ();
|
||||
++globalStatesStored;
|
||||
}
|
||||
void restoreGlobalState () const
|
||||
{
|
||||
checkContextOrThrow ();
|
||||
context->restoreGlobalState ();
|
||||
--globalStatesStored;
|
||||
}
|
||||
void getStringWidth (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature = "drawContext.getStringWidth(string);"sv;
|
||||
checkContextOrThrow ();
|
||||
auto stringVar = getArgument (var, "string"sv, signature);
|
||||
auto width = context->getStringWidth (stringVar->getString ().data ());
|
||||
var->getReturnVar ()->setDouble (width);
|
||||
}
|
||||
void setDrawMode (CScriptVar* var) const
|
||||
{
|
||||
static constexpr auto signature = "drawContext.setDrawMode(mode);"sv;
|
||||
checkContextOrThrow ();
|
||||
auto modeVar = getArgument (var, "mode"sv, signature);
|
||||
if (modeVar->getString () == "aliasing"sv)
|
||||
context->setDrawMode (kAliasing);
|
||||
else if (modeVar->getString () == "anti-aliasing"sv)
|
||||
context->setDrawMode (kAntiAliasing);
|
||||
else
|
||||
throw CScriptException ("`mode` must be `aliasing` or `anti-aliasing`");
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
DrawContextObject::DrawContextObject ()
|
||||
{
|
||||
impl = std::make_unique<Impl> ();
|
||||
scriptVar->setLifeTimeObserver (this);
|
||||
addFunc ("clearRect"sv, [this] (auto var) { impl->clearRect (var); }, {"rect"sv});
|
||||
addFunc ("createRoundGraphicsPath"sv,
|
||||
[this] (auto var) { impl->createRoundGraphicsPath (var); }, {"rect"sv, "radius"sv});
|
||||
addFunc ("createGraphicsPath"sv, [this] (auto var) { impl->createGraphicsPath (var); });
|
||||
addFunc ("createGradient"sv, [this] (auto var) { impl->createGradient (var); },
|
||||
{"startColorPosition"sv, "startColor"sv, "endColorPosition"sv, "endColor"sv});
|
||||
addFunc ("getStringWidth"sv, [this] (auto var) { impl->getStringWidth (var); }, {"string"sv});
|
||||
addFunc ("drawArc"sv, [this] (auto var) { impl->drawArc (var); },
|
||||
{"rect"sv, "startAngle"sv, "endAngle"sv, "style"sv});
|
||||
addFunc ("drawBitmap"sv, [this] (auto var) { impl->drawBitmap (var); },
|
||||
{"name"sv, "destRect"sv, "offsetPoint?"sv, "alpha?"sv});
|
||||
addFunc ("drawEllipse"sv, [this] (auto var) { impl->drawEllipse (var); },
|
||||
{"rect"sv, "style"sv});
|
||||
addFunc ("drawGraphicsPath"sv, [this] (auto var) { impl->drawGraphicsPath (var); },
|
||||
{"path"sv, "mode?"sv, "transform?"sv});
|
||||
addFunc ("drawLine"sv, [this] (auto var) { impl->drawLine (var); }, {"from"sv, "to"sv});
|
||||
addFunc ("drawPolygon"sv, [this] (auto var) { impl->drawPolygon (var); },
|
||||
{"points"sv, "style"sv});
|
||||
addFunc ("drawRect"sv, [this] (auto var) { impl->drawRect (var); }, {"rect"sv, "style"sv});
|
||||
addFunc ("drawString"sv, [this] (auto var) { impl->drawString (var); },
|
||||
{"string"sv, "rect"sv, "align?"sv});
|
||||
addFunc ("fillLinearGradient"sv, [this] (auto var) { impl->fillLinearGradient (var); },
|
||||
{"path"sv, "gradient"sv, "startPoint"sv, "endPoint"sv, "evenOdd?"sv, "transform?"sv});
|
||||
addFunc ("fillRadialGradient"sv, [this] (auto var) { impl->fillRadialGradient (var); },
|
||||
{"path"sv, "gradient"sv, "centerPoint"sv, "radius"sv, "originOffsetPoint?"sv,
|
||||
"evenOdd?"sv, "transform?"sv});
|
||||
addFunc ("restoreGlobalState"sv, [this] (auto var) { impl->restoreGlobalState (); });
|
||||
addFunc ("saveGlobalState"sv, [this] (auto var) { impl->saveGlobalState (); });
|
||||
addFunc ("setClipRect"sv, [this] (auto var) { impl->setClipRect (var); }, {"rect"sv});
|
||||
addFunc ("setFont"sv, [this] (auto var) { impl->setFont (var); }, {"name"sv});
|
||||
addFunc ("setFontColor"sv, [this] (auto var) { impl->setFontColor (var); }, {"color"sv});
|
||||
addFunc ("setFillColor"sv, [this] (auto var) { impl->setFillColor (var); }, {"color"sv});
|
||||
addFunc ("setFrameColor"sv, [this] (auto var) { impl->setFrameColor (var); }, {"color"sv});
|
||||
addFunc ("setGlobalAlpha", [this] (auto var) { impl->setGlobalAlpha (var); }, {"alpha"sv});
|
||||
addFunc ("setLineWidth"sv, [this] (auto var) { impl->setLineWidth (var); }, {"width"sv});
|
||||
addFunc ("setLineStyle"sv, [this] (auto var) { impl->setLineStyle (var); },
|
||||
{"styleOrLineCap"sv, "lineJoin?"sv, "dashLengths?"sv, "dashPhase?"sv});
|
||||
addFunc ("setDrawMode"sv, [this] (auto var) { impl->setDrawMode (var); }, {"mode"sv});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
DrawContextObject::~DrawContextObject () noexcept
|
||||
{
|
||||
if (scriptVar)
|
||||
scriptVar->setLifeTimeObserver (nullptr);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void DrawContextObject::setDrawContext (CDrawContext* inContext, IUIDescription* inUIDesc)
|
||||
{
|
||||
impl->setContext (inContext, inUIDesc);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void DrawContextObject::onDestroy (CScriptVar* v)
|
||||
{
|
||||
v->setLifeTimeObserver (nullptr);
|
||||
scriptVar = nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // ScriptingInternal
|
||||
} // VSTGUI
|
||||
Reference in New Issue
Block a user