/*
* UltraStar Deluxe - Karaoke Game
*
* UltraStar Deluxe is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
*/
#include <cstddef>
#include "container.hpp"
#include "frame.hpp"
#include "modelview_matrix_cache.hpp"
namespace usdx
{
log4cpp::Category& Container::log =
log4cpp::Category::getInstance("usdx.menu.container");
Container::Container(Container* owner)
: DrawableControl(owner), frame(NULL), window_coords(0, 0)
{
init(owner);
}
Container::Container(Container* owner, const ContainerHelper& add)
: DrawableControl(owner, add), frame(NULL), window_coords(0, 0)
{
init(owner);
}
Container::~Container()
{
window_coords_connection.disconnect();
for (std::list<DrawableControl*>::iterator next = controls.begin(), it = next++;
it != controls.end(); it = next++) {
(*it)->remove_parent();
}
controls.clear();
}
void Container::init(Container* parent)
{
set_clipping_required(true);
if (parent) {
window_coords_connection = parent->window_coords_change.connect(
boost::bind(&Container::recalculate_window_coords, this));
}
}
void Container::draw(void)
{
DrawableControl::draw();
if (frame) {
frame->repaint();
}
ModelviewMatrixCache c;
for (std::list<DrawableControl*>::iterator it =
controls.begin(); it != controls.end(); it++) {
(*it)->repaint();
c.restore();
}
}
void Container::add(DrawableControl *child)
{
controls.push_back(child);
}
void Container::remove(DrawableControl *child)
{
controls.remove(child);
}
void Container::setFrame(Frame *f)
{
f->set_size(get_size());
frame = f;
}
void Container::removeFrame(void)
{
frame = NULL;
}
const Point<int>& Container::get_window_coords(void) const
{
return window_coords;
}
void Container::recalculate_window_coords(void)
{
if (parent) {
window_coords.set_x(parent->get_window_coords().get_x() +
get_left());
window_coords.set_y(parent->get_window_coords().get_y() +
get_parent()->get_height() -
(get_top() + get_height()));
window_coords_change();
}
}
void Container::set_position(const Point<int>& position)
{
DrawableControl::set_position(position);
recalculate_window_coords();
}
void Container::set_position(int left, int top)
{
DrawableControl::set_position(left, top);
recalculate_window_coords();
}
void Container::set_size(const Dimension<int>& size)
{
DrawableControl::set_size(size);
recalculate_window_coords();
}
void Container::set_size(int width, int height)
{
DrawableControl::set_size(width, height);
recalculate_window_coords();
}
DrawableControl* Container::get_component_at(const Point<int>& p)
{
if (!get_absolut_rect().is_in(p))
return NULL;
for (std::list<DrawableControl*>::iterator next = controls.begin(), it = next++;
it != controls.end(); it = next++) {
DrawableControl* c = (*it)->get_component_at(p);
if (c != NULL) {
return c;
}
}
if (frame) {
return frame->get_component_at(p);
}
return this;
}
}