diff options
| author | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-07-22 01:51:21 +0300 |
|---|---|---|
| committer | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-07-22 01:51:21 +0300 |
| commit | 8f082608ed86c6027cb88539d40d005189fa1cf6 (patch) | |
| tree | 31dc1898fbcdefbe12df5ed68df920d0ae7806c4 /Software/Visual_Studio | |
| parent | 9aa38289b089d2518c5b0ef68e78f262fe4a31ee (diff) | |
| download | Tango-8f082608ed86c6027cb88539d40d005189fa1cf6.tar.gz Tango-8f082608ed86c6027cb88539d40d005189fa1cf6.zip | |
Improved procedure designer.
Added support for static variables.
Added full results support for designer.
Added BitmapResult.
Added System.Windows.Forms / Drawing as default usings.
Diffstat (limited to 'Software/Visual_Studio')
16 files changed, 453 insertions, 241 deletions
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Converters/BitmapToBitmapSourceConverter.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Converters/BitmapToBitmapSourceConverter.cs new file mode 100644 index 000000000..34b00d23f --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Converters/BitmapToBitmapSourceConverter.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; + +namespace Tango.FSE.Procedures.Converters +{ + public class BitmapToBitmapSourceConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + try + { + Bitmap bitmap = value as Bitmap; + + if (bitmap != null) + { + var source = bitmap.ToBitmapSource(); + source.Freeze(); + bitmap.Dispose(); + return source; + } + + return null; + } + catch (Exception ex) + { + Logging.LogManager.Default.Log(ex, "Could not convert the specified bitmap result to bitmap source."); + return null; + } + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/IProcedureContext.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/IProcedureContext.cs index a142e183c..90bbc9911 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/IProcedureContext.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/IProcedureContext.cs @@ -3,6 +3,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Drawing; using System.Linq; using System.Text; using System.Threading; @@ -36,7 +37,7 @@ namespace Tango.FSE.Procedures Result AddResult(ResultType type, String name, object value); /// <summary> - /// Adds the procedure graph result. + /// Adds a new procedure graph result. /// </summary> /// <param name="type">The type.</param> /// <param name="name">The name.</param> @@ -45,6 +46,30 @@ namespace Tango.FSE.Procedures Result AddGraphResult(ResultType type, String name, IEnumerable<double> values); /// <summary> + /// Adds a new procedure bitmap result. + /// </summary> + /// <param name="type">The type.</param> + /// <param name="name">The name.</param> + /// <param name="bitmap">The bitmap.</param> + /// <returns></returns> + Result AddBitmapResult(ResultType type, String name, Bitmap bitmap); + + /// <summary> + /// Creates a new bitmap. + /// </summary> + /// <param name="width">The bitmap width.</param> + /// <param name="height">The bitmap height.</param> + /// <returns></returns> + Bitmap CreateBitmap(int width, int height); + + /// <summary> + /// Creates a new drawing context for the specified bitmap. + /// </summary> + /// <param name="bitmap">The bitmap.</param> + /// <returns></returns> + Graphics GetDrawingContext(Bitmap bitmap); + + /// <summary> /// Adds a new procedure result. /// </summary> /// <param name="result">The result.</param> @@ -74,6 +99,14 @@ namespace Tango.FSE.Procedures /// <summary> /// Sends a request by name with optional comma separated arguments. /// </summary> + /// <param name="messageName">Name of the message.</param> + /// <param name="args">The arguments separated by commas.</param> + /// <returns></returns> + IMessage Send(String messageName, params Object[] args); + + /// <summary> + /// Sends a request by name with optional comma separated arguments. + /// </summary> /// <typeparam name="T"></typeparam> /// <param name="messageName">Name of the message.</param> /// <param name="timeout">The timeout.</param> @@ -82,6 +115,15 @@ namespace Tango.FSE.Procedures T Send<T>(String messageName, int? timeout = null, params Object[] args) where T : class, IMessage; /// <summary> + /// Sends a request by name with optional comma separated arguments. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="messageName">Name of the message.</param> + /// <param name="args">The arguments separated by commas.</param> + /// <returns></returns> + T Send<T>(String messageName, params Object[] args) where T : class, IMessage; + + /// <summary> /// Sends the specified message. /// </summary> /// <param name="message">The message.</param> @@ -118,6 +160,15 @@ namespace Tango.FSE.Procedures void SendContinuous<T>(String messageName, Action<T> callback, int? timeout, params Object[] args) where T : class, IMessage; /// <summary> + /// Sends a continuous message with optional comma separated arguments. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="messageName">Name of the message.</param> + /// <param name="callback">Callback for continuous responses.</param> + /// <param name="args">The arguments.</param> + void SendContinuous<T>(String messageName, Action<T> callback, params Object[] args) where T : class, IMessage; + + /// <summary> /// Writes the specified object string representation to the output window. /// </summary> /// <param name="obj">The object.</param> @@ -280,7 +331,7 @@ namespace Tango.FSE.Procedures /// <param name="extension">Extension filter (default "*.*").</param> /// <param name="defaultFileName">Optional default file name.</param> /// <returns></returns> - String RequestFileSave(String message, String extension = "*.*",String defaultFileName = null); + String RequestFileSave(String message, String extension = "*.*", String defaultFileName = null); /// <summary> /// Updates the procedure progress. diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ProcedureContext.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ProcedureContext.cs index 8724b12a5..5663e0443 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ProcedureContext.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ProcedureContext.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; +using System.Drawing; using System.IO; using System.Linq; using System.Reactive.Concurrency; @@ -107,11 +108,21 @@ namespace Tango.FSE.Procedures return Send(request as IMessage, timeout); } + public IMessage Send(string messageName, params object[] args) + { + return Send(messageName, null, args); + } + public T Send<T>(string messageName, int? timeout = null, params object[] args) where T : class, IMessage { return Send(messageName, timeout, args) as T; } + public T Send<T>(string messageName, params object[] args) where T : class, IMessage + { + return Send<T>(messageName, null, args); + } + public IMessage Send(IMessage message, int? timeout = null) { TimeSpan? timespan = null; @@ -209,6 +220,11 @@ namespace Tango.FSE.Procedures SendContinuous<IMessage>(request, callback as Action<IMessage>, timeout); } + public void SendContinuous<T>(string messageName, Action<T> callback, params object[] args) where T : class, IMessage + { + SendContinuous<T>(messageName, callback, null, args); + } + public void WriteLine(object obj) { String line = "null"; @@ -563,5 +579,26 @@ namespace Tango.FSE.Procedures } public event EventHandler<TangoProgressChangedEventArgs<double>> Progress; + + public Result AddBitmapResult(ResultType type, String name, Bitmap bitmap) + { + return AddResult(new Result() + { + IsBitmap = true, + Name = name, + Type = type, + Value = bitmap + }); + } + + public Bitmap CreateBitmap(int width, int height) + { + return new Bitmap(width, height); + } + + public Graphics GetDrawingContext(Bitmap bitmap) + { + return Graphics.FromImage(bitmap); + } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Resources/lib_template.csx b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Resources/lib_template.csx index 0fcf7da88..0588f3ba3 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Resources/lib_template.csx +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Resources/lib_template.csx @@ -6,6 +6,8 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; +using System.Windows.Forms; +using System.Drawing; using Google.Protobuf; using Tango.BL.Enumerations; using Tango.PMR.Stubs; diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Resources/main_template.csx b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Resources/main_template.csx index 4f0dd0922..90b432a2f 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Resources/main_template.csx +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Resources/main_template.csx @@ -6,6 +6,8 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; +using System.Windows.Forms; +using System.Drawing; using Google.Protobuf; using Tango.BL.Enumerations; using Tango.PMR.Stubs; diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Result.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Result.cs index ef63ae108..8b7724eca 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Result.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Result.cs @@ -19,6 +19,9 @@ namespace Tango.FSE.Procedures public bool IsGraph { get; set; } [JsonIgnore] + public bool IsBitmap { get; set; } + + [JsonIgnore] public bool IsValueArray { get { return Value != null && typeof(IEnumerable).IsAssignableFrom(Value.GetType()) && Value.GetType() != typeof(String); } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Tango.FSE.Procedures.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Tango.FSE.Procedures.csproj index 8ff4f771e..db05d9ebd 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Tango.FSE.Procedures.csproj +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Tango.FSE.Procedures.csproj @@ -101,6 +101,7 @@ <ItemGroup> <Compile Include="ArrayParsingStyle.cs" /> <Compile Include="Contracts\IProcedureDesignerView.cs" /> + <Compile Include="Converters\BitmapToBitmapSourceConverter.cs" /> <Compile Include="CreateGroup.cs" /> <Compile Include="CreateItem.cs" /> <Compile Include="CSV\CsvColumn.cs" /> @@ -148,6 +149,7 @@ <Compile Include="ViewModels\MainViewVM.cs" /> <Compile Include="ViewModels\ProcedureDesignerViewVM.cs" /> <Compile Include="ViewModels\ProcedureRunnerViewVM.cs" /> + <Compile Include="ViewModels\ResultsViewVM.cs" /> <Compile Include="Views\MainView.xaml.cs"> <DependentUpon>MainView.xaml</DependentUpon> </Compile> @@ -163,6 +165,9 @@ <Compile Include="Views\ProcedureRunnerView.xaml.cs"> <DependentUpon>ProcedureRunnerView.xaml</DependentUpon> </Compile> + <Compile Include="Views\ResultsView.xaml.cs"> + <DependentUpon>ResultsView.xaml</DependentUpon> + </Compile> </ItemGroup> <ItemGroup> <Compile Include="Properties\AssemblyInfo.cs"> @@ -316,6 +321,10 @@ <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="Views\ResultsView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> </ItemGroup> <ItemGroup> <Resource Include="Images\test_designer.png" /> diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/ProcedureDesignerViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/ProcedureDesignerViewVM.cs index e20582352..b5d56f638 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/ProcedureDesignerViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/ProcedureDesignerViewVM.cs @@ -91,12 +91,7 @@ namespace Tango.FSE.Procedures.ViewModels set { _compilationErrors = value; RaisePropertyChangedAuto(); } } - private List<Result> _results; - public List<Result> Results - { - get { return _results; } - set { _results = value; RaisePropertyChangedAuto(); } - } + public ResultsViewVM ResultsViewVM { get; set; } public ObservableCollection<Script> OpenScripts { get; set; } @@ -180,7 +175,6 @@ namespace Tango.FSE.Procedures.ViewModels public RelayCommand TogglePublishPanelCommand { get; set; } public RelayCommand<Script> RenameLibraryCommand { get; set; } public RelayCommand<CreateItem> CreateItemCommand { get; set; } - public RelayCommand<Result> DisplayResultGridCommand { get; set; } #endregion @@ -191,7 +185,7 @@ namespace Tango.FSE.Procedures.ViewModels Status = "Ready"; LoadedAssemblies = new ObservableCollection<Assembly>(); - Results = new List<Result>(); + ResultsViewVM = new ResultsViewVM(); CompilationErrors = new List<CompilationError>(); Logger = new TextController(); ScriptEditor.LoadingSymbolsProgress += ScriptEditor_LoadingSymbolsProgress; @@ -228,7 +222,6 @@ namespace Tango.FSE.Procedures.ViewModels TogglePublishPanelCommand = new RelayCommand(() => IsPublishPanelOpened = !IsPublishPanelOpened, () => CurrentUser.HasPermission(Permissions.FSE_PublishProcedureProjects)); RenameLibraryCommand = new RelayCommand<Script>(RenameLibrary); CreateItemCommand = new RelayCommand<CreateItem>(AutoCreateItem); - DisplayResultGridCommand = new RelayCommand<Result>(DisplayResultGrid); } #endregion @@ -421,18 +414,18 @@ namespace Tango.FSE.Procedures.ViewModels if (await CompileProject()) { SelectedToolWindow = ToolWindows.Output; - Results = new List<Result>(); + ResultsViewVM.Results = new List<Result>(); Logger.Clear(); Logger.WriteLine("Running project..."); var context = new ProcedureContext(Project, this); await ProjectRunner.Run(context); - Results = context.Results.ToList(); + ResultsViewVM.Results = context.Results.ToList(); - if (Results.Count > 0) + if (ResultsViewVM.Results.Count > 0) { Logger.WriteLine("Project ran to completion with procedure results:"); - Logger.WriteLine(Results.ToJsonString()); + Logger.WriteLine(ResultsViewVM.Results.ToJsonString()); SelectedToolWindow = ToolWindows.Results; } } @@ -955,19 +948,6 @@ namespace Tango.FSE.Procedures.ViewModels #endregion - #region Results - - private void DisplayResultGrid(Result result) - { - if (result != null) - { - ResultGridViewVM vm = new ResultGridViewVM(result); - NotificationProvider.ShowDialog(vm); - } - } - - #endregion - #region INavigationObjectReceiver public async void OnNavigatedToWithObject(NavigationObject obj) diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/ProcedureRunnerViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/ProcedureRunnerViewVM.cs index 9d845218e..da5ecf324 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/ProcedureRunnerViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/ProcedureRunnerViewVM.cs @@ -68,12 +68,7 @@ namespace Tango.FSE.Procedures.ViewModels get { return RunningProcedureProject != null && RunningProcedureProject.Inputs.Count > 0; } } - private List<Result> _results; - public List<Result> Results - { - get { return _results; } - set { _results = value; RaisePropertyChangedAuto(); } - } + public ResultsViewVM ResultsViewVM { get; set; } private String _status; public String Status @@ -108,17 +103,15 @@ namespace Tango.FSE.Procedures.ViewModels public RelayCommand<PublishedProcedureProject> RunProjectCommand { get; set; } public RelayCommand StartProjectCommand { get; set; } public RelayCommand StopProjectCommand { get; set; } - public RelayCommand<Result> DisplayResultGridCommand { get; set; } - public RelayCommand<Result> ExportResultGridCommand { get; set; } public ProcedureRunnerViewVM() { + ResultsViewVM = new ResultsViewVM(); + EditProjectCommand = new RelayCommand<PublishedProcedureProject>(EditProject); RunProjectCommand = new RelayCommand<PublishedProcedureProject>(RunProject); StartProjectCommand = new RelayCommand(StartProject, () => ProjectRunner != null && ProjectRunner.CanRun); StopProjectCommand = new RelayCommand(StopProject, () => ProjectRunner != null && ProjectRunner.IsRunning); - DisplayResultGridCommand = new RelayCommand<Result>(DisplayResultGrid); - ExportResultGridCommand = new RelayCommand<Result>(ExportResultGrid); _requiresReloadingOfProjects = true; RegisterForMessage<ProcedureProjectPublishedOrSuppressed>((x) => _requiresReloadingOfProjects = true); @@ -130,14 +123,14 @@ namespace Tango.FSE.Procedures.ViewModels { IsRunning = true; FailedError = null; - Results = new List<Result>(); + ResultsViewVM.Results = new List<Result>(); Status = "Running..."; var context = new ProcedureContext(RunningProcedureProject, this); ProcedureProgress = new TangoProgress<double>(null); context.Progress += Context_Progress; await ProjectRunner.Run(context); Status = "Completed"; - Results = context.Results.ToList(); + ResultsViewVM.Results = context.Results.ToList(); } catch (OperationCanceledException) { @@ -249,107 +242,5 @@ namespace Tango.FSE.Procedures.ViewModels { //Do nothing } - - private void DisplayResultGrid(Result result) - { - if (result != null) - { - ResultGridViewVM vm = new ResultGridViewVM(result); - NotificationProvider.ShowDialog(vm); - } - } - - private async void ExportResultGrid(Result result) - { - if (result != null && result.IsValueArray && (result.Value as IList).Count > 0) - { - var r = await StorageProvider.SaveFile("Export procedure result", "CSV Files|*.csv", result.Name + ".csv", ".csv"); - if (r.Confirmed) - { - using (NotificationProvider.PushTaskItem("Exporting csv file...")) - { - try - { - await Task.Factory.StartNew(() => - { - List<Object> values = (result.Value as IEnumerable).Cast<Object>().ToList(); - - var model = values.First(); - - if (model.GetType().IsValueTypeOrString()) - { - CsvFile<CsvRow> csvFile = new CsvFile<CsvRow>(new CsvDestination(r.SelectedItem), new CsvDefinition() { Columns = new List<String>() { "Values" } }); - - foreach (var value in values) - { - csvFile.Append(new CsvRow() - { - V0 = value - }); - } - - csvFile.Dispose(); - } - else - { - List<CsvColumn> columns = new List<CsvColumn>(); - - //prop columns - foreach (var prop in model.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) - { - var att = prop.GetCustomAttribute<DescriptionAttribute>(); - columns.Add(new CsvColumn() - { - Name = prop.Name, - Description = att != null ? att.Description : prop.Name, - IsProperty = true, - PropertyInfo = prop - }); - } - - //field columns - foreach (var field in model.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance)) - { - var att = field.GetCustomAttribute<DescriptionAttribute>(); - columns.Add(new CsvColumn() - { - Name = field.Name, - Description = att != null ? att.Description : field.Name, - FieldInfo = field - }); - } - - CsvFile<CsvRow> csvFile = new CsvFile<CsvRow>(new CsvDestination(r.SelectedItem), new CsvDefinition() { Columns = columns.Select(x => x.Description).ToList() }); - - List<PropertyInfo> rowProps = typeof(CsvRow).GetProperties().ToList(); - - foreach (var value in values) - { - CsvRow row = new CsvRow(); - - for (int i = 0; i < columns.Count; i++) - { - var column = columns[i]; - rowProps[i].SetValue(row, column.GetValue(value)); - } - - csvFile.Append(row); - } - - csvFile.Dispose(); - } - }); - - await NotificationProvider.ShowSuccess("File exported successfully."); - } - catch (Exception ex) - { - LogManager.Log(ex, "Error exporting csv file."); - await NotificationProvider.ShowError($"Error occurred while exporting the csv file.\n{ex.FlattenMessage()}"); - } - } - } - } - } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/ResultsViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/ResultsViewVM.cs new file mode 100644 index 000000000..2fa496fb7 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/ResultsViewVM.cs @@ -0,0 +1,141 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.Commands; +using Tango.Core.DI; +using Tango.CSV; +using Tango.FSE.Common; +using Tango.FSE.Procedures.CSV; +using Tango.FSE.Procedures.Dialogs; + +namespace Tango.FSE.Procedures.ViewModels +{ + public class ResultsViewVM : FSEViewModel + { + private List<Result> _results; + public List<Result> Results + { + get { return _results; } + set { _results = value; RaisePropertyChangedAuto(); } + } + + public RelayCommand<Result> DisplayResultGridCommand { get; set; } + public RelayCommand<Result> ExportResultGridCommand { get; set; } + + public ResultsViewVM() + { + TangoIOC.Default.Inject(this); + + Results = new List<Result>(); + DisplayResultGridCommand = new RelayCommand<Result>(DisplayResultGrid); + ExportResultGridCommand = new RelayCommand<Result>(ExportResultGrid); + } + + private void DisplayResultGrid(Result result) + { + if (result != null) + { + ResultGridViewVM vm = new ResultGridViewVM(result); + NotificationProvider.ShowDialog(vm); + } + } + + private async void ExportResultGrid(Result result) + { + if (result != null && result.IsValueArray && (result.Value as IList).Count > 0) + { + var r = await StorageProvider.SaveFile("Export procedure result", "CSV Files|*.csv", result.Name + ".csv", ".csv"); + if (r.Confirmed) + { + using (NotificationProvider.PushTaskItem("Exporting csv file...")) + { + try + { + await Task.Factory.StartNew(() => + { + List<Object> values = (result.Value as IEnumerable).Cast<Object>().ToList(); + + var model = values.First(); + + if (model.GetType().IsValueTypeOrString()) + { + CsvFile<CsvRow> csvFile = new CsvFile<CsvRow>(new CsvDestination(r.SelectedItem), new CsvDefinition() { Columns = new List<String>() { "Values" } }); + + foreach (var value in values) + { + csvFile.Append(new CsvRow() + { + V0 = value + }); + } + + csvFile.Dispose(); + } + else + { + List<CsvColumn> columns = new List<CsvColumn>(); + + //prop columns + foreach (var prop in model.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) + { + var att = prop.GetCustomAttribute<DescriptionAttribute>(); + columns.Add(new CsvColumn() + { + Name = prop.Name, + Description = att != null ? att.Description : prop.Name, + IsProperty = true, + PropertyInfo = prop + }); + } + + //field columns + foreach (var field in model.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance)) + { + var att = field.GetCustomAttribute<DescriptionAttribute>(); + columns.Add(new CsvColumn() + { + Name = field.Name, + Description = att != null ? att.Description : field.Name, + FieldInfo = field + }); + } + + CsvFile<CsvRow> csvFile = new CsvFile<CsvRow>(new CsvDestination(r.SelectedItem), new CsvDefinition() { Columns = columns.Select(x => x.Description).ToList() }); + + List<PropertyInfo> rowProps = typeof(CsvRow).GetProperties().ToList(); + + foreach (var value in values) + { + CsvRow row = new CsvRow(); + + for (int i = 0; i < columns.Count; i++) + { + var column = columns[i]; + rowProps[i].SetValue(row, column.GetValue(value)); + } + + csvFile.Append(row); + } + + csvFile.Dispose(); + } + }); + + await NotificationProvider.ShowSuccess("File exported successfully."); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error exporting csv file."); + await NotificationProvider.ShowError($"Error occurred while exporting the csv file.\n{ex.FlattenMessage()}"); + } + } + } + } + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/ProcedureDesignerView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/ProcedureDesignerView.xaml index 26c1e19b8..51e966c9f 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/ProcedureDesignerView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/ProcedureDesignerView.xaml @@ -549,7 +549,7 @@ <TabItem.Header> <TextBlock> <Run>RESULTS</Run> - <Run>(</Run><Run Text="{Binding Results.Count,Mode=OneWay}"></Run><Run>)</Run> + <Run>(</Run><Run Text="{Binding ResultsViewVM.Results.Count,Mode=OneWay}"></Run><Run>)</Run> </TextBlock> </TabItem.Header> <DockPanel> @@ -558,52 +558,9 @@ <Rectangle VerticalAlignment="Bottom" Stroke="Black" StrokeThickness="2" /> </Grid> - <DataGrid ItemsSource="{Binding Results}" Style="{StaticResource FSE_LogsGridStyle}" CellStyle="{StaticResource FSE_LogsGridCellStyle}" HorizontalGridLinesBrush="{StaticResource FSE_PrimaryBackgroundBrush}" AutoGenerateColumns="False"> - <DataGrid.Columns> - <DataGridTemplateColumn Width="40"> - <DataGridTemplateColumn.CellTemplate> - <DataTemplate> - <material:PackIcon HorizontalAlignment="Center" VerticalAlignment="Center"> - <material:PackIcon.Style> - <Style TargetType="material:PackIcon"> - <Setter Property="Kind" Value="Check"></Setter> - <Setter Property="Foreground" Value="{StaticResource FSE_SuccessBrush}"></Setter> - <Style.Triggers> - <DataTrigger Binding="{Binding Type}" Value="Warning"> - <Setter Property="Kind" Value="Alert"></Setter> - <Setter Property="Foreground" Value="{StaticResource FSE_WarningBrush}"></Setter> - </DataTrigger> - <DataTrigger Binding="{Binding Type}" Value="Failed"> - <Setter Property="Kind" Value="Alert"></Setter> - <Setter Property="Foreground" Value="{StaticResource FSE_ErrorBrush}"></Setter> - </DataTrigger> - </Style.Triggers> - </Style> - </material:PackIcon.Style> - </material:PackIcon> - </DataTemplate> - </DataGridTemplateColumn.CellTemplate> - </DataGridTemplateColumn> - <DataGridTextColumn Header="NAME" Binding="{Binding Name}" /> - <DataGridTemplateColumn Header="VALUE" Width="1*"> - <DataGridTemplateColumn.CellTemplate> - <DataTemplate> - <Grid> - <TextBlock Visibility="{Binding IsValueArray,Converter={StaticResource BooleanToVisibilityInverseConverter}}" Text="{Binding Value}"></TextBlock> - <StackPanel Orientation="Horizontal" Visibility="{Binding IsValueArray,Converter={StaticResource BooleanToVisibilityConverter}}"> - <TextBlock Foreground="{StaticResource FSE_GrayBrush}"> - <Run>This procedure result contains</Run> - <Run Text="{Binding Value.Count,Mode=OneWay}"></Run> - <Run Text="Values."></Run> - </TextBlock> - <Button Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.DisplayResultGridCommand}" CommandParameter="{Binding}" Height="22" Foreground="{StaticResource FSE_PrimaryAccentBrush}" Background="Transparent" BorderBrush="Transparent" Margin="0 -4 0 0">(Grid View)</Button> - </StackPanel> - </Grid> - </DataTemplate> - </DataGridTemplateColumn.CellTemplate> - </DataGridTemplateColumn> - </DataGrid.Columns> - </DataGrid> + <ScrollViewer ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto"> + <local:ResultsView HorizontalAlignment="Left" DataContext="{Binding ResultsViewVM}" /> + </ScrollViewer> </DockPanel> </TabItem> </TabControl> diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/ProcedureRunnerExecutionView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/ProcedureRunnerExecutionView.xaml index 1f682c033..c47a2ac01 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/ProcedureRunnerExecutionView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/ProcedureRunnerExecutionView.xaml @@ -113,57 +113,8 @@ <TextBlock FontSize="{StaticResource FSE_LargeFontSize}" FontWeight="SemiBold" Foreground="{StaticResource FSE_PrimaryAccentBrush}">Results</TextBlock> <!--<Rectangle Margin="0 2 0 0" Stroke="{StaticResource FSE_BorderBrush}" StrokeDashArray="5" />--> </StackPanel> - <Grid> - <ItemsControl ItemsSource="{Binding Results}" HorizontalAlignment="Left" Margin="0 20 0 0"> - <ItemsControl.ItemTemplate> - <DataTemplate> - <DockPanel Margin="10"> - <material:PackIcon HorizontalAlignment="Center" VerticalAlignment="Center" Width="42" Height="42"> - <material:PackIcon.Style> - <Style TargetType="material:PackIcon"> - <Setter Property="Kind" Value="Check"></Setter> - <Setter Property="Foreground" Value="{StaticResource FSE_SuccessBrush}"></Setter> - <Style.Triggers> - <DataTrigger Binding="{Binding Type}" Value="Warning"> - <Setter Property="Kind" Value="Alert"></Setter> - <Setter Property="Foreground" Value="{StaticResource FSE_WarningBrush}"></Setter> - </DataTrigger> - <DataTrigger Binding="{Binding Type}" Value="Failed"> - <Setter Property="Kind" Value="Alert"></Setter> - <Setter Property="Foreground" Value="{StaticResource FSE_ErrorBrush}"></Setter> - </DataTrigger> - </Style.Triggers> - </Style> - </material:PackIcon.Style> - </material:PackIcon> - <StackPanel Margin="15 0 0 0" VerticalAlignment="Center"> - <TextBlock Text="{Binding Name}" ></TextBlock> - <Grid Margin="0 2 0 0"> - <TextBlock Visibility="{Binding IsValueArray,Converter={StaticResource BooleanToVisibilityInverseConverter}}" FontSize="{StaticResource FSE_SmallFontSize}" Foreground="{StaticResource FSE_GrayBrush}" Text="{Binding Value}"></TextBlock> - - <StackPanel Visibility="{Binding IsValueArray,Converter={StaticResource BooleanToVisibilityConverter}}"> - <StackPanel Orientation="Horizontal"> - <TextBlock FontSize="{StaticResource FSE_SmallFontSize}" Foreground="{StaticResource FSE_GrayBrush}"> - <Run>This procedure result contains</Run> - <Run Text="{Binding Value.Count,Mode=OneWay}"></Run> - <Run Text="Values."></Run> - </TextBlock> - <Button Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.DisplayResultGridCommand}" CommandParameter="{Binding}" Height="22" FontSize="{StaticResource FSE_SmallFontSize}" Foreground="{StaticResource FSE_PrimaryAccentBrush}" Background="Transparent" BorderBrush="Transparent" Margin="0 -4 0 0">(Grid View)</Button> - <Button Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.ExportResultGridCommand}" CommandParameter="{Binding}" Height="22" FontSize="{StaticResource FSE_SmallFontSize}" Foreground="{StaticResource FSE_PrimaryAccentBrush}" Background="Transparent" Padding="0" BorderBrush="Transparent" Margin="0 -4 0 0">(Export To CSV)</Button> - </StackPanel> - - <StackPanel Visibility="{Binding IsGraph,Converter={StaticResource BooleanToVisibilityConverter}}"> - <Border Margin="0 10 0 0" Padding="10" Background="#303030" CornerRadius="5"> - <graphs:RealTimeGraph Foreground="{StaticResource FSE_PrimaryForegroundBrush}" GridLinesBrush="#383838" BorderBrush="Transparent" Width="750" Height="250" Loaded="RealTimeGraph_Loaded" Style="{StaticResource FSE_RealTimeGraph_Result}" /> - </Border> - </StackPanel> - </StackPanel> - </Grid> - </StackPanel> - </DockPanel> - </DataTemplate> - </ItemsControl.ItemTemplate> - </ItemsControl> + <Grid HorizontalAlignment="Left" Margin="0 20 0 0"> + <local:ResultsView DataContext="{Binding ResultsViewVM}" /> </Grid> </StackPanel> </StackPanel> diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/ResultsView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/ResultsView.xaml new file mode 100644 index 000000000..569b77820 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/ResultsView.xaml @@ -0,0 +1,75 @@ +<UserControl x:Class="Tango.FSE.Procedures.Views.ResultsView" + 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:global="clr-namespace:Tango.FSE.Procedures" + xmlns:vm="clr-namespace:Tango.FSE.Procedures.ViewModels" + xmlns:graphs="clr-namespace:Tango.FSE.Common.Graphs;assembly=Tango.FSE.Common" + xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:converters="clr-namespace:Tango.FSE.Procedures.Converters" + xmlns:local="clr-namespace:Tango.FSE.Procedures.Views" + mc:Ignorable="d" + d:DesignHeight="720" d:DesignWidth="1280" d:DesignStyle="{StaticResource FSE_User_Control_Designer}" d:DataContext="{d:DesignInstance Type=vm:ResultsViewVM, IsDesignTimeCreatable=False}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}"> + + <UserControl.Resources> + <converters:BitmapToBitmapSourceConverter x:Key="BitmapToBitmapSourceConverter" /> + </UserControl.Resources> + + <Grid> + <ItemsControl ItemsSource="{Binding Results}"> + <ItemsControl.ItemTemplate> + <DataTemplate> + <DockPanel Margin="10"> + <material:PackIcon HorizontalAlignment="Center" VerticalAlignment="Center" Width="42" Height="42"> + <material:PackIcon.Style> + <Style TargetType="material:PackIcon"> + <Setter Property="Kind" Value="Check"></Setter> + <Setter Property="Foreground" Value="{StaticResource FSE_SuccessBrush}"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding Type}" Value="Warning"> + <Setter Property="Kind" Value="Alert"></Setter> + <Setter Property="Foreground" Value="{StaticResource FSE_WarningBrush}"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Type}" Value="Failed"> + <Setter Property="Kind" Value="Alert"></Setter> + <Setter Property="Foreground" Value="{StaticResource FSE_ErrorBrush}"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </material:PackIcon.Style> + </material:PackIcon> + <StackPanel Margin="15 0 0 0" VerticalAlignment="Center"> + <TextBlock Text="{Binding Name}" ></TextBlock> + <Grid Margin="0 2 0 0" Visibility="{Binding IsBitmap,Converter={StaticResource BooleanToVisibilityInverseConverter}}"> + <TextBlock Visibility="{Binding IsValueArray,Converter={StaticResource BooleanToVisibilityInverseConverter}}" FontSize="{StaticResource FSE_SmallFontSize}" Foreground="{StaticResource FSE_GrayBrush}" Text="{Binding Value}"></TextBlock> + + <StackPanel Visibility="{Binding IsValueArray,Converter={StaticResource BooleanToVisibilityConverter}}"> + <StackPanel Orientation="Horizontal"> + <TextBlock FontSize="{StaticResource FSE_SmallFontSize}" Foreground="{StaticResource FSE_GrayBrush}"> + <Run>This procedure result contains</Run> + <Run Text="{Binding Value.Count,Mode=OneWay}"></Run> + <Run Text="Values."></Run> + </TextBlock> + <Button Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.DisplayResultGridCommand}" CommandParameter="{Binding}" Height="22" FontSize="{StaticResource FSE_SmallFontSize}" Foreground="{StaticResource FSE_PrimaryAccentBrush}" Background="Transparent" BorderBrush="Transparent" Margin="0 -4 0 0">(Grid View)</Button> + <Button Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.ExportResultGridCommand}" CommandParameter="{Binding}" Height="22" FontSize="{StaticResource FSE_SmallFontSize}" Foreground="{StaticResource FSE_PrimaryAccentBrush}" Background="Transparent" Padding="0" BorderBrush="Transparent" Margin="0 -4 0 0">(Export To CSV)</Button> + </StackPanel> + + <StackPanel Visibility="{Binding IsGraph,Converter={StaticResource BooleanToVisibilityConverter}}"> + <Border Margin="0 10 0 0" Padding="10" Background="#303030" CornerRadius="5"> + <graphs:RealTimeGraph Foreground="{StaticResource FSE_PrimaryForegroundBrush}" GridLinesBrush="#383838" BorderBrush="Transparent" Width="750" Height="250" Loaded="RealTimeGraph_Loaded" Style="{StaticResource FSE_RealTimeGraph_Result}" /> + </Border> + </StackPanel> + </StackPanel> + </Grid> + + <Grid Margin="0 2 0 0" Visibility="{Binding IsBitmap,Converter={StaticResource BooleanToVisibilityConverter}}"> + <Image HorizontalAlignment="Left" Source="{Binding Value,Converter={StaticResource BitmapToBitmapSourceConverter}}" Stretch="None" /> + </Grid> + </StackPanel> + </DockPanel> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/ResultsView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/ResultsView.xaml.cs new file mode 100644 index 000000000..d85b0eca8 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/ResultsView.xaml.cs @@ -0,0 +1,55 @@ +using RealTimeGraphX.DataPoints; +using RealTimeGraphX.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.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.FSE.Common.Graphs; + +namespace Tango.FSE.Procedures.Views +{ + /// <summary> + /// Interaction logic for ResultsView.xaml + /// </summary> + public partial class ResultsView : UserControl + { + public ResultsView() + { + InitializeComponent(); + } + + private void RealTimeGraph_Loaded(object sender, RoutedEventArgs e) + { + RealTimeGraph graph = sender as RealTimeGraph; + Result result = graph.DataContext as Result; + + if (result != null && result.IsGraph) + { + var values = (result.Value as IEnumerable<double>).ToList(); + + WpfGraphController<Int32DataPoint, DoubleDataPoint> controller = new WpfGraphController<Int32DataPoint, DoubleDataPoint>(); + controller.Range.AutoY = false; + controller.Range.MinimumY = values.Min(); + controller.Range.MaximumY = values.Max(); + controller.Range.MaximumX = values.Count; + + controller.DataSeriesCollection.Add(new WpfGraphDataSeries() { Stroke = Colors.DodgerBlue }); + graph.Controller = controller; + + controller.PushData( + Enumerable.Range(0, values.Count).Select(x => new Int32DataPoint(x)), + values.Select(x => new DoubleDataPoint(x))); + } + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownType.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownType.cs index 3dc465541..3dc796152 100644 --- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownType.cs +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownType.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Drawing; using System.IO; using System.Linq; using System.Reflection; @@ -182,7 +183,12 @@ namespace Tango.Scripting.Editors.Intellisense //Load Properties { - var properties = Type.GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance).ToList(); + if (Type == typeof(Color)) + { + + } + + var properties = Type.GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static).ToList(); for (int i = 0; i < properties.Count; i++) { diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs index 3ceecae4b..71a455f86 100644 --- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs @@ -1114,6 +1114,11 @@ namespace Tango.Scripting.Editors return knownType; } } + else + { + //Maybe static... + return _knownTypes.FirstOrDefault(x => x.Name == variableName); + } } } @@ -1165,6 +1170,11 @@ namespace Tango.Scripting.Editors return declaredType; } } + else + { + //Maybe static... + return _declaredTypes.FirstOrDefault(x => x.Name == variableName); + } } } |
