mirror of
https://github.com/gwdevhub/Daybreak.git
synced 2026-09-16 13:29:30 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b38488937b | ||
|
|
d291d5825a | ||
|
|
9d6162f65f | ||
|
|
f54ab42a92 | ||
|
|
78c8ae3e8f | ||
|
|
c64830c5b6 | ||
|
|
561c7cf7b1 | ||
|
|
2c6862de41 | ||
|
|
69842cbadf | ||
|
|
c7327e7bb2 | ||
|
|
de33ed7fc4 | ||
|
|
c99bb8d074 | ||
|
|
a98e54ebc6 | ||
|
|
a832aa1925 | ||
|
|
c7eb5debcb | ||
|
|
91f0cb4e31 | ||
|
|
5e8407a6ab | ||
|
|
243c2c1536 | ||
|
|
930aca4ffe | ||
|
|
1639cabe8e | ||
|
|
5961a57c5b | ||
|
|
75d9bc6dec | ||
|
|
4ccca32881 | ||
|
|
a7f5d9dd96 | ||
|
|
c8ba125abc | ||
|
|
7d290031f1 | ||
|
|
5220a8c7ac | ||
|
|
33e221f60f | ||
|
|
7f77547c50 | ||
|
|
c5964e33ac | ||
|
|
1c6f3ec797 | ||
|
|
8601f61739 | ||
|
|
91bac0d50b | ||
|
|
0bf03e0fb5 | ||
|
|
81401178a5 | ||
|
|
882357a8e5 | ||
|
|
abf629c5c6 | ||
|
|
758f9004cd | ||
|
|
f174f8cbb3 | ||
|
|
f2f6bde25d | ||
|
|
85f378b303 | ||
|
|
71ab3fdefb | ||
|
|
2f83d6c860 | ||
|
|
3db4975b48 | ||
|
|
6a6eea5d02 | ||
|
|
8fe9eeb32f | ||
|
|
4c1025243b | ||
|
|
f24eb02ca1 | ||
|
|
b01c09491f | ||
|
|
54ae742899 | ||
|
|
4c862463d7 | ||
|
|
b455c89ddc | ||
|
|
782b76cd8e | ||
|
|
230c2d9457 | ||
|
|
63531e3b8c | ||
|
|
ac430305f4 | ||
|
|
3d830cfc16 | ||
|
|
b529aa8861 | ||
|
|
3798daa54e | ||
|
|
624380ed86 | ||
|
|
2b025e225b | ||
|
|
15a67ea28c | ||
|
|
c6b62fd5fd | ||
|
|
3c0877c1a0 | ||
|
|
967b57b9a8 | ||
|
|
f47cc319b5 | ||
|
|
26da84c4e7 | ||
|
|
a39e8dc5c6 | ||
|
|
1bb4669135 | ||
|
|
0203eef006 | ||
|
|
4ab50ee191 | ||
|
|
06c1ec1ac2 | ||
|
|
ef4befdc38 | ||
|
|
33f49ddffa | ||
|
|
49aa249b5b |
+134
@@ -0,0 +1,134 @@
|
||||
[*.cs]
|
||||
|
||||
# CA2254: Template should be a static expression
|
||||
dotnet_diagnostic.CA2254.severity = none
|
||||
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_expression_bodied_methods = false:silent
|
||||
csharp_style_expression_bodied_constructors = false:silent
|
||||
csharp_style_expression_bodied_operators = false:silent
|
||||
csharp_style_expression_bodied_properties = true:silent
|
||||
csharp_style_expression_bodied_indexers = true:silent
|
||||
csharp_style_expression_bodied_accessors = true:silent
|
||||
csharp_style_expression_bodied_lambdas = true:silent
|
||||
csharp_style_expression_bodied_local_functions = false:silent
|
||||
csharp_indent_braces = false
|
||||
insert_final_newline = true
|
||||
csharp_space_around_binary_operators = before_and_after
|
||||
csharp_style_throw_expression = true:suggestion
|
||||
csharp_style_prefer_null_check_over_type_check = true:suggestion
|
||||
csharp_prefer_simple_default_expression = true:suggestion
|
||||
csharp_style_prefer_local_over_anonymous_function = true:error
|
||||
csharp_style_prefer_index_operator = true:suggestion
|
||||
csharp_style_prefer_range_operator = true:suggestion
|
||||
csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
|
||||
csharp_style_prefer_tuple_swap = true:suggestion
|
||||
csharp_style_inlined_variable_declaration = true:suggestion
|
||||
csharp_style_deconstructed_variable_declaration = true:error
|
||||
csharp_style_unused_value_assignment_preference = discard_variable:error
|
||||
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
|
||||
csharp_prefer_static_local_function = true:suggestion
|
||||
csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent
|
||||
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent
|
||||
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false:suggestion
|
||||
csharp_style_conditional_delegate_call = true:suggestion
|
||||
csharp_style_prefer_parameter_null_checking = true:suggestion
|
||||
csharp_style_prefer_switch_expression = true:suggestion
|
||||
csharp_style_prefer_pattern_matching = true:silent
|
||||
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
|
||||
csharp_style_prefer_not_pattern = true:suggestion
|
||||
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
|
||||
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
|
||||
|
||||
[*.{cs,vb}]
|
||||
#### Naming styles ####
|
||||
|
||||
# Naming rules
|
||||
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.severity = error
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
|
||||
|
||||
dotnet_naming_rule.types_should_be_pascal_case.severity = error
|
||||
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
|
||||
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
|
||||
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = error
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
|
||||
|
||||
# Symbol specifications
|
||||
|
||||
dotnet_naming_symbols.interface.applicable_kinds = interface
|
||||
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.interface.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
|
||||
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.types.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
|
||||
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.non_field_members.required_modifiers =
|
||||
|
||||
# Naming styles
|
||||
|
||||
dotnet_naming_style.begins_with_i.required_prefix = I
|
||||
dotnet_naming_style.begins_with_i.required_suffix =
|
||||
dotnet_naming_style.begins_with_i.word_separator =
|
||||
dotnet_naming_style.begins_with_i.capitalization = pascal_case
|
||||
|
||||
dotnet_naming_style.pascal_case.required_prefix =
|
||||
dotnet_naming_style.pascal_case.required_suffix =
|
||||
dotnet_naming_style.pascal_case.word_separator =
|
||||
dotnet_naming_style.pascal_case.capitalization = pascal_case
|
||||
|
||||
dotnet_naming_style.pascal_case.required_prefix =
|
||||
dotnet_naming_style.pascal_case.required_suffix =
|
||||
dotnet_naming_style.pascal_case.word_separator =
|
||||
dotnet_naming_style.pascal_case.capitalization = pascal_case
|
||||
dotnet_style_operator_placement_when_wrapping = beginning_of_line
|
||||
tab_width = 4
|
||||
indent_size = 4
|
||||
end_of_line = crlf
|
||||
dotnet_style_coalesce_expression = true:suggestion
|
||||
dotnet_style_null_propagation = true:suggestion
|
||||
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:error
|
||||
dotnet_style_prefer_auto_properties = true:error
|
||||
dotnet_style_object_initializer = true:suggestion
|
||||
dotnet_style_collection_initializer = true:suggestion
|
||||
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
|
||||
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
|
||||
dotnet_style_prefer_conditional_expression_over_return = true:silent
|
||||
dotnet_style_explicit_tuple_names = true:suggestion
|
||||
dotnet_style_prefer_inferred_tuple_names = true:suggestion
|
||||
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
|
||||
dotnet_style_prefer_compound_assignment = true:suggestion
|
||||
dotnet_style_prefer_simplified_interpolation = true:suggestion
|
||||
dotnet_style_namespace_match_folder = true:suggestion
|
||||
dotnet_style_readonly_field = true:suggestion
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
|
||||
dotnet_style_predefined_type_for_member_access = true:silent
|
||||
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
|
||||
dotnet_style_allow_multiple_blank_lines_experimental = true:silent
|
||||
dotnet_style_allow_statement_immediately_after_block_experimental = false:suggestion
|
||||
dotnet_code_quality_unused_parameters = all:error
|
||||
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:suggestion
|
||||
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:suggestion
|
||||
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:suggestion
|
||||
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion
|
||||
dotnet_style_qualification_for_field = true:error
|
||||
dotnet_style_qualification_for_property = true:error
|
||||
dotnet_style_qualification_for_method = true:error
|
||||
dotnet_style_qualification_for_event = true:error
|
||||
dotnet_diagnostic.CA1000.severity = error
|
||||
|
||||
[*.vb]
|
||||
dotnet_diagnostic.CA1047.severity = error
|
||||
@@ -0,0 +1 @@
|
||||
* amacocian@yahoo.com
|
||||
@@ -0,0 +1,16 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions" # See documentation for possible values
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
|
||||
- package-ecosystem: "nuget"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
+44
-45
@@ -5,19 +5,21 @@
|
||||
# This pipeline builds the Wpf project, runs unit tests, then saves the MSIX build artifact.
|
||||
name: Daybreak CD Pipeline
|
||||
|
||||
# Trigger on every master branch push and pull request
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
paths:
|
||||
- "Daybreak/**"
|
||||
- "Daybreak.Installer/**"
|
||||
|
||||
jobs:
|
||||
|
||||
build:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
targetplatform: [x64]
|
||||
targetplatform: [x86]
|
||||
|
||||
runs-on: windows-latest
|
||||
|
||||
@@ -25,78 +27,75 @@ jobs:
|
||||
Configuration: Release
|
||||
Solution_Path: Daybreak.sln
|
||||
Test_Project_Path: Daybreak.Tests\Daybreak.Tests.csproj
|
||||
Wpf_Project_Path: Daybreak\Daybreal.csproj
|
||||
Actions_Allow_Unsecure_Commands: true # Allows AddPAth and SetEnv commands
|
||||
Wpf_Project_Path: Daybreak\Daybreak.csproj
|
||||
Actions_Allow_Unsecure_Commands: true
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # avoid shallow clone so nbgv can do its work.
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get Latest Tag
|
||||
id: getLatestTag
|
||||
uses: WyriHaximus/github-action-get-previous-tag@v1
|
||||
|
||||
- name: Generate changelog
|
||||
id: gen_changelog
|
||||
run: |
|
||||
$changeLog = git log --no-merges --pretty="%h - %s (%an)<br />" ${{ env.LatestReleaseTag }}..HEAD
|
||||
echo "::set-env name=Changelog::$changeLog"
|
||||
env:
|
||||
LatestReleaseTag: ${{steps.getLatestTag.outputs.tag}}
|
||||
|
||||
- name: Print changelog
|
||||
run: |
|
||||
echo "${{ env.Changelog }}"
|
||||
|
||||
# Install the .NET Core workload
|
||||
- name: Install .NET Core
|
||||
uses: actions/setup-dotnet@v1
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '5.0.202'
|
||||
dotnet-version: '7.x'
|
||||
|
||||
# Add MsBuild to the PATH: https://github.com/microsoft/setup-msbuild
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v1.0.1
|
||||
uses: microsoft/setup-msbuild@v1.3.1
|
||||
|
||||
# Restore the application
|
||||
- name: Restore the Wpf application to populate the obj folder
|
||||
- name: Setup project secrets
|
||||
run: |
|
||||
dotnet user-secrets --project Daybreak\Daybreak.csproj set AadApplicationId "${{ secrets.AadApplicationId }}"
|
||||
dotnet user-secrets --project Daybreak\Daybreak.csproj set AadTenantId "${{ secrets.AadTenantId }}"
|
||||
|
||||
- name: Restore project
|
||||
run: msbuild $env:Solution_Path /t:Restore /p:Configuration=$env:Configuration /p:RuntimeIdentifier=$env:RuntimeIdentifier
|
||||
env:
|
||||
RuntimeIdentifier: win-${{ matrix.targetplatform }}
|
||||
|
||||
# Build Daybreak project
|
||||
- name: Build Daybreak project
|
||||
run: dotnet build Daybreak -c $env:Configuration
|
||||
|
||||
# Set release version environment variable
|
||||
- name: Set version variable
|
||||
run: |
|
||||
$version = .\Scripts\GetBuildVersion.ps1
|
||||
echo "::set-env name=Version::$version"
|
||||
|
||||
# Publish release
|
||||
- name: Publish release
|
||||
- name: Create publish launcher files
|
||||
run: dotnet publish .\Daybreak\Daybreak.csproj -c $env:Configuration -r $env:RuntimeIdentifier -p:PublishReadyToRun=true -p:PublishSingleFile=true --self-contained true -o .\Publish
|
||||
env:
|
||||
RuntimeIdentifier: win-${{ matrix.targetplatform }}
|
||||
|
||||
# Create release payload
|
||||
- name: Create release payload
|
||||
- name: Create publish installer files
|
||||
run: dotnet publish .\Daybreak.Installer\Daybreak.Installer.csproj -c $env:Configuration -r $env:RuntimeIdentifier -p:PublishReadyToRun=true -p:PublishSingleFile=true --self-contained true -o .\Publish
|
||||
env:
|
||||
RuntimeIdentifier: win-${{ matrix.targetplatform }}
|
||||
|
||||
- name: Pack publish files
|
||||
run: |
|
||||
Write-Host $env
|
||||
.\Scripts\BuildRelease.ps1 -version $env:Version
|
||||
shell: pwsh
|
||||
|
||||
# Get latest release
|
||||
- name: Get latest release tag
|
||||
id: download_release
|
||||
uses: Xotl/cool-github-releases@v1.1.2
|
||||
with:
|
||||
mode: download
|
||||
github_token: ${{ env.GITHUB_TOKEN }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Generate changelog
|
||||
- name: Generate changelog
|
||||
id: gen_changelog
|
||||
uses: mikepenz/release-changelog-builder-action@v1.8.0
|
||||
with:
|
||||
fromTag: ${{ steps.download_release.outputs.tag_name }}
|
||||
toTag: ${{ env.Version }}
|
||||
token: ${{ env.GITHUB_TOKEN }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Post new release to github
|
||||
- name: Post release
|
||||
uses: Xotl/cool-github-releases@v1.1.2
|
||||
- name: Publish release
|
||||
uses: Xotl/cool-github-releases@v1.1.8
|
||||
with:
|
||||
mode: update
|
||||
tag_name: v${{ env.Version }}
|
||||
@@ -104,7 +103,7 @@ jobs:
|
||||
assets: .\Publish\daybreakv${{ env.Version }}.zip
|
||||
github_token: ${{ env.GITHUB_TOKEN }}
|
||||
replace_assets: true
|
||||
body_mrkdwn: ${{ steps.gen_changelog.outputs.changelog }}
|
||||
body_mrkdwn: ${{ env.Changelog }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
# This pipeline builds the Wpf project, runs unit tests, then saves the MSIX build artifact.
|
||||
name: Daybreak CI Pipeline
|
||||
|
||||
# Trigger on every master branch push and pull request
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
@@ -20,7 +19,7 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
targetplatform: [x64]
|
||||
targetplatform: [x86]
|
||||
|
||||
runs-on: windows-latest
|
||||
|
||||
@@ -28,29 +27,25 @@ jobs:
|
||||
Solution_Path: Daybreak.sln
|
||||
Test_Project_Path: Daybreak.Tests\Daybreak.Tests.csproj
|
||||
Wpf_Project_Path: Daybreak\Daybreal.csproj
|
||||
Actions_Allow_Unsecure_Commands: true # Allows AddPAth and SetEnv commands
|
||||
Actions_Allow_Unsecure_Commands: true
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # avoid shallow clone so nbgv can do its work.
|
||||
fetch-depth: 0
|
||||
|
||||
# Install the .NET Core workload
|
||||
- name: Install .NET Core
|
||||
uses: actions/setup-dotnet@v1
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '5.0.202'
|
||||
dotnet-version: '7.x'
|
||||
|
||||
# Add MsBuild to the PATH: https://github.com/microsoft/setup-msbuild
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v1.0.1
|
||||
uses: microsoft/setup-msbuild@v1.3.1
|
||||
|
||||
# Test
|
||||
- name: Execute Unit Tests
|
||||
run: dotnet test $env:Test_Project_Path
|
||||
|
||||
# Restore the application
|
||||
- name: Restore the Wpf application to populate the obj folder
|
||||
run: msbuild $env:Solution_Path /t:Restore /p:Configuration=$env:Configuration /p:RuntimeIdentifier=$env:RuntimeIdentifier
|
||||
env:
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ "master" ]
|
||||
schedule:
|
||||
- cron: '41 12 * * 6'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: windows-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'csharp' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
|
||||
- name: Install .NET Core
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '6.x'
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
|
||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||
|
||||
# - run: |
|
||||
# echo "Run, Build Application using script"
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
@@ -0,0 +1,48 @@
|
||||
name: Daybreak Version Check
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- "Daybreak/**"
|
||||
- "Daybreak.Installer/**"
|
||||
|
||||
jobs:
|
||||
|
||||
check_version:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
targetplatform: [x64]
|
||||
|
||||
runs-on: windows-latest
|
||||
|
||||
env:
|
||||
Configuration: Release
|
||||
Solution_Path: Daybreak.sln
|
||||
Actions_Allow_Unsecure_Commands: true
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get Latest Tag
|
||||
id: getLatestTag
|
||||
uses: WyriHaximus/github-action-get-previous-tag@v1
|
||||
|
||||
- name: Build Daybreak project
|
||||
run: dotnet build Daybreak -c $env:Configuration
|
||||
|
||||
- name: Set version variable
|
||||
run: |
|
||||
$version = .\Scripts\GetBuildVersion.ps1
|
||||
echo "::set-env name=Version::$version"
|
||||
|
||||
- name: Check version difference
|
||||
run: |
|
||||
.\Scripts\CompareVersions -currentVersion ${{ env.Version }} -lastVersion ${{ env.LatestReleaseTag }}
|
||||
env:
|
||||
LatestReleaseTag: ${{ steps.getLatestTag.outputs.tag }}
|
||||
@@ -0,0 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>AnyCPU;x86</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,67 @@
|
||||
// See https://aka.ms/new-console-template for more information
|
||||
using System.Diagnostics;
|
||||
using System.IO.Compression;
|
||||
|
||||
const string tempFile = "tempfile.zip";
|
||||
const string executableName = "Daybreak.exe";
|
||||
Console.Title = "Daybreak Installer";
|
||||
Console.WriteLine("Starting installation...");
|
||||
if (File.Exists(tempFile) is false)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine("Unable to find launcher package. Aborting installation");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine("Unpacking files...");
|
||||
try
|
||||
{
|
||||
ZipFile.ExtractToDirectory(tempFile, AppContext.BaseDirectory, true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
Console.WriteLine("Deleting package");
|
||||
try
|
||||
{
|
||||
File.Delete(tempFile);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Console.WriteLine($"Failed to delete {tempFile}.\n{e}");
|
||||
}
|
||||
|
||||
Console.WriteLine("Deleting browser caches");
|
||||
try
|
||||
{
|
||||
Directory.Delete("BrowserData", true);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Console.WriteLine($"Failed to delete BrowserData.\n{e}");
|
||||
}
|
||||
try
|
||||
{
|
||||
Directory.Delete("Daybreak.exe.WebView2", true);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Console.WriteLine($"Failed to delete Daybreak.exe.WebView2.\n{e}");
|
||||
}
|
||||
|
||||
Console.WriteLine("Launching application");
|
||||
var process = new Process
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = executableName
|
||||
}
|
||||
};
|
||||
|
||||
if (process.Start() is false)
|
||||
{
|
||||
Console.WriteLine("Failed to launch application");
|
||||
Console.ReadKey();
|
||||
}
|
||||
@@ -1,18 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0-windows</TargetFramework>
|
||||
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Platforms>AnyCPU;x86</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.0.0-alpha0002" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
|
||||
<PackageReference Include="Moq" Version="4.16.1" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="2.1.1" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="2.1.1" />
|
||||
<PackageReference Include="coverlet.collector" Version="1.3.0" />
|
||||
<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>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
using Daybreak.Models.Versioning;
|
||||
using FluentAssertions;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Version = Daybreak.Models.Versioning.Version;
|
||||
|
||||
namespace Daybreak.Tests.Models;
|
||||
|
||||
[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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
var parsedVersion = Version.Parse(version);
|
||||
if (hasSuffix)
|
||||
{
|
||||
parsedVersion.VersionTokens.Last().Should().BeOfType<VersionStringToken>();
|
||||
}
|
||||
else
|
||||
{
|
||||
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>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
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,96 +1,96 @@
|
||||
using Daybreak.Models.Builds;
|
||||
using Daybreak.Models.Guildwars;
|
||||
using Daybreak.Services.BuildTemplates;
|
||||
using Daybreak.Services.Logging;
|
||||
using FluentAssertions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
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()
|
||||
{
|
||||
buildTemplateManager = new BuildTemplateManager(new Mock<ILogger>().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[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 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
using Daybreak.Services.Logging;
|
||||
using FluentAssertions;
|
||||
using LiteDB;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Logging;
|
||||
|
||||
namespace Daybreak.Tests.Services;
|
||||
|
||||
[TestClass]
|
||||
public class JsonLoggerProviderTests
|
||||
{
|
||||
private ILogsManager logsManager;
|
||||
private ILoggerProvider loggerProvider;
|
||||
private ILiteDatabase liteDatabase;
|
||||
|
||||
[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();
|
||||
}
|
||||
|
||||
[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().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.DeleteLogs();
|
||||
this.logsManager.GetLogs().Should().HaveCount(0);
|
||||
}
|
||||
}
|
||||
+45
-13
@@ -1,36 +1,68 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.31005.135
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.2.32616.157
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Daybreak", "Daybreak\Daybreak.csproj", "{AA45C2B1-8BD0-466C-9271-699F168905AF}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Daybreak.Tests", "Daybreak.Tests\Daybreak.Tests.csproj", "{C911C1C2-6566-419C-89C7-F802EB3FE709}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Daybreak.Tests", "Daybreak.Tests\Daybreak.Tests.csproj", "{C911C1C2-6566-419C-89C7-F802EB3FE709}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Pipelines", "Pipelines", "{067BF93F-E5B2-4E99-886E-039C04F35EAB}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.github\workflows\cd.yaml = .github\workflows\cd.yaml
|
||||
.github\workflows\ci.yaml = .github\workflows\ci.yaml
|
||||
.github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml
|
||||
.github\dependabot.yml = .github\dependabot.yml
|
||||
.github\workflows\version_check.yaml = .github\workflows\version_check.yaml
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Daybreak.Installer", "Daybreak.Installer\Daybreak.Installer.csproj", "{4E2BB805-135D-4F02-8C53-3D8B6876D323}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{41AE8C5D-25E1-4B08-8D65-868552421A63}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
Scripts\BuildRelease.ps1 = Scripts\BuildRelease.ps1
|
||||
Scripts\CompareVersions.ps1 = Scripts\CompareVersions.ps1
|
||||
Scripts\GetBuildVersion.ps1 = Scripts\GetBuildVersion.ps1
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0E30DDA0-2111-4E6C-851E-01DC34124FC2}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.editorconfig = .editorconfig
|
||||
.github\CODEOWNERS = .github\CODEOWNERS
|
||||
EndProjectSection
|
||||
EndProject
|
||||
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|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|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|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|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|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|x86.ActiveCfg = Release|x86
|
||||
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -1,79 +1,78 @@
|
||||
using System;
|
||||
using Microsoft.Xaml.Behaviors;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Interactivity;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,55 +1,54 @@
|
||||
using System;
|
||||
using Microsoft.Xaml.Behaviors;
|
||||
using System;
|
||||
using System.Extensions;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Interactivity;
|
||||
|
||||
namespace Daybreak.Behaviors
|
||||
namespace Daybreak.Behaviors;
|
||||
|
||||
public class ScrollIntoView : Behavior<ListView>
|
||||
{
|
||||
public class ScrollIntoView : Behavior<ListView>
|
||||
/// <summary>
|
||||
/// When Beahvior is attached
|
||||
/// </summary>
|
||||
protected override void OnAttached()
|
||||
{
|
||||
/// <summary>
|
||||
/// When Beahvior is attached
|
||||
/// </summary>
|
||||
protected override void OnAttached()
|
||||
{
|
||||
base.OnAttached();
|
||||
this.AssociatedObject.SelectionChanged += AssociatedObject_SelectionChanged;
|
||||
}
|
||||
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)
|
||||
/// <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 -=
|
||||
AssociatedObject_SelectionChanged;
|
||||
}
|
||||
/// <summary>
|
||||
/// When behavior is detached
|
||||
/// </summary>
|
||||
protected override void OnDetaching()
|
||||
{
|
||||
base.OnDetaching();
|
||||
this.AssociatedObject.SelectionChanged -=
|
||||
this.AssociatedObject_SelectionChanged;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,37 +3,42 @@ using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Daybreak.Configuration
|
||||
namespace Daybreak.Configuration;
|
||||
|
||||
public sealed class ApplicationConfiguration
|
||||
{
|
||||
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("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; }
|
||||
}
|
||||
|
||||
@@ -2,21 +2,24 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Daybreak.Configuration
|
||||
namespace Daybreak.Configuration;
|
||||
|
||||
public sealed class ExperimentalFeatures
|
||||
{
|
||||
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("Macros")]
|
||||
public List<KeyMacro> Macros { get; set; } = new();
|
||||
}
|
||||
[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("FocusViewEnabled")]
|
||||
public bool FocusViewEnabled { get; set; }
|
||||
[JsonProperty("Macros")]
|
||||
public List<KeyMacro> Macros { get; set; } = new();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Daybreak.Services.ApplicationLauncher;
|
||||
using Daybreak.Services.ApplicationLifetime;
|
||||
using Daybreak.Services.Bloogum;
|
||||
using Daybreak.Services.BuildTemplates;
|
||||
using Daybreak.Services.Configuration;
|
||||
@@ -8,67 +7,142 @@ using Daybreak.Services.IconRetrieve;
|
||||
using Daybreak.Services.Logging;
|
||||
using Daybreak.Services.Mutex;
|
||||
using Daybreak.Services.Privilege;
|
||||
using Daybreak.Services.Runtime;
|
||||
using Daybreak.Services.Screens;
|
||||
using Daybreak.Services.Screenshots;
|
||||
using Daybreak.Services.Shortcuts;
|
||||
using Daybreak.Services.Updater;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Daybreak.Views;
|
||||
using Microsoft.Extensions.Http.Logging;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Slim;
|
||||
using System.Extensions;
|
||||
using System.Net.Http;
|
||||
using LiteDB;
|
||||
using Daybreak.Services.Options;
|
||||
using Daybreak.Models;
|
||||
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;
|
||||
|
||||
namespace Daybreak.Configuration
|
||||
namespace Daybreak.Configuration;
|
||||
|
||||
public static class ProjectConfiguration
|
||||
{
|
||||
public static class ProjectConfiguration
|
||||
public static void RegisterResolvers(IServiceManager serviceManager)
|
||||
{
|
||||
public static void RegisterServices(IServiceProducer serviceProducer)
|
||||
{
|
||||
serviceProducer.ThrowIfNull(nameof(serviceProducer));
|
||||
serviceManager.ThrowIfNull();
|
||||
|
||||
serviceProducer.RegisterSingleton<ICredentialManager, CredentialManager>();
|
||||
serviceProducer.RegisterSingleton<ILoggingDatabase, FlatLoggingDatabase>();
|
||||
serviceProducer.RegisterSingleton<ILogger, Logger>();
|
||||
serviceProducer.RegisterSingleton<ApplicationLifetimeManager>();
|
||||
serviceProducer.RegisterSingleton<ViewManager>();
|
||||
serviceProducer.RegisterSingleton<IApplicationLauncher, ApplicationLauncher>();
|
||||
serviceProducer.RegisterSingleton<IScreenshotProvider, ScreenshotProvider>();
|
||||
serviceProducer.RegisterSingleton<IConfigurationManager, ConfigurationManager>();
|
||||
serviceProducer.RegisterSingleton<IBloogumClient, BloogumClient>();
|
||||
serviceProducer.RegisterSingleton<IApplicationUpdater, ApplicationUpdater>();
|
||||
serviceProducer.RegisterSingleton<IMutexHandler, MutexHandler>();
|
||||
serviceProducer.RegisterSingleton<IRuntimeStore, RuntimeStore>();
|
||||
serviceProducer.RegisterSingleton<IBuildTemplateManager, BuildTemplateManager>();
|
||||
serviceProducer.RegisterSingleton<IIconRetriever, IconRetriever>();
|
||||
serviceProducer.RegisterSingleton<IPrivilegeManager, PrivilegeManager>();
|
||||
serviceProducer.RegisterSingleton<IScreenManager, ScreenManager>();
|
||||
serviceProducer.RegisterSingleton<IShortcutManager, ShortcutManager>();
|
||||
}
|
||||
public static void RegisterLifetimeServices(IApplicationLifetimeProducer applicationLifetimeProducer)
|
||||
{
|
||||
applicationLifetimeProducer.ThrowIfNull(nameof(applicationLifetimeProducer));
|
||||
serviceManager.RegisterOptionsManager<ApplicationConfigurationOptionsManager>();
|
||||
serviceManager.RegisterResolver(new LoggerResolver());
|
||||
serviceManager
|
||||
.RegisterHttpClient<ApplicationUpdater>()
|
||||
.WithMessageHandler(sp =>
|
||||
{
|
||||
var logger = sp.GetService<ILogger<ApplicationUpdater>>();
|
||||
return new LoggingHttpMessageHandler(logger!) { InnerHandler = new HttpClientHandler() };
|
||||
})
|
||||
.Build()
|
||||
.RegisterHttpClient<BloogumClient>()
|
||||
.WithMessageHandler(sp =>
|
||||
{
|
||||
var logger = sp.GetService<ILogger<BloogumClient>>();
|
||||
return new LoggingHttpMessageHandler(logger!) { InnerHandler = new HttpClientHandler() };
|
||||
})
|
||||
.Build()
|
||||
.RegisterHttpClient<GraphClient>()
|
||||
.WithMessageHandler(sp =>
|
||||
{
|
||||
var logger = sp.GetService<ILogger<GraphClient>>();
|
||||
return new LoggingHttpMessageHandler(logger!) { InnerHandler = new HttpClientHandler() };
|
||||
})
|
||||
.Build();
|
||||
}
|
||||
|
||||
applicationLifetimeProducer.RegisterService<ILoggingDatabase>();
|
||||
applicationLifetimeProducer.RegisterService<IScreenshotProvider>();
|
||||
applicationLifetimeProducer.RegisterService<IApplicationUpdater>();
|
||||
applicationLifetimeProducer.RegisterService<IShortcutManager>();
|
||||
}
|
||||
public static void RegisterViews(IViewProducer viewProducer)
|
||||
{
|
||||
viewProducer.ThrowIfNull(nameof(viewProducer));
|
||||
public static void RegisterServices(IServiceCollection services)
|
||||
{
|
||||
services.ThrowIfNull();
|
||||
|
||||
viewProducer.RegisterView<MainView>();
|
||||
viewProducer.RegisterView<SettingsView>();
|
||||
viewProducer.RegisterView<AskUpdateView>();
|
||||
viewProducer.RegisterView<UpdateView>();
|
||||
viewProducer.RegisterView<SettingsCategoryView>();
|
||||
viewProducer.RegisterView<AccountsView>();
|
||||
viewProducer.RegisterView<ExperimentalSettingsView>();
|
||||
viewProducer.RegisterView<ExecutablesView>();
|
||||
viewProducer.RegisterView<BuildTemplateView>();
|
||||
viewProducer.RegisterView<BuildsListView>();
|
||||
viewProducer.RegisterView<RequestElevationView>();
|
||||
viewProducer.RegisterView<ScreenChoiceView>();
|
||||
}
|
||||
services.AddSingleton<ILogsManager, JsonLogsManager>();
|
||||
services.AddSingleton<IDebugLogsWriter, Services.Logging.DebugLogsWriter>();
|
||||
services.AddSingleton<IEventViewerLogsWriter, EventViewerLogsWriter>();
|
||||
services.AddSingleton<ILoggerFactory, LoggerFactory>(sp =>
|
||||
{
|
||||
var factory = new LoggerFactory();
|
||||
factory.AddProvider(new CVLoggerProvider(sp.GetService<ILogsWriter>()));
|
||||
return factory;
|
||||
});
|
||||
services.AddSingleton<ILogsWriter, CompositeLogsWriter>(sp => new CompositeLogsWriter(
|
||||
sp.GetService<ILogsManager>()!,
|
||||
sp.GetService<IDebugLogsWriter>()!,
|
||||
sp.GetService<IEventViewerLogsWriter>()!));
|
||||
|
||||
services.AddScoped((sp) => new ScopeMetadata(new CorrelationVector()));
|
||||
services.AddSingleton<ViewManager>();
|
||||
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<IMenuService, MenuService>();
|
||||
services.AddSingleton<IMenuServiceInitializer, MenuService>(sp => sp.GetRequiredService<IMenuService>().As<MenuService>());
|
||||
services.AddSingleton<IConfigurationManager, ConfigurationManager>();
|
||||
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.AddScoped<ICredentialManager, CredentialManager>();
|
||||
services.AddScoped<IApplicationLauncher, ApplicationLauncher>();
|
||||
services.AddScoped<IScreenshotProvider, ScreenshotProvider>();
|
||||
services.AddScoped<IBloogumClient, BloogumClient>();
|
||||
services.AddScoped<IApplicationUpdater, ApplicationUpdater>();
|
||||
services.AddScoped<IBuildTemplateManager, BuildTemplateManager>();
|
||||
services.AddScoped<IIconCache, IconCache>();
|
||||
services.AddScoped<IPrivilegeManager, PrivilegeManager>();
|
||||
services.AddScoped<IScreenManager, ScreenManager>();
|
||||
services.AddScoped<IGraphClient, GraphClient>();
|
||||
services.AddScoped<IOnboardingService, OnboardingService>();
|
||||
services.AddScoped<IGuildwarsMemoryReader, GuildwarsMemoryReader>();
|
||||
services.AddScoped<IMemoryScanner, MemoryScanner>();
|
||||
}
|
||||
|
||||
public static void RegisterViews(IViewProducer viewProducer)
|
||||
{
|
||||
viewProducer.ThrowIfNull();
|
||||
|
||||
viewProducer.RegisterPermanentView<LauncherView>();
|
||||
viewProducer.RegisterView<SettingsView>();
|
||||
viewProducer.RegisterView<AskUpdateView>();
|
||||
viewProducer.RegisterView<UpdateView>();
|
||||
viewProducer.RegisterView<AccountsView>();
|
||||
viewProducer.RegisterView<ExperimentalSettingsView>();
|
||||
viewProducer.RegisterView<ExecutablesView>();
|
||||
viewProducer.RegisterView<BuildTemplateView>();
|
||||
viewProducer.RegisterView<BuildsListView>();
|
||||
viewProducer.RegisterView<RequestElevationView>();
|
||||
viewProducer.RegisterView<ScreenChoiceView>();
|
||||
viewProducer.RegisterView<VersionManagementView>();
|
||||
viewProducer.RegisterView<LogsView>();
|
||||
viewProducer.RegisterView<IconDownloadView>();
|
||||
viewProducer.RegisterView<GraphAuthorizationView>();
|
||||
viewProducer.RegisterView<BuildsSynchronizationView>();
|
||||
viewProducer.RegisterView<OnboardingView>();
|
||||
viewProducer.RegisterView<FocusView>();
|
||||
}
|
||||
|
||||
public static void RegisterPostUpdateActions(IPostUpdateActionProducer postUpdateActionProducer)
|
||||
{
|
||||
postUpdateActionProducer.ThrowIfNull();
|
||||
|
||||
postUpdateActionProducer.AddPostUpdateAction<RenameInstallerAction>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace Daybreak.Configuration;
|
||||
|
||||
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; } = string.Empty;
|
||||
private SecretKeys()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Extensions;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Daybreak.Configuration;
|
||||
|
||||
public static class SecretManager
|
||||
{
|
||||
private static JObject? SecretsHolder;
|
||||
|
||||
public static string GetSecret(SecretKeys secretKey)
|
||||
{
|
||||
if (SecretsHolder is null)
|
||||
{
|
||||
LoadSecrets();
|
||||
}
|
||||
|
||||
return SecretsHolder!.Value<string>(secretKey.Key)!;
|
||||
}
|
||||
|
||||
public static T GetSecret<T>(SecretKeys secretKey)
|
||||
{
|
||||
if (SecretsHolder is null)
|
||||
{
|
||||
LoadSecrets();
|
||||
}
|
||||
|
||||
return SecretsHolder!.Value<T>(secretKey.Key)!;
|
||||
}
|
||||
|
||||
private static void LoadSecrets()
|
||||
{
|
||||
var serializedSecrets = Assembly.GetExecutingAssembly().GetManifestResourceStream("Daybreak.secrets.json").ReadAllBytes().GetString();
|
||||
serializedSecrets = TrimUnwantedCharacters(serializedSecrets);
|
||||
SecretsHolder = JObject.Parse(serializedSecrets);
|
||||
}
|
||||
|
||||
private static string TrimUnwantedCharacters(string s)
|
||||
{
|
||||
return new string(s.Where(c =>
|
||||
char.IsWhiteSpace(c) ||
|
||||
char.IsLetterOrDigit(c) ||
|
||||
char.IsSymbol(c) ||
|
||||
char.IsSeparator(c) ||
|
||||
char.IsPunctuation(c))
|
||||
.ToArray());
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,11 +12,7 @@
|
||||
<Viewbox Stretch="Fill">
|
||||
<Grid>
|
||||
<Ellipse Height="4" Width="4" StrokeThickness="0.2" Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"></Ellipse>
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
||||
<Ellipse Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Height="1" Width="1"></Ellipse>
|
||||
<Ellipse Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Height="1" Width="1"></Ellipse>
|
||||
<Ellipse Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Height="1" Width="1"></Ellipse>
|
||||
</StackPanel>
|
||||
<local:ThreeDotsGlyph Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Padding="0.5"></local:ThreeDotsGlyph>
|
||||
</Grid>
|
||||
</Viewbox>
|
||||
<Ellipse Fill="Transparent" MouseEnter="Ellipse_MouseEnter" MouseLeave="Ellipse_MouseLeave" MouseLeftButtonDown="Ellipse_MouseLeftButtonDown"></Ellipse>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
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 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Visibility = System.Windows.Visibility.Visible;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<UserControl x:Class="Daybreak.Controls.Buttons.MenuButton"
|
||||
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.Buttons"
|
||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||
xmlns:behaviors="clr-namespace:Daybreak.Behaviors"
|
||||
xmlns:converters="clr-namespace:Daybreak.Converters"
|
||||
x:Name="_this"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
<converters:MenuButtonHighlightConverter x:Key="HighlightConverter"></converters:MenuButtonHighlightConverter>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"></ColumnDefinition>
|
||||
<ColumnDefinition Width="*"></ColumnDefinition>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Rectangle
|
||||
Fill="{Binding ElementName=_this, Path=HighlightColor, Mode=OneWay}"
|
||||
Opacity="{Binding ElementName=_this, Path=Highlighted, Converter={StaticResource HighlightConverter}}"
|
||||
Grid.ColumnSpan="2">
|
||||
</Rectangle>
|
||||
<ContentPresenter Margin="5"
|
||||
Content="{Binding ElementName=_this, Path=InnerContent, Mode=OneWay}" />
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{Binding ElementName=_this, Path=Title, Mode=OneWay}"
|
||||
FontSize="{Binding ElementName=_this, Path=FontSize, Mode=OneWay}"
|
||||
FontFamily="{Binding ElementName=_this, Path=FontFamily, Mode=OneWay}"
|
||||
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Stretch" TextWrapping="Wrap"
|
||||
TextAlignment="Left" />
|
||||
<Rectangle Fill="Transparent"
|
||||
MouseEnter="Grid_MouseEnter"
|
||||
MouseLeave="Grid_MouseLeave"
|
||||
MouseLeftButtonDown="Rectangle_MouseLeftButtonDown"
|
||||
Grid.ColumnSpan="2" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Windows.Extensions;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Daybreak.Controls.Buttons;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for MenuButton.xaml
|
||||
/// </summary>
|
||||
public partial class MenuButton : UserControl
|
||||
{
|
||||
public event EventHandler? Clicked;
|
||||
|
||||
[GenerateDependencyProperty]
|
||||
private bool highlighted;
|
||||
[GenerateDependencyProperty]
|
||||
private Brush highlightColor = default!;
|
||||
[GenerateDependencyProperty]
|
||||
private FrameworkElement innerContent = default!;
|
||||
[GenerateDependencyProperty(InitialValue = "")]
|
||||
private string title = string.Empty;
|
||||
|
||||
public MenuButton()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void Grid_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
|
||||
{
|
||||
this.Highlighted = true;
|
||||
}
|
||||
|
||||
private void Grid_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
|
||||
{
|
||||
this.Highlighted = false;
|
||||
}
|
||||
|
||||
private void Rectangle_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs 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 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()
|
||||
{
|
||||
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,87 +5,45 @@ 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;
|
||||
|
||||
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()
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
this.BackgroundEllipse.Visibility = System.Windows.Visibility.Visible;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<UserControl x:Class="Daybreak.Controls.SynchronizeButton"
|
||||
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">
|
||||
<Viewbox>
|
||||
<Grid>
|
||||
<Ellipse x:Name="BackgroundEllipse" Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Visibility="Visible" Opacity="0.1" Width="35" Height="35" />
|
||||
<Ellipse Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
StrokeThickness="3"/>
|
||||
<Grid VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center">
|
||||
<Path Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
StrokeThickness="1.5"
|
||||
Data="m19,15.6073c1.4937,-0.5852 3,-1.9184 3,-4.6073c0,-4 -3.3333,-5 -5,-5c0,-2 0,-6 -6,-6c-6,0 -6,4 -6,6c-1.66667,0 -5,1 -5,5c0,2.6889 1.50628,4.0221 3,4.6073" />
|
||||
<Path StrokeThickness="1.5"
|
||||
Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Data="m6,17l1.76777,1.7678c1.56214,1.5621 4.09474,1.5621 5.65684,0l0.3536,-0.3536" />
|
||||
<Path StrokeThickness="1.5"
|
||||
Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Data="m6.35355,19.4749l-0.35355,-2.4749l2.47482,0.3536l-2.12127,2.1213z" />
|
||||
<Path StrokeThickness="1.5"
|
||||
Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Data="m14.77821,14.93927l-1.7678,-1.7677c-1.5621,-1.5621 -4.0948,-1.5621 -5.65685,0l-0.35356,0.3535" />
|
||||
<Path StrokeThickness="1.5"
|
||||
Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Data="m14.1213,12l0.3536,2.4749l-2.4749,-0.3536l2.1213,-2.1213z" />
|
||||
</Grid>
|
||||
<Ellipse Fill="Transparent" MouseEnter="Ellipse_MouseEnter" MouseLeave="Ellipse_MouseLeave" MouseLeftButtonDown="Ellipse_MouseLeftButtonDown"></Ellipse>
|
||||
</Grid>
|
||||
</Viewbox>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for SynchronizeButton.xaml
|
||||
/// </summary>
|
||||
public partial class SynchronizeButton : UserControl
|
||||
{
|
||||
public event EventHandler? Clicked;
|
||||
|
||||
public SynchronizeButton()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
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_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
this.Clicked?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
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:i="http://schemas.microsoft.com/expression/2010/interactivity"
|
||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||
xmlns:behaviors="clr-namespace:Daybreak.Behaviors"
|
||||
xmlns:converters="clr-namespace:Daybreak.Converters"
|
||||
x:Name="_this"
|
||||
@@ -18,8 +18,8 @@
|
||||
<RowDefinition Height="*"></RowDefinition>
|
||||
<RowDefinition Height="auto"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<ContentPresenter x:Name="Content" Margin="5"
|
||||
Content="{Binding ElementName=_this, Path=InnerContent}"></ContentPresenter>
|
||||
<ContentPresenter Margin="5"
|
||||
Content="{Binding ElementName=_this, Path=InnerContent}"></ContentPresenter>
|
||||
<Border BorderBrush="{Binding ElementName=_this, Path=BorderBrush}"
|
||||
BorderThickness="{Binding ElementName=_this, Path=BorderThickness}"
|
||||
Opacity="{Binding ElementName=_this, Path=Highlighted, Converter={StaticResource HighlightConverter}}"
|
||||
|
||||
@@ -1,68 +1,44 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Extensions;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for TileButton.xaml
|
||||
/// </summary>
|
||||
public partial class TileButton : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for TileButton.xaml
|
||||
/// </summary>
|
||||
public partial class TileButton : UserControl
|
||||
public event EventHandler? Clicked;
|
||||
|
||||
[GenerateDependencyProperty]
|
||||
public bool highlighted;
|
||||
[GenerateDependencyProperty(InitialValue = "")]
|
||||
public string title = string.Empty;
|
||||
[GenerateDependencyProperty]
|
||||
public FrameworkElement InnerContent = default!;
|
||||
[GenerateDependencyProperty]
|
||||
public Brush HighlightColor = default!;
|
||||
|
||||
public TileButton()
|
||||
{
|
||||
public event EventHandler Clicked;
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
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);
|
||||
private void Grid_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
|
||||
{
|
||||
this.Highlighted = true;
|
||||
}
|
||||
|
||||
public TileButton()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
private void Grid_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
|
||||
{
|
||||
this.Highlighted = false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
private void Grid_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
|
||||
{
|
||||
this.Highlighted = false;
|
||||
}
|
||||
|
||||
private void Rectangle_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
Clicked?.Invoke(this, e);
|
||||
}
|
||||
private void Rectangle_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
this.Clicked?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
using Daybreak.Launch;
|
||||
using Daybreak.Configuration;
|
||||
using Daybreak.Models.Browser;
|
||||
using Daybreak.Models.Builds;
|
||||
using Daybreak.Models.Guildwars;
|
||||
using Daybreak.Services.BuildTemplates;
|
||||
using Daybreak.Services.Configuration;
|
||||
using Daybreak.Services.Logging;
|
||||
using Daybreak.Utils;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Web.WebView2.Core;
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Diagnostics;
|
||||
using System.Extensions;
|
||||
using System.Threading.Tasks;
|
||||
@@ -14,283 +15,328 @@ 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 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 = string.Empty;
|
||||
[GenerateDependencyProperty(InitialValue = false)]
|
||||
private bool preventDispose;
|
||||
public string Address
|
||||
{
|
||||
private const string BrowserDownloadLink = "https://developer.microsoft.com/en-us/microsoft-edge/webview2/";
|
||||
|
||||
public event EventHandler<string> FavoriteUriChanged;
|
||||
public event EventHandler MaximizeClicked;
|
||||
public event EventHandler<Build> BuildDecoded;
|
||||
|
||||
private readonly IConfigurationManager configurationManager;
|
||||
private readonly ILogger logger;
|
||||
private readonly IBuildTemplateManager buildTemplateManager;
|
||||
private CoreWebView2Environment coreWebView2Environment;
|
||||
|
||||
[GenerateDependencyProperty(InitialValue = true)]
|
||||
private bool canDownloadBuild;
|
||||
[GenerateDependencyProperty(InitialValue = true)]
|
||||
private bool canNavigate;
|
||||
[GenerateDependencyProperty(InitialValue = true)]
|
||||
private bool controlsEnabled;
|
||||
[GenerateDependencyProperty(InitialValue = true)]
|
||||
private bool browserSupported;
|
||||
[GenerateDependencyProperty]
|
||||
private bool addressBarReadonly;
|
||||
[GenerateDependencyProperty]
|
||||
private bool browserEnabled;
|
||||
[GenerateDependencyProperty]
|
||||
private bool navigating;
|
||||
[GenerateDependencyProperty]
|
||||
private string favoriteAddress;
|
||||
[GenerateDependencyProperty]
|
||||
private string address;
|
||||
|
||||
public ChromiumBrowserWrapper()
|
||||
{
|
||||
this.configurationManager = Launcher.ApplicationServiceManager.GetService<IConfigurationManager>();
|
||||
this.logger = Launcher.ApplicationServiceManager.GetService<ILogger>();
|
||||
this.buildTemplateManager = Launcher.ApplicationServiceManager.GetService<IBuildTemplateManager>();
|
||||
this.InitializeComponent();
|
||||
this.InitializeEnvironment();
|
||||
this.InitializeBrowser();
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
base.OnPropertyChanged(e);
|
||||
if (e.Property == AddressProperty || e.Property == FavoriteAddressProperty)
|
||||
{
|
||||
this.CheckFavoriteAddress();
|
||||
}
|
||||
}
|
||||
|
||||
public async void ReinitializeBrowser()
|
||||
{
|
||||
await this.InitializeBrowser();
|
||||
}
|
||||
|
||||
private void InitializeEnvironment()
|
||||
{
|
||||
if (this.configurationManager.GetConfiguration().BrowsersEnabled is false)
|
||||
{
|
||||
this.BrowserSupported = false;
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
this.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)
|
||||
{
|
||||
await this.WebBrowser.EnsureCoreWebView2Async(this.coreWebView2Environment);
|
||||
this.AddressBarReadonly = this.configurationManager.GetConfiguration().AddressBarReadonly;
|
||||
this.CanDownloadBuild = this.configurationManager.GetConfiguration().ExperimentalFeatures.DynamicBuildLoading;
|
||||
this.WebBrowser.CoreWebView2.NewWindowRequested += (browser, args) => args.Handled = true;
|
||||
this.WebBrowser.NavigationStarting += (browser, args) =>
|
||||
{
|
||||
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);
|
||||
}
|
||||
this.SetValue(AddressProperty, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async void RetryInitializeButton_Clicked(object sender, EventArgs e)
|
||||
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.InitializeEnvironment();
|
||||
try
|
||||
{
|
||||
await this.InitializeBrowser();
|
||||
}
|
||||
catch
|
||||
{
|
||||
this.BrowserSupported = false;
|
||||
}
|
||||
this.CheckFavoriteAddress();
|
||||
}
|
||||
}
|
||||
|
||||
private void Hyperlink_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
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)
|
||||
{
|
||||
if (Uri.TryCreate(BrowserDownloadLink, UriKind.Absolute, out var uri))
|
||||
{
|
||||
Process.Start("explorer.exe", uri.ToString());
|
||||
}
|
||||
this.BrowserSupported = false;
|
||||
return;
|
||||
}
|
||||
|
||||
private void TextBox_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
|
||||
try
|
||||
{
|
||||
if (e.Key == System.Windows.Input.Key.Enter)
|
||||
{
|
||||
var newAddress = sender.As<TextBox>().Text;
|
||||
newAddress = SanitizeAddress(newAddress);
|
||||
if (newAddress is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
coreWebView2Environment ??= System.Extensions.TaskExtensions.RunSync(() => CoreWebView2Environment.CreateAsync(null, "BrowserData", null));
|
||||
|
||||
this.Address = newAddress;
|
||||
this.WebBrowser.CoreWebView2.Navigate(this.Address);
|
||||
e.Handled = true;
|
||||
}
|
||||
this.BrowserSupported = true;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
this.logger!.LogWarning($"Browser initialization failed. Details: {e}");
|
||||
this.BrowserSupported = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void CoreWebView2_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs args)
|
||||
private async Task InitializeBrowser()
|
||||
{
|
||||
if (this.BrowserSupported is true)
|
||||
{
|
||||
BrowserPayload payload = default;
|
||||
try
|
||||
{
|
||||
payload = args.WebMessageAsJson.Deserialize<BrowserPayload>();
|
||||
}
|
||||
catch(Exception e)
|
||||
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.logger.LogError(e);
|
||||
}
|
||||
if (payload?.Key == BrowserPayload.PayloadKeys.ContextMenu)
|
||||
{
|
||||
var contextMenuPayload = args.WebMessageAsJson.Deserialize<BrowserPayload<OnContextMenuPayload>>();
|
||||
var maybeTemplate = contextMenuPayload.Value.Selection;
|
||||
if (string.IsNullOrWhiteSpace(maybeTemplate))
|
||||
if (this.CanNavigate is false && args.Uri != this.Address)
|
||||
{
|
||||
return;
|
||||
args.Cancel = true;
|
||||
}
|
||||
|
||||
if (this.buildTemplateManager.IsTemplate(maybeTemplate) is false)
|
||||
else
|
||||
{
|
||||
return;
|
||||
this.Navigating = true;
|
||||
}
|
||||
|
||||
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}");
|
||||
}
|
||||
});
|
||||
};
|
||||
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
|
||||
{
|
||||
await this.InitializeBrowser();
|
||||
}
|
||||
catch
|
||||
{
|
||||
var build = this.ContextMenu.DataContext.As<Build>();
|
||||
this.ContextMenu.IsOpen = false;
|
||||
this.BuildDecoded?.Invoke(this, build);
|
||||
this.BrowserSupported = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void UserControl_Unloaded(object sender, RoutedEventArgs e)
|
||||
private void Hyperlink_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
if (Uri.TryCreate(BrowserDownloadLink, UriKind.Absolute, out var uri))
|
||||
{
|
||||
this.WebBrowser?.Dispose();
|
||||
Process.Start("explorer.exe", uri.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private void BackButton_Clicked(object sender, EventArgs e)
|
||||
private void TextBox_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == System.Windows.Input.Key.Enter)
|
||||
{
|
||||
this.WebBrowser.GoBack();
|
||||
this.Address = this.WebBrowser.Source.ToString();
|
||||
var newAddress = sender.As<TextBox>().Text;
|
||||
newAddress = SanitizeAddress(newAddress);
|
||||
if (newAddress.IsNullOrWhiteSpace())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.Address = newAddress;
|
||||
this.WebBrowser.CoreWebView2.Navigate(this.Address);
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void ForwardButton_Clicked(object sender, EventArgs e)
|
||||
private void CoreWebView2_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs args)
|
||||
{
|
||||
BrowserPayload payload = default!;
|
||||
try
|
||||
{
|
||||
this.WebBrowser.GoForward();
|
||||
this.Address = this.WebBrowser.Source.ToString();
|
||||
payload = args.WebMessageAsJson.Deserialize<BrowserPayload>();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
this.logger!.LogError(e, $"Exception encountered when deserializing {nameof(BrowserPayload)}");
|
||||
}
|
||||
|
||||
private void RefreshGlyph_Clicked(object sender, EventArgs e)
|
||||
if (payload?.Key == BrowserPayload.PayloadKeys.ContextMenu)
|
||||
{
|
||||
this.WebBrowser.Reload();
|
||||
this.Address = this.WebBrowser.Source.ToString();
|
||||
var contextMenuPayload = args.WebMessageAsJson.Deserialize<BrowserPayload<OnContextMenuPayload>>();
|
||||
var maybeTemplate = contextMenuPayload.Value!.Selection;
|
||||
if (string.IsNullOrWhiteSpace(maybeTemplate))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.buildTemplateManager is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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}");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void CancelGlyph_Clicked(object sender, EventArgs e)
|
||||
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)
|
||||
{
|
||||
this.WebBrowser.Stop();
|
||||
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)
|
||||
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.FavoriteAddress = this.Address;
|
||||
this.FavoriteUriChanged?.Invoke(this, this.FavoriteAddress);
|
||||
this.FavoriteButton.IsEnabled = false;
|
||||
}
|
||||
|
||||
private void HomeButton_Clicked(object sender, EventArgs e)
|
||||
else
|
||||
{
|
||||
this.WebBrowser.CoreWebView2.Navigate(this.FavoriteAddress);
|
||||
this.FavoriteButton.IsEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void MaximizeButton_Clicked(object sender, EventArgs e)
|
||||
private static string SanitizeAddress(string address)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(address))
|
||||
{
|
||||
this.MaximizeClicked?.Invoke(this, e);
|
||||
return default!;
|
||||
}
|
||||
|
||||
private void CheckFavoriteAddress()
|
||||
if (address.StartsWith("www") is false &&
|
||||
address.StartsWith("http") is false)
|
||||
{
|
||||
if (this.Address == this.FavoriteAddress)
|
||||
{
|
||||
this.FavoriteButton.IsEnabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.FavoriteButton.IsEnabled = true;
|
||||
}
|
||||
address = "https://www." + address;
|
||||
}
|
||||
|
||||
private static string SanitizeAddress(string address)
|
||||
else if (address.StartsWith("www"))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(address))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
address = "https://" + 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();
|
||||
}
|
||||
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()
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 AvatarGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class AvatarGlyph : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for AvatarGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class AvatarGlyph : UserControl
|
||||
public AvatarGlyph()
|
||||
{
|
||||
public AvatarGlyph()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<UserControl x:Class="Daybreak.Controls.Glyphs.BadGlyph"
|
||||
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>
|
||||
<Ellipse Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
StrokeThickness="1"
|
||||
Width="32"
|
||||
Height="32"/>
|
||||
<Line X1="8" Y1="8" X2="24" Y2="24"
|
||||
Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"/>
|
||||
<Line X1="24" Y1="8" X2="8" Y2="24"
|
||||
Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"/>
|
||||
</Grid>
|
||||
</Viewbox>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Controls.Glyphs;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for BadGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class BadGlyph : UserControl
|
||||
{
|
||||
public BadGlyph()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<UserControl x:Class="Daybreak.Controls.CogGlyph"
|
||||
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">
|
||||
<Viewbox>
|
||||
<Grid>
|
||||
<Path Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" VerticalAlignment="Center" HorizontalAlignment="Center"
|
||||
Data="m76.89,45.018c0,-1.587 -0.151,-3.138 -0.383,-4.66l11.227,-6.48l-11.639,-20.136l-11.616,6.47c-2.421,-1.931 -5.479,-3.506 -8.479,-4.664l0,-11.548l-22,0l0,11.548c-4,1.112 -5.649,2.617 -8.005,4.448l-11.251,-6.604l-11.914,20.006l11.12,6.604c-0.262,1.643 -0.45,3.308 -0.45,5.016c0,1.587 0.153,3.136 0.376,4.658l-11.228,6.484l11.634,20.135l11.424,-6.472c2.431,1.933 4.294,3.506 8.294,4.665l0,12.512l22,0l0,-12.512c3,-1.115 5.839,-2.618 8.19,-4.449l11.348,6.604l11.96,-20.006l-11.095,-6.603c0.258,-1.64 0.487,-3.304 0.487,-5.016zm-31.704,14.137c-7.799,0 -14.138,-6.332 -14.138,-14.138c0,-7.808 6.339,-14.136 14.138,-14.136c7.81,0 14.14,6.328 14.14,14.136c-0.001,7.806 -6.331,14.138 -14.14,14.138z"></Path>
|
||||
<Path Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" VerticalAlignment="Center" HorizontalAlignment="Center"
|
||||
Data="m56.5,89l-22,0c-1.381,0 -2.5,-1.119 -2.5,-2.5l0,-10.199c-2.612,-0.955 -4.464,-2.126 -6.274,-3.49l-10.229,5.671c-1.192,0.661 -2.694,0.244 -3.377,-0.936l-11.633,-20.135c-0.331,-0.574 -0.422,-1.257 -0.25,-1.897s0.591,-1.188 1.165,-1.519l9.794,-5.654c-0.121,-1.164 -0.181,-2.262 -0.181,-3.323c0,-1.317 0.112,-2.592 0.254,-3.721l-9.656,-5.75c-0.57,-0.34 -0.982,-0.893 -1.145,-1.537c-0.163,-0.644 -0.063,-1.326 0.279,-1.896l11.977,-20.006c0.702,-1.173 2.218,-1.564 3.399,-0.878l9.927,5.762c1.618,-1.213 3.362,-2.346 5.949,-3.273l0,-10.219c0.001,-1.381 1.12,-2.5 2.501,-2.5l22,0c1.381,0 2.5,1.119 2.5,2.5l0,10.377c2.124,0.938 4.104,2.059 5.919,3.35l9.939,-5.657c1.19,-0.677 2.713,-0.269 3.4,0.922l11.639,20.135c0.332,0.574 0.423,1.257 0.251,1.897s-0.591,1.188 -1.165,1.519l-9.781,5.646c0.126,1.165 0.188,2.266 0.188,3.329c0,1.327 -0.108,2.597 -0.246,3.717l9.692,5.752c0.571,0.339 0.983,0.891 1.147,1.533c0.163,0.644 0.065,1.325 -0.274,1.896l-11.897,20.005c-0.703,1.183 -2.234,1.573 -3.416,0.876l-9.798,-5.765c-1.782,1.25 -3.634,2.29 -5.598,3.144l0,10.324c0,1.381 -1.119,2.5 -2.5,2.5zm-19.5,-5l17,0l0,-9.512c0,-1.045 0.649,-1.979 1.629,-2.344c2.624,-0.975 5.004,-2.309 7.275,-4.078c0.809,-0.629 1.921,-0.702 2.804,-0.182l9.078,5.341l9.347,-15.716l-8.974,-5.325c-0.88,-0.522 -1.354,-1.528 -1.194,-2.538c0.198,-1.259 0.425,-2.923 0.425,-4.629c0,-1.314 -0.116,-2.716 -0.354,-4.284c-0.154,-1.018 0.33,-2.026 1.222,-2.541l9.061,-5.23l-9.145,-15.818l-9.208,5.241c-0.888,0.505 -1.995,0.42 -2.795,-0.219c-2.199,-1.754 -4.747,-3.196 -7.57,-4.286c-0.964,-0.372 -1.6,-1.299 -1.6,-2.332l0,-9.548l-17.001,0l0,9.548c0,1.123 -0.748,2.107 -1.83,2.408c-3.47,0.965 -5.073,2.212 -7.293,3.938l-0.098,0.076c-0.804,0.625 -1.909,0.7 -2.789,0.188l-9.243,-5.365l-9.423,15.739l8.937,5.321c0.879,0.524 1.351,1.531 1.189,2.542c-0.202,1.27 -0.435,2.943 -0.435,4.622c0,1.318 0.112,2.724 0.342,4.297c0.148,1.013 -0.337,2.015 -1.224,2.526l-9.065,5.234l9.151,15.842l9.525,-5.28c0.883,-0.49 1.976,-0.4 2.768,0.229c2.384,1.896 4.207,3.214 7.684,4.221c1.069,0.31 1.804,1.29 1.804,2.402l0,9.512zm8.186,-22.345c-9.174,0 -16.638,-7.464 -16.638,-16.638c0,-9.173 7.464,-16.636 16.638,-16.636c9.175,0 16.64,7.463 16.64,16.636c-0.001,9.174 -7.466,16.638 -16.64,16.638zm0,-28.273c-6.417,0 -11.638,5.22 -11.638,11.636c0,6.417 5.221,11.638 11.638,11.638c6.418,0 11.64,-5.221 11.64,-11.638c-0.001,-6.416 -5.222,-11.636 -11.64,-11.636z"></Path>
|
||||
</Grid>
|
||||
</Viewbox>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for CogGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class CogGlyph : UserControl
|
||||
{
|
||||
public CogGlyph()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -13,16 +13,15 @@ using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,11 +10,14 @@
|
||||
<Viewbox>
|
||||
<Grid>
|
||||
<Line Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
X1="15" X2="26" Y1="11" Y2="0"></Line>
|
||||
X1="15" X2="26" Y1="11" Y2="0"
|
||||
StrokeThickness="2"></Line>
|
||||
<Ellipse Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Width="4" Height="4"
|
||||
Width="4" Height="4"
|
||||
StrokeThickness="2"
|
||||
Margin="8,13,13,8"></Ellipse>
|
||||
<Path Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
StrokeThickness="2"
|
||||
Data="m15.025,0l-12.7,11.3c-3.1,3.1 -3.1,8.2 0,11.3s8.2,3.1 11.3,0l12.4,-11.6"></Path>
|
||||
</Grid>
|
||||
</Viewbox>
|
||||
|
||||
@@ -13,16 +13,15 @@ using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
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()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,16 +13,15 @@ using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
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()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<UserControl x:Class="Daybreak.Controls.Glyphs.GoodGlyph"
|
||||
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>
|
||||
<Ellipse Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
StrokeThickness="1"
|
||||
Width="32"
|
||||
Height="32"/>
|
||||
<Polyline Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Points="26,8 13.625,22.714284896850586 8,16.02597427368164 "></Polyline>
|
||||
</Grid>
|
||||
</Viewbox>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Controls.Glyphs;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for GoodGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class GoodGlyph : UserControl
|
||||
{
|
||||
public GoodGlyph()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<UserControl x:Class="Daybreak.Controls.LogsGlyph"
|
||||
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">
|
||||
<Viewbox>
|
||||
<Path Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Data="m7,3l0,-1.00209c0,-1.09965 0.89762,-1.99791 2.00488,-1.99791l0.99024,0c1.11098,0 2.00488,0.8945 2.00488,1.99791l0,1.00209l2.00442,0c0.55074,0 0.99558,0.44725 0.99558,0.99896l0,1.00208c0,0.5563 -0.44574,0.99896 -0.99558,0.99896l-9.00884,0c-0.55074,0 -0.99558,-0.44725 -0.99558,-0.99896l0,-1.00208c0,-0.5563 0.44574,-0.99896 0.99558,-0.99896l2.00442,0l0,0zm8.99999,1l1.00259,0c1.10649,0 1.99742,0.89704 1.99742,2.00359l0,20.99282c0,1.11383 -0.89428,2.00359 -1.99742,2.00359l-15.00516,0c-1.10649,0 -1.99742,-0.89704 -1.99742,-2.00359l0,-20.99282c0,-1.11383 0.89428,-2.00359 1.99742,-2.00359l1.00259,0c-0.00001,0.00163 -0.00001,0.00325 -0.00001,0.00488l0,0.99024c0,1.10726 0.89354,2.00488 2.00276,2.00488l8.99448,0c1.10609,0 2.00276,-0.8939 2.00276,-2.00488l0,-0.99024c0,-0.00163 0,-0.00325 -0.00001,-0.00488l0,0l0,0zm-6.49999,-1c0.27614,0 0.5,-0.22386 0.5,-0.5c0,-0.27614 -0.22386,-0.5 -0.5,-0.5c-0.27614,0 -0.5,0.22386 -0.5,0.5c0,0.27614 0.22386,0.5 0.5,0.5l0,0zm-6.5,8l0,1l13,0l0,-1l-13,0l0,0zm0,3l0,1l13,0l0,-1l-13,0l0,0zm0,3l0,1l13,0l0,-1l-13,0l0,0zm0,3l0,1l13,0l0,-1l-13,0l0,0zm0,3l0,1l13,0l0,-1l-13,0l0,0z"></Path>
|
||||
</Viewbox>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for LogsGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class LogsGlyph : UserControl
|
||||
{
|
||||
public LogsGlyph()
|
||||
{
|
||||
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()
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<UserControl x:Class="Daybreak.Controls.StaticGlyph"
|
||||
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">
|
||||
<Viewbox>
|
||||
<Polygon Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Points="209.89999389648438,829.800048828125 279.1999816894531,493.9000244140625 0,493.9000244140625 415.89996337890625,0 346.699951171875,335.8999938964844 625.800048828125,335.8999938964844"></Polygon>
|
||||
</Viewbox>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for StaticGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class StaticGlyph : UserControl
|
||||
{
|
||||
public StaticGlyph()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<UserControl x:Class="Daybreak.Controls.ThreeDotsGlyph"
|
||||
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">
|
||||
<Viewbox>
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
||||
<Ellipse Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Height="1" Width="1"></Ellipse>
|
||||
<Ellipse Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Height="1" Width="1"></Ellipse>
|
||||
<Ellipse Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Height="1" Width="1"></Ellipse>
|
||||
</StackPanel>
|
||||
</Viewbox>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for ThreeDotsGlyph.xaml
|
||||
/// </summary>
|
||||
public partial class ThreeDotsGlyph : UserControl
|
||||
{
|
||||
public ThreeDotsGlyph()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
{
|
||||
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,93 @@
|
||||
<UserControl x:Class="Daybreak.Controls.MenuList"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
Width="40"></local:FireballGlyph>
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
<buttons:MenuButton Title="Account settings"
|
||||
Foreground="White"
|
||||
HighlightColor="White"
|
||||
Height="30"
|
||||
Clicked="AccountSettingsButton_Clicked">
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<local:AvatarGlyph Foreground="White"
|
||||
Width="40"></local:AvatarGlyph>
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
<buttons:MenuButton Title="Guildwars settings"
|
||||
Foreground="White"
|
||||
HighlightColor="White"
|
||||
Height="30"
|
||||
Clicked="GuildwarsSettingsButton_Clicked">
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<local:FileGlyph Foreground="White"
|
||||
Width="40"></local:FileGlyph>
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
<buttons:MenuButton Title="Launcher settings"
|
||||
Foreground="White"
|
||||
HighlightColor="White"
|
||||
Height="30"
|
||||
Clicked="LauncherSettingsButton_Clicked">
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<local:CogGlyph Foreground="White"
|
||||
Width="40"
|
||||
Height="20"></local:CogGlyph>
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
<buttons:MenuButton Title="Experimental settings"
|
||||
Foreground="White"
|
||||
HighlightColor="White"
|
||||
Height="30"
|
||||
Clicked="ExperimentalSettingsButton_Clicked">
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<local:ExperimentGlyph Foreground="White"
|
||||
Width="40"></local:ExperimentGlyph>
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
<buttons:MenuButton Title="Manage client version"
|
||||
Foreground="White"
|
||||
HighlightColor="White"
|
||||
Height="30"
|
||||
Clicked="VersionManagementButton_Clicked">
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<local:StaticGlyph Foreground="White"
|
||||
Width="40"></local:StaticGlyph>
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
<buttons:MenuButton Title="Logs"
|
||||
Foreground="White"
|
||||
HighlightColor="White"
|
||||
Height="30"
|
||||
Clicked="LogsButton_Clicked">
|
||||
<buttons:MenuButton.InnerContent>
|
||||
<local:LogsGlyph Foreground="White"
|
||||
Width="40"></local:LogsGlyph>
|
||||
</buttons:MenuButton.InnerContent>
|
||||
</buttons:MenuButton>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,77 @@
|
||||
using Daybreak.Configuration;
|
||||
using Daybreak.Launch;
|
||||
using Daybreak.Services.Navigation;
|
||||
using Daybreak.Views;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for MenuList.xaml
|
||||
/// </summary>
|
||||
public partial class MenuList : UserControl
|
||||
{
|
||||
public MenuList()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void GameCompanionButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
var viewManager = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>();
|
||||
viewManager.ShowView<LauncherView>();
|
||||
}
|
||||
|
||||
private void AccountSettingsButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
var viewManager = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>();
|
||||
viewManager.ShowView<AccountsView>();
|
||||
}
|
||||
|
||||
private void GuildwarsSettingsButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
var viewManager = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>();
|
||||
viewManager.ShowView<ExecutablesView>();
|
||||
}
|
||||
|
||||
private void LauncherSettingsButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
var viewManager = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>();
|
||||
viewManager.ShowView<SettingsView>();
|
||||
}
|
||||
|
||||
private void ExperimentalSettingsButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
var viewManager = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>();
|
||||
viewManager.ShowView<ExperimentalSettingsView>();
|
||||
}
|
||||
|
||||
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 VersionManagementButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
var viewManager = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>();
|
||||
viewManager.ShowView<VersionManagementView>();
|
||||
}
|
||||
|
||||
private void LogsButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
var viewManager = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>();
|
||||
viewManager.ShowView<LogsView>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<UserControl x:Class="Daybreak.Controls.SearchTextBox"
|
||||
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">
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"></BooleanToVisibilityConverter>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<TextBox Foreground="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=Foreground, Mode=OneWay}"
|
||||
FontSize="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=FontSize, Mode=OneWay}"
|
||||
FontFamily="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=FontFamily, Mode=OneWay}"
|
||||
FontStretch="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=FontStretch, Mode=OneWay}"
|
||||
FontWeight="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=FontWeight, Mode=OneWay}"
|
||||
FontStyle="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=FontStyle, Mode=OneWay}"
|
||||
TextChanged="TextBox_TextChanged"
|
||||
Background="Transparent"/>
|
||||
<TextBlock Margin="5, 0, 0, 0"
|
||||
Text="Search"
|
||||
Background="Transparent"
|
||||
Opacity="0.5"
|
||||
IsHitTestVisible="False"
|
||||
FontSize="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=FontSize, Mode=OneWay}"
|
||||
FontFamily="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=FontFamily, Mode=OneWay}"
|
||||
FontStretch="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=FontStretch, Mode=OneWay}"
|
||||
FontWeight="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=FontWeight, Mode=OneWay}"
|
||||
FontStyle="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=FontStyle, Mode=OneWay}"
|
||||
Foreground="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=Foreground, Mode=OneWay}"
|
||||
Visibility="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=PlaceholderVisibility, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}"/>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Extensions;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Extensions;
|
||||
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <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()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -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 += 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,70 +5,72 @@ 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;
|
||||
|
||||
[GenerateDependencyProperty(InitialValue = false)]
|
||||
private bool canAdd;
|
||||
[GenerateDependencyProperty(InitialValue = false)]
|
||||
private bool canSubtract;
|
||||
|
||||
public AttributeTemplate()
|
||||
{
|
||||
public event EventHandler<AttributeEntry> HelpClicked;
|
||||
|
||||
[GenerateDependencyProperty(InitialValue = false)]
|
||||
private bool canAdd;
|
||||
[GenerateDependencyProperty(InitialValue = false)]
|
||||
private bool canSubtract;
|
||||
this.InitializeComponent();
|
||||
this.DataContextChanged += this.AttributeTemplate_DataContextChanged;
|
||||
}
|
||||
|
||||
public AttributeTemplate()
|
||||
private void AttributeTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.NewValue is AttributeEntry attributeEntry)
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.DataContextChanged += AttributeTemplate_DataContextChanged;
|
||||
}
|
||||
|
||||
private void AttributeTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.NewValue is AttributeEntry attributeEntry)
|
||||
if (attributeEntry.Points > 0)
|
||||
{
|
||||
if (attributeEntry.Points > 0)
|
||||
{
|
||||
this.CanSubtract = true;
|
||||
}
|
||||
|
||||
if (attributeEntry.Points < 12)
|
||||
{
|
||||
this.CanAdd = true;
|
||||
}
|
||||
this.CanSubtract = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void MinusButton_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
if (this.DataContext.As<AttributeEntry>().Points > 0)
|
||||
if (attributeEntry.Points < 12)
|
||||
{
|
||||
this.DataContext.As<AttributeEntry>().Points--;
|
||||
this.CanSubtract = this.DataContext.As<AttributeEntry>().Points > 0;
|
||||
this.CanAdd = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddButton_Clicked(object sender, System.EventArgs e)
|
||||
private void MinusButton_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
if (this.DataContext.As<AttributeEntry>().Points > 0)
|
||||
{
|
||||
if (this.DataContext.As<AttributeEntry>().Points < 12)
|
||||
{
|
||||
this.DataContext.As<AttributeEntry>().Points++;
|
||||
this.CanAdd = this.DataContext.As<AttributeEntry>().Points < 12;
|
||||
this.CanSubtract = true;
|
||||
}
|
||||
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 HelpButton_Clicked(object sender, System.EventArgs e)
|
||||
private void AddButton_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
if (this.DataContext.As<AttributeEntry>().Points < 12)
|
||||
{
|
||||
if (this.DataContext is AttributeEntry attributeEntry)
|
||||
{
|
||||
this.HelpClicked?.Invoke(this, attributeEntry);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,26 +2,25 @@
|
||||
using System;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for BuildEntryTemplate.xaml
|
||||
/// </summary>
|
||||
public partial class BuildEntryTemplate : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for BuildEntryTemplate.xaml
|
||||
/// </summary>
|
||||
public partial class BuildEntryTemplate : UserControl
|
||||
public event EventHandler<BuildEntry>? RemoveClicked;
|
||||
|
||||
public BuildEntryTemplate()
|
||||
{
|
||||
public event EventHandler<BuildEntry> RemoveClicked;
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
public BuildEntryTemplate()
|
||||
private void BinButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
if (this.DataContext is BuildEntry buildEntry)
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void BinButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
if (this.DataContext is BuildEntry buildEntry)
|
||||
{
|
||||
this.RemoveClicked?.Invoke(this, buildEntry);
|
||||
}
|
||||
this.RemoveClicked?.Invoke(this, buildEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
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:interactivity="http://schemas.microsoft.com/expression/2010/interactivity"
|
||||
xmlns:interactivity="http://schemas.microsoft.com/xaml/behaviors"
|
||||
xmlns:behaviors="clr-namespace:Daybreak.Behaviors"
|
||||
xmlns:converters="clr-namespace:Daybreak.Converters"
|
||||
mc:Ignorable="d"
|
||||
x:Name="_this"
|
||||
Unloaded="BuildTemplate_Unloaded"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid Background="Transparent" MouseLeftButtonDown="Grid_MouseLeftButtonDown">
|
||||
<Grid.RowDefinitions>
|
||||
@@ -75,7 +76,7 @@
|
||||
HorizontalContentAlignment="Stretch" BorderThickness="0">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<local:AttributeTemplate HelpClicked="AttributeTemplate_HelpClicked"></local:AttributeTemplate>
|
||||
<local:AttributeTemplate HelpClicked="AttributeTemplate_HelpClicked" AttributeChanged="AttributeTemplate_AttributeChanged"></local:AttributeTemplate>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
@@ -95,42 +96,42 @@
|
||||
<RowDefinition Height="*"></RowDefinition>
|
||||
<RowDefinition Height="auto"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<local:SkillTemplate Grid.Column="0"
|
||||
<local:SkillTemplate Grid.Column="0" x:Name="SkillTemplate0"
|
||||
Foreground="White" Cursor="Hand"
|
||||
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill0, Mode=TwoWay}"
|
||||
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
|
||||
RemoveClicked="SkillTemplate_RemoveClicked"></local:SkillTemplate>
|
||||
<local:SkillTemplate Grid.Column="1"
|
||||
<local:SkillTemplate Grid.Column="1" x:Name="SkillTemplate1"
|
||||
Foreground="White" Cursor="Hand"
|
||||
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill1, Mode=TwoWay}"
|
||||
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
|
||||
RemoveClicked="SkillTemplate_RemoveClicked"></local:SkillTemplate>
|
||||
<local:SkillTemplate Grid.Column="2"
|
||||
<local:SkillTemplate Grid.Column="2" x:Name="SkillTemplate2"
|
||||
Foreground="White" Cursor="Hand"
|
||||
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill2, Mode=TwoWay}"
|
||||
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
|
||||
RemoveClicked="SkillTemplate_RemoveClicked"></local:SkillTemplate>
|
||||
<local:SkillTemplate Grid.Column="3"
|
||||
<local:SkillTemplate Grid.Column="3" x:Name="SkillTemplate3"
|
||||
Foreground="White" Cursor="Hand"
|
||||
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill3, Mode=TwoWay}"
|
||||
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
|
||||
RemoveClicked="SkillTemplate_RemoveClicked"></local:SkillTemplate>
|
||||
<local:SkillTemplate Grid.Column="4"
|
||||
<local:SkillTemplate Grid.Column="4" x:Name="SkillTemplate4"
|
||||
Foreground="White" Cursor="Hand"
|
||||
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill4, Mode=TwoWay}"
|
||||
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
|
||||
RemoveClicked="SkillTemplate_RemoveClicked"></local:SkillTemplate>
|
||||
<local:SkillTemplate Grid.Column="5"
|
||||
<local:SkillTemplate Grid.Column="5" x:Name="SkillTemplate5"
|
||||
Foreground="White" Cursor="Hand"
|
||||
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill5, Mode=TwoWay}"
|
||||
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
|
||||
RemoveClicked="SkillTemplate_RemoveClicked"></local:SkillTemplate>
|
||||
<local:SkillTemplate Grid.Column="6"
|
||||
<local:SkillTemplate Grid.Column="6" x:Name="SkillTemplate6"
|
||||
Foreground="White" Cursor="Hand"
|
||||
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill6, Mode=TwoWay}"
|
||||
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
|
||||
RemoveClicked="SkillTemplate_RemoveClicked"></local:SkillTemplate>
|
||||
<local:SkillTemplate Grid.Column="7"
|
||||
<local:SkillTemplate Grid.Column="7" x:Name="SkillTemplate7"
|
||||
Foreground="White" Cursor="Hand"
|
||||
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill7, Mode=TwoWay}"
|
||||
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
|
||||
@@ -156,14 +157,36 @@
|
||||
<local:ChromiumBrowserWrapper x:Name="SkillBrowser" ControlsEnabled="False" Width="0" AddressBarReadonly="True" CanNavigate="True"></local:ChromiumBrowserWrapper>
|
||||
</Grid>
|
||||
<Grid Grid.Column="1" Grid.RowSpan="6">
|
||||
<ListView x:Name="SkillsListView" Background="Transparent" Width="0"
|
||||
ItemsSource="{Binding ElementName=_this, Path=AvailableSkills, Mode=OneWay}" MouseDoubleClick="ListView_MouseDoubleClick">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock FontSize="16" Foreground="White" TextWrapping="Wrap" Text="{Binding Name}"></TextBlock>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
<Grid x:Name="SkillListContainer">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"></RowDefinition>
|
||||
<RowDefinition Height="*"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<local:SearchTextBox FontSize="20"
|
||||
Foreground="White"
|
||||
Background="Transparent"
|
||||
SearchText="{Binding ElementName=_this, Path=SkillSearchText, Mode=TwoWay}"
|
||||
TextChanged="SearchTextBox_TextChanged"></local:SearchTextBox>
|
||||
<ListView x:Name="SkillsListView"
|
||||
Grid.Row="1"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Hidden"
|
||||
Background="Transparent"
|
||||
ItemsSource="{Binding ElementName=_this, Path=AvailableSkills, Mode=OneWay}"
|
||||
MouseDoubleClick="ListView_MouseDoubleClick">
|
||||
<ListView.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<VirtualizingStackPanel>
|
||||
</VirtualizingStackPanel>
|
||||
</ItemsPanelTemplate>
|
||||
</ListView.ItemsPanel>
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock FontSize="16" Foreground="White" TextWrapping="Wrap" Text="{Binding Name}"></TextBlock>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -1,332 +1,475 @@
|
||||
using Daybreak.Models.Builds;
|
||||
using Daybreak.Configuration;
|
||||
using Daybreak.Models.Builds;
|
||||
using Daybreak.Models.Guildwars;
|
||||
using Daybreak.Services.BuildTemplates;
|
||||
using Daybreak.Services.IconRetrieve;
|
||||
using Daybreak.Utils;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Configuration;
|
||||
using System.Core.Extensions;
|
||||
using System.Extensions;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
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 BuildTemplate.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 BuildTemplate : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for BuildTemplate.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 BuildTemplate : UserControl
|
||||
private const string InfoNamePlaceholder = "[NAME]";
|
||||
private const string BaseAddress = $"https://wiki.guildwars.com/wiki/{InfoNamePlaceholder}";
|
||||
|
||||
private bool suppressBuildChanged = false;
|
||||
private bool loadedProperties = false;
|
||||
private IIconBrowser? iconBrowser;
|
||||
private BuildEntry? loadedBuild;
|
||||
private SkillTemplate? selectingSkillTemplate;
|
||||
private CancellationTokenSource? cancellationTokenSource = new();
|
||||
|
||||
public event EventHandler? BuildChanged;
|
||||
|
||||
[GenerateDependencyProperty]
|
||||
private string skillSearchText = string.Empty;
|
||||
[GenerateDependencyProperty]
|
||||
private Profession primaryProfession = default!;
|
||||
[GenerateDependencyProperty]
|
||||
private Profession secondaryProfession = default!;
|
||||
[GenerateDependencyProperty]
|
||||
private Skill skill0 = default!;
|
||||
[GenerateDependencyProperty]
|
||||
private Skill skill1 = default!;
|
||||
[GenerateDependencyProperty]
|
||||
private Skill skill2 = default!;
|
||||
[GenerateDependencyProperty]
|
||||
private Skill skill3 = default!;
|
||||
[GenerateDependencyProperty]
|
||||
private Skill skill4 = default!;
|
||||
[GenerateDependencyProperty]
|
||||
private Skill skill5 = default!;
|
||||
[GenerateDependencyProperty]
|
||||
private Skill skill6 = default!;
|
||||
[GenerateDependencyProperty]
|
||||
private Skill skill7 = default!;
|
||||
public ObservableCollection<Skill> AvailableSkills { get; } = new ObservableCollection<Skill>();
|
||||
public ObservableCollection<AttributeEntry> Attributes { get; } = new ObservableCollection<AttributeEntry>();
|
||||
public ObservableCollection<Profession> Professions { get; } = new ObservableCollection<Profession>(Profession.Professions);
|
||||
|
||||
public BuildTemplate()
|
||||
{
|
||||
private const string InfoNamePlaceholder = "[NAME]";
|
||||
private const string BaseAddress = $"https://wiki.guildwars.com/wiki/{InfoNamePlaceholder}";
|
||||
this.InitializeComponent();
|
||||
this.InitializeProperties();
|
||||
this.DataContextChanged += this.BuildTemplate_DataContextChanged;
|
||||
}
|
||||
|
||||
private bool loadedProperties = false;
|
||||
private BuildEntry loadedBuild;
|
||||
private SkillTemplate selectingSkillTemplate;
|
||||
public async void InitializeTemplate(
|
||||
IIconCache iconRetriever,
|
||||
IIconBrowser iconBrowser,
|
||||
ILiveOptions<ApplicationConfiguration> liveOptions,
|
||||
IBuildTemplateManager buildTemplateManager,
|
||||
ILogger<ChromiumBrowserWrapper> logger)
|
||||
{
|
||||
this.iconBrowser = iconBrowser.ThrowIfNull();
|
||||
await this.SkillBrowser.InitializeDefaultBrowser(liveOptions, buildTemplateManager, logger);
|
||||
this.SkillTemplate0.InitializeSkillTemplate(iconRetriever);
|
||||
this.SkillTemplate1.InitializeSkillTemplate(iconRetriever);
|
||||
this.SkillTemplate2.InitializeSkillTemplate(iconRetriever);
|
||||
this.SkillTemplate3.InitializeSkillTemplate(iconRetriever);
|
||||
this.SkillTemplate4.InitializeSkillTemplate(iconRetriever);
|
||||
this.SkillTemplate5.InitializeSkillTemplate(iconRetriever);
|
||||
this.SkillTemplate6.InitializeSkillTemplate(iconRetriever);
|
||||
this.SkillTemplate7.InitializeSkillTemplate(iconRetriever);
|
||||
|
||||
[GenerateDependencyProperty]
|
||||
private Profession primaryProfession;
|
||||
[GenerateDependencyProperty]
|
||||
private Profession secondaryProfession;
|
||||
[GenerateDependencyProperty]
|
||||
private Skill skill0;
|
||||
[GenerateDependencyProperty]
|
||||
private Skill skill1;
|
||||
[GenerateDependencyProperty]
|
||||
private Skill skill2;
|
||||
[GenerateDependencyProperty]
|
||||
private Skill skill3;
|
||||
[GenerateDependencyProperty]
|
||||
private Skill skill4;
|
||||
[GenerateDependencyProperty]
|
||||
private Skill skill5;
|
||||
[GenerateDependencyProperty]
|
||||
private Skill skill6;
|
||||
[GenerateDependencyProperty]
|
||||
private Skill skill7;
|
||||
public ObservableCollection<Skill> AvailableSkills { get; } = new ObservableCollection<Skill>();
|
||||
public ObservableCollection<AttributeEntry> Attributes { get; } = new ObservableCollection<AttributeEntry>();
|
||||
public ObservableCollection<Profession> Professions { get; } = new ObservableCollection<Profession>(Profession.Professions);
|
||||
this.HideSkillListView();
|
||||
this.HideInfoBrowser();
|
||||
}
|
||||
|
||||
public BuildTemplate()
|
||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
base.OnPropertyChanged(e);
|
||||
if (this.loadedProperties is false)
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.InitializeProperties();
|
||||
this.DataContextChanged += BuildTemplate_DataContextChanged;
|
||||
return;
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
|
||||
if (e.Property == PrimaryProfessionProperty || e.Property == SecondaryProfessionProperty)
|
||||
{
|
||||
base.OnPropertyChanged(e);
|
||||
if (this.loadedProperties is false)
|
||||
if (e.Property == PrimaryProfessionProperty)
|
||||
{
|
||||
return;
|
||||
this.loadedBuild!.Build!.Primary = this.PrimaryProfession;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.loadedBuild!.Build!.Secondary = this.SecondaryProfession;
|
||||
}
|
||||
|
||||
if (e.Property == PrimaryProfessionProperty || e.Property == SecondaryProfessionProperty)
|
||||
this.LoadSkills();
|
||||
this.LoadAttributes();
|
||||
if (this.suppressBuildChanged is false)
|
||||
{
|
||||
if (e.Property == PrimaryProfessionProperty)
|
||||
{
|
||||
this.loadedBuild.Build.Primary = this.PrimaryProfession;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.loadedBuild.Build.Secondary = this.SecondaryProfession;
|
||||
}
|
||||
this.LoadSkills();
|
||||
this.LoadAttributes();
|
||||
this.BuildChanged?.Invoke(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeProperties()
|
||||
if (e.Property == Skill0Property ||
|
||||
e.Property == Skill1Property ||
|
||||
e.Property == Skill2Property ||
|
||||
e.Property == Skill3Property ||
|
||||
e.Property == Skill4Property ||
|
||||
e.Property == Skill5Property ||
|
||||
e.Property == Skill6Property ||
|
||||
e.Property == Skill7Property)
|
||||
{
|
||||
this.PrimaryProfession = Profession.None;
|
||||
this.SecondaryProfession = Profession.None;
|
||||
this.Skill0 = Skill.NoSkill;
|
||||
this.Skill1 = Skill.NoSkill;
|
||||
this.Skill2 = Skill.NoSkill;
|
||||
this.Skill3 = Skill.NoSkill;
|
||||
this.Skill4 = Skill.NoSkill;
|
||||
this.Skill5 = Skill.NoSkill;
|
||||
this.Skill6 = Skill.NoSkill;
|
||||
this.Skill7 = Skill.NoSkill;
|
||||
this.loadedProperties = true;
|
||||
}
|
||||
|
||||
private void BuildTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if(e.NewValue is BuildEntry)
|
||||
if (this.suppressBuildChanged is false)
|
||||
{
|
||||
this.LoadBuild();
|
||||
this.LoadSkills();
|
||||
this.LoadAttributes();
|
||||
this.loadedBuild!.Build!.Skills[0] = this.Skill0;
|
||||
this.loadedBuild!.Build!.Skills[1] = this.Skill1;
|
||||
this.loadedBuild!.Build!.Skills[2] = this.Skill2;
|
||||
this.loadedBuild!.Build!.Skills[3] = this.Skill3;
|
||||
this.loadedBuild!.Build!.Skills[4] = this.Skill4;
|
||||
this.loadedBuild!.Build!.Skills[5] = this.Skill5;
|
||||
this.loadedBuild!.Build!.Skills[6] = this.Skill6;
|
||||
this.loadedBuild!.Build!.Skills[7] = this.Skill7;
|
||||
this.BuildChanged?.Invoke(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Grid_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
private void BuildTemplate_Unloaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.cancellationTokenSource?.Cancel();
|
||||
}
|
||||
|
||||
private void InitializeProperties()
|
||||
{
|
||||
this.PrimaryProfession = Profession.None;
|
||||
this.SecondaryProfession = Profession.None;
|
||||
this.Skill0 = Skill.NoSkill;
|
||||
this.Skill1 = Skill.NoSkill;
|
||||
this.Skill2 = Skill.NoSkill;
|
||||
this.Skill3 = Skill.NoSkill;
|
||||
this.Skill4 = Skill.NoSkill;
|
||||
this.Skill5 = Skill.NoSkill;
|
||||
this.Skill6 = Skill.NoSkill;
|
||||
this.Skill7 = Skill.NoSkill;
|
||||
this.loadedProperties = true;
|
||||
}
|
||||
|
||||
private void BuildTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if(e.NewValue is BuildEntry)
|
||||
{
|
||||
this.HideSkillListView();
|
||||
this.HideInfoBrowser();
|
||||
this.LoadBuild();
|
||||
this.LoadSkills();
|
||||
this.LoadAttributes();
|
||||
}
|
||||
}
|
||||
|
||||
private void Grid_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
this.HideSkillListView();
|
||||
this.HideInfoBrowser();
|
||||
}
|
||||
|
||||
private void LoadAttributes()
|
||||
{
|
||||
var possibleAttributes = new List<AttributeEntry>();
|
||||
if (this.PrimaryProfession != Profession.None)
|
||||
{
|
||||
possibleAttributes.Add(new AttributeEntry { Attribute = this.PrimaryProfession.PrimaryAttribute });
|
||||
possibleAttributes.AddRange(this.PrimaryProfession.Attributes!.Select(a => new AttributeEntry { Attribute = a }));
|
||||
}
|
||||
|
||||
private void LoadAttributes()
|
||||
if (this.SecondaryProfession != Profession.None && this.SecondaryProfession != this.PrimaryProfession)
|
||||
{
|
||||
var possibleAttributes = new List<AttributeEntry>();
|
||||
if (this.PrimaryProfession != Profession.None)
|
||||
{
|
||||
possibleAttributes.Add(new AttributeEntry { Attribute = this.PrimaryProfession.PrimaryAttribute });
|
||||
possibleAttributes.AddRange(this.PrimaryProfession.Attributes.Select(a => new AttributeEntry { Attribute = a }));
|
||||
}
|
||||
possibleAttributes.AddRange(this.SecondaryProfession.Attributes!.Select(a => new AttributeEntry { Attribute = a }));
|
||||
}
|
||||
|
||||
if (this.SecondaryProfession != Profession.None && this.SecondaryProfession != this.PrimaryProfession)
|
||||
this.Attributes.ClearAnd().AddRange(possibleAttributes.Select(entry =>
|
||||
{
|
||||
var maybePresentAttribute = this.loadedBuild!.Build!.Attributes.Where(buildEntry => entry.Attribute == buildEntry.Attribute).FirstOrDefault();
|
||||
if (maybePresentAttribute is null)
|
||||
{
|
||||
possibleAttributes.AddRange(this.SecondaryProfession.Attributes.Select(a => new AttributeEntry { Attribute = a }));
|
||||
}
|
||||
|
||||
this.Attributes.ClearAnd().AddRange(possibleAttributes.Select(entry =>
|
||||
{
|
||||
var maybePresentAttribute = this.loadedBuild.Build.Attributes.Where(buildEntry => entry.Attribute == buildEntry.Attribute).FirstOrDefault();
|
||||
if (maybePresentAttribute is null)
|
||||
{
|
||||
return entry;
|
||||
}
|
||||
|
||||
entry.Points = maybePresentAttribute.Points;
|
||||
return entry;
|
||||
}));
|
||||
}
|
||||
|
||||
this.loadedBuild.Build.Attributes = this.Attributes.ToList();
|
||||
}
|
||||
entry.Points = maybePresentAttribute.Points;
|
||||
return entry;
|
||||
}));
|
||||
|
||||
private void LoadSkills()
|
||||
this.loadedBuild!.Build!.Attributes = this.Attributes.ToList();
|
||||
}
|
||||
|
||||
private async void LoadSkills()
|
||||
{
|
||||
if (this.Skill0.Profession != this.PrimaryProfession &&
|
||||
this.Skill0.Profession != this.SecondaryProfession &&
|
||||
this.Skill0.Profession != Profession.None)
|
||||
{
|
||||
var possibleSkills = Skill.Skills
|
||||
.Where(s => s.Profession == PrimaryProfession || s.Profession == SecondaryProfession || s.Profession == Profession.None)
|
||||
.Where(s => s != Skill.NoSkill)
|
||||
.OrderBy(s => s.Name);
|
||||
this.AvailableSkills.ClearAnd().AddRange(possibleSkills);
|
||||
|
||||
if (this.Skill0.Profession != PrimaryProfession &&
|
||||
this.Skill0.Profession != SecondaryProfession &&
|
||||
this.Skill0.Profession != Profession.None)
|
||||
{
|
||||
this.Skill0 = Skill.NoSkill;
|
||||
}
|
||||
if (this.Skill1.Profession != PrimaryProfession &&
|
||||
this.Skill1.Profession != SecondaryProfession &&
|
||||
this.Skill1.Profession != Profession.None)
|
||||
{
|
||||
this.Skill1 = Skill.NoSkill;
|
||||
}
|
||||
if (this.Skill2.Profession != PrimaryProfession &&
|
||||
this.Skill2.Profession != SecondaryProfession &&
|
||||
this.Skill2.Profession != Profession.None)
|
||||
{
|
||||
this.Skill2 = Skill.NoSkill;
|
||||
}
|
||||
if (this.Skill3.Profession != PrimaryProfession &&
|
||||
this.Skill3.Profession != SecondaryProfession &&
|
||||
this.Skill3.Profession != Profession.None)
|
||||
{
|
||||
this.Skill3 = Skill.NoSkill;
|
||||
}
|
||||
if (this.Skill4.Profession != PrimaryProfession &&
|
||||
this.Skill4.Profession != SecondaryProfession &&
|
||||
this.Skill4.Profession != Profession.None)
|
||||
{
|
||||
this.Skill4 = Skill.NoSkill;
|
||||
}
|
||||
if (this.Skill5.Profession != PrimaryProfession &&
|
||||
this.Skill5.Profession != SecondaryProfession &&
|
||||
this.Skill5.Profession != Profession.None)
|
||||
{
|
||||
this.Skill5 = Skill.NoSkill;
|
||||
}
|
||||
if (this.Skill6.Profession != PrimaryProfession &&
|
||||
this.Skill6.Profession != SecondaryProfession &&
|
||||
this.Skill6.Profession != Profession.None)
|
||||
{
|
||||
this.Skill6 = Skill.NoSkill;
|
||||
}
|
||||
if (this.Skill7.Profession != PrimaryProfession &&
|
||||
this.Skill7.Profession != SecondaryProfession &&
|
||||
this.Skill7.Profession != Profession.None)
|
||||
{
|
||||
this.Skill7 = Skill.NoSkill;
|
||||
}
|
||||
this.Skill0 = Skill.NoSkill;
|
||||
}
|
||||
|
||||
private void LoadBuild()
|
||||
if (this.Skill1.Profession != this.PrimaryProfession &&
|
||||
this.Skill1.Profession != this.SecondaryProfession &&
|
||||
this.Skill1.Profession != Profession.None)
|
||||
{
|
||||
var build = this.DataContext.As<BuildEntry>();
|
||||
this.loadedBuild = build;
|
||||
this.PrimaryProfession = build.Build.Primary;
|
||||
this.SecondaryProfession = build.Build.Secondary;
|
||||
this.Skill0 = build.Build.Skills[0];
|
||||
this.Skill1 = build.Build.Skills[1];
|
||||
this.Skill2 = build.Build.Skills[2];
|
||||
this.Skill3 = build.Build.Skills[3];
|
||||
this.Skill4 = build.Build.Skills[4];
|
||||
this.Skill5 = build.Build.Skills[5];
|
||||
this.Skill6 = build.Build.Skills[6];
|
||||
this.Skill7 = build.Build.Skills[7];
|
||||
this.Skill1 = Skill.NoSkill;
|
||||
}
|
||||
|
||||
private void BrowseToInfo(string infoName)
|
||||
if (this.Skill2.Profession != this.PrimaryProfession &&
|
||||
this.Skill2.Profession != this.SecondaryProfession &&
|
||||
this.Skill2.Profession != Profession.None)
|
||||
{
|
||||
var address = BaseAddress.Replace(InfoNamePlaceholder, infoName.Replace(" ", "_"));
|
||||
this.SkillBrowser.Address = address;
|
||||
this.ShowInfoBrowser();
|
||||
this.Skill2 = Skill.NoSkill;
|
||||
}
|
||||
|
||||
private void ShowInfoBrowser()
|
||||
if (this.Skill3.Profession != this.PrimaryProfession &&
|
||||
this.Skill3.Profession != this.SecondaryProfession &&
|
||||
this.Skill3.Profession != Profession.None)
|
||||
{
|
||||
this.Skill3 = Skill.NoSkill;
|
||||
}
|
||||
|
||||
if (this.Skill4.Profession != this.PrimaryProfession &&
|
||||
this.Skill4.Profession != this.SecondaryProfession &&
|
||||
this.Skill4.Profession != Profession.None)
|
||||
{
|
||||
this.Skill4 = Skill.NoSkill;
|
||||
}
|
||||
|
||||
if (this.Skill5.Profession != this.PrimaryProfession &&
|
||||
this.Skill5.Profession != this.SecondaryProfession &&
|
||||
this.Skill5.Profession != Profession.None)
|
||||
{
|
||||
this.Skill5 = Skill.NoSkill;
|
||||
}
|
||||
|
||||
if (this.Skill6.Profession != this.PrimaryProfession &&
|
||||
this.Skill6.Profession != this.SecondaryProfession &&
|
||||
this.Skill6.Profession != Profession.None)
|
||||
{
|
||||
this.Skill6 = Skill.NoSkill;
|
||||
}
|
||||
|
||||
if (this.Skill7.Profession != this.PrimaryProfession &&
|
||||
this.Skill7.Profession != this.SecondaryProfession &&
|
||||
this.Skill7.Profession != Profession.None)
|
||||
{
|
||||
this.Skill7 = Skill.NoSkill;
|
||||
}
|
||||
|
||||
var filteredSkills = await this.FilterSkills(this.SkillSearchText).ToListAsync().ConfigureAwait(true);
|
||||
this.AvailableSkills.ClearAnd().AddRange(filteredSkills);
|
||||
}
|
||||
|
||||
private void LoadBuild()
|
||||
{
|
||||
this.suppressBuildChanged = true;
|
||||
var build = this.DataContext.As<BuildEntry>();
|
||||
this.loadedBuild = build;
|
||||
this.PrimaryProfession = build.Build!.Primary;
|
||||
this.SecondaryProfession = build.Build.Secondary;
|
||||
this.Skill0 = build.Build.Skills[0];
|
||||
this.Skill1 = build.Build.Skills[1];
|
||||
this.Skill2 = build.Build.Skills[2];
|
||||
this.Skill3 = build.Build.Skills[3];
|
||||
this.Skill4 = build.Build.Skills[4];
|
||||
this.Skill5 = build.Build.Skills[5];
|
||||
this.Skill6 = build.Build.Skills[6];
|
||||
this.Skill7 = build.Build.Skills[7];
|
||||
this.suppressBuildChanged = false;
|
||||
}
|
||||
|
||||
private void BrowseToInfo(string infoName)
|
||||
{
|
||||
var address = BaseAddress.Replace(InfoNamePlaceholder, infoName.Replace(" ", "_"));
|
||||
this.SkillBrowser.Address = address;
|
||||
this.ShowInfoBrowser();
|
||||
}
|
||||
|
||||
private void ShowInfoBrowser()
|
||||
{
|
||||
if (this.SkillBrowser.BrowserSupported is true)
|
||||
{
|
||||
this.SkillBrowser.Width = 400;
|
||||
this.SkillsListView.Width = 0;
|
||||
this.SkillListContainer.Width = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void HideInfoBrowser()
|
||||
private void HideInfoBrowser()
|
||||
{
|
||||
if (this.SkillBrowser.BrowserSupported is true)
|
||||
{
|
||||
this.SkillBrowser.Width = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowSkillListView()
|
||||
private void ShowSkillListView()
|
||||
{
|
||||
this.SkillBrowser.Width = 0;
|
||||
this.SkillListContainer.Width = 400;
|
||||
}
|
||||
|
||||
private void HideSkillListView()
|
||||
{
|
||||
this.SkillListContainer.Width = 0;
|
||||
}
|
||||
|
||||
private void HelpButtonPrimary_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
if (this.PrimaryProfession == Profession.None)
|
||||
{
|
||||
this.SkillBrowser.Width = 0;
|
||||
this.SkillsListView.Width = 400;
|
||||
return;
|
||||
}
|
||||
|
||||
private void HideSkillListView()
|
||||
this.BrowseToInfo(this.PrimaryProfession.Name!);
|
||||
if (e is RoutedEventArgs routedEventArgs)
|
||||
{
|
||||
this.SkillsListView.Width = 0;
|
||||
routedEventArgs.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void HelpButtonSecondary_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
if (this.SecondaryProfession == Profession.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
private void HelpButtonPrimary_Clicked(object sender, System.EventArgs e)
|
||||
this.BrowseToInfo(this.SecondaryProfession.Name!);
|
||||
if (e is RoutedEventArgs routedEventArgs)
|
||||
{
|
||||
if (this.PrimaryProfession == Profession.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
routedEventArgs.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
this.BrowseToInfo(PrimaryProfession.Name);
|
||||
if (e is RoutedEventArgs routedEventArgs)
|
||||
{
|
||||
routedEventArgs.Handled = true;
|
||||
}
|
||||
private void AttributeTemplate_HelpClicked(object _, AttributeEntry e)
|
||||
{
|
||||
this.BrowseToInfo(e.Attribute?.Name!);
|
||||
}
|
||||
|
||||
private void AttributeTemplate_AttributeChanged(object _, AttributeEntry e)
|
||||
{
|
||||
e.ThrowIfNull();
|
||||
this.BuildChanged?.Invoke(this, new EventArgs());
|
||||
}
|
||||
|
||||
private void SkillTemplate_Clicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var skill = sender.As<SkillTemplate>().DataContext.As<Skill>();
|
||||
if (skill == Skill.NoSkill)
|
||||
{
|
||||
this.SkillSearchText = string.Empty;
|
||||
this.ShowSkillListView();
|
||||
this.selectingSkillTemplate = sender.As<SkillTemplate>();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.BrowseToInfo(skill.Name!);
|
||||
}
|
||||
|
||||
private void HelpButtonSecondary_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
if (this.SecondaryProfession == Profession.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
this.BrowseToInfo(this.SecondaryProfession.Name);
|
||||
if (e is RoutedEventArgs routedEventArgs)
|
||||
{
|
||||
routedEventArgs.Handled = true;
|
||||
}
|
||||
private void SearchTextBox_TextChanged(object _, string e)
|
||||
{
|
||||
e.ThrowIfNull();
|
||||
this.LoadSkills();
|
||||
}
|
||||
|
||||
private void SkillTemplate_RemoveClicked(object sender, System.EventArgs e)
|
||||
{
|
||||
sender.As<SkillTemplate>().DataContext = Skill.NoSkill;
|
||||
}
|
||||
|
||||
private void ListView_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
if (this.selectingSkillTemplate is null)
|
||||
{
|
||||
this.HideSkillListView();
|
||||
return;
|
||||
}
|
||||
|
||||
private void AttributeTemplate_HelpClicked(object sender, AttributeEntry e)
|
||||
this.selectingSkillTemplate.DataContext = sender.As<ListView>().SelectedItem;
|
||||
this.HideSkillListView();
|
||||
this.loadedBuild!.Build!.Skills[0] = this.Skill0;
|
||||
this.loadedBuild!.Build!.Skills[1] = this.Skill1;
|
||||
this.loadedBuild!.Build!.Skills[2] = this.Skill2;
|
||||
this.loadedBuild!.Build!.Skills[3] = this.Skill3;
|
||||
this.loadedBuild!.Build!.Skills[4] = this.Skill4;
|
||||
this.loadedBuild!.Build!.Skills[5] = this.Skill5;
|
||||
this.loadedBuild!.Build!.Skills[6] = this.Skill6;
|
||||
this.loadedBuild!.Build!.Skills[7] = this.Skill7;
|
||||
}
|
||||
|
||||
private void ListView_NavigateWithMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
|
||||
{
|
||||
e.Handled = true;
|
||||
if (e.Delta > 0)
|
||||
{
|
||||
this.BrowseToInfo(e.Attribute.Name);
|
||||
sender.As<ListView>().SelectedIndex = sender.As<ListView>().SelectedIndex > 0 ?
|
||||
sender.As<ListView>().SelectedIndex - 1 :
|
||||
0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sender.As<ListView>().SelectedIndex = sender.As<ListView>().SelectedIndex < sender.As<ListView>().Items.Count - 1 ?
|
||||
sender.As<ListView>().SelectedIndex + 1 :
|
||||
sender.As<ListView>().Items.Count;
|
||||
}
|
||||
}
|
||||
|
||||
private void ScrollViewer_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
|
||||
{
|
||||
if (sender is not ScrollViewer scrollViewer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
private void SkillTemplate_Clicked(object sender, RoutedEventArgs e)
|
||||
e.Handled = true;
|
||||
scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - e.Delta);
|
||||
}
|
||||
|
||||
private async IAsyncEnumerable<Skill> FilterSkills(string searchTerm)
|
||||
{
|
||||
// Replace symbols to ease search
|
||||
searchTerm = searchTerm?.Replace("\"", "").Replace("!", "")!;
|
||||
|
||||
foreach (var skill in Skill.Skills)
|
||||
{
|
||||
var skill = sender.As<SkillTemplate>().DataContext.As<Skill>();
|
||||
if (skill == Skill.NoSkill)
|
||||
{
|
||||
this.ShowSkillListView();
|
||||
this.selectingSkillTemplate = sender.As<SkillTemplate>();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.BrowseToInfo(skill.Name);
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void SkillTemplate_RemoveClicked(object sender, System.EventArgs e)
|
||||
{
|
||||
sender.As<SkillTemplate>().DataContext = Skill.NoSkill;
|
||||
}
|
||||
|
||||
private void ListView_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
if (this.selectingSkillTemplate is null)
|
||||
{
|
||||
this.HideSkillListView();
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
this.selectingSkillTemplate.DataContext = sender.As<ListView>().SelectedItem;
|
||||
this.HideSkillListView();
|
||||
this.loadedBuild.Build.Skills[0] = Skill0;
|
||||
this.loadedBuild.Build.Skills[1] = Skill1;
|
||||
this.loadedBuild.Build.Skills[2] = Skill2;
|
||||
this.loadedBuild.Build.Skills[3] = Skill3;
|
||||
this.loadedBuild.Build.Skills[4] = Skill4;
|
||||
this.loadedBuild.Build.Skills[5] = Skill5;
|
||||
this.loadedBuild.Build.Skills[6] = Skill6;
|
||||
this.loadedBuild.Build.Skills[7] = Skill7;
|
||||
}
|
||||
|
||||
private void ListView_NavigateWithMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
|
||||
{
|
||||
e.Handled = true;
|
||||
if (e.Delta > 0)
|
||||
if (skill.Profession != this.PrimaryProfession &&
|
||||
skill.Profession != this.SecondaryProfession &&
|
||||
skill.Profession != Profession.None)
|
||||
{
|
||||
sender.As<ListView>().SelectedIndex = sender.As<ListView>().SelectedIndex > 0 ?
|
||||
sender.As<ListView>().SelectedIndex - 1 :
|
||||
0;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
|
||||
if (searchTerm.IsNullOrWhiteSpace())
|
||||
{
|
||||
sender.As<ListView>().SelectedIndex = sender.As<ListView>().SelectedIndex < sender.As<ListView>().Items.Count - 1 ?
|
||||
sender.As<ListView>().SelectedIndex + 1 :
|
||||
sender.As<ListView>().Items.Count;
|
||||
yield return skill;
|
||||
continue;
|
||||
}
|
||||
|
||||
var matchesName = await Task.Run(() => StringUtils.MatchesSearchString(skill.Name!.Replace("\"", "").Replace("!", ""), searchTerm!));
|
||||
if (matchesName)
|
||||
{
|
||||
yield return skill;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,67 +6,66 @@ using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Extensions;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for GuildwarsPathTemplate.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 GuildwarsPathTemplate : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for GuildwarsPathTemplate.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 GuildwarsPathTemplate : UserControl
|
||||
public event EventHandler? RemoveClicked;
|
||||
public event EventHandler? DefaultClicked;
|
||||
|
||||
[GenerateDependencyProperty]
|
||||
private string path = string.Empty;
|
||||
[GenerateDependencyProperty]
|
||||
private bool isDefault;
|
||||
|
||||
public GuildwarsPathTemplate()
|
||||
{
|
||||
public event EventHandler RemoveClicked;
|
||||
public event EventHandler DefaultClicked;
|
||||
this.InitializeComponent();
|
||||
this.DataContextChanged += this.GuildwarsPathTemplate_DataContextChanged;
|
||||
}
|
||||
|
||||
[GenerateDependencyProperty]
|
||||
private string path;
|
||||
[GenerateDependencyProperty]
|
||||
private bool isDefault;
|
||||
|
||||
public GuildwarsPathTemplate()
|
||||
private void GuildwarsPathTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.NewValue is GuildwarsPath guildwarsPath)
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.DataContextChanged += GuildwarsPathTemplate_DataContextChanged;
|
||||
this.IsDefault = guildwarsPath.Default;
|
||||
this.Path = guildwarsPath.Path;
|
||||
}
|
||||
}
|
||||
|
||||
private void GuildwarsPathTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.NewValue is GuildwarsPath guildwarsPath)
|
||||
{
|
||||
this.IsDefault = guildwarsPath.Default;
|
||||
this.Path = guildwarsPath.Path;
|
||||
}
|
||||
}
|
||||
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
this.DataContext.As<GuildwarsPath>().Path = this.Path;
|
||||
}
|
||||
|
||||
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
this.DataContext.As<GuildwarsPath>().Path = this.Path;
|
||||
}
|
||||
private void StarGlyph_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.DefaultClicked?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private void StarGlyph_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.DefaultClicked?.Invoke(this, e);
|
||||
}
|
||||
private void BinButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.RemoveClicked?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private void BinButton_Clicked(object sender, EventArgs e)
|
||||
private void FilePickerGlyph_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
var filePicker = new OpenFileDialog()
|
||||
{
|
||||
this.RemoveClicked?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private void FilePickerGlyph_Clicked(object sender, EventArgs e)
|
||||
CheckFileExists = true,
|
||||
CheckPathExists = true,
|
||||
DefaultExt = "exe",
|
||||
Multiselect = false
|
||||
};
|
||||
if (filePicker.ShowDialog() is true)
|
||||
{
|
||||
var filePicker = new OpenFileDialog()
|
||||
{
|
||||
CheckFileExists = true,
|
||||
CheckPathExists = true,
|
||||
DefaultExt = "exe",
|
||||
Multiselect = false
|
||||
};
|
||||
if (filePicker.ShowDialog() is true)
|
||||
{
|
||||
this.Path = filePicker.FileName;
|
||||
this.DataContext.As<GuildwarsPath>().Path = filePicker.FileName;
|
||||
}
|
||||
this.Path = filePicker.FileName;
|
||||
this.DataContext.As<GuildwarsPath>().Path = filePicker.FileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<UserControl x:Class="Daybreak.Controls.LogMessageTemplate"
|
||||
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">
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter"></BooleanToVisibilityConverter>
|
||||
</UserControl.Resources>
|
||||
<Grid HorizontalAlignment="Stretch">
|
||||
<TextBlock Text="{Binding ElementName=_this, Path=Message, Mode=OneWay}" Background="Transparent"
|
||||
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
MouseLeftButtonDown="TextBox_MouseLeftButtonDown" MaxHeight="18" TextWrapping="Wrap"></TextBlock>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,35 @@
|
||||
using System.Windows.Extensions;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Extensions;
|
||||
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for LogTemplate.xaml
|
||||
/// </summary>
|
||||
public partial class LogMessageTemplate : UserControl
|
||||
{
|
||||
private bool expanded;
|
||||
|
||||
[GenerateDependencyProperty]
|
||||
private string message = string.Empty;
|
||||
|
||||
public LogMessageTemplate()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void TextBox_MouseLeftButtonDown(object sender, MouseButtonEventArgs eventArgs)
|
||||
{
|
||||
this.expanded = !this.expanded;
|
||||
if (this.expanded)
|
||||
{
|
||||
sender.As<TextBlock>().MaxHeight = double.MaxValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
sender.As<TextBlock>().MaxHeight = 18;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,58 +6,57 @@ using System.Windows.Controls;
|
||||
using System.Windows.Extensions;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Daybreak.Controls.Templates
|
||||
namespace Daybreak.Controls.Templates;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for ScreenTemplate.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 ScreenTemplate : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ScreenTemplate.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 ScreenTemplate : UserControl
|
||||
public event EventHandler<Screen>? Clicked;
|
||||
|
||||
[GenerateDependencyProperty]
|
||||
private string screenId = string.Empty;
|
||||
[GenerateDependencyProperty]
|
||||
private Brush highlight = default!;
|
||||
|
||||
public ScreenTemplate()
|
||||
{
|
||||
public event EventHandler<Screen> Clicked;
|
||||
this.InitializeComponent();
|
||||
this.DataContextChanged += this.ScreenTemplate_DataContextChanged;
|
||||
}
|
||||
|
||||
[GenerateDependencyProperty]
|
||||
private string screenId;
|
||||
[GenerateDependencyProperty]
|
||||
private Brush highlight;
|
||||
|
||||
public ScreenTemplate()
|
||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
base.OnPropertyChanged(e);
|
||||
if (e.Property == ForegroundProperty)
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.DataContextChanged += ScreenTemplate_DataContextChanged;
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
base.OnPropertyChanged(e);
|
||||
if (e.Property == ForegroundProperty)
|
||||
{
|
||||
this.Highlight = e.NewValue.As<Brush>();
|
||||
}
|
||||
}
|
||||
|
||||
private void ScreenTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.NewValue is Screen screen)
|
||||
{
|
||||
this.ScreenId = screen.Id.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
private void Rectangle_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
|
||||
{
|
||||
this.Highlight = Brushes.LightSteelBlue;
|
||||
}
|
||||
|
||||
private void Rectangle_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
|
||||
{
|
||||
this.Highlight = this.Foreground;
|
||||
}
|
||||
|
||||
private void Rectangle_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
this.Clicked?.Invoke(this, this.DataContext.As<Screen>());
|
||||
this.Highlight = e.NewValue.As<Brush>();
|
||||
}
|
||||
}
|
||||
|
||||
private void ScreenTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.NewValue is Screen screen)
|
||||
{
|
||||
this.ScreenId = screen.Id.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
private void Rectangle_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
|
||||
{
|
||||
this.Highlight = Brushes.LightSteelBlue;
|
||||
}
|
||||
|
||||
private void Rectangle_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
|
||||
{
|
||||
this.Highlight = this.Foreground;
|
||||
}
|
||||
|
||||
private void Rectangle_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
this.Clicked?.Invoke(this, this.DataContext.As<Screen>());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<UserControl x:Class="Daybreak.Controls.SkillTemplate"
|
||||
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:webview="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
|
||||
xmlns:local="clr-namespace:Daybreak.Controls"
|
||||
mc:Ignorable="d"
|
||||
x:Name="_this"
|
||||
|
||||
@@ -1,112 +1,93 @@
|
||||
using Daybreak.Launch;
|
||||
using Daybreak.Models.Builds;
|
||||
using Daybreak.Models.Guildwars;
|
||||
using Daybreak.Services.IconRetrieve;
|
||||
using System;
|
||||
using System.Extensions;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Extensions;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
namespace Daybreak.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for SkillTemplate.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 SkillTemplate : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for SkillTemplate.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 SkillTemplate : UserControl
|
||||
public event EventHandler<RoutedEventArgs>? Clicked;
|
||||
public event EventHandler? RemoveClicked;
|
||||
|
||||
private IIconCache? iconRetriever;
|
||||
|
||||
[GenerateDependencyProperty]
|
||||
private ImageSource imageSource = default!;
|
||||
[GenerateDependencyProperty]
|
||||
private double borderOpacity;
|
||||
|
||||
public SkillTemplate()
|
||||
{
|
||||
public event EventHandler<RoutedEventArgs> Clicked;
|
||||
public event EventHandler RemoveClicked;
|
||||
this.InitializeComponent();
|
||||
this.DataContextChanged += this.SkillTemplate_DataContextChanged;
|
||||
}
|
||||
|
||||
private readonly IIconRetriever iconRetriever;
|
||||
public void InitializeSkillTemplate(IIconCache iconRetriever)
|
||||
{
|
||||
this.iconRetriever = iconRetriever;
|
||||
this.SkillTemplate_DataContextChanged(this, new DependencyPropertyChangedEventArgs(UserControl.DataContextProperty, null, this.DataContext));
|
||||
}
|
||||
|
||||
[GenerateDependencyProperty]
|
||||
private ImageSource imageSource;
|
||||
[GenerateDependencyProperty]
|
||||
private double borderOpacity;
|
||||
|
||||
public SkillTemplate()
|
||||
private async void SkillTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (this.iconRetriever is null)
|
||||
{
|
||||
this.iconRetriever = Launcher.ApplicationServiceManager.GetService<IIconRetriever>();
|
||||
this.InitializeComponent();
|
||||
this.DataContextChanged += SkillTemplate_DataContextChanged;
|
||||
return;
|
||||
}
|
||||
|
||||
private void SkillTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
if (e.NewValue is Skill skill)
|
||||
{
|
||||
if (e.NewValue is Skill skill)
|
||||
if (skill != Skill.NoSkill)
|
||||
{
|
||||
if (skill != Skill.NoSkill)
|
||||
var maybeUri = await this.iconRetriever.GetIconUri(skill).ConfigureAwait(true);
|
||||
if (maybeUri.ExtractValue() is Uri uri)
|
||||
{
|
||||
Task.Run(() => GetImageStream(skill)).ContinueWith((previousTask) =>
|
||||
{
|
||||
this.Dispatcher.Invoke(() =>
|
||||
{
|
||||
this.ImageSource = GetImageSource(previousTask.Result);
|
||||
});
|
||||
});
|
||||
}
|
||||
else if (this.ImageSource is not null)
|
||||
{
|
||||
this.ImageSource = null;
|
||||
this.ImageSource = new BitmapImage(uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Border_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
|
||||
{
|
||||
this.BorderOpacity = 1;
|
||||
this.CancelButton.Visibility = this.HasSkill() ? Visibility.Visible : Visibility.Hidden;
|
||||
}
|
||||
private void Border_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
|
||||
{
|
||||
this.BorderOpacity = 0;
|
||||
this.CancelButton.Visibility = Visibility.Hidden;
|
||||
}
|
||||
private void Rectangle_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
this.Clicked?.Invoke(this, e);
|
||||
}
|
||||
private void CancelButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.RemoveClicked?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private bool HasSkill()
|
||||
{
|
||||
if (this.DataContext is Skill skill)
|
||||
else if (this.ImageSource is not null)
|
||||
{
|
||||
return skill != Skill.NoSkill;
|
||||
this.ImageSource = null;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
private async Task<Stream> GetImageStream(Skill skill)
|
||||
{
|
||||
var maybeStream = await this.iconRetriever.GetIcon(skill);
|
||||
return maybeStream.ExtractValue();
|
||||
}
|
||||
private ImageSource GetImageSource(Stream stream)
|
||||
{
|
||||
if (stream is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.Dispatcher.Invoke(() =>
|
||||
{
|
||||
var bitmapImage = new BitmapImage();
|
||||
bitmapImage.BeginInit();
|
||||
bitmapImage.StreamSource = stream;
|
||||
bitmapImage.CacheOption = BitmapCacheOption.OnDemand;
|
||||
bitmapImage.EndInit();
|
||||
return bitmapImage;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void Border_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
|
||||
{
|
||||
this.BorderOpacity = 1;
|
||||
this.CancelButton.Visibility = this.HasSkill() ? Visibility.Visible : Visibility.Hidden;
|
||||
}
|
||||
private void Border_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
|
||||
{
|
||||
this.BorderOpacity = 0;
|
||||
this.CancelButton.Visibility = Visibility.Hidden;
|
||||
}
|
||||
private void Rectangle_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
this.Clicked?.Invoke(this, e);
|
||||
}
|
||||
private void CancelButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.RemoveClicked?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private bool HasSkill()
|
||||
{
|
||||
if (this.DataContext is Skill skill)
|
||||
{
|
||||
return skill != Skill.NoSkill;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,46 +1,53 @@
|
||||
using System;
|
||||
using System.Extensions;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Daybreak.Converters
|
||||
namespace Daybreak.Converters;
|
||||
|
||||
public class BooleanToVisibilityConverter : IValueConverter
|
||||
{
|
||||
public class BooleanToVisibilityConverter : IValueConverter
|
||||
/// <summary>
|
||||
/// Set to true if you want to show control when boolean value is true.
|
||||
/// Set to false if you want to hide/collapse control when value is true.
|
||||
/// </summary>
|
||||
public bool TriggerValue { get; set; } = true;
|
||||
/// <summary>
|
||||
/// Set to true if you just want to hide the control, else set to false if you want to collapse the control.
|
||||
/// </summary>
|
||||
public bool IsHidden { get; set; }
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
/// <summary>
|
||||
/// Set to true if you want to show control when boolean value is true.
|
||||
/// Set to false if you want to hide/collapse control when value is true.
|
||||
/// </summary>
|
||||
public bool TriggerValue { get; set; } = true;
|
||||
/// <summary>
|
||||
/// Set to true if you just want to hide the control, else set to false if you want to collapse the control.
|
||||
/// </summary>
|
||||
public bool IsHidden { get; set; }
|
||||
return this.GetVisibility(value);
|
||||
}
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private object GetVisibility(object value)
|
||||
{
|
||||
if (value is not bool)
|
||||
{
|
||||
return GetVisibility(value);
|
||||
return this.IsHidden ?
|
||||
Visibility.Hidden :
|
||||
Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
var objValue = value.Cast<bool>();
|
||||
if ((objValue && this.TriggerValue && this.IsHidden) || (!objValue && !this.TriggerValue && this.IsHidden))
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return Visibility.Hidden;
|
||||
}
|
||||
|
||||
private object GetVisibility(object value)
|
||||
if ((objValue && this.TriggerValue && !this.IsHidden) || (!objValue && !this.TriggerValue && !this.IsHidden))
|
||||
{
|
||||
if (!(value is bool))
|
||||
return DependencyProperty.UnsetValue;
|
||||
bool objValue = (bool)value;
|
||||
if ((objValue && TriggerValue && IsHidden) || (!objValue && !TriggerValue && IsHidden))
|
||||
{
|
||||
return Visibility.Hidden;
|
||||
}
|
||||
if ((objValue && TriggerValue && !IsHidden) || (!objValue && !TriggerValue && !IsHidden))
|
||||
{
|
||||
return Visibility.Collapsed;
|
||||
}
|
||||
return Visibility.Visible;
|
||||
return Visibility.Collapsed;
|
||||
}
|
||||
|
||||
return Visibility.Visible;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,30 +3,29 @@ using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Daybreak.Converters
|
||||
namespace Daybreak.Converters;
|
||||
|
||||
public class HiddenWhenNull : IValueConverter
|
||||
{
|
||||
public class HiddenWhenNull : IValueConverter
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return GetVerticalAlignment(value);
|
||||
}
|
||||
return this.GetVerticalAlignment(value);
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private object GetVerticalAlignment(object value)
|
||||
private object GetVerticalAlignment(object value)
|
||||
{
|
||||
if (value is null)
|
||||
{
|
||||
if (value is null)
|
||||
{
|
||||
return Visibility.Hidden;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Visibility.Visible;
|
||||
}
|
||||
return Visibility.Hidden;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Visibility.Visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,24 @@
|
||||
using System;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Daybreak.Converters
|
||||
namespace Daybreak.Converters;
|
||||
|
||||
public class InverseBooleanConverter : IValueConverter
|
||||
{
|
||||
public class InverseBooleanConverter : IValueConverter
|
||||
public object Convert(object value, Type targetType, object parameter,
|
||||
System.Globalization.CultureInfo culture)
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter,
|
||||
System.Globalization.CultureInfo culture)
|
||||
if (targetType != typeof(bool))
|
||||
{
|
||||
if (targetType != typeof(bool))
|
||||
{
|
||||
throw new InvalidOperationException("The target must be a boolean");
|
||||
}
|
||||
|
||||
return !(bool)value;
|
||||
throw new InvalidOperationException("The target must be a boolean");
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter,
|
||||
System.Globalization.CultureInfo culture)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
return !(bool)value;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter,
|
||||
System.Globalization.CultureInfo culture)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Daybreak.Converters;
|
||||
|
||||
public class MenuButtonHighlightConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (targetType == typeof(double) &&
|
||||
value is bool boolean)
|
||||
{
|
||||
return boolean ? 0.4 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (targetType == typeof(bool) &&
|
||||
value is double doubleValue)
|
||||
{
|
||||
return doubleValue == 0.4;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,34 +2,33 @@
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Daybreak.Converters
|
||||
{
|
||||
public class TileButtonHighlightConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (targetType == typeof(double) &&
|
||||
value is bool boolean)
|
||||
{
|
||||
return boolean ? 1 : 0.4;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
namespace Daybreak.Converters;
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
public class TileButtonHighlightConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (targetType == typeof(double) &&
|
||||
value is bool boolean)
|
||||
{
|
||||
if (targetType == typeof(bool) &&
|
||||
value is double doubleValue)
|
||||
{
|
||||
return doubleValue == 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
return boolean ? 1 : 0.4;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (targetType == typeof(bool) &&
|
||||
value is double doubleValue)
|
||||
{
|
||||
return doubleValue == 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+66
-15
@@ -1,33 +1,65 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net5.0-windows</TargetFramework>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>Daybreak</RootNamespace>
|
||||
<!--Unable to migrate to .net 7 due to issues with font families not being found #140-->
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<UseWPF>true</UseWPF>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<Platforms>AnyCPU</Platforms>
|
||||
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
|
||||
<Platforms>AnyCPU;x86</Platforms>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<ApplicationIcon>Daybreak.ico</ApplicationIcon>
|
||||
<IncludePackageReferencesDuringMarkupCompilation>true</IncludePackageReferencesDuringMarkupCompilation>
|
||||
<Version>0.8.8</Version>
|
||||
<Version>0.9.8</Version>
|
||||
<EnableWindowsTargeting>true</EnableWindowsTargeting>
|
||||
<UserSecretsId>cfb2a489-db80-448d-a969-80270f314c46</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="HtmlAgilityPack" Version="1.11.32" />
|
||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.818.41" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<None Include="..\.editorconfig" Link=".editorconfig" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="AddUserSecrets" BeforeTargets="PrepareForBuild" Condition=" '$(UserSecretsId)' != '' ">
|
||||
<PropertyGroup>
|
||||
<UserSecretsFilePath Condition=" '$(OS)' == 'Windows_NT' ">
|
||||
$([System.Environment]::GetFolderPath(SpecialFolder.UserProfile))\AppData\Roaming\Microsoft\UserSecrets\$(UserSecretsId)\secrets.json
|
||||
</UserSecretsFilePath>
|
||||
<UserSecretsFilePath Condition=" '$(OS)' == 'Unix' ">
|
||||
$([System.Environment]::GetFolderPath(SpecialFolder.UserProfile))/.microsoft/usersecrets/$(UserSecretsId)/secrets.json
|
||||
</UserSecretsFilePath>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="$(UserSecretsFilePath)" Condition="Exists($(UserSecretsFilePath))" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="LiteDB" Version="5.0.15" />
|
||||
<PackageReference Include="Microsoft.CorrelationVector" Version="1.0.42" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.1587.40" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.39" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
|
||||
<PackageReference Include="securifybv.ShellLink" Version="0.1.0" />
|
||||
<PackageReference Include="Slim" Version="1.2.2" />
|
||||
<PackageReference Include="System.Windows.Interactivity.WPF" Version="2.0.20525" />
|
||||
<PackageReference Include="SystemExtensions.NetStandard" Version="1.1.4" />
|
||||
<PackageReference Include="Slim" Version="1.9.2" />
|
||||
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
|
||||
<PackageReference Include="SystemExtensions.NetCore" Version="1.0.1" />
|
||||
<PackageReference Include="SystemExtensions.NetStandard" Version="1.5.0" />
|
||||
<PackageReference Include="WCL" Version="1.0.2" />
|
||||
<PackageReference Include="WpfExtended" Version="0.2.1" />
|
||||
<PackageReference Include="WpfExtended" Version="0.7.1" />
|
||||
<PackageReference Include="WpfExtended.SourceGeneration" Version="0.1.1" />
|
||||
<PackageReference Include="WpfScreenHelper" Version="1.0.0" />
|
||||
<PackageReference Include="WpfScreenHelper" Version="2.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Controls\Buttons\SynchronizeButton.xaml.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Controls\Buttons\HelpButton.xaml.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
@@ -40,9 +72,16 @@
|
||||
<Compile Update="Controls\Buttons\CancelButton.xaml.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Views\IconDownloadView.xaml.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\Buttons\SynchronizeButton.xaml">
|
||||
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Update="Controls\Buttons\HelpButton.xaml">
|
||||
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
|
||||
<SubType>Designer</SubType>
|
||||
@@ -63,10 +102,22 @@
|
||||
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Update="Views\IconDownloadView.xaml">
|
||||
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Release'">
|
||||
<Exec Command="echo.>$(Version).version" />
|
||||
</Target>
|
||||
|
||||
<Target Name="RemoveDuplicateAnalyzers" BeforeTargets="CoreCompile">
|
||||
<!-- Work around https://github.com/dotnet/wpf/issues/6792 -->
|
||||
<ItemGroup>
|
||||
<FilteredAnalyzer Include="@(Analyzer->Distinct())" />
|
||||
<Analyzer Remove="@(Analyzer)" />
|
||||
<Analyzer Include="@(FilteredAnalyzer)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
</Project>
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Daybreak.Exceptions
|
||||
namespace Daybreak.Exceptions;
|
||||
|
||||
public sealed class CredentialsNotFoundException : Exception
|
||||
{
|
||||
public sealed class CredentialsNotFoundException : Exception
|
||||
public CredentialsNotFoundException()
|
||||
{
|
||||
public CredentialsNotFoundException()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public CredentialsNotFoundException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
public CredentialsNotFoundException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public CredentialsNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||
{
|
||||
}
|
||||
public CredentialsNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||
{
|
||||
}
|
||||
|
||||
public CredentialsNotFoundException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
public CredentialsNotFoundException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Daybreak.Exceptions
|
||||
namespace Daybreak.Exceptions;
|
||||
|
||||
public sealed class ExecutableNotFoundException : Exception
|
||||
{
|
||||
public sealed class ExecutableNotFoundException : Exception
|
||||
public ExecutableNotFoundException()
|
||||
{
|
||||
public ExecutableNotFoundException()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public ExecutableNotFoundException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
public ExecutableNotFoundException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public ExecutableNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||
{
|
||||
}
|
||||
public ExecutableNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||
{
|
||||
}
|
||||
|
||||
public ExecutableNotFoundException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
public ExecutableNotFoundException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Daybreak.Exceptions
|
||||
namespace Daybreak.Exceptions;
|
||||
|
||||
public sealed class FatalException : Exception
|
||||
{
|
||||
public sealed class FatalException : Exception
|
||||
public FatalException()
|
||||
{
|
||||
public FatalException()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public FatalException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
public FatalException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public FatalException(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||
{
|
||||
}
|
||||
public FatalException(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||
{
|
||||
}
|
||||
|
||||
public FatalException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
public FatalException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
+92
-62
@@ -1,88 +1,118 @@
|
||||
using Daybreak.Configuration;
|
||||
using Daybreak.Exceptions;
|
||||
using Daybreak.Services.ApplicationLifetime;
|
||||
using Daybreak.Services.Logging;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Daybreak.Utils;
|
||||
using Microsoft.Web.WebView2.Core;
|
||||
using Microsoft.Web.WebView2.Wpf;
|
||||
using Daybreak.Services.Navigation;
|
||||
using Daybreak.Services.Updater.PostUpdate;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Slim;
|
||||
using Slim.Integration.ServiceCollection;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Extensions;
|
||||
|
||||
namespace Daybreak.Launch
|
||||
namespace Daybreak.Launch;
|
||||
|
||||
public sealed class Launcher : ExtendedApplication<MainWindow>
|
||||
{
|
||||
public sealed class Launcher : ExtendedApplication<MainWindow>
|
||||
public readonly static Launcher Instance = new();
|
||||
|
||||
private ILogger? logger;
|
||||
|
||||
public System.IServiceProvider ApplicationServiceProvider => this.ServiceProvider;
|
||||
|
||||
[STAThread]
|
||||
public static int Main()
|
||||
{
|
||||
public static IServiceManager ApplicationServiceManager { get; private set; }
|
||||
private readonly static Launcher launcher = new();
|
||||
return LaunchMainWindow();
|
||||
}
|
||||
|
||||
[STAThread]
|
||||
public static int Main()
|
||||
protected override System.IServiceProvider SetupServiceProvider(IServiceCollection services)
|
||||
{
|
||||
var serviceManager = new ServiceManager();
|
||||
ProjectConfiguration.RegisterResolvers(serviceManager);
|
||||
return services.BuildSlimServiceProvider(serviceManager);
|
||||
}
|
||||
protected override void RegisterServices(IServiceCollection services)
|
||||
{
|
||||
ProjectConfiguration.RegisterServices(services);
|
||||
}
|
||||
protected override bool HandleException(Exception e)
|
||||
{
|
||||
if (e is null)
|
||||
{
|
||||
return LaunchMainWindow();
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override void RegisterServices(IServiceProducer serviceProducer)
|
||||
if (this.logger is null)
|
||||
{
|
||||
ProjectConfiguration.RegisterServices(this.ServiceManager);
|
||||
ProjectConfiguration.RegisterLifetimeServices(this.ServiceManager.GetService<IApplicationLifetimeManager>());
|
||||
ProjectConfiguration.RegisterViews(this.ServiceManager.GetService<IViewManager>());
|
||||
return false;
|
||||
}
|
||||
protected override bool HandleException(Exception e)
|
||||
|
||||
if (e is FatalException fatalException)
|
||||
{
|
||||
if (e is null)
|
||||
this.logger.LogCritical(e, $"{nameof(FatalException)} encountered. Closing application");
|
||||
MessageBox.Show(fatalException.ToString());
|
||||
File.WriteAllText("crash.log", e.ToString());
|
||||
return false;
|
||||
}
|
||||
else if (e is TargetInvocationException targetInvocationException && e.InnerException is FatalException innerFatalException)
|
||||
{
|
||||
this.logger.LogCritical(e, $"{nameof(FatalException)} encountered. Closing application");
|
||||
MessageBox.Show(innerFatalException.ToString());
|
||||
File.WriteAllText("crash.log", e.ToString());
|
||||
return false;
|
||||
}
|
||||
else if (e is AggregateException aggregateException)
|
||||
{
|
||||
if (aggregateException.InnerExceptions.FirstOrDefault() is COMException comException &&
|
||||
comException.Message.Contains("Invalid window handle"))
|
||||
{
|
||||
return false;
|
||||
/*
|
||||
* Ignore exception caused by browser failing to initialize due to missing window.
|
||||
* Likely caused by switching views before browser was initialized.
|
||||
*/
|
||||
this.logger.LogError(e, "Failed to initialize browser");
|
||||
return true;
|
||||
}
|
||||
|
||||
this.ServiceManager.GetService<ILogger>().LogCritical(e);
|
||||
if (e is FatalException fatalException)
|
||||
{
|
||||
MessageBox.Show(fatalException.ToString());
|
||||
return false;
|
||||
}
|
||||
else if (e is AggregateException aggregateException)
|
||||
{
|
||||
if (aggregateException.InnerExceptions.FirstOrDefault() is COMException comException &&
|
||||
comException.Message.Contains("Invalid window handle"))
|
||||
{
|
||||
/*
|
||||
* Ignore exception caused by browser failing to initialize due to missing window.
|
||||
* Likely caused by switching windows before browser was initialized.
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
MessageBox.Show(e.ToString());
|
||||
}
|
||||
else if (e.Message.Contains("Invalid window handle.") && e.StackTrace?.Contains("CoreWebView2Environment.CreateCoreWebView2ControllerAsync") is true)
|
||||
{
|
||||
/*
|
||||
* Ignore exception caused by browser failing to initialize due to missing window.
|
||||
* Likely caused by switching views before the browser was initialized.
|
||||
*/
|
||||
this.logger.LogError(e, "Failed to initialize browser");
|
||||
return true;
|
||||
}
|
||||
protected override void ApplicationStarting()
|
||||
{
|
||||
ApplicationServiceManager = this.ServiceManager;
|
||||
this.ServiceManager.GetService<IApplicationLifetimeManager>().OnStartup();
|
||||
this.RegisterViewContainer();
|
||||
}
|
||||
protected override void ApplicationClosing()
|
||||
{
|
||||
this.ServiceManager.GetService<IApplicationLifetimeManager>().OnClosing();
|
||||
}
|
||||
|
||||
private void RegisterViewContainer()
|
||||
{
|
||||
var viewManager = this.ServiceManager.GetService<IViewManager>();
|
||||
var mainWindow = this.ServiceManager.GetService<MainWindow>();
|
||||
viewManager.RegisterContainer(mainWindow.Container);
|
||||
}
|
||||
private static int LaunchMainWindow()
|
||||
{
|
||||
return launcher.Run();
|
||||
}
|
||||
this.logger.LogError(e, $"Unhandled exception caught {e.GetType()}");
|
||||
MessageBox.Show(e.ToString());
|
||||
return true;
|
||||
}
|
||||
protected override void ApplicationStarting()
|
||||
{
|
||||
ProjectConfiguration.RegisterViews(this.ServiceProvider.GetService<IViewManager>()!);
|
||||
ProjectConfiguration.RegisterPostUpdateActions(this.ServiceProvider.GetService<IPostUpdateActionProducer>()!);
|
||||
|
||||
this.logger = this.ServiceProvider.GetRequiredService<ILogger<Launcher>>();
|
||||
this.RegisterViewContainer();
|
||||
}
|
||||
protected override void ApplicationClosing()
|
||||
{
|
||||
}
|
||||
|
||||
private void RegisterViewContainer()
|
||||
{
|
||||
var viewManager = this.ServiceProvider.GetRequiredService<IViewManager>();
|
||||
var mainWindow = this.ServiceProvider.GetRequiredService<MainWindow>();
|
||||
viewManager.RegisterContainer(mainWindow.Container);
|
||||
}
|
||||
private static int LaunchMainWindow()
|
||||
{
|
||||
return Instance.Run();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
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:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Daybreak.Launch"
|
||||
xmlns:wcl="clr-namespace:WCL;assembly=WCL"
|
||||
mc:Ignorable="d"
|
||||
xmlns:controls="clr-namespace:Daybreak.Controls"
|
||||
xmlns:converters="clr-namespace:Daybreak.Converters"
|
||||
xmlns:effects="clr-namespace:System.Windows.Media.Extensions.Effects;assembly=WpfExtended"
|
||||
WindowStyle="None"
|
||||
ResizeMode="NoResize"
|
||||
@@ -24,14 +25,7 @@
|
||||
<ControlTemplate TargetType="{x:Type ToggleButton}">
|
||||
<Grid>
|
||||
<Rectangle x:Name="OverlayRect" Fill="{TemplateBinding Background}" Opacity="0"></Rectangle>
|
||||
<Viewbox Margin="5" Stretch="Uniform">
|
||||
<Grid>
|
||||
<Path Stroke="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"
|
||||
Data="m76.89,45.018c0,-1.587 -0.151,-3.138 -0.383,-4.66l11.227,-6.48l-11.639,-20.136l-11.616,6.47c-2.421,-1.931 -5.479,-3.506 -8.479,-4.664l0,-11.548l-22,0l0,11.548c-4,1.112 -5.649,2.617 -8.005,4.448l-11.251,-6.604l-11.914,20.006l11.12,6.604c-0.262,1.643 -0.45,3.308 -0.45,5.016c0,1.587 0.153,3.136 0.376,4.658l-11.228,6.484l11.634,20.135l11.424,-6.472c2.431,1.933 4.294,3.506 8.294,4.665l0,12.512l22,0l0,-12.512c3,-1.115 5.839,-2.618 8.19,-4.449l11.348,6.604l11.96,-20.006l-11.095,-6.603c0.258,-1.64 0.487,-3.304 0.487,-5.016zm-31.704,14.137c-7.799,0 -14.138,-6.332 -14.138,-14.138c0,-7.808 6.339,-14.136 14.138,-14.136c7.81,0 14.14,6.328 14.14,14.136c-0.001,7.806 -6.331,14.138 -14.14,14.138z"></Path>
|
||||
<Path Fill="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"
|
||||
Data="m56.5,89l-22,0c-1.381,0 -2.5,-1.119 -2.5,-2.5l0,-10.199c-2.612,-0.955 -4.464,-2.126 -6.274,-3.49l-10.229,5.671c-1.192,0.661 -2.694,0.244 -3.377,-0.936l-11.633,-20.135c-0.331,-0.574 -0.422,-1.257 -0.25,-1.897s0.591,-1.188 1.165,-1.519l9.794,-5.654c-0.121,-1.164 -0.181,-2.262 -0.181,-3.323c0,-1.317 0.112,-2.592 0.254,-3.721l-9.656,-5.75c-0.57,-0.34 -0.982,-0.893 -1.145,-1.537c-0.163,-0.644 -0.063,-1.326 0.279,-1.896l11.977,-20.006c0.702,-1.173 2.218,-1.564 3.399,-0.878l9.927,5.762c1.618,-1.213 3.362,-2.346 5.949,-3.273l0,-10.219c0.001,-1.381 1.12,-2.5 2.501,-2.5l22,0c1.381,0 2.5,1.119 2.5,2.5l0,10.377c2.124,0.938 4.104,2.059 5.919,3.35l9.939,-5.657c1.19,-0.677 2.713,-0.269 3.4,0.922l11.639,20.135c0.332,0.574 0.423,1.257 0.251,1.897s-0.591,1.188 -1.165,1.519l-9.781,5.646c0.126,1.165 0.188,2.266 0.188,3.329c0,1.327 -0.108,2.597 -0.246,3.717l9.692,5.752c0.571,0.339 0.983,0.891 1.147,1.533c0.163,0.644 0.065,1.325 -0.274,1.896l-11.897,20.005c-0.703,1.183 -2.234,1.573 -3.416,0.876l-9.798,-5.765c-1.782,1.25 -3.634,2.29 -5.598,3.144l0,10.324c0,1.381 -1.119,2.5 -2.5,2.5zm-19.5,-5l17,0l0,-9.512c0,-1.045 0.649,-1.979 1.629,-2.344c2.624,-0.975 5.004,-2.309 7.275,-4.078c0.809,-0.629 1.921,-0.702 2.804,-0.182l9.078,5.341l9.347,-15.716l-8.974,-5.325c-0.88,-0.522 -1.354,-1.528 -1.194,-2.538c0.198,-1.259 0.425,-2.923 0.425,-4.629c0,-1.314 -0.116,-2.716 -0.354,-4.284c-0.154,-1.018 0.33,-2.026 1.222,-2.541l9.061,-5.23l-9.145,-15.818l-9.208,5.241c-0.888,0.505 -1.995,0.42 -2.795,-0.219c-2.199,-1.754 -4.747,-3.196 -7.57,-4.286c-0.964,-0.372 -1.6,-1.299 -1.6,-2.332l0,-9.548l-17.001,0l0,9.548c0,1.123 -0.748,2.107 -1.83,2.408c-3.47,0.965 -5.073,2.212 -7.293,3.938l-0.098,0.076c-0.804,0.625 -1.909,0.7 -2.789,0.188l-9.243,-5.365l-9.423,15.739l8.937,5.321c0.879,0.524 1.351,1.531 1.189,2.542c-0.202,1.27 -0.435,2.943 -0.435,4.622c0,1.318 0.112,2.724 0.342,4.297c0.148,1.013 -0.337,2.015 -1.224,2.526l-9.065,5.234l9.151,15.842l9.525,-5.28c0.883,-0.49 1.976,-0.4 2.768,0.229c2.384,1.896 4.207,3.214 7.684,4.221c1.069,0.31 1.804,1.29 1.804,2.402l0,9.512zm8.186,-22.345c-9.174,0 -16.638,-7.464 -16.638,-16.638c0,-9.173 7.464,-16.636 16.638,-16.636c9.175,0 16.64,7.463 16.64,16.636c-0.001,9.174 -7.466,16.638 -16.64,16.638zm0,-28.273c-6.417,0 -11.638,5.22 -11.638,11.636c0,6.417 5.221,11.638 11.638,11.638c6.418,0 11.64,-5.221 11.64,-11.638c-0.001,-6.416 -5.222,-11.636 -11.64,-11.636z"></Path>
|
||||
</Grid>
|
||||
</Viewbox>
|
||||
<controls:ThreeDotsGlyph Margin="13"></controls:ThreeDotsGlyph>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<MultiTrigger>
|
||||
@@ -62,42 +56,98 @@
|
||||
<RowDefinition Height="30"></RowDefinition>
|
||||
<RowDefinition Height="*"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<Border BorderBrush="Transparent" BorderThickness="0" Grid.RowSpan="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border BorderBrush="Transparent" BorderThickness="0" Grid.RowSpan="2" Grid.ColumnSpan="2">
|
||||
<Border.Effect>
|
||||
<BlurEffect Radius="5" KernelType="Gaussian" RenderingBias="Performance"></BlurEffect>
|
||||
</Border.Effect>
|
||||
<controls:ImageViewer x:Name="ImageViewer">
|
||||
<controls:ImageViewer x:Name="ImageViewer"
|
||||
MouseDown="TitleBar_MouseLeftButtonDown">
|
||||
<controls:ImageViewer.Effect>
|
||||
<effects:LightStreak Attenuation="0.4" BrightThreshold="0.9"></effects:LightStreak>
|
||||
</controls:ImageViewer.Effect>
|
||||
</controls:ImageViewer>
|
||||
</Border>
|
||||
<wcl:TitleBar x:Name="Titlebar"
|
||||
Grid.ColumnSpan="2"
|
||||
Background="Transparent" MouseLeftButtonDown="TitleBar_MouseLeftButtonDown"
|
||||
WindowState="Normal" MinimizeButtonClicked="TitleBar_MinimizeButtonClicked"
|
||||
MaximizeButtonClicked="TitleBar_MaximizeButtonClicked"
|
||||
RestoreButtonClicked="TitleBar_RestoreButtonClicked"
|
||||
CloseButtonClicked="TitleBar_CloseButtonClicked"
|
||||
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"></wcl:TitleBar>
|
||||
<ToggleButton Style="{StaticResource Window_SettingsButton}" Width="50" Height="30" HorizontalAlignment="Right"
|
||||
Margin="0, 0, 150, 0" Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Click="SettingsButton_Clicked"></ToggleButton>
|
||||
<controls:OpaqueButton Grid.Row="1" Background="Transparent" BorderBrush="Transparent" BorderThickness="0" Opacity="0.6"
|
||||
Text="{Binding ElementName=_this, Path=CreditText, Mode=OneWay}" VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Right" Margin="0, 0, 20, 30" FontSize="22" Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
<controls:OpaqueButton Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Background="Transparent"
|
||||
BorderBrush="Transparent"
|
||||
BorderThickness="0"
|
||||
Opacity="0.6"
|
||||
Text="{Binding ElementName=_this, Path=CreditText, Mode=OneWay}"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Right"
|
||||
Margin="0, 0, 20, 30"
|
||||
FontSize="22"
|
||||
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Clicked="CreditTextBox_MouseLeftButtonDown" Cursor="Hand"></controls:OpaqueButton>
|
||||
<WrapPanel Grid.Row="1" Margin="0, 0, 20, 10" VerticalAlignment="Bottom" HorizontalAlignment="Right">
|
||||
<TextBox Grid.Row="1" Background="Transparent" BorderBrush="Transparent" BorderThickness="0" Opacity="0.6"
|
||||
Text="{Binding ElementName=_this, Path=CurrentVersionText, Mode=OneWay}" IsReadOnly="True" FontSize="10"
|
||||
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"></TextBox>
|
||||
<TextBox Grid.Row="1" Background="Transparent" Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
<WrapPanel Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Margin="0, 0, 20, 10"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Right">
|
||||
<controls:OpaqueButton Grid.Row="1" Background="Transparent" BorderBrush="Transparent" BorderThickness="0" Opacity="0.6"
|
||||
Text="{Binding ElementName=_this, Path=CurrentVersionText, Mode=OneWay}" FontSize="10"
|
||||
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Clicked="VersionText_Clicked"></controls:OpaqueButton>
|
||||
<controls:OpaqueButton Grid.Row="1" Background="Transparent" Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Opacity="0.6" Text=" - " FontSize="10" BorderBrush="Transparent" BorderThickness="0"
|
||||
Visibility="{Binding ElementName=_this, Path=IsRunningAsAdmin, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}"></TextBox>
|
||||
<TextBox Grid.Row="1" Background="Transparent" Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Visibility="{Binding ElementName=_this, Path=IsRunningAsAdmin, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}"
|
||||
Clicked="VersionText_Clicked"></controls:OpaqueButton>
|
||||
<controls:OpaqueButton Grid.Row="1" Background="Transparent" Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Opacity="0.6" Text="[Admin]" FontSize="10" BorderBrush="Transparent" BorderThickness="0"
|
||||
Visibility="{Binding ElementName=_this, Path=IsRunningAsAdmin, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}"></TextBox>
|
||||
Visibility="{Binding ElementName=_this, Path=IsRunningAsAdmin, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}"
|
||||
Clicked="VersionText_Clicked"></controls:OpaqueButton>
|
||||
</WrapPanel>
|
||||
<Grid x:Name="Container" Grid.Row="1">
|
||||
<Grid x:Name="Container"
|
||||
Grid.Column="1"
|
||||
Grid.Row="1"/>
|
||||
<Grid x:Name="MenuContainer"
|
||||
Width="0"
|
||||
Grid.RowSpan="2"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Left"
|
||||
Background="#A0202020">
|
||||
<controls:MenuList Margin="0, 30, 0, 0"/>
|
||||
</Grid>
|
||||
<wcl:Border OnResize="Border_OnResize" Grid.RowSpan="2" Active="True"></wcl:Border>
|
||||
<ToggleButton x:Name="OpeningSettingsButton"
|
||||
Style="{StaticResource Window_SettingsButton}"
|
||||
Width="50"
|
||||
Height="30"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="0, 0, 0, 0"
|
||||
Grid.ColumnSpan="2"
|
||||
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
|
||||
Click="SettingsButton_Clicked"></ToggleButton>
|
||||
<ToggleButton x:Name="ClosingSettingsButton"
|
||||
Style="{StaticResource Window_SettingsButton}"
|
||||
Width="50"
|
||||
Height="30"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="0, 0, 0, 0"
|
||||
Grid.ColumnSpan="2"
|
||||
Foreground="White"
|
||||
Visibility="{Binding ElementName=_this, Path=IsShowingDropdown, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}"
|
||||
Click="SettingsButton_Clicked"></ToggleButton>
|
||||
<wcl:Border OnResize="Border_OnResize" Grid.RowSpan="2" Grid.ColumnSpan="2" Active="True"></wcl:Border>
|
||||
<controls:ChromiumBrowserWrapper x:Name="BackgroundWebView"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"
|
||||
Visibility="Visible"
|
||||
ControlsEnabled="False"
|
||||
CanNavigate="False"
|
||||
CanDownloadBuild="False"
|
||||
Grid.Row="1"></controls:ChromiumBrowserWrapper>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
+270
-162
@@ -1,217 +1,325 @@
|
||||
using Daybreak.Services.Bloogum;
|
||||
using Daybreak.Configuration;
|
||||
using Daybreak.Services.Bloogum;
|
||||
using Daybreak.Services.IconRetrieve;
|
||||
using Daybreak.Services.Menu;
|
||||
using Daybreak.Services.Navigation;
|
||||
using Daybreak.Services.Privilege;
|
||||
using Daybreak.Services.Runtime;
|
||||
using Daybreak.Services.Screenshots;
|
||||
using Daybreak.Services.Updater;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Daybreak.Utils;
|
||||
using Daybreak.Views;
|
||||
using Pepa.Wpf.Utilities;
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Core.Extensions;
|
||||
using System.Diagnostics;
|
||||
using System.Extensions;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Extensions;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace Daybreak.Launch
|
||||
namespace Daybreak.Launch;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for MainWindow.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 MainWindow : Window
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for MainWindow.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 MainWindow : Window
|
||||
private readonly IMenuServiceInitializer menuServiceInitializer;
|
||||
private readonly IViewManager viewManager;
|
||||
private readonly IScreenshotProvider screenshotProvider;
|
||||
private readonly IBloogumClient bloogumClient;
|
||||
private readonly IApplicationUpdater applicationUpdater;
|
||||
private readonly IPrivilegeManager privilegeManager;
|
||||
private readonly IIconDownloader iconDownloader;
|
||||
private readonly ILiveOptions<ApplicationConfiguration> liveOptions;
|
||||
private readonly CancellationTokenSource cancellationToken = new();
|
||||
|
||||
[GenerateDependencyProperty]
|
||||
private string creditText = string.Empty;
|
||||
[GenerateDependencyProperty]
|
||||
private string currentVersionText = string.Empty;
|
||||
[GenerateDependencyProperty]
|
||||
private bool isRunningAsAdmin;
|
||||
[GenerateDependencyProperty]
|
||||
private bool isShowingDropdown;
|
||||
|
||||
public MainWindow(
|
||||
IMenuServiceInitializer menuServiceInitializer,
|
||||
IViewManager viewManager,
|
||||
IScreenshotProvider screenshotProvider,
|
||||
IBloogumClient bloogumClient,
|
||||
IApplicationUpdater applicationUpdater,
|
||||
IPrivilegeManager privilegeManager,
|
||||
IIconDownloader iconDownloader,
|
||||
ILiveOptions<ApplicationConfiguration> liveOptions)
|
||||
{
|
||||
private readonly IViewManager viewManager;
|
||||
private readonly IScreenshotProvider screenshotProvider;
|
||||
private readonly IBloogumClient bloogumClient;
|
||||
private readonly IApplicationUpdater applicationUpdater;
|
||||
private readonly IPrivilegeManager privilegeManager;
|
||||
private readonly CancellationTokenSource cancellationToken = new();
|
||||
this.menuServiceInitializer = menuServiceInitializer.ThrowIfNull();
|
||||
this.viewManager = viewManager.ThrowIfNull();
|
||||
this.screenshotProvider = screenshotProvider.ThrowIfNull();
|
||||
this.bloogumClient = bloogumClient.ThrowIfNull();
|
||||
this.applicationUpdater = applicationUpdater.ThrowIfNull();
|
||||
this.privilegeManager = privilegeManager.ThrowIfNull();
|
||||
this.iconDownloader = iconDownloader.ThrowIfNull();
|
||||
this.liveOptions = liveOptions.ThrowIfNull();
|
||||
this.InitializeComponent();
|
||||
this.CurrentVersionText = this.applicationUpdater.CurrentVersion.ToString();
|
||||
this.IsRunningAsAdmin = this.privilegeManager.AdminPrivileges;
|
||||
this.SetupMenuService();
|
||||
}
|
||||
|
||||
[GenerateDependencyProperty]
|
||||
private string creditText;
|
||||
[GenerateDependencyProperty]
|
||||
private string currentVersionText;
|
||||
[GenerateDependencyProperty]
|
||||
private bool isRunningAsAdmin;
|
||||
|
||||
public MainWindow(
|
||||
IViewManager viewManager,
|
||||
IScreenshotProvider screenshotProvider,
|
||||
IBloogumClient bloogumClient,
|
||||
IApplicationUpdater applicationUpdater,
|
||||
IPrivilegeManager privilegeManager)
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.SetupImageCycle();
|
||||
this.CheckForUpdates();
|
||||
this.SetupBackgroundBrowser();
|
||||
}
|
||||
|
||||
private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton is not MouseButton.Left &&
|
||||
e.LeftButton is not MouseButtonState.Pressed)
|
||||
{
|
||||
this.viewManager = viewManager.ThrowIfNull(nameof(viewManager));
|
||||
this.screenshotProvider = screenshotProvider.ThrowIfNull(nameof(screenshotProvider));
|
||||
this.bloogumClient = bloogumClient.ThrowIfNull(nameof(bloogumClient));
|
||||
this.applicationUpdater = applicationUpdater.ThrowIfNull(nameof(applicationUpdater));
|
||||
this.privilegeManager = privilegeManager.ThrowIfNull(nameof(privilegeManager));
|
||||
this.InitializeComponent();
|
||||
this.CurrentVersionText = this.applicationUpdater.CurrentVersion;
|
||||
this.IsRunningAsAdmin = this.privilegeManager.AdminPrivileges;
|
||||
return;
|
||||
}
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.SetupImageCycle();
|
||||
this.CheckForUpdates();
|
||||
}
|
||||
this.DragMove();
|
||||
}
|
||||
|
||||
private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
this.DragMove();
|
||||
}
|
||||
private void TitleBar_MinimizeButtonClicked(object sender, EventArgs e)
|
||||
{
|
||||
this.WindowState = WindowState.Minimized;
|
||||
this.Titlebar.WindowState = WindowState.Minimized;
|
||||
}
|
||||
|
||||
private void TitleBar_MinimizeButtonClicked(object sender, EventArgs e)
|
||||
{
|
||||
this.WindowState = WindowState.Minimized;
|
||||
this.Titlebar.WindowState = WindowState.Minimized;
|
||||
}
|
||||
private void TitleBar_MaximizeButtonClicked(object sender, EventArgs e)
|
||||
{
|
||||
this.WindowState = WindowState.Maximized;
|
||||
this.Titlebar.WindowState = WindowState.Maximized;
|
||||
}
|
||||
|
||||
private void TitleBar_MaximizeButtonClicked(object sender, EventArgs e)
|
||||
{
|
||||
this.WindowState = WindowState.Maximized;
|
||||
this.Titlebar.WindowState = WindowState.Maximized;
|
||||
}
|
||||
private void TitleBar_RestoreButtonClicked(object sender, EventArgs e)
|
||||
{
|
||||
this.WindowState = WindowState.Normal;
|
||||
this.Titlebar.WindowState = WindowState.Normal;
|
||||
}
|
||||
|
||||
private void TitleBar_RestoreButtonClicked(object sender, EventArgs e)
|
||||
{
|
||||
this.WindowState = WindowState.Normal;
|
||||
this.Titlebar.WindowState = WindowState.Normal;
|
||||
}
|
||||
private void TitleBar_CloseButtonClicked(object sender, EventArgs e)
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
|
||||
private void TitleBar_CloseButtonClicked(object sender, EventArgs e)
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
private void Border_OnResize(object sender, WCL.Border.ResizeDirection e)
|
||||
{
|
||||
NativeMethods.SendMessage(new WindowInteropHelper(this).Handle, NativeMethods.WM_SYSCOMMAND, (IntPtr)e, IntPtr.Zero);
|
||||
}
|
||||
|
||||
private void Border_OnResize(object sender, WCL.Border.ResizeDirection e)
|
||||
{
|
||||
NativeMethods.SendMessage(new WindowInteropHelper(this).Handle, NativeMethods.WM_SYSCOMMAND, (IntPtr)e, IntPtr.Zero);
|
||||
}
|
||||
private void SetupBackgroundBrowser()
|
||||
{
|
||||
this.iconDownloader.SetBrowser(this.BackgroundWebView);
|
||||
}
|
||||
|
||||
private void SetupImageCycle()
|
||||
{
|
||||
TaskExtensions.RunPeriodicAsync(() => this.Dispatcher.Invoke(() => this.UpdateRandomImage()), TimeSpan.Zero, TimeSpan.FromSeconds(15), this.cancellationToken.Token);
|
||||
}
|
||||
private void SetupImageCycle()
|
||||
{
|
||||
TaskExtensions.RunPeriodicAsync(() => this.Dispatcher.Invoke(() => this.UpdateRandomImage()), TimeSpan.Zero, TimeSpan.FromSeconds(15), this.cancellationToken.Token);
|
||||
}
|
||||
|
||||
private void UpdateRandomImage()
|
||||
{
|
||||
var maybeImage = this.screenshotProvider.GetRandomScreenShot();
|
||||
maybeImage.Do(
|
||||
onSome: (image) =>
|
||||
{
|
||||
this.SetImage(image);
|
||||
this.CreditText = string.Empty;
|
||||
},
|
||||
onNone: async () =>
|
||||
{
|
||||
var maybeImageStream = await this.bloogumClient.GetRandomScreenShot().ConfigureAwait(true);
|
||||
maybeImageStream.DoAny(
|
||||
onSome: (stream) =>
|
||||
{
|
||||
var bitmapImage = new BitmapImage();
|
||||
bitmapImage.BeginInit();
|
||||
bitmapImage.StreamSource = stream;
|
||||
bitmapImage.EndInit();
|
||||
this.SetImage(bitmapImage);
|
||||
this.CreditText = "http://bloogum.net/guildwars";
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void SettingsButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<SettingsCategoryView>();
|
||||
}
|
||||
|
||||
private void CreditTextBox_MouseLeftButtonDown(object sender, EventArgs e)
|
||||
{
|
||||
if (Uri.TryCreate(this.CreditText, UriKind.Absolute, out var uri))
|
||||
private void UpdateRandomImage()
|
||||
{
|
||||
var maybeImage = this.screenshotProvider.GetRandomScreenShot();
|
||||
maybeImage.Do(
|
||||
onSome: (image) =>
|
||||
{
|
||||
Process.Start("explorer.exe", uri.ToString());
|
||||
}
|
||||
this.SetImage(image);
|
||||
this.CreditText = string.Empty;
|
||||
},
|
||||
onNone: async () =>
|
||||
{
|
||||
var maybeImageStream = await this.bloogumClient.GetRandomScreenShot().ConfigureAwait(true);
|
||||
maybeImageStream.DoAny(
|
||||
onSome: (stream) =>
|
||||
{
|
||||
var bitmapImage = new BitmapImage();
|
||||
bitmapImage.BeginInit();
|
||||
bitmapImage.StreamSource = stream;
|
||||
bitmapImage.EndInit();
|
||||
this.SetImage(bitmapImage);
|
||||
this.CreditText = "http://bloogum.net/guildwars";
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void SettingsButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.ToggleDropdownMenu();
|
||||
}
|
||||
|
||||
private void OpenDropdownMenu()
|
||||
{
|
||||
if (this.IsShowingDropdown)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
private void SetImage(ImageSource imageSource)
|
||||
this.ToggleDropdownMenu();
|
||||
}
|
||||
|
||||
private void CloseDropdownMenu()
|
||||
{
|
||||
if (!this.IsShowingDropdown)
|
||||
{
|
||||
this.ImageViewer.ShowImage(imageSource);
|
||||
if (imageSource is BitmapImage bitmapImage)
|
||||
{
|
||||
var avgColor = GetAverageColor(bitmapImage);
|
||||
var luminace = GetLuminace(avgColor);
|
||||
if (luminace < 0.15)
|
||||
{
|
||||
this.Foreground = Brushes.White;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Foreground = Brushes.Black;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
private async void CheckForUpdates()
|
||||
this.ToggleDropdownMenu();
|
||||
}
|
||||
|
||||
private void ToggleDropdownMenu()
|
||||
{
|
||||
var button = this.IsShowingDropdown ?
|
||||
this.ClosingSettingsButton :
|
||||
this.OpeningSettingsButton;
|
||||
button.IsEnabled = false;
|
||||
var widthAnimation = new DoubleAnimation
|
||||
{
|
||||
var updateAvailable = await this.applicationUpdater.UpdateAvailable().ConfigureAwait(true);
|
||||
if (updateAvailable)
|
||||
From = this.IsShowingDropdown ?
|
||||
this.MenuContainer.ActualWidth :
|
||||
0,
|
||||
To = this.IsShowingDropdown ?
|
||||
0 :
|
||||
300,
|
||||
Duration = new Duration(TimeSpan.FromMilliseconds(200)),
|
||||
DecelerationRatio = 0.7
|
||||
};
|
||||
|
||||
var opacityAnimation = new DoubleAnimation
|
||||
{
|
||||
From = this.IsShowingDropdown ?
|
||||
this.MenuContainer.Opacity :
|
||||
0,
|
||||
To = this.IsShowingDropdown ?
|
||||
0 :
|
||||
1,
|
||||
Duration = new Duration(TimeSpan.FromMilliseconds(100)),
|
||||
DecelerationRatio = 0.7
|
||||
};
|
||||
|
||||
var storyBoard = new Storyboard();
|
||||
storyBoard.Children.Add(widthAnimation);
|
||||
Storyboard.SetTarget(widthAnimation, this.MenuContainer);
|
||||
Storyboard.SetTargetProperty(widthAnimation, new PropertyPath(Grid.WidthProperty));
|
||||
storyBoard.Children.Add(opacityAnimation);
|
||||
Storyboard.SetTarget(opacityAnimation, this.MenuContainer);
|
||||
Storyboard.SetTargetProperty(opacityAnimation, new PropertyPath(Grid.OpacityProperty));
|
||||
|
||||
storyBoard.Completed += (_, _) =>
|
||||
{
|
||||
button.IsEnabled = true;
|
||||
this.IsShowingDropdown = !this.IsShowingDropdown;
|
||||
};
|
||||
|
||||
storyBoard.Begin();
|
||||
}
|
||||
|
||||
private void CreditTextBox_MouseLeftButtonDown(object sender, EventArgs e)
|
||||
{
|
||||
if (Uri.TryCreate(this.CreditText, UriKind.Absolute, out var uri))
|
||||
{
|
||||
Process.Start("explorer.exe", uri.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private void VersionText_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<VersionManagementView>();
|
||||
}
|
||||
|
||||
private void SetImage(ImageSource imageSource)
|
||||
{
|
||||
this.ImageViewer.ShowImage(imageSource);
|
||||
if (imageSource is BitmapImage bitmapImage)
|
||||
{
|
||||
var avgColor = GetAverageColor(bitmapImage);
|
||||
var luminace = GetLuminace(avgColor);
|
||||
if (luminace < 0.15)
|
||||
{
|
||||
this.viewManager.ShowView<AskUpdateView>();
|
||||
this.Foreground = Brushes.White;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.viewManager.ShowView<MainView>();
|
||||
this.PeriodicallyCheckForUpdates();
|
||||
this.Foreground = Brushes.Black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void PeriodicallyCheckForUpdates()
|
||||
private async void CheckForUpdates()
|
||||
{
|
||||
var updateAvailable = this.liveOptions.Value.AutoCheckUpdate is true && await this.applicationUpdater.UpdateAvailable().ConfigureAwait(true);
|
||||
if (updateAvailable)
|
||||
{
|
||||
this.applicationUpdater.PeriodicallyCheckForUpdates();
|
||||
this.viewManager.ShowView<AskUpdateView>();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.viewManager.ShowView<LauncherView>();
|
||||
this.PeriodicallyCheckForUpdates();
|
||||
}
|
||||
}
|
||||
|
||||
private static Color GetAverageColor(BitmapSource bitmap)
|
||||
{
|
||||
var format = bitmap.Format;
|
||||
if (format != PixelFormats.Bgr24 &&
|
||||
format != PixelFormats.Bgr32 &&
|
||||
format != PixelFormats.Bgra32 &&
|
||||
format != PixelFormats.Pbgra32)
|
||||
{
|
||||
throw new InvalidOperationException("BitmapSource must have Bgr24, Bgr32, Bgra32 or Pbgra32 format");
|
||||
}
|
||||
private void PeriodicallyCheckForUpdates()
|
||||
{
|
||||
this.applicationUpdater.PeriodicallyCheckForUpdates();
|
||||
}
|
||||
|
||||
var width = bitmap.PixelWidth;
|
||||
var height = bitmap.PixelHeight;
|
||||
var numPixels = width * height;
|
||||
var bytesPerPixel = format.BitsPerPixel / 8;
|
||||
var pixelBuffer = new byte[numPixels * bytesPerPixel];
|
||||
bitmap.CopyPixels(pixelBuffer, width * bytesPerPixel, 0);
|
||||
long blue = 0;
|
||||
long green = 0;
|
||||
long red = 0;
|
||||
for (int i = 0; i < pixelBuffer.Length; i += bytesPerPixel)
|
||||
{
|
||||
blue += pixelBuffer[i];
|
||||
green += pixelBuffer[i + 1];
|
||||
red += pixelBuffer[i + 2];
|
||||
}
|
||||
private void SetupMenuService()
|
||||
{
|
||||
this.menuServiceInitializer.InitializeMenuService(this.OpenDropdownMenu, this.CloseDropdownMenu, this.ToggleDropdownMenu);
|
||||
}
|
||||
|
||||
return Color.FromRgb((byte)(red / numPixels), (byte)(green / numPixels), (byte)(blue / numPixels));
|
||||
private static Color GetAverageColor(BitmapSource bitmap)
|
||||
{
|
||||
var format = bitmap.Format;
|
||||
if (format != PixelFormats.Bgr24 &&
|
||||
format != PixelFormats.Bgr32 &&
|
||||
format != PixelFormats.Bgra32 &&
|
||||
format != PixelFormats.Pbgra32)
|
||||
{
|
||||
throw new InvalidOperationException("BitmapSource must have Bgr24, Bgr32, Bgra32 or Pbgra32 format");
|
||||
}
|
||||
|
||||
private static double GetLuminace(Color color)
|
||||
var width = bitmap.PixelWidth;
|
||||
var height = bitmap.PixelHeight;
|
||||
var numPixels = width * height;
|
||||
var bytesPerPixel = format.BitsPerPixel / 8;
|
||||
var pixelBuffer = new byte[numPixels * bytesPerPixel];
|
||||
bitmap.CopyPixels(pixelBuffer, width * bytesPerPixel, 0);
|
||||
long blue = 0;
|
||||
long green = 0;
|
||||
long red = 0;
|
||||
for (int i = 0; i < pixelBuffer.Length; i += bytesPerPixel)
|
||||
{
|
||||
double R = color.ScR;
|
||||
double G = color.ScG;
|
||||
double B = color.ScB;
|
||||
return 0.299 * R + 0.587 * G + 0.114 * B;
|
||||
blue += pixelBuffer[i];
|
||||
green += pixelBuffer[i + 1];
|
||||
red += pixelBuffer[i + 2];
|
||||
}
|
||||
|
||||
return Color.FromRgb((byte)(red / numPixels), (byte)(green / numPixels), (byte)(blue / numPixels));
|
||||
}
|
||||
|
||||
private static double GetLuminace(Color color)
|
||||
{
|
||||
double R = color.ScR;
|
||||
double G = color.ScG;
|
||||
double B = color.ScB;
|
||||
return 0.299 * R + 0.587 * G + 0.114 * B;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace Daybreak.Models.Browser
|
||||
namespace Daybreak.Models.Browser;
|
||||
|
||||
public class BrowserPayload
|
||||
{
|
||||
public class BrowserPayload
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public enum PayloadKeys
|
||||
{
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public enum PayloadKeys
|
||||
{
|
||||
ContextMenu
|
||||
}
|
||||
|
||||
[JsonProperty("Key")]
|
||||
public PayloadKeys Key { get; set; }
|
||||
None,
|
||||
ContextMenu
|
||||
}
|
||||
|
||||
public sealed class BrowserPayload<T> : BrowserPayload
|
||||
{
|
||||
[JsonProperty("Value")]
|
||||
public T Value { get; set; }
|
||||
}
|
||||
[JsonProperty("Key")]
|
||||
public PayloadKeys Key { get; set; }
|
||||
}
|
||||
|
||||
public sealed class BrowserPayload<T> : BrowserPayload
|
||||
{
|
||||
[JsonProperty("Value")]
|
||||
public T? Value { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Daybreak.Models.Browser
|
||||
namespace Daybreak.Models.Browser;
|
||||
|
||||
public sealed class OnContextMenuPayload
|
||||
{
|
||||
public sealed class OnContextMenuPayload
|
||||
{
|
||||
[JsonProperty("X")]
|
||||
public double X { get; set; }
|
||||
[JsonProperty("Y")]
|
||||
public double Y { get; set; }
|
||||
[JsonProperty("Selection")]
|
||||
public string Selection { get; set; }
|
||||
}
|
||||
[JsonProperty("X")]
|
||||
public double X { get; set; }
|
||||
[JsonProperty("Y")]
|
||||
public double Y { get; set; }
|
||||
[JsonProperty("Selection")]
|
||||
public string? Selection { get; set; }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
using Daybreak.Models.Builds;
|
||||
|
||||
namespace Daybreak.Models;
|
||||
|
||||
public sealed class BuildWithTemplateCode
|
||||
{
|
||||
public BuildEntry? Build { get; set; }
|
||||
public string? TemplateCode { get; set; }
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Daybreak.Models.Builds
|
||||
{
|
||||
public sealed class Attribute
|
||||
{
|
||||
public static Attribute FastCasting { get; } = new() { Name = "Fast Casting", Id = 0 };
|
||||
public static Attribute IllusionMagic { get; } = new() { Name = "Illusion Magic", Id = 1 };
|
||||
public static Attribute DominationMagic { get; } = new() { Name = "Domination Magic", Id = 2 };
|
||||
public static Attribute InspirationMagic { get; } = new() { Name = "Inspiration Magic", Id = 3 };
|
||||
public static Attribute BloodMagic { get; } = new() { Name = "Blood Magic", Id = 4 };
|
||||
public static Attribute DeathMagic { get; } = new() { Name = "Death Magic", Id = 5 };
|
||||
public static Attribute SoulReaping { get; } = new() { Name = "Soul Reaping", Id = 6 };
|
||||
public static Attribute Curses { get; } = new() { Name = "Curses", Id = 7 };
|
||||
public static Attribute AirMagic { get; } = new() { Name = "Air Magic", Id = 8 };
|
||||
public static Attribute EarthMagic { get; } = new() { Name = "Earth Magic", Id = 9 };
|
||||
public static Attribute FireMagic { get; } = new() { Name = "Fire Magic", Id = 10 };
|
||||
public static Attribute WaterMagic { get; } = new() { Name = "Water Magic", Id = 11 };
|
||||
public static Attribute EnergyStorage { get; } = new() { Name = "Energy Storage", Id = 12 };
|
||||
public static Attribute HealingPrayers { get; } = new() { Name = "Healing Prayers", Id = 13 };
|
||||
public static Attribute SmitingPrayers { get; } = new() { Name = "Smiting Prayers", Id = 14 };
|
||||
public static Attribute ProtectionPrayers { get; } = new() { Name = "Protection Prayers", Id = 15 };
|
||||
public static Attribute DivineFavor { get; } = new() { Name = "Divine Favor", Id = 16 };
|
||||
public static Attribute Strength { get; } = new() { Name = "Strength", Id = 17 };
|
||||
public static Attribute AxeMastery { get; } = new() { Name = "Axe Mastery", Id = 18 };
|
||||
public static Attribute HammerMastery { get; } = new() { Name = "Hammer Mastery", Id = 19 };
|
||||
public static Attribute Swordsmanship { get; } = new() { Name = "Swordsmanship", Id = 20};
|
||||
public static Attribute Tactics { get; } = new() { Name = "Tactics", Id = 21 };
|
||||
public static Attribute BeastMastery { get; } = new() { Name = "Beast Mastery", Id = 22 };
|
||||
public static Attribute Expertise { get; } = new() { Name = "Expertise", Id = 23 };
|
||||
public static Attribute WildernessSurvival { get; } = new() { Name = "Wilderness Survival", Id = 24 };
|
||||
public static Attribute Marksmanship { get; } = new() { Name = "Marksmanship", Id = 25 };
|
||||
public static Attribute DaggerMastery { get; } = new() { Name = "Dagger Mastery", Id = 29 };
|
||||
public static Attribute DeadlyArts { get; } = new() { Name = "Deadly Arts", Id = 30 };
|
||||
public static Attribute ShadowArts { get; } = new() { Name = "Shadow Arts", Id = 31 };
|
||||
public static Attribute Communing { get; } = new() { Name = "Communing", Id = 32 };
|
||||
public static Attribute RestorationMagic { get; } = new() { Name = "Restoration Magic", Id = 33 };
|
||||
public static Attribute ChannelingMagic { get; } = new() { Name = "Channeling Magic", Id = 34 };
|
||||
public static Attribute CriticalStrikes { get; } = new() { Name = "Critical Strikes", Id = 35 };
|
||||
public static Attribute SpawningPower { get; } = new() { Name = "Spawning Power", Id = 36 };
|
||||
public static Attribute SpearMastery { get; } = new() { Name = "Spear Mastery", Id = 37 };
|
||||
public static Attribute Command { get; } = new() { Name = "Command", Id = 38 };
|
||||
public static Attribute Motivation { get; } = new() { Name = "Motivation", Id = 39 };
|
||||
public static Attribute Leadership { get; } = new() { Name = "Leadership", Id = 40 };
|
||||
public static Attribute ScytheMastery { get; } = new() { Name = "Scythe Mastery", Id = 41 };
|
||||
public static Attribute WindPrayers { get; } = new() { Name = "Wind Prayers", Id = 42 };
|
||||
public static Attribute EarthPrayers { get; } = new() { Name = "Earth Prayers", Id = 43 };
|
||||
public static Attribute Mysticism { get; } = new() { Name = "Mysticism", Id = 44 };
|
||||
public static IEnumerable<Attribute> Attributes { get; } = new List<Attribute>
|
||||
{
|
||||
FastCasting,
|
||||
IllusionMagic,
|
||||
DominationMagic,
|
||||
InspirationMagic,
|
||||
BloodMagic,
|
||||
DeathMagic,
|
||||
SoulReaping,
|
||||
Curses,
|
||||
AirMagic,
|
||||
EarthMagic,
|
||||
FireMagic,
|
||||
WaterMagic,
|
||||
EnergyStorage,
|
||||
HealingPrayers,
|
||||
SmitingPrayers,
|
||||
ProtectionPrayers,
|
||||
DivineFavor,
|
||||
Strength,
|
||||
AxeMastery,
|
||||
HammerMastery,
|
||||
Swordsmanship,
|
||||
Tactics,
|
||||
BeastMastery,
|
||||
Expertise,
|
||||
WildernessSurvival,
|
||||
Marksmanship,
|
||||
DaggerMastery,
|
||||
DeadlyArts,
|
||||
ShadowArts,
|
||||
Communing,
|
||||
RestorationMagic,
|
||||
ChannelingMagic,
|
||||
CriticalStrikes,
|
||||
SpawningPower,
|
||||
SpearMastery,
|
||||
Command,
|
||||
Motivation,
|
||||
Leadership,
|
||||
ScytheMastery,
|
||||
EarthPrayers,
|
||||
WindPrayers,
|
||||
EarthMagic,
|
||||
Mysticism
|
||||
};
|
||||
|
||||
public static bool TryParse(int id, out Attribute attribute)
|
||||
{
|
||||
attribute = Attributes.Where(attr => attr.Id == id).FirstOrDefault();
|
||||
if (attribute is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
public static bool TryParse(string name, out Attribute attribute)
|
||||
{
|
||||
attribute = Attributes.Where(attr => attr.Name == name).FirstOrDefault();
|
||||
if (attribute is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
public static Attribute Parse(int id)
|
||||
{
|
||||
if (TryParse(id, out var attribute) is false)
|
||||
{
|
||||
throw new InvalidOperationException($"Could not find an attribute with id {id}");
|
||||
}
|
||||
|
||||
return attribute;
|
||||
}
|
||||
public static Attribute Parse(string name)
|
||||
{
|
||||
if (TryParse(name, out var attribute) is false)
|
||||
{
|
||||
throw new InvalidOperationException($"Could not find an attribute with name {name}");
|
||||
}
|
||||
|
||||
return attribute;
|
||||
}
|
||||
|
||||
public int Id { get; private set; }
|
||||
public string Name { get; private set; }
|
||||
private Attribute()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +1,31 @@
|
||||
using System.ComponentModel;
|
||||
using Daybreak.Models.Guildwars;
|
||||
|
||||
namespace Daybreak.Models.Builds
|
||||
namespace Daybreak.Models.Builds;
|
||||
|
||||
public sealed class AttributeEntry : INotifyPropertyChanged
|
||||
{
|
||||
public sealed class AttributeEntry : INotifyPropertyChanged
|
||||
private Attribute? attribute;
|
||||
private int points;
|
||||
|
||||
public Attribute? Attribute
|
||||
{
|
||||
private Attribute attribute;
|
||||
private int points;
|
||||
|
||||
public Attribute Attribute
|
||||
get => this.attribute;
|
||||
set
|
||||
{
|
||||
get => this.attribute;
|
||||
set
|
||||
{
|
||||
this.attribute = value;
|
||||
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Attribute)));
|
||||
}
|
||||
this.attribute = value;
|
||||
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Attribute)));
|
||||
}
|
||||
public int Points
|
||||
{
|
||||
get => this.points;
|
||||
set
|
||||
{
|
||||
this.points = value;
|
||||
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Points)));
|
||||
}
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
}
|
||||
public int Points
|
||||
{
|
||||
get => this.points;
|
||||
set
|
||||
{
|
||||
this.points = value;
|
||||
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Points)));
|
||||
}
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Daybreak.Models.Builds
|
||||
{
|
||||
public sealed class Build
|
||||
{
|
||||
public BuildMetadata BuildMetadata { get; set; }
|
||||
public Profession Primary { get; set; } = Profession.None;
|
||||
public Profession Secondary { get; set; } = Profession.None;
|
||||
public List<AttributeEntry> Attributes { get; set; } = new();
|
||||
public List<Skill> Skills { get; set; } = new() { Skill.NoSkill, Skill.NoSkill, Skill.NoSkill, Skill.NoSkill, Skill.NoSkill, Skill.NoSkill, Skill.NoSkill, Skill.NoSkill };
|
||||
}
|
||||
}
|
||||
@@ -1,31 +1,31 @@
|
||||
using System.ComponentModel;
|
||||
using Daybreak.Models.Guildwars;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Daybreak.Models.Builds
|
||||
namespace Daybreak.Models.Builds;
|
||||
|
||||
public sealed class BuildEntry : INotifyPropertyChanged
|
||||
{
|
||||
public sealed class BuildEntry : INotifyPropertyChanged
|
||||
{
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
private string name;
|
||||
private Build build;
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
private string? name;
|
||||
private Build? build;
|
||||
|
||||
public string PreviousName { get; set; }
|
||||
public string Name
|
||||
public string? PreviousName { get; set; }
|
||||
public string? Name
|
||||
{
|
||||
get => this.name;
|
||||
set
|
||||
{
|
||||
get => this.name;
|
||||
set
|
||||
{
|
||||
this.name = value;
|
||||
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
|
||||
}
|
||||
this.name = value;
|
||||
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Name)));
|
||||
}
|
||||
public Build Build
|
||||
}
|
||||
public Build? Build
|
||||
{
|
||||
get => this.build;
|
||||
set
|
||||
{
|
||||
get => this.build;
|
||||
set
|
||||
{
|
||||
this.build = value;
|
||||
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Build)));
|
||||
}
|
||||
this.build = value;
|
||||
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Build)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Daybreak.Models.Builds
|
||||
{
|
||||
public sealed class BuildMetadata
|
||||
{
|
||||
public List<int> Base64Decoded { get; set; }
|
||||
public List<string> BinaryDecoded { get; set; }
|
||||
public int Header { get; set; }
|
||||
public int VersionNumber { get; set; }
|
||||
public int ProfessionIdLength { get; set; }
|
||||
public int PrimaryProfessionId { get; set; }
|
||||
public int SecondaryProfessionId { get; set; }
|
||||
public int AttributeCount { get; set; }
|
||||
public int AttributesLength { get; set; }
|
||||
public int SkillsLength { get; set; }
|
||||
public bool TailPresent { get; set; }
|
||||
public bool NewTemplate { get; set; }
|
||||
public List<int> SkillIds { get; set; } = new();
|
||||
public List<int> AttributesIds { get; set; } = new();
|
||||
public List<int> AttributePoints { get; set; } = new();
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Daybreak.Models.Builds
|
||||
{
|
||||
public sealed class Profession
|
||||
{
|
||||
public static Profession None { get; } = new() { Name = "None", Id = 0, };
|
||||
public static Profession Warrior { get; } = new() { Name = "Warrior", Id = 1, PrimaryAttribute = Attribute.Strength, Attributes = new List<Attribute> { Attribute.AxeMastery, Attribute.HammerMastery, Attribute.Swordsmanship, Attribute.Tactics } };
|
||||
public static Profession Ranger { get; } = new() { Name = "Ranger", Id = 2, PrimaryAttribute = Attribute.Expertise, Attributes = new List<Attribute> { Attribute.BeastMastery, Attribute.Marksmanship, Attribute.WildernessSurvival } };
|
||||
public static Profession Monk { get; } = new() { Name = "Monk", Id = 3, PrimaryAttribute = Attribute.DivineFavor, Attributes = new List<Attribute> { Attribute.HealingPrayers, Attribute.SmitingPrayers, Attribute.ProtectionPrayers } };
|
||||
public static Profession Necromancer { get; } = new() { Name = "Necromancer", Id = 4, PrimaryAttribute = Attribute.SoulReaping, Attributes = new List<Attribute> { Attribute.Curses, Attribute.BloodMagic, Attribute.DeathMagic } };
|
||||
public static Profession Mesmer { get; } = new() { Name = "Mesmer", Id = 5, PrimaryAttribute = Attribute.FastCasting, Attributes = new List<Attribute> { Attribute.DominationMagic, Attribute.IllusionMagic, Attribute.InspirationMagic } };
|
||||
public static Profession Elementalist { get; } = new() { Name = "Elementalist", Id = 6, PrimaryAttribute = Attribute.EnergyStorage, Attributes = new List<Attribute> { Attribute.AirMagic, Attribute.EarthMagic, Attribute.FireMagic, Attribute.WaterMagic } };
|
||||
public static Profession Assassin { get; } = new() { Name = "Assassin", Id = 7, PrimaryAttribute = Attribute.CriticalStrikes, Attributes = new List<Attribute> { Attribute.DaggerMastery, Attribute.DeadlyArts, Attribute.ShadowArts } };
|
||||
public static Profession Ritualist { get; } = new() { Name = "Ritualist", Id = 8, PrimaryAttribute = Attribute.SpawningPower, Attributes = new List<Attribute> { Attribute.ChannelingMagic, Attribute.Communing, Attribute.RestorationMagic } };
|
||||
public static Profession Paragon { get; } = new() { Name = "Paragon", Id = 9, PrimaryAttribute = Attribute.Leadership, Attributes = new List<Attribute> { Attribute.Command, Attribute.Motivation, Attribute.SpearMastery } };
|
||||
public static Profession Dervish { get; } = new() { Name = "Dervish", Id = 10, PrimaryAttribute = Attribute.Mysticism, Attributes = new List<Attribute> { Attribute.EarthPrayers, Attribute.ScytheMastery, Attribute.WindPrayers } };
|
||||
public static IEnumerable<Profession> Professions { get; } = new List<Profession>
|
||||
{
|
||||
None,
|
||||
Warrior,
|
||||
Ranger,
|
||||
Monk,
|
||||
Necromancer,
|
||||
Mesmer,
|
||||
Elementalist,
|
||||
Assassin,
|
||||
Ritualist,
|
||||
Paragon,
|
||||
Dervish
|
||||
};
|
||||
public static bool TryParse(int id, out Profession profession)
|
||||
{
|
||||
profession = Professions.Where(prof => prof.Id == id).FirstOrDefault();
|
||||
if (profession is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
public static bool TryParse(string name, out Profession profession)
|
||||
{
|
||||
profession = Professions.Where(prof => prof.Name == name).FirstOrDefault();
|
||||
if (profession is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
public static Profession Parse(int id)
|
||||
{
|
||||
if (TryParse(id, out var profession) is false)
|
||||
{
|
||||
throw new InvalidOperationException($"Could not find a profession with id {id}");
|
||||
}
|
||||
|
||||
return profession;
|
||||
}
|
||||
public static Profession Parse(string name)
|
||||
{
|
||||
if (TryParse(name, out var profession) is false)
|
||||
{
|
||||
throw new InvalidOperationException($"Could not find a profession with name {name}");
|
||||
}
|
||||
|
||||
return profession;
|
||||
}
|
||||
|
||||
public string Name { get; private set; }
|
||||
public int Id { get; set; }
|
||||
public Attribute PrimaryAttribute { get; private set; }
|
||||
public List<Attribute> Attributes { get; private set; }
|
||||
private Profession()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user