open Types
-let showWindow (parent: Window) (state: State.State) : bool =
+let showWindow (parent : Window) (state : State.State) : bool =
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.
+ win.Owner <- parent
+ win.Left <- (if parent.WindowState = WindowState.Maximized then 0. else parent.Left) + parent.ActualWidth / 2. - win.Width / 2.
+ win.Top <- (if parent.WindowState = WindowState.Maximized then 0. else parent.Top) + parent.ActualHeight / 2. - win.Height / 2.
let logListener =
- { new Logger.IListener with
- member this.NewEntry severity mess =
- win.Root.Dispatcher.Invoke(fun () ->
- win.textLog.Inlines.Add(Documents.Run(mess))
- win.textLog.Inlines.Add(Documents.LineBreak())
- win.scrollLog.ScrollToBottom()) }
+ {
+ new Logger.IListener with
+ member this.NewEntry severity _header mess =
+ win.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 parseAndValidatePPI (input : string) : float option =
match Double.TryParse(input) with
| true, value when value >= minPPI && value <= maxPPI -> Some value
| _ -> None
imageSourceSelection.lblDateLastAnalysis.Content <- if srcImg.dateLastAnalysis.Ticks = 0L then "<Never>" else srcImg.dateLastAnalysis.ToString()
imageSourceSelection.txtResolution.Text <- if srcImg.dateLastAnalysis.Ticks = 0L then "" else srcImg.config.Parameters.resolution.ToString()
- 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
+ for ppi in Utils.predefinedPPI do
+ let menu = MenuItem()
+ menu.Header <- ppi.ToString()
+ menu.Click.AddHandler(fun obj args -> imageSourceSelection.txtResolution.Text <- ppi.ppi.ToString())
+ imageSourceSelection.predefinedValuesMenu.Items.Add(menu) |> ignore
+
+ imageSourceSelection.butPPICalculator.Click.AddHandler(fun obj args ->
+ match PPICalculator.showWindow win with
| Some resolution -> imageSourceSelection.txtResolution.Text <- resolution.ToString()
| None -> ())
// The boolean is 'true' if the image is selected (checked).
let getInputImagesParameters () : (SourceImage * bool * Parameters) list option =
let sourceImagesControls = win.stackSourceImagesSelection.Children |> Seq.cast<Views.ImageSourceSelection>
- let parameters = seq {
- for srcImgCtrl in sourceImagesControls do
- let srcImg = srcImgCtrl.Tag :?> SourceImage
- let isChecked = srcImgCtrl.chkSelection.IsChecked
- match parseAndValidatePPI srcImgCtrl.txtResolution.Text with
- | Some resolution ->
- yield Some (srcImg, isChecked.HasValue && isChecked.Value, { srcImg.config.Parameters with resolution = resolution * 1.<ppi> })
- | None ->
- MessageBox.Show(sprintf "No resolution defined for the image number %d" srcImg.num, "No resolution defined", MessageBoxButton.OK, MessageBoxImage.Information) |> ignore
- yield None } |> Seq.takeWhile (fun e -> e.IsSome) |> Seq.map (fun e -> e.Value) |> List.ofSeq
- if parameters.Count() <> sourceImagesControls.Count()
- then None
- else Some parameters
-
- win.butClose.Click.AddHandler(fun obj args -> win.Root.Close())
+ let parameters =
+ seq {
+ for srcImgCtrl in sourceImagesControls do
+ let srcImg = srcImgCtrl.Tag :?> SourceImage
+ let isChecked = srcImgCtrl.chkSelection.IsChecked
+ match parseAndValidatePPI srcImgCtrl.txtResolution.Text with
+ | Some resolution ->
+ yield Some (srcImg, isChecked.HasValue && isChecked.Value, { srcImg.config.Parameters with resolution = resolution * 1.<ppi> })
+ | None ->
+ MessageBox.Show(sprintf "No resolution defined for the image number %d" srcImg.num, "No resolution defined", MessageBoxButton.OK, MessageBoxImage.Information) |> ignore
+ yield None
+ } |> Seq.takeWhile (fun e -> e.IsSome) |> Seq.map (fun e -> e.Value) |> List.ofSeq
+
+ if parameters.Count() <> sourceImagesControls.Count() then
+ None
+ else
+ Some parameters
+
+ win.butClose.Click.AddHandler(fun obj args -> win.Close())
win.butStart.Click.AddHandler(fun obj args ->
match getInputImagesParameters () with
| Some imagesParameters ->
- let imagesToProcess = [
- for srcImg, selected, parameters in imagesParameters do
- srcImg.config.Parameters <- parameters // Save parameters.
- if selected
- then yield srcImg.num.ToString(), srcImg.config, srcImg.img ]
-
- if imagesToProcess.IsEmpty
- then
+ let imagesToProcess =
+ [
+ for srcImg, selected, parameters in imagesParameters do
+ srcImg.config.Parameters <- parameters // Save parameters.
+ if selected then
+ yield srcImg.num.ToString(), srcImg.config, srcImg.img
+ ]
+
+ if imagesToProcess.IsEmpty then
MessageBox.Show("No image selected", "Cannot start analysis", MessageBoxButton.OK, MessageBoxImage.Information) |> ignore
else
win.stackSourceImagesSelection.IsEnabled <- false
let maybeResults =
ParasitemiaCore.Analysis.doMultipleAnalysis
imagesToProcess
- (Some (fun progress -> win.Root.Dispatcher.Invoke(fun () -> win.progress.Value <- float progress); not analysisCancelled))
+ (Some (fun progress -> win.Dispatcher.Invoke(fun () -> win.progress.Value <- float progress); not analysisCancelled))
lock monitor (
fun() ->
| Some results ->
for id, cells in results do
state.SetResult (int id) cells
-
- 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")
+ Logger.Log.Info "All analyses terminated successfully"
atLeastOneAnalysisPerformed <- true
analysisPerformed <- true
- | None -> ())
+ | None ->
+ Logger.Log.Info "Analysis aborted"
+
+ win.Dispatcher.Invoke(fun () ->
+ win.progress.Value <- if maybeResults.IsSome then 100. else 0.
+ win.stackSourceImagesSelection.IsEnabled <- true
+ win.butStart.IsEnabled <- true
+ win.butClose.Content <- "Close"
+ updateSourceImages ()
+ )
+ )
} |> Async.Start
- | _ -> ())
+ | _ -> ()
+ )
- win.Root.Loaded.AddHandler(fun obj args -> updateSourceImages ())
+ win.Loaded.AddHandler(fun obj args -> updateSourceImages ())
- win.Root.ShowDialog() |> ignore
+ win.ShowDialog() |> ignore
Logger.Log.RmListener(logListener)
- lock monitor (fun () ->
- if not analysisPerformed
- then
+ lock monitor (
+ fun () ->
+ if not analysisPerformed then
+ // To cancel the current analysis if one is running on the next call to the progress function.
analysisCancelled <- true
- atLeastOneAnalysisPerformed)
+ atLeastOneAnalysisPerformed
+ )