diff options
| author | Vaxry <43317083+vaxerski@users.noreply.github.com> | 2026-05-06 13:56:12 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-05-06 13:56:12 +0100 |
| commit | 1681bea42dd2f11ba3fe6df05560d0b231de3c76 (patch) | |
| tree | 899103dbddf675a01758c7cdd379224c9c81a7fb /src/config/lua/layout/LuaLayoutTarget.cpp | |
| parent | 5f1350f522d3fe3af78cbe30a98311763b3509d5 (diff) | |
config/lua: add simple layout API (#14258)
Adds a simple layout lua api
Diffstat (limited to 'src/config/lua/layout/LuaLayoutTarget.cpp')
| -rw-r--r-- | src/config/lua/layout/LuaLayoutTarget.cpp | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/config/lua/layout/LuaLayoutTarget.cpp b/src/config/lua/layout/LuaLayoutTarget.cpp new file mode 100644 index 00000000..9113f0fd --- /dev/null +++ b/src/config/lua/layout/LuaLayoutTarget.cpp @@ -0,0 +1,98 @@ +#include "LuaLayoutTarget.hpp" + +#include "LuaLayoutContext.hpp" +#include "../bindings/LuaBindingsInternal.hpp" +#include "../objects/LuaObjectHelpers.hpp" +#include "../objects/LuaWindow.hpp" + +#include "../../../layout/target/Target.hpp" + +#include <string_view> + +using namespace Config::Lua; +using namespace Config::Lua::Layouts; + +static constexpr const char* TARGET_MT = "HL.LayoutTarget"; + +namespace { + struct SLuaLayoutTargetRef { + WP<Layout::ITarget> target; + size_t index = 0; + }; +} + +static int layoutTargetPlace(lua_State* L) { + auto* ref = sc<SLuaLayoutTargetRef*>(luaL_checkudata(L, 1, TARGET_MT)); + auto target = ref->target.lock(); + if (!target) + return 0; + + CBox box; + if (!boxFromTable(L, 2, box)) + return Bindings::Internal::configError(L, "HL.LayoutTarget: place expects a box table { x, y, w, h }"); + + target->setPositionGlobal(box.noNegativeSize()); + return 0; +} + +static int layoutTargetIndex(lua_State* L) { + auto* ref = sc<SLuaLayoutTargetRef*>(luaL_checkudata(L, 1, TARGET_MT)); + const std::string_view key = luaL_checkstring(L, 2); + + auto target = ref->target.lock(); + if (!target) { + lua_pushnil(L); + return 1; + } + + if (key == "index") + lua_pushinteger(L, sc<lua_Integer>(ref->index)); + else if (key == "window") { + const auto window = target->window(); + if (window) + Objects::CLuaWindow::push(L, window); + else + lua_pushnil(L); + } else if (key == "box") + pushBox(L, target->position()); + else if (key == "place" || key == "set_box") + lua_pushcfunction(L, layoutTargetPlace); + else + lua_pushnil(L); + + return 1; +} + +static int layoutTargetGc(lua_State* L) { + sc<SLuaLayoutTargetRef*>(lua_touserdata(L, 1))->~SLuaLayoutTargetRef(); + return 0; +} + +static int layoutTargetToString(lua_State* L) { + auto* ref = sc<SLuaLayoutTargetRef*>(luaL_checkudata(L, 1, TARGET_MT)); + auto target = ref->target.lock(); + if (!target) + lua_pushstring(L, "HL.LayoutTarget(expired)"); + else + lua_pushfstring(L, "HL.LayoutTarget(%d)", sc<int>(ref->index)); + return 1; +} + +void Config::Lua::Layouts::setupLayoutTarget(lua_State* L) { + luaL_newmetatable(L, TARGET_MT); + lua_pushcfunction(L, layoutTargetIndex); + lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, Objects::readOnlyNewIndex); + lua_setfield(L, -2, "__newindex"); + lua_pushcfunction(L, layoutTargetGc); + lua_setfield(L, -2, "__gc"); + lua_pushcfunction(L, layoutTargetToString); + lua_setfield(L, -2, "__tostring"); + lua_pop(L, 1); +} + +void Config::Lua::Layouts::pushLayoutTarget(lua_State* L, const SP<Layout::ITarget>& target, size_t index) { + new (lua_newuserdata(L, sizeof(SLuaLayoutTargetRef))) SLuaLayoutTargetRef{target, index}; + luaL_getmetatable(L, TARGET_MT); + lua_setmetatable(L, -2); +} |
