using System; using System.IO; using Avalonia; using Avalonia.Controls; using Avalonia.Layout; using Avalonia.Markup.Xaml; using UVtools.Core.Operations; using UVtools.Core.Scripting; using UVtools.WPF.Extensions; using UVtools.WPF.Windows; namespace UVtools.WPF.Controls.Tools { public class ToolScriptingControl : ToolControl { public OperationScripting Operation => BaseOperation as OperationScripting; private readonly StackPanel _scriptConfigurationPanel; private readonly Grid _scriptVariablesGrid; public ToolScriptingControl() { InitializeComponent(); _scriptConfigurationPanel = this.FindControl("ScriptConfigurationPanel"); _scriptVariablesGrid = this.FindControl("ScriptVariablesGrid"); BaseOperation = new OperationScripting(SlicerFile); } private void InitializeComponent() { AvaloniaXamlLoader.Load(this); } public override void Callback(ToolWindow.Callbacks callback) { switch (callback) { case ToolWindow.Callbacks.Init: case ToolWindow.Callbacks.Loaded: ParentWindow.ButtonOkEnabled = Operation.CanExecute; ReloadGUI(); Operation.PropertyChanged += (sender, e) => { if (e.PropertyName == nameof(Operation.CanExecute)) { ParentWindow.ButtonOkEnabled = Operation.CanExecute; } }; Operation.OnScriptReload += (sender, e) => ReloadGUI(); break; } } public async void LoadScript() { var dialog = new OpenFileDialog { AllowMultiple = false, Directory = UserSettings.Instance.General.DefaultDirectoryScripts, Filters = Helpers.ScriptsFileFilter, }; var files = await dialog.ShowAsync(ParentWindow); if (files is null || files.Length == 0) return; Operation.FilePath = files[0]; ReloadScript(); } public async void ReloadScript() { try { Operation.ReloadScriptFromFile(); } catch (Exception e) { await ParentWindow.MessageBoxError(e.Message); } } public void OpenScriptFolder() { if (!Operation.HaveFile) return; App.StartProcess(Path.GetDirectoryName(Operation.FilePath)); } public void OpenScriptFile() { if (!Operation.HaveFile) return; App.StartProcess(Operation.FilePath); } public void ReloadGUI() { if (!Operation.CanExecute) return; _scriptConfigurationPanel.Children.Clear(); _scriptVariablesGrid.Children.Clear(); _scriptVariablesGrid.RowDefinitions.Clear(); TextBox tbScriptName = new() { IsReadOnly = true, Text = $"{Operation.ScriptGlobals.Script.Name} | Version: {Operation.ScriptGlobals.Script.Version} by {Operation.ScriptGlobals.Script.Author}", UseFloatingWatermark = true, Watermark = "Script name, version and author" }; TextBox tbScriptDescription = new() { IsReadOnly = true, Text = Operation.ScriptGlobals.Script.Description, AcceptsReturn = true, UseFloatingWatermark = true, Watermark = "Script description" }; _scriptConfigurationPanel.Children.Add(tbScriptName); _scriptConfigurationPanel.Children.Add(tbScriptDescription); //Operation.ScriptGlobals.Script.UserInputs.Add(new ScriptBoolInput() { Label = "Hellow" }); //Operation.ScriptGlobals.Script.UserInputs.Add(new ScriptTextBoxInput() { Label = "Hellow", Value = "m,e", MultiLine = true}); if (Operation.ScriptGlobals.Script.UserInputs.Count == 0) { return; } string rowDefinitions = string.Empty; for (var i = 0; i < Operation.ScriptGlobals.Script.UserInputs.Count; i++) { if (i < Operation.ScriptGlobals.Script.UserInputs.Count - 1) { rowDefinitions += "Auto,10,"; } else { rowDefinitions += "Auto"; } } _scriptVariablesGrid.RowDefinitions = RowDefinitions.Parse(rowDefinitions); for (var i = 0; i < Operation.ScriptGlobals.Script.UserInputs.Count; i++) { var variable = Operation.ScriptGlobals.Script.UserInputs[i]; if (!string.IsNullOrWhiteSpace(variable.Label) && variable is not ScriptCheckBoxInput) { TextBlock tbLabel = new() { VerticalAlignment = VerticalAlignment.Center, Text = $"{variable.Label}:" }; if (!string.IsNullOrWhiteSpace(variable.ToolTip)) { ToolTip.SetTip(tbLabel, variable.ToolTip); } _scriptVariablesGrid.Children.Add(tbLabel); Grid.SetRow(tbLabel, i * 2); Grid.SetColumn(tbLabel, 0); } if (!string.IsNullOrWhiteSpace(variable.Unit)) { TextBlock control = new() { VerticalAlignment = VerticalAlignment.Center, Text = variable.Unit }; _scriptVariablesGrid.Children.Add(control); Grid.SetRow(control, i * 2); Grid.SetColumn(control, 4); } switch (variable) { case ScriptNumericalInput numSBYTE: { NumericUpDown control = new() { Minimum = numSBYTE.Minimum, Maximum = numSBYTE.Maximum, Value = numSBYTE.Value, Increment = numSBYTE.Increment, MinWidth = 150 }; var valueProperty = control.GetObservable(NumericUpDown.ValueProperty); valueProperty.Subscribe(value => { numSBYTE.Value = (sbyte)value; control.Value = numSBYTE.Value; }); _scriptVariablesGrid.Children.Add(control); Grid.SetRow(control, i * 2); Grid.SetColumn(control, 2); continue; } case ScriptNumericalInput numBYTE: { NumericUpDown control = new() { Minimum = numBYTE.Minimum, Maximum = numBYTE.Maximum, Value = numBYTE.Value, Increment = numBYTE.Increment, MinWidth = 150 }; var valueProperty = control.GetObservable(NumericUpDown.ValueProperty); valueProperty.Subscribe(value => { numBYTE.Value = (byte)value; control.Value = numBYTE.Value; }); _scriptVariablesGrid.Children.Add(control); Grid.SetRow(control, i * 2); Grid.SetColumn(control, 2); continue; } case ScriptNumericalInput numSHORT: { NumericUpDown control = new() { Minimum = numSHORT.Minimum, Maximum = numSHORT.Maximum, Value = numSHORT.Value, Increment = numSHORT.Increment, MinWidth = 150 }; var valueProperty = control.GetObservable(NumericUpDown.ValueProperty); valueProperty.Subscribe(value => { numSHORT.Value = (short)value; control.Value = numSHORT.Value; }); _scriptVariablesGrid.Children.Add(control); Grid.SetRow(control, i * 2); Grid.SetColumn(control, 2); continue; } case ScriptNumericalInput numUSHORT: { NumericUpDown control = new() { Minimum = numUSHORT.Minimum, Maximum = numUSHORT.Maximum, Value = numUSHORT.Value, Increment = numUSHORT.Increment, MinWidth = 150 }; var valueProperty = control.GetObservable(NumericUpDown.ValueProperty); valueProperty.Subscribe(value => { numUSHORT.Value = (ushort)value; control.Value = numUSHORT.Value; }); _scriptVariablesGrid.Children.Add(control); Grid.SetRow(control, i * 2); Grid.SetColumn(control, 2); continue; } case ScriptNumericalInput numINT: { NumericUpDown control = new() { Minimum = numINT.Minimum, Maximum = numINT.Maximum, Value = numINT.Value, Increment = numINT.Increment, MinWidth = 150 }; var valueProperty = control.GetObservable(NumericUpDown.ValueProperty); valueProperty.Subscribe(value => { numINT.Value = (int)value; control.Value = numINT.Value; }); _scriptVariablesGrid.Children.Add(control); Grid.SetRow(control, i * 2); Grid.SetColumn(control, 2); continue; } case ScriptNumericalInput numUINT: { NumericUpDown control = new() { Minimum = numUINT.Minimum, Maximum = numUINT.Maximum, Value = numUINT.Value, Increment = numUINT.Increment, MinWidth = 150 }; var valueProperty = control.GetObservable(NumericUpDown.ValueProperty); valueProperty.Subscribe(value => { numUINT.Value = (uint)value; control.Value = numUINT.Value; }); _scriptVariablesGrid.Children.Add(control); Grid.SetRow(control, i * 2); Grid.SetColumn(control, 2); continue; } case ScriptNumericalInput numLONG: { NumericUpDown control = new() { Minimum = numLONG.Minimum, Maximum = numLONG.Maximum, Value = numLONG.Value, Increment = numLONG.Increment, MinWidth = 150 }; var valueProperty = control.GetObservable(NumericUpDown.ValueProperty); valueProperty.Subscribe(value => { numLONG.Value = (long)value; control.Value = numLONG.Value; }); _scriptVariablesGrid.Children.Add(control); Grid.SetRow(control, i * 2); Grid.SetColumn(control, 2); continue; } case ScriptNumericalInput numULONG: { NumericUpDown control = new() { Minimum = numULONG.Minimum, Maximum = numULONG.Maximum, Value = numULONG.Value, Increment = numULONG.Increment, MinWidth = 150 }; var valueProperty = control.GetObservable(NumericUpDown.ValueProperty); valueProperty.Subscribe(value => { numULONG.Value = (ulong)value; control.Value = numULONG.Value; }); _scriptVariablesGrid.Children.Add(control); Grid.SetRow(control, i * 2); Grid.SetColumn(control, 2); continue; } case ScriptNumericalInput numFLOAT: { NumericUpDown control = new() { Minimum = numFLOAT.Minimum, Maximum = numFLOAT.Maximum, Value = numFLOAT.Value, Increment = numFLOAT.Increment, MinWidth = 150 }; if (numFLOAT.DecimalPlates > 0) { control.FormatString = $"F{numFLOAT.DecimalPlates}"; } var valueProperty = control.GetObservable(NumericUpDown.ValueProperty); valueProperty.Subscribe(value => { numFLOAT.Value = (float) Math.Round(value, numFLOAT.DecimalPlates); control.Value = numFLOAT.Value; }); _scriptVariablesGrid.Children.Add(control); Grid.SetRow(control, i * 2); Grid.SetColumn(control, 2); continue; } case ScriptNumericalInput numDOUBLE: { NumericUpDown control = new() { Minimum = numDOUBLE.Minimum, Maximum = numDOUBLE.Maximum, Value = numDOUBLE.Value, Increment = numDOUBLE.Increment, MinWidth = 150 }; if (numDOUBLE.DecimalPlates > 0) { control.FormatString = $"F{numDOUBLE.DecimalPlates}"; } var valueProperty = control.GetObservable(NumericUpDown.ValueProperty); valueProperty.Subscribe(value => { numDOUBLE.Value = Math.Round(value, numDOUBLE.DecimalPlates); control.Value = numDOUBLE.Value; }); _scriptVariablesGrid.Children.Add(control); Grid.SetRow(control, i * 2); Grid.SetColumn(control, 2); continue; } case ScriptNumericalInput numDECIMAL: { NumericUpDown control = new() { Minimum = (double)numDECIMAL.Minimum, Maximum = (double)numDECIMAL.Maximum, Value = (double)numDECIMAL.Value, Increment = (double)numDECIMAL.Increment, MinWidth = 150 }; if (numDECIMAL.DecimalPlates > 0) { control.FormatString = $"F{numDECIMAL.DecimalPlates}"; } var valueProperty = control.GetObservable(NumericUpDown.ValueProperty); valueProperty.Subscribe(value => { numDECIMAL.Value = (decimal)Math.Round(value, numDECIMAL.DecimalPlates); control.Value = (double)numDECIMAL.Value; }); _scriptVariablesGrid.Children.Add(control); Grid.SetRow(control, i * 2); Grid.SetColumn(control, 2); continue; } case ScriptCheckBoxInput inputCheckBox: { CheckBox control = new() { Content = variable.Label, IsChecked = inputCheckBox.Value }; var valueProperty = control.GetObservable(CheckBox.IsCheckedProperty); valueProperty.Subscribe(value => { if (value != null) inputCheckBox.Value = value.Value; }); _scriptVariablesGrid.Children.Add(control); Grid.SetRow(control, i * 2); Grid.SetColumn(control, 2); if (!string.IsNullOrWhiteSpace(variable.ToolTip)) { ToolTip.SetTip(control, variable.ToolTip); } continue; } case ScriptTextBoxInput inputTextBox: { TextBox control = new() { AcceptsReturn = inputTextBox.MultiLine, Text = inputTextBox.Value, }; var valueProperty = control.GetObservable(TextBox.TextProperty); valueProperty.Subscribe(value => { inputTextBox.Value = value; }); _scriptVariablesGrid.Children.Add(control); Grid.SetRow(control, i * 2); Grid.SetColumn(control, 2); continue; } } } ParentWindow.FitToSize(); } } }