From 3990946e49fe34e9adcf0e04b0418cd16676e6fe Mon Sep 17 00:00:00 2001 From: Greg Burri Date: Wed, 20 Jan 2016 10:40:15 +0100 Subject: [PATCH] Force the user to input a DPI value for new image. --- Parasitemia/ParasitemiaUI/Analysis.fs | 115 ++++++++++-------- .../ParasitemiaUI/XAML/AnalysisWindow.xaml | 2 +- .../XAML/ImageSourceSelection.xaml | 8 +- 3 files changed, 69 insertions(+), 56 deletions(-) diff --git a/Parasitemia/ParasitemiaUI/Analysis.fs b/Parasitemia/ParasitemiaUI/Analysis.fs index 40fd303..24f9adb 100644 --- a/Parasitemia/ParasitemiaUI/Analysis.fs +++ b/Parasitemia/ParasitemiaUI/Analysis.fs @@ -29,7 +29,7 @@ let showWindow (parent: Window) (state: State.State) : bool = let butClose: Button = ctrl "butClose" let butStart: Button = ctrl "butStart" - let stackImagesSourceSelection: StackPanel = ctrl "stackImagesSourceSelection" + let stackSourceImagesSelection: StackPanel = ctrl "stackSourceImagesSelection" let progressBar: ProgressBar = ctrl "progress" let textLog: TextBlock = ctrl "textLog" let scrollLog: ScrollViewer = ctrl "scrollLog" @@ -58,15 +58,11 @@ let showWindow (parent: Window) (state: State.State) : bool = let mutable analysisCancelled = false let updateSourceImages () = - stackImagesSourceSelection.Children.Clear() - let width = int stackImagesSourceSelection.ActualWidth + stackSourceImagesSelection.Children.Clear() + let width = int stackSourceImagesSelection.ActualWidth for srcImg in state.SourceImages do let imageSourceSelection = Views.ImageSourceSelection(Tag = srcImg, Margin = Thickness(3.)) - - let updateResolution () = - match parseAndValidatePPI imageSourceSelection.txtResolution.Text with - | Some resolution -> srcImg.config.Parameters <- { srcImg.config.Parameters with resolution = resolution * 1. } - | None -> () + imageSourceSelection.Tag <- srcImg imageSourceSelection.txtImageNumber.Text <- srcImg.num.ToString() let height = srcImg.img.Height * width / srcImg.img.Width @@ -74,9 +70,9 @@ let showWindow (parent: Window) (state: State.State) : bool = imageSourceSelection.chkSelection.IsChecked <- Nullable(srcImg.dateLastAnalysis.Ticks = 0L) imageSourceSelection.lblDateLastAnalysis.Content <- if srcImg.dateLastAnalysis.Ticks = 0L then "" else srcImg.dateLastAnalysis.ToString() - imageSourceSelection.txtResolution.Text <- srcImg.config.Parameters.resolution.ToString() - imageSourceSelection.menuZoom50X.Click.AddHandler(fun obj args -> imageSourceSelection.txtResolution.Text <- "230000"; updateResolution ()) - imageSourceSelection.menuZoom100X.Click.AddHandler(fun obj args -> imageSourceSelection.txtResolution.Text <- "460000"; updateResolution ()) + 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.txtResolution.PreviewTextInput.AddHandler(fun obj args -> let text = imageSourceSelection.txtResolution.Text + args.Text @@ -86,50 +82,67 @@ let showWindow (parent: Window) (state: State.State) : bool = let checkbox = imageSourceSelection.chkSelection checkbox.IsChecked <- Nullable(not (checkbox.IsChecked.HasValue && checkbox.IsChecked.Value))) - imageSourceSelection.txtResolution.LostFocus.AddHandler(fun obj args -> updateResolution ()) - - stackImagesSourceSelection.Children.Add(imageSourceSelection) |> ignore + 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 + 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. }) + | 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 butClose.Click.AddHandler(fun obj args -> window.Root.Close()) butStart.Click.AddHandler(fun obj args -> - let imagesToProcess = [ - for imageSelection in stackImagesSourceSelection.Children |> Seq.cast do - let chk = imageSelection.chkSelection.IsChecked - if chk.HasValue && chk.Value - then - let srcImg = imageSelection.Tag :?> SourceImage - 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 - analysisPerformed <- false - butStart.IsEnabled <- false - butClose.Content <- "Abort" - async { - let results = - ParasitemiaCore.Analysis.doMultipleAnalysis - imagesToProcess - (Some (fun progress -> window.Root.Dispatcher.Invoke(fun () -> progressBar.Value <- float progress))) - - lock monitor ( - fun() -> - if not analysisCancelled - then - 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) - } |> Async.Start) + 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 + MessageBox.Show("No image selected", "Cannot start analysis", MessageBoxButton.OK, MessageBoxImage.Information) |> ignore + else + analysisPerformed <- false + butStart.IsEnabled <- false + butClose.Content <- "Abort" + async { + let results = + ParasitemiaCore.Analysis.doMultipleAnalysis + imagesToProcess + (Some (fun progress -> window.Root.Dispatcher.Invoke(fun () -> progressBar.Value <- float progress))) + + lock monitor ( + fun() -> + if not analysisCancelled + then + 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) + } |> Async.Start + | _ -> ()) window.Root.Loaded.AddHandler(fun obj args -> updateSourceImages ()) diff --git a/Parasitemia/ParasitemiaUI/XAML/AnalysisWindow.xaml b/Parasitemia/ParasitemiaUI/XAML/AnalysisWindow.xaml index 599d581..3f3686e 100644 --- a/Parasitemia/ParasitemiaUI/XAML/AnalysisWindow.xaml +++ b/Parasitemia/ParasitemiaUI/XAML/AnalysisWindow.xaml @@ -12,7 +12,7 @@ - + diff --git a/Parasitemia/ParasitemiaUI/XAML/ImageSourceSelection.xaml b/Parasitemia/ParasitemiaUI/XAML/ImageSourceSelection.xaml index 62a97f5..7958818 100644 --- a/Parasitemia/ParasitemiaUI/XAML/ImageSourceSelection.xaml +++ b/Parasitemia/ParasitemiaUI/XAML/ImageSourceSelection.xaml @@ -4,7 +4,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:fsxaml="clr-namespace:FsXaml;assembly=FsXaml.Wpf" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - mc:Ignorable="d" d:DesignWidth="349.723" d:DesignHeight="118.911" + mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="120" > @@ -41,11 +41,11 @@ -