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:
parent
086a7d9bc5
commit
f07f05ddd3
9 changed files with 107 additions and 35 deletions
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
35
components/lua_ui/container.cpp
Normal file
35
components/lua_ui/container.cpp
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
21
components/lua_ui/container.hpp
Normal file
21
components/lua_ui/container.hpp
Normal 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
|
|
@ -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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue