src/view.cpp in reflexion-0.1.7 vs src/view.cpp in reflexion-0.1.8
- old
+ new
@@ -2,14 +2,14 @@
#include <assert.h>
#include <algorithm>
#include <boost/scoped_ptr.hpp>
-#include <rays/bounds.h>
-#include <rays/painter.h>
#include "reflex/window.h"
+#include "reflex/body.h"
#include "reflex/exception.h"
+#include "world.h"
namespace Reflex
{
@@ -36,10 +36,14 @@
boost::scoped_ptr<ChildList> pchildren;
boost::scoped_ptr<StyleList> pstyles;
+ boost::scoped_ptr<World> pworld;
+
+ boost::scoped_ptr<Body> pbody;
+
Style style;
ushort capture;
short hide_count;
@@ -78,10 +82,34 @@
{
if (!pstyles) pstyles.reset(new StyleList);
return *pstyles;
}
+ World* world ()
+ {
+ if (!pworld) pworld.reset(new World());
+ return pworld.get();
+ }
+
+ World* parent_world ()
+ {
+ if (!parent) return NULL;
+ return parent->self->world();
+ }
+
+ Body* body (View* this_)
+ {
+ if (!pbody)
+ {
+ World* world = parent_world();
+ if (!world) return NULL;
+ pbody.reset(world->create_body(frame.position()));
+ this_->make_body();
+ }
+ return pbody.get();
+ }
+
};// View::Data
void
set_window (View* this_, Window* window_)
@@ -108,10 +136,11 @@
if (this_->self->window)
{
Event e;
this_->on_attach(&e);
+ this_->resize_to_fit();
}
}
static void
set_parent (View* this_, View* parent_)
@@ -131,31 +160,56 @@
this_->self->parent = parent_;
set_window(this_, parent_ ? parent_->window() : NULL);
}
+ static void
+ update_world (View* view, float dt)
+ {
+ World* world = view->self->pworld.get();
+ if (world) world->step(dt);
+
+ Body* body = view->self->pbody.get();
+ if (body)
+ {
+ Bounds b = view->frame();
+ b.move_to(body->position());
+ view->set_frame(b);
+ }
+ }
+
void
update_view_tree (View* view, const UpdateEvent& event)
{
if (!view)
argument_error(__FILE__, __LINE__);
UpdateEvent e = event;
+ update_world(view, e.dt);
view->on_update(&e);
View::child_iterator end = view->child_end();
for (View::child_iterator it = view->child_begin(); it != end; ++it)
update_view_tree(it->get(), e);
}
+ static void
+ draw_world (View* view, Painter* painter)
+ {
+ World* world = view->self->pworld.get();
+ if (world) world->draw(painter);
+ }
+
void
draw_view_tree (
View* view, const DrawEvent& event, const Point& offset, const Bounds& clip)
{
if (!view)
argument_error(__FILE__, __LINE__);
+ if (view->hidden()) return;
+
DrawEvent e = event;
e.painter->push_matrix();
e.painter->push_attr();
Bounds b = view->frame();
@@ -172,10 +226,12 @@
View::child_iterator end = view->child_end();
for (View::child_iterator it = view->child_begin(); it != end; ++it)
draw_view_tree(it->get(), e, p, c);
+ draw_world(view, e.painter);
+
e.painter->pop_attr();
e.painter->pop_matrix();
}
#if 0
void
@@ -649,22 +705,40 @@
View::show ()
{
if (!*this)
invalid_state_error(__FILE__, __LINE__);
- --self->hide_count;
- redraw();
+ int new_count = self->hide_count - 1;
+ if (new_count == 0)
+ {
+ Event e;
+ on_show(&e);
+ if (e.is_blocked()) return;
+
+ redraw();
+ }
+
+ self->hide_count = new_count;
}
void
View::hide ()
{
if (!*this)
invalid_state_error(__FILE__, __LINE__);
- ++self->hide_count;
- redraw();
+ int new_count = self->hide_count + 1;
+ if (new_count == 1)
+ {
+ Event e;
+ on_hide(&e);
+ if (e.is_blocked()) return;
+
+ redraw();
+ }
+
+ self->hide_count = new_count;
}
bool
View::hidden () const
{
@@ -978,10 +1052,36 @@
return -1;
}
void
+ View::make_body ()
+ {
+ Body* b = body();
+ if (!b) return;
+
+ b->clear_fixtures();
+
+ const Point& size = frame().size();
+ b->add_box(size.x, size.y);
+ }
+
+ void
+ View::clear_body ()
+ {
+ Body* body = self->pbody.get();
+ if (!body) return;
+
+ World* world = self->parent_world();
+ if (!world)
+ invalid_state_error(__FILE__, __LINE__);
+
+ world->destroy_body(body);
+ self->pbody.reset();
+ }
+
+ void
View::set_name (const char* name)
{
if (!*this)
invalid_state_error(__FILE__, __LINE__);
@@ -1222,19 +1322,104 @@
View::window () const
{
return const_cast<View*>(this)->window();
}
- Rays::Point
- View::from_parent (const Rays::Point& point) const
+ Body*
+ View::body ()
{
+ if (!*this)
+ invalid_state_error(__FILE__, __LINE__);
+
+ return self->body(this);
+ }
+
+ const Body*
+ View::body () const
+ {
+ return const_cast<View*>(this)->body();
+ }
+
+ void
+ View::set_density (float density)
+ {
+ Body* b = body();
+ if (!b)
+ invalid_state_error(__FILE__, __LINE__);
+
+ b->set_density(density);
+ }
+
+ void
+ View::set_friction (float friction)
+ {
+ Body* b = body();
+ if (!b)
+ invalid_state_error(__FILE__, __LINE__);
+
+ b->set_friction(friction);
+ }
+
+ void
+ View::set_restitution (float restitution)
+ {
+ Body* b = body();
+ if (!b)
+ invalid_state_error(__FILE__, __LINE__);
+
+ b->set_restitution(restitution);
+ }
+
+ void
+ View::set_gravity (float x, float y)
+ {
+ set_gravity(Point(x, y));
+ }
+
+ void
+ View::set_gravity (const Point& vector)
+ {
+ World* world = self->world();
+ if (!world)
+ invalid_state_error(__FILE__, __LINE__);
+
+ world->set_gravity(vector);
+ }
+
+ Point
+ View::gravity () const
+ {
+ World* world = self->pworld.get();
+ return world ? world->gravity() : 0;
+ }
+
+ void
+ View::set_debug (bool state)
+ {
+ World* world = self->world();
+ if (!world)
+ invalid_state_error(__FILE__, __LINE__);
+
+ world->set_debug(state);
+ }
+
+ bool
+ View::is_debug () const
+ {
+ World* world = self->pworld.get();
+ return world ? world->is_debug() : false;
+ }
+
+ Point
+ View::from_parent (const Point& point) const
+ {
not_implemented_error(__FILE__, __LINE__);
return 0;
}
- Rays::Point
- View::to_parent (const Rays::Point& point) const
+ Point
+ View::to_parent (const Point& point) const
{
not_implemented_error(__FILE__, __LINE__);
return 0;
}
@@ -1245,38 +1430,53 @@
for (const View* v = parent(); v; v = v->parent())
p -= v->frame().position();
return p;
}
- Rays::Point
- View::to_window (const Rays::Point& point) const
+ Point
+ View::to_window (const Point& point) const
{
not_implemented_error(__FILE__, __LINE__);
return 0;
}
- Rays::Point
- View::from_screen (const Rays::Point& point) const
+ Point
+ View::from_screen (const Point& point) const
{
not_implemented_error(__FILE__, __LINE__);
return 0;
}
- Rays::Point
- View::to_screen (const Rays::Point& point) const
+ Point
+ View::to_screen (const Point& point) const
{
not_implemented_error(__FILE__, __LINE__);
return 0;
}
void
View::on_attach (Event* e)
{
- resize_to_fit();
+ if (!e)
+ argument_error(__FILE__, __LINE__);
}
void
View::on_detach (Event* e)
+ {
+ if (!e)
+ argument_error(__FILE__, __LINE__);
+ }
+
+ void
+ View::on_show (Event* e)
+ {
+ if (!e)
+ argument_error(__FILE__, __LINE__);
+ }
+
+ void
+ View::on_hide (Event* e)
{
if (!e)
argument_error(__FILE__, __LINE__);
}