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
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
imageSourceSelection.menuZoom50X.Click.AddHandler(fun obj args -> imageSourceSelection.txtResolution.Text <- "230000")
imageSourceSelection.menuZoom100X.Click.AddHandler(fun obj args -> imageSourceSelection.txtResolution.Text <- "460000")
+ imageSourceSelection.butPPICalculator.Click.AddHandler(fun obj args ->
+ match PPICalculator.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)
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
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 = [
then
MessageBox.Show("No image selected", "Cannot start analysis", MessageBoxButton.OK, MessageBoxImage.Information) |> ignore
else
+ win.stackSourceImagesSelection.IsEnabled <- false
analysisPerformed <- false
- butStart.IsEnabled <- false
- butClose.Content <- "Abort"
+ win.butStart.IsEnabled <- false
+ win.butClose.Content <- "Abort"
+
async {
- let results =
+ let maybeResults =
ParasitemiaCore.Analysis.doMultipleAnalysis
imagesToProcess
- (Some (fun progress -> window.Root.Dispatcher.Invoke(fun () -> progressBar.Value <- float progress)))
+ (Some (fun progress -> win.Root.Dispatcher.Invoke(fun () -> win.progress.Value <- float progress); not analysisCancelled))
lock monitor (
fun() ->
- if not analysisCancelled
- then
+ match maybeResults with
+ | Some results ->
for id, cells in results do
state.SetResult (int id) cells
-
- window.Root.Dispatcher.Invoke(fun () ->
- butStart.IsEnabled <- true
- butClose.Content <- "Close"
- updateSourceImages ())
-
Logger.Log.User("All analyses terminated successfully")
atLeastOneAnalysisPerformed <- true
- analysisPerformed <- true)
+ analysisPerformed <- true
+ | None ->
+ Logger.Log.User("Analysis aborted")
+
+ win.Root.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
| _ -> ())
- 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)
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)