diff --git a/SMTx/ViewModels/MainWindowViewModel.cs b/SMTx/ViewModels/MainWindowViewModel.cs
index cdf5710b..5dd29e3b 100644
--- a/SMTx/ViewModels/MainWindowViewModel.cs
+++ b/SMTx/ViewModels/MainWindowViewModel.cs
@@ -7,6 +7,7 @@
using Dock.Model.Core;
using Avalonia;
using Avalonia.Controls;
+using Avalonia.Controls.ApplicationLifetimes;
namespace SMTx.ViewModels;
@@ -68,5 +69,9 @@ public void ResetLayout()
public void QuitApp()
{
+ if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktopAppLifetime)
+ desktopAppLifetime.Shutdown();
+ else if (Application.Current?.ApplicationLifetime is IControlledApplicationLifetime controlledAppLifetime)
+ controlledAppLifetime.Shutdown();
}
}
diff --git a/SMTx/Views/Documents/UniverseView.axaml b/SMTx/Views/Documents/UniverseView.axaml
index 54e12536..5ce9129b 100644
--- a/SMTx/Views/Documents/UniverseView.axaml
+++ b/SMTx/Views/Documents/UniverseView.axaml
@@ -19,7 +19,11 @@
Grid.ColumnSpan="3"
MaxZoomX="2" MaxZoomY="2"
MinZoomX="0.2" MinZoomY="0.2"
- SizeChanged="ZoomBorder_OnSizeChanged">
+ MaxOffsetX="2500" MaxOffsetY="2500"
+ MinOffsetX="-2500" MinOffsetY="-2500"
+ EnableConstrains="False"
+ SizeChanged="ZoomBorder_OnSizeChanged"
+ ZoomChanged="ZoomBorder_ZoomChanged">
diff --git a/SMTx/Views/Documents/UniverseView.axaml.cs b/SMTx/Views/Documents/UniverseView.axaml.cs
index c717b0be..53b965f5 100644
--- a/SMTx/Views/Documents/UniverseView.axaml.cs
+++ b/SMTx/Views/Documents/UniverseView.axaml.cs
@@ -7,6 +7,9 @@
using Avalonia.Controls.Shapes;
using Avalonia.Interactivity;
using Avalonia.Layout;
+using System;
+using Avalonia.Controls.PanAndZoom;
+using System.Diagnostics;
namespace SMTx.Views.Documents
{
@@ -39,6 +42,8 @@ public partial class UniverseView : UserControl
private Brush ConstellationLinkStroke;
private Brush BackgroundFill;
+ private List canvasObjects = new List();
+
private struct GateHelper
{
public SMT.EVEData.System from { get; set; }
@@ -81,9 +86,32 @@ private void AddSystems()
// cache all system links
List systemLinks = new List();
+ SMT.EVEData.MapRegion mr = SMT.EVEData.EveManager.Instance.GetRegion("Delve");
+
+ // absolute coodinate variables
+ double minX, maxX, minY, maxY, absWidth, absHeight;
+ minX = maxX = minY = maxY = absWidth = absHeight = 0;
+ // offsets
+ double xOffset, yOffset;
- SMT.EVEData.MapRegion mr = SMT.EVEData.EveManager.Instance.GetRegion("Delve");
+ // Iterate all systems (points) in the region data to find the min and max coordinate offsets
+ foreach (SMT.EVEData.System s in SMT.EVEData.EveManager.Instance.Systems)
+ {
+ minX = Math.Min(minX, s.UniverseX);
+ maxX = Math.Max(maxX, s.UniverseX);
+ minY = Math.Min(minY, s.UniverseY);
+ maxY = Math.Max(maxY, s.UniverseY);
+ }
+ // Calculate absolute width and height
+ absWidth = maxX - minX;
+ absHeight = maxY - minY;
+ // Calculate an offset for each object on the canvas to normalize
+ xOffset = (SystemTextWidth / 2d) - minX;
+ yOffset = (SystemShapeSize / 2d) - minY;
+
+ UniverseViewGrid.Width = absWidth + SystemTextWidth;
+ UniverseViewGrid.Height = absHeight + SystemShapeSize + SystemShapeTextYOffset;
// Add all of the systems
foreach (SMT.EVEData.System s in SMT.EVEData.EveManager.Instance.Systems)
@@ -119,9 +147,10 @@ private void AddSystems()
}
- Canvas.SetLeft(sys, s.UniverseX - SystemShapeOffset);
- Canvas.SetTop(sys, s.UniverseY - SystemShapeOffset);
+ Canvas.SetLeft(sys, s.UniverseX - SystemShapeOffset + xOffset);
+ Canvas.SetTop(sys, s.UniverseY - SystemShapeOffset + yOffset);
UniverseViewGrid.Children.Add(sys);
+ canvasObjects.Add(sys);
// System Name
TextBlock systemName = new TextBlock
@@ -140,10 +169,12 @@ private void AddSystems()
VerticalAlignment = VerticalAlignment.Top,
};
- Canvas.SetLeft(systemName, s.UniverseX - SystemTextWidthOffset);
- Canvas.SetTop(systemName, s.UniverseY + SystemShapeTextYOffset);
+ Canvas.SetLeft(systemName, s.UniverseX - SystemTextWidthOffset + xOffset);
+ Canvas.SetTop(systemName, s.UniverseY + SystemShapeTextYOffset + yOffset);
UniverseViewGrid.Children.Add(systemName);
+ // TODO put the text block into a collection along with the canvas objects.
+ // canvasObjects.Add(systemName);
// generate the list of links
@@ -175,8 +206,8 @@ private void AddSystems()
foreach (GateHelper gh in systemLinks)
{
Line sysLink = new Line();
- sysLink.StartPoint = new Point(gh.from.UniverseX, gh.from.UniverseY);
- sysLink.EndPoint = new Point(gh.to.UniverseX, gh.to.UniverseY);
+ sysLink.StartPoint = new Point(gh.from.UniverseX + xOffset, gh.from.UniverseY + yOffset);
+ sysLink.EndPoint = new Point(gh.to.UniverseX + xOffset, gh.to.UniverseY + yOffset);
sysLink.Stroke = LinkStroke;
if (gh.from.ConstellationID != gh.to.ConstellationID)
@@ -192,6 +223,7 @@ private void AddSystems()
sysLink.StrokeThickness = 1.2;
sysLink.ZIndex = SystemLinkZIndex;
UniverseViewGrid.Children.Add(sysLink);
+ canvasObjects.Add(sysLink);
}
}
@@ -202,9 +234,11 @@ private void AddSystems()
private void SldZoom_OnValueChanged(object sender, RangeBaseValueChangedEventArgs e)
{
double zoomTo = SldZoom.Value;
- double zoomCentreX = ZoomBorder.DesiredSize.Width / 2;
- double zoomCentreY = ZoomBorder.DesiredSize.Height / 2;
+ var desiredSize = ZoomBorder.DesiredSize;
+
+ double zoomCentreX = ZoomBorder.Bounds.Width / 2.0;
+ double zoomCentreY = ZoomBorder.Bounds.Height / 2.0;
ZoomBorder.Zoom(zoomTo, zoomCentreX, zoomCentreY, true);
}
@@ -230,6 +264,52 @@ private void ZoomBorder_OnSizeChanged(object sender, SizeChangedEventArgs e)
}
}
+ private void ZoomBorder_ZoomChanged(object sender, ZoomChangedEventArgs e)
+ {
+ Debug.WriteLine($"[ZoomChanged] {e.ZoomX} {e.ZoomY} {e.OffsetX} {e.OffsetY}");
+ double normalizedX = e.OffsetX / e.ZoomX;
+ double normalizedY = e.OffsetY / e.ZoomY;
+ Debug.WriteLine($"[Normalized X] {normalizedX} [Normalized Y] {normalizedY}");
+ if (sender is ZoomBorder zoomBorder)
+ {
+ double maxBaseOffsetX = zoomBorder.Bounds.Width;
+ double maxBaseOffsetY = zoomBorder.Bounds.Height;
+
+ Point originVector = new Point(UniverseViewGrid.Bounds.Left, UniverseViewGrid.Bounds.Top);
+ Point boundsVector = new Point(UniverseViewGrid.Bounds.Right, UniverseViewGrid.Bounds.Bottom);
+
+ Avalonia.Matrix zoomMatrix = Avalonia.Matrix.CreateScale(e.ZoomX, e.ZoomY);
+
+ /*
+ double newFromX = zoomBorder.Matrix.Transform(originVector).X;
+ double newFromY = zoomBorder.Matrix.Transform(originVector).Y;
+ double newToX = zoomBorder.Matrix.Transform(boundsVector).X;
+ double newToY = zoomBorder.Matrix.Transform(boundsVector).Y;
+ */
+
+ double newFromX = zoomMatrix.Transform(originVector).X;
+ double newFromY = zoomMatrix.Transform(originVector).Y;
+ double newToX = zoomMatrix.Transform(boundsVector).X;
+ double newToY = zoomMatrix.Transform(boundsVector).Y;
+
+ if (Math.Round(zoomBorder.MinOffsetX) != Math.Round(newFromX))
+ zoomBorder.MinOffsetX = newFromX;
+ if (Math.Round(zoomBorder.MinOffsetY) != Math.Round(newFromY))
+ zoomBorder.MinOffsetY = newFromY;
+ if (Math.Round(zoomBorder.MaxOffsetX) != Math.Round(newToX))
+ zoomBorder.MaxOffsetX = newToX;
+ if (Math.Round(zoomBorder.MaxOffsetY) != Math.Round(newToY))
+ zoomBorder.MaxOffsetY = newToY;
+
+ /*
+ foreach (Shape sys in canvasObjects)
+ {
+ // TODO iterate and clip objects based on their bounds
+ }
+ */
+ }
+ }
+
#endregion
}