//---------------------------------------------------------------------------
void WtRubiksClockWidget::DrawRubiksClock(
  Wt::WPainter& painter,
  const int left, const int top,
  const int width, const int height,
  const RubiksClock * const clock,
  const bool front_side)
{
  //Draw main clock ring
  {
    Wt::WPen pen = painter.pen();
    pen.setColor(Wt::black);
    painter.setPen(pen);
  }
  {
    painter.setBrush(
      Wt::WBrush(
        Wt::WColor(
          front_side ? 127 : 96,
          front_side ? 127 : 96,
          196)));
  }
  painter.drawEllipse(
    static_cast<double>(left),
    static_cast<double>(top),
    static_cast<double>(width),
    static_cast<double>(height));



  //Draw the clocks and pegs
  {
    for (int y=0; y!=3; ++y)
    {
      for (int x=0; x!=3; ++x)
      {
        const boost::shared_ptr<RubiksClockDialWidget> w
          = (front_side ? clock->GetFrontTimes() : clock->GetBackTimes()).times[x][y];
        WtDialWidget::DrawDial(
          painter,
          w->GetGeometry().GetX(),
          w->GetGeometry().GetY(),
          w->GetGeometry().GetWidth(),
          w->GetGeometry().GetHeight(),
          w->GetRubiksClockDial()->GetDial());
      }
    }
    //Draw the pegs
    for (int y=0; y!=2; ++y)
    {
      for (int x=0; x!=2; ++x)
      {
        WtToggleButtonWidget::DrawToggleButton(
          painter,
          (front_side
            ? clock->GetFrontPegs()
            : clock->GetBackPegs()).pegs[x][y].get());
      }
    }
  }
}
	void elevator_system_drawer::draw_getting_on(Wt::WPainter& painter, Wt::WRectF const& rc)
	{
		auto const floor = get_current_floor();
		Direction const dir = m_sys.m_state.direction;
		auto count = m_sys.m_transitions.num_got_on;

		auto rc_floor = floor_rect(floor, rc);
		auto rc_q_corridor = queue_corridor_rect(dir, rc_floor);
		auto rc_q = queue_rect(
			count,
			QueueSide::Right,
			rc_q_corridor
			);

		auto walked = WalkingSpeed * m_stage_step * m_pix_multiplier;
		rc_q = Wt::WRectF(
			rc_q.left() + walked,
			rc_q.top(),
			rc_q.width(),
			rc_q.height()
			);

		painter.save();
		Wt::WPainterPath clip_path;
		clip_path.addRect(
			rc_q_corridor.left(),
			rc_q_corridor.top(),
			rc_q_corridor.width() + get_door_gap_width(SizeFormat::Pixels),
			rc_q_corridor.height()
			);
		painter.setClipping(true);
		painter.setClipPath(clip_path);

		draw_queue(count, painter, rc_q);

		painter.restore();
	}
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 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 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 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 elevator_system_drawer::draw_person(Wt::WPainter& painter, Wt::WRectF const& rc)
	{
		painter.drawRect(rc);
	}
示例#9
0
	void basic_spaceship::draw(Wt::WPainter& painter) const
	{
		simple_rigid_body::draw(painter);

/*		Wt::WRectF rc(
			-m_half_width,
			-m_half_width,
			m_half_width * 2,
			m_half_width * 2
			);
*/		painter.save();
		painter.translate(m_body->GetPosition().x, m_body->GetPosition().y);
		painter.rotate(m_body->GetAngle() * 360.0 / (2 * b2_pi));
//		painter.drawRect(rc);

		thruster_config< WorldDimensionality::dim2D > const& t_cfg = *m_t_cfg;
		double const ThrusterSize = m_half_width * 0.3;
		std::array< Wt::WPointF, 3 > points = {
			Wt::WPointF(0, 0),
			Wt::WPointF(-ThrusterSize / 2, -ThrusterSize),
			Wt::WPointF(ThrusterSize / 2, -ThrusterSize)
		};
		Wt::WPen pen(Wt::GlobalColor::black);
		for(size_t i = 0; i < m_t_cfg->num_thrusters(); ++i)
		{
			painter.save();

			auto const& tpos = m_half_width * t_cfg[i].pos;
			painter.translate(tpos[0], tpos[1]);
			double dir_x = t_cfg[i].dir[0];
			double dir_y = t_cfg[i].dir[1];
			double theta = boost::math::copysign(std::acos(dir_y), dir_x);
			painter.rotate(360.0 * -theta / (2 * boost::math::double_constants::pi));

			double temperature = m_t_system[i].t.temperature();
			Wt::WColor color((int)(temperature * 255), 0, 0);
			pen.setColor(color);
			painter.setPen(pen);
			Wt::WBrush br(color);
			painter.setBrush(br);
			painter.drawPolygon(&points[0], points.size());

			painter.restore();
		}

//		double const IndicatorSize = m_half_width * 0.35;
		auto const IndicatorPos = b2Vec2(0.f, 1.4f * m_half_width);
		m_front_sensor->draw(painter, IndicatorPos);
		m_rear_sensor->draw(painter, IndicatorPos);
		m_left_sensor->draw(painter, IndicatorPos);
		m_right_sensor->draw(painter, IndicatorPos);

		painter.restore();
	}
示例#10
0
		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());
		}