//----------------------------------------------------------------------- // // Copyright © 2012 Nils Hammar. All rights reserved. // //----------------------------------------------------------------------- /* * Software to access vehicle information via the OBD-II connector. * * Copyright © 2012 Nils Hammar * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Alternative licensing is possible, see the licensing document. * * The above text may not be removed or modified. */ namespace Gauges { using System; using System.Threading; using System.Windows.Forms; using global::AquaControls; using global::Gauges.TelltalePanel; using global::SharedObjects.Misc; /// /// Class for displaying gauges to the user. /// /// The gauges are displaying the instant value, no moving average or similar. /// /// public partial class GaugeForm1 : Form { /// /// Array of gauges. /// private AquaGauge[] gauges; /// /// Array of icon panels. /// private CenterFlowPanel[] iconPanels; /// /// Divisor for each supported gauge, default to 1. /// private float[] divisors = { 1, 1, 1, 1, 1, 1, 1, 1, }; /// /// Divisor for each supported gauge, default to 1. /// private float[] digitalDivisors = { 1, 1, 1, 1, 1, 1, 1, 1, }; /// /// Current gauge manager instance. /// private GaugeManager gaugeManager; /// /// Palette instances container. /// private PaletteCreator paletteCreator; /// /// Toggle for icon flashing. /// private bool toggleOn = true; /// /// Initializes a new instance of the class. /// /// Current gauge manager instance. /// Palette collection instance. public GaugeForm1(GaugeManager gaugeManager, PaletteCreator paletteCreator) { this.paletteCreator = paletteCreator; this.gaugeManager = gaugeManager; this.InitializeComponent(); this.gauges = new AquaGauge[] { this.aquaGauge1a, this.aquaGauge1b, this.aquaGauge2, this.aquaGauge3, this.aquaGauge4, this.aquaGauge5, this.aquaGauge6, this.aquaGauge7, }; this.iconPanels = new CenterFlowPanel[] { this.centerFlowPanel0, this.centerFlowPanel1, this.centerFlowPanel2, this.centerFlowPanel3, this.centerFlowPanel4, this.centerFlowPanel5, this.centerFlowPanel6, this.centerFlowPanel7, }; foreach (CenterFlowPanel centerFlowPanel in this.iconPanels) { centerFlowPanel.paletteCreator = this.paletteCreator; } this.timer1.Start(); } /// /// Set value of one gauge. /// /// Gauge number /// Gauge value /// Gauge digital display value public void setValue(uint gauge, float value, float digitalValue) { if (this.InvokeRequired) { try { this.Invoke(new setValueFunc(this.setValue), new object[] { gauge, value, digitalValue }); } catch (ThreadAbortException) { throw; } catch (System.Reflection.TargetParameterCountException ex) { MessageBox.Show( "Exception: " + ex.Message + "\r\n", "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop); } catch (System.ObjectDisposedException) { // Ignore. } } else { this.gauges[gauge].DigitalValue = digitalValue / this.divisors[gauge]; this.gauges[gauge].Value = value / this.divisors[gauge]; } } /// /// Set values for the gauges, array has one item per gauge. /// /// Array of values to set. /// Gauge digital display value public void setValues(float[] value, float[] digitalValue) { if (value != null && digitalValue != null) { if (this.InvokeRequired) { try { this.Invoke(new setValuesFunc(this.setValues), new object[] { value, digitalValue }); } catch (ThreadAbortException) { throw; } catch (System.Reflection.TargetParameterCountException ex) { MessageBox.Show( "Exception: " + ex.Message + "\r\n", "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop); } catch (System.ObjectDisposedException) { // Ignore. } } else { for (int i = 0; i < digitalValue.Length; i++) { this.gauges[i].DigitalValue = digitalValue[i] / this.digitalDivisors[i]; } for (int i = 0; i < value.Length; i++) { this.gauges[i].Value = value[i] / this.divisors[i]; } } } } /// /// Configure one gauge. /// /// Gauge item. /// Sensor data. public void configureGauge( XmlClass.gaugeitem item, XmlClass.pidgroup.pidlist.sensordata sensor) { if (item != null && sensor != null) { uint gauge = item.gaugeNumber; float divisor = item.divisor; float digitalDivisor = item.digitalDivisor; // Protect against stupidity and division with zero. if (divisor == 0) { divisor = 1; } if (digitalDivisor == 0) { digitalDivisor = 1; } this.divisors[gauge] = divisor; this.digitalDivisors[gauge] = digitalDivisor; this.gauges[gauge].Visible = true; this.gauges[gauge].DialText = item.gaugetext; this.gauges[gauge].DigitalGaugeText = item.digitalGaugetext; this.gauges[gauge].DigitMask = item.digitalFormat; this.gauges[gauge].MinValue = (float)sensor.presentation_min / divisor; this.gauges[gauge].MaxValue = (float)sensor.presentation_max / divisor; this.gauges[gauge].NoOfDivisions = (int)item.majorScaleSteps; this.gauges[gauge].NoOfSubDivisions = (int)item.minorScaleSteps; this.gauges[gauge].RecommendedValueMin = (float)sensor.green_zone_min / divisor; this.gauges[gauge].RecommendedValueMax = (float)sensor.green_zone_max / divisor; this.gauges[gauge].Red1ValueMin = (float)sensor.red_zone_min / divisor; this.gauges[gauge].Red1ValueMax = (float)sensor.red_zone_max / divisor; this.gauges[gauge].Red2ValueMin = (float)sensor.red2_zone_min / divisor; this.gauges[gauge].Red2ValueMax = (float)sensor.red2_zone_max / divisor; this.gauges[gauge].YellowValueMin = (float)sensor.yellow_zone_min / divisor; this.gauges[gauge].YellowValueMax = (float)sensor.yellow_zone_max / divisor; this.gauges[gauge].BlueValueMin = (float)sensor.blue_zone_min / divisor; this.gauges[gauge].BlueValueMax = (float)sensor.blue_zone_max / divisor; } } /// /// Add one icon. /// /// Index of icon area. /// Telltale instance. public void addIcon(int iconArea, TellTale tellTale) { if (this.iconPanels[iconArea].InvokeRequired) { try { this.iconPanels[iconArea].Invoke(new addIconFunc(this.addIcon), new object[] { iconArea, tellTale }); } catch (ThreadAbortException) { throw; } catch (System.Reflection.TargetParameterCountException ex) { MessageBox.Show( "Exception: " + ex.Message + "\r\n", "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop); } catch (System.ObjectDisposedException) { // Ignore. } } else { this.iconPanels[iconArea].Visible = true; this.iconPanels[iconArea].Controls.Add(tellTale); } } /// /// Remove one icon. /// /// Index of icon area. /// Telltale instance. public void removeIcon(int iconArea, TellTale tellTale) { if (this.iconPanels[iconArea].InvokeRequired) { try { this.iconPanels[iconArea].Invoke(new removeIconFunc(this.removeIcon), new object[] { iconArea, tellTale }); } catch (ThreadAbortException) { throw; } catch (System.Reflection.TargetParameterCountException ex) { MessageBox.Show( "Exception: " + ex.Message + "\r\n", "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop); } catch (System.ObjectDisposedException) { // Ignore. } } else { if (this.iconPanels[iconArea].Controls.Contains(tellTale)) { this.iconPanels[iconArea].Controls.Remove(tellTale); } } } /// /// Add an array of icons. /// /// Index of icon area. /// Telltale instance. public void addIcons(int iconArea, TellTale[] tellTale) { if (this.iconPanels[iconArea].InvokeRequired) { try { this.iconPanels[iconArea].Invoke(new addIconsFunc(this.addIcons), new object[] { iconArea, tellTale }); } catch (ThreadAbortException) { throw; } catch (System.Reflection.TargetParameterCountException ex) { MessageBox.Show( "Exception: " + ex.Message + "\r\n", "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop); } catch (System.ObjectDisposedException) { // Ignore. } } else { this.iconPanels[iconArea].Controls.AddRange(tellTale); } } /// /// Clear all icons from area. /// /// Area to clear from icons. public void clearIcons(int iconArea) { if (this.iconPanels[iconArea].InvokeRequired) { try { this.iconPanels[iconArea].Invoke(new clearIconsFunc(this.clearIcons), new object[] { iconArea }); } catch (ThreadAbortException) { throw; } catch (System.Reflection.TargetParameterCountException ex) { MessageBox.Show( "Exception: " + ex.Message + "\r\n", "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop); } catch (System.ObjectDisposedException) { // Ignore. } } else { this.iconPanels[iconArea].Controls.Clear(); } } /// /// Refresh panels. /// /// Area to refresh. public void refreshIconPanels(int iconArea) { if (this.iconPanels[iconArea].InvokeRequired) { try { this.iconPanels[iconArea].Invoke(new refreshIconPanelsFunc(this.refreshIconPanels), new object[] { iconArea }); } catch (ThreadAbortException) { throw; } catch (System.Reflection.TargetParameterCountException ex) { MessageBox.Show( "Exception: " + ex.Message + "\r\n", "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop); } catch (System.ObjectDisposedException) { // Ignore. } } else { this.iconPanels[iconArea].Invalidate(); } } /// /// Add one icon. /// /// Index of icon area. /// Telltale instance. private delegate void addIconFunc(int iconArea, TellTale tellTale); /// /// Remove one icon. /// /// Index of icon area. /// Telltale instance. private delegate void removeIconFunc(int iconArea, TellTale tellTale); /// /// Add an array of icons. /// /// Index of icon area. /// Telltale instance. private delegate void addIconsFunc(int iconArea, TellTale[] tellTale); /// /// Clear all icons from area. /// /// Area to clear from icons. private delegate void clearIconsFunc(int iconArea); /// /// Refresh panels. /// /// Area to refresh. private delegate void refreshIconPanelsFunc(int iconArea); /// /// Close button clicked. /// /// Sending object. /// Event data. private void closeButton_Click(object sender, EventArgs e) { this.Close(); } /// /// Handle closing of form. /// /// Sending object. /// Event data. private void GaugeForm1_FormClosing(object sender, FormClosingEventArgs e) { this.gaugeManager.stopPoll(); } /// /// Workaround for insufficient C# thread handling. /// /// Gauge number /// Gauge value /// Gauge digital display value private delegate void setValueFunc(uint gauge, float value, float digitalValue); /// /// Workaround for insufficient C# thread handling. /// /// Array of values to set. /// Gauge digital display value private delegate void setValuesFunc(float[] value, float[] digitalValue); /// /// Handle tick for toggling flashing icons. /// /// Sending object. /// Event data. private void timer1_Tick(object sender, EventArgs e) { foreach (CenterFlowPanel centerFlowPanel in this.iconPanels) { centerFlowPanel.toggleIconFlash(this.toggleOn); centerFlowPanel.Invalidate(); } this.toggleOn = !this.toggleOn; } } }