void ribi::WtToggleButtonWidget::DrawToggleButton( Wt::WPainter& painter, const int left, const int top, const int width, const int height, const ToggleButton * const button) { { Wt::WPen pen = painter.pen(); pen.setWidth(1); pen.setColor(Wt::WColor(0,0,0)); painter.setPen(pen); } painter.setBrush(Wt::WColor( button->GetRed(), button->GetGreen(), button->GetBlue())); //Draw base painter.drawArc( left + 0, top + (height * 1 / 3), width, height * 2 / 3, 180 * 16, 180 * 16); //Draw top painter.drawEllipse( left + 0, top + (button->IsPressed() ? (height * 1 / 3) - 2 : 0.0), width, height * 2 / 3); painter.drawLine( left + 1, top + (button->IsPressed() ? (height * 2 / 3) - 2 : (height * 1 / 3)), left + 1, top + (height * 2 / 3)); painter.drawLine( left + (width - 1), top + (button->IsPressed() ? (height * 2 / 3) - 2 : (height * 1 / 3)), left + width - 1, top + (height * 2 / 3)); }
void ribi::WtDialWidget::DrawDial( Wt::WPainter& painter, const int left, const int top, const int width, const int height, const Dial * const dial) { const double position = dial->GetPosition(); //Draw knob { Wt::WPen pen = painter.pen(); pen.setWidth(1); pen.setColor(Wt::WColor(0,0,0)); painter.setPen(pen); } painter.setBrush(Wt::WColor( dial->GetRed(), dial->GetGreen(), dial->GetBlue())); painter.drawEllipse(left+1,top+1,width-2,height-2); //Draw pointer const int midx = width / 2; const int midy = height / 2; const double ray = static_cast<double>(std::min( midx, midy )); const double two_pi = boost::math::constants::two_pi<double>(); const double angle = position * two_pi; const int pointerX = static_cast<int>( static_cast<double>(midx) + (std::sin(angle) * ray) ); const int pointerY = static_cast<int>( static_cast<double>(midy) - (std::cos(angle) * ray) ); { Wt::WPen pen = painter.pen(); pen.setWidth(4); painter.setPen(pen); } painter.drawLine(left+midx,top+midy,left+pointerX,top+pointerY); }
void elevator_system_drawer::draw_elevator(Wt::WPainter& painter, Wt::WRectF const& rc) { const auto floor_height = get_floor_height(SizeFormat::Pixels); const auto elevator_height = get_elevator_height(SizeFormat::Pixels); painter.save(); Wt::WRectF rc_elevator( rc.left(), rc.bottom() - get_current_floor() * floor_height - elevator_height, rc.width(), elevator_height ); if(m_stage == AnimationStage::Moving) { auto travelled = m_stage_step * ElevatorSpeed * m_pix_multiplier; travelled = std::min(travelled, floor_height); auto sign = m_sys.m_state.direction == Direction::Up ? 1.0 : -1.0; rc_elevator = Wt::WRectF( rc_elevator.left(), rc_elevator.top() - sign * travelled, rc_elevator.width(), rc_elevator.height() ); } double exit_door_openness = 0.0; switch(m_stage) { case AnimationStage::ExitDoorsOpening: exit_door_openness = m_stage_step * DoorSpeed * m_pix_multiplier / elevator_height; exit_door_openness = std::min(exit_door_openness, 1.0); break; case AnimationStage::ExitDoorsClosing: exit_door_openness = 1.0 - m_stage_step * DoorSpeed * m_pix_multiplier / elevator_height; exit_door_openness = std::max(exit_door_openness, 0.0); break; case AnimationStage::GettingOff: exit_door_openness = 1.0; break; } double entry_door_openness = 0.0; switch(m_stage) { case AnimationStage::EntryDoorsOpening: entry_door_openness = m_stage_step * DoorSpeed * m_pix_multiplier / elevator_height; entry_door_openness = std::min(entry_door_openness, 1.0); break; case AnimationStage::EntryDoorsClosing: entry_door_openness = 1.0 - m_stage_step * DoorSpeed * m_pix_multiplier / elevator_height; entry_door_openness = std::max(entry_door_openness, 0.0); break; case AnimationStage::GettingOn: entry_door_openness = 1.0; break; } painter.drawLine(rc_elevator.topLeft(), rc_elevator.topRight()); painter.drawLine(rc_elevator.bottomLeft(), rc_elevator.bottomRight()); painter.drawLine( rc_elevator.left(), rc_elevator.top(), rc_elevator.left(), rc_elevator.top() + (1.0 - entry_door_openness) * elevator_height ); painter.drawLine( rc_elevator.right(), rc_elevator.top(), rc_elevator.right(), rc_elevator.top() + (1.0 - exit_door_openness) * elevator_height ); if(m_sys.is_moving(m_sys.m_state.direction)) { painter.save(); painter.translate(rc_elevator.left(), rc_elevator.top()); if(m_sys.m_state.direction == elevator_system::Direction::Down) { painter.translate(0.0, rc_elevator.height() * 0.5); painter.scale(1.0, -1.0); } painter.scale(rc_elevator.width(), rc_elevator.height()); std::array< Wt::WPointF, 3 > points{ { { 0.5, 0.1 }, { 0.2, 0.4 }, { 0.8, 0.4 }, } }; painter.setPen(Wt::WPen(Wt::green)); painter.setBrush(Wt::WBrush(Wt::green)); painter.drawPolygon(&points[0], 3); painter.restore(); } Wt::WFont font = painter.font(); //font.setFamily(Wt::WFont::Default); font.setSize(20); painter.setFont(font); painter.drawText( Wt::WRectF(rc_elevator.left(), rc_elevator.center().y(), rc_elevator.width(), rc_elevator.height() * 0.5), Wt::AlignCenter | Wt::AlignMiddle, std::to_string(get_current_occupancy()) ); painter.restore(); }
void elevator_system_drawer::draw_floor(Wt::WPainter& painter, Wt::WRectF const& rc) { painter.drawLine(rc.left(), rc.bottom(), rc.right(), rc.bottom()); }
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()); }