1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-06-19 10:11:32 +00:00

Add Container widget type, use it to make Adapter code less hacky

This commit is contained in:
uramer 2022-01-29 23:40:31 +01:00
parent 086a7d9bc5
commit f07f05ddd3
9 changed files with 107 additions and 35 deletions

View file

@ -166,7 +166,7 @@ add_component_dir (queries
add_component_dir (lua_ui add_component_dir (lua_ui
properties widget element util layers content scriptsettings properties widget element util layers content scriptsettings
adapter text textedit window image adapter text textedit window image container
) )

View file

@ -3,6 +3,7 @@
#include <MyGUI_Gui.h> #include <MyGUI_Gui.h>
#include "element.hpp" #include "element.hpp"
#include "container.hpp"
namespace LuaUi namespace LuaUi
{ {
@ -15,18 +16,12 @@ namespace LuaUi
: mElement(nullptr) : mElement(nullptr)
, mContent(nullptr) , mContent(nullptr)
{ {
MyGUI::Widget* widget = MyGUI::Gui::getInstancePtr()->createWidgetT( mContent = MyGUI::Gui::getInstancePtr()->createWidget<LuaContainer>(
"LuaWidget", "", "", MyGUI::IntCoord(), MyGUI::Align::Default, "", "");
MyGUI::IntCoord(), MyGUI::Align::Default, mContent->initialize(luaState, mContent);
std::string(), ""); mContent->onCoordChange([this](WidgetExtension* ext, MyGUI::IntCoord coord)
mContent = dynamic_cast<WidgetExtension*>(widget);
if (!mContent)
throw std::runtime_error("Invalid widget!");
mContent->initialize(luaState, widget);
mContent->onSizeChange([this](MyGUI::IntSize size)
{ {
setSize(size); setSize(coord.size());
}); });
mContent->widget()->attachToWidget(this); mContent->widget()->attachToWidget(this);
} }

View file

@ -5,7 +5,7 @@
namespace LuaUi namespace LuaUi
{ {
class WidgetExtension; class LuaContainer;
struct Element; struct Element;
class LuaAdapter : public MyGUI::Widget class LuaAdapter : public MyGUI::Widget
{ {
@ -19,7 +19,7 @@ namespace LuaUi
bool empty() { return mElement.get() == nullptr; } bool empty() { return mElement.get() == nullptr; }
private: private:
WidgetExtension* mContent; LuaContainer* mContent;
std::shared_ptr<Element> mElement; std::shared_ptr<Element> mElement;
void attachElement(); void attachElement();
void detachElement(); void detachElement();

View file

@ -0,0 +1,35 @@
#include "container.hpp"
#include <algorithm>
namespace LuaUi
{
void LuaContainer::updateChildren()
{
WidgetExtension::updateChildren();
for (auto w : children())
{
w->onCoordChange([this](WidgetExtension* child, MyGUI::IntCoord coord)
{ updateSizeToFit(); });
}
updateSizeToFit();
}
MyGUI::IntSize LuaContainer::childScalingSize()
{
return MyGUI::IntSize();
}
void LuaContainer::updateSizeToFit()
{
MyGUI::IntSize size;
for (auto w : children())
{
MyGUI::IntCoord coord = w->widget()->getCoord();
size.width = std::max(size.width, coord.left + coord.width);
size.height = std::max(size.height, coord.top + coord.height);
}
setForcedSize(size);
updateCoord();
}
}

View file

@ -0,0 +1,21 @@
#ifndef OPENMW_LUAUI_CONTAINER
#define OPENMW_LUAUI_CONTAINER
#include "widget.hpp"
namespace LuaUi
{
class LuaContainer : public WidgetExtension, public MyGUI::Widget
{
MYGUI_RTTI_DERIVED(LuaContainer)
protected:
virtual void updateChildren() override;
virtual MyGUI::IntSize childScalingSize() override;
private:
void updateSizeToFit();
};
}
#endif // !OPENMW_LUAUI_CONTAINER

View file

@ -221,10 +221,7 @@ namespace LuaUi
void Element::detachFromWidget() void Element::detachFromWidget()
{ {
if (mRoot) if (mRoot)
{
mRoot->onSizeChange({});
mRoot->widget()->detachFromWidget(); mRoot->widget()->detachFromWidget();
}
if (mAttachedTo) if (mAttachedTo)
mAttachedTo->setChildren({}); mAttachedTo->setChildren({});
mAttachedTo = nullptr; mAttachedTo = nullptr;
@ -239,16 +236,7 @@ namespace LuaUi
if (!mLayer.empty()) if (!mLayer.empty())
Log(Debug::Warning) << "Ignoring element's layer " << mLayer << " because it's attached to a widget"; Log(Debug::Warning) << "Ignoring element's layer " << mLayer << " because it's attached to a widget";
mAttachedTo->setChildren({ mRoot }); mAttachedTo->setChildren({ mRoot });
auto callback = [this](MyGUI::IntSize size)
{
if (!mAttachedTo)
return;
mAttachedTo->setForcedSize(mRoot->widget()->getSize());
mAttachedTo->updateCoord();
};
mRoot->onSizeChange(callback);
mRoot->updateCoord(); mRoot->updateCoord();
callback(mRoot->widget()->getSize());
} }
} }
} }

View file

@ -8,6 +8,7 @@
#include "textedit.hpp" #include "textedit.hpp"
#include "window.hpp" #include "window.hpp"
#include "image.hpp" #include "image.hpp"
#include "container.hpp"
#include "element.hpp" #include "element.hpp"
#include "scriptsettings.hpp" #include "scriptsettings.hpp"
@ -23,6 +24,7 @@ namespace LuaUi
MyGUI::FactoryManager::getInstance().registerFactory<LuaTextEdit>("Widget"); MyGUI::FactoryManager::getInstance().registerFactory<LuaTextEdit>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<LuaWindow>("Widget"); MyGUI::FactoryManager::getInstance().registerFactory<LuaWindow>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<LuaImage>("Widget"); MyGUI::FactoryManager::getInstance().registerFactory<LuaImage>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<LuaContainer>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<LuaTileRect>("BasisSkin"); MyGUI::FactoryManager::getInstance().registerFactory<LuaTileRect>("BasisSkin");
} }
@ -34,6 +36,7 @@ namespace LuaUi
{ "LuaTextEdit", "TextEdit" }, { "LuaTextEdit", "TextEdit" },
{ "LuaWindow", "Window" }, { "LuaWindow", "Window" },
{ "LuaImage", "Image" }, { "LuaImage", "Image" },
{ "LuaContainer", "Container" },
}; };
return types; return types;
} }

View file

@ -14,10 +14,11 @@ namespace LuaUi
, mAbsoluteCoord() , mAbsoluteCoord()
, mRelativeCoord() , mRelativeCoord()
, mAnchor() , mAnchor()
, mLua{ nullptr } , mLua(nullptr)
, mWidget{ nullptr } , mWidget(nullptr)
, mSlot(this) , mSlot(this)
, mLayout{ sol::nil } , mParent(nullptr)
, mLayout(sol::nil)
{} {}
void WidgetExtension::initialize(lua_State* lua, MyGUI::Widget* self) void WidgetExtension::initialize(lua_State* lua, MyGUI::Widget* self)
@ -64,6 +65,8 @@ namespace LuaUi
mWidget->eventKeySetFocus.clear(); mWidget->eventKeySetFocus.clear();
mWidget->eventKeyLostFocus.clear(); mWidget->eventKeyLostFocus.clear();
mOnSizeChange.reset();
for (WidgetExtension* w : mChildren) for (WidgetExtension* w : mChildren)
w->deinitialize(); w->deinitialize();
for (WidgetExtension* w : mTemplateChildren) for (WidgetExtension* w : mTemplateChildren)
@ -72,6 +75,7 @@ namespace LuaUi
void WidgetExtension::attach(WidgetExtension* ext) void WidgetExtension::attach(WidgetExtension* ext)
{ {
ext->mParent = this;
ext->widget()->attachToWidget(mSlot->widget()); ext->widget()->attachToWidget(mSlot->widget());
ext->updateCoord(); ext->updateCoord();
} }
@ -150,6 +154,7 @@ namespace LuaUi
mChildren[i] = children[i]; mChildren[i] = children[i];
attach(mChildren[i]); attach(mChildren[i]);
} }
updateChildren();
} }
void WidgetExtension::setTemplateChildren(const std::vector<WidgetExtension*>& children) void WidgetExtension::setTemplateChildren(const std::vector<WidgetExtension*>& children)
@ -212,6 +217,8 @@ namespace LuaUi
if (mOnSizeChange.has_value()) if (mOnSizeChange.has_value())
mOnSizeChange.value()(newCoord.size()); mOnSizeChange.value()(newCoord.size());
} }
if (oldCoord != newCoord && mOnCoordChange.has_value())
mOnCoordChange.value()(this, newCoord);
} }
void WidgetExtension::setProperties(sol::object props) void WidgetExtension::setProperties(sol::object props)
@ -240,23 +247,31 @@ namespace LuaUi
w->updateCoord(); w->updateCoord();
} }
MyGUI::IntSize WidgetExtension::parentSize()
{
if (mParent)
return mParent->childScalingSize();
else
return widget()->getParentSize();
}
MyGUI::IntSize WidgetExtension::calculateSize() MyGUI::IntSize WidgetExtension::calculateSize()
{ {
const MyGUI::IntSize& parentSize = mWidget->getParentSize(); MyGUI::IntSize pSize = parentSize();
MyGUI::IntSize newSize; MyGUI::IntSize newSize;
newSize = mAbsoluteCoord.size() + mForcedCoord.size(); newSize = mAbsoluteCoord.size() + mForcedCoord.size();
newSize.width += mRelativeCoord.width * parentSize.width; newSize.width += mRelativeCoord.width * pSize.width;
newSize.height += mRelativeCoord.height * parentSize.height; newSize.height += mRelativeCoord.height * pSize.height;
return newSize; return newSize;
} }
MyGUI::IntPoint WidgetExtension::calculatePosition(const MyGUI::IntSize& size) MyGUI::IntPoint WidgetExtension::calculatePosition(const MyGUI::IntSize& size)
{ {
const MyGUI::IntSize& parentSize = mWidget->getParentSize(); MyGUI::IntSize pSize = parentSize();
MyGUI::IntPoint newPosition; MyGUI::IntPoint newPosition;
newPosition = mAbsoluteCoord.point() + mForcedCoord.point(); newPosition = mAbsoluteCoord.point() + mForcedCoord.point();
newPosition.left += mRelativeCoord.left * parentSize.width - mAnchor.width * size.width; newPosition.left += mRelativeCoord.left * pSize.width - mAnchor.width * size.width;
newPosition.top += mRelativeCoord.top * parentSize.height - mAnchor.height * size.height; newPosition.top += mRelativeCoord.top * pSize.height - mAnchor.height * size.height;
return newPosition; return newPosition;
} }
@ -268,6 +283,11 @@ namespace LuaUi
return newCoord; return newCoord;
} }
MyGUI::IntSize WidgetExtension::childScalingSize()
{
return widget()->getSize();
}
void WidgetExtension::triggerEvent(std::string_view name, const sol::object& argument = sol::nil) const void WidgetExtension::triggerEvent(std::string_view name, const sol::object& argument = sol::nil) const
{ {
auto it = mCallbacks.find(name); auto it = mCallbacks.find(name);

View file

@ -57,6 +57,11 @@ namespace LuaUi
return parseExternal(mExternal, name, defaultValue); return parseExternal(mExternal, name, defaultValue);
} }
void onCoordChange(const std::optional<std::function<void(WidgetExtension*, MyGUI::IntCoord)>>& callback)
{
mOnCoordChange = callback;
}
void onSizeChange(const std::optional<std::function<void(MyGUI::IntSize)>>& callback) void onSizeChange(const std::optional<std::function<void(MyGUI::IntSize)>>& callback)
{ {
mOnSizeChange = callback; mOnSizeChange = callback;
@ -68,9 +73,11 @@ namespace LuaUi
sol::object keyEvent(MyGUI::KeyCode) const; sol::object keyEvent(MyGUI::KeyCode) const;
sol::object mouseEvent(int left, int top, MyGUI::MouseButton button) const; sol::object mouseEvent(int left, int top, MyGUI::MouseButton button) const;
MyGUI::IntSize parentSize();
virtual MyGUI::IntSize calculateSize(); virtual MyGUI::IntSize calculateSize();
virtual MyGUI::IntPoint calculatePosition(const MyGUI::IntSize& size); virtual MyGUI::IntPoint calculatePosition(const MyGUI::IntSize& size);
MyGUI::IntCoord calculateCoord(); MyGUI::IntCoord calculateCoord();
virtual MyGUI::IntSize childScalingSize();
template<typename T> template<typename T>
T propertyValue(std::string_view name, const T& defaultValue) T propertyValue(std::string_view name, const T& defaultValue)
@ -83,6 +90,7 @@ namespace LuaUi
virtual void updateTemplate(); virtual void updateTemplate();
virtual void updateProperties(); virtual void updateProperties();
virtual void updateChildren() {};
void triggerEvent(std::string_view name, const sol::object& argument) const; void triggerEvent(std::string_view name, const sol::object& argument) const;
@ -108,6 +116,7 @@ namespace LuaUi
sol::object mProperties; sol::object mProperties;
sol::object mTemplateProperties; sol::object mTemplateProperties;
sol::object mExternal; sol::object mExternal;
WidgetExtension* mParent;
void attach(WidgetExtension* ext); void attach(WidgetExtension* ext);
@ -127,6 +136,7 @@ namespace LuaUi
void focusGain(MyGUI::Widget*, MyGUI::Widget*); void focusGain(MyGUI::Widget*, MyGUI::Widget*);
void focusLoss(MyGUI::Widget*, MyGUI::Widget*); void focusLoss(MyGUI::Widget*, MyGUI::Widget*);
std::optional<std::function<void(WidgetExtension*, MyGUI::IntCoord)>> mOnCoordChange;
std::optional<std::function<void(MyGUI::IntSize)>> mOnSizeChange; std::optional<std::function<void(MyGUI::IntSize)>> mOnSizeChange;
}; };