mirror of
https://github.com/gwdevhub/Daybreak.git
synced 2026-09-18 06:15:15 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d6623a8646 | ||
|
|
403ba51a7d | ||
|
|
b185a606e6 | ||
|
|
342a9a4826 | ||
|
|
2df2e8a65e | ||
|
|
2d5e9231a9 | ||
|
|
818e2bf1d0 | ||
|
|
f0a876f7cc | ||
|
|
3fae8f91cb | ||
|
|
8b08056ca7 | ||
|
|
39eaf53deb | ||
|
|
4674d1d7e5 | ||
|
|
b8b5cc8b1d | ||
|
|
dc987233a7 | ||
|
|
266b400c22 | ||
|
|
a4ac083fd0 | ||
|
|
320dd16838 | ||
|
|
5c05c636bc | ||
|
|
7103a8a83a | ||
|
|
ad749d801a | ||
|
|
747e9a0490 | ||
|
|
836402bd0f | ||
|
|
a3d5e1ce1f | ||
|
|
f2cc59a4ab | ||
|
|
6ea77f7e05 | ||
|
|
5ea8df7cb9 | ||
|
|
c70e8ec90d | ||
|
|
210e3a8cb1 | ||
|
|
a0c3bb094c | ||
|
|
b4d932692a | ||
|
|
667534a07a | ||
|
|
159928f24b | ||
|
|
8a91ded610 | ||
|
|
4226b7eb32 | ||
|
|
b61c99dd1c | ||
|
|
1ccb0d5334 | ||
|
|
7fa01353dd | ||
|
|
4f849d880b | ||
|
|
4b60c96aad | ||
|
|
a4dc0d65cf | ||
|
|
85e017423f | ||
|
|
b38488937b | ||
|
|
d291d5825a | ||
|
|
9d6162f65f | ||
|
|
f54ab42a92 | ||
|
|
78c8ae3e8f | ||
|
|
c64830c5b6 | ||
|
|
561c7cf7b1 | ||
|
|
2c6862de41 | ||
|
|
69842cbadf | ||
|
|
c7327e7bb2 | ||
|
|
de33ed7fc4 |
+5
-2
@@ -6,8 +6,8 @@ csharp_indent_labels = one_less_than_current
|
||||
csharp_using_directive_placement = outside_namespace:error
|
||||
csharp_prefer_simple_using_statement = true:error
|
||||
csharp_prefer_braces = true:silent
|
||||
csharp_style_namespace_declarations = block_scoped:silent
|
||||
csharp_style_prefer_method_group_conversion = true:silent
|
||||
csharp_style_namespace_declarations = file_scoped:error
|
||||
csharp_style_prefer_method_group_conversion = true:suggestion
|
||||
csharp_style_expression_bodied_methods = false:silent
|
||||
csharp_style_expression_bodied_constructors = false:silent
|
||||
csharp_style_expression_bodied_operators = false:silent
|
||||
@@ -46,6 +46,9 @@ csharp_style_prefer_extended_property_pattern = true:suggestion
|
||||
csharp_style_var_for_built_in_types = false:silent
|
||||
csharp_style_var_when_type_is_apparent = false:silent
|
||||
csharp_style_var_elsewhere = false:silent
|
||||
csharp_style_prefer_top_level_statements = true:suggestion
|
||||
csharp_style_prefer_utf8_string_literals = true:suggestion
|
||||
csharp_style_prefer_readonly_struct = true:suggestion
|
||||
|
||||
[*.{cs,vb}]
|
||||
#### Naming styles ####
|
||||
|
||||
@@ -53,12 +53,12 @@ jobs:
|
||||
echo "${{ env.Changelog }}"
|
||||
|
||||
- name: Install .NET Core
|
||||
uses: actions/setup-dotnet@v2
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '6.x'
|
||||
dotnet-version: '7.x'
|
||||
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v1.0.1
|
||||
uses: microsoft/setup-msbuild@v1.3.1
|
||||
|
||||
- name: Setup project secrets
|
||||
run: |
|
||||
@@ -95,7 +95,7 @@ jobs:
|
||||
shell: pwsh
|
||||
|
||||
- name: Publish release
|
||||
uses: Xotl/cool-github-releases@v1.1.7
|
||||
uses: Xotl/cool-github-releases@v1.1.8
|
||||
with:
|
||||
mode: update
|
||||
tag_name: v${{ env.Version }}
|
||||
|
||||
@@ -36,12 +36,12 @@ jobs:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install .NET Core
|
||||
uses: actions/setup-dotnet@v2
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '6.x'
|
||||
dotnet-version: '7.x'
|
||||
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v1.0.1
|
||||
uses: microsoft/setup-msbuild@v1.3.1
|
||||
|
||||
- name: Execute Unit Tests
|
||||
run: dotnet test $env:Test_Project_Path
|
||||
|
||||
@@ -57,7 +57,7 @@ jobs:
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
|
||||
- name: Install .NET Core
|
||||
uses: actions/setup-dotnet@v2
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '6.x'
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>AnyCPU;x86;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -3,15 +3,16 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Platforms>AnyCPU;x86;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.7.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0-preview-20220726-02" />
|
||||
<PackageReference Include="Moq" Version="4.18.2" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
|
||||
<PackageReference Include="coverlet.collector" Version="3.1.2" />
|
||||
<PackageReference Include="FluentAssertions" Version="6.10.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
|
||||
<PackageReference Include="Moq" Version="4.18.4" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="3.0.2" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="3.0.2" />
|
||||
<PackageReference Include="coverlet.collector" Version="3.2.0" />
|
||||
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -5,132 +5,182 @@ using System;
|
||||
using System.Linq;
|
||||
using Version = Daybreak.Models.Versioning.Version;
|
||||
|
||||
namespace Daybreak.Tests.Models
|
||||
namespace Daybreak.Tests.Models;
|
||||
|
||||
[TestClass]
|
||||
public class VersionTests
|
||||
{
|
||||
[TestClass]
|
||||
public class VersionTests
|
||||
[DataRow("v0.1.0.0.1", "v0.1.0.0.1")]
|
||||
[DataRow("v0.1.0.0.1.0.0.0.0", "v0.1.0.0.1")]
|
||||
[DataRow("v0.1.0", "v0.1")]
|
||||
[DataRow("0.1.0", "0.1")]
|
||||
[DataRow("v0.1.0.0.0", "v0.1")]
|
||||
[DataRow("0.1.0.0.0", "0.1")]
|
||||
[DataRow("v0", "v0")]
|
||||
[DataRow("0", "0")]
|
||||
[DataRow("v0.1", "v0.1")]
|
||||
[DataRow("0.1-release", "0.1-release")]
|
||||
[DataRow("v0.1-release", "v0.1-release")]
|
||||
[TestMethod]
|
||||
public void VersionToString(string version, string expectedString)
|
||||
{
|
||||
[DataRow("v0.1.0.0.1", "v0.1.0.0.1")]
|
||||
[DataRow("v0.1.0.0.1.0.0.0.0", "v0.1.0.0.1")]
|
||||
[DataRow("v0.1.0", "v0.1")]
|
||||
[DataRow("0.1.0", "0.1")]
|
||||
[DataRow("v0.1.0.0.0", "v0.1")]
|
||||
[DataRow("0.1.0.0.0", "0.1")]
|
||||
[DataRow("v0", "v0")]
|
||||
[DataRow("0", "0")]
|
||||
[DataRow("v0.1", "v0.1")]
|
||||
[DataRow("0.1-release", "0.1-release")]
|
||||
[DataRow("v0.1-release", "v0.1-release")]
|
||||
[TestMethod]
|
||||
public void VersionToString(string version, string expectedString)
|
||||
{
|
||||
var parsedVersion = Version.Parse(version);
|
||||
parsedVersion.ToString().Should().Be(expectedString);
|
||||
}
|
||||
var parsedVersion = Version.Parse(version);
|
||||
parsedVersion.ToString().Should().Be(expectedString);
|
||||
}
|
||||
|
||||
[DataRow("v0", false)]
|
||||
[DataRow("0", false)]
|
||||
[DataRow("v0.1", false)]
|
||||
[DataRow("0.1-release", true)]
|
||||
[DataRow("v0.1-release", true)]
|
||||
[TestMethod]
|
||||
public void VersionHasStringSuffix(string version, bool hasSuffix)
|
||||
[DataRow("v0", false)]
|
||||
[DataRow("0", false)]
|
||||
[DataRow("v0.1", false)]
|
||||
[DataRow("0.1-release", true)]
|
||||
[DataRow("v0.1-release", true)]
|
||||
[TestMethod]
|
||||
public void VersionHasStringSuffix(string version, bool hasSuffix)
|
||||
{
|
||||
var parsedVersion = Version.Parse(version);
|
||||
if (hasSuffix)
|
||||
{
|
||||
var parsedVersion = Version.Parse(version);
|
||||
if (hasSuffix)
|
||||
{
|
||||
parsedVersion.VersionTokens.Last().Should().BeOfType<VersionStringToken>();
|
||||
}
|
||||
else
|
||||
{
|
||||
parsedVersion.VersionTokens.Last().Should().BeOfType<VersionNumberToken>();
|
||||
}
|
||||
parsedVersion.VersionTokens.Last().Should().BeOfType<VersionStringToken>();
|
||||
}
|
||||
|
||||
[DataRow("v0", true)]
|
||||
[DataRow("0", false)]
|
||||
[DataRow("v0.1", true)]
|
||||
[DataRow("0.1", false)]
|
||||
[TestMethod]
|
||||
public void VersionTokensHasPrefix(string version, bool hasPrefix)
|
||||
else
|
||||
{
|
||||
var parsedVersion = Version.Parse(version);
|
||||
parsedVersion.HasPrefix.Should().Be(hasPrefix);
|
||||
}
|
||||
|
||||
[DataRow(null, false)]
|
||||
[DataRow("", false)]
|
||||
[DataRow("asd", false)]
|
||||
[DataRow("ads.pls.er", false)]
|
||||
[DataRow("0.0.1", true)]
|
||||
[DataRow("1", true)]
|
||||
[DataRow("0.1.asd", false)]
|
||||
[DataRow("0.", false)]
|
||||
[DataRow(".1", false)]
|
||||
[DataRow("0.1-", false)]
|
||||
[DataRow("0.1-release", true)]
|
||||
[DataRow("0..1", false)]
|
||||
[TestMethod]
|
||||
public void TryParseVersionTest(string version, bool result)
|
||||
{
|
||||
var success = Version.TryParse(version, out var parsedVersion);
|
||||
success.Should().Be(result);
|
||||
if (success is true)
|
||||
{
|
||||
parsedVersion.Should().NotBeNull();
|
||||
}
|
||||
}
|
||||
|
||||
[DataRow(null, false)]
|
||||
[DataRow("", false)]
|
||||
[DataRow("asd", false)]
|
||||
[DataRow("ads.pls.er", false)]
|
||||
[DataRow("0.0.1", true)]
|
||||
[DataRow("1", true)]
|
||||
[DataRow("0.1.asd", false)]
|
||||
[DataRow("0.", false)]
|
||||
[DataRow(".1", false)]
|
||||
[DataRow("0.1-", false)]
|
||||
[DataRow("0.1-release", true)]
|
||||
[DataRow("0..1", false)]
|
||||
[TestMethod]
|
||||
public void ParseVersionTest(string version, bool shouldNotThrow)
|
||||
{
|
||||
var action = new Action(() => Version.Parse(version));
|
||||
if (shouldNotThrow is false)
|
||||
{
|
||||
action.Should().Throw<InvalidOperationException>();
|
||||
}
|
||||
else
|
||||
{
|
||||
action.Should().NotThrow<InvalidOperationException>();
|
||||
}
|
||||
}
|
||||
|
||||
[DataRow(null, false)]
|
||||
[DataRow("", false)]
|
||||
[DataRow("asd", false)]
|
||||
[DataRow("ads.pls.er", false)]
|
||||
[DataRow("0.0.1", true)]
|
||||
[DataRow("1", true)]
|
||||
[DataRow("0.1.asd", false)]
|
||||
[DataRow("0.", false)]
|
||||
[DataRow(".1", false)]
|
||||
[DataRow("0.1-", false)]
|
||||
[DataRow("0.1-release", true)]
|
||||
[DataRow("0..1", false)]
|
||||
[TestMethod]
|
||||
public void VersionConstructorTest(string version, bool shouldNotThrow)
|
||||
{
|
||||
var action = new Action(() => new Version(version));
|
||||
if (shouldNotThrow is false)
|
||||
{
|
||||
action.Should().Throw<ArgumentException>();
|
||||
}
|
||||
else
|
||||
{
|
||||
action.Should().NotThrow<ArgumentException>();
|
||||
}
|
||||
parsedVersion.VersionTokens.Last().Should().BeOfType<VersionNumberToken>();
|
||||
}
|
||||
}
|
||||
|
||||
[DataRow("v0", true)]
|
||||
[DataRow("0", false)]
|
||||
[DataRow("v0.1", true)]
|
||||
[DataRow("0.1", false)]
|
||||
[TestMethod]
|
||||
public void VersionTokensHasPrefix(string version, bool hasPrefix)
|
||||
{
|
||||
var parsedVersion = Version.Parse(version);
|
||||
parsedVersion.HasPrefix.Should().Be(hasPrefix);
|
||||
}
|
||||
|
||||
[DataRow(null, false)]
|
||||
[DataRow("", false)]
|
||||
[DataRow("asd", false)]
|
||||
[DataRow("ads.pls.er", false)]
|
||||
[DataRow("0.0.1", true)]
|
||||
[DataRow("1", true)]
|
||||
[DataRow("0.1.asd", false)]
|
||||
[DataRow("0.", false)]
|
||||
[DataRow(".1", false)]
|
||||
[DataRow("0.1-", false)]
|
||||
[DataRow("0.1-release", true)]
|
||||
[DataRow("0..1", false)]
|
||||
[TestMethod]
|
||||
public void TryParseVersionTest(string version, bool result)
|
||||
{
|
||||
var success = Version.TryParse(version, out var parsedVersion);
|
||||
success.Should().Be(result);
|
||||
if (success is true)
|
||||
{
|
||||
parsedVersion.Should().NotBeNull();
|
||||
}
|
||||
}
|
||||
|
||||
[DataRow(null, false)]
|
||||
[DataRow("", false)]
|
||||
[DataRow("asd", false)]
|
||||
[DataRow("ads.pls.er", false)]
|
||||
[DataRow("0.0.1", true)]
|
||||
[DataRow("1", true)]
|
||||
[DataRow("0.1.asd", false)]
|
||||
[DataRow("0.", false)]
|
||||
[DataRow(".1", false)]
|
||||
[DataRow("0.1-", false)]
|
||||
[DataRow("0.1-release", true)]
|
||||
[DataRow("0..1", false)]
|
||||
[TestMethod]
|
||||
public void ParseVersionTest(string version, bool shouldNotThrow)
|
||||
{
|
||||
var action = new Action(() => Version.Parse(version));
|
||||
if (shouldNotThrow is false)
|
||||
{
|
||||
action.Should().Throw<InvalidOperationException>();
|
||||
}
|
||||
else
|
||||
{
|
||||
action.Should().NotThrow<InvalidOperationException>();
|
||||
}
|
||||
}
|
||||
|
||||
[DataRow(null, false)]
|
||||
[DataRow("", false)]
|
||||
[DataRow("asd", false)]
|
||||
[DataRow("ads.pls.er", false)]
|
||||
[DataRow("0.0.1", true)]
|
||||
[DataRow("1", true)]
|
||||
[DataRow("0.1.asd", false)]
|
||||
[DataRow("0.", false)]
|
||||
[DataRow(".1", false)]
|
||||
[DataRow("0.1-", false)]
|
||||
[DataRow("0.1-release", true)]
|
||||
[DataRow("0..1", false)]
|
||||
[TestMethod]
|
||||
public void VersionConstructorTest(string version, bool shouldNotThrow)
|
||||
{
|
||||
var action = new Action(() => new Version(version));
|
||||
if (shouldNotThrow is false)
|
||||
{
|
||||
action.Should().Throw<ArgumentException>();
|
||||
}
|
||||
else
|
||||
{
|
||||
action.Should().NotThrow<ArgumentException>();
|
||||
}
|
||||
}
|
||||
|
||||
[DataRow("v0.1.0.0.1", "v0.1.0.0.1", true)]
|
||||
[DataRow("v0.1.0.0.1.0.0.0.0", "v0.1.0.0.1", true)]
|
||||
[DataRow("v0.1.0", "v0.1", true)]
|
||||
[DataRow("0.1.0", "0.1", true)]
|
||||
[DataRow("v0.1.0.0.0", "v0.1", true)]
|
||||
[DataRow("0.1.0.0.0", "0.1", true)]
|
||||
[DataRow("v0", "v0", true)]
|
||||
[DataRow("0", "0", true)]
|
||||
[DataRow("v0.1", "v0.1", true)]
|
||||
[DataRow("0.1-release", "0.1-release", true)]
|
||||
[DataRow("v0.1-release", "v0.1-release", true)]
|
||||
[DataRow("v0.1.0.0", "v0.1.0.0.1", false)]
|
||||
[DataRow("v0.1.0.0.1", "v0.1.0.0", false)]
|
||||
[DataRow("v0.9.8.9", "v0.9.8.10", false)]
|
||||
[DataRow("0.1-release", "0.2-release", false)]
|
||||
[DataRow("v1.1-release", "v0.1-release", false)]
|
||||
[TestMethod]
|
||||
public void Equals(string version, string version2, bool result)
|
||||
{
|
||||
var parsedVersion1 = Version.Parse(version);
|
||||
var parsedVersion2 = Version.Parse(version2);
|
||||
|
||||
parsedVersion1.Equals(parsedVersion2).Should().Be(result);
|
||||
}
|
||||
|
||||
[DataRow("v0.1.0.0.1", "v0.1.0.0.1", 0)]
|
||||
[DataRow("v0.1.0.0.1.0.0.0.0", "v0.1.0.0.1", 0)]
|
||||
[DataRow("v0.1.0", "v0.1", 0)]
|
||||
[DataRow("0.1.0", "0.1", 0)]
|
||||
[DataRow("v0.1.0.0.0", "v0.1", 0)]
|
||||
[DataRow("0.1.0.0.0", "0.1", 0)]
|
||||
[DataRow("v0", "v0", 0)]
|
||||
[DataRow("0", "0", 0)]
|
||||
[DataRow("v0.1", "v0.1", 0)]
|
||||
[DataRow("0.1-release", "0.1-release", 0)]
|
||||
[DataRow("v0.1-release", "v0.1-release", 0)]
|
||||
[DataRow("v0.1.0.0", "v0.1.0.0.1", -1)]
|
||||
[DataRow("v0.1.0.0.1", "v0.1.0.0", 1)]
|
||||
[DataRow("v0.9.8.9", "v0.9.8.10", -1)]
|
||||
[DataRow("v0.9.8.10", "v0.9.8.9", 1)]
|
||||
[DataRow("0.1-release", "0.2-release", -1)]
|
||||
[DataRow("v1.1-release", "v0.1-release", 1)]
|
||||
[TestMethod]
|
||||
public void CompareTo(string version, string version2, int comparisonResult)
|
||||
{
|
||||
var parsedVersion1 = Version.Parse(version);
|
||||
var parsedVersion2 = Version.Parse(version2);
|
||||
|
||||
parsedVersion1.CompareTo(parsedVersion2).Should().Be(comparisonResult);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
using Daybreak.Configuration;
|
||||
using Daybreak.Services.Configuration;
|
||||
using Daybreak.Services.Options;
|
||||
using FluentAssertions;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using System;
|
||||
|
||||
namespace Daybreak.Tests.Services
|
||||
{
|
||||
[TestClass]
|
||||
public class ApplicationConfigurationOptionsManagerTests
|
||||
{
|
||||
private ApplicationConfigurationOptionsManager applicationConfigurationOptionsManager;
|
||||
|
||||
[TestInitialize]
|
||||
public void TestInitialize()
|
||||
{
|
||||
var configurationManagerMock = new Mock<IConfigurationManager>();
|
||||
configurationManagerMock
|
||||
.Setup(u => u.GetConfiguration())
|
||||
.Returns(new ApplicationConfiguration());
|
||||
|
||||
this.applicationConfigurationOptionsManager = new ApplicationConfigurationOptionsManager(configurationManagerMock.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetApplicationConfiguration_ReturnsObject()
|
||||
{
|
||||
var config = this.applicationConfigurationOptionsManager.GetOptions<ApplicationConfiguration>();
|
||||
|
||||
config.Should().NotBeNull();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetOtherOptions_ThrowsInvalidOperationException()
|
||||
{
|
||||
var action = new Action(() =>
|
||||
{
|
||||
this.applicationConfigurationOptionsManager.GetOptions<object>();
|
||||
});
|
||||
|
||||
action.Should().Throw<InvalidOperationException>();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void UpdateOptions_OnApplicationConfiguration_Succeeds()
|
||||
{
|
||||
this.applicationConfigurationOptionsManager.UpdateOptions(new ApplicationConfiguration());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void UpdateOptions_OnOthers_ThrowsInvalidOperationException()
|
||||
{
|
||||
var action = new Action(() =>
|
||||
{
|
||||
this.applicationConfigurationOptionsManager.UpdateOptions(new object());
|
||||
});
|
||||
|
||||
action.Should().Throw<InvalidOperationException>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using Daybreak.Models.Builds;
|
||||
using Daybreak.Models.Guildwars;
|
||||
using Daybreak.Services.BuildTemplates;
|
||||
using FluentAssertions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -6,91 +7,90 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Daybreak.Tests.Services
|
||||
namespace Daybreak.Tests.Services;
|
||||
|
||||
[TestClass]
|
||||
public class BuildTemplateManagerTests
|
||||
{
|
||||
[TestClass]
|
||||
public class BuildTemplateManagerTests
|
||||
private const string EncodedTemplate = "OwBk0texXNu0Dj/z+TDzBj+TN4AE";
|
||||
private IBuildTemplateManager buildTemplateManager;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
private const string EncodedTemplate = "OwBk0texXNu0Dj/z+TDzBj+TN4AE";
|
||||
private IBuildTemplateManager buildTemplateManager;
|
||||
this.buildTemplateManager = new BuildTemplateManager(new Mock<ILogger<BuildTemplateManager>>().Object);
|
||||
}
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
this.buildTemplateManager = new BuildTemplateManager(new Mock<ILogger<BuildTemplateManager>>().Object);
|
||||
}
|
||||
[TestMethod]
|
||||
public void TestDecode()
|
||||
{
|
||||
var build = this.buildTemplateManager.DecodeTemplate(EncodedTemplate);
|
||||
build.Primary.Should().Be(Profession.Assassin);
|
||||
build.Secondary.Should().Be(Profession.None);
|
||||
build.Attributes.Count.Should().Be(4);
|
||||
build.Attributes[1].Attribute.Should().Be(Attribute.DaggerMastery);
|
||||
build.Attributes[1].Points.Should().Be(11);
|
||||
build.Attributes[2].Attribute.Should().Be(Attribute.DeadlyArts);
|
||||
build.Attributes[2].Points.Should().Be(1);
|
||||
build.Attributes[3].Attribute.Should().Be(Attribute.ShadowArts);
|
||||
build.Attributes[3].Points.Should().Be(5);
|
||||
build.Attributes[0].Attribute.Should().Be(Attribute.CriticalStrikes);
|
||||
build.Attributes[0].Points.Should().Be(11);
|
||||
build.Skills.Count.Should().Be(8);
|
||||
build.Skills[0].Should().Be(Skill.UnsuspectingStrike);
|
||||
build.Skills[1].Should().Be(Skill.WildStrike);
|
||||
build.Skills[2].Should().Be(Skill.CriticalStrike);
|
||||
build.Skills[3].Should().Be(Skill.MoebiusStrike);
|
||||
build.Skills[4].Should().Be(Skill.DeathBlossom);
|
||||
build.Skills[5].Should().Be(Skill.CriticalEye);
|
||||
build.Skills[6].Should().Be(Skill.CriticalAgility);
|
||||
build.Skills[7].Should().Be(Skill.CriticalDefenses);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestDecode()
|
||||
[TestMethod]
|
||||
public void TestEncode()
|
||||
{
|
||||
var build = new Build()
|
||||
{
|
||||
var build = this.buildTemplateManager.DecodeTemplate(EncodedTemplate);
|
||||
build.Primary.Should().Be(Profession.Assassin);
|
||||
build.Secondary.Should().Be(Profession.None);
|
||||
build.Attributes.Count.Should().Be(4);
|
||||
build.Attributes[0].Attribute.Should().Be(Attribute.DaggerMastery);
|
||||
build.Attributes[0].Points.Should().Be(11);
|
||||
build.Attributes[1].Attribute.Should().Be(Attribute.DeadlyArts);
|
||||
build.Attributes[1].Points.Should().Be(1);
|
||||
build.Attributes[2].Attribute.Should().Be(Attribute.ShadowArts);
|
||||
build.Attributes[2].Points.Should().Be(5);
|
||||
build.Attributes[3].Attribute.Should().Be(Attribute.CriticalStrikes);
|
||||
build.Attributes[3].Points.Should().Be(11);
|
||||
build.Skills.Count.Should().Be(8);
|
||||
build.Skills[0].Should().Be(Skill.UnsuspectingStrike);
|
||||
build.Skills[1].Should().Be(Skill.WildStrike);
|
||||
build.Skills[2].Should().Be(Skill.CriticalStrike);
|
||||
build.Skills[3].Should().Be(Skill.MoebiusStrike);
|
||||
build.Skills[4].Should().Be(Skill.DeathBlossom);
|
||||
build.Skills[5].Should().Be(Skill.CriticalEye);
|
||||
build.Skills[6].Should().Be(Skill.CriticalAgility);
|
||||
build.Skills[7].Should().Be(Skill.CriticalDefenses);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestEncode()
|
||||
{
|
||||
var build = new Build()
|
||||
Primary = Profession.Assassin,
|
||||
Secondary = Profession.None,
|
||||
Attributes = new List<AttributeEntry>
|
||||
{
|
||||
Primary = Profession.Assassin,
|
||||
Secondary = Profession.None,
|
||||
Attributes = new List<AttributeEntry>
|
||||
new AttributeEntry
|
||||
{
|
||||
new AttributeEntry
|
||||
{
|
||||
Attribute = Attribute.DaggerMastery,
|
||||
Points = 11
|
||||
},
|
||||
new AttributeEntry
|
||||
{
|
||||
Attribute = Attribute.DeadlyArts,
|
||||
Points = 1
|
||||
},
|
||||
new AttributeEntry
|
||||
{
|
||||
Attribute = Attribute.ShadowArts,
|
||||
Points = 5
|
||||
},
|
||||
new AttributeEntry
|
||||
{
|
||||
Attribute = Attribute.CriticalStrikes,
|
||||
Points = 11
|
||||
}
|
||||
Attribute = Attribute.DaggerMastery,
|
||||
Points = 11
|
||||
},
|
||||
Skills = new List<Skill>
|
||||
new AttributeEntry
|
||||
{
|
||||
Skill.UnsuspectingStrike,
|
||||
Skill.WildStrike,
|
||||
Skill.CriticalStrike,
|
||||
Skill.MoebiusStrike,
|
||||
Skill.DeathBlossom,
|
||||
Skill.CriticalEye,
|
||||
Skill.CriticalAgility,
|
||||
Skill.CriticalDefenses
|
||||
Attribute = Attribute.DeadlyArts,
|
||||
Points = 1
|
||||
},
|
||||
new AttributeEntry
|
||||
{
|
||||
Attribute = Attribute.ShadowArts,
|
||||
Points = 5
|
||||
},
|
||||
new AttributeEntry
|
||||
{
|
||||
Attribute = Attribute.CriticalStrikes,
|
||||
Points = 11
|
||||
}
|
||||
};
|
||||
},
|
||||
Skills = new List<Skill>
|
||||
{
|
||||
Skill.UnsuspectingStrike,
|
||||
Skill.WildStrike,
|
||||
Skill.CriticalStrike,
|
||||
Skill.MoebiusStrike,
|
||||
Skill.DeathBlossom,
|
||||
Skill.CriticalEye,
|
||||
Skill.CriticalAgility,
|
||||
Skill.CriticalDefenses
|
||||
}
|
||||
};
|
||||
|
||||
var encoded = this.buildTemplateManager.EncodeTemplate(build);
|
||||
encoded.Should().Be(EncodedTemplate);
|
||||
}
|
||||
var encoded = this.buildTemplateManager.EncodeTemplate(build);
|
||||
encoded.Should().Be(EncodedTemplate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,68 +7,67 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Logging;
|
||||
|
||||
namespace Daybreak.Tests.Services
|
||||
namespace Daybreak.Tests.Services;
|
||||
|
||||
[TestClass]
|
||||
public class JsonLoggerProviderTests
|
||||
{
|
||||
[TestClass]
|
||||
public class JsonLoggerProviderTests
|
||||
private ILogsManager logsManager;
|
||||
private ILoggerProvider loggerProvider;
|
||||
private ILiteDatabase liteDatabase;
|
||||
|
||||
[TestInitialize]
|
||||
public void InitializeProvider()
|
||||
{
|
||||
private ILogsManager logsManager;
|
||||
private ILoggerProvider loggerProvider;
|
||||
private ILiteDatabase liteDatabase;
|
||||
File.Delete("Daybreak.db");
|
||||
this.liteDatabase = new LiteDatabase("Daybreak.db");
|
||||
this.logsManager = new JsonLogsManager(this.liteDatabase);
|
||||
this.loggerProvider = new CVLoggerProvider(this.logsManager);
|
||||
}
|
||||
|
||||
[TestInitialize]
|
||||
public void InitializeProvider()
|
||||
{
|
||||
File.Delete("Daybreak.db");
|
||||
this.liteDatabase = new LiteDatabase("Daybreak.db");
|
||||
this.logsManager = new JsonLogsManager(this.liteDatabase);
|
||||
this.loggerProvider = new CVLoggerProvider(this.logsManager);
|
||||
}
|
||||
[TestCleanup]
|
||||
public void TestCleanup()
|
||||
{
|
||||
this.liteDatabase.Dispose();
|
||||
}
|
||||
|
||||
[TestCleanup]
|
||||
public void TestCleanup()
|
||||
{
|
||||
this.liteDatabase.Dispose();
|
||||
}
|
||||
[TestMethod]
|
||||
public void CreateLoggerReturnsLogger()
|
||||
{
|
||||
var logger = this.loggerProvider.CreateLogger("SomeCategory");
|
||||
logger.Should().NotBeNull();
|
||||
}
|
||||
[TestMethod]
|
||||
public void LoggerLogsAndReaderReadsFiltered()
|
||||
{
|
||||
var logger = this.loggerProvider.CreateLogger("SomeCategory");
|
||||
logger.LogTrace("Logging some trace");
|
||||
logger.LogInformation("Logging some stuff");
|
||||
logger.LogError("Logging some error");
|
||||
|
||||
[TestMethod]
|
||||
public void CreateLoggerReturnsLogger()
|
||||
{
|
||||
var logger = this.loggerProvider.CreateLogger("SomeCategory");
|
||||
logger.Should().NotBeNull();
|
||||
}
|
||||
[TestMethod]
|
||||
public void LoggerLogsAndReaderReadsFiltered()
|
||||
{
|
||||
var logger = this.loggerProvider.CreateLogger("SomeCategory");
|
||||
logger.LogTrace("Logging some trace");
|
||||
logger.LogInformation("Logging some stuff");
|
||||
logger.LogError("Logging some error");
|
||||
this.logsManager.GetLogs(l => l.LogLevel < LogLevel.Information).Should().HaveCount(1);
|
||||
var log = this.logsManager.GetLogs(l => l.LogLevel < LogLevel.Information).First();
|
||||
log.LogLevel.Should().Be(LogLevel.Error);
|
||||
}
|
||||
[TestMethod]
|
||||
public void LoggerLogsAndReaderReads()
|
||||
{
|
||||
var logger = this.loggerProvider.CreateLogger("SomeCategory");
|
||||
logger.LogInformation("Logging some stuff");
|
||||
logger.LogError("Logging some error");
|
||||
|
||||
this.logsManager.GetLogs(l => l.LogLevel < LogLevel.Information).Should().HaveCount(1);
|
||||
var log = this.logsManager.GetLogs(l => l.LogLevel < LogLevel.Information).First();
|
||||
log.LogLevel.Should().Be(LogLevel.Error);
|
||||
}
|
||||
[TestMethod]
|
||||
public void LoggerLogsAndReaderReads()
|
||||
{
|
||||
var logger = this.loggerProvider.CreateLogger("SomeCategory");
|
||||
logger.LogInformation("Logging some stuff");
|
||||
logger.LogError("Logging some error");
|
||||
this.logsManager.GetLogs().Should().HaveCount(2);
|
||||
}
|
||||
[TestMethod]
|
||||
public void DeletingLogsShouldDeleteLogs()
|
||||
{
|
||||
var logger = this.loggerProvider.CreateLogger("SomeCategory");
|
||||
logger.LogInformation("Logging some stuff");
|
||||
logger.LogError("Logging some error");
|
||||
|
||||
this.logsManager.GetLogs().Should().HaveCount(2);
|
||||
}
|
||||
[TestMethod]
|
||||
public void DeletingLogsShouldDeleteLogs()
|
||||
{
|
||||
var logger = this.loggerProvider.CreateLogger("SomeCategory");
|
||||
logger.LogInformation("Logging some stuff");
|
||||
logger.LogError("Logging some error");
|
||||
this.logsManager.GetLogs().Should().HaveCount(2);
|
||||
|
||||
this.logsManager.GetLogs().Should().HaveCount(2);
|
||||
|
||||
this.logsManager.DeleteLogs();
|
||||
this.logsManager.GetLogs().Should().HaveCount(0);
|
||||
}
|
||||
this.logsManager.DeleteLogs();
|
||||
this.logsManager.GetLogs().Should().HaveCount(0);
|
||||
}
|
||||
}
|
||||
|
||||
+26
-12
@@ -35,34 +35,48 @@ Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Debug|x64.Build.0 = Debug|x64
|
||||
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Debug|x86.Build.0 = Debug|x86
|
||||
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Release|x64.Build.0 = Release|Any CPU
|
||||
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Release|x64.ActiveCfg = Release|x64
|
||||
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Release|x64.Build.0 = Release|x64
|
||||
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Release|x86.ActiveCfg = Release|x86
|
||||
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Release|x86.Build.0 = Release|x86
|
||||
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Debug|x64.Build.0 = Debug|x64
|
||||
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Debug|x86.Build.0 = Debug|x86
|
||||
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Release|x64.Build.0 = Release|Any CPU
|
||||
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Release|x64.ActiveCfg = Release|x64
|
||||
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Release|x64.Build.0 = Release|x64
|
||||
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Release|x86.ActiveCfg = Release|x86
|
||||
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Release|x86.Build.0 = Release|x86
|
||||
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Debug|x64.Build.0 = Debug|x64
|
||||
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Debug|x86.Build.0 = Debug|x86
|
||||
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Release|x64.Build.0 = Release|Any CPU
|
||||
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Release|x64.ActiveCfg = Release|x64
|
||||
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Release|x64.Build.0 = Release|x64
|
||||
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Release|x86.ActiveCfg = Release|x86
|
||||
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace Daybreak.Attributes;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public sealed class OptionsNameAttribute : Attribute
|
||||
{
|
||||
public string? Name { get; init; }
|
||||
}
|
||||
@@ -6,74 +6,73 @@ using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Daybreak.Behaviors
|
||||
namespace Daybreak.Behaviors;
|
||||
|
||||
public class ScaleFontWithSize : Behavior<TextBlock>
|
||||
{
|
||||
public class ScaleFontWithSize : Behavior<TextBlock>
|
||||
public static readonly DependencyProperty MaxFontSizeProperty = DependencyProperty.Register("MaxFontSize", typeof(double), typeof(ScaleFontWithSize), new PropertyMetadata(12d));
|
||||
|
||||
public double MaxFontSize
|
||||
{
|
||||
public static readonly DependencyProperty MaxFontSizeProperty = DependencyProperty.Register("MaxFontSize", typeof(double), typeof(ScaleFontWithSize), new PropertyMetadata(12d));
|
||||
|
||||
public double MaxFontSize
|
||||
get
|
||||
{
|
||||
get
|
||||
{
|
||||
return (double)this.GetValue(MaxFontSizeProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
this.SetValue(MaxFontSizeProperty, value);
|
||||
}
|
||||
return (double)this.GetValue(MaxFontSizeProperty);
|
||||
}
|
||||
|
||||
protected override void OnAttached()
|
||||
set
|
||||
{
|
||||
base.OnAttached();
|
||||
this.AssociatedObject.SizeChanged += (_, __) => this.CalculateFontSize();
|
||||
DependencyPropertyDescriptor.FromProperty(
|
||||
TextBlock.TextProperty, typeof(TextBlock)).AddValueChanged(this.AssociatedObject, (_, __) => this.CalculateFontSize());
|
||||
DependencyPropertyDescriptor.FromProperty(
|
||||
TextBlock.FontSizeProperty, typeof(TextBlock)).AddValueChanged(this.AssociatedObject, (_, __) => this.CalculateFontSize());
|
||||
}
|
||||
|
||||
private void CalculateFontSize()
|
||||
{
|
||||
var textMeasurement = this.MeasureText(this.AssociatedObject.FontSize);
|
||||
var maximumTextMeasurement = this.MeasureText(this.MaxFontSize);
|
||||
var desiredWidthFontSize = this.MaxFontSize;
|
||||
var desiredHeightFontSize = this.MaxFontSize;
|
||||
|
||||
if (Math.Round(textMeasurement.Height) != Math.Round(this.AssociatedObject.ActualHeight))
|
||||
{
|
||||
|
||||
var scale = this.AssociatedObject.ActualHeight / maximumTextMeasurement.Height;
|
||||
desiredHeightFontSize = (this.MaxFontSize * scale) - 1;
|
||||
desiredHeightFontSize = desiredHeightFontSize <= this.MaxFontSize ? desiredHeightFontSize : this.MaxFontSize;
|
||||
}
|
||||
|
||||
if (Math.Round(textMeasurement.Width) != Math.Round(this.AssociatedObject.ActualWidth))
|
||||
{
|
||||
var scale = this.AssociatedObject.ActualWidth / maximumTextMeasurement.Width;
|
||||
desiredWidthFontSize = (this.MaxFontSize * scale) - 1;
|
||||
desiredWidthFontSize = desiredWidthFontSize <= this.MaxFontSize ? desiredWidthFontSize : this.MaxFontSize;
|
||||
|
||||
}
|
||||
|
||||
var desiredFontSize = Math.Min(desiredHeightFontSize, desiredWidthFontSize);
|
||||
|
||||
if ((int)desiredFontSize != (int)this.AssociatedObject.FontSize && desiredFontSize > 0)
|
||||
{
|
||||
this.AssociatedObject.FontSize = desiredFontSize;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private Size MeasureText(double fontSize)
|
||||
{
|
||||
var formattedText = new FormattedText(this.AssociatedObject.Text, CultureInfo.CurrentUICulture,
|
||||
FlowDirection.LeftToRight,
|
||||
new Typeface(this.AssociatedObject.FontFamily, this.AssociatedObject.FontStyle, this.AssociatedObject.FontWeight, this.AssociatedObject.FontStretch),
|
||||
fontSize, Brushes.Black, VisualTreeHelper.GetDpi(this.AssociatedObject).PixelsPerDip);
|
||||
|
||||
return new Size(formattedText.Width, formattedText.Height);
|
||||
this.SetValue(MaxFontSizeProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnAttached()
|
||||
{
|
||||
base.OnAttached();
|
||||
this.AssociatedObject.SizeChanged += (_, __) => this.CalculateFontSize();
|
||||
DependencyPropertyDescriptor.FromProperty(
|
||||
TextBlock.TextProperty, typeof(TextBlock)).AddValueChanged(this.AssociatedObject, (_, __) => this.CalculateFontSize());
|
||||
DependencyPropertyDescriptor.FromProperty(
|
||||
TextBlock.FontSizeProperty, typeof(TextBlock)).AddValueChanged(this.AssociatedObject, (_, __) => this.CalculateFontSize());
|
||||
}
|
||||
|
||||
private void CalculateFontSize()
|
||||
{
|
||||
var textMeasurement = this.MeasureText(this.AssociatedObject.FontSize);
|
||||
var maximumTextMeasurement = this.MeasureText(this.MaxFontSize);
|
||||
var desiredWidthFontSize = this.MaxFontSize;
|
||||
var desiredHeightFontSize = this.MaxFontSize;
|
||||
|
||||
if (Math.Round(textMeasurement.Height) != Math.Round(this.AssociatedObject.ActualHeight))
|
||||
{
|
||||
|
||||
var scale = this.AssociatedObject.ActualHeight / maximumTextMeasurement.Height;
|
||||
desiredHeightFontSize = (this.MaxFontSize * scale) - 1;
|
||||
desiredHeightFontSize = desiredHeightFontSize <= this.MaxFontSize ? desiredHeightFontSize : this.MaxFontSize;
|
||||
}
|
||||
|
||||
if (Math.Round(textMeasurement.Width) != Math.Round(this.AssociatedObject.ActualWidth))
|
||||
{
|
||||
var scale = this.AssociatedObject.ActualWidth / maximumTextMeasurement.Width;
|
||||
desiredWidthFontSize = (this.MaxFontSize * scale) - 1;
|
||||
desiredWidthFontSize = desiredWidthFontSize <= this.MaxFontSize ? desiredWidthFontSize : this.MaxFontSize;
|
||||
|
||||
}
|
||||
|
||||
var desiredFontSize = Math.Min(desiredHeightFontSize, desiredWidthFontSize);
|
||||
|
||||
if ((int)desiredFontSize != (int)this.AssociatedObject.FontSize && desiredFontSize > 0)
|
||||
{
|
||||
this.AssociatedObject.FontSize = desiredFontSize;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private Size MeasureText(double fontSize)
|
||||
{
|
||||
var formattedText = new FormattedText(this.AssociatedObject.Text, CultureInfo.CurrentUICulture,
|
||||
FlowDirection.LeftToRight,
|
||||
new Typeface(this.AssociatedObject.FontFamily, this.AssociatedObject.FontStyle, this.AssociatedObject.FontWeight, this.AssociatedObject.FontStretch),
|
||||
fontSize, Brushes.Black, VisualTreeHelper.GetDpi(this.AssociatedObject).PixelsPerDip);
|
||||
|
||||
return new Size(formattedText.Width, formattedText.Height);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,53 +3,52 @@ using System;
|
||||
using System.Extensions;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Behaviors
|
||||
{
|
||||
public class ScrollIntoView : Behavior<ListView>
|
||||
{
|
||||
/// <summary>
|
||||
/// When Beahvior is attached
|
||||
/// </summary>
|
||||
protected override void OnAttached()
|
||||
{
|
||||
base.OnAttached();
|
||||
this.AssociatedObject.SelectionChanged += this.AssociatedObject_SelectionChanged;
|
||||
}
|
||||
namespace Daybreak.Behaviors;
|
||||
|
||||
/// <summary>
|
||||
/// On Selection Changed
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
void AssociatedObject_SelectionChanged(object sender,
|
||||
SelectionChangedEventArgs e)
|
||||
public class ScrollIntoView : Behavior<ListView>
|
||||
{
|
||||
/// <summary>
|
||||
/// When Beahvior is attached
|
||||
/// </summary>
|
||||
protected override void OnAttached()
|
||||
{
|
||||
base.OnAttached();
|
||||
this.AssociatedObject.SelectionChanged += this.AssociatedObject_SelectionChanged;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On Selection Changed
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
void AssociatedObject_SelectionChanged(object sender,
|
||||
SelectionChangedEventArgs e)
|
||||
{
|
||||
if (sender is ListView)
|
||||
{
|
||||
if (sender is ListView)
|
||||
var listView = sender.As<ListView>();
|
||||
if (listView.SelectedItem != null)
|
||||
{
|
||||
var listView = sender.As<ListView>();
|
||||
if (listView.SelectedItem != null)
|
||||
{
|
||||
listView.Dispatcher.BeginInvoke(
|
||||
(Action)(() =>
|
||||
{
|
||||
listView.UpdateLayout();
|
||||
if (listView.SelectedItem !=
|
||||
null)
|
||||
listView.ScrollIntoView(
|
||||
listView.SelectedItem);
|
||||
}));
|
||||
}
|
||||
listView.Dispatcher.BeginInvoke(
|
||||
(Action)(() =>
|
||||
{
|
||||
listView.UpdateLayout();
|
||||
if (listView.SelectedItem !=
|
||||
null)
|
||||
listView.ScrollIntoView(
|
||||
listView.SelectedItem);
|
||||
}));
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// When behavior is detached
|
||||
/// </summary>
|
||||
protected override void OnDetaching()
|
||||
{
|
||||
base.OnDetaching();
|
||||
this.AssociatedObject.SelectionChanged -=
|
||||
this.AssociatedObject_SelectionChanged;
|
||||
}
|
||||
/// <summary>
|
||||
/// When behavior is detached
|
||||
/// </summary>
|
||||
protected override void OnDetaching()
|
||||
{
|
||||
base.OnDetaching();
|
||||
this.AssociatedObject.SelectionChanged -=
|
||||
this.AssociatedObject_SelectionChanged;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
using Daybreak.Models;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Daybreak.Configuration
|
||||
{
|
||||
public sealed class ApplicationConfiguration
|
||||
{
|
||||
[JsonProperty("SetGuildwarsWindowSizeOnLaunch")]
|
||||
public bool SetGuildwarsWindowSizeOnLaunch { get; set; }
|
||||
[JsonProperty("DesiredGuildwarsScreen")]
|
||||
public int DesiredGuildwarsScreen { get; set; }
|
||||
[JsonProperty("BrowsersEnabled")]
|
||||
public bool BrowsersEnabled { get; set; } = true;
|
||||
[JsonProperty("ToolboxPath")]
|
||||
public string ToolboxPath { get; set; }
|
||||
[JsonProperty("TexmodPath")]
|
||||
public string TexmodPath { get; set; }
|
||||
[JsonProperty("ToolboxAutoLaunch")]
|
||||
public bool ToolboxAutoLaunch { get; set; }
|
||||
[JsonProperty("LeftBrowserDefault")]
|
||||
public string LeftBrowserDefault { get; set; } = "https://gwpvx.fandom.com/wiki/PvX_wiki";
|
||||
[JsonProperty("RightBrowserDefault")]
|
||||
public string RightBrowserDefault { get; set; } = "https://wiki.guildwars.com/wiki/Quick_access_links";
|
||||
[JsonProperty("GuildwarsPaths")]
|
||||
public List<GuildwarsPath> GuildwarsPaths { get; set; } = new();
|
||||
[JsonProperty("ProtectedLoginCredentials")]
|
||||
public List<ProtectedLoginCredentials> ProtectedLoginCredentials { get; set; } = new();
|
||||
[JsonProperty("AddressBarReadonly")]
|
||||
public bool AddressBarReadonly { get; set; } = true;
|
||||
[JsonProperty("ExperimentalFeatures")]
|
||||
public ExperimentalFeatures ExperimentalFeatures { get; set; } = new();
|
||||
[JsonProperty("ShortcutLocation")]
|
||||
public string ShortcutLocation { get; set; } = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
|
||||
[JsonProperty("PlaceShortcut")]
|
||||
public bool PlaceShortcut { get; set; }
|
||||
[JsonProperty("AutoCheckUpdate")]
|
||||
public bool AutoCheckUpdate { get; set; } = true;
|
||||
[JsonProperty("ProtectedGraphAccessToken")]
|
||||
public string ProtectedGraphAccessToken { get; set; }
|
||||
[JsonProperty("ProtectedGraphRefreshToken")]
|
||||
public string ProtectedGraphRefreshToken { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
using Daybreak.Models;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Daybreak.Configuration
|
||||
{
|
||||
public sealed class ExperimentalFeatures
|
||||
{
|
||||
[JsonProperty("MultiLaunchSupport")]
|
||||
public bool MultiLaunchSupport { get; set; }
|
||||
[JsonProperty("ToolboxAutoLaunchDelay")]
|
||||
public int ToolboxAutoLaunchDelay { get; set; } = 5000;
|
||||
[JsonProperty("DynamicBuildLoading")]
|
||||
public bool DynamicBuildLoading { get; set; } = true;
|
||||
[JsonProperty("LaunchGuildwarsAsCurrentUser")]
|
||||
public bool LaunchGuildwarsAsCurrentUser { get; set; } = true;
|
||||
[JsonProperty("CanInterceptKeys")]
|
||||
public bool CanInterceptKeys { get; set; }
|
||||
[JsonProperty("DownloadIcons")]
|
||||
public bool DownloadIcons { get; set; }
|
||||
[JsonProperty("Macros")]
|
||||
public List<KeyMacro> Macros { get; set; } = new();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Daybreak.Configuration.FocusView;
|
||||
|
||||
public enum ExperienceDisplay
|
||||
{
|
||||
TotalCurretAndTotalMax,
|
||||
CurrentLevelCurrentAndCurrentLevelMax,
|
||||
RemainingUntilNextLevel,
|
||||
Percentage
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Daybreak.Configuration.FocusView;
|
||||
|
||||
public enum PointsDisplay
|
||||
{
|
||||
CurrentAndMax,
|
||||
Remaining,
|
||||
Percentage
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using Daybreak.Attributes;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Daybreak.Configuration.Options;
|
||||
|
||||
[OptionsName(Name = "Browser")]
|
||||
public sealed class BrowserOptions
|
||||
{
|
||||
[JsonProperty(nameof(Enabled))]
|
||||
public bool Enabled { get; set; } = true;
|
||||
|
||||
[JsonProperty(nameof(AddressBarReadonly))]
|
||||
public bool AddressBarReadonly { get; set; } = true;
|
||||
|
||||
[JsonProperty(nameof(DynamicBuildLoading))]
|
||||
public bool DynamicBuildLoading { get; set; } = true;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using Daybreak.Attributes;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Daybreak.Configuration.Options;
|
||||
|
||||
[OptionsName(Name = "Build Synchronization")]
|
||||
public sealed class BuildSynchronizationOptions
|
||||
{
|
||||
[JsonProperty(nameof(ProtectedGraphAccessToken))]
|
||||
public string? ProtectedGraphAccessToken { get; set; }
|
||||
[JsonProperty(nameof(ProtectedGraphRefreshToken))]
|
||||
public string? ProtectedGraphRefreshToken { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using Daybreak.Attributes;
|
||||
using Daybreak.Configuration.FocusView;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Daybreak.Configuration.Options;
|
||||
|
||||
[OptionsName(Name = "Focus View")]
|
||||
public sealed class FocusViewOptions
|
||||
{
|
||||
[JsonProperty(nameof(Enabled))]
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
[JsonProperty(nameof(MemoryReaderFrequency))]
|
||||
public double MemoryReaderFrequency { get; set; } = 16;
|
||||
|
||||
[JsonProperty(nameof(EnablePathfinding))]
|
||||
public bool EnablePathfinding { get; set; } = true;
|
||||
|
||||
[JsonProperty(nameof(ExperienceDisplay))]
|
||||
public ExperienceDisplay ExperienceDisplay { get; set; }
|
||||
|
||||
[JsonProperty(nameof(KurzickPointsDisplay))]
|
||||
public PointsDisplay KurzickPointsDisplay { get; set; }
|
||||
|
||||
[JsonProperty(nameof(LuxonPointsDisplay))]
|
||||
public PointsDisplay LuxonPointsDisplay { get; set; }
|
||||
|
||||
[JsonProperty(nameof(BalthazarPointsDisplay))]
|
||||
public PointsDisplay BalthazarPointsDisplay { get; set; }
|
||||
|
||||
[JsonProperty(nameof(ImperialPointsDisplay))]
|
||||
public PointsDisplay ImperialPointsDisplay { get; set; }
|
||||
|
||||
[JsonProperty(nameof(VanquishingDisplay))]
|
||||
public PointsDisplay VanquishingDisplay { get; set; }
|
||||
|
||||
[JsonProperty(nameof(HealthDisplay))]
|
||||
public PointsDisplay HealthDisplay { get; set; }
|
||||
|
||||
[JsonProperty(nameof(EnergyDisplay))]
|
||||
public PointsDisplay EnergyDisplay { get; set; }
|
||||
|
||||
[JsonProperty(nameof(BrowserUrl))]
|
||||
public string? BrowserUrl { get; set; } = "https://wiki.guildwars.com/wiki/Main_Page";
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using Daybreak.Attributes;
|
||||
using Daybreak.Models;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Daybreak.Configuration.Options;
|
||||
|
||||
[OptionsName(Name = "Launcher")]
|
||||
public sealed class LauncherOptions
|
||||
{
|
||||
[JsonProperty(nameof(SetGuildwarsWindowSizeOnLaunch))]
|
||||
public bool SetGuildwarsWindowSizeOnLaunch { get; set; }
|
||||
|
||||
[JsonProperty(nameof(DesiredGuildwarsScreen))]
|
||||
public int DesiredGuildwarsScreen { get; set; }
|
||||
|
||||
[JsonProperty(nameof(LaunchGuildwarsAsCurrentUser))]
|
||||
public bool LaunchGuildwarsAsCurrentUser { get; set; } = true;
|
||||
|
||||
[JsonProperty(nameof(GuildwarsPaths))]
|
||||
public List<GuildwarsPath> GuildwarsPaths { get; set; } = new();
|
||||
|
||||
[JsonProperty(nameof(ProtectedLoginCredentials))]
|
||||
public List<ProtectedLoginCredentials> ProtectedLoginCredentials { get; set; } = new();
|
||||
|
||||
[JsonProperty(nameof(ShortcutLocation))]
|
||||
public string? ShortcutLocation { get; set; } = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
|
||||
|
||||
[JsonProperty(nameof(PlaceShortcut))]
|
||||
public bool PlaceShortcut { get; set; }
|
||||
|
||||
[JsonProperty(nameof(AutoCheckUpdate))]
|
||||
public bool AutoCheckUpdate { get; set; } = true;
|
||||
|
||||
[JsonProperty(nameof(MultiLaunchSupport))]
|
||||
public bool MultiLaunchSupport { get; set; }
|
||||
|
||||
[JsonProperty(nameof(DownloadIcons))]
|
||||
public bool DownloadIcons { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using Daybreak.Attributes;
|
||||
|
||||
namespace Daybreak.Configuration.Options;
|
||||
|
||||
[OptionsName(Name = "Screen Manager")]
|
||||
public sealed class ScreenManagerOptions
|
||||
{
|
||||
public double X { get; set; }
|
||||
public double Y { get; set; }
|
||||
public double Width { get; set; }
|
||||
public double Height { get; set; }
|
||||
public double DpiX { get; set; }
|
||||
public double DpiY { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using Daybreak.Attributes;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Daybreak.Configuration.Options;
|
||||
|
||||
[OptionsName(Name = "Toolbox")]
|
||||
public sealed class ToolboxOptions
|
||||
{
|
||||
[JsonProperty(nameof(Path))]
|
||||
public string? Path { get; set; }
|
||||
|
||||
[JsonProperty(nameof(Enabled))]
|
||||
public bool Enabled { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using Daybreak.Attributes;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Daybreak.Configuration.Options;
|
||||
|
||||
[OptionsName(Name = "uMod")]
|
||||
public sealed class UModOptions
|
||||
{
|
||||
[JsonProperty(nameof(Path))]
|
||||
public string? Path { get; set; }
|
||||
|
||||
[JsonProperty(nameof(Enabled))]
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
[JsonProperty(nameof(AutoEnableMods))]
|
||||
public bool AutoEnableMods { get; set; }
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
using Daybreak.Services.ApplicationLauncher;
|
||||
using Daybreak.Services.Bloogum;
|
||||
using Daybreak.Services.BuildTemplates;
|
||||
using Daybreak.Services.Configuration;
|
||||
using Daybreak.Services.Credentials;
|
||||
using Daybreak.Services.IconRetrieve;
|
||||
using Daybreak.Services.Logging;
|
||||
@@ -24,42 +23,77 @@ using Microsoft.CorrelationVector;
|
||||
using System.Logging;
|
||||
using Daybreak.Services.Updater.PostUpdate;
|
||||
using System.Core.Extensions;
|
||||
using Daybreak.Services.Updater.PostUpdate.Actions;
|
||||
using Daybreak.Services.Graph;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Daybreak.Services.Navigation;
|
||||
using Daybreak.Services.Onboarding;
|
||||
using Daybreak.Services.Menu;
|
||||
using Daybreak.Services.Scanner;
|
||||
using Daybreak.Services.Experience;
|
||||
using Daybreak.Services.Metrics;
|
||||
using Daybreak.Services.Monitoring;
|
||||
using System.Net.Http.Headers;
|
||||
using Daybreak.Services.Downloads;
|
||||
using Daybreak.Services.ExceptionHandling;
|
||||
using Daybreak.Services.Pathfinding;
|
||||
using Daybreak.Services.Startup;
|
||||
using Daybreak.Services.Startup.Actions;
|
||||
using Daybreak.Services.Drawing;
|
||||
using Daybreak.Services.Drawing.Modules.Entities;
|
||||
using Daybreak.Services.Drawing.Modules.MapIcons;
|
||||
using Daybreak.Services.Drawing.Modules;
|
||||
using Daybreak.Services.Guildwars;
|
||||
using Daybreak.Configuration.Options;
|
||||
using System.Configuration;
|
||||
using Daybreak.Services.UMod;
|
||||
using Daybreak.Services.Toolbox;
|
||||
using Daybreak.Views.Onboarding.UMod;
|
||||
using Daybreak.Views.Onboarding.Toolbox;
|
||||
|
||||
namespace Daybreak.Configuration;
|
||||
|
||||
public static class ProjectConfiguration
|
||||
{
|
||||
private const string DaybreakUserAgent = "Daybreak";
|
||||
|
||||
public static void RegisterResolvers(IServiceManager serviceManager)
|
||||
{
|
||||
serviceManager.ThrowIfNull();
|
||||
|
||||
serviceManager.RegisterOptionsManager<ApplicationConfigurationOptionsManager>();
|
||||
serviceManager.RegisterOptionsManager<OptionsManager>();
|
||||
serviceManager.RegisterResolver(new LoggerResolver());
|
||||
serviceManager
|
||||
.RegisterHttpClient<ApplicationUpdater>()
|
||||
.WithMessageHandler(sp =>
|
||||
{
|
||||
var logger = sp.GetService<ILogger<ApplicationUpdater>>();
|
||||
return new LoggingHttpMessageHandler(logger) { InnerHandler = new HttpClientHandler() };
|
||||
return new LoggingHttpMessageHandler(logger!) { InnerHandler = new HttpClientHandler() };
|
||||
})
|
||||
.WithDefaultRequestHeadersSetup(SetupDaybreakUserAgent)
|
||||
.Build()
|
||||
.RegisterHttpClient<BloogumClient>()
|
||||
.WithMessageHandler(sp =>
|
||||
{
|
||||
var logger = sp.GetService<ILogger<BloogumClient>>();
|
||||
return new LoggingHttpMessageHandler(logger) { InnerHandler = new HttpClientHandler() };
|
||||
return new LoggingHttpMessageHandler(logger!) { InnerHandler = new HttpClientHandler() };
|
||||
})
|
||||
.WithDefaultRequestHeadersSetup(SetupDaybreakUserAgent)
|
||||
.Build()
|
||||
.RegisterHttpClient<GraphClient>()
|
||||
.WithMessageHandler(sp =>
|
||||
{
|
||||
var logger = sp.GetService<ILogger<GraphClient>>();
|
||||
return new LoggingHttpMessageHandler(logger) { InnerHandler = new HttpClientHandler() };
|
||||
return new LoggingHttpMessageHandler(logger!) { InnerHandler = new HttpClientHandler() };
|
||||
})
|
||||
.WithDefaultRequestHeadersSetup(SetupDaybreakUserAgent)
|
||||
.Build()
|
||||
.RegisterHttpClient<DownloadService>()
|
||||
.WithMessageHandler(sp =>
|
||||
{
|
||||
var logger = sp.GetService<ILogger<GraphClient>>();
|
||||
return new LoggingHttpMessageHandler(logger!) { InnerHandler = new HttpClientHandler() };
|
||||
})
|
||||
.WithDefaultRequestHeadersSetup(SetupDaybreakUserAgent)
|
||||
.Build();
|
||||
}
|
||||
|
||||
@@ -69,6 +103,7 @@ public static class ProjectConfiguration
|
||||
|
||||
services.AddSingleton<ILogsManager, JsonLogsManager>();
|
||||
services.AddSingleton<IDebugLogsWriter, Services.Logging.DebugLogsWriter>();
|
||||
services.AddSingleton<IEventViewerLogsWriter, EventViewerLogsWriter>();
|
||||
services.AddSingleton<ILoggerFactory, LoggerFactory>(sp =>
|
||||
{
|
||||
var factory = new LoggerFactory();
|
||||
@@ -76,23 +111,31 @@ public static class ProjectConfiguration
|
||||
return factory;
|
||||
});
|
||||
services.AddSingleton<ILogsWriter, CompositeLogsWriter>(sp => new CompositeLogsWriter(
|
||||
sp.GetService<ILogsManager>(),
|
||||
sp.GetService<IDebugLogsWriter>()));
|
||||
sp.GetService<ILogsManager>()!,
|
||||
sp.GetService<IDebugLogsWriter>()!,
|
||||
sp.GetService<IEventViewerLogsWriter>()!));
|
||||
|
||||
services.AddScoped((sp) => new ScopeMetadata(new CorrelationVector()));
|
||||
services.AddSingleton<ViewManager>();
|
||||
services.AddSingleton<ProcessorUsageMonitor>();
|
||||
services.AddSingleton<MemoryUsageMonitor>();
|
||||
services.AddSingleton<IViewManager, ViewManager>(sp => sp.GetRequiredService<ViewManager>());
|
||||
services.AddSingleton<IViewProducer, ViewManager>(sp => sp.GetRequiredService<ViewManager>());
|
||||
services.AddSingleton<PostUpdateActionManager>();
|
||||
services.AddSingleton<IPostUpdateActionManager>(sp => sp.GetRequiredService<PostUpdateActionManager>());
|
||||
services.AddSingleton<IPostUpdateActionProducer>(sp => sp.GetRequiredService<PostUpdateActionManager>());
|
||||
services.AddSingleton<IPostUpdateActionProvider>(sp => sp.GetRequiredService<PostUpdateActionManager>());
|
||||
services.AddSingleton<IConfigurationManager, ConfigurationManager>();
|
||||
services.AddSingleton<IMenuService, MenuService>();
|
||||
services.AddSingleton<IMenuServiceInitializer, MenuService>(sp => sp.GetRequiredService<IMenuService>().As<MenuService>());
|
||||
services.AddSingleton<ILiteDatabase, LiteDatabase>(sp => new LiteDatabase("Daybreak.db"));
|
||||
services.AddSingleton<IMutexHandler, MutexHandler>();
|
||||
services.AddSingleton<IShortcutManager, ShortcutManager>();
|
||||
services.AddSingleton<IIconBrowser, IconBrowser>();
|
||||
services.AddSingleton<IIconDownloader, IconDownloader>();
|
||||
services.AddSingleton<IMetricsService, MetricsService>();
|
||||
services.AddSingleton<IStartupActionProducer, StartupActionManager>();
|
||||
services.AddSingleton<IOptionsProducer, OptionsManager>(sp => sp.GetRequiredService<IOptionsManager>().As<OptionsManager>());
|
||||
services.AddSingleton<IOptionsUpdateHook, OptionsManager>(sp => sp.GetRequiredService<IOptionsManager>().As<OptionsManager>());
|
||||
services.AddScoped<ICredentialManager, CredentialManager>();
|
||||
services.AddScoped<IApplicationLauncher, ApplicationLauncher>();
|
||||
services.AddScoped<IScreenshotProvider, ScreenshotProvider>();
|
||||
@@ -103,13 +146,28 @@ public static class ProjectConfiguration
|
||||
services.AddScoped<IPrivilegeManager, PrivilegeManager>();
|
||||
services.AddScoped<IScreenManager, ScreenManager>();
|
||||
services.AddScoped<IGraphClient, GraphClient>();
|
||||
services.AddScoped<IOnboardingService, OnboardingService>();
|
||||
services.AddScoped<IGuildwarsMemoryReader, GuildwarsMemoryReader>();
|
||||
services.AddScoped<IMemoryScanner, MemoryScanner>();
|
||||
services.AddScoped<IExperienceCalculator, ExperienceCalculator>();
|
||||
services.AddScoped<IAttributePointCalculator, AttributePointCalculator>();
|
||||
services.AddScoped<IDownloadService, DownloadService>();
|
||||
services.AddScoped<IGuildwarsInstaller, GuildwarsInstaller>();
|
||||
services.AddScoped<IGuildwarsEntityDebouncer, GuildwarsEntityDebouncer>();
|
||||
services.AddScoped<IExceptionHandler, ExceptionHandler>();
|
||||
services.AddScoped<IPathfinder, StupidPathfinder>();
|
||||
services.AddScoped<IDrawingService, DrawingService>();
|
||||
services.AddScoped<IDrawingModuleProducer, DrawingService>(sp => sp.GetRequiredService<IDrawingService>().As<DrawingService>());
|
||||
services.AddScoped<IUModService, UModService>();
|
||||
services.AddScoped<IToolboxService, ToolboxService>();
|
||||
}
|
||||
|
||||
public static void RegisterViews(IViewProducer viewProducer)
|
||||
{
|
||||
viewProducer.ThrowIfNull();
|
||||
|
||||
viewProducer.RegisterPermanentView<CompanionView>();
|
||||
viewProducer.RegisterPermanentView<LauncherView>();
|
||||
viewProducer.RegisterPermanentView<Views.FocusView>();
|
||||
viewProducer.RegisterView<SettingsView>();
|
||||
viewProducer.RegisterView<AskUpdateView>();
|
||||
viewProducer.RegisterView<UpdateView>();
|
||||
@@ -125,12 +183,80 @@ public static class ProjectConfiguration
|
||||
viewProducer.RegisterView<IconDownloadView>();
|
||||
viewProducer.RegisterView<GraphAuthorizationView>();
|
||||
viewProducer.RegisterView<BuildsSynchronizationView>();
|
||||
viewProducer.RegisterView<LauncherOnboardingView>();
|
||||
viewProducer.RegisterView<MetricsView>();
|
||||
viewProducer.RegisterView<GuildwarsDownloadView>();
|
||||
viewProducer.RegisterView<UModInstallingView>();
|
||||
viewProducer.RegisterView<UModInstallationChoiceView>();
|
||||
viewProducer.RegisterView<UModOnboardingEntryView>();
|
||||
viewProducer.RegisterView<UModSwitchView>();
|
||||
viewProducer.RegisterView<UModBrowserView>();
|
||||
viewProducer.RegisterView<ToolboxInstallationView>();
|
||||
viewProducer.RegisterView<ToolboxInstallationChoiceView>();
|
||||
viewProducer.RegisterView<ToolboxOnboardingEntryView>();
|
||||
viewProducer.RegisterView<ToolboxSwitchView>();
|
||||
viewProducer.RegisterView<ToolboxHomepageView>();
|
||||
}
|
||||
|
||||
public static void RegisterStartupActions(IStartupActionProducer startupActionProducer)
|
||||
{
|
||||
startupActionProducer.ThrowIfNull();
|
||||
|
||||
startupActionProducer.RegisterAction<RenameInstallerAction>();
|
||||
}
|
||||
|
||||
public static void RegisterPostUpdateActions(IPostUpdateActionProducer postUpdateActionProducer)
|
||||
{
|
||||
postUpdateActionProducer.ThrowIfNull();
|
||||
}
|
||||
|
||||
postUpdateActionProducer.AddPostUpdateAction<RenameInstallerAction>();
|
||||
public static void RegisterDrawingModules(IDrawingModuleProducer drawingModuleProducer)
|
||||
{
|
||||
drawingModuleProducer.ThrowIfNull();
|
||||
|
||||
|
||||
drawingModuleProducer.RegisterDrawingModule<DeadEntityDrawingModule>();
|
||||
drawingModuleProducer.RegisterDrawingModule<NeutralEntityDrawingModule>();
|
||||
drawingModuleProducer.RegisterDrawingModule<AlliedCreatureEntityDrawingModule>();
|
||||
drawingModuleProducer.RegisterDrawingModule<AllyEntityDrawingModule>();
|
||||
drawingModuleProducer.RegisterDrawingModule<BossEntityDrawingModule>();
|
||||
drawingModuleProducer.RegisterDrawingModule<EnemyEntityDrawingModule>();
|
||||
drawingModuleProducer.RegisterDrawingModule<NpcEntityDrawingModule>();
|
||||
|
||||
drawingModuleProducer.RegisterDrawingModule<ResurrectionShrineDrawingModule>();
|
||||
drawingModuleProducer.RegisterDrawingModule<CollectorDrawingModule>();
|
||||
drawingModuleProducer.RegisterDrawingModule<GateDrawingModule>();
|
||||
drawingModuleProducer.RegisterDrawingModule<StairsDownDrawingModule>();
|
||||
drawingModuleProducer.RegisterDrawingModule<StairsUpDrawingModule>();
|
||||
drawingModuleProducer.RegisterDrawingModule<CircledStarDrawingModule>();
|
||||
drawingModuleProducer.RegisterDrawingModule<AreaMapDrawingModule>();
|
||||
drawingModuleProducer.RegisterDrawingModule<DungeonBossDrawingModule>();
|
||||
drawingModuleProducer.RegisterDrawingModule<DungeonKeyDrawingModule>();
|
||||
|
||||
drawingModuleProducer.RegisterDrawingModule<PathfindingDrawingModule>();
|
||||
drawingModuleProducer.RegisterDrawingModule<PlayerPositionHistoryDrawingModule>();
|
||||
drawingModuleProducer.RegisterDrawingModule<QuestObjectiveDrawingModule>();
|
||||
|
||||
drawingModuleProducer.RegisterDrawingModule<MainPlayerDrawingModule>();
|
||||
drawingModuleProducer.RegisterDrawingModule<PartyMemberDrawingModule>();
|
||||
drawingModuleProducer.RegisterDrawingModule<WorldPlayerDrawingModule>();
|
||||
}
|
||||
|
||||
public static void RegisterOptions(IOptionsProducer optionsProducer)
|
||||
{
|
||||
optionsProducer.ThrowIfNull();
|
||||
|
||||
optionsProducer.RegisterOptions<BrowserOptions>();
|
||||
optionsProducer.RegisterOptions<BuildSynchronizationOptions>();
|
||||
optionsProducer.RegisterOptions<FocusViewOptions>();
|
||||
optionsProducer.RegisterOptions<LauncherOptions>();
|
||||
optionsProducer.RegisterOptions<ToolboxOptions>();
|
||||
optionsProducer.RegisterOptions<UModOptions>();
|
||||
optionsProducer.RegisterOptions<ScreenManagerOptions>();
|
||||
}
|
||||
|
||||
private static void SetupDaybreakUserAgent(HttpRequestHeaders httpRequestHeaders)
|
||||
{
|
||||
httpRequestHeaders.ThrowIfNull().TryAddWithoutValidation("User-Agent", DaybreakUserAgent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ public class SecretKeys
|
||||
public static readonly SecretKeys AadApplicationId = new() { Key = "AadApplicationId" };
|
||||
public static readonly SecretKeys AadTenantId = new() { Key = "AadTenantId" };
|
||||
|
||||
public string Key { get; private set; }
|
||||
public string Key { get; private set; } = string.Empty;
|
||||
private SecretKeys()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Daybreak.Configuration;
|
||||
|
||||
public static class SecretManager
|
||||
{
|
||||
private static JObject SecretsHolder;
|
||||
private static JObject? SecretsHolder;
|
||||
|
||||
public static string GetSecret(SecretKeys secretKey)
|
||||
{
|
||||
@@ -16,7 +16,7 @@ public static class SecretManager
|
||||
LoadSecrets();
|
||||
}
|
||||
|
||||
return SecretsHolder.Value<string>(secretKey.Key);
|
||||
return SecretsHolder!.Value<string>(secretKey.Key)!;
|
||||
}
|
||||
|
||||
public static T GetSecret<T>(SecretKeys secretKey)
|
||||
@@ -26,7 +26,7 @@ public static class SecretManager
|
||||
LoadSecrets();
|
||||
}
|
||||
|
||||
return SecretsHolder.Value<T>(secretKey.Key);
|
||||
return SecretsHolder!.Value<T>(secretKey.Key)!;
|
||||
}
|
||||
|
||||
private static void LoadSecrets()
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
xmlns:local="clr-namespace:Daybreak.Controls"
|
||||
mc:Ignorable="d"
|
||||
x:Name="_this"
|
||||
Cursor="Hand"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Viewbox>
|
||||
<Grid>
|
||||
|
||||
@@ -2,36 +2,35 @@
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for AddButton.xaml
|
||||
/// </summary>
|
||||
public partial class AddButton : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for AddButton.xaml
|
||||
/// </summary>
|
||||
public partial class AddButton : UserControl
|
||||
public event EventHandler? Clicked;
|
||||
|
||||
public AddButton()
|
||||
{
|
||||
public event EventHandler Clicked;
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
public AddButton()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0.6;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0.6;
|
||||
}
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
Clicked?.Invoke(this, e);
|
||||
}
|
||||
Clicked?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
xmlns:local="clr-namespace:Daybreak.Controls"
|
||||
mc:Ignorable="d"
|
||||
x:Name="_this"
|
||||
Cursor="Hand"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Viewbox>
|
||||
<Grid>
|
||||
|
||||
@@ -2,36 +2,35 @@
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for BackButton.xaml
|
||||
/// </summary>
|
||||
public partial class BackButton : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for BackButton.xaml
|
||||
/// </summary>
|
||||
public partial class BackButton : UserControl
|
||||
public event EventHandler? Clicked;
|
||||
|
||||
public BackButton()
|
||||
{
|
||||
public event EventHandler Clicked;
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
public BackButton()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0.6;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0.6;
|
||||
}
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
Clicked?.Invoke(this, e);
|
||||
}
|
||||
Clicked?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
xmlns:local="clr-namespace:Daybreak.Controls"
|
||||
mc:Ignorable="d"
|
||||
x:Name="_this"
|
||||
Cursor="Hand"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Viewbox>
|
||||
<Grid>
|
||||
|
||||
@@ -2,35 +2,34 @@
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for BinButton.xaml
|
||||
/// </summary>
|
||||
public partial class BinButton : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for BinButton.xaml
|
||||
/// </summary>
|
||||
public partial class BinButton : UserControl
|
||||
public event EventHandler? Clicked;
|
||||
public BinButton()
|
||||
{
|
||||
public event EventHandler Clicked;
|
||||
public BinButton()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
this.Clicked?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Visibility = System.Windows.Visibility.Visible;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Visibility = System.Windows.Visibility.Hidden;
|
||||
this.Clicked?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Visibility = System.Windows.Visibility.Visible;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Visibility = System.Windows.Visibility.Hidden;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
xmlns:local="clr-namespace:Daybreak.Controls"
|
||||
mc:Ignorable="d"
|
||||
x:Name="_this"
|
||||
Cursor="Hand"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Viewbox>
|
||||
<Grid>
|
||||
|
||||
@@ -2,36 +2,35 @@
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for BackButton.xaml
|
||||
/// </summary>
|
||||
public partial class CancelButton : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for BackButton.xaml
|
||||
/// </summary>
|
||||
public partial class CancelButton : UserControl
|
||||
public event EventHandler? Clicked;
|
||||
|
||||
public CancelButton()
|
||||
{
|
||||
public event EventHandler Clicked;
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
public CancelButton()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0.6;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0.6;
|
||||
}
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
Clicked?.Invoke(this, e);
|
||||
}
|
||||
Clicked?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
xmlns:local="clr-namespace:Daybreak.Controls"
|
||||
mc:Ignorable="d"
|
||||
x:Name="_this"
|
||||
Cursor="Hand"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
<Ellipse x:Name="BackgroundEllipse" Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Visibility="Visible" Opacity="0.1" />
|
||||
|
||||
@@ -2,36 +2,35 @@
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for FilePickerGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class FilePickerGlyph : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for FilePickerGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class FilePickerGlyph : UserControl
|
||||
public event EventHandler? Clicked;
|
||||
|
||||
public FilePickerGlyph()
|
||||
{
|
||||
public event EventHandler Clicked;
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
public FilePickerGlyph()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0.6;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0.6;
|
||||
}
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
this.Clicked?.Invoke(this, e);
|
||||
}
|
||||
this.Clicked?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
xmlns:local="clr-namespace:Daybreak.Controls"
|
||||
mc:Ignorable="d"
|
||||
x:Name="_this"
|
||||
Cursor="Hand"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Viewbox>
|
||||
<Grid>
|
||||
|
||||
@@ -2,36 +2,35 @@
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for AddButton.xaml
|
||||
/// </summary>
|
||||
public partial class HelpButton : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for AddButton.xaml
|
||||
/// </summary>
|
||||
public partial class HelpButton : UserControl
|
||||
public event EventHandler? Clicked;
|
||||
|
||||
public HelpButton()
|
||||
{
|
||||
public event EventHandler Clicked;
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
public HelpButton()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0.6;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0.6;
|
||||
}
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
this.Clicked?.Invoke(this, e);
|
||||
}
|
||||
this.Clicked?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Daybreak.Controls"
|
||||
mc:Ignorable="d"
|
||||
mc:Ignorable="d"
|
||||
x:Name="_this"
|
||||
Cursor="Hand"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Viewbox>
|
||||
<Grid>
|
||||
|
||||
@@ -2,36 +2,35 @@
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for HomeButton.xaml
|
||||
/// </summary>
|
||||
public partial class HomeButton : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for HomeButton.xaml
|
||||
/// </summary>
|
||||
public partial class HomeButton : UserControl
|
||||
public event EventHandler? Clicked;
|
||||
|
||||
public HomeButton()
|
||||
{
|
||||
public event EventHandler Clicked;
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
public HomeButton()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0.6;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0.6;
|
||||
}
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
Clicked?.Invoke(this, e);
|
||||
}
|
||||
Clicked?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Daybreak.Controls"
|
||||
x:Name="_this"
|
||||
Cursor="Hand"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="50" d:DesignWidth="50">
|
||||
<Grid>
|
||||
|
||||
@@ -2,36 +2,35 @@
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for SaveButton.xaml
|
||||
/// </summary>
|
||||
public partial class MaximizeButton : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for SaveButton.xaml
|
||||
/// </summary>
|
||||
public partial class MaximizeButton : UserControl
|
||||
public event EventHandler? Clicked;
|
||||
|
||||
public MaximizeButton()
|
||||
{
|
||||
public event EventHandler Clicked;
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
public MaximizeButton()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Visibility = System.Windows.Visibility.Visible;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Visibility = System.Windows.Visibility.Visible;
|
||||
}
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Visibility = System.Windows.Visibility.Hidden;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
this.BackgroundEllipse.Visibility = System.Windows.Visibility.Hidden;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
Clicked?.Invoke(this, e);
|
||||
}
|
||||
Clicked?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
xmlns:behaviors="clr-namespace:Daybreak.Behaviors"
|
||||
xmlns:converters="clr-namespace:Daybreak.Converters"
|
||||
x:Name="_this"
|
||||
Cursor="Hand"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
|
||||
@@ -11,16 +11,16 @@ namespace Daybreak.Controls.Buttons;
|
||||
/// </summary>
|
||||
public partial class MenuButton : UserControl
|
||||
{
|
||||
public event EventHandler Clicked;
|
||||
public event EventHandler? Clicked;
|
||||
|
||||
[GenerateDependencyProperty]
|
||||
private bool highlighted;
|
||||
[GenerateDependencyProperty]
|
||||
private Brush highlightColor;
|
||||
private Brush highlightColor = default!;
|
||||
[GenerateDependencyProperty]
|
||||
private FrameworkElement innerContent;
|
||||
[GenerateDependencyProperty]
|
||||
private string title;
|
||||
private FrameworkElement innerContent = default!;
|
||||
[GenerateDependencyProperty(InitialValue = "")]
|
||||
private string title = string.Empty;
|
||||
|
||||
public MenuButton()
|
||||
{
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
xmlns:local="clr-namespace:Daybreak.Controls"
|
||||
mc:Ignorable="d"
|
||||
x:Name="_this"
|
||||
Cursor="Hand"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Viewbox>
|
||||
<Grid>
|
||||
|
||||
@@ -2,36 +2,35 @@
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for AddButton.xaml
|
||||
/// </summary>
|
||||
public partial class MinusButton : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for AddButton.xaml
|
||||
/// </summary>
|
||||
public partial class MinusButton : UserControl
|
||||
public event EventHandler? Clicked;
|
||||
|
||||
public MinusButton()
|
||||
{
|
||||
public event EventHandler Clicked;
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
public MinusButton()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0.6;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0.6;
|
||||
}
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
Clicked?.Invoke(this, e);
|
||||
}
|
||||
Clicked?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
xmlns:local="clr-namespace:Daybreak.Controls"
|
||||
mc:Ignorable="d"
|
||||
x:Name="_this"
|
||||
Cursor="Hand"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"></BooleanToVisibilityConverter>
|
||||
@@ -20,13 +21,12 @@
|
||||
FontStretch="{Binding ElementName=_this, Path=FontStretch, Mode=OneWay}"
|
||||
FontWeight="{Binding ElementName=_this, Path=FontWeight, Mode=OneWay}"
|
||||
FontStyle="{Binding ElementName=_this, Path=FontStyle, Mode=OneWay}"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"></TextBlock>
|
||||
VerticalAlignment="{Binding ElementName=_this, Path=TextVerticalAlignment, Mode=OneWay}"
|
||||
HorizontalAlignment="{Binding ElementName=_this, Path=TextHorizontalAlignment, Mode=OneWay}"></TextBlock>
|
||||
<Rectangle Fill="{Binding ElementName=_this, Path=Highlight, Mode=OneWay}"
|
||||
Opacity="{Binding ElementName=_this, Path=HighlightOpacity, Mode=OneWay}"
|
||||
Visibility="{Binding ElementName=_this, Path=HighlightVisible, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}"></Rectangle>
|
||||
<Rectangle MouseEnter="Rectangle_MouseEnter" MouseLeave="Rectangle_MouseLeave"
|
||||
MouseLeftButtonDown="Rectangle_MouseLeftButtonDown" Fill="Transparent"
|
||||
Cursor="Hand"></Rectangle>
|
||||
MouseLeftButtonDown="Rectangle_MouseLeftButtonDown" Fill="Transparent"></Rectangle>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -5,87 +5,49 @@ using System.Windows.Extensions;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for OpaqueButton.xaml
|
||||
/// </summary>
|
||||
public partial class OpaqueButton : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for OpaqueButton.xaml
|
||||
/// </summary>
|
||||
public partial class OpaqueButton : UserControl
|
||||
public event EventHandler? Clicked;
|
||||
|
||||
[GenerateDependencyProperty(InitialValue = "")]
|
||||
private string text = string.Empty;
|
||||
[GenerateDependencyProperty]
|
||||
private Brush transparentBackground = default!;
|
||||
[GenerateDependencyProperty]
|
||||
private Brush highlight = default!;
|
||||
[GenerateDependencyProperty]
|
||||
public double backgroundOpacity;
|
||||
[GenerateDependencyProperty]
|
||||
public double highlightOpacity;
|
||||
[GenerateDependencyProperty]
|
||||
public bool highlightVisible;
|
||||
[GenerateDependencyProperty(InitialValue = VerticalAlignment.Center)]
|
||||
public VerticalAlignment textVerticalAlignment;
|
||||
[GenerateDependencyProperty(InitialValue = HorizontalAlignment.Center)]
|
||||
public HorizontalAlignment textHorizontalAlignment;
|
||||
|
||||
public OpaqueButton()
|
||||
{
|
||||
public static readonly DependencyProperty TextProperty =
|
||||
DependencyPropertyExtensions.Register<OpaqueButton, string>(nameof(Text));
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty TransparentBackgroundProperty =
|
||||
DependencyPropertyExtensions.Register<OpaqueButton, Brush>(nameof(TransparentBackground));
|
||||
private void Rectangle_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.HighlightVisible = true;
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty HighlightProperty =
|
||||
DependencyPropertyExtensions.Register<OpaqueButton, Brush>(nameof(Highlight));
|
||||
private void Rectangle_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.HighlightVisible = false;
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty BackgroundOpacityProperty =
|
||||
DependencyPropertyExtensions.Register<OpaqueButton, double>(nameof(BackgroundOpacity));
|
||||
|
||||
public static readonly DependencyProperty HighlightOpacityProperty =
|
||||
DependencyPropertyExtensions.Register<OpaqueButton, double>(nameof(HighlightOpacity));
|
||||
|
||||
public static readonly DependencyProperty HighlightVisibleProperty =
|
||||
DependencyPropertyExtensions.Register<OpaqueButton, bool>(nameof(HighlightVisible));
|
||||
|
||||
public event EventHandler Clicked;
|
||||
|
||||
public string Text
|
||||
{
|
||||
get => this.GetTypedValue<string>(TextProperty);
|
||||
set => this.SetTypedValue(TextProperty, value);
|
||||
}
|
||||
|
||||
public Brush TransparentBackground
|
||||
{
|
||||
get => this.GetTypedValue<Brush>(TransparentBackgroundProperty);
|
||||
set => this.SetTypedValue(TransparentBackgroundProperty, value);
|
||||
}
|
||||
|
||||
public Brush Highlight
|
||||
{
|
||||
get => this.GetTypedValue<Brush>(HighlightProperty);
|
||||
set => this.SetTypedValue(HighlightProperty, value);
|
||||
}
|
||||
|
||||
public double BackgroundOpacity
|
||||
{
|
||||
get => this.GetTypedValue<double>(BackgroundOpacityProperty);
|
||||
set => this.SetTypedValue(BackgroundOpacityProperty, value);
|
||||
}
|
||||
|
||||
public double HighlightOpacity
|
||||
{
|
||||
get => this.GetTypedValue<double>(HighlightOpacityProperty);
|
||||
set => this.SetTypedValue(HighlightOpacityProperty, value);
|
||||
}
|
||||
|
||||
public bool HighlightVisible
|
||||
{
|
||||
get => this.GetTypedValue<bool>(HighlightVisibleProperty);
|
||||
set => this.SetTypedValue(HighlightVisibleProperty, value);
|
||||
}
|
||||
|
||||
public OpaqueButton()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void Rectangle_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.HighlightVisible = true;
|
||||
}
|
||||
|
||||
private void Rectangle_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.HighlightVisible = false;
|
||||
}
|
||||
|
||||
private void Rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
this.Clicked?.Invoke(this, e);
|
||||
}
|
||||
private void Rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
this.Clicked?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Daybreak.Controls"
|
||||
x:Name="_this"
|
||||
Cursor="Hand"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Viewbox>
|
||||
|
||||
@@ -2,36 +2,35 @@
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for SaveButton.xaml
|
||||
/// </summary>
|
||||
public partial class SaveButton : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for SaveButton.xaml
|
||||
/// </summary>
|
||||
public partial class SaveButton : UserControl
|
||||
public event EventHandler? Clicked;
|
||||
|
||||
public SaveButton()
|
||||
{
|
||||
public event EventHandler Clicked;
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
public SaveButton()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Visibility = System.Windows.Visibility.Visible;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Visibility = System.Windows.Visibility.Visible;
|
||||
}
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Visibility = System.Windows.Visibility.Hidden;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
this.BackgroundEllipse.Visibility = System.Windows.Visibility.Hidden;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
Clicked?.Invoke(this, e);
|
||||
}
|
||||
Clicked?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
xmlns:local="clr-namespace:Daybreak.Controls"
|
||||
mc:Ignorable="d"
|
||||
x:Name="_this"
|
||||
Cursor="Hand"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Viewbox>
|
||||
<Grid>
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Daybreak.Controls;
|
||||
/// </summary>
|
||||
public partial class SynchronizeButton : UserControl
|
||||
{
|
||||
public event EventHandler Clicked;
|
||||
public event EventHandler? Clicked;
|
||||
|
||||
public SynchronizeButton()
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
xmlns:behaviors="clr-namespace:Daybreak.Behaviors"
|
||||
xmlns:converters="clr-namespace:Daybreak.Converters"
|
||||
x:Name="_this"
|
||||
Cursor="Hand"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Extensions;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Daybreak.Controls;
|
||||
@@ -10,46 +11,22 @@ namespace Daybreak.Controls;
|
||||
/// </summary>
|
||||
public partial class TileButton : UserControl
|
||||
{
|
||||
public event EventHandler Clicked;
|
||||
public event EventHandler? Clicked;
|
||||
|
||||
public static readonly DependencyProperty HighlightedProperty =
|
||||
DependencyProperty.Register("Highlighted", typeof(bool), typeof(TileButton), null);
|
||||
public static readonly DependencyProperty HighlightColorProperty =
|
||||
DependencyProperty.Register("HighlightColor", typeof(Brush), typeof(TileButton), null);
|
||||
public static readonly DependencyProperty InnerContentProperty =
|
||||
DependencyProperty.Register("InnerContent", typeof(FrameworkElement), typeof(TileButton), null);
|
||||
public static readonly DependencyProperty TitleProperty =
|
||||
DependencyProperty.Register("Title", typeof(string), typeof(TileButton), null);
|
||||
[GenerateDependencyProperty]
|
||||
public bool highlighted;
|
||||
[GenerateDependencyProperty(InitialValue = "")]
|
||||
public string title = string.Empty;
|
||||
[GenerateDependencyProperty]
|
||||
public FrameworkElement InnerContent = default!;
|
||||
[GenerateDependencyProperty]
|
||||
public Brush HighlightColor = default!;
|
||||
|
||||
public TileButton()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
public bool Highlighted
|
||||
{
|
||||
get => (bool)this.GetValue(HighlightedProperty);
|
||||
set => this.SetValue(HighlightedProperty, value);
|
||||
}
|
||||
|
||||
public string Title
|
||||
{
|
||||
get => this.GetValue(TitleProperty) as string;
|
||||
set => this.SetValue(TitleProperty, value);
|
||||
}
|
||||
|
||||
public FrameworkElement InnerContent
|
||||
{
|
||||
get => this.GetValue(InnerContentProperty) as FrameworkElement;
|
||||
set => this.SetValue(InnerContentProperty, value);
|
||||
}
|
||||
|
||||
public Brush HighlightColor
|
||||
{
|
||||
get => this.GetValue(HighlightColorProperty) as Brush;
|
||||
set => this.SetValue(HighlightColorProperty, value);
|
||||
}
|
||||
|
||||
private void Grid_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
|
||||
{
|
||||
this.Highlighted = true;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
mc:Ignorable="d"
|
||||
Unloaded="UserControl_Unloaded"
|
||||
x:Name="_this"
|
||||
Initialized="UserControl_Initialized"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" TriggerValue="True"></converters:BooleanToVisibilityConverter>
|
||||
@@ -19,7 +20,7 @@
|
||||
<ContextMenu.Template>
|
||||
<ControlTemplate>
|
||||
<StackPanel Margin="10">
|
||||
<local:OpaqueButton Text="Load build template" Foreground="White" Background="#F0202020" BackgroundOpacity="0.4"
|
||||
<local:OpaqueButton Text="Load build template" Foreground="White" Background="#F0212121" BackgroundOpacity="0.4"
|
||||
Clicked="LoadBuildTemplateButton_Click" FontSize="16" Height="40" Width="200"></local:OpaqueButton>
|
||||
</StackPanel>
|
||||
</ControlTemplate>
|
||||
@@ -33,7 +34,7 @@
|
||||
</Grid.RowDefinitions>
|
||||
<wv2:WebView2 x:Name="WebBrowser" Source="{Binding ElementName=_this, Path=Address, Mode=TwoWay}"
|
||||
IsEnabled="{Binding ElementName=_this, Path=BrowserSupported, Mode=OneWay}"></wv2:WebView2>
|
||||
<Grid Grid.Row="1" Background="#80808080" IsEnabled="{Binding ElementName=_this, Path=BrowserSupported, Mode=OneWay}"
|
||||
<Grid Grid.Row="1" Background="#F0212121" IsEnabled="{Binding ElementName=_this, Path=BrowserSupported, Mode=OneWay}"
|
||||
Visibility="{Binding ElementName=_this, Path=ControlsEnabled, Mode=OneWay, Converter={StaticResource ReverseBooleanToVisibilityConverter}}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"></ColumnDefinition>
|
||||
@@ -69,17 +70,19 @@
|
||||
IsEnabled="{Binding ElementName=_this, Path=BrowserSupported, Mode=OneWay}"></TextBox>
|
||||
<StackPanel Grid.Column="2" Orientation="Horizontal">
|
||||
<local:HomeButton Width="30" Height="30" Margin="5"
|
||||
Visibility="{Binding ElementName=_this, Path=HomeButtonVisible, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}"
|
||||
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
IsEnabled="{Binding ElementName=_this, Path=BrowserSupported, Mode=OneWay}"
|
||||
Clicked="HomeButton_Clicked"></local:HomeButton>
|
||||
<local:StarGlyph Height="30" Width="30" Margin="5"
|
||||
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
IsEnabled="{Binding ElementName=_this, Path=BrowserSupported, Mode=OneWay}"
|
||||
Clicked="StarGlyph_Clicked" x:Name="FavoriteButton"></local:StarGlyph>
|
||||
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Visibility="{Binding ElementName=_this, Path=HomeButtonVisible, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}"
|
||||
IsEnabled="{Binding ElementName=_this, Path=BrowserSupported, Mode=OneWay}"
|
||||
Clicked="StarGlyph_Clicked" x:Name="FavoriteButton"></local:StarGlyph>
|
||||
<local:MaximizeButton Height="30" Width="30" Margin="5"
|
||||
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
IsEnabled="{Binding ElementName=_this, Path=BrowserSupported, Mode=OneWay}"
|
||||
Clicked="MaximizeButton_Clicked"></local:MaximizeButton>
|
||||
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
IsEnabled="{Binding ElementName=_this, Path=BrowserSupported, Mode=OneWay}"
|
||||
Clicked="MaximizeButton_Clicked"></local:MaximizeButton>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Grid Grid.RowSpan="2" Background="Gray"
|
||||
@@ -95,6 +98,5 @@
|
||||
<TextBlock Foreground="White" Text="Restart after the installation." FontSize="26" TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Daybreak.Configuration;
|
||||
using Daybreak.Configuration.Options;
|
||||
using Daybreak.Models.Browser;
|
||||
using Daybreak.Models.Builds;
|
||||
using Daybreak.Models.Guildwars;
|
||||
using Daybreak.Services.BuildTemplates;
|
||||
using Daybreak.Utils;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -8,339 +8,417 @@ using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Web.WebView2.Core;
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Core.Extensions;
|
||||
using System.Diagnostics;
|
||||
using System.Extensions;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Extensions;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for ChromiumBrowserWrapper.xaml
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0044:Add readonly modifier", Justification = "Fields used by source generator for DependencyProperty")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0052:Remove unread private members", Justification = "Used by source generators")]
|
||||
public partial class ChromiumBrowserWrapper : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ChromiumBrowserWrapper.xaml
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0044:Add readonly modifier", Justification = "Fields used by source generator for DependencyProperty")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0052:Remove unread private members", Justification = "Used by source generators")]
|
||||
public partial class ChromiumBrowserWrapper : UserControl
|
||||
public static readonly DependencyProperty AddressProperty =
|
||||
DependencyPropertyExtensions.Register<ChromiumBrowserWrapper, string>(nameof(Address));
|
||||
|
||||
private const string BrowserSearchPlaceholder = "[PLACEHOLDER]";
|
||||
private const string BrowserSearchLink = $"https://www.google.com/search?q={BrowserSearchPlaceholder}";
|
||||
private const string BrowserDownloadLink = "https://developer.microsoft.com/en-us/microsoft-edge/webview2/";
|
||||
|
||||
private static readonly Regex WebAddressRegex = new("^((http|ftp|https)://)?([\\w_-]+(?:(?:\\.[\\w_-]+)+))([\\w.,@?^=%&:/~+#-]*[\\w@?^=%&/~+#-])?", RegexOptions.Compiled);
|
||||
|
||||
private static CoreWebView2Environment? coreWebView2Environment;
|
||||
|
||||
public event EventHandler<string>? FavoriteUriChanged;
|
||||
public event EventHandler? MaximizeClicked;
|
||||
public event EventHandler<Build>? BuildDecoded;
|
||||
public event EventHandler<DownloadPayload>? DownloadingFile;
|
||||
public event EventHandler<string>? DownloadedFile;
|
||||
|
||||
private readonly Task initializationTask;
|
||||
private readonly ILiveOptions<BrowserOptions>? liveOptions;
|
||||
private readonly ILogger<ChromiumBrowserWrapper>? logger;
|
||||
private readonly IBuildTemplateManager? buildTemplateManager;
|
||||
|
||||
[GenerateDependencyProperty(InitialValue = true)]
|
||||
private bool canDownloadBuild;
|
||||
[GenerateDependencyProperty(InitialValue = true)]
|
||||
private bool canNavigate;
|
||||
[GenerateDependencyProperty(InitialValue = false)]
|
||||
private bool canDownloadFiles;
|
||||
[GenerateDependencyProperty(InitialValue = true)]
|
||||
private bool controlsEnabled;
|
||||
[GenerateDependencyProperty(InitialValue = null)]
|
||||
private bool? browserSupported;
|
||||
[GenerateDependencyProperty]
|
||||
private bool addressBarReadonly;
|
||||
[GenerateDependencyProperty]
|
||||
private bool browserEnabled;
|
||||
[GenerateDependencyProperty]
|
||||
private bool navigating;
|
||||
[GenerateDependencyProperty]
|
||||
private string favoriteAddress = string.Empty;
|
||||
[GenerateDependencyProperty(InitialValue = false)]
|
||||
private bool preventDispose;
|
||||
[GenerateDependencyProperty(InitialValue = true)]
|
||||
private bool homeButtonVisible = true;
|
||||
[GenerateDependencyProperty(InitialValue = true)]
|
||||
private bool favoriteButtonVisible = true;
|
||||
[GenerateDependencyProperty]
|
||||
private string downloadsDirectory = string.Empty;
|
||||
|
||||
public string Address
|
||||
{
|
||||
public static readonly DependencyProperty AddressProperty =
|
||||
DependencyPropertyExtensions.Register<ChromiumBrowserWrapper, string>(nameof(Address));
|
||||
|
||||
private const string BrowserDownloadLink = "https://developer.microsoft.com/en-us/microsoft-edge/webview2/";
|
||||
|
||||
private static CoreWebView2Environment coreWebView2Environment;
|
||||
|
||||
public event EventHandler<string> FavoriteUriChanged;
|
||||
public event EventHandler MaximizeClicked;
|
||||
public event EventHandler<Build> BuildDecoded;
|
||||
|
||||
private ILiveOptions<ApplicationConfiguration> liveOptions;
|
||||
private ILogger<ChromiumBrowserWrapper> logger;
|
||||
private IBuildTemplateManager buildTemplateManager;
|
||||
|
||||
[GenerateDependencyProperty(InitialValue = true)]
|
||||
private bool canDownloadBuild;
|
||||
[GenerateDependencyProperty(InitialValue = true)]
|
||||
private bool canNavigate;
|
||||
[GenerateDependencyProperty(InitialValue = true)]
|
||||
private bool controlsEnabled;
|
||||
[GenerateDependencyProperty(InitialValue = null)]
|
||||
private bool? browserSupported;
|
||||
[GenerateDependencyProperty]
|
||||
private bool addressBarReadonly;
|
||||
[GenerateDependencyProperty]
|
||||
private bool browserEnabled;
|
||||
[GenerateDependencyProperty]
|
||||
private bool navigating;
|
||||
[GenerateDependencyProperty]
|
||||
private string favoriteAddress;
|
||||
[GenerateDependencyProperty(InitialValue = false)]
|
||||
private bool preventDispose;
|
||||
public string Address
|
||||
{
|
||||
get => this.GetTypedValue<string>(AddressProperty);
|
||||
set
|
||||
{
|
||||
if (this.BrowserSupported is true)
|
||||
{
|
||||
this.SetValue(AddressProperty, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ChromiumBrowserWrapper()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.WebBrowser.IsEnabled = false;
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
base.OnPropertyChanged(e);
|
||||
if (e.Property == AddressProperty || e.Property == FavoriteAddressProperty)
|
||||
{
|
||||
this.CheckFavoriteAddress();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task InitializeDefaultBrowser()
|
||||
{
|
||||
var options = Launch.Launcher.Instance.ApplicationServiceProvider.GetRequiredService<ILiveOptions<ApplicationConfiguration>>();
|
||||
var buildTemplateManager = Launch.Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IBuildTemplateManager>();
|
||||
var logger = Launch.Launcher.Instance.ApplicationServiceProvider.GetRequiredService<ILogger<ChromiumBrowserWrapper>>();
|
||||
|
||||
await this.InitializeDefaultBrowser(options, buildTemplateManager, logger);
|
||||
}
|
||||
|
||||
public async Task InitializeDefaultBrowser(
|
||||
ILiveOptions<ApplicationConfiguration> liveOptions,
|
||||
IBuildTemplateManager buildTemplateManager,
|
||||
ILogger<ChromiumBrowserWrapper> logger)
|
||||
{
|
||||
this.liveOptions = liveOptions;
|
||||
this.buildTemplateManager = buildTemplateManager;
|
||||
this.logger = logger;
|
||||
this.InitializeEnvironment();
|
||||
await this.InitializeBrowser();
|
||||
}
|
||||
|
||||
public async void ReinitializeBrowser()
|
||||
{
|
||||
await this.InitializeBrowser();
|
||||
}
|
||||
|
||||
private void InitializeEnvironment()
|
||||
{
|
||||
if (this.liveOptions.Value.BrowsersEnabled is false)
|
||||
{
|
||||
this.BrowserSupported = false;
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (coreWebView2Environment is null)
|
||||
{
|
||||
coreWebView2Environment = System.Extensions.TaskExtensions.RunSync(() => CoreWebView2Environment.CreateAsync(null, "BrowserData", null));
|
||||
}
|
||||
|
||||
this.BrowserSupported = true;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
this.logger.LogWarning($"Browser initialization failed. Details: {e}");
|
||||
this.BrowserSupported = false;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task InitializeBrowser()
|
||||
get => this.GetTypedValue<string>(AddressProperty);
|
||||
set
|
||||
{
|
||||
if (this.BrowserSupported is true)
|
||||
{
|
||||
this.WebBrowser.IsEnabled = true;
|
||||
this.BrowserEnabled = true;
|
||||
await this.WebBrowser.EnsureCoreWebView2Async(coreWebView2Environment);
|
||||
this.AddressBarReadonly = this.liveOptions.Value.AddressBarReadonly;
|
||||
this.CanDownloadBuild = this.liveOptions.Value.ExperimentalFeatures.DynamicBuildLoading;
|
||||
this.WebBrowser.CoreWebView2.NewWindowRequested += (browser, args) => args.Handled = true;
|
||||
this.WebBrowser.NavigationStarting += (browser, args) =>
|
||||
this.SetValue(AddressProperty, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ChromiumBrowserWrapper()
|
||||
: this(Launch.Launcher.Instance.ApplicationServiceProvider.GetRequiredService<ILiveOptions<BrowserOptions>>(),
|
||||
Launch.Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IBuildTemplateManager>(),
|
||||
Launch.Launcher.Instance.ApplicationServiceProvider.GetRequiredService<ILogger<ChromiumBrowserWrapper>>())
|
||||
{
|
||||
}
|
||||
|
||||
public ChromiumBrowserWrapper(
|
||||
ILiveOptions<BrowserOptions> liveOptions,
|
||||
IBuildTemplateManager buildTemplateManager,
|
||||
ILogger<ChromiumBrowserWrapper> logger)
|
||||
{
|
||||
this.liveOptions = liveOptions.ThrowIfNull();
|
||||
this.buildTemplateManager = buildTemplateManager.ThrowIfNull();
|
||||
this.logger = logger.ThrowIfNull();
|
||||
this.initializationTask = this.InitializeBrowser();
|
||||
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
base.OnPropertyChanged(e);
|
||||
if (e.Property == AddressProperty || e.Property == FavoriteAddressProperty)
|
||||
{
|
||||
this.CheckFavoriteAddress();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ReinitializeBrowser()
|
||||
{
|
||||
await this.InitializeBrowser();
|
||||
}
|
||||
|
||||
public Task InitializationTask() => this.initializationTask;
|
||||
|
||||
private async void UserControl_Initialized(object sender, EventArgs e)
|
||||
{
|
||||
this.InitializeEnvironment();
|
||||
await this.InitializeBrowser();
|
||||
}
|
||||
|
||||
private void InitializeEnvironment()
|
||||
{
|
||||
if (this.liveOptions!.Value.Enabled is false)
|
||||
{
|
||||
this.BrowserSupported = false;
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
coreWebView2Environment ??= System.Extensions.TaskExtensions.RunSync(() => CoreWebView2Environment.CreateAsync(null, "BrowserData", new CoreWebView2EnvironmentOptions
|
||||
{
|
||||
EnableTrackingPrevention = true,
|
||||
AllowSingleSignOnUsingOSPrimaryAccount = true
|
||||
}));
|
||||
|
||||
this.BrowserSupported = true;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
this.logger!.LogWarning($"Browser initialization failed. Details: {e}");
|
||||
this.BrowserSupported = false;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task InitializeBrowser()
|
||||
{
|
||||
if (this.BrowserSupported is true)
|
||||
{
|
||||
this.WebBrowser.IsEnabled = true;
|
||||
this.BrowserEnabled = true;
|
||||
await this.WebBrowser.EnsureCoreWebView2Async(coreWebView2Environment);
|
||||
this.AddressBarReadonly = this.liveOptions!.Value.AddressBarReadonly;
|
||||
this.CanDownloadBuild = this.liveOptions.Value.DynamicBuildLoading;
|
||||
this.WebBrowser.CoreWebView2.NewWindowRequested += (browser, args) => args.Handled = true;
|
||||
this.WebBrowser.NavigationStarting += (browser, args) =>
|
||||
{
|
||||
if (this.CanNavigate is false && args.Uri != this.Address)
|
||||
{
|
||||
if (this.CanNavigate is false && args.Uri != this.Address)
|
||||
{
|
||||
args.Cancel = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Navigating = true;
|
||||
}
|
||||
};
|
||||
this.WebBrowser.NavigationCompleted += (browser, args) => this.Navigating = false;
|
||||
this.WebBrowser.WebMessageReceived += this.CoreWebView2_WebMessageReceived;
|
||||
this.WebBrowser.CoreWebView2.Settings.AreDevToolsEnabled = false;
|
||||
this.WebBrowser.CoreWebView2.Settings.AreDefaultContextMenusEnabled = false;
|
||||
if (this.CanDownloadBuild)
|
||||
{
|
||||
await this.WebBrowser.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(Scripts.SendSelectionOnContextMenu);
|
||||
args.Cancel = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async void RetryInitializeButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.InitializeEnvironment();
|
||||
try
|
||||
{
|
||||
await this.InitializeBrowser();
|
||||
}
|
||||
catch
|
||||
{
|
||||
this.BrowserSupported = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void Hyperlink_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
if (Uri.TryCreate(BrowserDownloadLink, UriKind.Absolute, out var uri))
|
||||
{
|
||||
Process.Start("explorer.exe", uri.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private void TextBox_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == System.Windows.Input.Key.Enter)
|
||||
{
|
||||
var newAddress = sender.As<TextBox>().Text;
|
||||
newAddress = SanitizeAddress(newAddress);
|
||||
if (newAddress is null)
|
||||
else
|
||||
{
|
||||
this.Navigating = true;
|
||||
}
|
||||
};
|
||||
this.WebBrowser.CoreWebView2.DownloadStarting += (browser, args) =>
|
||||
{
|
||||
if (this.CanDownloadFiles is false)
|
||||
{
|
||||
this.logger?.LogInformation("Downloads are disallowed. Cancelling download");
|
||||
args.Cancel = true;
|
||||
}
|
||||
|
||||
if (this.DownloadsDirectory.IsNullOrWhiteSpace())
|
||||
{
|
||||
this.logger?.LogInformation("No downloads directory specified. Downloading to default directory");
|
||||
return;
|
||||
}
|
||||
|
||||
this.Address = newAddress;
|
||||
this.WebBrowser.CoreWebView2.Navigate(this.Address);
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void CoreWebView2_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs args)
|
||||
{
|
||||
BrowserPayload payload = default;
|
||||
try
|
||||
{
|
||||
payload = args.WebMessageAsJson.Deserialize<BrowserPayload>();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
this.logger.LogError(e, $"Exception encountered when deserializing {nameof(BrowserPayload)}");
|
||||
}
|
||||
|
||||
if (payload?.Key == BrowserPayload.PayloadKeys.ContextMenu)
|
||||
{
|
||||
var contextMenuPayload = args.WebMessageAsJson.Deserialize<BrowserPayload<OnContextMenuPayload>>();
|
||||
var maybeTemplate = contextMenuPayload.Value.Selection;
|
||||
if (string.IsNullOrWhiteSpace(maybeTemplate))
|
||||
var fileName = Path.GetFileName(args.ResultFilePath);
|
||||
var finalPath = Path.GetFullPath(Path.Combine(this.DownloadsDirectory, fileName));
|
||||
var downloadPayload = new DownloadPayload { ResultingFilePath = finalPath, CanDownload = true };
|
||||
this.DownloadingFile?.Invoke(this, downloadPayload);
|
||||
if (!downloadPayload.CanDownload)
|
||||
{
|
||||
args.Cancel = true;
|
||||
this.logger?.LogInformation("Download blocked by handler. Cancelling download");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.buildTemplateManager is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
args.ResultFilePath = finalPath;
|
||||
|
||||
if (this.buildTemplateManager.IsTemplate(maybeTemplate) is false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var build = this.buildTemplateManager.DecodeTemplate(maybeTemplate);
|
||||
this.Dispatcher.Invoke(() =>
|
||||
{
|
||||
this.ContextMenu.DataContext = build;
|
||||
this.ContextMenu.IsOpen = true;
|
||||
});
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
this.logger.LogWarning($"Exception when decoding template {maybeTemplate}. Details {e}");
|
||||
}
|
||||
});
|
||||
args.DownloadOperation.StateChanged += this.DownloadOperation_StateChanged;
|
||||
};
|
||||
this.WebBrowser.NavigationCompleted += (browser, args) => this.Navigating = false;
|
||||
this.WebBrowser.WebMessageReceived += this.CoreWebView2_WebMessageReceived!;
|
||||
this.WebBrowser.CoreWebView2.Settings.AreDevToolsEnabled = false;
|
||||
this.WebBrowser.CoreWebView2.Settings.AreDefaultContextMenusEnabled = false;
|
||||
if (this.CanDownloadBuild)
|
||||
{
|
||||
await this.WebBrowser.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(Scripts.SendSelectionOnContextMenu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadBuildTemplateButton_Click(object sender, EventArgs e)
|
||||
private async void RetryInitializeButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.InitializeEnvironment();
|
||||
try
|
||||
{
|
||||
var build = this.ContextMenu.DataContext.As<Build>();
|
||||
this.ContextMenu.IsOpen = false;
|
||||
this.BuildDecoded?.Invoke(this, build);
|
||||
await this.InitializeBrowser();
|
||||
}
|
||||
catch
|
||||
{
|
||||
this.BrowserSupported = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void Hyperlink_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
if (Uri.TryCreate(BrowserDownloadLink, UriKind.Absolute, out var uri))
|
||||
{
|
||||
Process.Start("explorer.exe", uri.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private void TextBox_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == System.Windows.Input.Key.Enter)
|
||||
{
|
||||
var input = sender.As<TextBox>().Text;
|
||||
var maybeAddress = SanitizeAddress(input);
|
||||
// If input is address, navigate to address. Otherwise search for the text input in Google
|
||||
if (Uri.TryCreate(maybeAddress, UriKind.Absolute, out _))
|
||||
{
|
||||
this.Address = maybeAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
var address = BrowserSearchLink.Replace(BrowserSearchPlaceholder, maybeAddress);
|
||||
this.Address = address;
|
||||
}
|
||||
|
||||
this.WebBrowser.CoreWebView2.Navigate(this.Address);
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void CoreWebView2_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs args)
|
||||
{
|
||||
BrowserPayload payload = default!;
|
||||
try
|
||||
{
|
||||
payload = args.WebMessageAsJson.Deserialize<BrowserPayload>();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
this.logger!.LogError(e, $"Exception encountered when deserializing {nameof(BrowserPayload)}");
|
||||
}
|
||||
|
||||
private void UserControl_Unloaded(object sender, RoutedEventArgs e)
|
||||
if (payload?.Key == BrowserPayload.PayloadKeys.ContextMenu)
|
||||
{
|
||||
if (this.PreventDispose)
|
||||
var contextMenuPayload = args.WebMessageAsJson.Deserialize<BrowserPayload<OnContextMenuPayload>>();
|
||||
var maybeTemplate = contextMenuPayload.Value!.Selection;
|
||||
if (string.IsNullOrWhiteSpace(maybeTemplate))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.WebBrowser?.Dispose();
|
||||
}
|
||||
|
||||
private void BackButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.WebBrowser.GoBack();
|
||||
this.Address = this.WebBrowser.Source.ToString();
|
||||
}
|
||||
|
||||
private void ForwardButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.WebBrowser.GoForward();
|
||||
this.Address = this.WebBrowser.Source.ToString();
|
||||
}
|
||||
|
||||
private void RefreshGlyph_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.WebBrowser.Reload();
|
||||
this.Address = this.WebBrowser.Source.ToString();
|
||||
}
|
||||
|
||||
private void CancelGlyph_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.WebBrowser.Stop();
|
||||
}
|
||||
|
||||
private void StarGlyph_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.FavoriteAddress = this.Address;
|
||||
this.FavoriteUriChanged?.Invoke(this, this.FavoriteAddress);
|
||||
}
|
||||
|
||||
private void HomeButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.WebBrowser.CoreWebView2.Navigate(this.FavoriteAddress);
|
||||
}
|
||||
|
||||
private void MaximizeButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.MaximizeClicked?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private void CheckFavoriteAddress()
|
||||
{
|
||||
if (this.Address == this.FavoriteAddress)
|
||||
if (this.buildTemplateManager is null)
|
||||
{
|
||||
this.FavoriteButton.IsEnabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.FavoriteButton.IsEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private static string SanitizeAddress(string address)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(address))
|
||||
{
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (address.StartsWith("www") is false &&
|
||||
address.StartsWith("http") is false)
|
||||
if (this.buildTemplateManager.IsTemplate(maybeTemplate) is false)
|
||||
{
|
||||
address = "https://www." + address;
|
||||
}
|
||||
else if (address.StartsWith("www"))
|
||||
{
|
||||
address = "https://" + address;
|
||||
return;
|
||||
}
|
||||
|
||||
Uri.TryCreate(address, UriKind.Absolute, out var uri);
|
||||
return uri?.ToString();
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var build = this.buildTemplateManager.DecodeTemplate(maybeTemplate);
|
||||
this.Dispatcher.Invoke(() =>
|
||||
{
|
||||
this.ContextMenu.DataContext = build;
|
||||
this.ContextMenu.IsOpen = true;
|
||||
});
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
this.logger!.LogWarning($"Exception when decoding template {maybeTemplate}. Details {e}");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void DownloadOperation_StateChanged(object? sender, object? e)
|
||||
{
|
||||
if (sender is not CoreWebView2DownloadOperation downloadOperation)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (downloadOperation.State != CoreWebView2DownloadState.Completed &&
|
||||
downloadOperation.State != CoreWebView2DownloadState.Interrupted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
downloadOperation.StateChanged -= this.DownloadOperation_StateChanged;
|
||||
var filePath = Path.GetFullPath(downloadOperation.ResultFilePath);
|
||||
this.DownloadedFile?.Invoke(this, filePath);
|
||||
}
|
||||
|
||||
private void LoadBuildTemplateButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
var build = this.ContextMenu.DataContext.As<Build>();
|
||||
this.ContextMenu.IsOpen = false;
|
||||
this.BuildDecoded?.Invoke(this, build);
|
||||
}
|
||||
|
||||
private void UserControl_Unloaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (this.PreventDispose)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.WebBrowser?.Dispose();
|
||||
}
|
||||
|
||||
private void BackButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.WebBrowser.GoBack();
|
||||
this.Address = this.WebBrowser.Source.ToString();
|
||||
}
|
||||
|
||||
private void ForwardButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.WebBrowser.GoForward();
|
||||
this.Address = this.WebBrowser.Source.ToString();
|
||||
}
|
||||
|
||||
private void RefreshGlyph_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.WebBrowser.Reload();
|
||||
this.Address = this.WebBrowser.Source.ToString();
|
||||
}
|
||||
|
||||
private void CancelGlyph_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.WebBrowser.Stop();
|
||||
}
|
||||
|
||||
private void StarGlyph_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.FavoriteAddress = this.Address;
|
||||
this.FavoriteUriChanged?.Invoke(this, this.FavoriteAddress);
|
||||
}
|
||||
|
||||
private void HomeButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.WebBrowser.CoreWebView2.Navigate(this.FavoriteAddress);
|
||||
}
|
||||
|
||||
private void MaximizeButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.MaximizeClicked?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private void CheckFavoriteAddress()
|
||||
{
|
||||
if (this.Address == this.FavoriteAddress)
|
||||
{
|
||||
this.FavoriteButton.IsEnabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.FavoriteButton.IsEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private static string SanitizeAddress(string address)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(address))
|
||||
{
|
||||
return default!;
|
||||
}
|
||||
|
||||
if (WebAddressRegex.IsMatch(address) is false)
|
||||
{
|
||||
return address;
|
||||
}
|
||||
|
||||
if (address.StartsWith("www") is false &&
|
||||
address.StartsWith("http") is false)
|
||||
{
|
||||
address = "https://www." + address;
|
||||
}
|
||||
else if (address.StartsWith("www"))
|
||||
{
|
||||
address = "https://" + address;
|
||||
}
|
||||
|
||||
Uri.TryCreate(address, UriKind.Absolute, out var uri);
|
||||
return uri?.ToString() ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +1,30 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for CircularLoadingWidget.xaml
|
||||
/// </summary>
|
||||
public partial class CircularLoadingWidget : UserControl
|
||||
{
|
||||
public CircularLoadingWidget()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
|
||||
/// <summary>
|
||||
/// Interaction logic for CircularLoadingWidget.xaml
|
||||
/// </summary>
|
||||
public partial class CircularLoadingWidget : UserControl
|
||||
{
|
||||
public CircularLoadingWidget()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
base.OnPropertyChanged(e);
|
||||
if (e.Property == IsEnabledProperty)
|
||||
{
|
||||
base.OnPropertyChanged(e);
|
||||
if (e.Property == IsEnabledProperty)
|
||||
if (e.NewValue is true)
|
||||
{
|
||||
if (e.NewValue is true)
|
||||
{
|
||||
this.ProgressAnimation_BeginStoryboard.Storyboard.Pause();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.ProgressAnimation_BeginStoryboard.Storyboard.Resume();
|
||||
}
|
||||
this.ProgressAnimation_BeginStoryboard.Storyboard.Pause();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.ProgressAnimation_BeginStoryboard.Storyboard.Resume();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<UserControl x:Class="Daybreak.Controls.ExpandableMenuSection"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Daybreak.Controls"
|
||||
xmlns:buttons="clr-namespace:Daybreak.Controls.Buttons"
|
||||
mc:Ignorable="d"
|
||||
x:Name="_this"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"></BooleanToVisibilityConverter>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<StackPanel Orientation="Vertical"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch">
|
||||
<buttons:MenuButton
|
||||
Cursor="Hand"
|
||||
HighlightColor="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Title="{Binding ElementName=_this, Path=SectionTitle, Mode=OneWay}"
|
||||
FontSize="{Binding ElementName=_this, Path=FontSize, Mode=OneWay}"
|
||||
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Clicked="MenuButton_Clicked"
|
||||
IsEnabled="{Binding ElementName=_this, Path=ExpanderButtonEnabled, Mode=OneWay}"
|
||||
Height="30"></buttons:MenuButton>
|
||||
<Rectangle Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Height="1"
|
||||
HorizontalAlignment="Stretch"></Rectangle>
|
||||
<Grid MaxHeight="{Binding ElementName=_this, Path=ExpanderHeight, Mode=OneWay}"
|
||||
Margin="10, 0, 0, 0">
|
||||
<ItemsControl x:Name="ContentListView"
|
||||
ItemsSource="{Binding ElementName=_this, Path=Children, Mode=OneWay}"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"></ItemsControl>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Extensions;
|
||||
using System.Windows.Media.Animation;
|
||||
|
||||
namespace Daybreak.Controls;
|
||||
/// <summary>
|
||||
/// Interaction logic for ExpandableMenuSection.xaml
|
||||
/// </summary>
|
||||
public partial class ExpandableMenuSection : UserControl
|
||||
{
|
||||
[GenerateDependencyProperty]
|
||||
private string sectionTitle = string.Empty;
|
||||
[GenerateDependencyProperty]
|
||||
private double expanderHeight = 0;
|
||||
[GenerateDependencyProperty(InitialValue = true)]
|
||||
private bool expanderButtonEnabled;
|
||||
[GenerateDependencyProperty(InitialValue = false)]
|
||||
private bool expanded = false;
|
||||
|
||||
public ObservableCollection<FrameworkElement> Children { get; } = new ObservableCollection<FrameworkElement>();
|
||||
|
||||
public ExpandableMenuSection()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void MenuButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.ExpanderButtonEnabled = false;
|
||||
var desiredHeight = 0d;
|
||||
foreach (var child in this.Children)
|
||||
{
|
||||
desiredHeight += child.DesiredSize.Height > 0 ?
|
||||
child.DesiredSize.Height :
|
||||
child.Height;
|
||||
}
|
||||
|
||||
var doubleAnimation = new DoubleAnimation();
|
||||
|
||||
if (this.expanded)
|
||||
{
|
||||
doubleAnimation.From = desiredHeight;
|
||||
doubleAnimation.To = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
doubleAnimation.From = 0;
|
||||
doubleAnimation.To = desiredHeight;
|
||||
}
|
||||
|
||||
doubleAnimation.AccelerationRatio = 0.3;
|
||||
doubleAnimation.DecelerationRatio = 0.3;
|
||||
doubleAnimation.Duration = TimeSpan.FromMilliseconds(100);
|
||||
doubleAnimation.Completed += (_, _) =>
|
||||
{
|
||||
this.Expanded = !this.Expanded;
|
||||
this.ExpanderButtonEnabled = true;
|
||||
};
|
||||
|
||||
this.BeginAnimation(ExpanderHeightProperty, doubleAnimation);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,14 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for AvatarGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class AvatarGlyph : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for AvatarGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class AvatarGlyph : UserControl
|
||||
public AvatarGlyph()
|
||||
{
|
||||
public AvatarGlyph()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<UserControl x:Class="Daybreak.Controls.Glyphs.DownloadGlyph"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Daybreak.Controls.Glyphs"
|
||||
mc:Ignorable="d"
|
||||
x:Name="_this"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Viewbox>
|
||||
<Grid>
|
||||
<Path Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" StrokeThickness="3"
|
||||
Data="m32,30.454c0,0 8.312,0 9.098,0c4.365,0 7.902,-3.537 7.902,-7.901s-3.537,-7.902 -7.902,-7.902c-0.02,0 -0.038,0.003 -0.058,0.003c0.061,-0.494 0.103,-0.994 0.103,-1.504c0,-6.71 -5.439,-12.15 -12.15,-12.15c-5.229,0 -9.672,3.309 -11.386,7.941c-1.087,-1.089 -2.591,-1.764 -4.251,-1.764c-3.319,0 -6.009,2.69 -6.009,6.008c0,0.085 0.01,0.167 0.013,0.251c-3.665,1.013 -6.36,4.362 -6.36,8.349c0,4.788 3.881,8.669 8.67,8.669c0.827,0 8.33,0 8.33,0"></Path>
|
||||
<Polyline Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Points="30,36 25,41 20,36" StrokeThickness="3"></Polyline>
|
||||
<Line X1="25" X2="25" Y1="21" Y2="41" Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" StrokeThickness="3"></Line>
|
||||
</Grid>
|
||||
</Viewbox>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Controls.Glyphs;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for DownloadGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class DownloadGlyph : UserControl
|
||||
{
|
||||
public DownloadGlyph()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -1,28 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for ExperimentGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class ExperimentGlyph : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ExperimentGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class ExperimentGlyph : UserControl
|
||||
public ExperimentGlyph()
|
||||
{
|
||||
public ExperimentGlyph()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for FileGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class FileGlyph : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for FileGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class FileGlyph : UserControl
|
||||
public FileGlyph()
|
||||
{
|
||||
public FileGlyph()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for FireballGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class FireballGlyph : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for FireballGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class FireballGlyph : UserControl
|
||||
public FireballGlyph()
|
||||
{
|
||||
public FireballGlyph()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<UserControl x:Class="Daybreak.Controls.Glyphs.GWToolboxGlyph"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Daybreak.Controls.Glyphs"
|
||||
mc:Ignorable="d"
|
||||
x:Name="_this"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Viewbox>
|
||||
<TextBlock Text="G" Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"></TextBlock>
|
||||
</Viewbox>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Daybreak.Controls.Glyphs;
|
||||
/// <summary>
|
||||
/// Interaction logic for GWToolboxGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class GWToolboxGlyph : UserControl
|
||||
{
|
||||
public GWToolboxGlyph()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<UserControl x:Class="Daybreak.Controls.Glyphs.GaugeGlyph"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Daybreak.Controls.Glyphs"
|
||||
mc:Ignorable="d"
|
||||
Name="_this"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Viewbox>
|
||||
<Grid>
|
||||
<Path Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Data="m13.5,13.5c1.44772,-1.44772 2.5,-3.29086 2.5,-5.5c0,-4.41828 -3.58172,-8 -8,-8s-8,3.58172 -8,8c0,2.20914 1.05228,4.05228 2.5,5.5"></Path>
|
||||
<Path Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Data="m8,8l-4,-4"></Path>
|
||||
<Ellipse Margin="6, 7.5, 6, 6" Width="1.5" Height="1.5"
|
||||
Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"></Ellipse>
|
||||
</Grid>
|
||||
</Viewbox>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Controls.Glyphs;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for GaugeGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class GaugeGlyph : UserControl
|
||||
{
|
||||
public GaugeGlyph()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -1,28 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for GoldenArrowGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class GoldenArrowGlyph : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for GoldenArrowGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class GoldenArrowGlyph : UserControl
|
||||
public GoldenArrowGlyph()
|
||||
{
|
||||
public GoldenArrowGlyph()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for LogsGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class LogsGlyph : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for LogsGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class LogsGlyph : UserControl
|
||||
public LogsGlyph()
|
||||
{
|
||||
public LogsGlyph()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<UserControl x:Class="Daybreak.Controls.Glyphs.MapGlyph"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Daybreak.Controls.Glyphs"
|
||||
mc:Ignorable="d"
|
||||
Name="_this"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Viewbox>
|
||||
<Grid>
|
||||
<Path Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Data="m18.53,14.53a9.37,9.37 0 0 1 -9.26,9.47l0,0a9.5,9.5 0 0 1 -3.26,-18.33a9.61,9.61 0 0 0 0.77,1.82a14.22,14.22 0 0 0 2.51,3.25a14.06,14.06 0 0 0 2.49,-3.24a9.2,9.2 0 0 0 0.75,-1.83a9.47,9.47 0 0 1 6,8.86z"></Path>
|
||||
<Polyline Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Points="9.270000457763672,24 9.270000457763672,23.989999771118164 9.270000457763672,10.739999771118164"></Polyline>
|
||||
<Path Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Data="m9.27,24l0,0c-0.32,-0.22 -5.27,-3.85 -4.94,-10.1a11.36,11.36 0 0 1 2.44,-6.4"></Path>
|
||||
<Path Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Data="m9.25,24a0,0 0 0 1 0,0l0,0c0.4,-0.29 5.25,-3.91 4.92,-10.1a11.35,11.35 0 0 0 -2.43,-6.39"></Path>
|
||||
<Line Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
X1="0" X2="18.53" Y1="14.53" Y2="14.53"></Line>
|
||||
<Path Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Data="m12.35,1.89a3.81,3.81 0 0 0 -3.08,-1.89a3.82,3.82 0 0 0 -3.09,1.89a4.75,4.75 0 0 0 -0.19,3.78a9.61,9.61 0 0 0 0.77,1.82a14.22,14.22 0 0 0 2.51,3.25a14.06,14.06 0 0 0 2.49,-3.24a9.2,9.2 0 0 0 0.77,-1.83a4.79,4.79 0 0 0 -0.18,-3.78z"></Path>
|
||||
<Ellipse Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Width="1.24" Height="1.26" Margin="8.6, 3" HorizontalAlignment="Left" VerticalAlignment="Top"></Ellipse>
|
||||
</Grid>
|
||||
</Viewbox>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Controls.Glyphs;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for MapGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class MapGlyph : UserControl
|
||||
{
|
||||
public MapGlyph()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -2,36 +2,35 @@
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for RefreshGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class RefreshGlyph : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for RefreshGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class RefreshGlyph : UserControl
|
||||
public event EventHandler? Clicked;
|
||||
|
||||
public RefreshGlyph()
|
||||
{
|
||||
public event EventHandler Clicked;
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
public RefreshGlyph()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0.6;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0.6;
|
||||
}
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
this.Clicked?.Invoke(this, e);
|
||||
}
|
||||
this.Clicked?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,36 +2,35 @@
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for BackButton.xaml
|
||||
/// </summary>
|
||||
public partial class StarGlyph : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for BackButton.xaml
|
||||
/// </summary>
|
||||
public partial class StarGlyph : UserControl
|
||||
public event EventHandler? Clicked;
|
||||
|
||||
public StarGlyph()
|
||||
{
|
||||
public event EventHandler Clicked;
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
public StarGlyph()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0.6;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0.6;
|
||||
}
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
this.BackgroundEllipse.Opacity = 0;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
Clicked?.Invoke(this, e);
|
||||
}
|
||||
Clicked?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for StaticGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class StaticGlyph : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for StaticGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class StaticGlyph : UserControl
|
||||
public StaticGlyph()
|
||||
{
|
||||
public StaticGlyph()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<UserControl x:Class="Daybreak.Controls.Glyphs.UModGlyph"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Daybreak.Controls.Glyphs"
|
||||
x:Name="_this"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Viewbox>
|
||||
<TextBlock Text="U" Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"></TextBlock>
|
||||
</Viewbox>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Daybreak.Controls.Glyphs;
|
||||
/// <summary>
|
||||
/// Interaction logic for UModGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class UModGlyph : UserControl
|
||||
{
|
||||
public UModGlyph()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<UserControl x:Class="Daybreak.Controls.GuildwarsMinimap"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Daybreak.Controls"
|
||||
x:Name="_this"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
MouseWheel="GuildwarsMinimap_MouseWheel"
|
||||
MouseLeftButtonDown="GuildwarsMinimap_MouseLeftButtonDown"
|
||||
MouseLeftButtonUp="GuildwarsMinimap_MouseLeftButtonUp"
|
||||
MouseRightButtonDown="GuildwarsMinimap_MouseRightButtonDown"
|
||||
MouseRightButtonUp="GuildwarsMinimap_MouseRightButtonUp"
|
||||
MouseMove="GuildwarsMinimap_MouseMove"
|
||||
Loaded="GuildwarsMinimap_Loaded"
|
||||
Unloaded="GuildwarsMinimap_Unloaded">
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"></BooleanToVisibilityConverter>
|
||||
<ContextMenu x:Key="WorldPlayerContextMenu">
|
||||
<ContextMenu.Template>
|
||||
<ControlTemplate>
|
||||
<local:WorldPlayerContextMenu DataContext="{Binding DataContext, RelativeSource={RelativeSource TemplatedParent}}"></local:WorldPlayerContextMenu>
|
||||
</ControlTemplate>
|
||||
</ContextMenu.Template>
|
||||
</ContextMenu>
|
||||
<ContextMenu x:Key="MainPlayerContextMenu">
|
||||
<ContextMenu.Template>
|
||||
<ControlTemplate>
|
||||
<local:MainPlayerContextMenu DataContext="{Binding DataContext, RelativeSource={RelativeSource TemplatedParent}}"></local:MainPlayerContextMenu>
|
||||
</ControlTemplate>
|
||||
</ContextMenu.Template>
|
||||
</ContextMenu>
|
||||
<ContextMenu x:Key="LivingEntityContextMenu">
|
||||
<ContextMenu.Template>
|
||||
<ControlTemplate>
|
||||
<local:LivingEntityContextMenu DataContext="{Binding DataContext, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
LivingEntityContextMenuClicked="LivingEntityContextMenu_LivingEntityContextMenuClicked"></local:LivingEntityContextMenu>
|
||||
</ControlTemplate>
|
||||
</ContextMenu.Template>
|
||||
</ContextMenu>
|
||||
<ContextMenu x:Key="PlayerContextMenu">
|
||||
<ContextMenu.Template>
|
||||
<ControlTemplate>
|
||||
<local:PlayerContextMenu DataContext="{Binding DataContext, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
PlayerContextMenuClicked="PlayerContextMenu_PlayerContextMenuClicked"></local:PlayerContextMenu>
|
||||
</ControlTemplate>
|
||||
</ContextMenu.Template>
|
||||
</ContextMenu>
|
||||
<ContextMenu x:Key="QuestContextMenu">
|
||||
<ContextMenu.Template>
|
||||
<ControlTemplate>
|
||||
<local:QuestContextMenu DataContext="{Binding DataContext, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
QuestContextMenuClicked="QuestContextMenu_QuestContextMenuClicked"></local:QuestContextMenu>
|
||||
</ControlTemplate>
|
||||
</ContextMenu.Template>
|
||||
</ContextMenu>
|
||||
<ContextMenu x:Key="MapIconContextMenu">
|
||||
<ContextMenu.Template>
|
||||
<ControlTemplate>
|
||||
<local:MapIconContextMenu DataContext="{Binding DataContext, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
MapIconContextMenuClicked="MapIconContextMenu_MapIconContextMenuClicked"></local:MapIconContextMenu>
|
||||
</ControlTemplate>
|
||||
</ContextMenu.Template>
|
||||
</ContextMenu>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Image x:Name="MapDrawingHost" VerticalAlignment="Top" HorizontalAlignment="Left" Stretch="Fill"/>
|
||||
<Image x:Name="EntitiesDrawingHost" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
|
||||
<Grid Background="#F0212121"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Right"
|
||||
Visibility="{Binding ElementName=_this, Path=ControlsVisible, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||
<local:MaximizeButton Height="30" Width="30" Margin="5"
|
||||
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Clicked="MaximizeButton_Clicked"></local:MaximizeButton>
|
||||
</Grid>
|
||||
<WrapPanel Background="#F0212121" VerticalAlignment="Top" HorizontalAlignment="Right" >
|
||||
<TextBlock Text="{Binding ElementName=_this, Path=TargetEntityId, Mode=OneWay}" Foreground="White"
|
||||
FontSize="16" Padding="5" ></TextBlock>
|
||||
<TextBlock Text=" - " Foreground="White"
|
||||
FontSize="16" Padding="5" ></TextBlock>
|
||||
<TextBlock Text="{Binding ElementName=_this, Path=TargetEntityModelId, Mode=OneWay}" Foreground="White"
|
||||
FontSize="16" Padding="5" ></TextBlock>
|
||||
</WrapPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,699 @@
|
||||
using Daybreak.Models.Guildwars;
|
||||
using Daybreak.Models;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Extensions;
|
||||
using System.Windows;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Media;
|
||||
using System;
|
||||
using System.Extensions;
|
||||
using Daybreak.Services.Scanner;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Core.Extensions;
|
||||
using System.Windows.Input;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Daybreak.Services.Pathfinding;
|
||||
using Daybreak.Services.Pathfinding.Models;
|
||||
using System.Windows.Threading;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Daybreak.Services.Drawing;
|
||||
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0052:Remove unread private members", Justification = "Using source generators to auto-implement dependency properties")]
|
||||
/// <summary>
|
||||
/// Interaction logic for GuildwarsMinimap.xaml
|
||||
/// </summary>
|
||||
public partial class GuildwarsMinimap : UserControl
|
||||
{
|
||||
private const int MapDownscaleFactor = 10;
|
||||
private const int EntitySize = 100;
|
||||
private const float PositionRadius = 150;
|
||||
// Minimum amount of milliseconds to pass between calculating paths to objectives
|
||||
private const int MinPathCalculationFrequency = 500;
|
||||
|
||||
private readonly DispatcherTimer dispatcherTimer = new(DispatcherPriority.ApplicationIdle);
|
||||
private readonly List<Position> mainPlayerPositionHistory = new();
|
||||
private readonly IPathfinder pathfinder;
|
||||
private readonly IDrawingService drawingService;
|
||||
private readonly IGuildwarsEntityDebouncer guildwarsEntityDebouncer;
|
||||
private readonly Color outlineColor = Colors.Chocolate;
|
||||
private readonly TimeSpan offsetRevertDelay = TimeSpan.FromSeconds(3);
|
||||
|
||||
private bool calculatingPathToObjectives = false;
|
||||
private bool resizeEntities;
|
||||
private bool dragging;
|
||||
private double mapVirtualMinWidth;
|
||||
private double mapVirtualMinHeight;
|
||||
private double mapWidth;
|
||||
private double mapHeight;
|
||||
private DateTime offsetRevertTime = DateTime.Now;
|
||||
private double offsetRevert = 0;
|
||||
private Point originPoint = new(0, 0);
|
||||
private Vector originOffset = new(0, 0);
|
||||
private Point initialClickPoint = new(0, 0);
|
||||
private DebounceResponse? cachedDebounceResponse;
|
||||
private PathfindingCache? pathfindingCache;
|
||||
|
||||
[GenerateDependencyProperty]
|
||||
private PathingData pathingData = new();
|
||||
[GenerateDependencyProperty]
|
||||
private GameData gameData = new();
|
||||
[GenerateDependencyProperty]
|
||||
private double zoom = 0.08;
|
||||
[GenerateDependencyProperty(InitialValue = true)]
|
||||
private bool drawPositionHistory = true;
|
||||
[GenerateDependencyProperty]
|
||||
private bool controlsVisible;
|
||||
[GenerateDependencyProperty]
|
||||
private int targetEntityId;
|
||||
[GenerateDependencyProperty]
|
||||
private int targetEntityModelId;
|
||||
|
||||
public event EventHandler? MaximizeClicked;
|
||||
public event EventHandler<QuestMetadata>? QuestMetadataClicked;
|
||||
public event EventHandler<LivingEntity>? LivingEntityClicked;
|
||||
public event EventHandler<PlayerInformation>? PlayerInformationClicked;
|
||||
public event EventHandler<MapIcon>? MapIconClicked;
|
||||
|
||||
public GuildwarsMinimap()
|
||||
:this(
|
||||
Launch.Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IPathfinder>(),
|
||||
Launch.Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IDrawingService>(),
|
||||
Launch.Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IGuildwarsEntityDebouncer>())
|
||||
{
|
||||
}
|
||||
|
||||
public GuildwarsMinimap(
|
||||
IPathfinder pathfinder,
|
||||
IDrawingService drawingService,
|
||||
IGuildwarsEntityDebouncer guildwarsEntityDebouncer)
|
||||
{
|
||||
this.pathfinder = pathfinder.ThrowIfNull();
|
||||
this.drawingService = drawingService.ThrowIfNull();
|
||||
this.guildwarsEntityDebouncer = guildwarsEntityDebouncer.ThrowIfNull();
|
||||
|
||||
this.dispatcherTimer.Tick += (_, _) => this.ApplyOffsetRevert();
|
||||
this.dispatcherTimer.Interval = TimeSpan.FromMilliseconds(16);
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
base.OnPropertyChanged(e);
|
||||
if (e.Property == ActualHeightProperty ||
|
||||
e.Property == ActualWidthProperty)
|
||||
{
|
||||
this.resizeEntities = true;
|
||||
}
|
||||
else if (e.Property == PathingDataProperty)
|
||||
{
|
||||
this.guildwarsEntityDebouncer.ClearCaches();
|
||||
this.mainPlayerPositionHistory.Clear();
|
||||
this.UpdateGameData();
|
||||
this.DrawMap();
|
||||
}
|
||||
else if (e.Property == ZoomProperty)
|
||||
{
|
||||
this.UpdateGameData();
|
||||
}
|
||||
else if (e.Property == GameDataProperty &&
|
||||
this.GameData.Valid)
|
||||
{
|
||||
this.UpdateGameData();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateGameData()
|
||||
{
|
||||
if(this.GameData.Valid is false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var debounceResponse = this.guildwarsEntityDebouncer.DebounceEntities(this.GameData);
|
||||
if (!double.IsFinite(this.mapWidth) ||
|
||||
!double.IsFinite(this.mapHeight) ||
|
||||
!double.IsFinite(this.mapVirtualMinWidth) ||
|
||||
!double.IsFinite(this.mapVirtualMinHeight) ||
|
||||
debounceResponse.MainPlayer.Position is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.TargetEntityId = this.GameData.Session?.CurrentTargetId ?? 0;
|
||||
this.TargetEntityModelId = (int?)this.GameData.LivingEntities?.FirstOrDefault(e => e.Id == this.TargetEntityId).ModelType ?? 0;
|
||||
var screenVirtualWidth = this.ActualWidth / this.Zoom;
|
||||
var screenVirtualHeight = this.ActualHeight / this.Zoom;
|
||||
var position = debounceResponse.MainPlayer.Position!.Value;
|
||||
this.originPoint = new Point(
|
||||
position.X - (screenVirtualWidth / 2) - (this.originOffset.X / this.Zoom),
|
||||
position.Y + (screenVirtualHeight / 2) + (this.originOffset.Y / this.Zoom));
|
||||
|
||||
var adjustedPosition = new Point((int)((position.X - this.mapVirtualMinWidth) * this.Zoom), (int)(this.mapHeight - position.Y + this.mapVirtualMinHeight) * this.Zoom);
|
||||
|
||||
this.MapDrawingHost.Margin = new Thickness(
|
||||
-adjustedPosition.X + (this.ActualWidth / 2) + this.originOffset.X,
|
||||
-adjustedPosition.Y + (this.ActualHeight / 2) + this.originOffset.Y,
|
||||
0,
|
||||
0);
|
||||
this.MapDrawingHost.Height = this.mapHeight * this.Zoom;
|
||||
this.MapDrawingHost.Width = this.mapWidth * this.Zoom;
|
||||
this.cachedDebounceResponse = debounceResponse;
|
||||
this.ManageMainPlayerPositionHistory();
|
||||
this.DrawEntities();
|
||||
}
|
||||
|
||||
private void ManageMainPlayerPositionHistory()
|
||||
{
|
||||
if (this.cachedDebounceResponse is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var currentPosition = this.cachedDebounceResponse.MainPlayer.Position ?? throw new InvalidOperationException("Unexpected main player null position");
|
||||
if (this.mainPlayerPositionHistory.Any(oldPosition => PositionsCollide(oldPosition, currentPosition)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.mainPlayerPositionHistory.Add(currentPosition);
|
||||
}
|
||||
|
||||
private void DrawMap()
|
||||
{
|
||||
if (this.PathingData.Trapezoids is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var maxWidth = double.MinValue;
|
||||
var maxHeight = double.MinValue;
|
||||
var minWidth = double.MaxValue;
|
||||
var minHeight = double.MaxValue;
|
||||
foreach (var trapezoid in this.PathingData.Trapezoids!)
|
||||
{
|
||||
if (trapezoid.YT < minHeight)
|
||||
{
|
||||
minHeight = trapezoid.YT;
|
||||
}
|
||||
|
||||
if (trapezoid.YB > maxHeight)
|
||||
{
|
||||
maxHeight = trapezoid.YB;
|
||||
}
|
||||
|
||||
if (trapezoid.XTL < minWidth)
|
||||
{
|
||||
minWidth = trapezoid.XTL;
|
||||
}
|
||||
|
||||
if (trapezoid.XBL < minWidth)
|
||||
{
|
||||
minWidth = trapezoid.XBL;
|
||||
}
|
||||
|
||||
if (trapezoid.XTR > maxWidth)
|
||||
{
|
||||
maxWidth = trapezoid.XTR;
|
||||
}
|
||||
|
||||
if (trapezoid.XBR > maxWidth)
|
||||
{
|
||||
maxWidth = trapezoid.XBR;
|
||||
}
|
||||
}
|
||||
|
||||
var width = maxWidth - minWidth;
|
||||
var height = maxHeight - minHeight;
|
||||
this.mapVirtualMinHeight = minHeight;
|
||||
this.mapVirtualMinWidth = minWidth;
|
||||
this.mapWidth = width;
|
||||
this.mapHeight = height;
|
||||
|
||||
if (width <= 0 || height <= 0 ||
|
||||
!double.IsFinite(width) ||
|
||||
!double.IsFinite(height))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var bitmap = BitmapFactory.New((int)(width / MapDownscaleFactor), (int)(height / MapDownscaleFactor));
|
||||
this.MapDrawingHost.Source = bitmap;
|
||||
this.MapDrawingHost.Width = width / MapDownscaleFactor;
|
||||
this.MapDrawingHost.Height = height / MapDownscaleFactor;
|
||||
|
||||
using var bitmapContext = bitmap.GetBitmapContext();
|
||||
bitmap.Clear(Colors.Transparent);
|
||||
|
||||
foreach (var trapezoid in this.PathingData.Trapezoids)
|
||||
{
|
||||
var a = new Point((int)((trapezoid.XTL - minWidth) / MapDownscaleFactor), (int)((height - trapezoid.YT + minHeight) / MapDownscaleFactor));
|
||||
var b = new Point((int)((trapezoid.XTR - minWidth) / MapDownscaleFactor), (int)((height - trapezoid.YT + minHeight) / MapDownscaleFactor));
|
||||
var c = new Point((int)((trapezoid.XBR - minWidth) / MapDownscaleFactor), (int)((height - trapezoid.YB + minHeight) / MapDownscaleFactor));
|
||||
var d = new Point((int)((trapezoid.XBL - minWidth) / MapDownscaleFactor), (int)((height - trapezoid.YB + minHeight) / MapDownscaleFactor));
|
||||
|
||||
bitmap.FillPolygon(new int[] { (int)a.X, (int)a.Y, (int)b.X, (int)b.Y, (int)c.X, (int)c.Y, (int)d.X, (int)d.Y, (int)a.X, (int)a.Y }, Colors.White);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawEntities()
|
||||
{
|
||||
if (this.ActualWidth == 0 || this.ActualHeight == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.EntitiesDrawingHost.Source is not WriteableBitmap bitmap ||
|
||||
this.resizeEntities ||
|
||||
bitmap.PixelHeight != (int)this.ActualHeight ||
|
||||
bitmap.PixelWidth != (int)this.ActualWidth)
|
||||
{
|
||||
bitmap = BitmapFactory.New((int)this.ActualWidth, (int)this.ActualHeight);
|
||||
this.EntitiesDrawingHost.Source = bitmap;
|
||||
this.resizeEntities = false;
|
||||
}
|
||||
|
||||
this.CalculatePathsToObjectives();
|
||||
|
||||
bitmap.Clear(Colors.Transparent);
|
||||
using var context = bitmap.GetBitmapContext();
|
||||
|
||||
this.drawingService.UpdateDrawingParameters(
|
||||
(int)this.ActualWidth,
|
||||
(int)this.ActualHeight,
|
||||
this.originPoint,
|
||||
this.Zoom,
|
||||
PositionRadius,
|
||||
EntitySize);
|
||||
this.drawingService.DrawMainPlayerPositionHistory(bitmap, this.mainPlayerPositionHistory);
|
||||
this.drawingService.DrawPaths(bitmap, this.pathfindingCache);
|
||||
this.drawingService.DrawQuestObjectives(bitmap, this.GameData.MainPlayer?.QuestLog ?? new List<QuestMetadata>());
|
||||
this.drawingService.DrawMapIcons(bitmap, this.GameData.MapIcons ?? new List<MapIcon>());
|
||||
this.drawingService.DrawEntities(bitmap, this.cachedDebounceResponse ?? new DebounceResponse(), this.TargetEntityId);
|
||||
}
|
||||
|
||||
private bool MouseOverEntity(IPositionalEntity entity, Point mousePosition)
|
||||
{
|
||||
var x = (int)((entity.Position!.Value.X - this.originPoint.X) * this.Zoom);
|
||||
var y = 0 - (int)((entity.Position!.Value.Y - this.originPoint.Y) * this.Zoom);
|
||||
|
||||
return Math.Pow(mousePosition.X - x, 2) + Math.Pow(mousePosition.Y - y, 2) < Math.Pow(EntitySize * this.Zoom, 2);
|
||||
}
|
||||
|
||||
private void DragMinimap()
|
||||
{
|
||||
if (this.dragging is false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var mousePosition = Mouse.GetPosition(this);
|
||||
this.offsetRevert = 0;
|
||||
this.originOffset = mousePosition - this.initialClickPoint;
|
||||
this.offsetRevertTime = DateTime.Now + this.offsetRevertDelay;
|
||||
this.UpdateGameData();
|
||||
}
|
||||
|
||||
private void ApplyOffsetRevert()
|
||||
{
|
||||
if (DateTime.Now < this.offsetRevertTime)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.ContextMenu?.IsOpen is true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.offsetRevert = 0.0001 + (this.offsetRevert * 1.0001);
|
||||
this.offsetRevert = Math.Min(99, this.offsetRevert);
|
||||
this.originOffset /= 1 + this.offsetRevert;
|
||||
this.UpdateGameData();
|
||||
}
|
||||
|
||||
private async void CalculatePathsToObjectives()
|
||||
{
|
||||
if (this.calculatingPathToObjectives)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.calculatingPathToObjectives = true;
|
||||
var currentMapQuests = this.GameData.MainPlayer?.QuestLog?.Where(q => IsValidPositionalEntity(q)).ToList();
|
||||
if (currentMapQuests is null)
|
||||
{
|
||||
this.calculatingPathToObjectives = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var pathfindingTasks = currentMapQuests
|
||||
.Select(questMetaData =>
|
||||
{
|
||||
return this.pathfinder.CalculatePath(
|
||||
this.PathingData,
|
||||
new Point
|
||||
{
|
||||
X = this.cachedDebounceResponse?.MainPlayer.Position?.X ?? 0,
|
||||
Y = this.cachedDebounceResponse?.MainPlayer.Position?.Y ?? 0,
|
||||
},
|
||||
new Point
|
||||
{
|
||||
X = questMetaData.Position!.Value.X,
|
||||
Y = questMetaData.Position!.Value.Y
|
||||
},
|
||||
CancellationToken.None);
|
||||
})
|
||||
.ToList();
|
||||
|
||||
await Task.WhenAll(pathfindingTasks.Append(Task.Delay(MinPathCalculationFrequency)));
|
||||
var paths = new List<PathfindingResponse>();
|
||||
var colors = new List<Color>();
|
||||
for(var i = 0; i < currentMapQuests.Count; i++)
|
||||
{
|
||||
var quest = currentMapQuests[i];
|
||||
var result = await pathfindingTasks[i];
|
||||
if (result.TryExtractSuccess(out var pathfindingResponse))
|
||||
{
|
||||
paths.Add(pathfindingResponse);
|
||||
var questColor = GetQuestColor(quest);
|
||||
var pathColor = Color.FromArgb(100, questColor.R, questColor.G, questColor.B);
|
||||
colors.Add(pathColor);
|
||||
}
|
||||
}
|
||||
|
||||
this.pathfindingCache = new PathfindingCache { PathfindingResponses = paths, Colors = colors };
|
||||
this.calculatingPathToObjectives = false;
|
||||
}
|
||||
|
||||
private IPositionalEntity? CheckMouseOverEntity(IEnumerable<IPositionalEntity>? maybeEntities)
|
||||
{
|
||||
if (maybeEntities is not IEnumerable<IPositionalEntity> entities)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
if (this.GameData.Valid is false)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
var mousePoint = Mouse.GetPosition(this);
|
||||
foreach(var entity in entities)
|
||||
{
|
||||
if (this.MouseOverEntity(entity, mousePoint))
|
||||
{
|
||||
this.Cursor = Cursors.Hand;
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
|
||||
this.Cursor = default;
|
||||
return default;
|
||||
}
|
||||
|
||||
private Position ForceOnScreenPosition(Position entityPosition)
|
||||
{
|
||||
var screenVirtualWidth = this.ActualWidth / this.Zoom;
|
||||
var screenVirtualHeight = this.ActualHeight / this.Zoom;
|
||||
var finalEntitySize = EntitySize * this.Zoom;
|
||||
return new Position
|
||||
{
|
||||
X = (float)Math.Clamp(
|
||||
entityPosition.X,
|
||||
Math.Min(this.originPoint.X + finalEntitySize, this.originPoint.X + screenVirtualWidth - finalEntitySize),
|
||||
Math.Max(this.originPoint.X + finalEntitySize, this.originPoint.X + screenVirtualWidth - finalEntitySize)),
|
||||
Y = (float)Math.Clamp(
|
||||
entityPosition.Y,
|
||||
Math.Min(this.originPoint.Y - screenVirtualHeight + finalEntitySize, this.originPoint.Y - finalEntitySize),
|
||||
Math.Max(this.originPoint.Y - screenVirtualHeight + finalEntitySize, this.originPoint.Y - finalEntitySize)),
|
||||
};
|
||||
}
|
||||
|
||||
private void GuildwarsMinimap_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
this.initialClickPoint = Mouse.GetPosition(this) - this.originOffset;
|
||||
this.offsetRevert = 0;
|
||||
this.offsetRevertTime = DateTime.Now + this.offsetRevertDelay;
|
||||
this.dragging = true;
|
||||
}
|
||||
|
||||
private void GuildwarsMinimap_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
this.dragging = false;
|
||||
}
|
||||
|
||||
private void GuildwarsMinimap_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
var maybeOffScreenQuestMetadata = this.CheckMouseOverEntity(
|
||||
this.GameData.MainPlayer?.QuestLog?
|
||||
.Where(q => IsValidPositionalEntity(q))
|
||||
.Where(entity => !this.drawingService.IsEntityOnScreen(entity.Position, out _, out _))
|
||||
.Select(oldQuestMetadata =>
|
||||
{
|
||||
var onScreenPosition = this.ForceOnScreenPosition(oldQuestMetadata.Position!.Value);
|
||||
return new QuestMetadata
|
||||
{
|
||||
From = oldQuestMetadata.From,
|
||||
To = oldQuestMetadata.To,
|
||||
Quest = oldQuestMetadata.Quest,
|
||||
Position = onScreenPosition
|
||||
};
|
||||
})
|
||||
.OfType<IPositionalEntity>());
|
||||
if (maybeOffScreenQuestMetadata is QuestMetadata offscreenQuestMetadata &&
|
||||
this.TryFindResource("QuestContextMenu") is ContextMenu offscreenQuestContextMenu)
|
||||
{
|
||||
this.ContextMenu = offscreenQuestContextMenu;
|
||||
this.ContextMenu.DataContext = offscreenQuestMetadata;
|
||||
this.ContextMenu.IsOpen = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var maybeQuestMetadata = this.CheckMouseOverEntity(
|
||||
this.GameData.MainPlayer?.QuestLog?
|
||||
.OfType<IPositionalEntity>().Where(IsValidPositionalEntity)
|
||||
.Where(entity => this.drawingService.IsEntityOnScreen(entity.Position, out _, out _)));
|
||||
if (maybeQuestMetadata is QuestMetadata questMetadata &&
|
||||
this.TryFindResource("QuestContextMenu") is ContextMenu questContextMenu)
|
||||
{
|
||||
this.ContextMenu = questContextMenu;
|
||||
this.ContextMenu.DataContext = questMetadata;
|
||||
this.ContextMenu.IsOpen = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.CheckMouseOverEntity(Enumerable.Repeat(this.GameData.MainPlayer.As<IEntity>(), 1)) is MainPlayerInformation &&
|
||||
this.TryFindResource("MainPlayerContextMenu") is ContextMenu mainPlayerContextMenu)
|
||||
{
|
||||
this.ContextMenu = mainPlayerContextMenu;
|
||||
this.ContextMenu.DataContext = this.GameData.MainPlayer;
|
||||
this.ContextMenu.IsOpen = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var maybeWorldPlayer = this.CheckMouseOverEntity(this.GameData.WorldPlayers?.OfType<IEntity>().Where(IsValidPositionalEntity).OrderByDescending(p => p.Id == this.TargetEntityId));
|
||||
if (maybeWorldPlayer is WorldPlayerInformation worldPlayerInformation &&
|
||||
this.TryFindResource("WorldPlayerContextMenu") is ContextMenu worldPlayerContextMenu)
|
||||
{
|
||||
this.ContextMenu = worldPlayerContextMenu;
|
||||
this.ContextMenu.DataContext = worldPlayerInformation;
|
||||
this.ContextMenu.IsOpen = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var maybePartyMember = this.CheckMouseOverEntity(this.GameData.Party?.OfType<IEntity>().Where(IsValidPositionalEntity).OrderByDescending(p => p.Id == this.TargetEntityId));
|
||||
if (maybePartyMember is PlayerInformation partyMember &&
|
||||
this.TryFindResource("PlayerContextMenu") is ContextMenu playerContextMenu)
|
||||
{
|
||||
this.ContextMenu = playerContextMenu;
|
||||
this.ContextMenu.DataContext = partyMember;
|
||||
this.ContextMenu.IsOpen = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var maybeLivingEntity = this.CheckMouseOverEntity(this.GameData.LivingEntities?.OfType<IEntity>().Where(IsValidPositionalEntity).OrderByDescending(p => p.Id == this.TargetEntityId));
|
||||
if (maybeLivingEntity is LivingEntity livingEntity &&
|
||||
this.TryFindResource("LivingEntityContextMenu") is ContextMenu livingEntityContextMenu)
|
||||
{
|
||||
this.ContextMenu = livingEntityContextMenu;
|
||||
this.ContextMenu.DataContext = livingEntity;
|
||||
this.ContextMenu.IsOpen = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var maybeMapIcon = this.CheckMouseOverEntity(this.GameData.MapIcons?.OfType<IPositionalEntity>().Where(IsValidPositionalEntity));
|
||||
if (maybeMapIcon is MapIcon mapIcon &&
|
||||
this.TryFindResource("MapIconContextMenu") is ContextMenu mapIconContextMenu)
|
||||
{
|
||||
this.ContextMenu = mapIconContextMenu;
|
||||
this.ContextMenu.DataContext = mapIcon;
|
||||
this.ContextMenu.IsOpen = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this.ContextMenu = default;
|
||||
}
|
||||
|
||||
private void GuildwarsMinimap_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
}
|
||||
|
||||
private void GuildwarsMinimap_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (this.GameData.Valid is false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.DragMinimap();
|
||||
if (this.CheckMouseOverEntity(this.GameData.Party!.OfType<IEntity>()) is not null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.CheckMouseOverEntity(this.GameData.WorldPlayers!.OfType<IEntity>()) is not null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.CheckMouseOverEntity(Enumerable.Repeat(this.GameData.MainPlayer.As<IEntity>(), 1)) is not null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.CheckMouseOverEntity(this.GameData.LivingEntities!.OfType<IEntity>()) is not null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.CheckMouseOverEntity(this.GameData.MapIcons!.OfType<IPositionalEntity>()) is not null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.CheckMouseOverEntity(this.GameData.MainPlayer!.Value.QuestLog!
|
||||
.Where(entity => this.drawingService.IsEntityOnScreen(entity.Position, out _, out _))
|
||||
.OfType<IPositionalEntity>()) is not null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.CheckMouseOverEntity(this.GameData.MainPlayer!.Value.QuestLog!
|
||||
.Where(entity => !this.drawingService.IsEntityOnScreen(entity.Position, out _, out _))
|
||||
.Select(oldQuestMetadata =>
|
||||
{
|
||||
var onScreenPosition = this.ForceOnScreenPosition(oldQuestMetadata.Position!.Value);
|
||||
return new QuestMetadata
|
||||
{
|
||||
From = oldQuestMetadata.From,
|
||||
To = oldQuestMetadata.To,
|
||||
Quest = oldQuestMetadata.Quest,
|
||||
Position = onScreenPosition
|
||||
};
|
||||
})
|
||||
.OfType<IPositionalEntity>()) is not null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void GuildwarsMinimap_MouseWheel(object sender, MouseWheelEventArgs e)
|
||||
{
|
||||
var delta = e.Delta > 0 ? 0.1 : -0.1;
|
||||
var previousZoom = this.Zoom;
|
||||
var newZoom = this.Zoom + this.Zoom * delta;
|
||||
this.originOffset *= newZoom / previousZoom;
|
||||
this.initialClickPoint = new Point(
|
||||
this.initialClickPoint.X * newZoom / previousZoom,
|
||||
this.initialClickPoint.Y * newZoom / previousZoom);
|
||||
|
||||
this.Zoom = newZoom;
|
||||
}
|
||||
|
||||
private void GuildwarsMinimap_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.dispatcherTimer.Start();
|
||||
}
|
||||
|
||||
private void GuildwarsMinimap_Unloaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.dispatcherTimer.Stop();
|
||||
}
|
||||
|
||||
private void QuestContextMenu_QuestContextMenuClicked(object _, QuestMetadata? quest)
|
||||
{
|
||||
if (quest is not QuestMetadata)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.QuestMetadataClicked?.Invoke(this, quest.Value);
|
||||
}
|
||||
|
||||
private void PlayerContextMenu_PlayerContextMenuClicked(object _, PlayerInformation? playerInformation)
|
||||
{
|
||||
if (playerInformation is not PlayerInformation)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.PlayerInformationClicked?.Invoke(this, playerInformation.Value);
|
||||
}
|
||||
|
||||
private void LivingEntityContextMenu_LivingEntityContextMenuClicked(object _, LivingEntity? livingEntity)
|
||||
{
|
||||
if (livingEntity is not LivingEntity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.LivingEntityClicked?.Invoke(this, livingEntity.Value);
|
||||
}
|
||||
|
||||
private void MapIconContextMenu_MapIconContextMenuClicked(object _, MapIcon? mapIcon)
|
||||
{
|
||||
if (mapIcon is not MapIcon)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.MapIconClicked?.Invoke(this, mapIcon.Value);
|
||||
}
|
||||
|
||||
private void MaximizeButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.MaximizeClicked?.Invoke(this, e);
|
||||
if (e is MouseButtonEventArgs mouseButtonEventArgs)
|
||||
{
|
||||
mouseButtonEventArgs.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool PositionsCollide(Position position1, Position position2)
|
||||
{
|
||||
var a = PositionRadius + PositionRadius;
|
||||
var dx = position1.X - position2.X;
|
||||
var dy = position1.Y - position2.Y;
|
||||
return a * a > ((dx * dx) + (dy * dy));
|
||||
}
|
||||
|
||||
private static bool IsValidPositionalEntity(IPositionalEntity entity)
|
||||
{
|
||||
if (entity.Position?.X == 0 &&
|
||||
entity.Position?.Y == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Color GetQuestColor(QuestMetadata questMetadata)
|
||||
{
|
||||
return QuestObjectiveColors.Colors[questMetadata.Quest?.Id % QuestObjectiveColors.Colors.Count ?? 0];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<UserControl x:Class="Daybreak.Controls.HorizontalResourceBar"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Daybreak.Controls"
|
||||
mc:Ignorable="d"
|
||||
x:Name="_this"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
<Viewbox VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Stretch="Fill">
|
||||
<Grid Height="1">
|
||||
<Rectangle
|
||||
Fill="{Binding ElementName=_this, Path=BarColor, Mode=OneWay}"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="{Binding ElementName=_this, Path=FillAlignment, Mode=OneWay}"
|
||||
Width="{Binding ElementName=_this, Path=MaxResourceValue, Mode=TwoWay}"></Rectangle>
|
||||
<Rectangle
|
||||
Fill="#F0202020"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch"></Rectangle>
|
||||
<Rectangle
|
||||
Fill="{Binding ElementName=_this, Path=BarColor, Mode=OneWay}"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="{Binding ElementName=_this, Path=FillAlignment, Mode=OneWay}"
|
||||
Width="{Binding ElementName=_this, Path=CurrentResourceValue, Mode=TwoWay}"></Rectangle>
|
||||
</Grid>
|
||||
</Viewbox>
|
||||
<TextBlock
|
||||
FontSize="{Binding ElementName=_this, Path=FontSize, Mode=OneWay}"
|
||||
FontFamily="{Binding ElementName=_this, Path=FontFamily, Mode=OneWay}"
|
||||
Text="{Binding ElementName=_this, Path=Text, Mode=OneWay}"
|
||||
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"></TextBlock>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,34 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Extensions;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for ResourceBar.xaml
|
||||
/// </summary>
|
||||
public partial class HorizontalResourceBar : UserControl
|
||||
{
|
||||
[GenerateDependencyProperty]
|
||||
private double currentResourceValue;
|
||||
[GenerateDependencyProperty]
|
||||
private double maxResourceValue;
|
||||
[GenerateDependencyProperty]
|
||||
private Brush barColor;
|
||||
[GenerateDependencyProperty]
|
||||
private string text;
|
||||
[GenerateDependencyProperty(InitialValue = HorizontalAlignment.Left)]
|
||||
private HorizontalAlignment fillAlignment;
|
||||
|
||||
public HorizontalResourceBar()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.MaxResourceValue = 1;
|
||||
this.CurrentResourceValue = 0;
|
||||
this.barColor = Brushes.Transparent;
|
||||
this.text = string.Empty;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -5,88 +5,87 @@ using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for ImageViewer.xaml
|
||||
/// </summary>
|
||||
public partial class ImageViewer : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ImageViewer.xaml
|
||||
/// </summary>
|
||||
public partial class ImageViewer : UserControl
|
||||
public ImageSource ImageSource
|
||||
{
|
||||
public ImageSource ImageSource
|
||||
get => this.CurrentVisible().Source;
|
||||
set => this.ShowImage(value);
|
||||
}
|
||||
|
||||
public ImageViewer()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.Image1.Visibility = Visibility.Visible;
|
||||
this.Image1.Opacity = 1;
|
||||
this.Image2.Visibility = Visibility.Hidden;
|
||||
this.Image2.Opacity = 0;
|
||||
}
|
||||
|
||||
public async void ShowImage(ImageSource imageSource)
|
||||
{
|
||||
var currentVisible = this.CurrentVisible();
|
||||
var nextVisible = this.NextVisible();
|
||||
|
||||
if (nextVisible.Source is BitmapImage bitmapImage)
|
||||
{
|
||||
get => this.CurrentVisible().Source;
|
||||
set => this.ShowImage(value);
|
||||
await bitmapImage.StreamSource.DisposeAsync().ConfigureAwait(true);
|
||||
}
|
||||
|
||||
public ImageViewer()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.Image1.Visibility = Visibility.Visible;
|
||||
this.Image1.Opacity = 1;
|
||||
this.Image2.Visibility = Visibility.Hidden;
|
||||
this.Image2.Opacity = 0;
|
||||
}
|
||||
nextVisible.Source = imageSource;
|
||||
Transition(currentVisible, nextVisible);
|
||||
}
|
||||
|
||||
public async void ShowImage(ImageSource imageSource)
|
||||
private Image CurrentVisible()
|
||||
{
|
||||
if (this.Image1.Visibility == Visibility.Visible)
|
||||
{
|
||||
var currentVisible = this.CurrentVisible();
|
||||
var nextVisible = this.NextVisible();
|
||||
|
||||
if (nextVisible.Source is BitmapImage bitmapImage)
|
||||
{
|
||||
await bitmapImage.StreamSource.DisposeAsync().ConfigureAwait(true);
|
||||
}
|
||||
|
||||
nextVisible.Source = imageSource;
|
||||
Transition(currentVisible, nextVisible);
|
||||
return this.Image1;
|
||||
}
|
||||
|
||||
private Image CurrentVisible()
|
||||
else
|
||||
{
|
||||
if (this.Image1.Visibility == Visibility.Visible)
|
||||
{
|
||||
return this.Image1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.Image2;
|
||||
}
|
||||
}
|
||||
private Image NextVisible()
|
||||
{
|
||||
if (this.Image1.Visibility == Visibility.Visible)
|
||||
{
|
||||
return this.Image2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.Image1;
|
||||
}
|
||||
}
|
||||
private static void Transition(Image from, Image to)
|
||||
{
|
||||
to.Visibility = Visibility.Visible;
|
||||
to.Opacity = 0;
|
||||
from.Visibility = Visibility.Visible;
|
||||
from.Opacity = 1;
|
||||
var showAnimation = new DoubleAnimation()
|
||||
{
|
||||
From = 0,
|
||||
To = 1,
|
||||
Duration = TimeSpan.FromSeconds(1.5)
|
||||
};
|
||||
var hideAnimation = new DoubleAnimation
|
||||
{
|
||||
From = 1,
|
||||
To = 0,
|
||||
Duration = TimeSpan.FromSeconds(1.5)
|
||||
};
|
||||
hideAnimation.Completed += (s, e) =>
|
||||
{
|
||||
from.Visibility = Visibility.Hidden;
|
||||
to.BeginAnimation(Image.OpacityProperty, showAnimation);
|
||||
};
|
||||
from.BeginAnimation(Image.OpacityProperty, hideAnimation);
|
||||
return this.Image2;
|
||||
}
|
||||
}
|
||||
private Image NextVisible()
|
||||
{
|
||||
if (this.Image1.Visibility == Visibility.Visible)
|
||||
{
|
||||
return this.Image2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.Image1;
|
||||
}
|
||||
}
|
||||
private static void Transition(Image from, Image to)
|
||||
{
|
||||
to.Visibility = Visibility.Visible;
|
||||
to.Opacity = 0;
|
||||
from.Visibility = Visibility.Visible;
|
||||
from.Opacity = 1;
|
||||
var showAnimation = new DoubleAnimation()
|
||||
{
|
||||
From = 0,
|
||||
To = 1,
|
||||
Duration = TimeSpan.FromSeconds(1.5)
|
||||
};
|
||||
var hideAnimation = new DoubleAnimation
|
||||
{
|
||||
From = 1,
|
||||
To = 0,
|
||||
Duration = TimeSpan.FromSeconds(1.5)
|
||||
};
|
||||
hideAnimation.Completed += (s, e) =>
|
||||
{
|
||||
from.Visibility = Visibility.Hidden;
|
||||
to.BeginAnimation(Image.OpacityProperty, showAnimation);
|
||||
};
|
||||
from.BeginAnimation(Image.OpacityProperty, hideAnimation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<UserControl x:Class="Daybreak.Controls.LivingEntityContextMenu"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:guildwars="clr-namespace:Daybreak.Models.Guildwars"
|
||||
mc:Ignorable="d"
|
||||
Background="#F0212121"
|
||||
d:DataContext="{d:DesignInstance Type=guildwars:LivingEntity, IsDesignTimeCreatable=True}"
|
||||
d:DesignHeight="300" d:DesignWidth="100">
|
||||
<StackPanel Margin="5, 0, 5, 0">
|
||||
<TextBlock
|
||||
Text="{Binding Allegiance, Mode=OneWay}" FontSize="16" Foreground="White"></TextBlock>
|
||||
<TextBlock Text="{Binding NpcDefinition.Name}" Foreground="LightBlue" Cursor="Hand"
|
||||
MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"></TextBlock>
|
||||
<WrapPanel>
|
||||
<TextBlock Text="Id: " Foreground="White"></TextBlock>
|
||||
<TextBlock Text="{Binding ModelType, Mode=OneWay}" Foreground="White"></TextBlock>
|
||||
</WrapPanel>
|
||||
<WrapPanel>
|
||||
<TextBlock Text="Lvl: " Foreground="White"></TextBlock>
|
||||
<TextBlock Text="{Binding Level, Mode=OneWay}" Foreground="White"></TextBlock>
|
||||
</WrapPanel>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,23 @@
|
||||
using Daybreak.Models.Guildwars;
|
||||
using System;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Daybreak.Controls;
|
||||
/// <summary>
|
||||
/// Interaction logic for LivingEntityContextMenu.xaml
|
||||
/// </summary>
|
||||
public partial class LivingEntityContextMenu : UserControl
|
||||
{
|
||||
public event EventHandler<LivingEntity?>? LivingEntityContextMenuClicked;
|
||||
|
||||
public LivingEntityContextMenu()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void TextBlock_MouseLeftButtonDown(object _, MouseButtonEventArgs e)
|
||||
{
|
||||
this.LivingEntityContextMenuClicked?.Invoke(this, this.DataContext as LivingEntity? ?? default);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<UserControl x:Class="Daybreak.Controls.MainPlayerContextMenu"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Daybreak.Controls"
|
||||
xmlns:guildwars="clr-namespace:Daybreak.Models.Guildwars"
|
||||
mc:Ignorable="d"
|
||||
Background="#F0212121"
|
||||
d:DataContext="{d:DesignInstance Type=guildwars:MainPlayerInformation, IsDesignTimeCreatable=True}"
|
||||
d:DesignHeight="300" d:DesignWidth="100">
|
||||
<StackPanel Margin="5, 0, 5, 0">
|
||||
<TextBlock
|
||||
Text="{Binding Name, Mode=OneWay}" FontSize="16" Foreground="White"></TextBlock>
|
||||
<WrapPanel>
|
||||
<TextBlock Text="Lvl: " Foreground="White"></TextBlock>
|
||||
<TextBlock Text="{Binding Level, Mode=OneWay}" Foreground="White"></TextBlock>
|
||||
</WrapPanel>
|
||||
<WrapPanel>
|
||||
<TextBlock Text="{Binding PrimaryProfession.Alias, Mode=OneWay}" Foreground="White"></TextBlock>
|
||||
<TextBlock Text="/" Foreground="White"></TextBlock>
|
||||
<TextBlock Text="{Binding SecondaryProfession.Alias, Mode=OneWay}" Foreground="White"></TextBlock>
|
||||
</WrapPanel>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for MainPlayerContextMenu.xaml
|
||||
/// </summary>
|
||||
public partial class MainPlayerContextMenu : UserControl
|
||||
{
|
||||
public MainPlayerContextMenu()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<UserControl x:Class="Daybreak.Controls.MapIconContextMenu"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Daybreak.Controls"
|
||||
xmlns:guildwars="clr-namespace:Daybreak.Models.Guildwars"
|
||||
mc:Ignorable="d"
|
||||
Background="#F0212121"
|
||||
d:DataContext="{d:DesignInstance Type=guildwars:MapIcon, IsDesignTimeCreatable=True}"
|
||||
d:DesignHeight="300" d:DesignWidth="100">
|
||||
<StackPanel Margin="5, 0, 5, 0">
|
||||
<TextBlock Text="Map Icon" Foreground="White" FontSize="16"></TextBlock>
|
||||
<TextBlock Text="{Binding Icon.Name}" Foreground="LightBlue" Cursor="Hand"
|
||||
MouseLeftButtonDown="TextBlock_MouseLeftButtonDown" Margin="0, 0, 0, 10"></TextBlock>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,24 @@
|
||||
using Daybreak.Models.Guildwars;
|
||||
using System;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for MapIconContextMenu.xaml
|
||||
/// </summary>
|
||||
public partial class MapIconContextMenu : UserControl
|
||||
{
|
||||
public event EventHandler<MapIcon?>? MapIconContextMenuClicked;
|
||||
|
||||
public MapIconContextMenu()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void TextBlock_MouseLeftButtonDown(object _, MouseButtonEventArgs e)
|
||||
{
|
||||
this.MapIconContextMenuClicked?.Invoke(this, this.DataContext as MapIcon? ?? default);
|
||||
}
|
||||
}
|
||||
+128
-48
@@ -5,89 +5,169 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Daybreak.Controls"
|
||||
xmlns:buttons="clr-namespace:Daybreak.Controls.Buttons"
|
||||
xmlns:glyphs="clr-namespace:Daybreak.Controls.Glyphs"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<StackPanel>
|
||||
<buttons:MenuButton Title="Game companion"
|
||||
Foreground="White"
|
||||
HighlightColor="White"
|
||||
Height="30"
|
||||
Clicked="GameCompanionButton_Clicked">
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<local:GoldenArrowGlyph Foreground="White"
|
||||
<local:ExpandableMenuSection
|
||||
SectionTitle="Guild Wars" Foreground="White"
|
||||
FontSize="16">
|
||||
<local:ExpandableMenuSection.Children>
|
||||
<buttons:MenuButton Title="Game companion"
|
||||
FontSize="12"
|
||||
Foreground="White"
|
||||
HighlightColor="White"
|
||||
Height="30"
|
||||
Cursor="Hand"
|
||||
Clicked="GameCompanionButton_Clicked">
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<local:GoldenArrowGlyph Foreground="White"
|
||||
Width="40"></local:GoldenArrowGlyph>
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
<buttons:MenuButton Title="Manage builds"
|
||||
Foreground="White"
|
||||
HighlightColor="White"
|
||||
Height="30"
|
||||
Clicked="ManageBuildsButton_Clicked">
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<local:FireballGlyph Foreground="White"
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
<buttons:MenuButton Title="Manage builds"
|
||||
FontSize="12"
|
||||
Foreground="White"
|
||||
HighlightColor="White"
|
||||
Height="30"
|
||||
Cursor="Hand"
|
||||
Clicked="ManageBuildsButton_Clicked">
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<local:FireballGlyph Foreground="White"
|
||||
Width="40"></local:FireballGlyph>
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
<buttons:MenuButton Title="Account settings"
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
<buttons:MenuButton Title="Download Guildwars"
|
||||
FontSize="12"
|
||||
Foreground="White"
|
||||
HighlightColor="White"
|
||||
Height="30"
|
||||
Cursor="Hand"
|
||||
Clicked="DownloadGuildwarsButton_Clicked">
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<glyphs:DownloadGlyph Foreground="White"
|
||||
Width="40"></glyphs:DownloadGlyph>
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
</local:ExpandableMenuSection.Children>
|
||||
</local:ExpandableMenuSection>
|
||||
<local:ExpandableMenuSection
|
||||
SectionTitle="Mods" Foreground="White"
|
||||
FontSize="16">
|
||||
<local:ExpandableMenuSection.Children>
|
||||
<buttons:MenuButton Title="uMod"
|
||||
Foreground="White"
|
||||
HighlightColor="White"
|
||||
Height="30"
|
||||
Cursor="Hand"
|
||||
Clicked="UModButton_Clicked">
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<glyphs:UModGlyph Foreground="White"
|
||||
Width="40"></glyphs:UModGlyph>
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
<buttons:MenuButton Title="GWToolboxpp"
|
||||
Foreground="White"
|
||||
HighlightColor="White"
|
||||
Height="30"
|
||||
Cursor="Hand"
|
||||
Clicked="ToolboxButton_Clicked">
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<glyphs:GWToolboxGlyph Foreground="White"
|
||||
Width="40"></glyphs:GWToolboxGlyph>
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
</local:ExpandableMenuSection.Children>
|
||||
</local:ExpandableMenuSection>
|
||||
<local:ExpandableMenuSection
|
||||
SectionTitle="Settings" Foreground="White"
|
||||
FontSize="16">
|
||||
<local:ExpandableMenuSection.Children>
|
||||
<buttons:MenuButton Title="Accounts"
|
||||
Foreground="White"
|
||||
HighlightColor="White"
|
||||
Height="30"
|
||||
Cursor="Hand"
|
||||
Clicked="AccountSettingsButton_Clicked">
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<local:AvatarGlyph Foreground="White"
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<local:AvatarGlyph Foreground="White"
|
||||
Width="40"></local:AvatarGlyph>
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
<buttons:MenuButton Title="Guildwars settings"
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
<buttons:MenuButton Title="Executables"
|
||||
Foreground="White"
|
||||
HighlightColor="White"
|
||||
Height="30"
|
||||
Cursor="Hand"
|
||||
Clicked="GuildwarsSettingsButton_Clicked">
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<local:FileGlyph Foreground="White"
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<local:FileGlyph Foreground="White"
|
||||
Width="40"></local:FileGlyph>
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
<buttons:MenuButton Title="Launcher settings"
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
<buttons:MenuButton Title="Launcher"
|
||||
Foreground="White"
|
||||
HighlightColor="White"
|
||||
Height="30"
|
||||
Cursor="Hand"
|
||||
Clicked="LauncherSettingsButton_Clicked">
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<local:CogGlyph Foreground="White"
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<local:CogGlyph Foreground="White"
|
||||
Width="40"
|
||||
Height="20"></local:CogGlyph>
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
<buttons:MenuButton Title="Experimental settings"
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
<buttons:MenuButton Title="Experimental"
|
||||
Foreground="White"
|
||||
HighlightColor="White"
|
||||
Height="30"
|
||||
Cursor="Hand"
|
||||
Clicked="ExperimentalSettingsButton_Clicked">
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<local:ExperimentGlyph Foreground="White"
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<local:ExperimentGlyph Foreground="White"
|
||||
Width="40"></local:ExperimentGlyph>
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
<buttons:MenuButton Title="Manage client version"
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
</local:ExpandableMenuSection.Children>
|
||||
</local:ExpandableMenuSection>
|
||||
<local:ExpandableMenuSection
|
||||
SectionTitle="Diagnostics" Foreground="White"
|
||||
FontSize="16">
|
||||
<local:ExpandableMenuSection.Children>
|
||||
<buttons:MenuButton Title="Manage client version"
|
||||
Foreground="White"
|
||||
HighlightColor="White"
|
||||
Height="30"
|
||||
Cursor="Hand"
|
||||
Clicked="VersionManagementButton_Clicked">
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<local:StaticGlyph Foreground="White"
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<local:StaticGlyph Foreground="White"
|
||||
Width="40"></local:StaticGlyph>
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
<buttons:MenuButton Title="Logs"
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
<buttons:MenuButton Title="Logs"
|
||||
Foreground="White"
|
||||
HighlightColor="White"
|
||||
Height="30"
|
||||
Cursor="Hand"
|
||||
Clicked="LogsButton_Clicked">
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<local:LogsGlyph Foreground="White"
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<local:LogsGlyph Foreground="White"
|
||||
Width="40"></local:LogsGlyph>
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
<buttons:MenuButton Title="Metrics"
|
||||
Foreground="White"
|
||||
HighlightColor="White"
|
||||
Height="30"
|
||||
Cursor="Hand"
|
||||
Clicked="MetricsButton_Clicked">
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<glyphs:GaugeGlyph Foreground="White"
|
||||
Width="40"></glyphs:GaugeGlyph>
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
</local:ExpandableMenuSection.Children>
|
||||
</local:ExpandableMenuSection>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
|
||||
@@ -1,78 +1,105 @@
|
||||
using Daybreak.Configuration;
|
||||
using Daybreak.Configuration.Options;
|
||||
using Daybreak.Launch;
|
||||
using Daybreak.Services.Navigation;
|
||||
using Daybreak.Views;
|
||||
using Daybreak.Views.Onboarding.Toolbox;
|
||||
using Daybreak.Views.Onboarding.UMod;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Core.Extensions;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for MenuList.xaml
|
||||
/// </summary>
|
||||
public partial class MenuList : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for MenuList.xaml
|
||||
/// </summary>
|
||||
public partial class MenuList : UserControl
|
||||
private readonly IViewManager viewManager;
|
||||
private readonly ILiveOptions<LauncherOptions> liveOptions;
|
||||
|
||||
public MenuList()
|
||||
: this(
|
||||
Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>(),
|
||||
Launcher.Instance.ApplicationServiceProvider.GetRequiredService<ILiveOptions<LauncherOptions>>())
|
||||
{
|
||||
public MenuList()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void GameCompanionButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
var viewManager = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>();
|
||||
viewManager.ShowView<CompanionView>();
|
||||
}
|
||||
private MenuList(
|
||||
IViewManager viewManager,
|
||||
ILiveOptions<LauncherOptions> liveOptions)
|
||||
{
|
||||
this.viewManager = viewManager.ThrowIfNull();
|
||||
this.liveOptions = liveOptions.ThrowIfNull();
|
||||
}
|
||||
|
||||
private void AccountSettingsButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
var viewManager = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>();
|
||||
viewManager.ShowView<AccountsView>();
|
||||
}
|
||||
private void GameCompanionButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<LauncherView>();
|
||||
}
|
||||
|
||||
private void GuildwarsSettingsButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
var viewManager = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>();
|
||||
viewManager.ShowView<ExecutablesView>();
|
||||
}
|
||||
private void AccountSettingsButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<AccountsView>();
|
||||
}
|
||||
|
||||
private void LauncherSettingsButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
var viewManager = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>();
|
||||
viewManager.ShowView<SettingsView>();
|
||||
}
|
||||
private void GuildwarsSettingsButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<ExecutablesView>();
|
||||
}
|
||||
|
||||
private void ExperimentalSettingsButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
var viewManager = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>();
|
||||
viewManager.ShowView<ExperimentalSettingsView>();
|
||||
}
|
||||
private void LauncherSettingsButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<SettingsView>();
|
||||
}
|
||||
|
||||
private void ManageBuildsButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
var viewManager = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>();
|
||||
var options = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<ILiveOptions<ApplicationConfiguration>>();
|
||||
if (options.Value.ExperimentalFeatures.DownloadIcons)
|
||||
{
|
||||
viewManager.ShowView<IconDownloadView>();
|
||||
}
|
||||
else
|
||||
{
|
||||
viewManager.ShowView<BuildsListView>();
|
||||
}
|
||||
}
|
||||
private void ExperimentalSettingsButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<ExperimentalSettingsView>();
|
||||
}
|
||||
|
||||
private void VersionManagementButton_Clicked(object sender, EventArgs e)
|
||||
private void ManageBuildsButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
if (this.liveOptions.Value.DownloadIcons)
|
||||
{
|
||||
var viewManager = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>();
|
||||
viewManager.ShowView<VersionManagementView>();
|
||||
this.viewManager.ShowView<IconDownloadView>();
|
||||
}
|
||||
|
||||
private void LogsButton_Clicked(object sender, EventArgs e)
|
||||
else
|
||||
{
|
||||
var viewManager = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>();
|
||||
viewManager.ShowView<LogsView>();
|
||||
this.viewManager.ShowView<BuildsListView>();
|
||||
}
|
||||
}
|
||||
|
||||
private void VersionManagementButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<VersionManagementView>();
|
||||
}
|
||||
|
||||
private void LogsButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<LogsView>();
|
||||
}
|
||||
|
||||
private void MetricsButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<MetricsView>();
|
||||
}
|
||||
|
||||
private void DownloadGuildwarsButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<GuildwarsDownloadView>();
|
||||
}
|
||||
|
||||
private void UModButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<UModOnboardingEntryView>();
|
||||
}
|
||||
|
||||
private void ToolboxButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<ToolboxOnboardingEntryView>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<UserControl x:Class="Daybreak.Controls.PlayerContextMenu"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:guildwars="clr-namespace:Daybreak.Models.Guildwars"
|
||||
mc:Ignorable="d"
|
||||
d:DataContext="{d:DesignInstance Type=guildwars:PlayerInformation, IsDesignTimeCreatable=True}"
|
||||
d:DesignHeight="300" d:DesignWidth="100"
|
||||
Margin="5, 0, 5, 0">
|
||||
<StackPanel Background="#F0212121">
|
||||
<TextBlock Text="Party Member" FontSize="16" Foreground="White"></TextBlock>
|
||||
<TextBlock Text="{Binding NpcDefinition.Name}" Foreground="LightBlue" Cursor="Hand"
|
||||
MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"></TextBlock>
|
||||
<WrapPanel>
|
||||
<TextBlock Text="Id: " Foreground="White"></TextBlock>
|
||||
<TextBlock Text="{Binding ModelType, Mode=OneWay}" Foreground="White"></TextBlock>
|
||||
</WrapPanel>
|
||||
<WrapPanel>
|
||||
<TextBlock Text="Lvl: " Foreground="White"></TextBlock>
|
||||
<TextBlock Text="{Binding Level, Mode=OneWay}" Foreground="White"></TextBlock>
|
||||
</WrapPanel>
|
||||
<WrapPanel>
|
||||
<TextBlock Text="{Binding PrimaryProfession.Alias, Mode=OneWay}" Foreground="White"></TextBlock>
|
||||
<TextBlock Text="/" Foreground="White"></TextBlock>
|
||||
<TextBlock Text="{Binding SecondaryProfession.Alias, Mode=OneWay}" Foreground="White"></TextBlock>
|
||||
</WrapPanel>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,23 @@
|
||||
using Daybreak.Models.Guildwars;
|
||||
using System;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Daybreak.Controls;
|
||||
/// <summary>
|
||||
/// Interaction logic for PlayerContextMenu.xaml
|
||||
/// </summary>
|
||||
public partial class PlayerContextMenu : UserControl
|
||||
{
|
||||
public event EventHandler<PlayerInformation?>? PlayerContextMenuClicked;
|
||||
|
||||
public PlayerContextMenu()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void TextBlock_MouseLeftButtonDown(object _, MouseButtonEventArgs e)
|
||||
{
|
||||
this.PlayerContextMenuClicked?.Invoke(this, this.DataContext as PlayerInformation? ?? default);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<UserControl x:Class="Daybreak.Controls.QuestContextMenu"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Daybreak.Controls"
|
||||
xmlns:guildwars="clr-namespace:Daybreak.Models.Guildwars"
|
||||
mc:Ignorable="d"
|
||||
Background="#F0212121"
|
||||
d:DataContext="{d:DesignInstance Type=guildwars:QuestMetadata, IsDesignTimeCreatable=True}"
|
||||
d:DesignHeight="300" d:DesignWidth="100">
|
||||
<StackPanel Margin="5, 0, 5, 0">
|
||||
<TextBlock Text="{Binding Quest.Name}" FontSize="16" Foreground="White" TextWrapping="Wrap"></TextBlock>
|
||||
<TextBlock Text="{Binding Quest.WikiUrl}" TextWrapping="Wrap" Foreground="LightBlue" Cursor="Hand"
|
||||
MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"></TextBlock>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,24 @@
|
||||
using Daybreak.Models.Guildwars;
|
||||
using System;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for QuestContextMenu.xaml
|
||||
/// </summary>
|
||||
public partial class QuestContextMenu : UserControl
|
||||
{
|
||||
public event EventHandler<QuestMetadata?>? QuestContextMenuClicked;
|
||||
|
||||
public QuestContextMenu()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void TextBlock_MouseLeftButtonDown(object _, MouseButtonEventArgs e)
|
||||
{
|
||||
this.QuestContextMenuClicked?.Invoke(this, this.DataContext as QuestMetadata? ?? default);
|
||||
}
|
||||
}
|
||||
@@ -1,42 +1,40 @@
|
||||
using System;
|
||||
using System.Extensions;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Extensions;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for SearchTextBox.xaml
|
||||
/// </summary>
|
||||
public partial class SearchTextBox : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for SearchTextBox.xaml
|
||||
/// </summary>
|
||||
public partial class SearchTextBox : UserControl
|
||||
public event EventHandler<string>? TextChanged;
|
||||
|
||||
[GenerateDependencyProperty(InitialValue = true)]
|
||||
private bool placeholderVisibility;
|
||||
[GenerateDependencyProperty]
|
||||
private string searchText = default!;
|
||||
|
||||
public SearchTextBox()
|
||||
{
|
||||
public event EventHandler<string> TextChanged;
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
[GenerateDependencyProperty(InitialValue = true)]
|
||||
private bool placeholderVisibility;
|
||||
[GenerateDependencyProperty]
|
||||
private string searchText;
|
||||
|
||||
public SearchTextBox()
|
||||
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
var searchText = e.Source.As<TextBox>().Text;
|
||||
if (searchText.IsNullOrWhiteSpace())
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.PlaceholderVisibility = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.PlaceholderVisibility = false;
|
||||
}
|
||||
|
||||
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
var searchText = e.Source.As<TextBox>().Text;
|
||||
if (searchText.IsNullOrWhiteSpace())
|
||||
{
|
||||
this.PlaceholderVisibility = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.PlaceholderVisibility = false;
|
||||
}
|
||||
|
||||
this.SearchText = searchText;
|
||||
this.TextChanged?.Invoke(this, searchText);
|
||||
}
|
||||
this.SearchText = searchText;
|
||||
this.TextChanged?.Invoke(this, searchText);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,68 +5,67 @@ using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Extensions;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for AccountTemplate.xaml
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0044:Add readonly modifier", Justification = "Fields used by source generator for DependencyProperty")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0052:Remove unread private members", Justification = "Used by source generators")]
|
||||
public partial class AccountTemplate : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for AccountTemplate.xaml
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0044:Add readonly modifier", Justification = "Fields used by source generator for DependencyProperty")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0052:Remove unread private members", Justification = "Used by source generators")]
|
||||
public partial class AccountTemplate : UserControl
|
||||
public event EventHandler? RemoveClicked;
|
||||
public event EventHandler? DefaultClicked;
|
||||
|
||||
[GenerateDependencyProperty]
|
||||
private string username = string.Empty;
|
||||
[GenerateDependencyProperty]
|
||||
private string password = string.Empty;
|
||||
[GenerateDependencyProperty]
|
||||
private string characterName = string.Empty;
|
||||
[GenerateDependencyProperty]
|
||||
private bool isDefault;
|
||||
|
||||
public AccountTemplate()
|
||||
{
|
||||
public event EventHandler RemoveClicked;
|
||||
public event EventHandler DefaultClicked;
|
||||
|
||||
[GenerateDependencyProperty]
|
||||
private string username;
|
||||
[GenerateDependencyProperty]
|
||||
private string password;
|
||||
[GenerateDependencyProperty]
|
||||
private string characterName;
|
||||
[GenerateDependencyProperty]
|
||||
private bool isDefault;
|
||||
this.InitializeComponent();
|
||||
this.DataContextChanged += this.AccountTemplate_DataContextChanged;
|
||||
}
|
||||
|
||||
public AccountTemplate()
|
||||
private void AccountTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.NewValue is LoginCredentials loginCredentials)
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.DataContextChanged += this.AccountTemplate_DataContextChanged;
|
||||
}
|
||||
|
||||
private void AccountTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.NewValue is LoginCredentials loginCredentials)
|
||||
{
|
||||
this.PasswordBox.Password = loginCredentials.Password;
|
||||
this.Username = loginCredentials.Username;
|
||||
this.CharacterName = loginCredentials.CharacterName;
|
||||
this.IsDefault = loginCredentials.Default;
|
||||
}
|
||||
}
|
||||
|
||||
private void BinButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.RemoveClicked?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private void UsernameTextbox_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
this.DataContext.As<LoginCredentials>().Username = this.Username;
|
||||
}
|
||||
|
||||
private void CharacterNameTextbox_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
this.DataContext.As<LoginCredentials>().CharacterName = this.CharacterName;
|
||||
}
|
||||
|
||||
private void Passwordbox_PasswordChanged(object sender, EventArgs e)
|
||||
{
|
||||
this.Password = sender.As<PasswordBox>()?.Password;
|
||||
this.DataContext.As<LoginCredentials>().Password = this.Password;
|
||||
}
|
||||
|
||||
private void StarGlyph_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.DefaultClicked?.Invoke(this, e);
|
||||
this.PasswordBox.Password = loginCredentials.Password;
|
||||
this.Username = loginCredentials.Username;
|
||||
this.CharacterName = loginCredentials.CharacterName;
|
||||
this.IsDefault = loginCredentials.Default;
|
||||
}
|
||||
}
|
||||
|
||||
private void BinButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.RemoveClicked?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private void UsernameTextbox_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
this.DataContext.As<LoginCredentials>().Username = this.Username;
|
||||
}
|
||||
|
||||
private void CharacterNameTextbox_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
this.DataContext.As<LoginCredentials>().CharacterName = this.CharacterName;
|
||||
}
|
||||
|
||||
private void Passwordbox_PasswordChanged(object sender, EventArgs e)
|
||||
{
|
||||
this.Password = sender.As<PasswordBox>()?.Password;
|
||||
this.DataContext.As<LoginCredentials>().Password = this.Password;
|
||||
}
|
||||
|
||||
private void StarGlyph_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.DefaultClicked?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,77 +1,107 @@
|
||||
using Daybreak.Models.Builds;
|
||||
using Daybreak.Services.BuildTemplates;
|
||||
using System;
|
||||
using System.Core.Extensions;
|
||||
using System.Extensions;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Extensions;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for AttributeTemplate.xaml
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0044:Add readonly modifier", Justification = "Fields used by source generator for DependencyProperty")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0052:Remove unread private members", Justification = "Used by source generators")]
|
||||
public partial class AttributeTemplate : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for AttributeTemplate.xaml
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0044:Add readonly modifier", Justification = "Fields used by source generator for DependencyProperty")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0052:Remove unread private members", Justification = "Used by source generators")]
|
||||
public partial class AttributeTemplate : UserControl
|
||||
public event EventHandler<AttributeEntry>? HelpClicked;
|
||||
public event EventHandler<AttributeEntry>? AttributeChanged;
|
||||
|
||||
private IAttributePointCalculator? attributePointCalculator;
|
||||
|
||||
[GenerateDependencyProperty(InitialValue = false)]
|
||||
private bool canAdd;
|
||||
[GenerateDependencyProperty(InitialValue = false)]
|
||||
private bool canSubtract;
|
||||
[GenerateDependencyProperty]
|
||||
private int attributePoints;
|
||||
|
||||
public AttributeTemplate()
|
||||
{
|
||||
public event EventHandler<AttributeEntry> HelpClicked;
|
||||
public event EventHandler<AttributeEntry> AttributeChanged;
|
||||
|
||||
[GenerateDependencyProperty(InitialValue = false)]
|
||||
private bool canAdd;
|
||||
[GenerateDependencyProperty(InitialValue = false)]
|
||||
private bool canSubtract;
|
||||
this.InitializeComponent();
|
||||
this.DataContextChanged += this.AttributeTemplate_DataContextChanged;
|
||||
}
|
||||
|
||||
public AttributeTemplate()
|
||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
base.OnPropertyChanged(e);
|
||||
if (e.Property == AttributePointsProperty &&
|
||||
this.DataContext is AttributeEntry attributeEntry)
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.DataContextChanged += this.AttributeTemplate_DataContextChanged;
|
||||
}
|
||||
|
||||
private void AttributeTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.NewValue is AttributeEntry attributeEntry)
|
||||
var remainingPoints = this.AttributePoints;
|
||||
var requiredPointsForNextLevel = this.attributePointCalculator?.GetPointsRequiredToIncreaseRank(attributeEntry.Points) ?? 0;
|
||||
if (remainingPoints < requiredPointsForNextLevel)
|
||||
{
|
||||
if (attributeEntry.Points > 0)
|
||||
{
|
||||
this.CanSubtract = true;
|
||||
}
|
||||
|
||||
if (attributeEntry.Points < 12)
|
||||
{
|
||||
this.CanAdd = true;
|
||||
}
|
||||
this.CanAdd = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void MinusButton_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
if (this.DataContext.As<AttributeEntry>().Points > 0)
|
||||
else if (this.DataContext.As<AttributeEntry>().Points < 12)
|
||||
{
|
||||
this.DataContext.As<AttributeEntry>().Points--;
|
||||
this.CanSubtract = this.DataContext.As<AttributeEntry>().Points > 0;
|
||||
this.CanAdd = true;
|
||||
this.AttributeChanged?.Invoke(this, this.DataContext.As<AttributeEntry>());
|
||||
}
|
||||
}
|
||||
|
||||
private void AddButton_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
if (this.DataContext.As<AttributeEntry>().Points < 12)
|
||||
{
|
||||
this.DataContext.As<AttributeEntry>().Points++;
|
||||
this.CanAdd = this.DataContext.As<AttributeEntry>().Points < 12;
|
||||
this.CanSubtract = true;
|
||||
this.AttributeChanged?.Invoke(this, this.DataContext.As<AttributeEntry>());
|
||||
}
|
||||
}
|
||||
|
||||
private void HelpButton_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
if (this.DataContext is AttributeEntry attributeEntry)
|
||||
{
|
||||
this.HelpClicked?.Invoke(this, attributeEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void InitializeAttributeTemplate(
|
||||
IAttributePointCalculator attributePointCalculator)
|
||||
{
|
||||
this.attributePointCalculator = attributePointCalculator.ThrowIfNull();
|
||||
}
|
||||
|
||||
private void AttributeTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.NewValue is AttributeEntry attributeEntry)
|
||||
{
|
||||
if (attributeEntry.Points > 0)
|
||||
{
|
||||
this.CanSubtract = true;
|
||||
}
|
||||
|
||||
if (attributeEntry.Points < 12)
|
||||
{
|
||||
this.CanAdd = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void MinusButton_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
if (this.DataContext.As<AttributeEntry>().Points > 0)
|
||||
{
|
||||
this.DataContext.As<AttributeEntry>().Points--;
|
||||
this.CanSubtract = this.DataContext.As<AttributeEntry>().Points > 0;
|
||||
this.CanAdd = true;
|
||||
this.AttributeChanged?.Invoke(this, this.DataContext.As<AttributeEntry>());
|
||||
}
|
||||
}
|
||||
|
||||
private void AddButton_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
if (this.DataContext.As<AttributeEntry>().Points < 12)
|
||||
{
|
||||
this.DataContext.As<AttributeEntry>().Points++;
|
||||
this.CanAdd = this.DataContext.As<AttributeEntry>().Points < 12;
|
||||
this.CanSubtract = true;
|
||||
this.AttributeChanged?.Invoke(this, this.DataContext.As<AttributeEntry>());
|
||||
}
|
||||
}
|
||||
|
||||
private void HelpButton_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
if (this.DataContext is AttributeEntry attributeEntry)
|
||||
{
|
||||
this.HelpClicked?.Invoke(this, attributeEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user