File LogarithmicSliderControl.xaml.cs¶
File List > PGRControls > LogarithmicSliderControl.xaml.cs
Go to the documentation of this file
//=============================================================================
// Copyright (c) 2026 FLIR Integrated Imaging Solutions, Inc. All Rights Reserved.
//
// This software is the confidential and proprietary information of FLIR
// Integrated Imaging Solutions, Inc. ("Confidential Information"). You
// shall not disclose such Confidential Information and shall use it only in
// accordance with the terms of the license agreement you entered into
// with FLIR Integrated Imaging Solutions, Inc. (FLIR)
//
// FLIR MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
// SOFTWARE, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE, OR NON-INFRINGEMENT. FLIR SHALL NOT BE LIABLE FOR ANY DAMAGES
// SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
// THIS SOFTWARE OR ITS DERIVATIVES.
//=============================================================================
using SpinnakerNET.GenApi;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.ExceptionServices;
using System.Security;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace SpinnakerNET.GUI
{
namespace WPFControls
{
public sealed partial class LogarithmicSliderControl : BaseClass
{
#region Properties
// Basic Properties
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(LogarithmicSliderControl));
private static readonly log4net.ILog analytics = log4net.LogManager.GetLogger("Analytics");
private const int k_numOfRetried = 5;
private INode _node;
private IInteger _integerNode;
private IFloat _floatNode;
private bool _nameLabelOnTop = false;
private bool _nameLabelOnBottom = false;
private bool _isNodeReadable = false;
private double _minimum = 0;
private double _maximum = 0;
private double _increment = 0;
private bool _disposed = false;
private double _oldValue = 0;
private string _editBoxTooltip;
private bool _isEditing = false;
private bool _isEditboxEnabled;
private bool _isEditboxReadOnly;
private bool _isSpinnerControlEnabled;
private bool _isSliderBarEnabled;
// Slider Dragging
private bool _dragStarted = false;
private bool _editStarted = false;
private bool _skipCallback = false;
private int _counter = 0;
// GenICam callback update thread
BackgroundWorker _updateWorker;
// SpinButton
private System.Windows.Visibility _SpinButtonVisibility = System.Windows.Visibility.Hidden;
Integer _pAliasNode;
long _spinnerValue;
#endregion
#region PROPERTIES
public bool IsSliderBarEnabled
{
get
{
return _isSliderBarEnabled;
}
set
{
_isSliderBarEnabled = value;
NotifyPropertyChanged("IsSliderBarEnabled");
}
}
public bool IsEditboxEnabled
{
get
{
return _isEditboxEnabled;
}
set
{
_isEditboxEnabled = value;
NotifyPropertyChanged("IsEditboxEnabled");
}
}
public bool IsEditboxReadOnly
{
get
{
return _isEditboxReadOnly;
}
set
{
_isEditboxReadOnly = value;
NotifyPropertyChanged("IsEditboxReadOnly");
}
}
public bool IsSpinnerControlEnabled
{
get
{
return _isSpinnerControlEnabled;
}
set
{
_isSpinnerControlEnabled = value;
NotifyPropertyChanged("IsSpinnerControlEnabled");
}
}
public string EditBoxTooltip
{
get
{
return _editBoxTooltip;
}
set
{
_editBoxTooltip = value;
NotifyPropertyChanged("EditBoxTooltip");
}
}
public System.Windows.Visibility SpinButtonVisibility
{
get
{
if (_pAliasNode == null)
{
return System.Windows.Visibility.Hidden;
}
else
{
return _SpinButtonVisibility;
}
}
set
{
_SpinButtonVisibility = value;
NotifyPropertyChanged("SpinButtonVisibility");
}
}
public long SpinnerValue
{
get
{
return _spinnerValue;
}
set
{
_spinnerValue = value;
NotifyPropertyChanged("SpinnerValue");
}
}
public Boolean IsNodeReadable
{
get
{
return _isNodeReadable;
}
set
{
_isNodeReadable = value;
NotifyPropertyChanged("IsNodeReadable");
}
}
public double CurrentValue
{
get
{
try
{
return (sliderbar != null) ? log2Double(sliderbar.Value) : float.NaN;
}
catch (System.Exception /*ex*/)
{
return float.NaN;
}
}
set
{
if (IsNodeReadable)
{
double logVal = double2Log(value);
if (!double.IsNaN(logVal) && !double.IsNegativeInfinity(logVal) &&
!double.IsPositiveInfinity(logVal))
{
sliderbar.Value = logVal;
NotifyPropertyChanged("CurrentValue");
NotifyPropertyChanged("CurrentValueFormatted");
}
}
}
}
public string CurrentValueFormatted
{
get
{
return NumericFormatter.FormatNumericToString(CurrentValue, DecimalPlaces);
}
set
{
double parsed;
if (double.TryParse(value, out parsed))
{
CurrentValue = parsed;
}
}
}
public double Min
{
get
{
return _minimum;
}
set
{
_minimum = value;
}
}
public double Max
{
get
{
return _maximum;
}
set
{
_maximum = value;
}
}
public double Increment
{
get
{
return _increment;
}
set
{
_increment = value;
}
}
public string Unit
{
get
{
return unitLabel.Content.ToString();
}
set
{
unitLabel.Content = value;
}
}
public System.Windows.Visibility UnitLabelVisibility
{
get
{
return this.unitLabel.Visibility;
}
set
{
this.unitLabel.Visibility = value;
}
}
public System.Windows.Visibility EditBoxVisibility
{
get
{
return this.editbox.Visibility;
}
set
{
this.editbox.Visibility = value;
}
}
public System.Windows.Visibility SliderVisibility
{
get
{
return sliderbar.Visibility;
}
set
{
this.sliderbar.Visibility = value;
}
}
public double MinLabelWidth
{
get
{
return this.nameLabel.MinWidth;
}
set
{
this.nameLabel.MinWidth = value;
}
}
public double MaxLabelWidth
{
get
{
return this.nameLabel.MaxWidth;
}
set
{
this.nameLabel.MaxWidth = value;
}
}
public double EditBoxWidth
{
get
{
return editbox.ActualWidth;
}
set
{
editbox.Width = value;
}
}
public double MinEditBoxWidth
{
get
{
return editbox.MinWidth;
}
set
{
editbox.MinWidth = value;
}
}
public double MaxEditBoxWidth
{
get
{
return editbox.MaxWidth;
}
set
{
editbox.MaxWidth = value;
}
}
public bool NameLabelOnTop
{
get
{
return _nameLabelOnTop;
}
set
{
this._nameLabelOnTop = value;
if (_nameLabelOnTop)
{
LabelAppearOnTop();
}
}
}
public bool NameLabelOnBottom
{
get
{
return _nameLabelOnBottom;
}
set
{
this._nameLabelOnBottom = value;
if (_nameLabelOnBottom)
{
LabelAppearOnBottom();
}
}
}
#endregion
#region Constructor
public LogarithmicSliderControl()
{
InitializeComponent();
this.DataContext = this;
_timer = new System.Windows.Forms.Timer();
_updateWorker = new BackgroundWorker();
_updateWorker.DoWork += _updateWorker_DoWork;
_updateWorker.RunWorkerCompleted += _updateWorker_RunWorkerCompleted;
}
~LogarithmicSliderControl()
{
if (_counter != 0)
{
Disconnect();
}
}
internal LogarithmicSliderControl(LogarithmicSliderControl originalControl)
{
InitializeComponent();
this.DataContext = this;
_timer = new System.Windows.Forms.Timer();
_updateWorker = new BackgroundWorker();
_updateWorker.DoWork += _updateWorker_DoWork;
_updateWorker.RunWorkerCompleted += _updateWorker_RunWorkerCompleted;
// Common Properties
this.SetMapper(originalControl.GetMapper());
this.Connect(
originalControl.NodeMap, originalControl.GetNodeToControl(), originalControl.GetControlNameLabel());
this.SetNameLabelBoldness(originalControl.NameLabelBoldness);
this.SetVisibility(originalControl.ControlVisibility);
this.SetControlID(originalControl.ControlID);
this.SetMin(originalControl.GetMin());
this.SetMax(originalControl.GetMax());
this.SetControlNameLabel(originalControl.ControlNameLabel);
this.SetNameLabelVisibility(originalControl.NameLabelVisibility);
this.SetNameLabelBoldness(originalControl.GetNameLabelBoldness());
try
{
this.SetToolTip(originalControl.GetToolTip());
}
catch (System.Exception /*ex*/)
{
}
this.SetMaximumControlSize(originalControl.GetMaximumControlSize());
this.SetMinimumControlSize(originalControl.GetMinimumControlSize());
this.SetControlHeight(originalControl.GetControlHeight());
this.SetControlWidth(originalControl.GetControlWidth());
this.SetRefreshTime(originalControl.GetRefreshTime());
this.SetMargin(originalControl.GetMargin());
this.NameLabelOnTop = originalControl.NameLabelOnTop;
this.NameLabelOnBottom = originalControl.NameLabelOnBottom;
// Slider specific properties
this.UnitLabelVisibility = originalControl.UnitLabelVisibility;
this.MinLabelWidth = originalControl.MinLabelWidth;
this.MaxLabelWidth = originalControl.MaxLabelWidth;
this.MinEditBoxWidth = originalControl.MinEditBoxWidth;
this.MaxEditBoxWidth = originalControl.MinEditBoxWidth;
}
protected override void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
}
// Consider GenICam callbacks as unmanaged resource
Disconnect();
_disposed = true;
}
// Call Dispose in the base class.
base.Dispose(disposing);
}
#endregion
#region ICAMERACONTROL_INTERFACE
public override void SetMin(double min)
{
Min = min;
}
public override void SetMax(double max)
{
Max = max;
}
public override void SetRefreshTime(int seconds)
{
this.RefreshTime = seconds;
// Start timer if an valid refresh time was provided
if (this._refreshTime > 0)
{
try
{
_timer = new System.Windows.Forms.Timer();
_timer.Interval = this._refreshTime;
_timer.Tick += new EventHandler(timer_Tick);
_timer.Start();
}
catch (System.Exception /*ex*/)
{
}
}
}
public override void Refresh()
{
// Sanity check
if (_nodeMap == null)
{
return;
}
try
{
_initializing = true;
UpdateControlValues(this._nodeType, this._nodeMap, this.PropertyToControl, this.ControlNameLabel);
UpdateControlStatus();
}
catch (System.Exception /*ex*/)
{
Debug.WriteLine("Problem updating control values.");
}
finally
{
_initializing = false;
}
}
public void SetUnitLabel(string unitLabel)
{
this.Unit = unitLabel;
}
public void SetUnitLabelVisibility(System.Windows.Visibility visibility)
{
this.UnitLabelVisibility = visibility;
}
public void SetEditBoxVisibility(bool overrideDefault, System.Windows.Visibility visibility)
{
if (overrideDefault)
{
this.editbox.Visibility = visibility;
}
}
public void SetSliderVisibility(System.Windows.Visibility visibility)
{
this.sliderbar.Visibility = visibility;
}
public override double GetMin()
{
return Min;
}
public override double GetMax()
{
return Max;
}
public override void Connect(INodeMap nodemap, string nodename, string namelabel = "")
{
this._propertyToControl = nodename;
this._nodeMap = nodemap;
if (nodemap != null && nodename.Length > 0)
{
// Acquire device serial number
if (string.IsNullOrWhiteSpace(_serialNumber))
{
_serialNumber = RetrieveSerialNumber(nodemap);
}
// Acquire device model name
if (string.IsNullOrWhiteSpace(_deviceModelName))
{
_deviceModelName = RetrieveModelName(nodemap);
}
try
{
_node = nodemap.GetNode<INode>(nodename);
if (_node == null)
{
throw new Exception("Feature not found");
}
this._nodeType = _node.GetType();
_featureAvailable = _node.IsImplemented;
}
catch (System.Exception ex)
{
_featureAvailable = false;
UpdateControlStatus();
log.Debug(
string.Format(
"{1}Problem accessing {0} node. {2}",
this._propertyToControl,
FormattedSerialNumber,
ex.Message),
ex);
throw new Exception(
string.Format("Problem accessing {0} node. {1}", this._propertyToControl, ex.Message));
}
_initializing = true;
try
{
UpdateControlValues(this._nodeType, this._nodeMap, this._propertyToControl, namelabel);
// Determine whether Spinbutton is visible
if (this._nodeType == typeof (Float))
{
if (_floatNode.Alias != null &&
_floatNode.Alias.GetType() == typeof (Integer) && _floatNode.Alias.IsReadable)
{
_pAliasNode = _floatNode.Alias as Integer;
SpinButtonVisibility = System.Windows.Visibility.Visible;
spinnerControl.Value = _pAliasNode.Value;
spinnerControl.Change = _pAliasNode.Increment;
spinnerControl.Maximum = _pAliasNode.Max;
spinnerControl.Minimum = _pAliasNode.Min;
spinnerControl.ValueChanged += spinnerControl_ValueChanged;
}
else
{
SpinButtonVisibility = System.Windows.Visibility.Hidden;
}
}
else
{
SpinButtonVisibility = System.Windows.Visibility.Hidden;
}
UpdateControlStatus();
RegisterGenICamCallbacks();
RegisterInterfaceEvents();
}
catch (System.Exception ex)
{
log.Error(
string.Format(
"{1}Problem accessing {0} node.", this._propertyToControl, FormattedSerialNumber),
ex);
}
finally
{
_initializing = false;
}
}
}
public override void Disconnect()
{
try
{
if (_floatNode != null)
{
_floatNode.Updated -= node_Updated;
_floatNode = null;
}
else if (_integerNode != null)
{
_integerNode.Updated -= node_Updated;
_integerNode = null;
}
_node = null;
_mapper = null;
_counter--;
base.Disconnect();
}
catch (System.Exception /*ex*/)
{
}
}
#endregion
#region GENICAM_CALLBACK
private void RegisterGenICamCallbacks()
{
if (_floatNode != null)
{
_floatNode.Updated += node_Updated;
}
else if (_integerNode != null)
{
_integerNode.Updated += node_Updated;
}
_counter++;
}
[HandleProcessCorruptedStateExceptions]
[SecurityCritical]
private void
_updateWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
bool refreshRequired = false;
if (e.Cancelled)
{
return;
}
try
{
Dispatcher.Invoke(() => {
_isUpdating = true;
_skipCallback = true;
INode node = e.Result as INode;
NodeStatus currentNodeStatus = new NodeStatus(node);
if (currentNodeStatus.ExceptionObject != null)
{
return;
}
string logMessage =
string.Format("Spinnaker Callback: Feature=\"{0}\"", currentNodeStatus.NodeName);
logMessage += string.Format(", Value=\"{0}\"", currentNodeStatus.CurrentStringValue);
LogNodeCallback(log, currentNodeStatus.NodeName, logMessage);
if (_controlNameLabel != currentNodeStatus.NodeDisplayName)
{
ControlNameLabel = currentNodeStatus.NodeDisplayName;
}
if (_tooltip != currentNodeStatus.Tooltip)
{
ControlToolTip = currentNodeStatus.Tooltip;
refreshRequired = true;
}
if (Min != currentNodeStatus.Min)
{
Min = currentNodeStatus.Min;
refreshRequired = true;
}
if (Max != currentNodeStatus.Max)
{
Max = currentNodeStatus.Max;
refreshRequired = true;
EditBoxTooltip =
string.Format("Min: {0}, Max: {1}", Min.ToString("G5"), Max.ToString("G5"));
}
if (currentNodeStatus.CurrentValue != double.NaN)
{
if (CurrentValue != currentNodeStatus.CurrentValue)
{
if (!Dispatcher.CheckAccess())
{
Dispatcher.BeginInvoke(
(Action)(() => {
sliderbar.ValueChanged -= sliderbar_ValueChanged;
CurrentValue = currentNodeStatus.CurrentValue;
NotifyPropertyChanged("CurrentValueFormatted");
sliderbar.ValueChanged += sliderbar_ValueChanged;
}),
DispatcherPriority.Background,
null);
}
else
{
sliderbar.ValueChanged -= sliderbar_ValueChanged;
CurrentValue = currentNodeStatus.CurrentValue;
NotifyPropertyChanged("CurrentValueFormatted");
sliderbar.ValueChanged += sliderbar_ValueChanged;
}
refreshRequired = true;
}
}
if (!currentNodeStatus.IsWritable)
{
// Node becomes non-writable
base.IsEditable = false;
IsSliderBarEnabled = false;
IsEditboxReadOnly = true;
IsSpinnerControlEnabled = false;
SpinButtonVisibility = System.Windows.Visibility.Hidden;
}
if (currentNodeStatus.IsWritable)
{
// Node becomes writable
base.IsEditable = true;
IsSliderBarEnabled = true;
IsEditboxEnabled = true;
IsSpinnerControlEnabled = true;
SpinButtonVisibility = System.Windows.Visibility.Visible;
IsEditboxReadOnly = false;
}
});
}
catch (System.Exception ex)
{
log.Debug(
string.Format(
"{1}Problem updating control for {0} node", _propertyToControl, FormattedSerialNumber),
ex);
}
finally
{
_skipCallback = false;
_isUpdating = false;
}
if (!refreshRequired)
{
return;
}
if (!Dispatcher.CheckAccess())
{
Dispatcher.BeginInvoke((Action)(() => { Refresh(); }), DispatcherPriority.Background, null);
}
else
{
Refresh();
}
}
private void _updateWorker_DoWork(object sender, DoWorkEventArgs e)
{
// Limit the refresh rate
Thread.Sleep(1000 / _maxRefreshRateHz);
INode node = e.Argument as INode;
e.Result = node;
}
void node_Updated(INode node)
{
// Cancel update if slider was being dragged
if (_dragStarted || _initializing || _skipCallback || _isEditing)
{
return;
}
if (_nodeMap == null)
{
return;
}
if (_updateWorker.IsBusy || _isUpdating)
{
return;
}
if (!IsVisible)
{
return;
}
_updateWorker.RunWorkerAsync(node);
}
#endregion
#region IEditableObject
public void BeginEdit()
{
_isEditing = true;
double tempValue = 0;
if (double.TryParse(editbox.Text, out tempValue))
{
_oldValue = tempValue;
}
}
public void CancelEdit()
{
CurrentValue = _oldValue;
_isEditing = false;
}
public void EndEdit()
{
double tempValue = 0;
if (double.TryParse(editbox.Text, out tempValue))
{
_oldValue = tempValue;
}
_isEditing = false;
}
#endregion
#region UI_CONTROL_UPDATE
private void editbox_TextChanged(object sender, TextChangedEventArgs e)
{
if (_initializing)
{
return;
}
BeginEdit();
if (!CheckValueBounds(editbox.Text))
{
CancelEdit();
}
else
{
try
{
double temp = 0;
if (double.TryParse(editbox.Text, out temp))
{
CurrentValue = temp;
SyncSpinnerValue();
}
}
catch
{
}
}
}
private void editbox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ClickCount == 2)
{
e.Handled = true;
editbox.SelectAll();
}
BeginEdit();
}
private void Sliderbar_OnPreviewMouseUp(object sender, MouseButtonEventArgs e)
{
if (_nodeType == typeof (Integer))
{
AnalyticsNodeUpdateAction(analytics, _node, _integerNode.ToString());
}
else if (_nodeType == typeof (Float))
{
AnalyticsNodeUpdateAction(analytics, _node, string.Format("{0:0.00}", _floatNode.Value));
}
}
private void Sliderbar_OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ClickCount == 2)
{
e.Handled = true;
}
}
private bool CheckValueBounds(string input)
{
if (_initializing)
{
return false;
}
bool result = true;
if (_nodeType == typeof (Integer))
{
try
{
if (_integerNode != null && _integerNode.IsWritable)
{
string formattedInput;
if (_mapper != null)
{
formattedInput = _mapper.ConvertStringToNodeFormat(_propertyToControl, input);
}
else
{
formattedInput = input;
}
long convertedInput = 0;
if (long.TryParse(formattedInput, out convertedInput))
{
if (convertedInput < Min || convertedInput > Max)
{
result = false;
}
}
else
{
result = false;
}
}
}
catch (System.Exception /*ex*/)
{
}
}
else if (_nodeType == typeof (Float))
{
try
{
if (_floatNode != null && _floatNode.IsWritable)
{
string formattedInput;
if (_mapper != null)
{
formattedInput = _mapper.ConvertStringToNodeFormat(_propertyToControl, input);
}
else
{
formattedInput = input;
}
float convertedInput = 0;
if (float.TryParse(formattedInput, out convertedInput))
{
if (convertedInput < Min || convertedInput > Max)
{
result = false;
}
}
else
{
result = false;
}
}
}
catch (System.Exception /*ex*/)
{
}
}
return result;
}
private void UpdateControlStatus()
{
try
{
if (_node == null || !_node.IsAvailable)
{
base.IsEditable = false;
IsSliderBarEnabled = false;
IsEditboxEnabled = false;
IsSpinnerControlEnabled = false;
SpinButtonVisibility = System.Windows.Visibility.Hidden;
return;
}
if (!_node.IsWritable)
{
base.IsEditable = false;
IsSliderBarEnabled = false;
IsEditboxReadOnly = true;
IsSpinnerControlEnabled = false;
SpinButtonVisibility = System.Windows.Visibility.Hidden;
return;
}
else
{
base.IsEditable = true;
IsSliderBarEnabled = true;
IsEditboxEnabled = true;
IsSpinnerControlEnabled = true;
SpinButtonVisibility = System.Windows.Visibility.Visible;
IsEditboxReadOnly = false;
}
}
catch (System.Exception ex)
{
log.Error(
string.Format("{0}There was a problem updating control status.", FormattedSerialNumber), ex);
throw new Exception(ex.Message);
}
}
private void UpdateControlValues(Type type, INodeMap nodemap, string nodename, string namelabel = "")
{
if (type == typeof (Float))
{
try
{
_floatNode = nodemap.GetNode<IFloat>(nodename);
}
catch (System.Exception ex)
{
log.Error(
string.Format("{1}Problem obtaining {0} from NodeMap.", nodename, FormattedSerialNumber),
ex);
return;
}
if (Min != _floatNode.Min)
{
Min = _floatNode.Min;
}
if (Max != _floatNode.Max)
{
Max = _floatNode.Max;
}
ControlNameLabel = namelabel.Length == 0 ? _floatNode.DisplayName : namelabel;
Unit = _floatNode.Unit;
// Set display precision from camera XML
if (_floatNode.IsReadable)
{
try
{
DecimalPlaces = ClampDisplayPrecision(_floatNode.DisplayPrecision);
}
catch (System.Exception /*ex*/)
{
// If DisplayPrecision is not available, keep existing DecimalPlaces value
}
}
// Set tooltip
ControlToolTip = _floatNode.ToolTip;
// Update _isReadable
IsNodeReadable = _floatNode.IsReadable;
if (_isNodeReadable)
{
try
{
_skipCallback = true;
if (_pAliasNode != null && _pAliasNode.IsReadable)
{
SpinnerValue = _pAliasNode.Value;
}
CurrentValue = _floatNode.Value;
NotifyPropertyChanged("CurrentValueFormatted");
}
catch
{
}
finally
{
_skipCallback = false;
}
}
}
else if (type == typeof (Integer))
{
try
{
_integerNode = nodemap.GetNode<IInteger>(nodename);
}
catch (System.Exception ex)
{
log.Error(
string.Format("{1}Problem obtaining {0} from NodeMap.", nodename, FormattedSerialNumber),
ex);
return;
}
if (Min != _integerNode.Min)
{
Min = _integerNode.Min;
}
if (Max != _integerNode.Max)
{
Max = _integerNode.Max;
}
Increment = _integerNode.Increment;
this.sliderbar.IsSnapToTickEnabled = true;
// Update _isReadable
IsNodeReadable = _integerNode.IsReadable;
if (_isNodeReadable)
{
try
{
_skipCallback = true;
CurrentValue = _integerNode.Value;
NotifyPropertyChanged("CurrentValueFormatted");
}
catch (Exception /*ex*/)
{
}
finally
{
_skipCallback = false;
}
}
ControlNameLabel = namelabel.Length == 0 ? _integerNode.DisplayName : namelabel;
// No unit available for IInteger node
Unit = string.Empty;
// Set tooltip
ControlToolTip = _integerNode.ToolTip;
}
else
{
// Unhandled node type detected
log.Warn(string.Format("{0}Unexpected control type.", FormattedSerialNumber));
}
try
{
editbox.ToolTip = string.Format(
"Min: {0}, Max: {1}",
Min.ToString("G5", CultureInfo.InvariantCulture),
Max.ToString("G5", CultureInfo.InvariantCulture));
}
catch
{
}
}
#endregion
#region Event_Handlers
void timer_Tick(object sender, EventArgs e)
{
try
{
if (_dragStarted || _editStarted)
{
// Skip update if user was
// dragging the slider or
// editing textbox
return;
}
Refresh();
}
catch (System.Exception /*ex*/)
{
Debug.WriteLine(string.Format("Problem retrieving new value from {0} node", _propertyToControl));
}
}
private void editbox_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
try
{
if (!CheckValueBounds(editbox.Text))
{
CancelEdit();
}
else
{
EndEdit();
BindingExpression exp = this.editbox.GetBindingExpression(TextBox.TextProperty);
exp.UpdateSource();
SyncSpinnerValue();
if (_nodeType == typeof (Integer))
{
AnalyticsNodeUpdateAction(analytics, _node, CurrentValue.ToString());
}
else if (_nodeType == typeof (Float))
{
AnalyticsNodeUpdateAction(analytics, _node, string.Format("{0:0.00}", CurrentValue));
}
}
}
catch
{
}
}
else if (e.Key == Key.Escape)
{
CancelEdit();
}
}
private void editbox_LostFocus(object sender, RoutedEventArgs e)
{
if (!CheckValueBounds(editbox.Text))
{
CancelEdit();
}
else
{
EndEdit();
BindingExpression exp = this.editbox.GetBindingExpression(TextBox.TextProperty);
exp.UpdateSource();
SyncSpinnerValue();
}
}
private void sliderbar_DragCompleted(object sender, DragCompletedEventArgs e)
{
CurrentValue = log2Double(sliderbar.Value);
UpdateNodeValue();
_dragStarted = false;
SyncSpinnerValue();
}
private void sliderbar_DragStarted(object sender, DragStartedEventArgs e)
{
_dragStarted = true;
}
private void sliderbar_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double>e)
{
if (_skipCallback || _initializing)
{
return;
}
if (!_dragStarted)
{
CurrentValue = log2Double(sliderbar.Value);
UpdateNodeValue();
}
}
#endregion
#region HELPERS
private bool UpdateNodeValue()
{
if (_initializing)
{
return false;
}
bool result = true;
if (_nodeType == typeof (Integer))
{
try
{
if (_integerNode != null && _integerNode.IsWritable)
{
double currentSliderValue = CurrentValue;
double currentNodeValue = _integerNode.Value;
// Special case for DeviceLinkThroughputLimit
if (base.PropertyToControl == "DeviceLinkThroughputLimit")
{
long previousValue = 0;
long currentValue = 0;
int iterations = 0;
// Find closest valid points between current cursor position
while (currentValue < currentSliderValue)
{
previousValue = currentValue;
currentValue = (_integerNode.Increment * iterations++) + _integerNode.Min;
}
// Pick value based on direction of dragging
if (currentSliderValue < currentNodeValue)
{
currentSliderValue = previousValue;
}
else
{
currentSliderValue = currentValue;
}
}
else
{
while (currentSliderValue % _integerNode.Increment != 0)
{
if (currentSliderValue < currentNodeValue)
{
currentSliderValue--;
}
else
{
currentSliderValue++;
}
}
}
bool success = false;
int count = 0;
while (!success && count < k_numOfRetried)
{
try
{
_skipCallback = true;
_integerNode.Value = (long) currentSliderValue;
LogNodeUpdateAction(log, _node, currentSliderValue.ToString());
success = true;
}
catch (System.Exception /*ex*/)
{
count++;
}
finally
{
_skipCallback = false;
}
}
}
else
{
Debug.WriteLine(string.Format("{0} node is currently not writable.", _propertyToControl));
result = false;
}
}
catch (Exception ex)
{
result = false;
throw new Exception(
string.Format("Error updating node value for {0}. {1}", _propertyToControl, ex.Message));
}
finally
{
// read value back from node
if (_integerNode != null && _integerNode.IsReadable)
{
_skipCallback = true;
CurrentValue = _integerNode.Value;
_skipCallback = false;
}
}
}
else if (_nodeType == typeof (Float))
{
try
{
if (_floatNode != null && _floatNode.IsWritable)
{
double valueToWrite = CurrentValue;
double increment;
if (TryGetFloatIncrement(_floatNode, out increment))
{
valueToWrite = NormalizeValueToIncrement(valueToWrite, _floatNode.Min, _floatNode.Max, increment);
}
bool success = false;
int count = 0;
while (!success && count < k_numOfRetried)
{
try
{
_skipCallback = true;
_floatNode.Value = valueToWrite;
LogNodeUpdateAction(log, _node, valueToWrite.ToString());
success = true;
}
catch (System.Exception /*ex*/)
{
count++;
}
finally
{
_skipCallback = false;
}
}
}
else
{
Debug.WriteLine(string.Format("{0} node is currently not writable.", _propertyToControl));
result = false;
}
}
catch (Exception ex)
{
result = false;
throw new Exception(
string.Format("Error updating node value for {0}. {1}", _propertyToControl, ex.Message));
}
finally
{
// read new value back from node
if (_floatNode != null && _floatNode.IsReadable)
{
_skipCallback = true;
CurrentValue = _floatNode.Value;
_skipCallback = false;
}
}
}
// Update Dependency
if (_dependencyControlList != null && _dependencyControlList.Count > 0)
{
_dependencyControlList.Refresh();
}
return result;
}
public void SliderAppearRight()
{
try
{
_skipCallback = true;
rootLayout.Children.Clear();
DockPanel.SetDock(nameLabel, Dock.Left);
DockPanel.SetDock(editboxContainer, Dock.Left);
DockPanel.SetDock(unitLabel, Dock.Left);
DockPanel.SetDock(lockIcon, Dock.Left);
// DockPanel.SetDock(sliderbar, Dock.Left);
rootLayout.Children.Add(nameLabel);
rootLayout.Children.Add(editboxContainer);
rootLayout.Children.Add(unitLabel);
rootLayout.Children.Add(lockIcon);
rootLayout.Children.Add(sliderbar);
UpdateControlStatus();
}
catch
{
}
finally
{
_skipCallback = false;
}
}
public void SliderAppearLeft()
{
try
{
_skipCallback = true;
rootLayout.Children.Clear();
DockPanel.SetDock(nameLabel, Dock.Left);
DockPanel.SetDock(unitLabel, Dock.Right);
DockPanel.SetDock(editboxContainer, Dock.Right);
DockPanel.SetDock(lockIcon, Dock.Right);
rootLayout.Children.Add(nameLabel);
rootLayout.Children.Add(unitLabel);
rootLayout.Children.Add(editboxContainer);
rootLayout.Children.Add(lockIcon);
rootLayout.Children.Add(sliderbar);
UpdateControlStatus();
}
catch
{
}
finally
{
_skipCallback = false;
}
}
public void LabelAppearOnTop()
{
try
{
_skipCallback = true;
rootLayout.Children.Clear();
DockPanel.SetDock(nameLabel, Dock.Top);
DockPanel.SetDock(lockIcon, Dock.Right);
DockPanel.SetDock(unitLabel, Dock.Right);
DockPanel.SetDock(editboxContainer, Dock.Right);
DockPanel.SetDock(sliderbar, Dock.Left);
DockPanel childPanel = new DockPanel();
DockPanel.SetDock(childPanel, Dock.Bottom);
childPanel.Children.Add(lockIcon);
childPanel.Children.Add(unitLabel);
childPanel.Children.Add(editboxContainer);
childPanel.Children.Add(sliderbar);
rootLayout.LastChildFill = false;
rootLayout.Children.Add(nameLabel);
rootLayout.Children.Add(childPanel);
UpdateControlStatus();
}
catch
{
}
finally
{
_skipCallback = false;
}
}
public void LabelAppearOnBottom()
{
try
{
_skipCallback = true;
rootLayout.Children.Clear();
DockPanel childPanel = new DockPanel();
DockPanel.SetDock(nameLabel, Dock.Bottom);
DockPanel.SetDock(lockIcon, Dock.Right);
DockPanel.SetDock(unitLabel, Dock.Right);
DockPanel.SetDock(editboxContainer, Dock.Right);
DockPanel.SetDock(sliderbar, Dock.Left);
childPanel.Children.Add(lockIcon);
childPanel.Children.Add(unitLabel);
childPanel.Children.Add(editboxContainer);
childPanel.Children.Add(sliderbar);
rootLayout.Children.Add(nameLabel);
rootLayout.Children.Add(childPanel);
UpdateControlStatus();
}
catch
{
}
finally
{
_skipCallback = false;
}
}
#endregion
#region SpinnerButton
private void SyncSpinnerValue()
{
if (_pAliasNode != null && _pAliasNode.IsReadable)
{
spinnerControl.ValueChanged -= spinnerControl_ValueChanged;
SpinnerValue = _pAliasNode.Value;
spinnerControl.ValueChanged += spinnerControl_ValueChanged;
}
}
private void spinnerControl_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
return;
}
private void spinnerControl_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ClickCount == 1)
{
e.Handled = true;
var source = e.OriginalSource;
if (source != null && source.GetType() == typeof (Rectangle))
{
// Find out whether upper or lower button was clicked
Rectangle tempRect = source as Rectangle;
if (tempRect == null)
{
return;
}
SyncSpinnerValue();
if (tempRect.Name == "UpRect")
{
SpinnerValue++;
}
else if (tempRect.Name == "DownRect")
{
SpinnerValue--;
}
if (_nodeType == typeof (Integer))
{
AnalyticsNodeUpdateAction(analytics, _node, CurrentValue.ToString());
}
else if (_nodeType == typeof (Float))
{
AnalyticsNodeUpdateAction(analytics, _node, string.Format("{0:0.00}", CurrentValue));
}
}
}
}
void spinnerControl_ValueChanged(object sender, RoutedPropertyChangedEventArgs<decimal>e)
{
if (_skipCallback)
{
return;
}
if (_pAliasNode != null)
{
try
{
if (_pAliasNode.IsWritable)
{
LogNodeUpdateAction(log, _pAliasNode, SpinnerValue.ToString());
_pAliasNode.Value = SpinnerValue;
}
}
catch (Exception ex)
{
log.Debug(
string.Format(
"{1}Problem updating pAlias \"{2}\" for {0} node.",
this._propertyToControl,
FormattedSerialNumber,
_pAliasNode.Name),
ex);
}
}
}
#endregion
double log2Double(double position)
{
// position will be between 0 and 100
int minp = 0;
int maxp = 100;
// The result should be between 100 an 10000000
var minv = Math.Log(Min);
var maxv = Math.Log(Max);
// calculate adjustment factor
var scale = (maxv - minv) / (maxp - minp);
return Math.Exp(minv + scale * (position - minp));
}
double double2Log(double value)
{
// position will be between 0 and 100
int minp = 0;
int maxp = 100;
// The result should be between 100 an 10000000
var minv = Math.Log(Min);
var maxv = Math.Log(Max);
// calculate adjustment factor
var scale = (maxv - minv) / (maxp - minp);
return (Math.Log(value) - minv) / scale + minp;
}
private void editbox_GotFocus(object sender, RoutedEventArgs e)
{
editbox.SelectAll();
BeginEdit();
}
}
}
}