aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner
diff options
context:
space:
mode:
authorVictoria Plitt <Victoria.Plitt@twine-s.com>2019-09-25 18:29:12 +0300
committerVictoria Plitt <Victoria.Plitt@twine-s.com>2019-09-25 18:29:12 +0300
commitd990cf35a8816c7447fef4552ee83d041466636d (patch)
treeca9ce9e9a729d204c4e0726710873f9cfad9b749 /Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner
parent0286fc4f7675459d660ec7a1b6a6a149376ad74e (diff)
downloadTango-d990cf35a8816c7447fef4552ee83d041466636d.tar.gz
Tango-d990cf35a8816c7447fef4552ee83d041466636d.zip
Implemented Hardware Configuration Tab on Machine Designer !!!
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner')
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Models/HardwareCollection.cs27
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Models/HardwareComponent.cs27
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Models/HardwareParameter.cs122
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Tango.MachineStudio.MachineDesigner.csproj13
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/HardwareConfigurationViewVM.cs413
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs42
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/HardwareConfigurationView.xaml239
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/HardwareConfigurationView.xaml.cs76
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml3
9 files changed, 961 insertions, 1 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Models/HardwareCollection.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Models/HardwareCollection.cs
new file mode 100644
index 000000000..765bc9dfd
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Models/HardwareCollection.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+
+namespace Tango.MachineStudio.MachineDesigner.Models
+{
+ public class HardwareCollection : ExtendedObject
+ {
+ public String CollectionName { get; set; }
+
+ public SynchronizedObservableCollection<HardwareComponent> Components { get; set; }
+ public bool HasDifferences
+ {
+ get
+ {
+ return Components.Any(item => item.HasDifferences);
+ }
+ }
+ public HardwareCollection()
+ {
+ Components = new SynchronizedObservableCollection<HardwareComponent>();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Models/HardwareComponent.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Models/HardwareComponent.cs
new file mode 100644
index 000000000..d03428ce5
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Models/HardwareComponent.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+
+namespace Tango.MachineStudio.MachineDesigner.Models
+{
+ public class HardwareComponent : ExtendedObject
+ {
+ public String ComponentName { get; set; }
+ public String Description { get; set; }
+ public SynchronizedObservableCollection<HardwareParameter> Properties { get; set; }
+ public bool HasDifferences
+ {
+ get
+ {
+ return Properties.Any(item => item.IsDifferent);
+ }
+ }
+ public HardwareComponent()
+ {
+ Properties = new SynchronizedObservableCollection<HardwareParameter>();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Models/HardwareParameter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Models/HardwareParameter.cs
new file mode 100644
index 000000000..33dbcad71
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Models/HardwareParameter.cs
@@ -0,0 +1,122 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+using Tango.Core.Commands;
+
+namespace Tango.MachineStudio.MachineDesigner.Models
+{
+ public class HardwareParameter : ExtendedObject
+ {
+ public event EventHandler Selected;
+
+ public HardwareComponent Component { get; set; }
+
+ public RelayCommand DeleteCommand { get; set; }
+
+ public String PropertyName { get; set; }
+
+ private Object _defaultValue;
+ public Object DefaultValue
+ {
+ get { return _defaultValue; }
+ set
+ {
+ _defaultValue = value;
+ }
+ }
+
+ public Type Type
+ {
+ get { return DefaultValue.GetType(); }
+ }
+ // updated after editing
+ private Object _actualValue = null;
+ public Object ActualValue
+ {
+ get { return _actualValue; }
+ set
+ {
+ _actualValue = value;
+ RaisePropertyChangedAuto();
+ RaisePropertyChanged(nameof(IsDifferent));
+ RaisePropertyChanged(nameof(IsValuesMatched));
+ }
+ }
+
+ // displayed during editing
+ private Object _editableValue = null;
+ public Object EditableValue
+ {
+ get { return _editableValue; }
+ set
+ {
+ _editableValue = value;
+ RaisePropertyChangedAuto();
+ }
+ }
+
+ private bool _isSelected;
+ public bool IsSelected
+ {
+ get { return _isSelected; }
+ set
+ {
+ _isSelected = value;
+
+ OnIsSelectedChanged();
+
+ RaisePropertyChangedAuto();
+ if (_isSelected)
+ {
+ Selected?.Invoke(this, new EventArgs());
+ }
+ }
+ }
+
+
+ private void OnIsSelectedChanged()
+ {
+ if (IsSelected)
+ {
+ EditableValue = ActualValue != null ? ActualValue : DefaultValue;
+ }
+ else
+ {
+ if (EditableValue != null)
+ {
+ ActualValue = EditableValue;
+ }
+ }
+ }
+
+ public bool IsDifferent
+ {
+ get
+ {
+ return (ActualValue != null);
+ }
+ }
+
+ public bool IsValuesMatched
+ {
+ get
+ {
+ return ActualValue != null && ActualValue.ToString() == DefaultValue.ToString();
+ }
+ }
+
+ public void DeleteValue()
+ {
+ ActualValue = null;
+ EditableValue = null;
+ }
+
+ public HardwareParameter()
+ {
+ DeleteCommand = new RelayCommand(DeleteValue);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Tango.MachineStudio.MachineDesigner.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Tango.MachineStudio.MachineDesigner.csproj
index 71f5ec864..855b0d196 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Tango.MachineStudio.MachineDesigner.csproj
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Tango.MachineStudio.MachineDesigner.csproj
@@ -81,14 +81,21 @@
</Compile>
<Compile Include="AutoComplete\MachineVersionsProvider.cs" />
<Compile Include="Contracts\IMainView.cs" />
+ <Compile Include="Models\HardwareCollection.cs" />
+ <Compile Include="Models\HardwareComponent.cs" />
+ <Compile Include="Models\HardwareParameter.cs" />
<Compile Include="ViewModelLocator.cs" />
<Compile Include="ViewModels\ColorCalibrationViewVM.cs" />
+ <Compile Include="ViewModels\HardwareConfigurationViewVM.cs" />
<Compile Include="ViewModels\MachineCreationDialogVM.cs" />
<Compile Include="ViewModels\MachineVersionDialogVM.cs" />
<Compile Include="ViewModels\MainViewVM.cs" />
<Compile Include="Views\ColorCalibrationView.xaml.cs">
<DependentUpon>ColorCalibrationView.xaml</DependentUpon>
</Compile>
+ <Compile Include="Views\HardwareConfigurationView.xaml.cs">
+ <DependentUpon>HardwareConfigurationView.xaml</DependentUpon>
+ </Compile>
<Compile Include="Views\MachineCreationDialog.xaml.cs">
<DependentUpon>MachineCreationDialog.xaml</DependentUpon>
</Compile>
@@ -121,6 +128,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
+ <Page Include="Views\HardwareConfigurationView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="Views\MachineCreationDialog.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -292,7 +303,7 @@
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
- <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" />
+ <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" />
</VisualStudio>
</ProjectExtensions>
</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/HardwareConfigurationViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/HardwareConfigurationViewVM.cs
new file mode 100644
index 000000000..415a8ab72
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/HardwareConfigurationViewVM.cs
@@ -0,0 +1,413 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+using Tango.BL;
+using Tango.BL.Entities;
+using Tango.BL.Enumerations;
+using Tango.BL.ValueObjects;
+using Tango.Core;
+using Tango.Core.Commands;
+using Tango.MachineStudio.Common.Notifications;
+using Tango.MachineStudio.MachineDesigner.Models;
+using Tango.SharedUI;
+
+namespace Tango.MachineStudio.MachineDesigner.ViewModels
+{
+ public class HardwareConfigurationViewVM : ViewModel
+ {
+ private INotificationProvider _notification;
+ private HardwareConfiguration _hwConfig;
+
+ #region Properties
+
+ public SynchronizedObservableCollection<HardwareCollection> Collections { get; set; }
+
+ private bool _isShowDifference;
+ public bool IsShowDifference
+ {
+ get { return _isShowDifference; }
+ set
+ {
+ _isShowDifference = value;
+ RaisePropertyChangedAuto();
+ }
+ }
+
+ private ICollectionView _collectionViewSource;
+ public ICollectionView CollectionsViewSource
+ {
+ get { return _collectionViewSource; }
+ set { _collectionViewSource = value; RaisePropertyChangedAuto(); }
+ }
+
+ private String _PropertyFilter;
+ public String PropertyFilter
+ {
+ get { return _PropertyFilter; }
+ set
+ {
+ _PropertyFilter = value;
+ RaisePropertyChangedAuto();
+ OnFilterChanged();
+ }
+ }
+
+ private String _componentFilter;
+ public String ComponentFilter
+ {
+ get { return _componentFilter; }
+ set
+ {
+ _componentFilter = value;
+ RaisePropertyChangedAuto();
+ OnFilterChanged();
+ }
+ }
+
+ #endregion
+
+ private void OnFilterChanged()
+ {
+ CollectionsViewSource.Refresh();
+ }
+
+ public HardwareConfigurationViewVM(INotificationProvider notification)
+ {
+ _notification = notification;
+ Collections = new SynchronizedObservableCollection<HardwareCollection>();
+ CollectionsViewSource = CollectionViewSource.GetDefaultView(Collections);
+ CollectionsViewSource.Filter = new Predicate<object>(FilterCollection);
+
+ //Test();
+ }
+
+ #region Build Collection
+
+ public void Init(Configuration configuration)
+ {
+ HardwareVersion hardwareVersion = configuration.HardwareVersion;
+
+ _hwConfig = configuration.GetHardwareConfiguration();
+
+ Collections.Clear();
+ Collections.Add(CreateMotorsCollection(hardwareVersion));
+ Collections.Add(CreateDancerCollection(hardwareVersion));
+ Collections.Add(CreatePidCollection(hardwareVersion));
+ Collections.Add(CreateWindersCollection(hardwareVersion));
+ Collections.Add(CreateSpeedSensorsCollection(hardwareVersion));
+ Collections.Add(CreateBlowersCollection(hardwareVersion));
+ Collections.Add(CreateBreakSensorCollection(hardwareVersion));
+ }
+
+ private HardwareCollection CreateMotorsCollection(HardwareVersion hardwareVersion)
+ {
+ HardwareCollection collection = new HardwareCollection()
+ {
+ CollectionName = "MOTORS"
+ };
+ foreach (var motorTypeCode in Enum.GetValues(typeof(HardwareMotorTypes)).Cast<HardwareMotorTypes>())
+ {
+ var motor = hardwareVersion.HardwareMotors.SingleOrDefault(x => x.HardwareMotorType.Code == motorTypeCode.ToInt32());
+ if (motor != null)
+ {
+ var componentResult = CreateComponent(
+ motor.HardwareMotorType.Name,
+ motorTypeCode.ToDescription(),
+ GetComponentProperties(typeof(HardwareMotorBase)),
+ motor);
+
+ collection.Components.Add(componentResult);
+ }
+ }
+ return collection;
+ }
+ private HardwareCollection CreateDancerCollection(HardwareVersion hardwareVersion)
+ {
+ HardwareCollection collection = new HardwareCollection()
+ {
+ CollectionName = "DANCERS"
+ };
+ foreach (var dancerTypeCode in Enum.GetValues(typeof(HardwareDancerTypes)).Cast<HardwareDancerTypes>())
+ {
+ var dancer = hardwareVersion.HardwareDancers.SingleOrDefault(x => x.HardwareDancerType.Code == dancerTypeCode.ToInt32());
+ if (dancer != null)
+ {
+ var componentResult = CreateComponent(
+ dancer.HardwareDancerType.Name,
+ dancerTypeCode.ToDescription(),
+ GetComponentProperties(typeof(HardwareDancerBase)),
+ dancer);
+
+ collection.Components.Add(componentResult);
+ }
+ }
+ return collection;
+ }
+ private HardwareCollection CreatePidCollection(HardwareVersion hardwareVersion)
+ {
+ HardwareCollection collection = new HardwareCollection()
+ {
+ CollectionName = "PID CONTROLS"
+ };
+ foreach (var pidTypeCode in Enum.GetValues(typeof(HardwarePidControlTypes)).Cast<HardwarePidControlTypes>())
+ {
+ var pidControl = hardwareVersion.HardwarePidControls.SingleOrDefault(x => x.HardwarePidControlType.Code == pidTypeCode.ToInt32());
+ if (pidControl != null)
+ {
+ var componentResult = CreateComponent(
+ pidControl.HardwarePidControlType.Name,
+ pidTypeCode.ToDescription(),
+ GetComponentProperties(typeof(HardwarePidControlBase)),
+ pidControl);
+
+ collection.Components.Add(componentResult);
+ }
+ }
+ return collection;
+ }
+ private HardwareCollection CreateWindersCollection(HardwareVersion hardwareVersion)
+ {
+ HardwareCollection collection = new HardwareCollection()
+ {
+ CollectionName = "WINDERS"
+ };
+ foreach (var winderTypeCode in Enum.GetValues(typeof(HardwareWinderTypes)).Cast<HardwareWinderTypes>())
+ {
+ var winderControl = hardwareVersion.HardwareWinders.SingleOrDefault(x => x.HardwareWinderType.Code == winderTypeCode.ToInt32());
+ if (winderControl != null)
+ {
+ var componentResult = CreateComponent(
+ winderControl.HardwareWinderType.Name,
+ winderTypeCode.ToDescription(),
+ GetComponentProperties(typeof(HardwareWinderBase)),
+ winderControl);
+
+ collection.Components.Add(componentResult);
+ }
+ }
+ return collection;
+ }
+ private HardwareCollection CreateSpeedSensorsCollection(HardwareVersion hardwareVersion)
+ {
+ HardwareCollection collection = new HardwareCollection()
+ {
+ CollectionName = "SPEED SENSORS"
+ };
+ foreach (var speedSensorTypeCode in Enum.GetValues(typeof(HardwareSpeedSensorTypes)).Cast<HardwareSpeedSensorTypes>())
+ {
+ var speedSensor = hardwareVersion.HardwareSpeedSensors.SingleOrDefault(x => x.HardwareSpeedSensorType.Code == speedSensorTypeCode.ToInt32());
+ if (speedSensor != null)
+ {
+ var componentResult = CreateComponent(
+ speedSensor.HardwareSpeedSensorType.Name,
+ speedSensorTypeCode.ToDescription(),
+ GetComponentProperties(typeof(HardwareSpeedSensorBase)),
+ speedSensor);
+
+ collection.Components.Add(componentResult);
+ }
+ }
+ return collection;
+ }
+ private HardwareCollection CreateBlowersCollection(HardwareVersion hardwareVersion)
+ {
+ HardwareCollection collection = new HardwareCollection()
+ {
+ CollectionName = "BLOWERS"
+ };
+ foreach (var blowersTypeCode in Enum.GetValues(typeof(HardwareBlowerTypes)).Cast<HardwareBlowerTypes>())
+ {
+ var blower = hardwareVersion.HardwareBlowers.SingleOrDefault(x => x.HardwareBlowerType.Code == blowersTypeCode.ToInt32());
+ if (blower != null)
+ {
+ var componentResult = CreateComponent(
+ blower.HardwareBlowerType.Name,
+ blowersTypeCode.ToDescription(),
+ GetComponentProperties(typeof(HardwareBlowerBase)),
+ blower);
+
+ collection.Components.Add(componentResult);
+ }
+ }
+ return collection;
+ }
+ private HardwareCollection CreateBreakSensorCollection(HardwareVersion hardwareVersion)
+ {
+ HardwareCollection collection = new HardwareCollection()
+ {
+ CollectionName = "BREAK SENSOR"
+ };
+ foreach (var breakSensorsTypeCode in Enum.GetValues(typeof(HardwareBreakSensorTypes)).Cast<HardwareBreakSensorTypes>())
+ {
+ var breakSensor = hardwareVersion.HardwareBreakSensors.SingleOrDefault(x => x.HardwareBreakSensorType.Code == breakSensorsTypeCode.ToInt32());
+ if (breakSensor != null)
+ {
+ var componentResult = CreateComponent(
+ breakSensor.HardwareBreakSensorType.Name,
+ breakSensorsTypeCode.ToDescription(),
+ GetComponentProperties(typeof(HardwareBreakSensorBase)),
+ breakSensor);
+
+ collection.Components.Add(componentResult);
+ }
+ }
+ return collection;
+ }
+ private HardwareComponent CreateComponent(String name, String description, List<PropertyInfo> properties, Object component)
+ {
+ HardwareComponent hwComponent = new HardwareComponent()
+ {
+ Description = description,
+ ComponentName = name
+ };
+
+ foreach (var prop in properties)
+ {
+ var hProp = new HardwareParameter();
+ hProp.Component = hwComponent;
+ hProp.PropertyName = prop.Name;
+ hProp.DefaultValue = prop.GetValue(component);
+ hProp.Selected -= HProp_Selected;
+ hProp.Selected += HProp_Selected;
+
+ var configParam = _hwConfig.Parameters.SingleOrDefault(x => x.ComponentName == name && x.ParameterName == prop.Name);
+ hProp.ActualValue = configParam != null ? configParam.Value : null;
+ hwComponent.Properties.Add(hProp);
+ }
+ return hwComponent;
+ }
+
+ private void HProp_Selected(object sender, EventArgs e)
+ {
+ if (Collections != null)
+ {
+ Collections.SelectMany(x => x.Components).SelectMany(x => x.Properties).Where(x => x != sender).ToList().ForEach(x => x.IsSelected = false);
+ }
+ }
+
+ public void ClearSelections()
+ {
+ if (Collections != null)
+ {
+ Collections.SelectMany(x => x.Components).SelectMany(x => x.Properties).ToList().ForEach(x => x.IsSelected = false);
+ }
+ }
+
+ private List<PropertyInfo> GetComponentProperties(Type componentType)
+ {
+ List<String> exclude = new List<string>()
+ {
+ "Guid",
+ "ID",
+ "LastUpdated",
+ "Parameters",
+ };
+ return componentType.GetProperties(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public).Where(x => !x.PropertyType.IsClass && !exclude.Contains(x.Name)).ToList();
+ }
+
+ #endregion
+
+ public HardwareConfiguration GetResultingHardwareConfiguration()
+ {
+ HardwareConfiguration hwConfig = new HardwareConfiguration();
+
+ foreach (var parameter in Collections.SelectMany(x => x.Components).SelectMany(x => x.Properties).Where(x => x.IsDifferent))
+ {
+ hwConfig.Parameters.Add(new HardwareConfiguration.HardwareConfigurationParameter()
+ {
+ ComponentName = parameter.Component.ComponentName,
+ ParameterName = parameter.PropertyName,
+ Value = parameter.ActualValue
+ });
+ }
+
+ return hwConfig;
+ }
+
+ #region Filter
+
+ private bool FilterCollection(object obj)
+ {
+ HardwareCollection collection = obj as HardwareCollection;
+ var components = CollectionViewSource.GetDefaultView(collection.Components);
+ components.Filter = new Predicate<object>(FilterComponent);
+ return true;
+ }
+ private bool FilterComponent(object obj)
+ {
+ HardwareComponent component = obj as HardwareComponent;
+ var properties = CollectionViewSource.GetDefaultView(component.Properties);
+ properties.Filter = new Predicate<object>(FilterProperty);
+
+ if (!String.IsNullOrWhiteSpace(ComponentFilter))
+ {
+ var words = ComponentFilter.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
+ return words.Any(x => component.Description.ToLower().Contains(x.ToLower()));
+ }
+ else
+ {
+ return true;
+ }
+ }
+ private bool FilterProperty(object obj)
+ {
+ HardwareParameter hparameter = obj as HardwareParameter;
+
+ if (!String.IsNullOrWhiteSpace(PropertyFilter))
+ {
+ var words = PropertyFilter.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
+ return words.Any(x => hparameter.PropertyName.ToLower().Contains(x.ToLower()));
+ }
+ else
+ {
+ return true;
+ }
+
+ }
+
+ #endregion
+
+ #region test
+
+ private void Test()
+ {
+ HardwareCollection col1 = new HardwareCollection()
+ {
+ CollectionName = "Motors",
+
+ };
+ HardwareParameter par1 = new HardwareParameter()
+ {
+ PropertyName = "Prop1",
+ ActualValue = null,
+ DefaultValue = 12,
+
+ };
+
+ HardwareParameter par2 = new HardwareParameter()
+ {
+ PropertyName = "Prop2",
+ ActualValue = null,
+ DefaultValue = true
+ };
+
+ HardwareComponent comp1 = new HardwareComponent()
+ {
+ ComponentName = "H_C_1",
+ Description = "HardwareComponent"
+ };
+ comp1.Properties.Add(par1);
+ comp1.Properties.Add(par2);
+ col1.Components.Add(comp1);
+ Collections.Add(col1);
+
+ }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs
index eaca7cd6a..5f2dcd00d 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs
@@ -122,6 +122,19 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels
set { _colorCalibrationViewVM = value; RaisePropertyChangedAuto(); }
}
+ private HardwareConfigurationViewVM _hardwareConfigurationViewVM;
+
+ public HardwareConfigurationViewVM HardwareConfigurationViewVM
+ {
+ get { return _hardwareConfigurationViewVM; }
+ set
+ {
+ _hardwareConfigurationViewVM = value;
+ RaisePropertyChangedAuto();
+ }
+ }
+
+
#endregion
#region Commands
@@ -442,6 +455,11 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels
SelectedRML = ActiveMachineAdapter.Rmls.FirstOrDefault(),
};
+ HardwareConfigurationViewVM = new HardwareConfigurationViewVM(_notification);
+ HardwareConfigurationViewVM.Init(ActiveMachine.Configuration);
+
+ ActiveMachine.Configuration.HardwareVersionChanged += Configuration_HardwareVersionChanged;
+
View.NavigateTo(MachineDesignerNavigationView.MachineDetailsView);
}
catch (Exception ex)
@@ -457,6 +475,27 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels
}
}
+ private async void Configuration_HardwareVersionChanged(object sender, HardwareVersion e)
+ {
+ var version = ActiveMachine.Configuration.HardwareVersion;
+
+ if (version != null)
+ {
+ using (_notification.PushTaskItem("Loading hardware version..."))
+ {
+ try
+ {
+ version = await new HardwareVersionBuilder(ActiveMachineAdapter.Context).Set(version.Guid).WithHardwareComponents().BuildAsync();
+ HardwareConfigurationViewVM.Init(ActiveMachine.Configuration);
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex);
+ }
+ }
+ }
+ }
+
private async void SaveMachine()
{
foreach (var ids in ActiveMachine.Configuration.IdsPacks)
@@ -585,6 +624,9 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels
ColorCalibrationViewVM.Save();
+ var hwConfig = HardwareConfigurationViewVM.GetResultingHardwareConfiguration();
+ ActiveMachine.Configuration.SetHardwareConfiguration(hwConfig);
+
await ActiveMachineAdapter.Context.SaveChangesAsync();
if (SelectedMachine != null)
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/HardwareConfigurationView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/HardwareConfigurationView.xaml
new file mode 100644
index 000000000..78f5dad59
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/HardwareConfigurationView.xaml
@@ -0,0 +1,239 @@
+<UserControl x:Class="Tango.MachineStudio.MachineDesigner.Views.HardwareConfigurationView"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
+ xmlns:sys="clr-namespace:System;assembly=mscorlib"
+ xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI"
+ xmlns:local="clr-namespace:Tango.MachineStudio.MachineDesigner.Views"
+ xmlns:vm="clr-namespace:Tango.MachineStudio.MachineDesigner.ViewModels"
+ mc:Ignorable="d"
+ d:DesignHeight="450" d:DesignWidth="800" DataContext="{Binding HardwareConfigurationViewVM}">
+ <UserControl.Resources>
+ <converters:BooleanToVisibilityInverseConverter x:Key="BooleanToVisibilityInverseConverter" />
+ <converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
+ <converters:IsNullToVisibilityConverter x:Key="IsNullToVisibilityConverter" />
+ <converters:BooleanToYesNoConverter x:Key="BooleanToYesNoConverter" />
+ <converters:DoubleToIntConverter x:Key="DoubleToIntConverter" />
+
+ </UserControl.Resources>
+ <Grid Margin="0 40 0 0">
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="400"></ColumnDefinition>
+ <ColumnDefinition Width="Auto"></ColumnDefinition>
+ <ColumnDefinition Width="300"></ColumnDefinition>
+ </Grid.ColumnDefinitions>
+ <StackPanel Orientation="Vertical" HorizontalAlignment="Right" Margin="0 30 0 0" MouseUp="Main_container_MouseUp">
+
+ <TextBlock FontSize="10">Find component</TextBlock>
+ <Border Margin="0 2 0 0" Background="#78FFFFFF" BorderThickness="1" BorderBrush="Gray" CornerRadius="3" Padding="5">
+ <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
+ <materialDesign:PackIcon VerticalAlignment="Center" Width="24" Height="24" Kind="Magnify" />
+ <TextBox Style="{x:Null}" Background="Transparent" BorderThickness="0" Text="{Binding ComponentFilter,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,Delay=1000}" materialDesign:HintAssist.Hint="Search" Width="350" FontSize="16" />
+ </StackPanel>
+ </Border>
+
+ <TextBlock Margin="0 10 0 0" FontSize="10">Find parameter</TextBlock>
+ <Border Margin="0 2 0 0" Background="#78FFFFFF" BorderThickness="1" BorderBrush="Gray" CornerRadius="3" Padding="5">
+ <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
+ <materialDesign:PackIcon VerticalAlignment="Center" Width="24" Height="24" Kind="Magnify" />
+ <TextBox Style="{x:Null}" Background="Transparent" BorderThickness="0" Text="{Binding PropertyFilter,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,Delay=1000}" materialDesign:HintAssist.Hint="Search" Width="350" FontSize="16" />
+ </StackPanel>
+ </Border>
+ <StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="0 30 0 0" HorizontalAlignment="Left">
+ <CheckBox Name="cbShowOnlyDifference" IsChecked="{Binding IsShowDifference}" VerticalAlignment="Center"></CheckBox>
+ <TextBlock Margin="10 0 0 0" VerticalAlignment="Center" Text="Display only overridden parameters" FontSize="16" FontWeight="Normal"></TextBlock>
+ </StackPanel>
+ </StackPanel>
+ <ScrollViewer Focusable="False" Padding="0 0 10 0" VerticalScrollBarVisibility="Auto" Margin="0 0 0 0" HorizontalAlignment="Center" Grid.Column="1">
+ <Grid x:Name="main_container" MouseUp="Main_container_MouseUp">
+ <ItemsControl Focusable="False" Margin="0, 0, 0, 0" Name="lvDataBinding" ItemsSource="{Binding Collections}" HorizontalContentAlignment="Center"
+ VerticalContentAlignment="Top" >
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <DockPanel>
+ <TextBlock Margin="0 40 20 0" DockPanel.Dock="Left" Text="{Binding CollectionName}" FontSize="22" FontWeight="SemiBold" HorizontalAlignment="Right" TextAlignment="Right" VerticalAlignment="Top" Width="200" />
+ <Grid>
+ <Border Name="LeftB" Grid.Column="0" VerticalAlignment="Stretch" HorizontalAlignment="Center" MinWidth="800">
+ <Grid>
+ <StackPanel Orientation="Vertical">
+ <ItemsControl Focusable="False" Margin="10,0,0,0" Name="ComponentListLeft" ItemsSource="{Binding Components}" HorizontalContentAlignment="Stretch">
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <StackPanel Orientation="Vertical" Margin="0 10">
+ <TextBlock Margin="0 5" Text="{Binding Description}" FontWeight="SemiBold" FontSize="18"/>
+ <Border BorderThickness="1" BorderBrush="Gray" CornerRadius="3" Background="#6EFFFFFF">
+ <ItemsControl Focusable="False" Grid.Row="1" Margin="10" Name="PropertyListL" ItemsSource="{Binding Properties}" HorizontalContentAlignment="Stretch">
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <Grid VerticalAlignment="Center" Height="25" Background="Transparent">
+ <StackPanel Orientation="Horizontal">
+ <ToggleButton FocusVisualStyle="{x:Null}" x:Name="editPropertyButton" IsChecked="{Binding IsSelected,Mode=TwoWay}" BorderThickness="0" VerticalAlignment="Center" Cursor="Hand" Margin="10 0 0 0" Background="Transparent" VerticalContentAlignment="Top" Checked="EditPropertyButton_Checked">
+ <ToggleButton.Content>
+ <StackPanel Orientation="Horizontal">
+ <TextBlock VerticalAlignment="Center" FontWeight="Normal">
+ <Run Text="{Binding PropertyName}"></Run>
+ <Run>:</Run>
+ </TextBlock>
+ <TextBlock VerticalAlignment="Center" Text="{Binding DefaultValue}" Margin="10 0 10 0"/>
+ <materialDesign:PackIcon Visibility="{Binding IsDifferent,Converter={StaticResource BooleanToVisibilityConverter}}" Margin="10 0" VerticalAlignment="Center" Kind="ChevronRight" />
+
+ <TextBlock x:Name="actualValueTextBox" Text="{Binding ActualValue}" Margin="20 0 0 0" FontWeight="Bold" HorizontalAlignment="Left" Visibility="{Binding Path=IsChecked, ElementName=editPropertyButton, Converter={StaticResource BooleanToVisibilityInverseConverter}}" VerticalAlignment="Center" >
+ <TextBlock.Style>
+ <Style TargetType="TextBlock">
+ <Setter Property="Visibility" Value="Collapsed" />
+ <Style.Triggers>
+ <MultiDataTrigger>
+ <MultiDataTrigger.Conditions>
+ <Condition Binding="{ Binding Path=IsChecked, ElementName=editPropertyButton}" Value="False" />
+ <Condition Binding="{ Binding Path=ActualValue ,Converter={StaticResource IsNullToVisibilityConverter}}" Value="Visible" />
+ </MultiDataTrigger.Conditions>
+ <Setter Property="Visibility" Value="Visible" />
+ </MultiDataTrigger>
+ </Style.Triggers>
+ </Style>
+ </TextBlock.Style>
+ </TextBlock>
+ <ContentControl Visibility="{Binding ElementName=editPropertyButton,Path=IsChecked,Converter={StaticResource BooleanToVisibilityConverter}}" Margin="5 0 0 0" Content="{Binding}">
+ <ContentControl.Resources>
+ <DataTemplate x:Key="int" DataType="{x:Type sys:Int32}">
+ <mahapps:NumericUpDown KeyDown="NumericUpDown_KeyDown" MinHeight="20" MaxWidth="400" VerticalContentAlignment="Center" ScrollViewer.HorizontalScrollBarVisibility="Disabled" HorizontalAlignment="Center" Value="{Binding EditableValue,Converter={StaticResource DoubleToIntConverter}, UpdateSourceTrigger=PropertyChanged}" Background="Transparent" HideUpDownButtons="True" InterceptArrowKeys="True" BorderThickness="0 0 0 1" InterceptMouseWheel="True" HasDecimals="False" HorizontalContentAlignment="Center"/>
+ </DataTemplate>
+ <DataTemplate x:Key="double" DataType="{x:Type sys:Double}">
+ <mahapps:NumericUpDown KeyDown="NumericUpDown_KeyDown" MinHeight="20" MaxWidth="400" VerticalContentAlignment="Center" ScrollViewer.HorizontalScrollBarVisibility="Disabled" HorizontalAlignment="Center" Value="{Binding EditableValue, UpdateSourceTrigger=PropertyChanged}" Background="Transparent" HideUpDownButtons="True" InterceptArrowKeys="True" BorderThickness="0 0 0 1" InterceptMouseWheel="True" HasDecimals="True" HorizontalContentAlignment="Center"/>
+ </DataTemplate>
+ <DataTemplate x:Key="bool" DataType="{x:Type sys:Boolean}">
+ <ToggleButton Margin="10 2 0 0" IsChecked="{Binding EditableValue,UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Center" VerticalContentAlignment="Center" HorizontalAlignment="Right"></ToggleButton>
+ </DataTemplate>
+ </ContentControl.Resources>
+ <ContentControl.Style>
+ <Style TargetType="ContentControl">
+ <Setter Property="ContentTemplate" Value="{x:Null}">
+ </Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding Type.Name}" Value="Int32">
+ <Setter Property="ContentTemplate" Value="{StaticResource int}" />
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Type.Name}" Value="Double">
+ <Setter Property="ContentTemplate" Value="{StaticResource double}" />
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Type.Name}" Value="Boolean">
+ <Setter Property="ContentTemplate" Value="{StaticResource bool}" />
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </ContentControl.Style>
+ </ContentControl>
+
+ </StackPanel>
+ </ToggleButton.Content>
+ <ToggleButton.Style>
+ <Style TargetType="{x:Type ToggleButton}">
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="ToggleButton">
+ <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1" Background="{TemplateBinding Background}" Margin="0" Padding="3,0,4,2">
+ <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
+ </Border>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ <Setter Property="BorderBrush" Value="Transparent"/>
+ <Style.Triggers>
+ <Trigger Property="IsMouseOver" Value="True">
+ <Setter Property="Background" Value="Transparent"></Setter>
+ <Setter Property="BorderBrush" Value="Gray" />
+ </Trigger>
+ <Trigger Property="IsPressed" Value="True">
+ <Setter Property="Background" Value="Transparent"></Setter>
+ <Setter Property="BorderBrush" Value="{StaticResource AccentColorBrush}" />
+ </Trigger>
+ <Trigger Property="IsChecked" Value="True">
+ <Setter Property="Background" Value="Transparent"></Setter>
+ <Setter Property="BorderBrush" Value="{StaticResource RedBrush300}" />
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+ </ToggleButton.Style>
+ </ToggleButton>
+ <materialDesign:PackIcon x:Name="pencilicon" Foreground="{StaticResource RedBrush300}" Kind="Pencil" VerticalAlignment="Center" Visibility="{Binding IsSelected,Converter={StaticResource BooleanToVisibilityConverter}}"/>
+
+ <StackPanel Margin="10 0 0 0" Orientation="Horizontal">
+ <materialDesign:PackIcon VerticalAlignment="Center" Visibility="{Binding IsValuesMatched,Converter={StaticResource BooleanToVisibilityConverter}}" Width="18" Height="18" Kind="Alert" ToolTip="Parameter is overridden but equal" Foreground="{StaticResource OrangeBrush300}">
+ <materialDesign:PackIcon.Style>
+ <Style TargetType="FrameworkElement">
+ <Style.Triggers>
+ <EventTrigger RoutedEvent="Loaded">
+ <EventTrigger.Actions>
+ <BeginStoryboard x:Name="alertStory">
+ <Storyboard>
+ <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Duration="00:00:01" RepeatBehavior="Forever">
+ <DiscreteDoubleKeyFrame KeyTime="00:00:00" Value="1" />
+ <DiscreteDoubleKeyFrame KeyTime="00:00:0.5" Value="0" />
+ </DoubleAnimationUsingKeyFrames>
+ </Storyboard>
+ </BeginStoryboard>
+ </EventTrigger.Actions>
+ </EventTrigger>
+ <EventTrigger RoutedEvent="Unloaded">
+ <EventTrigger.Actions>
+ <RemoveStoryboard BeginStoryboardName="alertStory" />
+ </EventTrigger.Actions>
+ </EventTrigger>
+ </Style.Triggers>
+ </Style>
+ </materialDesign:PackIcon.Style>
+ </materialDesign:PackIcon>
+ <Button Margin="5 0 0 0" Command="{Binding DeleteCommand}" VerticalAlignment="Center" Width="24" Height="24" Padding="0" Style="{StaticResource MaterialDesignFlatButton}" Visibility="{Binding IsDifferent,Converter={StaticResource BooleanToVisibilityConverter}}">
+ <materialDesign:PackIcon Width="16" Height="16" Kind="Close" ToolTip="Clear" Foreground="{StaticResource RedBrush300}" />
+ </Button>
+ </StackPanel>
+ </StackPanel>
+ </Grid>
+ <DataTemplate.Triggers>
+ <MultiDataTrigger>
+ <MultiDataTrigger.Conditions>
+ <Condition Binding="{Binding ElementName=cbShowOnlyDifference, Path=IsChecked}" Value="True" />
+ <Condition Binding="{Binding IsDifferent}" Value="False" />
+ </MultiDataTrigger.Conditions>
+ <MultiDataTrigger.Setters>
+ <Setter Property="Visibility" Value="Collapsed" />
+ </MultiDataTrigger.Setters>
+ </MultiDataTrigger>
+ </DataTemplate.Triggers>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
+ </Border>
+ </StackPanel>
+ <DataTemplate.Triggers>
+ <MultiDataTrigger>
+ <MultiDataTrigger.Conditions>
+ <Condition Binding="{Binding ElementName=cbShowOnlyDifference, Path=IsChecked}" Value="True" />
+ <Condition Binding="{Binding HasDifferences}" Value="False" />
+ </MultiDataTrigger.Conditions>
+ <MultiDataTrigger.Setters>
+ <Setter Property="Visibility" Value="Collapsed" />
+ </MultiDataTrigger.Setters>
+ </MultiDataTrigger>
+ </DataTemplate.Triggers>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
+ </StackPanel>
+ </Grid>
+ </Border>
+ </Grid>
+ </DockPanel>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
+ </Grid>
+ </ScrollViewer>
+ </Grid>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/HardwareConfigurationView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/HardwareConfigurationView.xaml.cs
new file mode 100644
index 000000000..0103b3220
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/HardwareConfigurationView.xaml.cs
@@ -0,0 +1,76 @@
+using MahApps.Metro.Controls;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using Tango.MachineStudio.MachineDesigner.ViewModels;
+
+namespace Tango.MachineStudio.MachineDesigner.Views
+{
+ /// <summary>
+ /// Interaction logic for HardwereConfigurationView.xaml
+ /// </summary>
+ public partial class HardwareConfigurationView : UserControl
+ {
+ public HardwareConfigurationView()
+ {
+ InitializeComponent();
+ }
+
+ private void Property_MouseEnter(object sender, MouseEventArgs e)
+ {
+
+ }
+
+ private void Property_MouseLeave(object sender, MouseEventArgs e)
+ {
+
+ }
+
+ private void Main_container_MouseUp(object sender, MouseButtonEventArgs e)
+ {
+ ClearSelection();
+ }
+
+ private void NumericUpDown_KeyDown(object sender, KeyEventArgs e)
+ {
+ if (e.Key == Key.Return)
+ {
+ ClearSelection();
+ }
+ }
+
+ private void ClearSelection()
+ {
+ if (DataContext != null)
+ {
+ (DataContext as HardwareConfigurationViewVM).ClearSelections();
+ }
+ }
+
+ private async void EditPropertyButton_Checked(object sender, RoutedEventArgs e)
+ {
+ FrameworkElement toggle = sender as FrameworkElement;
+ FrameworkElement parent = toggle.FindAncestor<StackPanel>() as StackPanel;
+ var num = parent.FindChild<NumericUpDown>();
+
+ if (num != null)
+ {
+ await Task.Delay(50);
+ num.Focus();
+ num.SelectAll();
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml
index 7acb4c806..1f748fe9f 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml
@@ -58,6 +58,9 @@
<TabItem Header="COLOR CALIBRATION">
<local:ColorCalibrationView/>
</TabItem>
+ <TabItem Header="HW CONFIGURATION">
+ <local:HardwareConfigurationView/>
+ </TabItem>
</TabControl>
</Grid>
</DockPanel>