X-Git-Url: http://git.euphorik.ch/?p=master-thesis.git;a=blobdiff_plain;f=Parasitemia%2FParasitemiaUI%2FGUI.fs;fp=Parasitemia%2FParasitemiaUI%2FGUI.fs;h=8438b4b196095e1613bddb8b2cf5238c259c0080;hp=3746461e567527b6299573bb6f9fe5bb0da41566;hb=23466ba92c5595f6c0b9f97c86a221a4e5ffebe9;hpb=e588f9c954a54cb259b2c1f6f9e8d9dbd4639269 diff --git a/Parasitemia/ParasitemiaUI/GUI.fs b/Parasitemia/ParasitemiaUI/GUI.fs index 3746461..8438b4b 100644 --- a/Parasitemia/ParasitemiaUI/GUI.fs +++ b/Parasitemia/ParasitemiaUI/GUI.fs @@ -21,52 +21,16 @@ open Types let run (defaultConfig: Config) (fileToOpen: string option) = let app = new Application() - let mainWindow = Views.MainWindow() - let ctrl (name: string): 'a = mainWindow.Root.FindName(name) :?> 'a + let win = Views.MainWindow() let state = State.State(defaultConfig) 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" - let menuView: MenuItem = ctrl "menuView" - let menuHightlightRBC: MenuItem = ctrl "menuHightlightRBC" - let menuAbout: MenuItem = ctrl "menuAbout" - - let txtDocumentStatus: TextBlock = ctrl "txtDocumentStatus" - let txtMessageStatus: TextBlock = ctrl "txtMessageStatus" - - let txtPatient: TextBox = ctrl "txtPatient" - 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" - - let imgLogos: Border = ctrl "imgLogos" - // Initializations. - let canvasCurrentImageColor = canvasCurrentImage.Background - menuHightlightRBC.IsChecked <- displayHealthy + let canvasCurrentImageColor = win.canvasCurrentImage.Background + win.menuHightlightRBC.IsChecked <- displayHealthy // Utils. let extractRBCPreview (img: Emgu.CV.Image) (rbc: RBC) : Emgu.CV.Image = @@ -98,13 +62,13 @@ let run (defaultConfig: Config) (fileToOpen: string option) = frame let updateDocumentStatus () = - txtDocumentStatus.Text <- if state.FilePath = "" then "" else state.FilePath + win.txtDocumentStatus.Text <- if state.FilePath = "" then "" else state.FilePath let statusMessageTimer = Threading.DispatcherTimer() - statusMessageTimer.Tick.AddHandler(fun obj args -> statusMessageTimer.Stop(); txtMessageStatus.Text <- "") + statusMessageTimer.Tick.AddHandler(fun obj args -> statusMessageTimer.Stop(); win.txtMessageStatus.Text <- "") statusMessageTimer.Interval <- TimeSpan(0, 0, 2) let displayStatusMessage (message: string) = - txtMessageStatus.Text <- message + win.txtMessageStatus.Text <- message statusMessageTimer.Stop() statusMessageTimer.Start() @@ -119,71 +83,71 @@ let run (defaultConfig: Config) (fileToOpen: string option) = if not rbc.infected && not rbc.setManually && not displayHealthy then frame.Opacity <- 0. let zoomToRBC (rbc: RBC) = - scrollViewCurrentImage.ScrollToHorizontalOffset(rbc.center.X * currentScale - scrollViewCurrentImage.ViewportWidth / 2. + borderCurrentImage.BorderThickness.Left) - scrollViewCurrentImage.ScrollToVerticalOffset(rbc.center.Y * currentScale - scrollViewCurrentImage.ViewportHeight / 2. + borderCurrentImage.BorderThickness.Top) + win.scrollViewCurrentImage.ScrollToHorizontalOffset(rbc.center.X * currentScale - win.scrollViewCurrentImage.ViewportWidth / 2. + win.borderCurrentImage.BorderThickness.Left) + win.scrollViewCurrentImage.ScrollToVerticalOffset(rbc.center.Y * currentScale - win.scrollViewCurrentImage.ViewportHeight / 2. + win.borderCurrentImage.BorderThickness.Top) let txtImageName_TextChanged = - TextChangedEventHandler(fun obj args -> state.CurrentImage |> Option.iter(fun srcImg -> state.SetName srcImg txtImageName.Text)) + TextChangedEventHandler(fun obj args -> state.CurrentImage |> Option.iter(fun srcImg -> state.SetName srcImg win.txtImageName.Text)) let updateCurrentImageInformation () = - txtImageName.TextChanged.RemoveHandler(txtImageName_TextChanged) - txtImageInformation1.Inlines.Clear() - txtImageInformation2.Inlines.Clear() - txtImageName.Text <- "" + win.txtImageName.TextChanged.RemoveHandler(txtImageName_TextChanged) + win.txtImageInformation1.Inlines.Clear() + win.txtImageInformation2.Inlines.Clear() + win.txtImageName.Text <- "" match state.CurrentImage with | Some srcImg -> - gridImageInformation.Visibility <- Visibility.Visible - txtImageName.Text <- srcImg.name - txtImageName.TextChanged.AddHandler(txtImageName_TextChanged) + win.gridImageInformation.Visibility <- Visibility.Visible + win.txtImageName.Text <- srcImg.name + win.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()) + win.txtImageInformation1.Inlines.Add(Documents.Run("Parasitemia: ", FontWeight = FontWeights.Bold)) + win.txtImageInformation1.Inlines.Add(parasitemiaStr) + win.txtImageInformation1.Inlines.Add(Documents.LineBreak()) - 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())) + win.txtImageInformation1.Inlines.Add(Documents.Run("Last analysis: ", FontWeight = FontWeights.Bold)) + win.txtImageInformation1.Inlines.Add(Documents.Run(if srcImg.dateLastAnalysis.Ticks = 0L then "" else srcImg.dateLastAnalysis.ToLocalTime().ToString())) // 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))) + win.txtImageInformation2.Inlines.Add(Documents.Run("Added infected erythrocyte: ", FontWeight = FontWeights.Bold)) + win.txtImageInformation2.Inlines.Add(Documents.Run((state.ImageNbManuallyChangedRBCStr srcImg true) + " " + (state.ImageManuallyChangedRBCStr srcImg true))) + win.txtImageInformation2.Inlines.Add(Documents.LineBreak()) + win.txtImageInformation2.Inlines.Add(Documents.Run("Removed infected erythrocyte: ", FontWeight = FontWeights.Bold)) + win.txtImageInformation2.Inlines.Add(Documents.Run((state.ImageNbManuallyChangedRBCStr srcImg false) + " " + (state.ImageManuallyChangedRBCStr srcImg false))) | _ -> - gridImageInformation.Visibility <- Visibility.Hidden + win.gridImageInformation.Visibility <- Visibility.Hidden let updateGlobalParasitemia () = - txtGlobalParasitemia.Inlines.Clear() + win.txtGlobalParasitemia.Inlines.Clear() let total, infected = state.GlobalParasitemia - txtGlobalParasitemia.Inlines.Add(Documents.Run(Utils.percentText (total, infected), FontWeight = FontWeights.Bold)) + win.txtGlobalParasitemia.Inlines.Add(Documents.Run(Utils.percentText (total, infected), FontWeight = FontWeights.Bold)) if total > 0 && total < warningBelowNumberOfRBC then - txtGlobalParasitemia.Inlines.Add( + win.txtGlobalParasitemia.Inlines.Add( Documents.Run( sprintf " Warning: the number of erythrocytes should be above %d" warningBelowNumberOfRBC, FontWeight = FontWeights.Bold, Foreground = Brushes.Red)) let updateViewportPreview () = - for preview in stackPreviews.Children |> Seq.cast do + for preview in win.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 canvasWidth = win.canvasCurrentImage.ActualWidth * currentScale + let canvasHeight = win.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. + let marginLeft = previewWidth * (win.scrollViewCurrentImage.HorizontalOffset - win.borderCurrentImage.BorderThickness.Left) / canvasWidth - 2. + let marginRight = previewWidth * (canvasWidth - (win.scrollViewCurrentImage.HorizontalOffset - win.borderCurrentImage.BorderThickness.Right) - win.scrollViewCurrentImage.ViewportWidth) / canvasWidth - 2. + let marginTop = previewHeight * (win.scrollViewCurrentImage.VerticalOffset - win.borderCurrentImage.BorderThickness.Top) / canvasHeight - 2. + let marginBottom = previewHeight * (canvasHeight - (win.scrollViewCurrentImage.VerticalOffset - win.borderCurrentImage.BorderThickness.Bottom) - win.scrollViewCurrentImage.ViewportHeight) / canvasHeight - 2. preview.viewport.Margin <- Thickness( @@ -196,7 +160,7 @@ let run (defaultConfig: Config) (fileToOpen: string option) = let rec setAsInfected (srcImg: SourceImage) (rbc: RBC) (infected: bool) = state.SetAsInfected rbc infected - canvasCurrentImage.Children + win.canvasCurrentImage.Children |> Seq.cast |> Seq.iter (fun frame -> @@ -233,22 +197,22 @@ let run (defaultConfig: Config) (fileToOpen: string option) = let mutable currentPreview = 0 for rbc in srcImg.rbcs |> List.filter (fun rbc -> displayHealthy || rbc.infected) do let previewInfected = - if currentPreview < stackRBC.Children.Count + if currentPreview < win.stackRBC.Children.Count then - RBCFrameFromExisting srcImg rbc (stackRBC.Children.[currentPreview] :?> Views.RBCFrame) + RBCFrameFromExisting srcImg rbc (win.stackRBC.Children.[currentPreview] :?> Views.RBCFrame) else let f = RBCFrame srcImg rbc f.MouseLeftButtonUp.AddHandler(fun obj args -> zoomToRBC (f.Tag :?> RBC)) - stackRBC.Children.Add(f) |> ignore + win.stackRBC.Children.Add(f) |> ignore f currentPreview <- currentPreview + 1 - previewInfected.Height <- stackRBC.ActualHeight - previewInfected.Width <- stackRBC.ActualHeight * rbc.size.Width / rbc.size.Height + previewInfected.Height <- win.stackRBC.ActualHeight + previewInfected.Width <- win.stackRBC.ActualHeight * rbc.size.Width / rbc.size.Height previewInfected.border.Fill <- ImageBrush(BitmapSourceConvert.ToBitmapSource(extractRBCPreview srcImg.img rbc)) - stackRBC.Children.RemoveRange(currentPreview, stackRBC.Children.Count - currentPreview) + win.stackRBC.Children.RemoveRange(currentPreview, win.stackRBC.Children.Count - currentPreview) | _ -> () updateViewportPreview () @@ -259,13 +223,13 @@ let run (defaultConfig: Config) (fileToOpen: string option) = let mutable currentCanvas = 0 for rbc in srcImg.rbcs do let frame = - if currentCanvas < canvasCurrentImage.Children.Count + if currentCanvas < win.canvasCurrentImage.Children.Count then - RBCFrameFromExisting srcImg rbc (canvasCurrentImage.Children.[currentCanvas] :?> Views.RBCFrame) + RBCFrameFromExisting srcImg rbc (win.canvasCurrentImage.Children.[currentCanvas] :?> Views.RBCFrame) else let f = RBCFrame srcImg rbc f.Root.Opacity <- 0.7 - canvasCurrentImage.Children.Add(f) |> ignore + win.canvasCurrentImage.Children.Add(f) |> ignore f currentCanvas <- currentCanvas + 1 @@ -273,8 +237,8 @@ let run (defaultConfig: Config) (fileToOpen: string option) = Canvas.SetLeft(frame, rbc.center.X - rbc.size.Width / 2.) Canvas.SetTop(frame, rbc.center.Y - rbc.size.Height / 2.) - for i in currentCanvas .. canvasCurrentImage.Children.Count - 1 do - canvasCurrentImage.Children.[i].Visibility <- Visibility.Hidden + for i in currentCanvas .. win.canvasCurrentImage.Children.Count - 1 do + win.canvasCurrentImage.Children.[i].Visibility <- Visibility.Hidden | _ -> () let askDocumentPathToSave () : string option = @@ -329,26 +293,26 @@ let run (defaultConfig: Config) (fileToOpen: string option) = let updateCurrentImage () = match state.CurrentImage with | Some srcImg -> - imgLogos.Visibility <- Visibility.Collapsed + win.imgLogos.Visibility <- Visibility.Collapsed // Highlight the preview. - stackPreviews.Children + win.stackPreviews.Children |> Seq.cast |> Seq.iter (fun preview -> preview.border.BorderThickness <- Thickness(if preview.Tag = (srcImg :> Object) then 3. else 0.)) - canvasCurrentImage.Height <- float srcImg.img.Height - canvasCurrentImage.Width <- float srcImg.img.Width - canvasCurrentImage.Background <- ImageBrush(BitmapSourceConvert.ToBitmapSource(srcImg.img)) + win.canvasCurrentImage.Height <- float srcImg.img.Height + win.canvasCurrentImage.Width <- float srcImg.img.Width + win.canvasCurrentImage.Background <- ImageBrush(BitmapSourceConvert.ToBitmapSource(srcImg.img)) updateRBCFramesCurrent () updateRBCFramesPreview () | None -> - imgLogos.Visibility <- Visibility.Visible + win.imgLogos.Visibility <- Visibility.Visible - stackRBC.Children.Clear() - canvasCurrentImage.Children.Clear() - canvasCurrentImage.Background <- canvasCurrentImageColor + win.stackRBC.Children.Clear() + win.canvasCurrentImage.Children.Clear() + win.canvasCurrentImage.Background <- canvasCurrentImageColor updateCurrentImageInformation () @@ -362,7 +326,7 @@ let run (defaultConfig: Config) (fileToOpen: string option) = let imgCtrl = Views.ImageSourcePreview(Margin = Thickness(3.)) imgCtrl.menuRemoveImage.Click.AddHandler(fun obj args -> - stackPreviews.Children.Remove(imgCtrl) + win.stackPreviews.Children.Remove(imgCtrl) let srcImg = imgCtrl.Tag :?> SourceImage let currentRemoved = Some srcImg = state.CurrentImage state.RemoveSourceImage srcImg @@ -373,23 +337,23 @@ let run (defaultConfig: Config) (fileToOpen: string option) = updateGlobalParasitemia() // Update image numbers. - stackPreviews.Children |> Seq.cast |> Seq.iter (fun imgPreview -> imgPreview.txtImageNumber.Text <- (imgPreview.Tag :?> SourceImage).num.ToString())) + win.stackPreviews.Children |> Seq.cast |> Seq.iter (fun imgPreview -> imgPreview.txtImageNumber.Text <- (imgPreview.Tag :?> SourceImage).num.ToString())) imgCtrl.Tag <- srcImg imgCtrl.txtImageNumber.Text <- srcImg.num.ToString() let width = 200 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 + win.stackPreviews.Children.Add(imgCtrl) |> ignore // Zoom to a mouse position into the control 'imgCtrl'. let zoomTo (mousePos: Point) = - let canvasW = canvasCurrentImage.ActualWidth * currentScale - let canvasH = canvasCurrentImage.ActualHeight * currentScale + let canvasW = win.canvasCurrentImage.ActualWidth * currentScale + let canvasH = win.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) + win.scrollViewCurrentImage.ScrollToHorizontalOffset(centerX - win.scrollViewCurrentImage.ViewportWidth / 2. + win.borderCurrentImage.BorderThickness.Left) + win.scrollViewCurrentImage.ScrollToVerticalOffset(centerY - win.scrollViewCurrentImage.ViewportHeight / 2. + win.borderCurrentImage.BorderThickness.Top) imgCtrl.MouseLeftButtonDown.AddHandler(fun obj args -> setCurrentImage (state.SourceImages |> Seq.find (fun srcImg -> (srcImg :> Object) = imgCtrl.Tag)) @@ -408,13 +372,13 @@ let run (defaultConfig: Config) (fileToOpen: string option) = imgCtrl.ReleaseMouseCapture()) let updatePreviews () = - stackPreviews.Children.Clear () + win.stackPreviews.Children.Clear () for srcImg in state.SourceImages do addPreview srcImg updateCurrentImage () let updateGUI () = - txtPatient.Text <- state.PatientID + win.txtPatient.Text <- state.PatientID updatePreviews () updateGlobalParasitemia () updateDocumentStatus () @@ -463,16 +427,16 @@ let run (defaultConfig: Config) (fileToOpen: string option) = 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) + win.txtPatient.TextChanged.AddHandler(fun obj args -> state.PatientID <- win.txtPatient.Text) - menuExit.Click.AddHandler(fun obj args -> mainWindow.Root.Close()) - menuSaveFile.Click.AddHandler(fun obj args -> saveCurrentDocument ()) - 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 ()) + win.menuExit.Click.AddHandler(fun obj args -> win.Root.Close()) + win.menuSave.Click.AddHandler(fun obj args -> saveCurrentDocument ()) + win.menuSaveAs.Click.AddHandler(fun obj args -> saveCurrentDocumentAsNewFile ()) + win.menuOpen.Click.AddHandler(fun obj args -> askLoadFile ()) + win.menuNew.Click.AddHandler(fun obj args -> newFile ()) + win.menuExportResults.Click.AddHandler(fun obj args -> exportResults ()) - menuAddSourceImage.Click.AddHandler(fun obj args -> + win.menuAddSourceImage.Click.AddHandler(fun obj args -> let dialog = OpenFileDialog(Filter = "Image Files|*.png;*.jpg;*.tif;*.tiff", Multiselect = true) let res = dialog.ShowDialog() if res.HasValue && res.Value @@ -494,55 +458,55 @@ let run (defaultConfig: Config) (fileToOpen: string option) = then updateCurrentImage ()) - menuAnalysis.SubmenuOpened.AddHandler(fun obj args -> menuStartAnalysis.IsEnabled <- state.SourceImages.Count() > 0) + win.menuAnalysis.SubmenuOpened.AddHandler(fun obj args -> win.menuStartAnalysis.IsEnabled <- state.SourceImages.Count() > 0) - menuStartAnalysis.Click.AddHandler(fun obj args -> - if Analysis.showWindow mainWindow.Root state + win.menuStartAnalysis.Click.AddHandler(fun obj args -> + if Analysis.showWindow win.Root state then updateGlobalParasitemia () updateCurrentImage ()) - menuHightlightRBC.Click.AddHandler(fun obj args -> - displayHealthy <- menuHightlightRBC.IsChecked + win.menuHightlightRBC.Click.AddHandler(fun obj args -> + displayHealthy <- win.menuHightlightRBC.IsChecked updateRBCFramesPreview () updateRBCFramesCurrent ()) - menuAbout.Click.AddHandler(fun obj args -> About.showWindow mainWindow.Root) + win.menuAbout.Click.AddHandler(fun obj args -> About.showWindow win.Root) - mainWindow.Root.Closing.AddHandler(fun obj args -> askSaveCurrent ()) + win.Root.Closing.AddHandler(fun obj args -> askSaveCurrent ()) // Zoom on the current image. let adjustCurrentImageBorders (deltaX: float) (deltaY: float) = - borderCurrentImage.BorderThickness <- + win.borderCurrentImage.BorderThickness <- Thickness( - (scrollViewCurrentImage.ViewportWidth + deltaX) / 2., - (scrollViewCurrentImage.ViewportHeight + deltaY) / 2., - (scrollViewCurrentImage.ViewportWidth + deltaX) / 2., - (scrollViewCurrentImage.ViewportHeight + deltaY) / 2.) + (win.scrollViewCurrentImage.ViewportWidth + deltaX) / 2., + (win.scrollViewCurrentImage.ViewportHeight + deltaY) / 2., + (win.scrollViewCurrentImage.ViewportWidth + deltaX) / 2., + (win.scrollViewCurrentImage.ViewportHeight + deltaY) / 2.) - canvasCurrentImage.SizeChanged.AddHandler(fun obj args -> + win.canvasCurrentImage.SizeChanged.AddHandler(fun obj args -> let deltaX = args.NewSize.Width - args.PreviousSize.Width let deltaY = args.NewSize.Height - args.PreviousSize.Height if deltaX > 0.5 || deltaY > 0.5 then adjustCurrentImageBorders 0.0 0.0 // Center the view at the center of the image initialy. - scrollViewCurrentImage.UpdateLayout() - scrollViewCurrentImage.ScrollToHorizontalOffset(borderCurrentImage.ActualWidth / 2. - scrollViewCurrentImage.ViewportWidth / 2.) - scrollViewCurrentImage.ScrollToVerticalOffset(borderCurrentImage.ActualHeight / 2. - scrollViewCurrentImage.ViewportHeight / 2.)) + win.scrollViewCurrentImage.UpdateLayout() + win.scrollViewCurrentImage.ScrollToHorizontalOffset(win.borderCurrentImage.ActualWidth / 2. - win.scrollViewCurrentImage.ViewportWidth / 2.) + win.scrollViewCurrentImage.ScrollToVerticalOffset(win.borderCurrentImage.ActualHeight / 2. - win.scrollViewCurrentImage.ViewportHeight / 2.)) - scrollViewCurrentImage.SizeChanged.AddHandler(fun obj args -> + win.scrollViewCurrentImage.SizeChanged.AddHandler(fun obj args -> let deltaX = args.NewSize.Width - args.PreviousSize.Width let deltaY = args.NewSize.Height - args.PreviousSize.Height adjustCurrentImageBorders deltaX deltaY - scrollViewCurrentImage.ScrollToHorizontalOffset(scrollViewCurrentImage.HorizontalOffset + deltaX / 8.) - scrollViewCurrentImage.ScrollToVerticalOffset(scrollViewCurrentImage.VerticalOffset + deltaY / 8.)) + win.scrollViewCurrentImage.ScrollToHorizontalOffset(win.scrollViewCurrentImage.HorizontalOffset + deltaX / 8.) + win.scrollViewCurrentImage.ScrollToVerticalOffset(win.scrollViewCurrentImage.VerticalOffset + deltaY / 8.)) let mutable maxScale = 4. let mutable minScale = 0.25 let currentImageScaleTransform = ScaleTransform() - canvasCurrentImage.LayoutTransform <- currentImageScaleTransform - borderCurrentImage.PreviewMouseWheel.AddHandler(fun obj args -> + win.canvasCurrentImage.LayoutTransform <- currentImageScaleTransform + win.borderCurrentImage.PreviewMouseWheel.AddHandler(fun obj args -> let scaleFactor = if args.Delta > 0 then 2.0 else 0.5 if scaleFactor > 1. && currentScale < maxScale || scaleFactor < 1. && currentScale > minScale then @@ -552,14 +516,14 @@ let run (defaultConfig: Config) (fileToOpen: string option) = if newScale > maxScale then maxScale elif newScale < minScale then minScale else newScale let realScaleFactor = currentScale / previousScale - let centerX = scrollViewCurrentImage.HorizontalOffset + scrollViewCurrentImage.ViewportWidth / 2. - borderCurrentImage.BorderThickness.Left - let centerY = scrollViewCurrentImage.VerticalOffset + scrollViewCurrentImage.ViewportHeight / 2. - borderCurrentImage.BorderThickness.Top + let centerX = win.scrollViewCurrentImage.HorizontalOffset + win.scrollViewCurrentImage.ViewportWidth / 2. - win.borderCurrentImage.BorderThickness.Left + let centerY = win.scrollViewCurrentImage.VerticalOffset + win.scrollViewCurrentImage.ViewportHeight / 2. - win.borderCurrentImage.BorderThickness.Top currentImageScaleTransform.ScaleX <- currentScale currentImageScaleTransform.ScaleY <- currentScale - scrollViewCurrentImage.ScrollToHorizontalOffset(centerX * realScaleFactor - scrollViewCurrentImage.ViewportWidth / 2. + borderCurrentImage.BorderThickness.Left) - scrollViewCurrentImage.ScrollToVerticalOffset(centerY * realScaleFactor - scrollViewCurrentImage.ViewportHeight / 2. + borderCurrentImage.BorderThickness.Top) + win.scrollViewCurrentImage.ScrollToHorizontalOffset(centerX * realScaleFactor - win.scrollViewCurrentImage.ViewportWidth / 2. + win.borderCurrentImage.BorderThickness.Left) + win.scrollViewCurrentImage.ScrollToVerticalOffset(centerY * realScaleFactor - win.scrollViewCurrentImage.ViewportHeight / 2. + win.borderCurrentImage.BorderThickness.Top) args.Handled <- true) @@ -567,70 +531,70 @@ let run (defaultConfig: Config) (fileToOpen: string option) = let mutable scrollStartPosition = Point(0., 0.) let mutable scrollStartOffsetX = 0. let mutable scrollStartOffsetY = 0. - borderCurrentImage.PreviewMouseLeftButtonDown.AddHandler(fun obj args -> - scrollStartPosition <- args.GetPosition(scrollViewCurrentImage) - scrollStartOffsetX <- scrollViewCurrentImage.HorizontalOffset - scrollStartOffsetY <- scrollViewCurrentImage.VerticalOffset - borderCurrentImage.Cursor <- Input.Cursors.ScrollAll - borderCurrentImage.CaptureMouse() |> ignore + win.borderCurrentImage.PreviewMouseLeftButtonDown.AddHandler(fun obj args -> + scrollStartPosition <- args.GetPosition(win.scrollViewCurrentImage) + scrollStartOffsetX <- win.scrollViewCurrentImage.HorizontalOffset + scrollStartOffsetY <- win.scrollViewCurrentImage.VerticalOffset + win.borderCurrentImage.Cursor <- Input.Cursors.ScrollAll + win.borderCurrentImage.CaptureMouse() |> ignore args.Handled <- true) - borderCurrentImage.PreviewMouseMove.AddHandler(fun obj args -> - if borderCurrentImage.IsMouseCaptured + win.borderCurrentImage.PreviewMouseMove.AddHandler(fun obj args -> + if win.borderCurrentImage.IsMouseCaptured then - let position = args.GetPosition(scrollViewCurrentImage) + let position = args.GetPosition(win.scrollViewCurrentImage) let deltaX = scrollStartPosition.X - position.X let deltaY = scrollStartPosition.Y - position.Y - scrollViewCurrentImage.ScrollToHorizontalOffset(deltaX + scrollStartOffsetX) - scrollViewCurrentImage.ScrollToVerticalOffset(deltaY + scrollStartOffsetY) + win.scrollViewCurrentImage.ScrollToHorizontalOffset(deltaX + scrollStartOffsetX) + win.scrollViewCurrentImage.ScrollToVerticalOffset(deltaY + scrollStartOffsetY) args.Handled <- true) - borderCurrentImage.PreviewMouseLeftButtonUp.AddHandler(fun obj args -> - if borderCurrentImage.IsMouseCaptured + win.borderCurrentImage.PreviewMouseLeftButtonUp.AddHandler(fun obj args -> + if win.borderCurrentImage.IsMouseCaptured then - borderCurrentImage.Cursor <- Input.Cursors.Arrow - borderCurrentImage.ReleaseMouseCapture() + win.borderCurrentImage.Cursor <- Input.Cursors.Arrow + win.borderCurrentImage.ReleaseMouseCapture() args.Handled <- true) // Shortcuts. // Save. - mainWindow.Root.InputBindings.Add( + win.Root.InputBindings.Add( Input.KeyBinding( FSharp.ViewModule.FunCommand((fun obj -> saveCurrentDocument ()), (fun obj -> true)), Input.KeyGesture(Input.Key.S, Input.ModifierKeys.Control))) |> ignore // Save as. - mainWindow.Root.InputBindings.Add( + win.Root.InputBindings.Add( Input.KeyBinding( FSharp.ViewModule.FunCommand((fun obj -> saveCurrentDocumentAsNewFile ()), (fun obj -> true)), Input.KeyGesture(Input.Key.S, Input.ModifierKeys.Control ||| Input.ModifierKeys.Shift))) |> ignore // Open. - mainWindow.Root.InputBindings.Add( + win.Root.InputBindings.Add( Input.KeyBinding( FSharp.ViewModule.FunCommand((fun obj -> askLoadFile ()), (fun obj -> true)), Input.KeyGesture(Input.Key.O, Input.ModifierKeys.Control))) |> ignore // New file. - mainWindow.Root.InputBindings.Add( + win.Root.InputBindings.Add( Input.KeyBinding( FSharp.ViewModule.FunCommand((fun obj -> newFile ()), (fun obj -> true)), Input.KeyGesture(Input.Key.N, Input.ModifierKeys.Control))) |> ignore // Export results. - mainWindow.Root.InputBindings.Add( + win.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 ()) + win.scrollViewCurrentImage.ScrollChanged.AddHandler(fun obj args -> updateViewportPreview ()) updateDocumentStatus () - gridImageInformation.Visibility <- Visibility.Hidden + win.gridImageInformation.Visibility <- Visibility.Hidden - mainWindow.Root.Show() + win.Root.Show() match fileToOpen with | Some filepath -> loadFile filepath