Compare commits

...
158 Commits
Author SHA1 Message Date
amacocianandGitHub 320dd16838 Show objective direction for loaded quests (#194) 2023-04-02 19:22:17 +00:00
amacocianandGitHub 5c05c636bc Add quest marker functionality to the minimap (#192) 2023-04-02 14:57:49 +00:00
amacocianandGitHub 7103a8a83a Show party member context (#190)
Fix one Map id
2023-03-25 18:30:29 +00:00
amacocianandGitHub ad749d801a Minimap improvements (#189)
Closes #187
Closes #188

Minimap performance improvements
Add context menues for main player and living entities
2023-03-25 08:36:15 +00:00
amacocianandGitHub 747e9a0490 Minimap improvements (#186)
Closes #185
Closes #184
Closes #183
Show player information when right clicking on minimap
Allow minimap fullscreen
Decouple scrolling from memory reading frequency
Ignore task cancelled exceptions
2023-03-24 22:39:52 +00:00
amacocianandGitHub 836402bd0f Draw player position history on the minimap (#182) 2023-03-21 15:19:25 +00:00
amacocianandGitHub a3d5e1ce1f Add another check for corrupted images (#181)
* Add another check for corrupted images

* Check validity of icons on startup
Improve screen position saving
2023-03-21 08:45:22 +00:00
f2cc59a4ab Daybreak 0.9.8.18 (#179)
* Minimap implementation

* Fix minimap

* Add debounce logic to entities positions

* Cleanup

* Fix x64 build memory reading
Move build to x64
Fix entity debouncing
Added some backstops to prevent reading corrupted memory

* Add minimap zooming and panning functionality
Add main window position saving procedure

* Increment version

---------

Co-authored-by: Alex Macocian <amacocian@hotmail.com>
2023-03-20 21:38:53 +02:00
amacocianandGitHub 6ea77f7e05 Bugfixes and improvements (#176)
Closes #175
Closes #174
Closes #173
2023-03-09 19:53:28 +00:00
amacocianandGitHub 5ea8df7cb9 Bugfixes to memory reader (#172) 2023-03-08 20:17:58 +00:00
amacocianandGitHub c70e8ec90d Implement Guildwars downloader (#171) 2023-03-08 13:24:14 +00:00
amacocianandGitHub 210e3a8cb1 Add title data to memory retrieval (#169)
Add metrics for diagnostics
Add metrics view
2023-03-07 17:20:20 +00:00
amacocianandGitHub a0c3bb094c Performance improvements (#168)
* Performance improvements and bugfixes

* Increment version

* Better builds links

* Unify loading widget size
2023-03-05 08:55:21 +01:00
amacocianandGitHub b4d932692a Reduce words in FocusView character line (#167) 2023-03-04 17:18:03 +00:00
amacocianandGitHub 667534a07a Fix version parsing (#166) 2023-03-04 18:06:53 +01:00
amacocianandGitHub 159928f24b Integrate builds with Focus view (#164)
* Integrate builds with Focus view
Detect when GameData is invalid
Detect when reading memory is faulty
Show current character data in Focus View
Closes #161
Closes #162
Closes #163

* Increment version

* Bugfix version comparison script
2023-03-04 17:21:08 +01:00
amacocianandGitHub 8a91ded610 Fix buildtemplate skill removal (#160)
Closes #159
2023-03-03 22:28:27 +00:00
amacocianandGitHub 4226b7eb32 Improve performance of buildtemplateview (#158) 2023-03-03 21:50:25 +00:00
amacocianandGitHub b61c99dd1c Fix build template failing to load secondary attributes (#157)
Improve build template handling logic
Add attribute points calculator
2023-03-03 20:51:03 +00:00
amacocianandGitHub 1ccb0d5334 Add map entry to FocusView (#155)
Fix Icon Downloader
Improve settings navigation
Change multiple views to match the design of the rest of the application
2023-03-02 20:11:00 +01:00
amacocianandGitHub 7fa01353dd UX Bugfixes and improvements (#151)
Fix memory reading issues when restarting the game
Fixed current energy and health retrieval and calculation
Added health and energy bars in focus view
Fixed focus view size calculation
Improved buildtemplate performance
Improved buildtemplate navigation
Added loading widgets to menus that are loading asynchronously
2023-03-02 16:49:00 +00:00
amacocianandGitHub 4f849d880b Ux improvements (#148)
Rearrange quest log layout
Fix some quest names
Fix some buttons ux
Mitigate issues when reading guildwars memory
2023-03-02 01:58:07 +00:00
amacocianandGitHub 4b60c96aad Closes #146 #145 (#147) 2023-03-02 00:39:52 +00:00
amacocianandGitHub a4dc0d65cf Implement Focus View (#144)
* Implement Focus View
Read extra information from guildwars

* Prever focusview browser from being disposed
2023-03-01 18:42:53 +00:00
amacocianandGitHub 85e017423f #142 - Fix Vanguard Quests Missing (#143)
Closes #142
2023-02-28 18:24:37 +00:00
amacocianandGitHub b38488937b Alexmacocian/gwca integration (#141)
Setup memory scanner
Setup Focus View
Scan for player information and show in the Focus View
Setup Quest parsing
2023-02-27 17:22:04 +01:00
amacocianandGitHub d291d5825a #125 - Setup onboarding flow (#133)
* #125 - Setup onboarding flow
Closes #125

* Fix MenuService logging
2023-02-03 15:27:06 +00:00
amacocianandGitHub 9d6162f65f #131 - Downgrade to .net6 (#132) 2023-02-02 20:50:35 +00:00
amacocianandGitHub f54ab42a92 #129 - Change hashing algorithm to SHA512 (#130) 2023-02-02 18:31:07 +00:00
amacocianandGitHub 78c8ae3e8f #127 - Introduce Nullable Support (#128) 2023-02-02 18:05:10 +00:00
amacocianandGitHub c64830c5b6 #123 #113 #105 Build Templates Improvements (#124) 2023-01-21 21:35:16 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
561c7cf7b1 Bump microsoft/setup-msbuild from 1.0.1 to 1.1.3 (#111)
Bumps [microsoft/setup-msbuild](https://github.com/microsoft/setup-msbuild) from 1.0.1 to 1.1.3.
- [Release notes](https://github.com/microsoft/setup-msbuild/releases)
- [Changelog](https://github.com/microsoft/setup-msbuild/blob/master/building-release.md)
- [Commits](https://github.com/microsoft/setup-msbuild/compare/v1.0.1...v1.1.3)

---
updated-dependencies:
- dependency-name: microsoft/setup-msbuild
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-09 15:22:44 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2c6862de41 Bump coverlet.collector from 3.1.2 to 3.2.0 (#112)
Bumps [coverlet.collector](https://github.com/coverlet-coverage/coverlet) from 3.1.2 to 3.2.0.
- [Release notes](https://github.com/coverlet-coverage/coverlet/releases)
- [Commits](https://github.com/coverlet-coverage/coverlet/commits/v3.2.0)

---
updated-dependencies:
- dependency-name: coverlet.collector
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-09 15:10:18 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
69842cbadf Bump Microsoft.NET.Test.Sdk from 17.4.0-preview-20221003-03 to 17.4.0 (#116)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.4.0-preview-20221003-03 to 17.4.0.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Commits](https://github.com/microsoft/vstest/compare/v17.4.0-preview-20221003-03...v17.4.0)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-09 14:24:26 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
c7327e7bb2 Bump Microsoft.NET.Test.Sdk (#108)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.4.0-preview-20220726-02 to 17.4.0-preview-20221003-03.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Commits](https://github.com/microsoft/vstest/compare/v17.4.0-preview-20220726-02...v17.4.0-preview-20221003-03)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 10:18:44 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
de33ed7fc4 Bump actions/setup-dotnet from 2 to 3 (#107)
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 2 to 3.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](https://github.com/actions/setup-dotnet/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/setup-dotnet
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 10:09:29 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>amacocian
c99bb8d074 Bump Microsoft.Web.WebView2 from 1.0.1343.22 to 1.0.1370.28 (#109)
* Bump Microsoft.Web.WebView2 from 1.0.1343.22 to 1.0.1370.28

Bumps Microsoft.Web.WebView2 from 1.0.1343.22 to 1.0.1370.28.

---
updated-dependencies:
- dependency-name: Microsoft.Web.WebView2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Update daybreak version

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Alexandru Macocian <amacocian@yahoo.com>
2022-10-11 10:02:33 +00:00
amacocianandGitHub a98e54ebc6 Sync namespaces (#104) 2022-09-23 09:56:47 +00:00
amacocianandGitHub a832aa1925 Minor fixes (#102) 2022-09-21 13:55:37 +00:00
amacocianandGitHub c7eb5debcb Refresh access token (#100) 2022-09-20 11:46:36 +00:00
amacocianandGitHub 91f0cb4e31 Implement expandable menu view (#95) 2022-09-19 19:08:34 +00:00
amacocianandGitHub 5e8407a6ab Make main view maintain its state (#94)
* Make main view maintain its state

* Stop checking game state when mainview is not loaded
2022-09-15 17:05:30 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>amacocian
243c2c1536 Bump Microsoft.Extensions.Logging.Abstractions from 6.0.1 to 6.0.2 (#91)
* Bump Microsoft.Extensions.Logging.Abstractions from 6.0.1 to 6.0.2

Bumps [Microsoft.Extensions.Logging.Abstractions](https://github.com/dotnet/runtime) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/dotnet/runtime/releases)
- [Commits](https://github.com/dotnet/runtime/compare/v6.0.1...v6.0.2)

---
updated-dependencies:
- dependency-name: Microsoft.Extensions.Logging.Abstractions
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump version

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Alexandru Macocian <amacocian@yahoo.com>
2022-09-15 14:34:21 +00:00
amacocianandGitHub 930aca4ffe Bump dependencies (#90)
Signed-off-by: Macocian Alexandru Victor <amacocian@yahoo.com>
2022-09-12 18:11:36 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
1639cabe8e Bump Slim from 1.7.3 to 1.8.1 (#86)
Bumps [Slim](https://github.com/AlexMacocian/Slim) from 1.7.3 to 1.8.1.
- [Release notes](https://github.com/AlexMacocian/Slim/releases)
- [Commits](https://github.com/AlexMacocian/Slim/commits)

---
updated-dependencies:
- dependency-name: Slim
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-07 08:38:17 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
5961a57c5b Bump Microsoft.Web.WebView2 from 1.0.1293.44 to 1.0.1343.22 (#85)
Bumps Microsoft.Web.WebView2 from 1.0.1293.44 to 1.0.1343.22.

---
updated-dependencies:
- dependency-name: Microsoft.Web.WebView2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-07 10:29:18 +02:00
amacocianandGitHub 75d9bc6dec Add checkmark when builds are synchronized (#84) 2022-08-27 12:54:48 +00:00
amacocianandGitHub 4ccca32881 Build synchronization speedups (#82) 2022-08-27 12:15:21 +00:00
amacocianandGitHub a7f5d9dd96 Fix deletion error when installing (#80)
Signed-off-by: Macocian Alexandru Victor <amacocian@yahoo.com>
2022-08-25 20:55:01 +00:00
amacocianandGitHub c8ba125abc Allow individual uploads/downloads for backed up builds (#77) 2022-08-25 20:44:20 +00:00
amacocianandGitHub 7d290031f1 Alexmacocian/fix secret build (#76)
* Fix pre-build secret building action

* Update version
2022-08-22 22:10:18 +00:00
amacocianandGitHub 5220a8c7ac Run fixed CD pipeline (#75) 2022-08-22 21:31:58 +00:00
amacocianandGitHub 33e221f60f Fix secret generation for CD pipeline (#74) 2022-08-22 21:05:13 +00:00
amacocianandGitHub 7f77547c50 Add support for build backups (#73) 2022-08-22 20:30:10 +00:00
amacocianandGitHub c5964e33ac Setup support for secrets (#72) 2022-08-22 12:55:29 +00:00
amacocianandGitHub 1c6f3ec797 Make all browsers use BrowserData folder (#70)
* Make all browsers use BrowserData folder

* Increment version
2022-08-21 14:09:26 +00:00
amacocianandGitHub 8601f61739 Run CD pipeline only on code changes (#67) 2022-08-20 15:24:45 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
91bac0d50b Bump actions/setup-dotnet from 1 to 2 (#64)
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 1 to 2.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](https://github.com/actions/setup-dotnet/compare/v1...v2)

---
updated-dependencies:
- dependency-name: actions/setup-dotnet
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-20 15:22:41 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
0bf03e0fb5 Bump Xotl/cool-github-releases from 1.1.2 to 1.1.7 (#65)
Bumps [Xotl/cool-github-releases](https://github.com/Xotl/cool-github-releases) from 1.1.2 to 1.1.7.
- [Release notes](https://github.com/Xotl/cool-github-releases/releases)
- [Commits](https://github.com/Xotl/cool-github-releases/compare/v1.1.2...v1.1.7)

---
updated-dependencies:
- dependency-name: Xotl/cool-github-releases
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-20 15:22:24 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>amacocian
81401178a5 Bump Microsoft.Web.WebView2 from 1.0.1264.42 to 1.0.1293.44 (#66)
* Bump Microsoft.Web.WebView2 from 1.0.1264.42 to 1.0.1293.44

Bumps Microsoft.Web.WebView2 from 1.0.1264.42 to 1.0.1293.44.

---
updated-dependencies:
- dependency-name: Microsoft.Web.WebView2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump Microsoft.Web.WebView2 from 1.0.1264.42 to 1.0.1293.44

Bumps Microsoft.Web.WebView2 from 1.0.1264.42 to 1.0.1293.44.

---
updated-dependencies:
- dependency-name: Microsoft.Web.WebView2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Increment version

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Alexandru Macocian <amacocian@yahoo.com>
2022-08-20 15:19:17 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
882357a8e5 Bump Microsoft.NET.Test.Sdk (#63)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.4.0-preview-20220707-01 to 17.4.0-preview-20220726-02.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Commits](https://github.com/microsoft/vstest/compare/v17.4.0-preview-20220707-01...v17.4.0-preview-20220726-02)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-20 13:18:22 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
abf629c5c6 Bump actions/checkout from 2 to 3 (#62)
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-20 13:10:53 +00:00
amacocianandGitHub 758f9004cd Setup code owners (#61)
* Setup code owners

* Install .net6 on codeql pipeline

* Fix csproj

* Make version check only work when changing code files
2022-08-20 15:03:35 +02:00
amacocianandGitHub f174f8cbb3 Create dependabot.yml
Signed-off-by: Macocian Alexandru Victor <amacocian@yahoo.com>
2022-08-20 14:42:07 +02:00
amacocianandGitHub f2f6bde25d Create codeql-analysis.yml
Signed-off-by: Macocian Alexandru Victor <amacocian@yahoo.com>
2022-08-20 14:37:59 +02:00
amacocianandGitHub 85f378b303 Improve performance across builds and skills menus (#59)
Make buildtemplate load builds asynchronously
Make buildtemplateview load skills asynchronously
Improve search experience by making string matching be done asynchronously
Reduce memory footprint by virtualizing long skill list
2022-08-20 12:30:11 +00:00
amacocianandGitHub 71ab3fdefb Post-update actions (#57) 2022-08-19 12:45:07 +00:00
amacocianandGitHub 2f83d6c860 Delete browser cache on update (#56) 2022-08-18 20:17:36 +00:00
amacocianandGitHub 3db4975b48 Make launcher update the installer after an update (#55) 2022-08-18 19:59:08 +00:00
amacocianandGitHub 6a6eea5d02 Implement search bar for builds and skills (#50)
* Add search bars to builds and skills

* Fix search bar not appearing.
Improve search function.

* Increment version

* Rename version check so it can be added to status checks
2022-08-18 21:26:57 +02:00
amacocianandGitHub 8fe9eeb32f Icon downloader bugfixes (#47)
* Fix icon download to properly finish
2022-08-16 19:47:25 +02:00
amacocianandGitHub 4c1025243b Background Icon Downloader (#44)
* Download icons in the background

* Fix icon downloader browser setup
2022-08-16 17:51:35 +02:00
amacocianandGitHub f24eb02ca1 Pipeline to check that version is updated (#43)
* Pipeline to check that version is updated
2022-08-13 00:24:54 +02:00
amacocianandGitHub b01c09491f Download and check icons at startup (#41) 2022-08-12 23:41:22 +02:00
amacocianandGitHub 54ae742899 Increment version (#40) 2022-08-12 13:22:59 +02:00
amacocianandGitHub 4c862463d7 Fix IconRetriever (#38)
Use browser to bypass header issues with http client
2022-08-12 13:15:46 +02:00
amacocianandGitHub b455c89ddc Minor improvements (#36)
Deprecate Microsoft.Xaml.Behaviors.Wpf
Reverse version order in management view
2022-08-04 23:05:55 +02:00
amacocianandGitHub 782b76cd8e Remove admin mode when updating (#31) 2022-08-04 21:59:55 +02:00
amacocianandGitHub 230c2d9457 Setup executable installer (#29)
* Setup executable installer

* Increment update to 0.9.3

* Improve installer
2022-08-04 21:39:17 +02:00
amacocianandGitHub 63531e3b8c Hide console window (#25) 2022-08-04 19:52:54 +02:00
amacocianandGitHub ac430305f4 Update to .net 6 and update dependencies (#24)
* Update to .net 6 and update dependencies
2022-08-04 19:25:53 +02:00
amacocianandGitHub 3d830cfc16 Update dependencies (#23) 2021-07-10 13:39:00 +03:00
amacocianandGitHub b529aa8861 Fix logging on startup when ILogger is null (#22) 2021-07-10 12:45:44 +03:00
amacocianandGitHub 3798daa54e Update dependencies (#21)
* Update dependencies
* Minor nit fixes
* Fix UTs
2021-07-10 12:08:43 +03:00
amacocianandGitHub 624380ed86 Use IOptions instead of IConfigurationManager (#20)
* Use IOptions instead of dependency on IConfigurationManager
2021-06-22 15:48:37 +03:00
amacocianandGitHub 2b025e225b Updated wpfextended dependency 2021-06-11 13:50:58 +02:00
amacocianandGitHub 15a67ea28c Minor fixes
Stop showing browser when browser is disabled
Prevent setting address of browser when browser is disabled (should prevent browser from instantiating when disabled)
Ignore errors from browser caused by switching view before the browser could be initialized
Provide expression to filter logs
Button to export logs to json file
2021-06-07 14:33:54 +02:00
amacocianandGitHub c6b62fd5fd Logging improvements
Log uncaught exceptions
Logview expander
2021-06-07 00:34:43 +02:00
amacocianandGitHub 3c0877c1a0 Ability to keep a local cache of icons (#16) 2021-06-03 21:12:31 +02:00
967b57b9a8 Fix build code encoding/decoding view (#15)
Co-authored-by: Alexandru Macocian <almacoci@microsoft.com>
2021-06-03 20:40:56 +02:00
amacocianandGitHub f47cc319b5 Build template code field 2021-06-03 19:57:29 +02:00
amacocianandGitHub 26da84c4e7 Update to new version of wpfextended
Fix a bug where version parsing would ignore all 0s before the first digit
Remove LoggerFactory and LoggerProviders duplicated in WpfExtended
2021-06-03 14:48:35 +02:00
a39e8dc5c6 Separate CV from message (#12)
Co-authored-by: Alexandru Macocian <almacoci@microsoft.com>
2021-06-01 21:57:27 +02:00
1bb4669135 Introduce correlated logs (#11)
Co-authored-by: Alexandru Macocian <almacoci@microsoft.com>
2021-06-01 20:43:55 +02:00
amacocianandGitHub 0203eef006 Rework logging (#10)
* Rework log storing into a litedb.
LogView implementation to view logs.
Create crash.log on crash.

* Rename Logs namespace to Logging.
2021-05-18 19:49:51 +02:00
amacocianandGitHub 4ab50ee191 Use Microsoft.Logging.Abstractions
Typed ILogger.
2021-05-14 14:31:33 +02:00
amacocianandGitHub 06c1ec1ac2 Add scoped http client. (#8)
* Introduce scoped http client.
* Uts for scoped httpclient
2021-05-10 12:46:01 +02:00
amacocianandGitHub ef4befdc38 Version management view.
Enable/disable version autocheck.
Version management view.
2021-05-06 18:23:07 +02:00
amacocianandGitHub 33f49ddffa Cleanup cd pipeline (#6)
* Cleanup cd pipeline

* Remove cd pipeline on PR

* Cleanup CI pipeline comments.
2021-05-06 12:33:58 +02:00
amacocianandGitHub 49aa249b5b Generate changelog from last release tag.
Generate changelog from last release tag.
2021-05-05 23:01:57 +02:00
amacocianandGitHub c387d44890 Generate changelog from latest release.
Auto-generate changelog.
2021-05-05 21:31:45 +02:00
d4d09e7267 Update version (#3)
Co-authored-by: Alexandru Macocian <almacoci@microsoft.com>
2021-05-05 20:52:43 +02:00
amacocianandGitHub dd7bf02a97 Add CI & CD pipelines
Add CD&CI pipelines
2021-05-05 20:46:36 +02:00
Alexandru Macocian 6d0eeb478f Use source generator to generate dependency properties. 2021-05-05 17:23:37 +02:00
d4e9de48b1 Add ci pipeline (#1)
* Add ci pipeline

* Remove unused env variables.

* Change dotnet version to 5.0.5

* Change to dotnet 5.0.202

Co-authored-by: Alexandru Macocian <almacoci@microsoft.com>
2021-05-03 17:11:59 +02:00
Alexandru Macocian 6bd9877925 Remove dependency on InputSimulator. 2021-05-03 16:23:30 +02:00
Alexandru Macocian d38df6596f Remove keyboard macro functionality for now.
Unify input prompts.
Modify screenshot manager functionality to apply functionality of settings changed.
Update to 0.8.6.
2021-05-03 16:16:00 +02:00
Alexandru Macocian b4e31e859c Merge branch 'master' of https://github.com/AlexMacocian/Daybreak 2021-05-02 18:49:31 +02:00
Alexandru Macocian 1acd07c1be Change the way shortcut manager manages shortcuts.
Base for keyboard macros.
2021-05-02 18:49:25 +02:00
amacocianandGitHub b9b25bb098 Update README.md 2021-04-27 17:28:25 +02:00
amacocianandGitHub 5ea2981dc7 Update README.md 2021-04-27 17:25:03 +02:00
Alexandru Macocian 4fb96ca3a4 Ability to place screenshots in desired location. 2021-04-27 17:06:28 +02:00
Alexandru Macocian 6de52f5585 Ability to test placement while guildwars is running. 2021-04-26 11:26:43 +02:00
Alexandru Macocian 6622e41f64 Wait for guildwars window to be initialized before moving to desired window. 2021-04-26 11:02:23 +02:00
Alexandru Macocian 8405e4d1e5 Return to settings category after saving desired window. 2021-04-25 18:26:29 +02:00
Alexandru Macocian 0edc3f1560 Throw exception when screen id is invalid. 2021-04-25 18:24:51 +02:00
Alexandru Macocian c109fe7561 Ability to select on which window to place guildwars. 2021-04-25 18:20:45 +02:00
Alexandru Macocian b5413dca5c Include [Admin] tag when running as administrator. 2021-04-24 01:35:46 +02:00
Alexandru Macocian 6c2d4a1e70 No longer require administrator rights for normal usage.
Request elevation only in necesarry parts of the code.
Request elevation on update.
After update, launch application without elevation.
2021-04-24 01:20:36 +02:00
Alexandru Macocian be03f1a32d Run updates as admin 2021-04-23 23:37:01 +02:00
Alexandru Macocian 3ed1cc453a Implemented functionality to launch guildwars with lower privilege. 2021-04-23 20:24:28 +02:00
Alexandru Macocian 16030063ed Fix skill icon not unloading.
Moved all help icons on same side.
2021-04-23 19:52:09 +02:00
Alexandru Macocian 458696ad8f Fixed a bug where skill templates would try to load the image for No Skill.
Fixed a bug where build template manager would delete saved template.
2021-04-23 17:28:12 +02:00
Alexandru Macocian 6201702563 Skill holder now properly shows the top half of icons in the case where icons are bigger than normal. 2021-04-23 17:14:24 +02:00
Alexandru Macocian c5bea23a8f Make professions and attributes searchable.
Minor QOL changes to build view.
Handle exception caused by browser initialization getting canceled.
2021-04-23 16:59:31 +02:00
Alexandru Macocian e5f38f77ef Reverted html agility pack. 2021-04-23 11:40:05 +02:00
Alexandru Macocian 1d774ab8de Disable script injection when dynamic build loading is disabled.
Fixed a bug where earth prayers was not a recognized attribute.
2021-04-23 11:11:19 +02:00
Alexandru Macocian bc66ca9948 Feature flag to disable dynamic build loading in experimental settings. 2021-04-22 17:53:04 +02:00
amacocianandGitHub 524cd21fd4 Update README.md 2021-04-22 17:39:51 +02:00
amacocianandGitHub 132cb0e1f4 Update README.md 2021-04-22 17:32:35 +02:00
amacocianandGitHub 09c99e7731 Update README.md 2021-04-22 17:29:49 +02:00
Alexandru Macocian c9d0be1117 Update to 0.7.0 2021-04-22 17:02:48 +02:00
Alexandru Macocian 965055c8d7 Build management implementation.
Load build from browser when selection is detected to be a build template.
Load skill images from internet on demand.
Load skill details page when a skill is selected.
Separate skills on professions.
2021-04-22 17:02:28 +02:00
Alexandru Macocian f6bb21d0ef Build template parser and encoder.
Unit test project.
2021-04-20 20:06:15 +02:00
Alexandru Macocian 465e0a4ce0 Fix buttons while browser is fullscreen. 2021-04-20 12:51:26 +02:00
Alexandru Macocian 55f304b885 Update to wpfextended 0.2 2021-04-19 21:37:15 +02:00
Alexandru Macocian 0cb1d97332 Remove hyperlink from version text. 2021-04-17 20:04:20 +02:00
Alexandru Macocian e2091cd82f Home button for browsers.
Stop asking for updates if user already answered no.
2021-04-17 19:39:56 +02:00
Alexandru Macocian d2bada4159 Button to disable browsers. 2021-04-17 10:21:06 +02:00
Alexandru Macocian b27998d7f2 Basic support for texmod/umod. 2021-04-15 11:15:36 +02:00
amacocianandGitHub 98d3e21db9 Update README.md 2021-04-15 10:17:24 +02:00
Alexandru Macocian 0683504330 Minor gui fixes.
Set default webpages in application configuration.
Option to auto-launch gwtoolbox.
2021-04-15 09:57:19 +02:00
Alexandru Macocian 98bd1b2de6 Periodically check for updates.
Reorder settings in the settings category view.
2021-04-14 15:15:56 +02:00
Alexandru Macocian c169ca1684 Menu to manage guildwars executables. 2021-04-14 15:01:43 +02:00
Alexandru Macocian 88214ea166 Darken views with text to improve readability.
Better define the reason why guildwars failed to launch.
Auto set to default when adding first account.
Auto set another default when removing the default account.
2021-04-14 14:12:38 +02:00
Alexandru Macocian 4bdcd1a811 Changed version control to check all subversions. 2021-04-14 13:50:15 +02:00
Alexandru Macocian fa4f665a3e Fixed a bug with updating account details. 2021-04-13 21:28:49 +02:00
Alexandru Macocian e59e022c0a Updated to 0.5.0 2021-04-13 21:13:38 +02:00
Alexandru Macocian d096dc696a Multi-account management.
Split settings into multiple categories.
2021-04-13 21:09:41 +02:00
Alexandru Macocian 071007c3e5 Create application manifest.
Require highest available rights.
Return dialog message when registry is failed to be set.
2021-04-12 19:35:08 +02:00
Alexandru Macocian 57192d5043 Experimental multi-launch support 2021-04-12 19:09:00 +02:00
amacocianandGitHub 6af72683a8 Update README.md 2021-04-12 13:26:54 +02:00
amacocianandGitHub 3af9567506 Update README.md 2021-04-12 13:09:02 +02:00
Alexandru Macocian 1d7adf3944 Merge branch 'master' of https://github.com/AlexMacocian/Daybreak 2021-04-10 19:00:46 +02:00
Alexandru Macocian fb7399adf8 Add support for experimental features. 2021-04-10 19:00:39 +02:00
amacocianandGitHub 6ebbffdda1 Update README.md 2021-04-10 11:25:13 +02:00
Alexandru Macocian 2c35333cac Handle missing dependency on webview2 browser. 2021-04-10 11:18:46 +02:00
Alexandru Macocian fe5e38b216 Change update process to modify and restore execution policy before and after update.
Change update process to wait for the client to close instead of a static wait.
2021-04-10 10:31:36 +02:00
394 changed files with 28382 additions and 3107 deletions
+137
View File
@@ -0,0 +1,137 @@
[*.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 = file_scoped:error
csharp_style_prefer_method_group_conversion = true:suggestion
csharp_style_expression_bodied_methods = false:silent
csharp_style_expression_bodied_constructors = false:silent
csharp_style_expression_bodied_operators = false:silent
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
csharp_style_prefer_top_level_statements = true:suggestion
csharp_style_prefer_utf8_string_literals = true:suggestion
csharp_style_prefer_readonly_struct = true:suggestion
[*.{cs,vb}]
#### Naming styles ####
# 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
+1
View File
@@ -0,0 +1 @@
* amacocian@yahoo.com
+16
View File
@@ -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"
+109
View File
@@ -0,0 +1,109 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
# This continuous integration pipeline is triggered anytime a user pushes code to the repo.
# This pipeline builds the Wpf project, runs unit tests, then saves the MSIX build artifact.
name: Daybreak CD Pipeline
on:
push:
branches:
- master
paths:
- "Daybreak/**"
- "Daybreak.Installer/**"
jobs:
build:
strategy:
matrix:
targetplatform: [x64]
runs-on: windows-latest
env:
Configuration: Release
Solution_Path: Daybreak.sln
Test_Project_Path: Daybreak.Tests\Daybreak.Tests.csproj
Wpf_Project_Path: Daybreak\Daybreak.csproj
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: 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 }}"
- name: Install .NET Core
uses: actions/setup-dotnet@v3
with:
dotnet-version: '7.x'
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.3.1
- 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 }}
- 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: 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 }}
- 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
- name: Publish release
uses: Xotl/cool-github-releases@v1.1.8
with:
mode: update
tag_name: v${{ env.Version }}
release_name: Daybreak v${{ env.Version }}
assets: .\Publish\daybreakv${{ env.Version }}.zip
github_token: ${{ env.GITHUB_TOKEN }}
replace_assets: true
body_mrkdwn: ${{ env.Changelog }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+53
View File
@@ -0,0 +1,53 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
# This continuous integration pipeline is triggered anytime a user pushes code to the repo.
# This pipeline builds the Wpf project, runs unit tests, then saves the MSIX build artifact.
name: Daybreak CI Pipeline
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
build:
strategy:
matrix:
targetplatform: [x64]
runs-on: windows-latest
env:
Solution_Path: Daybreak.sln
Test_Project_Path: Daybreak.Tests\Daybreak.Tests.csproj
Wpf_Project_Path: Daybreak\Daybreal.csproj
Actions_Allow_Unsecure_Commands: true
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install .NET Core
uses: actions/setup-dotnet@v3
with:
dotnet-version: '7.x'
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.3.1
- name: Execute Unit Tests
run: dotnet test $env:Test_Project_Path
- 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:
Configuration: Debug
RuntimeIdentifier: win-${{ matrix.targetplatform }}
+78
View File
@@ -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
+48
View File
@@ -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 }}
+1
View File
@@ -9,6 +9,7 @@
*.user
*.userosscache
*.sln.docstates
*.version
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
@@ -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;x64</Platforms>
</PropertyGroup>
</Project>
+67
View File
@@ -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();
}
+23
View File
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework>
<IsPackable>false</IsPackable>
<Platforms>AnyCPU;x86;x64</Platforms>
</PropertyGroup>
<ItemGroup>
<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>
<ProjectReference Include="..\Daybreak\Daybreak.csproj" />
</ItemGroup>
</Project>
+186
View File
@@ -0,0 +1,186 @@
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>();
}
}
[DataRow("v0.1.0.0.1", "v0.1.0.0.1", true)]
[DataRow("v0.1.0.0.1.0.0.0.0", "v0.1.0.0.1", true)]
[DataRow("v0.1.0", "v0.1", true)]
[DataRow("0.1.0", "0.1", true)]
[DataRow("v0.1.0.0.0", "v0.1", true)]
[DataRow("0.1.0.0.0", "0.1", true)]
[DataRow("v0", "v0", true)]
[DataRow("0", "0", true)]
[DataRow("v0.1", "v0.1", true)]
[DataRow("0.1-release", "0.1-release", true)]
[DataRow("v0.1-release", "v0.1-release", true)]
[DataRow("v0.1.0.0", "v0.1.0.0.1", false)]
[DataRow("v0.1.0.0.1", "v0.1.0.0", false)]
[DataRow("v0.9.8.9", "v0.9.8.10", false)]
[DataRow("0.1-release", "0.2-release", false)]
[DataRow("v1.1-release", "v0.1-release", false)]
[TestMethod]
public void Equals(string version, string version2, bool result)
{
var parsedVersion1 = Version.Parse(version);
var parsedVersion2 = Version.Parse(version2);
parsedVersion1.Equals(parsedVersion2).Should().Be(result);
}
[DataRow("v0.1.0.0.1", "v0.1.0.0.1", 0)]
[DataRow("v0.1.0.0.1.0.0.0.0", "v0.1.0.0.1", 0)]
[DataRow("v0.1.0", "v0.1", 0)]
[DataRow("0.1.0", "0.1", 0)]
[DataRow("v0.1.0.0.0", "v0.1", 0)]
[DataRow("0.1.0.0.0", "0.1", 0)]
[DataRow("v0", "v0", 0)]
[DataRow("0", "0", 0)]
[DataRow("v0.1", "v0.1", 0)]
[DataRow("0.1-release", "0.1-release", 0)]
[DataRow("v0.1-release", "v0.1-release", 0)]
[DataRow("v0.1.0.0", "v0.1.0.0.1", -1)]
[DataRow("v0.1.0.0.1", "v0.1.0.0", 1)]
[DataRow("v0.9.8.9", "v0.9.8.10", -1)]
[DataRow("v0.9.8.10", "v0.9.8.9", 1)]
[DataRow("0.1-release", "0.2-release", -1)]
[DataRow("v1.1-release", "v0.1-release", 1)]
[TestMethod]
public void CompareTo(string version, string version2, int comparisonResult)
{
var parsedVersion1 = Version.Parse(version);
var parsedVersion2 = Version.Parse(version2);
parsedVersion1.CompareTo(parsedVersion2).Should().Be(comparisonResult);
}
}
@@ -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>();
}
}
@@ -0,0 +1,96 @@
using Daybreak.Models.Builds;
using Daybreak.Models.Guildwars;
using Daybreak.Services.BuildTemplates;
using FluentAssertions;
using Microsoft.Extensions.Logging;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using System.Collections.Generic;
namespace Daybreak.Tests.Services;
[TestClass]
public class BuildTemplateManagerTests
{
private const string EncodedTemplate = "OwBk0texXNu0Dj/z+TDzBj+TN4AE";
private IBuildTemplateManager buildTemplateManager;
[TestInitialize]
public void Initialize()
{
this.buildTemplateManager = new BuildTemplateManager(new Mock<ILogger<BuildTemplateManager>>().Object);
}
[TestMethod]
public void TestDecode()
{
var build = this.buildTemplateManager.DecodeTemplate(EncodedTemplate);
build.Primary.Should().Be(Profession.Assassin);
build.Secondary.Should().Be(Profession.None);
build.Attributes.Count.Should().Be(4);
build.Attributes[1].Attribute.Should().Be(Attribute.DaggerMastery);
build.Attributes[1].Points.Should().Be(11);
build.Attributes[2].Attribute.Should().Be(Attribute.DeadlyArts);
build.Attributes[2].Points.Should().Be(1);
build.Attributes[3].Attribute.Should().Be(Attribute.ShadowArts);
build.Attributes[3].Points.Should().Be(5);
build.Attributes[0].Attribute.Should().Be(Attribute.CriticalStrikes);
build.Attributes[0].Points.Should().Be(11);
build.Skills.Count.Should().Be(8);
build.Skills[0].Should().Be(Skill.UnsuspectingStrike);
build.Skills[1].Should().Be(Skill.WildStrike);
build.Skills[2].Should().Be(Skill.CriticalStrike);
build.Skills[3].Should().Be(Skill.MoebiusStrike);
build.Skills[4].Should().Be(Skill.DeathBlossom);
build.Skills[5].Should().Be(Skill.CriticalEye);
build.Skills[6].Should().Be(Skill.CriticalAgility);
build.Skills[7].Should().Be(Skill.CriticalDefenses);
}
[TestMethod]
public void TestEncode()
{
var build = new Build()
{
Primary = Profession.Assassin,
Secondary = Profession.None,
Attributes = new List<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
}
},
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);
}
}
@@ -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);
}
}
+58 -2
View File
@@ -1,26 +1,82 @@
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("{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|x64
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Debug|x64.Build.0 = Debug|x64
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Debug|x86.ActiveCfg = Debug|x86
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Debug|x86.Build.0 = Debug|x86
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Release|Any CPU.Build.0 = Release|Any CPU
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Release|x64.ActiveCfg = Release|x64
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Release|x64.Build.0 = Release|x64
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Release|x86.ActiveCfg = Release|x86
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Release|x86.Build.0 = Release|x86
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Debug|x64.ActiveCfg = Debug|x64
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Debug|x64.Build.0 = Debug|x64
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Debug|x86.ActiveCfg = Debug|x86
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Debug|x86.Build.0 = Debug|x86
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Release|Any CPU.Build.0 = Release|Any CPU
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Release|x64.ActiveCfg = Release|x64
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Release|x64.Build.0 = Release|x64
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Release|x86.ActiveCfg = Release|x86
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
+78
View File
@@ -0,0 +1,78 @@
using Microsoft.Xaml.Behaviors;
using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace Daybreak.Behaviors;
public class ScaleFontWithSize : Behavior<TextBlock>
{
public static readonly DependencyProperty MaxFontSizeProperty = DependencyProperty.Register("MaxFontSize", typeof(double), typeof(ScaleFontWithSize), new PropertyMetadata(12d));
public double MaxFontSize
{
get
{
return (double)this.GetValue(MaxFontSizeProperty);
}
set
{
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);
}
}
+54
View File
@@ -0,0 +1,54 @@
using Microsoft.Xaml.Behaviors;
using System;
using System.Extensions;
using System.Windows.Controls;
namespace Daybreak.Behaviors;
public class ScrollIntoView : Behavior<ListView>
{
/// <summary>
/// When Beahvior is attached
/// </summary>
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.SelectionChanged += this.AssociatedObject_SelectionChanged;
}
/// <summary>
/// On Selection Changed
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void AssociatedObject_SelectionChanged(object sender,
SelectionChangedEventArgs e)
{
if (sender is ListView)
{
var listView = sender.As<ListView>();
if (listView.SelectedItem != null)
{
listView.Dispatcher.BeginInvoke(
(Action)(() =>
{
listView.UpdateLayout();
if (listView.SelectedItem !=
null)
listView.ScrollIntoView(
listView.SelectedItem);
}));
}
}
}
/// <summary>
/// When behavior is detached
/// </summary>
protected override void OnDetaching()
{
base.OnDetaching();
this.AssociatedObject.SelectionChanged -=
this.AssociatedObject_SelectionChanged;
}
}
@@ -1,24 +1,49 @@
using Newtonsoft.Json;
using Daybreak.Configuration.FocusView;
using Daybreak.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
namespace Daybreak.Configuration
namespace Daybreak.Configuration;
public sealed class ApplicationConfiguration
{
public sealed class ApplicationConfiguration
{
[JsonProperty("GamePath")]
public string GamePath { get; set; }
[JsonProperty("ToolboxPath")]
public string ToolboxPath { get; set; }
[JsonProperty("CharacterName")]
public string CharacterName { get; set; }
[JsonProperty("LeftBrowserDefault")]
public string LeftBrowserDefault { get; set; }
[JsonProperty("RightBrowserDefault")]
public string RightBrowserDefault { get; set; }
[JsonProperty("ProtectedUsername")]
public string ProtectedUsername { get; set; }
[JsonProperty("ProtectedPassword")]
public string ProtectedPassword { get; set; }
[JsonProperty("AddressBarReadonly")]
public bool AddressBarReadonly { get; set; } = true;
}
[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; }
[JsonProperty("FocusViewOptions")]
public FocusViewOptions FocusViewOptions { get; set; } = new FocusViewOptions();
[JsonProperty("ScreenManagerOptions")]
public ScreenManagerOptions ScreenManagerOptions { get; set; } = new ScreenManagerOptions();
}
@@ -0,0 +1,27 @@
using Daybreak.Models;
using Newtonsoft.Json;
using System.Collections.Generic;
namespace Daybreak.Configuration;
public sealed class ExperimentalFeatures
{
[JsonProperty("MultiLaunchSupport")]
public bool MultiLaunchSupport { get; set; }
[JsonProperty("ToolboxAutoLaunchDelay")]
public int ToolboxAutoLaunchDelay { get; set; } = 5000;
[JsonProperty("DynamicBuildLoading")]
public bool DynamicBuildLoading { get; set; } = true;
[JsonProperty("LaunchGuildwarsAsCurrentUser")]
public bool LaunchGuildwarsAsCurrentUser { get; set; } = true;
[JsonProperty("CanInterceptKeys")]
public bool CanInterceptKeys { get; set; }
[JsonProperty("DownloadIcons")]
public bool DownloadIcons { get; set; }
[JsonProperty("FocusViewEnabled")]
public bool FocusViewEnabled { get; set; }
[JsonProperty("MemoryReaderFrequency")]
public double MemoryReaderFrequency { get; set; } = 16;
[JsonProperty("Macros")]
public List<KeyMacro> Macros { get; set; } = new();
}
@@ -0,0 +1,9 @@
namespace Daybreak.Configuration.FocusView;
public enum ExperienceDisplay
{
TotalCurretAndTotalMax,
CurrentLevelCurrentAndCurrentLevelMax,
RemainingUntilNextLevel,
Percentage
}
@@ -0,0 +1,25 @@
using Newtonsoft.Json;
namespace Daybreak.Configuration.FocusView;
public sealed class FocusViewOptions
{
[JsonProperty("ExperienceDisplay")]
public ExperienceDisplay ExperienceDisplay { get; set; }
[JsonProperty("KurzickPointsDisplay")]
public PointsDisplay KurzickPointsDisplay { get; set; }
[JsonProperty("LuxonPointsDisplay")]
public PointsDisplay LuxonPointsDisplay { get; set; }
[JsonProperty("BalthazarPointsDisplay")]
public PointsDisplay BalthazarPointsDisplay { get; set; }
[JsonProperty("ImperialPointsDisplay")]
public PointsDisplay ImperialPointsDisplay { get; set; }
[JsonProperty("VanquishingDisplay")]
public PointsDisplay VanquishingDisplay { get; set; }
[JsonProperty("HealthDisplay")]
public PointsDisplay HealthDisplay { get; set; }
[JsonProperty("EnergyDisplay")]
public PointsDisplay EnergyDisplay { get; set; }
[JsonProperty("BrowserUrl")]
public string? BrowserUrl { get; set; } = string.Empty;
}
@@ -0,0 +1,8 @@
namespace Daybreak.Configuration.FocusView;
public enum PointsDisplay
{
CurrentAndMax,
Remaining,
Percentage
}
+166 -36
View File
@@ -1,53 +1,183 @@
using Daybreak.Services.ApplicationDetection;
using Daybreak.Services.ApplicationLifetime;
using Daybreak.Services.ApplicationLauncher;
using Daybreak.Services.Bloogum;
using Daybreak.Services.BuildTemplates;
using Daybreak.Services.Configuration;
using Daybreak.Services.Credentials;
using Daybreak.Services.IconRetrieve;
using Daybreak.Services.Logging;
using Daybreak.Services.Mutex;
using Daybreak.Services.Privilege;
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.Web.WebView2.Core;
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;
using Daybreak.Services.Experience;
using Daybreak.Services.Metrics;
using Daybreak.Services.Monitoring;
using System.Net;
using System.Net.Http.Headers;
using Daybreak.Services.Downloads;
using Daybreak.Services.ExceptionHandling;
namespace Daybreak.Configuration
namespace Daybreak.Configuration;
public static class ProjectConfiguration
{
// TODO: Credit http://bloogum.net/guildwars/
public static class ProjectConfiguration
private const string DaybreakUserAgent = "Daybreak";
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<IApplicationDetector, ApplicationDetector>();
serviceProducer.RegisterSingleton<IScreenshotProvider, ScreenshotProvider>();
serviceProducer.RegisterSingleton<IConfigurationManager, ConfigurationManager>();
serviceProducer.RegisterSingleton<IBloogumClient, BloogumClient>();
serviceProducer.RegisterSingleton<IApplicationUpdater, ApplicationUpdater>();
serviceProducer.RegisterSingleton<CoreWebView2Environment, CoreWebView2Environment>((sp) => TaskExtensions.RunSync(() => CoreWebView2Environment.CreateAsync(null, "BrowserData", null)));
}
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() };
})
.WithDefaultRequestHeadersSetup(SetupDaybreakUserAgent)
.Build()
.RegisterHttpClient<BloogumClient>()
.WithMessageHandler(sp =>
{
var logger = sp.GetService<ILogger<BloogumClient>>();
return new LoggingHttpMessageHandler(logger!) { InnerHandler = new HttpClientHandler() };
})
.WithDefaultRequestHeadersSetup(SetupDaybreakUserAgent)
.Build()
.RegisterHttpClient<GraphClient>()
.WithMessageHandler(sp =>
{
var logger = sp.GetService<ILogger<GraphClient>>();
return new LoggingHttpMessageHandler(logger!) { InnerHandler = new HttpClientHandler() };
})
.WithDefaultRequestHeadersSetup(SetupDaybreakUserAgent)
.Build()
.RegisterHttpClient<DownloadService>()
.WithMessageHandler(sp =>
{
var logger = sp.GetService<ILogger<GraphClient>>();
return new LoggingHttpMessageHandler(logger!) { InnerHandler = new HttpClientHandler() };
})
.WithDefaultRequestHeadersSetup(SetupDaybreakUserAgent)
.Build();
}
applicationLifetimeProducer.RegisterService<ILoggingDatabase>();
applicationLifetimeProducer.RegisterService<IScreenshotProvider>();
}
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>();
}
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<ProcessorUsageMonitor>();
services.AddSingleton<MemoryUsageMonitor>();
services.AddSingleton<IViewManager, ViewManager>(sp => sp.GetRequiredService<ViewManager>());
services.AddSingleton<IViewProducer, ViewManager>(sp => sp.GetRequiredService<ViewManager>());
services.AddSingleton<PostUpdateActionManager>();
services.AddSingleton<IPostUpdateActionManager>(sp => sp.GetRequiredService<PostUpdateActionManager>());
services.AddSingleton<IPostUpdateActionProducer>(sp => sp.GetRequiredService<PostUpdateActionManager>());
services.AddSingleton<IPostUpdateActionProvider>(sp => sp.GetRequiredService<PostUpdateActionManager>());
services.AddSingleton<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.AddSingleton<IMetricsService, MetricsService>();
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>();
services.AddScoped<IExperienceCalculator, ExperienceCalculator>();
services.AddScoped<IAttributePointCalculator, AttributePointCalculator>();
services.AddScoped<IDownloadService, DownloadService>();
services.AddScoped<IGuildwarsEntityDebouncer, GuildwarsEntityDebouncer>();
services.AddScoped<IExceptionHandler, ExceptionHandler>();
}
public static void RegisterViews(IViewProducer viewProducer)
{
viewProducer.ThrowIfNull();
viewProducer.RegisterPermanentView<LauncherView>();
viewProducer.RegisterPermanentView<Views.FocusView>();
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<MetricsView>();
viewProducer.RegisterView<DownloadView>();
}
public static void RegisterPostUpdateActions(IPostUpdateActionProducer postUpdateActionProducer)
{
postUpdateActionProducer.ThrowIfNull();
postUpdateActionProducer.AddPostUpdateAction<RenameInstallerAction>();
}
private static void SetupDaybreakUserAgent(HttpRequestHeaders httpRequestHeaders)
{
httpRequestHeaders.ThrowIfNull().TryAddWithoutValidation("User-Agent", DaybreakUserAgent);
}
}
@@ -0,0 +1,11 @@
namespace Daybreak.Configuration;
public sealed class ScreenManagerOptions
{
public double X { get; set; }
public double Y { get; set; }
public double Width { get; set; }
public double Height { get; set; }
public double DpiX { get; set; }
public double DpiY { get; set; }
}
+12
View File
@@ -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()
{
}
}
+49
View File
@@ -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());
}
}
-37
View File
@@ -1,37 +0,0 @@
using System;
using System.Windows.Controls;
using System.Windows.Input;
namespace Daybreak.Controls
{
/// <summary>
/// Interaction logic for BackButton.xaml
/// </summary>
public partial class BackButton : UserControl
{
public event EventHandler Clicked;
public BackButton()
{
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)
{
Clicked?.Invoke(this, e);
}
}
}
}
+23
View File
@@ -0,0 +1,23 @@
<UserControl x:Class="Daybreak.Controls.AddButton"
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"
Cursor="Hand"
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" />
<Path Data="m13,26a13,13 0 1 1 13,-13a13,13 0 0 1 -13,13zm0,-24a11,11 0 1 0 11,11a11,11 0 0 0 -11,-11z"
Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"></Path>
<Path Data="m13,20a1,1 0 0 1 -1,-1l0,-12a1,1 0 0 1 2,0l0,12a1,1 0 0 1 -1,1z"
Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"></Path>
<Path Data="m19,14l-12,0a1,1 0 0 1 0,-2l12,0a1,1 0 0 1 0,2z"
Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"></Path>
<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 AddButton.xaml
/// </summary>
public partial class AddButton : UserControl
{
public event EventHandler? Clicked;
public AddButton()
{
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)
{
Clicked?.Invoke(this, e);
}
}
}
@@ -6,6 +6,7 @@
xmlns:local="clr-namespace:Daybreak.Controls"
mc:Ignorable="d"
x:Name="_this"
Cursor="Hand"
d:DesignHeight="450" d:DesignWidth="800">
<Viewbox>
<Grid>
@@ -0,0 +1,36 @@
using System;
using System.Windows.Controls;
using System.Windows.Input;
namespace Daybreak.Controls;
/// <summary>
/// Interaction logic for BackButton.xaml
/// </summary>
public partial class BackButton : UserControl
{
public event EventHandler? Clicked;
public BackButton()
{
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)
{
Clicked?.Invoke(this, e);
}
}
}
+31
View File
@@ -0,0 +1,31 @@
<UserControl x:Class="Daybreak.Controls.BinButton"
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"
Cursor="Hand"
d:DesignHeight="450" d:DesignWidth="800">
<Viewbox>
<Grid>
<Ellipse x:Name="BackgroundEllipse" Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Width="80" Height="80" Opacity="0.6"
Visibility="Hidden"></Ellipse>
<Path Data="m40,7l-2,0l0,-5l-18,0l0,5l-2,0l0,-6a1,1 0 0 1 1,-1l20,0a1,1 0 0 1 1,1l0,6z"
Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Margin="11"></Path>
<Path Data="m58,14l-2,0l0,-3l-54,0l0,3l-2,0l0,-4a1,1 0 0 1 1,-1l56,0a1,1 0 0 1 1,1l0,4z"
Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Margin="11"></Path>
<Path Data="m51,64l-44,0a1,1 0 0 1 -1,-1l0,-48l2,0l0,47l42,0l0,-47l2,0l0,48a1,1 0 0 1 -1,1z"
Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Margin="11"></Path>
<Rectangle Margin="38, 32, 0, 0" Width="2" Height="32" Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
VerticalAlignment="Top" HorizontalAlignment="Left"></Rectangle>
<Rectangle Margin="26, 35, 0, 0" Width="2" Height="32" Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
VerticalAlignment="Top" HorizontalAlignment="Left"></Rectangle>
<Rectangle Margin="50, 35, 0, 0" Width="2" Height="32" Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
VerticalAlignment="Top" HorizontalAlignment="Left"></Rectangle>
<Ellipse Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" StrokeThickness="3" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Fill="Transparent"
MouseLeftButtonDown="Ellipse_MouseLeftButtonDown" MouseEnter="Ellipse_MouseEnter" MouseLeave="Ellipse_MouseLeave"></Ellipse>
</Grid>
</Viewbox>
</UserControl>
@@ -0,0 +1,35 @@
using System;
using System.Windows.Controls;
using System.Windows.Input;
namespace Daybreak.Controls;
/// <summary>
/// Interaction logic for BinButton.xaml
/// </summary>
public partial class BinButton : UserControl
{
public event EventHandler? Clicked;
public BinButton()
{
this.InitializeComponent();
}
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
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;
}
}
@@ -6,6 +6,7 @@
xmlns:local="clr-namespace:Daybreak.Controls"
mc:Ignorable="d"
x:Name="_this"
Cursor="Hand"
d:DesignHeight="450" d:DesignWidth="800">
<Viewbox>
<Grid>
@@ -0,0 +1,36 @@
using System;
using System.Windows.Controls;
using System.Windows.Input;
namespace Daybreak.Controls;
/// <summary>
/// Interaction logic for BackButton.xaml
/// </summary>
public partial class CancelButton : UserControl
{
public event EventHandler? Clicked;
public CancelButton()
{
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)
{
Clicked?.Invoke(this, e);
}
}
}
@@ -0,0 +1,21 @@
<UserControl x:Class="Daybreak.Controls.FilePickerGlyph"
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"
Cursor="Hand"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Ellipse x:Name="BackgroundEllipse" Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Visibility="Visible" Opacity="0.1" />
<Viewbox Stretch="Fill">
<Grid>
<Ellipse Height="4" Width="4" StrokeThickness="0.2" Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"></Ellipse>
<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>
</Grid>
</UserControl>
@@ -0,0 +1,36 @@
using System;
using System.Windows.Controls;
using System.Windows.Input;
namespace Daybreak.Controls;
/// <summary>
/// Interaction logic for FilePickerGlyph.xaml
/// </summary>
public partial class FilePickerGlyph : UserControl
{
public event EventHandler? Clicked;
public FilePickerGlyph()
{
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);
}
}
}
+20
View File
@@ -0,0 +1,20 @@
<UserControl x:Class="Daybreak.Controls.HelpButton"
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"
Cursor="Hand"
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="30" Height="30" />
<Ellipse Width="30" Height="30" StrokeThickness="2" Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"></Ellipse>
<Path Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" VerticalAlignment="Center" HorizontalAlignment="Center"
Data="m4.99353,17.899l0,-1.47c0,-1.436 0.322,-2.188 1.075,-3.229l2.404,-3.3c1.254,-1.721 1.684,-2.546 1.684,-3.766c0,-2.044 -1.434,-3.335 -3.479,-3.335c-2.008,0 -3.299,1.219 -3.729,3.407c-0.036,0.215 -0.179,0.323 -0.395,0.287l-2.259,-0.395c-0.216,-0.036 -0.323,-0.179 -0.288,-0.395c0.539,-3.443 3.014,-5.703 6.744,-5.703c3.872,0 6.49,2.546 6.49,6.097c0,1.722 -0.608,2.977 -1.828,4.663l-2.403,3.3c-0.717,0.968 -0.933,1.47 -0.933,2.689l0,1.147c0,0.215 -0.143,0.358 -0.358,0.358l-2.367,0c-0.215,0.004 -0.358,-0.14 -0.358,-0.355zm-0.179,3.444c0,-0.215 0.143,-0.358 0.359,-0.358l2.726,0c0.215,0 0.358,0.144 0.358,0.358l0,3.084c0,0.216 -0.144,0.358 -0.358,0.358l-2.726,0c-0.217,0 -0.359,-0.143 -0.359,-0.358l0,-3.084z"></Path>
<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 AddButton.xaml
/// </summary>
public partial class HelpButton : UserControl
{
public event EventHandler? Clicked;
public HelpButton()
{
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);
}
}
}
+26
View File
@@ -0,0 +1,26 @@
<UserControl x:Class="Daybreak.Controls.HomeButton"
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"
Cursor="Hand"
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" />
<Ellipse Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" StrokeThickness="3" Width="60" Height="60"></Ellipse>
<Grid VerticalAlignment="Center" HorizontalAlignment="Center">
<Path Data="m42,45.384l-14,0l0,-13l-8,0l0,13l-14,0l0,-21c0,-0.552 0.447,-1 1,-1s1,0.448 1,1l0,19l10,0l0,-13l12,0l0,13l10,0l0,-18c0,-0.552 0.447,-1 1,-1s1,0.448 1,1l0,20z"
Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"></Path>
<Path Data="m47,24.384c-0.249,0 -0.497,-0.092 -0.691,-0.277l-22.309,-21.339l-22.309,21.339c-0.399,0.381 -1.032,0.368 -1.414,-0.031c-0.382,-0.399 -0.367,-1.032 0.031,-1.414l23.692,-22.662l23.691,22.661c0.398,0.382 0.413,1.015 0.031,1.414c-0.196,0.205 -0.458,0.309 -0.722,0.309z"
Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"></Path>
<Path Data="m39,12.384c-0.553,0 -1,-0.448 -1,-1l0,-6l-6,0c-0.553,0 -1,-0.448 -1,-1s0.447,-1 1,-1l8,0l0,8c0,0.552 -0.447,1 -1,1z"
Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"></Path>
</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 HomeButton.xaml
/// </summary>
public partial class HomeButton : UserControl
{
public event EventHandler? Clicked;
public HomeButton()
{
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)
{
Clicked?.Invoke(this, e);
}
}
}
@@ -5,6 +5,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Daybreak.Controls"
x:Name="_this"
Cursor="Hand"
mc:Ignorable="d"
d:DesignHeight="50" d:DesignWidth="50">
<Grid>
@@ -0,0 +1,36 @@
using System;
using System.Windows.Controls;
using System.Windows.Input;
namespace Daybreak.Controls;
/// <summary>
/// Interaction logic for SaveButton.xaml
/// </summary>
public partial class MaximizeButton : UserControl
{
public event EventHandler? Clicked;
public MaximizeButton()
{
this.InitializeComponent();
}
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
{
this.BackgroundEllipse.Visibility = System.Windows.Visibility.Visible;
}
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
{
this.BackgroundEllipse.Visibility = System.Windows.Visibility.Hidden;
}
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
Clicked?.Invoke(this, e);
}
}
}
+42
View File
@@ -0,0 +1,42 @@
<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"
Cursor="Hand"
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);
}
}
@@ -0,0 +1,21 @@
<UserControl x:Class="Daybreak.Controls.MinusButton"
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"
Cursor="Hand"
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" />
<Path Data="m13,26a13,13 0 1 1 13,-13a13,13 0 0 1 -13,13zm0,-24a11,11 0 1 0 11,11a11,11 0 0 0 -11,-11z"
Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"></Path>
<Path Data="m19,14l-12,0a1,1 0 0 1 0,-2l12,0a1,1 0 0 1 0,2z"
Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"></Path>
<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 AddButton.xaml
/// </summary>
public partial class MinusButton : UserControl
{
public event EventHandler? Clicked;
public MinusButton()
{
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)
{
Clicked?.Invoke(this, e);
}
}
}
@@ -6,6 +6,7 @@
xmlns:local="clr-namespace:Daybreak.Controls"
mc:Ignorable="d"
x:Name="_this"
Cursor="Hand"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"></BooleanToVisibilityConverter>
@@ -20,13 +21,12 @@
FontStretch="{Binding ElementName=_this, Path=FontStretch, Mode=OneWay}"
FontWeight="{Binding ElementName=_this, Path=FontWeight, Mode=OneWay}"
FontStyle="{Binding ElementName=_this, Path=FontStyle, Mode=OneWay}"
VerticalAlignment="Center"
HorizontalAlignment="Center"></TextBlock>
VerticalAlignment="{Binding ElementName=_this, Path=TextVerticalAlignment, Mode=OneWay}"
HorizontalAlignment="{Binding ElementName=_this, Path=TextHorizontalAlignment, Mode=OneWay}"></TextBlock>
<Rectangle Fill="{Binding ElementName=_this, Path=Highlight, Mode=OneWay}"
Opacity="{Binding ElementName=_this, Path=HighlightOpacity, Mode=OneWay}"
Visibility="{Binding ElementName=_this, Path=HighlightVisible, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}"></Rectangle>
<Rectangle MouseEnter="Rectangle_MouseEnter" MouseLeave="Rectangle_MouseLeave"
MouseLeftButtonDown="Rectangle_MouseLeftButtonDown" Fill="Transparent"
Cursor="Hand"></Rectangle>
MouseLeftButtonDown="Rectangle_MouseLeftButtonDown" Fill="Transparent"></Rectangle>
</Grid>
</UserControl>
@@ -0,0 +1,53 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Extensions;
using System.Windows.Input;
using System.Windows.Media;
namespace Daybreak.Controls;
/// <summary>
/// Interaction logic for OpaqueButton.xaml
/// </summary>
public partial class OpaqueButton : UserControl
{
public event EventHandler? Clicked;
[GenerateDependencyProperty(InitialValue = "")]
private string text = string.Empty;
[GenerateDependencyProperty]
private Brush transparentBackground = default!;
[GenerateDependencyProperty]
private Brush highlight = default!;
[GenerateDependencyProperty]
public double backgroundOpacity;
[GenerateDependencyProperty]
public double highlightOpacity;
[GenerateDependencyProperty]
public bool highlightVisible;
[GenerateDependencyProperty(InitialValue = VerticalAlignment.Center)]
public VerticalAlignment textVerticalAlignment;
[GenerateDependencyProperty(InitialValue = HorizontalAlignment.Center)]
public HorizontalAlignment textHorizontalAlignment;
public OpaqueButton()
{
this.InitializeComponent();
}
private void Rectangle_MouseEnter(object sender, MouseEventArgs e)
{
this.HighlightVisible = true;
}
private void Rectangle_MouseLeave(object sender, MouseEventArgs e)
{
this.HighlightVisible = false;
}
private void Rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.Clicked?.Invoke(this, e);
}
}
@@ -5,6 +5,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Daybreak.Controls"
x:Name="_this"
Cursor="Hand"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Viewbox>
@@ -21,7 +22,7 @@
VerticalAlignment="Top" HorizontalAlignment="Left" StrokeThickness="3" Width="47.25" Height="3" />
<Rectangle Stroke="{Binding ElementName=_this, Path=Foreground}" Margin="39.375, 85.625, 0, 0"
VerticalAlignment="Top" HorizontalAlignment="Left" StrokeThickness="3" Width="47.25" Height="3" />
<Ellipse Stroke="{Binding ElementName=_this, Path=Foreground}" Width="128" Height="128" StrokeThickness="5" Fill="Transparent"
<Ellipse Stroke="{Binding ElementName=_this, Path=Foreground}" Width="128" Height="128" StrokeThickness="8" Fill="Transparent"
MouseEnter="Ellipse_MouseEnter" MouseLeave="Ellipse_MouseLeave" MouseLeftButtonDown="Ellipse_MouseLeftButtonDown"></Ellipse>
</Grid>
</Viewbox>
@@ -0,0 +1,36 @@
using System;
using System.Windows.Controls;
using System.Windows.Input;
namespace Daybreak.Controls;
/// <summary>
/// Interaction logic for SaveButton.xaml
/// </summary>
public partial class SaveButton : UserControl
{
public event EventHandler? Clicked;
public SaveButton()
{
this.InitializeComponent();
}
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
{
this.BackgroundEllipse.Visibility = System.Windows.Visibility.Visible;
}
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
{
this.BackgroundEllipse.Visibility = System.Windows.Visibility.Hidden;
}
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
Clicked?.Invoke(this, e);
}
}
}
@@ -0,0 +1,37 @@
<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"
Cursor="Hand"
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);
}
}
}
+46
View File
@@ -0,0 +1,46 @@
<UserControl x:Class="Daybreak.Controls.TileButton"
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:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:behaviors="clr-namespace:Daybreak.Behaviors"
xmlns:converters="clr-namespace:Daybreak.Converters"
x:Name="_this"
Cursor="Hand"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<converters:TileButtonHighlightConverter x:Key="HighlightConverter"></converters:TileButtonHighlightConverter>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<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}}"
Grid.RowSpan="2">
</Border>
<TextBlock Grid.Row="1" Text="{Binding ElementName=_this, Path=Title}"
FontSize="{Binding ElementName=_this, Path=FontSize}"
FontFamily="{Binding ElementName=_this, Path=FontFamily}"
Foreground="{Binding ElementName=_this, Path=Foreground}"
VerticalAlignment="Center" HorizontalAlignment="Stretch" TextWrapping="Wrap"
TextAlignment="Center">
<i:Interaction.Behaviors>
<behaviors:ScaleFontWithSize MaxFontSize="22"></behaviors:ScaleFontWithSize>
</i:Interaction.Behaviors>
</TextBlock>
<Rectangle Fill="Transparent"
MouseEnter="Grid_MouseEnter"
MouseLeave="Grid_MouseLeave"
MouseLeftButtonDown="Rectangle_MouseLeftButtonDown"
Grid.RowSpan="2">
</Rectangle>
</Grid>
</UserControl>
@@ -0,0 +1,44 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Extensions;
using System.Windows.Media;
namespace Daybreak.Controls;
/// <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()
{
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);
}
}
-37
View File
@@ -1,37 +0,0 @@
using System;
using System.Windows.Controls;
using System.Windows.Input;
namespace Daybreak.Controls
{
/// <summary>
/// Interaction logic for BackButton.xaml
/// </summary>
public partial class CancelButton : UserControl
{
public event EventHandler Clicked;
public CancelButton()
{
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)
{
Clicked?.Invoke(this, e);
}
}
}
}
+45 -7
View File
@@ -9,18 +9,33 @@
mc:Ignorable="d"
Unloaded="UserControl_Unloaded"
x:Name="_this"
Initialized="UserControl_Initialized"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" TriggerValue="True"></converters:BooleanToVisibilityConverter>
<converters:BooleanToVisibilityConverter x:Key="ReverseBooleanToVisibilityConverter" TriggerValue="False"></converters:BooleanToVisibilityConverter>
</UserControl.Resources>
<UserControl.ContextMenu>
<ContextMenu>
<ContextMenu.Template>
<ControlTemplate>
<StackPanel Margin="10">
<local:OpaqueButton Text="Load build template" Foreground="White" Background="#F0212121" BackgroundOpacity="0.4"
Clicked="LoadBuildTemplateButton_Click" FontSize="16" Height="40" Width="200"></local:OpaqueButton>
</StackPanel>
</ControlTemplate>
</ContextMenu.Template>
</ContextMenu>
</UserControl.ContextMenu>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<wv2:WebView2 x:Name="WebBrowser" Source="{Binding ElementName=_this, Path=Address, Mode=TwoWay}"></wv2:WebView2>
<Grid Grid.Row="1" Background="#80808080">
<wv2:WebView2 x:Name="WebBrowser" Source="{Binding ElementName=_this, Path=Address, Mode=TwoWay}"
IsEnabled="{Binding ElementName=_this, Path=BrowserSupported, Mode=OneWay}"></wv2:WebView2>
<Grid Grid.Row="1" Background="#F0212121" IsEnabled="{Binding ElementName=_this, Path=BrowserSupported, Mode=OneWay}"
Visibility="{Binding ElementName=_this, Path=ControlsEnabled, Mode=OneWay, Converter={StaticResource ReverseBooleanToVisibilityConverter}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
@@ -51,15 +66,38 @@
Grid.Column="1" IsReadOnly="{Binding ElementName=_this, Path=AddressBarReadonly, Mode=OneWay}" Background="Transparent"
BorderThickness="1" VerticalAlignment="Center" VerticalContentAlignment="Center"
BorderBrush="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
PreviewKeyDown="TextBox_PreviewKeyDown"></TextBox>
PreviewKeyDown="TextBox_PreviewKeyDown"
IsEnabled="{Binding ElementName=_this, Path=BrowserSupported, Mode=OneWay}"></TextBox>
<StackPanel Grid.Column="2" Orientation="Horizontal">
<local:HomeButton Width="30" Height="30" Margin="5"
Visibility="{Binding ElementName=_this, Path=HomeButtonVisible, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}"
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
IsEnabled="{Binding ElementName=_this, Path=BrowserSupported, Mode=OneWay}"
Clicked="HomeButton_Clicked"></local:HomeButton>
<local:StarGlyph Height="30" Width="30" Margin="5"
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Clicked="StarGlyph_Clicked" x:Name="FavoriteButton"></local:StarGlyph>
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Visibility="{Binding ElementName=_this, Path=HomeButtonVisible, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}"
IsEnabled="{Binding ElementName=_this, Path=BrowserSupported, Mode=OneWay}"
Clicked="StarGlyph_Clicked" x:Name="FavoriteButton"></local:StarGlyph>
<local:MaximizeButton Height="30" Width="30" Margin="5"
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Clicked="MaximizeButton_Clicked"></local:MaximizeButton>
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
IsEnabled="{Binding ElementName=_this, Path=BrowserSupported, Mode=OneWay}"
Clicked="MaximizeButton_Clicked"></local:MaximizeButton>
</StackPanel>
</Grid>
<Grid Grid.RowSpan="2" Background="Gray"
Visibility="{Binding ElementName=_this, Path=BrowserSupported, Mode=OneWay,Converter={StaticResource BooleanToVisibilityConverter}}">
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock Foreground="White" Text="Browser not supported." FontSize="26" TextWrapping="Wrap"></TextBlock>
<TextBlock Foreground="White" Text="Download the Evergreen Bootstrapper from here:" FontSize="26" TextWrapping="Wrap" />
<TextBox Background="Transparent" BorderBrush="Transparent" BorderThickness="0"
Text="https://go.microsoft.com/fwlink/p/?LinkId=2124703"
IsReadOnly="True" Margin="0, 0, 0, 30" FontSize="22" Foreground="Blue"
PreviewMouseLeftButtonDown="Hyperlink_PreviewMouseLeftButtonDown" Cursor="Hand"
TextWrapping="Wrap"></TextBox>
<TextBlock Foreground="White" Text="Restart after the installation." FontSize="26" TextWrapping="Wrap" />
</StackPanel>
</Grid>
</Grid>
</UserControl>
+322 -126
View File
@@ -1,169 +1,365 @@
using Daybreak.Launch;
using Daybreak.Services.Configuration;
using Daybreak.Configuration;
using Daybreak.Models.Browser;
using Daybreak.Models.Guildwars;
using Daybreak.Services.BuildTemplates;
using Daybreak.Utils;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Web.WebView2.Core;
using System;
using System.Configuration;
using System.Core.Extensions;
using System.Diagnostics;
using System.Extensions;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Extensions;
namespace Daybreak.Controls
namespace Daybreak.Controls;
/// <summary>
/// Interaction logic for ChromiumBrowserWrapper.xaml
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0044:Add readonly modifier", Justification = "Fields used by source generator for DependencyProperty")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0052:Remove unread private members", Justification = "Used by source generators")]
public partial class ChromiumBrowserWrapper : UserControl
{
/// <summary>
/// Interaction logic for ChromiumBrowserWrapper.xaml
/// </summary>
public partial class ChromiumBrowserWrapper : UserControl
public static readonly DependencyProperty AddressProperty =
DependencyPropertyExtensions.Register<ChromiumBrowserWrapper, string>(nameof(Address));
private const string BrowserSearchPlaceholder = "[PLACEHOLDER]";
private const string BrowserSearchLink = $"https://www.google.com/search?q={BrowserSearchPlaceholder}";
private const string BrowserDownloadLink = "https://developer.microsoft.com/en-us/microsoft-edge/webview2/";
private static readonly Regex WebAddressRegex = new("^((http|ftp|https)://)?([\\w_-]+(?:(?:\\.[\\w_-]+)+))([\\w.,@?^=%&:/~+#-]*[\\w@?^=%&/~+#-])?", RegexOptions.Compiled);
private static CoreWebView2Environment? coreWebView2Environment;
public event EventHandler<string>? FavoriteUriChanged;
public event EventHandler? MaximizeClicked;
public event EventHandler<Build>? BuildDecoded;
private readonly Task initializationTask;
private readonly ILiveOptions<ApplicationConfiguration>? liveOptions;
private readonly ILogger<ChromiumBrowserWrapper>? logger;
private readonly 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;
[GenerateDependencyProperty(InitialValue = true)]
private bool homeButtonVisible = true;
[GenerateDependencyProperty(InitialValue = true)]
private bool favoriteButtonVisible = true;
public string Address
{
public readonly static DependencyProperty AddressProperty = DependencyPropertyExtensions.Register<ChromiumBrowserWrapper, string>(nameof(Address));
public readonly static DependencyProperty FavoriteAddressProperty = DependencyPropertyExtensions.Register<ChromiumBrowserWrapper, string>(nameof(FavoriteAddress));
public readonly static DependencyProperty NavigatingProperty = DependencyPropertyExtensions.Register<ChromiumBrowserWrapper, bool>(nameof(Navigating));
public readonly static DependencyProperty AddressBarReadonlyProperty = DependencyPropertyExtensions.Register<ChromiumBrowserWrapper, bool>(nameof(AddressBarReadonly));
public event EventHandler<string> FavoriteUriChanged;
public event EventHandler MaximizeClicked;
private readonly CoreWebView2Environment coreWebView2Environment;
private readonly IConfigurationManager configurationManager;
public string Address
get => this.GetTypedValue<string>(AddressProperty);
set
{
get => this.GetTypedValue<string>(AddressProperty);
set => this.SetTypedValue(AddressProperty, value);
}
public string FavoriteAddress
{
get => this.GetTypedValue<string>(FavoriteAddressProperty);
set => this.SetTypedValue(FavoriteAddressProperty, value);
}
public bool Navigating
{
get => this.GetTypedValue<bool>(NavigatingProperty);
private set => this.SetTypedValue<bool>(NavigatingProperty, value);
}
public bool AddressBarReadonly
{
get => this.GetTypedValue<bool>(AddressBarReadonlyProperty);
private set => this.SetTypedValue<bool>(AddressBarReadonlyProperty, value);
}
public ChromiumBrowserWrapper()
{
this.coreWebView2Environment = Launcher.ApplicationServiceManager.GetService<CoreWebView2Environment>();
this.configurationManager = Launcher.ApplicationServiceManager.GetService<IConfigurationManager>();
this.InitializeComponent();
this.InitializeBrowser();
}
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (e.Property == AddressProperty || e.Property == FavoriteAddressProperty)
if (this.BrowserSupported is true)
{
this.CheckFavoriteAddress();
this.SetValue(AddressProperty, value);
}
}
}
public void ReinitializeBrowser()
public ChromiumBrowserWrapper()
: this(Launch.Launcher.Instance.ApplicationServiceProvider.GetRequiredService<ILiveOptions<ApplicationConfiguration>>(),
Launch.Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IBuildTemplateManager>(),
Launch.Launcher.Instance.ApplicationServiceProvider.GetRequiredService<ILogger<ChromiumBrowserWrapper>>())
{
}
public ChromiumBrowserWrapper(
ILiveOptions<ApplicationConfiguration> liveOptions,
IBuildTemplateManager buildTemplateManager,
ILogger<ChromiumBrowserWrapper> logger)
{
this.liveOptions = liveOptions.ThrowIfNull();
this.buildTemplateManager = buildTemplateManager.ThrowIfNull();
this.logger = logger.ThrowIfNull();
this.initializationTask = this.InitializeBrowser();
this.InitializeComponent();
}
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (e.Property == AddressProperty || e.Property == FavoriteAddressProperty)
{
this.InitializeBrowser();
this.CheckFavoriteAddress();
}
}
public async Task ReinitializeBrowser()
{
await this.InitializeBrowser();
}
public Task InitializationTask() => this.initializationTask;
private async void UserControl_Initialized(object sender, EventArgs e)
{
this.InitializeEnvironment();
await this.InitializeBrowser();
}
private void InitializeEnvironment()
{
if (this.liveOptions!.Value.BrowsersEnabled is false)
{
this.BrowserSupported = false;
return;
}
private async void InitializeBrowser()
try
{
await this.WebBrowser.EnsureCoreWebView2Async(this.coreWebView2Environment);
this.AddressBarReadonly = this.configurationManager.GetConfiguration().AddressBarReadonly;
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()
{
if (this.BrowserSupported is true)
{
this.WebBrowser.IsEnabled = true;
this.BrowserEnabled = true;
await this.WebBrowser.EnsureCoreWebView2Async(coreWebView2Environment);
this.AddressBarReadonly = this.liveOptions!.Value.AddressBarReadonly;
this.CanDownloadBuild = this.liveOptions.Value.ExperimentalFeatures.DynamicBuildLoading;
this.WebBrowser.CoreWebView2.NewWindowRequested += (browser, args) => args.Handled = true;
this.WebBrowser.NavigationStarting += (browser, args) => this.Navigating = true;
this.WebBrowser.NavigationCompleted += (browser, args) => this.Navigating = false;
}
private void TextBox_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
if (e.Key == System.Windows.Input.Key.Enter)
this.WebBrowser.NavigationStarting += (browser, args) =>
{
var newAddress = sender.As<TextBox>().Text;
newAddress = SanitizeAddress(newAddress);
if (newAddress is null)
if (this.CanNavigate is false && args.Uri != this.Address)
{
return;
args.Cancel = true;
}
this.Address = newAddress;
this.WebBrowser.CoreWebView2.Navigate(this.Address);
e.Handled = 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);
}
}
}
private void UserControl_Unloaded(object sender, RoutedEventArgs e)
private async void RetryInitializeButton_Clicked(object sender, EventArgs e)
{
this.InitializeEnvironment();
try
{
this.WebBrowser.Dispose();
await this.InitializeBrowser();
}
private void BackButton_Clicked(object sender, EventArgs e)
catch
{
this.WebBrowser.GoBack();
this.Address = this.WebBrowser.Source.ToString();
this.BrowserSupported = false;
}
}
private void ForwardButton_Clicked(object sender, EventArgs e)
private void Hyperlink_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (Uri.TryCreate(BrowserDownloadLink, UriKind.Absolute, out var uri))
{
this.WebBrowser.GoForward();
this.Address = this.WebBrowser.Source.ToString();
Process.Start("explorer.exe", uri.ToString());
}
}
private void RefreshGlyph_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.Reload();
this.Address = this.WebBrowser.Source.ToString();
}
private void CancelGlyph_Clicked(object sender, EventArgs e)
{
this.WebBrowser.Stop();
}
private void StarGlyph_Clicked(object sender, EventArgs e)
{
this.FavoriteAddress = this.Address;
this.FavoriteUriChanged?.Invoke(this, this.FavoriteAddress);
}
private void MaximizeButton_Clicked(object sender, EventArgs e)
{
this.MaximizeClicked?.Invoke(this, e);
}
private void CheckFavoriteAddress()
{
if (this.Address == this.FavoriteAddress)
var input = sender.As<TextBox>().Text;
var maybeAddress = SanitizeAddress(input);
// If input is address, navigate to address. Otherwise search for the text input in Google
if (Uri.TryCreate(maybeAddress, UriKind.Absolute, out _))
{
this.FavoriteButton.IsEnabled = false;
this.Address = maybeAddress;
}
else
{
this.FavoriteButton.IsEnabled = true;
}
}
private static string SanitizeAddress(string address)
{
if (string.IsNullOrWhiteSpace(address))
{
return null;
var address = BrowserSearchLink.Replace(BrowserSearchPlaceholder, maybeAddress);
this.Address = 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();
this.WebBrowser.CoreWebView2.Navigate(this.Address);
e.Handled = true;
}
}
private void CoreWebView2_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs args)
{
BrowserPayload payload = default!;
try
{
payload = args.WebMessageAsJson.Deserialize<BrowserPayload>();
}
catch(Exception e)
{
this.logger!.LogError(e, $"Exception encountered when deserializing {nameof(BrowserPayload)}");
}
if (payload?.Key == BrowserPayload.PayloadKeys.ContextMenu)
{
var contextMenuPayload = args.WebMessageAsJson.Deserialize<BrowserPayload<OnContextMenuPayload>>();
var maybeTemplate = contextMenuPayload.Value!.Selection;
if (string.IsNullOrWhiteSpace(maybeTemplate))
{
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 LoadBuildTemplateButton_Click(object sender, EventArgs e)
{
var build = this.ContextMenu.DataContext.As<Build>();
this.ContextMenu.IsOpen = false;
this.BuildDecoded?.Invoke(this, build);
}
private void UserControl_Unloaded(object sender, RoutedEventArgs e)
{
if (this.PreventDispose)
{
return;
}
this.WebBrowser?.Dispose();
}
private void BackButton_Clicked(object sender, EventArgs e)
{
this.WebBrowser.GoBack();
this.Address = this.WebBrowser.Source.ToString();
}
private void ForwardButton_Clicked(object sender, EventArgs e)
{
this.WebBrowser.GoForward();
this.Address = this.WebBrowser.Source.ToString();
}
private void RefreshGlyph_Clicked(object sender, EventArgs e)
{
this.WebBrowser.Reload();
this.Address = this.WebBrowser.Source.ToString();
}
private void CancelGlyph_Clicked(object sender, EventArgs e)
{
this.WebBrowser.Stop();
}
private void StarGlyph_Clicked(object sender, EventArgs e)
{
this.FavoriteAddress = this.Address;
this.FavoriteUriChanged?.Invoke(this, this.FavoriteAddress);
}
private void HomeButton_Clicked(object sender, EventArgs e)
{
this.WebBrowser.CoreWebView2.Navigate(this.FavoriteAddress);
}
private void MaximizeButton_Clicked(object sender, EventArgs e)
{
this.MaximizeClicked?.Invoke(this, e);
}
private void CheckFavoriteAddress()
{
if (this.Address == this.FavoriteAddress)
{
this.FavoriteButton.IsEnabled = false;
}
else
{
this.FavoriteButton.IsEnabled = true;
}
}
private static string SanitizeAddress(string address)
{
if (string.IsNullOrWhiteSpace(address))
{
return default!;
}
if (WebAddressRegex.IsMatch(address) is false)
{
return address;
}
if (address.StartsWith("www") is false &&
address.StartsWith("http") is false)
{
address = "https://www." + address;
}
else if (address.StartsWith("www"))
{
address = "https://" + address;
}
Uri.TryCreate(address, UriKind.Absolute, out var uri);
return uri?.ToString() ?? string.Empty;
}
}
@@ -0,0 +1,553 @@
<UserControl x:Class="Daybreak.Controls.CircularLoadingWidget"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Daybreak.Controls"
Height="Auto" Width="Auto">
<UserControl.Resources>
<Storyboard x:Key="ProgressAnimation" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="Black"/>
<SplineColorKeyFrame KeyTime="00:00:00.2290000" Value="#EF000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.4590000" Value="#E2000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.6880000" Value="#D3000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.9180000" Value="#C6000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.1470000" Value="#B7000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.3760000" Value="#AA000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.6060000" Value="#9B000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.8350000" Value="#8E000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.0650000" Value="#7F000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.2940000" Value="#72000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.5240000" Value="#63000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.7530000" Value="#56000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.9820000" Value="#3D000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.2120000" Value="#26000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.4410000" Value="#19000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.6710000" Value="#0C000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="#00000000"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block17" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#EF000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.2290000" Value="#E2000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.4590000" Value="#D3000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.6880000" Value="#C6000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.9180000" Value="#B7000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.1470000" Value="#AA000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.3760000" Value="#9B000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.6060000" Value="#8E000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.8350000" Value="#7F000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.0650000" Value="#72000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.2940000" Value="#63000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.5240000" Value="#56000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.7530000" Value="#3D000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.9820000" Value="#26000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.2120000" Value="#19000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.4410000" Value="#0C000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.6710000" Value="#00000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="Black"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block16" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#E2000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.2290000" Value="#D3000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.4590000" Value="#C6000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.6880000" Value="#B7000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.9180000" Value="#AA000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.1470000" Value="#9B000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.3760000" Value="#8E000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.6060000" Value="#7F000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.8350000" Value="#72000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.0650000" Value="#63000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.2940000" Value="#56000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.5240000" Value="#3D000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.7530000" Value="#26000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.9820000" Value="#19000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.2120000" Value="#0C000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.4410000" Value="#00000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.6710000" Value="Black"/>
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="#EF000000"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block15" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#D3000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.2290000" Value="#C6000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.4590000" Value="#B7000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.6880000" Value="#AA000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.9180000" Value="#9B000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.1470000" Value="#8E000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.3760000" Value="#7F000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.6060000" Value="#72000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.8350000" Value="#63000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.0650000" Value="#56000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.2940000" Value="#3D000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.5240000" Value="#26000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.7530000" Value="#19000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.9820000" Value="#0C000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.2120000" Value="#00000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.4410000" Value="Black"/>
<SplineColorKeyFrame KeyTime="00:00:03.6710000" Value="#EF000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="#E2000000"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block14" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#C6000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.2290000" Value="#B7000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.4590000" Value="#AA000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.6880000" Value="#9B000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.9180000" Value="#8E000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.1470000" Value="#7F000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.3760000" Value="#72000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.6060000" Value="#63000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.8350000" Value="#56000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.0650000" Value="#3D000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.2940000" Value="#26000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.5240000" Value="#19000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.7530000" Value="#0C000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.9820000" Value="#00000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.2120000" Value="Black"/>
<SplineColorKeyFrame KeyTime="00:00:03.4410000" Value="#EF000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.6710000" Value="#E2000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="#D3000000"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block13" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#B7000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.2290000" Value="#AA000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.4590000" Value="#9B000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.6880000" Value="#8E000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.9180000" Value="#7F000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.1470000" Value="#72000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.3760000" Value="#63000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.6060000" Value="#56000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.8350000" Value="#3D000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.0650000" Value="#26000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.2940000" Value="#19000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.5240000" Value="#0C000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.7530000" Value="#00000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.9820000" Value="Black"/>
<SplineColorKeyFrame KeyTime="00:00:03.2120000" Value="#EF000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.4410000" Value="#E2000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.6710000" Value="#D3000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="#C6000000"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block12" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#AA000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.2290000" Value="#9B000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.4590000" Value="#8E000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.6880000" Value="#7F000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.9180000" Value="#72000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.1470000" Value="#63000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.3760000" Value="#56000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.6060000" Value="#3D000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.8350000" Value="#26000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.0650000" Value="#19000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.2940000" Value="#0C000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.5240000" Value="#00000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.7530000" Value="Black"/>
<SplineColorKeyFrame KeyTime="00:00:02.9820000" Value="#EF000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.2120000" Value="#E2000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.4410000" Value="#D3000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.6710000" Value="#C6000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="#B7000000"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block11" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#9B000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.2290000" Value="#8E000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.4590000" Value="#7F000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.6880000" Value="#72000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.9180000" Value="#63000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.1470000" Value="#56000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.3760000" Value="#3D000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.6060000" Value="#26000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.8350000" Value="#19000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.0650000" Value="#0C000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.2940000" Value="#00000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.5240000" Value="Black"/>
<SplineColorKeyFrame KeyTime="00:00:02.7530000" Value="#EF000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.9820000" Value="#E2000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.2120000" Value="#D3000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.4410000" Value="#C6000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.6710000" Value="#B7000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="#AA000000"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block10" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#8E000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.2290000" Value="#7F000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.4590000" Value="#72000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.6880000" Value="#63000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.9180000" Value="#56000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.1470000" Value="#3D000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.3760000" Value="#23000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.6060000" Value="#19000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.8350000" Value="#0C000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.0650000" Value="#00000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.2940000" Value="Black"/>
<SplineColorKeyFrame KeyTime="00:00:02.5240000" Value="#EF000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.7530000" Value="#E2000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.9820000" Value="#D3000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.2120000" Value="#C6000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.4410000" Value="#B7000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.6710000" Value="#AA000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="#9B000000"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block9" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#7F000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.2290000" Value="#72000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.4590000" Value="#63000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.6880000" Value="#56000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.9180000" Value="#3D000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.1470000" Value="#26000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.3760000" Value="#19000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.6060000" Value="#0C000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.8350000" Value="#00000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.0650000" Value="Black"/>
<SplineColorKeyFrame KeyTime="00:00:02.2940000" Value="#EF000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.5240000" Value="#E2000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.7530000" Value="#D3000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.9820000" Value="#C6000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.2120000" Value="#B7000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.4410000" Value="#AA000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.6710000" Value="#9B000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="#91000000"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block8" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#72000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.2290000" Value="#63000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.4590000" Value="#56000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.6880000" Value="#3D000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.9180000" Value="#26000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.1470000" Value="#19000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.3760000" Value="#0C000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.6060000" Value="#00000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.8350000" Value="Black"/>
<SplineColorKeyFrame KeyTime="00:00:02.0650000" Value="#EF000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.2940000" Value="#E2000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.5240000" Value="#D3000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.7530000" Value="#C6000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.9820000" Value="#B7000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.2120000" Value="#AA000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.4410000" Value="#9B000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.6710000" Value="#91000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="#7F000000"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block7" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#63000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.2290000" Value="#56000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.4590000" Value="#3D000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.6880000" Value="#26000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.9180000" Value="#19000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.1470000" Value="#0C000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.3760000" Value="#00000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.6060000" Value="Black"/>
<SplineColorKeyFrame KeyTime="00:00:01.8350000" Value="#EF000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.0650000" Value="#E2000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.2940000" Value="#D3000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.5240000" Value="#C6000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.7530000" Value="#B7000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.9820000" Value="#AA000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.2120000" Value="#9B000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.4410000" Value="#91000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.6710000" Value="#7F000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="#72000000"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block6" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#56000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.2290000" Value="#3D000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.4590000" Value="#26000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.6880000" Value="#19000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.9180000" Value="#0C000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.1470000" Value="#00000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.3760000" Value="Black"/>
<SplineColorKeyFrame KeyTime="00:00:01.6060000" Value="#EF000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.8350000" Value="#E2000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.0650000" Value="#D3000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.2940000" Value="#C6000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.5240000" Value="#B7000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.7530000" Value="#AA000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.9820000" Value="#9B000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.2120000" Value="#91000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.4410000" Value="#7F000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.6710000" Value="#72000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="#63000000"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block5" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#3D000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.2290000" Value="#26000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.4590000" Value="#19000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.6880000" Value="#0C000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.9180000" Value="#00000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.1470000" Value="Black"/>
<SplineColorKeyFrame KeyTime="00:00:01.3760000" Value="#EF000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.6060000" Value="#E2000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.8350000" Value="#D3000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.0650000" Value="#C6000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.2940000" Value="#B7000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.5240000" Value="#AA000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.7530000" Value="#9B000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.9820000" Value="#91000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.2120000" Value="#7F000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.4410000" Value="#72000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.6710000" Value="#63000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="#56000000"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block4" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#26000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.2290000" Value="#19000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.4590000" Value="#0C000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.6880000" Value="#00000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.9180000" Value="Black"/>
<SplineColorKeyFrame KeyTime="00:00:01.1470000" Value="#EF000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.3760000" Value="#E2000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.6060000" Value="#D3000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.8350000" Value="#C6000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.0650000" Value="#B7000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.2940000" Value="#AA000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.5240000" Value="#9B000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.7530000" Value="#91000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.9820000" Value="#7F000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.2120000" Value="#72000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.4410000" Value="#63000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.6710000" Value="#56000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="#3D000000"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block3" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#19000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.2290000" Value="#0C000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.4590000" Value="#00000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.6880000" Value="Black"/>
<SplineColorKeyFrame KeyTime="00:00:00.9180000" Value="#EF000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.1470000" Value="#E2000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.3760000" Value="#D3000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.6060000" Value="#C6000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.8350000" Value="#B7000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.0650000" Value="#AA000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.2940000" Value="#9B000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.5240000" Value="#91000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.7530000" Value="#7F000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.9820000" Value="#72000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.2120000" Value="#63000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.4410000" Value="#56000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.6710000" Value="#3D000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="#26000000"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block2" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#0C000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.2290000" Value="#00000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.4590000" Value="Black"/>
<SplineColorKeyFrame KeyTime="00:00:00.6880000" Value="#EF000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.9180000" Value="#E2000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.1470000" Value="#D3000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.3760000" Value="#C6000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.6060000" Value="#B7000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.8350000" Value="#AA000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.0650000" Value="#9B000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.2940000" Value="#91000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.5240000" Value="#7F000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.7530000" Value="#72000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.9820000" Value="#63000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.2120000" Value="#56000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.4410000" Value="#3D000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.6710000" Value="#26000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="#19000000"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block1" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#00000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.2290000" Value="Black"/>
<SplineColorKeyFrame KeyTime="00:00:00.4590000" Value="#EF000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.6880000" Value="#E2000000"/>
<SplineColorKeyFrame KeyTime="00:00:00.9180000" Value="#D3000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.1470000" Value="#C6000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.3760000" Value="#B7000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.6060000" Value="#AA000000"/>
<SplineColorKeyFrame KeyTime="00:00:01.8350000" Value="#9B000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.0650000" Value="#8E000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.2940000" Value="#7F000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.5240000" Value="#72000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.7530000" Value="#63000000"/>
<SplineColorKeyFrame KeyTime="00:00:02.9820000" Value="#56000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.2120000" Value="#3D000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.4410000" Value="#26000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.6710000" Value="#19000000"/>
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="#0C000000"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<UserControl.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard x:Name="ProgressAnimation_BeginStoryboard" Storyboard="{StaticResource ProgressAnimation}"/>
</EventTrigger>
</UserControl.Triggers>
<Viewbox>
<Canvas x:Name="LayoutRoot" VerticalAlignment="Top" Height="88" Width="88">
<Grid Width="10.734" Height="10.004" Canvas.Left="38.614" Canvas.Top="0.331">
<Rectangle Fill="White" x:Name="block" RenderTransformOrigin="0.5,4.3689" OpacityMask="#00000000" VerticalAlignment="Top" Height="10.004">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="180"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="block1" Fill="White" RenderTransformOrigin="0.5,4.3689" OpacityMask="#0C000000" VerticalAlignment="Top" Height="10.004">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="0.99999999999999989" ScaleY="0.99999999999999989"/>
<SkewTransform/>
<RotateTransform Angle="-160"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="block2" Fill="White" RenderTransformOrigin="0.5,4.3689" OpacityMask="#19000000" VerticalAlignment="Top" Height="10.004">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="-140"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="block3" Fill="White" RenderTransformOrigin="0.5,4.3689" OpacityMask="#26000000" VerticalAlignment="Top" Height="10.004">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="0.99999999999999989" ScaleY="0.99999999999999989"/>
<SkewTransform/>
<RotateTransform Angle="-119.99999999999999"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="block4" Fill="White" RenderTransformOrigin="0.5,4.3689" OpacityMask="#3D000000" VerticalAlignment="Top" Height="10.004">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="0.99999999999999989" ScaleY="0.99999999999999989"/>
<SkewTransform/>
<RotateTransform Angle="-100"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="block5" Fill="White" RenderTransformOrigin="0.5,4.3689" OpacityMask="#56000000" VerticalAlignment="Top" Height="10.004">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="0.99999999999999989" ScaleY="0.99999999999999989"/>
<SkewTransform/>
<RotateTransform Angle="-80"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="block6" Fill="White" RenderTransformOrigin="0.5,4.3689" OpacityMask="#64000000" VerticalAlignment="Top" Height="10.004">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="-59.999999999999993"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="block7" Fill="White" RenderTransformOrigin="0.5,4.3689" OpacityMask="#72000000" VerticalAlignment="Top" Height="10.004">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="0.99999999999999989" ScaleY="0.99999999999999989"/>
<SkewTransform/>
<RotateTransform Angle="-40"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="block8" Fill="White" RenderTransformOrigin="0.5,4.3689" OpacityMask="#80000000" VerticalAlignment="Top" Height="10.004">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="-19.999999999999996"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="block9" Fill="White" OpacityMask="#8E000000" RenderTransformOrigin="0.5,4.3689" VerticalAlignment="Top" Height="10.004"/>
<Rectangle x:Name="block10" Fill="White" RenderTransformOrigin="0.5,4.3689" OpacityMask="#9C000000" VerticalAlignment="Top" Height="10.004">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="19.999999999999996"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="block11" Fill="White" RenderTransformOrigin="0.5,4.3689" OpacityMask="#AA000000" VerticalAlignment="Top" Height="10.004">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="0.99999999999999989" ScaleY="0.99999999999999989"/>
<SkewTransform/>
<RotateTransform Angle="40"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="block12" Fill="White" RenderTransformOrigin="0.5,4.3689" OpacityMask="#B8000000" VerticalAlignment="Top" Height="10.004">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="59.999999999999993"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="block13" Fill="White" RenderTransformOrigin="0.5,4.3689" OpacityMask="#C6000000" VerticalAlignment="Top" Height="10.004">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="0.99999999999999989" ScaleY="0.99999999999999989"/>
<SkewTransform/>
<RotateTransform Angle="80"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="block14" Fill="White" RenderTransformOrigin="0.5,4.3689" OpacityMask="#D4000000" VerticalAlignment="Top" Height="10.004">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="0.99999999999999989" ScaleY="0.99999999999999989"/>
<SkewTransform/>
<RotateTransform Angle="100"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="block15" Fill="White" RenderTransformOrigin="0.5,4.3689" OpacityMask="#E2000000" VerticalAlignment="Top" Height="10.004">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="0.99999999999999989" ScaleY="0.99999999999999989"/>
<SkewTransform/>
<RotateTransform Angle="119.99999999999999"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="block16" Fill="White" RenderTransformOrigin="0.5,4.3689" OpacityMask="#F0000000" VerticalAlignment="Top" Height="10.004">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="140"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="block17" Fill="White" RenderTransformOrigin="0.5,4.3689" OpacityMask="Black" VerticalAlignment="Top" Height="10.004">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="0.99999999999999989" ScaleY="0.99999999999999989"/>
<SkewTransform/>
<RotateTransform Angle="160"/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
</Canvas>
</Viewbox>
</UserControl>
@@ -0,0 +1,31 @@
using System.Windows;
using System.Windows.Controls;
namespace Daybreak.Controls;
/// <summary>
/// Interaction logic for CircularLoadingWidget.xaml
/// </summary>
public partial class CircularLoadingWidget : UserControl
{
public CircularLoadingWidget()
{
this.InitializeComponent();
}
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (e.Property == IsEnabledProperty)
{
if (e.NewValue is true)
{
this.ProgressAnimation_BeginStoryboard.Storyboard.Pause();
}
else
{
this.ProgressAnimation_BeginStoryboard.Storyboard.Resume();
}
}
}
}
-21
View File
@@ -1,21 +0,0 @@
<UserControl x:Class="Daybreak.Controls.FilePickerGlyph"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Daybreak.Controls"
mc:Ignorable="d"
x:Name="_this"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Rectangle x:Name="BackgroundEllipse" Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Visibility="Visible" Opacity="0.1" />
<Viewbox>
<StackPanel Orientation="Horizontal">
<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>
<Rectangle Fill="Transparent" MouseEnter="Ellipse_MouseEnter" MouseLeave="Ellipse_MouseLeave" MouseLeftButtonDown="Ellipse_MouseLeftButtonDown"></Rectangle>
</Grid>
</UserControl>
-37
View File
@@ -1,37 +0,0 @@
using System;
using System.Windows.Controls;
using System.Windows.Input;
namespace Daybreak.Controls
{
/// <summary>
/// Interaction logic for FilePickerGlyph.xaml
/// </summary>
public partial class FilePickerGlyph : UserControl
{
public event EventHandler Clicked;
public FilePickerGlyph()
{
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);
}
}
}
}
+18
View File
@@ -0,0 +1,18 @@
<UserControl x:Class="Daybreak.Controls.AvatarGlyph"
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>
<Path Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Data="m5.7,104.4c10.6,-10.6 24.6,-16.4 39.6,-16.4s29,5.8 39.6,16.4l5.7,-5.7c-12.1,-12 -28.2,-18.7 -45.3,-18.7s-33.2,6.7 -45.3,18.7l5.7,5.7z"></Path>
<Path Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Data="m11.3,34c0,18.7 15.3,34 34,34s34,-15.3 34,-34s-15.3,-34 -34,-34s-34,15.3 -34,34zm60,0c0,14.3 -11.7,26 -26,26s-26,-11.7 -26,-26s11.7,-26 26,-26s26,11.7 26,26z"></Path>
</Grid>
</Viewbox>
</UserControl>
@@ -0,0 +1,14 @@
using System.Windows.Controls;
namespace Daybreak.Controls;
/// <summary>
/// Interaction logic for AvatarGlyph.xaml
/// </summary>
public partial class AvatarGlyph : UserControl
{
public AvatarGlyph()
{
this.InitializeComponent();
}
}
+22
View File
@@ -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>
+14
View File
@@ -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();
}
}
+18
View File
@@ -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>
+14
View File
@@ -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();
}
}
@@ -0,0 +1,18 @@
<UserControl x:Class="Daybreak.Controls.Glyphs.DownloadGlyph"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Daybreak.Controls.Glyphs"
mc:Ignorable="d"
x:Name="_this"
d:DesignHeight="450" d:DesignWidth="800">
<Viewbox>
<Grid>
<Path Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" StrokeThickness="3"
Data="m32,30.454c0,0 8.312,0 9.098,0c4.365,0 7.902,-3.537 7.902,-7.901s-3.537,-7.902 -7.902,-7.902c-0.02,0 -0.038,0.003 -0.058,0.003c0.061,-0.494 0.103,-0.994 0.103,-1.504c0,-6.71 -5.439,-12.15 -12.15,-12.15c-5.229,0 -9.672,3.309 -11.386,7.941c-1.087,-1.089 -2.591,-1.764 -4.251,-1.764c-3.319,0 -6.009,2.69 -6.009,6.008c0,0.085 0.01,0.167 0.013,0.251c-3.665,1.013 -6.36,4.362 -6.36,8.349c0,4.788 3.881,8.669 8.67,8.669c0.827,0 8.33,0 8.33,0"></Path>
<Polyline Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Points="30,36 25,41 20,36" StrokeThickness="3"></Polyline>
<Line X1="25" X2="25" Y1="21" Y2="41" Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" StrokeThickness="3"></Line>
</Grid>
</Viewbox>
</UserControl>
@@ -0,0 +1,14 @@
using System.Windows.Controls;
namespace Daybreak.Controls.Glyphs;
/// <summary>
/// Interaction logic for DownloadGlyph.xaml
/// </summary>
public partial class DownloadGlyph : UserControl
{
public DownloadGlyph()
{
this.InitializeComponent();
}
}
@@ -0,0 +1,14 @@
<UserControl x:Class="Daybreak.Controls.ExperimentGlyph"
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="m23.8,22.5l-7.8,-12.6l0,-7.9l1,0c0.6,0 1,-0.4 1,-1s-0.4,-1 -1,-1l-3,0l0,9.9l3.5,6.1l-11,0l3.5,-6.1l0,-9.9l-3,0c-0.6,0 -1,0.4 -1,1s0.4,1 1,1l1,0l0,7.9l-7.8,12.7c-0.5,0.7 0,1.4 0.8,1.4l22,0c0.8,0 1.3,-0.5 0.8,-1.5zm-20.8,-0.5l2.9,-5l12.2,0l2.9,5l-18,0z"></Path>
</Viewbox>
</UserControl>
@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Daybreak.Controls;
/// <summary>
/// Interaction logic for ExperimentGlyph.xaml
/// </summary>
public partial class ExperimentGlyph : UserControl
{
public ExperimentGlyph()
{
this.InitializeComponent();
}
}
+14
View File
@@ -0,0 +1,14 @@
<UserControl x:Class="Daybreak.Controls.FileGlyph"
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="m52,0l-40,0c-6.627,0 -12,5.373 -12,12l0,72c0,6.627 5.373,12 12,12l55.875,0c6.627,0 12.125,-5.373 12.125,-12l0,-56c-4,-4 -22,-22 -28,-28zm0,11.178l16.709,16.822l-16.709,0l0,-16.822zm15.875,76.822l-55.875,0c-2.206,0 -4,-1.794 -4,-4l0,-72c0,-2.206 1.794,-4 4,-4l32,0l0,20l0,8l8,0l20,0l0,48c0,2.168 -1.889,4 -4.125,4z"></Path>
</Viewbox>
</UserControl>
@@ -0,0 +1,14 @@
using System.Windows.Controls;
namespace Daybreak.Controls;
/// <summary>
/// Interaction logic for FileGlyph.xaml
/// </summary>
public partial class FileGlyph : UserControl
{
public FileGlyph()
{
this.InitializeComponent();
}
}
@@ -0,0 +1,24 @@
<UserControl x:Class="Daybreak.Controls.FireballGlyph"
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>
<Line Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
X1="15" X2="26" Y1="11" Y2="0"
StrokeThickness="2"></Line>
<Ellipse Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
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>
</UserControl>
@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Daybreak.Controls;
/// <summary>
/// Interaction logic for FireballGlyph.xaml
/// </summary>
public partial class FireballGlyph : UserControl
{
public FireballGlyph()
{
this.InitializeComponent();
}
}
+20
View File
@@ -0,0 +1,20 @@
<UserControl x:Class="Daybreak.Controls.Glyphs.GaugeGlyph"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Daybreak.Controls.Glyphs"
mc:Ignorable="d"
Name="_this"
d:DesignHeight="450" d:DesignWidth="800">
<Viewbox>
<Grid>
<Path Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Data="m13.5,13.5c1.44772,-1.44772 2.5,-3.29086 2.5,-5.5c0,-4.41828 -3.58172,-8 -8,-8s-8,3.58172 -8,8c0,2.20914 1.05228,4.05228 2.5,5.5"></Path>
<Path Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Data="m8,8l-4,-4"></Path>
<Ellipse Margin="6, 7.5, 6, 6" Width="1.5" Height="1.5"
Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"></Ellipse>
</Grid>
</Viewbox>
</UserControl>
@@ -0,0 +1,14 @@
using System.Windows.Controls;
namespace Daybreak.Controls.Glyphs;
/// <summary>
/// Interaction logic for GaugeGlyph.xaml
/// </summary>
public partial class GaugeGlyph : UserControl
{
public GaugeGlyph()
{
this.InitializeComponent();
}
}
@@ -0,0 +1,19 @@
<UserControl x:Class="Daybreak.Controls.GoldenArrowGlyph"
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>
<Grid.RenderTransform>
<RotateTransform Angle="180" CenterX="900" CenterY="595"></RotateTransform>
</Grid.RenderTransform>
<Path Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Data="m771.53119,1071.05017c-81,-64 -151,-120 -154,-126c-4,-5 -15,-7 -25,-3c-11,4 -77,12 -149,16c-146,10 -203,26 -326,92c-63,35 -82,41 -96,32c-22,-13 -28,-55 -14,-95c7,-20 7,-39 -1,-60c-8,-25 -7,-38 5,-65c9,-19 21,-34 27,-34c5,0 10,-15 10,-34c0,-49 32,-75 83,-67c4,0 7,-10 7,-24c0,-31 41,-75 70,-75c11,0 20,-6 20,-14c0,-41 73,-60 136,-36c23,9 30,7 50,-15c13,-14 27,-25 32,-25c5,0 14,-11 20,-25c6,-14 17,-25 23,-25c7,0 22,-10 34,-22c12,-13 38,-36 58,-53c34,-28 37,-34 38,-90l1,-60l149,-133c82,-74 154,-132 160,-130c6,2 73,62 149,133l138,130l1,60c1,56 4,62 38,90c20,17 46,40 58,53c12,12 27,22 34,22c6,0 17,11 23,25c6,14 15,25 20,25c5,0 19,11 32,25c20,22 27,24 50,15c63,-24 136,-5 136,36c0,8 8,14 19,14c32,0 71,39 71,71c0,16 3,28 8,28c50,-8 82,18 82,67c0,19 4,34 9,34c5,0 16,16 26,36c13,27 14,42 6,65c-7,20 -7,38 0,58c14,40 8,82 -14,95c-14,9 -33,3 -96,-32c-123,-66 -180,-82 -326,-92c-71,-4 -138,-11 -148,-15c-11,-5 -22,-2 -30,7c-7,9 -76,65 -154,126l-141,111l-149,-116zm277,-45c99,-78 119,-97 119,-120c1,-32 1,-32 78,-14c32,8 114,19 183,25c134,11 208,31 297,81c61,35 63,35 63,15c0,-8 -12,-22 -26,-31l-25,-17l25,-24c14,-13 26,-30 26,-38c0,-19 -27,-44 -56,-51c-24,-6 -24,-7 -9,-31c27,-40 13,-55 -44,-47l-50,6l11,-35c23,-76 -11,-87 -77,-26c-25,23 -48,39 -51,36c-3,-3 6,-27 20,-53c14,-27 26,-57 26,-68c0,-16 -6,-18 -41,-13c-22,3 -58,17 -80,31c-21,14 -41,26 -44,26c-3,0 -5,-20 -5,-45c0,-42 -2,-45 -19,-35c-32,16 -41,12 -41,-20c0,-36 -13,-38 -34,-8c-15,22 -16,21 -16,-27c0,-47 -1,-48 -17,-32c-17,17 -18,16 -28,-24c-6,-24 -17,-45 -24,-47c-11,-4 -12,5 -5,44c15,83 11,140 -11,164c-13,14 -18,33 -16,55c8,101 -156,220 -241,174c-14,-8 -23,-8 -31,0c-15,15 -61,14 -101,-3c-74,-31 -155,-132 -142,-179c3,-13 -2,-29 -13,-42c-26,-28 -32,-84 -17,-150c13,-52 8,-74 -13,-61c-5,4 -12,24 -16,47c-7,39 -8,40 -26,23c-18,-17 -19,-16 -19,32c0,47 -1,48 -16,26c-21,-30 -34,-28 -34,8c0,32 -9,36 -41,20c-17,-10 -19,-7 -19,35c0,25 -2,45 -5,45c-3,0 -23,-12 -44,-26c-22,-14 -58,-28 -80,-31c-35,-5 -41,-3 -41,13c0,11 12,41 26,68c14,26 23,50 20,53c-3,3 -26,-13 -51,-36c-66,-61 -100,-50 -77,26l11,35l-43,-6c-23,-4 -50,-4 -60,0c-15,6 -15,9 3,39l19,33l-26,7c-59,15 -69,55 -25,91c27,21 27,23 8,30c-24,9 -35,23 -35,46c0,14 10,11 57,-17c92,-53 173,-76 313,-87c69,-5 150,-15 181,-23c72,-19 69,-20 69,13c1,23 20,42 118,119c64,50 123,92 130,92c7,1 66,-41 132,-91zm-149,-229c7,-21 15,-39 19,-39c4,0 14,18 23,40c13,34 20,40 45,40c37,0 108,-52 135,-98l19,-32l-31,-31c-17,-17 -31,-32 -31,-34c0,-1 17,-6 37,-10c45,-8 53,-18 53,-66c0,-68 -45,-159 -78,-159c-9,1 -32,14 -51,30c-19,16 -36,28 -37,27c-2,-2 4,-27 13,-56c13,-47 13,-55 0,-68c-22,-23 -91,-34 -139,-24c-59,14 -69,31 -52,86c15,51 7,56 -33,25c-14,-11 -31,-20 -38,-20c-20,0 -52,43 -69,93c-29,88 -18,121 45,131l42,7l-34,35l-33,34l19,36c20,37 84,88 120,96c32,7 44,-2 56,-43zm-154,-439c11,0 23,-11 29,-28c32,-85 252,-85 292,1c7,15 21,27 31,27c10,0 30,9 45,21l26,20l0,-55l0,-56l-106,-102c-58,-57 -114,-108 -124,-115c-14,-10 -34,3 -143,100l-127,112l0,67l0,66l29,-29c16,-16 38,-29 48,-29z" />
</Grid>
</Viewbox>
</UserControl>
@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Daybreak.Controls;
/// <summary>
/// Interaction logic for GoldenArrowGlyph.xaml
/// </summary>
public partial class GoldenArrowGlyph : UserControl
{
public GoldenArrowGlyph()
{
this.InitializeComponent();
}
}
+20
View File
@@ -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();
}
}
+14
View File
@@ -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();
}
}
+28
View File
@@ -0,0 +1,28 @@
<UserControl x:Class="Daybreak.Controls.Glyphs.MapGlyph"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Daybreak.Controls.Glyphs"
mc:Ignorable="d"
Name="_this"
d:DesignHeight="450" d:DesignWidth="800">
<Viewbox>
<Grid>
<Path Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Data="m18.53,14.53a9.37,9.37 0 0 1 -9.26,9.47l0,0a9.5,9.5 0 0 1 -3.26,-18.33a9.61,9.61 0 0 0 0.77,1.82a14.22,14.22 0 0 0 2.51,3.25a14.06,14.06 0 0 0 2.49,-3.24a9.2,9.2 0 0 0 0.75,-1.83a9.47,9.47 0 0 1 6,8.86z"></Path>
<Polyline Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Points="9.270000457763672,24 9.270000457763672,23.989999771118164 9.270000457763672,10.739999771118164"></Polyline>
<Path Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Data="m9.27,24l0,0c-0.32,-0.22 -5.27,-3.85 -4.94,-10.1a11.36,11.36 0 0 1 2.44,-6.4"></Path>
<Path Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Data="m9.25,24a0,0 0 0 1 0,0l0,0c0.4,-0.29 5.25,-3.91 4.92,-10.1a11.35,11.35 0 0 0 -2.43,-6.39"></Path>
<Line Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
X1="0" X2="18.53" Y1="14.53" Y2="14.53"></Line>
<Path Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Data="m12.35,1.89a3.81,3.81 0 0 0 -3.08,-1.89a3.82,3.82 0 0 0 -3.09,1.89a4.75,4.75 0 0 0 -0.19,3.78a9.61,9.61 0 0 0 0.77,1.82a14.22,14.22 0 0 0 2.51,3.25a14.06,14.06 0 0 0 2.49,-3.24a9.2,9.2 0 0 0 0.77,-1.83a4.79,4.79 0 0 0 -0.18,-3.78z"></Path>
<Ellipse Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Width="1.24" Height="1.26" Margin="8.6, 3" HorizontalAlignment="Left" VerticalAlignment="Top"></Ellipse>
</Grid>
</Viewbox>
</UserControl>
+14
View File
@@ -0,0 +1,14 @@
using System.Windows.Controls;
namespace Daybreak.Controls.Glyphs;
/// <summary>
/// Interaction logic for MapGlyph.xaml
/// </summary>
public partial class MapGlyph : UserControl
{
public MapGlyph()
{
this.InitializeComponent();
}
}
@@ -0,0 +1,36 @@
using System;
using System.Windows.Controls;
using System.Windows.Input;
namespace Daybreak.Controls;
/// <summary>
/// Interaction logic for RefreshGlyph.xaml
/// </summary>
public partial class RefreshGlyph : UserControl
{
public event EventHandler? Clicked;
public RefreshGlyph()
{
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);
}
}
}
@@ -0,0 +1,36 @@
using System;
using System.Windows.Controls;
using System.Windows.Input;
namespace Daybreak.Controls;
/// <summary>
/// Interaction logic for BackButton.xaml
/// </summary>
public partial class StarGlyph : UserControl
{
public event EventHandler? Clicked;
public StarGlyph()
{
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)
{
Clicked?.Invoke(this, e);
}
}
}
+14
View File
@@ -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();
}
}
+69
View File
@@ -0,0 +1,69 @@
<UserControl x:Class="Daybreak.Controls.GuildwarsMinimap"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Daybreak.Controls"
x:Name="_this"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
MouseWheel="GuildwarsMinimap_MouseWheel"
MouseLeftButtonDown="GuildwarsMinimap_MouseLeftButtonDown"
MouseLeftButtonUp="GuildwarsMinimap_MouseLeftButtonUp"
MouseRightButtonDown="GuildwarsMinimap_MouseRightButtonDown"
MouseRightButtonUp="GuildwarsMinimap_MouseRightButtonUp"
MouseMove="GuildwarsMinimap_MouseMove"
Loaded="GuildwarsMinimap_Loaded"
Unloaded="GuildwarsMinimap_Unloaded">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"></BooleanToVisibilityConverter>
<ContextMenu x:Key="WorldPlayerContextMenu">
<ContextMenu.Template>
<ControlTemplate>
<local:WorldPlayerContextMenu DataContext="{Binding DataContext, RelativeSource={RelativeSource TemplatedParent}}"></local:WorldPlayerContextMenu>
</ControlTemplate>
</ContextMenu.Template>
</ContextMenu>
<ContextMenu x:Key="MainPlayerContextMenu">
<ContextMenu.Template>
<ControlTemplate>
<local:MainPlayerContextMenu DataContext="{Binding DataContext, RelativeSource={RelativeSource TemplatedParent}}"></local:MainPlayerContextMenu>
</ControlTemplate>
</ContextMenu.Template>
</ContextMenu>
<ContextMenu x:Key="LivingEntityContextMenu">
<ContextMenu.Template>
<ControlTemplate>
<local:LivingEntityContextMenu DataContext="{Binding DataContext, RelativeSource={RelativeSource TemplatedParent}}"></local:LivingEntityContextMenu>
</ControlTemplate>
</ContextMenu.Template>
</ContextMenu>
<ContextMenu x:Key="PlayerContextMenu">
<ContextMenu.Template>
<ControlTemplate>
<local:PlayerContextMenu DataContext="{Binding DataContext, RelativeSource={RelativeSource TemplatedParent}}"></local:PlayerContextMenu>
</ControlTemplate>
</ContextMenu.Template>
</ContextMenu>
<ContextMenu x:Key="QuestContextMenu">
<ContextMenu.Template>
<ControlTemplate>
<local:QuestContextMenu DataContext="{Binding DataContext, RelativeSource={RelativeSource TemplatedParent}}"
QuestContextMenuClicked="QuestContextMenu_QuestContextMenuClicked"></local:QuestContextMenu>
</ControlTemplate>
</ContextMenu.Template>
</ContextMenu>
</UserControl.Resources>
<Grid>
<Image x:Name="MapDrawingHost" VerticalAlignment="Top" HorizontalAlignment="Left" Stretch="Fill"/>
<Image x:Name="EntitiesDrawingHost" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
<Grid Background="#F0212121"
VerticalAlignment="Bottom"
HorizontalAlignment="Right"
Visibility="{Binding ElementName=_this, Path=ControlsVisible, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}">
<local:MaximizeButton Height="30" Width="30" Margin="5"
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Clicked="MaximizeButton_Clicked"></local:MaximizeButton>
</Grid>
</Grid>
</UserControl>
+692
View File
@@ -0,0 +1,692 @@
using Daybreak.Models.Guildwars;
using Daybreak.Models;
using System.Windows.Controls;
using System.Windows.Extensions;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Media;
using System;
using System.Extensions;
using Daybreak.Services.Scanner;
using Microsoft.Extensions.DependencyInjection;
using System.Core.Extensions;
using System.Windows.Input;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Windows.Threading;
namespace Daybreak.Controls;
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0052:Remove unread private members", Justification = "Using source generators to auto-implement dependency properties")]
/// <summary>
/// Interaction logic for GuildwarsMinimap.xaml
/// </summary>
public partial class GuildwarsMinimap : UserControl
{
private const int MapDownscaleFactor = 10;
private const int EntitySize = 100;
private const float PositionRadius = 150;
private static readonly Lazy<(Point[] OuterPoints, Point[] InnerPoints)> StarCoordinates = new(GetStarGlyphPoints);
private readonly DispatcherTimer dispatcherTimer = new(DispatcherPriority.ApplicationIdle);
private readonly List<Position> mainPlayerPositionHistory = new();
private readonly IGuildwarsEntityDebouncer guildwarsEntityDebouncer;
private readonly Color positionHistoryColor = Color.FromArgb(155, Colors.Red.R, Colors.Red.G, Colors.Red.B);
private readonly TimeSpan offsetRevertDelay = TimeSpan.FromSeconds(3);
private bool resizeEntities;
private bool dragging;
private double mapVirtualMinWidth;
private double mapVirtualMinHeight;
private double mapWidth;
private double mapHeight;
private DateTime offsetRevertTime = DateTime.Now;
private double offsetRevert = 0;
private Point originPoint = new(0, 0);
private System.Windows.Vector originOffset = new(0, 0);
private Point initialClickPoint = new(0, 0);
private DebounceResponse? cachedDebounceResponse;
[GenerateDependencyProperty]
private PathingData pathingData = new();
[GenerateDependencyProperty]
private GameData gameData = new();
[GenerateDependencyProperty]
private double zoom = 0.08;
[GenerateDependencyProperty(InitialValue = true)]
private bool drawPositionHistory = true;
[GenerateDependencyProperty]
private bool controlsVisible;
public event EventHandler? MaximizeClicked;
public event EventHandler<QuestMetadata>? QuestMetadataClicked;
public GuildwarsMinimap()
:this(Launch.Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IGuildwarsEntityDebouncer>())
{
}
public GuildwarsMinimap(
IGuildwarsEntityDebouncer guildwarsEntityDebouncer)
{
this.guildwarsEntityDebouncer = guildwarsEntityDebouncer.ThrowIfNull();
this.dispatcherTimer.Tick += (_, _) => this.ApplyOffsetRevert();
this.dispatcherTimer.Interval = TimeSpan.FromMilliseconds(16);
this.InitializeComponent();
}
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (e.Property == ActualHeightProperty ||
e.Property == ActualWidthProperty)
{
this.resizeEntities = true;
}
else if (e.Property == PathingDataProperty)
{
this.guildwarsEntityDebouncer.ClearCaches();
this.mainPlayerPositionHistory.Clear();
this.UpdateGameData();
this.DrawMap();
}
else if (e.Property == ZoomProperty)
{
this.UpdateGameData();
}
else if (e.Property == GameDataProperty &&
this.GameData.Valid)
{
this.UpdateGameData();
}
}
private void UpdateGameData()
{
if(this.GameData.Valid is false)
{
return;
}
var debounceResponse = this.guildwarsEntityDebouncer.DebounceEntities(this.GameData);
if (!double.IsFinite(this.mapWidth) ||
!double.IsFinite(this.mapHeight) ||
!double.IsFinite(this.mapVirtualMinWidth) ||
!double.IsFinite(this.mapVirtualMinHeight))
{
return;
}
var screenVirtualWidth = this.ActualWidth / this.Zoom;
var screenVirtualHeight = this.ActualHeight / this.Zoom;
var position = debounceResponse.MainPlayer.Position!.Value;
this.originPoint = new Point(
position.X - (screenVirtualWidth / 2) - (this.originOffset.X / this.Zoom),
position.Y + (screenVirtualHeight / 2) + (this.originOffset.Y / this.Zoom));
var adjustedPosition = new Point((int)((position.X - this.mapVirtualMinWidth) * this.Zoom), (int)(this.mapHeight - position.Y + this.mapVirtualMinHeight) * this.Zoom);
this.MapDrawingHost.Margin = new Thickness(
-adjustedPosition.X + (this.ActualWidth / 2) + this.originOffset.X,
-adjustedPosition.Y + (this.ActualHeight / 2) + this.originOffset.Y,
0,
0);
this.MapDrawingHost.Height = this.mapHeight * this.Zoom;
this.MapDrawingHost.Width = this.mapWidth * this.Zoom;
this.ManageMainPlayerPositionHistory();
this.DrawEntities(debounceResponse);
this.cachedDebounceResponse = debounceResponse;
}
private void ManageMainPlayerPositionHistory()
{
if (this.cachedDebounceResponse is null)
{
return;
}
var currentPosition = this.cachedDebounceResponse.MainPlayer.Position ?? throw new InvalidOperationException("Unexpected main player null position");
if (this.mainPlayerPositionHistory.Any(oldPosition => PositionsCollide(oldPosition, currentPosition)))
{
return;
}
this.mainPlayerPositionHistory.Add(currentPosition);
}
private void DrawMap()
{
if (this.PathingData.Trapezoids is null)
{
return;
}
var maxWidth = double.MinValue;
var maxHeight = double.MinValue;
var minWidth = double.MaxValue;
var minHeight = double.MaxValue;
foreach (var trapezoid in this.PathingData.Trapezoids!)
{
if (trapezoid.YT < minHeight)
{
minHeight = trapezoid.YT;
}
if (trapezoid.YB > maxHeight)
{
maxHeight = trapezoid.YB;
}
if (trapezoid.XTL < minWidth)
{
minWidth = trapezoid.XTL;
}
if (trapezoid.XBL < minWidth)
{
minWidth = trapezoid.XBL;
}
if (trapezoid.XTR > maxWidth)
{
maxWidth = trapezoid.XTR;
}
if (trapezoid.XBR > maxWidth)
{
maxWidth = trapezoid.XBR;
}
}
var width = maxWidth - minWidth;
var height = maxHeight - minHeight;
this.mapVirtualMinHeight = minHeight;
this.mapVirtualMinWidth = minWidth;
this.mapWidth = width;
this.mapHeight = height;
if (width <= 0 || height <= 0 ||
!double.IsFinite(width) ||
!double.IsFinite(height))
{
return;
}
var bitmap = BitmapFactory.New((int)(width / MapDownscaleFactor), (int)(height / MapDownscaleFactor));
this.MapDrawingHost.Source = bitmap;
this.MapDrawingHost.Width = width / MapDownscaleFactor;
this.MapDrawingHost.Height = height / MapDownscaleFactor;
using var bitmapContext = bitmap.GetBitmapContext();
bitmap.Clear(Colors.Transparent);
foreach (var trapezoid in this.PathingData.Trapezoids!)
{
var a = new Point((int)((trapezoid.XTL - minWidth) / MapDownscaleFactor), (int)((height - trapezoid.YT + minHeight) / MapDownscaleFactor));
var b = new Point((int)((trapezoid.XTR - minWidth) / MapDownscaleFactor), (int)((height - trapezoid.YT + minHeight) / MapDownscaleFactor));
var c = new Point((int)((trapezoid.XBR - minWidth) / MapDownscaleFactor), (int)((height - trapezoid.YB + minHeight) / MapDownscaleFactor));
var d = new Point((int)((trapezoid.XBL - minWidth) / MapDownscaleFactor), (int)((height - trapezoid.YB + minHeight) / MapDownscaleFactor));
var e = new Point((int)((trapezoid.XTL - minWidth) / MapDownscaleFactor), (int)((height - trapezoid.YT + minHeight) / MapDownscaleFactor));
bitmap.FillPolygon(new int[] { (int)a.X, (int)a.Y, (int)b.X, (int)b.Y, (int)c.X, (int)c.Y, (int)d.X, (int)d.Y, (int)e.X, (int)e.Y, (int)a.X, (int)a.Y }, Colors.White);
}
}
private void DrawEntities(DebounceResponse debounceResponse)
{
if (this.EntitiesDrawingHost.Source is not WriteableBitmap bitmap || this.resizeEntities)
{
bitmap = BitmapFactory.New((int)this.ActualWidth, (int)this.ActualHeight);
this.EntitiesDrawingHost.Source = bitmap;
this.resizeEntities = false;
}
bitmap.Clear(Colors.Transparent);
using var context = bitmap.GetBitmapContext();
this.DrawMainPlayerPositionHistory(bitmap);
this.FillEllipse(debounceResponse.MainPlayer.Position, bitmap, Colors.Green);
foreach (var partyMember in debounceResponse.Party.Where(p => IsValidPositionalEntity(p)))
{
this.FillEllipse(partyMember.Position, bitmap, Colors.Green);
}
foreach (var player in debounceResponse.WorldPlayers.Where(p => IsValidPositionalEntity(p)))
{
this.FillEllipse(player.Position, bitmap, Colors.CornflowerBlue);
}
foreach (var livingEntity in debounceResponse.LivingEntities.Where(p => IsValidPositionalEntity(p)))
{
if (livingEntity.State is LivingEntityState.ToBeCleanedUp)
{
continue;
}
else if (livingEntity.State is LivingEntityState.Dead)
{
this.FillEllipse(livingEntity.Position, bitmap, Colors.Gray);
}
else if (livingEntity.State is LivingEntityState.Boss)
{
this.FillStar(livingEntity.Position, bitmap, Colors.DarkRed);
}
else if (livingEntity.Allegiance is LivingEntityAllegiance.AllyNonAttackable)
{
this.FillEllipse(livingEntity.Position, bitmap, Colors.Green);
}
else if (livingEntity.Allegiance is LivingEntityAllegiance.Neutral)
{
this.FillEllipse(livingEntity.Position, bitmap, Colors.LightSteelBlue);
}
else if (livingEntity.Allegiance is LivingEntityAllegiance.Enemy)
{
this.FillTriangle(livingEntity.Position, bitmap, Colors.Red);
}
else if (livingEntity.Allegiance is LivingEntityAllegiance.SpiritOrPet)
{
this.FillTriangle(livingEntity.Position, bitmap, Colors.Green);
}
else if (livingEntity.Allegiance is LivingEntityAllegiance.Minion)
{
this.FillTriangle(livingEntity.Position, bitmap, Colors.Green);
}
else if (livingEntity.Allegiance is LivingEntityAllegiance.NpcOrMinipet)
{
this.FillTriangle(livingEntity.Position, bitmap, Colors.LimeGreen);
}
}
this.DrawQuestObjectives(bitmap);
}
private void DrawQuestObjectives(WriteableBitmap writeableBitmap)
{
var currentMapQuests = this.GameData.MainPlayer!.Value.QuestLog!
.Where(v => v.Position.GetValueOrDefault().X != 0 && v.Position.GetValueOrDefault().Y != 0);
var screenVirtualWidth = this.ActualWidth / this.Zoom;
var screenVirtualHeight = this.ActualHeight / this.Zoom;
foreach (var questMetaData in currentMapQuests)
{
if (!this.EntityOnScreen(questMetaData.Position, writeableBitmap, out var x, out var y))
{
var questPoint = new Point(questMetaData.Position!.Value.X, questMetaData.Position.Value.Y);
var position = new Position
{
X = (float)Math.Clamp(
questPoint.X,
Math.Min(this.originPoint.X + (EntitySize * this.Zoom), this.originPoint.X + screenVirtualWidth - (EntitySize * this.Zoom)),
Math.Max(this.originPoint.X + (EntitySize * this.Zoom), this.originPoint.X + screenVirtualWidth - (EntitySize * this.Zoom))),
Y = (float)Math.Clamp(
questPoint.Y,
Math.Min(this.originPoint.Y - screenVirtualHeight + (EntitySize * this.Zoom), this.originPoint.Y - (EntitySize * this.Zoom)),
Math.Max(this.originPoint.Y - screenVirtualHeight + (EntitySize * this.Zoom), this.originPoint.Y - (EntitySize * this.Zoom))),
};
this.FillStar(position, writeableBitmap, Colors.BlueViolet);
}
else
{
this.FillStar(questMetaData.Position, writeableBitmap, Colors.BlueViolet);
}
}
}
private void DrawMainPlayerPositionHistory(WriteableBitmap writeableBitmap)
{
if (!this.DrawPositionHistory)
{
return;
}
if (this.cachedDebounceResponse is null)
{
return;
}
foreach(var position in this.mainPlayerPositionHistory)
{
this.FillEllipse(position, writeableBitmap, this.positionHistoryColor);
}
}
private void FillStar(Position? position, WriteableBitmap bitmap, Color color)
{
if (!this.EntityOnScreen(position, bitmap, out var x, out var y))
{
return;
}
(var outerPoints, var innerPoints) = StarCoordinates.Value;
for(var i = 1; i <= 5; i++)
{
var outerPoint = outerPoints[i % 5];
var innerPointPrev = innerPoints[(i - 1) % 5];
var innerPointNext = innerPoints[(i + 1) % 5];
bitmap.FillTriangle(
x + (int)(innerPointPrev.X * this.Zoom), y + (int)(innerPointPrev.Y * this.Zoom),
x + (int)(outerPoint.X * this.Zoom), y + (int)(outerPoint.Y * this.Zoom),
x + (int)(innerPointNext.X * this.Zoom), y + (int)(innerPointNext.Y * this.Zoom),
color);
}
bitmap.FillTriangle(
x + (int)(innerPoints[0].X * this.Zoom), y + (int)(innerPoints[0].Y * this.Zoom),
x + (int)(innerPoints[1].X * this.Zoom), y + (int)(innerPoints[1].Y * this.Zoom),
x + (int)(innerPoints[2].X * this.Zoom), y + (int)(innerPoints[2].Y * this.Zoom),
color);
bitmap.FillTriangle(
x + (int)(innerPoints[2].X * this.Zoom), y + (int)(innerPoints[2].Y * this.Zoom),
x + (int)(innerPoints[3].X * this.Zoom), y + (int)(innerPoints[3].Y * this.Zoom),
x + (int)(innerPoints[4].X * this.Zoom), y + (int)(innerPoints[4].Y * this.Zoom),
color);
bitmap.FillTriangle(
x + (int)(innerPoints[0].X * this.Zoom), y + (int)(innerPoints[0].Y * this.Zoom),
x + (int)(innerPoints[2].X * this.Zoom), y + (int)(innerPoints[2].Y * this.Zoom),
x + (int)(innerPoints[4].X * this.Zoom), y + (int)(innerPoints[4].Y * this.Zoom),
color);
}
private void FillEllipse(Position? position, WriteableBitmap bitmap, Color color)
{
if (!this.EntityOnScreen(position, bitmap, out var x, out var y))
{
return;
}
bitmap.FillEllipseCentered(
x,
y,
(int)(EntitySize * this.Zoom),
(int)(EntitySize * this.Zoom),
color);
}
private void FillTriangle(Position? position, WriteableBitmap bitmap, Color color)
{
if (!this.EntityOnScreen(position, bitmap, out _, out _))
{
return;
}
bitmap.FillTriangle(
(int)((position!.Value.X - this.originPoint.X - EntitySize) * this.Zoom),
0 - (int)((position.Value.Y - this.originPoint.Y + EntitySize) * this.Zoom),
(int)((position.Value.X - this.originPoint.X) * this.Zoom),
0 - (int)((position.Value.Y - this.originPoint.Y - EntitySize) * this.Zoom),
(int)((position.Value.X - this.originPoint.X + EntitySize) * this.Zoom),
0 - (int)((position.Value.Y - this.originPoint.Y + EntitySize) * this.Zoom),
color);
}
private bool EntityOnScreen(Position? position, WriteableBitmap bitmap, out int x, out int y)
{
x = 0;
y = 0;
if (position.HasValue is false)
{
return false;
}
x = (int)((position.Value.X - this.originPoint.X) * this.Zoom);
y = 0 - (int)((position.Value.Y - this.originPoint.Y) * this.Zoom);
if (x < 0 || x > bitmap.Width ||
y < 0 || y > bitmap.Height)
{
return false;
}
return true;
}
private bool MouseOverEntity(IPositionalEntity entity, Point mousePosition)
{
var x = (int)((entity.Position!.Value.X - this.originPoint.X) * this.Zoom);
var y = 0 - (int)((entity.Position!.Value.Y - this.originPoint.Y) * this.Zoom);
return Math.Pow(mousePosition.X - x, 2) + Math.Pow(mousePosition.Y - y, 2) < Math.Pow(EntitySize * this.Zoom, 2);
}
private void DragMinimap()
{
if (this.dragging is false)
{
return;
}
var mousePosition = Mouse.GetPosition(this);
this.offsetRevert = 0;
this.originOffset = mousePosition - this.initialClickPoint;
this.offsetRevertTime = DateTime.Now + this.offsetRevertDelay;
this.UpdateGameData();
}
private void ApplyOffsetRevert()
{
if (DateTime.Now < this.offsetRevertTime)
{
return;
}
this.offsetRevert = 0.0001 + (this.offsetRevert * 1.0001);
this.offsetRevert = Math.Min(99, this.offsetRevert);
this.originOffset /= 1 + this.offsetRevert;
this.UpdateGameData();
}
private IPositionalEntity? CheckMouseOverEntity(IEnumerable<IPositionalEntity>? maybeEntities)
{
if (maybeEntities is not IEnumerable<IPositionalEntity> entities)
{
return default;
}
if (this.GameData.Valid is false)
{
return default;
}
var mousePoint = Mouse.GetPosition(this);
foreach(var entity in entities)
{
if (this.MouseOverEntity(entity, mousePoint))
{
this.Cursor = Cursors.Hand;
return entity;
}
}
this.Cursor = default;
return default;
}
private void GuildwarsMinimap_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.initialClickPoint = Mouse.GetPosition(this) - this.originOffset;
this.offsetRevert = 0;
this.offsetRevertTime = DateTime.Now + this.offsetRevertDelay;
this.dragging = true;
}
private void GuildwarsMinimap_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
this.dragging = false;
}
private void GuildwarsMinimap_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
var maybeQuestMetadata = this.CheckMouseOverEntity(this.GameData.MainPlayer?.QuestLog?.OfType<IPositionalEntity>().Where(IsValidPositionalEntity));
if (maybeQuestMetadata is QuestMetadata questMetadata &&
this.TryFindResource("QuestContextMenu") is ContextMenu questContextMenu)
{
this.ContextMenu = questContextMenu;
this.ContextMenu.DataContext = questMetadata;
this.ContextMenu.IsOpen = true;
return;
}
if (this.CheckMouseOverEntity(Enumerable.Repeat(this.GameData.MainPlayer.As<IEntity>(), 1)) is MainPlayerInformation &&
this.TryFindResource("MainPlayerContextMenu") is ContextMenu mainPlayerContextMenu)
{
this.ContextMenu = mainPlayerContextMenu;
this.ContextMenu.DataContext = this.GameData.MainPlayer;
this.ContextMenu.IsOpen = true;
return;
}
var maybeWorldPlayer = this.CheckMouseOverEntity(this.GameData.WorldPlayers?.OfType<IEntity>().Where(IsValidPositionalEntity));
if (maybeWorldPlayer is WorldPlayerInformation worldPlayerInformation &&
this.TryFindResource("WorldPlayerContextMenu") is ContextMenu worldPlayerContextMenu)
{
this.ContextMenu = worldPlayerContextMenu;
this.ContextMenu.DataContext = worldPlayerInformation;
this.ContextMenu.IsOpen = true;
return;
}
var maybePartyMember = this.CheckMouseOverEntity(this.GameData.Party?.OfType<IEntity>().Where(IsValidPositionalEntity));
if (maybePartyMember is PlayerInformation partyMember &&
this.TryFindResource("PlayerContextMenu") is ContextMenu playerContextMenu)
{
this.ContextMenu = playerContextMenu;
this.ContextMenu.DataContext = partyMember;
this.ContextMenu.IsOpen = true;
return;
}
var maybeLivingEntity = this.CheckMouseOverEntity(this.GameData.LivingEntities?.OfType<IEntity>().Where(IsValidPositionalEntity));
if (maybeLivingEntity is LivingEntity livingEntity &&
this.TryFindResource("LivingEntityContextMenu") is ContextMenu livingEntityContextMenu)
{
this.ContextMenu = livingEntityContextMenu;
this.ContextMenu.DataContext = livingEntity;
this.ContextMenu.IsOpen = true;
return;
}
this.ContextMenu = default;
}
private void GuildwarsMinimap_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
}
private void GuildwarsMinimap_MouseMove(object sender, MouseEventArgs e)
{
if (this.GameData.Valid is false)
{
return;
}
this.DragMinimap();
if (this.CheckMouseOverEntity(this.GameData.Party!.OfType<IEntity>()) is not null)
{
return;
}
if (this.CheckMouseOverEntity(this.GameData.WorldPlayers!.OfType<IEntity>()) is not null)
{
return;
}
if (this.CheckMouseOverEntity(Enumerable.Repeat(this.GameData.MainPlayer.As<IEntity>(), 1)) is not null)
{
return;
}
if (this.CheckMouseOverEntity(this.GameData.LivingEntities!.OfType<IEntity>()) is not null)
{
return;
}
if (this.CheckMouseOverEntity(this.GameData.MainPlayer!.Value.QuestLog!.OfType<IPositionalEntity>()) is not null)
{
return;
}
}
private void GuildwarsMinimap_MouseWheel(object sender, MouseWheelEventArgs e)
{
var delta = e.Delta > 0 ? 0.1 : -0.1;
this.Zoom += this.Zoom * delta;
}
private void GuildwarsMinimap_Loaded(object sender, RoutedEventArgs e)
{
this.dispatcherTimer.Start();
}
private void GuildwarsMinimap_Unloaded(object sender, RoutedEventArgs e)
{
this.dispatcherTimer.Stop();
}
private void QuestContextMenu_QuestContextMenuClicked(object _, QuestMetadata? quest)
{
if (quest is not QuestMetadata)
{
return;
}
this.QuestMetadataClicked?.Invoke(this, quest.Value);
}
private void MaximizeButton_Clicked(object sender, EventArgs e)
{
this.MaximizeClicked?.Invoke(this, e);
if (e is MouseButtonEventArgs mouseButtonEventArgs)
{
mouseButtonEventArgs.Handled = true;
}
}
private static bool PositionsCollide(Position position1, Position position2)
{
var a = PositionRadius + PositionRadius;
var dx = position1.X - position2.X;
var dy = position1.Y - position2.Y;
return a * a > ((dx * dx) + (dy * dy));
}
private static bool IsValidPositionalEntity(IPositionalEntity entity)
{
if (entity.Position?.X == 0 &&
entity.Position?.Y == 0)
{
return false;
}
return true;
}
private static (Point[] OuterPoints, Point[] InnerPoints) GetStarGlyphPoints()
{
var entitySize = EntitySize * 1.5;
var halfSize = entitySize / 2;
var outerPoints = new Point[]
{
new Point(entitySize * Math.Cos((2 * Math.PI * 0 / 5) - (Math.PI / 10)), entitySize * Math.Sin((2 * Math.PI * 0 / 5) - (Math.PI / 10))),
new Point(entitySize * Math.Cos((2 * Math.PI * 1 / 5) - (Math.PI / 10)), entitySize * Math.Sin((2 * Math.PI * 1 / 5) - (Math.PI / 10))),
new Point(entitySize * Math.Cos((2 * Math.PI * 2 / 5) - (Math.PI / 10)), entitySize * Math.Sin((2 * Math.PI * 2 / 5) - (Math.PI / 10))),
new Point(entitySize * Math.Cos((2 * Math.PI * 3 / 5) - (Math.PI / 10)), entitySize * Math.Sin((2 * Math.PI * 3 / 5) - (Math.PI / 10))),
new Point(entitySize * Math.Cos((2 * Math.PI * 4 / 5) - (Math.PI / 10)), entitySize * Math.Sin((2 * Math.PI * 4 / 5) - (Math.PI / 10))),
};
var innerPoints = new Point[]
{
new Point(halfSize * Math.Cos((2 * Math.PI * 0 / 5) + (2 * Math.PI / 10) - (Math.PI / 10)), halfSize * Math.Sin((2 * Math.PI * 0 / 5) + (2 * Math.PI / 10) - (Math.PI / 10))),
new Point(halfSize * Math.Cos((2 * Math.PI * 1 / 5) + (2 * Math.PI / 10) - (Math.PI / 10)), halfSize * Math.Sin((2 * Math.PI * 1 / 5) + (2 * Math.PI / 10) - (Math.PI / 10))),
new Point(halfSize * Math.Cos((2 * Math.PI * 2 / 5) + (2 * Math.PI / 10) - (Math.PI / 10)), halfSize * Math.Sin((2 * Math.PI * 2 / 5) + (2 * Math.PI / 10) - (Math.PI / 10))),
new Point(halfSize * Math.Cos((2 * Math.PI * 3 / 5) + (2 * Math.PI / 10) - (Math.PI / 10)), halfSize * Math.Sin((2 * Math.PI * 3 / 5) + (2 * Math.PI / 10) - (Math.PI / 10))),
new Point(halfSize * Math.Cos((2 * Math.PI * 4 / 5) + (2 * Math.PI / 10) - (Math.PI / 10)), halfSize * Math.Sin((2 * Math.PI * 4 / 5) + (2 * Math.PI / 10) - (Math.PI / 10))),
};
return (outerPoints, innerPoints);
}
}
@@ -0,0 +1,37 @@
<UserControl x:Class="Daybreak.Controls.HorizontalResourceBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Daybreak.Controls"
mc:Ignorable="d"
x:Name="_this"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Viewbox VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Stretch="Fill">
<Grid Height="1">
<Rectangle
Fill="{Binding ElementName=_this, Path=BarColor, Mode=OneWay}"
VerticalAlignment="Stretch"
HorizontalAlignment="{Binding ElementName=_this, Path=FillAlignment, Mode=OneWay}"
Width="{Binding ElementName=_this, Path=MaxResourceValue, Mode=TwoWay}"></Rectangle>
<Rectangle
Fill="#F0202020"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"></Rectangle>
<Rectangle
Fill="{Binding ElementName=_this, Path=BarColor, Mode=OneWay}"
VerticalAlignment="Stretch"
HorizontalAlignment="{Binding ElementName=_this, Path=FillAlignment, Mode=OneWay}"
Width="{Binding ElementName=_this, Path=CurrentResourceValue, Mode=TwoWay}"></Rectangle>
</Grid>
</Viewbox>
<TextBlock
FontSize="{Binding ElementName=_this, Path=FontSize, Mode=OneWay}"
FontFamily="{Binding ElementName=_this, Path=FontFamily, Mode=OneWay}"
Text="{Binding ElementName=_this, Path=Text, Mode=OneWay}"
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
VerticalAlignment="Center"
HorizontalAlignment="Center"></TextBlock>
</Grid>
</UserControl>
@@ -0,0 +1,34 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Extensions;
using System.Windows.Media;
namespace Daybreak.Controls;
/// <summary>
/// Interaction logic for ResourceBar.xaml
/// </summary>
public partial class HorizontalResourceBar : UserControl
{
[GenerateDependencyProperty]
private double currentResourceValue;
[GenerateDependencyProperty]
private double maxResourceValue;
[GenerateDependencyProperty]
private Brush barColor;
[GenerateDependencyProperty]
private string text;
[GenerateDependencyProperty(InitialValue = HorizontalAlignment.Left)]
private HorizontalAlignment fillAlignment;
public HorizontalResourceBar()
{
this.InitializeComponent();
this.MaxResourceValue = 1;
this.CurrentResourceValue = 0;
this.barColor = Brushes.Transparent;
this.text = string.Empty;
}
}
+73 -75
View File
@@ -1,93 +1,91 @@
using Daybreak.Utils;
using System;
using System;
using System.Windows;
using System.Windows.Controls;
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;
this.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 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);
}
}

Some files were not shown because too many files have changed in this diff Show More