Skip to content

Commit

Permalink
Merge branch 'lua_ui_child_element' into 'master'
Browse files Browse the repository at this point in the history
Lua Element as layout children

See merge request OpenMW/openmw!3582
  • Loading branch information
Zackhasacat committed Nov 28, 2023
2 parents 7245c50 + 2be3824 commit ae3f9f8
Show file tree
Hide file tree
Showing 12 changed files with 191 additions and 98 deletions.
7 changes: 7 additions & 0 deletions apps/openmw/mwlua/uibindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ namespace MWLua
MWBase::WindowManager* windowManager = MWBase::Environment::get().getWindowManager();

auto element = context.mLua->sol().new_usertype<LuaUi::Element>("Element");
element[sol::meta_function::to_string] = [](const LuaUi::Element& element) {
std::stringstream res;
res << "UiElement";
if (element.mLayer != "")
res << "[" << element.mLayer << "]";
return res.str();
};
element["layout"] = sol::property([](LuaUi::Element& element) { return element.mLayout; },
[](LuaUi::Element& element, const sol::table& layout) { element.mLayout = layout; });
element["update"] = [luaManager = context.mLuaManager](const std::shared_ptr<LuaUi::Element>& element) {
Expand Down
23 changes: 17 additions & 6 deletions components/lua_ui/adapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,16 @@ namespace LuaUi
{
mContainer = MyGUI::Gui::getInstancePtr()->createWidget<LuaContainer>(
"", MyGUI::IntCoord(), MyGUI::Align::Default, "", "");
mContainer->initialize(luaState, mContainer);
mContainer->onCoordChange([this](WidgetExtension* ext, MyGUI::IntCoord coord) { setSize(coord.size()); });
mContainer->initialize(luaState, mContainer, false);
mContainer->widget()->eventChangeCoord += MyGUI::newDelegate(this, &LuaAdapter::containerChangedCoord);
mContainer->widget()->attachToWidget(this);
}

void LuaAdapter::containerChangedCoord(MyGUI::Widget*)
{
setSize(mContainer->getSize());
}

void LuaAdapter::attach(const std::shared_ptr<Element>& element)
{
detachElement();
Expand All @@ -44,14 +49,20 @@ namespace LuaUi

void LuaAdapter::attachElement()
{
if (mElement.get())
mElement->attachToWidget(mContainer);
if (!mElement.get())
return;
if (!mElement->mRoot)
throw std::logic_error("Attempting to use a destroyed UI Element");
mContainer->setChildren({ mElement->mRoot });
mElement->mRoot->updateCoord();
mContainer->updateCoord();
}

void LuaAdapter::detachElement()
{
if (mElement.get())
mElement->detachFromWidget();
mContainer->setChildren({});
if (mElement && mElement->mRoot)
mElement->mRoot->widget()->detachFromWidget();
mElement = nullptr;
}
}
2 changes: 2 additions & 0 deletions components/lua_ui/adapter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ namespace LuaUi

void attachElement();
void detachElement();

void containerChangedCoord(MyGUI::Widget*);
};
}

Expand Down
1 change: 1 addition & 0 deletions components/lua_ui/container.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace LuaUi
{
MYGUI_RTTI_DERIVED(LuaContainer)

public:
MyGUI::IntSize calculateSize() override;
void updateCoord() override;

Expand Down
3 changes: 3 additions & 0 deletions components/lua_ui/content.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "content.hpp"
#include "element.hpp"

namespace LuaUi
{
Expand All @@ -14,6 +15,8 @@ namespace LuaUi

bool isValidContent(const sol::object& object)
{
if (object.is<Element>())
return true;
if (object.get_type() != sol::type::table)
return false;
sol::table table = object;
Expand Down
10 changes: 5 additions & 5 deletions components/lua_ui/content.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace LuaUi
: mTable(std::move(table))
{
if (!isValidContent(mTable))
throw std::domain_error("Expected a Content table");
throw std::domain_error("Invalid UI Content");
}

size_t size() const { return mTable.size(); }
Expand All @@ -43,17 +43,17 @@ namespace LuaUi
}
void insert(size_t index, const sol::table& table) { callMethod("insert", toLua(index), table); }

sol::table at(size_t index) const
sol::object at(size_t index) const
{
if (index < size())
return mTable.get<sol::table>(toLua(index));
return mTable.get<sol::object>(toLua(index));
else
throw std::range_error("Invalid Content index");
}
sol::table at(std::string_view name) const
sol::object at(std::string_view name) const
{
if (indexOf(name).has_value())
return mTable.get<sol::table>(name);
return mTable.get<sol::object>(name);
else
throw std::range_error("Invalid Content key");
}
Expand Down
22 changes: 12 additions & 10 deletions components/lua_ui/content.lua
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
local M = {}
M.__Content = true

function validateContentChild(v)
if not (type(v) == 'table' or v.__type and v.__type.name == 'LuaUi::Element') then
error('Content can only contain tables and Elements')
end
end

M.new = function(source)
local result = {}
result.__nameIndex = {}
for i, v in ipairs(source) do
if type(v) ~= 'table' then
error('Content can only contain tables')
end
validateContentChild(v)
result[i] = v
if type(v.name) == 'string' then
result.__nameIndex[v.name] = i
Expand Down Expand Up @@ -38,9 +43,7 @@ end
local methods = {
insert = function(self, index, value)
validateIndex(self, index)
if type(value) ~= 'table' then
error('Content can only contain tables')
end
validateContentChild(value)
for i = #self, index, -1 do
rawset(self, i + 1, rawget(self, i))
local name = rawget(self, i + 1)
Expand All @@ -56,7 +59,7 @@ local methods = {
indexOf = function(self, value)
if type(value) == 'string' then
return self.__nameIndex[value]
elseif type(value) == 'table' then
else
for i = 1, #self do
if rawget(self, i) == value then
return i
Expand Down Expand Up @@ -113,10 +116,9 @@ M.__newindex = function(self, key, value)
local index = getIndexFromKey(self, key)
if value == nil then
remove(self, index)
elseif type(value) == 'table' then
assign(self, index, value)
else
error('Content can only contain tables')
validateContentChild(value)
assign(self, index, value)
end
end
M.__tostring = function(self)
Expand Down
Loading

0 comments on commit ae3f9f8

Please sign in to comment.