Convert to a document based application

This commit is contained in:
Neil Brommer 2023-07-28 13:33:40 -07:00
parent 891e004a31
commit 963b18aa5c
8 changed files with 151 additions and 49 deletions

View File

@ -27,13 +27,6 @@ public partial class AppDelegate : NSApplicationDelegate
as MainWindow);
}
partial void NewTabMenuItemClicked(AppKit.NSMenuItem sender)
{
(NSApplication.SharedApplication.KeyWindow.WindowController
as MainWindow)
.CreateNewTab();
}
[Action("validateMenuItem:")]
public bool ValidateMenuItem(AppKit.NSMenuItem sender)
{

View File

@ -11,9 +11,6 @@ namespace Cauldron.Macos
{
partial class AppDelegate
{
[Action ("NewTabMenuItemClicked:")]
partial void NewTabMenuItemClicked (AppKit.NSMenuItem sender);
[Action ("RunScriptMenuItemClicked:")]
partial void RunScriptMenuItemClicked (AppKit.NSMenuItem sender);

View File

@ -0,0 +1,67 @@
using System;
using AppKit;
using Foundation;
namespace Cauldron.Macos;
[Register("CSharpScriptDocument")]
public class CSharpScriptDocument : NSDocument
{
public NSString _scriptText = new("");
[Export("ScriptText")]
public NSString ScriptText
{
get => this._scriptText;
set
{
this._scriptText = value;
if (this.MainWindow != null)
this.MainWindow.ContentViewController.RepresentedObject = value;
this.MainWindow?.SetDocumentEdited(this.IsDocumentEdited);
}
}
public NSString SavedScriptText { get; set; }
public MainWindow MainWindow { get; set; }
public CSharpScriptDocument() : base() { }
public CSharpScriptDocument(ObjCRuntime.NativeHandle handle) : base(handle) { }
public override void MakeWindowControllers()
{
NSStoryboard storyboard = NSStoryboard.FromName("Main", null);
MainWindow windowController = (MainWindow)storyboard
.InstantiateControllerWithIdentifier("MainWindowController");
windowController.ContentViewController.RepresentedObject = this.ScriptText;
windowController.ScriptEditorTextBox.Value = this.ScriptText;
windowController.ScriptEditorTextBox.Formatter.Reformat();
windowController.WindowTitleForDocumentDisplayName(this.DisplayName);
windowController.SynchronizeWindowTitleWithDocumentName();
windowController.Window.Subtitle = this.FileUrl?.FilePathUrl.Path ?? "";
windowController.SetDocumentEdited(this.IsDocumentEdited);
this.AddWindowController(windowController);
}
public override bool IsDocumentEdited { get => this.ScriptText != this.SavedScriptText; }
public override NSData GetAsData(string typeName, out NSError outError)
{
outError = null;
return NSData.FromString(this.ScriptText);
}
public override bool ReadFromData(NSData data, string typeName, out NSError outError)
{
outError = null;
this.SavedScriptText = this.ScriptText = new NSString(data, NSStringEncoding.UTF8);
return true;
}
[Export("autosavesInPlace")]
public static bool AutosaveInPlace()
{
return false;
}
}

View File

@ -2,30 +2,71 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>Cauldron</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeIconFile</key>
<string></string>
<key>CFBundleTypeName</key>
<string>C# Script</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSHandlerRank</key>
<string>Default</string>
<key>LSItemContentTypes</key>
<array>
<string>com.neilbrommer.cauldron-CsScript</string>
</array>
<key>NSDocumentClass</key>
<string>CSharpScriptDocument</string>
</dict>
</array>
<key>CFBundleIdentifier</key>
<string>com.neilbrommer.cauldron</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Cauldron</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>13.0</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>NSHumanReadableCopyright</key>
<string>${AuthorCopyright:HtmlEncode}</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSMainStoryboardFile</key>
<string>Main</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.script</string>
</array>
<key>UTTypeDescription</key>
<string>C# Script</string>
<key>UTTypeIcons</key>
<dict/>
<key>UTTypeIdentifier</key>
<string>com.neilbrommer.cauldron-CsScript</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>csx</string>
</array>
</dict>
</dict>
</array>
<key>XSAppIconAssets</key>
<string>Assets.xcassets/AppIcon.appiconset</string>
</dict>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="21701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="JKR-xj-8kh">
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="21701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21701"/>
<plugIn identifier="com.apple.WebKit2IBPlugin" version="21701"/>
@ -67,11 +67,6 @@
<action selector="newDocument:" target="Ady-hI-5gd" id="4Si-XN-c54"/>
</connections>
</menuItem>
<menuItem title="New Tab" keyEquivalent="t" id="NId-gA-yuH">
<connections>
<action selector="NewTabMenuItemClicked:" target="Voe-Tx-rLC" id="Uat-zk-F3C"/>
</connections>
</menuItem>
<menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
<connections>
<action selector="openDocument:" target="Ady-hI-5gd" id="bVn-NM-KNZ"/>
@ -419,7 +414,7 @@
<!--Window Controller-->
<scene sceneID="ktg-sd-7li">
<objects>
<windowController id="JKR-xj-8kh" customClass="MainWindow" sceneMemberID="viewController">
<windowController storyboardIdentifier="MainWindowController" id="JKR-xj-8kh" customClass="MainWindow" sceneMemberID="viewController">
<window key="window" title="Cauldron" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" frameAutosaveName="" animationBehavior="default" tabbingMode="preferred" toolbarStyle="unified" id="d7K-Gm-g9N">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES" fullSizeContentView="YES"/>
<rect key="contentRect" x="211" y="264" width="749" height="445"/>
@ -440,11 +435,6 @@
<toolbarItem implicitItemIdentifier="8EDDDA98-E8C5-404C-9832-8C97B1DAEF5C" label="Run Script" paletteLabel="Run Script" tag="-1" image="play.fill" catalog="system" bordered="YES" sizingBehavior="auto" autovalidates="NO" id="BH3-uw-K5S"/>
<toolbarItem implicitItemIdentifier="NSToolbarSpaceItem" id="ib2-fU-LMb"/>
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="GqC-ht-JU0"/>
<toolbarItem implicitItemIdentifier="3C40411F-C0EC-43C1-B18B-82BA5661BF11" label="New Tab" paletteLabel="New Tab" tag="-1" image="plus" catalog="system" bordered="YES" sizingBehavior="auto" id="uBe-lp-9U2">
<connections>
<action selector="NewTabClicked:" target="JKR-xj-8kh" id="x1O-6U-svq"/>
</connections>
</toolbarItem>
<toolbarItem implicitItemIdentifier="1FDD22AF-AF38-4957-AC69-1E8377E11C5D" label="Script Status" paletteLabel="Script Status" bordered="YES" sizingBehavior="auto" autovalidates="NO" id="bj4-Kg-7Qc">
<nil key="toolTip"/>
<segmentedControl key="view" verticalHuggingPriority="750" id="63L-Ya-hDW">
@ -473,7 +463,6 @@
<toolbarItem reference="GqC-ht-JU0"/>
<toolbarItem reference="bj4-Kg-7Qc"/>
<toolbarItem reference="BH3-uw-K5S"/>
<toolbarItem reference="uBe-lp-9U2"/>
</defaultToolbarItems>
</toolbar>
<connections>
@ -487,6 +476,7 @@
</connections>
</windowController>
<customObject id="Dyo-ea-3jV" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
<objectController mode="entity" entityName="CSharpScriptDocument" automaticallyPreparesContent="YES" id="IPo-2l-BeA"/>
</objects>
<point key="canvasLocation" x="-23" y="73"/>
</scene>
@ -652,7 +642,6 @@
<image name="exclamationmark.triangle.fill" catalog="system" width="17" height="15"/>
<image name="info.circle.fill" catalog="system" width="15" height="15"/>
<image name="play.fill" catalog="system" width="12" height="13"/>
<image name="plus" catalog="system" width="14" height="13"/>
<image name="sidebar.leading" catalog="system" width="18" height="14"/>
</resources>
</document>

View File

@ -2,7 +2,6 @@ using System;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using AppKit;
using Cauldron.Macos.SourceWriter;
@ -14,6 +13,8 @@ namespace Cauldron.Macos;
public partial class MainWindow : NSWindowController
{
public CSharpScriptDocument ScriptDocument { get => (CSharpScriptDocument)this.Document; }
#region Window components
private NSSplitViewController MainContentController
@ -34,7 +35,7 @@ public partial class MainWindow : NSWindowController
.ContentView.DocumentView as NSOutlineView;
}
private SourceTextView ScriptEditorTextBox
public SourceTextView ScriptEditorTextBox
{
get => (this.MainContentController
.SplitViewItems[0].ViewController.View as NSScrollView)
@ -60,14 +61,21 @@ public partial class MainWindow : NSWindowController
public MainWindow (ObjCRuntime.NativeHandle handle) : base (handle) { }
public override void AwakeFromNib()
public override void WindowDidLoad()
{
base.AwakeFromNib();
base.WindowDidLoad();
this.Document ??= new CSharpScriptDocument();
if (this.ScriptDocument.ScriptText == null)
this.ScriptDocument.ScriptText = new NSString(this.ScriptText);
this.RunScriptToolbarButton.Activated += RunScript;
SourceTextView scriptTextBox = this.ScriptEditorTextBox;
scriptTextBox.OnFinishedTyping += this.BuildScript;
scriptTextBox.OnTextChanged += this.UpdateDocument;
scriptTextBox.Font = NSFont.MonospacedSystemFont(new nfloat(14), NSFontWeight.Regular);
scriptTextBox.AutomaticQuoteSubstitutionEnabled = false;
scriptTextBox.AutomaticDashSubstitutionEnabled = false;
@ -79,6 +87,14 @@ public partial class MainWindow : NSWindowController
scriptTextBox.Formatter = new LanguageFormatter(scriptTextBox, new CSharpDescriptor());
scriptTextBox.Formatter.Reformat();
this.SetDocumentEdited(this.ScriptDocument.IsDocumentEdited);
}
public void UpdateDocument(object sender, EventArgs args)
{
this.ScriptDocument.ScriptText = new NSString(this.ScriptText);
this.SetDocumentEdited(this.ScriptDocument.IsDocumentEdited);
}
public void BuildScript(object sender, ElapsedEventArgs args)
@ -96,11 +112,6 @@ public partial class MainWindow : NSWindowController
this.ScriptCancellationTokenSource?.Cancel();
}
partial void NewTabClicked(AppKit.NSToolbarItem sender)
{
this.CreateNewTab();
}
partial void NewTabMenuItemClicked(AppKit.NSMenuItem sender)
{
this.CreateNewTab();

View File

@ -120,8 +120,6 @@ public static class ScriptRunner
+ head.RenderAsString()
+ body.RenderAsString();
Console.WriteLine("Contents: " + contents);
webView.LoadHtmlString(new Foundation.NSString(contents), null);
}

View File

@ -452,6 +452,9 @@ public class SourceTextView : NSTextView
/// </summary>
public event ElapsedEventHandler OnFinishedTyping;
/// <summary>Triggered when the value in the textbox is changed</summary>
public event EventHandler OnTextChanged;
/// <summary>
/// Look for special keys being pressed and does specific processing based on the key.
/// </summary>
@ -586,11 +589,14 @@ public class SourceTextView : NSTextView
}
this.Formatter.Reformat();
this.OnTextChanged.Invoke(this, null);
this.InputTimoutTimer?.Stop();
this.InputTimoutTimer?.Close();
this.InputTimoutTimer = new Timer(this.InputTimeoutInterval);
this.InputTimoutTimer.AutoReset = false;
this.InputTimoutTimer = new(this.InputTimeoutInterval)
{
AutoReset = false
};
this.InputTimoutTimer.Elapsed += this.OnFinishedTyping;
this.InputTimoutTimer.Start();
}