添加 MX-PD-盘古 项目文件
将 MX-PD-盘古 - new 目录下的所有文件添加到主仓库
This commit is contained in:
@@ -0,0 +1,607 @@
|
||||
using MainShell.Resources.CustomControl;
|
||||
using Newtonsoft.Json;
|
||||
using Stylet;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace MainShell.Common
|
||||
{
|
||||
public static class HeaderDeviceStatusOverlayHost
|
||||
{
|
||||
private static readonly object OverlayRootTag = new object();
|
||||
private static readonly HeaderDeviceStatusOverlaySettings OverlaySettings = new HeaderDeviceStatusOverlaySettings();
|
||||
|
||||
public static void Attach(Window window, HeaderDeviceStatusController controller)
|
||||
{
|
||||
if (window == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(window));
|
||||
}
|
||||
|
||||
if (controller == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(controller));
|
||||
}
|
||||
|
||||
window.Dispatcher.BeginInvoke(
|
||||
DispatcherPriority.Loaded,
|
||||
new Action(() => AttachCore(window, controller)));
|
||||
}
|
||||
|
||||
private static void AttachCore(Window window, HeaderDeviceStatusController controller)
|
||||
{
|
||||
Grid existingOverlayRoot = window.Content as Grid;
|
||||
if (existingOverlayRoot != null && ReferenceEquals(existingOverlayRoot.Tag, OverlayRootTag))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UIElement currentContent = window.Content as UIElement;
|
||||
if (currentContent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Grid overlayRoot = new Grid();
|
||||
overlayRoot.Tag = OverlayRootTag;
|
||||
|
||||
window.Content = null;
|
||||
overlayRoot.Children.Add(currentContent);
|
||||
overlayRoot.Children.Add(CreateOverlayElement(controller));
|
||||
overlayRoot.Children.Add(CreateDebugPanelElement());
|
||||
window.Content = overlayRoot;
|
||||
}
|
||||
|
||||
private static FrameworkElement CreateOverlayElement(HeaderDeviceStatusController controller)
|
||||
{
|
||||
HeaderDeviceStatusView statusView = new HeaderDeviceStatusView();
|
||||
statusView.DataContext = controller;
|
||||
statusView.IsHitTestVisible = false;
|
||||
statusView.HorizontalAlignment = HorizontalAlignment.Left;
|
||||
statusView.VerticalAlignment = VerticalAlignment.Top;
|
||||
|
||||
Binding marginBinding = new Binding(nameof(HeaderDeviceStatusOverlaySettings.Margin));
|
||||
marginBinding.Source = OverlaySettings;
|
||||
BindingOperations.SetBinding(statusView, FrameworkElement.MarginProperty, marginBinding);
|
||||
|
||||
Panel.SetZIndex(statusView, short.MaxValue);
|
||||
return statusView;
|
||||
}
|
||||
|
||||
private static FrameworkElement CreateDebugPanelElement()
|
||||
{
|
||||
Border panelBorder = new Border();
|
||||
panelBorder.Background = new SolidColorBrush(Color.FromArgb(235, 18, 26, 35));
|
||||
panelBorder.BorderBrush = new SolidColorBrush(Color.FromRgb(72, 93, 118));
|
||||
panelBorder.BorderThickness = new Thickness(1.0);
|
||||
panelBorder.CornerRadius = new CornerRadius(6.0);
|
||||
panelBorder.Padding = new Thickness(10.0, 8.0, 10.0, 8.0);
|
||||
panelBorder.HorizontalAlignment = HorizontalAlignment.Left;
|
||||
panelBorder.VerticalAlignment = VerticalAlignment.Top;
|
||||
|
||||
Binding panelMarginBinding = new Binding(nameof(HeaderDeviceStatusOverlaySettings.DebugPanelMargin));
|
||||
panelMarginBinding.Source = OverlaySettings;
|
||||
BindingOperations.SetBinding(panelBorder, FrameworkElement.MarginProperty, panelMarginBinding);
|
||||
|
||||
Binding panelVisibilityBinding = new Binding(nameof(HeaderDeviceStatusOverlaySettings.IsDebugPanelVisible));
|
||||
panelVisibilityBinding.Source = OverlaySettings;
|
||||
panelVisibilityBinding.Converter = new BooleanToVisibilityConverter();
|
||||
BindingOperations.SetBinding(panelBorder, UIElement.VisibilityProperty, panelVisibilityBinding);
|
||||
|
||||
StackPanel rootPanel = new StackPanel();
|
||||
rootPanel.Orientation = Orientation.Vertical;
|
||||
|
||||
DockPanel headerPanel = new DockPanel();
|
||||
|
||||
TextBlock titleText = new TextBlock();
|
||||
titleText.Text = "Overlay Debug";
|
||||
titleText.Foreground = Brushes.White;
|
||||
titleText.FontSize = 13.0;
|
||||
titleText.FontWeight = FontWeights.SemiBold;
|
||||
titleText.Margin = new Thickness(0.0, 0.0, 8.0, 6.0);
|
||||
DockPanel.SetDock(titleText, Dock.Left);
|
||||
headerPanel.Children.Add(titleText);
|
||||
|
||||
Button closeButton = CreateDebugButton("<22><><EFBFBD><EFBFBD>", 44.0);
|
||||
closeButton.Margin = new Thickness(6.0, 0.0, 0.0, 6.0);
|
||||
closeButton.Click += delegate(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OverlaySettings.HideDebugPanel();
|
||||
};
|
||||
DockPanel.SetDock(closeButton, Dock.Right);
|
||||
headerPanel.Children.Add(closeButton);
|
||||
|
||||
rootPanel.Children.Add(headerPanel);
|
||||
|
||||
TextBlock summaryText = new TextBlock();
|
||||
summaryText.Foreground = new SolidColorBrush(Color.FromRgb(210, 221, 236));
|
||||
summaryText.FontSize = 12.0;
|
||||
summaryText.Margin = new Thickness(0.0, 0.0, 0.0, 8.0);
|
||||
Binding summaryBinding = new Binding(nameof(HeaderDeviceStatusOverlaySettings.PositionSummary));
|
||||
summaryBinding.Source = OverlaySettings;
|
||||
BindingOperations.SetBinding(summaryText, TextBlock.TextProperty, summaryBinding);
|
||||
rootPanel.Children.Add(summaryText);
|
||||
|
||||
rootPanel.Children.Add(CreateDebugInputRow("Left", nameof(HeaderDeviceStatusOverlaySettings.LeftMarginText)));
|
||||
rootPanel.Children.Add(CreateDebugInputRow("Top", nameof(HeaderDeviceStatusOverlaySettings.TopMarginText)));
|
||||
rootPanel.Children.Add(CreateDebugInputRow("Step", nameof(HeaderDeviceStatusOverlaySettings.StepText)));
|
||||
|
||||
UniformGrid actionGrid = new UniformGrid();
|
||||
actionGrid.Columns = 4;
|
||||
actionGrid.Rows = 1;
|
||||
actionGrid.Margin = new Thickness(0.0, 0.0, 0.0, 8.0);
|
||||
|
||||
Button leftButton = CreateDebugButton("<22><>", 40.0);
|
||||
leftButton.Click += delegate(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OverlaySettings.AdjustMargin(-OverlaySettings.Step, 0.0);
|
||||
};
|
||||
actionGrid.Children.Add(leftButton);
|
||||
|
||||
Button rightButton = CreateDebugButton("<22><>", 40.0);
|
||||
rightButton.Click += delegate(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OverlaySettings.AdjustMargin(OverlaySettings.Step, 0.0);
|
||||
};
|
||||
actionGrid.Children.Add(rightButton);
|
||||
|
||||
Button upButton = CreateDebugButton("<22><>", 40.0);
|
||||
upButton.Click += delegate(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OverlaySettings.AdjustMargin(0.0, -OverlaySettings.Step);
|
||||
};
|
||||
actionGrid.Children.Add(upButton);
|
||||
|
||||
Button downButton = CreateDebugButton("<22><>", 40.0);
|
||||
downButton.Click += delegate(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OverlaySettings.AdjustMargin(0.0, OverlaySettings.Step);
|
||||
};
|
||||
actionGrid.Children.Add(downButton);
|
||||
|
||||
rootPanel.Children.Add(actionGrid);
|
||||
|
||||
Button applyButton = CreateDebugButton("Ӧ<><D3A6>", 0.0);
|
||||
applyButton.Width = 178.0;
|
||||
applyButton.Margin = new Thickness(0.0, 0.0, 0.0, 0.0);
|
||||
applyButton.Click += delegate(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OverlaySettings.ApplyTextValues();
|
||||
};
|
||||
rootPanel.Children.Add(applyButton);
|
||||
|
||||
panelBorder.Child = rootPanel;
|
||||
Panel.SetZIndex(panelBorder, short.MaxValue);
|
||||
return panelBorder;
|
||||
}
|
||||
|
||||
private static FrameworkElement CreateDebugInputRow(string labelText, string bindingPath)
|
||||
{
|
||||
Grid rowGrid = new Grid();
|
||||
rowGrid.Margin = new Thickness(0.0, 0.0, 0.0, 6.0);
|
||||
rowGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(44.0) });
|
||||
rowGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(92.0) });
|
||||
rowGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(56.0) });
|
||||
|
||||
TextBlock label = new TextBlock();
|
||||
label.Text = labelText;
|
||||
label.Foreground = new SolidColorBrush(Color.FromRgb(210, 221, 236));
|
||||
label.FontSize = 12.0;
|
||||
label.VerticalAlignment = VerticalAlignment.Center;
|
||||
Grid.SetColumn(label, 0);
|
||||
rowGrid.Children.Add(label);
|
||||
|
||||
TextBox inputBox = CreateDebugTextBox(bindingPath);
|
||||
Grid.SetColumn(inputBox, 1);
|
||||
rowGrid.Children.Add(inputBox);
|
||||
|
||||
TextBlock hint = new TextBlock();
|
||||
hint.Text = "<22>س<EFBFBD>";
|
||||
hint.Foreground = new SolidColorBrush(Color.FromRgb(150, 167, 188));
|
||||
hint.FontSize = 11.0;
|
||||
hint.VerticalAlignment = VerticalAlignment.Center;
|
||||
hint.HorizontalAlignment = HorizontalAlignment.Right;
|
||||
Grid.SetColumn(hint, 2);
|
||||
rowGrid.Children.Add(hint);
|
||||
|
||||
return rowGrid;
|
||||
}
|
||||
|
||||
private static TextBox CreateDebugTextBox(string bindingPath)
|
||||
{
|
||||
TextBox inputBox = new TextBox();
|
||||
inputBox.Height = 26.0;
|
||||
inputBox.Margin = new Thickness(0.0);
|
||||
inputBox.Padding = new Thickness(6.0, 2.0, 6.0, 2.0);
|
||||
inputBox.Background = new SolidColorBrush(Color.FromRgb(33, 46, 60));
|
||||
inputBox.BorderBrush = new SolidColorBrush(Color.FromRgb(96, 122, 149));
|
||||
inputBox.Foreground = Brushes.White;
|
||||
inputBox.FontSize = 12.0;
|
||||
inputBox.VerticalContentAlignment = VerticalAlignment.Center;
|
||||
|
||||
Binding textBinding = new Binding(bindingPath);
|
||||
textBinding.Source = OverlaySettings;
|
||||
textBinding.Mode = BindingMode.TwoWay;
|
||||
textBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
|
||||
BindingOperations.SetBinding(inputBox, TextBox.TextProperty, textBinding);
|
||||
|
||||
inputBox.LostFocus += delegate(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OverlaySettings.ApplyTextValues();
|
||||
};
|
||||
inputBox.KeyDown += delegate(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key != Key.Enter)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OverlaySettings.ApplyTextValues();
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
return inputBox;
|
||||
}
|
||||
|
||||
private static Button CreateDebugButton(string content, double width)
|
||||
{
|
||||
Button button = new Button();
|
||||
button.Content = content;
|
||||
if (width > 0.0)
|
||||
{
|
||||
button.Width = width;
|
||||
}
|
||||
button.Height = 28.0;
|
||||
button.Margin = new Thickness(0.0, 0.0, 6.0, 0.0);
|
||||
button.Padding = new Thickness(4.0, 0.0, 4.0, 0.0);
|
||||
button.Background = new SolidColorBrush(Color.FromRgb(43, 62, 81));
|
||||
button.BorderBrush = new SolidColorBrush(Color.FromRgb(96, 122, 149));
|
||||
button.Foreground = Brushes.White;
|
||||
button.FontSize = 12.0;
|
||||
return button;
|
||||
}
|
||||
|
||||
private sealed class HeaderDeviceStatusOverlaySettings : PropertyChangedBase, IDisposable
|
||||
{
|
||||
private const double DefaultTopMargin = 8.0;
|
||||
private const double DefaultLeftMargin = 8.0;
|
||||
private const double DefaultDebugPanelTopOffset = 50.0;
|
||||
private const double DefaultAdjustStep = 1.0;
|
||||
private const string ConfigurationDirectoryName = "Configuration";
|
||||
private const string ConfigurationFileName = "HeaderDeviceStatusOverlay.json";
|
||||
|
||||
private readonly string _configurationDirectoryPath;
|
||||
private readonly string _configurationFilePath;
|
||||
private readonly FileSystemWatcher _fileWatcher;
|
||||
private double _topMargin = DefaultTopMargin;
|
||||
private double _leftMargin = DefaultLeftMargin;
|
||||
private bool _isDebugPanelVisible;
|
||||
private double _step = DefaultAdjustStep;
|
||||
private string _leftMarginText = DefaultLeftMargin.ToString("0.##", CultureInfo.InvariantCulture);
|
||||
private string _topMarginText = DefaultTopMargin.ToString("0.##", CultureInfo.InvariantCulture);
|
||||
private string _stepText = DefaultAdjustStep.ToString("0.##", CultureInfo.InvariantCulture);
|
||||
|
||||
public HeaderDeviceStatusOverlaySettings()
|
||||
{
|
||||
_configurationDirectoryPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ConfigurationDirectoryName);
|
||||
_configurationFilePath = Path.Combine(_configurationDirectoryPath, ConfigurationFileName);
|
||||
|
||||
EnsureConfigurationFile();
|
||||
LoadFromFile();
|
||||
|
||||
_fileWatcher = new FileSystemWatcher(_configurationDirectoryPath, ConfigurationFileName);
|
||||
_fileWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.Size | NotifyFilters.CreationTime;
|
||||
_fileWatcher.Changed += OnConfigurationFileChanged;
|
||||
_fileWatcher.Created += OnConfigurationFileChanged;
|
||||
_fileWatcher.Renamed += OnConfigurationFileRenamed;
|
||||
_fileWatcher.EnableRaisingEvents = true;
|
||||
}
|
||||
|
||||
public Thickness Margin
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Thickness(_leftMargin, _topMargin, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
public Thickness DebugPanelMargin
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Thickness(_leftMargin, _topMargin + DefaultDebugPanelTopOffset, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsDebugPanelVisible
|
||||
{
|
||||
get
|
||||
{
|
||||
return _isDebugPanelVisible;
|
||||
}
|
||||
}
|
||||
|
||||
public double Step
|
||||
{
|
||||
get
|
||||
{
|
||||
return _step;
|
||||
}
|
||||
}
|
||||
|
||||
public string LeftMarginText
|
||||
{
|
||||
get
|
||||
{
|
||||
return _leftMarginText;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetAndNotify(ref _leftMarginText, value);
|
||||
}
|
||||
}
|
||||
|
||||
public string TopMarginText
|
||||
{
|
||||
get
|
||||
{
|
||||
return _topMarginText;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetAndNotify(ref _topMarginText, value);
|
||||
}
|
||||
}
|
||||
|
||||
public string StepText
|
||||
{
|
||||
get
|
||||
{
|
||||
return _stepText;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetAndNotify(ref _stepText, value);
|
||||
}
|
||||
}
|
||||
|
||||
public string PositionSummary
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format("Left={0:0.##}, Top={1:0.##}, Step={2:0.##}", _leftMargin, _topMargin, _step);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_fileWatcher.Changed -= OnConfigurationFileChanged;
|
||||
_fileWatcher.Created -= OnConfigurationFileChanged;
|
||||
_fileWatcher.Renamed -= OnConfigurationFileRenamed;
|
||||
_fileWatcher.Dispose();
|
||||
}
|
||||
|
||||
public void AdjustMargin(double leftOffset, double topOffset)
|
||||
{
|
||||
double leftMargin = _leftMargin + leftOffset;
|
||||
double topMargin = _topMargin + topOffset;
|
||||
|
||||
UpdateSettings(leftMargin, topMargin, _isDebugPanelVisible, _step);
|
||||
PersistCurrentConfiguration();
|
||||
}
|
||||
|
||||
public void HideDebugPanel()
|
||||
{
|
||||
UpdateSettings(_leftMargin, _topMargin, false, _step);
|
||||
PersistCurrentConfiguration();
|
||||
}
|
||||
|
||||
public void ApplyTextValues()
|
||||
{
|
||||
double leftMargin;
|
||||
double topMargin;
|
||||
double step;
|
||||
|
||||
bool canParseLeft = TryParseInput(LeftMarginText, _leftMargin, out leftMargin);
|
||||
bool canParseTop = TryParseInput(TopMarginText, _topMargin, out topMargin);
|
||||
bool canParseStep = TryParseInput(StepText, _step, out step);
|
||||
|
||||
if (!canParseStep)
|
||||
{
|
||||
step = _step;
|
||||
}
|
||||
|
||||
step = NormalizeStep(step);
|
||||
|
||||
UpdateSettings(leftMargin, topMargin, _isDebugPanelVisible, step);
|
||||
PersistCurrentConfiguration();
|
||||
}
|
||||
|
||||
private void OnConfigurationFileChanged(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
ReloadOnUiThread();
|
||||
}
|
||||
|
||||
private void OnConfigurationFileRenamed(object sender, RenamedEventArgs e)
|
||||
{
|
||||
ReloadOnUiThread();
|
||||
}
|
||||
|
||||
private void ReloadOnUiThread()
|
||||
{
|
||||
Application currentApplication = Application.Current;
|
||||
if (currentApplication == null)
|
||||
{
|
||||
LoadFromFile();
|
||||
return;
|
||||
}
|
||||
|
||||
currentApplication.Dispatcher.BeginInvoke(
|
||||
DispatcherPriority.Background,
|
||||
new Action(LoadFromFile));
|
||||
}
|
||||
|
||||
private void EnsureConfigurationFile()
|
||||
{
|
||||
if (!Directory.Exists(_configurationDirectoryPath))
|
||||
{
|
||||
Directory.CreateDirectory(_configurationDirectoryPath);
|
||||
}
|
||||
|
||||
if (File.Exists(_configurationFilePath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HeaderDeviceStatusOverlayPositionConfiguration configuration = new HeaderDeviceStatusOverlayPositionConfiguration();
|
||||
configuration.TopMargin = DefaultTopMargin;
|
||||
configuration.LeftMargin = DefaultLeftMargin;
|
||||
configuration.ShowDebugPanel = false;
|
||||
configuration.AdjustStep = DefaultAdjustStep;
|
||||
SaveConfiguration(configuration);
|
||||
}
|
||||
|
||||
private void LoadFromFile()
|
||||
{
|
||||
HeaderDeviceStatusOverlayPositionConfiguration configuration = TryReadConfiguration();
|
||||
if (configuration == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
double topMargin = NormalizeMargin(configuration.TopMargin, DefaultTopMargin);
|
||||
double leftMargin = NormalizeMargin(configuration.LeftMargin, DefaultLeftMargin);
|
||||
double adjustStep = NormalizeStep(configuration.AdjustStep);
|
||||
UpdateSettings(leftMargin, topMargin, configuration.ShowDebugPanel, adjustStep);
|
||||
}
|
||||
|
||||
private HeaderDeviceStatusOverlayPositionConfiguration TryReadConfiguration()
|
||||
{
|
||||
for (int attempt = 0; attempt < 3; attempt++)
|
||||
{
|
||||
try
|
||||
{
|
||||
string content = File.ReadAllText(_configurationFilePath);
|
||||
if (string.IsNullOrWhiteSpace(content))
|
||||
{
|
||||
return new HeaderDeviceStatusOverlayPositionConfiguration();
|
||||
}
|
||||
|
||||
HeaderDeviceStatusOverlayPositionConfiguration configuration = JsonConvert.DeserializeObject<HeaderDeviceStatusOverlayPositionConfiguration>(content);
|
||||
return configuration ?? new HeaderDeviceStatusOverlayPositionConfiguration();
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void SaveConfiguration(HeaderDeviceStatusOverlayPositionConfiguration configuration)
|
||||
{
|
||||
string content = JsonConvert.SerializeObject(configuration, Formatting.Indented);
|
||||
File.WriteAllText(_configurationFilePath, content);
|
||||
}
|
||||
|
||||
private void PersistCurrentConfiguration()
|
||||
{
|
||||
HeaderDeviceStatusOverlayPositionConfiguration configuration = new HeaderDeviceStatusOverlayPositionConfiguration();
|
||||
configuration.TopMargin = _topMargin;
|
||||
configuration.LeftMargin = _leftMargin;
|
||||
configuration.ShowDebugPanel = _isDebugPanelVisible;
|
||||
configuration.AdjustStep = _step;
|
||||
SaveConfiguration(configuration);
|
||||
}
|
||||
|
||||
private static double NormalizeMargin(double value, double fallbackValue)
|
||||
{
|
||||
if (double.IsNaN(value) || double.IsInfinity(value))
|
||||
{
|
||||
return fallbackValue;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private static double NormalizeStep(double value)
|
||||
{
|
||||
if (double.IsNaN(value) || double.IsInfinity(value) || value <= 0.0)
|
||||
{
|
||||
return DefaultAdjustStep;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private void UpdateSettings(double leftMargin, double topMargin, bool isDebugPanelVisible, double step)
|
||||
{
|
||||
bool hasChanged = !leftMargin.Equals(_leftMargin)
|
||||
|| !topMargin.Equals(_topMargin)
|
||||
|| !isDebugPanelVisible.Equals(_isDebugPanelVisible)
|
||||
|| !step.Equals(_step);
|
||||
if (!hasChanged)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_leftMargin = leftMargin;
|
||||
_topMargin = topMargin;
|
||||
_isDebugPanelVisible = isDebugPanelVisible;
|
||||
_step = step;
|
||||
LeftMarginText = FormatValue(_leftMargin);
|
||||
TopMarginText = FormatValue(_topMargin);
|
||||
StepText = FormatValue(_step);
|
||||
NotifyOfPropertyChange(nameof(Margin));
|
||||
NotifyOfPropertyChange(nameof(DebugPanelMargin));
|
||||
NotifyOfPropertyChange(nameof(IsDebugPanelVisible));
|
||||
NotifyOfPropertyChange(nameof(Step));
|
||||
NotifyOfPropertyChange(nameof(PositionSummary));
|
||||
}
|
||||
|
||||
private static bool TryParseInput(string text, double fallbackValue, out double value)
|
||||
{
|
||||
string trimmedText = string.IsNullOrWhiteSpace(text) ? string.Empty : text.Trim();
|
||||
if (string.IsNullOrEmpty(trimmedText))
|
||||
{
|
||||
value = fallbackValue;
|
||||
return false;
|
||||
}
|
||||
|
||||
return double.TryParse(trimmedText, NumberStyles.Float, CultureInfo.InvariantCulture, out value)
|
||||
|| double.TryParse(trimmedText, NumberStyles.Float, CultureInfo.CurrentCulture, out value);
|
||||
}
|
||||
|
||||
private static string FormatValue(double value)
|
||||
{
|
||||
return value.ToString("0.##", CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class HeaderDeviceStatusOverlayPositionConfiguration
|
||||
{
|
||||
public double TopMargin { get; set; }
|
||||
|
||||
public double LeftMargin { get; set; }
|
||||
|
||||
public bool ShowDebugPanel { get; set; }
|
||||
|
||||
public double AdjustStep { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user