diff --git a/.gitignore b/.gitignore
index 10657cc1b..5a56e2911 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,7 +50,7 @@ artifacts/
*_i.h
*.ilk
*.meta
-*.obj
+#*.obj
*.pch
*.pdb
*.pgc
@@ -261,4 +261,4 @@ __pycache__/
*.pyc
# dbc
-.DS_Store
\ No newline at end of file
+.DS_Store
diff --git a/Avalonia.props b/Avalonia.props
index e80105b46..87fb61713 100644
--- a/Avalonia.props
+++ b/Avalonia.props
@@ -4,7 +4,7 @@
-
+
diff --git a/AvaloniaEdit b/AvaloniaEdit
index 90540be74..e81fb0baa 160000
--- a/AvaloniaEdit
+++ b/AvaloniaEdit
@@ -1 +1 @@
-Subproject commit 90540be743bbae6b680314f817f2ce3cc49ba566
+Subproject commit e81fb0baa453c756fc85e8c6f60c531518cd42fb
diff --git a/AvaloniaStyles/Styles/BigSur/Button.xaml b/AvaloniaStyles/Styles/BigSur/Button.xaml
index de4ad883e..6e2817e2a 100644
--- a/AvaloniaStyles/Styles/BigSur/Button.xaml
+++ b/AvaloniaStyles/Styles/BigSur/Button.xaml
@@ -10,7 +10,7 @@
+
diff --git a/WDE.WorldMap/WoWMapViewer.axaml.cs b/WDE.WorldMap/WoWMapViewer.axaml.cs
new file mode 100644
index 000000000..ad680fb1a
--- /dev/null
+++ b/WDE.WorldMap/WoWMapViewer.axaml.cs
@@ -0,0 +1,140 @@
+using System;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.Primitives;
+using Avalonia.Threading;
+using WDE.WorldMap.Models;
+using WDE.WorldMap.PanAndZoom;
+
+namespace WDE.WorldMap
+{
+ public class WoWMapViewer : ContentControl
+ {
+ private double zoom;
+ public static readonly DirectProperty ZoomProperty = AvaloniaProperty.RegisterDirect("Zoom", o => o.Zoom, (o, v) => o.Zoom = v);
+
+ private string? map;
+ public static readonly DirectProperty MapProperty = AvaloniaProperty.RegisterDirect("Map", o => o.Map, (o, v) => o.Map = v);
+
+ private string? mapsPath;
+ public static readonly DirectProperty MapsPathProperty = AvaloniaProperty.RegisterDirect("MapsPath", o => o.MapsPath, (o, v) => o.MapsPath = v);
+
+ private IMapContext? mapViewModel;
+ public static readonly DirectProperty MapViewModelProperty = AvaloniaProperty.RegisterDirect("Context", o => o.MapViewModel, (o, v) => o.MapViewModel = v);
+
+ private bool renderBackground = true;
+ public static readonly DirectProperty RenderBackgroundProperty = AvaloniaProperty.RegisterDirect("RenderBackground", o => o.RenderBackground, (o, v) => o.RenderBackground = v);
+
+ private Point topLeftVirtual;
+ public static readonly DirectProperty TopLeftVirtualProperty = AvaloniaProperty.RegisterDirect("TopLeftVirtual", o => o.TopLeftVirtual, (o, v) => o.TopLeftVirtual = v);
+
+ private Point bottomRightVirtual;
+ public static readonly DirectProperty BottomRightVirtualProperty = AvaloniaProperty.RegisterDirect("BottomRightVirtual", o => o.BottomRightVirtual, (o, v) => o.BottomRightVirtual = v);
+
+ private ExtendedZoomBorder? zoomBorder;
+
+ public double Zoom
+ {
+ get => zoom;
+ set => SetAndRaise(ZoomProperty, ref zoom, value);
+ }
+
+ public string? Map
+ {
+ get => map;
+ set => SetAndRaise(MapProperty, ref map, value);
+ }
+
+ public string? MapsPath
+ {
+ get => mapsPath;
+ set => SetAndRaise(MapsPathProperty, ref mapsPath, value);
+ }
+
+ private void OnCenter(double x, double y)
+ {
+ var editorCoords = CoordsUtils.WorldToEditor(x, y);
+ if (zoomBorder != null)
+ zoomBorder.SetCenter(editorCoords.editorX, editorCoords.editorY);
+ }
+
+ private void BoundsToView(double left, double right, double top, double bottom)
+ {
+ var leftTopEditor = CoordsUtils.WorldToEditor(left - 10, top - 10);
+ var rightBottomEditor = CoordsUtils.WorldToEditor(right + 10, bottom + 10);
+ if (zoomBorder != null)
+ zoomBorder.MoveToBounds(leftTopEditor.editorX, rightBottomEditor.editorX, leftTopEditor.editorY, rightBottomEditor.editorY);
+ }
+
+ public IMapContext? MapViewModel
+ {
+ get => mapViewModel;
+ set
+ {
+ if (mapViewModel != null)
+ Unbind(mapViewModel);
+ SetAndRaise(MapViewModelProperty, ref mapViewModel, value);
+ if (value != null && Parent != null)
+ Bind(value);
+ }
+ }
+
+ public bool RenderBackground
+ {
+ get => renderBackground;
+ set => SetAndRaise(RenderBackgroundProperty, ref renderBackground, value);
+ }
+
+ public Point TopLeftVirtual
+ {
+ get => topLeftVirtual;
+ set => SetAndRaise(TopLeftVirtualProperty, ref topLeftVirtual, value);
+ }
+
+ public Point BottomRightVirtual
+ {
+ get => bottomRightVirtual;
+ set => SetAndRaise(BottomRightVirtualProperty, ref bottomRightVirtual, value);
+ }
+
+ private void Bind(IMapContext ctx)
+ {
+ ctx.RequestCenter += OnCenter;
+ ctx.RequestBoundsToView += BoundsToView;
+ InvalidateVisual();
+ }
+
+ private void Unbind(IMapContext ctx)
+ {
+ ctx.RequestCenter -= OnCenter;
+ ctx.RequestBoundsToView -= BoundsToView;
+ }
+
+ protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
+ {
+ if (mapViewModel != null)
+ {
+ Unbind(mapViewModel);
+ Bind(mapViewModel);
+ }
+ }
+
+ protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
+ {
+ if (mapViewModel != null)
+ Unbind(mapViewModel);
+ }
+
+ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
+ {
+ base.OnApplyTemplate(e);
+ zoomBorder = e.NameScope.Find("ZoomBorder");
+
+ DispatcherTimer.RunOnce(() =>
+ {
+ if (mapViewModel != null)
+ mapViewModel.Initialized();
+ }, TimeSpan.FromMilliseconds(500));
+ }
+ }
+}
\ No newline at end of file
diff --git a/WDE.WorldMap/WorldMapModule.cs b/WDE.WorldMap/WorldMapModule.cs
new file mode 100644
index 000000000..6821493e6
--- /dev/null
+++ b/WDE.WorldMap/WorldMapModule.cs
@@ -0,0 +1,11 @@
+using System;
+using WDE.Module;
+using WDE.Module.Attributes;
+
+namespace WDE.WorldMap
+{
+ [AutoRegister]
+ public class WorldMapModule : ModuleBase
+ {
+ }
+}
\ No newline at end of file
diff --git a/WoWDatabaseEditor.Common/WDE.Common/DBC/IDatabaseClientFileOpener.cs b/WoWDatabaseEditor.Common/WDE.Common/DBC/IDatabaseClientFileOpener.cs
new file mode 100644
index 000000000..abd19abed
--- /dev/null
+++ b/WoWDatabaseEditor.Common/WDE.Common/DBC/IDatabaseClientFileOpener.cs
@@ -0,0 +1,12 @@
+using System.Collections.Generic;
+using WDE.Module.Attributes;
+
+namespace WDE.Common.DBC
+{
+ [UniqueProvider]
+ public interface IDatabaseClientFileOpener
+ {
+ IEnumerable Open(byte[] data);
+ IEnumerable Open(string path);
+ }
+}
\ No newline at end of file
diff --git a/WoWDatabaseEditor.Common/WDE.DbcStore/FastReader/IDbcIterator.cs b/WoWDatabaseEditor.Common/WDE.Common/DBC/IDbcIterator.cs
similarity index 86%
rename from WoWDatabaseEditor.Common/WDE.DbcStore/FastReader/IDbcIterator.cs
rename to WoWDatabaseEditor.Common/WDE.Common/DBC/IDbcIterator.cs
index 02b4a95f3..1c72f97bd 100644
--- a/WoWDatabaseEditor.Common/WDE.DbcStore/FastReader/IDbcIterator.cs
+++ b/WoWDatabaseEditor.Common/WDE.Common/DBC/IDbcIterator.cs
@@ -1,4 +1,4 @@
-namespace WDE.DbcStore.FastReader
+namespace WDE.Common.DBC
{
public interface IDbcIterator
{
diff --git a/WoWDatabaseEditor.Common/WDE.Common/MPQ/IMpqService.cs b/WoWDatabaseEditor.Common/WDE.Common/MPQ/IMpqService.cs
index 2b199b429..a506b48a6 100644
--- a/WoWDatabaseEditor.Common/WDE.Common/MPQ/IMpqService.cs
+++ b/WoWDatabaseEditor.Common/WDE.Common/MPQ/IMpqService.cs
@@ -5,6 +5,7 @@ namespace WDE.Common.MPQ
[UniqueProvider]
public interface IMpqService
{
+ bool IsConfigured();
IMpqArchive Open();
}
}
\ No newline at end of file
diff --git a/WoWDatabaseEditor.Common/WDE.Common/Services/ISolutionTasksService.cs b/WoWDatabaseEditor.Common/WDE.Common/Services/ISolutionTasksService.cs
index b68ea1444..aabdfefe4 100644
--- a/WoWDatabaseEditor.Common/WDE.Common/Services/ISolutionTasksService.cs
+++ b/WoWDatabaseEditor.Common/WDE.Common/Services/ISolutionTasksService.cs
@@ -1,13 +1,14 @@
-using WDE.Module.Attributes;
+using System.Threading.Tasks;
+using WDE.Module.Attributes;
namespace WDE.Common.Services
{
[UniqueProvider]
public interface ISolutionTasksService
{
- void SaveSolutionToDatabaseTask(ISolutionItem item);
- void ReloadSolutionRemotelyTask(ISolutionItem item);
- void SaveAndReloadSolutionTask(ISolutionItem item);
+ Task SaveSolutionToDatabaseTask(ISolutionItem item);
+ Task ReloadSolutionRemotelyTask(ISolutionItem item);
+ Task SaveAndReloadSolutionTask(ISolutionItem item);
bool CanSaveToDatabase { get; }
bool CanReloadRemotely { get; }
diff --git a/WoWDatabaseEditor.Common/WDE.Common/Tasks/GlobalApplication.cs b/WoWDatabaseEditor.Common/WDE.Common/Tasks/GlobalApplication.cs
index 490a2df22..d26f7b31a 100644
--- a/WoWDatabaseEditor.Common/WDE.Common/Tasks/GlobalApplication.cs
+++ b/WoWDatabaseEditor.Common/WDE.Common/Tasks/GlobalApplication.cs
@@ -30,6 +30,7 @@ public static IMainThread MainThread
public static bool HighDpi { get; set; }
public static bool IsRunning { get; set; } = true;
+ public static bool Supports3D { get; set; } = true;
public static void InitializeApplication(IMainThread thread, AppBackend backend)
{
diff --git a/WoWDatabaseEditor.Common/WDE.Common/Utils/ListExtensions.cs b/WoWDatabaseEditor.Common/WDE.Common/Utils/ListExtensions.cs
index f09ffe784..805d011de 100644
--- a/WoWDatabaseEditor.Common/WDE.Common/Utils/ListExtensions.cs
+++ b/WoWDatabaseEditor.Common/WDE.Common/Utils/ListExtensions.cs
@@ -38,6 +38,19 @@ public static void OverrideWith(this IList that, IList with)
return default;
}
+ public static int IndexIf(this IList list, Func pred)
+ {
+ for (int i = 0; i < list.Count; i++)
+ {
+ if (pred(list[i]))
+ {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
public static T? RemoveIf(this IList list, Func pred)
{
for (int i = list.Count - 1; i >= 0; i--)
diff --git a/WoWDatabaseEditor.Common/WDE.Common/Windows/ITool.cs b/WoWDatabaseEditor.Common/WDE.Common/Windows/ITool.cs
index 070d53703..fc162b6ca 100644
--- a/WoWDatabaseEditor.Common/WDE.Common/Windows/ITool.cs
+++ b/WoWDatabaseEditor.Common/WDE.Common/Windows/ITool.cs
@@ -21,6 +21,6 @@ public interface IFocusableTool : ITool
public enum ToolPreferedPosition
{
- Left, Right, Bottom
+ Left, Right, Bottom, DocumentCenter
}
}
\ No newline at end of file
diff --git a/WoWDatabaseEditor.Common/WDE.DbcStore/FastReader/DatabaseClientFileOpener.cs b/WoWDatabaseEditor.Common/WDE.DbcStore/FastReader/DatabaseClientFileOpener.cs
index 41346c773..c47eb337b 100644
--- a/WoWDatabaseEditor.Common/WDE.DbcStore/FastReader/DatabaseClientFileOpener.cs
+++ b/WoWDatabaseEditor.Common/WDE.DbcStore/FastReader/DatabaseClientFileOpener.cs
@@ -1,11 +1,26 @@
using System;
using System.Collections.Generic;
using System.IO;
+using WDE.Common.DBC;
+using WDE.Module.Attributes;
namespace WDE.DbcStore.FastReader
{
- public class DatabaseClientFileOpener
+ [AutoRegister]
+ public class DatabaseClientFileOpener : IDatabaseClientFileOpener
{
+ public IEnumerable Open(byte[] data)
+ {
+ uint magic = BitConverter.ToUInt32(data);
+ if (magic == FastDbcReader.WDBC)
+ return new FastDbcReader(data);
+
+ if (magic == FastDb2Reader.WDB2)
+ return new FastDb2Reader(data);
+
+ throw new Exception("Only dbc and db2 supported");
+ }
+
public IEnumerable Open(string path)
{
byte[] buffer = new byte[4];
diff --git a/WoWDatabaseEditor.Common/WDE.DbcStore/FastReader/FastDBCReader.cs b/WoWDatabaseEditor.Common/WDE.DbcStore/FastReader/FastDBCReader.cs
index 6af94d0d1..f041a3b6b 100644
--- a/WoWDatabaseEditor.Common/WDE.DbcStore/FastReader/FastDBCReader.cs
+++ b/WoWDatabaseEditor.Common/WDE.DbcStore/FastReader/FastDBCReader.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
+using WDE.Common.DBC;
namespace WDE.DbcStore.FastReader
{
diff --git a/WoWDatabaseEditor.Common/WDE.DbcStore/FastReader/FastDb2Reader.cs b/WoWDatabaseEditor.Common/WDE.DbcStore/FastReader/FastDb2Reader.cs
index 755deb1ca..47e27621f 100644
--- a/WoWDatabaseEditor.Common/WDE.DbcStore/FastReader/FastDb2Reader.cs
+++ b/WoWDatabaseEditor.Common/WDE.DbcStore/FastReader/FastDb2Reader.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
+using WDE.Common.DBC;
namespace WDE.DbcStore.FastReader
{
diff --git a/WoWDatabaseEditor.Common/WDE.DbcStore/FastReader/SlowWdcReaderWrapper.cs b/WoWDatabaseEditor.Common/WDE.DbcStore/FastReader/SlowWdcReaderWrapper.cs
index a773fc40d..fc517fe62 100644
--- a/WoWDatabaseEditor.Common/WDE.DbcStore/FastReader/SlowWdcReaderWrapper.cs
+++ b/WoWDatabaseEditor.Common/WDE.DbcStore/FastReader/SlowWdcReaderWrapper.cs
@@ -4,6 +4,7 @@
using System.Data;
using WDBXEditor.Reader;
using WDBXEditor.Storage;
+using WDE.Common.DBC;
namespace WDE.DbcStore.FastReader
{
diff --git a/WoWDatabaseEditor.sln b/WoWDatabaseEditor.sln
index c41e8dab5..62ad0369b 100644
--- a/WoWDatabaseEditor.sln
+++ b/WoWDatabaseEditor.sln
@@ -233,6 +233,22 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WDE.SqlInterpreter.Test", "
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WDE.MPQ", "WDE.MPQ\WDE.MPQ.csproj", "{F63A6DDA-874A-41FF-A707-3B95862036A5}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenGLBindings", "Rendering\OpenGLBindings\OpenGLBindings.csproj", "{22B7CA06-975B-452A-96FB-78ED9988B94A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TheAvaloniaOpenGL", "Rendering\TheAvaloniaOpenGL\TheAvaloniaOpenGL.csproj", "{CCD7E775-0ED3-498D-A958-CEB993F42BDE}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TheEngine", "Rendering\TheEngine\TheEngine.csproj", "{05F74B30-019C-475B-BC54-79D470EB9EAA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TheMaths", "Rendering\TheMaths\TheMaths.csproj", "{6FF3D2AA-4FC5-4D50-A529-FCAC89CAC392}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WDE.MapRenderer", "WDE.MapRenderer\WDE.MapRenderer.csproj", "{28C4ACA6-EFD8-4A21-BD32-B2404EB59D68}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WDE.MpqReader", "WDE.MpqReader\WDE.MpqReader.csproj", "{B72EDF49-BF73-407A-A381-8FB7BD91A61D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TheEngine.Test", "Rendering\TheEngine.Test\TheEngine.Test.csproj", "{B6C2EDA7-665A-4CF1-97CF-356BB5141339}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WDE.WorldMap", "WoWDatabaseEditor\WDE.WorldMap\WDE.WorldMap.csproj", "{7A409931-190E-44E5-B5AC-159FA1743F07}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -540,6 +556,40 @@ Global
{F63A6DDA-874A-41FF-A707-3B95862036A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F63A6DDA-874A-41FF-A707-3B95862036A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F63A6DDA-874A-41FF-A707-3B95862036A5}.Release|Any CPU.Build.0 = Release|Any CPU
+
+
+ {7A409931-190E-44E5-B5AC-159FA1743F07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7A409931-190E-44E5-B5AC-159FA1743F07}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7A409931-190E-44E5-B5AC-159FA1743F07}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7A409931-190E-44E5-B5AC-159FA1743F07}.Release|Any CPU.Build.0 = Release|Any CPU
+ {22B7CA06-975B-452A-96FB-78ED9988B94A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {22B7CA06-975B-452A-96FB-78ED9988B94A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {22B7CA06-975B-452A-96FB-78ED9988B94A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {22B7CA06-975B-452A-96FB-78ED9988B94A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CCD7E775-0ED3-498D-A958-CEB993F42BDE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CCD7E775-0ED3-498D-A958-CEB993F42BDE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CCD7E775-0ED3-498D-A958-CEB993F42BDE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CCD7E775-0ED3-498D-A958-CEB993F42BDE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {05F74B30-019C-475B-BC54-79D470EB9EAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {05F74B30-019C-475B-BC54-79D470EB9EAA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {05F74B30-019C-475B-BC54-79D470EB9EAA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {05F74B30-019C-475B-BC54-79D470EB9EAA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6FF3D2AA-4FC5-4D50-A529-FCAC89CAC392}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6FF3D2AA-4FC5-4D50-A529-FCAC89CAC392}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6FF3D2AA-4FC5-4D50-A529-FCAC89CAC392}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6FF3D2AA-4FC5-4D50-A529-FCAC89CAC392}.Release|Any CPU.Build.0 = Release|Any CPU
+ {28C4ACA6-EFD8-4A21-BD32-B2404EB59D68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {28C4ACA6-EFD8-4A21-BD32-B2404EB59D68}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {28C4ACA6-EFD8-4A21-BD32-B2404EB59D68}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {28C4ACA6-EFD8-4A21-BD32-B2404EB59D68}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B72EDF49-BF73-407A-A381-8FB7BD91A61D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B72EDF49-BF73-407A-A381-8FB7BD91A61D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B72EDF49-BF73-407A-A381-8FB7BD91A61D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B72EDF49-BF73-407A-A381-8FB7BD91A61D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B6C2EDA7-665A-4CF1-97CF-356BB5141339}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B6C2EDA7-665A-4CF1-97CF-356BB5141339}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B6C2EDA7-665A-4CF1-97CF-356BB5141339}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B6C2EDA7-665A-4CF1-97CF-356BB5141339}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -616,5 +666,13 @@ Global
{5AE7D201-A541-49F3-A980-3935D3FCA48D} = {4C553308-1140-42F2-B99C-90402248A983}
{0370DA8A-3EC6-445E-97AF-0F517D853E1E} = {4C553308-1140-42F2-B99C-90402248A983}
{F63A6DDA-874A-41FF-A707-3B95862036A5} = {4C553308-1140-42F2-B99C-90402248A983}
+
+ {22B7CA06-975B-452A-96FB-78ED9988B94A} = {C9F8B770-A4E7-479A-A8A0-0DE5A1838AFD}
+ {CCD7E775-0ED3-498D-A958-CEB993F42BDE} = {C9F8B770-A4E7-479A-A8A0-0DE5A1838AFD}
+ {05F74B30-019C-475B-BC54-79D470EB9EAA} = {C9F8B770-A4E7-479A-A8A0-0DE5A1838AFD}
+ {6FF3D2AA-4FC5-4D50-A529-FCAC89CAC392} = {C9F8B770-A4E7-479A-A8A0-0DE5A1838AFD}
+ {28C4ACA6-EFD8-4A21-BD32-B2404EB59D68} = {C9F8B770-A4E7-479A-A8A0-0DE5A1838AFD}
+ {B72EDF49-BF73-407A-A381-8FB7BD91A61D} = {C9F8B770-A4E7-479A-A8A0-0DE5A1838AFD}
+ {B6C2EDA7-665A-4CF1-97CF-356BB5141339} = {C9F8B770-A4E7-479A-A8A0-0DE5A1838AFD}
EndGlobalSection
EndGlobal
diff --git a/WoWDatabaseEditor/Icons/icon_3d.png b/WoWDatabaseEditor/Icons/icon_3d.png
new file mode 100644
index 000000000..6ce4988f2
Binary files /dev/null and b/WoWDatabaseEditor/Icons/icon_3d.png differ
diff --git a/WoWDatabaseEditor/Icons/icon_3d@2x.png b/WoWDatabaseEditor/Icons/icon_3d@2x.png
new file mode 100644
index 000000000..7e9e76ecd
Binary files /dev/null and b/WoWDatabaseEditor/Icons/icon_3d@2x.png differ
diff --git a/WoWDatabaseEditor/Icons/icon_3d_dark.png b/WoWDatabaseEditor/Icons/icon_3d_dark.png
new file mode 100644
index 000000000..94608c77d
Binary files /dev/null and b/WoWDatabaseEditor/Icons/icon_3d_dark.png differ
diff --git a/WoWDatabaseEditor/Icons/icon_3d_dark@2x.png b/WoWDatabaseEditor/Icons/icon_3d_dark@2x.png
new file mode 100644
index 000000000..5d89625f6
Binary files /dev/null and b/WoWDatabaseEditor/Icons/icon_3d_dark@2x.png differ
diff --git a/WoWDatabaseEditor/Icons/icon_day_night.png b/WoWDatabaseEditor/Icons/icon_day_night.png
new file mode 100644
index 000000000..1452fbb6f
Binary files /dev/null and b/WoWDatabaseEditor/Icons/icon_day_night.png differ
diff --git a/WoWDatabaseEditor/Icons/icon_day_night@2x.png b/WoWDatabaseEditor/Icons/icon_day_night@2x.png
new file mode 100644
index 000000000..4c1971a88
Binary files /dev/null and b/WoWDatabaseEditor/Icons/icon_day_night@2x.png differ
diff --git a/WoWDatabaseEditor/Icons/icon_grid.png b/WoWDatabaseEditor/Icons/icon_grid.png
new file mode 100644
index 000000000..89791e91f
Binary files /dev/null and b/WoWDatabaseEditor/Icons/icon_grid.png differ
diff --git a/WoWDatabaseEditor/Icons/icon_grid@2x.png b/WoWDatabaseEditor/Icons/icon_grid@2x.png
new file mode 100644
index 000000000..7f0ee3a5a
Binary files /dev/null and b/WoWDatabaseEditor/Icons/icon_grid@2x.png differ
diff --git a/WoWDatabaseEditor/Icons/icon_grid_dark.png b/WoWDatabaseEditor/Icons/icon_grid_dark.png
new file mode 100644
index 000000000..044102ee2
Binary files /dev/null and b/WoWDatabaseEditor/Icons/icon_grid_dark.png differ
diff --git a/WoWDatabaseEditor/Icons/icon_grid_dark@2x.png b/WoWDatabaseEditor/Icons/icon_grid_dark@2x.png
new file mode 100644
index 000000000..3e080f098
Binary files /dev/null and b/WoWDatabaseEditor/Icons/icon_grid_dark@2x.png differ
diff --git a/WoWDatabaseEditor/Icons/icon_pause.png b/WoWDatabaseEditor/Icons/icon_pause.png
new file mode 100644
index 000000000..6a97aff28
Binary files /dev/null and b/WoWDatabaseEditor/Icons/icon_pause.png differ
diff --git a/WoWDatabaseEditor/Icons/icon_pause@2x.png b/WoWDatabaseEditor/Icons/icon_pause@2x.png
new file mode 100644
index 000000000..d52dce6af
Binary files /dev/null and b/WoWDatabaseEditor/Icons/icon_pause@2x.png differ
diff --git a/WoWDatabaseEditor/Icons/icon_play_path.png b/WoWDatabaseEditor/Icons/icon_play_path.png
new file mode 100644
index 000000000..99086348b
Binary files /dev/null and b/WoWDatabaseEditor/Icons/icon_play_path.png differ
diff --git a/WoWDatabaseEditor/Icons/icon_play_path@2x.png b/WoWDatabaseEditor/Icons/icon_play_path@2x.png
new file mode 100644
index 000000000..d8a06ca7e
Binary files /dev/null and b/WoWDatabaseEditor/Icons/icon_play_path@2x.png differ
diff --git a/WoWDatabaseEditor/Services/SolutionService/SolutionTasksService.cs b/WoWDatabaseEditor/Services/SolutionService/SolutionTasksService.cs
index 043bb070e..cfb7cc94a 100644
--- a/WoWDatabaseEditor/Services/SolutionService/SolutionTasksService.cs
+++ b/WoWDatabaseEditor/Services/SolutionService/SolutionTasksService.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading.Tasks;
using WDE.Common;
using WDE.Common.Database;
using WDE.Common.Managers;
@@ -41,13 +42,13 @@ public SolutionTasksService(ITaskRunner taskRunner,
this.statusBar = statusBar;
}
- public void SaveSolutionToDatabaseTask(ISolutionItem item)
+ public Task SaveSolutionToDatabaseTask(ISolutionItem item)
{
if (!CanSaveToDatabase)
- return;
+ return Task.CompletedTask;
var itemName = solutionItemNameRegistry.GetName(item);
- taskRunner.ScheduleTask($"Export {itemName} to database",
+ return taskRunner.ScheduleTask($"Export {itemName} to database",
async progress =>
{
progress.Report(0, 2, "Generate query");
@@ -66,11 +67,11 @@ public void SaveSolutionToDatabaseTask(ISolutionItem item)
});
}
- public void ReloadSolutionRemotelyTask(ISolutionItem item)
+ public Task ReloadSolutionRemotelyTask(ISolutionItem item)
{
var itemName = solutionItemNameRegistry.GetName(item);
- taskRunner.ScheduleTask($"Reload {itemName} on server",
+ return taskRunner.ScheduleTask($"Reload {itemName} on server",
async progress =>
{
var commands = remoteCommandGenerator.GenerateCommand(item);
@@ -99,10 +100,10 @@ public void ReloadSolutionRemotelyTask(ISolutionItem item)
});
}
- public void SaveAndReloadSolutionTask(ISolutionItem item)
+ public Task SaveAndReloadSolutionTask(ISolutionItem item)
{
var itemName = solutionItemNameRegistry.GetName(item);
- taskRunner.ScheduleTask($"Save and reload {itemName} on server",
+ return taskRunner.ScheduleTask($"Save and reload {itemName} on server",
async progress =>
{
progress.Report(0, 1, "Generate query");
diff --git a/WoWDatabaseEditor/ViewModels/MainWindowViewModel.cs b/WoWDatabaseEditor/ViewModels/MainWindowViewModel.cs
index a9dd91223..a10bee288 100644
--- a/WoWDatabaseEditor/ViewModels/MainWindowViewModel.cs
+++ b/WoWDatabaseEditor/ViewModels/MainWindowViewModel.cs
@@ -29,7 +29,7 @@ public class MainWindowViewModel : ObservableBase, ILayoutViewModelResolver, ICl
private readonly Func quickStartCreator;
private readonly Func textDocumentCreator;
- private string title = "WoW Database Editor 2021.2";
+ private string title = "WoW Database Editor 2021.3";
private readonly Dictionary toolById = new();
public MainWindowViewModel(IDocumentManager documentManager,
diff --git a/WoWDatabaseEditorCore.Avalonia/App.xaml.cs b/WoWDatabaseEditorCore.Avalonia/App.xaml.cs
index 7a1f22892..3006f9818 100644
--- a/WoWDatabaseEditorCore.Avalonia/App.xaml.cs
+++ b/WoWDatabaseEditorCore.Avalonia/App.xaml.cs
@@ -100,6 +100,7 @@ protected override IContainerExtension CreateContainerExtension()
var container = new UnityContainerExtension(unity);
var mainScope = new ScopedContainer(container, unity);
container.RegisterInstance(mainScope);
+ ViewBind.ContainerProvider = container;
return container;
}
diff --git a/WoWDatabaseEditorCore.Avalonia/Docking/AvaloniaDockAdapter.cs b/WoWDatabaseEditorCore.Avalonia/Docking/AvaloniaDockAdapter.cs
index 210bfd436..a1e2fda7b 100644
--- a/WoWDatabaseEditorCore.Avalonia/Docking/AvaloniaDockAdapter.cs
+++ b/WoWDatabaseEditorCore.Avalonia/Docking/AvaloniaDockAdapter.cs
@@ -2,6 +2,7 @@
using Dock.Model.Controls;
using Dock.Model.Core;
using WDE.Common.Managers;
+using WDE.Common.Windows;
using WDE.MVVM;
using WDE.MVVM.Observable;
using WoWDatabaseEditorCore.Avalonia.Docking.Serialization;
@@ -110,7 +111,14 @@ public AvaloniaDockAdapter(IDocumentManager documentManager, ILayoutViewModelRes
{
var dockable = new AvaloniaToolDockWrapper(documentManager, tool);
tools[tool] = dockable;
- factory.AddTool(currentLayout!, dockable);
+ if (tool.PreferedPosition == ToolPreferedPosition.DocumentCenter)
+ factory.AddToolAsDocument(currentLayout!, dockable);
+ else
+ factory.AddTool(currentLayout!, dockable);
+ factory.SetActiveDockable(dockable);
+ } else if (isVisible && tools.ContainsKey(tool))
+ {
+ factory.SetActiveDockable(tools[tool]);
}
else if (!isVisible)
{
diff --git a/WoWDatabaseEditorCore.Avalonia/Docking/AvaloniaToolDockWrapper.cs b/WoWDatabaseEditorCore.Avalonia/Docking/AvaloniaToolDockWrapper.cs
index aadbf859f..0e40de588 100644
--- a/WoWDatabaseEditorCore.Avalonia/Docking/AvaloniaToolDockWrapper.cs
+++ b/WoWDatabaseEditorCore.Avalonia/Docking/AvaloniaToolDockWrapper.cs
@@ -1,4 +1,5 @@
-using Dock.Model.ReactiveUI.Controls;
+using System;
+using Dock.Model.ReactiveUI.Controls;
using WDE.Common.Managers;
using WDE.Common.Windows;
using ITool = WDE.Common.Windows.ITool;
diff --git a/WoWDatabaseEditorCore.Avalonia/Docking/DockFactory.cs b/WoWDatabaseEditorCore.Avalonia/Docking/DockFactory.cs
index 145c77b31..faa0f33ff 100644
--- a/WoWDatabaseEditorCore.Avalonia/Docking/DockFactory.cs
+++ b/WoWDatabaseEditorCore.Avalonia/Docking/DockFactory.cs
@@ -14,6 +14,18 @@ public class DockFactory : Factory
public override IDocumentDock CreateDocumentDock() => new FocusAwareDocumentDock() {CanFloat = false};
public override IToolDock CreateToolDock() => new FocusAwareToolDock() {CanFloat = false};
+ public void AddToolAsDocument(IDock layout, AvaloniaToolDockWrapper tool)
+ {
+ var documentsDock = FindDockable(layout, dockable => dockable is IDocumentDock) as IDocumentDock;
+ if (documentsDock == null)
+ {
+ documentsDock = CreateDocumentDock();
+ documentsDock.Proportion = 1;
+ AddDockable(layout, documentsDock);
+ }
+ AddDockable(documentsDock, tool);
+ }
+
public void AddDocument(IDock layout, AvaloniaDocumentDockWrapper document)
{
var documentsDock = FindDockable(layout, dockable => dockable is IDocumentDock) as IDocumentDock;
diff --git a/WoWDatabaseEditorCore.Avalonia/Docking/PersistentDockDataTemplate.cs b/WoWDatabaseEditorCore.Avalonia/Docking/PersistentDockDataTemplate.cs
index c70c02c1c..bbd8dda68 100644
--- a/WoWDatabaseEditorCore.Avalonia/Docking/PersistentDockDataTemplate.cs
+++ b/WoWDatabaseEditorCore.Avalonia/Docking/PersistentDockDataTemplate.cs
@@ -1,12 +1,15 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Reactive.Linq;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Controls.Templates;
using Avalonia.VisualTree;
using WDE.Common.Avalonia.Utils;
+using WDE.Common.Disposables;
using WDE.Common.Managers;
using WDE.Common.Windows;
+using WDE.MVVM;
using WDE.MVVM.Observable;
namespace WoWDatabaseEditorCore.Avalonia.Docking
@@ -54,7 +57,7 @@ public IControl Build(object data, IControl? existing)
children.Remove(view);
return view;
}
-
+
if (ViewBind.TryResolve(toolDockWrapper.ViewModel, out var documentView) && documentView is IControl control)
{
tools[toolDockWrapper.ViewModel] = control;
@@ -82,6 +85,15 @@ private void Bind()
{
documents.Remove(item.Item);
});
+ foreach (var tool in DocumentManager.AllTools)
+ {
+ tool.ToObservable(i => i.Visibility)
+ .SubscribeAction(toolVisibility =>
+ {
+ if (!toolVisibility)
+ tools.Remove(tool);
+ });
+ }
}
}
}
diff --git a/WoWDatabaseEditorCore.Avalonia/Program.cs b/WoWDatabaseEditorCore.Avalonia/Program.cs
index 7381ee4f5..d64fed2f2 100644
--- a/WoWDatabaseEditorCore.Avalonia/Program.cs
+++ b/WoWDatabaseEditorCore.Avalonia/Program.cs
@@ -1,9 +1,14 @@
using System;
+using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using AsyncAwaitBestPractices;
using Avalonia;
+using Avalonia.Controls;
+using Avalonia.OpenGL;
+using Avalonia.OpenTK;
using Avalonia.ReactiveUI;
using WDE.Common.Tasks;
using WoWDatabaseEditorCore.Managers;
@@ -41,6 +46,25 @@ private static void FixCurrentDirectory()
Directory.SetCurrentDirectory(exePath.Directory.FullName);
}
+ private static T SafeUseOpenTK(T builder, IList probeVersions) where T : AppBuilderBase, new()
+ {
+ return builder.AfterPlatformServicesSetup(_ =>
+ {
+ var method = typeof(AvaloniaOpenTKIntegration).GetMethod("Initialize",
+ BindingFlags.NonPublic | BindingFlags.Static);
+
+ try
+ {
+ method!.Invoke(null, new object?[]{probeVersions});
+ }
+ catch (Exception e)
+ {
+ GlobalApplication.Supports3D = false;
+ Console.WriteLine(e);
+ }
+ });
+ }
+
// Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp()
{
@@ -51,11 +75,26 @@ public static AppBuilder BuildAvaloniaApp()
//.With(new Win32PlatformOptions(){AllowEglInitialization = false})
.UseReactiveUI()
.LogToTrace();
+#if USE_OPENTK
+ Console.WriteLine("Initializing OpenGL");
+ configuration = SafeUseOpenTK(configuration, new List { new GlVersion(GlProfileType.OpenGL, 4, 1, true) });
+// configuration = configuration.UseOpenTK(new List { new GlVersion(GlProfileType.OpenGL, 4, 1, true) });
+#endif
if (GlobalApplication.Arguments.IsArgumentSet("wgl"))
{
configuration = configuration.
- With(new Win32PlatformOptions() { UseWgl = true });
+ With(new Win32PlatformOptions() { UseWgl = true,
+ AllowEglInitialization = false,
+ WglProfiles = new List()
+ {
+ new GlVersion(GlProfileType.OpenGL, 4, 6),
+ new GlVersion(GlProfileType.OpenGL, 4, 5),
+ new GlVersion(GlProfileType.OpenGL, 4, 4),
+ new GlVersion(GlProfileType.OpenGL, 4, 3),
+ new GlVersion(GlProfileType.OpenGL, 4, 2),
+ new GlVersion(GlProfileType.OpenGL, 4, 1),
+ }});
}
return configuration;
diff --git a/WoWDatabaseEditorCore.Avalonia/Services/AppearanceService/Views/ThemeConfigView.axaml b/WoWDatabaseEditorCore.Avalonia/Services/AppearanceService/Views/ThemeConfigView.axaml
index 64adb0960..56fbabadc 100644
--- a/WoWDatabaseEditorCore.Avalonia/Services/AppearanceService/Views/ThemeConfigView.axaml
+++ b/WoWDatabaseEditorCore.Avalonia/Services/AppearanceService/Views/ThemeConfigView.axaml
@@ -3,6 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
xmlns:controls="clr-namespace:WDE.Common.Avalonia.Controls;assembly=WDE.Common.Avalonia"
+ xmlns:converters="clr-namespace:WDE.Common.Avalonia.Converters;assembly=WDE.Common.Avalonia"
prism:ViewModelLocator.AutoWireViewModel="False">
@@ -20,6 +21,6 @@
- Info: Custom scaling is available only on Windows
+ Info: Custom scaling is available only on Windows
\ No newline at end of file
diff --git a/WoWDatabaseEditorCore.Avalonia/Services/NewItemService/NewItemDialogView.axaml.cs b/WoWDatabaseEditorCore.Avalonia/Services/NewItemService/NewItemDialogView.axaml.cs
index 358f5456b..4a7761027 100644
--- a/WoWDatabaseEditorCore.Avalonia/Services/NewItemService/NewItemDialogView.axaml.cs
+++ b/WoWDatabaseEditorCore.Avalonia/Services/NewItemService/NewItemDialogView.axaml.cs
@@ -27,7 +27,7 @@ private void UIElement_OnKeyDown(object sender, KeyEventArgs e)
vm.Accept.Execute(null);
}
- private void InputElement_OnDoubleTapped(object? sender, RoutedEventArgs e)
+ private void InputElement_OnDoubleTapped(object? sender, TappedEventArgs e)
{
if (DataContext is NewItemDialogViewModel vm)
vm.Accept.Execute(null);
diff --git a/WoWDatabaseEditorCore.Avalonia/Views/AboutView.axaml b/WoWDatabaseEditorCore.Avalonia/Views/AboutView.axaml
index b75232abc..b0fd84689 100644
--- a/WoWDatabaseEditorCore.Avalonia/Views/AboutView.axaml
+++ b/WoWDatabaseEditorCore.Avalonia/Views/AboutView.axaml
@@ -12,7 +12,7 @@
- WoW Database Editor 2021.2
+ WoW Database Editor 2021.3
diff --git a/WoWDatabaseEditorCore.Avalonia/Views/QuickStartView.axaml b/WoWDatabaseEditorCore.Avalonia/Views/QuickStartView.axaml
index 1a25a10b3..5b15d2bb8 100644
--- a/WoWDatabaseEditorCore.Avalonia/Views/QuickStartView.axaml
+++ b/WoWDatabaseEditorCore.Avalonia/Views/QuickStartView.axaml
@@ -76,7 +76,7 @@
- WoW Database Editor 2021.2
+ WoW Database Editor 2021.3
diff --git a/WoWDatabaseEditorCore.Avalonia/WoWDatabaseEditorCore.Avalonia.csproj b/WoWDatabaseEditorCore.Avalonia/WoWDatabaseEditorCore.Avalonia.csproj
index fda9c35e0..af478647e 100644
--- a/WoWDatabaseEditorCore.Avalonia/WoWDatabaseEditorCore.Avalonia.csproj
+++ b/WoWDatabaseEditorCore.Avalonia/WoWDatabaseEditorCore.Avalonia.csproj
@@ -7,6 +7,8 @@
Icon.ico
enable
nullable
+ $(DefineConstants);USE_OPENTK
+ $(DefineConstants);USE_OPENTK
..\bin\$(Configuration)\
@@ -24,6 +26,7 @@
+
diff --git a/WoWPacketParser b/WoWPacketParser
index 3c33d8e20..1bd6638a1 160000
--- a/WoWPacketParser
+++ b/WoWPacketParser
@@ -1 +1 @@
-Subproject commit 3c33d8e20da119fdb82d0348fb11522591fe6fde
+Subproject commit 1bd6638a11e76908b7a17c4781fe426fd59d8286