X-Git-Url: http://git.euphorik.ch/?p=master-thesis.git;a=blobdiff_plain;f=Parasitemia%2FParasitemiaUI%2FGUI.fs;h=d749479a037cec8f8aee3ee81235a8902348109c;hp=2ff3116245197b634b369b26065563011e63f3fd;hb=c4a76a01f62568c6353396ff85551a3151fc5236;hpb=94fbffc758bf0299b077e344ebcbecca408ae564 diff --git a/Parasitemia/ParasitemiaUI/GUI.fs b/Parasitemia/ParasitemiaUI/GUI.fs index 2ff3116..d749479 100644 --- a/Parasitemia/ParasitemiaUI/GUI.fs +++ b/Parasitemia/ParasitemiaUI/GUI.fs @@ -27,12 +27,14 @@ let run (defaultConfig: Config) (fileToOpen: string option) = let state = State.State() let mutable currentScale = 1. let mutable displayHealthy = false + let warningBelowNumberOfRBC = 1000 let menuExit: MenuItem = ctrl "menuExit" let menuSaveFile: MenuItem = ctrl "menuSave" let menuSaveAsFile: MenuItem = ctrl "menuSaveAs" let menuLoadFile: MenuItem = ctrl "menuOpen" let menuNewFile: MenuItem = ctrl "menuNew" + let menuExportResults: MenuItem = ctrl "menuExportResults" let menuAddSourceImage: MenuItem = ctrl "menuAddSourceImage" let menuAnalysis: MenuItem = ctrl "menuAnalysis" let menuStartAnalysis: MenuItem = ctrl "menuStartAnalysis" @@ -44,15 +46,18 @@ let run (defaultConfig: Config) (fileToOpen: string option) = let txtMessageStatus: TextBlock = ctrl "txtMessageStatus" let txtPatient: TextBox = ctrl "txtPatient" - let txtGlobalParasitemia: TextBox = ctrl "txtGlobalParasitemia" + let txtGlobalParasitemia: TextBlock = ctrl "txtGlobalParasitemia" let stackPreviews: StackPanel = ctrl "stackPreviews" let scrollViewCurrentImage: ScrollViewer = ctrl "scrollViewCurrentImage" let borderCurrentImage: Border = ctrl "borderCurrentImage" let canvasCurrentImage: Canvas = ctrl "canvasCurrentImage" + + let gridImageInformation: Grid = ctrl "gridImageInformation" let txtImageInformation1: TextBlock = ctrl "txtImageInformation1" let txtImageInformation2: TextBlock = ctrl "txtImageInformation2" + let txtImageName: TextBox = ctrl "txtImageName" let scrollRBC: ScrollViewer = ctrl "scrollRBC" let stackRBC: StackPanel = ctrl "stackRBC" @@ -117,21 +122,24 @@ let run (defaultConfig: Config) (fileToOpen: string option) = scrollViewCurrentImage.ScrollToHorizontalOffset(rbc.center.X * currentScale - scrollViewCurrentImage.ViewportWidth / 2. + borderCurrentImage.BorderThickness.Left) scrollViewCurrentImage.ScrollToVerticalOffset(rbc.center.Y * currentScale - scrollViewCurrentImage.ViewportHeight / 2. + borderCurrentImage.BorderThickness.Top) - let percentText (nbTotal: int, nb: int) : string = - if nbTotal = 0 - then - "" - else - let percent = 100. * (float nb) / (float nbTotal) - sprintf "%.1f %% (%d / %d)" percent nb nbTotal + + let txtImageName_TextChanged = + TextChangedEventHandler(fun obj args -> state.CurrentImage |> Option.iter(fun srcImg -> state.SetName srcImg txtImageName.Text)) let updateCurrentImageInformation () = + txtImageName.TextChanged.RemoveHandler(txtImageName_TextChanged) txtImageInformation1.Inlines.Clear() txtImageInformation2.Inlines.Clear() + txtImageName.Text <- "" match state.CurrentImage with | Some srcImg -> - let parasitemiaStr = percentText (state.ImageParasitemia srcImg) + gridImageInformation.Visibility <- Visibility.Visible + txtImageName.Text <- srcImg.name + txtImageName.TextChanged.AddHandler(txtImageName_TextChanged) + + // The left part. + let parasitemiaStr = Utils.percentText (state.ImageParasitemia srcImg) txtImageInformation1.Inlines.Add(Documents.Run("Parasitemia: ", FontWeight = FontWeights.Bold)) txtImageInformation1.Inlines.Add(parasitemiaStr) txtImageInformation1.Inlines.Add(Documents.LineBreak()) @@ -139,17 +147,27 @@ let run (defaultConfig: Config) (fileToOpen: string option) = txtImageInformation1.Inlines.Add(Documents.Run("Last analysis: ", FontWeight = FontWeights.Bold)) txtImageInformation1.Inlines.Add(Documents.Run(if srcImg.dateLastAnalysis.Ticks = 0L then "" else srcImg.dateLastAnalysis.ToLocalTime().ToString())) - let alteredStr = percentText (state.ImageNbAltered srcImg) - txtImageInformation2.Inlines.Add(Documents.Run("Number of erytrocytes manually altered: ", FontWeight = FontWeights.Bold)) - txtImageInformation2.Inlines.Add(Documents.Run(alteredStr)) + // The right part part. + txtImageInformation2.Inlines.Add(Documents.Run("Added infected erythrocyte: ", FontWeight = FontWeights.Bold)) + txtImageInformation2.Inlines.Add(Documents.Run((state.ImageNbManuallyChangedRBCStr srcImg true) + " " + (state.ImageManuallyChangedRBCStr srcImg true))) txtImageInformation2.Inlines.Add(Documents.LineBreak()) + txtImageInformation2.Inlines.Add(Documents.Run("Removed infected erythrocyte: ", FontWeight = FontWeights.Bold)) + txtImageInformation2.Inlines.Add(Documents.Run((state.ImageNbManuallyChangedRBCStr srcImg false) + " " + (state.ImageManuallyChangedRBCStr srcImg false))) - txtImageInformation2.Inlines.Add(Documents.Run("Average erytrocyte diameter: ", FontWeight = FontWeights.Bold)) - txtImageInformation2.Inlines.Add(Documents.Run(srcImg.config.RBCRadius.ToString())) - | _ -> () + | _ -> + gridImageInformation.Visibility <- Visibility.Hidden let updateGlobalParasitemia () = - txtGlobalParasitemia.Text <- percentText state.GlobalParasitemia + txtGlobalParasitemia.Inlines.Clear() + let total, infected = state.GlobalParasitemia + txtGlobalParasitemia.Inlines.Add(Documents.Run(Utils.percentText (total, infected), FontWeight = FontWeights.Bold)) + if total > 0 && total < warningBelowNumberOfRBC + then + txtGlobalParasitemia.Inlines.Add( + Documents.Run( + sprintf " Warning: the number of erytrocytes should be above %d" warningBelowNumberOfRBC, + FontWeight = FontWeights.Bold, + Foreground = Brushes.Red)) let updateViewportPreview () = for preview in stackPreviews.Children |> Seq.cast do @@ -425,6 +443,26 @@ let run (defaultConfig: Config) (fileToOpen: string option) = state.Reset() updateGUI() + let exportResults () = + let extension = ".txt" + let dialog = SaveFileDialog(AddExtension = true, DefaultExt = extension) + + if state.FilePath <> "" + then + dialog.FileName <- Path.GetFileNameWithoutExtension(state.FilePath) + extension + elif state.PatientID <> "" + then + dialog.FileName <- state.PatientID + extension + + let res = dialog.ShowDialog() + if res.HasValue && res.Value then + try + Export.exportResults state dialog.FileName + with + | :? IOException as ex -> + Log.Error(ex.ToString()) + MessageBox.Show(sprintf "The results cannot be exported in '%s'" state.FilePath, "Error exporting the files", MessageBoxButton.OK, MessageBoxImage.Error) |> ignore + txtPatient.TextChanged.AddHandler(fun obj args -> state.PatientID <- txtPatient.Text) menuExit.Click.AddHandler(fun obj args -> mainWindow.Root.Close()) @@ -432,6 +470,7 @@ let run (defaultConfig: Config) (fileToOpen: string option) = menuSaveAsFile.Click.AddHandler(fun obj args -> saveCurrentDocumentAsNewFile ()) menuLoadFile.Click.AddHandler(fun obj args -> askLoadFile ()) menuNewFile.Click.AddHandler(fun obj args -> newFile ()) + menuExportResults.Click.AddHandler(fun obj args -> exportResults ()) menuAddSourceImage.Click.AddHandler(fun obj args -> let dialog = OpenFileDialog(Filter = "Image Files|*.png;*.jpg;*.tif;*.tiff", Multiselect = true) @@ -579,10 +618,17 @@ let run (defaultConfig: Config) (fileToOpen: string option) = FSharp.ViewModule.FunCommand((fun obj -> newFile ()), (fun obj -> true)), Input.KeyGesture(Input.Key.N, Input.ModifierKeys.Control))) |> ignore + // Export results. + mainWindow.Root.InputBindings.Add( + Input.KeyBinding( + FSharp.ViewModule.FunCommand((fun obj -> exportResults ()), (fun obj -> true)), + Input.KeyGesture(Input.Key.E, Input.ModifierKeys.Control))) |> ignore + // Viewport preview. scrollViewCurrentImage.ScrollChanged.AddHandler(fun obj args -> updateViewportPreview ()) updateDocumentStatus () + gridImageInformation.Visibility <- Visibility.Hidden mainWindow.Root.Show()