mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-11-15 05:35:34 -05:00
Tools > Set Offset Increment (F5) and Set Rotation Increment (F6) open the WinForms SetValueForm's dialog: an "Increment :" box shown with four decimals and a Set button that Enter also presses; Esc or closing the window changes nothing. - The offset dialog has the "Calculated distance (selection size + part spacing)" check box, which turns the value box off; with it on, arrow keys step the selection by its size plus the part spacing. - The rotation increment goes up to 360 degrees; Shift+wheel turns by it and Ctrl+Shift+wheel by a tenth of it. - A typed value out of range is taken to the nearest limit and an emptied box keeps the last value it held, as in WinForms. Each nest keeps its own increments for the session, starting at 10, as each WinForms nest window does; they are not saved. With no nest open both commands are off (WinForms hides them).
117 lines
4.4 KiB
C#
117 lines
4.4 KiB
C#
using System.Threading.Tasks;
|
|
using Avalonia;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Input;
|
|
using Avalonia.Interactivity;
|
|
using Avalonia.Layout;
|
|
|
|
namespace OpenNest.Avalonia
|
|
{
|
|
/// <summary>
|
|
/// One number to set, as the WinForms SetValueForm: an "Increment :" box from 0 to a maximum
|
|
/// shown with four decimals, an optional check box that disables the box, and a Set button
|
|
/// that is also Enter. Esc or closing the window changes nothing.
|
|
/// </summary>
|
|
internal sealed class SetValueDialog : Window
|
|
{
|
|
public const double DefaultMaximum = 999999;
|
|
|
|
/// <summary>What the user set: the value and the option check box.</summary>
|
|
public sealed record Result(double Value, bool OptionChecked);
|
|
|
|
private readonly NumericUpDown value;
|
|
private readonly CheckBox option;
|
|
// The last value the box held, which an emptied box keeps, as the WinForms box does.
|
|
private double lastValid;
|
|
private readonly double maximum;
|
|
|
|
private SetValueDialog(
|
|
string title, double initialValue, double maximum, string optionText,
|
|
bool optionChecked)
|
|
{
|
|
Title = title;
|
|
// Wide enough for the option's text on one line, as the WinForms form widens.
|
|
MinWidth = 300;
|
|
SizeToContent = SizeToContent.WidthAndHeight;
|
|
CanResize = false;
|
|
ShowInTaskbar = false;
|
|
WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
|
this.maximum = maximum;
|
|
lastValid = System.Math.Clamp(initialValue, 0, maximum);
|
|
|
|
value = new NumericUpDown
|
|
{
|
|
Name = "Value",
|
|
Minimum = 0,
|
|
Maximum = (decimal)maximum,
|
|
Increment = 1,
|
|
// A typed value out of range goes to the nearest limit, as in WinForms, rather
|
|
// than being refused.
|
|
ClipValueToMinMax = true,
|
|
FormatString = "0.0000",
|
|
Value = (decimal)lastValid,
|
|
HorizontalAlignment = HorizontalAlignment.Stretch,
|
|
};
|
|
value.ValueChanged += (_, e) =>
|
|
{
|
|
if (e.NewValue is { } v)
|
|
lastValid = (double)v;
|
|
};
|
|
var set = new Button { Name = "Set", Content = "Set", IsDefault = true };
|
|
set.Click += (_, _) => Close(new Result(Current, option.IsChecked == true));
|
|
|
|
var row = new Grid
|
|
{
|
|
ColumnDefinitions = new ColumnDefinitions("Auto,*,Auto"),
|
|
ColumnSpacing = 8,
|
|
};
|
|
var label = new TextBlock
|
|
{
|
|
Text = "Increment :",
|
|
VerticalAlignment = VerticalAlignment.Center,
|
|
};
|
|
row.Children.Add(label);
|
|
Grid.SetColumn(value, 1);
|
|
row.Children.Add(value);
|
|
Grid.SetColumn(set, 2);
|
|
row.Children.Add(set);
|
|
|
|
option = new CheckBox
|
|
{
|
|
Name = "Option",
|
|
Content = optionText,
|
|
IsChecked = optionChecked,
|
|
IsVisible = !string.IsNullOrEmpty(optionText),
|
|
};
|
|
value.IsEnabled = !optionChecked;
|
|
option.IsCheckedChanged += (_, _) => value.IsEnabled = option.IsChecked != true;
|
|
|
|
var panel = new StackPanel { Margin = new Thickness(12), Spacing = 10 };
|
|
panel.Children.Add(row);
|
|
panel.Children.Add(option);
|
|
Content = panel;
|
|
|
|
AddHandler(KeyDownEvent, (_, e) =>
|
|
{
|
|
if (e.Key != Key.Escape)
|
|
return;
|
|
e.Handled = true;
|
|
Close(null);
|
|
}, RoutingStrategies.Tunnel);
|
|
Opened += (_, _) => value.Focus();
|
|
}
|
|
|
|
// A value out of range is taken to the nearest limit, as the WinForms box does.
|
|
private double Current => System.Math.Clamp(lastValid, 0, maximum);
|
|
|
|
/// <summary>
|
|
/// The value and option the user set, or null when they closed the dialog without Set.
|
|
/// </summary>
|
|
public static Task<Result> ShowAsync(
|
|
Window owner, string title, double value, double maximum = DefaultMaximum,
|
|
string optionText = null, bool optionChecked = false) =>
|
|
new SetValueDialog(title, value, maximum, optionText, optionChecked)
|
|
.ShowDialog<Result>(owner);
|
|
}
|
|
}
|