Files
Tiago Conceição 89f5df35a8 v0.8.5.0
* (Add) Tool - Calculator: Convert millimeters to pixels
* (Add) Tool - Calculator: Find the optimal "Ligth-Off Delay"
* (Add) Internal abstraction of display size to all file formats
* (Add) Default demo file that loads on startup when no file is specified (this can be disable/enabled on settings)
2020-10-14 18:41:30 +01:00

481 lines
16 KiB
C#

/*
* GNU AFFERO GENERAL PUBLIC LICENSE
* Version 3, 19 November 2007
* Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
* Everyone is permitted to copy and distribute verbatim copies
* of this license document, but changing it is not allowed.
*/
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Windows.Forms;
using UVtools.Core.Extensions;
using UVtools.GUI.Controls;
namespace UVtools.GUI.Forms
{
public partial class FrmToolWindow : Form
{
#region Properties
public CtrlToolWindowContent Content { get; set; }
[Editor("System.ComponentModel.Design.MultilineStringEditor", typeof(UITypeEditor))]
[SettingsBindable(true)]
public string Description
{
get => lbDescription.Text;
set => lbDescription.Text = value;
}
[SettingsBindable(true)]
public bool ExtraButtonVisible
{
get => btnActionExtra.Visible;
set => btnActionExtra.Visible = value;
}
[Editor("System.ComponentModel.Design.MultilineStringEditor", typeof(UITypeEditor))]
[SettingsBindable(true)]
public string ExtraButtonText
{
get => btnActionExtra.Text;
set => btnActionExtra.Text = value;
}
[SettingsBindable(true)]
public bool ExtraCheckboxVisible
{
get => cbActionExtra.Visible;
set => cbActionExtra.Visible = value;
}
[Editor("System.ComponentModel.Design.MultilineStringEditor", typeof(UITypeEditor))]
[SettingsBindable(true)]
public string ExtraCheckboxText
{
get => cbActionExtra.Text;
set => cbActionExtra.Text = value;
}
[Editor("System.ComponentModel.Design.MultilineStringEditor", typeof(UITypeEditor))]
[SettingsBindable(true)]
public string ButtonOkText
{
get => btnOk.Text;
set => btnOk.Text = value;
}
[Editor("System.ComponentModel.Design.MultilineStringEditor", typeof(UITypeEditor))]
[SettingsBindable(true)]
public string ButtonCancelText
{
get => btnOk.Text;
set => btnOk.Text = value;
}
[SettingsBindable(true)]
public bool LayerRangeVisible
{
get => pnLayerRange.Visible;
set => pnLayerRange.Visible = value;
}
[SettingsBindable(true)]
public bool LayerRangeEndVisible
{
get => nmLayerRangeEnd.Visible;
set =>
nmLayerRangeEnd.Visible =
lbLayerRangeTo.Visible =
lbLayerRangeToMM.Visible =
btnLayerRangeSelect.Visible = value;
}
[ReadOnly(true)]
[Browsable(false)]
public uint LayerRangeStart
{
get => (uint)nmLayerRangeStart.Value;
set => nmLayerRangeStart.Value = value;
}
[ReadOnly(true)]
[Browsable(false)]
public uint LayerRangeEnd
{
get => (uint)Math.Min(nmLayerRangeEnd.Value, Program.SlicerFile.LayerCount - 1);
set => nmLayerRangeEnd.Value = value;
}
[ReadOnly(true)]
[Browsable(false)]
public virtual string ConfirmationText => $"{Text}?";
#endregion
#region Constructors
public FrmToolWindow()
{
InitializeComponent();
}
public FrmToolWindow(string title, string description, string buttonOkText, bool layerRangeVisible = true, int layerIndex = -1, bool layerRangeEndVisible = true, bool hideContent = false) : this()
{
if (!ReferenceEquals(title, null)) Text = title;
lbDescription.MaximumSize = new Size(Width - 10, 0);
Description = description;
if (string.IsNullOrEmpty(description))
{
pnDescription.Visible = false;
}
ButtonOkText = buttonOkText;
LayerRangeVisible = layerRangeVisible;
LayerRangeEndVisible = layerRangeEndVisible;
LayerRangeEnd = Program.SlicerFile.LayerCount - 1;
if (layerIndex >= 0)
{
LayerRangeStart =
LayerRangeEnd = (uint) layerIndex;
}
if (hideContent)
{
pnContent.Visible = false;
}
var ROI = Program.FrmMain.ROI;
if (ROI != Rectangle.Empty)
{
pnROI.Visible = true;
lbRoi.Text = ROI.ToString();
/*lbDescription.Text +=
"\n\nNOTE: The operation will only be applied to the selected Region of Interest indicated below.\n" +
"The Region of Interest can be set directly from the layer preview window prior to running this tool.";*/
}
EventValueChanged(nmLayerRangeStart, EventArgs.Empty);
EventValueChanged(nmLayerRangeEnd, EventArgs.Empty);
}
public FrmToolWindow(string description, string buttonOkText, bool layerRangeVisible = true, int layerIndex = -1, bool layerRangeEndVisible = true, bool hideContent = false) : this(null, description, buttonOkText, layerRangeVisible, layerIndex, layerRangeEndVisible, hideContent)
{ }
public FrmToolWindow(string description, string buttonOkText, int layerIndex, bool hideContent = false) : this(null, description, buttonOkText, true, layerIndex, hideContent)
{ }
public FrmToolWindow(CtrlToolWindowContent content, int layerIndex = -1) : this(content.Text, content.Description, content.ButtonOkText, content.LayerRangeVisible, layerIndex, content.LayerRangeEndVisible)
{
pnContent.Controls.Add(content);
Width = Math.Max(MinimumSize.Width, content.Width);
lbDescription.MaximumSize = new Size(Width - 10, 0);
//content.Dock = DockStyle.Fill;
ExtraButtonVisible = content.ExtraButtonVisible;
ExtraButtonText = content.ExtraButtonText;
ExtraCheckboxVisible = content.ExtraCheckboxVisible;
ExtraCheckboxText = content.ExtraCheckboxText;
btnOk.Enabled = content.ButtonOkEnabled;
//content.AutoSize = true;
if (string.IsNullOrEmpty(content.ButtonOkText))
{
btnOk.Visible = false;
}
if (!content.CanROI)
{
pnROI.Visible = false;
}
Content = content;
content.PropertyChanged += ContentOnPropertyChanged;
}
#endregion
#region Overrides
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
protected override void OnKeyUp(KeyEventArgs e)
{
base.OnKeyUp(e);
if (e.KeyCode == Keys.Enter)
{
e.Handled = true;
// Need exclude controls that require ENTER
if (!ReferenceEquals(ActiveControl, null))
{
switch (ActiveControl)
{
case NumericUpDown _:
case TextBox textBox when textBox.Multiline:
return;
}
}
btnOk.PerformClick();
return;
}
if ((ModifierKeys & Keys.Shift) == Keys.Shift && (ModifierKeys & Keys.Control) == Keys.Control)
{
if (e.KeyCode == Keys.A)
{
btnLayerRangeAllLayers.PerformClick();
e.Handled = true;
return;
}
if (e.KeyCode == Keys.C)
{
btnLayerRangeCurrentLayer.PerformClick();
e.Handled = true;
return;
}
if (e.KeyCode == Keys.B)
{
btnLayerRangeBottomLayers.PerformClick();
e.Handled = true;
return;
}
if (e.KeyCode == Keys.N)
{
btnLayerRangeNormalLayers.PerformClick();
e.Handled = true;
return;
}
if (e.KeyCode == Keys.F)
{
btnLayerRangeFirstLayer.PerformClick();
e.Handled = true;
return;
}
if (e.KeyCode == Keys.L)
{
btnLayerRangeLastLayer.PerformClick();
e.Handled = true;
return;
}
}
}
#endregion
#region Events
private void ContentOnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(Content.ButtonOkEnabled))
{
btnOk.Enabled = Content.ButtonOkEnabled;
return;
}
if (e.PropertyName == nameof(Content.LayerRangeVisible))
{
LayerRangeVisible = Content.LayerRangeVisible;
return;
}
}
private void EventClick(object sender, EventArgs e)
{
if (ReferenceEquals(sender, btnLayerRangeAllLayers))
{
nmLayerRangeStart.Value = 0;
nmLayerRangeEnd.Value = Program.SlicerFile.LayerCount-1;
return;
}
if (ReferenceEquals(sender, btnLayerRangeCurrentLayer))
{
nmLayerRangeStart.Value = Program.FrmMain.ActualLayer;
nmLayerRangeEnd.Value = Program.FrmMain.ActualLayer;
return;
}
if (ReferenceEquals(sender, btnLayerRangeBottomLayers))
{
nmLayerRangeStart.Value = 0;
nmLayerRangeEnd.Value = Program.SlicerFile.BottomLayerCount-1;
return;
}
if (ReferenceEquals(sender, btnLayerRangeNormalLayers))
{
nmLayerRangeStart.Value = Program.SlicerFile.BottomLayerCount - 1;
nmLayerRangeEnd.Value = Program.SlicerFile.LayerCount - 1;
return;
}
if (ReferenceEquals(sender, btnLayerRangeFirstLayer))
{
nmLayerRangeStart.Value =
nmLayerRangeEnd.Value = 0;
return;
}
if (ReferenceEquals(sender, btnLayerRangeLastLayer))
{
nmLayerRangeStart.Value =
nmLayerRangeEnd.Value = Program.SlicerFile.LayerCount - 1;
return;
}
if (ReferenceEquals(sender, btnClearRoi))
{
if (MessageQuestionBox("Are you sure you want to clear the current ROI?\n" +
"This action can not be reverted, to select another ROI you must quit this window and select it on layer preview.",
"Clear the current ROI?") != DialogResult.Yes) return;
Program.FrmMain.pbLayer.SelectNone();
cbClearRoiAfterOperation.Checked = false;
pnROI.Visible = false;
ExtraActionCall(btnClearRoi);
return;
}
if (ReferenceEquals(sender, btnActionExtra) || ReferenceEquals(sender, cbActionExtra))
{
ExtraActionCall(sender);
return;
}
if (ReferenceEquals(sender, btnOk))
{
if (!btnOk.Enabled) return;
if (LayerRangeStart > LayerRangeEnd)
{
MessageErrorBox("Layer range start can't be higher than layer end.\nPlease fix and try again.");
nmLayerRangeStart.Select();
return;
}
if (!ValidateForm()) return;
if (!ReferenceEquals(Content, null) && !Content.ValidateForm()) return;
string confirmationText = ConfirmationText;
if (!ReferenceEquals(Content, null))
{
confirmationText = Content.ConfirmationText;
}
if (!string.IsNullOrEmpty(confirmationText))
{
if (MessageQuestionBox(
$"Are you sure you want to {confirmationText}") !=
DialogResult.Yes) return;
}
if (cbClearRoiAfterOperation.Checked)
{
Program.FrmMain.pbLayer.SelectNone();
}
DialogResult = DialogResult.OK;
Close();
return;
}
if (ReferenceEquals(sender, btnCancel))
{
DialogResult = DialogResult.Cancel;
return;
}
}
private void EventValueChanged(object sender, EventArgs e)
{
if (ReferenceEquals(sender, nmLayerRangeStart) || ReferenceEquals(sender, nmLayerRangeEnd))
{
uint layerIndex = (uint) ((NumericUpDown) sender).Value;
if (layerIndex >= Program.SlicerFile.LayerCount) return;
var layer = Program.SlicerFile[layerIndex];
var text = $"({layer.PositionZ}mm)";
uint layerCount = LayerRangeEndVisible ? (uint) Math.Max(0, nmLayerRangeEnd.Value - nmLayerRangeStart.Value + 1) : 1;
lbLayerRangeCount.Text = $"({layerCount} layers / {Program.SlicerFile.LayerHeight * layerCount}mm)";
if (layerCount == 0)
{
lbLayerRangeCount.ForeColor = Color.Red;
btnOk.Enabled = false;
}
else
{
lbLayerRangeCount.ForeColor = Color.Black;
btnOk.Enabled = true;
}
if (ReferenceEquals(sender, nmLayerRangeStart))
{
lbLayerRangeFromMM.Text = text;
}
else if (ReferenceEquals(sender, nmLayerRangeEnd))
{
lbLayerRangeToMM.Text = text;
}
return;
}
}
#endregion
#region Methods
public virtual bool ValidateForm() => true;
/// <summary>
/// Called when button reset to defaults is clicked
/// </summary>
public virtual void ExtraActionCall(object sender)
{
Content?.ExtraActionCall(sender);
}
public DialogResult MessageErrorBox(string message) => GUIExtensions.MessageBoxError($"{Text} Error", message);
public DialogResult MessageQuestionBox(string message, string title = null) => GUIExtensions.MessageBoxQuestion($"{title ?? Text}", message);
public T GetContentCtrl<T>()
{
if (Content is T content)
{
return content;
}
try
{
return (T)Convert.ChangeType(Content, typeof(T));
}
catch (InvalidCastException)
{
return default(T);
}
}
#endregion
}
}