csharp/3RD-Dimension/3RDD-GCode-Sender-Issues/GCodeSender/MainWindow.xaml.cs

MainWindow.xaml.cs
using Microsoft.Win32;
using GCodeSender.Communication;
using GCodeSender.GCode;
using GCodeSender.Util;
using GCodeSender.Hotkey;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Text.RegularExpressions;
using System.Windows.Input;
using AutoUpdaterDotNET;
using Newtonsoft.Json;

namespace GCodeSender
{
	public partial clast MainWindow : Window, INotifyPropertyChanged
	{
		Machine machine = new Machine();

		OpenFileDialog openFileDialogGCode = new OpenFileDialog() { Filter = Constants.FileFilterGCode };
		SaveFileDialog saveFileDialogGCode = new SaveFileDialog() { Filter = Constants.FileFilterGCode };

		GCodeFile ToolPath { get; set; } = GCodeFile.Empty;

		GrblSettingsWindow settingsWindow = new GrblSettingsWindow();
        WorkOffsetsWindow workOffsetsWindows = new WorkOffsetsWindow();

		public event PropertyChangedEventHandler PropertyChanged;

        public static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClastLogger();

        private void RaisePropertyChanged(string propertyName)
		{
			PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
		}

        public MainWindow()
		{
			AppDomain.CurrentDomain.UnhandledException += UnhandledException;
			InitializeComponent();

            Logger.Info("++++++ 3RDD GCode Sender v{0} START ++++++", System.Reflection.astembly.GetEntryastembly().GetName().Version);

            // Check for any updates
            Logger.Info("Checking for Updates");
            AutoUpdater.ParseUpdateInfoEvent += AutoUpdaterOnParseUpdateInfoEvent;
           // AutoUpdater.Start("https://api.github.com/repos/3RD-Dimension/3RDD-GCode-Sender-Issues/releases/latest");

            openFileDialogGCode.FileOk += OpenFileDialogGCode_FileOk;
			saveFileDialogGCode.FileOk += SaveFileDialogGCode_FileOk;

			machine.ConnectionStateChanged += Machine_ConnectionStateChanged;

			machine.NonFatalException += Machine_NonFatalException;
			machine.Info += Machine_Info;
			machine.LineReceived += Machine_LineReceived;
			machine.LineReceived += settingsWindow.LineReceived;
            machine.LineReceived += workOffsetsWindows.parseG5xOffsets;
            machine.StatusReceived += Machine_StatusReceived;
			machine.LineSent += Machine_LineSent;

			machine.PositionUpdateReceived += Machine_PositionUpdateReceived;
			machine.StatusChanged += Machine_StatusChanged;
			machine.DistanceModeChanged += Machine_DistanceModeChanged;
			machine.UnitChanged += Machine_UnitChanged;
			machine.PlaneChanged += Machine_PlaneChanged;
			machine.BufferStateChanged += Machine_BufferStateChanged;
			machine.OperatingModeChanged += Machine_OperatingMode_Changed;
			machine.FileChanged += Machine_FileChanged;
			machine.FilePositionChanged += Machine_FilePositionChanged;
			machine.OverrideChanged += Machine_OverrideChanged;
			machine.PinStateChanged += Machine_PinStateChanged;

            // Global Function Number Validation for MainWindow
            TextBoxJogFeedX.PreviewTextInput += GlobalFunctions.NumberValidationTextBox;
            TextBoxJogDistanceX.PreviewTextInput += GlobalFunctions.NumberValidationTextBox;
            TextBoxJogFeedY.PreviewTextInput += GlobalFunctions.NumberValidationTextBox;
            TextBoxJogDistanceY.PreviewTextInput += GlobalFunctions.NumberValidationTextBox;
            TextBoxJogFeedZ.PreviewTextInput += GlobalFunctions.NumberValidationTextBox;
            TextBoxJogDistanceZ.PreviewTextInput += GlobalFunctions.NumberValidationTextBox;

            viewport.PanGesture = new MouseGesture(MouseAction.LeftClick);
            viewport.PanGesture2 = null;
 
            Machine_OperatingMode_Changed();
			Machine_PositionUpdateReceived();

			Properties.Settings.Default.SettingChanging += Default_SettingChanging;
			FileRuntimeTimer.Tick += FileRuntimeTimer_Tick;

			machine.ProbeFinished += Machine_ProbeFinished_UserOutput;

			LoadMacros();
            
			settingsWindow.SendLine += machine.SendLine;
            workOffsetsWindows.SendLine += machine.SendLine;
                       
			ButtonRestoreViewport_Click(null, null);

            HotKeys.LoadHotKeys(); // Load Hotkeys
       }

        private void AutoUpdaterOnParseUpdateInfoEvent(ParseUpdateInfoEventArgs args)
        {
            dynamic json = JsonConvert.DeserializeObject(args.RemoteData);

            string VersionGitHub = json.tag_name; // Version Number - Change this to tag_name on deployment

            string astetDownloadURL = "";
            VersionGitHub = (VersionGitHub.Remove(0, 1)); // Remove "v" from beginning
            Version v = new Version(VersionGitHub); // Conver to Version

            foreach (var astets in json.astets)
            {
                astetDownloadURL = astets.browser_download_url;
            }

            args.UpdateInfo = new UpdateInfoEventArgs
            {
                CurrentVersion = v,
                ChangelogURL = json.body,
                //Mandatory = json.mandatory,
                DownloadURL = astetDownloadURL
            };
        }

        private void Machine_LineReceived1(string obj)
        {
            throw new NotImplementedException();
        }

        public Vector3 LastProbePosMachine { get; set; }
		public Vector3 LastProbePosWork { get; set; }

		private void Machine_ProbeFinished_UserOutput(Vector3 position, bool success)
		{
			LastProbePosMachine = machine.LastProbePosMachine;
			LastProbePosWork = machine.LastProbePosWork;

			RaisePropertyChanged("LastProbePosMachine");
			RaisePropertyChanged("LastProbePosWork");
		}

		private void UnhandledException(object sender, UnhandledExceptionEventArgs ea)
		{
			Exception e = (Exception)ea.ExceptionObject;

			string info = "Unhandled Exception:\r\nMessage:\r\n";
			info += e.Message;
			info += "\r\nStackTrace:\r\n";
			info += e.StackTrace;
			info += "\r\nToString():\r\n";
			info += e.ToString();

			MessageBox.Show("There has been an Unhandled Exception, the error has been logged to a file in the directory");
            Logger.Error(info);

            Environment.Exit(1);
		}

		private void Default_SettingChanging(object sender, System.Configuration.SettingChangingEventArgs e)
		{
			if (e.SettingName.Equals("JogFeed") ||
				e.SettingName.Equals("JogDistance") ||
				e.SettingName.Equals("ProbeFeed") ||
				e.SettingName.Equals("ProbeSafeHeight") ||
				e.SettingName.Equals("ProbeMaxDepth") ||
				e.SettingName.Equals("SplitSegmentLength") ||
				e.SettingName.Equals("ViewportArcSplit") ||
				e.SettingName.Equals("ArcToLineSegmentLength") ||
				e.SettingName.Equals("ConsoleFadeTime"))
			{
				if (((double)e.NewValue)  0)
				{
					string file = files[0];
					
					if (machine.Mode != Machine.OperatingMode.SendFile)
					{
					    e.Effects = DragDropEffects.Copy;
						return;
					}
				}
			}

			e.Effects = DragDropEffects.None;
		}

		private void viewport_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
		{
			if (e.Key == System.Windows.Input.Key.Space)
			{
				machine.FeedHold();
				e.Handled = true;
			}
		}

		private void ButtonRapidOverride_Click(object sender, RoutedEventArgs e)
		{
			Button b = sender as Button;

			if (b == null)
				return;

			switch (b.Content as string)
			{
				case "100%":
					machine.SendControl(0x95);
					break;
				case "50%":
					machine.SendControl(0x96);
					break;
				case "25%":
					machine.SendControl(0x97);
					break;
			}
		}

		private void ButtonFeedOverride_Click(object sender, RoutedEventArgs e)
		{
			Button b = sender as Button;

			if (b == null)
				return;

			switch (b.Tag as string)
			{
				case "100%":
					machine.SendControl(0x90);
					break;
				case "+10%":
					machine.SendControl(0x91);
					break;
				case "-10%":
					machine.SendControl(0x92);
					break;
				case "+1%":
					machine.SendControl(0x93);
					break;
				case "-1%":
					machine.SendControl(0x94);
					break;
			}
		}

		private void ButtonSpindleOverride_Click(object sender, RoutedEventArgs e)
		{
			Button b = sender as Button;

			if (b == null)
				return;

			switch (b.Tag as string)
			{
				case "100%":
					machine.SendControl(0x99);
					break;
				case "+10%":
					machine.SendControl(0x9A);
					break;
				case "-10%":
					machine.SendControl(0x9B);
					break;
				case "+1%":
					machine.SendControl(0x9C);
					break;
				case "-1%":
					machine.SendControl(0x9D);
					break;
			}
		}

        // Spindle, Coolant, Mist Controlling
        /// 
        /// Enable and Disable Spindle
        /// 
        private void SpindleControl()
        {
            machine.SendControl(0x9E);
        }

        /// 
        /// Enable Disable Flood Coolant
        /// 
        private void FloodControl()
        {
           machine.SendControl(0xA0);
        }

        // Enable and Disable Mist Coolant
        private void MistControl()
        {
            machine.SendControl(0xA1);
        }
               
        private void ButtonResetViewport_Click(object sender, RoutedEventArgs e)
		{
			viewport.Camera.Position = new System.Windows.Media.Media3D.Point3D(50, -150, 250);
			viewport.Camera.LookDirection = new System.Windows.Media.Media3D.Vector3D(-50, 150, -250);
			viewport.Camera.UpDirection = new System.Windows.Media.Media3D.Vector3D(0, 0, 1);
		}

		private void ButtonRestoreViewport_Click(object sender, RoutedEventArgs e)
		{
			string[] scoords = Properties.Settings.Default.ViewPortPos.Split(';');

			try
			{
				IEnumerable coords = scoords.Select(s => double.Parse(s));

				viewport.Camera.Position = new Vector3(coords.Take(3).ToArray()).ToPoint3D();
				viewport.Camera.LookDirection = new Vector3(coords.Skip(3).ToArray()).ToVector3D();
				viewport.Camera.UpDirection = new System.Windows.Media.Media3D.Vector3D(0, 0, 1);
			}
			catch
			{
				ButtonResetViewport_Click(null, null);
			}
		}

		private void ButtonSaveViewport_Click(object sender, RoutedEventArgs e)
		{
			List coords = new List();

			coords.AddRange(new Vector3(viewport.Camera.Position).Array);
			coords.AddRange(new Vector3(viewport.Camera.LookDirection).Array);

			Properties.Settings.Default.ViewPortPos = string.Join(";", coords.Select(d => d.ToString()));
		}

		private void ButtonSaveTLOPos_Click(object sender, RoutedEventArgs e)
		{
			if (machine.Mode != Machine.OperatingMode.Manual)
				return;

			double Z = (Properties.Settings.Default.TLSUseActualPos) ? machine.MachinePosition.Z : LastProbePosMachine.Z;

			Properties.Settings.Default.ToolLengthSetterPos = Z;
		}

		private void ButtonApplyTLO_Click(object sender, RoutedEventArgs e)
		{
			if (machine.Mode != Machine.OperatingMode.Manual)
				return;

			double Z = (Properties.Settings.Default.TLSUseActualPos) ? machine.MachinePosition.Z : LastProbePosMachine.Z;

			double delta = Z - Properties.Settings.Default.ToolLengthSetterPos;

			machine.SendLine($"G43.1 Z{delta.ToString(Constants.DecimalOutputFormat)}");
		}

		private void ButtonClearTLO_Click(object sender, RoutedEventArgs e)
		{
			if (machine.Mode != Machine.OperatingMode.Manual)
				return;

			machine.SendLine("G49");
		}

        private void manualProbeBtn_Click(object sender, RoutedEventArgs e)
        {
            // Requires physical testing on the machine to make sure it is operating correctly
            machine.SendLine("G21");
            if (Properties.Settings.Default.AbortOnProbeFail)
            { // If Abort and Notify selected, display error if problem probing
                machine.SendLine($"G38.2 Z{Properties.Settings.Default.ProbeMaxDepth} F{Properties.Settings.Default.ProbeFeed}");
            }
            else
            { // If Abort and Notify not selected, dont display an error
                machine.SendLine($"G38.3 Z{Properties.Settings.Default.ProbeMaxDepth} F{Properties.Settings.Default.ProbeFeed}");
            }
            
            machine.SendLine($"G92 Z{Properties.Settings.Default.ProbeTouchPlateThickness}");
            machine.SendLine("G91");
            machine.SendLine($"G0 Z{Properties.Settings.Default.ProbeSafeHeight}");
            machine.SendLine("M30");
        }      

        private void viewport_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
        {             
            viewport.CalculateCursorPosition = true;
           if (Keyboard.IsKeyDown(Key.LeftShift))
            {
                if (machine.Connected && machine.Mode != Machine.OperatingMode.SendFile)
                {
                    // CurrentPosition Obsolete but works for now
                    string PositionX = GlobalFunctions.DecimalPlaceNoRounding(Convert.ToDouble(viewport.CurrentPosition.X), 3);
                    string PositionY = GlobalFunctions.DecimalPlaceNoRounding(Convert.ToDouble(viewport.CurrentPosition.Y), 3);
                    if (MessageBox.Show("Jog to Position " + "X:" + PositionX + ", Y:" + PositionY + "?", "Go to Position?", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
                    {
                        machine.SendLine($"G90 G0 X{PositionX} Y{PositionY}");
                    }
                }
            }          
        }
    }
}