diff --git a/Tools/ArdupilotMegaPlanner/ArduinoDetect.cs b/Tools/ArdupilotMegaPlanner/ArduinoDetect.cs index 320338126b..e7df4c3ed3 100644 --- a/Tools/ArdupilotMegaPlanner/ArduinoDetect.cs +++ b/Tools/ArdupilotMegaPlanner/ArduinoDetect.cs @@ -163,16 +163,11 @@ namespace ArdupilotMega { //Console.WriteLine("Dependant : " + obj2["Dependent"]); + // all apm 1-1.4 use a ftdi on the imu board. + if (obj2["Dependent"].ToString().Contains(@"USB\\VID_2341&PID_0010")) { - if (DialogResult.Yes == MessageBox.Show("Is this a APM 2?", "APM 2", MessageBoxButtons.YesNo)) - { return "2560-2"; - } - else - { - return "2560"; - } } } diff --git a/Tools/ArdupilotMegaPlanner/ArdupilotMega.csproj b/Tools/ArdupilotMegaPlanner/ArdupilotMega.csproj index 693b390139..d7965d596b 100644 --- a/Tools/ArdupilotMegaPlanner/ArdupilotMega.csproj +++ b/Tools/ArdupilotMegaPlanner/ArdupilotMega.csproj @@ -207,7 +207,7 @@ - + UserControl @@ -225,6 +225,12 @@ + + UserControl + + + ImageLabel.cs + Form @@ -267,14 +273,14 @@ - + Component Component - + Component @@ -337,7 +343,7 @@ Simulation.cs - + Component @@ -392,13 +398,16 @@ temp.cs - + AGauge.cs Designer Camera.cs + + ImageLabel.cs + georefimage.cs @@ -590,6 +599,12 @@ Always + + + + + + diff --git a/Tools/ArdupilotMegaPlanner/Common.cs b/Tools/ArdupilotMegaPlanner/Common.cs index 8823c2ea03..6ee90dfbbf 100644 --- a/Tools/ArdupilotMegaPlanner/Common.cs +++ b/Tools/ArdupilotMegaPlanner/Common.cs @@ -102,7 +102,7 @@ namespace ArdupilotMega const float rad2deg = (float)(180 / Math.PI); const float deg2rad = (float)(1.0 / rad2deg); - static readonly System.Drawing.Size SizeSt = new System.Drawing.Size(global::ArdupilotMega.Properties.Resources.planetracker.Width, global::ArdupilotMega.Properties.Resources.planetracker.Height); + static readonly System.Drawing.Size SizeSt = new System.Drawing.Size(global::ArdupilotMega.Properties.Resources.planeicon.Width, global::ArdupilotMega.Properties.Resources.planeicon.Height); float heading = 0; float cog = -1; float target = -1; @@ -131,7 +131,7 @@ namespace ArdupilotMega g.DrawLine(new Pen(Color.Orange, 2), 0.0f, 0.0f, (float)Math.Cos((target - 90) * deg2rad) * length, (float)Math.Sin((target - 90) * deg2rad) * length); g.RotateTransform(heading); - g.DrawImageUnscaled(global::ArdupilotMega.Properties.Resources.planetracker, global::ArdupilotMega.Properties.Resources.planetracker.Width / -2, global::ArdupilotMega.Properties.Resources.planetracker.Height / -2); + g.DrawImageUnscaled(global::ArdupilotMega.Properties.Resources.planeicon, global::ArdupilotMega.Properties.Resources.planeicon.Width / -2, global::ArdupilotMega.Properties.Resources.planeicon.Height / -2); g.Transform = temp; } @@ -143,7 +143,7 @@ namespace ArdupilotMega const float rad2deg = (float)(180 / Math.PI); const float deg2rad = (float)(1.0 / rad2deg); - static readonly System.Drawing.Size SizeSt = new System.Drawing.Size(global::ArdupilotMega.Properties.Resources.quad2.Width, global::ArdupilotMega.Properties.Resources.quad2.Height); + static readonly System.Drawing.Size SizeSt = new System.Drawing.Size(global::ArdupilotMega.Properties.Resources.quadicon.Width, global::ArdupilotMega.Properties.Resources.quadicon.Height); float heading = 0; float cog = -1; float target = -1; @@ -171,7 +171,7 @@ namespace ArdupilotMega g.RotateTransform(heading); - g.DrawImageUnscaled(global::ArdupilotMega.Properties.Resources.quad2, global::ArdupilotMega.Properties.Resources.quad2.Width / -2 + 2, global::ArdupilotMega.Properties.Resources.quad2.Height / -2); + g.DrawImageUnscaled(global::ArdupilotMega.Properties.Resources.quadicon, global::ArdupilotMega.Properties.Resources.quadicon.Width / -2 + 2, global::ArdupilotMega.Properties.Resources.quadicon.Height / -2); g.Transform = temp; } diff --git a/Tools/ArdupilotMegaPlanner/Controls/AGauge.cs b/Tools/ArdupilotMegaPlanner/Controls/AGauge.cs new file mode 100644 index 0000000000..7b7d9bfb94 --- /dev/null +++ b/Tools/ArdupilotMegaPlanner/Controls/AGauge.cs @@ -0,0 +1,1918 @@ +// Copyright (C) 2007 A.J.Bauer - Modified for multiple needles and scaling - Michael Oborne 2011 +// +// This software is provided as-is, without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. + +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: + +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. if you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Drawing.Drawing2D; +using System.Diagnostics; + + +namespace AGaugeApp +{ + [ToolboxBitmapAttribute(typeof(AGauge), "AGauge.bmp"), + DefaultEvent("ValueInRangeChanged"), + Description("Displays a value on an analog gauge. Raises an event if the value enters one of the definable ranges.")] + public partial class AGauge : MyUserControl + { +#region enum, var, delegate, event + public enum NeedleColorEnum + { + Gray = 0, + Red = 1, + Green = 2, + Blue = 3, + Yellow = 4, + Violet = 5, + Magenta = 6 + }; + + private const Byte ZERO = 0; + private const Byte NUMOFCAPS = 5; + private const Byte NUMOFRANGES = 5; + + private Single fontBoundY1; + private Single fontBoundY2; + private Bitmap gaugeBitmap; + private Boolean drawGaugeBackground = true; + + private Boolean[] m_valueIsInRange = { false, false, false, false, false }; + private Byte m_CapIdx = 1; + private Color[] m_CapColor = { Color.Black, Color.Black, Color.Black, Color.Black, Color.Black }; + private String[] m_CapText = { "", "", "", "", "" }; + private Point[] m_CapPosition = { new Point(10, 10), new Point(10, 10), new Point(10, 10), new Point(10, 10), new Point(10, 10) }; + private Point m_Center = new Point(100, 100); + private Single m_MinValue = -100; + private Single m_MaxValue = 400; + + private Color m_BaseArcColor = Color.Gray; + private Int32 m_BaseArcRadius = 80; + private Int32 m_BaseArcStart = 135; + private Int32 m_BaseArcSweep = 270; + private Int32 m_BaseArcWidth = 2; + + private Color m_ScaleLinesInterColor = Color.Black; + private Int32 m_ScaleLinesInterInnerRadius = 73; + private Int32 m_ScaleLinesInterOuterRadius = 80; + private Int32 m_ScaleLinesInterWidth = 1; + + private Int32 m_ScaleLinesMinorNumOf = 9; + private Color m_ScaleLinesMinorColor = Color.Gray; + private Int32 m_ScaleLinesMinorInnerRadius = 75; + private Int32 m_ScaleLinesMinorOuterRadius = 80; + private Int32 m_ScaleLinesMinorWidth = 1; + + private Single m_ScaleLinesMajorStepValue = 50.0f; + private Color m_ScaleLinesMajorColor = Color.Black; + private Int32 m_ScaleLinesMajorInnerRadius = 70; + private Int32 m_ScaleLinesMajorOuterRadius = 80; + private Int32 m_ScaleLinesMajorWidth = 2; + + private Byte m_RangeIdx; + private Boolean[] m_RangeEnabled = { true, true, false, false, false }; + private Color[] m_RangeColor = { Color.LightGreen, Color.Red, Color.FromKnownColor(KnownColor.Control), Color.FromKnownColor(KnownColor.Control), Color.FromKnownColor(KnownColor.Control) }; + private Single[] m_RangeStartValue = { -100.0f, 300.0f, 0.0f, 0.0f, 0.0f }; + private Single[] m_RangeEndValue = { 300.0f, 400.0f, 0.0f, 0.0f, 0.0f }; + private Int32[] m_RangeInnerRadius = { 70, 70, 70, 70, 70 }; + private Int32[] m_RangeOuterRadius = { 80, 80, 80, 80, 80 }; + + private Int32 m_ScaleNumbersRadius = 95; + private Color m_ScaleNumbersColor = Color.Black; + private String m_ScaleNumbersFormat; + private Int32 m_ScaleNumbersStartScaleLine; + private Int32 m_ScaleNumbersStepScaleLines = 1; + private Int32 m_ScaleNumbersRotation = 0; + + private Byte m_NeedIdx = 0; + private Int32[] m_NeedleType = { 0, 0, 0, 0 }; + private Int32[] m_NeedleRadius = { 80, 80, 80, 80}; + private NeedleColorEnum[] m_NeedleColor1 = { NeedleColorEnum.Gray, NeedleColorEnum.Gray, NeedleColorEnum.Gray, NeedleColorEnum.Gray }; + private Color[] m_NeedleColor2 = { Color.DimGray, Color.DimGray, Color.DimGray, Color.DimGray }; + private Int32[] m_NeedleWidth = { 2, 2, 2, 2 }; + private bool[] m_NeedleEnabled = { true, false, false, false }; + + private Single[] m_value = { 0, 0, 0, 0 }; + + public class ValueInRangeChangedEventArgs : EventArgs + { + public Int32 valueInRange; + + public ValueInRangeChangedEventArgs(Int32 valueInRange) + { + this.valueInRange = valueInRange; + } + } + + public delegate void ValueInRangeChangedDelegate(Object sender, ValueInRangeChangedEventArgs e); + [Description("This event is raised if the value falls into a defined range.")] + public event ValueInRangeChangedDelegate ValueInRangeChanged; +#endregion + +#region hidden , overridden inherited properties + public new Boolean AllowDrop + { + get + { + return false; + } + set + { + + } + } + public new Boolean AutoSize + { + get + { + return false; + } + set + { + + } + } + public new Boolean ForeColor + { + get + { + return false; + } + set + { + } + } + public new Boolean ImeMode + { + get + { + return false; + } + set + { + } + } + + public override System.Drawing.Color BackColor + { + get + { + return base.BackColor; + } + set + { + base.BackColor = value; + drawGaugeBackground = true; + Refresh(); + } + } + public override System.Drawing.Font Font + { + get + { + return base.Font; + } + set + { + base.Font = value; + drawGaugeBackground = true; + Refresh(); + } + } + public override System.Windows.Forms.ImageLayout BackgroundImageLayout + { + get + { + return base.BackgroundImageLayout; + } + set + { + base.BackgroundImageLayout = value; + drawGaugeBackground = true; + Refresh(); + } + } + #endregion + + public AGauge() + { + InitializeComponent(); + + SetStyle(ControlStyles.OptimizedDoubleBuffer, true); + } + +#region properties + [System.ComponentModel.Browsable(true)] + public Single Value0 { get { return m_value[0]; } set { m_NeedIdx = 0; Value = value; } } + [System.ComponentModel.Browsable(true)] + public Single Value1 { get { return m_value[1]; } set { m_NeedIdx = 1; Value = value; } } + [System.ComponentModel.Browsable(true)] + public Single Value2 { get { return m_value[2]; } set { m_NeedIdx = 2; Value = value; } } + [System.ComponentModel.Browsable(true)] + public Single Value3 { get { return m_value[3]; } set { m_NeedIdx = 3; Value = value; } } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The value.")] + public Single Value + { + get + { + return m_value[m_NeedIdx]; + } + set + { + if (m_value[m_NeedIdx] != value) + { + m_value[m_NeedIdx] = Math.Min(Math.Max(value, m_MinValue), m_MaxValue); + + if (this.DesignMode) + { + drawGaugeBackground = true; + } + + for (Int32 counter = 0; counter < NUMOFRANGES - 1; counter++) + { + if ((m_RangeStartValue[counter] <= m_value[m_NeedIdx]) + && (m_value[m_NeedIdx] <= m_RangeEndValue[counter]) + && (m_RangeEnabled[counter])) + { + if (!m_valueIsInRange[counter]) + { + if (ValueInRangeChanged!=null) + { + ValueInRangeChanged(this, new ValueInRangeChangedEventArgs(counter)); + } + } + } + else + { + m_valueIsInRange[counter] = false; + } + } + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.RefreshProperties(RefreshProperties.All), + System.ComponentModel.Description("The caption index. set this to a value of 0 up to 4 to change the corresponding caption's properties.")] + public Byte Cap_Idx + { + get + { + return m_CapIdx; + } + set + { + if ((m_CapIdx != value) + && (0 <= value) + && (value < 5)) + { + m_CapIdx = value; + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The color of the caption text.")] + public Color CapColor + { + get + { + return m_CapColor[m_CapIdx]; + } + set + { + if (m_CapColor[m_CapIdx] != value) + { + m_CapColor[m_CapIdx] = value; + CapColors = m_CapColor; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(false)] + public Color[] CapColors + { + get + { + return m_CapColor; + } + set + { + m_CapColor = value; + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The text of the caption.")] + public String CapText + { + get + { + return m_CapText[m_CapIdx]; + } + set + { + if (m_CapText[m_CapIdx] != value) + { + m_CapText[m_CapIdx] = value; + CapsText = m_CapText; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(false)] + public String[] CapsText + { + get + { + return m_CapText; + } + set + { + for (Int32 counter = 0; counter < 5; counter++) + { + m_CapText[counter] = value[counter]; + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The position of the caption.")] + public Point CapPosition + { + get + { + return m_CapPosition[m_CapIdx]; + } + set + { + if (m_CapPosition[m_CapIdx] != value) + { + m_CapPosition[m_CapIdx] = value; + CapsPosition = m_CapPosition; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(false)] + public Point[] CapsPosition + { + get + { + return m_CapPosition; + } + set + { + m_CapPosition = value; + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The center of the gauge (in the control's client area).")] + public Point Center + { + get + { + return m_Center; + } + set + { + if (m_Center != value) + { + m_Center = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The minimum value to show on the scale.")] + public Single MinValue + { + get + { + return m_MinValue; + } + set + { + if ((m_MinValue != value) + && (value < m_MaxValue)) + { + m_MinValue = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The maximum value to show on the scale.")] + public Single MaxValue + { + get + { + return m_MaxValue; + } + set + { + if ((m_MaxValue != value) + && (value > m_MinValue)) + { + m_MaxValue = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The color of the base arc.")] + public Color BaseArcColor + { + get + { + return m_BaseArcColor; + } + set + { + if (m_BaseArcColor != value) + { + m_BaseArcColor = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The radius of the base arc.")] + public Int32 BaseArcRadius + { + get + { + return m_BaseArcRadius; + } + set + { + if (m_BaseArcRadius != value) + { + m_BaseArcRadius = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The start angle of the base arc.")] + public Int32 BaseArcStart + { + get + { + return m_BaseArcStart; + } + set + { + if (m_BaseArcStart != value) + { + m_BaseArcStart = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The sweep angle of the base arc.")] + public Int32 BaseArcSweep + { + get + { + return m_BaseArcSweep; + } + set + { + if (m_BaseArcSweep != value) + { + m_BaseArcSweep = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The width of the base arc.")] + public Int32 BaseArcWidth + { + get + { + return m_BaseArcWidth; + } + set + { + if (m_BaseArcWidth != value) + { + m_BaseArcWidth = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The color of the inter scale lines which are the middle scale lines for an uneven number of minor scale lines.")] + public Color ScaleLinesInterColor + { + get + { + return m_ScaleLinesInterColor; + } + set + { + if (m_ScaleLinesInterColor != value) + { + m_ScaleLinesInterColor = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The inner radius of the inter scale lines which are the middle scale lines for an uneven number of minor scale lines.")] + public Int32 ScaleLinesInterInnerRadius + { + get + { + return m_ScaleLinesInterInnerRadius; + } + set + { + if (m_ScaleLinesInterInnerRadius != value) + { + m_ScaleLinesInterInnerRadius = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The outer radius of the inter scale lines which are the middle scale lines for an uneven number of minor scale lines.")] + public Int32 ScaleLinesInterOuterRadius + { + get + { + return m_ScaleLinesInterOuterRadius; + } + set + { + if (m_ScaleLinesInterOuterRadius != value) + { + m_ScaleLinesInterOuterRadius = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The width of the inter scale lines which are the middle scale lines for an uneven number of minor scale lines.")] + public Int32 ScaleLinesInterWidth + { + get + { + return m_ScaleLinesInterWidth; + } + set + { + if (m_ScaleLinesInterWidth != value) + { + m_ScaleLinesInterWidth = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The number of minor scale lines.")] + public Int32 ScaleLinesMinorNumOf + { + get + { + return m_ScaleLinesMinorNumOf; + } + set + { + if (m_ScaleLinesMinorNumOf != value) + { + m_ScaleLinesMinorNumOf = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The color of the minor scale lines.")] + public Color ScaleLinesMinorColor + { + get + { + return m_ScaleLinesMinorColor; + } + set + { + if (m_ScaleLinesMinorColor != value) + { + m_ScaleLinesMinorColor = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The inner radius of the minor scale lines.")] + public Int32 ScaleLinesMinorInnerRadius + { + get + { + return m_ScaleLinesMinorInnerRadius; + } + set + { + if (m_ScaleLinesMinorInnerRadius != value) + { + m_ScaleLinesMinorInnerRadius = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The outer radius of the minor scale lines.")] + public Int32 ScaleLinesMinorOuterRadius + { + get + { + return m_ScaleLinesMinorOuterRadius; + } + set + { + if (m_ScaleLinesMinorOuterRadius != value) + { + m_ScaleLinesMinorOuterRadius = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The width of the minor scale lines.")] + public Int32 ScaleLinesMinorWidth + { + get + { + return m_ScaleLinesMinorWidth; + } + set + { + if (m_ScaleLinesMinorWidth != value) + { + m_ScaleLinesMinorWidth = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The step value of the major scale lines.")] + public Single ScaleLinesMajorStepValue + { + get + { + return m_ScaleLinesMajorStepValue; + } + set + { + if ((m_ScaleLinesMajorStepValue != value) && (value > 0)) + { + m_ScaleLinesMajorStepValue = Math.Max(Math.Min(value, m_MaxValue), m_MinValue); + drawGaugeBackground = true; + Refresh(); + } + } + } + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The color of the major scale lines.")] + public Color ScaleLinesMajorColor + { + get + { + return m_ScaleLinesMajorColor; + } + set + { + if (m_ScaleLinesMajorColor != value) + { + m_ScaleLinesMajorColor = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The inner radius of the major scale lines.")] + public Int32 ScaleLinesMajorInnerRadius + { + get + { + return m_ScaleLinesMajorInnerRadius; + } + set + { + if (m_ScaleLinesMajorInnerRadius != value) + { + m_ScaleLinesMajorInnerRadius = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The outer radius of the major scale lines.")] + public Int32 ScaleLinesMajorOuterRadius + { + get + { + return m_ScaleLinesMajorOuterRadius; + } + set + { + if (m_ScaleLinesMajorOuterRadius != value) + { + m_ScaleLinesMajorOuterRadius = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The width of the major scale lines.")] + public Int32 ScaleLinesMajorWidth + { + get + { + return m_ScaleLinesMajorWidth; + } + set + { + if (m_ScaleLinesMajorWidth != value) + { + m_ScaleLinesMajorWidth = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.RefreshProperties(RefreshProperties.All), + System.ComponentModel.Description("The range index. set this to a value of 0 up to 4 to change the corresponding range's properties.")] + public Byte Range_Idx + { + get + { + return m_RangeIdx; + } + set + { + if ((m_RangeIdx != value) + && (0 <= value) + && (value < NUMOFRANGES)) + { + m_RangeIdx = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("Enables or disables the range selected by Range_Idx.")] + public Boolean RangeEnabled + { + get + { + return m_RangeEnabled[m_RangeIdx]; + } + set + { + if (m_RangeEnabled[m_RangeIdx] != value) + { + m_RangeEnabled[m_RangeIdx] = value; + RangesEnabled = m_RangeEnabled; + drawGaugeBackground = true; + Refresh(); + } + } + } + + + [System.ComponentModel.Browsable(false)] + public Boolean[] RangesEnabled + { + get + { + return m_RangeEnabled; + } + set + { + m_RangeEnabled = value; + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The color of the range.")] + public Color RangeColor + { + get + { + return m_RangeColor[m_RangeIdx]; + } + set + { + if (m_RangeColor[m_RangeIdx] != value) + { + m_RangeColor[m_RangeIdx] = value; + RangesColor = m_RangeColor; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(false)] + public Color[] RangesColor + { + get + { + return m_RangeColor; + } + set + { + m_RangeColor = value; + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The start value of the range, must be less than RangeEndValue.")] + public Single RangeStartValue + { + get + { + return m_RangeStartValue[m_RangeIdx]; + } + set + { + if ((m_RangeStartValue[m_RangeIdx] != value) + && (value < m_RangeEndValue[m_RangeIdx])) + { + m_RangeStartValue[m_RangeIdx] = value; + RangesStartValue = m_RangeStartValue; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(false)] + public Single[] RangesStartValue + { + get + { + return m_RangeStartValue; + } + set + { + m_RangeStartValue = value; + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The end value of the range. Must be greater than RangeStartValue.")] + public Single RangeEndValue + { + get + { + return m_RangeEndValue[m_RangeIdx]; + } + set + { + if ((m_RangeEndValue[m_RangeIdx] != value) + && (m_RangeStartValue[m_RangeIdx] < value)) + { + m_RangeEndValue[m_RangeIdx] = value; + RangesEndValue = m_RangeEndValue; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(false)] + public Single[] RangesEndValue + { + get + { + return m_RangeEndValue; + } + set + { + m_RangeEndValue = value; + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The inner radius of the range.")] + public Int32 RangeInnerRadius + { + get + { + return m_RangeInnerRadius[m_RangeIdx]; + } + set + { + if (m_RangeInnerRadius[m_RangeIdx] != value) + { + m_RangeInnerRadius[m_RangeIdx] = value; + RangesInnerRadius = m_RangeInnerRadius; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(false)] + public Int32[] RangesInnerRadius + { + get + { + return m_RangeInnerRadius; + } + set + { + m_RangeInnerRadius = value; + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The inner radius of the range.")] + public Int32 RangeOuterRadius + { + get + { + return m_RangeOuterRadius[m_RangeIdx]; + } + set + { + if (m_RangeOuterRadius[m_RangeIdx] != value) + { + m_RangeOuterRadius[m_RangeIdx] = value; + RangesOuterRadius = m_RangeOuterRadius; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(false)] + public Int32[] RangesOuterRadius + { + get + { + return m_RangeOuterRadius; + } + set + { + m_RangeOuterRadius = value; + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The radius of the scale numbers.")] + public Int32 ScaleNumbersRadius + { + get + { + return m_ScaleNumbersRadius; + } + set + { + if (m_ScaleNumbersRadius != value) + { + m_ScaleNumbersRadius = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The color of the scale numbers.")] + public Color ScaleNumbersColor + { + get + { + return m_ScaleNumbersColor; + } + set + { + if (m_ScaleNumbersColor != value) + { + m_ScaleNumbersColor = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The format of the scale numbers.")] + public String ScaleNumbersFormat + { + get + { + return m_ScaleNumbersFormat; + } + set + { + if (m_ScaleNumbersFormat != value) + { + m_ScaleNumbersFormat = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The number of the scale line to start writing numbers next to.")] + public Int32 ScaleNumbersStartScaleLine + { + get + { + return m_ScaleNumbersStartScaleLine; + } + set + { + if (m_ScaleNumbersStartScaleLine != value) + { + m_ScaleNumbersStartScaleLine = Math.Max(value, 1); + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The number of scale line steps for writing numbers.")] + public Int32 ScaleNumbersStepScaleLines + { + get + { + return m_ScaleNumbersStepScaleLines; + } + set + { + if (m_ScaleNumbersStepScaleLines != value) + { + m_ScaleNumbersStepScaleLines = Math.Max(value, 1); + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The angle relative to the tangent of the base arc at a scale line that is used to rotate numbers. set to 0 for no rotation or e.g. set to 90.")] + public Int32 ScaleNumbersRotation + { + get + { + return m_ScaleNumbersRotation; + } + set + { + if (m_ScaleNumbersRotation != value) + { + m_ScaleNumbersRotation = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(true), +System.ComponentModel.Category("AGauge"), +System.ComponentModel.RefreshProperties(RefreshProperties.All), +System.ComponentModel.Description("set needle number")] + public Byte Need_Idx + { + get + { + return m_NeedIdx; + } + set + { + if ((m_NeedIdx != value) + && (0 <= value) + && (value < 5)) + { + m_NeedIdx = value; + } + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The type of the needle, currently only type 0 and 1 are supported. Type 0 looks nicers but if you experience performance problems you might consider using type 1.")] + public Int32 NeedleType + { + get + { + return m_NeedleType[m_NeedIdx]; + } + set + { + if (m_NeedleType[m_NeedIdx] != value) + { + m_NeedleType[m_NeedIdx] = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(false)] + public Int32[] NeedlesType + { + get + { + return m_NeedleType; + } + set + { + m_NeedleType = value; + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The radius of the needle.")] + public Int32 NeedleRadius + { + get + { + return m_NeedleRadius[m_NeedIdx]; + } + set + { + if (m_NeedleRadius[m_NeedIdx] != value) + { + m_NeedleRadius[m_NeedIdx] = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(false)] + public Int32[] NeedlesRadius + { + get + { + return m_NeedleRadius; + } + set + { + m_NeedleRadius = value; + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The first color of the needle.")] + public NeedleColorEnum NeedleColor1 + { + get + { + return m_NeedleColor1[m_NeedIdx]; + } + set + { + if (m_NeedleColor1[m_NeedIdx] != value) + { + m_NeedleColor1[m_NeedIdx] = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(false)] + public NeedleColorEnum[] NeedlesColor1 + { + get + { + return m_NeedleColor1; + } + set + { + m_NeedleColor1 = value; + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The second color of the needle.")] + public Color NeedleColor2 + { + get + { + return m_NeedleColor2[m_NeedIdx]; + } + set + { + if (m_NeedleColor2[m_NeedIdx] != value) + { + m_NeedleColor2[m_NeedIdx] = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(false)] + public Color[] NeedlesColor2 + { + get + { + return m_NeedleColor2; + } + set + { + m_NeedleColor2 = value; + } + } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("The width of the needle.")] + public Int32 NeedleWidth + { + get + { + return m_NeedleWidth[m_NeedIdx]; + } + set + { + if (m_NeedleWidth[m_NeedIdx] != value) + { + m_NeedleWidth[m_NeedIdx] = value; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(false)] + public Int32[] NeedlesWidth + { + get + { + return m_NeedleWidth; + } + set + { + m_NeedleWidth = value; + } + } + + [System.ComponentModel.Browsable(true), +System.ComponentModel.Category("AGauge"), +System.ComponentModel.Description("Enables or disables the range selected by Need_Idx.")] + public Boolean NeedleEnabled + { + get + { + return m_NeedleEnabled[m_NeedIdx]; + } + set + { + if (m_NeedleEnabled[m_NeedIdx] != value) + { + m_NeedleEnabled[m_NeedIdx] = value; + NeedlesEnabled = m_NeedleEnabled; + drawGaugeBackground = true; + Refresh(); + } + } + } + + [System.ComponentModel.Browsable(false)] + public Boolean[] NeedlesEnabled + { + get + { + return m_NeedleEnabled; + } + set + { + m_NeedleEnabled = value; + } + } + + #endregion + +#region helper + private void FindFontBounds() + { + //find upper and lower bounds for numeric characters + Int32 c1; + Int32 c2; + Boolean boundfound; + Bitmap b; + Graphics g; + SolidBrush backBrush = new SolidBrush(Color.White); + SolidBrush foreBrush = new SolidBrush(Color.Black); + SizeF boundingBox; + + b = new Bitmap(5, 5); + g = Graphics.FromImage(b); + boundingBox = g.MeasureString("0123456789", Font, -1, StringFormat.GenericTypographic); + b = new Bitmap((Int32)(boundingBox.Width), (Int32)(boundingBox.Height)); + g = Graphics.FromImage(b); + g.FillRectangle(backBrush, 0.0F, 0.0F, boundingBox.Width, boundingBox.Height); + g.DrawString("0123456789", Font, foreBrush, 0.0F, 0.0F, StringFormat.GenericTypographic); + + fontBoundY1 = 0; + fontBoundY2 = 0; + c1 = 0; + boundfound = false; + while ((c1 < b.Height) && (!boundfound)) + { + c2 = 0; + while ((c2 < b.Width) && (!boundfound)) + { + if (b.GetPixel(c2, c1) != backBrush.Color) + { + fontBoundY1 = c1; + boundfound = true; + } + c2++; + } + c1++; + } + + c1 = b.Height - 1; + boundfound = false; + while ((0 < c1) && (!boundfound)) + { + c2 = 0; + while ((c2 < b.Width) && (!boundfound)) + { + if (b.GetPixel(c2, c1) != backBrush.Color) + { + fontBoundY2 = c1; + boundfound = true; + } + c2++; + } + c1--; + } + } +#endregion + +#region base member overrides + protected override void OnPaintBackground(PaintEventArgs pevent) + { + } + + protected override void OnPaint(PaintEventArgs pe) + { + if ((Width < 10) || (Height < 10)) + { + return; + } + + float scale = 1; + + // scale it + if (basesize != null) + { + scale = (float)this.Width / basesize.Width; + +// Console.WriteLine("Scale: " + scale); + } + + if (drawGaugeBackground) + { + drawGaugeBackground = false; + try + { + FindFontBounds(); + } + catch { } // ignore for now - happens when the control gets to small for text + + gaugeBitmap = new Bitmap(Width, Height, pe.Graphics); + Graphics ggr = Graphics.FromImage(gaugeBitmap); + ggr.FillRectangle(new SolidBrush(BackColor), ClientRectangle); + + if (BackgroundImage!=null) + { + switch (BackgroundImageLayout) + { + case ImageLayout.Center: + ggr.DrawImageUnscaled(BackgroundImage, Width / 2 - BackgroundImage.Width / 2, Height / 2 - BackgroundImage.Height / 2); + break; + case ImageLayout.None: + ggr.DrawImageUnscaled(BackgroundImage, 0, 0); + break; + case ImageLayout.Stretch: + ggr.DrawImage(BackgroundImage, 0, 0, Width, Height); + break; + case ImageLayout.Tile: + Int32 pixelOffsetX = 0; + Int32 pixelOffsetY = 0; + while (pixelOffsetX < Width) + { + pixelOffsetY = 0; + while (pixelOffsetY < Height) + { + ggr.DrawImageUnscaled(BackgroundImage, pixelOffsetX, pixelOffsetY); + pixelOffsetY += BackgroundImage.Height; + } + pixelOffsetX += BackgroundImage.Width; + } + break; + case ImageLayout.Zoom: + if ((Single)(BackgroundImage.Width / Width) < (Single)(BackgroundImage.Height / Height)) + { + ggr.DrawImage(BackgroundImage, 0, 0, Height, Height); + } + else + { + ggr.DrawImage(BackgroundImage, 0, 0, Width, Width); + } + break; + } + } + + ggr.SmoothingMode = SmoothingMode.HighQuality; + ggr.PixelOffsetMode = PixelOffsetMode.HighQuality; + + // scale it + if (basesize != null) + { + ggr.ScaleTransform(scale, scale); + } + + GraphicsPath gp = new GraphicsPath(); + Single rangeStartAngle; + Single rangeSweepAngle; + for (Int32 counter= 0; counter m_RangeStartValue[counter] + && m_RangeEnabled[counter]) + { + rangeStartAngle = m_BaseArcStart + (m_RangeStartValue[counter] - m_MinValue) * m_BaseArcSweep / (m_MaxValue - m_MinValue); + rangeSweepAngle = (m_RangeEndValue[counter] - m_RangeStartValue[counter]) * m_BaseArcSweep / (m_MaxValue - m_MinValue); + gp.Reset(); + gp.AddPie(new Rectangle(m_Center.X - m_RangeOuterRadius[counter], m_Center.Y - m_RangeOuterRadius[counter], 2 * m_RangeOuterRadius[counter], 2 * m_RangeOuterRadius[counter]), rangeStartAngle, rangeSweepAngle); + gp.Reverse(); + gp.AddPie(new Rectangle(m_Center.X - m_RangeInnerRadius[counter], m_Center.Y - m_RangeInnerRadius[counter], 2 * m_RangeInnerRadius[counter], 2 * m_RangeInnerRadius[counter]), rangeStartAngle, rangeSweepAngle); + gp.Reverse(); + ggr.SetClip(gp); + ggr.FillPie(new SolidBrush(m_RangeColor[counter]), new Rectangle(m_Center.X - m_RangeOuterRadius[counter], m_Center.Y - m_RangeOuterRadius[counter], 2 * m_RangeOuterRadius[counter], 2 * m_RangeOuterRadius[counter]), rangeStartAngle, rangeSweepAngle); + } + } + + ggr.SetClip(ClientRectangle); + if (m_BaseArcRadius > 0) + { + ggr.DrawArc(new Pen(m_BaseArcColor, m_BaseArcWidth), new Rectangle(m_Center.X - m_BaseArcRadius, m_Center.Y - m_BaseArcRadius, 2 * m_BaseArcRadius, 2 * m_BaseArcRadius), m_BaseArcStart, m_BaseArcSweep); + } + + String valueText = ""; + SizeF boundingBox; + Single countValue= 0; + Int32 counter1 = 0; + while (countValue <= (m_MaxValue - m_MinValue)) + { + valueText = (m_MinValue + countValue).ToString(m_ScaleNumbersFormat); + ggr.ResetTransform(); + // scale it + if (basesize != null) + { + ggr.ScaleTransform(scale, scale); + } + boundingBox = ggr.MeasureString(valueText, Font, -1, StringFormat.GenericTypographic); + + gp.Reset(); + gp.AddEllipse(new Rectangle(m_Center.X - m_ScaleLinesMajorOuterRadius, m_Center.Y - m_ScaleLinesMajorOuterRadius, 2 * m_ScaleLinesMajorOuterRadius, 2 * m_ScaleLinesMajorOuterRadius)); + gp.Reverse(); + gp.AddEllipse(new Rectangle(m_Center.X - m_ScaleLinesMajorInnerRadius, m_Center.Y - m_ScaleLinesMajorInnerRadius, 2 * m_ScaleLinesMajorInnerRadius, 2 * m_ScaleLinesMajorInnerRadius)); + gp.Reverse(); + ggr.SetClip(gp); + + ggr.DrawLine(new Pen(m_ScaleLinesMajorColor, m_ScaleLinesMajorWidth), + (Single)(Center.X), + (Single)(Center.Y), + (Single)(Center.X + 2 * m_ScaleLinesMajorOuterRadius * Math.Cos((m_BaseArcStart + countValue * m_BaseArcSweep / (m_MaxValue - m_MinValue)) * Math.PI / 180.0)), + (Single)(Center.Y + 2 * m_ScaleLinesMajorOuterRadius * Math.Sin((m_BaseArcStart + countValue * m_BaseArcSweep / (m_MaxValue - m_MinValue)) * Math.PI / 180.0))); + + gp.Reset(); + gp.AddEllipse(new Rectangle(m_Center.X - m_ScaleLinesMinorOuterRadius, m_Center.Y - m_ScaleLinesMinorOuterRadius, 2 * m_ScaleLinesMinorOuterRadius, 2 * m_ScaleLinesMinorOuterRadius)); + gp.Reverse(); + gp.AddEllipse(new Rectangle(m_Center.X - m_ScaleLinesMinorInnerRadius, m_Center.Y - m_ScaleLinesMinorInnerRadius, 2 * m_ScaleLinesMinorInnerRadius, 2 * m_ScaleLinesMinorInnerRadius)); + gp.Reverse(); + ggr.SetClip(gp); + + if (countValue < (m_MaxValue - m_MinValue)) + { + for (Int32 counter2= 1; counter2<=m_ScaleLinesMinorNumOf; counter2++) + { + if (((m_ScaleLinesMinorNumOf % 2) == 1) && ((Int32)(m_ScaleLinesMinorNumOf / 2) + 1 == counter2)) + { + gp.Reset(); + gp.AddEllipse(new Rectangle(m_Center.X - m_ScaleLinesInterOuterRadius, m_Center.Y - m_ScaleLinesInterOuterRadius, 2 * m_ScaleLinesInterOuterRadius, 2 * m_ScaleLinesInterOuterRadius)); + gp.Reverse(); + gp.AddEllipse(new Rectangle(m_Center.X - m_ScaleLinesInterInnerRadius, m_Center.Y - m_ScaleLinesInterInnerRadius, 2 * m_ScaleLinesInterInnerRadius, 2 * m_ScaleLinesInterInnerRadius)); + gp.Reverse(); + ggr.SetClip(gp); + + ggr.DrawLine(new Pen(m_ScaleLinesInterColor, m_ScaleLinesInterWidth), + (Single)(Center.X), + (Single)(Center.Y), + (Single)(Center.X + 2 * m_ScaleLinesInterOuterRadius * Math.Cos((m_BaseArcStart + countValue * m_BaseArcSweep / (m_MaxValue - m_MinValue) + counter2 * m_BaseArcSweep / (((Single)((m_MaxValue - m_MinValue) / m_ScaleLinesMajorStepValue)) * (m_ScaleLinesMinorNumOf + 1))) * Math.PI / 180.0)), + (Single)(Center.Y + 2 * m_ScaleLinesInterOuterRadius * Math.Sin((m_BaseArcStart + countValue * m_BaseArcSweep / (m_MaxValue - m_MinValue) + counter2 * m_BaseArcSweep / (((Single)((m_MaxValue - m_MinValue) / m_ScaleLinesMajorStepValue)) * (m_ScaleLinesMinorNumOf + 1))) * Math.PI / 180.0))); + + gp.Reset(); + gp.AddEllipse(new Rectangle(m_Center.X - m_ScaleLinesMinorOuterRadius, m_Center.Y - m_ScaleLinesMinorOuterRadius, 2 * m_ScaleLinesMinorOuterRadius, 2 * m_ScaleLinesMinorOuterRadius)); + gp.Reverse(); + gp.AddEllipse(new Rectangle(m_Center.X - m_ScaleLinesMinorInnerRadius, m_Center.Y - m_ScaleLinesMinorInnerRadius, 2 * m_ScaleLinesMinorInnerRadius, 2 * m_ScaleLinesMinorInnerRadius)); + gp.Reverse(); + ggr.SetClip(gp); + } + else + { + ggr.DrawLine(new Pen(m_ScaleLinesMinorColor, m_ScaleLinesMinorWidth), + (Single)(Center.X), + (Single)(Center.Y), + (Single)(Center.X + 2 * m_ScaleLinesMinorOuterRadius * Math.Cos((m_BaseArcStart + countValue * m_BaseArcSweep / (m_MaxValue - m_MinValue) + counter2 * m_BaseArcSweep / (((Single)((m_MaxValue - m_MinValue) / m_ScaleLinesMajorStepValue)) * (m_ScaleLinesMinorNumOf + 1))) * Math.PI / 180.0)), + (Single)(Center.Y + 2 * m_ScaleLinesMinorOuterRadius * Math.Sin((m_BaseArcStart + countValue * m_BaseArcSweep / (m_MaxValue - m_MinValue) + counter2 * m_BaseArcSweep / (((Single)((m_MaxValue - m_MinValue) / m_ScaleLinesMajorStepValue)) * (m_ScaleLinesMinorNumOf + 1))) * Math.PI / 180.0))); + } + } + } + + ggr.SetClip(ClientRectangle); + + if (m_ScaleNumbersRotation != 0) + { + ggr.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; + ggr.RotateTransform(90.0F + m_BaseArcStart + countValue * m_BaseArcSweep / (m_MaxValue - m_MinValue)); + } + + /*ggr.TranslateTransform((Single)(Center.X + m_ScaleNumbersRadius * Math.Cos((m_BaseArcStart + countValue * m_BaseArcSweep / (m_MaxValue - m_MinValue)) * Math.PI / 180.0f)), + (Single)(Center.Y + m_ScaleNumbersRadius * Math.Sin((m_BaseArcStart + countValue * m_BaseArcSweep / (m_MaxValue - m_MinValue)) * Math.PI / 180.0f)), + System.Drawing.Drawing2D.MatrixOrder.Append);*/ + + ggr.TranslateTransform((Single)(Center.X * scale + m_ScaleNumbersRadius * scale * Math.Cos((m_BaseArcStart + countValue * m_BaseArcSweep / (m_MaxValue - m_MinValue)) * Math.PI / 180.0f)), + (Single)(Center.Y * scale + m_ScaleNumbersRadius * scale * Math.Sin((m_BaseArcStart + countValue * m_BaseArcSweep / (m_MaxValue - m_MinValue)) * Math.PI / 180.0f)), + System.Drawing.Drawing2D.MatrixOrder.Append); + + if (counter1 >= ScaleNumbersStartScaleLine - 1) + { + ggr.DrawString(valueText, Font, new SolidBrush(m_ScaleNumbersColor), -boundingBox.Width / 2, -fontBoundY1 - (fontBoundY2 - fontBoundY1 + 1) / 2, StringFormat.GenericTypographic); + } + + countValue += m_ScaleLinesMajorStepValue; + counter1 ++; + } + + ggr.ResetTransform(); + // scale it + if (basesize != null) + { + ggr.ScaleTransform(scale, scale); + } + ggr.SetClip(ClientRectangle); + + if (m_ScaleNumbersRotation != 0) + { + ggr.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault; + } + + for (Int32 counter= 0; counter this.Height) + { + // this.Height = this.Width; + } + //else + { + this.Width = this.Height; + } + //this.Center = new Point(this.Width / 2, this.Width / 2); + + drawGaugeBackground = true; + Refresh(); + } + + public new Size Size { get { return base.Size; } set { base.Size = value; } } + + [System.ComponentModel.Browsable(true), + System.ComponentModel.Category("AGauge"), + System.ComponentModel.Description("Base Size the dials are designed for")] + public Size basesize { get { return _basesize; } set { _basesize = value; } } + + private Size _basesize = new Size(150,150); + +#endregion + + private void InitializeComponent() + { + this.SuspendLayout(); + // + // AGauge + // + this.BackColor = System.Drawing.Color.Transparent; + this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom; + this.DoubleBuffered = true; + this.Name = "AGauge"; + this.ResumeLayout(false); + + } + + } +} diff --git a/Tools/ArdupilotMegaPlanner/Controls/AGauge.resx b/Tools/ArdupilotMegaPlanner/Controls/AGauge.resx new file mode 100644 index 0000000000..7080a7d118 --- /dev/null +++ b/Tools/ArdupilotMegaPlanner/Controls/AGauge.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Tools/ArdupilotMegaPlanner/Controls/ImageLabel.Designer.cs b/Tools/ArdupilotMegaPlanner/Controls/ImageLabel.Designer.cs new file mode 100644 index 0000000000..40a6038712 --- /dev/null +++ b/Tools/ArdupilotMegaPlanner/Controls/ImageLabel.Designer.cs @@ -0,0 +1,76 @@ +namespace ArdupilotMega +{ + partial class ImageLabel + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + this.label1 = new System.Windows.Forms.Label(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + this.SuspendLayout(); + // + // pictureBox1 + // + this.pictureBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.pictureBox1.Cursor = System.Windows.Forms.Cursors.Hand; + this.pictureBox1.Location = new System.Drawing.Point(0, 0); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size(170, 155); + this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.pictureBox1.TabIndex = 0; + this.pictureBox1.TabStop = false; + this.pictureBox1.Click += new System.EventHandler(this.pictureBox1_Click); + // + // label1 + // + this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.label1.Location = new System.Drawing.Point(0, 157); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(170, 13); + this.label1.TabIndex = 1; + this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // ImageLabel + // + this.Controls.Add(this.label1); + this.Controls.Add(this.pictureBox1); + this.Name = "ImageLabel"; + this.Size = new System.Drawing.Size(170, 170); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.PictureBox pictureBox1; + private System.Windows.Forms.Label label1; + } +} diff --git a/Tools/ArdupilotMegaPlanner/Controls/ImageLabel.cs b/Tools/ArdupilotMegaPlanner/Controls/ImageLabel.cs new file mode 100644 index 0000000000..4bed18b5fd --- /dev/null +++ b/Tools/ArdupilotMegaPlanner/Controls/ImageLabel.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace ArdupilotMega +{ + public partial class ImageLabel : UserControl + { + public new event EventHandler Click; + + private Image picture; + private string text; + + public ImageLabel() + { + InitializeComponent(); + } + + public void setImageandText(Image image, string text) + { + pictureBox1.Image = image; + label1.Text = text; + } + + [System.ComponentModel.Browsable(true)] + public Image Image { + get { return picture; } + set { picture = value; pictureBox1.Image = picture; } + } + + [System.ComponentModel.Browsable(true)] + public override string Text + { + get { return text; } + set { text = value; label1.Text = text; } + } + + private void pictureBox1_Click(object sender, EventArgs e) + { + if (Click != null) + { + Click(sender,new EventArgs()); + } + } + } +} diff --git a/Tools/ArdupilotMegaPlanner/Controls/ImageLabel.resx b/Tools/ArdupilotMegaPlanner/Controls/ImageLabel.resx new file mode 100644 index 0000000000..7080a7d118 --- /dev/null +++ b/Tools/ArdupilotMegaPlanner/Controls/ImageLabel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Tools/ArdupilotMegaPlanner/Controls/MyButton.cs b/Tools/ArdupilotMegaPlanner/Controls/MyButton.cs new file mode 100644 index 0000000000..82f28d7e56 --- /dev/null +++ b/Tools/ArdupilotMegaPlanner/Controls/MyButton.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Linq; +using System.Text; +using System.Windows.Forms; + + +using System.Drawing.Drawing2D; + +namespace ArdupilotMega +{ + class MyButton : Button + { + bool mouseover = false; + bool mousedown = false; + + protected override void OnPaint(PaintEventArgs pevent) + { + //base.OnPaint(pevent); + + Graphics gr = pevent.Graphics; + + Rectangle outside = new Rectangle(0,0,this.Width,this.Height); + + LinearGradientBrush linear = new LinearGradientBrush(outside,Color.FromArgb(0x94,0xc1,0x1f),Color.FromArgb(0xcd,0xe2,0x96),LinearGradientMode.Vertical); + + Pen mypen = new Pen(Color.FromArgb(0x79,0x94,0x29),2); + + gr.FillRectangle(linear,outside); + + gr.DrawRectangle(mypen,outside); + + SolidBrush mybrush = new SolidBrush(Color.FromArgb(0x40,0x57,0x04)); + + if (mouseover) + { + SolidBrush brush = new SolidBrush(Color.FromArgb(73, 0x2b, 0x3a, 0x03)); + + gr.FillRectangle(brush, 0, 0, this.Width, this.Height); + } + if (mousedown) + { + SolidBrush brush = new SolidBrush(Color.FromArgb(73, 0x2b, 0x3a, 0x03)); + + gr.FillRectangle(brush, 0, 0, this.Width, this.Height); + } + + if (!this.Enabled) + { + SolidBrush brush = new SolidBrush(Color.FromArgb(150, 0x2b, 0x3a, 0x03)); + + gr.FillRectangle(brush, 0, 0, this.Width, this.Height); + } + + + StringFormat stringFormat = new StringFormat(); + stringFormat.Alignment = StringAlignment.Center; + stringFormat.LineAlignment = StringAlignment.Center; + + string display = this.Text; + int amppos = display.IndexOf('&'); + if (amppos != -1) + display = display.Remove(amppos,1); + + gr.DrawString(display, this.Font, mybrush, outside, stringFormat); + + } + + protected override void OnClick(EventArgs e) + { + base.OnClick(e); + } + + protected override void OnPaintBackground(PaintEventArgs pevent) + { + //base.OnPaintBackground(pevent); + } + + protected override void OnMouseEnter(EventArgs e) + { + mouseover = true; + base.OnMouseEnter(e); + } + + protected override void OnMouseLeave(EventArgs e) + { + mouseover = false; + base.OnMouseLeave(e); + } + + protected override void OnMouseDown(MouseEventArgs mevent) + { + mousedown = true; + base.OnMouseDown(mevent); + } + + protected override void OnMouseUp(MouseEventArgs mevent) + { + mousedown = false; + base.OnMouseUp(mevent); + } + } +} diff --git a/Tools/ArdupilotMegaPlanner/Controls/MyLabel.cs b/Tools/ArdupilotMegaPlanner/Controls/MyLabel.cs new file mode 100644 index 0000000000..bcd2271dc5 --- /dev/null +++ b/Tools/ArdupilotMegaPlanner/Controls/MyLabel.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace ArdupilotMega +{ + /// + /// profiling showed that the built in Label function was using alot ot call time. + /// + public partial class MyLabel : Control //: Label + { + string label = ""; + int noofchars = 0; + bool autosize = false; + + [System.ComponentModel.Browsable(true)] + public bool resize { get { return autosize; } set { autosize = value; } } + + public MyLabel() + { + } + + public override string Text + { + get + { + return label; + } + set + { + if (value == null) + return; + + if (label == value) + return; + + label = value; + + if (noofchars != label.Length && resize) + { + noofchars = label.Length; + Size textSize = TextRenderer.MeasureText(value, this.Font); + this.Width = textSize.Width; + } + + this.Invalidate(); + } + } + + SolidBrush s = new SolidBrush(Color.White); + SolidBrush b = new SolidBrush(Color.Black); + + StringFormat stringFormat = new StringFormat(); + + protected override void OnPaint(PaintEventArgs e) + { + stringFormat.Alignment = StringAlignment.Near; + stringFormat.LineAlignment = StringAlignment.Center; + + s = new SolidBrush(ForeColor); + + e.Graphics.DrawString(label, this.Font, s, new PointF(0, this.Height / 2.0f), stringFormat); + } + + protected override void OnPaintBackground(PaintEventArgs pevent) + { + b = new SolidBrush(BackColor); + + pevent.Graphics.FillRectangle(b, this.ClientRectangle); + + base.OnPaintBackground(pevent); + } + + protected override void WndProc(ref Message m) // seems to crash here on linux... so try ignore it + { + try + { + base.WndProc(ref m); + } + catch { } + } + } +} diff --git a/Tools/ArdupilotMegaPlanner/Controls/MyTrackBar.cs b/Tools/ArdupilotMegaPlanner/Controls/MyTrackBar.cs new file mode 100644 index 0000000000..1e010c806b --- /dev/null +++ b/Tools/ArdupilotMegaPlanner/Controls/MyTrackBar.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace ArdupilotMega +{ + class MyTrackBar : TrackBar + { + public new double Maximum { get { return base.Maximum / 100.0; } set { base.Maximum = (int)(value * 100); } } + public new double Minimum { get { return base.Minimum / 100.0; } set { base.Minimum = (int)(value * 100); } } + public new double Value { get { return base.Value / 100.0; } set { base.Value = (int)(value * 100); } } + } +} diff --git a/Tools/ArdupilotMegaPlanner/CurrentState.cs b/Tools/ArdupilotMegaPlanner/CurrentState.cs index 6cce04eea3..f273bc9354 100644 --- a/Tools/ArdupilotMegaPlanner/CurrentState.cs +++ b/Tools/ArdupilotMegaPlanner/CurrentState.cs @@ -20,6 +20,11 @@ namespace ArdupilotMega public float groundcourse { get { return _groundcourse; } set { if (value < 0) { _groundcourse = value + 360; } else { _groundcourse = value; } } } private float _groundcourse = 0; + /// + /// time over target in seconds + /// + public int tot { get { if (groundspeed <= 0) return 0; return (int)(wp_dist / groundspeed); } } + // speeds public float airspeed { get { return _airspeed * multiplierspeed; } set { _airspeed = value; } } public float groundspeed { get { return _groundspeed * multiplierspeed; } set { _groundspeed = value; } } diff --git a/Tools/ArdupilotMegaPlanner/GCSViews/Firmware.cs b/Tools/ArdupilotMegaPlanner/GCSViews/Firmware.cs index c8c07bb1c3..88d9cc76ba 100644 --- a/Tools/ArdupilotMegaPlanner/GCSViews/Firmware.cs +++ b/Tools/ArdupilotMegaPlanner/GCSViews/Firmware.cs @@ -17,58 +17,46 @@ namespace ArdupilotMega.GCSViews { class Firmware : MyUserControl { - private System.Windows.Forms.PictureBox pictureBoxAPM; - private System.Windows.Forms.PictureBox pictureBoxAPMHIL; - private System.Windows.Forms.PictureBox pictureBoxQuad; - private System.Windows.Forms.PictureBox pictureBoxHexa; - private System.Windows.Forms.PictureBox pictureBoxTri; - private System.Windows.Forms.PictureBox pictureBoxY6; + private ImageLabel pictureBoxAPM; + private ImageLabel pictureBoxQuad; + private ImageLabel pictureBoxHexa; + private ImageLabel pictureBoxTri; + private ImageLabel pictureBoxY6; private System.Windows.Forms.Label lbl_status; private System.Windows.Forms.ProgressBar progress; - private System.Windows.Forms.Label lbl_AP; private System.Windows.Forms.Label label2; - private System.Windows.Forms.Label lbl_APHil; - private System.Windows.Forms.Label lbl_ACQuad; - private System.Windows.Forms.Label lbl_ACHexa; - private System.Windows.Forms.Label lbl_ACTri; - private Label lbl_Heli; - private PictureBox pictureBoxHeli; + private ImageLabel pictureBoxHeli; private MyButton BUT_setup; - private Label lbl_ACHil; - private PictureBox pictureBoxQuadHil; - private System.Windows.Forms.Label lbl_ACY6; + private PictureBox pictureBoxHilimage; + private PictureBox pictureBoxAPHil; + private PictureBox pictureBoxACHil; + private PictureBox pictureBoxACHHil; + private ImageLabel pictureBoxOcta; + private ImageLabel pictureBoxOctav; private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Firmware)); - this.pictureBoxAPM = new System.Windows.Forms.PictureBox(); - this.pictureBoxAPMHIL = new System.Windows.Forms.PictureBox(); - this.pictureBoxQuad = new System.Windows.Forms.PictureBox(); - this.pictureBoxHexa = new System.Windows.Forms.PictureBox(); - this.pictureBoxTri = new System.Windows.Forms.PictureBox(); - this.pictureBoxY6 = new System.Windows.Forms.PictureBox(); + this.pictureBoxAPM = new ArdupilotMega.ImageLabel(); + this.pictureBoxQuad = new ArdupilotMega.ImageLabel(); + this.pictureBoxHexa = new ArdupilotMega.ImageLabel(); + this.pictureBoxTri = new ArdupilotMega.ImageLabel(); + this.pictureBoxY6 = new ArdupilotMega.ImageLabel(); this.lbl_status = new System.Windows.Forms.Label(); this.progress = new System.Windows.Forms.ProgressBar(); - this.lbl_AP = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label(); - this.lbl_APHil = new System.Windows.Forms.Label(); - this.lbl_ACQuad = new System.Windows.Forms.Label(); - this.lbl_ACHexa = new System.Windows.Forms.Label(); - this.lbl_ACTri = new System.Windows.Forms.Label(); - this.lbl_ACY6 = new System.Windows.Forms.Label(); - this.lbl_Heli = new System.Windows.Forms.Label(); - this.pictureBoxHeli = new System.Windows.Forms.PictureBox(); - this.lbl_ACHil = new System.Windows.Forms.Label(); - this.pictureBoxQuadHil = new System.Windows.Forms.PictureBox(); + this.pictureBoxHeli = new ArdupilotMega.ImageLabel(); this.BUT_setup = new ArdupilotMega.MyButton(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBoxAPM)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBoxAPMHIL)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBoxQuad)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBoxHexa)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBoxTri)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBoxY6)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBoxHeli)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBoxQuadHil)).BeginInit(); + this.pictureBoxHilimage = new System.Windows.Forms.PictureBox(); + this.pictureBoxAPHil = new System.Windows.Forms.PictureBox(); + this.pictureBoxACHil = new System.Windows.Forms.PictureBox(); + this.pictureBoxACHHil = new System.Windows.Forms.PictureBox(); + this.pictureBoxOcta = new ArdupilotMega.ImageLabel(); + this.pictureBoxOctav = new ArdupilotMega.ImageLabel(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBoxHilimage)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBoxAPHil)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBoxACHil)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBoxACHHil)).BeginInit(); this.SuspendLayout(); // // pictureBoxAPM @@ -80,19 +68,10 @@ namespace ArdupilotMega.GCSViews this.pictureBoxAPM.TabStop = false; this.pictureBoxAPM.Click += new System.EventHandler(this.pictureBoxAPM_Click); // - // pictureBoxAPMHIL - // - this.pictureBoxAPMHIL.Cursor = System.Windows.Forms.Cursors.Hand; - this.pictureBoxAPMHIL.Image = global::ArdupilotMega.Properties.Resources.APM_airframes_002; - resources.ApplyResources(this.pictureBoxAPMHIL, "pictureBoxAPMHIL"); - this.pictureBoxAPMHIL.Name = "pictureBoxAPMHIL"; - this.pictureBoxAPMHIL.TabStop = false; - this.pictureBoxAPMHIL.Click += new System.EventHandler(this.pictureBoxAPMHIL_Click); - // // pictureBoxQuad // this.pictureBoxQuad.Cursor = System.Windows.Forms.Cursors.Hand; - this.pictureBoxQuad.Image = global::ArdupilotMega.Properties.Resources.frames_03; + this.pictureBoxQuad.Image = ((System.Drawing.Image)(resources.GetObject("pictureBoxQuad.Image"))); resources.ApplyResources(this.pictureBoxQuad, "pictureBoxQuad"); this.pictureBoxQuad.Name = "pictureBoxQuad"; this.pictureBoxQuad.TabStop = false; @@ -101,7 +80,7 @@ namespace ArdupilotMega.GCSViews // pictureBoxHexa // this.pictureBoxHexa.Cursor = System.Windows.Forms.Cursors.Hand; - this.pictureBoxHexa.Image = global::ArdupilotMega.Properties.Resources.frames_07; + this.pictureBoxHexa.Image = global::ArdupilotMega.Properties.Resources.hexa; resources.ApplyResources(this.pictureBoxHexa, "pictureBoxHexa"); this.pictureBoxHexa.Name = "pictureBoxHexa"; this.pictureBoxHexa.TabStop = false; @@ -110,7 +89,7 @@ namespace ArdupilotMega.GCSViews // pictureBoxTri // this.pictureBoxTri.Cursor = System.Windows.Forms.Cursors.Hand; - this.pictureBoxTri.Image = global::ArdupilotMega.Properties.Resources.frames_05; + this.pictureBoxTri.Image = global::ArdupilotMega.Properties.Resources.tri; resources.ApplyResources(this.pictureBoxTri, "pictureBoxTri"); this.pictureBoxTri.Name = "pictureBoxTri"; this.pictureBoxTri.TabStop = false; @@ -119,7 +98,7 @@ namespace ArdupilotMega.GCSViews // pictureBoxY6 // this.pictureBoxY6.Cursor = System.Windows.Forms.Cursors.Hand; - this.pictureBoxY6.Image = global::ArdupilotMega.Properties.Resources.frames_08; + this.pictureBoxY6.Image = global::ArdupilotMega.Properties.Resources.y6; resources.ApplyResources(this.pictureBoxY6, "pictureBoxY6"); this.pictureBoxY6.Name = "pictureBoxY6"; this.pictureBoxY6.TabStop = false; @@ -136,46 +115,11 @@ namespace ArdupilotMega.GCSViews this.progress.Name = "progress"; this.progress.Step = 1; // - // lbl_AP - // - resources.ApplyResources(this.lbl_AP, "lbl_AP"); - this.lbl_AP.Name = "lbl_AP"; - // // label2 // resources.ApplyResources(this.label2, "label2"); this.label2.Name = "label2"; // - // lbl_APHil - // - resources.ApplyResources(this.lbl_APHil, "lbl_APHil"); - this.lbl_APHil.Name = "lbl_APHil"; - // - // lbl_ACQuad - // - resources.ApplyResources(this.lbl_ACQuad, "lbl_ACQuad"); - this.lbl_ACQuad.Name = "lbl_ACQuad"; - // - // lbl_ACHexa - // - resources.ApplyResources(this.lbl_ACHexa, "lbl_ACHexa"); - this.lbl_ACHexa.Name = "lbl_ACHexa"; - // - // lbl_ACTri - // - resources.ApplyResources(this.lbl_ACTri, "lbl_ACTri"); - this.lbl_ACTri.Name = "lbl_ACTri"; - // - // lbl_ACY6 - // - resources.ApplyResources(this.lbl_ACY6, "lbl_ACY6"); - this.lbl_ACY6.Name = "lbl_ACY6"; - // - // lbl_Heli - // - resources.ApplyResources(this.lbl_Heli, "lbl_Heli"); - this.lbl_Heli.Name = "lbl_Heli"; - // // pictureBoxHeli // this.pictureBoxHeli.Cursor = System.Windows.Forms.Cursors.Hand; @@ -185,20 +129,6 @@ namespace ArdupilotMega.GCSViews this.pictureBoxHeli.TabStop = false; this.pictureBoxHeli.Click += new System.EventHandler(this.pictureBoxHeli_Click); // - // lbl_ACHil - // - resources.ApplyResources(this.lbl_ACHil, "lbl_ACHil"); - this.lbl_ACHil.Name = "lbl_ACHil"; - // - // pictureBoxQuadHil - // - this.pictureBoxQuadHil.Cursor = System.Windows.Forms.Cursors.Hand; - this.pictureBoxQuadHil.Image = global::ArdupilotMega.Properties.Resources.new_frames_09; - resources.ApplyResources(this.pictureBoxQuadHil, "pictureBoxQuadHil"); - this.pictureBoxQuadHil.Name = "pictureBoxQuadHil"; - this.pictureBoxQuadHil.TabStop = false; - this.pictureBoxQuadHil.Click += new System.EventHandler(this.pictureBoxQuadHil_Click); - // // BUT_setup // resources.ApplyResources(this.BUT_setup, "BUT_setup"); @@ -206,41 +136,83 @@ namespace ArdupilotMega.GCSViews this.BUT_setup.UseVisualStyleBackColor = true; this.BUT_setup.Click += new System.EventHandler(this.BUT_setup_Click); // + // pictureBoxHilimage + // + this.pictureBoxHilimage.Image = global::ArdupilotMega.Properties.Resources.hil; + resources.ApplyResources(this.pictureBoxHilimage, "pictureBoxHilimage"); + this.pictureBoxHilimage.Name = "pictureBoxHilimage"; + this.pictureBoxHilimage.TabStop = false; + // + // pictureBoxAPHil + // + this.pictureBoxAPHil.Cursor = System.Windows.Forms.Cursors.Hand; + this.pictureBoxAPHil.Image = global::ArdupilotMega.Properties.Resources.hilplane; + resources.ApplyResources(this.pictureBoxAPHil, "pictureBoxAPHil"); + this.pictureBoxAPHil.Name = "pictureBoxAPHil"; + this.pictureBoxAPHil.TabStop = false; + this.pictureBoxAPHil.Click += new System.EventHandler(this.pictureBoxAPHil_Click); + // + // pictureBoxACHil + // + this.pictureBoxACHil.Cursor = System.Windows.Forms.Cursors.Hand; + this.pictureBoxACHil.Image = global::ArdupilotMega.Properties.Resources.hilquad; + resources.ApplyResources(this.pictureBoxACHil, "pictureBoxACHil"); + this.pictureBoxACHil.Name = "pictureBoxACHil"; + this.pictureBoxACHil.TabStop = false; + this.pictureBoxACHil.Click += new System.EventHandler(this.pictureBoxACHil_Click); + // + // pictureBoxACHHil + // + this.pictureBoxACHHil.Cursor = System.Windows.Forms.Cursors.Hand; + this.pictureBoxACHHil.Image = global::ArdupilotMega.Properties.Resources.hilheli; + resources.ApplyResources(this.pictureBoxACHHil, "pictureBoxACHHil"); + this.pictureBoxACHHil.Name = "pictureBoxACHHil"; + this.pictureBoxACHHil.TabStop = false; + this.pictureBoxACHHil.Click += new System.EventHandler(this.pictureBoxACHHil_Click); + // + // pictureBoxOcta + // + this.pictureBoxOcta.Image = global::ArdupilotMega.Properties.Resources.octo; + resources.ApplyResources(this.pictureBoxOcta, "pictureBoxOcta"); + this.pictureBoxOcta.Name = "pictureBoxOcta"; + this.pictureBoxOcta.TabStop = false; + this.pictureBoxOcta.Click += new System.EventHandler(this.pictureBoxOcta_Click); + // + // pictureBoxOctav + // + this.pictureBoxOctav.Image = global::ArdupilotMega.Properties.Resources.octov; + resources.ApplyResources(this.pictureBoxOctav, "pictureBoxOctav"); + this.pictureBoxOctav.Name = "pictureBoxOctav"; + this.pictureBoxOctav.TabStop = false; + this.pictureBoxOctav.Click += new System.EventHandler(this.pictureBoxOctav_Click); + // // Firmware // resources.ApplyResources(this, "$this"); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.Controls.Add(this.lbl_ACHil); - this.Controls.Add(this.pictureBoxQuadHil); + this.Controls.Add(this.pictureBoxOctav); + this.Controls.Add(this.pictureBoxOcta); + this.Controls.Add(this.pictureBoxACHHil); + this.Controls.Add(this.pictureBoxACHil); + this.Controls.Add(this.pictureBoxAPHil); + this.Controls.Add(this.pictureBoxHilimage); this.Controls.Add(this.BUT_setup); - this.Controls.Add(this.lbl_Heli); this.Controls.Add(this.pictureBoxHeli); - this.Controls.Add(this.lbl_ACY6); - this.Controls.Add(this.lbl_ACTri); - this.Controls.Add(this.lbl_ACHexa); - this.Controls.Add(this.lbl_ACQuad); - this.Controls.Add(this.lbl_APHil); this.Controls.Add(this.label2); - this.Controls.Add(this.lbl_AP); this.Controls.Add(this.lbl_status); this.Controls.Add(this.progress); this.Controls.Add(this.pictureBoxY6); this.Controls.Add(this.pictureBoxTri); this.Controls.Add(this.pictureBoxHexa); this.Controls.Add(this.pictureBoxQuad); - this.Controls.Add(this.pictureBoxAPMHIL); this.Controls.Add(this.pictureBoxAPM); this.MinimumSize = new System.Drawing.Size(1008, 461); this.Name = "Firmware"; this.Load += new System.EventHandler(this.FirmwareVisual_Load); - ((System.ComponentModel.ISupportInitialize)(this.pictureBoxAPM)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBoxAPMHIL)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBoxQuad)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBoxHexa)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBoxTri)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBoxY6)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBoxHeli)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBoxQuadHil)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBoxHilimage)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBoxAPHil)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBoxACHil)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBoxACHHil)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -384,39 +356,47 @@ namespace ArdupilotMega.GCSViews { if (temp.url.ToLower().Contains("firmware/AP-1".ToLower())) { - lbl_AP.Text = temp.name; + pictureBoxAPM.Text = temp.name; } else if (temp.url.ToLower().Contains("firmware/APHIL-".ToLower())) { - lbl_APHil.Text = temp.name; + pictureBoxAPHil.Text = temp.name; } else if (temp.url.ToLower().Contains("firmware/ac2-quad-".ToLower())) { - lbl_ACQuad.Text = temp.name; + pictureBoxQuad.Text = temp.name; } else if (temp.url.ToLower().Contains("firmware/ac2-tri".ToLower())) { - lbl_ACTri.Text = temp.name; + pictureBoxTri.Text = temp.name; } else if (temp.url.ToLower().Contains("firmware/ac2-hexa".ToLower())) { - lbl_ACHexa.Text = temp.name; + pictureBoxHexa.Text = temp.name; } else if (temp.url.ToLower().Contains("firmware/ac2-y6".ToLower())) { - lbl_ACY6.Text = temp.name; + pictureBoxY6.Text = temp.name; } else if (temp.url.ToLower().Contains("firmware/ac2-heli-1".ToLower())) { - lbl_Heli.Text = temp.name; + pictureBoxHeli.Text = temp.name; } else if (temp.url.ToLower().Contains("firmware/ac2-quadhil".ToLower())) { - lbl_ACHil.Text = temp.name; + pictureBoxACHil.Text = temp.name; + } + else if (temp.url.ToLower().Contains("firmware/ac2-octav-".ToLower())) + { + pictureBoxOctav.Text = temp.name; + } + else if (temp.url.ToLower().Contains("firmware/ac2-octa-".ToLower())) + { + pictureBoxOcta.Text = temp.name; } else { - Console.WriteLine("No Home "+ temp.name + " " + temp.url); + Console.WriteLine("No Home " + temp.name + " " + temp.url); } } @@ -546,7 +526,7 @@ namespace ArdupilotMega.GCSViews return; } - Console.WriteLine("Using "+baseurl); + Console.WriteLine("Using " + baseurl); // Create a request using a URL that can receive a post. WebRequest request = WebRequest.Create(baseurl); @@ -736,7 +716,7 @@ namespace ArdupilotMega.GCSViews byte[] readIntelHEXv2(StreamReader sr) { - byte[] FLASH = new byte[sr.BaseStream.Length / 2]; + byte[] FLASH = new byte[1024 * 1024]; int optionoffset = 0; int total = 0; @@ -770,7 +750,7 @@ namespace ArdupilotMega.GCSViews } else if (option == 2) { - optionoffset += (int)Convert.ToUInt16(line.Substring(9, 4), 16) << 4; + optionoffset = (int)Convert.ToUInt16(line.Substring(9, 4), 16) << 4; } else if (option == 1) { @@ -779,8 +759,8 @@ namespace ArdupilotMega.GCSViews int checksum = Convert.ToInt32(line.Substring(line.Length - 2, 2), 16); byte checksumact = 0; - for (int z = 0; z < ((line.Length - 1 - 2) / 2) ; z++) // minus 1 for : then mins 2 for checksum itself - { + for (int z = 0; z < ((line.Length - 1 - 2) / 2); z++) // minus 1 for : then mins 2 for checksum itself + { checksumact += Convert.ToByte(line.Substring(z * 2 + 1, 2), 16); } checksumact = (byte)(0x100 - checksumact); @@ -820,5 +800,30 @@ namespace ArdupilotMega.GCSViews MainV2.fixtheme(temp); temp.ShowDialog(); } + + private void pictureBoxOctav_Click(object sender, EventArgs e) + { + findfirmware("AC2-Octav-"); + } + + private void pictureBoxOcta_Click(object sender, EventArgs e) + { + findfirmware("AC2-Octa-"); + } + + private void pictureBoxAPHil_Click(object sender, EventArgs e) + { + findfirmware("Firmware/APHIL-"); + } + + private void pictureBoxACHil_Click(object sender, EventArgs e) + { + findfirmware("AC2-QUADHIL-"); + } + + private void pictureBoxACHHil_Click(object sender, EventArgs e) + { + findfirmware("AC2-HELHIL-"); + } } } \ No newline at end of file diff --git a/Tools/ArdupilotMegaPlanner/GCSViews/Firmware.resx b/Tools/ArdupilotMegaPlanner/GCSViews/Firmware.resx index 3e8d6b5151..bf9f0a8918 100644 --- a/Tools/ArdupilotMegaPlanner/GCSViews/Firmware.resx +++ b/Tools/ArdupilotMegaPlanner/GCSViews/Firmware.resx @@ -123,13 +123,10 @@ - 7, -9 + 94, 0 - 190, 190 - - - Zoom + 170, 170 @@ -139,52 +136,650 @@ pictureBoxAPM - System.Windows.Forms.PictureBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ArdupilotMega.ImageLabel, ArdupilotMegaPlanner, Version=1.0.0.0, Culture=neutral, PublicKeyToken=38326cb7e06851fc $this - 19 + 15 - - NoControl - - - 7, 184 - - - 190, 190 - - - Zoom - - - 1 - - - pictureBoxAPMHIL - - - System.Windows.Forms.PictureBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 18 + + + 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 + BsBA6RggEgeGS8cw7w+GozAQdVHLrJdvZ9YHBrLDACQOB4gvAwNNYqDJj8YJGyd83P1OGIvsCAk6Ge6M + IHHhYwbO2hyzg87mn2P367H7KHJ7inx4dbt+p1NiHXJ+YIAxKB0DkDgwXDqGp35/kbd7ne2/tLZ/6udx + /5l0koGeaaAzIEuH3TtcWAV2/0Di2pF/zboOiQPHNeN77LedPrtZPZbR/+xq5Wz/2HtyfSY6hyAyEcSE + JM/MwF7crp9Jey8+erE+/D8/g8TVL/eWdBsSB55bwvvQbz25Xq0fydh/dHm7PvmHJ+t7D59D4irTlaFg + 4LwyBX+vU+Kn0tr7n1yvj/7+8/Ub/9tvzI90KmnkCScOc9sLSFyZ9mlunLTyvOPLm9W7jrydvvd0Y/ch + cfXZ/VZAXdt3Krp23P1ObF2bnNi5uJrq3W5W6188v1m9kBI/+Oxmffz/fLFR4h6JM1zukxerB7ZOTulW + 3evU3l/PqW3s+J76ZAqJq0+m6Ol2mcru63fm2f77sv3Xt+sfdZN2k2b5/Gq1EmE7+N///RXb75G4tVKs + XXr1PV3r3Uv3PsTul+P3UJS8jZ8ja3JSF1bhXBRt67+dEptD4XN/BubIm/tXyqzf+T9/aaJ0+nn1Ept7 + K5JnCZ7eQaQRYpc3ZlrUaUgcmKwN90d2Mn0u++tq2u40/vaPsul98ubsvib0zva/9fGVsfvyFdsO628U + HNCkXu9T2xhX8T1VfERF4NIMSApz8fR69b6vWCJYUjgpqJRQyqif6hwef7laO/Km885+cvla5K1P4u76 + /5V2dfUTUvS+kn95u/5Y7wipw6hlonuQOBxs6b5MEbB7Lg3q235lU2SHZfc1MZfdl41+85cm2bI5XL1z + iK33z1WttO4t/+Em9/79tbK1s/1vd/9NUUBIXSY6Vzrwa3h/Ke95n7SJsElpRaakXH3F1H/7zr9erzvF + MofI27bweaxC96/TzM7N4vRu/tEp9kOr2IThM1HsTMjVXPoJiQN3c2Et1XNkK88sKdqYUxE2kTGRNb+G + 2bfH//H9L9fddZuJe7/eOZXNd/fRe4jY6b38Cb2dzCtSpwxNqnHhPoFjyYAFDlgisAr0F17PHlO75iJs + dymhyJRmSf0Z2K7weWqF9u8ngql36Sk2hG4ZTLWsy5A4MFcC/h1xk400h2ynI237bLjs7acvVuvnNy+v + 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 + 9sXsCwyAATAABsAAGIDEQeLAABgAA2AADIABMFAgBhBagUJj9sXsCwyAATAABsAAGIDEQeLAABgAA2AA + DIABMFAgBhBagUJj9sXsCwyAATAABsAAGIDEQeLAABgAA2AADIABMFAgBhBagUJj9sXsCwyAATAABsAA + GIDEQeLAABgAA2AADIABMFAgBhBagUJj9sXsCwyAATAABsAAGIDEQeLAABgAA2AADIABMFAgBhBagUJj + 9sXsCwyAATAABsAAGIDEQeLAABgAA2AADIABMFAgBhBagUJj9sXsCwyAATAABsAAGIDEQeLAABgAA2AA + DIABMFAgBhBagUJj9sXsCwyAATAABsAAGIDEQeLAABgAA2AADIABMFAgBhBagUJj9sXsCwyAATAABsAA + GIDEQeLAABgAA2AADIABMFAgBhBagUJj9sXsCwyAATAABsAAGIDEQeLAABgAA2AADIABMFAgBhBagUJj + 9sXsCwyAATAABsAAGIDEQeLAABgAA2AADIABMFAgBhBagUJj9sXsCwyAATAABsAAGIDEQeLAABgAA2AA + DIABMFAgBhBagUJj9sXsCwyAATAABsAAGIDEQeLAABgAA2AADIABMFAgBhBagUJj9sXsCwyAATAABsAA + GIDEQeLAABgAA2AADIABMFAgBv5/FOw4h5UG/3QAAAAASUVORK5CYII= + NoControl - 399, -9 + 304, 0 - 190, 190 - - - Zoom + 170, 170 2 @@ -193,25 +788,22 @@ pictureBoxQuad - System.Windows.Forms.PictureBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ArdupilotMega.ImageLabel, ArdupilotMegaPlanner, Version=1.0.0.0, Culture=neutral, PublicKeyToken=38326cb7e06851fc $this - 17 + 14 NoControl - 595, -8 + 500, 0 - 190, 190 - - - Zoom + 170, 170 3 @@ -220,25 +812,22 @@ pictureBoxHexa - System.Windows.Forms.PictureBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ArdupilotMega.ImageLabel, ArdupilotMegaPlanner, Version=1.0.0.0, Culture=neutral, PublicKeyToken=38326cb7e06851fc $this - 16 + 13 NoControl - 399, 185 + 304, 176 - 190, 190 - - - Zoom + 170, 170 4 @@ -247,25 +836,22 @@ pictureBoxTri - System.Windows.Forms.PictureBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ArdupilotMega.ImageLabel, ArdupilotMegaPlanner, Version=1.0.0.0, Culture=neutral, PublicKeyToken=38326cb7e06851fc $this - 15 + 12 NoControl - 595, 186 + 500, 176 - 190, 190 - - - Zoom + 170, 170 5 @@ -274,13 +860,13 @@ pictureBoxY6 - System.Windows.Forms.PictureBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ArdupilotMega.ImageLabel, ArdupilotMegaPlanner, Version=1.0.0.0, Culture=neutral, PublicKeyToken=38326cb7e06851fc $this - 14 + 11 True @@ -310,7 +896,7 @@ $this - 12 + 9 NoControl @@ -334,37 +920,7 @@ $this - 13 - - - NoControl - - - 4, 168 - - - 190, 13 - - - 8 - - - ArduPlane - - - TopCenter - - - lbl_AP - - - System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 11 + 10 True @@ -394,199 +950,16 @@ $this - 10 - - - NoControl - - - 4, 361 - - - 190, 13 - - - 10 - - - ArduPlane (Xplane simulator) - - - TopCenter - - - lbl_APHil - - - System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 9 - - - NoControl - - - 396, 169 - - - 190, 13 - - - 11 - - - ArduCopter Quad - - - TopCenter - - - lbl_ACQuad - - - System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - 8 - - NoControl - - - 592, 170 - - - 190, 13 - - - 12 - - - ArduCopter Hexa - - - TopCenter - - - lbl_ACHexa - - - System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 7 - - - NoControl - - - 396, 362 - - - 190, 13 - - - 13 - - - ArduCopter Tri - - - TopCenter - - - lbl_ACTri - - - System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 6 - - - NoControl - - - 592, 363 - - - 190, 13 - - - 14 - - - ArduCopter Y6 - - - TopCenter - - - lbl_ACY6 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 5 - - - NoControl - - - 200, 167 - - - 190, 13 - - - 18 - - - ArduCopter Heli - - - TopCenter - - - lbl_Heli - - - System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - NoControl - 203, -9 + 94, 176 - 190, 190 - - - Zoom + 170, 170 17 @@ -595,70 +968,13 @@ pictureBoxHeli - System.Windows.Forms.PictureBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ArdupilotMega.ImageLabel, ArdupilotMegaPlanner, Version=1.0.0.0, Culture=neutral, PublicKeyToken=38326cb7e06851fc $this - 4 - - - NoControl - - - 200, 361 - - - 190, 13 - - - 21 - - - ArduCopter Quad (Simulator) - - - TopCenter - - - lbl_ACHil - - - System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - NoControl - - - 203, 184 - - - 190, 190 - - - Zoom - - - 20 - - - pictureBoxQuadHil - - - System.Windows.Forms.PictureBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 + 7 NoControl @@ -685,8 +1001,155 @@ $this + 6 + + + 10, 362 + + + 0, 0, 0, 0 + + + 140, 50 + + + 20 + + + pictureBoxHilimage + + + System.Windows.Forms.PictureBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 5 + + + NoControl + + + 149, 362 + + + 0, 0, 0, 0 + + + 54, 50 + + + 21 + + + pictureBoxAPHil + + + System.Windows.Forms.PictureBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 4 + + + NoControl + + + 202, 362 + + + 0, 0, 0, 0 + + + 50, 50 + + + 22 + + + pictureBoxACHil + + + System.Windows.Forms.PictureBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 3 + + + NoControl + + + 251, 362 + + + 0, 0, 0, 0 + + + 45, 50 + + + 23 + + + pictureBoxACHHil + + + System.Windows.Forms.PictureBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + 2 + + 696, 176 + + + 170, 170 + + + 24 + + + pictureBoxOcta + + + ArdupilotMega.ImageLabel, ArdupilotMegaPlanner, Version=1.0.0.0, Culture=neutral, PublicKeyToken=38326cb7e06851fc + + + $this + + + 1 + + + 696, 0 + + + 170, 170 + + + 25 + + + pictureBoxOctav + + + ArdupilotMega.ImageLabel, ArdupilotMegaPlanner, Version=1.0.0.0, Culture=neutral, PublicKeyToken=38326cb7e06851fc + + + $this + + + 0 + True diff --git a/Tools/ArdupilotMegaPlanner/GCSViews/FlightData.cs b/Tools/ArdupilotMegaPlanner/GCSViews/FlightData.cs index e461f5559a..9b8de50aa4 100644 --- a/Tools/ArdupilotMegaPlanner/GCSViews/FlightData.cs +++ b/Tools/ArdupilotMegaPlanner/GCSViews/FlightData.cs @@ -79,6 +79,7 @@ namespace ArdupilotMega.GCSViews protected override void Dispose(bool disposing) { + threadrun = 0; MainV2.config["FlightSplitter"] = MainH.SplitterDistance.ToString(); base.Dispose(disposing); } @@ -91,7 +92,8 @@ namespace ArdupilotMega.GCSViews myhud = hud1; MainHcopy = MainH; - Control.CheckForIllegalCrossThreadCalls = false; // so can update display from another thread + int checkme; + //Control.CheckForIllegalCrossThreadCalls = false; // so can update display from another thread // setup default tuning graph if (MainV2.config["Tuning_Graph_Selected"] != null) @@ -292,7 +294,10 @@ namespace ArdupilotMega.GCSViews if (MainV2.comPort.logreadmode && MainV2.comPort.logplaybackfile != null) { - BUT_playlog.Text = "Pause"; + this.Invoke((System.Windows.Forms.MethodInvoker)delegate() +{ + BUT_playlog.Text = "Pause"; +}); if (comPort.BaseStream.IsOpen) MainV2.comPort.logreadmode = false; @@ -311,12 +316,12 @@ namespace ArdupilotMega.GCSViews if (act > 9999 || act < 0) act = 1; - int ts = 1; + int ts = 0; try { ts = (int)(act / (double)NUM_playbackspeed.Value); } - catch { } // cross thread + catch { } if (ts > 0) System.Threading.Thread.Sleep(ts); @@ -336,7 +341,15 @@ namespace ArdupilotMega.GCSViews } else { - BUT_playlog.Text = "Play"; + if (threadrun == 0) { return; } + try + { + this.Invoke((System.Windows.Forms.MethodInvoker)delegate() + { + BUT_playlog.Text = "Play"; + }); + } + catch { } } try diff --git a/Tools/ArdupilotMegaPlanner/GCSViews/Help.cs b/Tools/ArdupilotMegaPlanner/GCSViews/Help.cs index e7eab13a76..93d7524f67 100644 --- a/Tools/ArdupilotMegaPlanner/GCSViews/Help.cs +++ b/Tools/ArdupilotMegaPlanner/GCSViews/Help.cs @@ -14,6 +14,12 @@ namespace ArdupilotMega.GCSViews public Help() { InitializeComponent(); + + try + { + CHK_showconsole.Checked = MainV2.config["showconsole"].ToString() == "True"; + } + catch { } } private void BUT_updatecheck_Click(object sender, EventArgs e) diff --git a/Tools/ArdupilotMegaPlanner/GCSViews/Simulation.cs b/Tools/ArdupilotMegaPlanner/GCSViews/Simulation.cs index 3d60418cfd..601def43a7 100644 --- a/Tools/ArdupilotMegaPlanner/GCSViews/Simulation.cs +++ b/Tools/ArdupilotMegaPlanner/GCSViews/Simulation.cs @@ -238,6 +238,12 @@ namespace ArdupilotMega.GCSViews { quad = new HIL.QuadCopter(); + if (RAD_JSBSim.Checked) + { + simPort = 5124; + recvPort = 5123; + } + SetupUDPRecv(); if (RAD_softXplanes.Checked) @@ -1002,11 +1008,11 @@ namespace ArdupilotMega.GCSViews #else imu.usec = ((ulong)DateTime.Now.ToBinary()); #endif - imu.xgyro = (short)(fdm.phidot * 1150); // roll - yes + imu.xgyro = (short)(fdm.phidot); // roll - yes //imu.xmag = (short)(Math.Sin(head * deg2rad) * 1000); - imu.ygyro = (short)(fdm.thetadot * 1150); // pitch - yes + imu.ygyro = (short)(fdm.thetadot); // pitch - yes //imu.ymag = (short)(Math.Cos(head * deg2rad) * 1000); - imu.zgyro = (short)(fdm.psidot * 1150); + imu.zgyro = (short)(fdm.psidot); imu.zmag = 0; imu.xacc = (Int16)Math.Min(Int16.MaxValue, Math.Max(Int16.MinValue, (fdm.A_X_pilot * 9808 / 32.2))); // pitch @@ -1906,22 +1912,18 @@ namespace ArdupilotMega.GCSViews if (File.Exists(@"C:\Program Files (x86)\FlightGear\bin\Win32\fgfs.exe")) { ofd.InitialDirectory = @"C:\Program Files (x86)\FlightGear\bin\Win32\"; - extra = " --fg-root=\"C:\\Program Files (x86)\\FlightGear\\data\""; } else if (File.Exists(@"C:\Program Files\FlightGear\bin\Win32\fgfs.exe")) { ofd.InitialDirectory = @"C:\Program Files\FlightGear\bin\Win32\"; - extra = " --fg-root=\"C:\\Program Files\\FlightGear\\data\""; } else if (File.Exists(@"C:\Program Files\FlightGear 2.4.0\bin\Win32\fgfs.exe")) { ofd.InitialDirectory = @"C:\Program Files\FlightGear 2.4.0\bin\Win32\"; - extra = " --fg-root=\"C:\\Program Files\\FlightGear 2.4.0\\data\""; } else if (File.Exists(@"C:\Program Files (x86)\FlightGear 2.4.0\bin\Win32\fgfs.exe")) { ofd.InitialDirectory = @"C:\Program Files (x86)\FlightGear 2.4.0\bin\Win32\"; - extra = " --fg-root=\"C:\\Program Files (x86)\\FlightGear 2.4.0\\data\""; } else if (File.Exists(@"/usr/games/fgfs")) { @@ -1939,6 +1941,11 @@ namespace ArdupilotMega.GCSViews ofd.FileName = MainV2.config["fgexe"].ToString(); } + if (!MainV2.MONO) + { + extra = " --fg-root=\"" + Path.GetDirectoryName(ofd.FileName.ToLower().Replace("bin\\win32\\","")) + "\\data\""; + } + System.Diagnostics.Process P = new System.Diagnostics.Process(); P.StartInfo.FileName = ofd.FileName; P.StartInfo.Arguments = extra + @" --geometry=400x300 --native-fdm=socket,out,50,127.0.0.1,49005,udp --generic=socket,in,50,127.0.0.1,49000,udp,MAVLink --roll=0 --pitch=0 --wind=0@0 --turbulence=0.0 --prop:/sim/frame-rate-throttle-hz=30 --timeofday=noon --shading-flat --fog-disable --disable-specular-highlight --disable-skyblend --disable-random-objects --disable-panel --disable-horizon-effect --disable-clouds --disable-anti-alias-hud "; diff --git a/Tools/ArdupilotMegaPlanner/GCSViews/Terminal.cs b/Tools/ArdupilotMegaPlanner/GCSViews/Terminal.cs index 241f022370..b3ace064dd 100644 --- a/Tools/ArdupilotMegaPlanner/GCSViews/Terminal.cs +++ b/Tools/ArdupilotMegaPlanner/GCSViews/Terminal.cs @@ -27,8 +27,6 @@ namespace ArdupilotMega.GCSViews threadrun = false; InitializeComponent(); - - Control.CheckForIllegalCrossThreadCalls = false; // so can update display from another thread } void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e) @@ -39,21 +37,33 @@ namespace ArdupilotMega.GCSViews { lock (thisLock) { - TXT_terminal.SelectionStart = TXT_terminal.Text.Length; string data = comPort.ReadExisting(); - data = data.TrimEnd('\r'); // else added \n all by itself - TXT_terminal.AppendText(data); - if (data.Contains("\b")) - { - TXT_terminal.Text = TXT_terminal.Text.Remove(TXT_terminal.Text.IndexOf('\b')); - TXT_terminal.SelectionStart = TXT_terminal.Text.Length; - } - inputStartPos = TXT_terminal.SelectionStart; + //Console.Write(data); + + addText(data); } } catch (Exception) { if (!threadrun) return; TXT_terminal.AppendText("Error reading com port\r\n"); } } + void addText(string data) + { + this.Invoke((System.Windows.Forms.MethodInvoker)delegate() + { + TXT_terminal.SelectionStart = TXT_terminal.Text.Length; + + data = data.TrimEnd('\r'); // else added \n all by itself + data = data.Replace("\0", " "); + TXT_terminal.AppendText(data); + if (data.Contains("\b")) + { + TXT_terminal.Text = TXT_terminal.Text.Remove(TXT_terminal.Text.IndexOf('\b')); + TXT_terminal.SelectionStart = TXT_terminal.Text.Length; + } + inputStartPos = TXT_terminal.SelectionStart; + }); + } + private void TXT_terminal_Click(object sender, EventArgs e) { // auto scroll @@ -174,9 +184,17 @@ namespace ArdupilotMega.GCSViews { threadrun = true; - System.Threading.Thread.Sleep(2000); + DateTime start = DateTime.Now; - comPort.Write("\n\n\n\n\n"); + while ((DateTime.Now - start).TotalMilliseconds < 2000) + { + if (comPort.BytesToRead > 0) + { + comPort_DataReceived((object)null, (SerialDataReceivedEventArgs)null); + } + } + + comPort.Write("\n\n\n"); while (threadrun) { @@ -194,6 +212,9 @@ namespace ArdupilotMega.GCSViews } catch { } } + + comPort.DtrEnable = false; + if (threadrun == false) { comPort.Close(); diff --git a/Tools/ArdupilotMegaPlanner/Joystick.cs b/Tools/ArdupilotMegaPlanner/Joystick.cs index 2339b6fbb4..060e50f5d5 100644 --- a/Tools/ArdupilotMegaPlanner/Joystick.cs +++ b/Tools/ArdupilotMegaPlanner/Joystick.cs @@ -322,7 +322,7 @@ namespace ArdupilotMega { if (but.buttonno != -1 && getButtonState(but.buttonno)) { - MainV2.instance.Invoke((System.Windows.Forms.MethodInvoker)delegate() + MainV2.instance.BeginInvoke((System.Windows.Forms.MethodInvoker)delegate() { try { @@ -470,7 +470,7 @@ namespace ArdupilotMega { byte[] buts = state.GetButtons(); - if (buts == null) + if (buts == null || JoyButtons[buttonno].buttonno < 0) return false; return buts[JoyButtons[buttonno].buttonno] > 0; @@ -483,7 +483,7 @@ namespace ArdupilotMega state = joystick.CurrentJoystickState; ushort ans = pickchannel(channel, JoyChannels[channel].axis, JoyChannels[channel].reverse, JoyChannels[channel].expo); - + Console.WriteLine("{0} = {1} = {2}",channel,ans, state.X); return ans; } diff --git a/Tools/ArdupilotMegaPlanner/JoystickSetup.cs b/Tools/ArdupilotMegaPlanner/JoystickSetup.cs index 782e54ee3f..6e6d33511a 100644 --- a/Tools/ArdupilotMegaPlanner/JoystickSetup.cs +++ b/Tools/ArdupilotMegaPlanner/JoystickSetup.cs @@ -241,6 +241,8 @@ namespace ArdupilotMega joy.AcquireJoystick(CMB_joysticks.Text); + joy.name = CMB_joysticks.Text; + noButtons = joy.getNumButtons(); for (int f = 0; f < noButtons; f++) @@ -289,10 +291,11 @@ namespace ArdupilotMega for (int f = 0; f < noButtons; f++) { string name = (f + 1).ToString(); - ((HorizontalProgressBar)this.Controls.Find("hbar" + name, false)[0]).Value = MainV2.joystick.isButtonPressed(f) ? 100 : 0; + + ((HorizontalProgressBar)this.Controls.Find("hbar" + name, false)[0]).Value = MainV2.joystick.isButtonPressed(f) ? 100 : 0; } } - catch { } + catch (Exception ex) { } } diff --git a/Tools/ArdupilotMegaPlanner/Log.cs b/Tools/ArdupilotMegaPlanner/Log.cs index 68e31dd776..4fe8b67da1 100644 --- a/Tools/ArdupilotMegaPlanner/Log.cs +++ b/Tools/ArdupilotMegaPlanner/Log.cs @@ -57,8 +57,6 @@ namespace ArdupilotMega public Log() { InitializeComponent(); - - Control.CheckForIllegalCrossThreadCalls = false; // so can update display from another thread } private void Log_Load(object sender, EventArgs e) @@ -140,7 +138,10 @@ namespace ArdupilotMega { if (start.Second != DateTime.Now.Second) { - TXT_status.Text = status.ToString() + " " + receivedbytes + " " + comPort.BytesToRead; + this.BeginInvoke((System.Windows.Forms.MethodInvoker)delegate() +{ + TXT_status.Text = status.ToString() + " " + receivedbytes + " " + comPort.BytesToRead; +}); start = DateTime.Now; } } @@ -206,7 +207,10 @@ namespace ArdupilotMega MainV2.cs.firmware = MainV2.Firmwares.ArduPlane; - TXT_seriallog.AppendText("Createing KML for " + logfile); + this.Invoke((System.Windows.Forms.MethodInvoker)delegate() +{ + TXT_seriallog.AppendText("Createing KML for " + logfile); +}); while (tr.Peek() != -1) { @@ -230,7 +234,10 @@ namespace ArdupilotMega status = serialstatus.Waiting; lock (thisLock) { - TXT_seriallog.Clear(); + this.Invoke((System.Windows.Forms.MethodInvoker)delegate() +{ + TXT_seriallog.Clear(); +}); } //if (line.Contains("Dumping Log")) { @@ -257,7 +264,7 @@ namespace ArdupilotMega } lock (thisLock) { - this.BeginInvoke((System.Threading.ThreadStart)delegate() + this.BeginInvoke((MethodInvoker)delegate() { Console.Write(line); diff --git a/Tools/ArdupilotMegaPlanner/MainV2.cs b/Tools/ArdupilotMegaPlanner/MainV2.cs index 4391fbd290..3ec6f59792 100644 --- a/Tools/ArdupilotMegaPlanner/MainV2.cs +++ b/Tools/ArdupilotMegaPlanner/MainV2.cs @@ -254,7 +254,8 @@ namespace ArdupilotMega if (MONO) { - devs = Directory.GetFiles("/dev/", "*ACM*"); + if (Directory.Exists("/dev/")) + devs = Directory.GetFiles("/dev/", "*ACM*"); } string[] ports = SerialPort.GetPortNames(); @@ -1298,7 +1299,12 @@ namespace ArdupilotMega // makesure we have valid image GCSViews.FlightData.mymap.streamjpgenable = true; GCSViews.FlightData.myhud.streamjpgenable = true; - GCSViews.FlightData.mymap.Refresh(); + + MethodInvoker m = delegate() + { + GCSViews.FlightData.mymap.Refresh(); + }; + this.Invoke(m); NetworkStream stream = client.GetStream(); diff --git a/Tools/ArdupilotMegaPlanner/MavlinkLog.cs b/Tools/ArdupilotMegaPlanner/MavlinkLog.cs index 7b17af0a54..21963759d9 100644 --- a/Tools/ArdupilotMegaPlanner/MavlinkLog.cs +++ b/Tools/ArdupilotMegaPlanner/MavlinkLog.cs @@ -33,8 +33,6 @@ namespace ArdupilotMega public MavlinkLog() { InitializeComponent(); - - Control.CheckForIllegalCrossThreadCalls = false; // so can update display from another thread } private void writeKML(string filename) @@ -371,10 +369,13 @@ namespace ArdupilotMega float oldlatlngalt = 0; + DateTime appui = DateTime.Now; + while (mine.logplaybackfile.BaseStream.Position < mine.logplaybackfile.BaseStream.Length) { // bar moves to 50 % in this step progressBar1.Value = (int)((float)mine.logplaybackfile.BaseStream.Position / (float)mine.logplaybackfile.BaseStream.Length * 100.0f / 2.0f); + progressBar1.Invalidate(); progressBar1.Refresh(); byte[] packet = mine.readPacket(); @@ -383,9 +384,11 @@ namespace ArdupilotMega cs.UpdateCurrentSettings(null, true, mine); - if (cs.datetime.Second % 5 == 0) + if (appui != DateTime.Now) { - //Application.DoEvents(); + // cant do entire app as mixes with flightdata timer + this.Refresh(); + appui = DateTime.Now; } try @@ -411,6 +414,7 @@ namespace ArdupilotMega mine.logplaybackfile.Close(); mine.logplaybackfile = null; + Application.DoEvents(); writeKML(logfile + ".kml"); diff --git a/Tools/ArdupilotMegaPlanner/Program.cs b/Tools/ArdupilotMegaPlanner/Program.cs index 6c2ef0edd1..aab82e687e 100644 --- a/Tools/ArdupilotMegaPlanner/Program.cs +++ b/Tools/ArdupilotMegaPlanner/Program.cs @@ -28,7 +28,13 @@ namespace ArdupilotMega Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new MainV2()); + try + { + + Application.Run(new MainV2()); + + } + catch (Exception ex) { Console.WriteLine(ex.ToString()); } } static void Application_Idle(object sender, EventArgs e) diff --git a/Tools/ArdupilotMegaPlanner/Properties/AssemblyInfo.cs b/Tools/ArdupilotMegaPlanner/Properties/AssemblyInfo.cs index bee2fdc106..2fcc2a3ac8 100644 --- a/Tools/ArdupilotMegaPlanner/Properties/AssemblyInfo.cs +++ b/Tools/ArdupilotMegaPlanner/Properties/AssemblyInfo.cs @@ -34,5 +34,5 @@ using System.Resources; // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.1.7")] +[assembly: AssemblyFileVersion("1.1.8")] [assembly: NeutralResourcesLanguageAttribute("")] diff --git a/Tools/ArdupilotMegaPlanner/Properties/Resources.Designer.cs b/Tools/ArdupilotMegaPlanner/Properties/Resources.Designer.cs index 9e5b401c50..cb850fdcbc 100644 --- a/Tools/ArdupilotMegaPlanner/Properties/Resources.Designer.cs +++ b/Tools/ArdupilotMegaPlanner/Properties/Resources.Designer.cs @@ -109,13 +109,6 @@ namespace ArdupilotMega.Properties { } } - public static System.Drawing.Bitmap BR_0016_01_3T { - get { - object obj = ResourceManager.GetObject("BR_0016_01_3T", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - public static System.Drawing.Bitmap compass { get { object obj = ResourceManager.GetObject("compass", resourceCulture); @@ -165,27 +158,6 @@ namespace ArdupilotMega.Properties { } } - public static System.Drawing.Bitmap frames_03 { - get { - object obj = ResourceManager.GetObject("frames_03", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - public static System.Drawing.Bitmap frames_04 { - get { - object obj = ResourceManager.GetObject("frames_04", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - public static System.Drawing.Bitmap frames_05 { - get { - object obj = ResourceManager.GetObject("frames_05", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - public static System.Drawing.Bitmap frames_06 { get { object obj = ResourceManager.GetObject("frames_06", resourceCulture); @@ -193,20 +165,6 @@ namespace ArdupilotMega.Properties { } } - public static System.Drawing.Bitmap frames_07 { - get { - object obj = ResourceManager.GetObject("frames_07", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - public static System.Drawing.Bitmap frames_08 { - get { - object obj = ResourceManager.GetObject("frames_08", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - public static System.Drawing.Bitmap Gaugebg { get { object obj = ResourceManager.GetObject("Gaugebg", resourceCulture); @@ -221,23 +179,65 @@ namespace ArdupilotMega.Properties { } } - public static System.Drawing.Bitmap new_frames_09 { + public static System.Drawing.Bitmap hexa { get { - object obj = ResourceManager.GetObject("new_frames_09", resourceCulture); + object obj = ResourceManager.GetObject("hexa", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } - public static System.Drawing.Bitmap plane2 { + public static System.Drawing.Bitmap hil { get { - object obj = ResourceManager.GetObject("plane2", resourceCulture); + object obj = ResourceManager.GetObject("hil", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } - public static System.Drawing.Bitmap planetracker { + public static System.Drawing.Bitmap hilheli { get { - object obj = ResourceManager.GetObject("planetracker", resourceCulture); + object obj = ResourceManager.GetObject("hilheli", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap hilplane { + get { + object obj = ResourceManager.GetObject("hilplane", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap hilquad { + get { + object obj = ResourceManager.GetObject("hilquad", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap octo { + get { + object obj = ResourceManager.GetObject("octo", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap octov { + get { + object obj = ResourceManager.GetObject("octov", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap opticalflow { + get { + object obj = ResourceManager.GetObject("opticalflow", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap planeicon { + get { + object obj = ResourceManager.GetObject("planeicon", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } @@ -256,9 +256,16 @@ namespace ArdupilotMega.Properties { } } - public static System.Drawing.Bitmap quad2 { + public static System.Drawing.Bitmap quadicon { get { - object obj = ResourceManager.GetObject("quad2", resourceCulture); + object obj = ResourceManager.GetObject("quadicon", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap quadx { + get { + object obj = ResourceManager.GetObject("quadx", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } @@ -284,11 +291,25 @@ namespace ArdupilotMega.Properties { } } + public static System.Drawing.Bitmap tri { + get { + object obj = ResourceManager.GetObject("tri", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + public static System.Drawing.Bitmap up { get { object obj = ResourceManager.GetObject("up", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } + + public static System.Drawing.Bitmap y6 { + get { + object obj = ResourceManager.GetObject("y6", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } } } diff --git a/Tools/ArdupilotMegaPlanner/Properties/Resources.resx b/Tools/ArdupilotMegaPlanner/Properties/Resources.resx index 22592fa8b2..ca1caef98f 100644 --- a/Tools/ArdupilotMegaPlanner/Properties/Resources.resx +++ b/Tools/ArdupilotMegaPlanner/Properties/Resources.resx @@ -166,25 +166,25 @@ ..\Resources\APM_airframes-08.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - + ..\Resources\frames-03.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - + ..\Resources\frames-04.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - + ..\Resources\frames-05.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\frames-06.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - + ..\Resources\frames-07.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - + ..\Resources\frames-08.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - + ..\Resources\planetracker.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -1195,20 +1195,29 @@ ..\Resources\AC-0004-11-2.jpg;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\quad.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\plane2.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - + ..\Resources\quad2.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\new frames-09.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - + ..\Resources\BR-0016-01-3T.jpg;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\new frames-10.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\new frames-13.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\new frames-11.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\new frames-12.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\new frames-05.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\new frames-06.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/Tools/ArdupilotMegaPlanner/RAW_Sensor.cs b/Tools/ArdupilotMegaPlanner/RAW_Sensor.cs index 2ca1c4ee9c..1b15cf9f6e 100644 --- a/Tools/ArdupilotMegaPlanner/RAW_Sensor.cs +++ b/Tools/ArdupilotMegaPlanner/RAW_Sensor.cs @@ -31,9 +31,7 @@ namespace ArdupilotMega { InitializeComponent(); - Control.CheckForIllegalCrossThreadCalls = false; // so can update display from another thread - - CreateChart(zg1, "Raw Sensors", "Time", "Raw Data"); + CreateChart(zg1, "Raw Sensors", "Time", "Raw Data"); } public struct plot diff --git a/Tools/ArdupilotMegaPlanner/Resources/new frames-01.png b/Tools/ArdupilotMegaPlanner/Resources/new frames-01.png new file mode 100644 index 0000000000..b3d0936a5a Binary files /dev/null and b/Tools/ArdupilotMegaPlanner/Resources/new frames-01.png differ diff --git a/Tools/ArdupilotMegaPlanner/Resources/new frames-05.png b/Tools/ArdupilotMegaPlanner/Resources/new frames-05.png new file mode 100644 index 0000000000..48e73fc329 Binary files /dev/null and b/Tools/ArdupilotMegaPlanner/Resources/new frames-05.png differ diff --git a/Tools/ArdupilotMegaPlanner/Resources/new frames-06.png b/Tools/ArdupilotMegaPlanner/Resources/new frames-06.png new file mode 100644 index 0000000000..4880315f41 Binary files /dev/null and b/Tools/ArdupilotMegaPlanner/Resources/new frames-06.png differ diff --git a/Tools/ArdupilotMegaPlanner/Resources/new frames-10.png b/Tools/ArdupilotMegaPlanner/Resources/new frames-10.png new file mode 100644 index 0000000000..aa407e1e92 Binary files /dev/null and b/Tools/ArdupilotMegaPlanner/Resources/new frames-10.png differ diff --git a/Tools/ArdupilotMegaPlanner/Resources/new frames-11.png b/Tools/ArdupilotMegaPlanner/Resources/new frames-11.png new file mode 100644 index 0000000000..d8a9b5ed2f Binary files /dev/null and b/Tools/ArdupilotMegaPlanner/Resources/new frames-11.png differ diff --git a/Tools/ArdupilotMegaPlanner/Resources/new frames-12.png b/Tools/ArdupilotMegaPlanner/Resources/new frames-12.png new file mode 100644 index 0000000000..68d580c199 Binary files /dev/null and b/Tools/ArdupilotMegaPlanner/Resources/new frames-12.png differ diff --git a/Tools/ArdupilotMegaPlanner/Resources/new frames-13.png b/Tools/ArdupilotMegaPlanner/Resources/new frames-13.png new file mode 100644 index 0000000000..36bc0b6ab5 Binary files /dev/null and b/Tools/ArdupilotMegaPlanner/Resources/new frames-13.png differ diff --git a/Tools/ArdupilotMegaPlanner/Resources/new frames-14.png b/Tools/ArdupilotMegaPlanner/Resources/new frames-14.png new file mode 100644 index 0000000000..a0241c1e6b Binary files /dev/null and b/Tools/ArdupilotMegaPlanner/Resources/new frames-14.png differ diff --git a/Tools/ArdupilotMegaPlanner/Script.cs b/Tools/ArdupilotMegaPlanner/Script.cs index 534b3aa678..016bde55bd 100644 --- a/Tools/ArdupilotMegaPlanner/Script.cs +++ b/Tools/ArdupilotMegaPlanner/Script.cs @@ -18,7 +18,13 @@ namespace ArdupilotMega public Script() { - engine = Python.CreateEngine(); + Dictionary options = new Dictionary(); + options["Debug"] = true; + + if (engine != null) + engine.Runtime.Shutdown(); + + engine = Python.CreateEngine(options); scope = engine.CreateScope(); scope.SetVariable("cs", MainV2.cs); diff --git a/Tools/ArdupilotMegaPlanner/Setup/Setup.Designer.cs b/Tools/ArdupilotMegaPlanner/Setup/Setup.Designer.cs index 4d3f37c5c5..7b8bcc53a6 100644 --- a/Tools/ArdupilotMegaPlanner/Setup/Setup.Designer.cs +++ b/Tools/ArdupilotMegaPlanner/Setup/Setup.Designer.cs @@ -700,7 +700,7 @@ // pictureBox2 // this.pictureBox2.BackColor = System.Drawing.Color.White; - this.pictureBox2.BackgroundImage = global::ArdupilotMega.Properties.Resources.BR_0016_01_3T; + this.pictureBox2.BackgroundImage = global::ArdupilotMega.Properties.Resources.opticalflow; resources.ApplyResources(this.pictureBox2, "pictureBox2"); this.pictureBox2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.pictureBox2.Name = "pictureBox2"; @@ -936,7 +936,7 @@ // pictureBoxQuadX // this.pictureBoxQuadX.Cursor = System.Windows.Forms.Cursors.Hand; - this.pictureBoxQuadX.Image = global::ArdupilotMega.Properties.Resources.frames_04; + this.pictureBoxQuadX.Image = global::ArdupilotMega.Properties.Resources.quadx; resources.ApplyResources(this.pictureBoxQuadX, "pictureBoxQuadX"); this.pictureBoxQuadX.Name = "pictureBoxQuadX"; this.pictureBoxQuadX.TabStop = false; @@ -945,7 +945,7 @@ // pictureBoxQuad // this.pictureBoxQuad.Cursor = System.Windows.Forms.Cursors.Hand; - this.pictureBoxQuad.Image = global::ArdupilotMega.Properties.Resources.frames_03; + this.pictureBoxQuad.Image = global::ArdupilotMega.Properties.Resources.quad; resources.ApplyResources(this.pictureBoxQuad, "pictureBoxQuad"); this.pictureBoxQuad.Name = "pictureBoxQuad"; this.pictureBoxQuad.TabStop = false; diff --git a/Tools/ArdupilotMegaPlanner/m3u/networklink.kml b/Tools/ArdupilotMegaPlanner/m3u/networklink.kml new file mode 100644 index 0000000000..0f28d211d2 --- /dev/null +++ b/Tools/ArdupilotMegaPlanner/m3u/networklink.kml @@ -0,0 +1,19 @@ + + + + Network Links + 1 + + View Centered Placemark + 1 + 0 + 1 + + http://127.0.0.1:56781/network.kml + onInterval + 1 + 1 + + + +