Files
openglplayground/View.cc
2015-03-10 00:48:25 +01:00

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);
}
}