module ParasitemiaUI.DPICalculator open System open System.Windows open System.Windows.Media open System.Windows.Markup open System.Windows.Shapes open System.Windows.Controls open System.Diagnostics open ParasitemiaCore.UnitsOfMeasure open ParasitemiaCore.Types type SensorSize = { w: float h: float txt: string } with override this.ToString () = sprintf "%g mm × %g mm%s" this.w this.h (if this.txt = "" then "" else " (" + this.txt + ")") let showWindow (parent: Window) : int option = let win = Views.DPICalculatorWindow() win.Root.Owner <- parent win.Root.Left <- parent.Left + parent.ActualWidth / 2. - win.Root.Width / 2. win.Root.Top <- parent.Top + parent.ActualHeight / 2. - win.Root.Height / 2. let sensorSizes = [ { w = 5.76; h = 4.29; txt = "1/2.5″" } { w = 7.6; h = 5.7; txt = "1/1.7″" } { w = 8.6; h = 6.6; txt = "2/3″" } { w = 13.2; h = 8.8; txt = "1″" } { w = 17.3; h = 13.; txt = "" } { w = 20.7; h = 13.8; txt = "" } { w = 22.2; h = 14.8; txt = "" } { w = 23.6; h = 15.7; txt = "" } { w = 28.7; h = 19.; txt = "" } { w = 28.7; h = 19.; txt = "" } ] for size in sensorSizes do win.cmbSensorSize.Items.Add(size) |> ignore win.cmbSensorSize.SelectedIndex <- 0 let resolution (w_p: float) (w_mm: float) (zoom: float) : float = w_p * zoom / mmToInch w_mm let updateCurrentResolution () = let { w = w; h = h } = win.cmbSensorSize.SelectedValue :?> SensorSize let ratio = h / w let parseDouble txt errorMess = match Double.TryParse(txt) with true, value -> Success value | _ -> Fail errorMess match result { let! sensorResolution = parseDouble win.txtSensorResolution.Text "The sensor resolution is not valid" let! zoom = parseDouble win.txtZoom.Text "The zoom is not valid" let wPixel = 1. * sqrt (sensorResolution * 1e6 / ratio) return! Success (float <| resolution wPixel w zoom) } with | Success res -> win.txtImageResolution.Text <- (int (res / 1000.) * 1000).ToString() | Fail mess -> win.txtImageResolution.Text <- mess win.butCancel.Click.AddHandler(fun obj args -> win.Root.DialogResult <- Nullable(false); win.Root.Close()) win.butOK.Click.AddHandler(fun obj args -> win.Root.DialogResult <- Nullable(true); win.Root.Close()) win.cmbSensorSize.SelectionChanged.AddHandler(fun obj arg -> updateCurrentResolution ()) win.txtSensorResolution.TextChanged.AddHandler(fun obj arg -> updateCurrentResolution ()) win.txtZoom.TextChanged.AddHandler(fun obj arg -> updateCurrentResolution ()) let result = win.Root.ShowDialog() if result.HasValue && result.Value then match Int32.TryParse win.txtImageResolution.Text with | true, res -> Some res | _ -> None else None