BioGTK  6.7.0
A .NET library & program for annotating, editing various microscopy imaging formats using Bioformats supported images. Including whole slide, pyramidal, and series.
Loading...
Searching...
No Matches
App.cs
1using Bio;
2using Gdk;
3using Gtk;
4using OpenSlideGTK;
5using org.checkerframework.common.returnsreceiver.qual;
6using System;
7using System.Collections.Generic;
8using System.Linq;
9using System.Runtime.InteropServices;
10using System.Text;
11using System.Threading.Tasks;
12using Monitor = Gdk.Monitor;
13using Window = Gtk.Window;
14
15namespace BioGTK
16{
17 public static class App
18 {
19 public static Tools tools;
20 public static TabsView tabsView;
21 public static ImageView viewer;
22 public static ColorTool color;
23 public static Progress progress;
24 public static About about;
25 public static NodeView nodeView;
26 public static FiltersView filters;
27 public static ApplyFilter applyFilter;
28 public static ChannelsTool channelsTool;
29 public static ROIManager roiManager;
30 public static Scripting scripting;
31 public static BioConsole console;
32 public static Functions funcs;
33 public static StackTools stack;
34 public static SetTool setTool;
35 public static Resolutions resolutions;
36 public static Recorder recorder;
37 public static SAMTool samTool;
38 public static Updater updater;
39 private static int selectedIndex;
40 public static Progress prog = Progress.Create("Loading","", "");
41 static bool useGPU = true, useVips = false, useImageSharp = false;
42 public static bool UseGPU
43 {
44 get
45 {
46 return useGPU;
47 }
48 set
49 {
50 useGPU = value;
51 useVips = !value;
52 useImageSharp = !value;
53 UpdateStitching();
54 }
55 }
56 public static bool UseVips
57 {
58 get
59 {
60 return useVips;
61 }
62 set
63 {
64 useVips = value;
65 useImageSharp = !value;
66 useGPU = !value;
67 UpdateStitching();
68 }
69 }
70 public static bool UseImageSharp
71 {
72 get
73 {
74 return useImageSharp;
75 }
76 set
77 {
78 useImageSharp = value;
79 useVips = !value;
80 useGPU = !value;
81 UpdateStitching();
82 }
83 }
84 private static void UpdateStitching()
85 {
86 if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
87 {
88 useGPU = false;
89 OpenSlideBase.useGPU = false;
90 //SlideBase.useGPU = false;
91 OpenSlideBase.UseVips = false;
92 SlideBase.UseVips = false;
93 return;
94 }
95 OpenSlideBase.useGPU = useGPU;
96 //SlideBase.useGPU = useGPU;
97 OpenSlideBase.UseVips = useVips;
98 SlideBase.UseVips = useVips;
99
100 }
101 public static bool ToConsole
102 {
103 get
104 {
105 return BioLib.Recorder.outputConsole;
106 }
107 set
108 {
109 BioLib.Recorder.outputConsole = value;
110 }
111 }
112 static bool useFiji = true;
113 public static bool UseFiji
114 {
115 get
116 {
117 if (OperatingSystem.IsMacOS())
118 {
119 return true;
120 }
121 else
122 {
123 if(Fiji.ImageJPath.Contains("Fiji"))
124 return true;
125 else
126 return false;
127 }
128 }
129 }
134 public static bool SetFijiOrImageJPath()
135 {
136 bool ifb;
137 BioLib.Settings.Load();
138 string st = BioLib.Settings.GetSettings("ImageJPath");
139 if (st != "")
140 {
141 BioLib.Fiji.ImageJPath = st;
142 BioLib.ImageJ.ImageJPath = st;
143 if (!OperatingSystem.IsMacOS())
144 {
145 Fiji.Initialize(st);
146 ImageJ.Initialize(st);
147 }
148 return true;
149 }
150 string title = "Select ImageJ Executable Location";
151 if (OperatingSystem.IsMacOS())
152 title = "Select ImageJ Executable Location (Fiji.app/Contents/MacOS/ImageJ-macosx)";
153 Gtk.FileChooserDialog filechooser =
154 new Gtk.FileChooserDialog(title, Scripting.window,
155 FileChooserAction.Open,
156 "Cancel", ResponseType.Cancel,
157 "Save", ResponseType.Accept);
158 filechooser.SetCurrentFolder(System.IO.Path.GetDirectoryName(Environment.ProcessPath));
159 if (filechooser.Run() != (int)ResponseType.Accept)
160 return false;
161 Fiji.ImageJPath = filechooser.Filename;
162 ImageJ.ImageJPath = filechooser.Filename;
163 if (!OperatingSystem.IsMacOS())
164 {
165 Fiji.Initialize(filechooser.Filename);
166 ImageJ.Initialize(filechooser.Filename);
167 }
168 BioLib.Settings.AddSettings("ImageJPath", filechooser.Filename);
169 filechooser.Destroy();
170 BioLib.Settings.Save();
171 return true;
172 }
173 public static void MoveToMain(Window window)
174 {
175 MoveToMonitor(window, 0);
176 }
177 public static void MoveToMonitor(Window window, int monitorIndex)
178 {
179 Display display = Display.Default;
180 if (display == null)
181 return;
182
183 int monitorCount = display.NMonitors;
184
185 if (monitorIndex >= monitorCount)
186 monitorIndex = 0; // fallback to primary
187
188 Monitor monitor = display.GetMonitor(monitorIndex);
189 Rectangle geometry = monitor.Geometry;
190
191 // Move window to monitor origin
192 window.Move(geometry.X, geometry.Y);
193 }
194
196 public static void Initialize()
197 {
198 AppLog.Clear();
199 Console.WriteLine("Initializing components.");
200 SetFijiOrImageJPath();
201 if (!OperatingSystem.IsMacOS() && UseFiji)
202 {
203 Fiji.Initialize(Fiji.ImageJPath);
204 BioImage.Initialize(Fiji.ImageJPath);
205 }
206 else if (!OperatingSystem.IsMacOS())
207 {
208 ImageJ.Initialize(ImageJ.ImageJPath);
209 BioImage.Initialize(ImageJ.ImageJPath);
210 }
211 Console.WriteLine("Loading settings.");
212 BioLib.Settings.Load();
213 updater = Updater.Create();
214 tools = Tools.Create();
215 filters = FiltersView.Create();
216 roiManager = ROIManager.Create();
217 scripting = Scripting.Create();
218 funcs = Functions.Create();
219 progress = Progress.Create("","","");
220 tools= Tools.Create();
221 //channelsTool = ChannelsTool.Create();
222 console = BioConsole.Create();
223 stack = StackTools.Create();
224 about = About.Create();
225 setTool = SetTool.Create();
226 recorder = Recorder.Create();
227 //color = ColorTool.Create();
228 UpdateStitching();
229 BioLib.Settings.Load();
230 }
231
232 public static void ApplyStyles(Widget widget, bool applyToContainer = true, bool applyColor = true)
233 {
234 if (widget != null)
235 {
236 if (widget is not Button || widget is not SpinButton || widget is not Scrollbar && applyColor)
237 {
238 widget.ModifyBg(StateType.Normal, new Gdk.Color(49, 91, 138));
239 widget.ModifyFg(StateType.Normal, new Gdk.Color(255, 255, 255));
240 }
241 else
242 return;
243 }
244 try
245 {
246 if (widget is Container && applyToContainer)
247 {
248 foreach (var child in ((Container)widget).Children)
249 {
250 if(child is not Button || child is not SpinButton)
251 ApplyStyles(child);
252 }
253 }
254 }
255 catch (Exception e)
256 {
257 Console.WriteLine(e.Message.ToString());
258 }
259 if(widget is Gtk.Window)
260 {
261 var window = (Gtk.Window)widget;
262 window.Icon = new Gdk.Pixbuf("bio.png");
263 window.DeleteEvent += Window_DeleteEvent;
264 window.DestroyEvent += Window_DestroyEvent;
265 window.FocusInEvent += Window_FocusInEvent;
266 }
267 }
268 private static void Window_FocusInEvent(object o, FocusInEventArgs args)
269 {
270 Gtk.Window w = (Gtk.Window)o;
271 w.GrabFocus();
272 }
273 private static void Window_DestroyEvent(object o, DestroyEventArgs args)
274 {
275 }
276
277 private static void Dialog_DeleteEvent(object o, DeleteEventArgs args)
278 {
279 Dialog w = (Dialog)o;
280 w.Hide();
281 w.Destroy();
282 args.RetVal = true;
283 }
284 private static void Dialog_DestroyEvent(object o, DestroyEventArgs args)
285 {
286 }
287 private static void Window_DeleteEvent(object o, DeleteEventArgs args)
288 {
289 Gtk.Window w = (Gtk.Window)o;
290 // ImageView handles its own close lifecycle in ImageView_DeleteEvent.
291 // If we also Hide+Destroy here, it races with that handler and can
292 // cause double-destroy or ghost windows.
293 if (w is ImageView)
294 return;
295 w.Hide();
296 w.Destroy();
297 args.RetVal = true;
298 }
299
300 public static void SelectWindow(string name)
301 {
302 TabsView tbs = App.tabsView;
303
304 int c = tbs.GetViewerCount();
305 for (int v = 0; v < c; v++)
306 {
307 int cc = tbs.GetViewer(v).Images.Count;
308 for (int im = 0; im < cc; im++)
309 {
310 if (tbs.GetViewer(v).Images[im].Filename == Path.GetFileName(name))
311 {
312 tbs.SetTab(v);
313 BioLib.Recorder.Record("App.SelectWindow(\"" + name + "\")");
314 ImageView.SelectedImage = tbs.GetViewer(v).Images[im];
315 viewer = tbs.GetViewer(v);
316 viewer.Present();
317 return;
318 }
319 }
320 }
321 }
322
323 public static void CloseWindow(string name)
324 {
325 BioLib.Recorder.Record("App.CloseWindow(\"" + name + "\")");
326 TabsView tbs = App.tabsView;
327 int c = tbs.GetViewerCount();
328 if (name == "ROI Manager")
329 App.roiManager.Close();
330 else
331 if (name == "Stack Tool")
332 App.stack.Close();
333 else
334 if (name == "Channels Tool")
335 App.channelsTool.Close();
336 else
337 if (name == "Scripting")
338 App.scripting.Close();
339 else
340 if (name == "SAM Tool")
341 App.samTool.Close();
342 else
343 if (name == "Recorder")
344 App.recorder.Close();
345 else
346 if (name == "Color Tool")
347 App.color.Destroy();
348 else
349 for (int v = 0; v < c; v++)
350 {
351 int cc = tbs.GetViewer(v).Images.Count;
352 for (int im = 0; im < cc; im++)
353 {
354 ImageView vi = tbs.GetViewer(v);
355 if (vi.Images[im].Filename == Path.GetFileName(name) || vi.Title == name)
356 {
357 // Remove the image and tab BEFORE destroying the viewer,
358 // and remove the viewer from the list so TabsView events
359 // (WindowStateEvent, SwitchPage) don't try to re-present it.
360 Images.RemoveImage(vi.Images[im]);
361 tbs.RemoveTab(name);
362 tbs.RemoveViewer(vi);
363 vi.Hide();
364 vi.Destroy();
365 return;
366 }
367 }
368 }
369
370 }
371
372 public static void Rename(string text)
373 {
374 App.tabsView.RenameTab(ImageView.SelectedImage.Filename, text);
375 ImageView.SelectedImage.Rename(text);
376 ImageView v = App.tabsView.GetViewer(ImageView.SelectedImage.Filename);
377 v.SetTitle(ImageView.SelectedImage.Filename);
378 BioLib.Recorder.AddLine("App.Rename(\"" + text + "\");",false);
379 }
380
390 static MenuItem FindItem(Menu w,string label)
391 {
392 foreach (Widget item in w.Children)
393 {
394 //We use a try block incase this widget is a menu instead of a menuitem.
395 try
396 {
397 Menu m = (Menu)item;
398 for (int i = 0; i < m.Children.Length; i++)
399 {
400 //We again use a try block incase this is a Menu instead of a menuitem
401 try
402 {
403 MenuItem it = (MenuItem)m.Children[i];
404 if (it.Label == label)
405 {
406 return it;
407 }
408 }
409 catch (Exception)
410 {
411
412 }
413 }
414 }
415 catch (Exception)
416 {
417 MenuItem it = (MenuItem)item;
418 if (it.Label == label)
419 {
420 return it;
421 }
422 }
423 }
424 return null;
425 }
426
442 private static void GetMainMenuItem(string path, out Widget wid, out bool Menu)
443 {
444 wid = null;
445 Menu = false;
446 string[] s = path.Split('/');
447 MenuBar w = tabsView.MainMenu;
448 for (int i = 0; i < s.Length; i++)
449 {
450 foreach (Widget item in w.Children)
451 {
452 //We use a try block incase this widget is a MenuItem instead of Menu.
453 try
454 {
455 MenuItem m = FindItem((Menu)item, s[i]);
456 if(m != null && i == s.Length -1)
457 {
458 wid = m;
459 Menu = true;
460 return;
461 }
462 }
463 catch (Exception)
464 {
465 MenuItem mi = (MenuItem)item;
466 if (mi.Label == s[i])
467 {
468 wid = mi;
469 Menu = false;
470 return;
471 }
472 }
473 }
474 }
475 if(wid == null)
476 GetMainImageJMenuItem(path, out wid, out Menu);
477 }
478
494 private static void GetMainImageJMenuItem(string path, out Widget wid, out bool Menu)
495 {
496 string[] s = path.Split('/');
497 MenuBar w = tabsView.ImageJMenu;
498 for (int i = 0; i < s.Length; i++)
499 {
500 foreach (Widget item in w.Children)
501 {
502 //We use a try block incase this widget is a MenuItem instead of Menu.
503 try
504 {
505 MenuItem m = FindItem((Menu)item, s[i]);
506 if (m != null && i == s.Length - 1)
507 {
508 wid = m;
509 Menu = true;
510 return;
511 }
512 }
513 catch (Exception)
514 {
515 MenuItem mi = (MenuItem)item;
516 if (mi.Label == s[i] && i == s.Length - 1)
517 {
518 wid = mi;
519 Menu = false;
520 return;
521 }
522 }
523 }
524 }
525 wid = null;
526 Menu = false;
527 }
528
544 private static void GetContextMenuItem(string path, out Widget wid, out bool Menu)
545 {
546 string[] s = path.Split('/');
547 Menu w = App.viewer.contextMenu;
548 for (int i = 0; i < s.Length; i++)
549 {
550 foreach (Widget item in w.Children)
551 {
552 //We use a try block incase this widget is a MenuItem instead of Menu.
553 try
554 {
555 MenuItem m = FindItem((Menu)item, s[i]);
556 if (m != null && i == s.Length - 1)
557 {
558 wid = m;
559 Menu = true;
560 return;
561 }
562 }
563 catch (Exception)
564 {
565 MenuItem mi = (MenuItem)item;
566 if (mi.Label == s[i] && i == s.Length - 1)
567 {
568 wid = mi;
569 Menu = false;
570 return;
571 }
572 }
573 }
574 }
575 wid = null;
576 Menu = false;
577 }
578
586 public static void AddMenu(string path)
587 {
588 if (path == null || path == "")
589 return;
590 //We get the Menu containing the MenuItem specified by the path.
591 Widget w;
592 bool menu;
593 GetMainMenuItem(System.IO.Path.GetDirectoryName(path), out w, out menu);
594 if(!menu && w != null)
595 {
596 MenuItem m = (MenuItem)w;
597 if(m.Submenu != null)
598 {
599 Menu me = (Menu)m.Submenu;
600 MenuItem mi = new MenuItem(System.IO.Path.GetFileName(path));
601 mi.ButtonPressEvent += ItemClicked;
602 me.Append(mi);
603 me.ShowAll();
604 return;
605 }
606 else
607 {
608 //If the item we need to add a child item to, is not already a Menu we need to make it a menu
609 Menu me = new Menu();
610 MenuItem mi = new MenuItem(System.IO.Path.GetFileName(path));
611 mi.ButtonPressEvent += ItemClicked;
612 me.Append(mi);
613 m.Submenu = me;
614 me.ShowAll();
615 return;
616 }
617 }
618 else if(menu && w!=null)
619 {
620 //Since this is already a Menu we can just append the item to it.
621 Menu m = (Menu)w;
622 MenuItem mi = new MenuItem(System.IO.Path.GetFileName(path));
623 mi.ButtonPressEvent += ItemClicked;
624 m.Append(mi);
625 }
626
627 GetMainImageJMenuItem(System.IO.Path.GetDirectoryName(path), out w, out menu);
628 if (!menu && w != null)
629 {
630 MenuItem m = (MenuItem)w;
631 if (m.Submenu != null)
632 {
633 Menu me = (Menu)m.Submenu;
634 MenuItem mi = new MenuItem(System.IO.Path.GetFileName(path));
635 mi.ButtonPressEvent += ItemClicked;
636 me.Append(mi);
637 me.ShowAll();
638 }
639 else
640 {
641 //If the item we need to add a child item to, is not already a Menu we need to make it a menu
642 Menu me = new Menu();
643 MenuItem mi = new MenuItem(System.IO.Path.GetFileName(path));
644 mi.ButtonPressEvent += ItemClicked;
645 me.Append(mi);
646 m.Submenu = me;
647 me.ShowAll();
648 }
649 }
650 else if (menu && w != null)
651 {
652 //Since this is already a Menu we can just append the item to it.
653 Menu m = (Menu)w;
654 MenuItem mi = new MenuItem(System.IO.Path.GetFileName(path));
655 mi.ButtonPressEvent += ItemClicked;
656 m.Append(mi);
657 }
658 }
665 public static void AddContextMenu(string path)
666 {
667 if (path == null || path == "")
668 return;
669 string[] s = path.Split('/');
670 //We get the Menu containing the MenuItem specified by the path.
671
672 Widget w;
673 bool menu;
674 GetContextMenuItem(System.IO.Path.GetDirectoryName(path), out w, out menu);
675 if (!menu && w != null)
676 {
677 MenuItem m = (MenuItem)w;
678 if (m.Submenu != null)
679 {
680 Menu me = (Menu)m.Submenu;
681 MenuItem mi = new MenuItem(System.IO.Path.GetFileName(path));
682 mi.ButtonPressEvent += ItemClicked;
683 me.Append(mi);
684 me.ShowAll();
685 }
686 else
687 {
688 //If the item we need to add a child item to, is not already a Menu we need to make it a menu
689 Menu me = new Menu();
690 MenuItem mi = new MenuItem(System.IO.Path.GetFileName(path));
691 mi.ButtonPressEvent += ItemClicked;
692 me.Append(mi);
693 m.Submenu = me;
694 me.ShowAll();
695 }
696 }
697 else if (!menu && w == null)
698 {
699 MenuItem mi = new MenuItem(System.IO.Path.GetFileName(path));
700 mi.ButtonPressEvent += ItemClicked;
701 viewer.contextMenu.Append(mi);
702 viewer.contextMenu.ShowAll();
703 }
704 }
714 private static void ItemClicked(object o, ButtonPressEventArgs args)
715 {
716 MenuItem ts = (MenuItem)o;
717 if (Function.Functions.ContainsKey(ts.Label))
718 {
719 Function f = Function.Functions[ts.Label];
720 f.PerformFunction(true);
721 }
722 else
723 {
724 if (ts.Label.EndsWith(".dll"))
725 {
726 try
727 {
728 Plugin.Plugins[ts.Label].Execute(new string[] { });
729 }
730 catch (Exception e)
731 {
732 Console.WriteLine(e.Message.ToString());
733 }
734 }
735 else if(ts.Label.EndsWith(".onnx") || ts.Label.EndsWith(".pt"))
736 {
737 try
738 {
739 ML.ML.Run(ts.Label, ImageView.SelectedImage);
740 }
741 catch (Exception e)
742 {
743 Console.WriteLine(e.Message.ToString());
744 }
745 }
746 }
747 }
748 }
749}
Definition ML.cs:17
Definition Zarr.cs:20