void CoverSearchStatisticsDialog::Show(
    const CoverSearchStatistics& statistics) {
  QStringList providers(statistics.total_images_by_provider_.keys());
  qSort(providers);

  ui_->summary->setText(
      tr("Got %1 covers out of %2 (%3 failed)")
          .arg(statistics.chosen_images_)
          .arg(statistics.chosen_images_ + statistics.missing_images_)
          .arg(statistics.missing_images_));

  for (const QString& provider : providers) {
    AddLine(tr("Covers from %1").arg(provider),
            QString::number(statistics.chosen_images_by_provider_[provider]));
  }

  if (!providers.isEmpty()) {
    AddSpacer();
  }

  AddLine(tr("Total network requests made"),
          QString::number(statistics.network_requests_made_));
  AddLine(tr("Average image size"), statistics.AverageDimensions());
  AddLine(tr("Total bytes transferred"),
          statistics.bytes_transferred_
              ? Utilities::PrettySize(statistics.bytes_transferred_)
              : "0 bytes");

  details_layout_->addStretch();

  show();
}
Esempio n. 2
0
    SuggestionWidget(wxWindow *parent) : wxPanel(parent, wxID_ANY)
    {
        m_appIsRTL = (wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft);

        m_icon = new wxStaticBitmap(this, wxID_ANY, wxNullBitmap);
        m_text = new AutoWrappingText(this, "TEXT");
        m_info = new InfoStaticText(this);

        auto top = new wxBoxSizer(wxHORIZONTAL);
        auto right = new wxBoxSizer(wxVERTICAL);
        top->AddSpacer(2);
        top->Add(m_icon, wxSizerFlags().Top().Border(wxTOP|wxBOTTOM));
        top->Add(right, wxSizerFlags(1).Expand().Border(wxLEFT));
        right->Add(m_text, wxSizerFlags().Expand().Border(wxTOP, 4));
        right->Add(m_info, wxSizerFlags().Expand().Border(wxTOP|wxBOTTOM, 2));
        SetSizerAndFit(top);

        // setup mouse hover highlighting:
        m_bg = parent->GetBackgroundColour();
        m_bgHighlight = m_bg.ChangeLightness(160);

        wxWindow* parts [] = { this, m_icon, m_text, m_info };
        for (auto w : parts)
        {
            w->Bind(wxEVT_MOTION,       &SuggestionWidget::OnMouseMove, this);
            w->Bind(wxEVT_LEAVE_WINDOW, &SuggestionWidget::OnMouseMove, this);
            w->Bind(wxEVT_LEFT_UP,      &SuggestionWidget::OnMouseClick, this);
        }
    }
Esempio n. 3
0
void
FlarmTrafficDetailsWidget::Prepare(ContainerWindow &parent,
                                   const PixelRect &rc)
{
  AddReadOnly(_("Callsign"));
  AddButton(_("Change callsign"), *this, CHANGE_CALLSIGN);
  AddSpacer();
  AddReadOnly(_("Distance"));
  AddReadOnly(_("Altitude"));
  AddReadOnly(_("Vario"));
  AddSpacer();
  AddReadOnly(_("Pilot"));
  AddReadOnly(_("Airport"));
  AddReadOnly(_("Radio frequency"));
  AddReadOnly(_("Plane"));

  Update();
}
Esempio n. 4
0
void nwxShiftSizer::_SetupLayout(bool bShow)
{
  Clear();
  if(bShow)
  {
    Add(m_pButtonLeft,0,wxALIGN_CENTER);
    if(m_nBorder)
    {
      AddSpacer(m_nBorder);
    }
    Add(m_pPeerWindow,1,wxEXPAND);
    if(m_nBorder)
    {
      AddSpacer(m_nBorder);
    }
    Add(m_pButtonRight,0,wxALIGN_CENTER);
  }
}
Esempio n. 5
0
void
TrackingConfigPanel::Prepare(ContainerWindow &parent, const PixelRect &rc)
{
  const TrackingSettings &settings =
    CommonInterface::GetComputerSettings().tracking;

  RowFormWidget::Prepare(parent, rc);

#ifdef HAVE_SKYLINES_TRACKING
  AddBoolean(_T("SkyLines"), NULL, settings.skylines.enabled, this);
  AddTime(_("Tracking Interval"), NULL, 5, 1200, 5,
          settings.skylines.interval);

#ifdef HAVE_SKYLINES_TRACKING_HANDLER
  AddBoolean(_("Track friends"),
             _("Download the position of your friends live from the SkyLines server."),
             settings.skylines.traffic_enabled, this);
#endif

  StaticString<64> buffer;
  if (settings.skylines.key != 0)
    buffer.UnsafeFormat(_T("%llX"), (unsigned long long)settings.skylines.key);
  else
    buffer.clear();
  AddText(_T("Key"), NULL, buffer);
#endif

#if defined(HAVE_SKYLINES_TRACKING) && defined(HAVE_LIVETRACK24)
  AddSpacer();
#endif

#ifdef HAVE_LIVETRACK24
  AddBoolean(_T("LiveTrack24"),  _T(""), settings.livetrack24.enabled, this);

  AddTime(_("Tracking Interval"), _T(""), 5, 3600, 5, settings.interval);

  AddEnum(_("Vehicle Type"), _("Type of vehicle used."), vehicle_type_list,
          (unsigned) settings.vehicleType);

  WndProperty *edit = AddEnum(_("Server"), _T(""), server_list, 0);
  ((DataFieldEnum *)edit->GetDataField())->Set(settings.livetrack24.server);
  edit->RefreshDisplay();

  AddText(_("Username"), _T(""), settings.livetrack24.username);
  AddPassword(_("Password"), _T(""), settings.livetrack24.password);
#endif

#ifdef HAVE_SKYLINES_TRACKING
  SetSkyLinesEnabled(settings.skylines.enabled);
#endif

#ifdef HAVE_LIVETRACK24
  SetEnabled(settings.livetrack24.enabled);
#endif
}
Esempio n. 6
0
wxFlatButtonBar::wxFlatButtonBar(wxWindow* parent, const wxFlatButton::eTheme theme, int flags)
    : wxFlatButtonBarBase(parent)
    , m_theme(theme)
    , m_style(flags)
{
    SetBackgroundStyle(wxBG_STYLE_PAINT);

    // Colours - dark theme
    SetBgColour(wxFlatButton::GetBarBgColour(theme));
    SetPenColour(wxFlatButton::GetBarBgColour(theme));
    AddSpacer(2);
}
Esempio n. 7
0
// -----------------------------------------------------------------------------
// Opens the appropriate properties dialog for objects in [list].
// Returns true if the property edit was applied
// -----------------------------------------------------------------------------
bool MapEditor::editObjectProperties(vector<MapObject*>& list)
{
	wxString selsize = "";
	wxString type    = edit_context->modeString(false);
	if (list.size() == 1)
		type += wxString::Format(" #%d", list[0]->index());
	else if (list.size() > 1)
		selsize = wxString::Format("(%lu selected)", list.size());

	// Create dialog for properties panel
	SDialog dlg(
		MapEditor::window(),
		wxString::Format("%s Properties %s", type, selsize),
		wxString::Format("mobjprops_%s", edit_context->modeString(false)),
		-1,
		-1);
	auto sizer = new wxBoxSizer(wxVERTICAL);
	dlg.SetSizer(sizer);

	// Create/add properties panel
	PropsPanelBase* panel_props = nullptr;
	switch (edit_context->editMode())
	{
	case Mode::Lines: panel_props = new LinePropsPanel(&dlg); break;
	case Mode::Sectors: panel_props = new SectorPropsPanel(&dlg); break;
	case Mode::Things: panel_props = new ThingPropsPanel(&dlg); break;
	default: panel_props = new MapObjectPropsPanel(&dlg, true);
	}
	sizer->Add(panel_props, 1, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, UI::padLarge());

	// Add dialog buttons
	sizer->AddSpacer(UI::pad());
	sizer->Add(dlg.CreateButtonSizer(wxOK | wxCANCEL), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, UI::padLarge());

	// Open current selection
	panel_props->openObjects(list);

	// Open the dialog and apply changes if OK was clicked
	dlg.SetMinClientSize(sizer->GetMinSize());
	dlg.CenterOnParent();
	if (dlg.ShowModal() == wxID_OK)
	{
		panel_props->applyChanges();
		return true;
	}

	return false;
}
/*****
Constructor
*****/
tmwxConditionPathAngleQuantPanel::tmwxConditionPathAngleQuantPanel(
  wxWindow* parent) : 
  tmwxInspectorPanel(parent), mConditionPathAngleQuant(0)
{
  AddTextPair(wxT("Condition Index = "), mIndex);
  AddTextPair(wxT("From Node = "), mNode1);
  AddTextPair(wxT("To Node = "), mNode2);
  AddTextPair(wxT("Quantization = "), mQuant);
  AddTextPair(wxT("Offset = "), mQuantOffset, wxT("%.2f"));
  AddApplyButton();
  AddSpacer(5);
  AddStaticText(mIsFeasible);
#if tmwxINSPECTOR_EXTRA
  InitExtra();
  AddStatTextGridExtra(mPath);
  AddStatTextGridExtra(mCurAngle);
#endif
  SetSizerAndFit(mPanelSizer);
}
void
AudioVarioConfigPanel::Prepare(ContainerWindow &parent, const PixelRect &rc)
{
  RowFormWidget::Prepare(parent, rc);

  if (!AudioVarioGlue::HaveAudioVario())
    return;

  const auto &settings = CommonInterface::GetUISettings().sound.vario;

  AddBoolean(_("Audio vario"),
             _("Emulate the sound of an electronic vario."),
             settings.enabled);

  AddInteger(_("Volume"), NULL, _T("%u %%"), _T("%u"),
             0, 100, 1, settings.volume);

  AddBoolean(_("Enable Deadband"),
             _("Mute the audio output in when the current lift is in a certain "
               "range around zero"), settings.dead_band_enabled);

  AddSpacer();
  SetExpertRow(SPACER);

  AddInteger(_("Min. Frequency"),
             _("The tone frequency that is played at maximum sink rate."),
             _T("%u Hz"), _T("%u"),
             50, 3000, 50, settings.min_frequency);
  SetExpertRow(MIN_FREQUENCY);

  AddInteger(_("Zero Frequency"),
             _("The tone frequency that is played at zero climb rate."),
             _T("%u Hz"), _T("%u"),
             50, 3000, 50, settings.zero_frequency);
  SetExpertRow(ZERO_FREQUENCY);

  AddInteger(_("Max. Frequency"),
             _("The tone frequency that is played at maximum climb rate."),
             _T("%u Hz"), _T("%u"),
             50, 3000, 50, settings.max_frequency);
  SetExpertRow(MAX_FREQUENCY);

}
Esempio n. 10
0
void EditToolBar::AddSeparator()
{
   AddSpacer();
}
Esempio n. 11
0
void
UnitsConfigPanel::Prepare(ContainerWindow &parent, const PixelRect &rc)
{
  const UnitSetting &config = CommonInterface::GetUISettings().format.units;
  const CoordinateFormat coordinate_format =
      CommonInterface::GetUISettings().format.coordinate_format;

  RowFormWidget::Prepare(parent, rc);

  WndProperty *wp = AddEnum(_("Preset"), _("Load a set of units."));
  DataFieldEnum &df = *(DataFieldEnum *)wp->GetDataField();

  df.addEnumText(_("Custom"), (unsigned)0, _("My individual set of units."));
  unsigned len = Units::Store::Count();
  for (unsigned i = 0; i < len; i++)
    df.addEnumText(Units::Store::GetName(i), i+1);

  LoadValueEnum(UnitsPreset, Units::Store::EqualsPresetUnits(config));
  wp->GetDataField()->SetListener(this);

  AddSpacer();
  SetExpertRow(spacer_1);

  static constexpr StaticEnumChoice units_speed_list[] = {
    { (unsigned)Unit::STATUTE_MILES_PER_HOUR, _T("mph") },
    { (unsigned)Unit::KNOTS, N_("knots") },
    { (unsigned)Unit::KILOMETER_PER_HOUR, _T("km/h") },
    { 0 }
  };
  AddEnum(_("Aircraft/Wind speed"),
          _("Units used for airspeed and ground speed.  "
            "A separate unit is available for task speeds."),
          units_speed_list,
          (unsigned int)config.speed_unit, this);
  SetExpertRow(UnitsSpeed);

  static constexpr StaticEnumChoice units_distance_list[] = {
    { (unsigned)Unit::STATUTE_MILES, _T("sm") },
    { (unsigned)Unit::NAUTICAL_MILES, _T("nm") },
    { (unsigned)Unit::KILOMETER, _T("km") },
    { 0 }
  };
  AddEnum(_("Distance"),
          _("Units used for horizontal distances e.g. "
            "range to waypoint, distance to go."),
          units_distance_list,
          (unsigned)config.distance_unit, this);
  SetExpertRow(UnitsDistance);

  static constexpr StaticEnumChoice units_lift_list[] = {
    { (unsigned)Unit::KNOTS, N_("knots") },
    { (unsigned)Unit::METER_PER_SECOND, _T("m/s") },
    { (unsigned)Unit::FEET_PER_MINUTE, _T("ft/min") },
    { 0 }
  };
  AddEnum(_("Lift"), _("Units used for vertical speeds (variometer)."),
          units_lift_list,
          (unsigned)config.vertical_speed_unit, this);
  SetExpertRow(UnitsLift);

  static constexpr StaticEnumChoice units_altitude_list[] = {
    { (unsigned)Unit::FEET,  N_("foot") },
    { (unsigned)Unit::METER, N_("meter") },
    { 0 }
  };
  AddEnum(_("Altitude"), _("Units used for altitude and heights."),
          units_altitude_list,
          (unsigned)config.altitude_unit, this);
  SetExpertRow(UnitsAltitude);

  static constexpr StaticEnumChoice units_temperature_list[] = {
    { (unsigned)Unit::DEGREES_CELCIUS, _T(DEG "C") },
    { (unsigned)Unit::DEGREES_FAHRENHEIT, _T(DEG "F") },
    { 0 }
  };
  AddEnum(_("Temperature"), _("Units used for temperature."),
          units_temperature_list,
          (unsigned)config.temperature_unit, this);
  SetExpertRow(UnitsTemperature);

  static constexpr StaticEnumChoice units_taskspeed_list[] = {
    { (unsigned)Unit::STATUTE_MILES_PER_HOUR, _T("mph") },
    { (unsigned)Unit::KNOTS, N_("knots") },
    { (unsigned)Unit::KILOMETER_PER_HOUR, _T("km/h") },
    { 0 }
  };
  AddEnum(_("Task speed"), _("Units used for task speeds."),
          units_taskspeed_list,
          (unsigned)config.task_speed_unit, this);
  SetExpertRow(UnitsTaskSpeed);

  static constexpr StaticEnumChoice pressure_labels_list[] = {
    { (unsigned)Unit::HECTOPASCAL, _T("hPa") },
    { (unsigned)Unit::MILLIBAR, _T("mb") },
    { (unsigned)Unit::INCH_MERCURY, _T("inHg") },
    { 0 }
  };
  AddEnum(_("Pressure"), _("Units used for pressures."),
          pressure_labels_list,
          (unsigned)config.pressure_unit, this);
  SetExpertRow(UnitsPressure);

  AddSpacer();
  SetExpertRow(spacer_2);

  static constexpr StaticEnumChoice units_lat_lon_list[] = {
    { (unsigned)CoordinateFormat::DDMMSS, _T("DDMMSS") },
    { (unsigned)CoordinateFormat::DDMMSS_S, _T("DDMMSS.s") },
    { (unsigned)CoordinateFormat::DDMM_MMM, _T("DDMM.mmm") },
    { (unsigned)CoordinateFormat::DD_DDDDD, _T("DD.ddddd") },
    { (unsigned)CoordinateFormat::UTM, _T("UTM") },
    { 0 }
  };
  AddEnum(_("Lat./Lon."), _("Units used for latitude and longitude."),
          units_lat_lon_list,
          (unsigned)coordinate_format);
  SetExpertRow(UnitsLatLon);
}
Esempio n. 12
0
void
AudioVarioConfigPanel::Prepare(ContainerWindow &parent, const PixelRect &rc)
{
  RowFormWidget::Prepare(parent, rc);

  if (!AudioVarioGlue::HaveAudioVario())
    return;

  const auto &settings = CommonInterface::GetUISettings().sound.vario;

  AddBoolean(_("Audio vario"),
             _("Emulate the sound of an electronic vario."),
             settings.enabled);

  AddInteger(_("Volume"), nullptr, _T("%u %%"), _T("%u"),
             0, 100, 1, settings.volume);

  AddBoolean(_("Enable Deadband"),
             _("Mute the audio output in when the current lift is in a certain "
               "range around zero"), settings.dead_band_enabled);

  AddSpacer();
  SetExpertRow(SPACER);

  AddInteger(_("Min. Frequency"),
             _("The tone frequency that is played at maximum sink rate."),
             _T("%u Hz"), _T("%u"),
             50, 3000, 50, settings.min_frequency);
  SetExpertRow(MIN_FREQUENCY);

  AddInteger(_("Zero Frequency"),
             _("The tone frequency that is played at zero climb rate."),
             _T("%u Hz"), _T("%u"),
             50, 3000, 50, settings.zero_frequency);
  SetExpertRow(ZERO_FREQUENCY);

  AddInteger(_("Max. Frequency"),
             _("The tone frequency that is played at maximum climb rate."),
             _T("%u Hz"), _T("%u"),
             50, 3000, 50, settings.max_frequency);
  SetExpertRow(MAX_FREQUENCY);

  AddSpacer();
  SetExpertRow(SPACER2);

  AddFloat(_("Deadband min. lift"),
           _("Below this lift threshold the vario will start to play sounds if the 'Deadband' feature is enabled."),
           _T("%.1f %s"), _T("%.1f"),
           Units::ToUserVSpeed(-5), 0,
           GetUserVerticalSpeedStep(), false, UnitGroup::VERTICAL_SPEED,
           settings.min_dead);
  SetExpertRow(DEAD_BAND_MIN);
  DataFieldFloat &db_min = (DataFieldFloat &)GetDataField(DEAD_BAND_MIN);
  db_min.SetFormat(GetUserVerticalSpeedFormat(false, true));

  AddFloat(_("Deadband max. lift"),
           _("Above this lift threshold the vario will start to play sounds if the 'Deadband' feature is enabled."),
           _T("%.1f %s"), _T("%.1f"),
           0, Units::ToUserVSpeed(2),
           GetUserVerticalSpeedStep(), false, UnitGroup::VERTICAL_SPEED,
           settings.max_dead);
  SetExpertRow(DEAD_BAND_MAX);
  DataFieldFloat &db_max = (DataFieldFloat &)GetDataField(DEAD_BAND_MAX);
  db_max.SetFormat(GetUserVerticalSpeedFormat(false, true));
}
Esempio n. 13
0
void
TaskRulesConfigPanel::Prepare(ContainerWindow &parent, const PixelRect &rc)
{
  const ComputerSettings &settings_computer = XCSoarInterface::GetComputerSettings();
  const TaskBehaviour &task_behaviour = settings_computer.task;

  RowFormWidget::Prepare(parent, rc);

  AddFloat(_("Start max. speed"), _("Maximum speed allowed in start observation zone.  Set to 0 for no limit."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(300), fixed(5), false, UnitGroup::HORIZONTAL_SPEED,
           task_behaviour.ordered_defaults.start_max_speed);
  SetExpertRow(StartMaxSpeed);

  AddFloat(_("Start max. speed margin"),
           _("Maximum speed above maximum start speed to tolerate.  Set to 0 for no tolerance."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(300), fixed(5), false, UnitGroup::HORIZONTAL_SPEED,
           task_behaviour.start_max_speed_margin);
  SetExpertRow(StartMaxSpeedMargin);

  AddSpacer();
  SetExpertRow(spacer_1);

  AddFloat(_("Start max. height"),
           _("Maximum height based on start height reference (AGL or MSL) while starting the task.  "
               "Set to 0 for no limit."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(10000), fixed(50), false, UnitGroup::ALTITUDE,
           fixed(task_behaviour.ordered_defaults.start_max_height));
  SetExpertRow(StartMaxHeight);

  AddFloat(_("Start max. height margin"),
           _("Maximum height above maximum start height to tolerate.  Set to 0 for no tolerance."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(10000), fixed(50), false, UnitGroup::ALTITUDE,
           fixed(task_behaviour.start_max_height_margin));
  SetExpertRow(StartMaxHeightMargin);

  static constexpr StaticEnumChoice start_max_height_ref_list[] = {
    { (unsigned)HeightReferenceType::AGL, N_("AGL"), N_("Reference AGL for start maximum height rule (above start point).") },
    { (unsigned)HeightReferenceType::MSL, N_("MSL"), N_("Reference MSL for start maximum height rule (above sea level).") },
    { 0 }
  };
  AddEnum(_("Start height ref."), NULL, start_max_height_ref_list,
          (unsigned)task_behaviour.ordered_defaults.start_max_height_ref);
  SetExpertRow(StartHeightRef);

  AddSpacer();
  SetExpertRow(spacer_2);

  AddFloat(_("Finish min. height"),
           _("Minimum height based on finish height reference (AGL or MSL) while finishing the task.  "
               "Set to 0 for no limit."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(10000), fixed(50), false, UnitGroup::ALTITUDE,
           fixed(task_behaviour.ordered_defaults.finish_min_height));
  SetExpertRow(FinishMinHeight);

  static constexpr StaticEnumChoice finish_min_height_ref_list[] = {
    { (unsigned)HeightReferenceType::AGL, N_("AGL"), N_("Reference AGL for finish minimum height rule (above finish point).") },
    { (unsigned)HeightReferenceType::MSL, N_("MSL"), N_("Reference MSL for finish minimum height rule (above sea level).") },
    { 0 }
  };
  AddEnum(_("Finish height ref."), NULL, finish_min_height_ref_list,
          (unsigned)task_behaviour.ordered_defaults.finish_min_height_ref);
  SetExpertRow(FinishHeightRef);

  AddSpacer();
  SetExpertRow(spacer_3);

  const StaticEnumChoice contests_list[] = {
    { OLC_FAI, ContestToString(OLC_FAI),
      N_("Conforms to FAI triangle rules. Three turns and common start and finish. No leg less than 28% "
          "of total except for tasks longer than 500km: No leg less than 25% or larger than 45%.") },
    { OLC_Classic, ContestToString(OLC_Classic),
      N_("Up to seven points including start and finish, finish height must not be lower than "
          "start height less 1000 meters.") },
    { OLC_League, ContestToString(OLC_League),
      N_("The most recent contest with Sprint task rules.") },
    { OLC_Plus, ContestToString(OLC_Plus),
      N_("A combination of Classic and FAI rules. 30% of the FAI score are added to the Classic score.") },
    { OLC_XContest, ContestToString(OLC_XContest), _T("tbd.") },
    { OLC_DHVXC, ContestToString(OLC_DHVXC), _T("tbd.") },
    { OLC_SISAT, ContestToString(OLC_SISAT), _T("tbd.") },
    { OLC_NetCoupe, ContestToString(OLC_NetCoupe), N_("The FFVV NetCoupe \"libre\" competiton.") },
    { 0 }
  };
  AddEnum(_("On-Line Contest"),
      _("Select the rules used for calculating optimal points for the On-Line Contest. "
          "The implementation  conforms to the official release 2010, Sept.23."),
          contests_list, task_behaviour.contest);

  AddBoolean(_("Predict Contest"),
             _("If enabled, then the next task point is included in the "
               "score calculation, assuming that you will reach it."),
             task_behaviour.predict_contest);
}
Esempio n. 14
0
void
TaskRulesConfigPanel::Prepare(ContainerWindow &parent, const PixelRect &rc)
{
  const ComputerSettings &settings_computer = CommonInterface::GetComputerSettings();
  const TaskBehaviour &task_behaviour = settings_computer.task;

  RowFormWidget::Prepare(parent, rc);

  AddFloat(_("Start max. speed"), _("Maximum speed allowed in start observation zone.  Set to 0 for no limit."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(300), fixed(5), false, UnitGroup::HORIZONTAL_SPEED,
           task_behaviour.ordered_defaults.start_constraints.max_speed);
  SetExpertRow(StartMaxSpeed);

  AddFloat(_("Start max. speed margin"),
           _("Maximum speed above maximum start speed to tolerate.  Set to 0 for no tolerance."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(300), fixed(5), false, UnitGroup::HORIZONTAL_SPEED,
           task_behaviour.start_margins.max_speed_margin);
  SetExpertRow(StartMaxSpeedMargin);

  AddSpacer();
  SetExpertRow(spacer_1);

  AddFloat(_("Start max. height"),
           _("Maximum height based on start height reference (AGL or MSL) while starting the task.  "
               "Set to 0 for no limit."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(10000), fixed(50), false, UnitGroup::ALTITUDE,
           fixed(task_behaviour.ordered_defaults.start_constraints.max_height));
  SetExpertRow(StartMaxHeight);

  AddFloat(_("Start max. height margin"),
           _("Maximum height above maximum start height to tolerate.  Set to 0 for no tolerance."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(10000), fixed(50), false, UnitGroup::ALTITUDE,
           fixed(task_behaviour.start_margins.max_height_margin));
  SetExpertRow(StartMaxHeightMargin);

  static constexpr StaticEnumChoice altitude_reference_list[] = {
    { (unsigned)AltitudeReference::AGL, N_("AGL"),
      N_("Reference is altitude above mean sea level."), },
    { (unsigned)AltitudeReference::MSL, N_("MSL"),
      N_("Reference is the height above the task point."), },
    { 0 }
  };

  AddEnum(_("Start height ref."),
          _("Reference used for start max height rule."),
          altitude_reference_list,
          (unsigned)task_behaviour.ordered_defaults.start_constraints.max_height_ref);
  SetExpertRow(StartHeightRef);

  AddSpacer();
  SetExpertRow(spacer_2);

  AddFloat(_("Finish min. height"),
           _("Minimum height based on finish height reference (AGL or MSL) while finishing the task.  "
               "Set to 0 for no limit."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(10000), fixed(50), false, UnitGroup::ALTITUDE,
           fixed(task_behaviour.ordered_defaults.finish_constraints.min_height));
  SetExpertRow(FinishMinHeight);

  AddEnum(_("Finish height ref."),
          _("Reference used for finish min height rule."),
          altitude_reference_list,
          (unsigned)task_behaviour.ordered_defaults.finish_constraints.min_height_ref);
  SetExpertRow(FinishHeightRef);
}
Esempio n. 15
0
void
RouteConfigPanel::Prepare(ContainerWindow &parent, const PixelRect &rc)
{
  const ComputerSettings &settings_computer = CommonInterface::GetComputerSettings();
  const RoutePlannerConfig &route_planner = settings_computer.task.route_planner;

  RowFormWidget::Prepare(parent, rc);

  static constexpr StaticEnumChoice route_mode_list[] = {
    { (unsigned)RoutePlannerConfig::Mode::NONE, N_("None"),
      N_("Neither airspace nor terrain is used for route planning.") },
    { (unsigned)RoutePlannerConfig::Mode::TERRAIN, N_("Terrain"),
      N_("Routes will avoid terrain.") },
    { (unsigned)RoutePlannerConfig::Mode::AIRSPACE, N_("Airspace"),
      N_("Routes will avoid airspace.") },
    { (unsigned)RoutePlannerConfig::Mode::BOTH, N_("Both"),
      N_("Routes will avoid airspace and terrain.") },
    { 0 }
  };

  AddEnum(_("Route mode"), NULL, route_mode_list,
          (unsigned)route_planner.mode, this);

  AddBoolean(_("Route climb"),
             _("When enabled and MC is positive, route planning allows climbs between the aircraft "
                 "location and destination."),
             route_planner.allow_climb);
  SetExpertRow(RoutePlannerAllowClimb);

  AddBoolean(_("Route ceiling"),
             _("When enabled, route planning climbs are limited to ceiling defined by greater of "
                 "current aircraft altitude plus 500 m and the thermal ceiling.  If disabled, "
                 "climbs are unlimited."),
             route_planner.use_ceiling);
  SetExpertRow(RoutePlannerUseCeiling);

  static constexpr StaticEnumChoice turning_reach_list[] = {
    { (unsigned)RoutePlannerConfig::ReachMode::OFF, N_("Off"),
      N_("Reach calculations disabled.") },
    { (unsigned)RoutePlannerConfig::ReachMode::STRAIGHT, N_("Straight"),
      N_("The reach is from straight line paths from the glider.") },
    { (unsigned)RoutePlannerConfig::ReachMode::TURNING, N_("Turning"),
      N_("The reach is calculated allowing turns around terrain obstacles.") },
    { 0 }
  };

  AddSpacer(); // Spacer

  AddEnum(_("Reach mode"),
          _("How calculations are performed of the reach of the glider with respect to terrain."),
          turning_reach_list, (unsigned)route_planner.reach_calc_mode,
          this);

  static constexpr StaticEnumChoice final_glide_terrain_list[] = {
    { (unsigned)FeaturesSettings::FinalGlideTerrain::OFF, N_("Off"),
      N_("Disables the reach display.") },
    { (unsigned)FeaturesSettings::FinalGlideTerrain::LINE, N_("Line"),
      N_("Draws a dashed line at the glide reach.") },
    { (unsigned)FeaturesSettings::FinalGlideTerrain::SHADE, N_("Shade"),
      N_("Shades terrain outside glide reach.") },
    { 0 }
  };

  AddEnum(_("Reach display"), NULL, final_glide_terrain_list,
          (unsigned)settings_computer.features.final_glide_terrain);

  static constexpr StaticEnumChoice reach_polar_list[] = {
    { (unsigned)RoutePlannerConfig::Polar::TASK, N_("Task"),
      N_("Uses task glide polar.") },
    { (unsigned)RoutePlannerConfig::Polar::SAFETY, N_("Safety MC"),
      N_("Uses safety MacCready value") },
    { 0 }
  };

  AddEnum(_("Reach polar"),
          _("This determines the glide performance used in reach, landable arrival, abort and alternate calculations."),
          reach_polar_list, (unsigned)route_planner.reach_polar_mode);
  SetExpertRow(ReachPolarMode);

  ShowRouteControls(route_planner.mode != RoutePlannerConfig::Mode::NONE);
  ShowReachControls(route_planner.reach_calc_mode != RoutePlannerConfig::ReachMode::OFF);
}
Esempio n. 16
0
void
TaskRulesConfigPanel::Prepare(ContainerWindow &parent, const PixelRect &rc)
{
  const ComputerSettings &settings_computer = CommonInterface::GetComputerSettings();
  const TaskBehaviour &task_behaviour = settings_computer.task;
  const ContestSettings &contest_settings = settings_computer.contest;

  RowFormWidget::Prepare(parent, rc);

  AddFloat(_("Start max. speed"), _("Maximum speed allowed in start observation zone.  Set to 0 for no limit."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(300), fixed(5), false, UnitGroup::HORIZONTAL_SPEED,
           task_behaviour.ordered_defaults.start_constraints.max_speed);
  SetExpertRow(StartMaxSpeed);

  AddFloat(_("Start max. speed margin"),
           _("Maximum speed above maximum start speed to tolerate.  Set to 0 for no tolerance."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(300), fixed(5), false, UnitGroup::HORIZONTAL_SPEED,
           task_behaviour.start_margins.max_speed_margin);
  SetExpertRow(StartMaxSpeedMargin);

  AddSpacer();
  SetExpertRow(spacer_1);

  AddFloat(_("Start max. height"),
           _("Maximum height based on start height reference (AGL or MSL) while starting the task.  "
               "Set to 0 for no limit."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(10000), fixed(50), false, UnitGroup::ALTITUDE,
           fixed(task_behaviour.ordered_defaults.start_constraints.max_height));
  SetExpertRow(StartMaxHeight);

  AddFloat(_("Start max. height margin"),
           _("Maximum height above maximum start height to tolerate.  Set to 0 for no tolerance."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(10000), fixed(50), false, UnitGroup::ALTITUDE,
           fixed(task_behaviour.start_margins.max_height_margin));
  SetExpertRow(StartMaxHeightMargin);

  static constexpr StaticEnumChoice altitude_reference_list[] = {
    { (unsigned)AltitudeReference::AGL, N_("AGL"),
      N_("Reference is altitude above mean sea level."), },
    { (unsigned)AltitudeReference::MSL, N_("MSL"),
      N_("Reference is the height above the task point."), },
    { 0 }
  };

  AddEnum(_("Start height ref."),
          _("Reference used for start max height rule."),
          altitude_reference_list,
          (unsigned)task_behaviour.ordered_defaults.start_constraints.max_height_ref);
  SetExpertRow(StartHeightRef);

  AddSpacer();
  SetExpertRow(spacer_2);

  AddFloat(_("Finish min. height"),
           _("Minimum height based on finish height reference (AGL or MSL) while finishing the task.  "
               "Set to 0 for no limit."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(10000), fixed(50), false, UnitGroup::ALTITUDE,
           fixed(task_behaviour.ordered_defaults.finish_constraints.min_height));
  SetExpertRow(FinishMinHeight);

  AddEnum(_("Finish height ref."),
          _("Reference used for finish min height rule."),
          altitude_reference_list,
          (unsigned)task_behaviour.ordered_defaults.finish_constraints.min_height_ref);
  SetExpertRow(FinishHeightRef);

  AddSpacer();
  SetExpertRow(spacer_3);

  const StaticEnumChoice contests_list[] = {
    { (unsigned)Contest::OLC_FAI, ContestToString(Contest::OLC_FAI),
      N_("Conforms to FAI triangle rules. Three turns and common start and finish. No leg less than 28% "
          "of total except for tasks longer than 500km: No leg less than 25% or larger than 45%.") },
    { (unsigned)Contest::OLC_CLASSIC, ContestToString(Contest::OLC_CLASSIC),
      N_("Up to seven points including start and finish, finish height must not be lower than "
          "start height less 1000 meters.") },
    { (unsigned)Contest::OLC_LEAGUE, ContestToString(Contest::OLC_LEAGUE),
      N_("The most recent contest with Sprint task rules.") },
    { (unsigned)Contest::OLC_PLUS, ContestToString(Contest::OLC_PLUS),
      N_("A combination of Classic and FAI rules. 30% of the FAI score are added to the Classic score.") },
    { (unsigned)Contest::DMST, ContestToString(Contest::DMST),
      /* German competition, no translation */
      _T("Deutsche Meisterschaft im Streckensegelflug.") },
    { (unsigned)Contest::XCONTEST, ContestToString(Contest::XCONTEST),
      _T("tbd.") },
    { (unsigned)Contest::DHV_XC, ContestToString(Contest::DHV_XC),
      _T("tbd.") },
    { (unsigned)Contest::SIS_AT, ContestToString(Contest::SIS_AT),
      _T("tbd.") },
    { (unsigned)Contest::NET_COUPE, ContestToString(Contest::NET_COUPE),
      N_("The FFVV NetCoupe \"libre\" competiton.") },
    { 0 }
  };
  AddEnum(_("On-Line Contest"),
      _("Select the rules used for calculating optimal points for the On-Line Contest. "
          "The implementation  conforms to the official release 2010, Sept.23."),
          contests_list, (unsigned)contest_settings.contest);

  AddBoolean(_("Predict Contest"),
             _("If enabled, then the next task point is included in the "
               "score calculation, assuming that you will reach it."),
             contest_settings.predict);
}
Esempio n. 17
0
void OptionsGroup::append_line(const Line& line) {
//!    if (line.sizer != nullptr || (line.widget != nullptr && line.full_width > 0)){
	if ( (line.sizer != nullptr || line.widget != nullptr) && line.full_width){
		if (line.sizer != nullptr) {
            sizer->Add(line.sizer, 0, wxEXPAND | wxALL, wxOSX ? 0 : 15);
            return;
        }
        if (line.widget != nullptr) {
            sizer->Add(line.widget(m_parent), 0, wxEXPAND | wxALL, wxOSX ? 0 : 15);
            return;
        }
    }

	auto option_set = line.get_options();
	for (auto opt : option_set) 
		m_options.emplace(opt.opt_id, opt);

	// if we have a single option with no label, no sidetext just add it directly to sizer
	if (option_set.size() == 1 && label_width == 0 && option_set.front().opt.full_width &&
		option_set.front().opt.sidetext.size() == 0 && option_set.front().side_widget == nullptr && 
		line.get_extra_widgets().size() == 0) {
		const auto& option = option_set.front();
		const auto& field = build_field(option);

		if (is_window_field(field))
			sizer->Add(field->getWindow(), 0, wxEXPAND | wxALL, wxOSX ? 0 : 5);
		if (is_sizer_field(field))
			sizer->Add(field->getSizer(), 0, wxEXPAND | wxALL, wxOSX ? 0 : 5);
		return;
	}

    auto grid_sizer = m_grid_sizer;

    // Build a label if we have it
    if (label_width != 0) {
		auto label = new wxStaticText(parent(), wxID_ANY, line.label + (line.label.IsEmpty() ? "" : ":"), 
							wxDefaultPosition, wxSize(label_width, -1));
        label->SetFont(label_font);
        label->Wrap(label_width); // avoid a Linux/GTK bug
		grid_sizer->Add(label, 0, wxALIGN_CENTER_VERTICAL,0);
		if (line.label_tooltip.compare("") != 0)
			label->SetToolTip(line.label_tooltip);
    }

    // If there's a widget, build it and add the result to the sizer.
	if (line.widget != nullptr) {
		auto wgt = line.widget(parent());
		grid_sizer->Add(wgt, 0, wxEXPAND | wxBOTTOM | wxTOP, wxOSX ? 0 : 5);
		return;
	}
	
	// if we have a single option with no sidetext just add it directly to the grid sizer
    if (option_set.size() == 1 && option_set.front().opt.sidetext.size() == 0 &&
        option_set.front().side_widget == nullptr && line.get_extra_widgets().size() == 0) {
        const auto& option = option_set.front();
        const auto& field = build_field(option);
//!         std::cerr << "single option, no sidetext.\n";
//!         std::cerr << "field parent is not null?: " << (field->parent != nullptr) << "\n";

        if (is_window_field(field)) 
			grid_sizer->Add(field->getWindow(), 0, (option.opt.full_width ? wxEXPAND : 0) |
							wxBOTTOM | wxTOP | wxALIGN_CENTER_VERTICAL, wxOSX ? 0 : 2);
        if (is_sizer_field(field)) 
            grid_sizer->Add(field->getSizer(), 0, (option.opt.full_width ? wxEXPAND : 0) | wxALIGN_CENTER_VERTICAL, 0);
        return;
    }

    // if we're here, we have more than one option or a single option with sidetext
    // so we need a horizontal sizer to arrange these things
    auto sizer = new wxBoxSizer(wxHORIZONTAL);
	grid_sizer->Add(sizer, 0, wxEXPAND | wxALL, 0);
	for (auto opt : option_set) {
		ConfigOptionDef option = opt.opt;
		// add label if any
		if (option.label != "") {
			wxString str_label = L_str(option.label);
//!			To correct translation by context have to use wxGETTEXT_IN_CONTEXT macro from wxWidget 3.1.1
// 			wxString str_label = (option.label == "Top" || option.label == "Bottom") ?
// 								wxGETTEXT_IN_CONTEXT("Layers", wxString(option.label.c_str()):
// 								L_str(option.label);
			auto field_label = new wxStaticText(parent(), wxID_ANY, str_label + ":", wxDefaultPosition, wxDefaultSize);
			field_label->SetFont(label_font);
			sizer->Add(field_label, 0, wxALIGN_CENTER_VERTICAL, 0);
		}

		// add field
		const Option& opt_ref = opt;
		auto& field = build_field(opt_ref);
		is_sizer_field(field) ? 
			sizer->Add(field->getSizer(), 0, wxALIGN_CENTER_VERTICAL, 0) :
			sizer->Add(field->getWindow(), 0, wxALIGN_CENTER_VERTICAL, 0);
		
		// add sidetext if any
		if (option.sidetext != "") {
			auto sidetext = new wxStaticText(parent(), wxID_ANY, L_str(option.sidetext), wxDefaultPosition, wxDefaultSize);
			sidetext->SetFont(sidetext_font);
			sizer->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4);
		}

		// add side widget if any
		if (opt.side_widget != nullptr) {
			sizer->Add(opt.side_widget(parent())/*!.target<wxWindow>()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 1);	//! requires verification
		}

		if (opt.opt_id != option_set.back().opt_id) //! istead of (opt != option_set.back())
		{
			sizer->AddSpacer(6);
	    }
	}
	// add extra sizers if any
	for (auto extra_widget : line.get_extra_widgets()) {
		sizer->Add(extra_widget(parent())/*!.target<wxWindow>()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4);		//! requires verification
	}
}
void
TaskDefaultsConfigPanel::Prepare(ContainerWindow &parent, const PixelRect &rc)
{
    WndProperty *wp;
    const ComputerSettings &settings_computer = XCSoarInterface::GetComputerSettings();
    const TaskBehaviour &task_behaviour = settings_computer.task;
    OrderedTask temptask(task_behaviour);
    temptask.SetFactory(TaskFactoryType::RACING);

    RowFormWidget::Prepare(parent, rc);

    wp = AddEnum(_("Start point"),
                 _("Default start type for new tasks you create."),
                 this);
    if (wp) {
        const auto point_types = temptask.GetFactory().GetValidStartTypes();
        DataFieldEnum* dfe = (DataFieldEnum*)wp->GetDataField();
        dfe->EnableItemHelp(true);

        for (auto i = point_types.begin(), end = point_types.end();
                i != end; ++i) {
            const AbstractTaskFactory::LegalPointType type = *i;
            dfe->addEnumText(OrderedTaskPointName(type), (unsigned)type,
                             OrderedTaskPointDescription(type));
            if (type == task_behaviour.sector_defaults.start_type)
                dfe->Set((unsigned)type);
        }
        wp->RefreshDisplay();
    }

    AddFloat(Caption_GateWidth, _("Default radius or gate width of the start zone for new tasks."),
             _T("%.1f %s"), _T("%.1f"), fixed(0.1), fixed(100), fixed(1.0), true, UnitGroup::DISTANCE,
             task_behaviour.sector_defaults.start_radius);

    AddSpacer();

    wp = AddEnum(_("Finish point"),
                 _("Default finish type for new tasks you create."),
                 this);
    if (wp) {
        const auto point_types = temptask.GetFactory().GetValidFinishTypes();
        DataFieldEnum* dfe = (DataFieldEnum*)wp->GetDataField();
        dfe->EnableItemHelp(true);

        for (auto i = point_types.begin(), end = point_types.end();
                i != end; ++i) {
            const AbstractTaskFactory::LegalPointType type = *i;
            dfe->addEnumText(OrderedTaskPointName(type), (unsigned)type,
                             OrderedTaskPointDescription(type));
            if (type == task_behaviour.sector_defaults.finish_type)
                dfe->Set((unsigned)type);
        }
        wp->RefreshDisplay();
    }

    AddFloat(Caption_GateWidth, _("Default radius or gate width of the finish zone in new tasks."),
             _T("%.1f %s"), _T("%.1f"), fixed(0.1), fixed(100), fixed(1.0), true, UnitGroup::DISTANCE,
             task_behaviour.sector_defaults.finish_radius);

    AddSpacer();

    wp = AddEnum(_("Turn point"), _("Default turn point type for new tasks you create."));
    if (wp) {
        const auto point_types = temptask.GetFactory().GetValidIntermediateTypes();
        DataFieldEnum* dfe = (DataFieldEnum*)wp->GetDataField();
        dfe->EnableItemHelp(true);

        for (auto i = point_types.begin(), end = point_types.end();
                i != end; ++i) {
            const AbstractTaskFactory::LegalPointType type = *i;
            dfe->addEnumText(OrderedTaskPointName(type), (unsigned)type,
                             OrderedTaskPointDescription(type));
            if (type == task_behaviour.sector_defaults.turnpoint_type) {
                dfe->Set((unsigned)type);
            }
        }
        wp->RefreshDisplay();
    }

    AddFloat(Caption_Radius, _("Default radius of turnpoint cylinders and sectors in new tasks."),
             _T("%.1f %s"), _T("%.1f"), fixed(0.1), fixed(100), fixed(1.0), true, UnitGroup::DISTANCE,
             task_behaviour.sector_defaults.turnpoint_radius);

    AddSpacer();

    wp = AddEnum(_("Task"), _("Default task type for new tasks you create."));
    if (wp) {
        const std::vector<TaskFactoryType> factory_types =
            temptask.GetFactoryTypes();
        DataFieldEnum* dfe = (DataFieldEnum*)wp->GetDataField();
        dfe->EnableItemHelp(true);

        for (unsigned i = 0; i < factory_types.size(); i++) {
            dfe->addEnumText(OrderedTaskFactoryName(factory_types[i]),
                             (unsigned)factory_types[i], OrderedTaskFactoryDescription(
                                 factory_types[i]));
            if (factory_types[i] == task_behaviour.task_type_default)
                dfe->Set((unsigned)factory_types[i]);
        }
        wp->RefreshDisplay();
    }

    AddTime(_("AAT min. time"), _("Default AAT min. time for new AAT tasks."),
            60, 10 * 60 * 60, 60, (unsigned)task_behaviour.ordered_defaults.aat_min_time);

    AddTime(_("Optimisation margin"),
            _("Safety margin for AAT task optimisation.  Optimisation "
              "seeks to complete the task at the minimum time plus this margin time."),
            0, 30 * 60, 60, (unsigned)task_behaviour.optimise_targets_margin);
    SetExpertRow(AATTimeMargin);

    SetStartLabel();
    SetFinishLabel();
}
Esempio n. 19
0
DialogProperties::DialogProperties(agi::Context *c)
: wxDialog(c->parent, -1, _("Script Properties"))
, c(c)
{
	SetIcon(GETICON(properties_toolbutton_16));

	// Script details crap
	wxSizer *TopSizer = new wxStaticBoxSizer(wxHORIZONTAL,this,_("Script"));
	auto TopSizerGrid = new wxFlexGridSizer(0,2,5,5);

	AddProperty(TopSizerGrid, _("Title:"), "Title");
	AddProperty(TopSizerGrid, _("Original script:"), "Original Script");
	AddProperty(TopSizerGrid, _("Translation:"), "Original Translation");
	AddProperty(TopSizerGrid, _("Editing:"), "Original Editing");
	AddProperty(TopSizerGrid, _("Timing:"), "Original Timing");
	AddProperty(TopSizerGrid, _("Synch point:"), "Synch Point");
	AddProperty(TopSizerGrid, _("Updated by:"), "Script Updated By");
	AddProperty(TopSizerGrid, _("Update details:"), "Update Details");

	TopSizerGrid->AddGrowableCol(1,1);
	TopSizer->Add(TopSizerGrid,1,wxALL | wxEXPAND,0);

	// Resolution box
	wxSizer *ResSizer = new wxStaticBoxSizer(wxHORIZONTAL,this,_("Resolution"));
	ResX = new wxTextCtrl(this,-1,"",wxDefaultPosition,wxSize(50,20),0,IntValidator(c->ass->GetScriptInfoAsInt("PlayResX")));
	ResY = new wxTextCtrl(this,-1,"",wxDefaultPosition,wxSize(50,20),0,IntValidator(c->ass->GetScriptInfoAsInt("PlayResY")));
	wxStaticText *ResText = new wxStaticText(this,-1,"x");

	wxButton *FromVideo = new wxButton(this,-1,_("From &video"));
	if (!c->videoController->IsLoaded())
		FromVideo->Enable(false);
	else
		FromVideo->Bind(wxEVT_BUTTON, &DialogProperties::OnSetFromVideo, this);

	ResSizer->Add(ResX,1,wxRIGHT | wxALIGN_CENTER_VERTICAL,5);
	ResSizer->Add(ResText,0,wxALIGN_CENTER | wxRIGHT,5);
	ResSizer->Add(ResY,1,wxRIGHT | wxALIGN_CENTER_VERTICAL,5);
	ResSizer->Add(FromVideo,1,0,0);

	// Options
	wxSizer *optionsBox = new wxStaticBoxSizer(wxHORIZONTAL,this,_("Options"));
	auto optionsGrid = new wxFlexGridSizer(3,2,5,5);
	wxString wrap_opts[] = {
		_("0: Smart wrapping, top line is wider"),
		_("1: End-of-line word wrapping, only \\N breaks"),
		_("2: No word wrapping, both \\n and \\N break"),
		_("3: Smart wrapping, bottom line is wider")
	};
	WrapStyle = new wxComboBox(this, -1, "", wxDefaultPosition, wxDefaultSize, 4, wrap_opts, wxCB_READONLY);
	WrapStyle->SetSelection(c->ass->GetScriptInfoAsInt("WrapStyle"));
	optionsGrid->Add(new wxStaticText(this,-1,_("Wrap Style: ")),0,wxALIGN_CENTER_VERTICAL,0);
	optionsGrid->Add(WrapStyle,1,wxEXPAND,0);

	ScaleBorder = new wxCheckBox(this,-1,_("Scale Border and Shadow"));
	ScaleBorder->SetToolTip(_("Scale border and shadow together with script/render resolution. If this is unchecked, relative border and shadow size will depend on renderer."));
	ScaleBorder->SetValue(boost::iequals(c->ass->GetScriptInfo("ScaledBorderAndShadow"), "yes"));
	optionsGrid->AddSpacer(0);
	optionsGrid->Add(ScaleBorder,1,wxEXPAND,0);
	optionsGrid->AddGrowableCol(1,1);
	optionsBox->Add(optionsGrid,1,wxEXPAND,0);

	// Button sizer
	wxStdDialogButtonSizer *ButtonSizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL | wxHELP);
	Bind(wxEVT_BUTTON, &DialogProperties::OnOK, this, wxID_OK);
	Bind(wxEVT_BUTTON, std::bind(&HelpButton::OpenPage, "Properties"), wxID_HELP);

	// MainSizer
	wxSizer *MainSizer = new wxBoxSizer(wxVERTICAL);
	MainSizer->Add(TopSizer,0,wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND,5);
	MainSizer->Add(ResSizer,0,wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND,5);
	MainSizer->Add(optionsBox,0,wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND,5);
	MainSizer->Add(ButtonSizer,0,wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND,5);

	SetSizerAndFit(MainSizer);
	CenterOnParent();
}