mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-29 22:45:36 +00:00
Prevent iterator invalidation when updating Lua UI and increase const correctness
This commit is contained in:
parent
2497164b2b
commit
8cbcb82dd4
11 changed files with 81 additions and 56 deletions
|
@ -10,12 +10,12 @@ namespace LuaUi
|
|||
updateSizeToFit();
|
||||
}
|
||||
|
||||
MyGUI::IntSize LuaContainer::childScalingSize()
|
||||
MyGUI::IntSize LuaContainer::childScalingSize() const
|
||||
{
|
||||
return MyGUI::IntSize();
|
||||
}
|
||||
|
||||
MyGUI::IntSize LuaContainer::templateScalingSize()
|
||||
MyGUI::IntSize LuaContainer::templateScalingSize() const
|
||||
{
|
||||
return mInnerSize;
|
||||
}
|
||||
|
@ -23,14 +23,14 @@ namespace LuaUi
|
|||
void LuaContainer::updateSizeToFit()
|
||||
{
|
||||
MyGUI::IntSize innerSize = MyGUI::IntSize();
|
||||
for (auto w : children())
|
||||
for (const auto w : children())
|
||||
{
|
||||
MyGUI::IntCoord coord = w->calculateCoord();
|
||||
innerSize.width = std::max(innerSize.width, coord.left + coord.width);
|
||||
innerSize.height = std::max(innerSize.height, coord.top + coord.height);
|
||||
}
|
||||
MyGUI::IntSize outerSize = innerSize;
|
||||
for (auto w : templateChildren())
|
||||
for (const auto w : templateChildren())
|
||||
{
|
||||
MyGUI::IntCoord coord = w->calculateCoord();
|
||||
outerSize.width = std::max(outerSize.width, coord.left + coord.width);
|
||||
|
@ -40,7 +40,7 @@ namespace LuaUi
|
|||
mOuterSize = outerSize;
|
||||
}
|
||||
|
||||
MyGUI::IntSize LuaContainer::calculateSize()
|
||||
MyGUI::IntSize LuaContainer::calculateSize() const
|
||||
{
|
||||
return mOuterSize;
|
||||
}
|
||||
|
|
|
@ -10,13 +10,13 @@ namespace LuaUi
|
|||
MYGUI_RTTI_DERIVED(LuaContainer)
|
||||
|
||||
public:
|
||||
MyGUI::IntSize calculateSize() override;
|
||||
MyGUI::IntSize calculateSize() const override;
|
||||
void updateCoord() override;
|
||||
|
||||
protected:
|
||||
void updateChildren() override;
|
||||
MyGUI::IntSize childScalingSize() override;
|
||||
MyGUI::IntSize templateScalingSize() override;
|
||||
MyGUI::IntSize childScalingSize() const override;
|
||||
MyGUI::IntSize templateScalingSize() const override;
|
||||
|
||||
private:
|
||||
void updateSizeToFit();
|
||||
|
|
|
@ -54,25 +54,19 @@ namespace LuaUi
|
|||
if (!ext->isRoot())
|
||||
destroyWidget(ext);
|
||||
else
|
||||
ext->detachFromParent();
|
||||
ext->detachFromParent(false);
|
||||
}
|
||||
|
||||
void detachElements(WidgetExtension* ext)
|
||||
{
|
||||
for (auto* child : ext->children())
|
||||
{
|
||||
auto predicate = [](WidgetExtension* child) {
|
||||
if (child->isRoot())
|
||||
child->detachFromParent();
|
||||
else
|
||||
detachElements(child);
|
||||
}
|
||||
for (auto* child : ext->templateChildren())
|
||||
{
|
||||
if (child->isRoot())
|
||||
child->detachFromParent();
|
||||
else
|
||||
detachElements(child);
|
||||
}
|
||||
return true;
|
||||
detachElements(child);
|
||||
return false;
|
||||
};
|
||||
ext->detachChildrenIf(predicate);
|
||||
ext->detachTemplateChildrenIf(predicate);
|
||||
}
|
||||
|
||||
void destroyRoot(WidgetExtension* ext)
|
||||
|
@ -194,8 +188,8 @@ namespace LuaUi
|
|||
throw std::logic_error(std::string("Invalid widget type ") += type);
|
||||
|
||||
std::string name = layout.get_or(LayoutKeys::name, std::string());
|
||||
MyGUI::Widget* widget = MyGUI::Gui::getInstancePtr()->createWidgetT(
|
||||
type, "", MyGUI::IntCoord(), MyGUI::Align::Default, std::string(), name);
|
||||
MyGUI::Widget* widget
|
||||
= MyGUI::Gui::getInstancePtr()->createWidgetT(type, {}, {}, MyGUI::Align::Default, {}, name);
|
||||
|
||||
WidgetExtension* ext = dynamic_cast<WidgetExtension*>(widget);
|
||||
if (!ext)
|
||||
|
|
|
@ -79,7 +79,7 @@ namespace LuaUi
|
|||
WidgetExtension::updateChildren();
|
||||
}
|
||||
|
||||
MyGUI::IntSize LuaFlex::childScalingSize()
|
||||
MyGUI::IntSize LuaFlex::childScalingSize() const
|
||||
{
|
||||
// Call the base method to prevent relativeSize feedback loop
|
||||
MyGUI::IntSize size = WidgetExtension::calculateSize();
|
||||
|
@ -88,7 +88,7 @@ namespace LuaUi
|
|||
return size;
|
||||
}
|
||||
|
||||
MyGUI::IntSize LuaFlex::calculateSize()
|
||||
MyGUI::IntSize LuaFlex::calculateSize() const
|
||||
{
|
||||
MyGUI::IntSize size = WidgetExtension::calculateSize();
|
||||
if (mAutoSized)
|
||||
|
|
|
@ -11,10 +11,10 @@ namespace LuaUi
|
|||
MYGUI_RTTI_DERIVED(LuaFlex)
|
||||
|
||||
protected:
|
||||
MyGUI::IntSize calculateSize() override;
|
||||
MyGUI::IntSize calculateSize() const override;
|
||||
void updateProperties() override;
|
||||
void updateChildren() override;
|
||||
MyGUI::IntSize childScalingSize() override;
|
||||
MyGUI::IntSize childScalingSize() const override;
|
||||
|
||||
void updateCoord() override;
|
||||
|
||||
|
@ -26,25 +26,37 @@ namespace LuaUi
|
|||
Alignment mArrange;
|
||||
|
||||
template <typename T>
|
||||
T& primary(MyGUI::types::TPoint<T>& point)
|
||||
T& primary(MyGUI::types::TPoint<T>& point) const
|
||||
{
|
||||
return mHorizontal ? point.left : point.top;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& secondary(MyGUI::types::TPoint<T>& point)
|
||||
T& secondary(MyGUI::types::TPoint<T>& point) const
|
||||
{
|
||||
return mHorizontal ? point.top : point.left;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& primary(MyGUI::types::TSize<T>& size)
|
||||
T& primary(MyGUI::types::TSize<T>& size) const
|
||||
{
|
||||
return mHorizontal ? size.width : size.height;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& secondary(MyGUI::types::TSize<T>& size)
|
||||
T& secondary(MyGUI::types::TSize<T>& size) const
|
||||
{
|
||||
return mHorizontal ? size.height : size.width;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T primary(const MyGUI::types::TSize<T>& size) const
|
||||
{
|
||||
return mHorizontal ? size.width : size.height;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T secondary(const MyGUI::types::TSize<T>& size) const
|
||||
{
|
||||
return mHorizontal ? size.height : size.width;
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace LuaUi
|
|||
updateCoord();
|
||||
}
|
||||
|
||||
MyGUI::IntSize LuaText::calculateSize()
|
||||
MyGUI::IntSize LuaText::calculateSize() const
|
||||
{
|
||||
if (mAutoSized)
|
||||
return getTextSize();
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace LuaUi
|
|||
bool mAutoSized;
|
||||
|
||||
protected:
|
||||
MyGUI::IntSize calculateSize() override;
|
||||
MyGUI::IntSize calculateSize() const override;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace LuaUi
|
|||
mEditBox->attachToWidget(this);
|
||||
}
|
||||
|
||||
MyGUI::IntSize LuaTextEdit::calculateSize()
|
||||
MyGUI::IntSize LuaTextEdit::calculateSize() const
|
||||
{
|
||||
MyGUI::IntSize normalSize = WidgetExtension::calculateSize();
|
||||
if (mAutoSize)
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace LuaUi
|
|||
void updateProperties() override;
|
||||
void updateCoord() override;
|
||||
void updateChildren() override;
|
||||
MyGUI::IntSize calculateSize() override;
|
||||
MyGUI::IntSize calculateSize() const override;
|
||||
|
||||
private:
|
||||
void textChange(MyGUI::EditBox*);
|
||||
|
|
|
@ -101,7 +101,7 @@ namespace LuaUi
|
|||
void WidgetExtension::attach(WidgetExtension* ext)
|
||||
{
|
||||
if (ext->mParent != this)
|
||||
ext->detachFromParent();
|
||||
ext->detachFromParent(true);
|
||||
ext->mParent = this;
|
||||
ext->mTemplateChild = false;
|
||||
ext->widget()->attachToWidget(mSlot->widget());
|
||||
|
@ -114,13 +114,16 @@ namespace LuaUi
|
|||
ext->widget()->attachToWidget(widget());
|
||||
}
|
||||
|
||||
void WidgetExtension::detachFromParent()
|
||||
void WidgetExtension::detachFromParent(bool updateParent)
|
||||
{
|
||||
if (mParent)
|
||||
{
|
||||
auto children = mParent->children();
|
||||
std::erase(children, this);
|
||||
mParent->setChildren(children);
|
||||
if (updateParent)
|
||||
{
|
||||
auto children = mParent->children();
|
||||
std::erase(children, this);
|
||||
mParent->setChildren(children);
|
||||
}
|
||||
mParent = nullptr;
|
||||
}
|
||||
widget()->detachFromWidget();
|
||||
|
@ -307,7 +310,7 @@ namespace LuaUi
|
|||
w->updateCoord();
|
||||
}
|
||||
|
||||
MyGUI::IntSize WidgetExtension::parentSize()
|
||||
MyGUI::IntSize WidgetExtension::parentSize() const
|
||||
{
|
||||
if (!mParent)
|
||||
return widget()->getParentSize(); // size of the layer
|
||||
|
@ -317,7 +320,7 @@ namespace LuaUi
|
|||
return mParent->childScalingSize();
|
||||
}
|
||||
|
||||
MyGUI::IntSize WidgetExtension::calculateSize()
|
||||
MyGUI::IntSize WidgetExtension::calculateSize() const
|
||||
{
|
||||
if (mForceSize)
|
||||
return mForcedCoord.size();
|
||||
|
@ -330,7 +333,7 @@ namespace LuaUi
|
|||
return newSize;
|
||||
}
|
||||
|
||||
MyGUI::IntPoint WidgetExtension::calculatePosition(const MyGUI::IntSize& size)
|
||||
MyGUI::IntPoint WidgetExtension::calculatePosition(const MyGUI::IntSize& size) const
|
||||
{
|
||||
if (mForcePosition)
|
||||
return mForcedCoord.point();
|
||||
|
@ -342,7 +345,7 @@ namespace LuaUi
|
|||
return newPosition;
|
||||
}
|
||||
|
||||
MyGUI::IntCoord WidgetExtension::calculateCoord()
|
||||
MyGUI::IntCoord WidgetExtension::calculateCoord() const
|
||||
{
|
||||
MyGUI::IntCoord newCoord;
|
||||
newCoord = calculateSize();
|
||||
|
@ -350,12 +353,12 @@ namespace LuaUi
|
|||
return newCoord;
|
||||
}
|
||||
|
||||
MyGUI::IntSize WidgetExtension::childScalingSize()
|
||||
MyGUI::IntSize WidgetExtension::childScalingSize() const
|
||||
{
|
||||
return mSlot->widget()->getSize();
|
||||
}
|
||||
|
||||
MyGUI::IntSize WidgetExtension::templateScalingSize()
|
||||
MyGUI::IntSize WidgetExtension::templateScalingSize() const
|
||||
{
|
||||
return widget()->getSize();
|
||||
}
|
||||
|
|
|
@ -31,11 +31,13 @@ namespace LuaUi
|
|||
virtual void deinitialize();
|
||||
|
||||
MyGUI::Widget* widget() const { return mWidget; }
|
||||
WidgetExtension* slot() const { return mSlot; }
|
||||
|
||||
bool isRoot() const { return mElementRoot; }
|
||||
WidgetExtension* getParent() const { return mParent; }
|
||||
void detachFromParent();
|
||||
void detachFromParent(bool updateParent);
|
||||
|
||||
void detachChildrenIf(auto&& predicate) { detachChildrenIf(predicate, mChildren); }
|
||||
void detachTemplateChildrenIf(auto&& predicate) { detachChildrenIf(predicate, mTemplateChildren); }
|
||||
|
||||
void reset();
|
||||
|
||||
|
@ -65,14 +67,14 @@ namespace LuaUi
|
|||
void setLayout(const sol::table& layout) { mLayout = layout; }
|
||||
|
||||
template <typename T>
|
||||
T externalValue(std::string_view name, const T& defaultValue)
|
||||
T externalValue(std::string_view name, const T& defaultValue) const
|
||||
{
|
||||
return parseExternal(mExternal, name, defaultValue);
|
||||
}
|
||||
|
||||
virtual MyGUI::IntSize calculateSize();
|
||||
virtual MyGUI::IntPoint calculatePosition(const MyGUI::IntSize& size);
|
||||
MyGUI::IntCoord calculateCoord();
|
||||
virtual MyGUI::IntSize calculateSize() const;
|
||||
virtual MyGUI::IntPoint calculatePosition(const MyGUI::IntSize& size) const;
|
||||
MyGUI::IntCoord calculateCoord() const;
|
||||
|
||||
virtual bool isTextInput() { return false; }
|
||||
|
||||
|
@ -85,9 +87,9 @@ namespace LuaUi
|
|||
sol::object keyEvent(MyGUI::KeyCode) const;
|
||||
sol::object mouseEvent(int left, int top, MyGUI::MouseButton button) const;
|
||||
|
||||
MyGUI::IntSize parentSize();
|
||||
virtual MyGUI::IntSize childScalingSize();
|
||||
virtual MyGUI::IntSize templateScalingSize();
|
||||
MyGUI::IntSize parentSize() const;
|
||||
virtual MyGUI::IntSize childScalingSize() const;
|
||||
virtual MyGUI::IntSize templateScalingSize() const;
|
||||
|
||||
template <typename T>
|
||||
T propertyValue(std::string_view name, const T& defaultValue)
|
||||
|
@ -176,6 +178,20 @@ namespace LuaUi
|
|||
void focusLoss(MyGUI::Widget*, MyGUI::Widget*);
|
||||
|
||||
void updateVisible();
|
||||
|
||||
void detachChildrenIf(auto&& predicate, std::vector<WidgetExtension*> children)
|
||||
{
|
||||
for (auto it = children.begin(); it != children.end();)
|
||||
{
|
||||
if (predicate(*it))
|
||||
{
|
||||
(*it)->detachFromParent(false);
|
||||
it = children.erase(it);
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class LuaWidget : public MyGUI::Widget, public WidgetExtension
|
||||
|
|
Loading…
Reference in a new issue