zetaPRIME 7f27018808 UIContainer::AddNew, Add uses std::move, Optional type,
button styles and glyphs, lower memory footprint for default text
style on Label
2017-03-18 19:29:32 -04:00

91 lines
3.5 KiB
C++

#include <algorithm>
#include "starlight/GFXManager.h"
#include "UIContainer.h"
using starlight::GFXManager;
using starlight::ui::UIElement;
using starlight::ui::UIContainer;
UIContainer::UIContainer() { }
void UIContainer::Dive(std::function<bool(UIElement*)> check, std::function<bool(UIElement*)> func, bool consumable, bool frontFirst) {
bool finished = false;
_Dive(check, func, consumable, frontFirst, finished);
}
void UIContainer::Dive(std::function<bool(UIElement*)> func, bool consumable, bool frontFirst) {
bool finished = false;
_Dive(func, consumable, frontFirst, finished);
}
void UIContainer::_Dive(std::function<bool(UIElement*)>& check, std::function<bool(UIElement*)>& func, bool consumable, bool frontFirst, bool& finished) {
if (!check(this)) return; // early out, don't bother checking further branches
if (frontFirst) for (auto itr = children.rbegin(); itr != children.rend(); ++itr) {
(*itr)->_Dive(check, func, consumable, frontFirst, finished);
if (finished) return;
} else for (auto itr = children.begin(); itr != children.end(); ++itr) {
(*itr)->_Dive(check, func, consumable, frontFirst, finished);
if (finished) return;
}
// same thing as plain UIElement's version
finished = func(this) && consumable;
}
void UIContainer::_Dive(std::function<bool(UIElement*)>& func, bool consumable, bool frontFirst, bool& finished) {
if (frontFirst) for (auto itr = children.rbegin(); itr != children.rend(); ++itr) {
(*itr)->_Dive(func, consumable, frontFirst, finished);
if (finished) return;
} else for (auto itr = children.begin(); itr != children.end(); ++itr) {
(*itr)->_Dive(func, consumable, frontFirst, finished);
if (finished) return;
}
// same thing as plain UIElement's version
finished = func(this) && consumable;
}
void UIContainer::Add(std::shared_ptr<UIElement> elem, bool front) {
elem->parent = std::weak_ptr<UIContainer>(std::static_pointer_cast<UIContainer>(this->shared_from_this()));
if (front) children.push_front(std::move(elem));
else children.push_back(std::move(elem));
MarkForRedraw();
}
//void UIContainer::Add(UIElement* elem) {
// as it turns out, you *have* to immediately encapsulate because herp derp shared_from_this doesn't even bother to check
//if (std::shared_ptr<UIElement> ptr = elem->shared_from_this()) this->Add(ptr);
//else this->Add(std::shared_ptr<UIElement>(elem)); // support initial encapsulation
//}
void UIContainer::Remove(std::shared_ptr<UIElement> elem) {
if (elem->parent.lock().get() != this) return;
elem->parent = std::weak_ptr<UIContainer>(); // explicit null expressed in a slightly silly way
//children.remove_if([&elem](std::shared_ptr<UIElement> ie){return ie == elem;});
children.remove(elem); // I think this uses operator ==()?
MarkForRedraw();
}
void UIContainer::RemoveAll() {
for (auto it : children) {
it->parent = std::weak_ptr<UIContainer>(); // clear parent
}
children.clear();
}
void UIContainer::Update() {
for (auto& it : children) { it->Update(); }
}
void UIContainer::PreDraw() {
VRect vr = ViewportRect();
for (auto& it : children) { if (it->rect.Overlaps(vr)) it->PreDraw(); else it->PreDrawOffscreen(); }
}
void UIContainer::Draw() {
GFXManager::PushOffsetAdd(rect.pos - scrollOffset);
VRect vr = ViewportRect();
for (auto& it : children) { if (it->rect.Overlaps(vr)) it->Draw(); }
GFXManager::PopOffset();
}