The-Powder-Toy/src/interface/Window.cpp
2012-04-19 14:38:15 +01:00

344 lines
7.8 KiB
C++

#include "Window.h"
#include "Component.h"
#include "interface/Point.h"
using namespace ui;
Window::Window(Point _position, Point _size):
Position(_position),
Size(_size),
focusedComponent_(NULL),
AllowExclusiveDrawing(true),
halt(false),
destruct(false)
{
}
Window::~Window()
{
for(unsigned i = 0, sz = Components.size(); i < sz; ++i)
if( Components[i] )
{
delete Components[i];
if(Components[i]==focusedComponent_)
focusedComponent_ = NULL;
}
}
void Window::AddComponent(Component* c)
{
// TODO: do a check if component was already added?
if(c->GetParentWindow()==NULL)
{
c->SetParentWindow(this);
Components.push_back(c);
}
else
{
//Component already has a state, don't sad it
}
}
unsigned Window::GetComponentCount()
{
return Components.size();
}
Component* Window::GetComponent(unsigned idx)
{
return Components[idx];
}
void Window::RemoveComponent(Component* c)
{
// remove component WITHOUT freeing it.
for(unsigned i = 0; i < Components.size(); ++i)
{
// find the appropriate component index
if(Components[i] == c)
{
//Make sure any events don't continue
halt = true;
if(Components[i]==focusedComponent_)
focusedComponent_ = NULL;
Components.erase(Components.begin() + i);
// we're done
return;
}
}
}
void Window::RemoveComponent(unsigned idx)
{
halt = true;
// free component and remove it.
if(Components[idx]==focusedComponent_)
focusedComponent_ = NULL;
delete Components[idx];
Components.erase(Components.begin() + idx);
}
bool Window::IsFocused(const Component* c) const
{
return c == focusedComponent_;
}
void Window::FocusComponent(Component* c)
{
this->focusedComponent_ = c;
}
void Window::DoExit()
{
OnExit();
}
void Window::DoInitialized()
{
OnInitialized();
}
void Window::DoDraw()
{
OnDraw();
//draw
for(int i = 0, sz = Components.size(); i < sz; ++i)
if(Components[i]->Visible)
{
if(AllowExclusiveDrawing)
{
Point scrpos(Components[i]->Position.X + Position.X, Components[i]->Position.Y + Position.Y);
Components[i]->Draw(scrpos);
}
else
{
if( Components[i]->Position.X+Position.X + Components[i]->Size.X >= 0 &&
Components[i]->Position.Y+Position.Y + Components[i]->Size.Y >= 0 &&
Components[i]->Position.X+Position.X < ui::Engine::Ref().GetWidth() &&
Components[i]->Position.Y+Position.Y < ui::Engine::Ref().GetHeight() )
{
Point scrpos(Components[i]->Position.X + Position.X, Components[i]->Position.Y + Position.Y);
Components[i]->Draw( Point(scrpos) );
}
}
}
}
void Window::DoTick(float dt)
{
//on mouse hover
for(int i = Components.size() - 1; i >= 0 && !halt; --i)
{
if(!Components[i]->Locked &&
ui::Engine::Ref().GetMouseX() >= Components[i]->Position.X+Position.X &&
ui::Engine::Ref().GetMouseY() >= Components[i]->Position.Y+Position.Y &&
ui::Engine::Ref().GetMouseX() < Components[i]->Position.X+Position.X + Components[i]->Size.X &&
ui::Engine::Ref().GetMouseY() < Components[i]->Position.Y+Position.Y + Components[i]->Size.Y )
{
Components[i]->OnMouseHover(ui::Engine::Ref().GetMouseX() - (Components[i]->Position.X + Position.X), ui::Engine::Ref().GetMouseY() - (Components[i]->Position.Y + Position.Y));
break;
}
}
//tick
for(int i = 0, sz = Components.size(); i < sz && !halt; ++i)
{
Components[i]->Tick(dt);
}
halt = false;
OnTick(dt);
if(destruct)
finalise();
}
void Window::DoKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool alt)
{
//on key press
if(focusedComponent_ != NULL)
{
if(!focusedComponent_->Locked && focusedComponent_->Visible)
focusedComponent_->OnKeyPress(key, character, shift, ctrl, alt);
}
OnKeyPress(key, character, shift, ctrl, alt);
if(destruct)
finalise();
}
void Window::DoKeyRelease(int key, Uint16 character, bool shift, bool ctrl, bool alt)
{
//on key unpress
if(focusedComponent_ != NULL)
{
if(!focusedComponent_->Locked && focusedComponent_->Visible)
focusedComponent_->OnKeyRelease(key, character, shift, ctrl, alt);
}
OnKeyRelease(key, character, shift, ctrl, alt);
if(destruct)
finalise();
}
void Window::DoMouseDown(int x_, int y_, unsigned button)
{
//on mouse click
int x = x_ - Position.X;
int y = y_ - Position.Y;
bool clickState = false;
for(int i = Components.size() - 1; i > -1 && !halt; --i)
{
if(!Components[i]->Locked && Components[i]->Visible)
{
if(x >= Components[i]->Position.X && y >= Components[i]->Position.Y && x < Components[i]->Position.X + Components[i]->Size.X && y < Components[i]->Position.Y + Components[i]->Size.Y)
{
FocusComponent(Components[i]);
Components[i]->OnMouseClick(x - Components[i]->Position.X, y - Components[i]->Position.Y, button);
clickState = true;
break;
}
}
}
if(!clickState)
FocusComponent(NULL);
//on mouse down
for(int i = Components.size() - 1; i > -1 && !halt; --i)
{
if(!Components[i]->Locked && Components[i]->Visible)
Components[i]->OnMouseDown(x, y, button);
}
OnMouseDown(x_, y_, button);
if(destruct)
finalise();
}
void Window::DoMouseMove(int x_, int y_, int dx, int dy)
{
//on mouse move (if true, and inside)
int x = x_ - Position.X;
int y = y_ - Position.Y;
for(int i = Components.size() - 1; i > -1 && !halt; --i)
{
if(!Components[i]->Locked && Components[i]->Visible)
{
Point local (x - Components[i]->Position.X, y - Components[i]->Position.Y)
, a (local.X - dx, local.Y - dy);
Components[i]->OnMouseMoved(local.X, local.Y, dx, dy);
if(local.X >= 0 &&
local.Y >= 0 &&
local.X < Components[i]->Size.X &&
local.Y < Components[i]->Size.Y && !halt)
{
Components[i]->OnMouseMovedInside(local.X, local.Y, dx, dy);
// entering?
if(!(
a.X >= 0 &&
a.Y >= 0 &&
a.X < Components[i]->Size.X &&
a.Y < Components[i]->Size.Y ))
{
Components[i]->OnMouseEnter(local.X, local.Y);
}
}
else if(!halt)
{
// leaving?
if( a.X >= 0 &&
a.Y >= 0 &&
a.X < Components[i]->Size.X &&
a.Y < Components[i]->Size.Y )
{
Components[i]->OnMouseLeave(local.X, local.Y);
}
}
}
}
OnMouseMove(x_, y_, dx, dy);
if(destruct)
finalise();
}
void Window::DoMouseUp(int x_, int y_, unsigned button)
{
int x = x_ - Position.X;
int y = y_ - Position.Y;
//on mouse unclick
for(int i = Components.size() - 1; i >= 0 && !halt; --i)
{
if(!Components[i]->Locked && Components[i]->Visible)
{
if(x >= Components[i]->Position.X && y >= Components[i]->Position.Y && x < Components[i]->Position.X + Components[i]->Size.X && y < Components[i]->Position.Y + Components[i]->Size.Y)
{
Components[i]->OnMouseUnclick(x - Components[i]->Position.X, y - Components[i]->Position.Y, button);
break;
}
}
}
//on mouse up
for(int i = Components.size() - 1; i >= 0 && !halt; --i)
{
if(!Components[i]->Locked && Components[i]->Visible)
Components[i]->OnMouseUp(x, y, button);
}
OnMouseUp(x_, y_, button);
if(destruct)
finalise();
}
void Window::DoMouseWheel(int x_, int y_, int d)
{
int x = x_ - Position.X;
int y = y_ - Position.Y;
//on mouse wheel focused
for(int i = Components.size() - 1; i >= 0 && !halt; --i)
{
if(x >= Components[i]->Position.X && y >= Components[i]->Position.Y && x < Components[i]->Position.X + Components[i]->Size.X && y < Components[i]->Position.Y + Components[i]->Size.Y)
{
if(!Components[i]->Locked && Components[i]->Visible)
Components[i]->OnMouseWheelInside(x - Components[i]->Position.X, y - Components[i]->Position.Y, d);
break;
}
}
//on mouse wheel
for(int i = Components.size() - 1; i >= 0 && !halt; --i)
{
if(!Components[i]->Locked && Components[i]->Visible)
Components[i]->OnMouseWheel(x - Components[i]->Position.X, y - Components[i]->Position.Y, d);
}
OnMouseWheel(x_, y_, d);
if(destruct)
finalise();
}
void Window::finalise()
{
delete this;
}
void Window::SelfDestruct()
{
destruct = true;
halt = true;
}