moonfall/Window.cpp
2014-10-21 13:54:42 +09:00

266 lines
6.2 KiB
C++

/*
Moonfall Copyright (C) 2008 Alex Yatskov
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 3 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. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Pch.h"
#include "Window.h"
#include "Surface.h"
Window::Window() :
m_done(false)
{
}
void Window::Render(const boost::shared_ptr<Surface>& target)
{
if (IsDone())
{
return;
}
target->PushState();
target->SetViewportRelative(GetBounds());
OnRender(target);
target->PopState();
}
void Window::Update(float elapsed)
{
if (IsDone())
{
return;
}
OnUpdate(elapsed);
WindowList doneChildren;
for (WindowList::iterator iter = m_children.begin(); iter != m_children.end(); ++iter)
{
const boost::shared_ptr<Window> child(*iter);
if (child->IsDone())
{
doneChildren.push_back(child);
}
}
for (WindowList::iterator iter = doneChildren.begin(); iter != doneChildren.end(); ++iter)
{
m_children.erase(find(m_children.begin(), m_children.end(), *iter));
}
}
void Window::SetPosition(const Vector2i& position)
{
m_position = position;
}
Vector2i Window::GetPosition() const
{
return m_position;
}
void Window::SetSize(const Vector2i& size)
{
m_size = size;
}
Vector2i Window::GetSize() const
{
return m_size;
}
void Window::SetBounds(const Rect4i& bounds)
{
SetPosition(Vector2i(bounds.x0, bounds.y0));
SetSize(Vector2i(bounds.x1 - bounds.x0, bounds.y1 - bounds.y0));
}
Rect4i Window::GetBounds() const
{
return Rect4i(
GetPosition().x,
GetPosition().y,
GetPosition().x + GetSize().x,
GetPosition().y + GetSize().y
);
}
void Window::AddChild(const boost::shared_ptr<Window>& window)
{
m_children.push_back(window);
window->OnLoad();
}
void Window::RemoveChild(const boost::shared_ptr<Window>& window)
{
WindowList::iterator iter = find(m_children.begin(), m_children.end(), window);
if (iter != m_children.end())
{
(*iter)->OnUnload();
m_children.erase(iter);
}
}
void Window::ClearChildren()
{
m_children.clear();
}
void Window::SetDone()
{
m_done = true;
}
bool Window::IsDone() const
{
return m_done;
}
void Window::OnRender(const boost::shared_ptr<Surface>& target)
{
for (WindowList::iterator iter = m_children.begin(); iter != m_children.end(); ++iter)
{
(*iter)->Render(target);
}
}
void Window::OnUpdate(float elapsed)
{
for (WindowList::iterator iter = m_children.begin(); iter != m_children.end(); ++iter)
{
(*iter)->Update(elapsed);
}
}
void Window::OnKeyDown(const InputKey& args)
{
for (WindowList::iterator iter = m_children.begin(); iter != m_children.end(); ++iter)
{
(*iter)->OnKeyDown(args);
}
}
void Window::OnKeyUp(const InputKey& args)
{
for (WindowList::iterator iter = m_children.begin(); iter != m_children.end(); ++iter)
{
(*iter)->OnKeyUp(args);
}
}
void Window::OnMouseMove(const InputMouse& args)
{
for (WindowList::iterator iter = m_children.begin(); iter != m_children.end(); ++iter)
{
InputMouse adjustedArgs(args);
boost::shared_ptr<Window> child(*iter);
if (AdjustMouseArgs(child, args, &adjustedArgs))
{
child->OnMouseMove(adjustedArgs);
}
}
}
void Window::OnMouseButtonDown(const InputMouse& args)
{
for (WindowList::iterator iter = m_children.begin(); iter != m_children.end(); ++iter)
{
InputMouse adjustedArgs(args);
boost::shared_ptr<Window> child(*iter);
if (AdjustMouseArgs(child, args, &adjustedArgs))
{
child->OnMouseButtonDown(adjustedArgs);
}
}
}
void Window::OnMouseButtonUp(const InputMouse& args)
{
for (WindowList::iterator iter = m_children.begin(); iter != m_children.end(); ++iter)
{
InputMouse adjustedArgs(args);
boost::shared_ptr<Window> child(*iter);
if (AdjustMouseArgs(child, args, &adjustedArgs))
{
child->OnMouseButtonUp(adjustedArgs);
}
}
}
void Window::OnMouseWheel(const InputMouse& args)
{
for (WindowList::iterator iter = m_children.begin(); iter != m_children.end(); ++iter)
{
InputMouse adjustedArgs(args);
boost::shared_ptr<Window> child(*iter);
if (AdjustMouseArgs(child, args, &adjustedArgs))
{
child->OnMouseWheel(adjustedArgs);
}
}
}
void Window::OnActivate()
{
for (WindowList::iterator iter = m_children.begin(); iter != m_children.end(); ++iter)
{
(*iter)->OnActivate();
}
}
void Window::OnDeactivate()
{
for (WindowList::iterator iter = m_children.begin(); iter != m_children.end(); ++iter)
{
(*iter)->OnDeactivate();
}
}
void Window::OnLoad()
{
for (WindowList::iterator iter = m_children.begin(); iter != m_children.end(); ++iter)
{
(*iter)->OnLoad();
}
}
void Window::OnUnload()
{
for (WindowList::iterator iter = m_children.begin(); iter != m_children.end(); ++iter)
{
(*iter)->OnUnload();
}
}
void Window::OnQuit()
{
for (WindowList::iterator iter = m_children.begin(); iter != m_children.end(); ++iter)
{
(*iter)->OnQuit();
}
}
bool Window::AdjustMouseArgs(const boost::shared_ptr<Window>& window, const InputMouse& sourceArgs, InputMouse* destArgs) const
{
*destArgs = sourceArgs;
destArgs->position = sourceArgs.position - window->GetPosition();
return
destArgs->position.x >= 0 &&
destArgs->position.y >= 0 &&
destArgs->position.x < window->GetSize().x &&
destArgs->position.y < window->GetSize().y;
}