Use a web view for output
This commit is contained in:
parent
1f8d7a661b
commit
e887ce9507
|
@ -48,4 +48,8 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Cauldron.Core\Cauldron.Core.csproj" />
|
<ProjectReference Include="..\Cauldron.Core\Cauldron.Core.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.ViewFeatures" Version="2.2.0" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
17
Cauldron.Macos/Extensions.cs
Normal file
17
Cauldron.Macos/Extensions.cs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
using System.IO;
|
||||||
|
using System.Text.Encodings.Web;
|
||||||
|
using Microsoft.AspNetCore.Html;
|
||||||
|
|
||||||
|
namespace Cauldron.Macos;
|
||||||
|
|
||||||
|
public static class Extensions
|
||||||
|
{
|
||||||
|
public static string RenderAsString(this IHtmlContent htmlContent)
|
||||||
|
{
|
||||||
|
using (var writer = new StringWriter())
|
||||||
|
{
|
||||||
|
htmlContent.WriteTo(writer, HtmlEncoder.Default);
|
||||||
|
return writer.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
<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" initialViewController="JKR-xj-8kh">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21701"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21701"/>
|
||||||
|
<plugIn identifier="com.apple.WebKit2IBPlugin" version="21701"/>
|
||||||
<capability name="NSView safe area layout guides" minToolsVersion="12.0"/>
|
<capability name="NSView safe area layout guides" minToolsVersion="12.0"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@ -567,37 +568,18 @@
|
||||||
<scene sceneID="l4o-FF-cV6">
|
<scene sceneID="l4o-FF-cV6">
|
||||||
<objects>
|
<objects>
|
||||||
<viewController id="71j-pP-grU" sceneMemberID="viewController">
|
<viewController id="71j-pP-grU" sceneMemberID="viewController">
|
||||||
<scrollView key="view" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" id="DqK-nD-55b">
|
<wkWebView key="view" wantsLayer="YES" id="8OW-Al-ci0">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="700" height="200"/>
|
<rect key="frame" x="0.0" y="0.0" width="700" height="300"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<clipView key="contentView" drawsBackground="NO" id="79H-al-KZe">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="700" height="200"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<subviews>
|
|
||||||
<textView wantsLayer="YES" editable="NO" importsGraphics="NO" richText="NO" verticallyResizable="YES" spellingCorrection="YES" smartInsertDelete="YES" id="Dvs-AF-xxf">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="700" height="200"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<size key="minSize" width="700" height="200"/>
|
|
||||||
<size key="maxSize" width="700" height="10000000"/>
|
|
||||||
<color key="insertionPointColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textView>
|
|
||||||
</subviews>
|
|
||||||
</clipView>
|
|
||||||
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="b5v-02-4gX">
|
|
||||||
<rect key="frame" x="-100" y="-100" width="240" height="16"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
</scroller>
|
<wkWebViewConfiguration key="configuration">
|
||||||
<scroller key="verticalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="XXI-2E-6rI">
|
<audiovisualMediaTypes key="mediaTypesRequiringUserActionForPlayback" none="YES"/>
|
||||||
<rect key="frame" x="684" y="0.0" width="16" height="200"/>
|
<wkPreferences key="preferences"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
</wkWebViewConfiguration>
|
||||||
</scroller>
|
</wkWebView>
|
||||||
</scrollView>
|
|
||||||
</viewController>
|
</viewController>
|
||||||
<customObject id="fhB-Tn-Q6J" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
<customObject id="fhB-Tn-Q6J" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="1156" y="830"/>
|
<point key="canvasLocation" x="1156" y="882"/>
|
||||||
</scene>
|
</scene>
|
||||||
<!--View Controller-->
|
<!--View Controller-->
|
||||||
<scene sceneID="hN3-Zg-qPS">
|
<scene sceneID="hN3-Zg-qPS">
|
||||||
|
|
|
@ -33,11 +33,10 @@ public partial class MainWindow : NSWindowController
|
||||||
.ContentView.DocumentView as NSTextView;
|
.ContentView.DocumentView as NSTextView;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NSTextView ScriptOutputTextBox
|
public WebKit.WKWebView ScriptOutputWebView
|
||||||
{
|
{
|
||||||
get => (this.MainContentController
|
get => this.MainContentController
|
||||||
.SplitViewItems[1].ViewController.View as NSScrollView)
|
.SplitViewItems[1].ViewController.View as WebKit.WKWebView;
|
||||||
.ContentView.DocumentView as NSTextView;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ScriptText { get => this.ScriptEditorTextBox.Value; }
|
public string ScriptText { get => this.ScriptEditorTextBox.Value; }
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
using Cauldron.Core;
|
using Cauldron.Core;
|
||||||
|
|
||||||
namespace Cauldron.Macos;
|
namespace Cauldron.Macos;
|
||||||
|
@ -10,16 +12,19 @@ public static class ScriptRunner
|
||||||
public static void RunScript(MainWindow window)
|
public static void RunScript(MainWindow window)
|
||||||
{
|
{
|
||||||
window.SetScriptRunState(true);
|
window.SetScriptRunState(true);
|
||||||
window.ScriptOutputTextBox.Value = "";
|
|
||||||
|
TagBuilder body = new("body");
|
||||||
|
|
||||||
|
window.ScriptOutputWebView.SetOutputPanelContent(body);
|
||||||
TaskScheduler uiThread = TaskScheduler.FromCurrentSynchronizationContext();
|
TaskScheduler uiThread = TaskScheduler.FromCurrentSynchronizationContext();
|
||||||
|
|
||||||
CauldronWriter writer = new(obj =>
|
CauldronWriter writer = new(obj =>
|
||||||
{
|
|
||||||
if (obj is string str)
|
|
||||||
{
|
{
|
||||||
window.BeginInvokeOnMainThread(() =>
|
window.BeginInvokeOnMainThread(() =>
|
||||||
window.ScriptOutputTextBox.Value += str + "\n");
|
{
|
||||||
}
|
body.InnerHtml.AppendHtml(GenerateValueOutput(obj));
|
||||||
|
window.ScriptOutputWebView.SetOutputPanelContent(body);
|
||||||
|
});
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
});
|
});
|
||||||
|
@ -40,11 +45,52 @@ public static class ScriptRunner
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
window.BeginInvokeOnMainThread(() =>
|
window.BeginInvokeOnMainThread(() =>
|
||||||
window.ScriptOutputTextBox.Value += ex.ToString());
|
{
|
||||||
|
TagBuilder exTag = new("pre");
|
||||||
|
exTag.InnerHtml.Append(ex.ToString());
|
||||||
|
body.InnerHtml.AppendHtml(exTag);
|
||||||
|
|
||||||
|
window.ScriptOutputWebView.SetOutputPanelContent(body);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}, window.ScriptCancellationTokenSource.Token)
|
}, window.ScriptCancellationTokenSource.Token)
|
||||||
.ContinueWith((t) => window.SetScriptRunState(false),
|
.ContinueWith((t) => window.SetScriptRunState(false),
|
||||||
uiThread);
|
uiThread);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
private static TagBuilder GenerateValueOutput(object value)
|
||||||
|
{
|
||||||
|
if (value is string str)
|
||||||
|
{
|
||||||
|
TagBuilder tag = new("p");
|
||||||
|
tag.InnerHtml.Append(str);
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
if (value.GetType().IsPrimitive)
|
||||||
|
{
|
||||||
|
TagBuilder tag = new("p");
|
||||||
|
tag.InnerHtml.Append(value.ToString());
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
if (value is IEnumerable<object> enumberable)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SetOutputPanelContent(this WebKit.WKWebView webView,
|
||||||
|
TagBuilder body)
|
||||||
|
{
|
||||||
|
TagBuilder head = new("head");
|
||||||
|
|
||||||
|
string contents = "<!DOCTYPE html>"
|
||||||
|
+ head.RenderAsString()
|
||||||
|
+ body.RenderAsString();
|
||||||
|
|
||||||
|
Console.WriteLine("Contents: " + contents);
|
||||||
|
|
||||||
|
webView.LoadHtmlString(new Foundation.NSString(contents), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue