X-Git-Url: http://git.euphorik.ch/?a=blobdiff_plain;f=Parasitemia%2FParasitemia%2FGUI%2FGUI.fs;h=8c57e20abeeb1480dc3d50f20e26d878b18bafc9;hb=81d1b86719a1ebaf649c1de4c1364603155a53e1;hp=f88bc3cc66fd7a3a87cc18634fb489994d43a537;hpb=807437584bdd3d7b7b33be8282472f81f8cce606;p=master-thesis.git diff --git a/Parasitemia/Parasitemia/GUI/GUI.fs b/Parasitemia/Parasitemia/GUI/GUI.fs index f88bc3c..8c57e20 100644 --- a/Parasitemia/Parasitemia/GUI/GUI.fs +++ b/Parasitemia/Parasitemia/GUI/GUI.fs @@ -16,7 +16,7 @@ open Emgu.CV.WPF open Config open Types -let run (defaultConfig: Config) = +let run (defaultConfig: Config) (fileToOpen: string option) = let app = new Application() let mainWindow = Views.MainWindow() let ctrl (name: string): 'a = @@ -34,7 +34,9 @@ let run (defaultConfig: Config) = let menuLoadFile: MenuItem = ctrl "menuOpen" let menuNewFile: MenuItem = ctrl "menuNew" let menuAddSourceImage: MenuItem = ctrl "menuAddSourceImage" + let menuAnalysis: MenuItem = ctrl "menuAnalysis" let menuStartAnalysis: MenuItem = ctrl "menuStartAnalysis" + let menuView: MenuItem = ctrl "menuView" let menuHightlightRBC: MenuItem = ctrl "menuHightlightRBC" let txtPatient: TextBox = ctrl "txtPatient" @@ -61,7 +63,6 @@ let run (defaultConfig: Config) = let y = rbc.center.Y - rbcHeight / 2. |> Utils.roundInt let w = Utils.roundInt rbcWidth let h = Utils.roundInt rbcHeight - //Utils.dprintfn "w: %A, h: %A, cx: %A, cy: %A, img.w: %A, img.h: %A" w h x y img.Width img.Height img.GetSubRect(System.Drawing.Rectangle(System.Drawing.Point((if x < 0 then 0 else x), (if y < 0 then 0 else y)), System.Drawing.Size((if x + w >= img.Width then img.Width - x else w), (if y + h >= img.Height then img.Height - y else h)))) @@ -115,8 +116,7 @@ let run (defaultConfig: Config) = txtImageInformation.Inlines.Add(Documents.LineBreak()) txtImageInformation.Inlines.Add(Documents.Run("Average erytrocyte diameter: ", FontWeight = FontWeights.Bold)) - txtImageInformation.Inlines.Add(Documents.Run(string (Utils.roundInt <| 2. * srcImg.rbcRadius))) - txtImageInformation.Inlines.Add(Documents.Run(" px")) + txtImageInformation.Inlines.Add(Documents.Run(srcImg.config.RBCRadius.ToString())) txtImageInformation.Inlines.Add(Documents.LineBreak()) txtImageInformation.Inlines.Add(Documents.Run("Last analysis: ", FontWeight = FontWeights.Bold)) @@ -126,6 +126,31 @@ let run (defaultConfig: Config) = let updateGlobalParasitemia () = txtGlobalParasitemia.Text <- parasitemiaText state.GlobalParasitemia + let updateViewportPreview () = + for preview in stackPreviews.Children |> Seq.cast do + let srcImg = preview.Tag :?> SourceImage + if Some srcImg = state.CurrentImage then + preview.viewport.Visibility <- Visibility.Visible + + let canvasWidth = canvasCurrentImage.ActualWidth * currentScale + let canvasHeight = canvasCurrentImage.ActualHeight * currentScale + let previewWidth = (preview.ActualWidth - preview.BorderThickness.Left - preview.BorderThickness.Right) + let previewHeight = (preview.ActualHeight - preview.BorderThickness.Top - preview.BorderThickness.Bottom) + + let marginLeft = previewWidth * (scrollViewCurrentImage.HorizontalOffset - borderCurrentImage.BorderThickness.Left) / canvasWidth - 2. + let marginRight = previewWidth * (canvasWidth - (scrollViewCurrentImage.HorizontalOffset - borderCurrentImage.BorderThickness.Right) - scrollViewCurrentImage.ViewportWidth) / canvasWidth - 2. + let marginTop = previewHeight * (scrollViewCurrentImage.VerticalOffset - borderCurrentImage.BorderThickness.Top) / canvasHeight - 2. + let marginBottom = previewHeight * (canvasHeight - (scrollViewCurrentImage.VerticalOffset - borderCurrentImage.BorderThickness.Bottom) - scrollViewCurrentImage.ViewportHeight) / canvasHeight - 2. + + preview.viewport.Margin <- + Thickness( + marginLeft, + marginTop, + marginRight, + marginBottom) + else + preview.viewport.Visibility <- Visibility.Hidden + let rec setAsInfected (rbc: RBC) (infected: bool) = state.SetAsInfected rbc infected canvasCurrentImage.Children @@ -140,23 +165,24 @@ let run (defaultConfig: Config) = updateGlobalParasitemia () and RBCFrame (rbc: RBC) : Views.RBCFrame = - let f = RBCFrameFromExisting rbc (Views.RBCFrame()) - f.menuRBCSetAsHealthy.Click.AddHandler(fun obj args -> setAsInfected (f.Tag :?> RBC) false) - f.menuRBCSetAsInfected.Click.AddHandler(fun obj args -> setAsInfected (f.Tag :?> RBC) true) - f.ContextMenuOpening.AddHandler( + let frame = RBCFrameFromExisting rbc (Views.RBCFrame()) + frame.SetValue(Panel.ZIndexProperty, Int32.MaxValue - rbc.num) // To be sure the + frame.menuRBCSetAsHealthy.Click.AddHandler(fun obj args -> setAsInfected (frame.Tag :?> RBC) false) + frame.menuRBCSetAsInfected.Click.AddHandler(fun obj args -> setAsInfected (frame.Tag :?> RBC) true) + frame.ContextMenuOpening.AddHandler( fun obj args -> - if (f.Tag :?> RBC).infected + if (frame.Tag :?> RBC).infected then - f.menuRBCSetAsHealthy.Visibility <- Visibility.Visible - f.menuRBCSetAsInfected.Visibility <- Visibility.Collapsed + frame.menuRBCSetAsHealthy.Visibility <- Visibility.Visible + frame.menuRBCSetAsInfected.Visibility <- Visibility.Collapsed else - f.menuRBCSetAsHealthy.Visibility <- Visibility.Collapsed - f.menuRBCSetAsInfected.Visibility <- Visibility.Visible) + frame.menuRBCSetAsHealthy.Visibility <- Visibility.Collapsed + frame.menuRBCSetAsInfected.Visibility <- Visibility.Visible) - f.ContextMenuClosing.AddHandler(fun obj args -> if not f.IsMouseOver then highlightRBCFrame f false ) - f.MouseEnter.AddHandler(fun obj args -> highlightRBCFrame f true) - f.MouseLeave.AddHandler(fun obj args -> if not f.grid.ContextMenu.IsOpen then highlightRBCFrame f false) - f + frame.ContextMenuClosing.AddHandler(fun obj args -> if not frame.IsMouseOver then highlightRBCFrame frame false ) + frame.MouseEnter.AddHandler(fun obj args -> highlightRBCFrame frame true) + frame.MouseLeave.AddHandler(fun obj args -> if not frame.grid.ContextMenu.IsOpen then highlightRBCFrame frame false) + frame and updateRBCFramesPreview () = match state.CurrentImage with @@ -182,6 +208,8 @@ let run (defaultConfig: Config) = stackRBC.Children.RemoveRange(currentPreview, stackRBC.Children.Count - currentPreview) | _ -> () + updateViewportPreview () + let updateRBCFramesCurrent () = match state.CurrentImage with | Some srcImg -> @@ -193,6 +221,7 @@ let run (defaultConfig: Config) = RBCFrameFromExisting rbc (canvasCurrentImage.Children.[currentCanvas] :?> Views.RBCFrame) else let f = RBCFrame rbc + f.Root.Opacity <- 0.7 canvasCurrentImage.Children.Add(f) |> ignore f @@ -251,31 +280,6 @@ let run (defaultConfig: Config) = state.CurrentImage <- Some srcImg updateCurrentImage () - let updateViewportPreview () = - for preview in stackPreviews.Children |> Seq.cast do - let srcImg = preview.Tag :?> SourceImage - if Some srcImg = state.CurrentImage then - preview.viewport.Visibility <- Visibility.Visible - - let canvasWidth = canvasCurrentImage.ActualWidth * currentScale - let canvasHeight = canvasCurrentImage.ActualHeight * currentScale - let previewWidth = (preview.ActualWidth - preview.BorderThickness.Left - preview.BorderThickness.Right) - let previewHeight = (preview.ActualHeight - preview.BorderThickness.Top - preview.BorderThickness.Bottom) - - let marginLeft = previewWidth * (scrollViewCurrentImage.HorizontalOffset - borderCurrentImage.BorderThickness.Left) / canvasWidth - 2. - let marginRight = previewWidth * (canvasWidth - (scrollViewCurrentImage.HorizontalOffset - borderCurrentImage.BorderThickness.Right) - scrollViewCurrentImage.ViewportWidth) / canvasWidth - 2. - let marginTop = previewHeight * (scrollViewCurrentImage.VerticalOffset - borderCurrentImage.BorderThickness.Top) / canvasHeight - 2. - let marginBottom = previewHeight * (canvasHeight - (scrollViewCurrentImage.VerticalOffset - borderCurrentImage.BorderThickness.Bottom) - scrollViewCurrentImage.ViewportHeight) / canvasHeight - 2. - - preview.viewport.Margin <- - Thickness( - marginLeft, - marginTop, - marginRight, - marginBottom) - else - preview.viewport.Visibility <- Visibility.Hidden - let addPreview (srcImg: SourceImage) = let imgCtrl = Views.ImageSourcePreview(Margin = Thickness(3.)) @@ -295,7 +299,31 @@ let run (defaultConfig: Config) = let height = srcImg.img.Height * width / srcImg.img.Width imgCtrl.imagePreview.Source <- BitmapSourceConvert.ToBitmapSource(srcImg.img.Resize(width, height, Emgu.CV.CvEnum.Inter.Cubic)) stackPreviews.Children.Add(imgCtrl) |> ignore - imgCtrl.MouseLeftButtonUp.AddHandler(fun obj args -> setCurrentImage (state.SourceImages |> Seq.find (fun srcImg -> (srcImg :> Object) = imgCtrl.Tag))) + + // Zoom to a mouse position into the control 'imgCtrl'. + let zoomTo (mousePos: Point) = + let canvasW = canvasCurrentImage.ActualWidth * currentScale + let canvasH = canvasCurrentImage.ActualHeight * currentScale + let centerX = (mousePos.X - imgCtrl.BorderThickness.Left) / (imgCtrl.ActualWidth - imgCtrl.BorderThickness.Left) * canvasW + let centerY = (mousePos.Y - imgCtrl.BorderThickness.Top) / (imgCtrl.ActualHeight - imgCtrl.BorderThickness.Top) * canvasH + scrollViewCurrentImage.ScrollToHorizontalOffset(centerX - scrollViewCurrentImage.ViewportWidth / 2. + borderCurrentImage.BorderThickness.Left) + scrollViewCurrentImage.ScrollToVerticalOffset(centerY - scrollViewCurrentImage.ViewportHeight / 2. + borderCurrentImage.BorderThickness.Top) + + imgCtrl.MouseLeftButtonDown.AddHandler(fun obj args -> + setCurrentImage (state.SourceImages |> Seq.find (fun srcImg -> (srcImg :> Object) = imgCtrl.Tag)) + imgCtrl.UpdateLayout() + zoomTo (args.GetPosition(imgCtrl)) + imgCtrl.CaptureMouse() |> ignore) + + imgCtrl.MouseMove.AddHandler(fun obj args -> + if imgCtrl.IsMouseCaptured + then + zoomTo (args.GetPosition(imgCtrl))) + + imgCtrl.MouseLeftButtonUp.AddHandler(fun obj args -> + if imgCtrl.IsMouseCaptured + then + imgCtrl.ReleaseMouseCapture()) let updatePreviews () = stackPreviews.Children.Clear () @@ -308,7 +336,13 @@ let run (defaultConfig: Config) = updatePreviews () updateGlobalParasitemia () - txtPatient.TextChanged.AddHandler(fun obj args -> state.PatientID <- txtPatient.Text) + let loadFile (filepath: string) = + askSaveCurrent () + state.FilePath <- filepath + state.Load() + updateGUI () + + txtPatient.LostFocus.AddHandler(fun obj args -> state.PatientID <- txtPatient.Text) menuExit.Click.AddHandler(fun obj args -> askSaveCurrent () @@ -321,11 +355,7 @@ let run (defaultConfig: Config) = let dialog = OpenFileDialog(Filter = PiaZ.filter) let res = dialog.ShowDialog() if res.HasValue && res.Value - then - askSaveCurrent () - state.FilePath <- dialog.FileName - state.Load() - updateGUI ()) + then loadFile dialog.FileName) menuNewFile.Click.AddHandler(fun obj args -> askSaveCurrent () @@ -337,15 +367,18 @@ let run (defaultConfig: Config) = let res = dialog.ShowDialog() if res.HasValue && res.Value then - let srcImg = state.AddSourceImage(dialog.FileName) + let srcImg = state.AddSourceImage dialog.FileName defaultConfig addPreview srcImg updateGlobalParasitemia () if state.SourceImages.Count() = 1 then updateCurrentImage ()) + + menuAnalysis.SubmenuOpened.AddHandler(fun obj args -> menuStartAnalysis.IsEnabled <- state.SourceImages.Count() > 0) + menuStartAnalysis.Click.AddHandler(fun obj args -> - if Analysis.showWindow mainWindow.Root state defaultConfig + if Analysis.showWindow mainWindow.Root state then updateGlobalParasitemia () updateCurrentImage ()) @@ -441,4 +474,9 @@ let run (defaultConfig: Config) = scrollViewCurrentImage.ScrollChanged.AddHandler(fun obj args -> updateViewportPreview ()) mainWindow.Root.Show() + + match fileToOpen with + | Some filepath -> loadFile filepath + | None -> () + app.Run() \ No newline at end of file