blob: 4f45e4aba952f8c1c5ad1c53d316256901ffef82 [file] [log] [blame]
#ifdef WITH_RIVE_SCRIPTING
#include "rive/lua/rive_lua_libs.hpp"
#endif
#include "rive/component_dirt.hpp"
#include "rive/layout_component.hpp"
#include "rive/scripted/scripted_layout.hpp"
using namespace rive;
#ifdef WITH_RIVE_SCRIPTING
bool ScriptedLayout::scriptInit(LuaState* state)
{
ScriptedDrawable::scriptInit(state);
if (parent() != nullptr && parent()->is<LayoutComponent>())
{
parent()->as<LayoutComponent>()->markLayoutNodeDirty(true);
}
return true;
}
void ScriptedLayout::callScriptedResize(Vec2D size)
{
if (m_state == nullptr)
{
return;
}
auto state = m_state->state;
rive_lua_pushRef(state, m_self);
if (static_cast<lua_Type>(lua_getfield(state, -1, "resize")) !=
LUA_TFUNCTION)
{
fprintf(stderr, "expected resize to be a function\n");
rive_lua_pop(state, 1);
}
else
{
lua_pushvalue(state, -2);
lua_pushvec2d(state, size);
if (static_cast<lua_Status>(rive_lua_pcall(state, 2, 0)) != LUA_OK)
{
fprintf(stderr, "resize failed\n");
rive_lua_pop(state, 1);
}
}
rive_lua_pop(state, 1);
}
Vec2D ScriptedLayout::measureLayout(float width,
LayoutMeasureMode widthMode,
float height,
LayoutMeasureMode heightMode)
{
if (!measures() || m_state == nullptr)
{
return Vec2D(0, 0);
}
auto measuredWidth = std::numeric_limits<float>::max();
auto measuredHeight = std::numeric_limits<float>::max();
auto state = m_state->state;
rive_lua_pushRef(state, m_self);
if (static_cast<lua_Type>(lua_getfield(state, -1, "measure")) !=
LUA_TFUNCTION)
{
fprintf(stderr, "expected measure to be a function\n");
rive_lua_pop(state, 1);
}
else
{
lua_pushvalue(state, -2);
if (static_cast<lua_Status>(rive_lua_pcall(state, 1, 1)) != LUA_OK)
{
fprintf(stderr, "measure failed\n");
}
else
{
if (static_cast<lua_Type>(lua_type(state, -1)) != LUA_TVECTOR)
{
fprintf(stderr, "expected measure to return a Vec2D\n");
}
else
{
auto size = lua_tovec2d(state, -1);
measuredWidth = size->x;
measuredHeight = size->y;
}
}
rive_lua_pop(state, 1);
}
rive_lua_pop(state, 1);
return Vec2D(std::min((widthMode == LayoutMeasureMode::undefined
? std::numeric_limits<float>::max()
: width),
measuredWidth),
std::min((heightMode == LayoutMeasureMode::undefined
? std::numeric_limits<float>::max()
: height),
measuredHeight));
}
void ScriptedLayout::controlSize(Vec2D size,
LayoutScaleType widthScaleType,
LayoutScaleType heightScaleType,
LayoutDirection direction)
{
m_size = size;
callScriptedResize(size);
}
#else
Vec2D ScriptedLayout::measureLayout(float width,
LayoutMeasureMode widthMode,
float height,
LayoutMeasureMode heightMode)
{
return Vec2D((widthMode == LayoutMeasureMode::undefined
? std::numeric_limits<float>::max()
: width),
(heightMode == LayoutMeasureMode::undefined
? std::numeric_limits<float>::max()
: height));
}
void ScriptedLayout::controlSize(Vec2D size,
LayoutScaleType widthScaleType,
LayoutScaleType heightScaleType,
LayoutDirection direction)
{
m_size = size;
}
#endif
void ScriptedLayout::addProperty(CustomProperty* prop)
{
auto scriptInput = ScriptInput::from(prop);
if (scriptInput != nullptr)
{
scriptInput->scriptedObject(this);
}
CustomPropertyContainer::addProperty(prop);
}
Core* ScriptedLayout::clone() const
{
ScriptedLayout* twin = ScriptedLayoutBase::clone()->as<ScriptedLayout>();
if (m_fileAsset != nullptr)
{
twin->setAsset(m_fileAsset);
}
return twin;
}