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