File SliderControl.xaml.cs¶
File List > PGRControls > SliderControl.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 SliderControl : BaseClass, IEditableObject
{
#region Properties
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(SliderControl));
private static readonly log4net.ILog analytics = log4net.LogManager.GetLogger("Analytics");
// Basic Properties
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 bool _disposed = false;
private double _oldValue = 0;
private double _smallIncrement = 1;
private double _largeIncrement = 1;
private double _min = 0;
private double _max = 1;
private bool _textChanged = false;
private string _unit;
private string _editBoxTooltip;
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;
// SpinButton
private System.Windows.Visibility _SpinButtonVisibility = System.Windows.Visibility.Hidden;
Integer _pAliasNode;
long _spinnerValue;
// GenICam callback update thread
BackgroundWorker _updateWorker;
#endregion
#region PROPERTIES
public static DependencyProperty ValueProperty = DependencyProperty.Register(
"CurrentValue",
typeof(double),
typeof(SliderControl),
new FrameworkPropertyMetadata((double) 0, OnCurrentValuePropertyChanged));
private static void OnCurrentValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
SliderControl control = d as SliderControl;
if (control != null)
{
control.NotifyPropertyChanged("CurrentValueFormatted");
}
}
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 System.Windows.Visibility SpinButtonVisibility
{
get
{
if (_pAliasNode == null)
{
return System.Windows.Visibility.Hidden;
}
else
{
return _SpinButtonVisibility;
}
}
set
{
_SpinButtonVisibility = value;
NotifyPropertyChanged("SpinButtonVisibility");
}
}
public Boolean IsNodeReadable
{
get
{
return _isNodeReadable;
}
private set
{
_isNodeReadable = value;
NotifyPropertyChanged("IsNodeReadable");
}
}
public double CurrentValue
{
get
{
return (double) GetValue(ValueProperty);
}
set
{
SetValue(ValueProperty, value);
}
}
public string CurrentValueFormatted
{
get
{
return NumericFormatter.FormatNumericToString(CurrentValue, DecimalPlaces);
}
set
{
double parsed;
if (double.TryParse(value, out parsed))
{
CurrentValue = parsed;
}
}
}
public long SpinnerValue
{
get
{
return _spinnerValue;
}
set
{
_spinnerValue = value;
NotifyPropertyChanged("SpinnerValue");
}
}
public string EditBoxTooltip
{
get
{
return _editBoxTooltip;
}
set
{
_editBoxTooltip = value;
NotifyPropertyChanged("EditBoxTooltip");
}
}
public double Min
{
get
{
return _min;
}
set
{
_min = value;
NotifyPropertyChanged("Min");
}
}
public double Max
{
get
{
return _max;
}
set
{
_max = value;
NotifyPropertyChanged("Max");
}
}
public double IncrementSmall
{
get
{
return _smallIncrement;
}
set
{
_smallIncrement = value;
NotifyPropertyChanged("IncrementSmall");
}
}
public double IncrementLarge
{
get
{
return _largeIncrement;
}
set
{
_largeIncrement = value;
NotifyPropertyChanged("IncrementLarge");
}
}
public string Unit
{
get
{
return _unit;
}
set
{
_unit = value;
NotifyPropertyChanged("Unit");
}
}
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 SliderControl()
{
InitializeComponent();
this.DataContext = this;
_timer = new System.Windows.Forms.Timer();
_updateWorker = new BackgroundWorker();
_updateWorker.DoWork += _updateWorker_DoWork;
_updateWorker.RunWorkerCompleted += _updateWorker_RunWorkerCompleted;
}
~SliderControl()
{
if (_counter != 0)
{
Disconnect();
}
}
internal SliderControl(SliderControl 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
override public void SetDecimalPlaces(int decimalPlaces)
{
this.DecimalPlaces = decimalPlaces;
NotifyPropertyChanged("CurrentValueFormatted");
}
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()
{
Dispatcher.BeginInvoke(
(Action)(() => {
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;
}
}),
DispatcherPriority.Background,
null);
}
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 sliderbar.Minimum;
}
public override double GetMax()
{
return sliderbar.Maximum;
}
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;
SetToolTip(_node.ToolTip);
}
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.IsAvailable &&
_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();
_featureAvailable = true;
}
catch (System.Exception ex)
{
log.Warn(
string.Format(
"{1}Problem accessing {0} node.", this._propertyToControl, FormattedSerialNumber),
ex);
throw;
}
finally
{
_initializing = false;
}
}
else
{
_featureAvailable = 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(() => {
if (_nodeMap == null)
{
// Nodemap is no longer valid. Control must have been disconnected.
return;
}
if (e.Error != null)
{
log.Debug(
string.Format(
"{1}There was a problem updating control status for \"{0}\"",
_propertyToControl,
FormattedSerialNumber),
e.Error);
return;
}
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);
if (currentNodeStatus.IsReadable)
{
logMessage += string.Format(", Value=\"{0}\"", currentNodeStatus.CurrentStringValue);
}
LogNodeCallback(log, currentNodeStatus.NodeName, logMessage);
if (currentNodeStatus.IsReadable)
{
_skipCallback = true;
_initializing = true;
_isUpdating = true;
if (_controlNameLabel != currentNodeStatus.NodeDisplayName)
{
ControlNameLabel = currentNodeStatus.NodeDisplayName;
}
if (_unit != currentNodeStatus.Unit)
{
Unit = currentNodeStatus.Unit;
refreshRequired = true;
}
if (_tooltip != currentNodeStatus.Tooltip)
{
ControlToolTip = currentNodeStatus.Tooltip;
refreshRequired = true;
}
if (IsNodeReadable != (currentNodeStatus.IsReadable && currentNodeStatus.IsAvailable))
{
IsNodeReadable = currentNodeStatus.IsReadable && currentNodeStatus.IsAvailable;
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.IsReadable)
{
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;
}
}
else
{
base.IsEditable = false;
IsSliderBarEnabled = false;
IsEditboxReadOnly = true;
IsSpinnerControlEnabled = false;
SpinButtonVisibility = System.Windows.Visibility.Hidden;
}
});
}
catch (System.Exception ex)
{
log.Debug(
string.Format(
"{1}Problem updating control for {0} node", _propertyToControl, FormattedSerialNumber),
ex);
}
finally
{
_skipCallback = false;
_initializing = 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)
{
return;
}
if (_updateWorker.IsBusy || _isUpdating)
{
return;
}
if (!IsVisible)
{
return;
}
_updateWorker.RunWorkerAsync(node);
}
#endregion
#region UI_CONTROL_UPDATE
private void editbox_TextChanged(object sender, TextChangedEventArgs e)
{
if (_initializing || _skipCallback)
{
return;
}
_textChanged = true;
BeginEdit();
if (!CheckValueBounds(editbox.Text))
{
CancelEdit();
}
}
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, CurrentValue.ToString());
}
else if (_nodeType == typeof (Float))
{
AnalyticsNodeUpdateAction(analytics, _node, string.Format("{0:0.00}", CurrentValue));
}
}
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;
// Special case for HexNumber Representation
if (_integerNode.Representation == SpinnakerNET.GenApi.Representation.HexNumber)
{
formattedInput.Replace("0x", "");
}
bool noError = true;
try
{
long.TryParse(formattedInput, out convertedInput);
}
catch
{
noError = false;
}
// Fallback for error case
if (!noError)
{
try
{
long.TryParse(input, out convertedInput);
noError = true;
}
catch
{
noError = false;
}
}
if (noError)
{
if (convertedInput < Min)
{
result = false;
log.Warn(string.Format(
"{3}{0} is below minimum allowable value of {1} for feature {2}.",
formattedInput,
Min,
_propertyToControl,
FormattedSerialNumber));
}
else if (convertedInput > Max)
{
result = false;
log.Warn(string.Format(
"{3}{0} is above maximum allowable value of {1} for feature {2}.",
formattedInput,
Max,
_propertyToControl,
FormattedSerialNumber));
}
}
else
{
result = false;
log.Warn(string.Format(
"{2}Invalid Input: {0} for feature {1}",
formattedInput,
_propertyToControl,
FormattedSerialNumber));
}
}
}
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;
// Special case for HexNumber Representation
if (_floatNode.Representation == SpinnakerNET.GenApi.Representation.HexNumber)
{
formattedInput.Replace("0x", "");
}
bool noError = true;
try
{
float.TryParse(formattedInput, out convertedInput);
}
catch
{
noError = false;
}
// Fallback for error case
if (!noError)
{
try
{
float.TryParse(input, out convertedInput);
noError = true;
}
catch
{
noError = false;
}
}
if (noError)
{
if (convertedInput < Min)
{
result = false;
log.Warn(string.Format(
"{3}{0} is below minimum allowable value of {1} for feature {2}.",
formattedInput,
Min,
_propertyToControl,
FormattedSerialNumber));
}
else if (convertedInput > Max)
{
result = false;
log.Warn(string.Format(
"{3}{0} is above maximum allowable value of {1} for feature {2}.",
formattedInput,
Max,
_propertyToControl,
FormattedSerialNumber));
}
}
else
{
result = false;
log.Warn(string.Format(
"{2}Invalid Input: {0} for feature {1}",
formattedInput,
_propertyToControl,
FormattedSerialNumber));
}
}
}
catch (System.Exception /*ex*/)
{
}
}
return result;
}
private void UpdateControlStatus()
{
try
{
if (_node == null || !_node.IsAvailable || !_node.IsImplemented)
{
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(
"{1}There was a problem updating control status for \"{0}\"",
_propertyToControl,
FormattedSerialNumber),
ex);
throw new Exception(ex.Message);
}
}
private void UpdateControlValues(Type type, INodeMap nodemap, string nodename, string namelabel = "")
{
// Sanity check
if (nodemap == null)
{
return;
}
if (type == typeof (Float))
{
try
{
_floatNode = nodemap.GetNode<IFloat>(nodename);
}
catch (System.Exception ex)
{
log.Error(
string.Format("{0}Problem accessing {1} from Nodemap.", FormattedSerialNumber, nodename),
ex);
return;
}
ControlNameLabel = namelabel.Length == 0 ? _floatNode.DisplayName : namelabel;
Unit = _floatNode.Unit;
// Set display precision from camera XML
if (_floatNode.IsReadable)
{
try
{
SetDecimalPlaces(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 && _floatNode.IsAvailable;
if (IsNodeReadable)
{
try
{
_skipCallback = true;
if (Min != _floatNode.Min)
{
Min = _floatNode.Min;
}
if (Max != _floatNode.Max)
{
Max = _floatNode.Max;
}
if (_pAliasNode != null && _pAliasNode.IsReadable)
{
SpinnerValue = _pAliasNode.Value;
}
CurrentValue = _floatNode.Value;
NotifyPropertyChanged("CurrentValueFormatted");
}
catch (System.Exception /*ex*/)
{
}
finally
{
_skipCallback = false;
}
}
}
else if (type == typeof (Integer))
{
try
{
_integerNode = nodemap.GetNode<IInteger>(nodename);
}
catch (System.Exception ex)
{
log.Error(
string.Format("{0}Problem accessing {1} from Nodemap.", FormattedSerialNumber, nodename),
ex);
return;
}
this.sliderbar.IsSnapToTickEnabled = true;
// Update _isReadable
IsNodeReadable = _integerNode.IsReadable && _integerNode.IsAvailable;
if (IsNodeReadable)
{
try
{
_skipCallback = true;
if (Min != _integerNode.Min)
{
Min = _integerNode.Min;
}
if (Max != _integerNode.Max)
{
Max = _integerNode.Max;
}
CurrentValue = _integerNode.Value;
NotifyPropertyChanged("CurrentValueFormatted");
}
catch (Exception ex)
{
log.Error(
string.Format(
"{1}There was a problem fetching node value for \"{0}\"",
_propertyToControl,
FormattedSerialNumber),
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.Error(string.Format(
"{0}Unexpected control type for {1} node from Nodemap.", FormattedSerialNumber, nodename));
throw new Exception(string.Format("Unexpected control type!"));
}
try
{
EditBoxTooltip = string.Format("Min: {0}, Max: {1}", Min.ToString("G5"), Max.ToString("G5"));
}
catch (System.Exception /*ex*/)
{
}
}
#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*/)
{
log.Warn(string.Format(
"{1}Problem retrieving new value from {0} node", _propertyToControl, FormattedSerialNumber));
}
}
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 (Exception /*ex*/)
{
}
}
else if (e.Key == Key.Escape)
{
CancelEdit();
}
}
private void editbox_LostFocus(object sender, RoutedEventArgs e)
{
if (!CheckValueBounds(editbox.Text))
{
CancelEdit();
}
else
{
EndEdit();
if (_textChanged)
{
BindingExpression exp = this.editbox.GetBindingExpression(TextBox.TextProperty);
exp.UpdateSource();
SyncSpinnerValue();
}
_textChanged = false;
}
}
private void sliderbar_DragCompleted(object sender, DragCompletedEventArgs e)
{
UpdateNodeValue(sliderbar.Value);
this._dragStarted = false;
SyncSpinnerValue();
}
private void sliderbar_DragStarted(object sender, DragStartedEventArgs e)
{
this._dragStarted = true;
}
private void sliderbar_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double>e)
{
if (_skipCallback || _initializing)
{
return;
}
if (!_dragStarted)
{
UpdateNodeValue(e.NewValue, e.OldValue);
}
}
#endregion
#region IEditableObject
public void BeginEdit()
{
double tempValue = 0;
if (double.TryParse(editbox.Text, out tempValue))
{
_oldValue = tempValue;
}
}
public void CancelEdit()
{
CurrentValue = _oldValue;
}
public void EndEdit()
{
double tempValue = 0;
if (double.TryParse(editbox.Text, out tempValue))
{
_oldValue = tempValue;
}
}
#endregion
#region HELPERS
private bool UpdateNodeValue(double newValue, double oldValue = 0)
{
if (_initializing)
{
return false;
}
bool result = true;
if (_nodeType == typeof (Integer))
{
try
{
if (_integerNode != null && _integerNode.IsWritable)
{
double currentNodeValue = _integerNode.Value;
double nodeMinimumValue = _integerNode.Min;
double nodeMaximumValue = _integerNode.Max;
double tempValue = newValue;
IncrementSmall = _integerNode.Increment;
IncrementLarge = IncrementSmall * 2;
if ((nodeMaximumValue - nodeMinimumValue) % IncrementSmall != 0)
{
// Special case where (Max - Min) is not dividable by Increment
while ((tempValue - nodeMinimumValue) % IncrementSmall != 0)
{
if (tempValue < currentNodeValue)
{
tempValue--;
}
else
{
tempValue++;
}
if (tempValue >= nodeMaximumValue)
{
// find closest allowable value near Max
tempValue--;
while ((tempValue - nodeMinimumValue) % IncrementSmall != 0)
{
tempValue--;
}
break;
}
else if (tempValue < nodeMinimumValue)
{
tempValue = nodeMinimumValue;
break;
}
}
}
else
{
while ((tempValue - nodeMinimumValue) % IncrementSmall != 0)
{
if (tempValue < currentNodeValue)
{
tempValue--;
}
else
{
tempValue++;
}
if (tempValue >= nodeMaximumValue)
{
tempValue = nodeMaximumValue;
break;
}
else if (tempValue < nodeMinimumValue)
{
tempValue = nodeMinimumValue;
break;
}
}
}
newValue = tempValue;
_skipCallback = true;
_integerNode.Value = (long) newValue;
LogNodeUpdateAction(log, _node, newValue.ToString());
_skipCallback = false;
}
else
{
log.Debug(string.Format(
"{1}{0} node is currently not writable.", _propertyToControl, FormattedSerialNumber));
result = false;
}
}
catch (Exception ex)
{
result = false;
log.Error(
string.Format("{1}Problem updating {0} node.", _propertyToControl, FormattedSerialNumber),
ex);
}
finally
{
// read value back from node
if (_integerNode != null && _integerNode.IsReadable)
{
_skipCallback = true;
sliderbar.Value = _integerNode.Value;
_skipCallback = false;
}
}
}
else if (_nodeType == typeof (Float))
{
bool success = false;
try
{
if (_floatNode != null && _floatNode.IsWritable)
{
double increment;
if (TryGetFloatIncrement(_floatNode, out increment))
{
newValue = NormalizeValueToIncrement(newValue, _floatNode.Min, _floatNode.Max, increment);
}
int count = 0;
while (!success && count < k_numOfRetried)
{
try
{
_skipCallback = true;
_floatNode.Value = newValue;
LogNodeUpdateAction(log, _node, newValue.ToString());
success = true;
}
catch (System.Exception /*ex*/)
{
count++;
}
finally
{
_skipCallback = false;
}
}
}
else
{
log.Debug(string.Format(
"{1}{0} node is currently not writable.", _propertyToControl, FormattedSerialNumber));
result = false;
}
}
catch (Exception ex)
{
result = false;
log.Error(
string.Format(
"{1}Problem updating node value for feature {0}.",
_propertyToControl,
FormattedSerialNumber),
ex);
}
finally
{
// read new value back from node
if (_floatNode != null && _floatNode.IsReadable)
{
_skipCallback = true;
sliderbar.Value = _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(lockIconBtn, Dock.Left);
DockPanel.SetDock(sliderbar, Dock.Left);
rootLayout.Children.Add(nameLabel);
rootLayout.Children.Add(editboxContainer);
rootLayout.Children.Add(unitLabel);
rootLayout.Children.Add(lockIconBtn);
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(lockIconBtn, Dock.Right);
rootLayout.Children.Add(nameLabel);
rootLayout.Children.Add(unitLabel);
rootLayout.Children.Add(editboxContainer);
rootLayout.Children.Add(lockIconBtn);
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(lockIconBtn, 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(lockIconBtn);
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(lockIconBtn, Dock.Right);
DockPanel.SetDock(unitLabel, Dock.Right);
DockPanel.SetDock(editboxContainer, Dock.Right);
DockPanel.SetDock(sliderbar, Dock.Left);
childPanel.Children.Add(lockIconBtn);
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
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);
}
}
}
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));
}
}
}
}
#endregion
private void editbox_GotFocus(object sender, RoutedEventArgs e)
{
editbox.SelectAll();
BeginEdit();
}
}
}
}