void elevator_system_drawer::draw_system(Wt::WPainter& painter, options_t const& options) { // boost::lock_guard< async_system_drawer > guard(*this); size_t Margin = 10; painter.save(); Wt::WPaintDevice* device = painter.device(); Wt::WLength dev_width = device->width(); Wt::WLength dev_height = device->height(); double pix_width = dev_width.toPixels() - 2 * Margin; double pix_height = dev_height.toPixels() - 2 * Margin; auto avail_aspect = pix_width / pix_height; if(avail_aspect > DisplayAspect) { pix_width = pix_height * DisplayAspect; } else { pix_height = pix_width / DisplayAspect; } auto x_margin = (dev_width.toPixels() - pix_width) / 2.0; auto y_margin = (dev_height.toPixels() - pix_height) / 2.0; painter.setViewPort( x_margin, y_margin, pix_width, pix_height ); painter.setWindow( 0.0, 0.0, pix_width, pix_height ); set_pixel_multiplier(pix_height); auto const& st = m_sys.m_state; const auto entry_width = get_entry_width(SizeFormat::Pixels); const auto exit_width = get_exit_width(SizeFormat::Pixels); const auto door_gap = get_door_gap_width(SizeFormat::Pixels); const auto elevator_width = get_elevator_width(SizeFormat::Pixels); // On floor side Wt::WRectF rc_all_on_floors( 0.0, 0.0, entry_width, pix_height ); draw_all_floors(painter, rc_all_on_floors); // Elevator shaft Wt::WRectF rc_shaft(entry_width + door_gap, 0.0, elevator_width, pix_height); draw_elevator(painter, rc_shaft); // Off floor side Wt::WRectF rc_all_off_floors( pix_width - exit_width, 0.0, exit_width, pix_height ); draw_all_floors(painter, rc_all_off_floors); // Queues draw_all_queues(painter, rc_all_on_floors); switch(m_stage) { case AnimationStage::Arrivals: draw_arrivals(painter, rc_all_on_floors); break; case AnimationStage::GettingOn: draw_getting_on(painter, rc_all_on_floors); break; case AnimationStage::GettingOff: draw_getting_off(painter, rc_all_off_floors); break; } ///// Wt::WFont font = painter.font(); font.setSize(30); painter.setFont(font); painter.drawText( Wt::WRectF(0.0, 0.0, 100.0, 30.0), Wt::AlignLeft | Wt::AlignTop, std::to_string((int)m_stage) + " / " + std::to_string(m_stage_step) ); ///// painter.restore(); reset_pixel_multiplier(); }
void phys2d_system_drawer::draw_system(Wt::WPainter& painter, options_t const& options) { size_t const Margin = 0; Wt::WPaintDevice* device = painter.device(); Wt::WLength dev_width = device->width(); Wt::WLength dev_height = device->height(); size_t avail_size = (size_t)std::min(dev_width.toPixels() - 2 * Margin, dev_height.toPixels() - 2 * Margin); painter.save(); Wt::WPen pen(Wt::GlobalColor::lightGray); painter.setPen(pen); double const scale = (avail_size / 25.0) * options.zoom; size_t const GridDim = 5; double const GridSquareSize = avail_size / GridDim; // TODO: Hack - locking onto first agent // auto agent_ptr = dynamic_cast<object const*>(m_sys.m_agents.front().agent.get()); b2Vec2 grid_ref_pos = b2Vec2(0, 0);//agent_ptr->get_position(); double x_off = std::fmod(-grid_ref_pos.x * scale, GridSquareSize); if(x_off < 0.0) { x_off += GridSquareSize; } double y_off = std::fmod(-grid_ref_pos.y * -scale, GridSquareSize); if(y_off < 0.0) { y_off += GridSquareSize; } for(size_t i = 0; i < dev_width.toPixels() / GridSquareSize; ++i) { painter.drawLine( x_off + i * GridSquareSize, 0.0, x_off + i * GridSquareSize, dev_height.toPixels() ); } for(size_t i = 0; i < dev_height.toPixels() / GridSquareSize; ++i) { painter.drawLine( 0.0, y_off + i * GridSquareSize, dev_width.toPixels(), y_off + i * GridSquareSize ); } painter.translate(dev_width.toPixels() / 2, dev_height.toPixels() / 2); painter.scale(scale, -scale); painter.translate(-grid_ref_pos.x, -grid_ref_pos.y); pen = Wt::WPen(Wt::GlobalColor::black); painter.setPen(pen); Wt::WBrush br(Wt::GlobalColor::white); painter.setBrush(br); painter.save(); auto world = m_sys.get_world(); auto body = world->GetBodyList(); while(body) { draw_body(body, painter); body = body->GetNext(); } /* TODO: maybe use visitor pattern for entity specific drawing http://programmers.stackexchange.com/questions/185525/design-pattern-for-polymorphic-behaviour-while-allowing-library-separation m_sys.m_scenario->draw_fixed_objects(painter); //phys_system::const_agent_range agents = m_sys.get_agent_range(); //for(auto it = agents.first; it != agents.second; ++it) for(auto const& agent : m_sys.m_agents) { //(*it)->draw(painter); agent.agent->draw(painter); } */ painter.restore(); painter.restore(); Wt::WFont font = painter.font(); //font.setFamily(Wt::WFont::Default); font.setSize(20); painter.setFont(font); pen.setColor(Wt::GlobalColor::blue); painter.setPen(pen); auto rc = Wt::WRectF( 0, 0, dev_width.toPixels(), 30 ); std::stringstream text; text.precision(2); std::fixed(text); text << m_sys.get_time() << "s"; painter.drawText(rc, Wt::AlignLeft | Wt::AlignMiddle, text.str()); }