//-----------------------------------------------------------------------
//
// 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;
}
}
}