2023-07-19 19:30:39 +00:00
|
|
|
using System;
|
2023-07-26 18:46:15 +00:00
|
|
|
using System.Collections.Immutable;
|
|
|
|
using System.Linq;
|
2023-07-19 22:09:25 +00:00
|
|
|
using System.Threading;
|
2023-07-26 18:46:15 +00:00
|
|
|
using System.Timers;
|
2023-07-19 19:30:39 +00:00
|
|
|
using AppKit;
|
2023-07-24 21:21:33 +00:00
|
|
|
using Cauldron.Macos.SourceWriter;
|
|
|
|
using Cauldron.Macos.SourceWriter.LanguageFormats;
|
2023-07-26 18:46:15 +00:00
|
|
|
using Foundation;
|
|
|
|
using Microsoft.CodeAnalysis;
|
2023-07-19 19:30:39 +00:00
|
|
|
|
2023-07-21 20:11:56 +00:00
|
|
|
namespace Cauldron.Macos;
|
2023-07-19 19:30:39 +00:00
|
|
|
|
|
|
|
public partial class MainWindow : NSWindowController
|
|
|
|
{
|
2023-07-28 20:33:40 +00:00
|
|
|
public CSharpScriptDocument ScriptDocument { get => (CSharpScriptDocument)this.Document; }
|
|
|
|
|
2023-07-19 22:09:25 +00:00
|
|
|
#region Window components
|
|
|
|
|
2023-07-19 19:30:39 +00:00
|
|
|
private NSSplitViewController MainContentController
|
|
|
|
{
|
|
|
|
get => (this.ContentViewController as NSSplitViewController)
|
|
|
|
.SplitViewItems[1].ViewController as NSSplitViewController;
|
|
|
|
}
|
|
|
|
|
|
|
|
private NSViewController SidebarController
|
|
|
|
{
|
|
|
|
get => (this.ContentViewController as NSSplitViewController)
|
|
|
|
.SplitViewItems[0].ViewController;
|
|
|
|
}
|
|
|
|
|
2023-07-21 20:11:56 +00:00
|
|
|
private NSOutlineView SidebarList
|
|
|
|
{
|
|
|
|
get => (this.SidebarController.View.Subviews[0] as NSScrollView)
|
|
|
|
.ContentView.DocumentView as NSOutlineView;
|
|
|
|
}
|
|
|
|
|
2023-07-28 20:33:40 +00:00
|
|
|
public SourceTextView ScriptEditorTextBox
|
2023-07-19 19:30:39 +00:00
|
|
|
{
|
|
|
|
get => (this.MainContentController
|
|
|
|
.SplitViewItems[0].ViewController.View as NSScrollView)
|
2023-07-24 21:21:33 +00:00
|
|
|
.ContentView.DocumentView as SourceTextView;
|
2023-07-19 19:30:39 +00:00
|
|
|
}
|
|
|
|
|
2023-07-22 00:20:46 +00:00
|
|
|
public WebKit.WKWebView ScriptOutputWebView
|
2023-07-19 19:30:39 +00:00
|
|
|
{
|
2023-07-22 00:20:46 +00:00
|
|
|
get => this.MainContentController
|
|
|
|
.SplitViewItems[1].ViewController.View as WebKit.WKWebView;
|
2023-07-19 19:30:39 +00:00
|
|
|
}
|
|
|
|
|
2023-07-19 22:09:25 +00:00
|
|
|
public string ScriptText { get => this.ScriptEditorTextBox.Value; }
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region Shared properties
|
|
|
|
|
|
|
|
public CancellationTokenSource ScriptCancellationTokenSource { get; set; }
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
2023-07-19 19:30:39 +00:00
|
|
|
|
2023-07-19 22:09:25 +00:00
|
|
|
public MainWindow (ObjCRuntime.NativeHandle handle) : base (handle) { }
|
2023-07-19 19:30:39 +00:00
|
|
|
|
2023-07-28 20:33:40 +00:00
|
|
|
public override void WindowDidLoad()
|
2023-07-19 19:30:39 +00:00
|
|
|
{
|
2023-07-28 20:33:40 +00:00
|
|
|
base.WindowDidLoad();
|
|
|
|
|
|
|
|
this.Document ??= new CSharpScriptDocument();
|
|
|
|
|
|
|
|
if (this.ScriptDocument.ScriptText == null)
|
|
|
|
this.ScriptDocument.ScriptText = new NSString(this.ScriptText);
|
2023-07-19 19:30:39 +00:00
|
|
|
|
|
|
|
this.RunScriptToolbarButton.Activated += RunScript;
|
|
|
|
|
2023-07-24 21:21:33 +00:00
|
|
|
SourceTextView scriptTextBox = this.ScriptEditorTextBox;
|
2023-07-26 18:46:15 +00:00
|
|
|
scriptTextBox.OnFinishedTyping += this.BuildScript;
|
2023-07-28 20:33:40 +00:00
|
|
|
scriptTextBox.OnTextChanged += this.UpdateDocument;
|
|
|
|
|
2023-07-19 19:30:39 +00:00
|
|
|
scriptTextBox.Font = NSFont.MonospacedSystemFont(new nfloat(14), NSFontWeight.Regular);
|
|
|
|
scriptTextBox.AutomaticQuoteSubstitutionEnabled = false;
|
|
|
|
scriptTextBox.AutomaticDashSubstitutionEnabled = false;
|
|
|
|
scriptTextBox.AutomaticDataDetectionEnabled = false;
|
|
|
|
scriptTextBox.AutomaticSpellingCorrectionEnabled = false;
|
|
|
|
scriptTextBox.AutomaticTextCompletionEnabled = false;
|
|
|
|
scriptTextBox.AutomaticTextReplacementEnabled = false;
|
|
|
|
scriptTextBox.AutomaticLinkDetectionEnabled = false;
|
2023-07-24 21:21:33 +00:00
|
|
|
|
|
|
|
scriptTextBox.Formatter = new LanguageFormatter(scriptTextBox, new CSharpDescriptor());
|
|
|
|
scriptTextBox.Formatter.Reformat();
|
2023-07-28 20:33:40 +00:00
|
|
|
|
|
|
|
this.SetDocumentEdited(this.ScriptDocument.IsDocumentEdited);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void UpdateDocument(object sender, EventArgs args)
|
|
|
|
{
|
|
|
|
this.ScriptDocument.ScriptText = new NSString(this.ScriptText);
|
|
|
|
this.SetDocumentEdited(this.ScriptDocument.IsDocumentEdited);
|
2023-07-19 19:30:39 +00:00
|
|
|
}
|
|
|
|
|
2023-07-26 18:46:15 +00:00
|
|
|
public void BuildScript(object sender, ElapsedEventArgs args)
|
|
|
|
{
|
|
|
|
ScriptRunner.BuildScript(this);
|
|
|
|
}
|
|
|
|
|
2023-07-19 19:30:39 +00:00
|
|
|
public void RunScript(object sender, EventArgs e)
|
|
|
|
{
|
2023-07-19 22:09:25 +00:00
|
|
|
ScriptRunner.RunScript(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void CancelScript(object sender, EventArgs e)
|
|
|
|
{
|
|
|
|
this.ScriptCancellationTokenSource?.Cancel();
|
|
|
|
}
|
2023-07-19 19:30:39 +00:00
|
|
|
|
2023-07-21 22:21:13 +00:00
|
|
|
partial void NewTabMenuItemClicked(AppKit.NSMenuItem sender)
|
|
|
|
{
|
|
|
|
this.CreateNewTab();
|
|
|
|
}
|
|
|
|
|
2023-07-26 18:46:15 +00:00
|
|
|
public void UpdateScriptDiagnostics(ImmutableArray<Diagnostic> diagnostics)
|
|
|
|
{
|
2023-07-26 20:59:15 +00:00
|
|
|
ImmutableList<Diagnostic> infoDiagnostics = diagnostics
|
|
|
|
.Where(d => d.Severity == DiagnosticSeverity.Info)
|
|
|
|
.ToImmutableList();
|
|
|
|
ImmutableList<Diagnostic> warningDiagnostics = diagnostics
|
|
|
|
.Where(d => d.Severity == DiagnosticSeverity.Warning)
|
|
|
|
.ToImmutableList();
|
|
|
|
ImmutableList<Diagnostic> errorDiagnostics = diagnostics
|
|
|
|
.Where(d => d.Severity == DiagnosticSeverity.Error)
|
|
|
|
.ToImmutableList();
|
|
|
|
|
|
|
|
this.DiagnosticsToolbarGroup.SetLabel(infoDiagnostics.Count.ToString(), 0);
|
|
|
|
this.DiagnosticsToolbarGroup.SetLabel(warningDiagnostics.Count.ToString(), 1);
|
|
|
|
this.DiagnosticsToolbarGroup.SetLabel(errorDiagnostics.Count.ToString(), 2);
|
2023-07-26 18:46:15 +00:00
|
|
|
|
|
|
|
foreach (Diagnostic diagnostic in diagnostics)
|
|
|
|
{
|
|
|
|
int start = diagnostic.Location.SourceSpan.Start;
|
|
|
|
int end = diagnostic.Location.SourceSpan.End;
|
|
|
|
|
|
|
|
if (start == end && end < this.ScriptText.Length)
|
|
|
|
end += 1;
|
|
|
|
else if (start == end)
|
|
|
|
start -= 1;
|
|
|
|
|
|
|
|
NSRange range = new(start,end);
|
|
|
|
|
|
|
|
this.ScriptEditorTextBox.LayoutManager
|
|
|
|
.AddTemporaryAttribute(NSStringAttributeKey.UnderlineStyle,
|
|
|
|
new NSNumber((int)(NSUnderlineStyle.Thick | NSUnderlineStyle.PatternDot)),
|
|
|
|
range);
|
|
|
|
this.ScriptEditorTextBox.LayoutManager
|
|
|
|
.AddTemporaryAttribute(NSStringAttributeKey.ToolTip,
|
|
|
|
new NSString($"{diagnostic.Id} {diagnostic.GetMessage()}"),
|
|
|
|
range);
|
|
|
|
|
|
|
|
if (diagnostic.Severity == DiagnosticSeverity.Error)
|
|
|
|
this.ScriptEditorTextBox.LayoutManager
|
|
|
|
.AddTemporaryAttribute(NSStringAttributeKey.UnderlineColor, NSColor.SystemRed,
|
|
|
|
range);
|
|
|
|
else if (diagnostic.Severity == DiagnosticSeverity.Warning)
|
|
|
|
this.ScriptEditorTextBox.LayoutManager
|
|
|
|
.AddTemporaryAttribute(NSStringAttributeKey.UnderlineColor, NSColor.SystemGreen,
|
|
|
|
range);
|
|
|
|
else if (diagnostic.Severity == DiagnosticSeverity.Info)
|
|
|
|
this.ScriptEditorTextBox.LayoutManager
|
|
|
|
.AddTemporaryAttribute(NSStringAttributeKey.UnderlineColor, NSColor.SystemBlue,
|
|
|
|
range);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-19 22:09:25 +00:00
|
|
|
public void SetScriptRunState(bool scriptIsRunning)
|
|
|
|
{
|
|
|
|
if (scriptIsRunning)
|
|
|
|
{
|
|
|
|
this.RunScriptToolbarButton.Enabled = false;
|
|
|
|
}
|
|
|
|
else
|
2023-07-19 19:30:39 +00:00
|
|
|
{
|
2023-07-19 22:09:25 +00:00
|
|
|
this.RunScriptToolbarButton.Enabled = true;
|
|
|
|
}
|
2023-07-19 19:30:39 +00:00
|
|
|
}
|
2023-07-21 22:21:13 +00:00
|
|
|
|
|
|
|
public void CreateNewTab()
|
|
|
|
{
|
|
|
|
MainWindow newWindow = this.Storyboard.InstantiateInitialController()
|
|
|
|
as MainWindow;
|
|
|
|
this.Window.AddTabbedWindow(newWindow.Window, NSWindowOrderingMode.Above);
|
|
|
|
this.Window.SelectNextTab(this);
|
|
|
|
}
|
2023-07-19 19:30:39 +00:00
|
|
|
}
|