Beispiel #1
0
void
TaskEditPanel::EditTaskPoint(unsigned ItemIndex)
{
  if (ItemIndex < ordered_task->TaskSize()) {
    if (dlgTaskPointShowModal(&ordered_task, ItemIndex)) {
      *task_modified = true;
      ordered_task->ClearName();
      ordered_task->UpdateGeometry();
      RefreshView();
    }
  } else if (!ordered_task->IsFull()) {

    OrderedTaskPoint* point = nullptr;
    AbstractTaskFactory &factory = ordered_task->GetFactory();
    const Waypoint* way_point =
      ShowWaypointListDialog(ordered_task->TaskSize() > 0
                             ? ordered_task->GetPoint(ordered_task->TaskSize() - 1).GetLocation()
                             : CommonInterface::Basic().location,
                        ordered_task, ItemIndex);
    if (!way_point)
      return;

    if (ItemIndex == 0) {
      point = (OrderedTaskPoint*)factory.CreateStart(*way_point);
    } else {
      point = (OrderedTaskPoint*)factory.CreateIntermediate(*way_point);
     }
    if (point == nullptr)
      return;

    if (factory.Append(*point, true)) {
      *task_modified = true;
      ordered_task->ClearName();
      ordered_task->UpdateGeometry();
      RefreshView();
    }

    delete point;
  }
}
Beispiel #2
0
void
TaskEditPanel::OnClearAllClicked()
{
  if ((ordered_task->TaskSize() < 2) ||
      (ShowMessageBox(_("Clear all points?"), _("Task edit"),
                   MB_YESNO|MB_ICONQUESTION) == IDYES)) {

    ordered_task->RemoveAllPoints();
    ordered_task->ClearName();
    *task_modified = true;
    RefreshView();
  }
}
Beispiel #3
0
void TaskEditPanel::ReverseTask()
{
  if (ordered_task->TaskSize() < 2)
    return;

  const unsigned start_index = 0;
  const unsigned finish_index = ordered_task->TaskSize() - 1;
  const Waypoint start_wp = ordered_task->GetTaskPoint(start_index).GetWaypoint();
  const Waypoint finish_wp = ordered_task->GetTaskPoint(finish_index).GetWaypoint();

  if (start_wp.location != finish_wp.location) {
    // swap start/finish TP if at different location but leave OZ type intact
    ordered_task->Relocate(start_index, finish_wp);
    ordered_task->Relocate(finish_index, start_wp);

    // remove optional start points
    while (ordered_task->HasOptionalStarts())
      ordered_task->RemoveOptionalStart(0);
  }

  // reverse intermediate TPs order keeping the OZ type with the respective TP
  unsigned length = ordered_task->TaskSize()-1;
  for (unsigned i = 1; i < length - 1; ++i) {
    const OrderedTaskPoint &otp = ordered_task->GetTaskPoint(length - 1);
    if (!ordered_task->GetFactory().Insert(otp, i, false))
      return;
    if (!ordered_task->GetFactory().Remove(length, false))
      return;
  }

  *task_modified = true;
  ordered_task->ClearName();
  ordered_task->GetFactory().CheckAddFinish();
  ordered_task->UpdateStatsGeometry();
  ordered_task->UpdateGeometry();
  RefreshView();
}
Beispiel #4
0
void
TaskEditPanel::MoveDown()
{
  unsigned index = GetList().GetCursorIndex();
  if (index >= ordered_task->TaskSize())
    return;

  if (!ordered_task->GetFactory().Swap(index, true))
    return;

  GetList().SetCursorIndex(index + 1);
  *task_modified = true;

  RefreshView();
}
bool
FAITriangleValidator::Validate(const OrderedTask &task)
{
  if (!task.GetFactory().IsUnique())
    return false;

  if (task.TaskSize() != 4)
    return false;

  const fixed d1 = task.GetTaskPoint(1).GetVectorPlanned().distance;
  const fixed d2 = task.GetTaskPoint(2).GetVectorPlanned().distance;
  const fixed d3 = task.GetTaskPoint(3).GetVectorPlanned().distance;

  return TestDistances(d1, d2, d3);
}
Beispiel #6
0
void
TaskRenderer::Draw(const OrderedTask &task)
{
    tpv.SetBoundingBox(task.get_bounding_box(screen_bounds));
    tpv.SetActiveIndex(task.GetActiveIndex());
    for (unsigned i = 0; i < 4; i++) {
        tpv.ResetIndex();

        if (i != RenderTaskPoint::LAYER_SYMBOLS && i != RenderTaskPoint::LAYER_LEG) {
            tpv.SetModeOptional(true);

            for (unsigned j = 0, end = task.optional_start_points_size(); j < end; ++j)
                tpv.Draw(*task.get_optional_start(j), (RenderTaskPoint::Layer)i);
        }

        tpv.SetModeOptional(false);
        for (unsigned j = 0, end = task.TaskSize(); j < end; ++j)
            tpv.Draw(task.GetTaskPoint(j), (RenderTaskPoint::Layer)i);
    }
}
Beispiel #7
0
void
TaskEditPanel::RefreshView()
{
  UpdateButtons();

  dialog.InvalidateTaskView();

  unsigned length = ordered_task->TaskSize();
  if (!ordered_task->IsFull())
    ++length;
  GetList().SetLength(length);
  GetList().Invalidate();

  {
    TCHAR text[300];
    OrderedTaskSummary(ordered_task, text, false);
    summary.SetText(text);
  }

  if (GetList().IsVisible() && two_widgets != nullptr)
    two_widgets->UpdateLayout();
}
Beispiel #8
0
static void
RenderFAISectors(Canvas &canvas, const WindowProjection &projection,
                 const OrderedTask &task)
{
  const FAITriangleSettings &settings =
    task.GetOrderedTaskSettings().fai_triangle;

  const unsigned size = task.TaskSize();
  const unsigned end = size - 1;

  for (unsigned i = 0; i != end; ++i)
    RenderFAISector(canvas, projection,
                    task.GetPoint(i).GetLocation(),
                    task.GetPoint(i + 1).GetLocation(),
                    true, settings);

  for (unsigned i = 0; i != end; ++i)
    RenderFAISector(canvas, projection,
                    task.GetPoint(i).GetLocation(),
                    task.GetPoint(i + 1).GetLocation(),
                    false, settings);
}
Beispiel #9
0
void
TaskPointWidget::RefreshView()
{
  map.Invalidate();

  OrderedTaskPoint &tp = ordered_task->GetPoint(active_index);

  properties_dock.SetWidget(new PanelWidget());

  ObservationZonePoint &oz = tp.GetObservationZone();
  const bool is_fai_general =
    ordered_task->GetFactoryType() == TaskFactoryType::FAI_GENERAL;
  properties_widget = CreateObservationZoneEditWidget(oz, is_fai_general);
  if (properties_widget != nullptr) {
    properties_widget->SetListener(this);
    properties_dock.SetWidget(properties_widget);
  }

  type_label.SetCaption(OrderedTaskPointName(ordered_task->GetFactory().GetType(tp)));

  previous_button->SetEnabled(active_index > 0);
  next_button->SetEnabled(active_index < (ordered_task->TaskSize() - 1));

  optional_starts.SetVisible(active_index == 0);
  if (!ordered_task->HasOptionalStarts())
    optional_starts.SetCaption(_("Enable Alternate Starts"));
  else {
    StaticString<50> tmp;
    tmp.Format(_T("%s (%d)"), _("Edit Alternates"),
               ordered_task->GetOptionalStartPointCount());
    optional_starts.SetCaption(tmp);
  }

  if (tp.GetType() == TaskPointType::AST) {
    const ASTPoint &ast = (const ASTPoint &)tp;
    score_exit.Show();
    score_exit.SetState(ast.GetScoreExit());
  } else
    score_exit.Hide();

  StaticString<100> name_prefix_buffer, type_buffer;

  switch (tp.GetType()) {
  case TaskPointType::START:
    type_buffer = _("Start point");
    name_prefix_buffer = _T("Start: ");
    break;

  case TaskPointType::AST:
    type_buffer = _("Task point");
    name_prefix_buffer.Format(_T("%d: "), active_index);
    break;

  case TaskPointType::AAT:
    type_buffer = _("Assigned area point");
    name_prefix_buffer.Format(_T("%d: "), active_index);
    break;

  case TaskPointType::FINISH:
    type_buffer = _("Finish point");
    name_prefix_buffer = _T("Finish: ");
    break;

  default:
    gcc_unreachable();
  }

  dialog.SetCaption(type_buffer);

  {
    StaticString<100> buffer;
    buffer.Format(_T("%s %s"), name_prefix_buffer.c_str(),
                  tp.GetWaypoint().name.c_str());
    waypoint_name.SetCaption(buffer);
  }
}
Beispiel #10
0
void
PrintHelper::orderedtask_print(const OrderedTask &task,
                               const AircraftState &state)
{
    abstracttask_print(task, state);
    if (!task.CheckTask())
        return;

    std::ofstream fi("output/results/res-isolines.txt");
    for (unsigned i = 0; i < task.TaskSize(); ++i) {
        const OrderedTaskPoint &tp = task.GetPoint(i);
        fi << "## point " << i << "\n";
        if (tp.GetType() == TaskPointType::AAT) {
            aatpoint_print(fi, (const AATPoint &)tp, state,
                           task.GetTaskProjection(), 1);
        } else {
            orderedtaskpoint_print(fi, tp, state, 1);
        }
        fi << "\n";
    }

    std::ofstream f1("output/results/res-task.txt");

    f1 << "#### Task points\n";
    for (unsigned i = 0; i < task.TaskSize(); ++i) {
        f1 << "## point " << i << " ###################\n";
        const OrderedTaskPoint &tp = task.GetPoint(i);
        if (tp.GetType() == TaskPointType::AAT) {
            aatpoint_print(f1, (const AATPoint &)tp, state,
                           task.GetTaskProjection(), 0);
        } else {
            orderedtaskpoint_print(f1, tp, state, 0);
        }
        f1 << "\n";
    }

    std::ofstream f5("output/results/res-ssample.txt");
    f5 << "#### Task sampled points\n";
    for (unsigned i =0 ; i < task.TaskSize(); ++i) {
        const OrderedTaskPoint &tp = task.GetPoint(i);
        f5 << "## point " << i << "\n";
        sampledtaskpoint_print_samples(f5, tp, state);
        f5 << "\n";
    }

    std::ofstream f2("output/results/res-max.txt");
    f2 << "#### Max task\n";
    for (unsigned i = 0; i < task.TaskSize(); ++i) {
        const OrderedTaskPoint &tp = task.GetPoint(i);
        f2 << tp.GetLocationMax().longitude << " "
           << tp.GetLocationMax().latitude << "\n";
    }

    std::ofstream f3("output/results/res-min.txt");
    f3 << "#### Min task\n";
    for (unsigned i = 0; i < task.TaskSize(); ++i) {
        const OrderedTaskPoint &tp = task.GetPoint(i);
        f3 << tp.GetLocationMin().longitude << " "
           << tp.GetLocationMin().latitude << "\n";
    }

    std::ofstream f4("output/results/res-rem.txt");
    f4 << "#### Remaining task\n";
    for (unsigned i = 0; i < task.TaskSize(); ++i) {
        const OrderedTaskPoint &tp = task.GetPoint(i);
        f4 << tp.GetLocationRemaining().longitude << " "
           << tp.GetLocationRemaining().latitude << "\n";
    }
}
Beispiel #11
0
/**
 * Is the current task point the finish point?
 */
gcc_pure
static bool
FinishIsCurrent(const OrderedTask &task)
{
    return task.GetActiveTaskPointIndex() + 1 == task.TaskSize();
}
Beispiel #12
0
void
TaskEditPanel::OnPaintItem(Canvas &canvas, const PixelRect rc,
                           unsigned DrawListIndex)
{
  assert(DrawListIndex <= ordered_task->TaskSize());

  const PixelScalar line_height = rc.bottom - rc.top;

  TCHAR buffer[120];

  const Font &name_font = *dialog.GetLook().list.font_bold;
  const Font &small_font = *dialog.GetLook().small_font;

  // Draw "Add turnpoint" label
  if (DrawListIndex == ordered_task->TaskSize()) {
    canvas.Select(name_font);
    canvas.SetTextColor(COLOR_BLACK);
    _stprintf(buffer, _T("  (%s)"), _("Add Turnpoint"));
    canvas.DrawText(rc.left + line_height + Layout::FastScale(2),
                    rc.top + line_height / 2 - name_font.GetHeight() / 2,
                    buffer);
    return;
  }

  const OrderedTaskPoint &tp = ordered_task->GetTaskPoint(DrawListIndex);
  GeoVector leg = tp.GetNominalLegVector();
  bool show_leg_info = leg.distance > fixed(0.01);

  // Draw icon
  const RasterPoint pt(rc.left + line_height / 2,
                       rc.top + line_height / 2);

  PixelScalar radius = std::min(PixelScalar(line_height / 2
                                            - Layout::FastScale(4)),
                                Layout::FastScale(10));

  OZPreviewRenderer::Draw(canvas, tp.GetObservationZone(),
                          pt, radius, task_look,
                          CommonInterface::GetMapSettings().airspace,
                          airspace_look);

  // Y-Coordinate of the second row
  PixelScalar top2 = rc.top + name_font.GetHeight() + Layout::FastScale(4);

  // Use small font for details
  canvas.Select(small_font);
  canvas.SetTextColor(COLOR_BLACK);

  UPixelScalar leg_info_width = 0;
  if (show_leg_info) {
    // Draw leg distance
    FormatUserDistanceSmart(leg.distance, buffer, true);
    UPixelScalar width = leg_info_width = canvas.CalcTextWidth(buffer);
    canvas.DrawText(rc.right - Layout::FastScale(2) - width,
                    rc.top + Layout::FastScale(2) +
                    (name_font.GetHeight() - small_font.GetHeight()) / 2,
                    buffer);

    // Draw leg bearing
    FormatBearing(buffer, ARRAY_SIZE(buffer), leg.bearing);
    width = canvas.CalcTextWidth(buffer);
    canvas.DrawText(rc.right - Layout::FastScale(2) - width, top2, buffer);

    if (width > leg_info_width)
      leg_info_width = width;

    leg_info_width += Layout::FastScale(2);
  }

  // Draw details line
  PixelScalar left = rc.left + line_height + Layout::FastScale(2);
  OrderedTaskPointRadiusLabel(tp.GetObservationZone(), buffer);
  if (!StringIsEmpty(buffer))
    canvas.DrawClippedText(left, top2, rc.right - leg_info_width - left,
                           buffer);

  // Draw turnpoint name
  canvas.Select(name_font);
  OrderedTaskPointLabel(tp.GetType(), tp.GetWaypoint().name.c_str(),
                        DrawListIndex, buffer);
  canvas.DrawClippedText(left, rc.top + Layout::FastScale(2),
                         rc.right - leg_info_width - left, buffer);
}
Beispiel #13
0
void
TaskEditPanel::OnPaintItem(Canvas &canvas, const PixelRect rc,
                           unsigned DrawListIndex)
{
  assert(DrawListIndex <= ordered_task->TaskSize());

  const unsigned padding = Layout::GetTextPadding();
  const unsigned line_height = rc.bottom - rc.top;

  TCHAR buffer[120];

  // Draw "Add turnpoint" label
  if (DrawListIndex == ordered_task->TaskSize()) {
    row_renderer.DrawFirstRow(canvas, rc, _("Add Turnpoint"));
    return;
  }

  const OrderedTaskPoint &tp = ordered_task->GetTaskPoint(DrawListIndex);
  GeoVector leg = tp.GetNominalLegVector();
  bool show_leg_info = leg.distance > fixed(0.01);

  PixelRect text_rc = rc;
  text_rc.left += line_height + padding;

  if (show_leg_info) {
    // Use small font for details
    canvas.Select(row_renderer.GetSecondFont());

    // Draw leg distance
    FormatUserDistanceSmart(leg.distance, buffer, true);
    unsigned width = canvas.CalcTextWidth(buffer);
    const int x1 = rc.right - padding - width;
    canvas.DrawText(x1, rc.top + row_renderer.GetFirstY(), buffer);

    // Draw leg bearing
    FormatBearing(buffer, ARRAY_SIZE(buffer), leg.bearing);
    width = canvas.CalcTextWidth(buffer);
    const int x2 = rc.right - padding - width;
    canvas.DrawText(x2, rc.top + row_renderer.GetSecondY(), buffer);

    text_rc.right = std::min(x1, x2) - padding;
  }

  // Draw details line
  OrderedTaskPointRadiusLabel(tp.GetObservationZone(), buffer);
  if (!StringIsEmpty(buffer))
    row_renderer.DrawSecondRow(canvas, text_rc, buffer);

  // Draw turnpoint name
  OrderedTaskPointLabel(tp.GetType(), tp.GetWaypoint().name.c_str(),
                        DrawListIndex, buffer);
  row_renderer.DrawFirstRow(canvas, text_rc, buffer);

  // Draw icon
  const RasterPoint pt(rc.left + line_height / 2,
                       rc.top + line_height / 2);

  const unsigned radius = line_height / 2 - padding;
  OZPreviewRenderer::Draw(canvas, tp.GetObservationZone(),
                          pt, radius, task_look,
                          CommonInterface::GetMapSettings().airspace,
                          airspace_look);
}
Beispiel #14
0
void
PaintTask(Canvas &canvas, const WindowProjection &projection,
          const OrderedTask &task,
          const GeoPoint &location,
          const MapSettings &settings_map,
          const TaskLook &task_look,
          const AirspaceLook &airspace_look,
          const RasterTerrain *terrain, const Airspaces *airspaces,
          bool fai_sectors,
          int highlight_index)
{
  BackgroundRenderer background;
  background.SetTerrain(terrain);
  background.Draw(canvas, projection, settings_map.terrain);

  if (airspaces != NULL) {
    AirspaceRenderer airspace_renderer(airspace_look);
    airspace_renderer.SetAirspaces(airspaces);

#ifndef ENABLE_OPENGL
    BufferCanvas stencil_canvas;
    stencil_canvas.Create(canvas);
#endif

    airspace_renderer.Draw(canvas,
#ifndef ENABLE_OPENGL
                           stencil_canvas,
#endif
                           projection, settings_map.airspace);
  }

#ifdef ENABLE_OPENGL
  /* desaturate the map background, to focus on the task */
  canvas.FadeToWhite(0xc0);
#endif

  if (fai_sectors && IsFAITriangleApplicable(task)) {
    static constexpr Color fill_color = COLOR_YELLOW;
#if defined(ENABLE_OPENGL) || defined(USE_MEMORY_CANVAS)
#ifdef ENABLE_OPENGL
    const ScopeAlphaBlend alpha_blend;
#endif

    canvas.Select(Brush(fill_color.WithAlpha(40)));
    canvas.Select(Pen(1, COLOR_BLACK.WithAlpha(80)));
    RenderFAISectors(canvas, projection, task);
#else
    BufferCanvas buffer_canvas;
    buffer_canvas.Create(canvas);
    buffer_canvas.ClearWhite();
#ifdef HAVE_HATCHED_BRUSH
    buffer_canvas.Select(airspace_look.brushes[3]);
    buffer_canvas.SetTextColor(fill_color);
    buffer_canvas.SetBackgroundColor(COLOR_WHITE);
#else
    buffer_canvas.Select(Brush(fill_color));
#endif
    buffer_canvas.SelectNullPen();
    RenderFAISectors(buffer_canvas, projection, task);
    canvas.CopyAnd(buffer_canvas);

    canvas.SelectHollowBrush();
    canvas.SelectBlackPen();
    RenderFAISectors(canvas, projection, task);
#endif
  }

  OZRenderer ozv(task_look, airspace_look, settings_map.airspace);
  TaskPointRenderer tpv(canvas, projection, task_look,
                        task.GetTaskProjection(),
                        ozv, false, TaskPointRenderer::NONE,
                        location);
  TaskRenderer dv(tpv, projection.GetScreenBounds());
  dv.Draw(task);

  // highlight a task point
  if (highlight_index >= 0 && highlight_index < (int) task.TaskSize()) {
    /* TODO: clumsy way of highlighting. maybe it should be done by
     *       painting the task point with a different pen and brush,
     *       e.g. red, 4px wide
     */
    auto pt = projection.GeoToScreen(task.GetPoint(highlight_index).
                                     GetLocation());
    canvas.Select(task_look.highlight_pen);
    canvas.DrawLine(pt.x - 7, pt.y - 7, pt.x + 7, pt.y + 7);
    canvas.DrawLine(pt.x + 7, pt.y - 7, pt.x - 7, pt.y + 7);
  }
}