ctb v3 and more abstraction on tool window

This commit is contained in:
Tiago Conceição
2020-09-08 05:20:51 +01:00
parent 018fa885f7
commit 851fe6b2d3
10 changed files with 186 additions and 76 deletions
+16 -8
View File
@@ -867,15 +867,15 @@ namespace UVtools.Core.FileFormats
{
}
public LayerDataEx(LayerData layerData)
public LayerDataEx(LayerData layerData, uint layerIndex)
{
LayerData = layerData;
if (!ReferenceEquals(layerData.Parent, null))
{
LiftHeight = layerData.Parent.LiftHeight;
LiftSpeed = layerData.Parent.LiftSpeed;
RetractSpeed = layerData.Parent.RetractSpeed;
LightPWM = layerData.Parent.HeaderSettings.LightPWM;
LiftHeight = layerData.Parent.GetInitialLayerValueOrNormal(layerIndex, layerData.Parent.PrintParametersSettings.BottomLiftHeight, layerData.Parent.PrintParametersSettings.LiftHeight);
LiftSpeed = layerData.Parent.GetInitialLayerValueOrNormal(layerIndex, layerData.Parent.PrintParametersSettings.BottomLiftSpeed, layerData.Parent.PrintParametersSettings.LiftSpeed);
RetractSpeed = layerData.Parent.PrintParametersSettings.RetractSpeed;
LightPWM = layerData.Parent.GetInitialLayerValueOrNormal(layerIndex, layerData.Parent.HeaderSettings.BottomLightPWM, layerData.Parent.HeaderSettings.LightPWM);
}
if (layerData.DataSize > 0)
@@ -1096,7 +1096,8 @@ namespace UVtools.Core.FileFormats
if(SlicerInfoSettings.MysteriousId == 0)
SlicerInfoSettings.MysteriousId = 0x12345678;
SlicerInfoSettings.Unknown1 = HeaderSettings.Version == 3 ? 0u : 0x200;
if(SlicerInfoSettings.Unknown1 == 0)
SlicerInfoSettings.Unknown1 = HeaderSettings.Version == 3 ? 0u : 0x200;
if (HeaderSettings.EncryptionKey == 0)
{
@@ -1166,7 +1167,7 @@ namespace UVtools.Core.FileFormats
HeaderSettings.LayersDefinitionOffsetAddress = currentOffset;
uint layerDataCurrentOffset = currentOffset + (uint)Helpers.Serializer.SizeOf(new LayerData()) * HeaderSettings.LayerCount * HeaderSettings.AntiAliasLevel;
progress.ItemCount *= 2 * HeaderSettings.AntiAliasLevel;
for (byte aaIndex = 0; aaIndex < HeaderSettings.AntiAliasLevel; aaIndex++)
@@ -1208,11 +1209,18 @@ namespace UVtools.Core.FileFormats
}
}
if (ReferenceEquals(layerDataHash, null))
if (layerDataHash is null)
{
layerData.DataAddress = layerDataCurrentOffset;
outputFile.Seek(layerDataCurrentOffset, SeekOrigin.Begin);
if (HeaderSettings.Version >= 3)
{
var layerDataEx = new LayerDataEx(layerData, layerIndex);
layerData.DataAddress = layerDataCurrentOffset += Helpers.SerializeWriteFileStream(outputFile, layerDataEx);
}
layerDataCurrentOffset += outputFile.WriteBytes(layerData.EncodedRle);
}
+26 -1
View File
@@ -5,6 +5,9 @@
* Everyone is permitted to copy and distribute verbatim copies
* of this license document, but changing it is not allowed.
*/
using UVtools.Core.Obects;
namespace UVtools.Core.Operations
{
public class Operation
@@ -16,8 +19,30 @@ namespace UVtools.Core.Operations
/// </summary>
public string Id => GetType().Name.Remove(0, ClassNameLength);
/// <summary>
/// Gets the title of this operation
/// </summary>
public virtual string Title => Id;
/// <summary>
/// Gets a descriptive text of this operation
/// </summary>
public virtual string Description => Id;
/// <summary>
/// Gets the Ok button text
/// </summary>
public virtual string ButtonOkText => Title;
/// <summary>
/// Gets the confirmation text for the operation
/// </summary>
public virtual string ConfirmationText => $"Are you sure you want to {Id}";
public virtual string Validate() => null;
/// <summary>
/// Validates the operation
/// </summary>
/// <returns>null or empty if validates, or else, return a string with error message</returns>
public virtual StringTag Validate(params object[] parameters) => null;
}
}
@@ -1,10 +1,12 @@
using System.Drawing;
using System.Text;
using UVtools.Core.Obects;
namespace UVtools.Core.Operations
{
public sealed class OperationChangeResolution : Operation
{
#region Subclasses
public class Resolution
{
public uint ResolutionX { get; }
@@ -28,7 +30,41 @@ namespace UVtools.Core.Operations
return str;
}
}
#endregion
#region Overrides
public override string Title => "Change Resolution";
public override string Description =>
"Crops or resizes all layer images to fit an alternate print area\n" +
"Useful to make files printable on a different printer than they were originally sliced for without the need to re-slice.\n" +
"NOTE: Please ensure that the actual object will fit within the new print resolution. The operation will be aborted if it will result in any of the actual model being clipped.";
public override string ConfirmationText =>
"Are you sure you want change file resolution?\n" +
$"From: {OldResolutionX} x {OldResolutionY}\n" +
$"To: {NewResolutionX} x {NewResolutionY}";
public override StringTag Validate(params object[] parameters)
{
var sb = new StringBuilder();
if (OldResolutionX == NewResolutionX && OldResolutionY == NewResolutionY)
{
sb.AppendLine($"The new resolution must be different from current resolution ({OldResolutionX} x {OldResolutionY}).");
}
if (NewResolutionX < VolumeBonds.Width || NewResolutionY < VolumeBonds.Height)
{
sb.AppendLine($"The new resolution ({NewResolutionX} x {NewResolutionY}) is not enough to accommodate the object volume ({VolumeBonds.Width} x {VolumeBonds.Height}), continuing operation would cut the object");
sb.AppendLine("To fix this, try to rotate the object and/or resize to fit on this new resolution.");
}
return new StringTag(sb.ToString());
}
#endregion
#region Properties
public uint OldResolutionX { get; }
public uint OldResolutionY { get; }
@@ -36,17 +72,16 @@ namespace UVtools.Core.Operations
public uint NewResolutionY { get; set; }
public Rectangle VolumeBonds { get; }
public override string ConfirmationText => "Are you sure you want change file resolution?\n" +
$"From: {OldResolutionX} x {OldResolutionY}\n" +
$"To: {NewResolutionX} x {NewResolutionY}";
#endregion
#region Constructor
public OperationChangeResolution(uint oldResolutionX, uint oldResolutionY, Rectangle volumeBonds)
{
OldResolutionX = oldResolutionX;
OldResolutionY = oldResolutionY;
VolumeBonds = volumeBonds;
}
#endregion
public static Resolution[] GetResolutions()
{
@@ -68,21 +103,6 @@ namespace UVtools.Core.Operations
};
}
public override string Validate()
{
var sb = new StringBuilder();
if (OldResolutionX == NewResolutionX && OldResolutionY == NewResolutionY)
{
sb.AppendLine($"The new resolution must be different from current resolution ({OldResolutionX} x {OldResolutionY}).");
}
if (NewResolutionX < VolumeBonds.Width || NewResolutionY < VolumeBonds.Height)
{
sb.AppendLine($"The new resolution ({NewResolutionX} x {NewResolutionY}) is not enough to accommodate the object volume ({VolumeBonds.Width} x {VolumeBonds.Height}), continuing operation would cut the object");
sb.AppendLine("To fix this, try to rotate the object and/or resize to fit on this new resolution.");
}
return sb.ToString();
}
}
}
@@ -4,14 +4,18 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Ocl;
using UVtools.Core.Obects;
namespace UVtools.Core.Operations
{
public sealed class OperationLayerImport : Operation
{
public Size FileResolution { get; }
public uint InsertAfterLayerIndex { get; set; }
public bool ReplaceStartLayer { get; set; }
public bool ReplaceSubsequentLayers { get; set; }
@@ -21,27 +25,55 @@ namespace UVtools.Core.Operations
public int Count => Files.Count;
public override string Title => "Import Layer(s)";
public override string Description =>
"Import layer(s) from local file(s) into the model at a selected height.\n" +
"NOTE: Images must respect file resolution and in greyscale color.";
public override string ConfirmationText => $"import {Count} layer(s)?";
public OperationLayerImport(Size fileResolution)
{
FileResolution = fileResolution;
}
public void Sort()
{
Files.Sort((file1, file2) => string.Compare(Path.GetFileNameWithoutExtension(file1), Path.GetFileNameWithoutExtension(file2), StringComparison.Ordinal));
}
public ConcurrentBag<string> Validate(Size resolution)
public override StringTag Validate(params object[] parameters)
{
var result = new ConcurrentBag<string>();
Parallel.ForEach(Files, file =>
{
using (Mat mat = CvInvoke.Imread(file, ImreadModes.AnyColor))
{
if (mat.Size != resolution)
if (mat.Size != FileResolution)
{
result.Add(file);
}
}
});
return result;
if (result.IsEmpty) return null;
var message = new StringBuilder();
message.AppendLine($"The following {result.Count} files mismatched the slice resolution of {FileResolution.Width} x {FileResolution.Height}:");
message.AppendLine();
uint count = 0;
foreach (var file in result)
{
count++;
if (count == 20)
{
message.AppendLine("... To many to show ...");
break;
}
message.AppendLine(Path.GetFileNameWithoutExtension(file));
}
return new StringTag(message.ToString(), result);
}
public uint CalculateTotalLayers(uint totalLayers)
+57 -3
View File
@@ -10,6 +10,8 @@ using System.Drawing.Design;
using System.Runtime.CompilerServices;
using System.Windows.Forms;
using UVtools.Core.Extensions;
using UVtools.Core.Obects;
using UVtools.Core.Operations;
using UVtools.GUI.Annotations;
using UVtools.GUI.Forms;
@@ -71,9 +73,10 @@ namespace UVtools.GUI.Controls
}
#endregion
#region Properties
[ReadOnly(true)] [Browsable(false)] public Operation BaseOperation { get; private set; }
[ReadOnly(true)] [Browsable(false)] public FrmToolWindow ParentToolWindow => ParentForm as FrmToolWindow;
[Editor("System.ComponentModel.Design.MultilineStringEditor", typeof(UITypeEditor))]
@@ -108,7 +111,18 @@ namespace UVtools.GUI.Controls
[ReadOnly(true)]
[Browsable(false)]
public virtual string ConfirmationText => $"{Text}?";
public virtual string ConfirmationText
{
get
{
if (BaseOperation is null || string.IsNullOrEmpty(BaseOperation.ConfirmationText))
{
return $"{Text}?";
}
return BaseOperation.ConfirmationText;
}
}
#endregion
@@ -121,8 +135,35 @@ namespace UVtools.GUI.Controls
#region Methods
public virtual bool ValidateForm() => true;
public void SetOperation(Operation operation)
{
BaseOperation = operation;
if(!string.IsNullOrEmpty(operation.Title)) Text = operation.Title;
if (!string.IsNullOrEmpty(operation.Description)) Description = operation.Description;
if (!string.IsNullOrEmpty(operation.ButtonOkText)) ButtonOkText = operation.ButtonOkText;
}
/// <summary>
/// Updates operation object with items retrieved from form fields
/// </summary>
public virtual void UpdateOperation(){}
/// <summary>
/// Validates if is safe to continue with operation
/// </summary>
/// <returns></returns>
public virtual bool ValidateForm()
{
if (BaseOperation is null) return true;
UpdateOperation();
return ValidateFormFromString(BaseOperation.Validate());
}
/// <summary>
/// Validates if is safe to continue with operation, if not shows a message box with the error
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
public bool ValidateFormFromString(string text)
{
if (string.IsNullOrEmpty(text)) return true;
@@ -130,6 +171,19 @@ namespace UVtools.GUI.Controls
return false;
}
/// <summary>
/// Validates if is safe to continue with operation, if not shows a message box with the error
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
public bool ValidateFormFromString(StringTag text)
{
if (text is null) return true;
if (string.IsNullOrEmpty(text.ToString())) return true;
MessageBoxError(text.ToString());
return false;
}
public DialogResult MessageBoxError(string message, MessageBoxButtons buttons = MessageBoxButtons.OK) => GUIExtensions.MessageErrorBox($"{Text} Error", message, buttons);
public DialogResult MessageQuestionBox(string message, string title = null, MessageBoxButtons buttons = MessageBoxButtons.YesNo) => GUIExtensions.MessageQuestionBox($"{title ?? Text}", message, buttons);
@@ -28,7 +28,6 @@
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CtrlToolChangeResolution));
this.lbObjectVolume = new System.Windows.Forms.Label();
this.nmNewY = new System.Windows.Forms.NumericUpDown();
this.label3 = new System.Windows.Forms.Label();
@@ -149,7 +148,6 @@
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.ButtonOkText = "Change Resolution";
this.Controls.Add(this.lbObjectVolume);
this.Controls.Add(this.nmNewY);
this.Controls.Add(this.label3);
@@ -158,7 +156,7 @@
this.Controls.Add(this.cbPreset);
this.Controls.Add(this.label2);
this.Controls.Add(this.lbCurrent);
this.Description = resources.GetString("$this.Description");
this.Description = "";
this.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.LayerRangeVisible = false;
this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
@@ -18,13 +18,11 @@ namespace UVtools.GUI.Controls.Tools
public uint NewResolutionX => (uint) nmNewX.Value;
public uint NewResolutionY => (uint) nmNewY.Value;
public override string ConfirmationText => Operation.ConfirmationText;
public CtrlToolChangeResolution(uint oldResolutionX, uint oldResolutionY, Rectangle volumeBonds)
{
InitializeComponent();
Text = "Change Resolution";
Operation = new OperationChangeResolution(oldResolutionX, oldResolutionY, volumeBonds);
SetOperation(Operation);
lbCurrent.Text = $"Current resolution (X/Y): {oldResolutionX} x {oldResolutionY}";
lbObjectVolume.Text = $"Object volume (X/Y): {volumeBonds.Width} x {volumeBonds.Height}";
@@ -58,11 +56,10 @@ namespace UVtools.GUI.Controls.Tools
}
}
public override bool ValidateForm()
public override void UpdateOperation()
{
Operation.NewResolutionX = NewResolutionX;
Operation.NewResolutionY = NewResolutionY;
return ValidateFormFromString(Operation.Validate());
}
}
}
@@ -120,10 +120,4 @@
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<data name="$this.Description" xml:space="preserve">
<value>Changes images resolution (X/Y).
Usefull to make files printable under a different printer resolution without have to reslice.
Note 1: Before run this tool, ensure object rotatation and volume fits new resolution.
Note 2: Object will auto-center on new resolution.</value>
</data>
</root>
@@ -281,7 +281,6 @@
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.ButtonOkText = "Import";
this.Controls.Add(this.cbDiscardRemainingLayers);
this.Controls.Add(this.cbReplaceSubsequentLayers);
this.Controls.Add(this.lbResult);
@@ -292,8 +291,6 @@
this.Controls.Add(this.nmInsertAfterLayer);
this.Controls.Add(this.label1);
this.Controls.Add(this.splitContainer);
this.Description = "Import layer(s) from local file(s) into the model at a selected height.\r\nNOTE: Im" +
"ages must respect file resolution and in greyscale color.";
this.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.LayerRangeVisible = false;
this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
@@ -7,6 +7,7 @@
*/
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Drawing;
using System.IO;
@@ -19,12 +20,13 @@ namespace UVtools.GUI.Controls.Tools
{
public partial class CtrlToolLayerImport : CtrlToolWindowContent
{
public OperationLayerImport Operation { get; } = new OperationLayerImport();
public OperationLayerImport Operation { get; }
public CtrlToolLayerImport(uint currentLayer = 0)
{
InitializeComponent();
Text = "Import Layer(s)";
Operation = new OperationLayerImport(Program.FrmMain.ActualLayerImage.Size);
SetOperation(Operation);
nmInsertAfterLayer.Maximum = Program.SlicerFile.LayerCount-1;
@@ -32,9 +34,7 @@ namespace UVtools.GUI.Controls.Tools
nmInsertAfterLayer_ValueChanged(nmInsertAfterLayer, EventArgs.Empty);
}
public override string ConfirmationText => Operation.ConfirmationText;
public void UpdateOperation()
public override void UpdateOperation()
{
Operation.InsertAfterLayerIndex = (uint)nmInsertAfterLayer.Value;
Operation.ReplaceStartLayer = cbReplaceStartLayer.Checked;
@@ -46,29 +46,14 @@ namespace UVtools.GUI.Controls.Tools
public override bool ValidateForm()
{
UpdateOperation();
var result = Operation.Validate(Program.FrmMain.ActualLayerImage.Size);
if (result.Count == 0) return true;
var message = Operation.Validate();
if (message is null) return true;
var message = new StringBuilder();
message.AppendLine($"The following {result.Count} files mismatched the slice resolution of {Program.FrmMain.ActualLayerImage.Size.Width}x{Program.FrmMain.ActualLayerImage.Size.Height}:");
message.AppendLine();
uint count = 0;
foreach (var file in result)
{
count++;
if (count == 20)
{
message.AppendLine("... To many to show ...");
break;
}
message.AppendLine(Path.GetFileNameWithoutExtension(file));
}
message.AppendLine();
message.AppendLine("Do you want to remove all invalid files from list?");
message.Content += "\nDo you want to remove all invalid files from list?";
if (MessageBoxError(message.ToString(), MessageBoxButtons.YesNo) == DialogResult.Yes)
{
ConcurrentBag<string> result = (ConcurrentBag<string>)message.Tag;
foreach (var file in result)
{
Operation.Files.Remove(file);