aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShlomo Hecht <shlomo@twine-s.com>2020-05-18 17:26:52 +0300
committerShlomo Hecht <shlomo@twine-s.com>2020-05-18 17:26:52 +0300
commit231591bb23fc74ffd038c2d58af1c8669e6cf61b (patch)
treebb8a52ba8dd482699b560d595eacd52bc69755b5
parent049be36c736eb88d9030c2ce720863375ce134cc (diff)
parent9b9121935fbf6fc46a346beac95604086961ddde (diff)
downloadTango-231591bb23fc74ffd038c2d58af1c8669e6cf61b.tar.gz
Tango-231591bb23fc74ffd038c2d58af1c8669e6cf61b.zip
Merge branch 'master' of https://twinetfs.visualstudio.com/Tango/_git/Tango
-rw-r--r--Software/DB/Tango.mdfbin75497472 -> 75497472 bytes
-rw-r--r--Software/DB/Tango_log.ldfbin22675456 -> 22675456 bytes
-rw-r--r--Software/Visual_Studio/Advanced Installer Projects/PPC Installer-cache/cacheIndex.txtbin52 -> 52 bytes
-rw-r--r--Software/Visual_Studio/Advanced Installer Projects/PPC Installer.aip24
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Controls/DiagnosticsGrid.cs38
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Controls/DiagnosticsGridLinesEditor.xaml108
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Controls/DiagnosticsGridLinesEditor.xaml.cs254
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Controls/DiagnosticsSelectionGrid.cs202
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Converters/DiagnosticsWidgetToSettingsViewConverter.cs12
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Converters/DiagnosticsWidgetToViewConverter.cs4
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Converters/ValveStateComparerToBooleanConverter.cs34
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/DiagnosticsPackage.cs49
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/DiagnosticsSettings.cs14
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsConfigurableWidget.cs39
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsProject.cs16
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsProjectTab.cs42
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsProjectTabColumnDefinition.cs10
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsProjectTabRowDefinition.cs10
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsUserSettingsCollection.cs100
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsUserSettingsManager.cs66
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsUserWidgetSettings.cs14
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsWidget.cs144
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsWidgetComponent.cs14
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/ISupportsComponentSelection.cs23
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidget.cs218
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidgetSettings.cs38
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidgetSettingsView.xaml27
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidgetSettingsView.xaml.cs28
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidgetView.xaml185
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidgetView.xaml.cs28
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/Images/dispenser_line.pngbin0 -> 36326 bytes
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Heater/HeaterWidget.cs153
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Heater/HeaterWidgetView.xaml202
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Heater/HeaterWidgetView.xaml.cs34
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Heater/Images/temperature.pngbin0 -> 1827 bytes
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Input/InputWidget.cs106
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Input/InputWidgetView.xaml18
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Input/InputWidgetView.xaml.cs28
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Monitor/MonitorWidget.cs56
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Monitor/MonitorWidgetSettingsView.xaml2
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Monitor/MonitorWidgetView.xaml36
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidget.cs219
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetSettings.cs38
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetSettingsView.xaml27
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetSettingsView.xaml.cs28
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetState.cs17
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetView.xaml175
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetView.xaml.cs28
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraph/RealTimeGraphWidget.cs2
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraph/RealTimeGraphWidgetBase.cs46
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraph/RealTimeGraphWidgetSettingsView.xaml4
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraphMultiChannel/RealTimeGraphMultiChannelWidget.cs85
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraphMultiChannel/RealTimeGraphMultiChannelWidgetSettingsView.xaml4
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidget.cs57
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidgetSettings.cs20
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidgetSettingsView.xaml24
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidgetSettingsView.xaml.cs28
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidgetView.xaml18
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidgetView.xaml.cs28
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Valve/Images/valve.pngbin0 -> 850 bytes
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Valve/ValveWidget.cs150
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Valve/ValveWidgetView.xaml111
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Valve/ValveWidgetView.xaml.cs28
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Tango.FSE.Diagnostics.csproj112
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Themes/Generic.xaml150
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModels/DiagnosticsTabViewVM.cs37
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModels/DiagnosticsViewVM.cs557
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Views/DiagnosticsTabView.xaml215
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Views/DiagnosticsTabView.xaml.cs15
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Views/DiagnosticsView.xaml389
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/diagnostics.json150
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/packages.config3
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/TestDesignerView.xaml2
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.UsersAndRoles/Models/RoleModel.cs9
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.UsersAndRoles/ViewModels/UserDetailsViewVM.cs2
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.UsersAndRoles/Views/UserDetailsView.xaml2
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.BL/EntityRepositoryBase.cs2
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.BL/Services/TechComponentsService.cs33
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Authorization/AuthorizationHelper.cs2
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/IconButton.cs1
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/IconButton.xaml143
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/IconRepeatButton.cs35
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/IconRepeatButton.xaml116
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs21
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Fonts/angelina.TTFbin0 -> 77048 bytes
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Fonts/indie.ttfbin0 -> 55300 bytes
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Images/shadow_left.pngbin0 -> 70330 bytes
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Images/shadow_right.pngbin0 -> 71368 bytes
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Images/shadow_top.pngbin0 -> 40011 bytes
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Controls.xaml1
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Images.xaml4
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/MahApps.xaml973
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Styles.xaml1
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj17
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/App.xaml6
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/FSEApplication/DefaultFSEApplicationManager.cs6
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/MainWindow.xaml2
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/InternalModuleViewVM.cs40
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LayoutView.xaml12
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LoginView.xaml9
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs23
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs2
-rw-r--r--Software/Visual_Studio/Tango.BL/Entities/Job.cs52
-rw-r--r--Software/Visual_Studio/Tango.BL/Enumerations/Permissions.cs6
-rw-r--r--Software/Visual_Studio/Tango.Core/ExtendedObject.cs2
-rw-r--r--Software/Visual_Studio/Tango.Core/TangoProgress.cs5
-rw-r--r--Software/Visual_Studio/Tango.Touch/Controls/LightTouchDataGrid.cs98
107 files changed, 6264 insertions, 504 deletions
diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf
index 90ddc4c39..3b670d23b 100644
--- a/Software/DB/Tango.mdf
+++ b/Software/DB/Tango.mdf
Binary files differ
diff --git a/Software/DB/Tango_log.ldf b/Software/DB/Tango_log.ldf
index 13bba78e4..811397251 100644
--- a/Software/DB/Tango_log.ldf
+++ b/Software/DB/Tango_log.ldf
Binary files differ
diff --git a/Software/Visual_Studio/Advanced Installer Projects/PPC Installer-cache/cacheIndex.txt b/Software/Visual_Studio/Advanced Installer Projects/PPC Installer-cache/cacheIndex.txt
index a603ff06b..9453b5c13 100644
--- a/Software/Visual_Studio/Advanced Installer Projects/PPC Installer-cache/cacheIndex.txt
+++ b/Software/Visual_Studio/Advanced Installer Projects/PPC Installer-cache/cacheIndex.txt
Binary files differ
diff --git a/Software/Visual_Studio/Advanced Installer Projects/PPC Installer.aip b/Software/Visual_Studio/Advanced Installer Projects/PPC Installer.aip
index 1cd0ba200..2da259bc0 100644
--- a/Software/Visual_Studio/Advanced Installer Projects/PPC Installer.aip
+++ b/Software/Visual_Studio/Advanced Installer Projects/PPC Installer.aip
@@ -18,10 +18,10 @@
<ROW Property="ARPNOREPAIR" Value="1" MultiBuildValue="DefaultBuild:1"/>
<ROW Property="ARPSYSTEMCOMPONENT" Value="1"/>
<ROW Property="Manufacturer" Value="Twine"/>
- <ROW Property="ProductCode" Value="1033:{61DA9B2E-261E-4CE4-94D8-1E04EF41CA9E} " Type="16"/>
+ <ROW Property="ProductCode" Value="1033:{E9D4AC4F-64FC-4C07-81BE-981370DA12AA} " Type="16"/>
<ROW Property="ProductLanguage" Value="1033"/>
<ROW Property="ProductName" Value="Tango"/>
- <ROW Property="ProductVersion" Value="1.1.15.0" Type="32"/>
+ <ROW Property="ProductVersion" Value="1.1.16.0" Type="32"/>
<ROW Property="SecureCustomProperties" Value="OLDPRODUCTS;AI_NEWERPRODUCTFOUND;AI_SETUPEXEPATH;SETUPEXEDIR"/>
<ROW Property="UpgradeCode" Value="{F8EAB8B4-FD57-45B7-8307-D52DF760273D}"/>
<ROW Property="WindowsType9X" MultiBuildValue="DefaultBuild:Windows 9x/ME" ValueLocId="-"/>
@@ -202,13 +202,11 @@
<ROW Component="mscoree.dll" ComponentId="{85F439D0-8FD0-4B99-888D-336C7A125E3D}" Directory_="APPDIR" Attributes="0" KeyPath="mscoree.dll"/>
<ROW Component="msvcp140d.dll" ComponentId="{69E32675-9ACF-4C23-A495-300B78913B66}" Directory_="APPDIR" Attributes="0" KeyPath="msvcp140d.dll"/>
<ROW Component="protobufnet.dll" ComponentId="{163F1E17-6462-4ABE-BC86-E055F7690139}" Directory_="APPDIR" Attributes="0" KeyPath="protobufnet.dll"/>
- <ROW Component="turbojpeg.dll" ComponentId="{C21C2FF4-FF27-4413-B12A-18D5859E5755}" Directory_="win7x64_Dir" Attributes="256" KeyPath="turbojpeg.dll"/>
- <ROW Component="turbojpeg.dll.meta" ComponentId="{A5E705A1-3D68-46A7-B45E-A227A8B3ABD4}" Directory_="win7x64_Dir" Attributes="0" KeyPath="turbojpeg.dll.meta" Type="0"/>
- <ROW Component="turbojpeg.dll.meta_1" ComponentId="{BD0788A1-1F83-4DD8-819F-943713292B13}" Directory_="win7x86_Dir" Attributes="0" KeyPath="turbojpeg.dll.meta_1" Type="0"/>
- <ROW Component="turbojpeg.dll_1" ComponentId="{7376D903-B1F4-4AD4-9027-73C947C73E64}" Directory_="win7x86_Dir" Attributes="0" KeyPath="turbojpeg.dll_1"/>
<ROW Component="ucrtbased.dll" ComponentId="{B8D025EA-CD16-4EE7-A3E7-713E2BE82BF3}" Directory_="APPDIR" Attributes="0" KeyPath="ucrtbased.dll"/>
<ROW Component="vcruntime140.dll" ComponentId="{144594CC-D19B-45E4-A420-7A1BBB122EE3}" Directory_="APPDIR" Attributes="0" KeyPath="vcruntime140.dll"/>
<ROW Component="vcruntime140d.dll" ComponentId="{7653420C-C6C3-4F31-97E8-D6DE417D3DF2}" Directory_="APPDIR" Attributes="0" KeyPath="vcruntime140d.dll"/>
+ <ROW Component="win7x64" ComponentId="{9D2172C7-152D-40CA-B098-C44ABA5AB1FB}" Directory_="win7x64_Dir" Attributes="0"/>
+ <ROW Component="win7x86" ComponentId="{BC564E77-CFC8-4588-A532-BBED1668761D}" Directory_="win7x86_Dir" Attributes="0"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiFeatsComponent">
<ROW Feature="MainFeature" Title="MainFeature" Description="Description" Display="1" Level="1" Directory_="APPDIR" Attributes="0"/>
@@ -455,10 +453,6 @@
<ROW File="LiteDB.dll" Component_="LiteDB.dll" FileName="LiteDB.dll" Version="65535.65535.65535.65535" Attributes="0" SourcePath="..\Build\PPC\Release\LiteDB.dll" SelfReg="false"/>
<ROW File="Tango.PPC.Shared.dll" Component_="Tango.PPC.Shared.dll" FileName="TANGO~13.DLL|Tango.PPC.Shared.dll" Version="65535.65535.65535.65535" Attributes="0" SourcePath="..\Build\PPC\Release\Tango.PPC.Shared.dll" SelfReg="false"/>
<ROW File="Tango.PPC.Shared.pdb" Component_="Tango.PPC.Shared.dll" FileName="TANGO~17.PDB|Tango.PPC.Shared.pdb" Version="65535.65535.65535.65535" Attributes="0" SourcePath="..\Build\PPC\Release\Tango.PPC.Shared.pdb" SelfReg="false"/>
- <ROW File="turbojpeg.dll" Component_="turbojpeg.dll" FileName="TURBOJ~1.DLL|turbojpeg.dll" Version="65535.65535.65535.65535" Attributes="0" SourcePath="..\Build\PPC\Release\win7-x64\turbojpeg.dll" SelfReg="false"/>
- <ROW File="turbojpeg.dll.meta" Component_="turbojpeg.dll.meta" FileName="TURBOJ~1.MET|turbojpeg.dll.meta" Version="65535.65535.65535.65535" Attributes="0" SourcePath="..\Build\PPC\Release\win7-x64\turbojpeg.dll.meta" SelfReg="false"/>
- <ROW File="turbojpeg.dll_1" Component_="turbojpeg.dll_1" FileName="TURBOJ~1.DLL|turbojpeg.dll" Version="65535.65535.65535.65535" Attributes="0" SourcePath="..\Build\PPC\Release\win7-x86\turbojpeg.dll" SelfReg="false"/>
- <ROW File="turbojpeg.dll.meta_1" Component_="turbojpeg.dll.meta_1" FileName="TURBOJ~1.MET|turbojpeg.dll.meta" Version="65535.65535.65535.65535" Attributes="0" SourcePath="..\Build\PPC\Release\win7-x86\turbojpeg.dll.meta" SelfReg="false"/>
<ATTRIBUTE name="DontAddFileAttributes" value="true"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.BootstrOptComponent">
@@ -468,7 +462,7 @@
<ROW Action="AI_DetectSoftware" Sequence="101"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.BuildComponent">
- <ROW BuildKey="DefaultBuild" BuildName="DefaultBuild" BuildOrder="1" BuildType="0" PackageFolder="..\Build\Installers\PPC" PackageFileName="PPC Installer v1.0.3" Languages="en" InstallationType="4" CabsLocation="1" PackageType="1" FilesInsideExe="true" ExtractionFolder="[AppDataFolder][|Manufacturer]\[|ProductName] [|ProductVersion]\install" ExtUI="true" UseLargeSchema="true" ExeName="PPC Installer_v1.1.15"/>
+ <ROW BuildKey="DefaultBuild" BuildName="DefaultBuild" BuildOrder="1" BuildType="0" PackageFolder="..\Build\Installers\PPC" PackageFileName="PPC Installer v1.0.3" Languages="en" InstallationType="4" CabsLocation="1" PackageType="1" FilesInsideExe="true" ExtractionFolder="[AppDataFolder][|Manufacturer]\[|ProductName] [|ProductVersion]\install" ExtUI="true" UseLargeSchema="true" ExeName="PPC Installer_v1.1.16"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.DictionaryComponent">
<ROW Path="&lt;AI_DICTS&gt;ui.ail"/>
@@ -536,6 +530,8 @@
<COMPONENT cid="caphyon.advinst.msicomp.MsiCreateFolderComponent">
<ROW Directory_="SHORTCUTDIR" Component_="SHORTCUTDIR" ManualDelete="false"/>
<ROW Directory_="APPDIR" Component_="APPDIR" ManualDelete="true"/>
+ <ROW Directory_="win7x64_Dir" Component_="win7x64" ManualDelete="false"/>
+ <ROW Directory_="win7x86_Dir" Component_="win7x86" ManualDelete="false"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiCustActComponent">
<ROW Action="AI_BACKUP_AI_SETUPEXEPATH" Type="51" Source="AI_SETUPEXEPATH_ORIGINAL" Target="[AI_SETUPEXEPATH]"/>
@@ -726,10 +722,8 @@
<ROW Feature_="MainFeature" Component_="WebRtc.NET.dll"/>
<ROW Feature_="MainFeature" Component_="LiteDB.dll"/>
<ROW Feature_="MainFeature" Component_="Tango.PPC.Shared.dll"/>
- <ROW Feature_="MainFeature" Component_="turbojpeg.dll"/>
- <ROW Feature_="MainFeature" Component_="turbojpeg.dll.meta"/>
- <ROW Feature_="MainFeature" Component_="turbojpeg.dll_1"/>
- <ROW Feature_="MainFeature" Component_="turbojpeg.dll.meta_1"/>
+ <ROW Feature_="MainFeature" Component_="win7x86"/>
+ <ROW Feature_="MainFeature" Component_="win7x64"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstExSeqComponent">
<ROW Action="AI_STORE_LOCATION" Condition="(Not Installed) OR REINSTALL" Sequence="1502"/>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Controls/DiagnosticsGrid.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Controls/DiagnosticsGrid.cs
index 45b6d9a36..bb647c6f6 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Controls/DiagnosticsGrid.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Controls/DiagnosticsGrid.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -11,23 +12,23 @@ namespace Tango.FSE.Diagnostics.Controls
{
public class DiagnosticsGrid : Grid
{
- public List<DiagnosticsProjectTabColumnDefinition> Columns
+ public ObservableCollection<DiagnosticsProjectTabColumnDefinition> Columns
{
- get { return (List<DiagnosticsProjectTabColumnDefinition>)GetValue(ColumnsProperty); }
+ get { return (ObservableCollection<DiagnosticsProjectTabColumnDefinition>)GetValue(ColumnsProperty); }
set { SetValue(ColumnsProperty, value); }
}
public static readonly DependencyProperty ColumnsProperty =
- DependencyProperty.Register("Columns", typeof(List<DiagnosticsProjectTabColumnDefinition>), typeof(DiagnosticsGrid), new PropertyMetadata(null, (d, e) => (d as DiagnosticsGrid).LoadDefinitions()));
+ DependencyProperty.Register("Columns", typeof(ObservableCollection<DiagnosticsProjectTabColumnDefinition>), typeof(DiagnosticsGrid), new PropertyMetadata(null, (d, e) => (d as DiagnosticsGrid).LoadDefinitions()));
- public List<DiagnosticsProjectTabRowDefinition> Rows
+ public ObservableCollection<DiagnosticsProjectTabRowDefinition> Rows
{
- get { return (List<DiagnosticsProjectTabRowDefinition>)GetValue(RowsProperty); }
+ get { return (ObservableCollection<DiagnosticsProjectTabRowDefinition>)GetValue(RowsProperty); }
set { SetValue(RowsProperty, value); }
}
public static readonly DependencyProperty RowsProperty =
- DependencyProperty.Register("Rows", typeof(List<DiagnosticsProjectTabRowDefinition>), typeof(DiagnosticsGrid), new PropertyMetadata(null, (d, e) => (d as DiagnosticsGrid).LoadDefinitions()));
+ DependencyProperty.Register("Rows", typeof(ObservableCollection<DiagnosticsProjectTabRowDefinition>), typeof(DiagnosticsGrid), new PropertyMetadata(null, (d, e) => (d as DiagnosticsGrid).LoadDefinitions()));
- private void LoadDefinitions()
+ protected virtual void LoadDefinitions()
{
if (Rows != null && Columns != null)
{
@@ -36,14 +37,33 @@ namespace Tango.FSE.Diagnostics.Controls
foreach (var column in Columns)
{
- ColumnDefinitions.Add(new ColumnDefinition() { Width = column.Width });
+ var columnDefinition = new ColumnDefinition() { Width = column.Width };
+ columnDefinition.Bind(ColumnDefinition.WidthProperty, column, nameof(DiagnosticsProjectTabColumnDefinition.Width), System.Windows.Data.BindingMode.TwoWay);
+ ColumnDefinitions.Add(columnDefinition);
}
foreach (var row in Rows)
{
- RowDefinitions.Add(new RowDefinition() { Height = row.Height });
+ var rowDefinition = new RowDefinition() { Height = row.Height };
+ rowDefinition.Bind(RowDefinition.HeightProperty, row, nameof(DiagnosticsProjectTabRowDefinition.Height), System.Windows.Data.BindingMode.TwoWay);
+ RowDefinitions.Add(rowDefinition);
}
+
+ Columns.CollectionChanged -= Columns_CollectionChanged;
+ Rows.CollectionChanged -= Rows_CollectionChanged;
+ Columns.CollectionChanged += Columns_CollectionChanged;
+ Rows.CollectionChanged += Rows_CollectionChanged;
}
}
+
+ private void Rows_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
+ {
+ LoadDefinitions();
+ }
+
+ private void Columns_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
+ {
+ LoadDefinitions();
+ }
}
}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Controls/DiagnosticsGridLinesEditor.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Controls/DiagnosticsGridLinesEditor.xaml
new file mode 100644
index 000000000..2ae7bbeca
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Controls/DiagnosticsGridLinesEditor.xaml
@@ -0,0 +1,108 @@
+<UserControl x:Class="Tango.FSE.Diagnostics.Controls.DiagnosticsGridLinesEditor"
+ 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:material="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:local="clr-namespace:Tango.FSE.Diagnostics.Controls"
+ xmlns:controls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common"
+ mc:Ignorable="d"
+ d:DesignHeight="450" d:DesignWidth="800" x:Name="control" Foreground="#20FFFFFF">
+ <Grid>
+
+ <Rectangle HorizontalAlignment="Left" Stroke="{Binding ElementName=control,Path=Foreground}" />
+
+ <ItemsControl ItemsSource="{Binding ElementName=control,Path=VerticalLineEditors}">
+ <ItemsControl.ItemsPanel>
+ <ItemsPanelTemplate>
+ <local:DiagnosticsGrid Loaded="Columns_DiagnosticsGrid_Loaded" Columns="{Binding ElementName=control,Path=Columns}" Rows="{Binding ElementName=control,Path=RowsZero}" />
+ </ItemsPanelTemplate>
+ </ItemsControl.ItemsPanel>
+ <ItemsControl.ItemContainerStyle>
+ <Style TargetType="FrameworkElement">
+ <Setter Property="Grid.Column" Value="{Binding Position}"></Setter>
+ </Style>
+ </ItemsControl.ItemContainerStyle>
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <Border>
+ <Grid HorizontalAlignment="Right">
+ <Grid Margin="0 -14 -5 0">
+ <Thumb Width="10" Background="Transparent" Cursor="SizeWE" VerticalAlignment="Top" DragDelta="Vertical_Thumb_DragDelta">
+
+ </Thumb>
+
+ <material:PackIcon Foreground="{StaticResource FSE_PrimaryForegroundBrush}" RenderTransformOrigin="0.5,0.5" Kind="Triangle" IsHitTestVisible="False" Width="12" Height="12">
+ <material:PackIcon.RenderTransform>
+ <RotateTransform Angle="180" />
+ </material:PackIcon.RenderTransform>
+ </material:PackIcon>
+ </Grid>
+ <Rectangle Opacity="0.6" StrokeThickness="2" IsHitTestVisible="False" Stroke="{Binding ElementName=control,Path=Foreground}" HorizontalAlignment="Right"></Rectangle>
+ </Grid>
+ </Border>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
+
+ <ItemsControl ItemsSource="{Binding ElementName=control,Path=HorizontalLineEditors}">
+ <ItemsControl.ItemsPanel>
+ <ItemsPanelTemplate>
+ <local:DiagnosticsGrid Loaded="Rows_DiagnosticsGrid_Loaded" Rows="{Binding ElementName=control,Path=Rows}" Columns="{Binding ElementName=control,Path=ColumnsZero}" />
+ </ItemsPanelTemplate>
+ </ItemsControl.ItemsPanel>
+ <ItemsControl.ItemContainerStyle>
+ <Style TargetType="FrameworkElement">
+ <Setter Property="Grid.Row" Value="{Binding Position}"></Setter>
+ </Style>
+ </ItemsControl.ItemContainerStyle>
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <Border>
+ <Grid VerticalAlignment="Bottom">
+ <Grid Margin="-12 0 0 -5.5">
+ <Thumb Height="10" Background="Transparent" Cursor="SizeNS" HorizontalAlignment="Left" DragDelta="Horizontal_Thumb_DragDelta">
+
+ </Thumb>
+
+ <material:PackIcon Foreground="{StaticResource FSE_PrimaryForegroundBrush}" RenderTransformOrigin="0.5,0.5" Kind="Triangle" IsHitTestVisible="False" Width="12" Height="12">
+ <material:PackIcon.RenderTransform>
+ <RotateTransform Angle="90" />
+ </material:PackIcon.RenderTransform>
+ </material:PackIcon>
+ </Grid>
+ <Rectangle IsHitTestVisible="False" Opacity="0.6" StrokeThickness="2" Stroke="{Binding ElementName=control,Path=Foreground}" VerticalAlignment="Bottom"></Rectangle>
+ </Grid>
+ </Border>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
+
+ <Grid Width="125" Height="125" Opacity="0.6" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="10">
+ <StackPanel HorizontalAlignment="Right" VerticalAlignment="Top" >
+ <UniformGrid Height="80" Width="40" Rows="2">
+ <Button x:Name="btnRemoveRow" Style="{StaticResource FSE_RaisedButton_Dark_Hover}" Padding="0" ToolTip="Remove Row" Click="BtnRemoveRow_Click">
+ <material:PackIcon Kind="Minus" />
+ </Button>
+ <Button x:Name="btnAddRow" Margin="0 2 0 0" Style="{StaticResource FSE_RaisedButton_Dark_Hover}" Padding="0" ToolTip="Add Row" Click="BtnAddRow_Click">
+ <material:PackIcon Kind="Plus" />
+ </Button>
+ </UniformGrid>
+ <TextBlock FontSize="{StaticResource FSE_SmallFontSize}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}" HorizontalAlignment="Center" Margin="0 5 0 0" Text="{Binding ElementName=control,Path=Rows.Count}"></TextBlock>
+ </StackPanel>
+
+ <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Bottom" >
+ <UniformGrid Height="40" Width="80" Columns="2">
+ <Button x:Name="btnRemoveColumn" Style="{StaticResource FSE_RaisedButton_Dark_Hover}" Padding="0" ToolTip="Remove Column" Click="BtnRemoveColumn_Click">
+ <material:PackIcon Kind="Minus" />
+ </Button>
+ <Button x:Name="btnAddColumn" Margin="2 0 0 0" Style="{StaticResource FSE_RaisedButton_Dark_Hover}" Padding="0" ToolTip="Add Column" Click="BtnAddColumn_Click">
+ <material:PackIcon Kind="Plus" />
+ </Button>
+ </UniformGrid>
+
+ <TextBlock FontSize="{StaticResource FSE_SmallFontSize}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}" VerticalAlignment="Center" Margin="5 0 0 0" Text="{Binding ElementName=control,Path=Columns.Count}"></TextBlock>
+ </StackPanel>
+ </Grid>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Controls/DiagnosticsGridLinesEditor.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Controls/DiagnosticsGridLinesEditor.xaml.cs
new file mode 100644
index 000000000..1aaddedb6
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Controls/DiagnosticsGridLinesEditor.xaml.cs
@@ -0,0 +1,254 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+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.Core.Commands;
+using Tango.FSE.Diagnostics.Project;
+
+namespace Tango.FSE.Diagnostics.Controls
+{
+ /// <summary>
+ /// Interaction logic for DiagnosticsGridLinesEditor.xaml
+ /// </summary>
+ public partial class DiagnosticsGridLinesEditor : UserControl
+ {
+ private DiagnosticsGrid _columnsDiagnosticsGrid;
+ private DiagnosticsGrid _rowsDiagnosticsGrid;
+ private const int MAX_LENGTH = 20;
+
+ public class LineEditor
+ {
+ public int Position { get; set; }
+ }
+
+ public ObservableCollection<DiagnosticsProjectTabColumnDefinition> Columns
+ {
+ get { return (ObservableCollection<DiagnosticsProjectTabColumnDefinition>)GetValue(ColumnsProperty); }
+ set { SetValue(ColumnsProperty, value); }
+ }
+ public static readonly DependencyProperty ColumnsProperty =
+ DependencyProperty.Register("Columns", typeof(ObservableCollection<DiagnosticsProjectTabColumnDefinition>), typeof(DiagnosticsGridLinesEditor), new PropertyMetadata(null, (d, e) => (d as DiagnosticsGridLinesEditor).LoadDefinitions()));
+
+ public ObservableCollection<DiagnosticsProjectTabRowDefinition> Rows
+ {
+ get { return (ObservableCollection<DiagnosticsProjectTabRowDefinition>)GetValue(RowsProperty); }
+ set { SetValue(RowsProperty, value); }
+ }
+ public static readonly DependencyProperty RowsProperty =
+ DependencyProperty.Register("Rows", typeof(ObservableCollection<DiagnosticsProjectTabRowDefinition>), typeof(DiagnosticsGridLinesEditor), new PropertyMetadata(null, (d, e) => (d as DiagnosticsGridLinesEditor).LoadDefinitions()));
+
+ public ObservableCollection<DiagnosticsProjectTabColumnDefinition> ColumnsZero
+ {
+ get { return (ObservableCollection<DiagnosticsProjectTabColumnDefinition>)GetValue(ColumnsZeroProperty); }
+ set { SetValue(ColumnsZeroProperty, value); }
+ }
+ public static readonly DependencyProperty ColumnsZeroProperty =
+ DependencyProperty.Register("ColumnsZero", typeof(ObservableCollection<DiagnosticsProjectTabColumnDefinition>), typeof(DiagnosticsGridLinesEditor), new PropertyMetadata(null));
+
+ public ObservableCollection<DiagnosticsProjectTabRowDefinition> RowsZero
+ {
+ get { return (ObservableCollection<DiagnosticsProjectTabRowDefinition>)GetValue(RowsZeroProperty); }
+ set { SetValue(RowsZeroProperty, value); }
+ }
+ public static readonly DependencyProperty RowsZeroProperty =
+ DependencyProperty.Register("RowsZero", typeof(ObservableCollection<DiagnosticsProjectTabRowDefinition>), typeof(DiagnosticsGridLinesEditor), new PropertyMetadata(null));
+
+ public List<LineEditor> HorizontalLineEditors
+ {
+ get { return (List<LineEditor>)GetValue(HorizontalLineEditorsProperty); }
+ set { SetValue(HorizontalLineEditorsProperty, value); }
+ }
+ public static readonly DependencyProperty HorizontalLineEditorsProperty =
+ DependencyProperty.Register("HorizontalLineEditors", typeof(List<LineEditor>), typeof(DiagnosticsGridLinesEditor), new PropertyMetadata(null));
+
+ public List<LineEditor> VerticalLineEditors
+ {
+ get { return (List<LineEditor>)GetValue(VerticalLineEditorsProperty); }
+ set { SetValue(VerticalLineEditorsProperty, value); }
+ }
+ public static readonly DependencyProperty VerticalLineEditorsProperty =
+ DependencyProperty.Register("VerticalLineEditors", typeof(List<LineEditor>), typeof(DiagnosticsGridLinesEditor), new PropertyMetadata(null));
+
+ public DiagnosticsGridLinesEditor()
+ {
+ RowsZero = new ObservableCollection<DiagnosticsProjectTabRowDefinition>();
+ ColumnsZero = new ObservableCollection<DiagnosticsProjectTabColumnDefinition>();
+ InitializeComponent();
+ }
+
+ private void LoadDefinitions()
+ {
+ if (Columns != null && Rows != null)
+ {
+ List<LineEditor> verticalLines = new List<LineEditor>();
+
+ for (int columnIndex = 0; columnIndex < Columns.Count; columnIndex++)
+ {
+ verticalLines.Add(new LineEditor() { Position = columnIndex });
+ }
+
+ List<LineEditor> horizontalLines = new List<LineEditor>();
+
+ for (int rowIndex = 0; rowIndex < Rows.Count; rowIndex++)
+ {
+ horizontalLines.Add(new LineEditor() { Position = rowIndex });
+ }
+
+ VerticalLineEditors = verticalLines;
+ HorizontalLineEditors = horizontalLines;
+
+ Columns.CollectionChanged -= Columns_CollectionChanged;
+ Rows.CollectionChanged -= Rows_CollectionChanged;
+ Columns.CollectionChanged += Columns_CollectionChanged;
+ Rows.CollectionChanged += Rows_CollectionChanged;
+ }
+ }
+
+ private void Rows_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
+ {
+ LoadDefinitions();
+ }
+
+ private void Columns_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
+ {
+ LoadDefinitions();
+ }
+
+ private void Vertical_Thumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
+ {
+ LineEditor line = (sender as FrameworkElement).DataContext as LineEditor;
+
+ if (line.Position == Columns.Count - 1) return;
+
+ var column = Columns[line.Position];
+
+ foreach (var definition in _columnsDiagnosticsGrid.ColumnDefinitions)
+ {
+ if (definition.Width.IsStar)
+ {
+ definition.Width = new GridLength(definition.ActualWidth);
+ }
+ }
+
+ DiagnosticsProjectTabColumnDefinition nextColumn = null;
+
+ if (line.Position < Columns.Count - 1)
+ {
+ nextColumn = Columns[line.Position + 1];
+ }
+
+ double oldWidth = column.Width.Value;
+ double newWidth = Math.Max(column.Width.Value + e.HorizontalChange, MAX_LENGTH);
+ double delta = newWidth - column.Width.Value;
+
+ if (nextColumn != null)
+ {
+ double nextWidth = nextColumn.Width.Value - delta;
+
+ if (nextWidth < MAX_LENGTH)
+ {
+ return;
+ }
+ }
+
+ column.Width = new GridLength(newWidth);
+
+ if (nextColumn != null)
+ {
+ nextColumn.Width = new GridLength(Math.Max(nextColumn.Width.Value - delta, MAX_LENGTH));
+ }
+ }
+
+ private void Horizontal_Thumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
+ {
+ LineEditor line = (sender as FrameworkElement).DataContext as LineEditor;
+
+ if (line.Position == Rows.Count - 1) return;
+
+ var row = Rows[line.Position];
+
+ foreach (var definition in _rowsDiagnosticsGrid.RowDefinitions)
+ {
+ if (definition.Height.IsStar)
+ {
+ definition.Height = new GridLength(definition.ActualHeight);
+ }
+ }
+
+ DiagnosticsProjectTabRowDefinition nextRow = null;
+
+ if (line.Position < Rows.Count - 1)
+ {
+ nextRow = Rows[line.Position + 1];
+ }
+
+ double oldHeight = row.Height.Value;
+ double newHeight = Math.Max(row.Height.Value + e.VerticalChange, MAX_LENGTH);
+ double delta = newHeight - row.Height.Value;
+
+ if (nextRow != null)
+ {
+ double nextHeight = nextRow.Height.Value - delta;
+
+ if (nextHeight < MAX_LENGTH)
+ {
+ return;
+ }
+ }
+
+ row.Height = new GridLength(newHeight);
+
+ if (nextRow != null)
+ {
+ nextRow.Height = new GridLength(Math.Max(nextRow.Height.Value - delta, MAX_LENGTH));
+ }
+ }
+
+ private void Columns_DiagnosticsGrid_Loaded(object sender, RoutedEventArgs e)
+ {
+ _columnsDiagnosticsGrid = sender as DiagnosticsGrid;
+ }
+
+ private void Rows_DiagnosticsGrid_Loaded(object sender, RoutedEventArgs e)
+ {
+ _rowsDiagnosticsGrid = sender as DiagnosticsGrid;
+ }
+
+ private void BtnRemoveRow_Click(object sender, RoutedEventArgs e)
+ {
+ if (Rows.Count > 0)
+ {
+ Rows.Remove(Rows.Last());
+ }
+ }
+
+ private void BtnAddRow_Click(object sender, RoutedEventArgs e)
+ {
+ Rows.Add(new DiagnosticsProjectTabRowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
+ }
+
+ private void BtnRemoveColumn_Click(object sender, RoutedEventArgs e)
+ {
+ if (Columns.Count > 0)
+ {
+ Columns.Remove(Columns.Last());
+ }
+ }
+
+ private void BtnAddColumn_Click(object sender, RoutedEventArgs e)
+ {
+ Columns.Add(new DiagnosticsProjectTabColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Controls/DiagnosticsSelectionGrid.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Controls/DiagnosticsSelectionGrid.cs
new file mode 100644
index 000000000..48e2cbad6
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Controls/DiagnosticsSelectionGrid.cs
@@ -0,0 +1,202 @@
+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.Input;
+using System.Windows.Media;
+using System.Windows.Shapes;
+
+namespace Tango.FSE.Diagnostics.Controls
+{
+ public class DiagnosticsSelectionGrid : DiagnosticsGrid
+ {
+ private List<Rectangle> _rects;
+ private Point _mouseDownLocation;
+ private bool _isMouseDown;
+ private List<Rectangle> _selectionRects;
+
+ public Brush RectanglesBackgroundBrush
+ {
+ get { return (Brush)GetValue(RectanglesBackgroundBrushProperty); }
+ set { SetValue(RectanglesBackgroundBrushProperty, value); }
+ }
+ public static readonly DependencyProperty RectanglesBackgroundBrushProperty =
+ DependencyProperty.Register("RectanglesBackgroundBrush", typeof(Brush), typeof(DiagnosticsSelectionGrid), new PropertyMetadata(new SolidColorBrush(Color.FromRgb(25, 25, 25))));
+
+ public Brush RectanglesHighlightBrush
+ {
+ get { return (Brush)GetValue(RectanglesHighlightBrushProperty); }
+ set { SetValue(RectanglesHighlightBrushProperty, value); }
+ }
+ public static readonly DependencyProperty RectanglesHighlightBrushProperty =
+ DependencyProperty.Register("RectanglesHighlightBrush", typeof(Brush), typeof(DiagnosticsSelectionGrid), new PropertyMetadata(new SolidColorBrush(Color.FromRgb(30, 30, 30))));
+
+ public Rect SelectionRect
+ {
+ get { return (Rect)GetValue(SelectionRectProperty); }
+ set { SetValue(SelectionRectProperty, value); }
+ }
+ public static readonly DependencyProperty SelectionRectProperty =
+ DependencyProperty.Register("SelectionRect", typeof(Rect), typeof(DiagnosticsSelectionGrid), new PropertyMetadata(default(Rect)));
+
+ public ICommand SelectionCommand
+ {
+ get { return (ICommand)GetValue(SelectionCommandProperty); }
+ set { SetValue(SelectionCommandProperty, value); }
+ }
+ public static readonly DependencyProperty SelectionCommandProperty =
+ DependencyProperty.Register("SelectionCommand", typeof(ICommand), typeof(DiagnosticsSelectionGrid), new PropertyMetadata(null));
+
+ public ICommand RightClickCommand
+ {
+ get { return (ICommand)GetValue(RightClickCommandProperty); }
+ set { SetValue(RightClickCommandProperty, value); }
+ }
+ public static readonly DependencyProperty RightClickCommandProperty =
+ DependencyProperty.Register("RightClickCommand", typeof(ICommand), typeof(DiagnosticsSelectionGrid), new PropertyMetadata(null));
+
+ public SelectionMode SelectionMode
+ {
+ get { return (SelectionMode)GetValue(SelectionModeProperty); }
+ set { SetValue(SelectionModeProperty, value); }
+ }
+ public static readonly DependencyProperty SelectionModeProperty =
+ DependencyProperty.Register("SelectionMode", typeof(SelectionMode), typeof(DiagnosticsSelectionGrid), new PropertyMetadata(SelectionMode.Multiple));
+
+ static DiagnosticsSelectionGrid()
+ {
+ DefaultStyleKeyProperty.OverrideMetadata(typeof(DiagnosticsSelectionGrid), new FrameworkPropertyMetadata(typeof(DiagnosticsSelectionGrid)));
+ }
+
+ public DiagnosticsSelectionGrid()
+ {
+ _rects = new List<Rectangle>();
+ _selectionRects = new List<Rectangle>();
+ Cursor = Cursors.Cross;
+ Background = Brushes.Transparent;
+ }
+
+ public void ClearSelection()
+ {
+ _selectionRects.Clear();
+ foreach (var rect in _rects)
+ {
+ rect.Fill = RectanglesBackgroundBrush;
+ }
+ }
+
+ protected override void LoadDefinitions()
+ {
+ base.LoadDefinitions();
+
+ if (Rows != null && Columns != null)
+ {
+ _rects.Clear();
+ _selectionRects.Clear();
+ Children.Clear();
+
+ for (int columnIndex = 0; columnIndex < Columns.Count; columnIndex++)
+ {
+ for (int rowIndex = 0; rowIndex < Rows.Count; rowIndex++)
+ {
+ var rect = new Rectangle();
+ rect.Margin = new Thickness(1);
+ rect.Fill = RectanglesBackgroundBrush;
+ rect.IsHitTestVisible = false;
+ Grid.SetColumn(rect, columnIndex);
+ Grid.SetRow(rect, rowIndex);
+ Children.Add(rect);
+ _rects.Add(rect);
+ }
+ }
+ }
+ }
+
+ protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
+ {
+ base.OnPreviewMouseDown(e);
+
+ if (SelectionMode == SelectionMode.Single) return;
+
+ if (e.ChangedButton == MouseButton.Left)
+ {
+ _mouseDownLocation = e.GetPosition(this);
+ _isMouseDown = true;
+ }
+ }
+
+ protected override void OnPreviewMouseUp(MouseButtonEventArgs e)
+ {
+ base.OnPreviewMouseUp(e);
+ _isMouseDown = false;
+
+ if (e.ChangedButton == MouseButton.Right)
+ {
+ RightClickCommand?.Execute(null);
+ return;
+ }
+
+ if (_selectionRects.Count > 0)
+ {
+ var column = _selectionRects.Min(x => Grid.GetColumn(x));
+ var row = _selectionRects.Min(x => Grid.GetRow(x));
+ var columnSpan = Math.Max(_selectionRects.Max(x => Grid.GetColumn(x)) - column + 1, 1);
+ var rowSpan = Math.Max(_selectionRects.Max(x => Grid.GetRow(x)) - row + 1, 1);
+
+ SelectionRect = new Rect(column, row, columnSpan, rowSpan);
+ SelectionCommand?.Execute(SelectionRect);
+
+ ClearSelection();
+ }
+ }
+
+ protected override void OnPreviewMouseMove(MouseEventArgs e)
+ {
+ base.OnPreviewMouseMove(e);
+
+ if (SelectionMode == SelectionMode.Single)
+ {
+ var position = e.GetPosition(this);
+ var selection = new Rect(position.X, position.Y, 1, 1);
+ HighlightIntersections(selection);
+ }
+ else if (_isMouseDown)
+ {
+ var position = e.GetPosition(this);
+
+ var x = Math.Min(position.X, _mouseDownLocation.X);
+ var y = Math.Min(position.Y, _mouseDownLocation.Y);
+ var w = Math.Max(position.X, _mouseDownLocation.X) - Math.Min(_mouseDownLocation.X, position.X);
+ var h = Math.Max(position.Y, _mouseDownLocation.Y) - Math.Min(_mouseDownLocation.Y, position.Y);
+
+ var selection = new Rect(x, y, w, h);
+ HighlightIntersections(selection);
+ }
+ }
+
+ private void HighlightIntersections(Rect selection)
+ {
+ _selectionRects.Clear();
+
+ foreach (var rect in _rects)
+ {
+ GeneralTransform gt = rect.TransformToAncestor(this);
+ var rectBounds = gt.TransformBounds(new Rect(0, 0, rect.ActualWidth, rect.ActualHeight));
+
+ if (selection.IntersectsWith(rectBounds))
+ {
+ rect.Fill = RectanglesHighlightBrush;
+ _selectionRects.Add(rect);
+ }
+ else
+ {
+ rect.Fill = RectanglesBackgroundBrush;
+ }
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Converters/DiagnosticsWidgetToSettingsViewConverter.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Converters/DiagnosticsWidgetToSettingsViewConverter.cs
index 3ba8f2e4b..ea6d52d0f 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Converters/DiagnosticsWidgetToSettingsViewConverter.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Converters/DiagnosticsWidgetToSettingsViewConverter.cs
@@ -20,8 +20,16 @@ namespace Tango.FSE.Diagnostics.Converters
if (widget.Settings != null)
{
var view = widget.Settings.GetView();
- view.DataContext = widget;
- return view;
+
+ if (view != null)
+ {
+ view.DataContext = widget;
+ return view;
+ }
+ else
+ {
+ return null;
+ }
}
}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Converters/DiagnosticsWidgetToViewConverter.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Converters/DiagnosticsWidgetToViewConverter.cs
index 439b1a17a..31ee1fbe3 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Converters/DiagnosticsWidgetToViewConverter.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Converters/DiagnosticsWidgetToViewConverter.cs
@@ -17,7 +17,9 @@ namespace Tango.FSE.Diagnostics.Converters
if (widget != null)
{
- return widget.GetView();
+ var view = widget.GetView();
+ view.DataContext = widget;
+ return view;
}
return null;
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Converters/ValveStateComparerToBooleanConverter.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Converters/ValveStateComparerToBooleanConverter.cs
new file mode 100644
index 000000000..2034c502f
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Converters/ValveStateComparerToBooleanConverter.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Data;
+using Tango.PMR.Diagnostics;
+
+namespace Tango.FSE.Diagnostics.Converters
+{
+ public class ValveStateComparerToBooleanConverter : IMultiValueConverter
+ {
+ public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (values.Length == 2 && values[0] != DependencyProperty.UnsetValue && values[1] != DependencyProperty.UnsetValue)
+ {
+ ValveStateCode v1 = (ValveStateCode)values[0];
+ ValveStateCode v2 = (ValveStateCode)Enum.Parse(typeof(ValveStateCode), values[1].ToString().Replace(" ", ""), true);
+ return v1 == v2;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/DiagnosticsPackage.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/DiagnosticsPackage.cs
index 48fe8c186..9e81f0bc7 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/DiagnosticsPackage.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/DiagnosticsPackage.cs
@@ -13,6 +13,8 @@ namespace Tango.FSE.Diagnostics
{
public class DiagnosticsPackage
{
+ private static Dictionary<String, PropertyInfo> _monitorsProperties;
+
/// <summary>
/// Gets or sets the frame.
/// </summary>
@@ -21,14 +23,27 @@ namespace Tango.FSE.Diagnostics
/// <summary>
/// Gets or sets the monitors properties.
/// </summary>
- public Dictionary<String, PropertyInfo> MonitorsProperties { get; set; }
+ public Dictionary<String, PropertyInfo> MonitorsProperties { get; private set; }
+
+ /// <summary>
+ /// Initializes the <see cref="DiagnosticsPackage"/> class.
+ /// </summary>
+ static DiagnosticsPackage()
+ {
+ _monitorsProperties = new Dictionary<string, PropertyInfo>();
+
+ foreach (var prop in typeof(DiagnosticsMonitors).GetProperties(BindingFlags.Public | BindingFlags.Instance).ToList())
+ {
+ _monitorsProperties.Add(prop.Name, prop);
+ }
+ }
/// <summary>
/// Initializes a new instance of the <see cref="DiagnosticsPackage"/> class.
/// </summary>
public DiagnosticsPackage()
{
- MonitorsProperties = new Dictionary<string, PropertyInfo>();
+ MonitorsProperties = _monitorsProperties;
}
/// <summary>
@@ -77,5 +92,35 @@ namespace Tango.FSE.Diagnostics
DoubleArray[] arrayOfDoubles = Enumerable.ToArray(value as IEnumerable<DoubleArray>);
return arrayOfDoubles.Select(x => x.Data.ToList()).ToList();
}
+
+ /// <summary>
+ /// Gets the state of the digital interface.
+ /// </summary>
+ /// <param name="interface">The interface.</param>
+ /// <returns></returns>
+ public DigitalInterfaceState GetDigitalInterfaceState(TechIos @interface)
+ {
+ return Frame.Data.DigitalInterfaceStates.SingleOrDefault(x => x.InterfaceIO == (InterfaceIOs)@interface);
+ }
+
+ /// <summary>
+ /// Gets the state of the specified valve.
+ /// </summary>
+ /// <param name="valve">The valve.</param>
+ /// <returns></returns>
+ public ValveState GetValveState(TechValves valve)
+ {
+ return Frame.Data.ValvesStates.SingleOrDefault(x => x.ValveType == (ValveType)valve);
+ }
+
+ /// <summary>
+ /// Gets the state of the specified heater.
+ /// </summary>
+ /// <param name="heater">The heater.</param>
+ /// <returns></returns>
+ public HeaterState GetHeaterState(TechHeaters heater)
+ {
+ return Frame.Data.HeatersStates.SingleOrDefault(x => x.HeaterType == (HeaterType)heater);
+ }
}
}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/DiagnosticsSettings.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/DiagnosticsSettings.cs
new file mode 100644
index 000000000..94475e72c
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/DiagnosticsSettings.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Settings;
+
+namespace Tango.FSE.Diagnostics
+{
+ public class DiagnosticsSettings : SettingsBase
+ {
+
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsConfigurableWidget.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsConfigurableWidget.cs
index ac1d29847..90ad17055 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsConfigurableWidget.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsConfigurableWidget.cs
@@ -8,34 +8,21 @@ namespace Tango.FSE.Diagnostics.Project
{
public abstract class DiagnosticsConfigurableWidget : DiagnosticsWidget
{
- public DiagnosticsWidgetSettings Settings { get; set; }
- }
-
- public abstract class DiagnosticsConfigurableWidget<T> : DiagnosticsConfigurableWidget where T : DiagnosticsWidgetSettings, new()
- {
- private T _settings;
- public new T Settings
+ private DiagnosticsWidgetSettings _settings;
+ public DiagnosticsWidgetSettings Settings
{
get { return _settings; }
set
{
_settings = value;
- RaisePropertyChangedAuto();
-
- if (_settings != null)
+ if (value != null)
{
- base.Settings = value;
OnSettingsChanged();
- _settings.PropertyChanged += _settings_PropertyChanged;
+ value.PropertyChanged += _settings_PropertyChanged;
}
}
}
- public DiagnosticsConfigurableWidget() : base()
- {
- Settings = new T();
- }
-
private void _settings_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
OnSettingsChanged();
@@ -46,4 +33,22 @@ namespace Tango.FSE.Diagnostics.Project
}
}
+
+ public abstract class DiagnosticsConfigurableWidget<T> : DiagnosticsConfigurableWidget where T : DiagnosticsWidgetSettings, new()
+ {
+ public new T Settings
+ {
+ get { return base.Settings as T; }
+ set
+ {
+ base.Settings = value;
+ RaisePropertyChangedAuto();
+ }
+ }
+
+ public DiagnosticsConfigurableWidget() : base()
+ {
+ Settings = new T();
+ }
+ }
}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsProject.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsProject.cs
index bc93f4101..aae0709d8 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsProject.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsProject.cs
@@ -11,15 +11,21 @@ using Tango.Core;
namespace Tango.FSE.Diagnostics.Project
{
public class DiagnosticsProject : ExtendedObject
- {
- private static JsonSerializerSettings _settings;
+ {
+ public static JsonSerializerSettings JsonSettings { get; private set; }
public String Name { get; set; }
+
public ObservableCollection<DiagnosticsProjectTab> Tabs { get; set; }
+ public List<DiagnosticsWidget> FlattenWidgets()
+ {
+ return Tabs.SelectMany(x => x.Widgets).ToList();
+ }
+
static DiagnosticsProject()
{
- _settings = new JsonSerializerSettings()
+ JsonSettings = new JsonSerializerSettings()
{
TypeNameHandling = TypeNameHandling.Auto,
Formatting = Formatting.Indented
@@ -34,12 +40,12 @@ namespace Tango.FSE.Diagnostics.Project
public String ToJson()
{
- return JsonConvert.SerializeObject(this, _settings);
+ return JsonConvert.SerializeObject(this, JsonSettings);
}
public static DiagnosticsProject FromJson(String json)
{
- return JsonConvert.DeserializeObject<DiagnosticsProject>(json, _settings);
+ return JsonConvert.DeserializeObject<DiagnosticsProject>(json, JsonSettings);
}
public void ToFile(String fileName)
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsProjectTab.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsProjectTab.cs
index d50a6aa0d..aab776137 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsProjectTab.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsProjectTab.cs
@@ -13,15 +13,49 @@ namespace Tango.FSE.Diagnostics.Project
public class DiagnosticsProjectTab : ExtendedObject
{
public String Name { get; set; }
- public List<DiagnosticsProjectTabColumnDefinition> Columns { get; set; }
- public List<DiagnosticsProjectTabRowDefinition> Rows { get; set; }
+ public ObservableCollection<DiagnosticsProjectTabColumnDefinition> Columns { get; set; }
+ public ObservableCollection<DiagnosticsProjectTabRowDefinition> Rows { get; set; }
public ObservableCollection<DiagnosticsWidget> Widgets { get; set; }
public DiagnosticsProjectTab()
{
- Columns = new List<DiagnosticsProjectTabColumnDefinition>();
- Rows = new List<DiagnosticsProjectTabRowDefinition>();
+ Columns = new ObservableCollection<DiagnosticsProjectTabColumnDefinition>();
+ Rows = new ObservableCollection<DiagnosticsProjectTabRowDefinition>();
Widgets = new ObservableCollection<DiagnosticsWidget>();
}
+
+ public static DiagnosticsProjectTab CreateNew(String name, int columns, int rows)
+ {
+ var tab = new DiagnosticsProjectTab();
+ tab.Name = name;
+
+ for (int i = 0; i < columns; i++)
+ {
+ tab.Columns.Add(CreateColumn());
+ }
+
+ for (int i = 0; i < rows; i++)
+ {
+ tab.Rows.Add(CreateRow());
+ }
+
+ return tab;
+ }
+
+ private static DiagnosticsProjectTabColumnDefinition CreateColumn()
+ {
+ return new DiagnosticsProjectTabColumnDefinition()
+ {
+ Width = new GridLength(1, GridUnitType.Star)
+ };
+ }
+
+ private static DiagnosticsProjectTabRowDefinition CreateRow()
+ {
+ return new DiagnosticsProjectTabRowDefinition()
+ {
+ Height = new GridLength(1, GridUnitType.Star)
+ };
+ }
}
}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsProjectTabColumnDefinition.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsProjectTabColumnDefinition.cs
index 3f10fa793..efffb4308 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsProjectTabColumnDefinition.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsProjectTabColumnDefinition.cs
@@ -4,11 +4,17 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
+using Tango.Core;
namespace Tango.FSE.Diagnostics.Project
{
- public class DiagnosticsProjectTabColumnDefinition
+ public class DiagnosticsProjectTabColumnDefinition : ExtendedObject
{
- public GridLength Width { get; set; }
+ private GridLength _width;
+ public GridLength Width
+ {
+ get { return _width; }
+ set { _width = value; RaisePropertyChangedAuto(); }
+ }
}
}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsProjectTabRowDefinition.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsProjectTabRowDefinition.cs
index 0797d89ac..e889ec979 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsProjectTabRowDefinition.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsProjectTabRowDefinition.cs
@@ -4,11 +4,17 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
+using Tango.Core;
namespace Tango.FSE.Diagnostics.Project
{
- public class DiagnosticsProjectTabRowDefinition
+ public class DiagnosticsProjectTabRowDefinition : ExtendedObject
{
- public GridLength Height { get; set; }
+ private GridLength _height;
+ public GridLength Height
+ {
+ get { return _height; }
+ set { _height = value; RaisePropertyChangedAuto(); }
+ }
}
}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsUserSettingsCollection.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsUserSettingsCollection.cs
new file mode 100644
index 000000000..35bc164b9
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsUserSettingsCollection.cs
@@ -0,0 +1,100 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core.ExtensionMethods;
+
+namespace Tango.FSE.Diagnostics.Project
+{
+ public class DiagnosticsUserSettingsCollection
+ {
+ private static JsonSerializerSettings _settings;
+
+ public List<DiagnosticsUserWidgetSettings> Widgets { get; set; }
+
+ public T GetWidgetSettings<T>(DiagnosticsConfigurableWidget widget) where T : DiagnosticsWidgetSettings
+ {
+ return GetWidgetSettings(widget) as T;
+ }
+
+ public DiagnosticsWidgetSettings GetWidgetSettings(DiagnosticsConfigurableWidget widget)
+ {
+ var record = Widgets.FirstOrDefault(x => x.WidgetID == widget.ID);
+ if (record != null)
+ {
+ return record.Settings;
+ }
+
+ return null;
+ }
+
+ public void ApplyWidgetSettings(DiagnosticsConfigurableWidget widget)
+ {
+ var record = Widgets.FirstOrDefault(x => x.WidgetID == widget.ID);
+ if (record != null)
+ {
+ if (widget.Settings == null)
+ {
+ widget.Settings = record.Settings;
+ }
+ else
+ {
+ record.Settings.MapPropertiesTo(widget.Settings, MappingFlags.All, (prop) => prop.GetCustomAttribute<JsonIgnoreAttribute>() == null);
+ }
+ }
+ }
+
+ public void SetWidgetSettings(DiagnosticsConfigurableWidget widget)
+ {
+ var record = Widgets.FirstOrDefault(x => x.WidgetID == widget.ID);
+ if (record == null)
+ {
+ record = new DiagnosticsUserWidgetSettings()
+ {
+ WidgetID = widget.ID,
+ };
+ Widgets.Add(record);
+ }
+
+ record.Settings = widget.Settings;
+ }
+
+ static DiagnosticsUserSettingsCollection()
+ {
+ _settings = new JsonSerializerSettings()
+ {
+ TypeNameHandling = TypeNameHandling.Auto,
+ Formatting = Formatting.Indented
+ };
+ }
+
+ public DiagnosticsUserSettingsCollection()
+ {
+ Widgets = new List<DiagnosticsUserWidgetSettings>();
+ }
+
+ public String ToJson()
+ {
+ return JsonConvert.SerializeObject(this, _settings);
+ }
+
+ public static DiagnosticsUserSettingsCollection FromJson(String json)
+ {
+ return JsonConvert.DeserializeObject<DiagnosticsUserSettingsCollection>(json, _settings);
+ }
+
+ public void ToFile(String fileName)
+ {
+ File.WriteAllText(fileName, ToJson());
+ }
+
+ public static DiagnosticsUserSettingsCollection FromFile(String fileName)
+ {
+ return FromJson(File.ReadAllText(fileName));
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsUserSettingsManager.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsUserSettingsManager.cs
new file mode 100644
index 000000000..1e3684733
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsUserSettingsManager.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+
+namespace Tango.FSE.Diagnostics.Project
+{
+ public class DiagnosticsUserSettingsManager : ExtendedObject
+ {
+ private static object _syncLock = new object();
+
+ private static DiagnosticsUserSettingsManager _default;
+ public static DiagnosticsUserSettingsManager Default
+ {
+ get
+ {
+ if (_default == null)
+ {
+ _default = new DiagnosticsUserSettingsManager();
+ }
+
+ return _default;
+ }
+ }
+
+ public String FilePath { get; protected set; }
+
+ public DiagnosticsUserSettingsCollection Settings { get; set; }
+
+ private DiagnosticsUserSettingsManager()
+ {
+ Settings = new DiagnosticsUserSettingsCollection();
+ FilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Twine", "Tango", "Diagnostics", Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.FriendlyName) + ".User.json");
+ Reload();
+ }
+
+ public void Reload()
+ {
+ try
+ {
+ Settings = DiagnosticsUserSettingsCollection.FromFile(FilePath);
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error loading diagnostics user settings.");
+ }
+ }
+
+ public void ClearGhostRecords(List<DiagnosticsConfigurableWidget> widgets)
+ {
+ Settings.Widgets.RemoveAll(x => !widgets.Exists(y => y.ID == x.WidgetID));
+ }
+
+ public void Save()
+ {
+ lock (_syncLock)
+ {
+ Directory.CreateDirectory(Path.GetDirectoryName(FilePath));
+ Settings.ToFile(FilePath);
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsUserWidgetSettings.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsUserWidgetSettings.cs
new file mode 100644
index 000000000..855bd31f9
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsUserWidgetSettings.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Diagnostics.Project
+{
+ public class DiagnosticsUserWidgetSettings
+ {
+ public String WidgetID { get; set; }
+ public DiagnosticsWidgetSettings Settings { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsWidget.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsWidget.cs
index c7880909b..ad63dd8b1 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsWidget.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsWidget.cs
@@ -2,9 +2,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
+using System.Windows.Controls;
+using Tango.BL.Enumerations;
using Tango.Core;
using Tango.Core.DI;
using Tango.FSE.BL;
@@ -15,7 +18,7 @@ using Tango.PMR.Diagnostics;
namespace Tango.FSE.Diagnostics.Project
{
- public abstract class DiagnosticsWidget : ExtendedObject
+ public abstract class DiagnosticsWidget : ExtendedObject, IDisposable
{
[JsonIgnore]
[TangoInject(TangoInjectMode.WhenAvailable)]
@@ -38,12 +41,63 @@ namespace Tango.FSE.Diagnostics.Project
set { _services = value; OnServicesAvailable(); }
}
- public int Column { get; set; }
- public int Row { get; set; }
- public int ColumnSpan { get; set; }
- public int RowSpan { get; set; }
- public double Width { get; set; }
- public double Height { get; set; }
+ public String ID { get; set; }
+
+ private int _column;
+ public int Column
+ {
+ get { return _column; }
+ set { _column = value; RaisePropertyChangedAuto(); }
+ }
+
+ private int _row;
+ public int Row
+ {
+ get { return _row; }
+ set { _row = value; RaisePropertyChangedAuto(); }
+ }
+
+ private int _columnSpan;
+ public int ColumnSpan
+ {
+ get { return _columnSpan; }
+ set { _columnSpan = value; RaisePropertyChangedAuto(); }
+ }
+
+ private int _rowSpan;
+ public int RowSpan
+ {
+ get { return _rowSpan; }
+ set { _rowSpan = value; RaisePropertyChangedAuto(); }
+ }
+
+ private double _width;
+ public double Width
+ {
+ get { return _width; }
+ set { _width = value; RaisePropertyChangedAuto(); }
+ }
+
+ private double _height;
+ public double Height
+ {
+ get { return _height; }
+ set { _height = value; RaisePropertyChangedAuto(); }
+ }
+
+ private bool _displayComponentName;
+ public bool DisplayComponentName
+ {
+ get { return _displayComponentName; }
+ set { _displayComponentName = value; RaisePropertyChangedAuto(); }
+ }
+
+ private Dock _componentNameAlignment;
+ public Dock ComponentNameAlignment
+ {
+ get { return _componentNameAlignment; }
+ set { _componentNameAlignment = value; RaisePropertyChangedAuto(); }
+ }
private bool _isVisible;
[JsonIgnore]
@@ -61,16 +115,64 @@ namespace Tango.FSE.Diagnostics.Project
}
}
+ private bool _isSelected;
+ [JsonIgnore]
+ public bool IsSelected
+ {
+ get { return _isSelected; }
+ set { _isSelected = value; RaisePropertyChangedAuto(); }
+ }
+
[JsonIgnore]
public abstract String DisplayName
{
get;
}
+ [JsonIgnore]
+ public bool SupportsComponentSelection
+ {
+ get
+ {
+ return this is ISupportsComponentSelection;
+ }
+ }
+
+ [JsonIgnore]
+ public bool IsCurrentUserEditor
+ {
+ get
+ {
+ return AuthenticationProvider.CurrentUser.HasPermission(Permissions.FSE_EditDiagnosticsProject);
+ }
+ }
+
+ [JsonIgnore]
+ public virtual bool HasSettings
+ {
+ get
+ {
+ return (this is DiagnosticsConfigurableWidget) || (SupportsComponentSelection && (this as ISupportsComponentSelection).EnableComponentSelection);
+ }
+ }
+
+ private bool _editMode;
+ [JsonIgnore]
+ public bool EditMode
+ {
+ get { return _editMode; }
+ set { _editMode = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(HasSettings)); }
+ }
+
+ [JsonIgnore]
+ public bool IsDisposed { get; protected set; }
+
public DiagnosticsWidget()
{
+ ID = Guid.NewGuid().ToString();
Width = 100;
Height = 100;
+ ComponentNameAlignment = Dock.Top;
TangoIOC.Default.Inject(this);
}
@@ -79,7 +181,10 @@ namespace Tango.FSE.Diagnostics.Project
}
- public abstract void OnDiagnosticsData(DiagnosticsPackage package);
+ public virtual void OnDiagnosticsData(DiagnosticsPackage package)
+ {
+ //Do Nothing.
+ }
protected virtual void OnVisibleChanged(bool isVisible)
{
@@ -92,5 +197,28 @@ namespace Tango.FSE.Diagnostics.Project
{
return Task.FromResult(true);
}
+
+ protected async void InitAsync()
+ {
+ await Init();
+ }
+
+ public DiagnosticsWidget Clone()
+ {
+ var json = JsonConvert.SerializeObject(this, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All });
+ var cloned = JsonConvert.DeserializeObject(json, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }) as DiagnosticsWidget;
+ cloned.ID = Guid.NewGuid().ToString();
+ return cloned;
+ }
+
+ public void RaiseHasSettings()
+ {
+ RaisePropertyChanged(nameof(HasSettings));
+ }
+
+ public virtual void Dispose()
+ {
+ IsDisposed = true;
+ }
}
}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsWidgetComponent.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsWidgetComponent.cs
new file mode 100644
index 000000000..c680ed0b1
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/DiagnosticsWidgetComponent.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Diagnostics.Project
+{
+ public class DiagnosticsWidgetComponent<T>
+ {
+ public String DisplayName { get; set; }
+ public T Object { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/ISupportsComponentSelection.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/ISupportsComponentSelection.cs
new file mode 100644
index 000000000..41ddd6a3a
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/ISupportsComponentSelection.cs
@@ -0,0 +1,23 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Diagnostics.Project
+{
+ public interface ISupportsComponentSelection
+ {
+ bool EnableComponentSelection { get; set; }
+ }
+
+ public interface ISupportsComponentSelection<T> : ISupportsComponentSelection
+ {
+ [JsonIgnore]
+ List<DiagnosticsWidgetComponent<T>> Components { get; }
+
+ [JsonIgnore]
+ T SelectedComponent { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidget.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidget.cs
new file mode 100644
index 000000000..d311e0c71
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidget.cs
@@ -0,0 +1,218 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using Tango.BL.Entities;
+using Tango.BL.Enumerations;
+using Tango.Core;
+using Tango.Core.Commands;
+using Tango.FSE.Common.Notifications;
+using Tango.FSE.Diagnostics.Project.Widgets.Motor;
+using Tango.PMR.Diagnostics;
+
+namespace Tango.FSE.Diagnostics.Project.Widgets.Dispenser
+{
+ [Description("Dispenser Controller")]
+ public class DispenserWidget : DiagnosticsConfigurableWidget<DispenserWidgetSettings>, ISupportsComponentSelection<TechDispensers>
+ {
+ public TechDispensers Dispenser { get; set; }
+
+ private TechDispenser _techDispenser;
+ [JsonIgnore]
+ public TechDispenser TechDispenser
+ {
+ get { return _techDispenser; }
+ set { _techDispenser = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(DisplayName)); }
+ }
+
+ [JsonIgnore]
+ public override string DisplayName
+ {
+ get
+ {
+ return this.TechDispenser != null ? this.TechDispenser.Description : String.Empty;
+ }
+ }
+
+ private MotorWidgetState _state;
+ [JsonIgnore]
+ public MotorWidgetState State
+ {
+ get { return _state; }
+ set { _state = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(IsHoming)); }
+ }
+
+ [JsonIgnore]
+ public bool IsHoming
+ {
+ get { return State == MotorWidgetState.HomingBackward || State == MotorWidgetState.HomingForward; }
+ }
+
+ private TangoProgress<double> _homingProgress;
+ [JsonIgnore]
+ public TangoProgress<double> HomingProgress
+ {
+ get { return _homingProgress; }
+ set { _homingProgress = value; RaisePropertyChangedAuto(); }
+ }
+
+ [JsonIgnore]
+ public RelayCommand<MotorWidgetState> ExecuteCommand { get; set; }
+
+ [JsonIgnore]
+ public RelayCommand StopCommand { get; set; }
+
+ public DispenserWidget()
+ {
+ HomingProgress = new TangoProgress<double>(null, false, 0, 100);
+
+ ExecuteCommand = new RelayCommand<MotorWidgetState>(Execute);
+ StopCommand = new RelayCommand(StopCurrentExecution);
+ }
+
+ public override async Task Init()
+ {
+ int motor = (int)Dispenser;
+ TechDispenser = await Services.TechComponentsService.Dispensers.FindOne(x => x.Code == motor);
+ }
+
+ public override FrameworkElement GetView()
+ {
+ return new DispenserWidgetView();
+ }
+
+ private async void Execute(MotorWidgetState command)
+ {
+ if (!MachineProvider.IsConnected || State != MotorWidgetState.Idle) return;
+
+ State = command;
+ HomingProgress = new TangoProgress<double>(null, true, 0, 100);
+
+ TaskCompletionSource<object> completion = null;
+
+ try
+ {
+ if (command == MotorWidgetState.JoggingForward || command == MotorWidgetState.JoggingBackward)
+ {
+ await MachineProvider.MachineOperator.StartDispenserJogging(new DispenserJoggingRequest()
+ {
+ Index = (int)Dispenser,
+ Direction = command == MotorWidgetState.JoggingForward ? MotorDirection.Forward : MotorDirection.Backward,
+ Speed = Settings.Speed
+ });
+ }
+ else if (command == MotorWidgetState.HomingForward || command == MotorWidgetState.HomingBackward)
+ {
+ completion = new TaskCompletionSource<object>();
+
+ MachineProvider.MachineOperator.StartDispenserHoming(new DispenserHomingRequest()
+ {
+ Index = (int)Dispenser,
+ Speed = Settings.Speed,
+ Direction = command == MotorWidgetState.HomingForward ? MotorDirection.Forward : MotorDirection.Backward
+ })
+ .Subscribe((response) =>
+ {
+ HomingProgress = new TangoProgress<double>(null, response.Progress == 0, response.Progress, response.MaxProgress);
+ }, (ex) =>
+ {
+ completion.SetException(ex);
+ }, () =>
+ {
+ State = MotorWidgetState.Idle;
+ completion.SetResult(true);
+ });
+ }
+
+ if (completion != null)
+ {
+ await completion.Task;
+ }
+ }
+ catch (Exception ex)
+ {
+ if (State != MotorWidgetState.Idle)
+ {
+ State = MotorWidgetState.Idle;
+ LogManager.Log(ex, $"Error occurred in diagnostics dispenser widget '{command}'.");
+ NotificationProvider.PushSnackbarItem(MessageType.Error, "Dispenser Controller Error", true, ex.Message, TimeSpan.FromSeconds(5));
+ }
+ }
+ finally
+ {
+ HomingProgress = new TangoProgress<double>(null, false);
+ }
+ }
+
+ private async void StopCurrentExecution()
+ {
+ if (!MachineProvider.IsConnected) return;
+
+ var command = State;
+
+ State = MotorWidgetState.Idle;
+ HomingProgress = new TangoProgress<double>(null, false);
+
+ try
+ {
+ if (command == MotorWidgetState.JoggingForward || command == MotorWidgetState.JoggingBackward)
+ {
+ await MachineProvider.MachineOperator.StopDispenserJogging(new DispenserAbortJoggingRequest()
+ {
+ Index = (int)Dispenser,
+ });
+ }
+ else if (command == MotorWidgetState.HomingForward || command == MotorWidgetState.HomingBackward)
+ {
+ await MachineProvider.MachineOperator.StopDispenserHoming(new DispenserAbortHomingRequest()
+ {
+ Index = (int)Dispenser,
+ });
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, $"Error occurred in diagnostics dispenser widget '{command}'.");
+ NotificationProvider.PushSnackbarItem(MessageType.Error, "Dispenser Controller Error", true, ex.Message, TimeSpan.FromSeconds(5));
+ }
+ }
+
+ #region Component Selection
+
+ public List<DiagnosticsWidgetComponent<TechDispensers>> Components
+ {
+ get
+ {
+ return Services.TechComponentsService.Dispensers.FindAll().Result.Select(x => new DiagnosticsWidgetComponent<TechDispensers>()
+ {
+ DisplayName = x.Description,
+ Object = (TechDispensers)x.Code,
+ }).OrderByAlphaNumeric(x => x.DisplayName).ToList();
+ }
+ }
+
+ public TechDispensers SelectedComponent
+ {
+ get
+ {
+ return Dispenser;
+ }
+ set
+ {
+ if (Dispenser != value)
+ {
+ Dispenser = value;
+ InitAsync();
+ }
+ }
+ }
+
+ public bool EnableComponentSelection { get; set; }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidgetSettings.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidgetSettings.cs
new file mode 100644
index 000000000..c205c56cf
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidgetSettings.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Media;
+
+namespace Tango.FSE.Diagnostics.Project.Widgets.Dispenser
+{
+ public class DispenserWidgetSettings : DiagnosticsWidgetSettings
+ {
+ private int _speed;
+ public int Speed
+ {
+ get { return _speed; }
+ set { _speed = value; RaisePropertyChangedAuto(); }
+ }
+
+ private Color _color;
+ public Color Color
+ {
+ get { return _color; }
+ set { _color = value; RaisePropertyChangedAuto(); }
+ }
+
+ public DispenserWidgetSettings()
+ {
+ Speed = 400;
+ Color = Color.FromRgb(20, 20, 20);
+ }
+
+ public override FrameworkElement GetView()
+ {
+ return new DispenserWidgetSettingsView();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidgetSettingsView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidgetSettingsView.xaml
new file mode 100644
index 000000000..1f288dc10
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidgetSettingsView.xaml
@@ -0,0 +1,27 @@
+<UserControl x:Class="Tango.FSE.Diagnostics.Project.Widgets.Dispenser.DispenserWidgetSettingsView"
+ 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:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:controls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common"
+ xmlns:colorPicker="clr-namespace:Tango;assembly=Tango.ColorPicker"
+ xmlns:local="clr-namespace:Tango.FSE.Diagnostics.Project.Widgets.Dispenser"
+ mc:Ignorable="d"
+ d:DesignHeight="700" d:DesignWidth="300" d:DataContext="{d:DesignInstance Type=local:DispenserWidgetSettings,IsDesignTimeCreatable=False}">
+ <Grid>
+ <StackPanel>
+ <controls:FSEGroupBox Header="SPEED" HeaderFontSize="{StaticResource FSE_SmallFontSize}">
+ <StackPanel>
+ <mahapps:NumericUpDown Minimum="0" Maximum="10000" Value="{Binding Settings.Speed,UpdateSourceTrigger=PropertyChanged}" />
+ </StackPanel>
+ </controls:FSEGroupBox>
+
+ <controls:FSEGroupBox Header="COLOR" Margin="0 10 0 0" HeaderFontSize="{StaticResource FSE_SmallFontSize}">
+ <Viewbox>
+ <colorPicker:ColorCanvas Background="Transparent" BorderThickness="0" FontSize="{StaticResource FSE_SmallerFontSize}" SelectedColor="{Binding Settings.Color,Mode=TwoWay}" />
+ </Viewbox>
+ </controls:FSEGroupBox>
+ </StackPanel>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidgetSettingsView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidgetSettingsView.xaml.cs
new file mode 100644
index 000000000..fd4d992a2
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidgetSettingsView.xaml.cs
@@ -0,0 +1,28 @@
+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.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;
+
+namespace Tango.FSE.Diagnostics.Project.Widgets.Dispenser
+{
+ /// <summary>
+ /// Interaction logic for DispenserWidgetSettingsView.xaml
+ /// </summary>
+ public partial class DispenserWidgetSettingsView : UserControl
+ {
+ public DispenserWidgetSettingsView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidgetView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidgetView.xaml
new file mode 100644
index 000000000..75294c59d
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidgetView.xaml
@@ -0,0 +1,185 @@
+<UserControl x:Class="Tango.FSE.Diagnostics.Project.Widgets.Dispenser.DispenserWidgetView"
+ 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:controls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common"
+ xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
+ xmlns:local="clr-namespace:Tango.FSE.Diagnostics.Project.Widgets.Dispenser"
+ xmlns:motor="clr-namespace:Tango.FSE.Diagnostics.Project.Widgets.Motor"
+ mc:Ignorable="d"
+ d:DesignHeight="450" d:DesignWidth="640" d:DataContext="{d:DesignInstance Type=local:DispenserWidget,IsDesignTimeCreatable=False}">
+ <Grid>
+ <Viewbox Stretch="Uniform">
+ <Grid Width="320" Height="400" Margin="70 0 0 0">
+ <Grid.LayoutTransform>
+ <RotateTransform Angle="-90" />
+ </Grid.LayoutTransform>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="25*"/>
+ <ColumnDefinition Width="100*"/>
+ <ColumnDefinition Width="25*"/>
+ </Grid.ColumnDefinitions>
+
+ <Grid.RowDefinitions>
+ <RowDefinition Height="87*" />
+ <RowDefinition Height="18*" />
+ </Grid.RowDefinitions>
+
+ <Grid Grid.Column="1">
+ <Border BorderThickness="1" BorderBrush="{StaticResource FSE_BorderBrush}" CornerRadius="10" Background="#252525">
+ <Grid>
+ <Grid.LayoutTransform>
+ <RotateTransform Angle="90" />
+ </Grid.LayoutTransform>
+ <Image Stretch="Fill" Source="../Dispenser/Images/dispenser_line.png" />
+ <Path HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="100" RenderTransformOrigin="0.5,0.5" StrokeThickness="1" Stretch="Uniform" Margin="10" Data="M500.633 211.454l-58.729-14.443c-3.53-11.133-8.071-21.929-13.55-32.256c8.818-14.678 27.349-45.571 27.349-45.571 c3.545-5.903 2.607-13.462-2.256-18.325l-42.422-42.422c-4.863-4.878-12.407-5.815-18.325-2.256L347.055 83.53 c-10.269-5.435-21.006-9.932-32.065-13.433l-14.443-58.729C298.876 4.688 292.885 0 286 0h-60 c-6.885 0-12.891 4.688-14.546 11.367c0 0-10.005 40.99-14.429 58.715c-11.792 3.735-23.188 8.584-34.043 14.502l-47.329-28.403 c-5.918-3.516-13.447-2.607-18.325 2.256l-42.422 42.422c-4.863 4.863-5.801 12.422-2.256 18.325l29.268 48.882 c-4.717 9.302-8.672 18.984-11.821 28.901l-58.729 14.487C4.688 213.124 0 219.115 0 226v60c0 6.885 4.688 12.891 11.367 14.546 l58.744 14.443c3.56 11.294 8.188 22.266 13.799 32.798l-26.191 43.652c-3.545 5.903-2.607 13.462 2.256 18.325l42.422 42.422 c4.849 4.849 12.407 5.771 18.325 2.256c0 0 29.37-17.607 43.755-26.221c10.415 5.552 21.313 10.137 32.549 13.696l14.429 58.715 C213.109 507.313 219.115 512 226 512h60c6.885 0 12.876-4.688 14.546-11.367l14.429-58.715 c11.558-3.662 22.69-8.394 33.281-14.136c14.78 8.862 44.443 26.66 44.443 26.66c5.903 3.53 13.462 2.622 18.325-2.256 l42.422-42.422c4.863-4.863 5.801-12.422 2.256-18.325l-26.968-44.927c5.317-10.093 9.727-20.654 13.169-31.523l58.729-14.443 C507.313 298.876 512 292.885 512 286v-60C512 219.115 507.313 213.124 500.633 211.454z M256 361c-57.891 0-105-47.109-105-105 s47.109-105 105-105s105 47.109 105 105S313.891 361 256 361z">
+ <Path.Stroke>
+ <SolidColorBrush Color="{Binding Settings.Color}" />
+ </Path.Stroke>
+ <Path.Style>
+ <Style TargetType="Path">
+ <Setter Property="RenderTransform">
+ <Setter.Value>
+ <RotateTransform x:Name="propRotate" Angle="0" />
+ </Setter.Value>
+ </Setter>
+ <Style.Triggers>
+
+ <DataTrigger Binding="{Binding State}" Value="{x:Static motor:MotorWidgetState.JoggingForward}">
+ <DataTrigger.EnterActions>
+ <BeginStoryboard Name="joggingForward">
+ <Storyboard>
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle" To="360" Duration="00:00:01" RepeatBehavior="Forever" FillBehavior="HoldEnd" />
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ <DataTrigger.ExitActions>
+ <RemoveStoryboard BeginStoryboardName="joggingForward" />
+ </DataTrigger.ExitActions>
+ </DataTrigger>
+
+ <DataTrigger Binding="{Binding State}" Value="{x:Static motor:MotorWidgetState.JoggingBackward}">
+ <DataTrigger.EnterActions>
+ <BeginStoryboard Name="joggingBackward">
+ <Storyboard>
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle" To="-360" Duration="00:00:01" RepeatBehavior="Forever" FillBehavior="HoldEnd" />
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ <DataTrigger.ExitActions>
+ <RemoveStoryboard BeginStoryboardName="joggingBackward" />
+ </DataTrigger.ExitActions>
+ </DataTrigger>
+
+ <DataTrigger Binding="{Binding State}" Value="{x:Static motor:MotorWidgetState.HomingForward}">
+ <DataTrigger.EnterActions>
+ <BeginStoryboard Name="homingForward">
+ <Storyboard>
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle" To="360" Duration="00:00:01" RepeatBehavior="Forever" FillBehavior="HoldEnd" />
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ <DataTrigger.ExitActions>
+ <RemoveStoryboard BeginStoryboardName="homingForward" />
+ </DataTrigger.ExitActions>
+ </DataTrigger>
+
+ <DataTrigger Binding="{Binding State}" Value="{x:Static motor:MotorWidgetState.HomingBackward}">
+ <DataTrigger.EnterActions>
+ <BeginStoryboard Name="homingBackward">
+ <Storyboard>
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle" To="-360" Duration="00:00:01" RepeatBehavior="Forever" FillBehavior="HoldEnd" />
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ <DataTrigger.ExitActions>
+ <RemoveStoryboard BeginStoryboardName="homingBackward" />
+ </DataTrigger.ExitActions>
+ </DataTrigger>
+
+ </Style.Triggers>
+ </Style>
+ </Path.Style>
+ <Path.Fill>
+ <LinearGradientBrush>
+ <GradientStop Color="Black"/>
+ <GradientStop Color="Transparent" Offset="0.8"/>
+ </LinearGradientBrush>
+ </Path.Fill>
+ </Path>
+ </Grid>
+ </Border>
+ </Grid>
+
+ <Grid>
+ <Button Margin="0 60" Style="{StaticResource FSE_MotorWidgetButton_Left}" IsEnabled="{Binding IsHoming,Converter={StaticResource BooleanInverseConverter}}">
+ <i:Interaction.Triggers>
+ <i:EventTrigger EventName="PreviewMouseDown">
+ <i:InvokeCommandAction Command="{Binding ExecuteCommand}" CommandParameter="{x:Static motor:MotorWidgetState.JoggingBackward}" />
+ </i:EventTrigger>
+ <i:EventTrigger EventName="PreviewMouseUp">
+ <i:InvokeCommandAction Command="{Binding StopCommand}" />
+ </i:EventTrigger>
+ </i:Interaction.Triggers>
+ <Viewbox Stretch="Fill" Margin="-10 20">
+ <material:PackIcon Kind="ChevronLeft" HorizontalAlignment="Center" VerticalAlignment="Center" Width="24" Height="24" />
+ </Viewbox>
+ </Button>
+ </Grid>
+
+ <Grid Grid.Column="2">
+ <Button Margin="0 60" Style="{StaticResource FSE_MotorWidgetButton_Right}" IsEnabled="{Binding IsHoming,Converter={StaticResource BooleanInverseConverter}}">
+ <i:Interaction.Triggers>
+ <i:EventTrigger EventName="PreviewMouseDown">
+ <i:InvokeCommandAction Command="{Binding ExecuteCommand}" CommandParameter="{x:Static motor:MotorWidgetState.JoggingForward}" />
+ </i:EventTrigger>
+ <i:EventTrigger EventName="PreviewMouseUp">
+ <i:InvokeCommandAction Command="{Binding StopCommand}" />
+ </i:EventTrigger>
+ </i:Interaction.Triggers>
+ <Viewbox Stretch="Fill" Margin="-10 20">
+ <material:PackIcon Kind="ChevronRight" HorizontalAlignment="Center" VerticalAlignment="Center" Width="24" Height="24" />
+ </Viewbox>
+ </Button>
+ </Grid>
+
+ <Grid Grid.Column="1" Grid.Row="1" Visibility="Visible">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="20*"/>
+ <ColumnDefinition Width="115*"/>
+ <ColumnDefinition Width="20*"/>
+ </Grid.ColumnDefinitions>
+
+ <Grid Grid.Column="1">
+ <Border Style="{StaticResource FSE_MotorWidgetBorder_Center}">
+ <Grid x:Name="gridDefault">
+ <DockPanel>
+ <controls:IconButton IsEnabled="{Binding IsHoming,Converter={StaticResource BooleanInverseConverter}}" Margin="5 0 0 0" HorizontalAlignment="Center" Command="{Binding ExecuteCommand}" CommandParameter="{x:Static motor:MotorWidgetState.HomingBackward}" Width="40" Height="40" Style="{StaticResource FSE_WidgetIconButton_Red}" DockPanel.Dock="Left" Icon="ChevronDoubleLeft"></controls:IconButton>
+ <controls:IconButton IsEnabled="{Binding IsHoming,Converter={StaticResource BooleanInverseConverter}}" HorizontalAlignment="Center" Command="{Binding ExecuteCommand}" CommandParameter="{x:Static motor:MotorWidgetState.HomingForward}" Width="40" Height="40" Style="{StaticResource FSE_WidgetIconButton_Red}" DockPanel.Dock="Right" Icon="ChevronDoubleRight"></controls:IconButton>
+
+ <Grid>
+ <Grid.LayoutTransform>
+ <RotateTransform Angle="90" />
+ </Grid.LayoutTransform>
+ <material:PackIcon Margin="-5 0 0 0" Visibility="{Binding IsHoming,Converter={StaticResource BooleanToVisibilityInverseConverter}}" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="{StaticResource FSE_PrimaryForegroundBrush}" Padding="0" Width="55" Height="55" Kind="Home"></material:PackIcon>
+
+ <Grid Visibility="{Binding IsHoming,Converter={StaticResource BooleanToVisibilityConverter}}">
+
+ <Viewbox Margin="0 5 5 5">
+ <controls:ProgressRingDouble HorizontalAlignment="Center" VerticalAlignment="Center" Minimum="0" Maximum="100" IsIndeterminate="{Binding HomingProgress.IsIndeterminate}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}" Value="{Binding HomingProgress.Value}" Thickness="5" Width="70" Height="70" />
+ </Viewbox>
+
+ <controls:IconButton Cursor="Hand" Padding="0" Command="{Binding StopCommand}" Icon="Stop" Width="42" Height="42" Foreground="{StaticResource FSE_RedBrush}" HorizontalAlignment="Center" VerticalAlignment="Center"></controls:IconButton>
+ </Grid>
+ </Grid>
+ </DockPanel>
+ </Grid>
+ </Border>
+ </Grid>
+ </Grid>
+ </Grid>
+ </Viewbox>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidgetView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidgetView.xaml.cs
new file mode 100644
index 000000000..24af229a8
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/DispenserWidgetView.xaml.cs
@@ -0,0 +1,28 @@
+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.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;
+
+namespace Tango.FSE.Diagnostics.Project.Widgets.Dispenser
+{
+ /// <summary>
+ /// Interaction logic for DispenserWidgetView.xaml
+ /// </summary>
+ public partial class DispenserWidgetView : UserControl
+ {
+ public DispenserWidgetView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/Images/dispenser_line.png b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/Images/dispenser_line.png
new file mode 100644
index 000000000..9e2e344c0
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Dispenser/Images/dispenser_line.png
Binary files differ
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Heater/HeaterWidget.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Heater/HeaterWidget.cs
new file mode 100644
index 000000000..ed10f3088
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Heater/HeaterWidget.cs
@@ -0,0 +1,153 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using Tango.BL.Entities;
+using Tango.BL.Enumerations;
+using Tango.Core.Commands;
+using Tango.FSE.Common.Notifications;
+using Tango.PMR.Diagnostics;
+
+namespace Tango.FSE.Diagnostics.Project.Widgets.Heater
+{
+ [Description("Heater Controller")]
+ public class HeaterWidget : DiagnosticsWidget, ISupportsComponentSelection<TechHeaters>
+ {
+ public TechHeaters Heater { get; set; }
+
+ private TechHeater _techHeater;
+ [JsonIgnore]
+ public TechHeater TechHeater
+ {
+ get { return _techHeater; }
+ set { _techHeater = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(DisplayName)); }
+ }
+
+ [JsonIgnore]
+ public override string DisplayName
+ {
+ get
+ {
+ return this.TechHeater != null ? this.TechHeater.Description : String.Empty;
+ }
+ }
+
+ private HeaterState _heaterState;
+ [JsonIgnore]
+ public HeaterState HeaterState
+ {
+ get { return _heaterState; }
+ set
+ {
+ _heaterState = value;
+ RaisePropertyChangedAuto();
+
+ if (!IsEditing)
+ {
+ SetPoint = _heaterState.SetPoint;
+ }
+
+ InvokeUI(() =>
+ {
+ SetCommand?.RaiseCanExecuteChanged();
+ });
+ }
+ }
+
+ private double _setPoint;
+ public double SetPoint
+ {
+ get { return _setPoint; }
+ set { _setPoint = value; RaisePropertyChangedAuto(); }
+ }
+
+ private bool _isEditing;
+ [JsonIgnore]
+ public bool IsEditing
+ {
+ get { return _isEditing; }
+ set { _isEditing = value; RaisePropertyChangedAuto(); }
+ }
+
+ [JsonIgnore]
+ public RelayCommand SetCommand { get; set; }
+
+ public HeaterWidget()
+ {
+ SetCommand = new RelayCommand(SetHeaterState, (x) => HeaterState.CurrentValue != SetPoint);
+ HeaterState = new HeaterState();
+ }
+
+ public override async Task Init()
+ {
+ int heater = (int)Heater;
+ TechHeater = await Services.TechComponentsService.Heaters.FindOne(x => x.Code == heater);
+ }
+
+ public override void OnDiagnosticsData(DiagnosticsPackage package)
+ {
+ base.OnDiagnosticsData(package);
+ HeaterState = package.GetHeaterState(Heater);
+ }
+
+ private async void SetHeaterState()
+ {
+ if (MachineProvider.IsConnected)
+ {
+ try
+ {
+ IsEditing = false;
+ await MachineProvider.MachineOperator.SetHeaterState((HeaterType)Heater, SetPoint);
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, $"Error executing SetHeaterState command for heater {Heater}.");
+ NotificationProvider.PushSnackbarItem(MessageType.Error, "Heater Controller Error", true, ex.Message, TimeSpan.FromSeconds(5));
+ }
+ }
+ }
+
+ public override FrameworkElement GetView()
+ {
+ return new HeaterWidgetView();
+ }
+
+ #region Component Selection
+
+ public List<DiagnosticsWidgetComponent<TechHeaters>> Components
+ {
+ get
+ {
+ return Services.TechComponentsService.Heaters.FindAll().Result.Select(x => new DiagnosticsWidgetComponent<TechHeaters>()
+ {
+ DisplayName = x.Description,
+ Object = (TechHeaters)x.Code,
+ }).OrderByAlphaNumeric(x => x.DisplayName).ToList();
+ }
+ }
+
+ public TechHeaters SelectedComponent
+ {
+ get
+ {
+ return Heater;
+ }
+ set
+ {
+ if (Heater != value)
+ {
+ Heater = value;
+ InitAsync();
+ }
+ }
+ }
+
+ public bool EnableComponentSelection { get; set; }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Heater/HeaterWidgetView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Heater/HeaterWidgetView.xaml
new file mode 100644
index 000000000..056d591ba
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Heater/HeaterWidgetView.xaml
@@ -0,0 +1,202 @@
+<UserControl x:Class="Tango.FSE.Diagnostics.Project.Widgets.Heater.HeaterWidgetView"
+ 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:local="clr-namespace:Tango.FSE.Diagnostics.Project.Widgets.Heater"
+ xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
+ mc:Ignorable="d"
+ d:DesignHeight="284" d:DesignWidth="243" d:DataContext="{d:DesignInstance Type=local:HeaterWidget,IsDesignTimeCreatable=False}">
+ <Grid>
+ <Viewbox>
+ <Border CornerRadius="5" Background="{StaticResource FSE_PrimaryBackgroundDarkBrush}" BorderBrush="#3B3B3B" BorderThickness="1" Padding="15">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="16"/>
+ <RowDefinition Height="74"/>
+ <RowDefinition Height="63"/>
+ <RowDefinition Height="37"/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+
+ <Grid>
+ <TextBlock FontFamily="{StaticResource digital-7}" Text="Heater Controller" FontSize="16" Foreground="#7CC924" HorizontalAlignment="Left" Width="123"></TextBlock>
+ <TextBlock HorizontalAlignment="Right" Text="TEMPERATURE" FontSize="9" VerticalAlignment="Bottom" Foreground="Gainsboro" Height="12" Width="58"></TextBlock>
+ </Grid>
+
+ <Grid Grid.Row="1">
+ <Border Background="{StaticResource FSE_PrimaryBackgroundMidBrush}" Margin="0 3 0 0" CornerRadius="3" Padding="5">
+ <Grid>
+ <TextBlock Text="{Binding HeaterState.CurrentValue,StringFormat=0.00,FallbackValue='0.00'}" HorizontalAlignment="Right" VerticalAlignment="Center" FontSize="80" FontFamily="{StaticResource digital-7}" Margin="0 0 12 0">
+ <TextBlock.Style>
+ <Style TargetType="TextBlock">
+ <Setter Property="Foreground" Value="#FF6F78"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding HeaterState.IsInSetPoint}" Value="True">
+ <Setter Property="Foreground" Value="#7CC924"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </TextBlock.Style>
+ </TextBlock>
+ <TextBlock ToolTip="Process Value" HorizontalAlignment="Right" VerticalAlignment="Bottom" FontSize="9" Foreground="Gainsboro">PV</TextBlock>
+ </Grid>
+ </Border>
+ </Grid>
+
+ <Grid Grid.Row="2" Margin="0 5 0 0">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="49"/>
+ <ColumnDefinition Width="162"/>
+ </Grid.ColumnDefinitions>
+
+ <Image Source="../Heater/Images/temperature.png" Margin="0 10 20 10" RenderOptions.BitmapScalingMode="Fant"></Image>
+
+ <Border Background="{StaticResource FSE_PrimaryBackgroundMidBrush}" Margin="0 3 0 0" CornerRadius="3" Padding="5" Grid.Column="1">
+ <Grid>
+ <mahapps:NumericUpDown x:Name="txtSetPoint" InterceptMouseWheel="True" IsHitTestVisible="{Binding IsEditing}" InterceptArrowKeys="True" Background="Transparent" BorderThickness="0" HorizontalContentAlignment="Right" HideUpDownButtons="True" ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Disabled" HasDecimals="True" Minimum="0" Maximum="400" Padding="0" Value="{Binding SetPoint,FallbackValue='0.0',Mode=TwoWay}" VerticalAlignment="Center" FontSize="44" FontFamily="{StaticResource digital-7}" Foreground="#FFD400" Margin="0 0 12 0">
+ <mahapps:NumericUpDown.Resources>
+ <Style TargetType="TextBox">
+ <Setter Property="Opacity" Value="1"></Setter>
+ <Setter Property="CaretBrush" Value="#FFD400"></Setter>
+ <Setter Property="SelectionBrush" Value="#50FFD400"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding IsEditing}" Value="True">
+ <DataTrigger.EnterActions>
+ <BeginStoryboard Name="blink">
+ <Storyboard>
+ <DoubleAnimationUsingKeyFrames RepeatBehavior="Forever" Storyboard.TargetProperty="Opacity" FillBehavior="Stop">
+ <DiscreteDoubleKeyFrame KeyTime="00:00:00" Value="0" />
+ <DiscreteDoubleKeyFrame KeyTime="00:00:0.5" Value="1" />
+ <DiscreteDoubleKeyFrame KeyTime="00:00:1" Value="1" />
+ </DoubleAnimationUsingKeyFrames>
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ <DataTrigger.ExitActions>
+ <RemoveStoryboard BeginStoryboardName="blink" />
+ </DataTrigger.ExitActions>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </mahapps:NumericUpDown.Resources>
+
+ <mahapps:NumericUpDown.Style>
+ <Style TargetType="mahapps:NumericUpDown">
+
+ </Style>
+ </mahapps:NumericUpDown.Style>
+ </mahapps:NumericUpDown>
+ <TextBlock ToolTip="Setting Value" HorizontalAlignment="Right" VerticalAlignment="Bottom" FontSize="9" Foreground="Gainsboro">SV</TextBlock>
+
+ <ToggleButton Checked="ToggleButton_Checked" Style="{x:Null}" IsChecked="{Binding IsEditing}" HorizontalAlignment="Left" VerticalAlignment="Top" Opacity="0.2" Cursor="Hand">
+ <ToggleButton.Template>
+ <ControlTemplate TargetType="ToggleButton">
+ <Grid Background="Transparent">
+ <material:PackIcon Width="24" Height="24" Foreground="#FFD400">
+ <material:PackIcon.Style>
+ <Style TargetType="material:PackIcon">
+ <Setter Property="Kind" Value="PencilBox"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding IsEditing}" Value="True">
+ <Setter Property="Kind" Value="Pencil"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </material:PackIcon.Style>
+ </material:PackIcon>
+ </Grid>
+ </ControlTemplate>
+ </ToggleButton.Template>
+ </ToggleButton>
+ </Grid>
+ </Border>
+ </Grid>
+
+ <Grid Grid.Row="3" Margin="0 5 0 0">
+ <StackPanel Orientation="Horizontal" TextElement.Foreground="Gray" TextElement.FontSize="9">
+ <StackPanel>
+ <TextBlock>ACTIVE</TextBlock>
+ <Ellipse Width="12" Height="12" Margin="0 4 0 0" Fill="#FF6262" Stroke="#526744">
+ <Ellipse.Style>
+ <Style TargetType="Ellipse">
+ <Setter Property="Opacity" Value="0.2"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding HeaterState.IsActive}" Value="True">
+ <Setter Property="Opacity" Value="1"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Ellipse.Style>
+ </Ellipse>
+ </StackPanel>
+
+ <StackPanel Margin="10 0 0 0">
+ <TextBlock>RAMP UP</TextBlock>
+ <Ellipse Width="12" Height="12" Margin="0 4 0 0" Fill="#FF8608" Stroke="#526744">
+ <Ellipse.Style>
+ <Style TargetType="Ellipse">
+ <Setter Property="Opacity" Value="0.2"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding HeaterState.IsRampingUp}" Value="True">
+ <Setter Property="Opacity" Value="1"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Ellipse.Style>
+ </Ellipse>
+ </StackPanel>
+
+ <StackPanel Margin="10 0 0 0">
+ <TextBlock>IN POINT</TextBlock>
+ <Ellipse Width="12" Height="12" Margin="0 4 0 0" Fill="#00C600" Stroke="#526744">
+ <Ellipse.Style>
+ <Style TargetType="Ellipse">
+ <Setter Property="Opacity" Value="0.2"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding HeaterState.IsInSetPoint}" Value="True">
+ <Setter Property="Opacity" Value="1"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Ellipse.Style>
+ </Ellipse>
+ </StackPanel>
+ </StackPanel>
+ </Grid>
+
+ <Grid Grid.Row="4">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="36"/>
+ <ColumnDefinition Width="175"/>
+ </Grid.ColumnDefinitions>
+
+ <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="Gray" FontSize="16" FontWeight="SemiBold">TWI</TextBlock>
+
+ <Grid Grid.Column="1">
+ <Button Style="{x:Null}" Width="60" Height="60" HorizontalAlignment="Right" Cursor="Hand" Command="{Binding SetCommand}" IsEnabled="{Binding IsEditing}">
+ <Button.Template>
+ <ControlTemplate TargetType="Button">
+ <Grid>
+ <Ellipse Stroke="#7C7C7C" Fill="#383838"></Ellipse>
+ <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="Gainsboro" FontSize="16" FontWeight="SemiBold">SET</TextBlock>
+ </Grid>
+ <ControlTemplate.Triggers>
+ <Trigger Property="IsPressed" Value="True">
+ <Setter Property="Opacity" Value="0.7"></Setter>
+ </Trigger>
+ <Trigger Property="IsEnabled" Value="False">
+ <Setter Property="Opacity" Value="0.5"></Setter>
+ </Trigger>
+ </ControlTemplate.Triggers>
+ </ControlTemplate>
+ </Button.Template>
+ </Button>
+ </Grid>
+ </Grid>
+ </Grid>
+ </Border>
+ </Viewbox>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Heater/HeaterWidgetView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Heater/HeaterWidgetView.xaml.cs
new file mode 100644
index 000000000..efd532179
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Heater/HeaterWidgetView.xaml.cs
@@ -0,0 +1,34 @@
+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.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;
+
+namespace Tango.FSE.Diagnostics.Project.Widgets.Heater
+{
+ /// <summary>
+ /// Interaction logic for HeaterWidgetView.xaml
+ /// </summary>
+ public partial class HeaterWidgetView : UserControl
+ {
+ public HeaterWidgetView()
+ {
+ InitializeComponent();
+ }
+
+ private void ToggleButton_Checked(object sender, RoutedEventArgs e)
+ {
+ txtSetPoint.Focus();
+ txtSetPoint.SelectAll();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Heater/Images/temperature.png b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Heater/Images/temperature.png
new file mode 100644
index 000000000..0bd30c002
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Heater/Images/temperature.png
Binary files differ
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Input/InputWidget.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Input/InputWidget.cs
new file mode 100644
index 000000000..2c2309807
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Input/InputWidget.cs
@@ -0,0 +1,106 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using Tango.BL.Entities;
+using Tango.BL.Enumerations;
+
+namespace Tango.FSE.Diagnostics.Project.Widgets.Input
+{
+ [Description("Digital Input LED")]
+ public class InputWidget : DiagnosticsWidget, ISupportsComponentSelection<TechIos>
+ {
+ public TechIos IO { get; set; } = TechIos.LS_DH_CLEAN_DOWN;
+
+ private TechIo _techIO;
+ [JsonIgnore]
+ public TechIo TechIo
+ {
+ get { return _techIO; }
+ set { _techIO = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(DisplayName)); }
+ }
+
+ [JsonIgnore]
+ public override string DisplayName
+ {
+ get
+ {
+ return this.TechIo != null ? this.TechIo.InterfaceName : String.Empty;
+ }
+ }
+
+ private bool _value;
+ [JsonIgnore]
+ public bool Value
+ {
+ get { return _value; }
+ set
+ {
+ if (_value != value)
+ {
+ _value = value;
+ RaisePropertyChangedAuto();
+ }
+ }
+ }
+
+ public override async Task Init()
+ {
+ int io = (int)IO;
+ TechIo = await Services.TechComponentsService.IOs.FindOne(x => x.Code == io);
+ }
+
+ public override void OnDiagnosticsData(DiagnosticsPackage package)
+ {
+ var state = package.GetDigitalInterfaceState(IO);
+
+ if (state != null)
+ {
+ Value = state.Value;
+ }
+ }
+
+ public override FrameworkElement GetView()
+ {
+ return new InputWidgetView();
+ }
+
+ #region Component Selection
+
+ public List<DiagnosticsWidgetComponent<TechIos>> Components
+ {
+ get
+ {
+ return Services.TechComponentsService.IOs.FindAll().Result.Where(x => x.Type == (int)IOType.DigitalInput).Select(x => new DiagnosticsWidgetComponent<TechIos>()
+ {
+ DisplayName = x.InterfaceName,
+ Object = (TechIos)x.Code,
+ }).OrderByAlphaNumeric(x => x.DisplayName).ToList();
+ }
+ }
+
+ public TechIos SelectedComponent
+ {
+ get
+ {
+ return IO;
+ }
+ set
+ {
+ if (IO != value)
+ {
+ IO = value;
+ InitAsync();
+ }
+ }
+ }
+
+ public bool EnableComponentSelection { get; set; }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Input/InputWidgetView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Input/InputWidgetView.xaml
new file mode 100644
index 000000000..9049f90d1
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Input/InputWidgetView.xaml
@@ -0,0 +1,18 @@
+<UserControl x:Class="Tango.FSE.Diagnostics.Project.Widgets.Input.InputWidgetView"
+ 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:visuals="clr-namespace:Tango.Visuals;assembly=Tango.Visuals"
+ xmlns:local="clr-namespace:Tango.FSE.Diagnostics.Project.Widgets.Input"
+ mc:Ignorable="d"
+ d:DesignHeight="83" d:DesignWidth="72" d:DataContext="{d:DesignInstance Type=local:InputWidget,IsDesignTimeCreatable=False}">
+ <Grid>
+ <Viewbox>
+ <Grid>
+ <Ellipse Width="100" Height="100" Fill="{StaticResource FSE_PrimaryBackgroundMidBrush}"></Ellipse>
+ <visuals:Led Width="100" Height="100" IsChecked="{Binding Value}" IsHitTestVisible="False" />
+ </Grid>
+ </Viewbox>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Input/InputWidgetView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Input/InputWidgetView.xaml.cs
new file mode 100644
index 000000000..22ed571e8
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Input/InputWidgetView.xaml.cs
@@ -0,0 +1,28 @@
+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.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;
+
+namespace Tango.FSE.Diagnostics.Project.Widgets.Input
+{
+ /// <summary>
+ /// Interaction logic for InputWidgetView.xaml
+ /// </summary>
+ public partial class InputWidgetView : UserControl
+ {
+ public InputWidgetView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Monitor/MonitorWidget.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Monitor/MonitorWidget.cs
index 3a2590ca2..611897191 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Monitor/MonitorWidget.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Monitor/MonitorWidget.cs
@@ -1,6 +1,7 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
+using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -10,12 +11,18 @@ using Tango.BL.Enumerations;
namespace Tango.FSE.Diagnostics.Project.Widgets.Monitor
{
- public class MonitorWidget : DiagnosticsConfigurableWidget<MonitorWidgetSettings>
+ [Description("Monitor")]
+ public class MonitorWidget : DiagnosticsConfigurableWidget<MonitorWidgetSettings>, ISupportsComponentSelection<TechMonitors>
{
public TechMonitors Monitor { get; set; }
+ private TechMonitor _techMonitor;
[JsonIgnore]
- public TechMonitor TechMonitor { get; private set; }
+ public TechMonitor TechMonitor
+ {
+ get { return _techMonitor; }
+ set { _techMonitor = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(DisplayName)); }
+ }
[JsonIgnore]
public override string DisplayName
@@ -31,7 +38,14 @@ namespace Tango.FSE.Diagnostics.Project.Widgets.Monitor
public String Value
{
get { return _value; }
- set { _value = value; RaisePropertyChangedAuto(); }
+ set
+ {
+ if (_value != value)
+ {
+ _value = value;
+ RaisePropertyChangedAuto();
+ }
+ }
}
public override async Task Init()
@@ -62,7 +76,41 @@ namespace Tango.FSE.Diagnostics.Project.Widgets.Monitor
public override FrameworkElement GetView()
{
- return new MonitorWidgetView() { DataContext = this };
+ return new MonitorWidgetView();
+ }
+
+ #region Component Selection
+
+ public List<DiagnosticsWidgetComponent<TechMonitors>> Components
+ {
+ get
+ {
+ return Services.TechComponentsService.Monitors.FindAll().Result.Where(x => !x.MultiChannel).Select(x => new DiagnosticsWidgetComponent<TechMonitors>()
+ {
+ DisplayName = x.Description,
+ Object = (TechMonitors)x.Code,
+ }).OrderByAlphaNumeric(x => x.DisplayName).ToList();
+ }
+ }
+
+ public TechMonitors SelectedComponent
+ {
+ get
+ {
+ return Monitor;
+ }
+ set
+ {
+ if (Monitor != value)
+ {
+ Monitor = value;
+ InitAsync();
+ }
+ }
}
+
+ public bool EnableComponentSelection { get; set; }
+
+ #endregion
}
}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Monitor/MonitorWidgetSettingsView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Monitor/MonitorWidgetSettingsView.xaml
index 9ddaea737..bd18da646 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Monitor/MonitorWidgetSettingsView.xaml
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Monitor/MonitorWidgetSettingsView.xaml
@@ -14,7 +14,7 @@
<controls:FSEGroupBox Header="FORMAT" HeaderFontSize="{StaticResource FSE_SmallFontSize}">
<StackPanel>
<TextBlock FontSize="{StaticResource FSE_SmallerFontSize}" >Decimal Places</TextBlock>
- <mahapps:NumericUpDown Background="Transparent" BorderThickness="0 0 0 1" HorizontalContentAlignment="Left" Minimum="0" Maximum="3" Focusable="False" Value="{Binding Settings.DecimalPlaces,UpdateSourceTrigger=PropertyChanged}" />
+ <mahapps:NumericUpDown Minimum="0" Maximum="3" Focusable="False" Value="{Binding Settings.DecimalPlaces,UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</controls:FSEGroupBox>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Monitor/MonitorWidgetView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Monitor/MonitorWidgetView.xaml
index 1d8ba96a6..0dc2d96ac 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Monitor/MonitorWidgetView.xaml
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Monitor/MonitorWidgetView.xaml
@@ -7,22 +7,30 @@
mc:Ignorable="d"
d:DesignHeight="250" d:DesignWidth="400" d:DataContext="{d:DesignInstance Type=local:MonitorWidget,IsDesignTimeCreatable=False}">
<Grid>
- <Viewbox Stretch="Fill">
+ <Viewbox Stretch="Uniform">
<StackPanel>
- <Grid Grid.Column="1" Grid.Row="1" Width="200" Height="120">
- <Border BorderThickness="0" BorderBrush="{StaticResource AccentColorBrush}">
- <Border.Background>
- <ImageBrush ImageSource="../Monitor/Images/tft_screen.png" Opacity="1" />
- </Border.Background>
-
+ <Grid Grid.Column="1" Grid.Row="1" Width="400" Height="250">
+ <Border BorderThickness="1" BorderBrush="{StaticResource FSE_BorderBrush}" CornerRadius="10">
<Grid>
- <Viewbox Stretch="Uniform" Width="150" VerticalAlignment="Center" Margin="25 10 10 10" HorizontalAlignment="Left">
- <TextBlock FontFamily="{StaticResource digital-7}" TextAlignment="Left" VerticalAlignment="Center" HorizontalAlignment="Left" FontSize="90" Text="{Binding Value,FallbackValue='0000'}">
- <TextBlock.Foreground>
- <SolidColorBrush Color="{Binding Settings.Color}"></SolidColorBrush>
- </TextBlock.Foreground>
- </TextBlock>
- </Viewbox>
+ <Border BorderBrush="{StaticResource FSE_PrimaryBackgroundDarkBrush}" BorderThickness="35" CornerRadius="1" Margin="1">
+ <Border BorderThickness="2" Background="#353535">
+ <Border.BorderBrush>
+ <LinearGradientBrush>
+ <GradientStop Offset="0.8" Color="{StaticResource FSE_PrimaryBackgroundLightColor}" />
+ <GradientStop Offset="0" Color="#121212" />
+ </LinearGradientBrush>
+ </Border.BorderBrush>
+ <Viewbox Stretch="Uniform" Width="270" VerticalAlignment="Center" Margin="25 0 10 0" HorizontalAlignment="Left">
+ <Border>
+ <TextBlock FontFamily="{StaticResource digital-7}" TextAlignment="Left" VerticalAlignment="Center" HorizontalAlignment="Left" FontSize="90" Text="{Binding Value,FallbackValue='0000',TargetNullValue='0000'}">
+ <TextBlock.Foreground>
+ <SolidColorBrush Color="{Binding Settings.Color}"></SolidColorBrush>
+ </TextBlock.Foreground>
+ </TextBlock>
+ </Border>
+ </Viewbox>
+ </Border>
+ </Border>
</Grid>
</Border>
</Grid>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidget.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidget.cs
new file mode 100644
index 000000000..28fed7c9d
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidget.cs
@@ -0,0 +1,219 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using Tango.BL.Entities;
+using Tango.BL.Enumerations;
+using Tango.Core;
+using Tango.Core.Commands;
+using Tango.FSE.Common.Notifications;
+using Tango.PMR.Diagnostics;
+
+namespace Tango.FSE.Diagnostics.Project.Widgets.Motor
+{
+ [Description("Motor Controller")]
+ public class MotorWidget : DiagnosticsConfigurableWidget<MotorWidgetSettings>, ISupportsComponentSelection<HardwareMotorTypes>
+ {
+ public HardwareMotorTypes Motor { get; set; }
+
+
+ private HardwareMotorType _hardwareMotorType;
+ [JsonIgnore]
+ public HardwareMotorType HardwareMotorType
+ {
+ get { return _hardwareMotorType; }
+ set { _hardwareMotorType = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(DisplayName)); }
+ }
+
+ [JsonIgnore]
+ public override string DisplayName
+ {
+ get
+ {
+ return this.HardwareMotorType != null ? this.HardwareMotorType.Description : String.Empty;
+ }
+ }
+
+ private MotorWidgetState _state;
+ [JsonIgnore]
+ public MotorWidgetState State
+ {
+ get { return _state; }
+ set { _state = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(IsHoming)); }
+ }
+
+ [JsonIgnore]
+ public bool IsHoming
+ {
+ get { return State == MotorWidgetState.HomingBackward || State == MotorWidgetState.HomingForward; }
+ }
+
+ private TangoProgress<double> _homingProgress;
+ [JsonIgnore]
+ public TangoProgress<double> HomingProgress
+ {
+ get { return _homingProgress; }
+ set { _homingProgress = value; RaisePropertyChangedAuto(); }
+ }
+
+ [JsonIgnore]
+ public RelayCommand<MotorWidgetState> ExecuteCommand { get; set; }
+
+ [JsonIgnore]
+ public RelayCommand StopCommand { get; set; }
+
+ public MotorWidget()
+ {
+ HomingProgress = new TangoProgress<double>(null, false, 0, 100);
+
+ ExecuteCommand = new RelayCommand<MotorWidgetState>(Execute);
+ StopCommand = new RelayCommand(StopCurrentExecution);
+ }
+
+ public override async Task Init()
+ {
+ int motor = (int)Motor;
+ HardwareMotorType = await Services.TechComponentsService.Motors.FindOne(x => x.Code == motor);
+ }
+
+ public override FrameworkElement GetView()
+ {
+ return new MotorWidgetView();
+ }
+
+ private async void Execute(MotorWidgetState command)
+ {
+ if (!MachineProvider.IsConnected || State != MotorWidgetState.Idle) return;
+
+ State = command;
+ HomingProgress = new TangoProgress<double>(null, true, 0, 100);
+
+ TaskCompletionSource<object> completion = null;
+
+ try
+ {
+ if (command == MotorWidgetState.JoggingForward || command == MotorWidgetState.JoggingBackward)
+ {
+ await MachineProvider.MachineOperator.StartMotorJogging(new MotorJoggingRequest()
+ {
+ MotorType = (PMR.Hardware.HardwareMotorType)Motor,
+ Direction = command == MotorWidgetState.JoggingForward ? MotorDirection.Forward : MotorDirection.Backward,
+ Speed = Settings.Speed
+ });
+ }
+ else if (command == MotorWidgetState.HomingForward || command == MotorWidgetState.HomingBackward)
+ {
+ completion = new TaskCompletionSource<object>();
+
+ MachineProvider.MachineOperator.StartMotorHoming(new MotorHomingRequest()
+ {
+ MotorType = (PMR.Hardware.HardwareMotorType)Motor,
+ Speed = Settings.Speed,
+ Direction = command == MotorWidgetState.HomingForward ? MotorDirection.Forward : MotorDirection.Backward
+ })
+ .Subscribe((response) =>
+ {
+ HomingProgress = new TangoProgress<double>(null, response.Progress == 0, response.Progress, response.MaxProgress);
+ }, (ex) =>
+ {
+ completion.SetException(ex);
+ }, () =>
+ {
+ State = MotorWidgetState.Idle;
+ completion.SetResult(true);
+ });
+ }
+
+ if (completion != null)
+ {
+ await completion.Task;
+ }
+ }
+ catch (Exception ex)
+ {
+ if (State != MotorWidgetState.Idle)
+ {
+ State = MotorWidgetState.Idle;
+ LogManager.Log(ex, $"Error occurred in diagnostics motor widget '{command}'.");
+ NotificationProvider.PushSnackbarItem(MessageType.Error, "Motor Controller Error", true, ex.Message, TimeSpan.FromSeconds(5));
+ }
+ }
+ finally
+ {
+ HomingProgress = new TangoProgress<double>(null, false);
+ }
+ }
+
+ private async void StopCurrentExecution()
+ {
+ if (!MachineProvider.IsConnected) return;
+
+ var command = State;
+
+ State = MotorWidgetState.Idle;
+ HomingProgress = new TangoProgress<double>(null, false);
+
+ try
+ {
+ if (command == MotorWidgetState.JoggingForward || command == MotorWidgetState.JoggingBackward)
+ {
+ await MachineProvider.MachineOperator.StopMotorJogging(new MotorAbortJoggingRequest()
+ {
+ MotorType = (PMR.Hardware.HardwareMotorType)Motor,
+ });
+ }
+ else if (command == MotorWidgetState.HomingForward || command == MotorWidgetState.HomingBackward)
+ {
+ await MachineProvider.MachineOperator.StopMotorHoming(new MotorAbortHomingRequest()
+ {
+ MotorType = (PMR.Hardware.HardwareMotorType)Motor,
+ });
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, $"Error occurred in diagnostics motor widget '{command}'.");
+ NotificationProvider.PushSnackbarItem(MessageType.Error, "Motor Controller Error", true, ex.Message, TimeSpan.FromSeconds(5));
+ }
+ }
+
+ #region Component Selection
+
+ public List<DiagnosticsWidgetComponent<HardwareMotorTypes>> Components
+ {
+ get
+ {
+ return Services.TechComponentsService.Motors.FindAll().Result.Select(x => new DiagnosticsWidgetComponent<HardwareMotorTypes>()
+ {
+ DisplayName = x.Description,
+ Object = (HardwareMotorTypes)x.Code,
+ }).OrderByAlphaNumeric(x => x.DisplayName).ToList();
+ }
+ }
+
+ public HardwareMotorTypes SelectedComponent
+ {
+ get
+ {
+ return Motor;
+ }
+ set
+ {
+ if (Motor != value)
+ {
+ Motor = value;
+ InitAsync();
+ }
+ }
+ }
+
+ public bool EnableComponentSelection { get; set; }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetSettings.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetSettings.cs
new file mode 100644
index 000000000..b68b57910
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetSettings.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Media;
+
+namespace Tango.FSE.Diagnostics.Project.Widgets.Motor
+{
+ public class MotorWidgetSettings : DiagnosticsWidgetSettings
+ {
+ private int _speed;
+ public int Speed
+ {
+ get { return _speed; }
+ set { _speed = value; RaisePropertyChangedAuto(); }
+ }
+
+ private Color _color;
+ public Color Color
+ {
+ get { return _color; }
+ set { _color = value; RaisePropertyChangedAuto(); }
+ }
+
+ public MotorWidgetSettings()
+ {
+ Speed = 400;
+ Color = Color.FromRgb(20, 20, 20);
+ }
+
+ public override FrameworkElement GetView()
+ {
+ return new MotorWidgetSettingsView();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetSettingsView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetSettingsView.xaml
new file mode 100644
index 000000000..3dabb5aef
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetSettingsView.xaml
@@ -0,0 +1,27 @@
+<UserControl x:Class="Tango.FSE.Diagnostics.Project.Widgets.Motor.MotorWidgetSettingsView"
+ 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:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:controls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common"
+ xmlns:colorPicker="clr-namespace:Tango;assembly=Tango.ColorPicker"
+ xmlns:local="clr-namespace:Tango.FSE.Diagnostics.Project.Widgets.Motor"
+ mc:Ignorable="d"
+ d:DesignHeight="700" d:DesignWidth="300" d:DataContext="{d:DesignInstance Type=local:MotorWidgetSettings,IsDesignTimeCreatable=False}">
+ <Grid>
+ <StackPanel>
+ <controls:FSEGroupBox Header="SPEED" HeaderFontSize="{StaticResource FSE_SmallFontSize}">
+ <StackPanel>
+ <mahapps:NumericUpDown Minimum="0" Maximum="10000" Value="{Binding Settings.Speed,UpdateSourceTrigger=PropertyChanged}" />
+ </StackPanel>
+ </controls:FSEGroupBox>
+
+ <controls:FSEGroupBox Header="COLOR" Margin="0 10 0 0" HeaderFontSize="{StaticResource FSE_SmallFontSize}">
+ <Viewbox>
+ <colorPicker:ColorCanvas Background="Transparent" BorderThickness="0" FontSize="{StaticResource FSE_SmallerFontSize}" SelectedColor="{Binding Settings.Color,Mode=TwoWay}" />
+ </Viewbox>
+ </controls:FSEGroupBox>
+ </StackPanel>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetSettingsView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetSettingsView.xaml.cs
new file mode 100644
index 000000000..b26f0c130
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetSettingsView.xaml.cs
@@ -0,0 +1,28 @@
+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.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;
+
+namespace Tango.FSE.Diagnostics.Project.Widgets.Motor
+{
+ /// <summary>
+ /// Interaction logic for MotorWidgetSettingsView.xaml
+ /// </summary>
+ public partial class MotorWidgetSettingsView : UserControl
+ {
+ public MotorWidgetSettingsView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetState.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetState.cs
new file mode 100644
index 000000000..0075c6038
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetState.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Diagnostics.Project.Widgets.Motor
+{
+ public enum MotorWidgetState
+ {
+ Idle,
+ JoggingForward,
+ JoggingBackward,
+ HomingForward,
+ HomingBackward
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetView.xaml
new file mode 100644
index 000000000..b2582676c
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetView.xaml
@@ -0,0 +1,175 @@
+<UserControl x:Class="Tango.FSE.Diagnostics.Project.Widgets.Motor.MotorWidgetView"
+ 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:controls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common"
+ xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
+ xmlns:local="clr-namespace:Tango.FSE.Diagnostics.Project.Widgets.Motor"
+ mc:Ignorable="d"
+ d:DesignHeight="450" d:DesignWidth="640" d:DataContext="{d:DesignInstance Type=local:MotorWidget,IsDesignTimeCreatable=False}">
+ <Grid>
+ <Viewbox Stretch="Uniform">
+ <Grid Width="400" Height="280">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="20*"/>
+ <ColumnDefinition Width="100*"/>
+ <ColumnDefinition Width="20*"/>
+ </Grid.ColumnDefinitions>
+
+ <Grid.RowDefinitions>
+ <RowDefinition Height="100*" />
+ <RowDefinition Height="30*" />
+ </Grid.RowDefinitions>
+
+ <Grid Grid.Column="1">
+ <Border BorderThickness="1" BorderBrush="{StaticResource FSE_BorderBrush}" CornerRadius="10" Background="#252525">
+ <Grid Margin="20">
+ <Path RenderTransformOrigin="0.5,0.5" StrokeThickness="1" Stretch="Uniform" Margin="10" Data="M500.633 211.454l-58.729-14.443c-3.53-11.133-8.071-21.929-13.55-32.256c8.818-14.678 27.349-45.571 27.349-45.571 c3.545-5.903 2.607-13.462-2.256-18.325l-42.422-42.422c-4.863-4.878-12.407-5.815-18.325-2.256L347.055 83.53 c-10.269-5.435-21.006-9.932-32.065-13.433l-14.443-58.729C298.876 4.688 292.885 0 286 0h-60 c-6.885 0-12.891 4.688-14.546 11.367c0 0-10.005 40.99-14.429 58.715c-11.792 3.735-23.188 8.584-34.043 14.502l-47.329-28.403 c-5.918-3.516-13.447-2.607-18.325 2.256l-42.422 42.422c-4.863 4.863-5.801 12.422-2.256 18.325l29.268 48.882 c-4.717 9.302-8.672 18.984-11.821 28.901l-58.729 14.487C4.688 213.124 0 219.115 0 226v60c0 6.885 4.688 12.891 11.367 14.546 l58.744 14.443c3.56 11.294 8.188 22.266 13.799 32.798l-26.191 43.652c-3.545 5.903-2.607 13.462 2.256 18.325l42.422 42.422 c4.849 4.849 12.407 5.771 18.325 2.256c0 0 29.37-17.607 43.755-26.221c10.415 5.552 21.313 10.137 32.549 13.696l14.429 58.715 C213.109 507.313 219.115 512 226 512h60c6.885 0 12.876-4.688 14.546-11.367l14.429-58.715 c11.558-3.662 22.69-8.394 33.281-14.136c14.78 8.862 44.443 26.66 44.443 26.66c5.903 3.53 13.462 2.622 18.325-2.256 l42.422-42.422c4.863-4.863 5.801-12.422 2.256-18.325l-26.968-44.927c5.317-10.093 9.727-20.654 13.169-31.523l58.729-14.443 C507.313 298.876 512 292.885 512 286v-60C512 219.115 507.313 213.124 500.633 211.454z M256 361c-57.891 0-105-47.109-105-105 s47.109-105 105-105s105 47.109 105 105S313.891 361 256 361z">
+ <Path.Stroke>
+ <SolidColorBrush Color="{Binding Settings.Color}" />
+ </Path.Stroke>
+ <Path.Style>
+ <Style TargetType="Path">
+ <Setter Property="RenderTransform">
+ <Setter.Value>
+ <RotateTransform x:Name="propRotate" Angle="0" />
+ </Setter.Value>
+ </Setter>
+ <Style.Triggers>
+
+ <DataTrigger Binding="{Binding State}" Value="{x:Static local:MotorWidgetState.JoggingForward}">
+ <DataTrigger.EnterActions>
+ <BeginStoryboard Name="joggingForward">
+ <Storyboard>
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle" To="360" Duration="00:00:01" RepeatBehavior="Forever" FillBehavior="HoldEnd" />
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ <DataTrigger.ExitActions>
+ <RemoveStoryboard BeginStoryboardName="joggingForward" />
+ </DataTrigger.ExitActions>
+ </DataTrigger>
+
+ <DataTrigger Binding="{Binding State}" Value="{x:Static local:MotorWidgetState.JoggingBackward}">
+ <DataTrigger.EnterActions>
+ <BeginStoryboard Name="joggingBackward">
+ <Storyboard>
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle" To="-360" Duration="00:00:01" RepeatBehavior="Forever" FillBehavior="HoldEnd" />
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ <DataTrigger.ExitActions>
+ <RemoveStoryboard BeginStoryboardName="joggingBackward" />
+ </DataTrigger.ExitActions>
+ </DataTrigger>
+
+ <DataTrigger Binding="{Binding State}" Value="{x:Static local:MotorWidgetState.HomingForward}">
+ <DataTrigger.EnterActions>
+ <BeginStoryboard Name="homingForward">
+ <Storyboard>
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle" To="360" Duration="00:00:01" RepeatBehavior="Forever" FillBehavior="HoldEnd" />
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ <DataTrigger.ExitActions>
+ <RemoveStoryboard BeginStoryboardName="homingForward" />
+ </DataTrigger.ExitActions>
+ </DataTrigger>
+
+ <DataTrigger Binding="{Binding State}" Value="{x:Static local:MotorWidgetState.HomingBackward}">
+ <DataTrigger.EnterActions>
+ <BeginStoryboard Name="homingBackward">
+ <Storyboard>
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle" To="-360" Duration="00:00:01" RepeatBehavior="Forever" FillBehavior="HoldEnd" />
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ <DataTrigger.ExitActions>
+ <RemoveStoryboard BeginStoryboardName="homingBackward" />
+ </DataTrigger.ExitActions>
+ </DataTrigger>
+
+ </Style.Triggers>
+ </Style>
+ </Path.Style>
+ <Path.Fill>
+ <LinearGradientBrush>
+ <GradientStop Color="Black"/>
+ <GradientStop Color="Transparent" Offset="0.8"/>
+ </LinearGradientBrush>
+ </Path.Fill>
+ </Path>
+ </Grid>
+ </Border>
+ </Grid>
+
+ <Grid>
+ <Button Margin="0 10" Style="{StaticResource FSE_MotorWidgetButton_Left}" IsEnabled="{Binding IsHoming,Converter={StaticResource BooleanInverseConverter}}">
+ <i:Interaction.Triggers>
+ <i:EventTrigger EventName="PreviewMouseDown">
+ <i:InvokeCommandAction Command="{Binding ExecuteCommand}" CommandParameter="{x:Static local:MotorWidgetState.JoggingBackward}" />
+ </i:EventTrigger>
+ <i:EventTrigger EventName="PreviewMouseUp">
+ <i:InvokeCommandAction Command="{Binding StopCommand}" />
+ </i:EventTrigger>
+ </i:Interaction.Triggers>
+ <Viewbox Stretch="Fill" Margin="-10 20">
+ <material:PackIcon Kind="ChevronLeft" HorizontalAlignment="Center" VerticalAlignment="Center" Width="24" Height="24" />
+ </Viewbox>
+ </Button>
+ </Grid>
+
+ <Grid Grid.Column="2">
+ <Button Margin="0 10" Style="{StaticResource FSE_MotorWidgetButton_Right}" IsEnabled="{Binding IsHoming,Converter={StaticResource BooleanInverseConverter}}">
+ <i:Interaction.Triggers>
+ <i:EventTrigger EventName="PreviewMouseDown">
+ <i:InvokeCommandAction Command="{Binding ExecuteCommand}" CommandParameter="{x:Static local:MotorWidgetState.JoggingForward}" />
+ </i:EventTrigger>
+ <i:EventTrigger EventName="PreviewMouseUp">
+ <i:InvokeCommandAction Command="{Binding StopCommand}" />
+ </i:EventTrigger>
+ </i:Interaction.Triggers>
+ <Viewbox Stretch="Fill" Margin="-10 20">
+ <material:PackIcon Kind="ChevronRight" HorizontalAlignment="Center" VerticalAlignment="Center" Width="24" Height="24" />
+ </Viewbox>
+ </Button>
+ </Grid>
+
+ <Grid Grid.Column="1" Grid.Row="1" Visibility="Visible">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="20*"/>
+ <ColumnDefinition Width="115*"/>
+ <ColumnDefinition Width="20*"/>
+ </Grid.ColumnDefinitions>
+
+ <Grid Grid.Column="1">
+ <Border Style="{StaticResource FSE_MotorWidgetBorder_Center}">
+ <Grid x:Name="gridDefault">
+ <DockPanel>
+ <controls:IconButton IsEnabled="{Binding IsHoming,Converter={StaticResource BooleanInverseConverter}}" Margin="5 0 0 0" HorizontalAlignment="Center" Command="{Binding ExecuteCommand}" CommandParameter="{x:Static local:MotorWidgetState.HomingBackward}" Width="40" Height="40" Style="{StaticResource FSE_WidgetIconButton_Red}" DockPanel.Dock="Left" Icon="ChevronDoubleLeft"></controls:IconButton>
+ <controls:IconButton IsEnabled="{Binding IsHoming,Converter={StaticResource BooleanInverseConverter}}" HorizontalAlignment="Center" Command="{Binding ExecuteCommand}" CommandParameter="{x:Static local:MotorWidgetState.HomingForward}" Width="40" Height="40" Style="{StaticResource FSE_WidgetIconButton_Red}" DockPanel.Dock="Right" Icon="ChevronDoubleRight"></controls:IconButton>
+
+ <Grid>
+ <material:PackIcon Margin="-5 0 0 0" Visibility="{Binding IsHoming,Converter={StaticResource BooleanToVisibilityInverseConverter}}" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="{StaticResource FSE_PrimaryForegroundBrush}" Padding="0" Width="55" Height="55" Kind="Home"></material:PackIcon>
+
+ <Grid Visibility="{Binding IsHoming,Converter={StaticResource BooleanToVisibilityConverter}}">
+
+ <Viewbox Margin="0 5 5 5">
+ <controls:ProgressRingDouble HorizontalAlignment="Center" VerticalAlignment="Center" Minimum="0" Maximum="100" IsIndeterminate="{Binding HomingProgress.IsIndeterminate}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}" Value="{Binding HomingProgress.Value}" Thickness="5" Width="70" Height="70" />
+ </Viewbox>
+
+ <controls:IconButton Cursor="Hand" Padding="0" Command="{Binding StopCommand}" Icon="Stop" Width="42" Height="42" Foreground="{StaticResource FSE_RedBrush}" HorizontalAlignment="Center" VerticalAlignment="Center"></controls:IconButton>
+ </Grid>
+ </Grid>
+ </DockPanel>
+ </Grid>
+ </Border>
+ </Grid>
+ </Grid>
+
+ </Grid>
+ </Viewbox>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetView.xaml.cs
new file mode 100644
index 000000000..7fc9f6343
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Motor/MotorWidgetView.xaml.cs
@@ -0,0 +1,28 @@
+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.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;
+
+namespace Tango.FSE.Diagnostics.Project.Widgets.Motor
+{
+ /// <summary>
+ /// Interaction logic for MotorWidgetView.xaml
+ /// </summary>
+ public partial class MotorWidgetView : UserControl
+ {
+ public MotorWidgetView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraph/RealTimeGraphWidget.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraph/RealTimeGraphWidget.cs
index 50693746e..98358f9b0 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraph/RealTimeGraphWidget.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraph/RealTimeGraphWidget.cs
@@ -3,6 +3,7 @@ using RealTimeGraphX.DataPoints;
using RealTimeGraphX.WPF;
using System;
using System.Collections.Generic;
+using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
@@ -15,6 +16,7 @@ using Tango.Core.Commands;
namespace Tango.FSE.Diagnostics.Project.Widgets.RealTimeGraph
{
+ [Description("Single Series Graph")]
public class RealTimeGraphWidget : RealTimeGraphWidgetBase<RealTimeGraphWidgetSettings>
{
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraph/RealTimeGraphWidgetBase.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraph/RealTimeGraphWidgetBase.cs
index 8e79e53e3..8fbed469c 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraph/RealTimeGraphWidgetBase.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraph/RealTimeGraphWidgetBase.cs
@@ -15,12 +15,17 @@ using Tango.Core.Commands;
namespace Tango.FSE.Diagnostics.Project.Widgets.RealTimeGraph
{
- public abstract class RealTimeGraphWidgetBase<T> : DiagnosticsConfigurableWidget<T> where T : RealTimeGraphWidgetSettings, new()
+ public abstract class RealTimeGraphWidgetBase<T> : DiagnosticsConfigurableWidget<T>, ISupportsComponentSelection<TechMonitors> where T : RealTimeGraphWidgetSettings, new()
{
public TechMonitors Monitor { get; set; }
+ private TechMonitor _techMonitor;
[JsonIgnore]
- public TechMonitor TechMonitor { get; private set; }
+ public TechMonitor TechMonitor
+ {
+ get { return _techMonitor; }
+ set { _techMonitor = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(DisplayName)); }
+ }
[JsonIgnore]
public override string DisplayName
@@ -62,13 +67,14 @@ namespace Tango.FSE.Diagnostics.Project.Widgets.RealTimeGraph
public override async Task Init()
{
+ Clear();
int monitor = (int)Monitor;
TechMonitor = await Services.TechComponentsService.Monitors.FindOne(x => x.Code == monitor);
}
public override FrameworkElement GetView()
{
- return new RealTimeGraphWidgetView() { DataContext = this };
+ return new RealTimeGraphWidgetView();
}
protected override void OnVisibleChanged(bool isVisible)
@@ -118,5 +124,39 @@ namespace Tango.FSE.Diagnostics.Project.Widgets.RealTimeGraph
Controller.PushData(dates, dPoints);
}
}
+
+ #region Component Selection
+
+ public virtual List<DiagnosticsWidgetComponent<TechMonitors>> Components
+ {
+ get
+ {
+ return Services.TechComponentsService.Monitors.FindAll().Result.Where(x => !x.MultiChannel).Select(x => new DiagnosticsWidgetComponent<TechMonitors>()
+ {
+ DisplayName = x.Description,
+ Object = (TechMonitors)x.Code,
+ }).OrderByAlphaNumeric(x => x.DisplayName).ToList();
+ }
+ }
+
+ public TechMonitors SelectedComponent
+ {
+ get
+ {
+ return Monitor;
+ }
+ set
+ {
+ if (Monitor != value)
+ {
+ Monitor = value;
+ InitAsync();
+ }
+ }
+ }
+
+ public bool EnableComponentSelection { get; set; }
+
+ #endregion
}
}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraph/RealTimeGraphWidgetSettingsView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraph/RealTimeGraphWidgetSettingsView.xaml
index 333f21b76..073d9dc23 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraph/RealTimeGraphWidgetSettingsView.xaml
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraph/RealTimeGraphWidgetSettingsView.xaml
@@ -43,14 +43,14 @@
LowerValue="{Binding Settings.Min,UpdateSourceTrigger=PropertyChanged}"
UpperValue="{Binding Settings.Max,UpdateSourceTrigger=PropertyChanged}"/>
- <CheckBox Margin="0 10 0 0" IsChecked="{Binding Settings.AutoRange}">Auto Range</CheckBox>
+ <CheckBox FontSize="{StaticResource FSE_SmallFontSize}" Margin="0 10 0 0" IsChecked="{Binding Settings.AutoRange}">Auto Range</CheckBox>
</StackPanel>
</controls:FSEGroupBox>
<controls:FSEGroupBox Header="FORMAT" Margin="0 10 0 0" HeaderFontSize="{StaticResource FSE_SmallFontSize}">
<StackPanel>
<TextBlock FontSize="{StaticResource FSE_SmallerFontSize}" >Decimal Places</TextBlock>
- <mahapps:NumericUpDown Background="Transparent" BorderThickness="0 0 0 1" HorizontalContentAlignment="Left" Minimum="0" Maximum="3" Focusable="False" Value="{Binding Settings.DecimalPlaces,UpdateSourceTrigger=PropertyChanged}" />
+ <mahapps:NumericUpDown Minimum="0" Maximum="3" Focusable="False" Value="{Binding Settings.DecimalPlaces,UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</controls:FSEGroupBox>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraphMultiChannel/RealTimeGraphMultiChannelWidget.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraphMultiChannel/RealTimeGraphMultiChannelWidget.cs
index 1ebaa199e..1b1390f15 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraphMultiChannel/RealTimeGraphMultiChannelWidget.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraphMultiChannel/RealTimeGraphMultiChannelWidget.cs
@@ -2,18 +2,26 @@
using RealTimeGraphX.WPF;
using System;
using System.Collections.Generic;
+using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
+using Tango.BL.Enumerations;
using Tango.FSE.Diagnostics.Project.Widgets.RealTimeGraph;
namespace Tango.FSE.Diagnostics.Project.Widgets.RealTimeGraphMultiChannel
{
+ [Description("Multi Series Graph")]
public class RealTimeGraphMultiChannelWidget : RealTimeGraphWidgetBase<RealTimeGraphMultiChannelWidgetSettings>
{
+ public RealTimeGraphMultiChannelWidget()
+ {
+ Monitor = TechMonitors.DispensersPressure;
+ }
+
public async override Task Init()
{
await base.Init();
@@ -30,48 +38,61 @@ namespace Tango.FSE.Diagnostics.Project.Widgets.RealTimeGraphMultiChannel
Controller.DataSeriesCollection.Add(new WpfGraphDataSeries()
{
Name = $"{TechMonitor.Name.First()}{i + 1}",
- Stroke = Colors.DodgerBlue,
+ Stroke = Colors.DimGray,
});
}
MachineProvider.MachineConnected -= MachineProvider_MachineConnected;
MachineProvider.MachineConnected += MachineProvider_MachineConnected;
- }
- public override FrameworkElement GetView()
- {
- return new RealTimeGraphMultiChannelWidgetView() { DataContext = this };
+ ConfigureByConnectedMachine();
}
- private void MachineProvider_MachineConnected(object sender, Common.Connection.MachineConnectedEventArgs e)
+ private void ConfigureByConnectedMachine()
{
- try
+ if (MachineProvider.IsConnected && MachineProvider.Machine != null)
{
- foreach (var pack in MachineProvider.Machine.Configuration.NoneEmptyIdsPacks.OrderBy(x => x.PackIndex).ToList())
+ try
{
- Color color = Colors.DodgerBlue;
+ Controller.DataSeriesCollection.ToList().ForEach(x => x.IsVisible = false);
- if (pack.LiquidType.LiquidTypeColor == Colors.Black)
- {
- color = Colors.Gray;
- }
- else if (pack.LiquidType.LiquidTypeColor == Colors.Transparent)
- {
- color = Colors.White;
- }
- else
+ foreach (var pack in MachineProvider.Machine.Configuration.NoneEmptyIdsPacks.OrderBy(x => x.PackIndex).ToList())
{
- color = pack.LiquidType.LiquidTypeColor;
- }
+ Color color = Colors.DimGray;
- Controller.DataSeriesCollection[pack.PackIndex].Name = pack.LiquidType.Name;
- Controller.DataSeriesCollection[pack.PackIndex].Stroke = color;
+ if (pack.LiquidType.LiquidTypeColor == Colors.Black)
+ {
+ color = Colors.Gray;
+ }
+ else if (pack.LiquidType.LiquidTypeColor == Colors.Transparent)
+ {
+ color = Colors.White;
+ }
+ else
+ {
+ color = pack.LiquidType.LiquidTypeColor;
+ }
+
+ Controller.DataSeriesCollection[pack.PackIndex].Name = pack.LiquidType.Name;
+ Controller.DataSeriesCollection[pack.PackIndex].Stroke = color;
+ Controller.DataSeriesCollection[pack.PackIndex].IsVisible = true;
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, $"Error initializing colors for real-time multi channel graph data series collection '{Monitor}'.");
}
}
- catch (Exception ex)
- {
- LogManager.Log(ex, $"Error initializing colors for real-time multi channel graph data series collection '{Monitor}'.");
- }
+ }
+
+ public override FrameworkElement GetView()
+ {
+ return new RealTimeGraphMultiChannelWidgetView();
+ }
+
+ private void MachineProvider_MachineConnected(object sender, Common.Connection.MachineConnectedEventArgs e)
+ {
+ ConfigureByConnectedMachine();
}
public override void OnDiagnosticsData(DiagnosticsPackage package)
@@ -110,5 +131,17 @@ namespace Tango.FSE.Diagnostics.Project.Widgets.RealTimeGraphMultiChannel
}
}
}
+
+ public override List<DiagnosticsWidgetComponent<TechMonitors>> Components
+ {
+ get
+ {
+ return Services.TechComponentsService.Monitors.FindAll().Result.Where(x => x.MultiChannel).Select(x => new DiagnosticsWidgetComponent<TechMonitors>()
+ {
+ DisplayName = x.Description,
+ Object = (TechMonitors)x.Code,
+ }).OrderByAlphaNumeric(x => x.DisplayName).ToList();
+ }
+ }
}
}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraphMultiChannel/RealTimeGraphMultiChannelWidgetSettingsView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraphMultiChannel/RealTimeGraphMultiChannelWidgetSettingsView.xaml
index 0ac731be0..253b1e5ac 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraphMultiChannel/RealTimeGraphMultiChannelWidgetSettingsView.xaml
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/RealTimeGraphMultiChannel/RealTimeGraphMultiChannelWidgetSettingsView.xaml
@@ -43,14 +43,14 @@
LowerValue="{Binding Settings.Min,UpdateSourceTrigger=PropertyChanged}"
UpperValue="{Binding Settings.Max,UpdateSourceTrigger=PropertyChanged}"/>
- <CheckBox Margin="0 10 0 0" IsChecked="{Binding Settings.AutoRange}">Auto Range</CheckBox>
+ <CheckBox FontSize="{StaticResource FSE_SmallFontSize}" Margin="0 10 0 0" IsChecked="{Binding Settings.AutoRange}">Auto Range</CheckBox>
</StackPanel>
</controls:FSEGroupBox>
<controls:FSEGroupBox Header="FORMAT" Margin="0 10 0 0" HeaderFontSize="{StaticResource FSE_SmallFontSize}">
<StackPanel>
<TextBlock FontSize="{StaticResource FSE_SmallerFontSize}" >Decimal Places</TextBlock>
- <mahapps:NumericUpDown Background="Transparent" BorderThickness="0 0 0 1" HorizontalContentAlignment="Left" Minimum="0" Maximum="3" Focusable="False" Value="{Binding Settings.DecimalPlaces,UpdateSourceTrigger=PropertyChanged}" />
+ <mahapps:NumericUpDown Minimum="0" Maximum="3" Focusable="False" Value="{Binding Settings.DecimalPlaces,UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</controls:FSEGroupBox>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidget.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidget.cs
new file mode 100644
index 000000000..65ac33341
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidget.cs
@@ -0,0 +1,57 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Media;
+
+namespace Tango.FSE.Diagnostics.Project.Widgets.Text
+{
+ public class TextWidget : DiagnosticsConfigurableWidget<TextWidgetSettings>
+ {
+ [JsonIgnore]
+ public override string DisplayName
+ {
+ get
+ {
+ return Text;
+ }
+ }
+
+ private String _text;
+ public String Text
+ {
+ get { return _text; }
+ set { _text = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(DisplayName)); }
+ }
+
+ private Color _color;
+ public Color Color
+ {
+ get { return _color; }
+ set { _color = value; RaisePropertyChangedAuto(); }
+ }
+
+ [JsonIgnore]
+ public override bool HasSettings
+ {
+ get
+ {
+ return EditMode;
+ }
+ }
+
+ public TextWidget()
+ {
+ Color = Colors.LightGray;
+ Text = "press to edit text";
+ }
+
+ public override FrameworkElement GetView()
+ {
+ return new TextWidgetView();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidgetSettings.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidgetSettings.cs
new file mode 100644
index 000000000..b0701e56b
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidgetSettings.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Media;
+
+namespace Tango.FSE.Diagnostics.Project.Widgets.Text
+{
+ [Description("Text")]
+ public class TextWidgetSettings : DiagnosticsWidgetSettings
+ {
+ public override FrameworkElement GetView()
+ {
+ return new TextWidgetSettingsView();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidgetSettingsView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidgetSettingsView.xaml
new file mode 100644
index 000000000..520326643
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidgetSettingsView.xaml
@@ -0,0 +1,24 @@
+<UserControl x:Class="Tango.FSE.Diagnostics.Project.Widgets.Text.TextWidgetSettingsView"
+ 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:controls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common"
+ xmlns:colorPicker="clr-namespace:Tango;assembly=Tango.ColorPicker"
+ xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:local="clr-namespace:Tango.FSE.Diagnostics.Project.Widgets.Text"
+ mc:Ignorable="d"
+ d:DesignHeight="700" d:DesignWidth="300" d:DataContext="{d:DesignInstance Type=local:TextWidget,IsDesignTimeCreatable=False}">
+ <Grid>
+ <StackPanel>
+ <controls:FSEGroupBox Header="TEXT" HeaderFontSize="{StaticResource FSE_SmallFontSize}">
+ <TextBox Text="{Binding Text,UpdateSourceTrigger=PropertyChanged}"></TextBox>
+ </controls:FSEGroupBox>
+ <controls:FSEGroupBox Header="COLOR" Margin="0 10 0 0" HeaderFontSize="{StaticResource FSE_SmallFontSize}">
+ <Viewbox>
+ <colorPicker:ColorCanvas Background="Transparent" BorderThickness="0" FontSize="{StaticResource FSE_SmallerFontSize}" SelectedColor="{Binding Color,Mode=TwoWay}" />
+ </Viewbox>
+ </controls:FSEGroupBox>
+ </StackPanel>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidgetSettingsView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidgetSettingsView.xaml.cs
new file mode 100644
index 000000000..34cf21cc3
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidgetSettingsView.xaml.cs
@@ -0,0 +1,28 @@
+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.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;
+
+namespace Tango.FSE.Diagnostics.Project.Widgets.Text
+{
+ /// <summary>
+ /// Interaction logic for TextWidgetSettingsView.xaml
+ /// </summary>
+ public partial class TextWidgetSettingsView : UserControl
+ {
+ public TextWidgetSettingsView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidgetView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidgetView.xaml
new file mode 100644
index 000000000..cf034f28b
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidgetView.xaml
@@ -0,0 +1,18 @@
+<UserControl x:Class="Tango.FSE.Diagnostics.Project.Widgets.Text.TextWidgetView"
+ 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:local="clr-namespace:Tango.FSE.Diagnostics.Project.Widgets.Text"
+ mc:Ignorable="d"
+ d:DesignHeight="100" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=local:TextWidget,IsDesignTimeCreatable=False}">
+ <Grid>
+ <Viewbox Stretch="Uniform">
+ <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Text}" FontSize="16">
+ <TextBlock.Foreground>
+ <SolidColorBrush Color="{Binding Color}" />
+ </TextBlock.Foreground>
+ </TextBlock>
+ </Viewbox>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidgetView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidgetView.xaml.cs
new file mode 100644
index 000000000..cd354d7fc
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Text/TextWidgetView.xaml.cs
@@ -0,0 +1,28 @@
+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.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;
+
+namespace Tango.FSE.Diagnostics.Project.Widgets.Text
+{
+ /// <summary>
+ /// Interaction logic for TextWidgetView.xaml
+ /// </summary>
+ public partial class TextWidgetView : UserControl
+ {
+ public TextWidgetView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Valve/Images/valve.png b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Valve/Images/valve.png
new file mode 100644
index 000000000..5c08d0fc5
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Valve/Images/valve.png
Binary files differ
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Valve/ValveWidget.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Valve/ValveWidget.cs
new file mode 100644
index 000000000..89f2b04e5
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Valve/ValveWidget.cs
@@ -0,0 +1,150 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using Tango.BL.Entities;
+using Tango.BL.Enumerations;
+using Tango.Core.Commands;
+using Tango.FSE.Common.Notifications;
+using Tango.PMR.Diagnostics;
+
+namespace Tango.FSE.Diagnostics.Project.Widgets.Valve
+{
+ [Description("Valve Controller")]
+ public class ValveWidget : DiagnosticsWidget, ISupportsComponentSelection<TechValves>
+ {
+ public TechValves Valve { get; set; }
+
+ private TechValve _techValve;
+ [JsonIgnore]
+ public TechValve TechValve
+ {
+ get { return _techValve; }
+ set { _techValve = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(DisplayName)); }
+ }
+
+ [JsonIgnore]
+ public override string DisplayName
+ {
+ get
+ {
+ return this.TechValve != null ? this.TechValve.Description : String.Empty;
+ }
+ }
+
+ private ValveStateCode _state;
+ [JsonIgnore]
+ public ValveStateCode State
+ {
+ get { return _state; }
+ set { _state = value; RaisePropertyChangedAuto(); }
+ }
+
+ private ValveStateCode _effectiveState;
+ [JsonIgnore]
+ public ValveStateCode EffectiveState
+ {
+ get { return _effectiveState; }
+ set
+ {
+ if (_effectiveState != value)
+ {
+ _effectiveState = value;
+ RaisePropertyChangedAuto();
+ _state = value;
+ RaisePropertyChanged(nameof(State));
+ }
+ }
+ }
+
+ [JsonIgnore]
+ public RelayCommand<String> SetCommand { get; set; }
+
+ public ValveWidget()
+ {
+ SetCommand = new RelayCommand<string>(CommitState);
+ }
+
+ private async void CommitState(string command)
+ {
+ try
+ {
+ State = (ValveStateCode)Enum.Parse(typeof(ValveStateCode), command.Replace(" ", ""), true);
+
+ if (MachineProvider.IsConnected)
+ {
+ await MachineProvider.MachineOperator.SetValveState((ValveType)Valve, State);
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error setting valve state.");
+ NotificationProvider.PushSnackbarItem(MessageType.Error, "Valve Controller Error", true, ex.Message, TimeSpan.FromSeconds(5));
+ }
+ }
+
+ public override async Task Init()
+ {
+ int valve = (int)Valve;
+ TechValve = await Services.TechComponentsService.Valves.FindOne(x => x.Code == valve);
+
+ if (TechValve != null)
+ {
+ State = (ValveStateCode)Enum.Parse(typeof(ValveStateCode), TechValve.State1.Replace(" ", ""), true);
+ }
+ }
+
+ public override void OnDiagnosticsData(DiagnosticsPackage package)
+ {
+ var valveState = package.GetValveState(Valve);
+
+ if (valveState != null)
+ {
+ EffectiveState = valveState.State;
+ }
+ }
+
+ public override FrameworkElement GetView()
+ {
+ return new ValveWidgetView();
+ }
+
+ #region Component Selection
+
+ public List<DiagnosticsWidgetComponent<TechValves>> Components
+ {
+ get
+ {
+ return Services.TechComponentsService.Valves.FindAll().Result.Select(x => new DiagnosticsWidgetComponent<TechValves>()
+ {
+ DisplayName = x.Description,
+ Object = (TechValves)x.Code,
+ }).OrderByAlphaNumeric(x => x.DisplayName).ToList();
+ }
+ }
+
+ public TechValves SelectedComponent
+ {
+ get
+ {
+ return Valve;
+ }
+ set
+ {
+ if (Valve != value)
+ {
+ Valve = value;
+ InitAsync();
+ }
+ }
+ }
+
+ public bool EnableComponentSelection { get; set; }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Valve/ValveWidgetView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Valve/ValveWidgetView.xaml
new file mode 100644
index 000000000..0ef9acbbe
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Valve/ValveWidgetView.xaml
@@ -0,0 +1,111 @@
+<UserControl x:Class="Tango.FSE.Diagnostics.Project.Widgets.Valve.ValveWidgetView"
+ 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:local="clr-namespace:Tango.FSE.Diagnostics.Project.Widgets.Valve"
+ xmlns:localConverters="clr-namespace:Tango.FSE.Diagnostics.Converters"
+ mc:Ignorable="d"
+ d:DesignHeight="250" d:DesignWidth="400" d:DataContext="{d:DesignInstance Type=local:ValveWidget,IsDesignTimeCreatable=False}">
+
+ <UserControl.Resources>
+ <localConverters:ValveStateComparerToBooleanConverter x:Key="ValveStateComparerToBooleanConverter" />
+ </UserControl.Resources>
+
+ <Grid>
+ <Viewbox Stretch="Uniform">
+ <Border Width="352" Height="101" Background="{StaticResource FSE_PrimaryBackgroundDarkBrush}" CornerRadius="5" BorderThickness="1" BorderBrush="#434343" Padding="5">
+ <Grid>
+ <Grid Grid.Row="1">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="27*"/>
+ <ColumnDefinition Width="30*"/>
+ <ColumnDefinition Width="27*"/>
+ </Grid.ColumnDefinitions>
+
+ <Button Margin="8" Cursor="Hand" Command="{Binding SetCommand}" CommandParameter="{Binding TechValve.State1}">
+ <Button.Style>
+ <Style TargetType="Button">
+ <Setter Property="Background" Value="#3E3E3E"></Setter>
+ <Setter Property="IsEnabled" Value="True"></Setter>
+ </Style>
+ </Button.Style>
+ <Button.Template>
+ <ControlTemplate TargetType="Button">
+ <Border Background="{TemplateBinding Background}" CornerRadius="5">
+ <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="Gainsboro" FontSize="16" FontWeight="SemiBold" Text="{Binding TechValve.State1}"></TextBlock>
+ </Border>
+ <ControlTemplate.Triggers>
+ <Trigger Property="IsPressed" Value="True">
+ <Setter Property="Opacity" Value="0.7"></Setter>
+ </Trigger>
+ <DataTrigger>
+ <DataTrigger.Binding>
+ <MultiBinding Converter="{StaticResource ValveStateComparerToBooleanConverter}">
+ <Binding Path="State" />
+ <Binding Path="TechValve.State1" />
+ </MultiBinding>
+ </DataTrigger.Binding>
+ <DataTrigger.Value>
+ True
+ </DataTrigger.Value>
+
+ <DataTrigger.Setters>
+ <Setter Property="Background" Value="#4AAB2F"></Setter>
+ <Setter Property="IsEnabled" Value="False"></Setter>
+ </DataTrigger.Setters>
+ </DataTrigger>
+ </ControlTemplate.Triggers>
+ </ControlTemplate>
+ </Button.Template>
+ </Button>
+
+ <Border Background="{StaticResource FSE_PrimaryBackgroundBrush}" Margin="8" CornerRadius="3" Padding="5" Grid.Column="1">
+ <StackPanel>
+ <TextBlock FontFamily="{StaticResource digital-7}" Text="Valve Controller" FontSize="13" Foreground="#E94A4A" HorizontalAlignment="Center"></TextBlock>
+ <Image Source="../Valve/Images/valve.png" RenderOptions.BitmapScalingMode="Fant" Margin="10" Stretch="Uniform" Height="36" />
+ </StackPanel>
+ </Border>
+
+ <Button Margin="8" Cursor="Hand" Grid.Column="2" Command="{Binding SetCommand}" CommandParameter="{Binding TechValve.State2}">
+ <Button.Style>
+ <Style TargetType="Button">
+ <Setter Property="Background" Value="#3E3E3E"></Setter>
+ <Setter Property="IsEnabled" Value="True"></Setter>
+ </Style>
+ </Button.Style>
+ <Button.Template>
+ <ControlTemplate TargetType="Button">
+ <Border Background="{TemplateBinding Background}" CornerRadius="5">
+ <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="Gainsboro" FontSize="16" FontWeight="SemiBold" Text="{Binding TechValve.State2}"></TextBlock>
+ </Border>
+ <ControlTemplate.Triggers>
+ <Trigger Property="IsPressed" Value="True">
+ <Setter Property="Opacity" Value="0.7"></Setter>
+ </Trigger>
+ <DataTrigger>
+ <DataTrigger.Binding>
+ <MultiBinding Converter="{StaticResource ValveStateComparerToBooleanConverter}">
+ <Binding Path="State" />
+ <Binding Path="TechValve.State2" />
+ </MultiBinding>
+ </DataTrigger.Binding>
+ <DataTrigger.Value>
+ True
+ </DataTrigger.Value>
+
+ <DataTrigger.Setters>
+ <Setter Property="Background" Value="#4AAB2F"></Setter>
+ <Setter Property="IsEnabled" Value="False"></Setter>
+ </DataTrigger.Setters>
+ </DataTrigger>
+ </ControlTemplate.Triggers>
+ </ControlTemplate>
+ </Button.Template>
+ </Button>
+ </Grid>
+ </Grid>
+ </Border>
+ </Viewbox>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Valve/ValveWidgetView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Valve/ValveWidgetView.xaml.cs
new file mode 100644
index 000000000..cdaf5a324
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Project/Widgets/Valve/ValveWidgetView.xaml.cs
@@ -0,0 +1,28 @@
+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.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;
+
+namespace Tango.FSE.Diagnostics.Project.Widgets.Valve
+{
+ /// <summary>
+ /// Interaction logic for ValveWidgetView.xaml
+ /// </summary>
+ public partial class ValveWidgetView : UserControl
+ {
+ public ValveWidgetView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Tango.FSE.Diagnostics.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Tango.FSE.Diagnostics.csproj
index 2b3699858..a61ddbd2d 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Tango.FSE.Diagnostics.csproj
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Tango.FSE.Diagnostics.csproj
@@ -63,6 +63,15 @@
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
+ <Reference Include="System.Reactive.Core, Version=3.0.3000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\System.Reactive.Core.3.1.1\lib\net46\System.Reactive.Core.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Reactive.Interfaces, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\System.Reactive.Interfaces.3.1.1\lib\net45\System.Reactive.Interfaces.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Reactive.Linq, Version=3.0.3000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\System.Reactive.Linq.3.1.1\lib\net46\System.Reactive.Linq.dll</HintPath>
+ </Reference>
<Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\ControlzEx.3.0.2.4\lib\net45\System.Windows.Interactivity.dll</HintPath>
</Reference>
@@ -81,18 +90,45 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Controls\DiagnosticsGrid.cs" />
+ <Compile Include="Controls\DiagnosticsGridLinesEditor.xaml.cs">
+ <DependentUpon>DiagnosticsGridLinesEditor.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Controls\DiagnosticsSelectionGrid.cs" />
<Compile Include="Converters\DecimalPlacesToStringFormatConverter.cs" />
<Compile Include="Converters\DiagnosticsWidgetToSettingsViewConverter.cs" />
<Compile Include="Converters\DiagnosticsWidgetToViewConverter.cs" />
<Compile Include="Converters\PercentageToWidthConverter.cs" />
+ <Compile Include="Converters\ValveStateComparerToBooleanConverter.cs" />
<Compile Include="DiagnosticsPackage.cs" />
+ <Compile Include="DiagnosticsSettings.cs" />
<Compile Include="Project\DiagnosticsConfigurableWidget.cs" />
<Compile Include="Project\DiagnosticsProject.cs" />
<Compile Include="Project\DiagnosticsProjectTab.cs" />
<Compile Include="Project\DiagnosticsProjectTabColumnDefinition.cs" />
<Compile Include="Project\DiagnosticsProjectTabRowDefinition.cs" />
+ <Compile Include="Project\DiagnosticsUserSettingsCollection.cs" />
+ <Compile Include="Project\DiagnosticsUserSettingsManager.cs" />
+ <Compile Include="Project\DiagnosticsUserWidgetSettings.cs" />
<Compile Include="Project\DiagnosticsWidget.cs" />
+ <Compile Include="Project\DiagnosticsWidgetComponent.cs" />
<Compile Include="Project\DiagnosticsWidgetSettings.cs" />
+ <Compile Include="Project\ISupportsComponentSelection.cs" />
+ <Compile Include="Project\Widgets\Dispenser\DispenserWidget.cs" />
+ <Compile Include="Project\Widgets\Dispenser\DispenserWidgetSettings.cs" />
+ <Compile Include="Project\Widgets\Dispenser\DispenserWidgetSettingsView.xaml.cs">
+ <DependentUpon>DispenserWidgetSettingsView.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Project\Widgets\Dispenser\DispenserWidgetView.xaml.cs">
+ <DependentUpon>DispenserWidgetView.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Project\Widgets\Heater\HeaterWidget.cs" />
+ <Compile Include="Project\Widgets\Heater\HeaterWidgetView.xaml.cs">
+ <DependentUpon>HeaterWidgetView.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Project\Widgets\Input\InputWidget.cs" />
+ <Compile Include="Project\Widgets\Input\InputWidgetView.xaml.cs">
+ <DependentUpon>InputWidgetView.xaml</DependentUpon>
+ </Compile>
<Compile Include="Project\Widgets\Monitor\MonitorWidget.cs" />
<Compile Include="Project\Widgets\Monitor\MonitorWidgetSettings.cs" />
<Compile Include="Project\Widgets\Monitor\MonitorWidgetSettingsView.xaml.cs">
@@ -101,6 +137,15 @@
<Compile Include="Project\Widgets\Monitor\MonitorWidgetView.xaml.cs">
<DependentUpon>MonitorWidgetView.xaml</DependentUpon>
</Compile>
+ <Compile Include="Project\Widgets\Motor\MotorWidget.cs" />
+ <Compile Include="Project\Widgets\Motor\MotorWidgetSettings.cs" />
+ <Compile Include="Project\Widgets\Motor\MotorWidgetSettingsView.xaml.cs">
+ <DependentUpon>MotorWidgetSettingsView.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Project\Widgets\Motor\MotorWidgetState.cs" />
+ <Compile Include="Project\Widgets\Motor\MotorWidgetView.xaml.cs">
+ <DependentUpon>MotorWidgetView.xaml</DependentUpon>
+ </Compile>
<Compile Include="Project\Widgets\RealTimeGraphMultiChannel\RealTimeGraphMultiChannelWidget.cs" />
<Compile Include="Project\Widgets\RealTimeGraphMultiChannel\RealTimeGraphMultiChannelWidgetSettingsView.xaml.cs">
<DependentUpon>RealTimeGraphMultiChannelWidgetSettingsView.xaml</DependentUpon>
@@ -118,6 +163,18 @@
<Compile Include="Project\Widgets\RealTimeGraph\RealTimeGraphWidgetView.xaml.cs">
<DependentUpon>RealTimeGraphWidgetView.xaml</DependentUpon>
</Compile>
+ <Compile Include="Project\Widgets\Text\TextWidget.cs" />
+ <Compile Include="Project\Widgets\Text\TextWidgetSettings.cs" />
+ <Compile Include="Project\Widgets\Text\TextWidgetSettingsView.xaml.cs">
+ <DependentUpon>TextWidgetSettingsView.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Project\Widgets\Text\TextWidgetView.xaml.cs">
+ <DependentUpon>TextWidgetView.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Project\Widgets\Valve\ValveWidget.cs" />
+ <Compile Include="Project\Widgets\Valve\ValveWidgetView.xaml.cs">
+ <DependentUpon>ValveWidgetView.xaml</DependentUpon>
+ </Compile>
<Compile Include="ViewModelLocator.cs" />
<Compile Include="DiagnosticsModule.cs" />
<Compile Include="ViewModels\DiagnosticsTabViewVM.cs" />
@@ -155,7 +212,7 @@
<SubType>Designer</SubType>
</None>
<None Include="diagnostics.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
@@ -212,6 +269,10 @@
<Project>{74e700b0-1156-4126-be40-ee450d3c3026}</Project>
<Name>Tango.Transport</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\..\Tango.Visuals\Tango.Visuals.csproj">
+ <Project>{cf7c0ff4-9440-42cf-83b8-c060772792d4}</Project>
+ <Name>Tango.Visuals</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Tango.FSE.BL\Tango.FSE.BL.csproj">
<Project>{834c81c3-09b5-45d7-be12-e7d1e6655a7c}</Project>
<Name>Tango.FSE.BL</Name>
@@ -226,6 +287,26 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
+ <Page Include="Controls\DiagnosticsGridLinesEditor.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="Project\Widgets\Dispenser\DispenserWidgetSettingsView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="Project\Widgets\Dispenser\DispenserWidgetView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="Project\Widgets\Heater\HeaterWidgetView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="Project\Widgets\Input\InputWidgetView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="Project\Widgets\Monitor\MonitorWidgetSettingsView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -234,6 +315,14 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
+ <Page Include="Project\Widgets\Motor\MotorWidgetSettingsView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="Project\Widgets\Motor\MotorWidgetView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="Project\Widgets\RealTimeGraphMultiChannel\RealTimeGraphMultiChannelWidgetView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@@ -250,6 +339,18 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
+ <Page Include="Project\Widgets\Text\TextWidgetSettingsView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="Project\Widgets\Text\TextWidgetView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="Project\Widgets\Valve\ValveWidgetView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="Themes\Generic.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -273,6 +374,15 @@
<ItemGroup>
<Resource Include="Project\Widgets\Monitor\Images\tft_screen.png" />
</ItemGroup>
+ <ItemGroup>
+ <Resource Include="Project\Widgets\Valve\Images\valve.png" />
+ </ItemGroup>
+ <ItemGroup>
+ <Resource Include="Project\Widgets\Dispenser\Images\dispenser_line.png" />
+ </ItemGroup>
+ <ItemGroup>
+ <Resource Include="Project\Widgets\Heater\Images\temperature.png" />
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\..\packages\MaterialDesignThemes.3.0.1\build\MaterialDesignThemes.targets" Condition="Exists('..\..\..\packages\MaterialDesignThemes.3.0.1\build\MaterialDesignThemes.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Themes/Generic.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Themes/Generic.xaml
index 2428e9255..ebc71072a 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Themes/Generic.xaml
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Themes/Generic.xaml
@@ -3,29 +3,44 @@
xmlns:graphs="clr-namespace:Tango.FSE.Common.Graphs;assembly=Tango.FSE.Common"
xmlns:localConverters="clr-namespace:Tango.FSE.Diagnostics.Converters"
xmlns:realTimeGraphX="clr-namespace:RealTimeGraphX.WPF;assembly=RealTimeGraphX.WPF"
+ xmlns:commonControls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common"
+ xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:local="clr-namespace:Tango.FSE.Diagnostics.Themes">
<localConverters:DecimalPlacesToStringFormatConverter x:Key="DecimalPlacesToStringFormatConverter" />
<Style TargetType="{x:Type graphs:RealTimeGraph}" x:Key="FSE_RealTimeGraph_Diagnostics">
<Setter Property="BorderThickness" Value="1"></Setter>
- <Setter Property="BorderBrush" Value="{StaticResource FSE_RealTimeGraph_OuterBorderBrush}"></Setter>
- <Setter Property="Padding" Value="20 20 30 20"></Setter>
+ <Setter Property="BorderBrush" Value="{StaticResource FSE_PrimaryBackgroundLightBrush}"></Setter>
+ <Setter Property="Padding" Value="20"></Setter>
<Setter Property="FontSize" Value="11"></Setter>
- <Setter Property="Foreground" Value="{StaticResource FSE_RealTimeGraph_ForegroundBrush}"></Setter>
- <Setter Property="Background" Value="{StaticResource FSE_RealTimeGraph_BackgroundBrush}"></Setter>
- <Setter Property="GridLinesBrush" Value="{StaticResource FSE_RealTimeGraph_GridLinesBrush}"></Setter>
+ <Setter Property="Foreground" Value="{StaticResource FSE_GrayBrush}"></Setter>
+ <Setter Property="Background">
+ <Setter.Value>
+ <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0" >
+ <GradientStop Color="#252525"/>
+ <GradientStop Color="#303030" Offset="1"/>
+ </LinearGradientBrush>
+ </Setter.Value>
+ </Setter>
+ <Setter Property="GridLinesBrush" Value="#282828"></Setter>
<Setter Property="HorizontalTicks" Value="7"></Setter>
<Setter Property="VerticalTicks" Value="5"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type graphs:RealTimeGraph}">
<Grid>
- <Border Background="{TemplateBinding Background}"
+ <Border
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="5"
Padding="{TemplateBinding Padding}">
+ <Border.Background>
+ <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0" >
+ <GradientStop Color="#252525"/>
+ <GradientStop Color="#303030" Offset="1"/>
+ </LinearGradientBrush>
+ </Border.Background>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
@@ -37,12 +52,12 @@
</Grid.ColumnDefinitions>
<Grid Grid.Column="1">
- <realTimeGraphX:WpfGraphGridLines Columns="{TemplateBinding HorizontalTicks}" Rows="{TemplateBinding VerticalTicks}" Controller="{TemplateBinding Controller}" Foreground="{TemplateBinding GridLinesBrush}" />
- <realTimeGraphX:WpfGraphSurface x:Name="surface" Controller="{TemplateBinding Controller}" BorderThickness="1 0 0 1" BorderBrush="{StaticResource FSE_RealTimeGraph_InnerBorderBrush}" />
+ <realTimeGraphX:WpfGraphSurface x:Name="surface" Background="{StaticResource FSE_PrimaryBackgroundDarkBrush}" Controller="{TemplateBinding Controller}" BorderThickness="1" BorderBrush="{TemplateBinding BorderBrush}" />
+ <realTimeGraphX:WpfGraphGridLines Columns="{TemplateBinding HorizontalTicks}" Rows="{TemplateBinding VerticalTicks}" Controller="{TemplateBinding Controller}" Foreground="{TemplateBinding GridLinesBrush}" Margin="1 0 0 1" />
</Grid>
- <realTimeGraphX:WpfGraphAxisControl Width="70" Visibility="{TemplateBinding VerticalAxisVisibility}" Orientation="Vertical" Controller="{TemplateBinding Controller}" StringFormat="{TemplateBinding StringFormat}" Ticks="{TemplateBinding VerticalTicks}" />
- <realTimeGraphX:WpfGraphAxisControl Height="35" Visibility="{TemplateBinding HorizontalAxisVisibility}" Orientation="Horizontal" Controller="{TemplateBinding Controller}" Grid.Column="1" Grid.Row="1" Ticks="{TemplateBinding HorizontalTicks}" StringFormat="hh\:mm\:ss"/>
+ <realTimeGraphX:WpfGraphAxisControl Width="50" Visibility="{TemplateBinding VerticalAxisVisibility}" Orientation="Vertical" Controller="{TemplateBinding Controller}" StringFormat="{TemplateBinding StringFormat}" Ticks="{TemplateBinding VerticalTicks}" />
+ <realTimeGraphX:WpfGraphAxisControl Height="30" Visibility="{TemplateBinding HorizontalAxisVisibility}" Orientation="Horizontal" Controller="{TemplateBinding Controller}" Grid.Column="1" Grid.Row="1" Ticks="{TemplateBinding HorizontalTicks}" StringFormat="hh\:mm\:ss"/>
</Grid>
</Border>
<Image HorizontalAlignment="Left" VerticalAlignment="Top" Margin="8" Source="{StaticResource FSE_Screw}" RenderOptions.BitmapScalingMode="Fant" Width="10" Height="10" />
@@ -56,5 +71,118 @@
</Setter>
</Style>
-
+ <Color x:Key="FSE_Widget_Gradient_Dark_Color">#232323</Color>
+ <Color x:Key="FSE_Widget_Gradient_Mid_Color">#FF333333</Color>
+ <Color x:Key="FSE_Widget_Gradient_Light_Color">#FF646464</Color>
+
+ <Style x:Key="FSE_WidgetIconButton_Red" TargetType="{x:Type commonControls:IconButton}" BasedOn="{StaticResource FSE_IconButton_Flat_Pressed_Highlight}">
+ <Style.Triggers>
+ <Trigger Property="IsPressed" Value="True">
+ <Setter Property="Foreground" Value="{StaticResource FSE_RedBrush}"></Setter>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+
+ <Style x:Key="FSE_MotorWidgetButton" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
+ <Setter Property="Padding" Value="0"></Setter>
+ <Setter Property="Width" Value="Auto"></Setter>
+ <Setter Property="Height" Value="Auto"></Setter>
+ <Setter Property="material:RippleAssist.IsDisabled" Value="True"></Setter>
+ <Setter Property="BorderBrush" Value="{StaticResource FSE_BorderBrush}"></Setter>
+ <Setter Property="Foreground" Value="{StaticResource FSE_PrimaryForegroundBrush}"></Setter>
+ <Setter Property="Opacity" Value="1"></Setter>
+ <Setter Property="Background">
+ <Setter.Value>
+ <LinearGradientBrush EndPoint="1,0">
+ <GradientStop Color="{StaticResource FSE_Widget_Gradient_Light_Color}" Offset="0" />
+ <GradientStop Color="{StaticResource FSE_Widget_Gradient_Dark_Color}" Offset="1"/>
+ </LinearGradientBrush>
+ </Setter.Value>
+ </Setter>
+ <Style.Triggers>
+ <EventTrigger RoutedEvent="PreviewMouseDown">
+ <EventTrigger.Actions>
+ <BeginStoryboard>
+ <Storyboard>
+ <ColorAnimation Storyboard.TargetProperty="Background.GradientStops[0].Color" To="{StaticResource FSE_Widget_Gradient_Mid_Color}" Duration="00:00:0.1" />
+ </Storyboard>
+ </BeginStoryboard>
+ </EventTrigger.Actions>
+ </EventTrigger>
+ <EventTrigger RoutedEvent="PreviewMouseUp">
+ <EventTrigger.Actions>
+ <BeginStoryboard>
+ <Storyboard>
+ <ColorAnimation Storyboard.TargetProperty="Background.GradientStops[0].Color" To="{StaticResource FSE_Widget_Gradient_Light_Color}" Duration="00:00:0.1" />
+ </Storyboard>
+ </BeginStoryboard>
+ </EventTrigger.Actions>
+ </EventTrigger>
+ <Trigger Property="IsMouseOver" Value="True">
+ <Setter Property="Foreground" Value="{StaticResource FSE_GrayBrush}"></Setter>
+ </Trigger>
+ <Trigger Property="IsPressed" Value="True">
+ <Setter Property="Foreground" Value="{StaticResource FSE_RedBrush}"></Setter>
+ </Trigger>
+ <Trigger Property="IsEnabled" Value="False">
+ <Setter Property="Foreground" Value="{StaticResource FSE_GrayBrush}"></Setter>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+
+ <Style x:Key="FSE_MotorWidgetButton_Left" TargetType="Button" BasedOn="{StaticResource FSE_MotorWidgetButton}">
+ <Setter Property="BorderThickness" Value="1 1 0 1"></Setter>
+ <Setter Property="material:ButtonAssist.CornerRadius" Value="10 0 0 10"></Setter>
+ <Setter Property="Background">
+ <Setter.Value>
+ <LinearGradientBrush EndPoint="1,0">
+ <GradientStop Color="{StaticResource FSE_Widget_Gradient_Light_Color}" Offset="1" />
+ <GradientStop Color="{StaticResource FSE_Widget_Gradient_Dark_Color}" Offset="0"/>
+ </LinearGradientBrush>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Style x:Key="FSE_MotorWidgetButton_Right" TargetType="Button" BasedOn="{StaticResource FSE_MotorWidgetButton}">
+ <Setter Property="BorderThickness" Value="0 1 1 1"></Setter>
+ <Setter Property="material:ButtonAssist.CornerRadius" Value="0 10 10 0"></Setter>
+ <Setter Property="Background">
+ <Setter.Value>
+ <LinearGradientBrush EndPoint="1,0">
+ <GradientStop Color="{StaticResource FSE_Widget_Gradient_Light_Color}" Offset="0" />
+ <GradientStop Color="{StaticResource FSE_Widget_Gradient_Dark_Color}" Offset="1"/>
+ </LinearGradientBrush>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Style x:Key="FSE_MotorWidgetButton_Center" TargetType="Button" BasedOn="{StaticResource FSE_MotorWidgetButton}">
+ <Setter Property="BorderThickness" Value="1 0 1 1"></Setter>
+ <Setter Property="material:ButtonAssist.CornerRadius" Value="0 0 20 20"></Setter>
+ <Setter Property="Background">
+ <Setter.Value>
+ <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
+ <GradientStop Color="{StaticResource FSE_Widget_Gradient_Light_Color}" Offset="0" />
+ <GradientStop Color="{StaticResource FSE_Widget_Gradient_Dark_Color}" Offset="1"/>
+ </LinearGradientBrush>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Style x:Key="FSE_MotorWidgetBorder_Center" TargetType="Border">
+ <Setter Property="Padding" Value="0"></Setter>
+ <Setter Property="Width" Value="Auto"></Setter>
+ <Setter Property="Height" Value="Auto"></Setter>
+ <Setter Property="BorderBrush" Value="{StaticResource FSE_BorderBrush}"></Setter>
+ <Setter Property="BorderThickness" Value="1 0 1 1"></Setter>
+ <Setter Property="CornerRadius" Value="0 0 20 20"></Setter>
+ <Setter Property="Background">
+ <Setter.Value>
+ <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
+ <GradientStop Color="{StaticResource FSE_Widget_Gradient_Dark_Color}" Offset="1" />
+ <GradientStop Color="{StaticResource FSE_Widget_Gradient_Light_Color}" Offset="0"/>
+ </LinearGradientBrush>
+ </Setter.Value>
+ </Setter>
+ </Style>
</ResourceDictionary> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModels/DiagnosticsTabViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModels/DiagnosticsTabViewVM.cs
index acea47b10..0acfa2a4f 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModels/DiagnosticsTabViewVM.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModels/DiagnosticsTabViewVM.cs
@@ -3,20 +3,24 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using System.Windows;
using Tango.Core.Commands;
+using Tango.Core.DI;
using Tango.FSE.Common;
+using Tango.FSE.Common.Authentication;
using Tango.FSE.Diagnostics.Project;
using Tango.PMR.Diagnostics;
+using Tango.Settings;
namespace Tango.FSE.Diagnostics.ViewModels
{
- public class DiagnosticsTabViewVM : FSEViewModel
+ public class DiagnosticsTabViewVM : FSEViewModelWithModuleSettings<DiagnosticsSettings>
{
private DiagnosticsProjectTab _tab;
public DiagnosticsProjectTab Tab
{
get { return _tab; }
- set { _tab = value; RaisePropertyChangedAuto(); }
+ set { _tab = value; RaisePropertyChangedAuto(); OnTabChanged(); }
}
private bool _isSelected;
@@ -40,6 +44,20 @@ namespace Tango.FSE.Diagnostics.ViewModels
set { _isWidgetSettingsOpened = value; RaisePropertyChangedAuto(); }
}
+ private bool _editMode;
+ public bool EditMode
+ {
+ get { return _editMode; }
+ set { _editMode = value; RaisePropertyChangedAuto(); Tab.Widgets.ToList().ForEach(x => x.EditMode = value); }
+ }
+
+ private bool _showGridLines;
+ public bool ShowGridLines
+ {
+ get { return _showGridLines; }
+ set { _showGridLines = value; RaisePropertyChangedAuto(); }
+ }
+
public RelayCommand<DiagnosticsWidget> OpenWidgetSettingsCommand { get; set; }
public RelayCommand CloseWidgetSettingsCommand { get; set; }
@@ -47,7 +65,7 @@ namespace Tango.FSE.Diagnostics.ViewModels
public DiagnosticsTabViewVM()
{
OpenWidgetSettingsCommand = new RelayCommand<DiagnosticsWidget>(OpenWidgetSettings);
- CloseWidgetSettingsCommand = new RelayCommand(() => IsWidgetSettingsOpened = false);
+ CloseWidgetSettingsCommand = new RelayCommand(() => { IsWidgetSettingsOpened = false; SelectedWidget = null; });
}
private void OpenWidgetSettings(DiagnosticsWidget widget)
@@ -67,5 +85,18 @@ namespace Tango.FSE.Diagnostics.ViewModels
widget.OnDiagnosticsData(package);
}
}
+
+ private void OnTabChanged()
+ {
+ if (Tab != null)
+ {
+ Tab.Widgets.CollectionChanged += Widgets_CollectionChanged;
+ }
+ }
+
+ private void Widgets_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
+ {
+ Tab.Widgets.ToList().ForEach(x => x.EditMode = EditMode);
+ }
}
}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModels/DiagnosticsViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModels/DiagnosticsViewVM.cs
index 75c623c62..17b9391c9 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModels/DiagnosticsViewVM.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModels/DiagnosticsViewVM.cs
@@ -1,14 +1,19 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
+using System.Windows;
+using Tango.BL.Entities;
+using Tango.BL.Enumerations;
using Tango.Core.Commands;
using Tango.FSE.Common;
using Tango.FSE.Common.Diagnostics;
+using Tango.FSE.Common.Notifications;
using Tango.FSE.Diagnostics.Project;
using Tango.PMR.Diagnostics;
@@ -16,10 +21,24 @@ namespace Tango.FSE.Diagnostics.ViewModels
{
public class DiagnosticsViewVM : FSEViewModel
{
- private Dictionary<String, PropertyInfo> _monitorsProperties;
+ public class WidgetType
+ {
+ public String Name { get; set; }
+ public Type Type { get; set; }
+
+ public override string ToString()
+ {
+ return Name;
+ }
+ }
+
private bool _isLoaded;
- private string _diagnosticsProjectFile;
+ private string _factoryPojectFile;
+ private string _customProjectFile;
private FileSystemWatcher _diagnosticsProjectFileWatcher;
+ private List<DiagnosticsWidget> _copiedWidget;
+
+ #region Properties
private bool _isLoadingProject;
public bool IsLoadingProject
@@ -49,23 +68,265 @@ namespace Tango.FSE.Diagnostics.ViewModels
set { _selectedTab = value; RaisePropertyChangedAuto(); OnSelectedTabChanged(); }
}
- public RelayCommand ExportProjectCommand { get; set; }
+ public List<WidgetType> AvailableWidgetTypes { get; set; }
- public DiagnosticsViewVM()
+ private WidgetType _selectedWidgetType;
+ public WidgetType SelectedWidgetType
+ {
+ get { return _selectedWidgetType; }
+ set { _selectedWidgetType = value; RaisePropertyChangedAuto(); }
+ }
+
+ private bool _editMode;
+ public bool EditMode
+ {
+ get { return _editMode; }
+ set { _editMode = value; RaisePropertyChangedAuto(); OnEditModeChanged(); }
+ }
+
+ private bool _creationMode;
+ public bool CreationMode
+ {
+ get { return _creationMode; }
+ set { _creationMode = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(NotInCreationOrPasteMode)); InvalidateRelayCommands(); }
+ }
+
+ private bool _pasteMode;
+ public bool PasteMode
{
- _monitorsProperties = new Dictionary<string, PropertyInfo>();
+ get { return _pasteMode; }
+ set { _pasteMode = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(NotInCreationOrPasteMode)); InvalidateRelayCommands(); }
+ }
- foreach (var prop in typeof(DiagnosticsMonitors).GetProperties(BindingFlags.Public | BindingFlags.Instance).ToList())
+ public bool NotInCreationOrPasteMode
+ {
+ get { return !CreationMode && !PasteMode; }
+ }
+
+ private bool _showGridLines;
+ public bool ShowGridLines
+ {
+ get { return _showGridLines; }
+ set
{
- _monitorsProperties.Add(prop.Name, prop);
+ _showGridLines = value;
+ RaisePropertyChangedAuto();
+ Tabs.ToList().ForEach(x => x.ShowGridLines = value);
}
+ }
+
+ #endregion
+
+ #region Commands
+
+ public RelayCommand NewProjectCommand { get; set; }
+ public RelayCommand OpenProjectCommand { get; set; }
+ public RelayCommand SaveProjectCommand { get; set; }
+ public RelayCommand SaveAsProjectCommand { get; set; }
+ public RelayCommand CutSelectedWidgetsCommand { get; set; }
+ public RelayCommand CopySelectedWidgetsCommand { get; set; }
+ public RelayCommand PasteWidgetsCommand { get; set; }
+ public RelayCommand DeleteSelectedWidgetsCommand { get; set; }
+ public RelayCommand AddNewTabCommand { get; set; }
+ public RelayCommand<DiagnosticsTabViewVM> RemoveTabCommand { get; set; }
+ public RelayCommand<WidgetType> AddWidgetCommand { get; set; }
+ public RelayCommand<Rect> SelectionCommand { get; set; }
+ public RelayCommand AbortCreationCommand { get; set; }
+ public RelayCommand DeselectWidgetsCommand { get; set; }
+ public RelayCommand ResetGridCommand { get; set; }
+ #endregion
+
+ #region Constructors
+
+ public DiagnosticsViewVM()
+ {
Tabs = new ObservableCollection<DiagnosticsTabViewVM>();
Project = new DiagnosticsProject();
+ AvailableWidgetTypes = new List<WidgetType>();
- ExportProjectCommand = new RelayCommand(ExportProject);
+ _copiedWidget = new List<DiagnosticsWidget>();
+
+ OpenProjectCommand = new RelayCommand(OpenProject, () => EditMode);
+ SaveProjectCommand = new RelayCommand(SaveProject, () => EditMode);
+ SaveAsProjectCommand = new RelayCommand(SaveAsProject, () => EditMode);
+ NewProjectCommand = new RelayCommand(CreateNewProject, () => EditMode);
+ AddNewTabCommand = new RelayCommand(AddNewTab, () => EditMode);
+ RemoveTabCommand = new RelayCommand<DiagnosticsTabViewVM>(RemoveTab, () => EditMode);
+ AddWidgetCommand = new RelayCommand<WidgetType>(StartWidgetCreation, () => EditMode && SelectedTab != null);
+ SelectionCommand = new RelayCommand<Rect>(OnWidgetCreation, () => EditMode && ((CreationMode && SelectedWidgetType != null) || PasteMode) && SelectedTab != null);
+ AbortCreationCommand = new RelayCommand(AbortWidgetCreation, () => EditMode && (CreationMode || PasteMode));
+ DeselectWidgetsCommand = new RelayCommand(DeselectAllWidgets, () => EditMode);
+ CopySelectedWidgetsCommand = new RelayCommand(CopySelectedWidgets, () => EditMode && SelectedTab != null && SelectedTab.Tab.Widgets.Any(x => x.IsSelected));
+ PasteWidgetsCommand = new RelayCommand(StartPasteWidgets, () => EditMode && !PasteMode && !CreationMode && _copiedWidget.Count > 0);
+ ResetGridCommand = new RelayCommand(ResetSelectedTabGrid, () => EditMode && SelectedTab != null);
+ DeleteSelectedWidgetsCommand = new RelayCommand(DeleteSelectedWidgets, () => EditMode && SelectedTab != null && SelectedTab.Tab.Widgets.Any(x => x.IsSelected));
+ CutSelectedWidgetsCommand = new RelayCommand(CutSelectedWidgets, () => EditMode && SelectedTab != null && SelectedTab.Tab.Widgets.Any(x => x.IsSelected));
+
+ InitAvailableWidgetTypes();
}
+ #endregion
+
+ #region Widget Management
+
+ private void InitAvailableWidgetTypes()
+ {
+ var types = this.GetType().Assembly.GetTypes().Where(x => typeof(DiagnosticsWidget).IsAssignableFrom(x) && !x.IsAbstract).ToList();
+
+ foreach (var type in types.OrderBy(x => x.Name).ToList())
+ {
+ var att = type.GetCustomAttribute<DescriptionAttribute>();
+
+ AvailableWidgetTypes.Add(new WidgetType()
+ {
+ Name = att != null ? att.Description : type.Name.Replace("Widget", ""),
+ Type = type
+ });
+ }
+ }
+
+ private void StartWidgetCreation(WidgetType widgetType)
+ {
+ if (SelectedTab == null || PasteMode) return;
+
+ DeselectAllWidgets();
+ SelectedWidgetType = widgetType;
+ CreationMode = true;
+ }
+
+ private void AbortWidgetCreation()
+ {
+ CreationMode = false;
+ PasteMode = false;
+ SelectedWidgetType = null;
+ }
+
+ private async void OnWidgetCreation(Rect rect)
+ {
+ if (CreationMode)
+ {
+ CreationMode = false;
+
+ if (SelectedTab == null || SelectedWidgetType == null) return;
+
+ DiagnosticsWidget widget = Activator.CreateInstance(SelectedWidgetType.Type) as DiagnosticsWidget;
+ widget.Column = (int)rect.X;
+ widget.Row = (int)rect.Y;
+ widget.ColumnSpan = (int)rect.Width;
+ widget.RowSpan = (int)rect.Height;
+
+ await AddWidget(SelectedTab.Tab, widget);
+
+ SelectedWidgetType = null;
+ }
+ else if (PasteMode && _copiedWidget.Count > 0)
+ {
+ PasteMode = false;
+
+ if (SelectedTab == null) return;
+
+ var startLeft = _copiedWidget.Min(x => x.Column);
+ var startTop = _copiedWidget.Min(x => x.Row);
+ var offsetX = rect.Left - startLeft;
+ var offsetY = rect.Top - startTop;
+
+ foreach (var widget in _copiedWidget.Select(x => x.Clone()).ToList())
+ {
+ widget.Column += (int)offsetX;
+ widget.Row += (int)offsetY;
+ await AddWidget(SelectedTab.Tab, widget);
+ }
+ }
+ }
+
+ private async Task AddWidget(DiagnosticsProjectTab tab, DiagnosticsWidget widget)
+ {
+ await widget.Init();
+ tab.Widgets.Add(widget);
+ }
+
+ private Rect? GetFirstAvailableTabSpace(DiagnosticsProjectTab tab, int columnSpan, int rowSpan)
+ {
+ int column = 0;
+ int row = 0;
+
+ List<Rect> board = tab.Widgets.Select(x => new Rect(x.Column, x.Row, Math.Max(x.ColumnSpan, 1), Math.Max(x.RowSpan, 1))).ToList();
+
+ bool found = false;
+
+ //Search for first available space by intersection.
+ for (int rowIndex = 0; rowIndex < tab.Rows.Count; rowIndex++)
+ {
+ for (int columnIndex = 0; columnIndex < tab.Columns.Count; columnIndex++)
+ {
+ Rect rect = new Rect(columnIndex, rowIndex, columnSpan, rowSpan);
+
+ if (board.Any(x =>
+ {
+ var intersect = Rect.Intersect(x, rect);
+ return (intersect.Width > 0 && intersect.Height > 0);
+ }))
+ {
+ continue;
+ }
+
+ column = columnIndex;
+ row = rowIndex;
+ found = true;
+ break;
+ }
+
+ if (found) break;
+ }
+
+ if (found)
+ {
+ return new Rect(column, row, columnSpan, rowSpan);
+ }
+
+ return null;
+ }
+
+ private void DisposeWidgets(IEnumerable<DiagnosticsWidget> widgets)
+ {
+ foreach (var widget in widgets.ToList())
+ {
+ try
+ {
+ widget.Dispose();
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, $"Error disposing widget {widget.DisplayName}, {widget.ID}.");
+ }
+ }
+ }
+
+ private void DeleteSelectedWidgets()
+ {
+ if (SelectedTab != null && SelectedTab.Tab.Widgets.Count(x => x.IsSelected) > 0)
+ {
+ var selectedWidgets = SelectedTab.Tab.Widgets.Where(x => x.IsSelected).ToList();
+
+ foreach (var widget in selectedWidgets)
+ {
+ SelectedTab.Tab.Widgets.Remove(widget);
+ widget.Dispose();
+ }
+ }
+ }
+
+ private void CutSelectedWidgets()
+ {
+ CopySelectedWidgets();
+ DeleteSelectedWidgets();
+ }
+
+ #endregion
+
+ #region Override Methods
+
public override void OnApplicationStarted()
{
base.OnApplicationStarted();
@@ -76,6 +337,28 @@ namespace Tango.FSE.Diagnostics.ViewModels
_diagnosticsProjectFileWatcher.EnableRaisingEvents = true;
}
+ public async override void OnApplicationReady()
+ {
+ base.OnApplicationReady();
+
+ if (!_isLoaded)
+ {
+ _factoryPojectFile = Path.Combine(ApplicationManager.StartPath, "diagnostics.json");
+ await LoadProject();
+ }
+ }
+
+ public override void OnApplicationShuttingDown()
+ {
+ base.OnApplicationShuttingDown();
+
+ SaveUserSettings();
+ }
+
+ #endregion
+
+ #region File System Watcher
+
private void _diagnosticsProjectFileWatcher_Changed(object sender, FileSystemEventArgs e)
{
InvokeUI(async () =>
@@ -97,37 +380,70 @@ namespace Tango.FSE.Diagnostics.ViewModels
});
}
+ #endregion
+
+ #region Diagnostics Frame Received
+
private void DiagnosticsProvider_FrameReceived(object sender, DiagnosticsFrameReceivedEventArgs e)
{
PopulateDiagnosticsData(e.Frame);
}
- public async override void OnApplicationReady()
+ #endregion
+
+ #region Project Management
+
+ private async void OpenProject()
{
- base.OnApplicationReady();
+ var result = await StorageProvider.OpenFile("Open diagnostics project", "Diagnostics Projects|*.json");
- if (!_isLoaded)
+ if (result.Confirmed)
{
- _diagnosticsProjectFile = Path.Combine(ApplicationManager.StartPath, "diagnostics.json");
- await LoadProject();
+ try
+ {
+ await LoadProject(result.SelectedItem, true);
+ _customProjectFile = result.SelectedItem;
+ }
+ catch (Exception ex)
+ {
+ await NotificationProvider.ShowError($"Error opening diagnostics project.\n{ex.FlattenMessage()}");
+ }
}
}
- private async Task LoadProject()
+ private Task LoadProject()
{
- Project = DiagnosticsProject.FromFile(_diagnosticsProjectFile);
+ return LoadProject(_factoryPojectFile);
+ }
+ private async Task LoadProject(String filePath, bool throwException = false)
+ {
try
{
IsLoadingProject = true;
_isLoaded = false;
+ if (Project != null)
+ {
+ DisposeWidgets(Project.FlattenWidgets());
+ }
+
+ Project = DiagnosticsProject.FromFile(filePath);
+
await Services.TechComponentsService.Preload();
foreach (var widget in Project.Tabs.SelectMany(x => x.Widgets))
{
try
{
+ if (widget is DiagnosticsConfigurableWidget)
+ {
+ await Task.Factory.StartNew(() =>
+ {
+ DiagnosticsUserSettingsManager.Default.Settings.ApplyWidgetSettings(widget as DiagnosticsConfigurableWidget);
+ });
+ }
+
await widget.Init();
}
catch (Exception ex)
@@ -149,7 +465,10 @@ namespace Tango.FSE.Diagnostics.ViewModels
catch (Exception ex)
{
NotificationProvider.PushErrorReportingSnackbar(ex, "Diagnostics Module Error", "Error initializing diagnostics module.");
- return;
+ if (throwException)
+ {
+ throw ex;
+ }
}
finally
{
@@ -157,11 +476,172 @@ namespace Tango.FSE.Diagnostics.ViewModels
}
}
+ private async void SaveAsProject()
+ {
+ var result = await StorageProvider.SaveFile("Save diagnostics project", "Diagnostics Projects|*.json", "diagnostics.json", ".json");
+
+ if (result.Confirmed)
+ {
+ SaveProject(result.SelectedItem);
+ }
+ }
+
+ private void SaveProject()
+ {
+ if (_customProjectFile != null)
+ {
+ SaveProject(_customProjectFile);
+ }
+ else
+ {
+ SaveAsProject();
+ }
+ }
+
+ private void SaveProject(String filePath, bool throwException = false)
+ {
+ try
+ {
+ Project.ToFile(filePath);
+ SaveUserSettings();
+ _customProjectFile = filePath;
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error saving diagnostics project.");
+ NotificationProvider.ShowError($"Error saving diagnostics project.\n{ex.FlattenMessage()}");
+
+ if (throwException)
+ {
+ throw ex;
+ }
+ }
+ }
+
+ private async void CreateNewProject()
+ {
+ if (!await NotificationProvider.ShowWarningQuestion("Are you sure you want to create a new project?")) return;
+
+ if (Project != null)
+ {
+ DisposeWidgets(Project.FlattenWidgets());
+ }
+
+ Project = new DiagnosticsProject();
+ Project.Tabs.Add(DiagnosticsProjectTab.CreateNew("untitled", 12, 12));
+
+ Tabs = new ObservableCollection<DiagnosticsTabViewVM>();
+ foreach (var tab in Project.Tabs)
+ {
+ Tabs.Add(new DiagnosticsTabViewVM() { Tab = tab });
+ }
+
+ SelectedTab = Tabs.FirstOrDefault();
+ }
+
+ private void SaveUserSettings()
+ {
+ if (EditMode) return;
+
+ try
+ {
+ foreach (var widget in Project.FlattenWidgets())
+ {
+ try
+ {
+ if (widget is DiagnosticsConfigurableWidget)
+ {
+ DiagnosticsUserSettingsManager.Default.Settings.SetWidgetSettings(widget as DiagnosticsConfigurableWidget);
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, $"Error saving widget user settings for widget '{widget.DisplayName}'.");
+ }
+ }
+
+ //If you are going to work with different projects in the future you need to remote this.
+ //Because it will erase any settings other than for the current project.
+ DiagnosticsUserSettingsManager.Default.ClearGhostRecords(Project.FlattenWidgets().OfType<DiagnosticsConfigurableWidget>().ToList());
+
+ DiagnosticsUserSettingsManager.Default.Save();
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error saving diagnostics user settings collection.");
+ }
+ }
+
+ #endregion
+
+ #region Tab Management
+
+ private void ResetSelectedTabGrid()
+ {
+ if (SelectedTab != null)
+ {
+ foreach (var column in SelectedTab.Tab.Columns)
+ {
+ column.Width = new GridLength(1, GridUnitType.Star);
+ }
+
+ foreach (var row in SelectedTab.Tab.Rows)
+ {
+ row.Height = new GridLength(1, GridUnitType.Star);
+ }
+ }
+ }
+
private void OnSelectedTabChanged()
{
}
+ private void AddNewTab()
+ {
+ var tab = DiagnosticsProjectTab.CreateNew("untitled", 12, 12);
+ var tabVM = new DiagnosticsTabViewVM()
+ {
+ Tab = tab
+ };
+
+ Project.Tabs.Add(tab);
+ Tabs.Add(tabVM);
+
+ tabVM.ShowGridLines = ShowGridLines;
+ tabVM.EditMode = EditMode;
+ SelectedTab = tabVM;
+ }
+
+ private async void RemoveTab(DiagnosticsTabViewVM tabVM)
+ {
+ if (await NotificationProvider.ShowWarningQuestion("Are you sure you want to remove this tab?"))
+ {
+ var index = Tabs.IndexOf(tabVM);
+ Tabs.Remove(tabVM);
+ Project.Tabs.Remove(tabVM.Tab);
+ DisposeWidgets(tabVM.Tab.Widgets);
+
+ if (Tabs.Count > index)
+ {
+ SelectedTab = Tabs[index];
+ }
+ else
+ {
+ SelectedTab = null;
+ }
+ }
+ }
+
+ private void DeselectAllWidgets()
+ {
+ Tabs.ToList().ForEach(x => { x.SelectedWidget = null; x.IsWidgetSettingsOpened = false; });
+ }
+
+ #endregion
+
+ #region Populate Diagnostics Data
+
private void PopulateDiagnosticsData(DiagnosticsFrame frame)
{
if (_isLoaded)
@@ -171,28 +651,43 @@ namespace Tango.FSE.Diagnostics.ViewModels
tab.PopulateDiagnosticsData(new DiagnosticsPackage()
{
Frame = frame,
- MonitorsProperties = _monitorsProperties
});
}
}
}
- private async void ExportProject()
+ #endregion
+
+ #region Properties Change
+
+ private void OnEditModeChanged()
{
- var result = await StorageProvider.SaveFile("Export diagnostics project", "Diagnostics Projects|*.json", "diagnostics.json", ".json");
+ Tabs.ToList().ForEach(x => x.EditMode = EditMode);
+ InvalidateRelayCommands();
+ }
- if (result.Confirmed)
- {
- try
- {
- Project.ToFile(result.SelectedItem);
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error exporting diagnostics project.");
- await NotificationProvider.ShowError($"Error exporting diagnostics project\n{ex.FlattenMessage()}");
- }
- }
+ #endregion
+
+ #region Cut / Copy /Paste
+
+ private void CopySelectedWidgets()
+ {
+ _copiedWidget.Clear();
+ var selectedWidgets = SelectedTab.Tab.Widgets.Where(x => x.IsSelected).ToList();
+ _copiedWidget.AddRange(selectedWidgets.Select(x => x.Clone()));
+ InvalidateRelayCommands();
+
+ NotificationProvider.PushSnackbarItem(MessageType.Info, "Diagnostics Widgets Copied", true, $"{_copiedWidget.Count} diagnostics widgets copied.", TimeSpan.FromSeconds(1.5));
+ }
+
+ private void StartPasteWidgets()
+ {
+ if (SelectedTab == null || CreationMode) return;
+
+ DeselectAllWidgets();
+ PasteMode = true;
}
+
+ #endregion
}
}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Views/DiagnosticsTabView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Views/DiagnosticsTabView.xaml
index 7a8545f86..ffd8ee983 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Views/DiagnosticsTabView.xaml
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Views/DiagnosticsTabView.xaml
@@ -7,12 +7,13 @@
xmlns:commonControls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common"
xmlns:vm="clr-namespace:Tango.FSE.Diagnostics.ViewModels"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
+ xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:controls="clr-namespace:Tango.FSE.Diagnostics.Controls"
xmlns:local="clr-namespace:Tango.FSE.Diagnostics.Views"
xmlns:converters="clr-namespace:Tango.FSE.Diagnostics.Converters"
mc:Ignorable="d"
- d:DesignHeight="720" d:DesignWidth="1280" d:DataContext="{d:DesignInstance Type=vm:DiagnosticsTabViewVM, IsDesignTimeCreatable=False}" Background="{StaticResource FSE_PrimaryBackgroundBrush}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}">
+ d:DesignHeight="720" d:DesignWidth="1280" FocusVisualStyle="{x:Null}" d:DataContext="{d:DesignInstance Type=vm:DiagnosticsTabViewVM, IsDesignTimeCreatable=False}" Background="{StaticResource FSE_PrimaryBackgroundBrush}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}">
<UserControl.Resources>
<converters:DiagnosticsWidgetToViewConverter x:Key="DiagnosticsWidgetToViewConverter" />
@@ -21,10 +22,10 @@
</UserControl.Resources>
<Grid>
- <ListBox HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" ItemsSource="{Binding Tab.Widgets}" SelectedItem="{Binding SelectedWidget,Mode=TwoWay}" Style="{StaticResource FSE_BlankListBox}" ScrollViewer.VerticalScrollBarVisibility="Disabled">
+ <ListBox FocusVisualStyle="{x:Null}" SelectionMode="Extended" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" ItemsSource="{Binding Tab.Widgets}" SelectedItem="{Binding SelectedWidget,Mode=TwoWay}" Style="{StaticResource FSE_BlankListBox}" ScrollViewer.VerticalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
- <controls:DiagnosticsGrid IsItemsHost="True" ShowGridLines="False" Columns="{Binding Tab.Columns}" Rows="{Binding Tab.Rows}"/>
+ <controls:DiagnosticsGrid IsItemsHost="True" Columns="{Binding Tab.Columns}" Rows="{Binding Tab.Rows}"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
@@ -33,67 +34,130 @@
<Setter Property="Grid.Row" Value="{Binding Row}"></Setter>
<Setter Property="Grid.ColumnSpan" Value="{Binding ColumnSpan}"></Setter>
<Setter Property="Grid.RowSpan" Value="{Binding RowSpan}"></Setter>
+ <Setter Property="IsSelected" Value="{Binding IsSelected,Mode=TwoWay}"></Setter>
<Setter Property="Margin" Value="5"></Setter>
</Style>
</ListBox.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
- <Grid x:Name="parentGrid">
- <Grid x:Name="widgetGrid" Background="Transparent" HorizontalAlignment="Center" VerticalAlignment="Center">
- <Grid.Width>
- <MultiBinding Converter="{StaticResource PercentageToWidthConverter}">
- <Binding ElementName="parentGrid" Path="ActualWidth" />
- <Binding Path="Width" />
- </MultiBinding>
- </Grid.Width>
- <Grid.Height>
- <MultiBinding Converter="{StaticResource PercentageToWidthConverter}">
- <Binding ElementName="parentGrid" Path="ActualHeight" />
- <Binding Path="Height" />
- </MultiBinding>
- </Grid.Height>
-
- <ContentPresenter Content="{Binding Converter={StaticResource DiagnosticsWidgetToViewConverter}}"/>
+ <Grid>
+ <DockPanel x:Name="dockPanel">
+ <Border Background="#292929" Padding="5" CornerRadius="5" DockPanel.Dock="{Binding ComponentNameAlignment}" Visibility="{Binding DisplayComponentName,Converter={StaticResource BooleanToVisibilityConverter}}">
+ <Border.Style>
+ <Style TargetType="Border">
+ <Setter Property="Margin" Value="0 0 0 5"></Setter>
+ <Setter Property="Visibility" Value="Collapsed"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding ComponentNameAlignment}" Value="Bottom">
+ <Setter Property="Margin" Value="0 5 0 0"></Setter>
+ <Setter Property="Visibility" Value="Visible"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Border.Style>
+ <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding DisplayName}"/>
+ </Border>
+ <Grid x:Name="parentGrid">
+ <Grid x:Name="widgetGrid" Background="Transparent" HorizontalAlignment="Center" VerticalAlignment="Center">
+ <Grid.Width>
+ <MultiBinding Converter="{StaticResource PercentageToWidthConverter}">
+ <Binding ElementName="parentGrid" Path="ActualWidth" />
+ <Binding Path="Width" />
+ </MultiBinding>
+ </Grid.Width>
+ <Grid.Height>
+ <MultiBinding Converter="{StaticResource PercentageToWidthConverter}">
+ <Binding ElementName="parentGrid" Path="ActualHeight" />
+ <Binding Path="Height" />
+ </MultiBinding>
+ </Grid.Height>
- <Grid HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="32" Height="32" Margin="10" Visibility="{Binding Settings,Converter={StaticResource IsNullToVisibilityConverter},FallbackValue='Collapsed',TargetNullValue='Collapsed'}">
- <i:Interaction.Triggers>
- <i:EventTrigger EventName="PreviewMouseUp">
- <i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.OpenWidgetSettingsCommand}" CommandParameter="{Binding}" />
- </i:EventTrigger>
- </i:Interaction.Triggers>
- <Grid Cursor="Hand" Visibility="{Binding ElementName=widgetGrid,Path=IsMouseOver,Converter={StaticResource BooleanToVisibilityConverter}}">
- <Grid.Style>
- <Style TargetType="Grid">
- <Setter Property="Opacity" Value="0.6"></Setter>
- <Style.Triggers>
- <Trigger Property="IsMouseOver" Value="True">
- <Setter Property="Opacity" Value="1"></Setter>
- </Trigger>
- </Style.Triggers>
- </Style>
- </Grid.Style>
- <Ellipse Fill="#202020"/>
- <material:PackIcon HorizontalAlignment="Center" VerticalAlignment="Center" Width="20" Height="20" Kind="SettingsOutline" />
+ <ContentPresenter Content="{Binding Converter={StaticResource DiagnosticsWidgetToViewConverter}}"/>
+
+ <Canvas Width="32" Height="32" Margin="10" HorizontalAlignment="Left" VerticalAlignment="Bottom" >
+ <Grid Width="32" Height="32">
+ <Grid.Style>
+ <Style TargetType="Grid">
+ <Setter Property="Visibility" Value="Collapsed"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding HasSettings}" Value="True">
+ <Setter Property="Visibility" Value="Visible"></Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.EditMode}" Value="True">
+ <Setter Property="Visibility" Value="Visible"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Grid.Style>
+ <i:Interaction.Triggers>
+ <i:EventTrigger EventName="PreviewMouseUp">
+ <i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.OpenWidgetSettingsCommand}" CommandParameter="{Binding}" />
+ </i:EventTrigger>
+ </i:Interaction.Triggers>
+ <Grid Cursor="Hand" Visibility="{Binding ElementName=dockPanel,Path=IsMouseOver,Converter={StaticResource BooleanToVisibilityConverter}}">
+ <Grid.Style>
+ <Style TargetType="Grid">
+ <Setter Property="Opacity" Value="0.6"></Setter>
+ <Style.Triggers>
+ <Trigger Property="IsMouseOver" Value="True">
+ <Setter Property="Opacity" Value="1"></Setter>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+ </Grid.Style>
+ <Ellipse Fill="#202020"/>
+ <material:PackIcon HorizontalAlignment="Center" VerticalAlignment="Center" Width="20" Height="20" Kind="SettingsOutline" />
+ </Grid>
+ </Grid>
+ </Canvas>
</Grid>
</Grid>
- </Grid>
+ </DockPanel>
+
+ <Border IsHitTestVisible="False" Opacity="0.4" CornerRadius="5">
+ <Border.Style>
+ <Style TargetType="Border">
+ <Setter Property="Background" Value="Transparent"></Setter>
+ <Style.Triggers>
+ <MultiDataTrigger>
+ <MultiDataTrigger.Conditions>
+ <Condition Binding="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.EditMode}" Value="True" />
+ <Condition Binding="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem},Path=IsSelected}" Value="True" />
+ </MultiDataTrigger.Conditions>
+ <Setter Property="Background" Value="{StaticResource FSE_PrimaryBackgroundLightBrush}"></Setter>
+ </MultiDataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Border.Style>
+ </Border>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListBox>
- <Grid Margin="20" HorizontalAlignment="Right" Width="300">
+ <Grid Margin="0 10 0 0" HorizontalAlignment="Right" Width="300">
<Grid.Style>
<Style TargetType="Grid">
<Setter Property="Visibility" Value="Collapsed"></Setter>
<Style.Triggers>
- <DataTrigger Binding="{Binding IsWidgetSettingsOpened}" Value="True">
+ <MultiDataTrigger>
+ <MultiDataTrigger.Conditions>
+ <Condition Binding="{Binding IsWidgetSettingsOpened}" Value="True" />
+ <Condition Binding="{Binding SelectedWidget.HasSettings}" Value="True" />
+ </MultiDataTrigger.Conditions>
<Setter Property="Visibility" Value="Visible"></Setter>
- </DataTrigger>
+ </MultiDataTrigger>
+ <MultiDataTrigger>
+ <MultiDataTrigger.Conditions>
+ <Condition Binding="{Binding IsWidgetSettingsOpened}" Value="True" />
+ <Condition Binding="{Binding EditMode}" Value="True" />
+ </MultiDataTrigger.Conditions>
+ <Setter Property="Visibility" Value="Visible"></Setter>
+ </MultiDataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
- <Border Background="#B1393939" CornerRadius="5">
+ <Border Background="{StaticResource FSE_PrimaryBackgroundBrush}" CornerRadius="5">
<Border.Effect>
<DropShadowEffect ShadowDepth="0" />
</Border.Effect>
@@ -101,12 +165,73 @@
<DockPanel>
<Border DockPanel.Dock="Top" Background="{StaticResource FSE_PrimaryBackgroundBrush}" CornerRadius="5 5 0 0">
<DockPanel Margin="20 10 10 10">
- <commonControls:IconButton Command="{Binding CloseWidgetSettingsCommand}" ToolTip="Close Settings" Icon="Close" DockPanel.Dock="Right" Padding="0" Width="24" Height="24"></commonControls:IconButton>
+ <commonControls:IconButton Cursor="Hand" Command="{Binding CloseWidgetSettingsCommand}" ToolTip="Close Settings" Icon="Close" DockPanel.Dock="Right" Padding="0" Width="24" Height="24"></commonControls:IconButton>
<TextBlock VerticalAlignment="Center" Text="{Binding SelectedWidget.DisplayName,Mode=OneWay}"></TextBlock>
</DockPanel>
</Border>
<ScrollViewer Padding="10" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
- <ContentPresenter Content="{Binding SelectedWidget,Converter={StaticResource DiagnosticsWidgetToSettingsViewConverter}}" />
+ <StackPanel>
+
+ <StackPanel Visibility="{Binding EditMode,Converter={StaticResource BooleanToVisibilityConverter}}">
+ <commonControls:FSEGroupBox Margin="0 0 0 10" Header="BOUNDS" HeaderFontSize="{StaticResource FSE_SmallFontSize}">
+ <StackPanel>
+ <UniformGrid Columns="2">
+ <mahapps:NumericUpDown HasDecimals="False" Margin="0 0 10 0" Value="{Binding SelectedWidget.Column,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Maximum="{Binding Tab.Columns.Count,Mode=OneWay}" Minimum="0" material:HintAssist.IsFloating="True" material:HintAssist.Hint="Column" />
+ <mahapps:NumericUpDown HasDecimals="False" Margin="10 0 0 0" Value="{Binding SelectedWidget.Row,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Maximum="{Binding Tab.Rows.Count,Mode=OneWay}" Minimum="0" material:HintAssist.IsFloating="True" material:HintAssist.Hint="Row" />
+ </UniformGrid>
+ <UniformGrid Margin="0 10 0 0" Columns="2">
+ <mahapps:NumericUpDown HasDecimals="False" Margin="0 0 10 0" Value="{Binding SelectedWidget.ColumnSpan,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Maximum="{Binding Tab.Columns.Count,Mode=OneWay}" Minimum="0" material:HintAssist.IsFloating="True" material:HintAssist.Hint="Column Span" />
+ <mahapps:NumericUpDown HasDecimals="False" Margin="10 0 0 0" Value="{Binding SelectedWidget.RowSpan,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Maximum="{Binding Tab.Rows.Count,Mode=OneWay}" Minimum="0" material:HintAssist.IsFloating="True" material:HintAssist.Hint="Row Span" />
+ </UniformGrid>
+ <UniformGrid Margin="0 10 0 0" Columns="2">
+ <mahapps:NumericUpDown HasDecimals="True" Margin="0 0 10 0" Value="{Binding SelectedWidget.Width,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Maximum="100" Minimum="1" material:HintAssist.IsFloating="True" material:HintAssist.Hint="Width (%)" />
+ <mahapps:NumericUpDown HasDecimals="True" Margin="10 0 0 0" Value="{Binding SelectedWidget.Height,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Maximum="100" Minimum="1" material:HintAssist.IsFloating="True" material:HintAssist.Hint="Height (%)" />
+ </UniformGrid>
+ </StackPanel>
+ </commonControls:FSEGroupBox>
+ </StackPanel>
+
+ <StackPanel Margin="0 0 0 10">
+ <StackPanel.Style>
+ <Style TargetType="StackPanel">
+ <Setter Property="Visibility" Value="Collapsed"></Setter>
+ <Style.Triggers>
+ <MultiDataTrigger>
+ <MultiDataTrigger.Conditions>
+ <Condition Binding="{Binding SelectedWidget.SupportsComponentSelection}" Value="True" />
+ <Condition Binding="{Binding SelectedWidget.EnableComponentSelection}" Value="True" />
+ </MultiDataTrigger.Conditions>
+ <Setter Property="Visibility" Value="Visible"></Setter>
+ </MultiDataTrigger>
+ <MultiDataTrigger>
+ <MultiDataTrigger.Conditions>
+ <Condition Binding="{Binding SelectedWidget.SupportsComponentSelection}" Value="True" />
+ <Condition Binding="{Binding EditMode}" Value="True" />
+ </MultiDataTrigger.Conditions>
+ <Setter Property="Visibility" Value="Visible"></Setter>
+ </MultiDataTrigger>
+ </Style.Triggers>
+ </Style>
+ </StackPanel.Style>
+ <commonControls:FSEGroupBox Header="COMPONENT" HeaderFontSize="{StaticResource FSE_SmallFontSize}">
+ <StackPanel>
+ <ComboBox FontSize="{StaticResource FSE_SmallFontSize}" material:ComboBoxAssist.ClassicMode="True" material:ComboBoxAssist.ShowSelectedItem="True" ItemsSource="{Binding SelectedWidget.Components}" SelectedValue="{Binding SelectedWidget.SelectedComponent}" SelectedValuePath="Object" DisplayMemberPath="DisplayName"></ComboBox>
+
+ <StackPanel Visibility="{Binding EditMode,Converter={StaticResource BooleanToVisibilityConverter}}">
+ <CheckBox Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked" ToolTip="Enable component selection for standard users" Margin="-2 10 0 0" IsChecked="{Binding SelectedWidget.EnableComponentSelection}" FontSize="{StaticResource FSE_SmallFontSize}">Enable Component Selection</CheckBox>
+
+ <CheckBox Margin="-2 10 0 0" FontSize="{StaticResource FSE_SmallFontSize}" IsChecked="{Binding SelectedWidget.DisplayComponentName}">Display Component Name</CheckBox>
+ <ComboBox Margin="0 10 0 0" FontSize="{StaticResource FSE_SmallFontSize}" material:HintAssist.Hint="Alignment" material:HintAssist.IsFloating="True" SelectedItem="{Binding SelectedWidget.ComponentNameAlignment,Mode=TwoWay}">
+ <Dock>Top</Dock>
+ <Dock>Bottom</Dock>
+ </ComboBox>
+ </StackPanel>
+ </StackPanel>
+ </commonControls:FSEGroupBox>
+ </StackPanel>
+
+ <ContentPresenter Content="{Binding SelectedWidget,Converter={StaticResource DiagnosticsWidgetToSettingsViewConverter}}" />
+ </StackPanel>
</ScrollViewer>
</DockPanel>
</Border>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Views/DiagnosticsTabView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Views/DiagnosticsTabView.xaml.cs
index e3814dd79..2aecb2a91 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Views/DiagnosticsTabView.xaml.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Views/DiagnosticsTabView.xaml.cs
@@ -12,6 +12,8 @@ using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
+using Tango.FSE.Diagnostics.Project;
+using Tango.FSE.Diagnostics.ViewModels;
namespace Tango.FSE.Diagnostics.Views
{
@@ -20,9 +22,22 @@ namespace Tango.FSE.Diagnostics.Views
/// </summary>
public partial class DiagnosticsTabView : UserControl
{
+ private DiagnosticsTabViewVM vm;
+
public DiagnosticsTabView()
{
InitializeComponent();
+ Loaded += (_, __) => vm = DataContext as DiagnosticsTabViewVM;
+ }
+
+ private void CheckBox_Checked(object sender, RoutedEventArgs e)
+ {
+ vm?.SelectedWidget?.RaiseHasSettings();
+ }
+
+ private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
+ {
+ vm?.SelectedWidget?.RaiseHasSettings();
}
}
}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Views/DiagnosticsView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Views/DiagnosticsView.xaml
index 96f9e1bf0..4232c2647 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Views/DiagnosticsView.xaml
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Views/DiagnosticsView.xaml
@@ -5,122 +5,295 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:global="clr-namespace:Tango.FSE.Diagnostics"
xmlns:vm="clr-namespace:Tango.FSE.Diagnostics.ViewModels"
+ xmlns:auth="clr-namespace:Tango.FSE.Common.Authorization;assembly=Tango.FSE.Common"
xmlns:controls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common"
+ xmlns:localControls="clr-namespace:Tango.FSE.Diagnostics.Controls"
+ xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:local="clr-namespace:Tango.FSE.Diagnostics.Views"
+ xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
mc:Ignorable="d"
- d:DesignHeight="720" d:DesignWidth="1280" d:DataContext="{d:DesignInstance Type=vm:DiagnosticsViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.DiagnosticsViewVM}" Background="{StaticResource FSE_PrimaryBackgroundBrush}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}">
- <Grid Margin="20">
- <DockPanel x:Name="dock">
- <Grid DockPanel.Dock="Top" Height="50">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="1*" />
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="1*" />
- </Grid.ColumnDefinitions>
- <Rectangle Grid.Column="0" VerticalAlignment="Bottom" StrokeThickness="2" Stroke="{StaticResource FSE_PrimaryAccentDarkBrush}" />
- <ListBox x:Name="listTabs" Grid.Column="1" DisplayMemberPath="Tag" ItemsSource="{Binding Tabs}" SelectedItem="{Binding SelectedTab}" SelectedIndex="0">
- <ListBox.Style>
- <Style TargetType="ListBox" BasedOn="{StaticResource {x:Type ListBox}}">
- <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"></Setter>
- <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Disabled"></Setter>
- <Setter Property="ItemsPanel">
- <Setter.Value>
+ d:DesignHeight="720" d:DesignWidth="1280" FocusVisualStyle="{x:Null}" d:DataContext="{d:DesignInstance Type=vm:DiagnosticsViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.DiagnosticsViewVM}" Background="{StaticResource FSE_PrimaryBackgroundBrush}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}" x:Name="control">
+ <UserControl.InputBindings>
+ <KeyBinding Modifiers="Ctrl" Key="S" Command="{Binding SaveProjectCommand}" />
+ <KeyBinding Modifiers="Ctrl+Shift" Key="S" Command="{Binding SaveAsProjectCommand}" />
+ <KeyBinding Modifiers="Ctrl" Key="N" Command="{Binding NewProjectCommand}" />
+ <KeyBinding Modifiers="Ctrl" Key="O" Command="{Binding OpenProjectCommand}" />
+ <KeyBinding Modifiers="Ctrl" Key="X" Command="{Binding CutSelectedWidgetsCommand}" />
+ <KeyBinding Modifiers="Ctrl" Key="C" Command="{Binding CopySelectedWidgetsCommand}" />
+ <KeyBinding Modifiers="Ctrl" Key="V" Command="{Binding PasteWidgetsCommand}" />
+ <KeyBinding Key="Delete" Command="{Binding DeleteSelectedWidgetsCommand}" />
+ <KeyBinding Key="Esc" Command="{Binding AbortCreationCommand}" />
+ </UserControl.InputBindings>
+ <DockPanel>
+ <Grid DockPanel.Dock="Top" IsEnabled="{Binding NotInCreationOrPasteMode}" Visibility="{Binding EditMode,Converter={StaticResource BooleanToVisibilityConverter}}">
+ <DockPanel>
+ <!--<Grid DockPanel.Dock="Right">
+ <StackPanel Orientation="Horizontal">
+ <TextBox Width="100" material:HintAssist.Hint="Tab" material:HintAssist.IsFloating="True" Text="{Binding SelectedTab.Tab.Name}"></TextBox>
+ <mahapps:NumericUpDown Minimum="0" Maximum="99" Value="{Binding SelectedTab.Tab.Columns}" />
+ </StackPanel>
+ </Grid>-->
+ <Menu IsMainMenu="True" Margin="50 0 0 0" VerticalAlignment="Top">
+ <MenuItem Header="_File">
+ <MenuItem Header="_New" MinWidth="250" Command="{Binding NewProjectCommand}" InputGestureText="Ctrl+N">
+ <MenuItem.Icon>
+ <material:PackIcon Kind="FileDocument" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <MenuItem Header="_Open" Command="{Binding OpenProjectCommand}" InputGestureText="Ctrl+O">
+ <MenuItem.Icon>
+ <material:PackIcon Kind="FileEdit" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <Separator/>
+ <MenuItem Header="_Save" Command="{Binding SaveProjectCommand}" InputGestureText="Ctrl+S">
+ <MenuItem.Icon>
+ <material:PackIcon Kind="ContentSave" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <MenuItem Header="_Save As" Command="{Binding SaveAsProjectCommand}" InputGestureText="Ctrl+Shift+S">
+ <MenuItem.Icon>
+ <material:PackIcon Kind="ContentSaveAll" />
+ </MenuItem.Icon>
+ </MenuItem>
+ </MenuItem>
+ <MenuItem Header="_Edit">
+ <MenuItem Header="_Cut" Command="{Binding CutSelectedWidgetsCommand}" InputGestureText="Ctrl+X">
+ <MenuItem.Icon>
+ <material:PackIcon Kind="ContentCopy" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <MenuItem Header="_Copy" Command="{Binding CopySelectedWidgetsCommand}" InputGestureText="Ctrl+C">
+ <MenuItem.Icon>
+ <material:PackIcon Kind="ContentCopy" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <MenuItem Header="_Paste" Command="{Binding PasteWidgetsCommand}" InputGestureText="Ctrl+V">
+ <MenuItem.Icon>
+ <material:PackIcon Kind="ContentPaste" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <Separator/>
+ <MenuItem Header="_Delete" Command="{Binding DeleteSelectedWidgetsCommand}" InputGestureText="DEL">
+ <MenuItem.Icon>
+ <material:PackIcon Kind="Delete" />
+ </MenuItem.Icon>
+ </MenuItem>
+ </MenuItem>
+ <MenuItem Header="_Grid">
+ <MenuItem IsCheckable="True" Header="_Display Grid Lines" MinWidth="250" IsChecked="{Binding ShowGridLines}">
+ <MenuItem.Icon>
+ <material:PackIcon Kind="Grid" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <MenuItem Header="_Reset Uniformity" Command="{Binding ResetGridCommand}">
+ <MenuItem.Icon>
+ <material:PackIcon Kind="Grid" />
+ </MenuItem.Icon>
+ </MenuItem>
+ </MenuItem>
+ <MenuItem Header="_Widgets" ItemsSource="{Binding AvailableWidgetTypes}">
+ <MenuItem.ItemContainerStyle>
+ <Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource {x:Type MenuItem}}">
+ <Setter Property="Command" Value="{Binding DataContext.AddWidgetCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type MenuItem}, AncestorLevel=1}}" />
+ <Setter Property="CommandParameter" Value="{Binding}"></Setter>
+ <Setter Property="HeaderTemplate">
+ <Setter.Value>
+ <DataTemplate>
+ <Border>
+ <DockPanel>
+ <material:PackIcon Kind="Plus" />
+ <ContentPresenter Margin="20 0 0 0" Content="{Binding Name}" />
+ </DockPanel>
+ </Border>
+ </DataTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+ </MenuItem.ItemContainerStyle>
+ </MenuItem>
+ </Menu>
+ </DockPanel>
+ </Grid>
+ <Grid>
+ <Grid.Style>
+ <Style TargetType="Grid">
+ <Setter Property="Margin" Value="20"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding EditMode}" Value="True">
+ <Setter Property="Margin" Value="20 0 20 5"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Grid.Style>
+ <DockPanel x:Name="dock">
+ <Grid DockPanel.Dock="Top" Height="50">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="1*" />
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="1*" />
+ </Grid.ColumnDefinitions>
+ <Rectangle Grid.Column="0" VerticalAlignment="Bottom" StrokeThickness="2" Stroke="{StaticResource FSE_PrimaryAccentDarkBrush}" />
+ <ListBox x:Name="listTabs" FocusVisualStyle="{x:Null}" Grid.Column="1" DisplayMemberPath="Tag" ItemsSource="{Binding Tabs}" SelectedItem="{Binding SelectedTab}" SelectedIndex="0">
+ <ListBox.Style>
+ <Style TargetType="ListBox" BasedOn="{StaticResource {x:Type ListBox}}">
+ <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"></Setter>
+ <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Disabled"></Setter>
+ <Setter Property="ItemsPanel">
+ <Setter.Value>
+ <ItemsPanelTemplate>
+ <UniformGrid Margin="15 0 0 0" Columns="{Binding RelativeSource={RelativeSource AncestorType=ListBox},Path=Items.Count}" IsItemsHost="True"></UniformGrid>
+ </ItemsPanelTemplate>
+ </Setter.Value>
+ </Setter>
+ <Setter Property="ItemContainerStyle">
+ <Setter.Value>
+ <Style TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListBoxItem}}">
+ <Setter Property="HorizontalContentAlignment" Value="Center"></Setter>
+ <Setter Property="VerticalContentAlignment" Value="Center"></Setter>
+ <Setter Property="Background" Value="{StaticResource FSE_PrimaryBackgroundBrush}"></Setter>
+ <Setter Property="FocusVisualStyle" Value="{x:Null}"></Setter>
+ <Setter Property="Foreground" Value="{StaticResource FSE_GrayBrush}"></Setter>
+ <Setter Property="Width" Value="200"></Setter>
+ <Setter Property="IsSelected" Value="{Binding IsSelected,Mode=OneWayToSource}"></Setter>
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="ListBoxItem">
+ <Grid x:Name="grid" Margin="-15 0 0 0" Background="Transparent">
+ <Viewbox Stretch="Fill">
+ <Grid>
+ <Polygon Fill="{TemplateBinding Background}" Stretch="Fill" Points="0,30 15,0 85,0 100,30"></Polygon>
+ <Polygon Fill="White" Stretch="Fill" Points="0,30 15,0 85,0 100,30" IsHitTestVisible="False" Opacity="0.1">
+ <Polygon.Style>
+ <Style TargetType="Polygon">
+ <Setter Property="Visibility" Value="Hidden"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem},Path=IsMouseOver}" Value="True">
+ <Setter Property="Visibility" Value="Visible"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Polygon.Style>
+ </Polygon>
+ <Polyline Stroke="{StaticResource FSE_PrimaryAccentDarkBrush}" StrokeThickness="1" Stretch="Fill" Points="0,30 15,0 85,0 100,30" />
+ <Rectangle VerticalAlignment="Bottom" Stroke="{StaticResource FSE_PrimaryAccentDarkBrush}" StrokeThickness="1" />
+ </Grid>
+ </Viewbox>
+ <ContentPresenter Content="{Binding Tab.Name}" TextElement.Foreground="{TemplateBinding Foreground}" HorizontalAlignment="Center" VerticalAlignment="Center" />
+ <controls:IconButton Visibility="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.EditMode,Converter={StaticResource BooleanToVisibilityConverter}}" Cursor="Hand" Margin="0 0 20 0" Foreground="{StaticResource FSE_PrimaryForegroundBrush}" VerticalAlignment="Center" HorizontalAlignment="Right" Icon="Close" Width="20" Height="20" Padding="0" Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.RemoveTabCommand}" CommandParameter="{Binding}" />
+ </Grid>
+ <ControlTemplate.Triggers>
+ <Trigger Property="IsSelected" Value="True">
+
+ </Trigger>
+ </ControlTemplate.Triggers>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ <Style.Triggers>
+ <Trigger Property="IsSelected" Value="True">
+ <Setter Property="Background" Value="{StaticResource FSE_PrimaryAccentDarkBrush}"></Setter>
+ <Setter Property="Foreground" Value="{StaticResource FSE_PrimaryForegroundBrush}"></Setter>
+ <Setter Property="FontWeight" Value="SemiBold"></Setter>
+ <Setter Property="Panel.ZIndex" Value="200"></Setter>
+ </Trigger>
+ <Trigger Property="IsSelected" Value="False">
+ <Setter Property="Panel.ZIndex" Value="-1"></Setter>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+ </Setter.Value>
+ </Setter>
+ </Style>
+ </ListBox.Style>
+ </ListBox>
+ <controls:IconButton Cursor="Hand" Command="{Binding AddNewTabCommand}" Visibility="{Binding EditMode,Converter={StaticResource BooleanToVisibilityConverter}}" Grid.Column="2" Width="24" Height="24" Padding="0" Margin="10 0 0 0" Icon="Plus" Foreground="{StaticResource FSE_PrimaryAccentBrush}" />
+ <Rectangle Margin="-50 0 0 0" Grid.Column="3" VerticalAlignment="Bottom" StrokeThickness="2" Stroke="{StaticResource FSE_PrimaryAccentDarkBrush}" />
+ </Grid>
+
+ <Grid x:Name="grid" Background="Transparent">
+ <i:Interaction.Triggers>
+ <i:EventTrigger EventName="PreviewMouseRightButtonUp">
+ <i:InvokeCommandAction Command="{Binding DeselectWidgetsCommand}" />
+ </i:EventTrigger>
+ <i:EventTrigger EventName="MouseDown">
+ <i:InvokeCommandAction Command="{Binding DeselectWidgetsCommand}" />
+ </i:EventTrigger>
+ </i:Interaction.Triggers>
+ <Viewbox Stretch="Uniform" Margin="0 0 0 0" VerticalAlignment="Top" Width="{Binding ElementName=grid,Path=ActualWidth}" Height="{Binding ElementName=grid,Path=ActualHeight}">
+ <Grid>
+ <ItemsControl x:Name="tabControl" Width="1810" Height="827" ItemsSource="{Binding Tabs}" BorderThickness="0" Background="Transparent">
+ <ItemsControl.Style>
+ <Style TargetType="ItemsControl">
+ <Setter Property="Opacity" Value="1"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding CreationMode}" Value="True">
+ <Setter Property="Opacity" Value="0.3"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </ItemsControl.Style>
+ <ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
- <UniformGrid Margin="15 0 0 0" Columns="{Binding RelativeSource={RelativeSource AncestorType=ListBox},Path=Items.Count}" IsItemsHost="True"></UniformGrid>
+ <Grid/>
</ItemsPanelTemplate>
- </Setter.Value>
- </Setter>
- <Setter Property="ItemContainerStyle">
- <Setter.Value>
- <Style TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListBoxItem}}">
- <Setter Property="HorizontalContentAlignment" Value="Center"></Setter>
- <Setter Property="VerticalContentAlignment" Value="Center"></Setter>
- <Setter Property="Background" Value="{StaticResource FSE_PrimaryBackgroundBrush}"></Setter>
- <Setter Property="FocusVisualStyle" Value="{x:Null}"></Setter>
- <Setter Property="Foreground" Value="{StaticResource FSE_GrayBrush}"></Setter>
- <Setter Property="Width" Value="200"></Setter>
- <Setter Property="IsSelected" Value="{Binding IsSelected,Mode=OneWayToSource}"></Setter>
- <Setter Property="Template">
- <Setter.Value>
- <ControlTemplate TargetType="ListBoxItem">
- <Grid x:Name="grid" Margin="-15 0 0 0" Background="Transparent">
- <Viewbox Stretch="Fill">
- <Grid>
- <Polygon Fill="{TemplateBinding Background}" Stretch="Fill" Points="0,30 15,0 85,0 100,30"></Polygon>
- <Polygon Fill="White" Stretch="Fill" Points="0,30 15,0 85,0 100,30" IsHitTestVisible="False" Opacity="0.1">
- <Polygon.Style>
- <Style TargetType="Polygon">
- <Setter Property="Visibility" Value="Hidden"></Setter>
- <Style.Triggers>
- <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem},Path=IsMouseOver}" Value="True">
- <Setter Property="Visibility" Value="Visible"></Setter>
- </DataTrigger>
- </Style.Triggers>
- </Style>
- </Polygon.Style>
- </Polygon>
- <Polyline Stroke="{StaticResource FSE_PrimaryAccentDarkBrush}" StrokeThickness="1" Stretch="Fill" Points="0,30 15,0 85,0 100,30" />
- <Rectangle VerticalAlignment="Bottom" Stroke="{StaticResource FSE_PrimaryAccentDarkBrush}" StrokeThickness="1" />
- </Grid>
- </Viewbox>
- <ContentPresenter Content="{Binding Tab.Name}" TextElement.Foreground="{TemplateBinding Foreground}" HorizontalAlignment="Center" VerticalAlignment="Center" />
- </Grid>
- <ControlTemplate.Triggers>
- <Trigger Property="IsSelected" Value="True">
-
- </Trigger>
- </ControlTemplate.Triggers>
- </ControlTemplate>
- </Setter.Value>
- </Setter>
+ </ItemsControl.ItemsPanel>
+ <ItemsControl.ItemContainerStyle>
+ <Style TargetType="FrameworkElement">
+ <Setter Property="Visibility" Value="Hidden"></Setter>
<Style.Triggers>
- <Trigger Property="IsSelected" Value="True">
- <Setter Property="Background" Value="{StaticResource FSE_PrimaryAccentDarkBrush}"></Setter>
- <Setter Property="Foreground" Value="{StaticResource FSE_PrimaryForegroundBrush}"></Setter>
- <Setter Property="FontWeight" Value="SemiBold"></Setter>
- <Setter Property="Panel.ZIndex" Value="200"></Setter>
- </Trigger>
- <Trigger Property="IsSelected" Value="False">
- <Setter Property="Panel.ZIndex" Value="-1"></Setter>
- </Trigger>
+ <DataTrigger Binding="{Binding IsSelected}" Value="True">
+ <Setter Property="Visibility" Value="Visible"></Setter>
+ </DataTrigger>
</Style.Triggers>
</Style>
- </Setter.Value>
- </Setter>
- </Style>
- </ListBox.Style>
- </ListBox>
- <Rectangle Grid.Column="2" VerticalAlignment="Bottom" StrokeThickness="2" Stroke="{StaticResource FSE_PrimaryAccentDarkBrush}" />
- </Grid>
+ </ItemsControl.ItemContainerStyle>
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <local:DiagnosticsTabView />
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
- <Grid x:Name="grid">
- <Viewbox Stretch="Fill" Margin="0 0 0 0" VerticalAlignment="Top" Width="{Binding ElementName=grid,Path=ActualWidth}" Height="{Binding ElementName=grid,Path=ActualHeight}">
- <ItemsControl x:Name="tabControl" Width="1810" Height="827" ItemsSource="{Binding Tabs}" BorderThickness="0" Background="Transparent">
- <ItemsControl.ItemsPanel>
- <ItemsPanelTemplate>
- <Grid/>
- </ItemsPanelTemplate>
- </ItemsControl.ItemsPanel>
- <ItemsControl.ItemContainerStyle>
- <Style TargetType="FrameworkElement">
- <Setter Property="Visibility" Value="Hidden"></Setter>
- <Style.Triggers>
- <DataTrigger Binding="{Binding IsSelected}" Value="True">
- <Setter Property="Visibility" Value="Visible"></Setter>
- </DataTrigger>
- </Style.Triggers>
- </Style>
- </ItemsControl.ItemContainerStyle>
- <ItemsControl.ItemTemplate>
- <DataTemplate>
- <local:DiagnosticsTabView />
- </DataTemplate>
- </ItemsControl.ItemTemplate>
- </ItemsControl>
- </Viewbox>
- </Grid>
- </DockPanel>
+ <Grid Visibility="{Binding EditMode,Converter={StaticResource BooleanToVisibilityConverter}}">
+ <Grid Visibility="{Binding CreationMode,Converter={StaticResource BooleanToVisibilityConverter}}">
+ <localControls:DiagnosticsSelectionGrid Opacity="0.4" RectanglesBackgroundBrush="{StaticResource FSE_PrimaryBackgroundLightBrush}" RectanglesHighlightBrush="{StaticResource FSE_BorderBrush}" Columns="{Binding SelectedTab.Tab.Columns}" Rows="{Binding SelectedTab.Tab.Rows}" SelectionCommand="{Binding SelectionCommand,Mode=OneWay}" RightClickCommand="{Binding AbortCreationCommand,Mode=OneWay}" Visibility="{Binding CreationMode,Converter={StaticResource BooleanToVisibilityConverter}}"/>
+
+ <StackPanel Opacity="0.5" IsHitTestVisible="False" HorizontalAlignment="Center" VerticalAlignment="Center" >
+ <material:PackIcon Kind="Plus" HorizontalAlignment="Center" Width="32" Height="32" />
+ <TextBlock FontSize="20" Margin="0 10 0 0">hold and drag the cursor over the desired widget cells</TextBlock>
+ <TextBlock HorizontalAlignment="Center" Margin="0 5 0 0" Foreground="{StaticResource FSE_GrayBrush}">(right click or escape to cancel the new widget)</TextBlock>
+ </StackPanel>
+ </Grid>
+
+ <Grid Visibility="{Binding PasteMode,Converter={StaticResource BooleanToVisibilityConverter}}">
+ <localControls:DiagnosticsSelectionGrid SelectionMode="Single" Opacity="0.4" RectanglesBackgroundBrush="{StaticResource FSE_PrimaryBackgroundLightBrush}" RectanglesHighlightBrush="{StaticResource FSE_BorderBrush}" Columns="{Binding SelectedTab.Tab.Columns}" Rows="{Binding SelectedTab.Tab.Rows}" SelectionCommand="{Binding SelectionCommand,Mode=OneWay}" RightClickCommand="{Binding AbortCreationCommand,Mode=OneWay}" Visibility="{Binding PasteMode,Converter={StaticResource BooleanToVisibilityConverter}}"/>
+
+ <StackPanel Opacity="0.5" IsHitTestVisible="False" HorizontalAlignment="Center" VerticalAlignment="Center" >
+ <material:PackIcon Kind="Plus" HorizontalAlignment="Center" Width="32" Height="32" />
+ <TextBlock FontSize="20" Margin="0 10 0 0">select the desired cell for pasting copied widgets</TextBlock>
+ <TextBlock HorizontalAlignment="Center" Margin="0 5 0 0" Foreground="{StaticResource FSE_GrayBrush}">(right click or escape to cancel pasting)</TextBlock>
+ </StackPanel>
+ </Grid>
+
+ <localControls:DiagnosticsGridLinesEditor Visibility="{Binding ShowGridLines,Converter={StaticResource BooleanToVisibilityConverter}}" Columns="{Binding SelectedTab.Tab.Columns}" Rows="{Binding SelectedTab.Tab.Rows}">
+
+ </localControls:DiagnosticsGridLinesEditor>
+ </Grid>
+ </Grid>
+ </Viewbox>
+ </Grid>
+ </DockPanel>
+
+ <controls:ToggleIconButton IsChecked="{Binding EditMode}" Width="24" Height="24" auth:AuthorizationHelper.Mode="Collapsed" auth:AuthorizationHelper.Permission="FSE_EditDiagnosticsProject" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0 10 0 0" Cursor="Hand" ToolTip="Edit Mode" UncheckedIcon="SettingsOutline" UncheckedForeground="{StaticResource FSE_GrayBrush}" CheckedForeground="{StaticResource FSE_OrangeBrush}" CheckedIcon="SettingsOutline" Foreground="{StaticResource FSE_OrangeBrush}"></controls:ToggleIconButton>
- <controls:IconButton HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0 10 0 0" Cursor="Hand" ToolTip="Export diagnostics project" Icon="LightningBolt" Foreground="{StaticResource FSE_OrangeBrush}" Command="{Binding ExportProjectCommand}"></controls:IconButton>
- </Grid>
+ <!--ZOOM? NOT SURE-->
+ <!--<DockPanel HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0 -15 0 0">
+ <material:PackIcon Kind="ZoomInOutline" DockPanel.Dock="Right" VerticalAlignment="Bottom" Margin="0 0 0 0"></material:PackIcon>
+ <Slider Style="{StaticResource MaterialDesignDiscreteSlider}" FocusVisualStyle="{x:Null}" Width="80" Minimum="0" Maximum="200" Value="100"></Slider>
+ </DockPanel>-->
+ </Grid>
+ </DockPanel>
</UserControl>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/diagnostics.json b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/diagnostics.json
index 6baf6b4c2..a3df27042 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/diagnostics.json
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/diagnostics.json
@@ -83,53 +83,175 @@
{
"$type": "Tango.FSE.Diagnostics.Project.Widgets.RealTimeGraph.RealTimeGraphWidget, Tango.FSE.Diagnostics",
"Monitor": "Dancer2Angle",
+ "EnableComponentSelection": false,
+ "Settings": {
+ "Duration": "00:10:00",
+ "DecimalPlaces": 0,
+ "Min": 0.0,
+ "Max": 1000.0,
+ "AutoRange": true,
+ "Color": "#FF1E90FF"
+ },
+ "ID": "632ba431-4875-46f9-b9d6-39cbef3de2e5",
"Column": 0,
"Row": 0,
"ColumnSpan": 3,
- "RowSpan": 3
+ "RowSpan": 3,
+ "Width": 100.0,
+ "Height": 100.0
},
{
"$type": "Tango.FSE.Diagnostics.Project.Widgets.RealTimeGraph.RealTimeGraphWidget, Tango.FSE.Diagnostics",
"Monitor": "Dancer2Angle",
+ "EnableComponentSelection": false,
+ "Settings": {
+ "Duration": "00:10:00",
+ "DecimalPlaces": 0,
+ "Min": 0.0,
+ "Max": 1000.0,
+ "AutoRange": true,
+ "Color": "#FF1E90FF"
+ },
+ "ID": "3e8ab666-ab5d-4f14-979c-bcad02007802",
"Column": 3,
"Row": 0,
"ColumnSpan": 3,
- "RowSpan": 3
+ "RowSpan": 3,
+ "Width": 100.0,
+ "Height": 100.0
},
{
"$type": "Tango.FSE.Diagnostics.Project.Widgets.RealTimeGraph.RealTimeGraphWidget, Tango.FSE.Diagnostics",
"Monitor": "Dancer2Angle",
+ "EnableComponentSelection": false,
+ "Settings": {
+ "Duration": "00:10:00",
+ "DecimalPlaces": 0,
+ "Min": 0.0,
+ "Max": 1000.0,
+ "AutoRange": true,
+ "Color": "#FF1E90FF"
+ },
+ "ID": "1b6580fb-ef48-42f6-a340-775b5f586dad",
"Column": 6,
"Row": 0,
"ColumnSpan": 3,
- "RowSpan": 3
+ "RowSpan": 3,
+ "Width": 100.0,
+ "Height": 100.0
},
{
"$type": "Tango.FSE.Diagnostics.Project.Widgets.RealTimeGraph.RealTimeGraphWidget, Tango.FSE.Diagnostics",
"Monitor": "Dancer2Angle",
+ "EnableComponentSelection": false,
+ "Settings": {
+ "Duration": "00:10:00",
+ "DecimalPlaces": 0,
+ "Min": 0.0,
+ "Max": 1000.0,
+ "AutoRange": true,
+ "Color": "#FF1E90FF"
+ },
+ "ID": "4f22da27-4b60-4ea1-871b-73b091cecdb9",
"Column": 9,
"Row": 0,
"ColumnSpan": 3,
- "RowSpan": 3
+ "RowSpan": 3,
+ "Width": 100.0,
+ "Height": 100.0
},
{
"$type": "Tango.FSE.Diagnostics.Project.Widgets.RealTimeGraphMultiChannel.RealTimeGraphMultiChannelWidget, Tango.FSE.Diagnostics",
"Monitor": "DispensersMotorsFrequency",
+ "EnableComponentSelection": false,
+ "Settings": {
+ "Duration": "00:10:00",
+ "DecimalPlaces": 0,
+ "Min": 0.0,
+ "Max": 1000.0,
+ "AutoRange": true,
+ "Color": "#FF1E90FF"
+ },
+ "ID": "a72aa86c-ae39-42cc-8ca8-340abd4dd7f2",
"Column": 0,
"Row": 3,
"ColumnSpan": 3,
- "RowSpan": 3
+ "RowSpan": 3,
+ "Width": 100.0,
+ "Height": 100.0
},
{
"$type": "Tango.FSE.Diagnostics.Project.Widgets.Monitor.MonitorWidget, Tango.FSE.Diagnostics",
"Monitor": "Dancer2Angle",
+ "EnableComponentSelection": false,
+ "Settings": {
+ "DecimalPlaces": 0,
+ "Color": "#FFDCDCDC"
+ },
+ "ID": "90899668-6cce-4f51-a401-3039fb2226b8",
"Column": 0,
"Row": 6,
"ColumnSpan": 3,
"RowSpan": 2,
- "Width": 50
+ "Width": 50.0,
+ "Height": 100.0
+ },
+ {
+ "$type": "Tango.FSE.Diagnostics.Project.Widgets.Input.InputWidget, Tango.FSE.Diagnostics",
+ "IO": "LS_DH_CLEAN_DOWN",
+ "EnableComponentSelection": true,
+ "ID": "3010722d-ef21-4c86-ad23-19956108169b",
+ "Column": 1,
+ "Row": 8,
+ "ColumnSpan": 1,
+ "RowSpan": 1,
+ "Width": 100.0,
+ "Height": 100.0
+ },
+ {
+ "$type": "Tango.FSE.Diagnostics.Project.Widgets.Motor.MotorWidget, Tango.FSE.Diagnostics",
+ "Motor": "MOTO_DH_CLEANHEAD",
+ "EnableComponentSelection": false,
+ "Settings": {
+ "Speed": 400,
+ "Color": "#FF79FF00"
+ },
+ "ID": "625be286-0670-4784-b1ef-d78f854c4072",
+ "Column": 3,
+ "Row": 8,
+ "ColumnSpan": 4,
+ "RowSpan": 3,
+ "Width": 100.0,
+ "Height": 100.0
+ },
+ {
+ "$type": "Tango.FSE.Diagnostics.Project.Widgets.Dispenser.DispenserWidget, Tango.FSE.Diagnostics",
+ "Dispenser": "Dispenser2",
+ "EnableComponentSelection": false,
+ "Settings": {
+ "Speed": 400,
+ "Color": "#FF141414"
+ },
+ "ID": "86e5683c-a9dc-46f4-a88b-087bff6f8432",
+ "Column": 8,
+ "Row": 8,
+ "ColumnSpan": 4,
+ "RowSpan": 3,
+ "Width": 100.0,
+ "Height": 100.0
+ },
+ {
+ "$type": "Tango.FSE.Diagnostics.Project.Widgets.Valve.ValveWidget, Tango.FSE.Diagnostics",
+ "Valve": "DispenserValve2",
+ "EnableComponentSelection": false,
+ "ID": "4829f0da-e128-42f9-a4af-621e895df3ef",
+ "Column": 3,
+ "Row": 3,
+ "ColumnSpan": 3,
+ "RowSpan": 2,
+ "Width": 100.0,
+ "Height": 100.0
}
-
]
},
{
@@ -214,10 +336,22 @@
{
"$type": "Tango.FSE.Diagnostics.Project.Widgets.RealTimeGraph.RealTimeGraphWidget, Tango.FSE.Diagnostics",
"Monitor": "Dancer2Angle",
+ "EnableComponentSelection": false,
+ "Settings": {
+ "Duration": "00:10:00",
+ "DecimalPlaces": 0,
+ "Min": 0.0,
+ "Max": 1000.0,
+ "AutoRange": true,
+ "Color": "#FF1E90FF"
+ },
+ "ID": "e1da6427-d164-42f7-a4a8-44f804dd51df",
"Column": 2,
"Row": 2,
"ColumnSpan": 6,
- "RowSpan": 6
+ "RowSpan": 6,
+ "Width": 100.0,
+ "Height": 100.0
}
]
}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/packages.config b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/packages.config
index dd8c723e4..fbddb4518 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/packages.config
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/packages.config
@@ -7,4 +7,7 @@
<package id="MaterialDesignColors" version="1.2.2" targetFramework="net461" />
<package id="MaterialDesignThemes" version="3.0.1" targetFramework="net461" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" />
+ <package id="System.Reactive.Core" version="3.1.1" targetFramework="net461" />
+ <package id="System.Reactive.Interfaces" version="3.1.1" targetFramework="net461" />
+ <package id="System.Reactive.Linq" version="3.1.1" targetFramework="net461" />
</packages> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/TestDesignerView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/TestDesignerView.xaml
index 29251ca31..bcac1bbaa 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/TestDesignerView.xaml
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/TestDesignerView.xaml
@@ -23,7 +23,7 @@
<KeyBinding Key="F5" Command="{Binding RunProjectCommand}" />
<KeyBinding Key="F6" Command="{Binding CompileProjectCommand}" />
<KeyBinding Modifiers="Ctrl" Key="S" Command="{Binding SaveProjectCommand}" />
- <KeyBinding Modifiers="Ctrl+Shift" Key="S" Command="{Binding SaveProjectCommand}" />
+ <KeyBinding Modifiers="Ctrl+Shift" Key="S" Command="{Binding SaveAsProjectCommand}" />
<KeyBinding Modifiers="Ctrl" Key="N" Command="{Binding NewProjectCommand}" />
<KeyBinding Modifiers="Ctrl" Key="O" Command="{Binding OpenProjectCommand}" />
<KeyBinding Modifiers="Ctrl" Key="P" Command="{Binding TogglePublishPanelCommand}" />
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.UsersAndRoles/Models/RoleModel.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.UsersAndRoles/Models/RoleModel.cs
index 266a5c090..4d3eb9885 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.UsersAndRoles/Models/RoleModel.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.UsersAndRoles/Models/RoleModel.cs
@@ -32,12 +32,21 @@ namespace Tango.FSE.UsersAndRoles.Models
set { _isSelected = value; RaisePropertyChangedAuto(); }
}
+ private bool _isVisible;
+ public bool IsVisible
+ {
+ get { return _isVisible; }
+ set { _isVisible = value; RaisePropertyChangedAuto(); }
+ }
+
+
public List<Roles> Dependencies { get; set; }
public RoleModel(Role role, params Roles[] dependencies)
{
Role = role;
IsEnabled = true;
+ IsVisible = true;
Dependencies = new List<Roles>();
if (dependencies != null)
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.UsersAndRoles/ViewModels/UserDetailsViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.UsersAndRoles/ViewModels/UserDetailsViewVM.cs
index dec2651d1..e7fd962ec 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.UsersAndRoles/ViewModels/UserDetailsViewVM.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.UsersAndRoles/ViewModels/UserDetailsViewVM.cs
@@ -191,7 +191,7 @@ namespace Tango.FSE.UsersAndRoles.ViewModels
collection.Add(new RoleModel(roles.SingleOrDefault(x => x.RoleEnum == Roles.FSETwineAdministrator), Roles.FSETechnician, Roles.FSEAdministrator));
collection.Add(new RoleModel(roles.SingleOrDefault(x => x.RoleEnum == Roles.FSETwineTestDesigner), Roles.FSETechnician));
collection.Add(new RoleModel(roles.SingleOrDefault(x => x.RoleEnum == Roles.FSETwineTestPublisher), Roles.FSETechnician, Roles.FSETwineTestDesigner));
- collection.Add(new RoleModel(roles.SingleOrDefault(x => x.RoleEnum == Roles.FSETwineDeveloper), Roles.FSETechnician));
+ collection.Add(new RoleModel(roles.SingleOrDefault(x => x.RoleEnum == Roles.FSETwineDeveloper), Roles.FSETechnician) { IsVisible = CurrentUser.HasRole(Roles.FSETwineDeveloper) });
}
collection.ToList().ForEach(x => x.IsSelected = user.FSERoles.Any(y => y.Code == x.Role.Code));
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.UsersAndRoles/Views/UserDetailsView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.UsersAndRoles/Views/UserDetailsView.xaml
index a2ad81cf4..bbd99a965 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.UsersAndRoles/Views/UserDetailsView.xaml
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.UsersAndRoles/Views/UserDetailsView.xaml
@@ -113,7 +113,7 @@
<ListBox ScrollViewer.CanContentScroll="False" ScrollViewer.VerticalScrollBarVisibility="Disabled" Style="{StaticResource FSE_BlankListBox}" ItemsSource="{Binding RolesCollection}">
<ListBox.ItemTemplate>
<DataTemplate>
- <CheckBox Margin="0 10 0 0" IsChecked="{Binding IsSelected}" IsEnabled="{Binding IsEnabled}" Content="{Binding Role.Description}"></CheckBox>
+ <CheckBox Margin="0 10 0 0" IsChecked="{Binding IsSelected}" IsEnabled="{Binding IsEnabled}" Visibility="{Binding IsVisible,Converter={StaticResource BooleanToVisibilityConverter}}" Content="{Binding Role.Description}"></CheckBox>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.BL/EntityRepositoryBase.cs b/Software/Visual_Studio/FSE/Tango.FSE.BL/EntityRepositoryBase.cs
index 513982ba0..e14b61f22 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.BL/EntityRepositoryBase.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.BL/EntityRepositoryBase.cs
@@ -44,7 +44,7 @@ namespace Tango.FSE.BL
{
using (ObservablesContext db = ObservablesContext.CreateDefault())
{
- var entities = db.Set<TEntity>().WhereDynamic(expression.ToString()).ToList();
+ var entities = db.Set<TEntity>().Where(expression).ToList();
using (var cache = DiskCache.CreateContext())
{
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/TechComponentsService.cs b/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/TechComponentsService.cs
index e24c5b876..cc7f0f6da 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/TechComponentsService.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/TechComponentsService.cs
@@ -19,6 +19,7 @@ namespace Tango.FSE.BL.Services
public ReadOnlyEntityRepository<TechController, TechControllerDTO> Controllers { get; private set; }
public ReadOnlyEntityRepository<TechHeater, TechHeaterDTO> Heaters { get; private set; }
public ReadOnlyEntityRepository<TechValve, TechValveDTO> Valves { get; private set; }
+ public ReadOnlyEntityRepository<HardwareMotorType, HardwareMotorTypeDTO> Motors { get; private set; }
public TechComponentsService()
{
@@ -26,43 +27,50 @@ namespace Tango.FSE.BL.Services
x => x.ToObservable(),
x => TechMonitorDTO.FromObservable(x),
DataResolverNode.InMemoryCache,
- DataResolverNode.DiskCache,
- DataResolverNode.Online);
+ DataResolverNode.Online,
+ DataResolverNode.DiskCache);
IOs = new ReadOnlyEntityRepository<TechIo, TechIoDTO>(
x => x.ToObservable(),
x => TechIoDTO.FromObservable(x),
DataResolverNode.InMemoryCache,
- DataResolverNode.DiskCache,
- DataResolverNode.Online);
+ DataResolverNode.Online,
+ DataResolverNode.DiskCache);
Dispensers = new ReadOnlyEntityRepository<TechDispenser, TechDispenserDTO>(
x => x.ToObservable(),
x => TechDispenserDTO.FromObservable(x),
DataResolverNode.InMemoryCache,
- DataResolverNode.DiskCache,
- DataResolverNode.Online);
+ DataResolverNode.Online,
+ DataResolverNode.DiskCache);
Controllers = new ReadOnlyEntityRepository<TechController, TechControllerDTO>(
x => x.ToObservable(),
x => TechControllerDTO.FromObservable(x),
DataResolverNode.InMemoryCache,
- DataResolverNode.DiskCache,
- DataResolverNode.Online);
+ DataResolverNode.Online,
+ DataResolverNode.DiskCache);
Heaters = new ReadOnlyEntityRepository<TechHeater, TechHeaterDTO>(
x => x.ToObservable(),
x => TechHeaterDTO.FromObservable(x),
DataResolverNode.InMemoryCache,
- DataResolverNode.DiskCache,
- DataResolverNode.Online);
+ DataResolverNode.Online,
+ DataResolverNode.DiskCache);
Valves = new ReadOnlyEntityRepository<TechValve, TechValveDTO>(
x => x.ToObservable(),
x => TechValveDTO.FromObservable(x),
DataResolverNode.InMemoryCache,
- DataResolverNode.DiskCache,
- DataResolverNode.Online);
+ DataResolverNode.Online,
+ DataResolverNode.DiskCache);
+
+ Motors = new ReadOnlyEntityRepository<HardwareMotorType, HardwareMotorTypeDTO>(
+ x => x.ToObservable(),
+ x => HardwareMotorTypeDTO.FromObservable(x),
+ DataResolverNode.InMemoryCache,
+ DataResolverNode.Online,
+ DataResolverNode.DiskCache);
}
public async Task Preload()
@@ -73,6 +81,7 @@ namespace Tango.FSE.BL.Services
await Controllers.FindAll();
await Heaters.FindAll();
await Valves.FindAll();
+ await Motors.FindAll();
}
}
}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Authorization/AuthorizationHelper.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Authorization/AuthorizationHelper.cs
index 7ef470ad1..10e3dafd2 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Authorization/AuthorizationHelper.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Authorization/AuthorizationHelper.cs
@@ -114,6 +114,8 @@ namespace Tango.FSE.Common.Authorization
element.Unloaded += Element_Unloaded;
}
+ if (_authenticationProvider == null) return;
+
var currentUser = _authenticationProvider.CurrentUser;
var permission = GetPermission(element);
var mode = GetMode(element);
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/IconButton.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/IconButton.cs
index f0485dd22..9a9c6de05 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/IconButton.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/IconButton.cs
@@ -6,6 +6,7 @@ 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;
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/IconButton.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/IconButton.xaml
index 679fefb78..21bf94f1c 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/IconButton.xaml
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/IconButton.xaml
@@ -13,62 +13,101 @@
<DockPanel>
<ContentPresenter Margin="5 0 0 0" DockPanel.Dock="Right" Content="{Binding}" VerticalAlignment="Center" />
<Grid Background="Transparent">
- <material:PackIcon IsHitTestVisible="False" RenderTransformOrigin="0.5, 0.5" Kind="{Binding RelativeSource={RelativeSource AncestorType=local:IconButton},Path=Icon}" Width="Auto" Height="Auto">
- <material:PackIcon.Style>
- <Style TargetType="material:PackIcon">
- <Setter Property="RenderTransform">
- <Setter.Value>
- <ScaleTransform ScaleX="1" ScaleY="1" />
- </Setter.Value>
- </Setter>
- <Style.Triggers>
- <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Button},Path=IsMouseOver}" Value="True">
- <Setter Property="RenderTransform">
- <Setter.Value>
- <ScaleTransform ScaleX="1.2" ScaleY="1.2" />
- </Setter.Value>
- </Setter>
- </DataTrigger>
- </Style.Triggers>
- </Style>
- </material:PackIcon.Style>
- </material:PackIcon>
- <Canvas IsHitTestVisible="False">
- <Grid Width="{Binding RelativeSource={RelativeSource AncestorType=Canvas},Path=ActualWidth}" Height="{Binding RelativeSource={RelativeSource AncestorType=Canvas},Path=ActualHeight}">
- <Ellipse x:Name="ellipse" Fill="White" RenderTransformOrigin="0.5,0.5">
- <Ellipse.Style>
- <Style TargetType="Ellipse">
- <Setter Property="Opacity" Value="0.2"></Setter>
- <Setter Property="RenderTransform">
- <Setter.Value>
- <ScaleTransform ScaleX="0" ScaleY="0" />
- </Setter.Value>
- </Setter>
- <Setter Property="Visibility" Value="Hidden"></Setter>
- <Style.Triggers>
- <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Button},Path=IsMouseOver}" Value="True">
- <Setter Property="Visibility" Value="Visible"></Setter>
- <DataTrigger.EnterActions>
- <BeginStoryboard>
- <Storyboard>
- <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" From="0" To="4" Duration="00:00:0.5" DecelerationRatio="0.8" />
- <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" From="0" To="4" Duration="00:00:0.5" DecelerationRatio="0.8" />
- <DoubleAnimation Storyboard.TargetProperty="Opacity" From="0.2" To="0.001" Duration="00:00:0.5" DecelerationRatio="0.8" />
- </Storyboard>
- </BeginStoryboard>
- </DataTrigger.EnterActions>
- </DataTrigger>
- </Style.Triggers>
- </Style>
- </Ellipse.Style>
- </Ellipse>
- </Grid>
- </Canvas>
- </Grid>
+ <material:PackIcon IsHitTestVisible="False" RenderTransformOrigin="0.5, 0.5" Kind="{Binding RelativeSource={RelativeSource AncestorType=local:IconButton},Path=Icon}" Width="Auto" Height="Auto">
+ <material:PackIcon.Style>
+ <Style TargetType="material:PackIcon">
+ <Setter Property="RenderTransform">
+ <Setter.Value>
+ <ScaleTransform ScaleX="1" ScaleY="1" />
+ </Setter.Value>
+ </Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Button},Path=IsMouseOver}" Value="True">
+ <Setter Property="RenderTransform">
+ <Setter.Value>
+ <ScaleTransform ScaleX="1.2" ScaleY="1.2" />
+ </Setter.Value>
+ </Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </material:PackIcon.Style>
+ </material:PackIcon>
+ <Canvas IsHitTestVisible="False">
+ <Grid Width="{Binding RelativeSource={RelativeSource AncestorType=Canvas},Path=ActualWidth}" Height="{Binding RelativeSource={RelativeSource AncestorType=Canvas},Path=ActualHeight}">
+ <Ellipse x:Name="ellipse" Fill="White" RenderTransformOrigin="0.5,0.5">
+ <Ellipse.Style>
+ <Style TargetType="Ellipse">
+ <Setter Property="Opacity" Value="0.2"></Setter>
+ <Setter Property="RenderTransform">
+ <Setter.Value>
+ <ScaleTransform ScaleX="0" ScaleY="0" />
+ </Setter.Value>
+ </Setter>
+ <Setter Property="Visibility" Value="Hidden"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Button},Path=IsMouseOver}" Value="True">
+ <Setter Property="Visibility" Value="Visible"></Setter>
+ <DataTrigger.EnterActions>
+ <BeginStoryboard>
+ <Storyboard>
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" From="0" To="4" Duration="00:00:0.5" DecelerationRatio="0.8" />
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" From="0" To="4" Duration="00:00:0.5" DecelerationRatio="0.8" />
+ <DoubleAnimation Storyboard.TargetProperty="Opacity" From="0.2" To="0.001" Duration="00:00:0.5" DecelerationRatio="0.8" />
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Ellipse.Style>
+ </Ellipse>
+ </Grid>
+ </Canvas>
+ </Grid>
</DockPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
+ <Style x:Key="FSE_IconButton_Flat_Pressed_Highlight" TargetType="{x:Type local:IconButton}" BasedOn="{StaticResource {x:Type local:IconButton}}">
+ <Setter Property="FocusVisualStyle" Value="{x:Null}"></Setter>
+ <Setter Property="Cursor" Value="Hand"></Setter>
+ <Setter Property="Opacity" Value="1"></Setter>
+ <Setter Property="Padding" Value="0"></Setter>
+ <Setter Property="Foreground" Value="{StaticResource FSE_PrimaryForegroundBrush}"></Setter>
+ <Setter Property="material:RippleAssist.IsDisabled" Value="True"></Setter>
+ <Setter Property="ContentTemplate">
+ <Setter.Value>
+ <DataTemplate>
+ <DockPanel>
+ <ContentPresenter Margin="5 0 0 0" DockPanel.Dock="Right" Content="{Binding}" VerticalAlignment="Center" />
+ <Grid Background="Transparent">
+ <material:PackIcon IsHitTestVisible="False" RenderTransformOrigin="0.5, 0.5" Kind="{Binding RelativeSource={RelativeSource AncestorType=local:IconButton},Path=Icon}" Width="Auto" Height="Auto">
+ <material:PackIcon.Style>
+ <Style TargetType="material:PackIcon">
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Button},Path=IsMouseOver}" Value="True">
+ <Setter Property="Opacity" Value="0.6" />
+ </DataTrigger>
+ <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Button},Path=IsPressed}" Value="True">
+ <Setter Property="Opacity" Value="1" />
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </material:PackIcon.Style>
+ </material:PackIcon>
+ </Grid>
+ </DockPanel>
+ </DataTemplate>
+ </Setter.Value>
+ </Setter>
+ <Style.Triggers>
+ <Trigger Property="IsPressed" Value="True">
+ <Setter Property="Foreground" Value="{StaticResource FSE_PrimaryAccentBrush}"></Setter>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+
</ResourceDictionary> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/IconRepeatButton.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/IconRepeatButton.cs
new file mode 100644
index 000000000..bf3f69287
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/IconRepeatButton.cs
@@ -0,0 +1,35 @@
+using MaterialDesignThemes.Wpf;
+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;
+
+namespace Tango.FSE.Common.Controls
+{
+ public class IconRepeatButton : RepeatButton
+ {
+ public PackIconKind Icon
+ {
+ get { return (PackIconKind)GetValue(IconProperty); }
+ set { SetValue(IconProperty, value); }
+ }
+ public static readonly DependencyProperty IconProperty =
+ DependencyProperty.Register("Icon", typeof(PackIconKind), typeof(IconRepeatButton), new PropertyMetadata(PackIconKind.BorderNone));
+
+ static IconRepeatButton()
+ {
+ DefaultStyleKeyProperty.OverrideMetadata(typeof(IconRepeatButton), new FrameworkPropertyMetadata(typeof(IconRepeatButton)));
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/IconRepeatButton.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/IconRepeatButton.xaml
new file mode 100644
index 000000000..db20acd64
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/IconRepeatButton.xaml
@@ -0,0 +1,116 @@
+<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:local="clr-namespace:Tango.FSE.Common.Controls">
+
+
+ <Style TargetType="{x:Type local:IconRepeatButton}" BasedOn="{StaticResource MaterialDesignToolForegroundButton}">
+ <Setter Property="FocusVisualStyle" Value="{x:Null}"></Setter>
+ <Setter Property="Cursor" Value="Hand"></Setter>
+ <Setter Property="material:RippleAssist.IsDisabled" Value="True"></Setter>
+ <Setter Property="ContentTemplate">
+ <Setter.Value>
+ <DataTemplate>
+ <DockPanel>
+ <ContentPresenter Margin="5 0 0 0" DockPanel.Dock="Right" Content="{Binding}" VerticalAlignment="Center" />
+ <Grid Background="Transparent">
+ <material:PackIcon IsHitTestVisible="False" RenderTransformOrigin="0.5, 0.5" Kind="{Binding RelativeSource={RelativeSource AncestorType=local:IconRepeatButton},Path=Icon}" Width="Auto" Height="Auto">
+ <material:PackIcon.Style>
+ <Style TargetType="material:PackIcon">
+ <Setter Property="RenderTransform">
+ <Setter.Value>
+ <ScaleTransform ScaleX="1" ScaleY="1" />
+ </Setter.Value>
+ </Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=RepeatButton},Path=IsMouseOver}" Value="True">
+ <Setter Property="RenderTransform">
+ <Setter.Value>
+ <ScaleTransform ScaleX="1.2" ScaleY="1.2" />
+ </Setter.Value>
+ </Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </material:PackIcon.Style>
+ </material:PackIcon>
+ <Canvas IsHitTestVisible="False">
+ <Grid Width="{Binding RelativeSource={RelativeSource AncestorType=Canvas},Path=ActualWidth}" Height="{Binding RelativeSource={RelativeSource AncestorType=Canvas},Path=ActualHeight}">
+ <Ellipse x:Name="ellipse" Fill="White" RenderTransformOrigin="0.5,0.5">
+ <Ellipse.Style>
+ <Style TargetType="Ellipse">
+ <Setter Property="Opacity" Value="0.2"></Setter>
+ <Setter Property="RenderTransform">
+ <Setter.Value>
+ <ScaleTransform ScaleX="0" ScaleY="0" />
+ </Setter.Value>
+ </Setter>
+ <Setter Property="Visibility" Value="Hidden"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=RepeatButton},Path=IsMouseOver}" Value="True">
+ <Setter Property="Visibility" Value="Visible"></Setter>
+ <DataTrigger.EnterActions>
+ <BeginStoryboard>
+ <Storyboard>
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" From="0" To="4" Duration="00:00:0.5" DecelerationRatio="0.8" />
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" From="0" To="4" Duration="00:00:0.5" DecelerationRatio="0.8" />
+ <DoubleAnimation Storyboard.TargetProperty="Opacity" From="0.2" To="0.001" Duration="00:00:0.5" DecelerationRatio="0.8" />
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Ellipse.Style>
+ </Ellipse>
+ </Grid>
+ </Canvas>
+ </Grid>
+ </DockPanel>
+ </DataTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Style x:Key="FSE_RepeatIconButton_Flat_Pressed_Highlight" TargetType="{x:Type local:IconRepeatButton}" BasedOn="{StaticResource {x:Type local:IconRepeatButton}}">
+ <Setter Property="FocusVisualStyle" Value="{x:Null}"></Setter>
+ <Setter Property="Cursor" Value="Hand"></Setter>
+ <Setter Property="Opacity" Value="1"></Setter>
+ <Setter Property="Padding" Value="0"></Setter>
+ <Setter Property="Foreground" Value="{StaticResource FSE_PrimaryForegroundBrush}"></Setter>
+ <Setter Property="material:RippleAssist.IsDisabled" Value="True"></Setter>
+ <Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
+ <Setter Property="VerticalContentAlignment" Value="Stretch"></Setter>
+ <Setter Property="ContentTemplate">
+ <Setter.Value>
+ <DataTemplate>
+ <DockPanel>
+ <ContentPresenter Visibility="{Binding Converter={StaticResource IsNullToVisibilityConverter}}" Margin="5 0 0 0" DockPanel.Dock="Right" Content="{Binding}" VerticalAlignment="Center" />
+ <Grid Background="Transparent">
+ <material:PackIcon VerticalAlignment="Stretch" IsHitTestVisible="False" RenderTransformOrigin="0.5, 0.5" Kind="{Binding RelativeSource={RelativeSource AncestorType=local:IconRepeatButton},Path=Icon}" Width="Auto" Height="Auto">
+ <material:PackIcon.Style>
+ <Style TargetType="material:PackIcon">
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=RepeatButton},Path=IsMouseOver}" Value="True">
+ <Setter Property="Opacity" Value="0.6" />
+ </DataTrigger>
+ <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=RepeatButton},Path=IsPressed}" Value="True">
+ <Setter Property="Opacity" Value="1" />
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </material:PackIcon.Style>
+ </material:PackIcon>
+ </Grid>
+ </DockPanel>
+ </DataTemplate>
+ </Setter.Value>
+ </Setter>
+ <Style.Triggers>
+ <Trigger Property="IsPressed" Value="True">
+ <Setter Property="Foreground" Value="{StaticResource FSE_PrimaryAccentBrush}"></Setter>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+
+</ResourceDictionary> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs
index c4b27e530..5e4645c7f 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs
@@ -439,6 +439,27 @@ namespace Tango.FSE.Common
}
/// <summary>
+ /// Represents an FSE view model with a auto ModuleSettings property.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <seealso cref="Tango.FSE.Common.FSEViewModel" />
+ public abstract class FSEViewModelWithModuleSettings<T> : FSEViewModel where T : SettingsBase
+ {
+ /// <summary>
+ /// Gets or sets the module settings.
+ /// </summary>
+ public T ModuleSettings { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FSEViewModelWithModuleSettings{T}"/> class.
+ /// </summary>
+ public FSEViewModelWithModuleSettings()
+ {
+ ModuleSettings = SettingsManager.Default.GetOrCreate<T>();
+ }
+ }
+
+ /// <summary>
/// Represents a FSE view model base class a View property as an instance of a <see cref="IFSEView"/> contract.
/// </summary>
/// <typeparam name="T"></typeparam>
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Fonts/angelina.TTF b/Software/Visual_Studio/FSE/Tango.FSE.Common/Fonts/angelina.TTF
new file mode 100644
index 000000000..fe880ab91
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Fonts/angelina.TTF
Binary files differ
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Fonts/indie.ttf b/Software/Visual_Studio/FSE/Tango.FSE.Common/Fonts/indie.ttf
new file mode 100644
index 000000000..1070aacda
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Fonts/indie.ttf
Binary files differ
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Images/shadow_left.png b/Software/Visual_Studio/FSE/Tango.FSE.Common/Images/shadow_left.png
new file mode 100644
index 000000000..3e7b2cb55
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Images/shadow_left.png
Binary files differ
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Images/shadow_right.png b/Software/Visual_Studio/FSE/Tango.FSE.Common/Images/shadow_right.png
new file mode 100644
index 000000000..bb217b671
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Images/shadow_right.png
Binary files differ
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Images/shadow_top.png b/Software/Visual_Studio/FSE/Tango.FSE.Common/Images/shadow_top.png
new file mode 100644
index 000000000..12f6ef010
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Images/shadow_top.png
Binary files differ
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Controls.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Controls.xaml
index d25bcdaef..f956aa582 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Controls.xaml
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Controls.xaml
@@ -4,6 +4,7 @@
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Controls/IconButton.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Controls/IconRepeatButton.xaml" />
<ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Controls/TextIconButton.xaml" />
<ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Controls/FSETabControl.xaml" />
<ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Controls/FSEPanel.xaml" />
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Images.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Images.xaml
index ef3cb683e..91bf1816f 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Images.xaml
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Images.xaml
@@ -13,4 +13,8 @@
<BitmapImage x:Key="FSE_Screw" UriSource="../Images/screw.png" />
<BitmapImage x:Key="FSE_Arrow_Right" UriSource="../Images/arrow_right.png" />
+ <BitmapImage x:Key="FSE_Shadow_Top" UriSource="../Images/shadow_top.png" />
+ <BitmapImage x:Key="FSE_Shadow_Left" UriSource="../Images/shadow_left.png" />
+ <BitmapImage x:Key="FSE_Shadow_Right" UriSource="../Images/shadow_right.png" />
+
</ResourceDictionary> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/MahApps.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/MahApps.xaml
new file mode 100644
index 000000000..deb614d8a
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/MahApps.xaml
@@ -0,0 +1,973 @@
+<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:mahShared="http://metro.mahapps.com/winfx/xaml/shared"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:commonControls="clr-namespace:Tango.FSE.Common.Controls"
+ xmlns:mdix="http://materialdesigninxaml.net/winfx/xaml/themes">
+
+ <ResourceDictionary.MergedDictionaries>
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ValidationErrorTemplate.xaml" />
+ </ResourceDictionary.MergedDictionaries>
+
+ <ContextMenu x:Key="MaterialDesignDefaultContextMenu">
+ <MenuItem Command="Cut">
+ <MenuItem.Icon>
+ <mdix:PackIcon Kind="ContentCut" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <MenuItem Command="Copy">
+ <MenuItem.Icon>
+ <mdix:PackIcon Kind="ContentCopy" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <MenuItem Command="Paste">
+ <MenuItem.Icon>
+ <mdix:PackIcon Kind="ContentPaste" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <Separator />
+ <MenuItem Command="SelectAll">
+ <MenuItem.Icon>
+ <mdix:PackIcon Kind="SelectAll" />
+ </MenuItem.Icon>
+ </MenuItem>
+ </ContextMenu>
+
+ <Style x:Key="FSE_NumericUpDown_Flat" TargetType="{x:Type mah:NumericUpDown}" BasedOn="{StaticResource {x:Type mah:NumericUpDown}}">
+ <Setter Property="Background" Value="{StaticResource FSE_PrimaryBackgroundBrush}" />
+ <Setter Property="BorderBrush" Value="{StaticResource FSE_GrayBrush}" />
+ <Setter Property="BorderThickness" Value="0 0 0 0"/>
+ <Setter Property="mah:ControlsHelper.FocusBorderBrush" Value="{DynamicResource MahApps.Brushes.TextBox.Border.Focus}" />
+ <Setter Property="mah:ControlsHelper.MouseOverBorderBrush" Value="{DynamicResource MahApps.Brushes.TextBox.Border.MouseOver}" />
+ <Setter Property="mah:TextBoxHelper.ButtonFontSize" Value="{DynamicResource MahApps.Font.Size.Button.ClearText}" />
+ <Setter Property="mah:TextBoxHelper.ButtonWidth" Value="22" />
+ <Setter Property="mah:TextBoxHelper.IsMonitoring" Value="True" />
+ <Setter Property="FocusVisualStyle" Value="{x:Null}" />
+ <Setter Property="FontFamily" Value="{StaticResource flexo}" />
+ <Setter Property="FontSize" Value="{StaticResource FSE_DefaultFontSize}" />
+ <Setter Property="Foreground" Value="{StaticResource FSE_PrimaryForegroundBrush}" />
+ <Setter Property="HorizontalAlignment" Value="Stretch" />
+ <Setter Property="HorizontalContentAlignment" Value="Stretch" />
+ <Setter Property="MinHeight" Value="26" />
+ <Setter Property="Height" Value="Auto"></Setter>
+ <Setter Property="MinWidth" Value="62" />
+ <Setter Property="Padding" Value="0" />
+ <Setter Property="VerticalAlignment" Value="Center"></Setter>
+ <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
+ <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden" />
+ <Setter Property="SnapsToDevicePixels" Value="true" />
+ <Setter Property="mdix:TextFieldAssist.UnderlineBrush" Value="{DynamicResource PrimaryHueMidBrush}" />
+ <Setter Property="mah:TextBoxHelper.UseFloatingWatermark" Value="{Binding Path=(mdix:HintAssist.IsFloating), Mode=TwoWay, RelativeSource={RelativeSource Self}}"></Setter>
+ <Setter Property="mah:TextBoxHelper.Watermark" Value="{Binding Path=(mdix:HintAssist.Hint), Mode=TwoWay, RelativeSource={RelativeSource Self}}"></Setter>
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="{x:Type mah:NumericUpDown}">
+ <Border x:Name="Base" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{Binding Path=(mdix:HintAssist.Hint), Mode=TwoWay, RelativeSource={RelativeSource AncestorType=mah:NumericUpDown}}">
+ <Grid SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
+ <Border />
+ <Grid Margin="{TemplateBinding BorderThickness}">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition x:Name="PART_LeftColumn" Width="*" />
+ <ColumnDefinition x:Name="PART_MiddleColumn" Width="Auto" />
+ <ColumnDefinition x:Name="PART_RightColumn" Width="Auto" />
+ </Grid.ColumnDefinitions>
+ <Grid.RowDefinitions>
+ <RowDefinition />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <TextBox x:Name="PART_TextBox"
+ Grid.Column="0"
+ Grid.Row="0"
+ MinWidth="20"
+ MinHeight="0"
+ Margin="0"
+ Padding="0"
+ HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
+ HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
+ VerticalAlignment="{TemplateBinding VerticalAlignment}"
+ VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
+ mah:ControlsHelper.DisabledVisualElementVisibility="Collapsed"
+ mah:TextBoxHelper.ButtonContent="{TemplateBinding mah:TextBoxHelper.ButtonContent}"
+ mah:TextBoxHelper.ButtonContentTemplate="{TemplateBinding mah:TextBoxHelper.ButtonContentTemplate}"
+ mah:TextBoxHelper.ButtonFontFamily="{TemplateBinding mah:TextBoxHelper.ButtonFontFamily}"
+ mah:TextBoxHelper.ButtonFontSize="{TemplateBinding mah:TextBoxHelper.ButtonFontSize}"
+ mah:TextBoxHelper.ButtonWidth="{TemplateBinding mah:TextBoxHelper.ButtonWidth}"
+ mah:TextBoxHelper.ButtonsAlignment="{TemplateBinding ButtonsAlignment}"
+ mah:TextBoxHelper.ClearTextButton="{TemplateBinding mah:TextBoxHelper.ClearTextButton}"
+ mah:TextBoxHelper.HasText="{TemplateBinding mah:TextBoxHelper.HasText}"
+ mah:TextBoxHelper.SelectAllOnFocus="{TemplateBinding mah:TextBoxHelper.SelectAllOnFocus}"
+ mah:TextBoxHelper.UseFloatingWatermark="{TemplateBinding mah:TextBoxHelper.UseFloatingWatermark}"
+ mah:TextBoxHelper.Watermark="{TemplateBinding mah:TextBoxHelper.Watermark}"
+ mah:TextBoxHelper.WatermarkAlignment="{TemplateBinding mah:TextBoxHelper.WatermarkAlignment}"
+ mah:TextBoxHelper.WatermarkTrimming="{TemplateBinding mah:TextBoxHelper.WatermarkTrimming}"
+ mdix:TextFieldAssist.DecorationVisibility="Collapsed"
+ Background="{x:Null}"
+ ContextMenu="{StaticResource MaterialDesignDefaultContextMenu}"
+ FocusVisualStyle="{x:Null}"
+ TextAlignment="Left"
+ Focusable="{TemplateBinding Focusable}"
+ BorderThickness="0"
+ FontFamily="{TemplateBinding FontFamily}"
+ FontSize="{TemplateBinding FontSize}"
+ Foreground="{TemplateBinding Foreground}"
+ HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
+ IsTabStop="{TemplateBinding IsTabStop}"
+ SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
+ TabIndex="{TemplateBinding TabIndex}"
+ VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" />
+
+ <commonControls:IconRepeatButton Style="{StaticResource FSE_RepeatIconButton_Flat_Pressed_Highlight}" x:Name="PART_NumericUp"
+ Grid.Column="1"
+ Grid.Row="0"
+ Width="{TemplateBinding UpDownButtonsWidth}"
+ VerticalAlignment="Center"
+ Cursor="Hand"
+ Delay="{TemplateBinding Delay}"
+ IsTabStop="False"
+ Icon="ChevronUp">
+ </commonControls:IconRepeatButton>
+ <commonControls:IconRepeatButton Style="{StaticResource FSE_RepeatIconButton_Flat_Pressed_Highlight}" x:Name="PART_NumericDown"
+ Grid.Column="2"
+ Grid.Row="0"
+ Width="{TemplateBinding UpDownButtonsWidth}"
+ VerticalAlignment="Center"
+ Cursor="Hand"
+ Delay="{TemplateBinding Delay}"
+ IsTabStop="False"
+ Icon="ChevronDown">
+ </commonControls:IconRepeatButton>
+
+ <mdix:Underline
+ x:Name="Underline"
+ Grid.Column="0"
+ Grid.Row="1"
+ Grid.ColumnSpan="3"
+ Height="1"
+ Visibility="Collapsed"
+ CornerRadius="{Binding Path=(mdix:TextFieldAssist.UnderlineCornerRadius), RelativeSource={RelativeSource TemplatedParent}}"
+ Background="{Binding Path=(mdix:TextFieldAssist.UnderlineBrush), RelativeSource={RelativeSource TemplatedParent}}" />
+ </Grid>
+ <Border x:Name="DisabledVisualElement"
+ Background="{DynamicResource MahApps.Brushes.Control.Disabled}"
+ BorderBrush="{DynamicResource MahApps.Brushes.Control.Disabled}"
+ BorderThickness="{TemplateBinding BorderThickness}"
+ CornerRadius="{TemplateBinding mah:ControlsHelper.CornerRadius}"
+ IsHitTestVisible="False"
+ Opacity="0"
+ SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
+ Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ControlsHelper.DisabledVisualElementVisibility), Mode=OneWay}" />
+ </Grid>
+ </Border>
+ <ControlTemplate.Triggers>
+ <MultiTrigger>
+ <MultiTrigger.Conditions>
+ <Condition Property="ButtonsAlignment" Value="Left" />
+ </MultiTrigger.Conditions>
+ <Setter TargetName="PART_LeftColumn" Property="Width" Value="Auto" />
+ <Setter TargetName="PART_MiddleColumn" Property="Width" Value="Auto" />
+ <Setter TargetName="PART_NumericDown" Property="Grid.Column" Value="1" />
+ <Setter TargetName="PART_NumericUp" Property="Grid.Column" Value="0" />
+ <Setter TargetName="PART_RightColumn" Property="Width" Value="*" />
+ <Setter TargetName="PART_TextBox" Property="Grid.Column" Value="2" />
+ </MultiTrigger>
+ <MultiTrigger>
+ <MultiTrigger.Conditions>
+ <Condition Property="ButtonsAlignment" Value="Left" />
+ </MultiTrigger.Conditions>
+ <Setter TargetName="PART_LeftColumn" Property="Width" Value="Auto" />
+ <Setter TargetName="PART_MiddleColumn" Property="Width" Value="Auto" />
+ <Setter TargetName="PART_NumericDown" Property="Grid.Column" Value="0" />
+ <Setter TargetName="PART_NumericUp" Property="Grid.Column" Value="1" />
+ <Setter TargetName="PART_RightColumn" Property="Width" Value="*" />
+ <Setter TargetName="PART_TextBox" Property="Grid.Column" Value="2" />
+ </MultiTrigger>
+ <MultiTrigger>
+ <MultiTrigger.Conditions>
+ <Condition Property="ButtonsAlignment" Value="Right" />
+ </MultiTrigger.Conditions>
+ <Setter TargetName="PART_LeftColumn" Property="Width" Value="*" />
+ <Setter TargetName="PART_MiddleColumn" Property="Width" Value="Auto" />
+ <Setter TargetName="PART_NumericDown" Property="Grid.Column" Value="1" />
+ <Setter TargetName="PART_NumericUp" Property="Grid.Column" Value="2" />
+ <Setter TargetName="PART_RightColumn" Property="Width" Value="Auto" />
+ <Setter TargetName="PART_TextBox" Property="Grid.Column" Value="0" />
+ </MultiTrigger>
+
+ <Trigger Property="IsEnabled" Value="False">
+ <Setter TargetName="DisabledVisualElement" Property="Opacity" Value="0.6" />
+ </Trigger>
+ <Trigger Property="IsReadOnly" Value="True">
+
+ </Trigger>
+ <MultiTrigger>
+ <MultiTrigger.Conditions>
+ <Condition Property="IsReadOnly" Value="False" />
+ <Condition Property="InterceptManualEnter" Value="False" />
+ </MultiTrigger.Conditions>
+ <Setter TargetName="PART_TextBox" Property="IsReadOnly" Value="True" />
+ </MultiTrigger>
+ <Trigger Property="IsMouseOver" Value="True">
+ <Setter TargetName="Base" Property="BorderBrush" Value="{StaticResource FSE_PrimaryAccentBrush}" />
+ </Trigger>
+ <Trigger SourceName="PART_TextBox" Property="IsFocused" Value="True">
+ <Setter TargetName="Base" Property="BorderBrush" Value="{StaticResource FSE_PrimaryAccentBrush}" />
+ </Trigger>
+ <Trigger SourceName="PART_NumericUp" Property="IsFocused" Value="True">
+ <Setter TargetName="Base" Property="BorderBrush" Value="{StaticResource FSE_PrimaryAccentBrush}" />
+ </Trigger>
+ <Trigger SourceName="PART_NumericDown" Property="IsFocused" Value="True">
+ <Setter TargetName="Base" Property="BorderBrush" Value="{StaticResource FSE_PrimaryAccentBrush}" />
+ </Trigger>
+ <Trigger Property="IsKeyboardFocusWithin" Value="True">
+ <Setter TargetName="Underline" Property="IsActive" Value="True"/>
+ </Trigger>
+ <Trigger Property="HideUpDownButtons" Value="True">
+ <Setter TargetName="PART_NumericDown" Property="Visibility" Value="Collapsed" />
+ <Setter TargetName="PART_NumericUp" Property="Visibility" Value="Collapsed" />
+ </Trigger>
+ </ControlTemplate.Triggers>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ <Setter Property="TextAlignment" Value="Right" />
+ <Setter Property="UpDownButtonsWidth" Value="22" />
+ <Setter Property="Validation.ErrorTemplate" Value="{StaticResource MaterialDesignValidationErrorTemplate}" />
+ </Style>
+
+ <Style x:Key="FSE_NumericUpDown_Flat_Dark" TargetType="{x:Type mah:NumericUpDown}" BasedOn="{StaticResource {x:Type mah:NumericUpDown}}">
+ <Setter Property="Background" Value="{StaticResource FSE_PrimaryBackgroundDarkBrush}" />
+ <Setter Property="BorderBrush" Value="{StaticResource FSE_GrayBrush}" />
+ <Setter Property="BorderThickness" Value="0 0 0 0"/>
+ <Setter Property="mah:ControlsHelper.FocusBorderBrush" Value="{DynamicResource MahApps.Brushes.TextBox.Border.Focus}" />
+ <Setter Property="mah:ControlsHelper.MouseOverBorderBrush" Value="{DynamicResource MahApps.Brushes.TextBox.Border.MouseOver}" />
+ <Setter Property="mah:TextBoxHelper.ButtonFontSize" Value="{DynamicResource MahApps.Font.Size.Button.ClearText}" />
+ <Setter Property="mah:TextBoxHelper.ButtonWidth" Value="22" />
+ <Setter Property="mah:TextBoxHelper.IsMonitoring" Value="True" />
+ <Setter Property="FocusVisualStyle" Value="{x:Null}" />
+ <Setter Property="FontFamily" Value="{StaticResource flexo}" />
+ <Setter Property="FontSize" Value="{StaticResource FSE_DefaultFontSize}" />
+ <Setter Property="Foreground" Value="{StaticResource FSE_PrimaryForegroundBrush}" />
+ <Setter Property="HorizontalAlignment" Value="Stretch" />
+ <Setter Property="HorizontalContentAlignment" Value="Stretch" />
+ <Setter Property="MinHeight" Value="26" />
+ <Setter Property="Height" Value="Auto"></Setter>
+ <Setter Property="MinWidth" Value="62" />
+ <Setter Property="Padding" Value="0" />
+ <Setter Property="mdix:ButtonAssist.CornerRadius" Value="5"></Setter>
+ <Setter Property="VerticalAlignment" Value="Center"></Setter>
+ <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
+ <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden" />
+ <Setter Property="SnapsToDevicePixels" Value="true" />
+ <Setter Property="mdix:TextFieldAssist.UnderlineBrush" Value="{DynamicResource PrimaryHueMidBrush}" />
+ <Setter Property="mah:TextBoxHelper.UseFloatingWatermark" Value="{Binding Path=(mdix:HintAssist.IsFloating), Mode=TwoWay, RelativeSource={RelativeSource Self}}"></Setter>
+ <Setter Property="mah:TextBoxHelper.Watermark" Value="{Binding Path=(mdix:HintAssist.Hint), Mode=TwoWay, RelativeSource={RelativeSource Self}}"></Setter>
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="{x:Type mah:NumericUpDown}">
+ <Border x:Name="Base" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{Binding Path=(mdix:ButtonAssist.CornerRadius), Mode=OneWay, RelativeSource={RelativeSource AncestorType=mah:NumericUpDown}}">
+ <Grid SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
+ <Border />
+ <Grid Margin="{TemplateBinding BorderThickness}">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition x:Name="PART_LeftColumn" Width="*" />
+ <ColumnDefinition x:Name="PART_MiddleColumn" Width="Auto" />
+ <ColumnDefinition x:Name="PART_RightColumn" Width="Auto" />
+ </Grid.ColumnDefinitions>
+ <Grid.RowDefinitions>
+ <RowDefinition />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <TextBox x:Name="PART_TextBox"
+ Grid.Column="0"
+ Grid.Row="0"
+ MinWidth="20"
+ MinHeight="0"
+ Margin="0"
+ Padding="0"
+ CaretBrush="{TemplateBinding Foreground}"
+ HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
+ HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
+ VerticalAlignment="{TemplateBinding VerticalAlignment}"
+ VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
+ mah:ControlsHelper.DisabledVisualElementVisibility="Collapsed"
+ mah:TextBoxHelper.ButtonContent="{TemplateBinding mah:TextBoxHelper.ButtonContent}"
+ mah:TextBoxHelper.ButtonContentTemplate="{TemplateBinding mah:TextBoxHelper.ButtonContentTemplate}"
+ mah:TextBoxHelper.ButtonFontFamily="{TemplateBinding mah:TextBoxHelper.ButtonFontFamily}"
+ mah:TextBoxHelper.ButtonFontSize="{TemplateBinding mah:TextBoxHelper.ButtonFontSize}"
+ mah:TextBoxHelper.ButtonWidth="{TemplateBinding mah:TextBoxHelper.ButtonWidth}"
+ mah:TextBoxHelper.ButtonsAlignment="{TemplateBinding ButtonsAlignment}"
+ mah:TextBoxHelper.ClearTextButton="{TemplateBinding mah:TextBoxHelper.ClearTextButton}"
+ mah:TextBoxHelper.HasText="{TemplateBinding mah:TextBoxHelper.HasText}"
+ mah:TextBoxHelper.SelectAllOnFocus="{TemplateBinding mah:TextBoxHelper.SelectAllOnFocus}"
+ mah:TextBoxHelper.UseFloatingWatermark="{TemplateBinding mah:TextBoxHelper.UseFloatingWatermark}"
+ mah:TextBoxHelper.Watermark="{TemplateBinding mah:TextBoxHelper.Watermark}"
+ mah:TextBoxHelper.WatermarkAlignment="{TemplateBinding mah:TextBoxHelper.WatermarkAlignment}"
+ mah:TextBoxHelper.WatermarkTrimming="{TemplateBinding mah:TextBoxHelper.WatermarkTrimming}"
+ mdix:TextFieldAssist.DecorationVisibility="Collapsed"
+ Background="{x:Null}"
+ ContextMenu="{StaticResource MaterialDesignDefaultContextMenu}"
+ FocusVisualStyle="{x:Null}"
+ TextAlignment="Left"
+ Focusable="{TemplateBinding Focusable}"
+ BorderThickness="0"
+ FontFamily="{TemplateBinding FontFamily}"
+ FontSize="{TemplateBinding FontSize}"
+ Foreground="{TemplateBinding Foreground}"
+ HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
+ IsTabStop="{TemplateBinding IsTabStop}"
+ SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
+ TabIndex="{TemplateBinding TabIndex}"
+ VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" />
+
+ <commonControls:IconRepeatButton Style="{StaticResource FSE_RepeatIconButton_Flat_Pressed_Highlight}" x:Name="PART_NumericUp"
+ Grid.Column="1"
+ Grid.Row="0"
+ Width="{TemplateBinding UpDownButtonsWidth}"
+ VerticalAlignment="Center"
+ Cursor="Hand"
+ Delay="{TemplateBinding Delay}"
+ IsTabStop="False"
+ Icon="ChevronUp">
+ </commonControls:IconRepeatButton>
+ <commonControls:IconRepeatButton Style="{StaticResource FSE_RepeatIconButton_Flat_Pressed_Highlight}" x:Name="PART_NumericDown"
+ Grid.Column="2"
+ Grid.Row="0"
+ Width="{TemplateBinding UpDownButtonsWidth}"
+ VerticalAlignment="Center"
+ Cursor="Hand"
+ Delay="{TemplateBinding Delay}"
+ IsTabStop="False"
+ Icon="ChevronDown">
+ </commonControls:IconRepeatButton>
+
+ <mdix:Underline
+ x:Name="Underline"
+ Grid.Column="0"
+ Grid.Row="1"
+ Grid.ColumnSpan="3"
+ Height="1"
+ Visibility="Collapsed"
+ CornerRadius="{Binding Path=(mdix:TextFieldAssist.UnderlineCornerRadius), RelativeSource={RelativeSource TemplatedParent}}"
+ Background="{Binding Path=(mdix:TextFieldAssist.UnderlineBrush), RelativeSource={RelativeSource TemplatedParent}}" />
+ </Grid>
+ <Border x:Name="DisabledVisualElement"
+ Background="{DynamicResource MahApps.Brushes.Control.Disabled}"
+ BorderBrush="{DynamicResource MahApps.Brushes.Control.Disabled}"
+ BorderThickness="{TemplateBinding BorderThickness}"
+ CornerRadius="{TemplateBinding mah:ControlsHelper.CornerRadius}"
+ IsHitTestVisible="False"
+ Opacity="0"
+ SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
+ Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ControlsHelper.DisabledVisualElementVisibility), Mode=OneWay}" />
+ </Grid>
+ </Border>
+ <ControlTemplate.Triggers>
+ <MultiTrigger>
+ <MultiTrigger.Conditions>
+ <Condition Property="ButtonsAlignment" Value="Left" />
+ </MultiTrigger.Conditions>
+ <Setter TargetName="PART_LeftColumn" Property="Width" Value="Auto" />
+ <Setter TargetName="PART_MiddleColumn" Property="Width" Value="Auto" />
+ <Setter TargetName="PART_NumericDown" Property="Grid.Column" Value="1" />
+ <Setter TargetName="PART_NumericUp" Property="Grid.Column" Value="0" />
+ <Setter TargetName="PART_RightColumn" Property="Width" Value="*" />
+ <Setter TargetName="PART_TextBox" Property="Grid.Column" Value="2" />
+ </MultiTrigger>
+ <MultiTrigger>
+ <MultiTrigger.Conditions>
+ <Condition Property="ButtonsAlignment" Value="Left" />
+ </MultiTrigger.Conditions>
+ <Setter TargetName="PART_LeftColumn" Property="Width" Value="Auto" />
+ <Setter TargetName="PART_MiddleColumn" Property="Width" Value="Auto" />
+ <Setter TargetName="PART_NumericDown" Property="Grid.Column" Value="0" />
+ <Setter TargetName="PART_NumericUp" Property="Grid.Column" Value="1" />
+ <Setter TargetName="PART_RightColumn" Property="Width" Value="*" />
+ <Setter TargetName="PART_TextBox" Property="Grid.Column" Value="2" />
+ </MultiTrigger>
+ <MultiTrigger>
+ <MultiTrigger.Conditions>
+ <Condition Property="ButtonsAlignment" Value="Right" />
+ </MultiTrigger.Conditions>
+ <Setter TargetName="PART_LeftColumn" Property="Width" Value="*" />
+ <Setter TargetName="PART_MiddleColumn" Property="Width" Value="Auto" />
+ <Setter TargetName="PART_NumericDown" Property="Grid.Column" Value="1" />
+ <Setter TargetName="PART_NumericUp" Property="Grid.Column" Value="2" />
+ <Setter TargetName="PART_RightColumn" Property="Width" Value="Auto" />
+ <Setter TargetName="PART_TextBox" Property="Grid.Column" Value="0" />
+ </MultiTrigger>
+
+ <Trigger Property="IsEnabled" Value="False">
+ <Setter TargetName="DisabledVisualElement" Property="Opacity" Value="0.6" />
+ </Trigger>
+ <Trigger Property="IsReadOnly" Value="True">
+
+ </Trigger>
+ <MultiTrigger>
+ <MultiTrigger.Conditions>
+ <Condition Property="IsReadOnly" Value="False" />
+ <Condition Property="InterceptManualEnter" Value="False" />
+ </MultiTrigger.Conditions>
+ <Setter TargetName="PART_TextBox" Property="IsReadOnly" Value="True" />
+ </MultiTrigger>
+ <Trigger Property="IsMouseOver" Value="True">
+ <!--<Setter TargetName="Base" Property="BorderBrush" Value="{StaticResource FSE_PrimaryAccentBrush}" />-->
+ </Trigger>
+ <Trigger SourceName="PART_TextBox" Property="IsFocused" Value="True">
+ <!--<Setter TargetName="Base" Property="BorderBrush" Value="{StaticResource FSE_PrimaryAccentBrush}" />-->
+ </Trigger>
+ <Trigger SourceName="PART_NumericUp" Property="IsFocused" Value="True">
+ <!--<Setter TargetName="Base" Property="BorderBrush" Value="{StaticResource FSE_PrimaryAccentBrush}" />-->
+ </Trigger>
+ <Trigger SourceName="PART_NumericDown" Property="IsFocused" Value="True">
+ <!--<Setter TargetName="Base" Property="BorderBrush" Value="{StaticResource FSE_PrimaryAccentBrush}" />-->
+ </Trigger>
+ <Trigger Property="IsKeyboardFocusWithin" Value="True">
+ <Setter TargetName="Underline" Property="IsActive" Value="True"/>
+ </Trigger>
+ <Trigger Property="HideUpDownButtons" Value="True">
+ <Setter TargetName="PART_NumericDown" Property="Visibility" Value="Collapsed" />
+ <Setter TargetName="PART_NumericUp" Property="Visibility" Value="Collapsed" />
+ </Trigger>
+ </ControlTemplate.Triggers>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ <Setter Property="TextAlignment" Value="Right" />
+ <Setter Property="UpDownButtonsWidth" Value="22" />
+ <Setter Property="Validation.ErrorTemplate" Value="{StaticResource MaterialDesignValidationErrorTemplate}" />
+ </Style>
+
+
+
+ <Style TargetType="{x:Type mah:NumericUpDown}">
+ <Setter Property="Background" Value="Transparent" />
+ <Setter Property="BorderBrush" Value="{StaticResource FSE_GrayBrush}" />
+ <Setter Property="BorderThickness" Value="0 0 0 1"/>
+ <Setter Property="mah:ControlsHelper.FocusBorderBrush" Value="{DynamicResource MahApps.Brushes.TextBox.Border.Focus}" />
+ <Setter Property="mah:ControlsHelper.MouseOverBorderBrush" Value="{DynamicResource MahApps.Brushes.TextBox.Border.MouseOver}" />
+ <Setter Property="mah:TextBoxHelper.ButtonFontSize" Value="{DynamicResource MahApps.Font.Size.Button.ClearText}" />
+ <Setter Property="mah:TextBoxHelper.ButtonWidth" Value="22" />
+ <Setter Property="mah:TextBoxHelper.IsMonitoring" Value="True" />
+ <Setter Property="FocusVisualStyle" Value="{x:Null}" />
+ <Setter Property="FontFamily" Value="{StaticResource flexo}" />
+ <Setter Property="Height" Value="Auto"></Setter>
+ <Setter Property="FontSize" Value="{StaticResource FSE_DefaultFontSize}" />
+ <Setter Property="Foreground" Value="{StaticResource FSE_PrimaryForegroundBrush}" />
+ <Setter Property="HorizontalAlignment" Value="Stretch" />
+ <Setter Property="HorizontalContentAlignment" Value="Stretch" />
+ <Setter Property="MinHeight" Value="26" />
+ <Setter Property="MinWidth" Value="62" />
+ <Setter Property="Padding" Value="0" />
+ <Setter Property="VerticalAlignment" Value="Center"></Setter>
+ <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
+ <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden" />
+ <Setter Property="SnapsToDevicePixels" Value="true" />
+ <Setter Property="mdix:TextFieldAssist.UnderlineBrush" Value="{DynamicResource PrimaryHueMidBrush}" />
+ <Setter Property="mah:TextBoxHelper.UseFloatingWatermark" Value="{Binding Path=(mdix:HintAssist.IsFloating), Mode=TwoWay, RelativeSource={RelativeSource Self}}"></Setter>
+ <Setter Property="mah:TextBoxHelper.Watermark" Value="{Binding Path=(mdix:HintAssist.Hint), Mode=TwoWay, RelativeSource={RelativeSource Self}}"></Setter>
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="{x:Type mah:NumericUpDown}">
+ <Grid SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
+ <Border x:Name="Base"
+ Background="{TemplateBinding Background}"
+ BorderBrush="{TemplateBinding BorderBrush}"
+ BorderThickness="{TemplateBinding BorderThickness}"
+ CornerRadius="{TemplateBinding mah:ControlsHelper.CornerRadius}"
+ SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
+ <Grid Margin="{TemplateBinding BorderThickness}">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition x:Name="PART_LeftColumn" Width="*" />
+ <ColumnDefinition x:Name="PART_MiddleColumn" Width="Auto" />
+ <ColumnDefinition x:Name="PART_RightColumn" Width="Auto" />
+ </Grid.ColumnDefinitions>
+ <Grid.RowDefinitions>
+ <RowDefinition />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <TextBox x:Name="PART_TextBox"
+ Grid.Column="0"
+ Grid.Row="0"
+ MinWidth="20"
+ MinHeight="0"
+ Margin="0"
+ Padding="{TemplateBinding Padding}"
+ HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
+ HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
+ VerticalAlignment="{TemplateBinding VerticalAlignment}"
+ VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
+ mah:ControlsHelper.DisabledVisualElementVisibility="Collapsed"
+ mah:TextBoxHelper.ButtonContent="{TemplateBinding mah:TextBoxHelper.ButtonContent}"
+ mah:TextBoxHelper.ButtonContentTemplate="{TemplateBinding mah:TextBoxHelper.ButtonContentTemplate}"
+ mah:TextBoxHelper.ButtonFontFamily="{TemplateBinding mah:TextBoxHelper.ButtonFontFamily}"
+ mah:TextBoxHelper.ButtonFontSize="{TemplateBinding mah:TextBoxHelper.ButtonFontSize}"
+ mah:TextBoxHelper.ButtonWidth="{TemplateBinding mah:TextBoxHelper.ButtonWidth}"
+ mah:TextBoxHelper.ButtonsAlignment="{TemplateBinding ButtonsAlignment}"
+ mah:TextBoxHelper.ClearTextButton="{TemplateBinding mah:TextBoxHelper.ClearTextButton}"
+ mah:TextBoxHelper.HasText="{TemplateBinding mah:TextBoxHelper.HasText}"
+ mah:TextBoxHelper.SelectAllOnFocus="{TemplateBinding mah:TextBoxHelper.SelectAllOnFocus}"
+ mah:TextBoxHelper.UseFloatingWatermark="{TemplateBinding mah:TextBoxHelper.UseFloatingWatermark}"
+ mah:TextBoxHelper.Watermark="{TemplateBinding mah:TextBoxHelper.Watermark}"
+ mah:TextBoxHelper.WatermarkAlignment="{TemplateBinding mah:TextBoxHelper.WatermarkAlignment}"
+ mah:TextBoxHelper.WatermarkTrimming="{TemplateBinding mah:TextBoxHelper.WatermarkTrimming}"
+ mdix:TextFieldAssist.DecorationVisibility="Collapsed"
+ Background="{x:Null}"
+ ContextMenu="{StaticResource MaterialDesignDefaultContextMenu}"
+ FocusVisualStyle="{x:Null}"
+ TextAlignment="Left"
+ Focusable="{TemplateBinding Focusable}"
+ BorderThickness="0"
+ FontFamily="{TemplateBinding FontFamily}"
+ FontSize="{TemplateBinding FontSize}"
+ Foreground="{TemplateBinding Foreground}"
+ HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
+ IsTabStop="{TemplateBinding IsTabStop}"
+ SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
+ TabIndex="{TemplateBinding TabIndex}"
+ VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" />
+
+ <commonControls:IconRepeatButton Style="{StaticResource FSE_RepeatIconButton_Flat_Pressed_Highlight}" x:Name="PART_NumericUp"
+ Grid.Column="1"
+ Grid.Row="0"
+ Width="{TemplateBinding UpDownButtonsWidth}"
+ VerticalAlignment="Center"
+ Cursor="Hand"
+ Delay="{TemplateBinding Delay}"
+ IsTabStop="False"
+ Icon="ChevronUp">
+ </commonControls:IconRepeatButton>
+ <commonControls:IconRepeatButton Style="{StaticResource FSE_RepeatIconButton_Flat_Pressed_Highlight}" x:Name="PART_NumericDown"
+ Grid.Column="2"
+ Grid.Row="0"
+ Width="{TemplateBinding UpDownButtonsWidth}"
+ VerticalAlignment="Center"
+ Cursor="Hand"
+ Delay="{TemplateBinding Delay}"
+ IsTabStop="False"
+ Icon="ChevronDown">
+ </commonControls:IconRepeatButton>
+
+ <mdix:Underline
+ x:Name="Underline"
+ Grid.Column="0"
+ Grid.Row="1"
+ Grid.ColumnSpan="3"
+ Height="1"
+ Visibility="{Binding Path=(mdix:TextFieldAssist.DecorationVisibility), RelativeSource={RelativeSource TemplatedParent}}"
+ CornerRadius="{Binding Path=(mdix:TextFieldAssist.UnderlineCornerRadius), RelativeSource={RelativeSource TemplatedParent}}"
+ Background="{Binding Path=(mdix:TextFieldAssist.UnderlineBrush), RelativeSource={RelativeSource TemplatedParent}}" />
+ </Grid>
+ <Border x:Name="DisabledVisualElement"
+ Background="{DynamicResource MahApps.Brushes.Control.Disabled}"
+ BorderBrush="{DynamicResource MahApps.Brushes.Control.Disabled}"
+ BorderThickness="{TemplateBinding BorderThickness}"
+ CornerRadius="{TemplateBinding mah:ControlsHelper.CornerRadius}"
+ IsHitTestVisible="False"
+ Opacity="0"
+ SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
+ Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ControlsHelper.DisabledVisualElementVisibility), Mode=OneWay}" />
+ </Grid>
+ <ControlTemplate.Triggers>
+ <MultiTrigger>
+ <MultiTrigger.Conditions>
+ <Condition Property="ButtonsAlignment" Value="Left" />
+ </MultiTrigger.Conditions>
+ <Setter TargetName="PART_LeftColumn" Property="Width" Value="Auto" />
+ <Setter TargetName="PART_MiddleColumn" Property="Width" Value="Auto" />
+ <Setter TargetName="PART_NumericDown" Property="Grid.Column" Value="1" />
+ <Setter TargetName="PART_NumericUp" Property="Grid.Column" Value="0" />
+ <Setter TargetName="PART_RightColumn" Property="Width" Value="*" />
+ <Setter TargetName="PART_TextBox" Property="Grid.Column" Value="2" />
+ </MultiTrigger>
+ <MultiTrigger>
+ <MultiTrigger.Conditions>
+ <Condition Property="ButtonsAlignment" Value="Left" />
+ </MultiTrigger.Conditions>
+ <Setter TargetName="PART_LeftColumn" Property="Width" Value="Auto" />
+ <Setter TargetName="PART_MiddleColumn" Property="Width" Value="Auto" />
+ <Setter TargetName="PART_NumericDown" Property="Grid.Column" Value="0" />
+ <Setter TargetName="PART_NumericUp" Property="Grid.Column" Value="1" />
+ <Setter TargetName="PART_RightColumn" Property="Width" Value="*" />
+ <Setter TargetName="PART_TextBox" Property="Grid.Column" Value="2" />
+ </MultiTrigger>
+ <MultiTrigger>
+ <MultiTrigger.Conditions>
+ <Condition Property="ButtonsAlignment" Value="Right" />
+ </MultiTrigger.Conditions>
+ <Setter TargetName="PART_LeftColumn" Property="Width" Value="*" />
+ <Setter TargetName="PART_MiddleColumn" Property="Width" Value="Auto" />
+ <Setter TargetName="PART_NumericDown" Property="Grid.Column" Value="1" />
+ <Setter TargetName="PART_NumericUp" Property="Grid.Column" Value="2" />
+ <Setter TargetName="PART_RightColumn" Property="Width" Value="Auto" />
+ <Setter TargetName="PART_TextBox" Property="Grid.Column" Value="0" />
+ </MultiTrigger>
+
+ <Trigger Property="IsEnabled" Value="False">
+ <Setter TargetName="DisabledVisualElement" Property="Opacity" Value="0.6" />
+ </Trigger>
+ <Trigger Property="IsReadOnly" Value="True">
+
+ </Trigger>
+ <MultiTrigger>
+ <MultiTrigger.Conditions>
+ <Condition Property="IsReadOnly" Value="False" />
+ <Condition Property="InterceptManualEnter" Value="False" />
+ </MultiTrigger.Conditions>
+ <Setter TargetName="PART_TextBox" Property="IsReadOnly" Value="True" />
+ </MultiTrigger>
+ <Trigger Property="IsMouseOver" Value="True">
+ <Setter TargetName="Base" Property="BorderBrush" Value="{StaticResource FSE_PrimaryAccentBrush}" />
+ </Trigger>
+ <Trigger SourceName="PART_TextBox" Property="IsFocused" Value="True">
+ <Setter TargetName="Base" Property="BorderBrush" Value="{StaticResource FSE_PrimaryAccentBrush}" />
+ </Trigger>
+ <Trigger SourceName="PART_NumericUp" Property="IsFocused" Value="True">
+ <Setter TargetName="Base" Property="BorderBrush" Value="{StaticResource FSE_PrimaryAccentBrush}" />
+ </Trigger>
+ <Trigger SourceName="PART_NumericDown" Property="IsFocused" Value="True">
+ <Setter TargetName="Base" Property="BorderBrush" Value="{StaticResource FSE_PrimaryAccentBrush}" />
+ </Trigger>
+ <Trigger Property="IsKeyboardFocusWithin" Value="True">
+ <Setter TargetName="Underline" Property="IsActive" Value="True"/>
+ </Trigger>
+ <Trigger Property="HideUpDownButtons" Value="True">
+ <Setter TargetName="PART_NumericDown" Property="Visibility" Value="Collapsed" />
+ <Setter TargetName="PART_NumericUp" Property="Visibility" Value="Collapsed" />
+ </Trigger>
+ </ControlTemplate.Triggers>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ <Setter Property="TextAlignment" Value="Right" />
+ <Setter Property="UpDownButtonsWidth" Value="22" />
+ <Setter Property="Validation.ErrorTemplate" Value="{StaticResource MaterialDesignValidationErrorTemplate}" />
+ </Style>
+
+
+
+ <!--RANGE SLIDER-->
+ <Style x:Key="MaterialDesign.RangeSlider.Thumb"
+ TargetType="Thumb">
+ <Setter Property="Template" Value="{StaticResource MaterialDesignSliderThumb}" />
+ </Style>
+
+ <Style x:Key="MaterialDesign.RangeSlider.HorizontalMiddleThumb"
+ TargetType="{x:Type controls:MetroThumb}">
+ <Setter Property="Background" Value="Transparent" />
+ <Setter Property="BorderThickness" Value="0" />
+ <Setter Property="IsTabStop" Value="True" />
+ <Setter Property="SnapsToDevicePixels" Value="True" />
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="{x:Type controls:MetroThumb}">
+ <Grid Background="{TemplateBinding Background}">
+ <Rectangle Height="2" Fill="{TemplateBinding Foreground}" />
+ </Grid>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Style x:Key="MaterialDesign.RangeSlider.VerticalMiddleThumb"
+ BasedOn="{StaticResource MaterialDesign.RangeSlider.HorizontalMiddleThumb}"
+ TargetType="{x:Type controls:MetroThumb}">
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="{x:Type controls:MetroThumb}">
+ <Grid Background="{TemplateBinding Background}">
+ <Rectangle Width="2" Fill="{TemplateBinding Foreground}" />
+ </Grid>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Style x:Key="MaterialDesign.RangeSlider.HorizontalTrack"
+ TargetType="{x:Type RepeatButton}">
+ <Setter Property="Background" Value="Transparent" />
+ <Setter Property="Focusable" Value="False" />
+ <Setter Property="IsTabStop" Value="False" />
+ <Setter Property="OverridesDefaultStyle" Value="True" />
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="{x:Type RepeatButton}">
+ <Grid Background="{TemplateBinding Background}">
+ <Rectangle Height="2" Fill="{TemplateBinding Foreground}" />
+ </Grid>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Style x:Key="MaterialDesign.RangeSlider.VerticalTrack"
+ BasedOn="{StaticResource MaterialDesign.RangeSlider.HorizontalTrack}"
+ TargetType="{x:Type RepeatButton}">
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="{x:Type RepeatButton}">
+ <Grid Background="{TemplateBinding Background}">
+ <Rectangle Width="2" Fill="{TemplateBinding Foreground}" />
+ </Grid>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <ControlTemplate x:Key="MaterialDesignMahAppsRangeSliderHorizontal"
+ TargetType="controls:RangeSlider">
+ <Grid x:Name="PART_Container"
+ VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
+ Background="{TemplateBinding Background}">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="*" MinHeight="{TemplateBinding controls:RangeSlider.MinHeight}" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <TickBar x:Name="PART_TopTick"
+ Grid.Row="0"
+ Height="4"
+ Fill="{TemplateBinding Foreground}"
+ IsSelectionRangeEnabled="{TemplateBinding IsSelectionRangeEnabled}"
+ Maximum="{TemplateBinding Maximum}"
+ Minimum="{TemplateBinding Minimum}"
+ Placement="Top"
+ ReservedSpace="{DynamicResource MahApps.Sizes.Slider.HorizontalThumb.Width}"
+ SelectionEnd="{TemplateBinding SelectionEnd}"
+ SelectionStart="{TemplateBinding SelectionStart}"
+ TickFrequency="{TemplateBinding TickFrequency}"
+ Ticks="{TemplateBinding Ticks}"
+ Visibility="Collapsed" />
+ <TickBar x:Name="PART_BottomTick"
+ Grid.Row="2"
+ Height="4"
+ Fill="{TemplateBinding Foreground}"
+ IsSelectionRangeEnabled="{TemplateBinding IsSelectionRangeEnabled}"
+ Maximum="{TemplateBinding Maximum}"
+ Minimum="{TemplateBinding Minimum}"
+ Placement="Bottom"
+ ReservedSpace="{DynamicResource MahApps.Sizes.Slider.HorizontalThumb.Width}"
+ SelectionEnd="{TemplateBinding SelectionEnd}"
+ SelectionStart="{TemplateBinding SelectionStart}"
+ TickFrequency="{TemplateBinding TickFrequency}"
+ Ticks="{TemplateBinding Ticks}"
+ Visibility="Collapsed" />
+ <StackPanel x:Name="PART_RangeSliderContainer"
+ Grid.Row="1"
+ Background="Transparent"
+ Orientation="Horizontal">
+ <RepeatButton x:Name="PART_LeftEdge"
+ Foreground="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillBrush)}"
+ Style="{DynamicResource MaterialDesign.RangeSlider.HorizontalTrack}" />
+
+ <controls:MetroThumb x:Name="PART_LeftThumb"
+ Foreground="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillBrush)}"
+ Cursor="Arrow"
+ Style="{DynamicResource MaterialDesign.RangeSlider.Thumb}" />
+ <controls:MetroThumb x:Name="PART_MiddleThumb"
+ MinWidth="{TemplateBinding MinRangeWidth}"
+ Cursor="Hand"
+ Foreground="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackValueFillBrush)}"
+ Style="{DynamicResource MaterialDesign.RangeSlider.HorizontalMiddleThumb}" />
+ <controls:MetroThumb x:Name="PART_RightThumb"
+ Foreground="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillBrush)}"
+ Cursor="Arrow"
+ Style="{DynamicResource MaterialDesign.RangeSlider.Thumb}" />
+
+ <RepeatButton x:Name="PART_RightEdge"
+ Foreground="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillBrush)}"
+ Style="{DynamicResource MaterialDesign.RangeSlider.HorizontalTrack}" />
+ </StackPanel>
+ </Grid>
+ <ControlTemplate.Triggers>
+ <Trigger Property="TickPlacement" Value="TopLeft">
+ <Setter TargetName="PART_TopTick" Property="Visibility" Value="Visible" />
+ </Trigger>
+ <Trigger Property="TickPlacement" Value="BottomRight">
+ <Setter TargetName="PART_BottomTick" Property="Visibility" Value="Visible" />
+ </Trigger>
+ <Trigger Property="TickPlacement" Value="Both">
+ <Setter TargetName="PART_BottomTick" Property="Visibility" Value="Visible" />
+ <Setter TargetName="PART_TopTick" Property="Visibility" Value="Visible" />
+ </Trigger>
+
+ <Trigger Property="IsMouseOver" Value="True">
+ <Setter TargetName="PART_LeftEdge" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillHoverBrush)}" />
+ <Setter TargetName="PART_LeftThumb" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillHoverBrush)}" />
+ <Setter TargetName="PART_MiddleThumb" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackValueFillHoverBrush)}" />
+ <Setter TargetName="PART_RightEdge" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillHoverBrush)}" />
+ <Setter TargetName="PART_RightThumb" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillHoverBrush)}" />
+ </Trigger>
+ <Trigger SourceName="PART_LeftEdge" Property="IsPressed" Value="True">
+ <Setter TargetName="PART_LeftEdge" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillPressedBrush)}" />
+ <Setter TargetName="PART_LeftThumb" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillPressedBrush)}" />
+ <Setter TargetName="PART_MiddleThumb" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackValueFillPressedBrush)}" />
+ <Setter TargetName="PART_RightEdge" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillPressedBrush)}" />
+ <Setter TargetName="PART_RightThumb" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillPressedBrush)}" />
+ </Trigger>
+ <Trigger SourceName="PART_RightEdge" Property="IsPressed" Value="True">
+ <Setter TargetName="PART_LeftEdge" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillPressedBrush)}" />
+ <Setter TargetName="PART_LeftThumb" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillPressedBrush)}" />
+ <Setter TargetName="PART_MiddleThumb" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackValueFillPressedBrush)}" />
+ <Setter TargetName="PART_RightEdge" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillPressedBrush)}" />
+ <Setter TargetName="PART_RightThumb" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillPressedBrush)}" />
+ </Trigger>
+ <Trigger SourceName="PART_MiddleThumb" Property="IsDragging" Value="True">
+ <Setter TargetName="PART_LeftEdge" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillPressedBrush)}" />
+ <Setter TargetName="PART_LeftThumb" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillPressedBrush)}" />
+ <Setter TargetName="PART_MiddleThumb" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackValueFillPressedBrush)}" />
+ <Setter TargetName="PART_RightEdge" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillPressedBrush)}" />
+ <Setter TargetName="PART_RightThumb" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillPressedBrush)}" />
+ </Trigger>
+ <Trigger Property="IsEnabled" Value="False">
+ <Setter TargetName="PART_LeftEdge" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillDisabledBrush)}" />
+ <Setter TargetName="PART_LeftThumb" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillDisabledBrush)}" />
+ <Setter TargetName="PART_MiddleThumb" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackValueFillDisabledBrush)}" />
+ <Setter TargetName="PART_RightEdge" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillDisabledBrush)}" />
+ <Setter TargetName="PART_RightThumb" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillDisabledBrush)}" />
+ </Trigger>
+ </ControlTemplate.Triggers>
+ </ControlTemplate>
+
+ <ControlTemplate x:Key="MaterialDesignRangeSliderVertical"
+ TargetType="controls:RangeSlider">
+ <Grid x:Name="PART_Container"
+ HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
+ Background="{TemplateBinding Background}">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="*" MinWidth="{TemplateBinding controls:RangeSlider.MinWidth}" />
+ <ColumnDefinition Width="Auto" />
+ </Grid.ColumnDefinitions>
+ <TickBar x:Name="PART_TopTick"
+ Grid.Column="0"
+ Width="4"
+ Fill="{TemplateBinding Foreground}"
+ IsSelectionRangeEnabled="{TemplateBinding IsSelectionRangeEnabled}"
+ Maximum="{TemplateBinding Maximum}"
+ Minimum="{TemplateBinding Minimum}"
+ Placement="Left"
+ ReservedSpace="{DynamicResource MahApps.Sizes.Slider.VerticalThumb.Height}"
+ SelectionEnd="{TemplateBinding SelectionEnd}"
+ SelectionStart="{TemplateBinding SelectionStart}"
+ TickFrequency="{TemplateBinding TickFrequency}"
+ Ticks="{TemplateBinding Ticks}"
+ Visibility="Collapsed" />
+ <TickBar x:Name="PART_BottomTick"
+ Grid.Column="2"
+ Width="4"
+ Fill="{TemplateBinding Foreground}"
+ IsSelectionRangeEnabled="{TemplateBinding IsSelectionRangeEnabled}"
+ Maximum="{TemplateBinding Maximum}"
+ Minimum="{TemplateBinding Minimum}"
+ Placement="Right"
+ ReservedSpace="{DynamicResource MahApps.Sizes.Slider.VerticalThumb.Height}"
+ SelectionEnd="{TemplateBinding SelectionEnd}"
+ SelectionStart="{TemplateBinding SelectionStart}"
+ TickFrequency="{TemplateBinding TickFrequency}"
+ Ticks="{TemplateBinding Ticks}"
+ Visibility="Collapsed" />
+ <StackPanel x:Name="PART_RangeSliderContainer"
+ Grid.Column="1"
+ Background="Transparent"
+ Orientation="Vertical">
+ <RepeatButton x:Name="PART_RightEdge"
+ Foreground="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillBrush)}"
+ Style="{DynamicResource MaterialDesign.RangeSlider.VerticalTrack}" />
+
+ <controls:MetroThumb x:Name="PART_RightThumb"
+ Foreground="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillBrush)}"
+ Cursor="Arrow"
+ Style="{DynamicResource MaterialDesign.RangeSlider.Thumb}" />
+ <controls:MetroThumb x:Name="PART_MiddleThumb"
+ MinHeight="{TemplateBinding MinRangeWidth}"
+ Cursor="Hand"
+ Foreground="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackValueFillBrush)}"
+ Style="{StaticResource MaterialDesign.RangeSlider.VerticalMiddleThumb}" />
+ <controls:MetroThumb x:Name="PART_LeftThumb"
+ Foreground="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillBrush)}"
+ Cursor="Arrow"
+ Style="{DynamicResource MaterialDesign.RangeSlider.Thumb}" />
+
+ <RepeatButton x:Name="PART_LeftEdge"
+ Foreground="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillBrush)}"
+ Style="{DynamicResource MaterialDesign.RangeSlider.VerticalTrack}" />
+ </StackPanel>
+ </Grid>
+ <ControlTemplate.Triggers>
+ <Trigger Property="TickPlacement" Value="TopLeft">
+ <Setter TargetName="PART_TopTick" Property="Visibility" Value="Visible" />
+ </Trigger>
+ <Trigger Property="TickPlacement" Value="BottomRight">
+ <Setter TargetName="PART_BottomTick" Property="Visibility" Value="Visible" />
+ </Trigger>
+ <Trigger Property="TickPlacement" Value="Both">
+ <Setter TargetName="PART_BottomTick" Property="Visibility" Value="Visible" />
+ <Setter TargetName="PART_TopTick" Property="Visibility" Value="Visible" />
+ </Trigger>
+
+ <Trigger Property="IsMouseOver" Value="True">
+ <Setter TargetName="PART_LeftEdge" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillHoverBrush)}" />
+ <Setter TargetName="PART_LeftThumb" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillHoverBrush)}" />
+ <Setter TargetName="PART_MiddleThumb" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackValueFillHoverBrush)}" />
+ <Setter TargetName="PART_RightEdge" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillHoverBrush)}" />
+ <Setter TargetName="PART_RightThumb" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillHoverBrush)}" />
+ </Trigger>
+ <Trigger SourceName="PART_LeftEdge" Property="IsPressed" Value="True">
+ <Setter TargetName="PART_LeftEdge" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillPressedBrush)}" />
+ <Setter TargetName="PART_LeftThumb" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillPressedBrush)}" />
+ <Setter TargetName="PART_MiddleThumb" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackValueFillPressedBrush)}" />
+ <Setter TargetName="PART_RightEdge" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillPressedBrush)}" />
+ <Setter TargetName="PART_RightThumb" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillPressedBrush)}" />
+ </Trigger>
+ <Trigger SourceName="PART_RightEdge" Property="IsPressed" Value="True">
+ <Setter TargetName="PART_LeftEdge" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillPressedBrush)}" />
+ <Setter TargetName="PART_LeftThumb" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillPressedBrush)}" />
+ <Setter TargetName="PART_MiddleThumb" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackValueFillPressedBrush)}" />
+ <Setter TargetName="PART_RightEdge" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillPressedBrush)}" />
+ <Setter TargetName="PART_RightThumb" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillPressedBrush)}" />
+ </Trigger>
+ <Trigger SourceName="PART_MiddleThumb" Property="IsDragging" Value="True">
+ <Setter TargetName="PART_LeftEdge" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillPressedBrush)}" />
+ <Setter TargetName="PART_LeftThumb" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillPressedBrush)}" />
+ <Setter TargetName="PART_MiddleThumb" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackValueFillPressedBrush)}" />
+ <Setter TargetName="PART_RightEdge" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillPressedBrush)}" />
+ <Setter TargetName="PART_RightThumb" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillPressedBrush)}" />
+ </Trigger>
+ <Trigger Property="IsEnabled" Value="False">
+ <Setter TargetName="PART_LeftEdge" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillDisabledBrush)}" />
+ <Setter TargetName="PART_LeftThumb" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillDisabledBrush)}" />
+ <Setter TargetName="PART_MiddleThumb" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackValueFillDisabledBrush)}" />
+ <Setter TargetName="PART_RightEdge" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.TrackFillDisabledBrush)}" />
+ <Setter TargetName="PART_RightThumb" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:SliderHelper.ThumbFillDisabledBrush)}" />
+ </Trigger>
+ </ControlTemplate.Triggers>
+ </ControlTemplate>
+
+ <Style TargetType="{x:Type controls:RangeSlider}">
+ <Setter Property="Background" Value="Transparent" />
+ <Setter Property="Margin" Value="6 0" />
+ <Setter Property="controls:SliderHelper.ThumbFillBrush" Value="{DynamicResource PrimaryHueMidBrush}" />
+ <Setter Property="controls:SliderHelper.ThumbFillDisabledBrush" Value="{DynamicResource PrimaryHueMidBrush}" />
+ <Setter Property="controls:SliderHelper.ThumbFillHoverBrush" Value="{DynamicResource PrimaryHueMidBrush}" />
+ <Setter Property="controls:SliderHelper.ThumbFillPressedBrush" Value="{DynamicResource PrimaryHueMidBrush}" />
+ <Setter Property="controls:SliderHelper.TrackFillBrush" Value="{DynamicResource MaterialDesignCheckBoxOff}" />
+ <Setter Property="controls:SliderHelper.TrackFillDisabledBrush" Value="{DynamicResource MaterialDesignCheckBoxDisabled}" />
+ <Setter Property="controls:SliderHelper.TrackFillHoverBrush" Value="{DynamicResource MaterialDesignCheckBoxOff}" />
+ <Setter Property="controls:SliderHelper.TrackFillPressedBrush" Value="{DynamicResource MaterialDesignCheckBoxOff}" />
+ <Setter Property="controls:SliderHelper.TrackValueFillBrush" Value="{DynamicResource PrimaryHueMidBrush}" />
+ <Setter Property="controls:SliderHelper.TrackValueFillDisabledBrush" Value="{DynamicResource PrimaryHueMidBrush}" />
+ <Setter Property="controls:SliderHelper.TrackValueFillHoverBrush" Value="{DynamicResource PrimaryHueMidBrush}" />
+ <Setter Property="controls:SliderHelper.TrackValueFillPressedBrush" Value="{DynamicResource PrimaryHueMidBrush}" />
+ <Setter Property="Foreground" Value="{DynamicResource PrimaryHueMidBrush}" />
+ <Setter Property="HorizontalContentAlignment" Value="Stretch" />
+ <Setter Property="Template" Value="{StaticResource MaterialDesignMahAppsRangeSliderHorizontal}" />
+ <Setter Property="VerticalContentAlignment" Value="Stretch" />
+ <Style.Triggers>
+ <Trigger Property="Orientation" Value="Vertical">
+ <Setter Property="Template" Value="{StaticResource MaterialDesignRangeSliderVertical}" />
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+
+</ResourceDictionary> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Styles.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Styles.xaml
index e4b3c00a2..b78f3d029 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Styles.xaml
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Styles.xaml
@@ -4,6 +4,7 @@
xmlns:actions="clr-namespace:Tango.FSE.Common.EventTriggerActions"
xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:wpf="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:local="clr-namespace:Tango.FSE.Common.Resources">
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj b/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj
index f4cd07490..8532c3e3a 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj
@@ -74,6 +74,7 @@
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
+ <Reference Include="PresentationFramework.Aero" />
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Data" />
@@ -116,6 +117,7 @@
<Compile Include="Connectivity\IConnectivityProvider.cs" />
<Compile Include="Console\IConsoleProvider.cs" />
<Compile Include="Controls\FSEGroupBox.cs" />
+ <Compile Include="Controls\IconRepeatButton.cs" />
<Compile Include="Controls\KeepAliveTabControl.cs" />
<Compile Include="Controls\ConnectedMachineIcon.xaml.cs">
<DependentUpon>ConnectedMachineIcon.xaml</DependentUpon>
@@ -247,6 +249,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
+ <Page Include="Controls\IconRepeatButton.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
<Page Include="Controls\IconButton.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -315,6 +321,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
+ <Page Include="Resources\MahApps.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="Resources\Styles.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -373,6 +383,8 @@
<Resource Include="Fonts\Flexo-ThinIt.otf" />
<Resource Include="Fonts\Caveat-Bold.ttf" />
<Resource Include="Fonts\Caveat-Regular.ttf" />
+ <Resource Include="Fonts\indie.ttf" />
+ <Resource Include="Fonts\angelina.TTF" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
@@ -506,6 +518,11 @@
<ItemGroup>
<Resource Include="Images\transparent_small.jpg" />
</ItemGroup>
+ <ItemGroup>
+ <Resource Include="Images\shadow_left.png" />
+ <Resource Include="Images\shadow_right.png" />
+ <Resource Include="Images\shadow_top.png" />
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/App.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/App.xaml
index 8f0cb79fd..73680103b 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/App.xaml
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/App.xaml
@@ -18,6 +18,8 @@
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />-->
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.Slider.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Themes/RangeSlider.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseDark.xaml" />
@@ -53,6 +55,9 @@
</ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.ProgressBar.xaml"/>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ComboBox.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Menu.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Slider.xaml" />
+
<ResourceDictionary Source="pack://application:,,,/Dragablz;component/Themes/materialdesign.xaml"/>
@@ -63,6 +68,7 @@
<ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Resources/Styles.xaml" />
<ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Resources/Controls.xaml" />
<ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Resources/Graphs.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Resources/MahApps.xaml" />
<ResourceDictionary>
<!--OVERRIDE MAHAPPS-->
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/FSEApplication/DefaultFSEApplicationManager.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/FSEApplication/DefaultFSEApplicationManager.cs
index c20116432..e0465d307 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/FSEApplication/DefaultFSEApplicationManager.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/FSEApplication/DefaultFSEApplicationManager.cs
@@ -382,6 +382,12 @@ namespace Tango.FSE.UI.FSEApplication
}
catch { }
+ try
+ {
+ SettingsManager.Default.Save();
+ }
+ catch { }
+
LogManager.Log("Disposing disk cache...");
DiskCacheManager.Default.Dispose();
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/MainWindow.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/MainWindow.xaml
index aa6413cab..bb18a26e0 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/MainWindow.xaml
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/MainWindow.xaml
@@ -21,7 +21,7 @@
UseNoneWindowStyle="True"
EnableDWMDropShadow="True"
MinWidth="1280"
- MinHeight="720"
+ MinHeight="690"
BorderThickness="1"
BorderBrush="Gray"
FontFamily="{StaticResource flexo}"
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/InternalModuleViewVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/InternalModuleViewVM.cs
index 81927608f..970d77b89 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/InternalModuleViewVM.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/InternalModuleViewVM.cs
@@ -16,16 +16,16 @@ namespace Tango.FSE.UI.ViewModels
{
if (AuthenticationProvider.CurrentUser.HasPermission(Tango.BL.Enumerations.Permissions.FSE_RunFSE))
{
- NavigationManager.MenuItems.Add(new NavigationMenuItem(() =>
- {
- NavigationManager.NavigateTo<InternalModule>(nameof(AccountView));
- })
- {
- Name = "Account",
- Index = -1,
- Description = "Manage your account details",
- Image = ResourceHelper.GetImageFromResources("Images/Menu/account.png"),
- });
+ //NavigationManager.MenuItems.Add(new NavigationMenuItem(() =>
+ //{
+ // NavigationManager.NavigateTo<InternalModule>(nameof(AccountView));
+ //})
+ //{
+ // Name = "Account",
+ // Index = -1,
+ // Description = "Manage your account details",
+ // Image = ResourceHelper.GetImageFromResources("Images/Menu/account.png"),
+ //});
NavigationManager.MenuItems.Add(new NavigationMenuItem(() =>
{
@@ -38,16 +38,16 @@ namespace Tango.FSE.UI.ViewModels
Image = ResourceHelper.GetImageFromResources("Images/Menu/events.png"),
});
- NavigationManager.MenuItems.Add(new NavigationMenuItem(() =>
- {
- NavigationManager.NavigateTo<InternalModule>(nameof(SettingsView));
- })
- {
- Name = "Settings",
- Index = 100,
- Description = "Configuration of your Tango FSE",
- Image = ResourceHelper.GetImageFromResources("Images/Menu/settings.png"),
- });
+ //NavigationManager.MenuItems.Add(new NavigationMenuItem(() =>
+ //{
+ // NavigationManager.NavigateTo<InternalModule>(nameof(SettingsView));
+ //})
+ //{
+ // Name = "Settings",
+ // Index = 100,
+ // Description = "Configuration of your Tango FSE",
+ // Image = ResourceHelper.GetImageFromResources("Images/Menu/settings.png"),
+ //});
}
}
}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LayoutView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LayoutView.xaml
index 5f5adfe59..612cbfa8b 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LayoutView.xaml
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LayoutView.xaml
@@ -24,7 +24,6 @@
</Grid.RowDefinitions>
<Grid Grid.Row="1">
-
<Grid x:Name="layoutGrid">
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
@@ -34,7 +33,7 @@
</Grid.RowDefinitions>
<ScrollViewer Focusable="False" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
- <controls:NavigationControl Focusable="False" x:Name="NavigationControl" VerticalAlignment="Top" TransitionAlwaysFades="True" Height="{Binding ElementName=layoutGrid,Path=ActualHeight,Converter={StaticResource MathOperatorConverter},ConverterParameter='-33'}">
+ <controls:NavigationControl Focusable="False" UseDefferedRendering="True" x:Name="NavigationControl" VerticalAlignment="Top" TransitionAlwaysFades="True" Height="{Binding ElementName=layoutGrid,Path=ActualHeight,Converter={StaticResource MathOperatorConverter},ConverterParameter='-33'}">
<!--MODULES-->
</controls:NavigationControl>
</ScrollViewer>
@@ -127,6 +126,8 @@
</Grid>
</Grid>
+ <Image IsHitTestVisible="False" Source="{StaticResource FSE_Shadow_Top}" VerticalAlignment="Top" Stretch="Fill" Height="10" Opacity="0.6" />
+
<Grid x:Name="paneMask" Background="{StaticResource FSE_SemiTransparentBrush}" Visibility="{Binding IsConnectionPaneOpened,Converter={StaticResource BooleanToVisibilityConverter},FallbackValue=Collapsed}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseUp">
@@ -190,9 +191,6 @@
<!--Top Bar-->
<Grid Background="{StaticResource FSE_PrimaryBackgroundLightBrush}">
- <Grid.Effect>
- <DropShadowEffect BlurRadius="10" />
- </Grid.Effect>
<Polygon HorizontalAlignment="Right" Points="220,0 300,0 300,100 0,100" Width="350" Stretch="Fill">
<Polygon.Fill>
@@ -234,14 +232,14 @@
<TextBlock FontSize="12" Foreground="{StaticResource FSE_GrayBrush}" TextTrimming="CharacterEllipsis" MaxWidth="170" FontStyle="Italic" Margin="10 5 0 0" VerticalAlignment="Center">
<Run Text="{Binding AuthenticationProvider.CurrentUser.Organization.Name}"></Run>
,
- <Run Text="{Binding AuthenticationProvider.CurrentUser.FSERoles[0].Name}">
+ <Run Text="{Binding AuthenticationProvider.CurrentUser.FSERoles[0].Description}">
<Run.ToolTip>
<ItemsControl ItemsSource="{Binding AuthenticationProvider.CurrentUser.FSERoles}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="2">
<material:PackIcon Kind="AccountKey" Width="16" Height="16" />
- <TextBlock Margin="5 0 0 0" Text="{Binding Name}"></TextBlock>
+ <TextBlock Margin="5 0 0 0" Text="{Binding Description}"></TextBlock>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LoginView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LoginView.xaml
index f818d0c10..a20ae68b3 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LoginView.xaml
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/LoginView.xaml
@@ -9,6 +9,7 @@
xmlns:helpers="clr-namespace:Tango.SharedUI.Helpers;assembly=Tango.SharedUI"
xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI"
+ xmlns:mahApps="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:local="clr-namespace:Tango.FSE.UI.Views"
mc:Ignorable="d"
d:DesignHeight="720" d:DesignWidth="1280" d:DataContext="{d:DesignInstance Type=vm:LoginViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.LoginViewVM}">
@@ -44,7 +45,7 @@
<Grid ClipToBounds="True">
<Image Source="/Images/Abstracts/abstract1.png" Stretch="UniformToFill" Opacity="0.8" HorizontalAlignment="Right" Width="{Binding RelativeSource={RelativeSource AncestorType=Grid},Path=ActualWidth,Converter={StaticResource MathOperatorConverter},ConverterParameter='*1.5'}"/>
<StackPanel>
- <TextBlock HorizontalAlignment="Center" Margin="0 30 0 0" FontSize="40" TextAlignment="Center" TextWrapping="Wrap" Foreground="{StaticResource FSE_PrimaryForegroundBrush}">Welcome</TextBlock>
+ <TextBlock HorizontalAlignment="Center" Margin="0 70 0 0" FontSize="40" TextAlignment="Center" FontWeight="Bold" TextWrapping="Wrap" Foreground="{StaticResource FSE_PrimaryForegroundBrush}">TANGO FSE</TextBlock>
</StackPanel>
<Image Source="{StaticResource FSE_Machine_Full}" VerticalAlignment="Bottom" RenderOptions.BitmapScalingMode="Fant" Margin="0 0 0 150" MaxWidth="300" MinWidth="100" />
<Rectangle HorizontalAlignment="Right" StrokeThickness="1" Stroke="{StaticResource FSE_BorderBrush}" StrokeDashArray="5" />
@@ -78,7 +79,7 @@
<StackPanel controls:NavigationControl.NavigationName="Logging">
<ProgressBar Width="200" Height="200" HorizontalAlignment="Center" VerticalAlignment="Center" IsIndeterminate="{Binding IsBusy}" Style="{StaticResource MaterialDesignCircularProgressBar}" Value="0" />
- <TextBlock HorizontalAlignment="Center" Margin="0 40 0 0" FontSize="18">Logging you in, please wait...</TextBlock>
+ <TextBlock HorizontalAlignment="Center" Margin="0 40 0 0" FontSize="18">logging you in, please wait...</TextBlock>
<TextBlock HorizontalAlignment="Center" Margin="0 20 0 0" Text="{Binding Status}" Foreground="{StaticResource FSE_GrayBrush}"></TextBlock>
</StackPanel>
@@ -104,7 +105,7 @@
<StackPanel controls:NavigationControl.NavigationName="ChangingPassword">
<ProgressBar Width="200" Height="200" HorizontalAlignment="Center" VerticalAlignment="Center" IsIndeterminate="{Binding IsBusy}" Style="{StaticResource MaterialDesignCircularProgressBar}" Value="0" />
- <TextBlock HorizontalAlignment="Center" Margin="0 40 0 0" FontSize="18">Updating your password, please wait...</TextBlock>
+ <TextBlock HorizontalAlignment="Center" Margin="0 40 0 0" FontSize="18">updating your password, please wait...</TextBlock>
</StackPanel>
<StackPanel TextElement.FontSize="16" controls:NavigationControl.NavigationName="ForgotPassword">
@@ -128,7 +129,7 @@
<StackPanel controls:NavigationControl.NavigationName="SendingForgotPasswordEmail">
<ProgressBar Width="200" Height="200" HorizontalAlignment="Center" VerticalAlignment="Center" IsIndeterminate="{Binding IsBusy}" Style="{StaticResource MaterialDesignCircularProgressBar}" Value="0" />
- <TextBlock HorizontalAlignment="Center" Margin="0 40 0 0" FontSize="18">Sending password reset email, please wait...</TextBlock>
+ <TextBlock HorizontalAlignment="Center" Margin="0 40 0 0" FontSize="18">sending password reset email, please wait...</TextBlock>
</StackPanel>
</controls:NavigationControl>
</Grid>
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs
index 2dfea3ff3..ae77c26d0 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs
@@ -659,10 +659,11 @@ namespace Tango.PPC.Common.MachineUpdate
{
throw LogManager.Log(new InvalidOperationException("Could not perform an update while the machine is not connected."));
}
- if (!op.CanPrint)
- {
- throw LogManager.Log(new InvalidOperationException($"Could not perform an update while the machine is in {op.Status} status."));
- }
+ }
+
+ if (!op.CanPrint)
+ {
+ throw LogManager.Log(new InvalidOperationException($"Could not perform an update while the machine is in {op.Status} status."));
}
//Connect to machine service and get matching packages for this machine.
@@ -970,6 +971,11 @@ namespace Tango.PPC.Common.MachineUpdate
{
LogManager.Log("Starting database update...");
+ if (!_machineProvider.MachineOperator.CanPrint)
+ {
+ throw LogManager.Log(new InvalidOperationException($"Could not perform an update while the machine is in {_machineProvider.MachineOperator} status."));
+ }
+
UpdateProgress("Updating Database", "Initializing...");
LogManager.Log("Looking for update scripts configuration on application path...");
@@ -1241,10 +1247,11 @@ namespace Tango.PPC.Common.MachineUpdate
{
throw LogManager.Log(new InvalidOperationException("Could not perform an update while the machine is not connected."));
}
- if (!op.CanPrint)
- {
- throw LogManager.Log(new InvalidOperationException($"Could not perform an update while the machine is in {op.Status} status."));
- }
+ }
+
+ if (!op.CanPrint)
+ {
+ throw LogManager.Log(new InvalidOperationException($"Could not perform an update while the machine is in {op.Status} status."));
}
UpdateProgress("Exploring package", "Extracting...");
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs
index a7ae770f3..23fecdf0e 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs
@@ -8,4 +8,4 @@ using System.Windows;
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Tango PPC Application")]
-[assembly: AssemblyVersion("1.1.15.0")]
+[assembly: AssemblyVersion("1.1.16.0")]
diff --git a/Software/Visual_Studio/Tango.BL/Entities/Job.cs b/Software/Visual_Studio/Tango.BL/Entities/Job.cs
index cf987f306..5cd756f27 100644
--- a/Software/Visual_Studio/Tango.BL/Entities/Job.cs
+++ b/Software/Visual_Studio/Tango.BL/Entities/Job.cs
@@ -389,34 +389,42 @@ namespace Tango.BL.Entities
public BitmapSource CreateSegmentsPie(double width, double height)
{
- Bitmap bmp = new Bitmap((int)width, (int)height);
-
- using (Graphics g = Graphics.FromImage(bmp))
+ try
{
- g.Clear(Color.Transparent);
- g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
- g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
- g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
-
- int fromAngle = -90;
- double totalLength = Segments.Sum(x => x.Length); //Excluding inter segment.
+ Bitmap bmp = new Bitmap((int)width, (int)height);
- foreach (var segment in OrderedSegments)
+ using (Graphics g = Graphics.FromImage(bmp))
{
- int toAngle = (int)((segment.Length / totalLength) * 360d);
- Rectangle rect = new Rectangle(0, 0, bmp.Width - 2, bmp.Height - 2);
- g.FillPie(segment.CreateGdiBrush(bmp.Width - 2, bmp.Height - 2), rect, fromAngle, toAngle);
+ g.Clear(Color.Transparent);
+ g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
+ g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
+ g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
+
+ int fromAngle = -90;
+ double totalLength = Segments.Sum(x => x.Length); //Excluding inter segment.
+
+ foreach (var segment in OrderedSegments)
+ {
+ int toAngle = (int)((segment.Length / totalLength) * 360d);
+ Rectangle rect = new Rectangle(0, 0, bmp.Width - 2, bmp.Height - 2);
+ g.FillPie(segment.CreateGdiBrush(bmp.Width - 2, bmp.Height - 2), rect, fromAngle, toAngle);
- Pen pen = new Pen(Color.Gainsboro);
- g.DrawEllipse(pen, rect);
- pen.Dispose();
- fromAngle += toAngle;
+ Pen pen = new Pen(Color.Gainsboro);
+ g.DrawEllipse(pen, rect);
+ pen.Dispose();
+ fromAngle += toAngle;
+ }
}
- }
- var source = bmp.ToBitmapSource();
- bmp.Dispose();
- return source;
+ var source = bmp.ToBitmapSource();
+ bmp.Dispose();
+ return source;
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, $"Error occurred while trying to create job pie image for job '{Name}'.");
+ return null;
+ }
}
/// <summary>
diff --git a/Software/Visual_Studio/Tango.BL/Enumerations/Permissions.cs b/Software/Visual_Studio/Tango.BL/Enumerations/Permissions.cs
index 514ce925d..38a760af4 100644
--- a/Software/Visual_Studio/Tango.BL/Enumerations/Permissions.cs
+++ b/Software/Visual_Studio/Tango.BL/Enumerations/Permissions.cs
@@ -235,5 +235,11 @@ namespace Tango.BL.Enumerations
[Description("Allows executing command prompt commands remotely")]
FSE_ExecuteRemoteConsoleCommands = 1014,
+ /// <summary>
+ /// (Allows editing of the default diagnostics project)
+ /// </summary>
+ [Description("Allows editing of the default diagnostics project")]
+ FSE_EditDiagnosticsProject = 1015,
+
}
}
diff --git a/Software/Visual_Studio/Tango.Core/ExtendedObject.cs b/Software/Visual_Studio/Tango.Core/ExtendedObject.cs
index 63a75480c..f09a82ae9 100644
--- a/Software/Visual_Studio/Tango.Core/ExtendedObject.cs
+++ b/Software/Visual_Studio/Tango.Core/ExtendedObject.cs
@@ -82,7 +82,7 @@ namespace Tango.Core
{
InvokeUI(() =>
{
- foreach (var prop in this.GetType().GetProperties().Where(x => x.PropertyType == typeof(RelayCommand)))
+ foreach (var prop in this.GetType().GetProperties().Where(x => typeof(RelayCommand).IsAssignableFrom(x.PropertyType)))
{
var value = prop.GetValue(this) as RelayCommand;
diff --git a/Software/Visual_Studio/Tango.Core/TangoProgress.cs b/Software/Visual_Studio/Tango.Core/TangoProgress.cs
index ccec0e546..e8a82a3b0 100644
--- a/Software/Visual_Studio/Tango.Core/TangoProgress.cs
+++ b/Software/Visual_Studio/Tango.Core/TangoProgress.cs
@@ -73,7 +73,10 @@ namespace Tango.Core
/// </summary>
public TangoProgress(String message, bool isIndeterminate = true, T value = default(T), T maximum = default(T)) : this()
{
-
+ Message = message;
+ IsIndeterminate = isIndeterminate;
+ Value = value;
+ Maximum = maximum;
}
public override string ToString()
diff --git a/Software/Visual_Studio/Tango.Touch/Controls/LightTouchDataGrid.cs b/Software/Visual_Studio/Tango.Touch/Controls/LightTouchDataGrid.cs
index 79e6739af..bc17ec394 100644
--- a/Software/Visual_Studio/Tango.Touch/Controls/LightTouchDataGrid.cs
+++ b/Software/Visual_Studio/Tango.Touch/Controls/LightTouchDataGrid.cs
@@ -549,66 +549,74 @@ namespace Tango.Touch.Controls
for (int i = 0; i < ordered.Count; i++)
{
- ContentPresenter contentPresenter = ordered[i];
- LightTouchDataGridRow row = contentPresenter.FindChild<LightTouchDataGridRow>();
+ try
+ {
+ ContentPresenter contentPresenter = ordered[i];
- bool display = true;
+ LightTouchDataGridRow row = contentPresenter.FindChild<LightTouchDataGridRow>();
- if (CollectionFilter != null && row != null)
- {
- row.Visibility = CollectionFilter.Filter(row.DataContext) ? Visibility.Visible : Visibility.Collapsed;
- display = row.Visibility == Visibility.Visible;
- }
+ bool display = true;
- if (display)
- {
- if (AnimateSorting && allowAnimation)
+ if (CollectionFilter != null && row != null)
+ {
+ row.Visibility = CollectionFilter.Filter(row.DataContext) ? Visibility.Visible : Visibility.Collapsed;
+ display = row.Visibility == Visibility.Visible;
+ }
+
+ if (display)
{
- if (double.IsNaN(Canvas.GetTop(contentPresenter)))
+ if (AnimateSorting && allowAnimation)
{
- Canvas.SetTop(contentPresenter, current_top);
- Canvas.SetLeft(contentPresenter, 0);
+ if (double.IsNaN(Canvas.GetTop(contentPresenter)))
+ {
+ Canvas.SetTop(contentPresenter, current_top);
+ Canvas.SetLeft(contentPresenter, 0);
+ }
+ else
+ {
+ int duration = _rnd.Next(200, 500);
+
+ DoubleAnimation aniY = new DoubleAnimation();
+ aniY.To = current_top;
+ aniY.Duration = TimeSpan.FromMilliseconds(duration);
+ contentPresenter.BeginAnimation(Canvas.TopProperty, aniY);
+
+ DoubleAnimation aniX = new DoubleAnimation();
+ aniX.FillBehavior = FillBehavior.Stop;
+ aniX.To = _rnd.Next(-20, 20);
+ aniX.AutoReverse = true;
+ aniX.Duration = TimeSpan.FromMilliseconds(duration / 2);
+ contentPresenter.BeginAnimation(Canvas.LeftProperty, aniX, HandoffBehavior.SnapshotAndReplace);
+ }
}
else
{
- int duration = _rnd.Next(200, 500);
+ if (AnimateSorting)
+ {
+ contentPresenter.BeginAnimation(Canvas.TopProperty, null);
+ }
- DoubleAnimation aniY = new DoubleAnimation();
- aniY.To = current_top;
- aniY.Duration = TimeSpan.FromMilliseconds(duration);
- contentPresenter.BeginAnimation(Canvas.TopProperty, aniY);
-
- DoubleAnimation aniX = new DoubleAnimation();
- aniX.FillBehavior = FillBehavior.Stop;
- aniX.To = _rnd.Next(-20, 20);
- aniX.AutoReverse = true;
- aniX.Duration = TimeSpan.FromMilliseconds(duration / 2);
- contentPresenter.BeginAnimation(Canvas.LeftProperty, aniX, HandoffBehavior.SnapshotAndReplace);
+ Canvas.SetTop(contentPresenter, current_top);
+ Canvas.SetLeft(contentPresenter, 0);
}
- }
- else
- {
- if (AnimateSorting)
+
+ if (row != null)
{
- contentPresenter.BeginAnimation(Canvas.TopProperty, null);
+ current_top += (row.Margin.Top + row.ActualHeight + row.Margin.Bottom);
}
- Canvas.SetTop(contentPresenter, current_top);
- Canvas.SetLeft(contentPresenter, 0);
- }
-
- if (row != null)
- {
- current_top += (row.Margin.Top + row.ActualHeight + row.Margin.Bottom);
- }
-
- if (row != null && row.Tag == null)
- {
- row.RegisterForPreviewMouseOrTouchUp(OnRowMouseTouchUp);
- row.RegisterForPreviewMouseOrTouchDown(OnRowMouseTouchDown);
- row.Tag = 1;
+ if (row != null && row.Tag == null)
+ {
+ row.RegisterForPreviewMouseOrTouchUp(OnRowMouseTouchUp);
+ row.RegisterForPreviewMouseOrTouchDown(OnRowMouseTouchDown);
+ row.Tag = 1;
+ }
}
}
+ catch (Exception ex)
+ {
+ Debug.WriteLine(ex);
+ }
}
_items_control_rows.Height = current_top;