1 //
2 // Copyright (c) 2010-2024 Antmicro
3 //
4 // This file is licensed under the MIT License.
5 // Full license text is available in 'licenses/MIT.txt'.
6 //
7 
8 #if PLATFORM_WINDOWS
9 using System.Windows;
10 #endif
11 using Xwt;
12 using Antmicro.Renode.Utilities;
13 using Point = Xwt.Point;
14 
15 namespace Antmicro.Renode.UI
16 {
17     public class WindowPositionProvider
18     {
WindowPositionProvider()19         static WindowPositionProvider()
20         {
21             Instance = new WindowPositionProvider();
22         }
23 
24         public static WindowPositionProvider Instance { get; private set; }
25 
GetNextPosition()26         public Point GetNextPosition()
27         {
28             lock(innerLock)
29             {
30                 nextPosition = SnapToViewport(nextPosition);
31                 var result = nextPosition;
32                 nextPosition.X += offset.X;
33                 nextPosition.Y += offset.Y;
34                 return result;
35             }
36         }
37 
SnapToViewport(Point position)38         private Point SnapToViewport(Point position)
39         {
40             if(!ConfigurationManager.Instance.Get("termsharp", "window-allow-outside-viewport", false))
41             {
42                 var currentScreen = Desktop.GetScreenAtLocation(position) ?? Desktop.PrimaryScreen;
43                 if(!currentScreen.VisibleBounds.Contains(position))
44                 {
45                     position.X = currentScreen.VisibleBounds.X;
46                     position.Y = currentScreen.VisibleBounds.Y;
47 #if PLATFORM_WINDOWS
48                     position.X += SystemParameters.BorderWidth;
49                     position.Y += SystemParameters.WindowCaptionHeight + SystemParameters.ResizeFrameHorizontalBorderHeight;
50 #endif
51                 }
52             }
53             return position;
54         }
55 
WindowPositionProvider()56         private WindowPositionProvider()
57         {
58 #if PLATFORM_WINDOWS
59             nextPosition = new Point(SystemParameters.BorderWidth, SystemParameters.WindowCaptionHeight + SystemParameters.ResizeFrameHorizontalBorderHeight);
60 #else
61             nextPosition = new Point(0, 0);
62 #endif
63             nextPosition.X += ConfigurationManager.Instance.Get("termsharp", "window-initial-offset-x", 0);
64             nextPosition.Y += ConfigurationManager.Instance.Get("termsharp", "window-initial-offset-y", 0);
65 
66             var x = ConfigurationManager.Instance.Get("termsharp", "window-next-offset-x", 30, i => i >= 0);
67             var y = ConfigurationManager.Instance.Get("termsharp", "window-next-offset-y", 50, i => i >= 0);
68             offset = new Point(x, y);
69             innerLock = new object();
70         }
71 
72         private readonly object innerLock;
73 
74         private Point nextPosition;
75         private readonly Point offset;
76     }
77 }
78