1
module Parasitemia.GUI.Main
6 open System.Windows.Media
7 open System.Windows.Markup
8 open System.Windows.Shapes
9 open System.Windows.Controls
10 open System.Diagnostics
11 open Microsoft.Win32 // For the common dialogs.
14 //open Emgu.CV.Structure
20 let run (defaultConfig
: Config) =
21 let app = new Application()
22 let mainWindow = Views.MainWindow()
23 let ctrl (name
: string): 'a =
24 mainWindow.Root.FindName(name) :?> 'a
26 // Utils.log <- (fun m -> log mainWindow m)
28 let currentImageMargin = 0.1 // 10 %.
30 let state = State.State()
32 let exit: MenuItem = ctrl "menuExit"
33 let saveFile: MenuItem = ctrl "menuSave"
34 let loadFile: MenuItem = ctrl "menuOpen"
35 let newFile: MenuItem = ctrl "menuNew"
37 let addSourceImage: MenuItem = ctrl "menuAddSourceImage"
38 let txtPatient: TextBox = ctrl "txtPatient"
39 let stackPreviews: StackPanel = ctrl "stackPreviews"
40 let butStartAnalysis: Button = ctrl "butStartAnalysis"
42 let scrollViewCurrentImage: ScrollViewer = ctrl "scrollViewCurrentImage"
43 let borderCurrentImage: Border = ctrl "borderCurrentImage"
44 let canvasCurrentImage: Canvas = ctrl "canvasCurrentImage"
49 let synchronizeState () =
50 state.PatientID <- txtPatient.Text
52 let setCurrentImage (srcImg
: SourceImage) =
53 canvasCurrentImage.Height <- float srcImg.img
.Height
54 canvasCurrentImage.Width <- float srcImg.img
.Width
55 canvasCurrentImage.Background <- ImageBrush(BitmapSourceConvert.ToBitmapSource(srcImg.img
))
56 (*for rbc in srcImg.rbcs do
57 let rectangle = Rectangle(Height = float rbc.size.Height, Width = float rbc.size.Width, )*)
59 let addPreview (srcImg: SourceImage) =
60 let imgCtrl = Views.ImageSourcePreview(Margin = Thickness(3.))
61 imgCtrl.lblImageNumber
.Content <- srcImg.num
63 let height = srcImg.img
.Height * width / srcImg.img
.Width
64 imgCtrl.imagePreview
.Source <- BitmapSourceConvert.ToBitmapSource(srcImg.img
.Resize(width, height, Emgu.CV.CvEnum.Inter.Cubic))
65 stackPreviews.Children.Add(imgCtrl) |> ignore
67 let updatePreviews () =
68 stackPreviews.Children.Clear ()
69 for srcImg in state.SourceImages do
73 txtPatient.Text <- state.PatientID
76 exit.Click.AddHandler(fun obj args
-> mainWindow.Root.Close())
77 saveFile.Click.AddHandler(fun obj args
->
79 if state.FilePath = ""
81 let dialog = SaveFileDialog(AddExtension = true, DefaultExt = Pia.extension
, Filter = Pia.filter
);
82 let res = dialog.ShowDialog()
83 if res.HasValue && res.Value
85 state.FilePath <- dialog.FileName
90 loadFile.Click.AddHandler(fun obj args
->
91 // TODO: if current state not saved and not empty, ask to save it.
92 let dialog = OpenFileDialog(Filter = Pia.filter
)
93 let res = dialog.ShowDialog()
94 if res.HasValue && res.Value
96 state.FilePath <- dialog.FileName
100 newFile.Click.AddHandler(fun obj args
->
101 // TODO: if current state not saved and not empty, ask to save it.
105 addSourceImage.Click.AddHandler(fun obj args
->
106 let dialog = OpenFileDialog(Filter = "Image Files|*.png;*.jpg;*.tif;*.tiff")
107 let res = dialog.ShowDialog()
108 if res.HasValue && res.Value
110 let srcImg = state.AddSourceImage(dialog.FileName)
112 if state.SourceImages.Count() = 1
114 setCurrentImage srcImg)
116 butStartAnalysis.Click.AddHandler(fun obj args
-> ())
118 // Zoom on the current image.
119 let adjustCurrentImageMargins () =
120 borderCurrentImage.BorderThickness <-
121 Thickness(scrollViewCurrentImage.ViewportWidth / 2., scrollViewCurrentImage.ViewportHeight / 2., scrollViewCurrentImage.ViewportWidth / 2., scrollViewCurrentImage.ViewportHeight / 2.)
123 scrollViewCurrentImage.Loaded.AddHandler(fun obj args
-> adjustCurrentImageMargins ())
124 scrollViewCurrentImage.SizeChanged.AddHandler(fun obj args
-> adjustCurrentImageMargins ())
126 let mutable currentScale = 1.
127 let mutable maxScale = 5.
128 let mutable minScale = 0.1
129 let currentImageScaleTransform = ScaleTransform()
130 borderCurrentImage.LayoutTransform <- currentImageScaleTransform
131 borderCurrentImage.PreviewMouseWheel.AddHandler(fun obj args
->
132 let scaleFactor = if args
.Delta > 0 then 2.0 else 0.5
133 if scaleFactor > 1. && currentScale < maxScale || scaleFactor < 1. && currentScale > minScale
135 let previousScale = currentScale
137 let newScale = currentScale * scaleFactor
138 if newScale > maxScale then maxScale elif newScale < minScale then minScale else newScale
139 let realScaleFactor = currentScale / previousScale
141 let centerX = scrollViewCurrentImage.HorizontalOffset + scrollViewCurrentImage.ViewportWidth / 2. - canvasCurrentImage.Margin.Left
142 let centerY = scrollViewCurrentImage.VerticalOffset + scrollViewCurrentImage.ViewportHeight / 2. - canvasCurrentImage.Margin.Top
144 canvasCurrentImage.Margin <- Thickness(canvasCurrentImage.Margin.Top * realScaleFactor)
145 currentImageScaleTransform.ScaleX <- currentScale
146 currentImageScaleTransform.ScaleY <- currentScale
148 scrollViewCurrentImage.ScrollToHorizontalOffset(centerX * realScaleFactor - scrollViewCurrentImage.ViewportWidth / 2. + canvasCurrentImage.Margin.Left)
149 scrollViewCurrentImage.ScrollToVerticalOffset(centerY * realScaleFactor - scrollViewCurrentImage.ViewportHeight / 2. + canvasCurrentImage.Margin.Top)
150 args
.Handled <- true)
152 // Pan on the current image.
153 let mutable scrollStartPosition = Point(0., 0.)
154 let mutable scrollStartOffsetX = 0.
155 let mutable scrollStartOffsetY = 0.
156 borderCurrentImage.PreviewMouseLeftButtonDown.AddHandler(fun obj args
->
157 scrollStartPosition <- args
.GetPosition(scrollViewCurrentImage)
158 scrollStartOffsetX <- scrollViewCurrentImage.HorizontalOffset
159 scrollStartOffsetY <- scrollViewCurrentImage.VerticalOffset
160 borderCurrentImage.Cursor <- Input.Cursors.ScrollAll
161 borderCurrentImage.CaptureMouse() |> ignore
162 args
.Handled <- true)
164 borderCurrentImage.PreviewMouseMove.AddHandler(fun obj args
->
165 if borderCurrentImage.IsMouseCaptured
167 let position = args
.GetPosition(scrollViewCurrentImage)
168 let deltaX = scrollStartPosition.X - position.X
169 let deltaY = scrollStartPosition.Y - position.Y
170 scrollViewCurrentImage.ScrollToHorizontalOffset(deltaX + scrollStartOffsetX)
171 scrollViewCurrentImage.ScrollToVerticalOffset(deltaY + scrollStartOffsetY)
172 args
.Handled <- true)
174 borderCurrentImage.PreviewMouseLeftButtonUp.AddHandler(fun obj args
->
175 if borderCurrentImage.IsMouseCaptured
177 borderCurrentImage.Cursor <- Input.Cursors.Arrow
178 borderCurrentImage.ReleaseMouseCapture()
179 args
.Handled <- true)
182 (*let txtPatient: Controls.TextBox = ctrl "txtPatient"
183 txtPatient.TextChanged.AddHandler(fun obj args ->
184 state.PatientID <- txtPatient.Text)*)
186 (*saveFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*" ;
187 saveFileDialog1.FilterIndex = 2 ;
188 saveFileDialog1.RestoreDirectory = true ;*)
190 // display mainWindow img
191 mainWindow.Root.Show()