Add a DPI calculator to help to find the correct image resolution.
[master-thesis.git] / Parasitemia / ParasitemiaUI / Analysis.fs
index 9b9ed51..70d9ef0 100644 (file)
@@ -19,38 +19,27 @@ open ParasitemiaCore.Config
 open Types
 
 let showWindow (parent: Window) (state: State.State) : bool =
-    let window = Views.AnalysisWindow()
-    window.Root.Owner <- parent
-    window.Root.Left <- parent.Left + parent.ActualWidth / 2. - window.Root.Width / 2.
-    window.Root.Top <- parent.Top + parent.ActualHeight / 2. - window.Root.Height / 2.
-
-    let ctrl (name: string): 'a = window.Root.FindName(name) :?> 'a
-
-    let butClose: Button = ctrl "butClose"
-    let butStart: Button = ctrl "butStart"
-
-    let stackSourceImagesSelection: StackPanel = ctrl "stackSourceImagesSelection"
-    let progressBar: ProgressBar = ctrl "progress"
-    let textLog: TextBlock = ctrl "textLog"
-    let scrollLog: ScrollViewer = ctrl "scrollLog"
+    let win = Views.AnalysisWindow()
+    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 logListener =
         { new Logger.IListener with
             member this.NewEntry severity mess =
-                window.Root.Dispatcher.Invoke(fun () ->
-                textLog.Inlines.Add(Documents.Run(mess))
-                textLog.Inlines.Add(Documents.LineBreak())
-                scrollLog.ScrollToBottom()) }
+                win.Root.Dispatcher.Invoke(fun () ->
+                    win.textLog.Inlines.Add(Documents.Run(mess))
+                    win.textLog.Inlines.Add(Documents.LineBreak())
+                    win.scrollLog.ScrollToBottom()) }
 
     Logger.Log.AddListener(logListener)
 
     let minPPI = 1.
     let maxPPI = 10e6
     let parseAndValidatePPI (input: string) : float option =
-        let res = ref 0.
-        if Double.TryParse(input, res) && !res >= minPPI && !res <= maxPPI
-        then Some !res
-        else None
+        match Double.TryParse(input) with
+        | true, value when value >= minPPI && value <= maxPPI -> Some value
+        | _ -> None
 
     let monitor = Object()
     let mutable atLeastOneAnalysisPerformed = false
@@ -58,8 +47,8 @@ let showWindow (parent: Window) (state: State.State) : bool =
     let mutable analysisCancelled = false
 
     let updateSourceImages () =
-        stackSourceImagesSelection.Children.Clear()
-        let width = int stackSourceImagesSelection.ActualWidth
+        win.stackSourceImagesSelection.Children.Clear()
+        let width = int win.stackSourceImagesSelection.ActualWidth
         for srcImg in state.SourceImages do
             let imageSourceSelection = Views.ImageSourceSelection(Tag = srcImg, Margin = Thickness(3.))
             imageSourceSelection.Tag <- srcImg
@@ -74,6 +63,11 @@ let showWindow (parent: Window) (state: State.State) : bool =
             imageSourceSelection.menuZoom50X.Click.AddHandler(fun obj args -> imageSourceSelection.txtResolution.Text <- "230000")
             imageSourceSelection.menuZoom100X.Click.AddHandler(fun obj args -> imageSourceSelection.txtResolution.Text <- "460000")
 
+            imageSourceSelection.butDPICalculator.Click.AddHandler(fun obj args ->
+                match DPICalculator.showWindow win.Root with
+                | Some resolution -> imageSourceSelection.txtResolution.Text <- resolution.ToString()
+                | None -> ())
+
             imageSourceSelection.txtResolution.PreviewTextInput.AddHandler(fun obj args ->
                 let text = imageSourceSelection.txtResolution.Text + args.Text
                 args.Handled <- match parseAndValidatePPI text with Some _ -> false | None -> true)
@@ -82,12 +76,12 @@ let showWindow (parent: Window) (state: State.State) : bool =
                 let checkbox = imageSourceSelection.chkSelection
                 checkbox.IsChecked <- Nullable<bool>(not (checkbox.IsChecked.HasValue && checkbox.IsChecked.Value)))
 
-            stackSourceImagesSelection.Children.Add(imageSourceSelection) |> ignore
+            win.stackSourceImagesSelection.Children.Add(imageSourceSelection) |> ignore
 
     // Get the new parameters for each image. If an error occurs then 'None' is returned and a message box is displayed.
     // The boolean is 'true' if the image is selected (checked).
     let getInputImagesParameters () : (SourceImage * bool * Parameters) list option =
-        let sourceImagesControls = stackSourceImagesSelection.Children |> Seq.cast<Views.ImageSourceSelection>
+        let sourceImagesControls = win.stackSourceImagesSelection.Children |> Seq.cast<Views.ImageSourceSelection>
         let parameters = seq {
             for srcImgCtrl in sourceImagesControls do
                 let srcImg = srcImgCtrl.Tag :?> SourceImage
@@ -102,9 +96,9 @@ let showWindow (parent: Window) (state: State.State) : bool =
         then None
         else Some parameters
 
-    butClose.Click.AddHandler(fun obj args -> window.Root.Close())
+    win.butClose.Click.AddHandler(fun obj args -> win.Root.Close())
 
-    butStart.Click.AddHandler(fun obj args ->
+    win.butStart.Click.AddHandler(fun obj args ->
         match getInputImagesParameters () with
         | Some imagesParameters ->
             let imagesToProcess = [
@@ -117,16 +111,16 @@ let showWindow (parent: Window) (state: State.State) : bool =
             then
                 MessageBox.Show("No image selected", "Cannot start analysis", MessageBoxButton.OK, MessageBoxImage.Information) |> ignore
             else
-                stackSourceImagesSelection.IsEnabled <- false
+                win.stackSourceImagesSelection.IsEnabled <- false
                 analysisPerformed <- false
-                butStart.IsEnabled <- false
-                butClose.Content <- "Abort"
+                win.butStart.IsEnabled <- false
+                win.butClose.Content <- "Abort"
 
                 async {
                     let maybeResults =
                         ParasitemiaCore.Analysis.doMultipleAnalysis
                             imagesToProcess
-                            (Some (fun progress -> window.Root.Dispatcher.Invoke(fun () -> progressBar.Value <- float progress); not analysisCancelled))
+                            (Some (fun progress -> win.Root.Dispatcher.Invoke(fun () -> win.progress.Value <- float progress); not analysisCancelled))
 
                     lock monitor (
                         fun() ->
@@ -135,10 +129,10 @@ let showWindow (parent: Window) (state: State.State) : bool =
                                 for id, cells in results do
                                     state.SetResult (int id) cells
 
-                                window.Root.Dispatcher.Invoke(fun () ->
-                                    stackSourceImagesSelection.IsEnabled <- true
-                                    butStart.IsEnabled <- true
-                                    butClose.Content <- "Close"
+                                win.Root.Dispatcher.Invoke(fun () ->
+                                    win.stackSourceImagesSelection.IsEnabled <- true
+                                    win.butStart.IsEnabled <- true
+                                    win.butClose.Content <- "Close"
                                     updateSourceImages ())
 
                                 Logger.Log.User("All analyses terminated successfully")
@@ -148,9 +142,9 @@ let showWindow (parent: Window) (state: State.State) : bool =
                 } |> Async.Start
         | _ -> ())
 
-    window.Root.Loaded.AddHandler(fun obj args -> updateSourceImages ())
+    win.Root.Loaded.AddHandler(fun obj args -> updateSourceImages ())
 
-    window.Root.ShowDialog() |> ignore
+    win.Root.ShowDialog() |> ignore
 
     Logger.Log.RmListener(logListener)