Skip to content

Commit f3e0213

Browse files
committed
q
1 parent 21e1e08 commit f3e0213

20 files changed

+416
-23
lines changed

01_SimilarEnough/01_SimilarEnough.fsproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<PlatformTarget>x64</PlatformTarget>
88
<AssemblyName>$(MSBuildProjectName).esapi</AssemblyName>
99
<IncrementVersionOnBuild>1.yyyy.MMdd.HHmm</IncrementVersionOnBuild>
10-
<Version>1.2024.1122.1514</Version>
10+
<Version>1.2024.1125.1813</Version>
1111
</PropertyGroup>
1212

1313
<ItemGroup>

02_calculate_IMAGER_positions/0202_calculate_IMAGER_positions.fs

+23-4
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ module ImagerPositionCalculation =
3333
/// - `x1`: The X1 jaw position.
3434
/// - `x2`: The X2 jaw position.
3535
let calculateImagerLat x1 x2 =
36+
3637
// Calculate the absolute shift needed
37-
let shiftLat = (abs (x1 - x2) / 2.0) * 1.6 // Because the imager is at 60.0cm
38+
let shiftLat =
39+
(abs (x1 - x2) / 2.0) * 1.6 // Because the imager is at 60.0cm
3840

3941
// Apply constraints to the shift
4042
let constrainedShiftLat =
@@ -45,7 +47,8 @@ module ImagerPositionCalculation =
4547

4648
// Calculate the imager lateral position based on direction
4749
let imagerLat =
48-
if ( constrainedShiftLat > 0.0 ) && ( x1 > x2 ) then
50+
if ( constrainedShiftLat > 0.0 ) && ( x1 > x2 )
51+
then
4952
1000.0 - constrainedShiftLat
5053
else
5154
constrainedShiftLat
@@ -113,7 +116,15 @@ module ImagerPositionCalculation =
113116
let imagerLat = calculateImagerLat x1 x2
114117

115118
// Create a setup beam record with the input values and calculated imager positions
116-
{ Id = id; X1 = x1; X2 = x2; Y1 = y1; Y2 = y2; ImagerVrt = 60.0; ImagerLng = imagerLng; ImagerLat = imagerLat })
119+
{ Id = id
120+
; X1 = x1
121+
; X2 = x2
122+
; Y1 = y1
123+
; Y2 = y2
124+
; ImagerVrt = 60.0
125+
; ImagerLng = imagerLng
126+
; ImagerLat = imagerLat
127+
})
117128
|> List.ofSeq // Convert seq<setupBeam> to setupBeam list
118129

119130
/// Helper function to check if a string contains all specified substrings.
@@ -178,7 +189,15 @@ module ImagerPositionCalculation =
178189
[
179190
yield! List.map (fun prop ->
180191
sprintf "<tr><td style=\"width: 100px;\">%s</td>%s</tr>" prop (String.concat "" [for beam in sortedBeams -> sprintf "<td>%.1f</td>" (getValue prop beam)])
181-
) ["X1"; "X2"; "Y1"; "Y2"; "ImagerVrt"; "ImagerLng"; "ImagerLat"]
192+
)
193+
[ "X1"
194+
; "X2"
195+
; "Y1"
196+
; "Y2"
197+
; "ImagerVrt"
198+
; "ImagerLng"
199+
; "ImagerLat"
200+
]
182201
]
183202
|> List.fold (+) ""
184203
sprintf "<!DOCTYPE html>\n<html>\n<head>\n<style>\nbody {\n margin-left: 5%%;\n margin-right: 5%%;\n font-family: sans-serif;\n}\n\nh1 {\n display: block;\n font-size: 2em;\n margin-block-start: 0.67em;\n margin-block-end: 0.67em;\n margin-inline-start: 0px;\n margin-inline-end: 0px;\n font-weight: bold;\n margin-left: -3%%;\n}\n\ntable {\n font-family: 'Trebuchet MS', Arial, Helvetica, sans-serif;\n border: 2px solid blue;\n border-collapse: collapse;\n text-indent: initial;\n white-space: normal;\n line-height: normal;\n font-weight: normal;\n font-style: normal;\n text-align: start;\n border-spacing: 2px;\n font-variant: normal;\n}\n\ntd, th {\n font-size: 1.17em;\n border: 1px solid blue;\n padding: 3px 7px 2px 7px;\n text-align: left;\n padding: 8px;\n width: 120px;\n}\nth {background-color: lightgray;}\n</style>\n</head>\n<body>\n<h1>\nImager Positions\n</h1>\n<table>%s%s</table>\n</body>\n</html>" headerRow bodyRows

02_calculate_IMAGER_positions/02_calculate_IMAGER_positions.fsproj

+2-3
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
<GenerateDocumentationFile>true</GenerateDocumentationFile>
66
<WarnOn>3390;$(WarnOn)</WarnOn>
7-
<AssemblyName>$(MSBuildProjectName).esapi</AssemblyName>
7+
<AssemblyName>calculate_IMAGER_positions.esapi</AssemblyName>
88
<PlatformTarget>x64</PlatformTarget>
99
<IncrementVersionOnBuild>1.yyyy.MMdd.HHmm</IncrementVersionOnBuild>
10-
<Version>1.2024.1122.1514</Version>
10+
<Version>1.2024.1125.1813</Version>
1111
</PropertyGroup>
1212
<ItemGroup>
1313
<EmbeddedResource Remove="Properties\**" />
@@ -22,7 +22,6 @@
2222
<ItemGroup>
2323
<PackageReference Include="System.Net.Http" Version="4.3.4" />
2424
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
25-
<PackageReference Include="FSharp.Core" Version="9.0.100" />
2625
</ItemGroup>
2726

2827
<ItemGroup>

04_onboard_AI_structures/04_onboard_AI_structures.fsproj

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@
66
<PlatformTarget>x64</PlatformTarget>
77
<AssemblyName>onboard_AI_structures.esapi</AssemblyName>
88
<IncrementVersionOnBuild>1.yyyy.Mdd.Hmm</IncrementVersionOnBuild>
9-
<Version>1.2024.1122.1514</Version>
9+
<Version>1.2024.1125.1813</Version>
1010
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
1111
</PropertyGroup>
1212
<ItemGroup>
13-
<None Include="App.config" />
1413
<Compile Include="0401_HtmlTableFetcher.fs" />
1514
<Compile Include="0402_StructureOperations.fs" />
1615
<Compile Include="0403_HtmlOutput.fs" />

04_onboard_AI_structures/App.config

-10
This file was deleted.

05_label_TBI_fields/05_label_TBI_fields.fsproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<PlatformTarget>x64</PlatformTarget>
1010
<OutputType>Library</OutputType>
1111
<IncrementVersionOnBuild>1.yyyy.Mdd.Hmm</IncrementVersionOnBuild>
12-
<Version>1.2024.1122.1514</Version>
12+
<Version>1.2024.1125.1813</Version>
1313
<UserSecretsId>09417e89-9a9e-46c7-ad36-870b407ecd12</UserSecretsId>
1414
</PropertyGroup>
1515

07_send_to_Electron_MOBIUS/07_send_to_Electron_MOBIUS.fsproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<PlatformTarget>x64</PlatformTarget>
1010
<OutputType>Library</OutputType>
1111
<IncrementVersionOnBuild>1.yyyy.Mdd.Hmm</IncrementVersionOnBuild>
12-
<Version>1.2024.1122.1514</Version>
12+
<Version>1.2024.1125.1813</Version>
1313
</PropertyGroup>
1414

1515
<ItemGroup>

08_remove_AI_structures/08_remove_AI_structures.fsproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<IncrementVersionOnBuild>1.yyyy.Mdd.Hmm</IncrementVersionOnBuild>
88
<AssemblyName>$(MSBuildProjectName).esapi</AssemblyName>
99
<PlatformTarget>x64</PlatformTarget>
10-
<Version>1.2024.1122.1514</Version>
10+
<Version>1.2024.1125.1813</Version>
1111
</PropertyGroup>
1212

1313
<ItemGroup>

FunctionalESAPI.sln

+12
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "08_remove_AI_structures", "
1919
EndProject
2020
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "07_send_to_Electron_MOBIUS", "07_send_to_Electron_MOBIUS\07_send_to_Electron_MOBIUS.fsproj", "{DB8CEE47-F090-4EA9-B49A-950469CF1C93}"
2121
EndProject
22+
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "00_FunctionalESAPI_Main", "FunctionalESAPI_Main\00_FunctionalESAPI_Main.fsproj", "{77E99FD2-71CE-4F10-BFDA-C9A70BA02089}"
23+
EndProject
24+
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "mainScreen", "mainScreen\mainScreen.fsproj", "{B37B28BA-3319-4FD4-A913-C220A8891CE1}"
25+
EndProject
2226
Global
2327
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2428
Debug|Any CPU = Debug|Any CPU
@@ -57,6 +61,14 @@ Global
5761
{DB8CEE47-F090-4EA9-B49A-950469CF1C93}.Debug|Any CPU.Build.0 = Debug|Any CPU
5862
{DB8CEE47-F090-4EA9-B49A-950469CF1C93}.Release|Any CPU.ActiveCfg = Release|Any CPU
5963
{DB8CEE47-F090-4EA9-B49A-950469CF1C93}.Release|Any CPU.Build.0 = Release|Any CPU
64+
{77E99FD2-71CE-4F10-BFDA-C9A70BA02089}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
65+
{77E99FD2-71CE-4F10-BFDA-C9A70BA02089}.Debug|Any CPU.Build.0 = Debug|Any CPU
66+
{77E99FD2-71CE-4F10-BFDA-C9A70BA02089}.Release|Any CPU.ActiveCfg = Release|Any CPU
67+
{77E99FD2-71CE-4F10-BFDA-C9A70BA02089}.Release|Any CPU.Build.0 = Release|Any CPU
68+
{B37B28BA-3319-4FD4-A913-C220A8891CE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
69+
{B37B28BA-3319-4FD4-A913-C220A8891CE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
70+
{B37B28BA-3319-4FD4-A913-C220A8891CE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
71+
{B37B28BA-3319-4FD4-A913-C220A8891CE1}.Release|Any CPU.Build.0 = Release|Any CPU
6072
EndGlobalSection
6173
GlobalSection(SolutionProperties) = preSolution
6274
HideSolutionNode = FALSE
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<TargetFramework>net48</TargetFramework>
4+
5+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
6+
<WarnOn>3390;$(WarnOn)</WarnOn>
7+
<OutputType>Exe</OutputType>
8+
<PlatformTarget>x64</PlatformTarget>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<Content Include="bin\Debug\net48\index4.html" />
13+
<Content Include="bin\Debug\net48\index3.html" />
14+
<Content Include="bin\Debug\net48\index2.html" />
15+
<Content Include="bin\Debug\net48\index.html" />
16+
<Compile Include="Model.fs" />
17+
<Compile Include="HtmlHelpers.fs" />
18+
<Compile Include="JavascriptHelpers.fs" />
19+
<Compile Include="View.fs" />
20+
<Compile Include="Update.fs" />
21+
<Compile Include="Subscriptions.fs" />
22+
<Compile Include="Program.fs" />
23+
</ItemGroup>
24+
25+
<ItemGroup />
26+
27+
<ItemGroup>
28+
<PackageReference Include="AngleSharp" Version="1.1.2" />
29+
<PackageReference Include="Elmish" Version="4.2.0" />
30+
</ItemGroup>
31+
32+
<ItemGroup>
33+
<Reference Include="WebUI4CSharp_net48">
34+
<HintPath>..\..\..\Documents\WebUI\Fsharp.BrowserUI\WebUI4CSharp_net48.dll</HintPath>
35+
</Reference>
36+
</ItemGroup>
37+
</Project>

FunctionalESAPI_Main/HtmlHelpers.fs

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
namespace VMS.TPS
2+
3+
open AngleSharp.Dom
4+
open Model
5+
6+
module HtmlHelpers =
7+
8+
// Helper function to get an element by ID from the body
9+
let escapeId (id: string) =
10+
id.Replace(".", "\\.").Replace("#", "\\#").Replace(" ", "\\ ")
11+
12+
let getElementById (id: string) (model: Model) =
13+
let selector = "#" + escapeId id
14+
printfn "Querying with selector: %s" selector
15+
16+
model.Body.QuerySelector(selector)
17+
18+
// Function to get the content (innerHtml, innerText, outerHtml)
19+
let get (id: string) (what: string) (model: Model) =
20+
let element = getElementById id model
21+
match what with
22+
| "innerHtml" -> element.InnerHtml
23+
| "textContent" -> element.TextContent
24+
| "outerHtml" -> element.OuterHtml
25+
| _ -> failwith "element or attr not found"
26+
27+
// Function to set the content (innerHtml, innerText, outerHtml)
28+
let set (id: string) (what: string) (value: string) (model: Model) =
29+
let element = getElementById id model
30+
match what with
31+
| "innerHtml" -> element.InnerHtml <- value
32+
| "textContent" -> element.TextContent <- value
33+
| "outerHtml" ->
34+
let parent = element.ParentElement
35+
if parent <> null then
36+
let newElement = element.Owner.CreateElement("div")
37+
newElement.OuterHtml <- value
38+
parent.ReplaceChild(newElement.FirstChild, element) |> ignore
39+
| _ -> ()
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
namespace VMS.TPS
2+
3+
open AngleSharp.Dom
4+
open Model
5+
6+
module JavascriptHelpers =
7+
8+
// Create a single line of JavaScript code to update the UI
9+
let createSingleJsCode (id: string) (what: string) (model: Model) =
10+
let newHtml = (HtmlHelpers.get id what model).Replace("'", "\\'")
11+
let jsCode = sprintf "document.getElementById('%s').%s = '%s';" id what (newHtml)
12+
jsCode
13+
14+
// Create full JavaScript code for a list of updates
15+
let createFullJsCode (idAndWhatList: (string * string) list) (model: Model) =
16+
idAndWhatList
17+
|> List.distinct // makes unique
18+
|> List.map (fun (id, what) -> createSingleJsCode id what model)
19+
|> String.concat " "

FunctionalESAPI_Main/Model.fs

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
namespace VMS.TPS
2+
3+
open System.IO
4+
open AngleSharp
5+
open AngleSharp.Dom
6+
7+
// Define the model
8+
module Model =
9+
10+
type Model = {
11+
Body: IElement // Representing the parsed HTML body as an AngleSharp node
12+
ViewNeedsToBeUpdated: bool
13+
ElementsToBeUpdated: (string * string) list // (id, what) for updates
14+
}
15+
16+
// Define the messages
17+
type Msg =
18+
| Increment of ( string * int )
19+
| Decrement of ( string * int )
20+
| SetViewUpdateOn
21+
| SetViewUpdateOff
22+
23+
let initialModel htmlContent =
24+
// Parse the initial HTML content
25+
let config = Configuration.Default
26+
let context = BrowsingContext.New(config)
27+
let documentTask = context.OpenAsync(fun req -> req.Content(htmlContent) |> ignore)
28+
let document = documentTask.Result
29+
let body = document.Body
30+
31+
{ Body = body; ViewNeedsToBeUpdated = false; ElementsToBeUpdated = [] }
32+
33+
// Function to read the HTML file and initialize the app
34+
let initializeApp htmlContent =
35+
36+
// Initialize the model with the parsed HTML
37+
let model = initialModel htmlContent
38+
39+
// Return the initial model
40+
model// Initial state of the model
41+

FunctionalESAPI_Main/Program.fs

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
namespace VMS.TPS
2+
3+
open Elmish
4+
open WebUI4CSharp_net48
5+
open Model
6+
open Update
7+
open Subscriptions
8+
open View
9+
10+
// Main program setup
11+
module Main =
12+
13+
[<EntryPoint>]
14+
let main argv =
15+
16+
let window = new WebUIWindow()
17+
18+
// Initialize Elmish program
19+
Program.mkProgram (fun () -> (initializeApp View.htmlContent), Cmd.none ) update (view window)
20+
|> Program.withSubscription (subscribe window)
21+
|> Program.run
22+
23+
// Wait for UI to close
24+
WebUI.Wait() |> ignore
25+
26+
// Clean up resources
27+
WebUI.Clean() |> ignore
28+
29+
0

FunctionalESAPI_Main/Subscriptions.fs

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
namespace VMS.TPS
2+
3+
open Model
4+
open WebUI4CSharp_net48
5+
open Elmish
6+
open System
7+
8+
9+
// Handle events dispatched from WebUI and return the appropriate message
10+
module Subscriptions =
11+
12+
let handleEvents (e: byref<webui_event_t>) : Msg =
13+
let lEvent = new WebUIEvent(e)
14+
let eventType = lEvent.GetString()
15+
let id = lEvent.GetStringAt(unativeint 1)
16+
printfn "handle event id: %s" id
17+
//System.Console.ReadLine() |> ignore
18+
19+
let value = lEvent.GetStringAt(unativeint 2) |> int
20+
printfn "handle event value: %s" (value.ToString())
21+
//System.Console.ReadLine() |> ignore
22+
23+
24+
match eventType with
25+
| "increment" ->
26+
Increment (id, value )
27+
28+
| "decrement" ->
29+
Decrement (id, value )
30+
31+
| _ ->
32+
failwith "unknown message"
33+
34+
// Keep a reference to the BindCallback delegate
35+
let mutable callbackReference : BindCallback = Unchecked.defaultof<_>
36+
37+
// Define a WebUI subscription for event handling
38+
let webUIEventSubscription (window: WebUIWindow) (dispatch: Dispatch<Msg>) : IDisposable =
39+
callbackReference <- BindCallback(fun e ->
40+
let msg = handleEvents (&e)
41+
dispatch msg )
42+
43+
window.Bind("uiEvent", callbackReference) |> ignore
44+
window.Show(View.htmlContent) |> ignore
45+
46+
{ new IDisposable with
47+
member _.Dispose() =
48+
window.Close() |> ignore
49+
callbackReference <- Unchecked.defaultof<_>
50+
}
51+
52+
// Subscription setup
53+
let subscribe (window: WebUIWindow) (_model: Model) : (string list * (Dispatch<Msg> -> IDisposable)) list =
54+
[ [ "counter-sub" ], webUIEventSubscription window ]

0 commit comments

Comments
 (0)