148 lines
3.0 KiB
C++
148 lines
3.0 KiB
C++
#include "View.hh"
|
|
|
|
View::View(int width, int height, std::string name)
|
|
: Widget(width, height, std::move(name))
|
|
{
|
|
}
|
|
|
|
View::~View()
|
|
{
|
|
}
|
|
|
|
void View::addChild(std::unique_ptr<Widget> child)
|
|
{
|
|
_setParent(*child);
|
|
children_.push_back(make_tuple(child->getName(), std::move(child), SDL_Rect{0, 0, 0, 0}));
|
|
|
|
layout();
|
|
}
|
|
|
|
Widget& View::getChildByName(std::string const& name)
|
|
{
|
|
if (name == "")
|
|
throw ChildNotFoundException{};
|
|
|
|
for(auto& ent : children_) {
|
|
if (std::get<0>(ent) == name)
|
|
return *std::get<1>(ent);
|
|
}
|
|
|
|
throw ChildNotFoundException{};
|
|
}
|
|
|
|
Widget const& View::getChildByName(std::string const& name) const
|
|
{
|
|
if (name == "")
|
|
throw ChildNotFoundException{};
|
|
|
|
for(auto& ent : children_) {
|
|
if (std::get<0>(ent) == name)
|
|
return *std::get<1>(ent);
|
|
}
|
|
|
|
throw ChildNotFoundException{};
|
|
}
|
|
|
|
Widget& View::getPath(std::string const& path)
|
|
{
|
|
auto slash = path.find('/');
|
|
|
|
// Last path element
|
|
if (slash == std::string::npos)
|
|
return getChildByName(path);
|
|
|
|
auto first = path.substr(0, slash);
|
|
auto& child = getChildByName(first);
|
|
try {
|
|
View& next = dynamic_cast<View&>(child);
|
|
|
|
return next.getPath(path.substr(slash+1));
|
|
} catch(std::bad_cast &ex) {
|
|
throw ChildNotFoundException{};
|
|
}
|
|
}
|
|
|
|
Widget const& View::getPath(std::string const& path) const
|
|
{
|
|
auto slash = path.find('/');
|
|
|
|
// Last path element
|
|
if (slash == std::string::npos)
|
|
return getChildByName(path);
|
|
|
|
auto first = path.substr(0, slash);
|
|
auto& child = getChildByName(first);
|
|
try {
|
|
View const& next = dynamic_cast<View const&>(child);
|
|
|
|
return next.getPath(path.substr(slash+1));
|
|
} catch(std::bad_cast &ex) {
|
|
throw ChildNotFoundException{};
|
|
}
|
|
}
|
|
|
|
std::unique_ptr<Widget> View::removeChild(std::string const& name)
|
|
{
|
|
if (name == "")
|
|
throw ChildNotFoundException{};
|
|
|
|
for(auto it = children_.begin(); it != children_.end(); ++it) {
|
|
if (std::get<0>(*it) == name) {
|
|
auto child = std::move(std::get<1>(*it));
|
|
children_.erase(it);
|
|
_clearParent(*child);
|
|
_layout(*child);
|
|
|
|
layout();
|
|
|
|
return child;
|
|
}
|
|
}
|
|
|
|
throw ChildNotFoundException{};
|
|
}
|
|
|
|
std::unique_ptr<Widget> View::removeChild(Widget& child)
|
|
{
|
|
for(auto it = children_.begin(); it != children_.end(); ++it) {
|
|
if (std::get<1>(*it).get() == &child) {
|
|
auto child = std::move(std::get<1>(*it));
|
|
children_.erase(it);
|
|
|
|
_clearParent(*child);
|
|
_layout(*child);
|
|
|
|
layout();
|
|
|
|
return child;
|
|
}
|
|
}
|
|
|
|
throw ChildNotFoundException{};
|
|
}
|
|
|
|
|
|
void View::render(SDL_Surface *dst, SDL_Rect *dstRect) const
|
|
{
|
|
Widget::render(dst, dstRect);
|
|
|
|
SDL_Rect rect;
|
|
if (dstRect)
|
|
memcpy(&rect, dstRect, sizeof(SDL_Rect));
|
|
else {
|
|
rect.x = 0;
|
|
rect.y = 0;
|
|
rect.w = dst->w;
|
|
rect.h = dst->h;
|
|
}
|
|
|
|
for (auto& ent : children_) {
|
|
SDL_Rect childDst = std::get<2>(ent), childDstCliped;
|
|
childDst.x += rect.x;
|
|
childDst.y += rect.y;
|
|
SDL_IntersectRect(&rect, &childDst, &childDstCliped);
|
|
|
|
std::get<1>(ent)->render(dst, &childDst);
|
|
}
|
|
}
|