using System; using System.Collections; using System.Collections.Generic; using System.Drawing; using System.Globalization; using System.IO; using System.Linq; using System.Text; using System.Windows.Forms; using ArdupilotMega.Controls; using ArdupilotMega.Controls.BackstageView; using ArdupilotMega.Utilities; using log4net; namespace ArdupilotMega.GCSViews.ConfigurationView { public partial class ConfigFriendlyParams : UserControl, IActivate { #region Class Fields private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); private readonly ParameterMetaDataRepository _parameterMetaDataRepository; private Dictionary _params = new Dictionary(); #endregion #region Properties /// /// Gets or sets the parameter mode. /// /// /// The parameter mode. /// public string ParameterMode { get; set; } #endregion #region Constructor public ConfigFriendlyParams() { InitializeComponent(); tableLayoutPanel1.Height = this.Height; _parameterMetaDataRepository = new ParameterMetaDataRepository(); MainV2.comPort.ParamListChanged += comPort_ParamListChanged; Resize += this_Resize; BUT_rerequestparams.Click += BUT_rerequestparams_Click; BUT_writePIDS.Click += BUT_writePIDS_Click; } #endregion #region Events /// /// Handles the Click event of the BUT_writePIDS control. /// /// The source of the event. /// The instance containing the event data. protected void BUT_writePIDS_Click(object sender, EventArgs e) { bool errorThrown = false; _params.ForEach(x => { var matchingControls = tableLayoutPanel1.Controls.Find(x.Key, true); if (matchingControls.Length > 0) { var ctl = (IDynamicParameterControl)matchingControls[0]; try { MainV2.comPort.setParam(x.Key, float.Parse(ctl.Value)); } catch { errorThrown = true; CustomMessageBox.Show("Set " + x.Key + " Failed"); } } }); if (!errorThrown) { CustomMessageBox.Show("Parameters successfully saved."); } } /// /// Handles the Click event of the BUT_rerequestparams control. /// /// The source of the event. /// The instance containing the event data. protected void BUT_rerequestparams_Click(object sender, EventArgs e) { if (!MainV2.comPort.BaseStream.IsOpen) return; ((Control)sender).Enabled = false; try { MainV2.comPort.getParamList(); } catch (Exception ex) { log.Error("Exception getting param list", ex); CustomMessageBox.Show("Error: getting param list"); } ((Control)sender).Enabled = true; BindParamList(); } /// /// Handles the Resize event of the this control. /// /// The source of the event. /// The instance containing the event data. protected void this_Resize(object sender, EventArgs e) { tableLayoutPanel1.Height = this.Height - 50; } /// /// Handles the Load event of the ConfigRawParamsV2 control. /// /// The source of the event. /// The instance containing the event data. public void Activate() { BindParamList(); } /// /// Handles the ParamListChanged event of the comPort control. /// /// The source of the event. /// The instance containing the event data. protected void comPort_ParamListChanged(object sender, EventArgs e) { SortParamList(); } #endregion #region Methods /// /// Sorts the param list. /// private void SortParamList() { // Clear list _params.Clear(); // When the parameter list is changed, re sort the list for our View's purposes MainV2.comPort.param.Keys.ForEach(x => { string displayName = _parameterMetaDataRepository.GetParameterMetaData(x.ToString(), ParameterMetaDataConstants.DisplayName); string parameterMode = _parameterMetaDataRepository.GetParameterMetaData(x.ToString(), ParameterMetaDataConstants.User); // If we have a friendly display name AND if (!String.IsNullOrEmpty(displayName) && // The user type is equal to the ParameterMode specified at class instantiation OR ((!String.IsNullOrEmpty(parameterMode) && parameterMode == ParameterMode) || // The user type is empty and this is in Advanced mode String.IsNullOrEmpty(parameterMode) && ParameterMode == ParameterMetaDataConstants.Advanced)) { _params.Add(x.ToString(), displayName); } }); _params = _params.OrderBy(x => x.Value).ToDictionary(x => x.Key, x => x.Value); } /// /// Binds the param list. /// private void BindParamList() { tableLayoutPanel1.Controls.Clear(); if (_params == null || _params.Count == 0) SortParamList(); // get the params if nothing exists already if (_params != null && _params.Count == 0) { try { Utilities.ParameterMetaDataParser.GetParameterInformation(); _parameterMetaDataRepository.Reload(); SortParamList(); } catch (Exception exp) { log.Error(exp); } // just to cleanup any errors } this.SuspendLayout(); _params.OrderBy(x => x.Key).ForEach(x => { if(!String.IsNullOrEmpty(x.Key)) { try { bool controlAdded = false; string value = ((float)MainV2.comPort.param[x.Key]).ToString("0.###", CultureInfo.InvariantCulture); string description = _parameterMetaDataRepository.GetParameterMetaData(x.Key, ParameterMetaDataConstants.Description); string displayName = x.Value + " (" + x.Key + ")"; string units = _parameterMetaDataRepository.GetParameterMetaData(x.Key, ParameterMetaDataConstants.Units); // If this is a range string rangeRaw = _parameterMetaDataRepository.GetParameterMetaData(x.Key, ParameterMetaDataConstants.Range); string incrementRaw = _parameterMetaDataRepository.GetParameterMetaData(x.Key, ParameterMetaDataConstants.Increment); // modify for scaling float test = 1; MAVLink.modifyParamForDisplay(true, x.Key, ref test); if (test != 1) { if (units.ToLower() == "centi-degrees") { units = "Degrees"; incrementRaw = "0.1"; string[] rangeParts = rangeRaw.Split(new[] { ' ' }); if (rangeParts.Count() == 2) { float lowerRange; float.TryParse(rangeParts[0], out lowerRange); float upperRange; float.TryParse(rangeParts[1], out upperRange); rangeRaw = (lowerRange / 100) + " " + (upperRange / 100); } } else if (units.ToLower() == "centimeters") { units = "Meters"; incrementRaw = "0.1"; string[] rangeParts = rangeRaw.Split(new[] { ' ' }); if (rangeParts.Count() == 2) { float lowerRange; float.TryParse(rangeParts[0], out lowerRange); float upperRange; float.TryParse(rangeParts[1], out upperRange); rangeRaw = (lowerRange / 100) + " " + (upperRange / 100); } } else { units += " / " + (int)(1 / test); } } if (!String.IsNullOrEmpty(rangeRaw) && !String.IsNullOrEmpty(incrementRaw)) { float increment, intValue; float.TryParse(incrementRaw, out increment); float.TryParse(value, out intValue); string[] rangeParts = rangeRaw.Split(new[] { ' ' }); if (rangeParts.Count() == 2 && increment > 0) { float lowerRange; float.TryParse(rangeParts[0], out lowerRange); float upperRange; float.TryParse(rangeParts[1], out upperRange); int scaler = (int)float.Parse((1 / increment).ToString(CultureInfo.InvariantCulture)); int scaledLowerRange = 0, scaledUpperRange = 0; int scaledIncrement = (int)increment; if (scaler > 0) { scaledLowerRange = (int)(lowerRange * scaler); scaledUpperRange = (int)(upperRange * scaler); scaledIncrement = (int)float.Parse((increment * scaler).ToString(CultureInfo.InvariantCulture)); intValue *= scaler; } var rangeControl = new RangeControl(); rangeControl.Name = x.Key; rangeControl.Scaler = scaler; rangeControl.DescriptionText = FitDescriptionText(units, description); rangeControl.LabelText = displayName; rangeControl.TrackBarControl.Minimum = Math.Min(scaledLowerRange,(int)intValue); rangeControl.TrackBarControl.Maximum = Math.Max(scaledUpperRange, (int)intValue); rangeControl.TrackBarControl.TickFrequency = scaledIncrement; rangeControl.TrackBarControl.Value = (int)intValue; rangeControl.NumericUpDownControl.Increment = (decimal)increment; rangeControl.NumericUpDownControl.DecimalPlaces = scaler.ToString(CultureInfo.InvariantCulture).Length - 1; rangeControl.NumericUpDownControl.Minimum = (decimal)Math.Min(lowerRange, ((float)MainV2.comPort.param[x.Key])); rangeControl.NumericUpDownControl.Maximum = (decimal)Math.Max(upperRange, ((float)MainV2.comPort.param[x.Key])); rangeControl.NumericUpDownControl.Value = (decimal)((float)MainV2.comPort.param[x.Key]); rangeControl.AttachEvents(); tableLayoutPanel1.Controls.Add(rangeControl); controlAdded = true; } } if (!controlAdded) { // If this is a subset of values string availableValuesRaw = _parameterMetaDataRepository.GetParameterMetaData(x.Key, ParameterMetaDataConstants.Values); if (!String.IsNullOrEmpty(availableValuesRaw)) { string[] availableValues = availableValuesRaw.Split(new[] { ',' }); if (availableValues.Any()) { var valueControl = new ValuesControl(); valueControl.Name = x.Key; valueControl.DescriptionText = FitDescriptionText(units, description); valueControl.LabelText = displayName; var splitValues = new List>(); // Add the values to the ddl availableValues.ForEach(val => { string[] valParts = val.Split(new[] { ':' }); splitValues.Add(new KeyValuePair(valParts[0], (valParts.Length > 1) ? valParts[1] : valParts[0])); }); valueControl.ComboBoxControl.DisplayMember = "Value"; valueControl.ComboBoxControl.ValueMember = "Key"; valueControl.ComboBoxControl.DataSource = splitValues; valueControl.ComboBoxControl.SelectedValue = value; tableLayoutPanel1.Controls.Add(valueControl); } } } } // if there is an error simply dont show it, ie bad pde file, bad scale etc catch (Exception ex) { log.Error(ex); } } }); ThemeManager.ApplyThemeTo(this); this.ResumeLayout(); } /// /// Fits the description text. /// /// The description. /// private string FitDescriptionText(string description) { return FitDescriptionText(string.Empty, description); } /// /// Fits the description text. /// /// The units. /// The description. /// private string FitDescriptionText(string units, string description) { var returnDescription = new StringBuilder(); if (!String.IsNullOrEmpty(units)) { returnDescription.Append(String.Format("Units: {0}{1}", units, Environment.NewLine)); } if (!String.IsNullOrEmpty(description)) { returnDescription.Append("Description: "); var descriptionParts = description.Split(new char[] { ' ' }); for (int i = 0; i < descriptionParts.Length; i++) { returnDescription.Append(String.Format("{0} ", descriptionParts[i])); if (i != 0 && i % 12 == 0) returnDescription.Append(Environment.NewLine); } } return returnDescription.ToString(); } #endregion } }