mirror of
https://github.com/Microsoft/calculator.git
synced 2025-08-21 05:43:10 -07:00
Merged PR 9118731: Sync up to GitHub Repo main branch
Sync up to GitHub Repo main branch
This commit is contained in:
commit
4103f51be4
461 changed files with 29437 additions and 26432 deletions
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
|
@ -8,7 +8,7 @@ assignees: ''
|
|||
---
|
||||
|
||||
<!--
|
||||
See https://github.com/Microsoft/calculator/blob/master/docs/NewFeatureProcess.md for suggestions on how to write a good feature pitch. Just want to submit an idea quickly? Try Feedback Hub instead: https://insider.windows.com/en-us/fb/?contextid=130
|
||||
See https://github.com/Microsoft/calculator/blob/main/docs/NewFeatureProcess.md for suggestions on how to write a good feature pitch. Just want to submit an idea quickly? Try Feedback Hub instead: https://insider.windows.com/en-us/fb/?contextid=130
|
||||
-->
|
||||
|
||||
**Problem Statement**
|
||||
|
|
1550
.github/fabricbot.json
vendored
Normal file
1550
.github/fabricbot.json
vendored
Normal file
File diff suppressed because it is too large
Load diff
2
.github/pull_request_template.md
vendored
2
.github/pull_request_template.md
vendored
|
@ -7,7 +7,7 @@
|
|||
-
|
||||
|
||||
### How changes were validated:
|
||||
<!--Review https://github.com/Microsoft/calculator/blob/master/CONTRIBUTING.md and ensure all contributing requirements are met.
|
||||
<!--Review https://github.com/Microsoft/calculator/blob/main/CONTRIBUTING.md and ensure all contributing requirements are met.
|
||||
|
||||
Specify how you tested your changes (i.e. manual/ad-hoc testing, automated testing, new automated tests added)-->
|
||||
-
|
||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -93,6 +93,9 @@ ipch/
|
|||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Code
|
||||
.vscode/
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ should be used where automated testing is not feasible.
|
|||
|
||||
### Git workflow
|
||||
Calculator uses the [GitHub flow](https://guides.github.com/introduction/flow/) where most
|
||||
development happens directly on the `master` branch. The `master` branch should always be in a
|
||||
development happens directly on the `main` branch. The `main` branch should always be in a
|
||||
healthy state which is ready for release.
|
||||
|
||||
If your change is complex, please clean up the branch history before submitting a pull request.
|
||||
|
|
208
NOTICE.txt
208
NOTICE.txt
|
@ -37,211 +37,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
Appium DotNet Driver
|
||||
|
||||
Copyright 2014-2015 Appium Contributors
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# Calculator
|
||||
The Windows Calculator app is a modern Windows app written in C++ that ships pre-installed with Windows.
|
||||
The Windows Calculator app is a modern Windows app written in C++ and C# that ships pre-installed with Windows.
|
||||
The app provides standard, scientific, and programmer calculator functionality, as well as a set of converters between various units of measurement and currencies.
|
||||
|
||||
Calculator ships regularly with new features and bug fixes. You can get the latest version of Calculator in the [Microsoft Store](https://www.microsoft.com/store/apps/9WZDNCRFHVN5).
|
||||
|
||||
[](https://dev.azure.com/ms/calculator/_build/latest?definitionId=57&branchName=master)
|
||||
[](https://dev.azure.com/ms/calculator/_build/latest?definitionId=57&branchName=main)
|
||||
|
||||

|
||||
|
||||
|
@ -22,11 +22,11 @@ Calculator ships regularly with new features and bug fixes. You can get the late
|
|||
|
||||
## Getting started
|
||||
Prerequisites:
|
||||
- Your computer must be running Windows 10, version 1803 or newer.
|
||||
- Your computer must be running Windows 11, build 22000 or newer.
|
||||
- Install the latest version of [Visual Studio](https://developer.microsoft.com/en-us/windows/downloads) (the free community edition is sufficient).
|
||||
- Install the "Universal Windows Platform Development" workload.
|
||||
- Install the optional "C++ Universal Windows Platform tools" component.
|
||||
- Install the latest Windows 10 SDK.
|
||||
- Install the latest Windows 11 SDK.
|
||||
|
||||

|
||||
- Install the [XAML Styler](https://marketplace.visualstudio.com/items?itemName=TeamXavalon.XAMLStyler) Visual Studio extension.
|
||||
|
|
58
build/pipelines/azure-pipelines.ci-internal.yaml
Normal file
58
build/pipelines/azure-pipelines.ci-internal.yaml
Normal file
|
@ -0,0 +1,58 @@
|
|||
#
|
||||
# Continuous Integration (CI) - Internal
|
||||
# This pipeline builds and validate the app for all supported architectures, in a production
|
||||
# configuration. This pipeline relies on Microsoft-internal resources to run.
|
||||
#
|
||||
|
||||
trigger:
|
||||
- main
|
||||
- release/*
|
||||
- feature/*
|
||||
pr: none
|
||||
|
||||
name: 0.$(Date:yyMM).$(DayOfMonth)$(Rev:rr).0
|
||||
|
||||
jobs:
|
||||
- template: ./templates/build-single-architecture.yaml
|
||||
parameters:
|
||||
isReleaseBuild: true
|
||||
useReleaseAppxManifest: false
|
||||
platform: x64
|
||||
|
||||
- template: ./templates/build-single-architecture.yaml
|
||||
parameters:
|
||||
isReleaseBuild: true
|
||||
useReleaseAppxManifest: false
|
||||
platform: x86
|
||||
|
||||
- template: ./templates/build-single-architecture.yaml
|
||||
parameters:
|
||||
isReleaseBuild: true
|
||||
useReleaseAppxManifest: false
|
||||
platform: ARM
|
||||
|
||||
- template: ./templates/build-single-architecture.yaml
|
||||
parameters:
|
||||
isReleaseBuild: true
|
||||
useReleaseAppxManifest: false
|
||||
platform: ARM64
|
||||
|
||||
- template: ./templates/run-ui-tests.yaml
|
||||
parameters:
|
||||
platform: x64
|
||||
runsettingsFileName: CalculatorUITests.ci-internal.runsettings
|
||||
|
||||
- template: ./templates/run-ui-tests.yaml
|
||||
parameters:
|
||||
platform: x86
|
||||
runsettingsFileName: CalculatorUITests.ci-internal.runsettings
|
||||
|
||||
- template: ./templates/run-unit-tests.yaml
|
||||
parameters:
|
||||
platform: x64
|
||||
|
||||
- template: ./templates/run-unit-tests.yaml
|
||||
parameters:
|
||||
platform: x86
|
||||
|
||||
- template: ./templates/package-msixbundle.yaml
|
|
@ -1,51 +1,60 @@
|
|||
#
|
||||
# Continuous Integration (CI)
|
||||
# This pipeline builds and validate the app in all supported configurations. If the build was
|
||||
# queued to validate a pull request, we build and test only x64.
|
||||
# This pipeline builds and validate the app for all supported architectures, in a public
|
||||
# configuration. If the build was queued to validate a pull request, we build and test only x64.
|
||||
#
|
||||
|
||||
trigger:
|
||||
- master
|
||||
- main
|
||||
- release/*
|
||||
- feature/*
|
||||
pr:
|
||||
- master
|
||||
- main
|
||||
- release/*
|
||||
- feature/*
|
||||
|
||||
name: 0.$(Date:yyMM).$(DayOfMonth)$(Rev:rr).0
|
||||
|
||||
jobs:
|
||||
- template: ./templates/build-app-public.yaml
|
||||
- template: ./templates/build-single-architecture.yaml
|
||||
parameters:
|
||||
platform: x64
|
||||
isOSSBuild: true
|
||||
|
||||
- template: ./templates/build-app-public.yaml
|
||||
- template: ./templates/build-single-architecture.yaml
|
||||
parameters:
|
||||
platform: x86
|
||||
isOSSBuild: true
|
||||
condition: not(eq(variables['Build.Reason'], 'PullRequest'))
|
||||
|
||||
- template: ./templates/build-app-public.yaml
|
||||
- template: ./templates/build-single-architecture.yaml
|
||||
parameters:
|
||||
platform: ARM
|
||||
isOSSBuild: true
|
||||
condition: not(eq(variables['Build.Reason'], 'PullRequest'))
|
||||
|
||||
- template: ./templates/build-app-public.yaml
|
||||
- template: ./templates/build-single-architecture.yaml
|
||||
parameters:
|
||||
platform: ARM64
|
||||
isOSSBuild: true
|
||||
condition: not(eq(variables['Build.Reason'], 'PullRequest'))
|
||||
|
||||
- template: ./templates/run-ui-tests.yaml
|
||||
parameters:
|
||||
platform: x64
|
||||
isOSSBuild: true
|
||||
runsettingsFileName: CalculatorUITests.ci.runsettings
|
||||
|
||||
- template: ./templates/run-unit-tests.yaml
|
||||
parameters:
|
||||
platform: x64
|
||||
isOSSBuild: true
|
||||
|
||||
- template: ./templates/run-unit-tests.yaml
|
||||
parameters:
|
||||
platform: x86
|
||||
isOSSBuild: true
|
||||
|
||||
- template: ./templates/package-appxbundle.yaml
|
||||
- template: ./templates/package-msixbundle.yaml
|
||||
parameters:
|
||||
isOSSBuild: true
|
||||
|
|
|
@ -12,7 +12,7 @@ schedules:
|
|||
displayName: Daily sync
|
||||
branches:
|
||||
include:
|
||||
- master
|
||||
- main
|
||||
always: true
|
||||
|
||||
trigger: none
|
||||
|
@ -23,7 +23,7 @@ name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr)
|
|||
jobs:
|
||||
- job: Localize
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
name: EssentialExperiences-windows-2022
|
||||
variables:
|
||||
skipComponentGovernanceDetection: true
|
||||
steps:
|
||||
|
@ -51,4 +51,4 @@ jobs:
|
|||
condition: eq(variables['hasChanges'], '1')
|
||||
inputs:
|
||||
artifactName: Patch
|
||||
targetPath: $(Build.ArtifactStagingDirectory)
|
||||
targetPath: $(Build.ArtifactStagingDirectory)
|
||||
|
|
|
@ -4,37 +4,43 @@
|
|||
# Store and the Windows image. This pipeline relies on Microsoft-internal resources to run.
|
||||
#
|
||||
|
||||
schedules:
|
||||
- cron: "0 7 * * *"
|
||||
displayName: Daily midnight build
|
||||
branches:
|
||||
include:
|
||||
- master
|
||||
|
||||
trigger: none
|
||||
pr: none
|
||||
|
||||
variables:
|
||||
versionMajor: 10
|
||||
versionMinor: 2103
|
||||
versionBuild: $[counter('10.2103.*', 0)]
|
||||
versionMajor: 11
|
||||
versionMinor: 2305
|
||||
versionBuild: $[counter(format('{0}.{1}.*', variables['versionMajor'], variables['versionMinor']), 0)]
|
||||
versionPatch: 0
|
||||
|
||||
name: '$(versionMajor).$(versionMinor).$(versionBuild).$(versionPatch)'
|
||||
|
||||
jobs:
|
||||
- template: ./templates/build-app-internal.yaml
|
||||
- template: ./templates/build-single-architecture.yaml
|
||||
parameters:
|
||||
platform: x64
|
||||
isReleaseBuild: true
|
||||
useReleaseAppxmanifest: true
|
||||
|
||||
- template: ./templates/build-app-internal.yaml
|
||||
- template: ./templates/build-single-architecture.yaml
|
||||
parameters:
|
||||
platform: x86
|
||||
isReleaseBuild: true
|
||||
useReleaseAppxmanifest: true
|
||||
condition: not(eq(variables['Build.Reason'], 'PullRequest'))
|
||||
|
||||
- template: ./templates/build-app-internal.yaml
|
||||
- template: ./templates/build-single-architecture.yaml
|
||||
parameters:
|
||||
platform: ARM
|
||||
isReleaseBuild: true
|
||||
useReleaseAppxmanifest: true
|
||||
condition: not(eq(variables['Build.Reason'], 'PullRequest'))
|
||||
|
||||
- template: ./templates/build-single-architecture.yaml
|
||||
parameters:
|
||||
platform: ARM64
|
||||
isReleaseBuild: true
|
||||
useReleaseAppxmanifest: true
|
||||
condition: not(eq(variables['Build.Reason'], 'PullRequest'))
|
||||
|
||||
- template: ./templates/run-ui-tests.yaml
|
||||
|
@ -55,8 +61,10 @@ jobs:
|
|||
parameters:
|
||||
platform: x86
|
||||
|
||||
- template: ./templates/package-appxbundle.yaml
|
||||
- template: ./templates/package-msixbundle.yaml
|
||||
parameters:
|
||||
signBundle: true
|
||||
createStoreBrokerPackages: true
|
||||
|
||||
- template: ./templates/prepare-release-internalonly.yaml
|
||||
- template: ./templates/release-store.yaml
|
||||
- template: ./templates/release-vpack.yaml
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
# This template contains a job to build the app for a single architecture and run static analysis
|
||||
# tools on the binaries.
|
||||
# The app is built in a production configuration to be released to the Store and the Windows image.
|
||||
# This job relies on Microsoft-internal resources to run.
|
||||
|
||||
parameters:
|
||||
platform: ''
|
||||
condition: ''
|
||||
|
||||
jobs:
|
||||
- job: Build${{ parameters.platform }}
|
||||
displayName: Build ${{ parameters.platform }}
|
||||
condition: ${{ parameters.condition }}
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
variables:
|
||||
BuildConfiguration: Release
|
||||
BuildPlatform: ${{ parameters.platform }}
|
||||
steps:
|
||||
- checkout: self
|
||||
fetchDepth: 1
|
||||
|
||||
- task: UniversalPackages@0
|
||||
displayName: Download internals package
|
||||
inputs:
|
||||
command: download
|
||||
downloadDirectory: $(Build.SourcesDirectory)
|
||||
vstsFeed: WindowsInboxApps
|
||||
vstsFeedPackage: calculator-internals
|
||||
vstsPackageVersion: 0.0.54
|
||||
|
||||
- template: ./build-single-architecture.yaml
|
||||
parameters:
|
||||
extraMsBuildArgs: '/p:IsStoreBuild=true'
|
||||
|
||||
- task: PublishSymbols@2
|
||||
displayName: Publish symbols
|
||||
inputs:
|
||||
symbolsFolder: $(Build.BinariesDirectory)\$(BuildConfiguration)\$(BuildPlatform)
|
||||
searchPattern: '**/*.pdb'
|
||||
symbolServerType: teamServices
|
||||
treatNotIndexedAsWarning: true
|
||||
symbolsArtifactName: $(System.teamProject)/$(Build.BuildNumber)_$(BuildPlatform)$(BuildConfiguration)
|
||||
|
||||
- task: securedevelopmentteam.vss-secure-development-tools.build-task-binskim.BinSkim@3
|
||||
displayName: Run BinSkim
|
||||
inputs:
|
||||
inputType: Basic
|
||||
analyzeTarget: $(Build.BinariesDirectory)\$(BuildConfiguration)\$(BuildPlatform)\Calculator\*
|
||||
analyzeVerbose: true
|
||||
analyzeHashes: true
|
||||
continueOnError: true
|
||||
|
||||
- task: securedevelopmentteam.vss-secure-development-tools.build-task-policheck.PoliCheck@1
|
||||
displayName: Run PoliCheck
|
||||
inputs:
|
||||
targetType: F
|
||||
|
||||
- task: securedevelopmentteam.vss-secure-development-tools.build-task-publishsecurityanalysislogs.PublishSecurityAnalysisLogs@2
|
||||
displayName: Publish security analysis logs
|
||||
|
||||
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
|
||||
displayName: Detect open source components
|
||||
inputs:
|
||||
sourceScanPath: $(Agent.BuildDirectory)
|
|
@ -1,21 +0,0 @@
|
|||
# This template contains a job to build the app for a single architecture.
|
||||
# Only the contents of the public repository are built; internal resources are not used.
|
||||
|
||||
parameters:
|
||||
platform: ''
|
||||
condition: ''
|
||||
|
||||
jobs:
|
||||
- job: Build${{ parameters.platform }}
|
||||
displayName: Build ${{ parameters.platform }}
|
||||
condition: ${{ parameters.condition }}
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
variables:
|
||||
BuildConfiguration: Release
|
||||
BuildPlatform: ${{ parameters.platform }}
|
||||
steps:
|
||||
- checkout: self
|
||||
fetchDepth: 1
|
||||
|
||||
- template: ./build-single-architecture.yaml
|
|
@ -1,18 +1,58 @@
|
|||
# This template contains steps to build the app for a single architecture.
|
||||
# The job containing these steps must set the variables 'BuildConfiguration' and 'BuildPlatform'.
|
||||
# This template contains a job to build the app for a single architecture.
|
||||
|
||||
parameters:
|
||||
extraMsBuildArgs: ''
|
||||
isReleaseBuild: false
|
||||
isOSSBuild: false
|
||||
useReleaseAppxManifest: false
|
||||
platform: ''
|
||||
condition: ''
|
||||
|
||||
jobs:
|
||||
- job: Build${{ parameters.platform }}
|
||||
displayName: Build ${{ parameters.platform }}
|
||||
condition: ${{ parameters.condition }}
|
||||
pool:
|
||||
${{ if eq(parameters.isOSSBuild, true) }}:
|
||||
name: EssentialExperiencesOpenSource-windows-2022
|
||||
${{ if eq(parameters.isOSSBuild, false) }}:
|
||||
name: EssentialExperiences-windows-2022
|
||||
variables:
|
||||
BuildConfiguration: Release
|
||||
BuildPlatform: ${{ parameters.platform }}
|
||||
${{ if eq(parameters.isReleaseBuild, true) }}:
|
||||
${{ if eq(parameters.useReleaseAppxManifest, true) }}:
|
||||
ExtraMSBuildArgs: '/p:IsStoreBuild=true /p:UseReleaseAppxManifest=true'
|
||||
${{ if eq(parameters.useReleaseAppxManifest, false) }}:
|
||||
ExtraMSBuildArgs: '/p:IsStoreBuild=true'
|
||||
${{ if eq(parameters.isReleaseBuild, false) }}:
|
||||
${{ if eq(parameters.useReleaseAppxManifest, true) }}:
|
||||
ExtraMSBuildArgs: '/p:UseReleaseAppxManifest=true'
|
||||
${{ if eq(parameters.useReleaseAppxManifest, false) }}:
|
||||
ExtraMSBuildArgs: ''
|
||||
${{ if eq(parameters.useReleaseAppxManifest, false) }}:
|
||||
ManifestFileName: 'Package.appxmanifest'
|
||||
${{ if eq(parameters.useReleaseAppxManifest, true) }}:
|
||||
ManifestFileName: 'Package.Release.appxmanifest'
|
||||
steps:
|
||||
- checkout: self
|
||||
fetchDepth: 1
|
||||
|
||||
- ${{ if eq(parameters.isReleaseBuild, true) }}:
|
||||
- task: UniversalPackages@0
|
||||
displayName: Download internals package
|
||||
inputs:
|
||||
command: download
|
||||
downloadDirectory: $(Build.SourcesDirectory)
|
||||
vstsFeed: WindowsInboxApps
|
||||
vstsFeedPackage: calculator-internals
|
||||
vstsPackageVersion: 0.0.105
|
||||
|
||||
steps:
|
||||
- task: NuGetToolInstaller@1
|
||||
displayName: Use NuGet 5.x
|
||||
displayName: Use NuGet 6.x
|
||||
inputs:
|
||||
versionSpec: 5.x
|
||||
versionSpec: 6.x
|
||||
|
||||
# In most accounts, you can just use 'NuGetCommand' instead of this GUID.
|
||||
# In the microsoft.visualstudio.com account, NuGetCommand is ambiguous so the GUID is needed.
|
||||
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
|
||||
- task: NuGetCommand@2
|
||||
displayName: NuGet restore src/Calculator.sln
|
||||
inputs:
|
||||
command: custom
|
||||
|
@ -22,21 +62,82 @@ steps:
|
|||
displayName: Set version number in AppxManifest
|
||||
inputs:
|
||||
filePath: $(Build.SourcesDirectory)\build\scripts\UpdateAppxManifestVersion.ps1
|
||||
arguments: '-AppxManifest $(Build.SourcesDirectory)\src\Calculator\Package.appxmanifest -Version $(Build.BuildNumber)'
|
||||
arguments: '-AppxManifest $(Build.SourcesDirectory)\src\Calculator\$(ManifestFileName) -Version $(Build.BuildNumber)'
|
||||
|
||||
- task: VSBuild@1
|
||||
displayName: 'Build solution src/Calculator.sln'
|
||||
inputs:
|
||||
solution: src/Calculator.sln
|
||||
vsVersion: 16.0
|
||||
msbuildArgs: /bl:$(Build.BinariesDirectory)\$(BuildConfiguration)\$(BuildPlatform)\Calculator.binlog /p:OutDir=$(Build.BinariesDirectory)\$(BuildConfiguration)\$(BuildPlatform)\ /p:GenerateProjectSpecificOutputFolder=true /p:AppVersion=$(Build.BuildNumber) /t:Publish /p:PublishDir=$(Build.BinariesDirectory)\$(BuildConfiguration)\$(BuildPlatform)\publish\ ${{ parameters.extraMsBuildArgs }}
|
||||
vsVersion: 17.0
|
||||
msbuildArgs: /bl:$(Build.BinariesDirectory)\$(BuildConfiguration)\$(BuildPlatform)\Calculator.binlog /p:OutDir=$(Build.BinariesDirectory)\$(BuildConfiguration)\$(BuildPlatform)\ /p:GenerateProjectSpecificOutputFolder=true /p:Version=$(Build.BuildNumber) /t:Publish /p:PublishDir=$(Build.BinariesDirectory)\$(BuildConfiguration)\$(BuildPlatform)\publish\ $(ExtraMSBuildArgs)
|
||||
platform: $(BuildPlatform)
|
||||
configuration: $(BuildConfiguration)
|
||||
maximumCpuCount: true
|
||||
|
||||
- ${{ if eq(parameters.isReleaseBuild, true) }}:
|
||||
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
|
||||
displayName: 'Generate Software Bill of Material(SBoM)'
|
||||
inputs:
|
||||
BuildDropPath: $(Build.BinariesDirectory)\$(BuildConfiguration)\$(BuildPlatform)\Calculator
|
||||
PackageName: 'Microsoft.WindowsCalculator'
|
||||
PackageVersion: $(Build.BuildNumber)
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish drop artifact
|
||||
inputs:
|
||||
artifactName: drop
|
||||
pathToPublish: $(Build.BinariesDirectory)
|
||||
parallel: true
|
||||
|
||||
- ${{ if eq(parameters.isReleaseBuild, true) }}:
|
||||
- task: PublishSymbols@2
|
||||
displayName: Publish symbols
|
||||
inputs:
|
||||
symbolsFolder: $(Build.BinariesDirectory)\$(BuildConfiguration)\$(BuildPlatform)
|
||||
searchPattern: '**/*.pdb'
|
||||
symbolServerType: teamServices
|
||||
treatNotIndexedAsWarning: true
|
||||
symbolsArtifactName: $(System.teamProject)/$(Build.BuildNumber)_$(BuildPlatform)$(BuildConfiguration)
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy Files for BinSkim analysis
|
||||
inputs:
|
||||
SourceFolder: '$(Build.BinariesDirectory)\$(BuildConfiguration)\$(BuildPlatform)\Calculator\'
|
||||
# Setting up a folder to store all the binary files that we need BinSkim to scan.
|
||||
# If we put more things than we produce pdbs for and can index (such as nuget packages that ship without pdbs), binskim will fail.
|
||||
# Below are ignored files
|
||||
# - clrcompression.dll
|
||||
# - WebView2Loader.dll
|
||||
# - Microsoft.Web.WebView2.Core.dll
|
||||
Contents: |
|
||||
**\*
|
||||
!**\clrcompression.dll
|
||||
!**\WebView2Loader.dll
|
||||
!**\Microsoft.Web.WebView2.Core.dll
|
||||
TargetFolder: '$(Agent.BuildDirectory)\binskim'
|
||||
CleanTargetFolder: true
|
||||
OverWrite: true
|
||||
flattenFolders: false
|
||||
analyzeTarget: '$(Agent.BuildDirectory)\binskim\*'
|
||||
|
||||
- task: securedevelopmentteam.vss-secure-development-tools.build-task-binskim.BinSkim@3
|
||||
displayName: Run BinSkim
|
||||
inputs:
|
||||
inputType: Basic
|
||||
analyzeTarget: '$(Agent.BuildDirectory)\binskim\*'
|
||||
analyzeVerbose: true
|
||||
analyzeHashes: true
|
||||
continueOnError: true
|
||||
|
||||
- task: securedevelopmentteam.vss-secure-development-tools.build-task-policheck.PoliCheck@1
|
||||
displayName: Run PoliCheck
|
||||
inputs:
|
||||
targetType: F
|
||||
|
||||
- task: securedevelopmentteam.vss-secure-development-tools.build-task-publishsecurityanalysislogs.PublishSecurityAnalysisLogs@2
|
||||
displayName: Publish security analysis logs
|
||||
|
||||
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
|
||||
displayName: Detect open source components
|
||||
inputs:
|
||||
sourceScanPath: $(Agent.BuildDirectory)
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
# This template contains a job which takes .appx packages which were built separately for each
|
||||
# architecture (arm, x86, etc.) and combines them into a single .appxbundle.
|
||||
|
||||
parameters:
|
||||
signBundle: false
|
||||
|
||||
jobs:
|
||||
- job: Package
|
||||
dependsOn:
|
||||
- Buildx64
|
||||
- Buildx86
|
||||
- BuildARM
|
||||
condition: |
|
||||
and
|
||||
(
|
||||
in(dependencies.Buildx64.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'),
|
||||
in(dependencies.Buildx86.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'),
|
||||
in(dependencies.BuildARM.result, 'Succeeded', 'SucceededWithIssues', 'Skipped')
|
||||
)
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
variables:
|
||||
skipComponentGovernanceDetection: true
|
||||
steps:
|
||||
- checkout: self
|
||||
fetchDepth: 1
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: Download all .appx artifacts
|
||||
inputs:
|
||||
artifactName: drop
|
||||
itemPattern: '**/*.appx'
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: Generate AppxBundle mapping
|
||||
inputs:
|
||||
filePath: $(Build.SourcesDirectory)\build\scripts\CreateAppxBundleMapping.ps1
|
||||
arguments: '-InputPath $(Build.ArtifactStagingDirectory)\drop\Release -ProjectName Calculator -OutputFile $(Build.BinariesDirectory)\AppxBundleMapping.txt'
|
||||
|
||||
- powershell: |
|
||||
$buildVersion = [version]$Env:BUILDVERSION
|
||||
$bundleVersion = "2020.$($buildVersion.Minor).$($buildVersion.Build).$($buildVersion.Revision)"
|
||||
& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x86\MakeAppx.exe" bundle /v /bv $bundleVersion /f $Env:MAPPINGFILEPATH /p $Env:OUTPUTPATH
|
||||
displayName: Make AppxBundle
|
||||
env:
|
||||
BUILDVERSION: $(Build.BuildNumber)
|
||||
MAPPINGFILEPATH: $(Build.BinariesDirectory)\AppxBundleMapping.txt
|
||||
OUTPUTPATH: $(Build.BinariesDirectory)\Microsoft.WindowsCalculator_8wekyb3d8bbwe.appxbundle
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy AppxBundle to staging directory
|
||||
inputs:
|
||||
sourceFolder: $(Build.BinariesDirectory)
|
||||
contents: Microsoft.WindowsCalculator_8wekyb3d8bbwe.appxbundle
|
||||
targetFolder: $(Build.ArtifactStagingDirectory)\appxBundle
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish AppxBundle artifact
|
||||
inputs:
|
||||
artifactName: appxBundle
|
||||
pathToPublish: $(Build.ArtifactStagingDirectory)\appxBundle
|
||||
|
||||
- ${{ if eq(parameters.signBundle, true) }}:
|
||||
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
|
||||
displayName: Send appxbundle to code signing service
|
||||
inputs:
|
||||
ConnectedServiceName: Essential Experiences Codesign
|
||||
FolderPath: $(Build.ArtifactStagingDirectory)\appxBundle
|
||||
Pattern: Microsoft.WindowsCalculator_8wekyb3d8bbwe.appxbundle
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: |
|
||||
[
|
||||
{
|
||||
"CertTemplateName": "WINMSAPP1ST",
|
||||
"CertSubjectName": "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
|
||||
"KeyCode": "Dynamic",
|
||||
"OperationCode": "SigntoolvNextSign",
|
||||
"Parameters": {
|
||||
"OpusName": "Microsoft",
|
||||
"OpusInfo": "http://www.microsoft.com",
|
||||
"FileDigest": "/fd \"SHA256\"",
|
||||
"TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
|
||||
},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"CertTemplateName": "WINMSAPP1ST",
|
||||
"CertSubjectName": "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
|
||||
"KeyCode": "Dynamic",
|
||||
"OperationCode": "SigntoolvNextVerify",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish AppxBundleSigned artifact
|
||||
inputs:
|
||||
pathtoPublish: $(Build.ArtifactStagingDirectory)\appxBundle
|
||||
artifactName: appxBundleSigned
|
160
build/pipelines/templates/package-msixbundle.yaml
Normal file
160
build/pipelines/templates/package-msixbundle.yaml
Normal file
|
@ -0,0 +1,160 @@
|
|||
# This template contains a job which takes .msix packages which were built separately for each
|
||||
# architecture (arm, x86, etc.) and combines them into a single .msixbundle. In release builds,
|
||||
# this job also signs the bundle and creates StoreBroker packages.
|
||||
|
||||
parameters:
|
||||
isOSSBuild: false
|
||||
signBundle: false
|
||||
createStoreBrokerPackages: false
|
||||
|
||||
jobs:
|
||||
- job: Package
|
||||
dependsOn:
|
||||
- Buildx64
|
||||
- Buildx86
|
||||
- BuildARM
|
||||
- BuildARM64
|
||||
condition: |
|
||||
and
|
||||
(
|
||||
in(dependencies.Buildx64.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'),
|
||||
in(dependencies.Buildx86.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'),
|
||||
in(dependencies.BuildARM.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'),
|
||||
in(dependencies.BuildARM64.result, 'Succeeded', 'SucceededWithIssues', 'Skipped')
|
||||
)
|
||||
pool:
|
||||
${{ if eq(parameters.isOSSBuild, true) }}:
|
||||
name: EssentialExperiencesOpenSource-windows-2022
|
||||
${{ if eq(parameters.isOSSBuild, false) }}:
|
||||
name: EssentialExperiences-windows-2022
|
||||
variables:
|
||||
skipComponentGovernanceDetection: true
|
||||
StoreBrokerMediaRootPath: $(TEMP)\SBMedia
|
||||
StoreBrokerPackagePath: $(Build.ArtifactStagingDirectory)\storeBrokerPayload
|
||||
steps:
|
||||
- checkout: self
|
||||
fetchDepth: 1
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: Download all .msix artifacts
|
||||
inputs:
|
||||
artifactName: drop
|
||||
itemPattern: '**/*.msix'
|
||||
|
||||
- ${{ if eq(parameters.createStoreBrokerPackages, true) }}:
|
||||
- task: UniversalPackages@0
|
||||
displayName: Download internals package
|
||||
inputs:
|
||||
command: download
|
||||
downloadDirectory: $(Build.SourcesDirectory)
|
||||
vstsFeed: WindowsInboxApps
|
||||
vstsFeedPackage: calculator-internals
|
||||
vstsPackageVersion: 0.0.105
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: Generate MsixBundle mapping
|
||||
inputs:
|
||||
filePath: $(Build.SourcesDirectory)\build\scripts\CreateMsixBundleMapping.ps1
|
||||
arguments: '-InputPath $(Build.ArtifactStagingDirectory)\drop\Release -ProjectName Calculator -OutputFile $(Build.BinariesDirectory)\MsixBundleMapping.txt'
|
||||
|
||||
- powershell: |
|
||||
$buildVersion = [version]$Env:BUILDVERSION
|
||||
$bundleVersion = "2021.$($buildVersion.Minor).$($buildVersion.Build).$($buildVersion.Revision)"
|
||||
& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x64\MakeAppx.exe" bundle /v /bv $bundleVersion /f $Env:MAPPINGFILEPATH /p $Env:OUTPUTPATH
|
||||
displayName: Make MsixBundle
|
||||
env:
|
||||
BUILDVERSION: $(Build.BuildNumber)
|
||||
MAPPINGFILEPATH: $(Build.BinariesDirectory)\MsixBundleMapping.txt
|
||||
OUTPUTPATH: $(Build.BinariesDirectory)\Microsoft.WindowsCalculator_8wekyb3d8bbwe.msixbundle
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy MsixBundle to staging directory
|
||||
inputs:
|
||||
sourceFolder: $(Build.BinariesDirectory)
|
||||
contents: Microsoft.WindowsCalculator_8wekyb3d8bbwe.msixbundle
|
||||
targetFolder: $(Build.ArtifactStagingDirectory)\msixBundle
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish MsixBundle artifact
|
||||
inputs:
|
||||
artifactName: msixBundle
|
||||
pathToPublish: $(Build.ArtifactStagingDirectory)\msixBundle
|
||||
|
||||
- ${{ if eq(parameters.signBundle, true) }}:
|
||||
- task: EsrpCodeSigning@2
|
||||
displayName: Send msixbundle to code signing service
|
||||
inputs:
|
||||
ConnectedServiceName: Essential Experiences Codesign
|
||||
FolderPath: $(Build.ArtifactStagingDirectory)\msixBundle
|
||||
Pattern: Microsoft.WindowsCalculator_8wekyb3d8bbwe.msixbundle
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: |
|
||||
[
|
||||
{
|
||||
"CertTemplateName": "WINMSAPP1ST",
|
||||
"CertSubjectName": "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
|
||||
"KeyCode": "Dynamic",
|
||||
"OperationCode": "SigntoolvNextSign",
|
||||
"Parameters": {
|
||||
"OpusName": "Microsoft",
|
||||
"OpusInfo": "http://www.microsoft.com",
|
||||
"FileDigest": "/fd \"SHA256\"",
|
||||
"TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
|
||||
},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"CertTemplateName": "WINMSAPP1ST",
|
||||
"CertSubjectName": "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
|
||||
"KeyCode": "Dynamic",
|
||||
"OperationCode": "SigntoolvNextVerify",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish MsixBundleSigned artifact
|
||||
inputs:
|
||||
pathtoPublish: $(Build.ArtifactStagingDirectory)\msixBundle
|
||||
artifactName: msixBundleSigned
|
||||
|
||||
- ${{ if eq(parameters.createStoreBrokerPackages, true) }}:
|
||||
- powershell: |
|
||||
# Just modify this line to indicate where your en-us PDP file is. Leave the other lines alone.
|
||||
$enUSPdpFilePath = "$(Build.SourcesDirectory)\PDP\en-US\PDP.xml"
|
||||
|
||||
# This is going to save the release value from the PDP file to $(SBMediaReleaseVersion)
|
||||
# which you can then refer to in the UniversalPackages task.
|
||||
$release = ([xml](Get-Content $enUSPdpFilePath)).ProductDescription.Release.Trim()
|
||||
Write-Host "##vso[task.setvariable variable=SBMediaReleaseVersion;]$release"
|
||||
displayName: Determine the PDP Media release version from the en-us PDP file
|
||||
|
||||
- task: UniversalPackages@0
|
||||
displayName: Download PDP media (screenshots, trailers) universal package
|
||||
inputs:
|
||||
command: download
|
||||
downloadDirectory: $(StoreBrokerMediaRootPath)/$(SBMediaReleaseVersion)
|
||||
vstsFeed: WindowsInboxApps
|
||||
vstsFeedPackage: calculator-pdp-media
|
||||
vstsPackageVersion: $(SBMediaReleaseVersion)
|
||||
|
||||
- task: MS-RDX-MRO.windows-store-publish-dev.package-task.store-package@2
|
||||
displayName: Create StoreBroker Payload
|
||||
inputs:
|
||||
serviceEndpoint: Calculator StoreBroker Connection
|
||||
sbConfigPath: Tools/Build/StoreBroker/SBCalculatorConfig.json
|
||||
sourceFolder: $(Build.ArtifactStagingDirectory)/msixBundle
|
||||
contents: Microsoft.WindowsCalculator_8wekyb3d8bbwe.msixbundle
|
||||
pdpPath: $(Build.SourcesDirectory)\PDP
|
||||
pdpInclude: PDP.xml
|
||||
pdpMediaPath: $(StoreBrokerMediaRootPath)
|
||||
outSBPackagePath: $(StoreBrokerPackagePath)
|
||||
outSBName: SBCalculator
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish StoreBroker Payload artifact
|
||||
inputs:
|
||||
pathtoPublish: $(StoreBrokerPackagePath)
|
||||
artifactName: storeBrokerPayload
|
|
@ -1,156 +0,0 @@
|
|||
# This template contains a job which builds artifacts needed to release the app to the store and to
|
||||
# Windows using Microsoft-internal systems. It relies on Microsoft-internal resources and will not
|
||||
# work outside of Microsoft.
|
||||
# Specifically, this job:
|
||||
# - Builds VPacks for including the app in the Windows OS build. Azure DevOps Universal Packages
|
||||
# offers similar capabilities.
|
||||
# - Creates StoreBroker packages containing Microsoft Store assets. Although the Store assets for
|
||||
# this app are not open source, the StoreBroker tool is available at
|
||||
# https://github.com/Microsoft/StoreBroker.
|
||||
|
||||
jobs:
|
||||
- job: WindowsInternalRelease
|
||||
dependsOn: Package
|
||||
pool:
|
||||
name: Package ES Standard Build
|
||||
workspace:
|
||||
clean: outputs
|
||||
variables:
|
||||
skipComponentGovernanceDetection: true
|
||||
SBMediaRootPath: '$(TEMP)\SBMedia'
|
||||
SBPackagePath: '$(Build.ArtifactStagingDirectory)\storeBrokerPayload'
|
||||
SBLogPath: '$(SBPackagePath)\StoreBroker.log'
|
||||
FlightId: '161f0975-cb5f-475b-8ef6-26383c37621f'
|
||||
AppId: '9WZDNCRFHVN5'
|
||||
ProductId: '00009007199266248474'
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
|
||||
# This must be the first task in the job definition, since it modifies the build environment
|
||||
# in ways other tasks would not expect (for example, it clears the artifacts directory).
|
||||
- task: PkgESSetupBuild@10
|
||||
displayName: Initialize Package ES
|
||||
inputs:
|
||||
productName: Calculator
|
||||
disableWorkspace: true
|
||||
useDfs: false
|
||||
env:
|
||||
XES_DISABLEPROV: true
|
||||
|
||||
- task: NuGetToolInstaller@1
|
||||
displayName: Use NuGet 5.x
|
||||
inputs:
|
||||
versionSpec: 5.x
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: Download appxBundleSigned artifact
|
||||
inputs:
|
||||
artifactName: appxBundleSigned
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy signed AppxBundle to vpack staging folder
|
||||
inputs:
|
||||
sourceFolder: $(Build.ArtifactStagingDirectory)\appxBundleSigned
|
||||
contents: Microsoft.WindowsCalculator_8wekyb3d8bbwe.appxbundle
|
||||
targetFolder: $(Build.ArtifactStagingDirectory)\vpack\appxBundle
|
||||
|
||||
- task: PkgESVPack@10
|
||||
displayName: Create and push vpack for app
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
inputs:
|
||||
sourceDirectory: $(Build.ArtifactStagingDirectory)\vpack\appxBundle
|
||||
description: VPack for the Calculator Application
|
||||
pushPkgName: calculator.app
|
||||
version: $(versionMajor).$(versionMinor).$(versionBuild)
|
||||
owner: paxeeapps
|
||||
provData: false
|
||||
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish vpack\app artifact with vpack manifest
|
||||
inputs:
|
||||
pathtoPublish: $(XES_VPACKMANIFESTDIRECTORY)\$(XES_VPACKMANIFESTNAME)
|
||||
artifactName: vpack\app
|
||||
|
||||
- task: UniversalPackages@0
|
||||
displayName: Download internals package
|
||||
inputs:
|
||||
command: download
|
||||
downloadDirectory: $(Build.SourcesDirectory)
|
||||
vstsFeed: WindowsInboxApps
|
||||
vstsFeedPackage: calculator-internals
|
||||
vstsPackageVersion: 0.0.54
|
||||
|
||||
- powershell: |
|
||||
# Just modify this line to indicate where your en-us PDP file is. Leave the other lines alone.
|
||||
$enUSPdpFilePath = "$(Build.SourcesDirectory)\PDP\en-US\PDP.xml"
|
||||
|
||||
# This is going to save the release value from the PDP file to $(SBMediaReleaseVersion)
|
||||
# which you can then refer to in the UniversalPackages task.
|
||||
$release = ([xml](Get-Content $enUSPdpFilePath)).ProductDescription.Release.Trim()
|
||||
Write-Host "##vso[task.setvariable variable=SBMediaReleaseVersion;]$release"
|
||||
displayName: Determine the PDP Media release version from the en-us PDP file
|
||||
|
||||
- task: UniversalPackages@0
|
||||
displayName: Download PDP media (screenshots, trailers) universal package
|
||||
inputs:
|
||||
command: download
|
||||
downloadDirectory: $(SBMediaRootPath)/$(SBMediaReleaseVersion)
|
||||
vstsFeed: WindowsInboxApps
|
||||
vstsFeedPackage: calculator-pdp-media
|
||||
vstsPackageVersion: $(SBMediaReleaseVersion)
|
||||
|
||||
- task: MS-RDX-MRO.windows-store-publish-dev.package-task.store-package@2
|
||||
displayName: Create StoreBroker Payload
|
||||
inputs:
|
||||
serviceEndpoint: Essential Experiences StoreBrokerProxy
|
||||
sbConfigPath: Tools/Build/StoreBroker/SBCalculatorConfig.json
|
||||
sourceFolder: $(Build.ArtifactStagingDirectory)/appxBundleSigned
|
||||
contents: Microsoft.WindowsCalculator_8wekyb3d8bbwe.appxbundle
|
||||
pdpPath: '$(Build.SourcesDirectory)\PDP'
|
||||
pdpInclude: PDP.xml
|
||||
pdpMediaPath: '$(SBMediaRootPath)'
|
||||
outSBPackagePath: '$(SBPackagePath)'
|
||||
outSBName: SBCalculator
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish StoreBroker Payload artifact
|
||||
inputs:
|
||||
pathtoPublish: '$(SBPackagePath)'
|
||||
artifactName: storeBrokerPayload
|
||||
|
||||
- task: MS-RDX-MRO.windows-store-publish-dev.flight-task.store-flight@2
|
||||
displayName: 'Flight StoreBroker Payload to team ring'
|
||||
name: StoreBrokerFlight
|
||||
inputs:
|
||||
serviceEndpoint: Essential Experiences StoreBrokerProxy
|
||||
appId: '$(AppId)'
|
||||
flightId: '$(FlightId)'
|
||||
inputMethod: JsonAndZip
|
||||
jsonPath: '$(SBPackagePath)\SBCalculator.json'
|
||||
zipPath: '$(SBPackagePath)\SBCalculator.zip'
|
||||
force: true
|
||||
skipPolling: true
|
||||
targetPublishMode: Immediate
|
||||
logPath: '$(SBLogPath)'
|
||||
deletePackages: true
|
||||
numberOfPackagesToKeep: 0
|
||||
|
||||
- task: PkgESStoreBrokerAeroUpload@10
|
||||
displayName: Upload to Aero flighting dashboard
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
inputs:
|
||||
ProductId: '$(ProductId)'
|
||||
FlightId: '$(FlightId)'
|
||||
SubmissionId: '$(StoreBrokerFlight.WS_SubmissionId)'
|
||||
SubmissionDataPath: '$(SBPackagePath)\SBCalculator.json'
|
||||
PackagePath: '$(SBPackagePath)\SBCalculator.zip'
|
||||
AeroEnvironment: Production
|
||||
|
||||
- task: PkgESLateTasks@10
|
||||
displayName: Run PackageES LateTasks
|
||||
env:
|
||||
XES_DISABLEPROV: true
|
48
build/pipelines/templates/release-store.yaml
Normal file
48
build/pipelines/templates/release-store.yaml
Normal file
|
@ -0,0 +1,48 @@
|
|||
# This template contains jobs to release the app to the Store.
|
||||
|
||||
jobs:
|
||||
- job: ReleaseStore
|
||||
dependsOn: Package
|
||||
pool:
|
||||
name: EssentialExperiences-windows-2022
|
||||
variables:
|
||||
skipComponentGovernanceDetection: true
|
||||
StoreBrokerPackagePath: $(Build.ArtifactStagingDirectory)\storeBrokerPayload
|
||||
StoreBrokerLogPath: $(StoreBrokerPackagePath)\StoreBroker.log
|
||||
FlightId: 161f0975-cb5f-475b-8ef6-26383c37621f
|
||||
AppId: 9WZDNCRFHVN5
|
||||
ProductId: 00009007199266248474
|
||||
steps:
|
||||
- checkout: none
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: Download storeBrokerPayload artifact
|
||||
inputs:
|
||||
artifactName: storeBrokerPayload
|
||||
|
||||
- task: MS-RDX-MRO.windows-store-publish-dev.flight-task.store-flight@2
|
||||
displayName: Flight StoreBroker Payload to team ring
|
||||
name: StoreBrokerFlight
|
||||
inputs:
|
||||
serviceEndpoint: Calculator StoreBroker Connection
|
||||
appId: $(AppId)
|
||||
flightId: $(FlightId)
|
||||
inputMethod: JsonAndZip
|
||||
jsonPath: $(StoreBrokerPackagePath)\SBCalculator.json
|
||||
zipPath: $(StoreBrokerPackagePath)\SBCalculator.zip
|
||||
force: true
|
||||
skipPolling: true
|
||||
targetPublishMode: Immediate
|
||||
logPath: $(StoreBrokerLogPath)
|
||||
deletePackages: true
|
||||
numberOfPackagesToKeep: 0
|
||||
|
||||
- task: APS-Aero-Package.aero-upload-task.AeroUploadTask.AeroUpload@0
|
||||
displayName: Aero Upload
|
||||
inputs:
|
||||
productId: $(ProductId)
|
||||
flightId: $(FlightId)
|
||||
submissionId: $(StoreBrokerFlight.WS_SubmissionId)
|
||||
submissionDataPath: $(StoreBrokerPackagePath)\SBCalculator.json
|
||||
packagePath: $(StoreBrokerPackagePath)\SBCalculator.zip
|
||||
serviceEndpoint: AeroUpload-APS-Calculator
|
42
build/pipelines/templates/release-vpack.yaml
Normal file
42
build/pipelines/templates/release-vpack.yaml
Normal file
|
@ -0,0 +1,42 @@
|
|||
# This template contains a job to create a VPack. The VPack is used to preinstall the app in a
|
||||
# Windows OS build.
|
||||
|
||||
jobs:
|
||||
- job: ReleaseVPack
|
||||
dependsOn: Package
|
||||
pool:
|
||||
name: EssentialExperiences-windows-2022
|
||||
variables:
|
||||
skipComponentGovernanceDetection: true
|
||||
steps:
|
||||
- checkout: none
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: Download msixBundleSigned artifact
|
||||
inputs:
|
||||
artifactName: msixBundleSigned
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy signed MsixBundle to vpack staging folder
|
||||
inputs:
|
||||
sourceFolder: $(Build.ArtifactStagingDirectory)\msixBundleSigned
|
||||
contents: Microsoft.WindowsCalculator_8wekyb3d8bbwe.msixbundle
|
||||
targetFolder: $(Build.ArtifactStagingDirectory)\vpack\msixBundle
|
||||
|
||||
- task: PkgESVPack@12
|
||||
displayName: Create and push vpack for app
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
inputs:
|
||||
sourceDirectory: $(Build.ArtifactStagingDirectory)\vpack\msixBundle
|
||||
description: VPack for the Calculator Application
|
||||
pushPkgName: calculator.app
|
||||
version: $(versionMajor).$(versionMinor).$(versionBuild)
|
||||
owner: paxeeapps
|
||||
provData: true
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish vpack\app artifact with vpack manifest
|
||||
inputs:
|
||||
pathtoPublish: $(XES_VPACKMANIFESTDIRECTORY)\$(XES_VPACKMANIFESTNAME)
|
||||
artifactName: vpackManifest
|
|
@ -1,6 +1,7 @@
|
|||
# This template contains jobs to run UI tests using WinAppDriver.
|
||||
|
||||
parameters:
|
||||
isOSSBuild: false
|
||||
platform: ''
|
||||
runsettingsFileName: ''
|
||||
|
||||
|
@ -10,18 +11,30 @@ jobs:
|
|||
dependsOn: Build${{ parameters.platform }}
|
||||
condition: succeeded()
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
${{ if eq(parameters.isOSSBuild, true) }}:
|
||||
name: EssentialExperiencesOpenSource-Win11
|
||||
${{ if eq(parameters.isOSSBuild, false) }}:
|
||||
name: EssentialExperiences-Win11
|
||||
variables:
|
||||
skipComponentGovernanceDetection: true
|
||||
steps:
|
||||
- checkout: none
|
||||
- checkout: self
|
||||
fetchDepth: 1
|
||||
|
||||
- powershell: Set-DisplayResolution -Width 1920 -Height 1080 -Force
|
||||
displayName: Set resolution to 1920x1080
|
||||
continueOnError: true
|
||||
- task: PowerShell@2
|
||||
displayName: Turn off animation effects
|
||||
inputs:
|
||||
filePath: $(Build.SourcesDirectory)\build\scripts\TurnOffAnimationEffects.ps1
|
||||
|
||||
- task: ScreenResolutionUtility@1
|
||||
displayName: Set resolution to 1920x1080
|
||||
inputs:
|
||||
displaySettings: 'specific'
|
||||
width: 1920
|
||||
height: 1080
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: Download AppxBundle and CalculatorUITests
|
||||
displayName: Download MsixBundle and CalculatorUITests
|
||||
inputs:
|
||||
artifactName: drop
|
||||
itemPattern: |
|
||||
|
@ -44,9 +57,8 @@ jobs:
|
|||
displayName: Run CalculatorUITests
|
||||
inputs:
|
||||
testAssemblyVer2: $(Build.ArtifactStagingDirectory)/drop/Release/${{ parameters.platform }}/publish/CalculatorUITests.dll
|
||||
vsTestVersion: 16.0
|
||||
runSettingsFile: $(Build.ArtifactStagingDirectory)/drop/Release/${{ parameters.platform }}/publish/${{ parameters.runsettingsFileName }}
|
||||
platform: ${{ parameters.platform }}
|
||||
configuration: Release
|
||||
${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
|
||||
testFiltercriteria: Priority=0
|
||||
testFiltercriteria: Priority=0
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# This template contains jobs to run unit tests.
|
||||
|
||||
parameters:
|
||||
isOSSBuild: false
|
||||
platform: ''
|
||||
runsettingsFileName: ''
|
||||
|
||||
|
@ -10,7 +11,10 @@ jobs:
|
|||
dependsOn: Build${{ parameters.platform }}
|
||||
condition: succeeded()
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
${{ if eq(parameters.isOSSBuild, true) }}:
|
||||
name: EssentialExperiencesOpenSource-windows-2022
|
||||
${{ if eq(parameters.isOSSBuild, false) }}:
|
||||
name: EssentialExperiences-windows-2022
|
||||
variables:
|
||||
skipComponentGovernanceDetection: true
|
||||
steps:
|
||||
|
@ -31,5 +35,5 @@ jobs:
|
|||
- task: VSTest@2
|
||||
displayName: Run CalculatorUnitTests
|
||||
inputs:
|
||||
testAssemblyVer2: $(Build.ArtifactStagingDirectory)\drop\Release\${{ parameters.platform }}\CalculatorUnitTests\AppPackages\CalculatorUnitTests_Test\CalculatorUnitTests.appx
|
||||
testAssemblyVer2: $(Build.ArtifactStagingDirectory)\drop\Release\${{ parameters.platform }}\CalculatorUnitTests\AppPackages\CalculatorUnitTests_Test\CalculatorUnitTests.msix
|
||||
otherConsoleOptions: /Platform:${{ parameters.platform }}
|
|
@ -10,26 +10,26 @@
|
|||
ARM\
|
||||
Project\
|
||||
AppPackages\
|
||||
Project_ARM.appx
|
||||
Project_scale-100.appx
|
||||
Project_ARM.msix
|
||||
Project_scale-100.msix
|
||||
x64\
|
||||
Project\
|
||||
AppPackages\
|
||||
Project_x64.appx
|
||||
Project_scale-100.appx
|
||||
Project_x64.msix
|
||||
Project_scale-100.msix
|
||||
|
||||
.PARAMETER InputPath
|
||||
The path where appx packages to bundle are located.
|
||||
The path where msix packages to bundle are located.
|
||||
|
||||
.PARAMETER ProjectName
|
||||
The folder name within each architecture to search recursively for appx packages. The appx files
|
||||
The folder name within each architecture to search recursively for msix packages. The msix files
|
||||
must also have the ProjectName in their file names.
|
||||
|
||||
.PARAMETER OutputFile
|
||||
The path to write the generated mapping file.
|
||||
|
||||
.EXAMPLE
|
||||
Create-AppxBundleMapping -InputPath "C:\drop" -ProjectName "CalculatorApp" -OutputFile "C:\Temp\AppxBundleMapping.txt"
|
||||
Create-MsixBundleMapping -InputPath "C:\drop" -ProjectName "CalculatorApp" -OutputFile "C:\Temp\MsixBundleMapping.txt"
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
|
@ -45,7 +45,7 @@ param(
|
|||
$OutputFile
|
||||
)
|
||||
|
||||
# List all appx packages by architecture
|
||||
# List all msix packages by architecture
|
||||
$architectures = @(Get-ChildItem -Path $InputPath -Directory | Foreach-Object Name | Foreach-Object ToLower)
|
||||
if ($architectures.Count -lt 1)
|
||||
{
|
||||
|
@ -57,22 +57,22 @@ $packages = @{}
|
|||
foreach ($architecture in $architectures)
|
||||
{
|
||||
$projectPath = [IO.Path]::Combine($InputPath, $architecture, $ProjectName)
|
||||
$packages[$architecture] = Get-ChildItem -Path $projectPath -Recurse -Filter *$ProjectName*.appx
|
||||
$packages[$architecture] = Get-ChildItem -Path $projectPath -Recurse -Filter *$ProjectName*.msix
|
||||
|
||||
if ($packages[$architecture].Count -lt 1)
|
||||
{
|
||||
throw "No .appx files found for architecture $architecture in $projectPath"
|
||||
throw "No .msix files found for architecture $architecture in $projectPath"
|
||||
}
|
||||
}
|
||||
|
||||
# List appx packages which are common to all architectures
|
||||
# List msix packages which are common to all architectures
|
||||
$commonPackages = $packages[$defaultArchitecture]
|
||||
foreach ($architecture in $architectures)
|
||||
{
|
||||
$commonPackages = $packages[$architecture] | Where {$commonPackages.Name -Contains $_.Name}
|
||||
}
|
||||
|
||||
# List appx packages which are architecture-specific and verify that there is exactly one per
|
||||
# List msix packages which are architecture-specific and verify that there is exactly one per
|
||||
# architecture.
|
||||
$architectureSpecificPackages = @()
|
||||
if ($architectures.Count -gt 1)
|
22
build/scripts/TurnOffAnimationEffects.ps1
Normal file
22
build/scripts/TurnOffAnimationEffects.ps1
Normal file
|
@ -0,0 +1,22 @@
|
|||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Disables animations on the system. Equivalent to turning off the "Animation effects" setting in the Windows Settings app.
|
||||
#>
|
||||
|
||||
Add-Type -AssemblyName System.Runtime.WindowsRuntime
|
||||
$asTaskGeneric = ([System.WindowsRuntimeSystemExtensions].GetMethods() | ? { $_.Name -eq 'AsTask' -and $_.GetParameters().Count -eq 1 -and $_.GetParameters()[0].ParameterType.Name -eq 'IAsyncOperation`1' })[0]
|
||||
|
||||
Function WaitForAsyncAction($WinRtTask, $ResultType) {
|
||||
$asTask = $asTaskGeneric.MakeGenericMethod($ResultType)
|
||||
$task = $asTask.Invoke($null, @($WinRtTask))
|
||||
$task.GetAwaiter().GetResult()
|
||||
}
|
||||
|
||||
[Windows.UI.ViewManagement.Core.UISettingsController,Windows.UI.ViewManagement.Core,ContentType=WindowsRuntime] | Out-Null
|
||||
|
||||
$controller = WaitForAsyncAction ([Windows.UI.ViewManagement.Core.UISettingsController]::RequestDefaultAsync()) ([Windows.UI.ViewManagement.Core.UISettingsController])
|
||||
|
||||
$controller.SetAnimationsEnabled($false)
|
|
@ -21,11 +21,11 @@ that build into the final Calculator application.
|
|||
|
||||
The View layer is contained in the [Calculator project][Calculator folder]. This project contains mostly XAML files
|
||||
and various custom controls that support the UI. [App.xaml][App.xaml] contains many of the [static][StaticResource] and
|
||||
[theme][ThemeResource] resources that the other XAML files will reference. Its code-behind file, [App.xaml.cpp][App.xaml.cpp],
|
||||
[theme][ThemeResource] resources that the other XAML files will reference. Its code-behind file, [App.xaml.cs][App.xaml.cs],
|
||||
contains the main entry point to the application. On startup, it navigates to the main page.
|
||||
|
||||
```C++
|
||||
rootFrame->Navigate(MainPage::typeid, argument)
|
||||
```C#
|
||||
rootFrame.Navigate(typeof(MainPage), argument)
|
||||
```
|
||||
|
||||
In Calculator, there is only one concrete [Page][Page] class: [MainPage.xaml][MainPage.xaml]. `MainPage` is the root
|
||||
|
@ -166,7 +166,7 @@ instead of regular floating point arithmetic). The interface to this layer is de
|
|||
|
||||
[Calculator folder]: ../src/Calculator
|
||||
[App.xaml]: ../src/Calculator/App.xaml
|
||||
[App.xaml.cpp]: ../src/Calculator/App.xaml.cpp
|
||||
[App.xaml.cs]: ../src/Calculator/App.xaml.cs
|
||||
[StaticResource]: https://docs.microsoft.com/en-us/windows/uwp/xaml-platform/staticresource-markup-extension
|
||||
[ThemeResource]: https://docs.microsoft.com/en-us/windows/uwp/xaml-platform/themeresource-markup-extension
|
||||
[Page]: https://docs.microsoft.com/en-us/uwp/api/Windows.UI.Xaml.Controls.Page
|
||||
|
|
BIN
docs/Images/CalculatorScreenshot.png
Normal file → Executable file
BIN
docs/Images/CalculatorScreenshot.png
Normal file → Executable file
Binary file not shown.
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 18 KiB |
Binary file not shown.
Before Width: | Height: | Size: 256 KiB After Width: | Height: | Size: 81 KiB |
|
@ -10,9 +10,9 @@ In 2021, the Windows Calculator team is focused on:
|
|||
* Migrating the codebase to C# ([#893](https://github.com/microsoft/calculator/issues/893))
|
||||
* Releasing infinite-precision engine as standalone package ([#1545](https://github.com/microsoft/calculator/issues/1545)) and adding support for arbitrary expression parsing ([#526](https://github.com/microsoft/calculator/issues/526))
|
||||
* Adding a settings page ([#596](https://github.com/microsoft/calculator/issues/596))
|
||||
* [Your feature idea here] - please review our [new feature development process](https://github.com/Microsoft/calculator/blob/master/docs/NewFeatureProcess.md) to get started!
|
||||
* [Your feature idea here] - please review our [new feature development process](https://github.com/Microsoft/calculator/blob/main/docs/NewFeatureProcess.md) to get started!
|
||||
|
||||
We welcome contributions of all kinds from the community, but especially those that support the efforts above. Please see our [contributing guidelines](https://github.com/Microsoft/calculator/blob/master/CONTRIBUTING.md) for more information on how to get involved.
|
||||
We welcome contributions of all kinds from the community, but especially those that support the efforts above. Please see our [contributing guidelines](https://github.com/Microsoft/calculator/blob/main/CONTRIBUTING.md) for more information on how to get involved.
|
||||
|
||||
## Releases
|
||||
|
||||
|
|
15
nuget.config
15
nuget.config
|
@ -1,6 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<config>
|
||||
<add key="repositorypath" value=".\packages" />
|
||||
</config>
|
||||
</configuration>
|
||||
<packageSources>
|
||||
<clear />
|
||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
|
||||
<add key="Toolkit Labs" value="https://pkgs.dev.azure.com/dotnet/CommunityToolkit/_packaging/CommunityToolkit-Labs/nuget/v3/index.json" />
|
||||
</packageSources>
|
||||
<disabledPackageSources>
|
||||
<clear />
|
||||
</disabledPackageSources>
|
||||
</configuration>
|
|
@ -143,14 +143,14 @@ void CHistoryCollector::AddBinOpToHistory(int nOpCode, bool isIntegerMode, bool
|
|||
// This is expected to be called when a binary op in the last say 1+2+ is changing to another one say 1+2* (+ changed to *)
|
||||
// It needs to know by this change a Precedence inversion happened. i.e. previous op was lower or equal to its previous op, but the new
|
||||
// one isn't. (Eg. 1*2* to 1*2^). It can add explicit brackets to ensure the precedence is inverted. (Eg. (1*2) ^)
|
||||
void CHistoryCollector::ChangeLastBinOp(int nOpCode, bool fPrecInvToHigher, bool isIntgerMode)
|
||||
void CHistoryCollector::ChangeLastBinOp(int nOpCode, bool fPrecInvToHigher, bool isIntegerMode)
|
||||
{
|
||||
TruncateEquationSzFromIch(m_lastBinOpStartIndex);
|
||||
if (fPrecInvToHigher)
|
||||
{
|
||||
EnclosePrecInversionBrackets();
|
||||
}
|
||||
AddBinOpToHistory(nOpCode, isIntgerMode);
|
||||
AddBinOpToHistory(nOpCode, isIntegerMode);
|
||||
}
|
||||
|
||||
void CHistoryCollector::PushLastOpndStart(int ichOpndStart)
|
||||
|
|
|
@ -22,10 +22,9 @@ namespace CalcEngine
|
|||
Number::Number(PNUMBER p) noexcept
|
||||
: m_sign{ p->sign }
|
||||
, m_exp{ p->exp }
|
||||
, m_mantissa{}
|
||||
{
|
||||
m_mantissa.reserve(p->cdigit);
|
||||
copy(p->mant, p->mant + p->cdigit, back_inserter(m_mantissa));
|
||||
copy_n(p->mant, p->cdigit, back_inserter(m_mantissa));
|
||||
}
|
||||
|
||||
PNUMBER Number::ToPNUMBER() const
|
||||
|
|
|
@ -101,7 +101,7 @@ CCalcEngine::CCalcEngine(
|
|||
{
|
||||
InitChopNumbers();
|
||||
|
||||
m_dwWordBitWidth = DwWordBitWidthFromeNumWidth(m_numwidth);
|
||||
m_dwWordBitWidth = DwWordBitWidthFromNumWidth(m_numwidth);
|
||||
|
||||
m_maxTrigonometricNum = RationalMath::Pow(10, 100);
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include <sstream>
|
||||
#include "Header Files/CalcEngine.h"
|
||||
#include "Header Files/CalcUtils.h"
|
||||
#include "NumberFormattingUtils.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace CalcEngine;
|
||||
|
@ -31,17 +30,31 @@ namespace
|
|||
// 0 is returned. Higher the number, higher the precedence of the operator.
|
||||
int NPrecedenceOfOp(int nopCode)
|
||||
{
|
||||
static uint16_t rgbPrec[] = { 0, 0, IDC_OR, 0, IDC_XOR, 0, IDC_AND, 1, IDC_NAND, 1, IDC_NOR, 1, IDC_ADD, 2, IDC_SUB, 2, IDC_RSHF, 3,
|
||||
IDC_LSHF, 3, IDC_RSHFL, 3, IDC_MOD, 3, IDC_DIV, 3, IDC_MUL, 3, IDC_PWR, 4, IDC_ROOT, 4, IDC_LOGBASEY, 4 };
|
||||
|
||||
for (unsigned int iPrec = 0; iPrec < size(rgbPrec); iPrec += 2)
|
||||
switch (nopCode)
|
||||
{
|
||||
if (nopCode == rgbPrec[iPrec])
|
||||
{
|
||||
return rgbPrec[iPrec + 1];
|
||||
}
|
||||
default:
|
||||
case IDC_OR:
|
||||
case IDC_XOR:
|
||||
return 0;
|
||||
case IDC_AND:
|
||||
case IDC_NAND:
|
||||
case IDC_NOR:
|
||||
return 1;
|
||||
case IDC_ADD:
|
||||
case IDC_SUB:
|
||||
return 2;
|
||||
case IDC_LSHF:
|
||||
case IDC_RSHF:
|
||||
case IDC_RSHFL:
|
||||
case IDC_MOD:
|
||||
case IDC_DIV:
|
||||
case IDC_MUL:
|
||||
return 3;
|
||||
case IDC_PWR:
|
||||
case IDC_ROOT:
|
||||
case IDC_LOGBASEY:
|
||||
return 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -519,6 +532,12 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
|
||||
if (wParam == IDC_OPENP)
|
||||
{
|
||||
// if there's an omitted multiplication sign
|
||||
if (IsDigitOpCode(m_nLastCom) || IsUnaryOpCode(m_nLastCom) || m_nLastCom == IDC_PNT || m_nLastCom == IDC_CLOSEP)
|
||||
{
|
||||
ProcessCommand(IDC_MUL);
|
||||
}
|
||||
|
||||
CheckAndAddLastBinOpToHistory();
|
||||
m_HistoryCollector.AddOpenBraceToHistory();
|
||||
|
||||
|
@ -594,7 +613,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
// Set the "(=xx" indicator.
|
||||
if (nullptr != m_pCalcDisplay)
|
||||
{
|
||||
m_pCalcDisplay->SetParenthesisNumber(m_openParenCount >= 0 ? static_cast<unsigned int>(m_openParenCount) : 0);
|
||||
m_pCalcDisplay->SetParenthesisNumber(static_cast<unsigned int>(m_openParenCount));
|
||||
}
|
||||
|
||||
if (!m_bError)
|
||||
|
@ -757,7 +776,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
|
|||
break;
|
||||
case IDC_FE:
|
||||
// Toggle exponential notation display.
|
||||
m_nFE = NumberFormat(!(int)m_nFE);
|
||||
m_nFE = m_nFE == NumberFormat::Float ? NumberFormat::Scientific : NumberFormat::Float;
|
||||
DisplayNum();
|
||||
break;
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ void CCalcEngine::SetRadixTypeAndNumWidth(RadixType radixtype, NUM_WIDTH numwidt
|
|||
if (numwidth >= NUM_WIDTH::QWORD_WIDTH && numwidth <= NUM_WIDTH::BYTE_WIDTH)
|
||||
{
|
||||
m_numwidth = numwidth;
|
||||
m_dwWordBitWidth = DwWordBitWidthFromeNumWidth(numwidth);
|
||||
m_dwWordBitWidth = DwWordBitWidthFromNumWidth(numwidth);
|
||||
}
|
||||
|
||||
// inform ratpak that a change in base or precision has occurred
|
||||
|
@ -50,7 +50,7 @@ void CCalcEngine::SetRadixTypeAndNumWidth(RadixType radixtype, NUM_WIDTH numwidt
|
|||
DisplayNum();
|
||||
}
|
||||
|
||||
int32_t CCalcEngine::DwWordBitWidthFromeNumWidth(NUM_WIDTH numwidth)
|
||||
int32_t CCalcEngine::DwWordBitWidthFromNumWidth(NUM_WIDTH numwidth)
|
||||
{
|
||||
switch (numwidth)
|
||||
{
|
||||
|
@ -85,7 +85,7 @@ uint32_t CCalcEngine::NRadixFromRadixType(RadixType radixtype)
|
|||
// Toggles a given bit into the number representation. returns true if it changed it actually.
|
||||
bool CCalcEngine::TryToggleBit(CalcEngine::Rational& rat, uint32_t wbitno)
|
||||
{
|
||||
uint32_t wmax = DwWordBitWidthFromeNumWidth(m_numwidth);
|
||||
uint32_t wmax = DwWordBitWidthFromNumWidth(m_numwidth);
|
||||
if (wbitno >= wmax)
|
||||
{
|
||||
return false; // ignore error cant happen
|
||||
|
|
|
@ -45,8 +45,8 @@
|
|||
<AppContainerApplication>true</AppContainerApplication>
|
||||
<ApplicationType>Windows Store</ApplicationType>
|
||||
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
|
||||
<WindowsTargetPlatformVersion Condition="'$(WindowsTargetPlatformVersion)' == ''">10.0.18362.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformMinVersion>10.0.17134.0</WindowsTargetPlatformMinVersion>
|
||||
<WindowsTargetPlatformVersion Condition="'$(WindowsTargetPlatformVersion)' == ''">10.0.22621.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformMinVersion>10.0.19041.0</WindowsTargetPlatformMinVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<!-- This has to be exactly in this place for this to work -->
|
||||
|
@ -56,28 +56,28 @@
|
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
|
@ -85,7 +85,7 @@
|
|||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
|
@ -93,7 +93,7 @@
|
|||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
|
@ -101,7 +101,7 @@
|
|||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
|
@ -346,4 +346,4 @@
|
|||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
</Project>
|
||||
</Project>
|
|
@ -79,7 +79,7 @@ vector<shared_ptr<HISTORYITEM>> const& CalculatorHistory::GetHistory()
|
|||
|
||||
shared_ptr<HISTORYITEM> const& CalculatorHistory::GetHistoryItem(unsigned int uIdx)
|
||||
{
|
||||
assert(uIdx >= 0 && uIdx < m_historyItems.size());
|
||||
assert(uIdx < m_historyItems.size());
|
||||
return m_historyItems.at(uIdx);
|
||||
}
|
||||
|
||||
|
|
|
@ -179,7 +179,7 @@ private:
|
|||
CalcEngine::Rational SciCalcFunctions(CalcEngine::Rational const& rat, uint32_t op);
|
||||
CalcEngine::Rational DoOperation(int operation, CalcEngine::Rational const& lhs, CalcEngine::Rational const& rhs);
|
||||
void SetRadixTypeAndNumWidth(RadixType radixtype, NUM_WIDTH numwidth);
|
||||
int32_t DwWordBitWidthFromeNumWidth(NUM_WIDTH numwidth);
|
||||
int32_t DwWordBitWidthFromNumWidth(NUM_WIDTH numwidth);
|
||||
uint32_t NRadixFromRadixType(RadixType radixtype);
|
||||
double GenerateRandomNumber();
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@ public:
|
|||
~CHistoryCollector();
|
||||
void AddOpndToHistory(std::wstring_view numStr, CalcEngine::Rational const& rat, bool fRepetition = false);
|
||||
void RemoveLastOpndFromHistory();
|
||||
void AddBinOpToHistory(int nOpCode, bool isIntgerMode, bool fNoRepetition = true);
|
||||
void ChangeLastBinOp(int nOpCode, bool fPrecInvToHigher, bool isIntgerMode);
|
||||
void AddBinOpToHistory(int nOpCode, bool isIntegerMode, bool fNoRepetition = true);
|
||||
void ChangeLastBinOp(int nOpCode, bool fPrecInvToHigher, bool isIntegerMode);
|
||||
void AddUnaryOpToHistory(int nOpCode, bool fInv, AngleType angletype);
|
||||
void AddOpenBraceToHistory();
|
||||
void AddCloseBraceToHistory();
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
namespace CalcManager::NumberFormattingUtils
|
||||
namespace UnitConversionManager::NumberFormattingUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Trims out any trailing zeros or decimals in the given input string
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <string>
|
||||
#include "sal_cross_platform.h"
|
||||
|
||||
namespace CalcManager::NumberFormattingUtils
|
||||
namespace UnitConversionManager::NumberFormattingUtils
|
||||
{
|
||||
void TrimTrailingZeros(_Inout_ std::wstring& input);
|
||||
unsigned int GetNumberDigits(std::wstring value);
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
// CalcErr.h
|
||||
//
|
||||
// Defines the error codes thrown by ratpak and caught by Calculator
|
||||
|
@ -36,7 +38,7 @@
|
|||
// This format is based loosely on an OLE HRESULT and is compatible with the
|
||||
// SUCCEEDED and FAILED macros as well as the HRESULT_CODE macro
|
||||
|
||||
typedef int32_t ResultCode;
|
||||
using ResultCode = int32_t;
|
||||
|
||||
// CALC_E_DIVIDEBYZERO
|
||||
//
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
void _readconstants(void);
|
||||
void _readconstants();
|
||||
|
||||
#if defined(GEN_CONST)
|
||||
static int cbitsofprecision = 0;
|
||||
|
@ -136,13 +136,7 @@ void ChangeConstants(uint32_t radix, int32_t precision)
|
|||
// in the internal BASEX radix, this is important for length calculations
|
||||
// in translating from radix to BASEX and back.
|
||||
|
||||
uint64_t limit = static_cast<uint64_t>(BASEX) / static_cast<uint64_t>(radix);
|
||||
g_ratio = 0;
|
||||
for (uint32_t digit = 1; digit < limit; digit *= radix)
|
||||
{
|
||||
g_ratio++;
|
||||
}
|
||||
g_ratio += !g_ratio;
|
||||
g_ratio = static_cast<int32_t>(ceil(BASEXPWR / log2(radix))) - 1;
|
||||
|
||||
destroyrat(rat_nRadix);
|
||||
rat_nRadix = i32torat(radix);
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace UnitConversionManager;
|
||||
using namespace CalcManager::NumberFormattingUtils;
|
||||
using namespace UnitConversionManager::NumberFormattingUtils;
|
||||
|
||||
static constexpr uint32_t EXPECTEDSERIALIZEDCATEGORYTOKENCOUNT = 3U;
|
||||
static constexpr uint32_t EXPECTEDSERIALIZEDUNITTOKENCOUNT = 6U;
|
||||
|
|
|
@ -156,13 +156,12 @@ namespace UnitConversionManager
|
|||
std::wstring targetCurrencyCode;
|
||||
};
|
||||
|
||||
typedef std::tuple<std::vector<UnitConversionManager::Unit>, UnitConversionManager::Unit, UnitConversionManager::Unit> CategorySelectionInitializer;
|
||||
typedef std::unordered_map<
|
||||
using CategorySelectionInitializer = std::tuple<std::vector<UnitConversionManager::Unit>, UnitConversionManager::Unit, UnitConversionManager::Unit>;
|
||||
using UnitToUnitToConversionDataMap = std::unordered_map<
|
||||
UnitConversionManager::Unit,
|
||||
std::unordered_map<UnitConversionManager::Unit, UnitConversionManager::ConversionData, UnitConversionManager::UnitHash>,
|
||||
UnitConversionManager::UnitHash>
|
||||
UnitToUnitToConversionDataMap;
|
||||
typedef std::unordered_map<int, std::vector<UnitConversionManager::Unit>> CategoryToUnitVectorMap;
|
||||
UnitConversionManager::UnitHash>;
|
||||
using CategoryToUnitVectorMap = std::unordered_map<int, std::vector<UnitConversionManager::Unit>>;
|
||||
|
||||
class IViewModelCurrencyCallback
|
||||
{
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
#include "DataLoaders/UnitConverterDataLoader.h"
|
||||
|
||||
using namespace CalculatorApp;
|
||||
using namespace CalculatorApp::Common;
|
||||
using namespace CalculatorApp::DataLoaders;
|
||||
using namespace CalculatorApp::ViewModel::Common;
|
||||
using namespace CalculatorApp::ViewModel::DataLoaders;
|
||||
using namespace CalculatorApp::ViewModel;
|
||||
using namespace CalculationManager;
|
||||
using namespace Platform;
|
||||
|
@ -75,7 +75,7 @@ void ApplicationViewModel::Categories::set(IObservableVector<NavCategoryGroup ^>
|
|||
|
||||
void ApplicationViewModel::Initialize(ViewMode mode)
|
||||
{
|
||||
if (!NavCategory::IsValidViewMode(mode) || !NavCategory::IsViewModeEnabled(mode))
|
||||
if (!NavCategoryStates::IsValidViewMode(mode) || !NavCategoryStates::IsViewModeEnabled(mode))
|
||||
{
|
||||
mode = ViewMode::Standard;
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ bool ApplicationViewModel::TryRecoverFromNavigationModeFailure()
|
|||
|
||||
void ApplicationViewModel::OnModeChanged()
|
||||
{
|
||||
assert(NavCategory::IsValidViewMode(m_mode));
|
||||
assert(NavCategoryStates::IsValidViewMode(m_mode));
|
||||
if (NavCategory::IsCalculatorViewMode(m_mode))
|
||||
{
|
||||
if (!m_CalculatorViewModel)
|
||||
|
@ -160,15 +160,15 @@ void ApplicationViewModel::OnModeChanged()
|
|||
}
|
||||
|
||||
auto resProvider = AppResourceProvider::GetInstance();
|
||||
CategoryName = resProvider->GetResourceString(NavCategory::GetNameResourceKey(m_mode));
|
||||
CategoryName = resProvider->GetResourceString(NavCategoryStates::GetNameResourceKey(m_mode));
|
||||
|
||||
// Cast mode to an int in order to save it to app data.
|
||||
// Save the changed mode, so that the new window launches in this mode.
|
||||
// Don't save until after we have adjusted to the new mode, so we don't save a mode that fails to load.
|
||||
ApplicationData::Current->LocalSettings->Values->Insert(ModePropertyName, NavCategory::Serialize(m_mode));
|
||||
ApplicationData::Current->LocalSettings->Values->Insert(ModePropertyName, NavCategoryStates::Serialize(m_mode));
|
||||
|
||||
// Log ModeChange event when not first launch, log WindowCreated on first launch
|
||||
if (NavCategory::IsValidViewMode(m_PreviousMode))
|
||||
if (NavCategoryStates::IsValidViewMode(m_PreviousMode))
|
||||
{
|
||||
TraceLogger::GetInstance()->LogModeChange(m_mode);
|
||||
}
|
||||
|
@ -213,7 +213,7 @@ void ApplicationViewModel::SetMenuCategories()
|
|||
// Use the Categories property instead of the backing variable
|
||||
// because we want to take advantage of binding updates and
|
||||
// property setter logic.
|
||||
Categories = NavCategoryGroup::CreateMenuOptions();
|
||||
Categories = NavCategoryStates::CreateMenuOptions();
|
||||
}
|
||||
|
||||
void ApplicationViewModel::ToggleAlwaysOnTop(float width, float height)
|
||||
|
|
|
@ -17,14 +17,14 @@ namespace CalculatorApp
|
|||
public:
|
||||
ApplicationViewModel();
|
||||
|
||||
void Initialize(CalculatorApp::Common::ViewMode mode); // Use for first init, use deserialize for rehydration
|
||||
void Initialize(CalculatorApp::ViewModel::Common::ViewMode mode); // Use for first init, use deserialize for rehydration
|
||||
|
||||
OBSERVABLE_OBJECT();
|
||||
OBSERVABLE_PROPERTY_RW(StandardCalculatorViewModel ^, CalculatorViewModel);
|
||||
OBSERVABLE_PROPERTY_RW(DateCalculatorViewModel ^, DateCalcViewModel);
|
||||
OBSERVABLE_PROPERTY_RW(GraphingCalculatorViewModel ^, GraphingCalcViewModel);
|
||||
OBSERVABLE_PROPERTY_RW(UnitConverterViewModel ^, ConverterViewModel);
|
||||
OBSERVABLE_PROPERTY_RW(CalculatorApp::Common::ViewMode, PreviousMode);
|
||||
OBSERVABLE_PROPERTY_RW(CalculatorApp::ViewModel::Common::ViewMode, PreviousMode);
|
||||
OBSERVABLE_PROPERTY_R(bool, IsAlwaysOnTop);
|
||||
OBSERVABLE_NAMED_PROPERTY_RW(Platform::String ^, CategoryName);
|
||||
|
||||
|
@ -34,14 +34,14 @@ namespace CalculatorApp
|
|||
COMMAND_FOR_METHOD(CopyCommand, ApplicationViewModel::OnCopyCommand);
|
||||
COMMAND_FOR_METHOD(PasteCommand, ApplicationViewModel::OnPasteCommand);
|
||||
|
||||
property CalculatorApp::Common::ViewMode Mode
|
||||
property CalculatorApp::ViewModel::Common::ViewMode Mode
|
||||
{
|
||||
CalculatorApp::Common::ViewMode get()
|
||||
CalculatorApp::ViewModel::Common::ViewMode get()
|
||||
{
|
||||
return m_mode;
|
||||
}
|
||||
|
||||
void set(CalculatorApp::Common::ViewMode value);
|
||||
void set(CalculatorApp::ViewModel::Common::ViewMode value);
|
||||
}
|
||||
static property Platform::String^ ModePropertyName
|
||||
{
|
||||
|
@ -51,21 +51,21 @@ namespace CalculatorApp
|
|||
}
|
||||
}
|
||||
|
||||
property Windows::Foundation::Collections::IObservableVector<CalculatorApp::Common::NavCategoryGroup^>^ Categories
|
||||
property Windows::Foundation::Collections::IObservableVector<CalculatorApp::ViewModel::Common::NavCategoryGroup^>^ Categories
|
||||
{
|
||||
Windows::Foundation::Collections::IObservableVector<CalculatorApp::Common::NavCategoryGroup^>^ get()
|
||||
Windows::Foundation::Collections::IObservableVector<CalculatorApp::ViewModel::Common::NavCategoryGroup^>^ get()
|
||||
{
|
||||
return m_categories;
|
||||
}
|
||||
|
||||
void set(Windows::Foundation::Collections::IObservableVector<CalculatorApp::Common::NavCategoryGroup^>^ value);
|
||||
void set(Windows::Foundation::Collections::IObservableVector<CalculatorApp::ViewModel::Common::NavCategoryGroup^>^ value);
|
||||
}
|
||||
|
||||
property Windows::UI::Xaml::Visibility ClearMemoryVisibility
|
||||
{
|
||||
Windows::UI::Xaml::Visibility get()
|
||||
{
|
||||
return CalculatorApp::Common::NavCategory::IsCalculatorViewMode(Mode) ? Windows::UI::Xaml::Visibility::Visible
|
||||
return CalculatorApp::ViewModel::Common::NavCategory::IsCalculatorViewMode(Mode) ? Windows::UI::Xaml::Visibility::Visible
|
||||
: Windows::UI::Xaml::Visibility::Collapsed;
|
||||
}
|
||||
}
|
||||
|
@ -106,8 +106,8 @@ namespace CalculatorApp
|
|||
|
||||
void SetMenuCategories();
|
||||
|
||||
CalculatorApp::Common::ViewMode m_mode;
|
||||
Windows::Foundation::Collections::IObservableVector<CalculatorApp::Common::NavCategoryGroup ^> ^ m_categories;
|
||||
CalculatorApp::ViewModel::Common::ViewMode m_mode;
|
||||
Windows::Foundation::Collections::IObservableVector<CalculatorApp::ViewModel::Common::NavCategoryGroup ^> ^ m_categories;
|
||||
Concurrency::task<void> HandleToggleAlwaysOnTop(float width, float height);
|
||||
void SetDisplayNormalAlwaysOnTopOption();
|
||||
};
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#define APP_FILE_NAME "Calculator"
|
||||
#define APP_FILE_NAME "CalcViewModel"
|
||||
#define APP_FILE_IS_EXE
|
||||
#define APP_PRODUCT_NAME "Microsoft Calculator"
|
||||
#define APP_PRODUCT_NAME "Microsoft Calculator ViewModel"
|
||||
#define APP_COMPANY_NAME "Microsoft Corporation"
|
||||
#define APP_COPYRIGHT "\251 Microsoft Corporation. All rights reserved."
|
||||
|
|
@ -35,61 +35,61 @@
|
|||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{90e9761d-9262-4773-942d-caeae75d7140}</ProjectGuid>
|
||||
<Keyword>StaticLibrary</Keyword>
|
||||
<RootNamespace>CalcViewModel</RootNamespace>
|
||||
<ProjectGuid>{812d1a7b-b8ac-49e4-8e6d-af5d59500d56}</ProjectGuid>
|
||||
<Keyword>WindowsRuntimeComponent</Keyword>
|
||||
<RootNamespace>CalculatorApp.ViewModel</RootNamespace>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
|
||||
<AppContainerApplication>true</AppContainerApplication>
|
||||
<ApplicationType>Windows Store</ApplicationType>
|
||||
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformMinVersion>10.0.17134.0</WindowsTargetPlatformMinVersion>
|
||||
<WindowsTargetPlatformVersion>10.0.22621.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformMinVersion>10.0.19041.0</WindowsTargetPlatformMinVersion>
|
||||
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
@ -105,13 +105,13 @@
|
|||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
|
@ -122,175 +122,181 @@
|
|||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
<GenerateProjectSpecificOutputFolder>true</GenerateProjectSpecificOutputFolder>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<CompileAsWinRT>true</CompileAsWinRT>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4453</DisableSpecificWarnings>
|
||||
<AdditionalOptions>/bigobj /await /std:c++17 /utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<PreprocessorDefinitions>_WINRT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
<AdditionalOptions>/bigobj /await %(AdditionalOptions)</AdditionalOptions>
|
||||
<DisableSpecificWarnings>28204;4453</DisableSpecificWarnings>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalOptions>/ignore:4264 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<CompileAsWinRT>true</CompileAsWinRT>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4453</DisableSpecificWarnings>
|
||||
<AdditionalOptions>/bigobj /await /std:c++17 /utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<PreprocessorDefinitions>_WINRT_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
<AdditionalOptions>/bigobj /await %(AdditionalOptions)</AdditionalOptions>
|
||||
<DisableSpecificWarnings>28204;4453</DisableSpecificWarnings>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<ControlFlowGuard>Guard</ControlFlowGuard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalOptions>/ignore:4264 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm'">
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<CompileAsWinRT>true</CompileAsWinRT>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4453</DisableSpecificWarnings>
|
||||
<AdditionalOptions>/bigobj /await /std:c++17 /utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<PreprocessorDefinitions>_WINRT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
<AdditionalOptions>/bigobj /await %(AdditionalOptions)</AdditionalOptions>
|
||||
<DisableSpecificWarnings>28204;4453</DisableSpecificWarnings>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalOptions>/ignore:4264 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm'">
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<CompileAsWinRT>true</CompileAsWinRT>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4453</DisableSpecificWarnings>
|
||||
<AdditionalOptions>/bigobj /await /std:c++17 /utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<PreprocessorDefinitions>_WINRT_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
<AdditionalOptions>/bigobj /await %(AdditionalOptions)</AdditionalOptions>
|
||||
<DisableSpecificWarnings>28204;4453</DisableSpecificWarnings>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<ControlFlowGuard>Guard</ControlFlowGuard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PreprocessorDefinitions>_WINRT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
<AdditionalOptions>/bigobj /await %(AdditionalOptions)</AdditionalOptions>
|
||||
<DisableSpecificWarnings>28204;4453</DisableSpecificWarnings>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PreprocessorDefinitions>_WINRT_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
<AdditionalOptions>/bigobj /await %(AdditionalOptions)</AdditionalOptions>
|
||||
<DisableSpecificWarnings>28204;4453</DisableSpecificWarnings>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<ControlFlowGuard>Guard</ControlFlowGuard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalOptions>/ignore:4264 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<CompileAsWinRT>true</CompileAsWinRT>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4453</DisableSpecificWarnings>
|
||||
<AdditionalOptions>/bigobj /await /std:c++17 /utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<PreprocessorDefinitions>_WINRT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
<AdditionalOptions>/bigobj /await %(AdditionalOptions)</AdditionalOptions>
|
||||
<DisableSpecificWarnings>28204;4453</DisableSpecificWarnings>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalOptions>/ignore:4264 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<CompileAsWinRT>true</CompileAsWinRT>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4453</DisableSpecificWarnings>
|
||||
<AdditionalOptions>/bigobj /await /std:c++17 /utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<PreprocessorDefinitions>_WINRT_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
<AdditionalOptions>/bigobj /await %(AdditionalOptions)</AdditionalOptions>
|
||||
<DisableSpecificWarnings>28204;4453</DisableSpecificWarnings>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<ControlFlowGuard>Guard</ControlFlowGuard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalOptions>/ignore:4264 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<CompileAsWinRT>true</CompileAsWinRT>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4453</DisableSpecificWarnings>
|
||||
<AdditionalOptions>/bigobj /await /std:c++17 /utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalOptions>/ignore:4264 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<CompileAsWinRT>true</CompileAsWinRT>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4453</DisableSpecificWarnings>
|
||||
<AdditionalOptions>/bigobj /await /std:c++17 /utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalOptions>/ignore:4264 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(IsStoreBuild)' == 'True'">
|
||||
<ClCompile>
|
||||
<AdditionalOptions>/DSEND_DIAGNOSTICS %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<PropertyGroup>
|
||||
<Version Condition="'$(Version)' == ''">0.0.0.0</Version>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="CalcViewModel.rc" PreprocessorDefinitions="%(PreprocessorDefinitions);APP_VERSION_MAJOR=$(Version.Split(`.`)[0]);APP_VERSION_MINOR=$(Version.Split(`.`)[1]);APP_VERSION_BUILD=$(Version.Split(`.`)[2]);APP_VERSION_REVISION=$(Version.Split(`.`)[3])" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ApplicationViewModel.h" />
|
||||
<ClInclude Include="Common\AppResourceProvider.h" />
|
||||
|
@ -314,6 +320,7 @@
|
|||
<ClInclude Include="Common\NavCategory.h" />
|
||||
<ClInclude Include="Common\NetworkManager.h" />
|
||||
<ClInclude Include="Common\NumberBase.h" />
|
||||
<ClInclude Include="Common\RadixType.h" />
|
||||
<ClInclude Include="Common\TraceLogger.h" />
|
||||
<ClInclude Include="Common\Utils.h" />
|
||||
<ClInclude Include="DataLoaders\CurrencyDataLoader.h" />
|
||||
|
@ -350,6 +357,7 @@
|
|||
<ClCompile Include="Common\LocalizationService.cpp" />
|
||||
<ClCompile Include="Common\NavCategory.cpp" />
|
||||
<ClCompile Include="Common\NetworkManager.cpp" />
|
||||
<ClCompile Include="Common\RadixType.cpp" />
|
||||
<ClCompile Include="Common\TraceLogger.cpp" />
|
||||
<ClCompile Include="Common\Utils.cpp" />
|
||||
<ClCompile Include="DataLoaders\CurrencyDataLoader.cpp" />
|
||||
|
@ -365,10 +373,10 @@
|
|||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
|
@ -407,5 +415,6 @@
|
|||
<None Include="DataLoaders\DefaultFromToCurrency.json" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -2,27 +2,20 @@
|
|||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Common">
|
||||
<UniqueIdentifier>{1daab7c4-63f6-4266-a259-f34acad66d09}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{05fb7833-4679-4430-bf21-808354e815bf}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Common\Automation">
|
||||
<UniqueIdentifier>{8d4edf06-c312-4312-978a-b6c2beb8295a}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{8f1ef587-e5ce-4fc2-b9b7-73326d5e779a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="DataLoaders">
|
||||
<UniqueIdentifier>{0184f727-b8aa-4af8-a699-63f1b56e7853}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{70216695-3d7b-451a-98e4-cacbea3ba0a6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="GraphingCalculator">
|
||||
<UniqueIdentifier>{cf7dca32-9727-4f98-83c3-1c0ca7dd1e0c}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{9b94309f-6b9b-4cbb-8584-4273061cc432}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp" />
|
||||
<ClCompile Include="ApplicationViewModel.cpp" />
|
||||
<ClCompile Include="DateCalculatorViewModel.cpp" />
|
||||
<ClCompile Include="HistoryItemViewModel.cpp" />
|
||||
<ClCompile Include="HistoryViewModel.cpp" />
|
||||
<ClCompile Include="MemoryItemViewModel.cpp" />
|
||||
<ClCompile Include="StandardCalculatorViewModel.cpp" />
|
||||
<ClCompile Include="UnitConverterViewModel.cpp" />
|
||||
<ClCompile Include="Common\AppResourceProvider.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
|
@ -56,12 +49,18 @@
|
|||
<ClCompile Include="Common\NetworkManager.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Common\RadixType.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Common\TraceLogger.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Common\Utils.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Common\Automation\NarratorAnnouncement.cpp">
|
||||
<Filter>Common\Automation</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Common\Automation\NarratorNotifier.cpp">
|
||||
<Filter>Common\Automation</Filter>
|
||||
</ClCompile>
|
||||
|
@ -80,26 +79,25 @@
|
|||
<ClCompile Include="GraphingCalculator\GraphingCalculatorViewModel.cpp">
|
||||
<Filter>GraphingCalculator</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Common\Automation\NarratorAnnouncement.cpp">
|
||||
<Filter>Common\Automation</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GraphingCalculator\GraphingSettingsViewModel.cpp">
|
||||
<Filter>GraphingCalculator</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ApplicationViewModel.cpp" />
|
||||
<ClCompile Include="DateCalculatorViewModel.cpp" />
|
||||
<ClCompile Include="HistoryItemViewModel.cpp" />
|
||||
<ClCompile Include="HistoryViewModel.cpp" />
|
||||
<ClCompile Include="MemoryItemViewModel.cpp" />
|
||||
<ClCompile Include="StandardCalculatorViewModel.cpp" />
|
||||
<ClCompile Include="UnitConverterViewModel.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
<ClInclude Include="ApplicationViewModel.h" />
|
||||
<ClInclude Include="DateCalculatorViewModel.h" />
|
||||
<ClInclude Include="HistoryItemViewModel.h" />
|
||||
<ClInclude Include="HistoryViewModel.h" />
|
||||
<ClInclude Include="MemoryItemViewModel.h" />
|
||||
<ClInclude Include="StandardCalculatorViewModel.h" />
|
||||
<ClInclude Include="UnitConverterViewModel.h" />
|
||||
<ClInclude Include="Common\AppResourceProvider.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\BitLength.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\CalculatorButtonPressedEventArgs.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
|
@ -115,6 +113,9 @@
|
|||
<ClInclude Include="Common\DateCalculator.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\DelegateCommand.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\DisplayExpressionToken.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
|
@ -145,12 +146,21 @@
|
|||
<ClInclude Include="Common\NetworkManager.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\NumberBase.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\RadixType.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\TraceLogger.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\Utils.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\Automation\NarratorAnnouncement.h">
|
||||
<Filter>Common\Automation</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\Automation\NarratorNotifier.h">
|
||||
<Filter>Common\Automation</Filter>
|
||||
</ClInclude>
|
||||
|
@ -160,6 +170,9 @@
|
|||
<ClInclude Include="DataLoaders\CurrencyHttpClient.h">
|
||||
<Filter>DataLoaders</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DataLoaders\DataLoaderMockConstants.h">
|
||||
<Filter>DataLoaders</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DataLoaders\ICurrencyHttpClient.h">
|
||||
<Filter>DataLoaders</Filter>
|
||||
</ClInclude>
|
||||
|
@ -169,36 +182,27 @@
|
|||
<ClInclude Include="DataLoaders\UnitConverterDataLoader.h">
|
||||
<Filter>DataLoaders</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DataLoaders\DataLoaderMockConstants.h">
|
||||
<Filter>DataLoaders</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\Automation\NarratorAnnouncement.h">
|
||||
<Filter>Common\Automation</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\BitLength.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\NumberBase.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GraphingCalculator\EquationViewModel.h">
|
||||
<Filter>GraphingCalculator</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GraphingCalculator\GraphingCalculatorViewModel.h">
|
||||
<Filter>GraphingCalculator</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GraphingCalculatorEnums.h">
|
||||
<Filter>Common</Filter>
|
||||
<ClInclude Include="GraphingCalculator\GraphingSettingsViewModel.h">
|
||||
<Filter>GraphingCalculator</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GraphingCalculator\VariableViewModel.h">
|
||||
<Filter>GraphingCalculator</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GraphingCalculator\GraphingSettingsViewModel.h">
|
||||
<Filter>GraphingCalculator</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\DelegateCommand.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ApplicationViewModel.h" />
|
||||
<ClInclude Include="DateCalculatorViewModel.h" />
|
||||
<ClInclude Include="GraphingCalculatorEnums.h" />
|
||||
<ClInclude Include="HistoryItemViewModel.h" />
|
||||
<ClInclude Include="HistoryViewModel.h" />
|
||||
<ClInclude Include="MemoryItemViewModel.h" />
|
||||
<ClInclude Include="StandardCalculatorViewModel.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
<ClInclude Include="UnitConverterViewModel.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="DataLoaders\DefaultFromToCurrency.json">
|
||||
|
@ -206,6 +210,6 @@
|
|||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="$(MSBuildThisFileDirectory)DensityStyles\Compact.xaml" />
|
||||
<ResourceCompile Include="CalcViewModel.rc" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -7,6 +7,7 @@
|
|||
using namespace Platform;
|
||||
using namespace Windows::ApplicationModel::Resources;
|
||||
using namespace CalculatorApp;
|
||||
using namespace CalculatorApp::ViewModel::Common;
|
||||
|
||||
AppResourceProvider::AppResourceProvider()
|
||||
{
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
namespace CalculatorApp
|
||||
namespace CalculatorApp::ViewModel::Common
|
||||
{
|
||||
public ref class AppResourceProvider sealed
|
||||
{
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// being used. Depending on the version of the OS the app is running on,
|
||||
// the app may need a host that uses LiveRegionChanged or RaiseNotification.
|
||||
|
||||
namespace CalculatorApp::Common::Automation
|
||||
namespace CalculatorApp::ViewModel::Common::Automation
|
||||
{
|
||||
public
|
||||
interface class INarratorAnnouncementHost
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "pch.h"
|
||||
#include "LiveRegionHost.h"
|
||||
|
||||
using namespace CalculatorApp::Common::Automation;
|
||||
using namespace CalculatorApp::ViewModel::Common::Automation;
|
||||
using namespace Windows::UI::Xaml::Automation;
|
||||
using namespace Windows::UI::Xaml::Automation::Peers;
|
||||
using namespace Windows::UI::Xaml::Controls;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// This event is unreliable and should be deprecated in favor of the new
|
||||
// RaiseNotification API in RS3.
|
||||
|
||||
namespace CalculatorApp::Common::Automation
|
||||
namespace CalculatorApp::ViewModel::Common::Automation
|
||||
{
|
||||
// This class exists so that the app can run on RS2 and use LiveRegions
|
||||
// to host notifications on those builds.
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
#include "pch.h"
|
||||
#include "NarratorAnnouncement.h"
|
||||
|
||||
using namespace CalculatorApp::Common::Automation;
|
||||
using namespace CalculatorApp::ViewModel::Common::Automation;
|
||||
using namespace Platform;
|
||||
using namespace Windows::UI::Xaml::Automation::Peers;
|
||||
|
||||
namespace CalculatorApp::Common::Automation
|
||||
namespace CalculatorApp::ViewModel::Common::Automation
|
||||
{
|
||||
namespace CalculatorActivityIds
|
||||
{
|
||||
|
@ -30,6 +30,7 @@ namespace CalculatorApp::Common::Automation
|
|||
StringReference GraphViewBestFitChanged(L"GraphViewBestFitChanged");
|
||||
StringReference AlwaysOnTop(L"AlwaysOnTop");
|
||||
StringReference BitShiftRadioButtonContent(L"BitShiftRadioButtonContent");
|
||||
StringReference SettingsPageOpened(L"SettingsPageOpened");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,3 +205,12 @@ NarratorAnnouncement ^ CalculatorAnnouncement::GetBitShiftRadioButtonCheckedAnno
|
|||
AutomationNotificationKind::ActionCompleted,
|
||||
AutomationNotificationProcessing::ImportantMostRecent);
|
||||
}
|
||||
|
||||
NarratorAnnouncement ^ CalculatorAnnouncement::GetSettingsPageOpenedAnnouncement(Platform::String ^ announcement)
|
||||
{
|
||||
return ref new NarratorAnnouncement(
|
||||
announcement,
|
||||
CalculatorActivityIds::SettingsPageOpened,
|
||||
AutomationNotificationKind::ActionCompleted,
|
||||
AutomationNotificationProcessing::ImportantMostRecent);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
namespace CalculatorApp::Common::Automation
|
||||
namespace CalculatorApp::ViewModel::Common::Automation
|
||||
{
|
||||
public
|
||||
ref class NarratorAnnouncement sealed
|
||||
|
@ -28,25 +28,23 @@ public
|
|||
static bool IsValid(NarratorAnnouncement ^ announcement);
|
||||
|
||||
private:
|
||||
// Make CalculatorAnnouncement a friend class so it is the only
|
||||
// class that can access the private constructor.
|
||||
friend class CalculatorAnnouncement;
|
||||
Platform::String ^ m_announcement;
|
||||
Platform::String ^ m_activityId;
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationNotificationKind m_kind;
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationNotificationProcessing m_processing;
|
||||
|
||||
internal:
|
||||
NarratorAnnouncement(
|
||||
Platform::String ^ announcement,
|
||||
Platform::String ^ activityId,
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationNotificationKind kind,
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationNotificationProcessing processing);
|
||||
|
||||
Platform::String ^ m_announcement;
|
||||
Platform::String ^ m_activityId;
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationNotificationKind m_kind;
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationNotificationProcessing m_processing;
|
||||
};
|
||||
|
||||
// CalculatorAnnouncement is intended to contain only static methods
|
||||
// that return announcements made for the Calculator app.
|
||||
class CalculatorAnnouncement
|
||||
public
|
||||
ref class CalculatorAnnouncement sealed
|
||||
{
|
||||
public:
|
||||
static NarratorAnnouncement ^ GetDisplayUpdatedAnnouncement(Platform::String ^ announcement);
|
||||
|
@ -77,5 +75,7 @@ public
|
|||
static NarratorAnnouncement ^ GetAlwaysOnTopChangedAnnouncement(Platform::String ^ announcement);
|
||||
|
||||
static NarratorAnnouncement ^ GetBitShiftRadioButtonCheckedAnnouncement(Platform::String ^ announcement);
|
||||
|
||||
static NarratorAnnouncement ^ GetSettingsPageOpenedAnnouncement(Platform::String ^ announcement);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "NotificationHost.h"
|
||||
#include "LiveRegionHost.h"
|
||||
|
||||
using namespace CalculatorApp::Common::Automation;
|
||||
using namespace CalculatorApp::ViewModel::Common::Automation;
|
||||
using namespace std;
|
||||
|
||||
INarratorAnnouncementHost ^ NarratorAnnouncementHostFactory::s_hostProducer;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// Depending on the version of the OS the app is running on, the factory will return
|
||||
// an announcement host appropriate for that version.
|
||||
|
||||
namespace CalculatorApp::Common::Automation
|
||||
namespace CalculatorApp::ViewModel::Common::Automation
|
||||
{
|
||||
class NarratorAnnouncementHostFactory
|
||||
{
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "pch.h"
|
||||
#include "NarratorNotifier.h"
|
||||
|
||||
using namespace CalculatorApp::Common::Automation;
|
||||
using namespace CalculatorApp::ViewModel::Common::Automation;
|
||||
using namespace Platform;
|
||||
using namespace Windows::UI::Xaml;
|
||||
using namespace Windows::UI::Xaml::Automation;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#pragma once
|
||||
#include "NarratorAnnouncement.h"
|
||||
|
||||
namespace CalculatorApp::Common::Automation
|
||||
namespace CalculatorApp::ViewModel::Common::Automation
|
||||
{
|
||||
public
|
||||
ref class NarratorNotifier sealed : public Windows::UI::Xaml::DependencyObject
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "pch.h"
|
||||
#include "NotificationHost.h"
|
||||
|
||||
using namespace CalculatorApp::Common::Automation;
|
||||
using namespace CalculatorApp::ViewModel::Common::Automation;
|
||||
using namespace Windows::Foundation::Metadata;
|
||||
using namespace Windows::UI::Xaml::Automation;
|
||||
using namespace Windows::UI::Xaml::Automation::Peers;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// This class announces NarratorAnnouncements using the RaiseNotification API
|
||||
// available in RS3.
|
||||
|
||||
namespace CalculatorApp::Common::Automation
|
||||
namespace CalculatorApp::ViewModel::Common::Automation
|
||||
{
|
||||
public
|
||||
ref class NotificationHost sealed : public INarratorAnnouncementHost
|
||||
|
@ -23,10 +23,10 @@ public
|
|||
|
||||
private:
|
||||
static Windows::UI::Xaml::Automation::Peers::AutomationNotificationKind
|
||||
GetWindowsNotificationKind(CalculatorApp::Common::Automation::AutomationNotificationKind customKindType);
|
||||
GetWindowsNotificationKind(CalculatorApp::ViewModel::Common::Automation::AutomationNotificationKind customKindType);
|
||||
|
||||
static Windows::UI::Xaml::Automation::Peers::AutomationNotificationProcessing
|
||||
GetWindowsNotificationProcessing(CalculatorApp::Common::Automation::AutomationNotificationProcessing customProcessingType);
|
||||
GetWindowsNotificationProcessing(CalculatorApp::ViewModel::Common::Automation::AutomationNotificationProcessing customProcessingType);
|
||||
|
||||
private:
|
||||
Windows::UI::Xaml::UIElement ^ m_host;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
namespace CalculatorApp
|
||||
namespace CalculatorApp::ViewModel
|
||||
{
|
||||
namespace Common
|
||||
{
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
#include "CalculatorButtonPressedEventArgs.h"
|
||||
|
||||
using namespace CalculatorApp;
|
||||
using namespace CalculatorApp::Common;
|
||||
using namespace CalculatorApp::ViewModel;
|
||||
using namespace CalculatorApp::ViewModel::Common;
|
||||
using namespace Platform;
|
||||
|
||||
NumbersAndOperatorsEnum CalculatorButtonPressedEventArgs::GetOperationFromCommandParameter(_In_ Object ^ commandParameter)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "CalculatorButtonUser.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace CalculatorApp
|
||||
namespace CalculatorApp::ViewModel
|
||||
{
|
||||
namespace Common
|
||||
{
|
||||
|
@ -15,15 +15,15 @@ namespace CalculatorApp
|
|||
{
|
||||
public:
|
||||
PROPERTY_R(Platform::String ^, AuditoryFeedback);
|
||||
PROPERTY_R(CalculatorApp::NumbersAndOperatorsEnum, Operation);
|
||||
PROPERTY_R(CalculatorApp::ViewModel::Common::NumbersAndOperatorsEnum, Operation);
|
||||
|
||||
CalculatorButtonPressedEventArgs(Platform::String ^ feedback, CalculatorApp::NumbersAndOperatorsEnum operation)
|
||||
CalculatorButtonPressedEventArgs(Platform::String ^ feedback, CalculatorApp::ViewModel::Common::NumbersAndOperatorsEnum operation)
|
||||
: m_AuditoryFeedback(feedback)
|
||||
, m_Operation(operation)
|
||||
{
|
||||
}
|
||||
|
||||
static CalculatorApp::NumbersAndOperatorsEnum GetOperationFromCommandParameter(_In_ Platform::Object ^ commandParameter);
|
||||
static CalculatorApp::ViewModel::Common::NumbersAndOperatorsEnum GetOperationFromCommandParameter(_In_ Platform::Object ^ commandParameter);
|
||||
static Platform::String ^ GetAuditoryFeedbackFromCommandParameter(_In_ Platform::Object ^ commandParameter);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,12 +5,11 @@
|
|||
|
||||
#include "CalcManager/Command.h"
|
||||
|
||||
namespace CalculatorApp
|
||||
namespace CalculatorApp::ViewModel::Common
|
||||
{
|
||||
namespace CM = CalculationManager;
|
||||
|
||||
public
|
||||
enum class NumbersAndOperatorsEnum
|
||||
public enum class NumbersAndOperatorsEnum
|
||||
{
|
||||
Zero = (int)CM::Command::Command0,
|
||||
One = (int)CM::Command::Command1,
|
||||
|
|
|
@ -8,143 +8,149 @@
|
|||
#include "StandardCalculatorViewModel.h"
|
||||
|
||||
using namespace CalculatorApp;
|
||||
using namespace CalculatorApp::ViewModel;
|
||||
using namespace CalculatorApp::ViewModel::Common;
|
||||
using namespace CalculationManager;
|
||||
using namespace Platform;
|
||||
using namespace std;
|
||||
|
||||
CalculatorDisplay::CalculatorDisplay()
|
||||
namespace CalculatorApp::ViewModel::Common
|
||||
{
|
||||
}
|
||||
|
||||
void CalculatorDisplay::SetCallback(Platform::WeakReference callbackReference)
|
||||
{
|
||||
m_callbackReference = callbackReference;
|
||||
}
|
||||
|
||||
void CalculatorDisplay::SetHistoryCallback(Platform::WeakReference callbackReference)
|
||||
{
|
||||
m_historyCallbackReference = callbackReference;
|
||||
}
|
||||
|
||||
void CalculatorDisplay::SetPrimaryDisplay(_In_ const wstring& displayStringValue, _In_ bool isError)
|
||||
{
|
||||
if (m_callbackReference)
|
||||
CalculatorDisplay::CalculatorDisplay()
|
||||
{
|
||||
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
|
||||
}
|
||||
|
||||
void CalculatorDisplay::SetCallback(Platform::WeakReference callbackReference)
|
||||
{
|
||||
m_callbackReference = callbackReference;
|
||||
}
|
||||
|
||||
void CalculatorDisplay::SetHistoryCallback(Platform::WeakReference callbackReference)
|
||||
{
|
||||
m_historyCallbackReference = callbackReference;
|
||||
}
|
||||
|
||||
void CalculatorDisplay::SetPrimaryDisplay(_In_ const wstring& displayStringValue, _In_ bool isError)
|
||||
{
|
||||
if (m_callbackReference)
|
||||
{
|
||||
calcVM->SetPrimaryDisplay(StringReference(displayStringValue.c_str()), isError);
|
||||
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
|
||||
{
|
||||
calcVM->SetPrimaryDisplay(StringReference(displayStringValue.c_str()), isError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorDisplay::SetParenthesisNumber(_In_ unsigned int parenthesisCount)
|
||||
{
|
||||
if (m_callbackReference != nullptr)
|
||||
{
|
||||
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
|
||||
{
|
||||
calcVM->SetParenthesisCount(parenthesisCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorDisplay::OnNoRightParenAdded()
|
||||
{
|
||||
if (m_callbackReference != nullptr)
|
||||
{
|
||||
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
|
||||
{
|
||||
calcVM->OnNoRightParenAdded();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorDisplay::SetIsInError(bool isError)
|
||||
{
|
||||
if (m_callbackReference != nullptr)
|
||||
{
|
||||
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
|
||||
{
|
||||
calcVM->IsInError = isError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorDisplay::SetExpressionDisplay(
|
||||
_Inout_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& tokens,
|
||||
_Inout_ std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& commands)
|
||||
{
|
||||
if (m_callbackReference != nullptr)
|
||||
{
|
||||
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
|
||||
{
|
||||
calcVM->SetExpressionDisplay(tokens, commands);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorDisplay::SetMemorizedNumbers(_In_ const vector<std::wstring>& newMemorizedNumbers)
|
||||
{
|
||||
if (m_callbackReference != nullptr)
|
||||
{
|
||||
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
|
||||
{
|
||||
calcVM->SetMemorizedNumbers(newMemorizedNumbers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorDisplay::OnHistoryItemAdded(_In_ unsigned int addedItemIndex)
|
||||
{
|
||||
if (m_historyCallbackReference != nullptr)
|
||||
{
|
||||
if (auto historyVM = m_historyCallbackReference.Resolve<ViewModel::HistoryViewModel>())
|
||||
{
|
||||
historyVM->OnHistoryItemAdded(addedItemIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorDisplay::MaxDigitsReached()
|
||||
{
|
||||
if (m_callbackReference != nullptr)
|
||||
{
|
||||
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
|
||||
{
|
||||
calcVM->OnMaxDigitsReached();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorDisplay::BinaryOperatorReceived()
|
||||
{
|
||||
if (m_callbackReference != nullptr)
|
||||
{
|
||||
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
|
||||
{
|
||||
calcVM->OnBinaryOperatorReceived();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorDisplay::MemoryItemChanged(unsigned int indexOfMemory)
|
||||
{
|
||||
if (m_callbackReference != nullptr)
|
||||
{
|
||||
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
|
||||
{
|
||||
calcVM->OnMemoryItemChanged(indexOfMemory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorDisplay::InputChanged()
|
||||
{
|
||||
if (m_callbackReference != nullptr)
|
||||
{
|
||||
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
|
||||
{
|
||||
calcVM->OnInputChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorDisplay::SetParenthesisNumber(_In_ unsigned int parenthesisCount)
|
||||
{
|
||||
if (m_callbackReference != nullptr)
|
||||
{
|
||||
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
|
||||
{
|
||||
calcVM->SetParenthesisCount(parenthesisCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorDisplay::OnNoRightParenAdded()
|
||||
{
|
||||
if (m_callbackReference != nullptr)
|
||||
{
|
||||
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
|
||||
{
|
||||
calcVM->OnNoRightParenAdded();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorDisplay::SetIsInError(bool isError)
|
||||
{
|
||||
if (m_callbackReference != nullptr)
|
||||
{
|
||||
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
|
||||
{
|
||||
calcVM->IsInError = isError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorDisplay::SetExpressionDisplay(
|
||||
_Inout_ std::shared_ptr<std::vector<std::pair<std::wstring, int>>> const& tokens,
|
||||
_Inout_ std::shared_ptr<std::vector<std::shared_ptr<IExpressionCommand>>> const& commands)
|
||||
{
|
||||
if (m_callbackReference != nullptr)
|
||||
{
|
||||
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
|
||||
{
|
||||
calcVM->SetExpressionDisplay(tokens, commands);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorDisplay::SetMemorizedNumbers(_In_ const vector<std::wstring>& newMemorizedNumbers)
|
||||
{
|
||||
if (m_callbackReference != nullptr)
|
||||
{
|
||||
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
|
||||
{
|
||||
calcVM->SetMemorizedNumbers(newMemorizedNumbers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorDisplay::OnHistoryItemAdded(_In_ unsigned int addedItemIndex)
|
||||
{
|
||||
if (m_historyCallbackReference != nullptr)
|
||||
{
|
||||
if (auto historyVM = m_historyCallbackReference.Resolve<ViewModel::HistoryViewModel>())
|
||||
{
|
||||
historyVM->OnHistoryItemAdded(addedItemIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorDisplay::MaxDigitsReached()
|
||||
{
|
||||
if (m_callbackReference != nullptr)
|
||||
{
|
||||
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
|
||||
{
|
||||
calcVM->OnMaxDigitsReached();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorDisplay::BinaryOperatorReceived()
|
||||
{
|
||||
if (m_callbackReference != nullptr)
|
||||
{
|
||||
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
|
||||
{
|
||||
calcVM->OnBinaryOperatorReceived();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorDisplay::MemoryItemChanged(unsigned int indexOfMemory)
|
||||
{
|
||||
if (m_callbackReference != nullptr)
|
||||
{
|
||||
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
|
||||
{
|
||||
calcVM->OnMemoryItemChanged(indexOfMemory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorDisplay::InputChanged()
|
||||
{
|
||||
if (m_callbackReference != nullptr)
|
||||
{
|
||||
if (auto calcVM = m_callbackReference.Resolve<ViewModel::StandardCalculatorViewModel>())
|
||||
{
|
||||
calcVM->OnInputChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include "CalcManager/Header Files/ICalcDisplay.h"
|
||||
|
||||
namespace CalculatorApp
|
||||
namespace CalculatorApp::ViewModel::Common
|
||||
{
|
||||
// Callback interface to be implemented by the CalculatorManager
|
||||
class CalculatorDisplay : public ICalcDisplay
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
using namespace std;
|
||||
using namespace concurrency;
|
||||
using namespace CalculatorApp;
|
||||
using namespace CalculatorApp::Common;
|
||||
using namespace CalculatorApp::ViewModel::Common;
|
||||
using namespace CalculatorApp::ViewModel;
|
||||
using namespace Platform;
|
||||
using namespace Platform::Collections;
|
||||
using namespace Windows::Foundation;
|
||||
|
@ -96,7 +97,7 @@ bool CopyPasteManager::HasStringToPaste()
|
|||
|
||||
String ^ CopyPasteManager::ValidatePasteExpression(String ^ pastedText, ViewMode mode, NumberBase programmerNumberBase, BitLength bitLengthType)
|
||||
{
|
||||
return ValidatePasteExpression(pastedText, mode, NavCategory::GetGroupType(mode), programmerNumberBase, bitLengthType);
|
||||
return ValidatePasteExpression(pastedText, mode, NavCategoryStates::GetGroupType(mode), programmerNumberBase, bitLengthType);
|
||||
}
|
||||
|
||||
// return "NoOp" if pastedText is invalid else return pastedText
|
||||
|
@ -116,7 +117,7 @@ String
|
|||
}
|
||||
|
||||
// Get english translated expression
|
||||
String ^ englishString = LocalizationSettings::GetInstance().GetEnglishValueFromLocalizedDigits(pastedText);
|
||||
String ^ englishString = LocalizationSettings::GetInstance()->GetEnglishValueFromLocalizedDigits(pastedText);
|
||||
|
||||
// Removing the spaces, comma separator from the pasteExpression to allow pasting of expressions like 1 + 2+1,333
|
||||
auto pasteExpression = wstring(RemoveUnwantedCharsFromString(englishString)->Data());
|
||||
|
@ -287,9 +288,8 @@ bool CopyPasteManager::ExpressionRegExMatch(
|
|||
}
|
||||
else if (mode == ViewMode::Programmer)
|
||||
{
|
||||
patterns.assign(
|
||||
programmerModePatterns[(int)programmerNumberBase - (int)NumberBase::HexBase].begin(),
|
||||
programmerModePatterns[(int)programmerNumberBase - (int)NumberBase::HexBase].end());
|
||||
auto pattern = &programmerModePatterns[static_cast<int>(programmerNumberBase) - static_cast<int>(NumberBase::HexBase)];
|
||||
patterns.assign(pattern->begin(), pattern->end());
|
||||
}
|
||||
else if (modeType == CategoryGroupType::Converter)
|
||||
{
|
||||
|
@ -504,18 +504,15 @@ ULONG32 CopyPasteManager::StandardScientificOperandLength(Platform::String ^ ope
|
|||
const bool hasDecimal = operandWstring.find('.') != wstring::npos;
|
||||
auto length = operandWstring.length();
|
||||
|
||||
if (hasDecimal)
|
||||
if (hasDecimal && length >= 2)
|
||||
{
|
||||
if (length >= 2)
|
||||
if ((operandWstring[0] == L'0') && (operandWstring[1] == L'.'))
|
||||
{
|
||||
if ((operandWstring[0] == L'0') && (operandWstring[1] == L'.'))
|
||||
{
|
||||
length -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
length -= 1;
|
||||
}
|
||||
length -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
length -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -614,7 +611,7 @@ ULONG32 CopyPasteManager::ProgrammerOperandLength(Platform::String ^ operand, Nu
|
|||
Platform::String ^ CopyPasteManager::RemoveUnwantedCharsFromString(Platform::String ^ input)
|
||||
{
|
||||
constexpr wchar_t unWantedChars[] = { L' ', L',', L'"', 165, 164, 8373, 36, 8353, 8361, 8362, 8358, 8377, 163, 8364, 8234, 8235, 8236, 8237, 160 };
|
||||
input = CalculatorApp::Common::LocalizationSettings::GetInstance().RemoveGroupSeparators(input);
|
||||
input = CalculatorApp::ViewModel::Common::LocalizationSettings::GetInstance()->RemoveGroupSeparators(input);
|
||||
return ref new String(Utils::RemoveUnwantedCharsFromString(input->Data(), unWantedChars).c_str());
|
||||
}
|
||||
|
||||
|
|
|
@ -13,10 +13,9 @@ namespace CalculatorUnitTests
|
|||
class CopyPasteManagerTest;
|
||||
}
|
||||
|
||||
namespace CalculatorApp
|
||||
namespace CalculatorApp::ViewModel::Common
|
||||
{
|
||||
public
|
||||
value struct CopyPasteMaxOperandLengthAndValue
|
||||
public value struct CopyPasteMaxOperandLengthAndValue
|
||||
{
|
||||
unsigned int maxLength;
|
||||
unsigned long long maxValue;
|
||||
|
@ -26,9 +25,11 @@ public
|
|||
{
|
||||
public:
|
||||
static void CopyToClipboard(Platform::String ^ stringToCopy);
|
||||
static Windows::Foundation::IAsyncOperation<
|
||||
Platform::String
|
||||
^> ^ GetStringToPaste(CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType, CalculatorApp::Common::NumberBase programmerNumberBase, CalculatorApp::Common::BitLength bitLengthType);
|
||||
static Windows::Foundation::IAsyncOperation<Platform::String ^> ^ GetStringToPaste(
|
||||
CalculatorApp::ViewModel::Common::ViewMode mode,
|
||||
CalculatorApp::ViewModel::Common::CategoryGroupType modeType,
|
||||
CalculatorApp::ViewModel::Common::NumberBase programmerNumberBase,
|
||||
CalculatorApp::ViewModel::Common::BitLength bitLengthType);
|
||||
static bool HasStringToPaste();
|
||||
static bool IsErrorMessage(Platform::String ^ message);
|
||||
static property unsigned int MaxPasteableLength
|
||||
|
@ -87,39 +88,39 @@ public
|
|||
static Platform::String
|
||||
^ ValidatePasteExpression(
|
||||
Platform::String ^ pastedText,
|
||||
CalculatorApp::Common::ViewMode mode,
|
||||
CalculatorApp::Common::NumberBase programmerNumberBase,
|
||||
CalculatorApp::Common::BitLength bitLengthType);
|
||||
CalculatorApp::ViewModel::Common::ViewMode mode,
|
||||
CalculatorApp::ViewModel::Common::NumberBase programmerNumberBase,
|
||||
CalculatorApp::ViewModel::Common::BitLength bitLengthType);
|
||||
static Platform::String
|
||||
^ ValidatePasteExpression(
|
||||
Platform::String ^ pastedText,
|
||||
CalculatorApp::Common::ViewMode mode,
|
||||
CalculatorApp::Common::CategoryGroupType modeType,
|
||||
CalculatorApp::Common::NumberBase programmerNumberBase,
|
||||
CalculatorApp::Common::BitLength bitLengthType);
|
||||
CalculatorApp::ViewModel::Common::ViewMode mode,
|
||||
CalculatorApp::ViewModel::Common::CategoryGroupType modeType,
|
||||
CalculatorApp::ViewModel::Common::NumberBase programmerNumberBase,
|
||||
CalculatorApp::ViewModel::Common::BitLength bitLengthType);
|
||||
static CopyPasteMaxOperandLengthAndValue GetMaxOperandLengthAndValue(
|
||||
CalculatorApp::Common::ViewMode mode,
|
||||
CalculatorApp::Common::CategoryGroupType modeType,
|
||||
CalculatorApp::Common::NumberBase programmerNumberBase,
|
||||
CalculatorApp::Common::BitLength bitLengthType);
|
||||
CalculatorApp::ViewModel::Common::ViewMode mode,
|
||||
CalculatorApp::ViewModel::Common::CategoryGroupType modeType,
|
||||
CalculatorApp::ViewModel::Common::NumberBase programmerNumberBase,
|
||||
CalculatorApp::ViewModel::Common::BitLength bitLengthType);
|
||||
static Windows::Foundation::Collections::IVector<
|
||||
Platform::String ^> ^ ExtractOperands(Platform::String ^ pasteExpression, CalculatorApp::Common::ViewMode mode);
|
||||
Platform::String ^> ^ ExtractOperands(Platform::String ^ pasteExpression, CalculatorApp::ViewModel::Common::ViewMode mode);
|
||||
static bool ExpressionRegExMatch(
|
||||
Windows::Foundation::Collections::IVector<Platform::String ^> ^ operands,
|
||||
CalculatorApp::Common::ViewMode mode,
|
||||
CalculatorApp::Common::CategoryGroupType modeType,
|
||||
CalculatorApp::Common::NumberBase programmerNumberBase,
|
||||
CalculatorApp::Common::BitLength bitLengthType);
|
||||
CalculatorApp::ViewModel::Common::ViewMode mode,
|
||||
CalculatorApp::ViewModel::Common::CategoryGroupType modeType,
|
||||
CalculatorApp::ViewModel::Common::NumberBase programmerNumberBase,
|
||||
CalculatorApp::ViewModel::Common::BitLength bitLengthType);
|
||||
static Platform::String ^ SanitizeOperand(Platform::String ^ operand);
|
||||
static Platform::String ^ RemoveUnwantedCharsFromString(Platform::String ^ input);
|
||||
static Platform::IBox<unsigned long long int> ^ TryOperandToULL(Platform::String ^ operand, CalculatorApp::Common::NumberBase numberBase);
|
||||
static Platform::IBox<unsigned long long int> ^ TryOperandToULL(Platform::String ^ operand, CalculatorApp::ViewModel::Common::NumberBase numberBase);
|
||||
static ULONG32 StandardScientificOperandLength(Platform::String ^ operand);
|
||||
static ULONG32 OperandLength(
|
||||
Platform::String ^ operand,
|
||||
CalculatorApp::Common::ViewMode mode,
|
||||
CalculatorApp::Common::CategoryGroupType modeType,
|
||||
CalculatorApp::Common::NumberBase programmerNumberBase);
|
||||
static ULONG32 ProgrammerOperandLength(Platform::String ^ operand, CalculatorApp::Common::NumberBase numberBase);
|
||||
CalculatorApp::ViewModel::Common::ViewMode mode,
|
||||
CalculatorApp::ViewModel::Common::CategoryGroupType modeType,
|
||||
CalculatorApp::ViewModel::Common::NumberBase programmerNumberBase);
|
||||
static ULONG32 ProgrammerOperandLength(Platform::String ^ operand, CalculatorApp::ViewModel::Common::NumberBase numberBase);
|
||||
|
||||
private:
|
||||
static constexpr size_t MaxStandardOperandLengthValue = 16;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
using namespace Platform;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::Globalization;
|
||||
using namespace CalculatorApp::Common::DateCalculation;
|
||||
using namespace CalculatorApp::ViewModel::Common::DateCalculation;
|
||||
|
||||
bool operator==(const DateDifference& l, const DateDifference& r)
|
||||
{
|
||||
|
|
|
@ -13,7 +13,7 @@ const int c_unitsOfDate = 4; // Units Year,Month,Week,Day
|
|||
const int c_unitsGreaterThanDays = 3; // Units Greater than Days (Year/Month/Week) 3
|
||||
const int c_daysInWeek = 7;
|
||||
|
||||
namespace CalculatorApp
|
||||
namespace CalculatorApp::ViewModel
|
||||
{
|
||||
namespace Common
|
||||
{
|
||||
|
@ -68,4 +68,4 @@ namespace CalculatorApp
|
|||
}
|
||||
}
|
||||
|
||||
bool operator==(const CalculatorApp::Common::DateCalculation::DateDifference& l, const CalculatorApp::Common::DateCalculation::DateDifference& r);
|
||||
bool operator==(const CalculatorApp::ViewModel::Common::DateCalculation::DateDifference& l, const CalculatorApp::ViewModel::Common::DateCalculation::DateDifference& r);
|
||||
|
|
|
@ -3,22 +3,18 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
namespace CalculatorApp
|
||||
namespace CalculatorApp::ViewModel
|
||||
{
|
||||
namespace Common
|
||||
{
|
||||
template <typename TTarget>
|
||||
ref class DelegateCommand : public Windows::UI::Xaml::Input::ICommand
|
||||
public delegate void DelegateCommandHandler(Platform::Object ^ parameter);
|
||||
|
||||
public ref class DelegateCommand sealed : public Windows::UI::Xaml::Input::ICommand
|
||||
{
|
||||
internal :
|
||||
|
||||
typedef void (TTarget::*CommandHandlerFunc)(Platform::Object ^);
|
||||
|
||||
DelegateCommand(TTarget ^ target, CommandHandlerFunc func)
|
||||
: m_weakTarget(target)
|
||||
, m_function(func)
|
||||
{
|
||||
}
|
||||
public:
|
||||
DelegateCommand(DelegateCommandHandler ^ handler)
|
||||
: m_handler(handler)
|
||||
{}
|
||||
|
||||
private:
|
||||
// Explicit, and private, implementation of ICommand, this way of programming makes it so
|
||||
|
@ -27,11 +23,7 @@ namespace CalculatorApp
|
|||
// code in the app calling Execute.
|
||||
virtual void ExecuteImpl(Platform::Object ^ parameter) sealed = Windows::UI::Xaml::Input::ICommand::Execute
|
||||
{
|
||||
TTarget ^ target = m_weakTarget.Resolve<TTarget>();
|
||||
if (target)
|
||||
{
|
||||
(target->*m_function)(parameter);
|
||||
}
|
||||
m_handler->Invoke(parameter);
|
||||
}
|
||||
|
||||
virtual bool CanExecuteImpl(Platform::Object ^ parameter) sealed = Windows::UI::Xaml::Input::ICommand::CanExecute
|
||||
|
@ -39,9 +31,9 @@ namespace CalculatorApp
|
|||
return true;
|
||||
}
|
||||
|
||||
virtual event Windows::Foundation::EventHandler<Platform::Object^>^ CanExecuteChangedImpl
|
||||
virtual event Windows::Foundation::EventHandler<Platform::Object ^> ^ CanExecuteChangedImpl
|
||||
{
|
||||
virtual Windows::Foundation::EventRegistrationToken add(Windows::Foundation::EventHandler<Platform::Object^>^ handler) sealed = Windows::UI::Xaml::Input::ICommand::CanExecuteChanged::add
|
||||
virtual Windows::Foundation::EventRegistrationToken add(Windows::Foundation::EventHandler<Platform::Object ^> ^ handler) sealed = Windows::UI::Xaml::Input::ICommand::CanExecuteChanged::add
|
||||
{
|
||||
return m_canExecuteChanged += handler;
|
||||
}
|
||||
|
@ -52,17 +44,25 @@ namespace CalculatorApp
|
|||
}
|
||||
|
||||
private:
|
||||
DelegateCommandHandler ^ m_handler;
|
||||
|
||||
event Windows::Foundation::EventHandler<Platform::Object^>^ m_canExecuteChanged;
|
||||
|
||||
CommandHandlerFunc m_function;
|
||||
Platform::WeakReference m_weakTarget;
|
||||
event Windows::Foundation::EventHandler<Platform::Object ^> ^ m_canExecuteChanged;
|
||||
};
|
||||
|
||||
template <typename TTarget, typename TFuncPtr>
|
||||
DelegateCommand<TTarget> ^ MakeDelegate(TTarget ^ target, TFuncPtr&& function) {
|
||||
return ref new DelegateCommand<TTarget>(target, std::forward<TFuncPtr>(function));
|
||||
}
|
||||
|
||||
DelegateCommandHandler ^ MakeDelegateCommandHandler(TTarget ^ target, TFuncPtr&& function)
|
||||
{
|
||||
Platform::WeakReference weakTarget(target);
|
||||
return ref new DelegateCommandHandler([weakTarget, function=std::forward<TFuncPtr>(function)](Platform::Object ^ param)
|
||||
{
|
||||
TTarget ^ thatTarget = weakTarget.Resolve<TTarget>();
|
||||
if (nullptr != thatTarget)
|
||||
{
|
||||
(thatTarget->*function)(param);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include "Utils.h"
|
||||
|
||||
namespace CalculatorApp::Common
|
||||
namespace CalculatorApp::ViewModel::Common
|
||||
{
|
||||
public
|
||||
enum class TokenType
|
||||
|
@ -33,6 +33,7 @@ public
|
|||
OBSERVABLE_PROPERTY_RW(int, TokenPosition);
|
||||
OBSERVABLE_PROPERTY_RW(bool, IsTokenEditable);
|
||||
OBSERVABLE_PROPERTY_RW(int, CommandIndex);
|
||||
OBSERVABLE_PROPERTY_RW(TokenType, Type);
|
||||
OBSERVABLE_PROPERTY_R(Platform::String ^, OriginalToken);
|
||||
|
||||
property bool IsTokenInEditMode
|
||||
|
@ -50,7 +51,6 @@ public
|
|||
m_InEditMode = val;
|
||||
}
|
||||
}
|
||||
internal : OBSERVABLE_PROPERTY_RW(TokenType, Type);
|
||||
|
||||
private:
|
||||
bool m_InEditMode;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include "EngineResourceProvider.h"
|
||||
#include "Common/LocalizationSettings.h"
|
||||
|
||||
using namespace CalculatorApp::Common;
|
||||
using namespace CalculatorApp::ViewModel::Common;
|
||||
using namespace Platform;
|
||||
using namespace Windows::ApplicationModel::Resources;
|
||||
using namespace std;
|
||||
|
@ -19,16 +19,16 @@ namespace CalculatorApp
|
|||
|
||||
wstring EngineResourceProvider::GetCEngineString(wstring_view id)
|
||||
{
|
||||
const auto& localizationSettings = LocalizationSettings::GetInstance();
|
||||
LocalizationSettings^ localizationSettings = LocalizationSettings::GetInstance();
|
||||
|
||||
if (id.compare(L"sDecimal") == 0)
|
||||
{
|
||||
return localizationSettings.GetDecimalSeparatorStr();
|
||||
return localizationSettings->GetDecimalSeparatorStr();
|
||||
}
|
||||
|
||||
if (id.compare(L"sThousand") == 0)
|
||||
{
|
||||
return localizationSettings.GetNumberGroupingSeparatorStr();
|
||||
return localizationSettings->GetNumberGroupingSeparatorStr();
|
||||
}
|
||||
|
||||
if (id.compare(L"sGrouping") == 0)
|
||||
|
@ -39,7 +39,7 @@ namespace CalculatorApp
|
|||
// 3;2;0 0x023 - group 1st 3 and then every 2 digits
|
||||
// 4;0 0x004 - group every 4 digits
|
||||
// 5;3;2;0 0x235 - group 5, then 3, then every 2
|
||||
wstring numberGroupingString = localizationSettings.GetNumberGroupingStr();
|
||||
wstring numberGroupingString = localizationSettings->GetNumberGroupingStr();
|
||||
return numberGroupingString;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include "CalcManager/CalculatorResource.h"
|
||||
|
||||
namespace CalculatorApp
|
||||
namespace CalculatorApp::ViewModel::Common
|
||||
{
|
||||
class EngineResourceProvider : public CalculationManager::IResourceProvider
|
||||
{
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "pch.h"
|
||||
#include "ExpressionCommandDeserializer.h"
|
||||
|
||||
using namespace CalculatorApp::Common;
|
||||
using namespace CalculatorApp::ViewModel::Common;
|
||||
using namespace Windows::Storage::Streams;
|
||||
|
||||
CommandDeserializer::CommandDeserializer(_In_ DataReader ^ dataReader)
|
||||
|
@ -17,24 +17,16 @@ std::shared_ptr<IExpressionCommand> CommandDeserializer::Deserialize(_In_ Calcul
|
|||
switch (cmdType)
|
||||
{
|
||||
case CalculationManager::CommandType::OperandCommand:
|
||||
|
||||
return std::make_shared<COpndCommand>(DeserializeOperand());
|
||||
break;
|
||||
|
||||
case CalculationManager::CommandType::Parentheses:
|
||||
|
||||
return std::make_shared<CParentheses>(DeserializeParentheses());
|
||||
break;
|
||||
|
||||
case CalculationManager::CommandType::UnaryCommand:
|
||||
|
||||
return std::make_shared<CUnaryCommand>(DeserializeUnary());
|
||||
break;
|
||||
|
||||
case CalculationManager::CommandType::BinaryCommand:
|
||||
|
||||
return std::make_shared<CBinaryCommand>(DeserializeBinary());
|
||||
break;
|
||||
|
||||
default:
|
||||
throw ref new Platform::Exception(E_INVALIDARG, ref new Platform::String(L"Unknown command type"));
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include "CalcManager/ExpressionCommand.h"
|
||||
|
||||
namespace CalculatorApp
|
||||
namespace CalculatorApp::ViewModel
|
||||
{
|
||||
namespace Common
|
||||
{
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "pch.h"
|
||||
#include "Common/ExpressionCommandSerializer.h"
|
||||
|
||||
using namespace CalculatorApp::Common;
|
||||
using namespace CalculatorApp::ViewModel::Common;
|
||||
using namespace Windows::Storage::Streams;
|
||||
|
||||
SerializeCommandVisitor::SerializeCommandVisitor(_In_ DataWriter ^ dataWriter)
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include "CalcManager/ExpressionCommand.h"
|
||||
|
||||
namespace CalculatorApp
|
||||
namespace CalculatorApp::ViewModel
|
||||
{
|
||||
namespace Common
|
||||
{
|
||||
|
|
|
@ -6,8 +6,9 @@
|
|||
#include "LocalizationSettings.h"
|
||||
#include "AppResourceProvider.h"
|
||||
|
||||
using namespace CalculatorApp::Common;
|
||||
using namespace CalculatorApp::Common::LocalizationServiceProperties;
|
||||
using namespace CalculatorApp::ViewModel::Common;
|
||||
using namespace CalculatorApp::ViewModel::Common::LocalizationServiceProperties;
|
||||
using namespace CalculatorApp::ViewModel;
|
||||
using namespace Concurrency;
|
||||
using namespace Platform;
|
||||
using namespace Platform::Collections;
|
||||
|
@ -371,7 +372,7 @@ void LocalizationService::UpdateFontFamilyAndSize(DependencyObject ^ target)
|
|||
|
||||
// If successful, returns a formatter that respects the user's regional format settings,
|
||||
// as configured by running intl.cpl.
|
||||
DecimalFormatter ^ LocalizationService::GetRegionalSettingsAwareDecimalFormatter() const
|
||||
DecimalFormatter ^ LocalizationService::GetRegionalSettingsAwareDecimalFormatter()
|
||||
{
|
||||
IIterable<String ^> ^ languageIdentifiers = LocalizationService::GetLanguageIdentifiers();
|
||||
if (languageIdentifiers != nullptr)
|
||||
|
@ -386,7 +387,7 @@ DecimalFormatter ^ LocalizationService::GetRegionalSettingsAwareDecimalFormatter
|
|||
// as configured by running intl.cpl.
|
||||
//
|
||||
// This helper function creates a DateTimeFormatter with a TwentyFour hour clock
|
||||
DateTimeFormatter ^ LocalizationService::GetRegionalSettingsAwareDateTimeFormatter(_In_ String ^ format) const
|
||||
DateTimeFormatter ^ LocalizationService::GetRegionalSettingsAwareDateTimeFormatter(_In_ String ^ format)
|
||||
{
|
||||
IIterable<String ^> ^ languageIdentifiers = LocalizationService::GetLanguageIdentifiers();
|
||||
if (languageIdentifiers == nullptr)
|
||||
|
@ -399,7 +400,7 @@ DateTimeFormatter ^ LocalizationService::GetRegionalSettingsAwareDateTimeFormatt
|
|||
|
||||
// If successful, returns a formatter that respects the user's regional format settings,
|
||||
// as configured by running intl.cpl.
|
||||
DateTimeFormatter ^ LocalizationService::GetRegionalSettingsAwareDateTimeFormatter(_In_ String ^ format, _In_ String ^ calendarIdentifier, _In_ String ^ clockIdentifier) const
|
||||
DateTimeFormatter ^ LocalizationService::GetRegionalSettingsAwareDateTimeFormatter(_In_ String ^ format, _In_ String ^ calendarIdentifier, _In_ String ^ clockIdentifier)
|
||||
{
|
||||
IIterable<String ^> ^ languageIdentifiers = LocalizationService::GetLanguageIdentifiers();
|
||||
if (languageIdentifiers == nullptr)
|
||||
|
@ -410,7 +411,7 @@ DateTimeFormatter ^ LocalizationService::GetRegionalSettingsAwareDateTimeFormatt
|
|||
return ref new DateTimeFormatter(format, languageIdentifiers, GlobalizationPreferences::HomeGeographicRegion, calendarIdentifier, clockIdentifier);
|
||||
}
|
||||
|
||||
CurrencyFormatter ^ LocalizationService::GetRegionalSettingsAwareCurrencyFormatter() const
|
||||
CurrencyFormatter ^ LocalizationService::GetRegionalSettingsAwareCurrencyFormatter()
|
||||
{
|
||||
String ^ userCurrency =
|
||||
(GlobalizationPreferences::Currencies->Size > 0) ? GlobalizationPreferences::Currencies->GetAt(0) : StringReference(DefaultCurrencyCode.data());
|
||||
|
@ -423,7 +424,7 @@ CurrencyFormatter ^ LocalizationService::GetRegionalSettingsAwareCurrencyFormatt
|
|||
|
||||
auto currencyFormatter = ref new CurrencyFormatter(userCurrency, languageIdentifiers, GlobalizationPreferences::HomeGeographicRegion);
|
||||
|
||||
int fractionDigits = LocalizationSettings::GetInstance().GetCurrencyTrailingDigits();
|
||||
int fractionDigits = LocalizationSettings::GetInstance()->GetCurrencyTrailingDigits();
|
||||
currencyFormatter->FractionDigits = fractionDigits;
|
||||
|
||||
return currencyFormatter;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include "Utils.h"
|
||||
|
||||
namespace CalculatorApp
|
||||
namespace CalculatorApp::ViewModel
|
||||
{
|
||||
namespace Common
|
||||
{
|
||||
|
@ -30,10 +30,7 @@ namespace CalculatorApp
|
|||
DEPENDENCY_PROPERTY_ATTACHED_WITH_DEFAULT_AND_CALLBACK(LanguageFontType, FontType, LanguageFontType::UIText);
|
||||
DEPENDENCY_PROPERTY_ATTACHED_WITH_CALLBACK(double, FontSize);
|
||||
|
||||
internal:
|
||||
static LocalizationService ^ GetInstance();
|
||||
static void OverrideWithLanguage(_In_ const wchar_t* const language);
|
||||
|
||||
Windows::UI::Xaml::FlowDirection GetFlowDirection();
|
||||
bool IsRtlLayout();
|
||||
bool GetOverrideFontApiValues();
|
||||
|
@ -42,7 +39,17 @@ namespace CalculatorApp
|
|||
Platform::String ^ GetFontFamilyOverride();
|
||||
Windows::UI::Text::FontWeight GetFontWeightOverride();
|
||||
double GetFontScaleFactorOverride(LanguageFontType fontType);
|
||||
Windows::Globalization::NumberFormatting::DecimalFormatter ^ GetRegionalSettingsAwareDecimalFormatter();
|
||||
Windows::Globalization::DateTimeFormatting::DateTimeFormatter ^ GetRegionalSettingsAwareDateTimeFormatter(_In_ Platform::String ^ format);
|
||||
Windows::Globalization::DateTimeFormatting::DateTimeFormatter
|
||||
^ GetRegionalSettingsAwareDateTimeFormatter(
|
||||
_In_ Platform::String ^ format,
|
||||
_In_ Platform::String ^ calendarIdentifier,
|
||||
_In_ Platform::String ^ clockIdentifier);
|
||||
Windows::Globalization::NumberFormatting::CurrencyFormatter ^ GetRegionalSettingsAwareCurrencyFormatter();
|
||||
|
||||
internal:
|
||||
static void OverrideWithLanguage(_In_ const wchar_t* const language);
|
||||
void Sort(std::vector<Platform::String ^>& source);
|
||||
|
||||
template <typename T>
|
||||
|
@ -56,16 +63,6 @@ namespace CalculatorApp
|
|||
});
|
||||
}
|
||||
|
||||
Windows::Globalization::NumberFormatting::DecimalFormatter ^ GetRegionalSettingsAwareDecimalFormatter() const;
|
||||
Windows::Globalization::DateTimeFormatting::DateTimeFormatter ^ GetRegionalSettingsAwareDateTimeFormatter(_In_ Platform::String ^ format) const;
|
||||
Windows::Globalization::DateTimeFormatting::DateTimeFormatter
|
||||
^ GetRegionalSettingsAwareDateTimeFormatter(
|
||||
_In_ Platform::String ^ format,
|
||||
_In_ Platform::String ^ calendarIdentifier,
|
||||
_In_ Platform::String ^ clockIdentifier) const;
|
||||
|
||||
Windows::Globalization::NumberFormatting::CurrencyFormatter ^ GetRegionalSettingsAwareCurrencyFormatter() const;
|
||||
|
||||
static Platform::String ^ GetNarratorReadableToken(Platform::String ^ rawToken);
|
||||
static Platform::String ^ GetNarratorReadableString(Platform::String ^ rawString);
|
||||
|
||||
|
@ -101,6 +98,5 @@ namespace CalculatorApp
|
|||
double m_uiCaptionFontScaleFactorOverride;
|
||||
std::locale m_locale;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,22 +6,191 @@
|
|||
|
||||
#include <iterator>
|
||||
|
||||
namespace CalculatorApp
|
||||
namespace CalculatorApp::ViewModel
|
||||
{
|
||||
namespace Common
|
||||
{
|
||||
class LocalizationSettings
|
||||
public ref class LocalizationSettings sealed
|
||||
{
|
||||
private:
|
||||
LocalizationSettings()
|
||||
// Use DecimalFormatter as it respects the locale and the user setting
|
||||
: LocalizationSettings(LocalizationService::GetInstance()->GetRegionalSettingsAwareDecimalFormatter())
|
||||
{
|
||||
Initialize(LocalizationService::GetInstance()->GetRegionalSettingsAwareDecimalFormatter());
|
||||
}
|
||||
|
||||
public:
|
||||
// This is only public for unit testing purposes.
|
||||
LocalizationSettings(Windows::Globalization::NumberFormatting::DecimalFormatter ^ formatter)
|
||||
{
|
||||
Initialize(formatter);
|
||||
}
|
||||
|
||||
// Provider of the singleton LocalizationSettings instance.
|
||||
static LocalizationSettings^ GetInstance()
|
||||
{
|
||||
static LocalizationSettings^ localizationSettings = ref new LocalizationSettings();
|
||||
return localizationSettings;
|
||||
}
|
||||
|
||||
Platform::String ^ GetLocaleName()
|
||||
{
|
||||
return m_resolvedName;
|
||||
}
|
||||
|
||||
bool IsDigitEnUsSetting()
|
||||
{
|
||||
return (this->GetDigitSymbolFromEnUsDigit('0') == L'0');
|
||||
}
|
||||
|
||||
Platform::String ^ GetEnglishValueFromLocalizedDigits(Platform::String ^ localizedString)
|
||||
{
|
||||
if (m_resolvedName == L"en-US")
|
||||
{
|
||||
return localizedString;
|
||||
}
|
||||
|
||||
std::wstring englishString;
|
||||
englishString.reserve(localizedString->Length());
|
||||
|
||||
for (wchar_t ch : localizedString)
|
||||
{
|
||||
if (!IsEnUsDigit(ch))
|
||||
{
|
||||
auto it = std::find(m_digitSymbols.begin(), m_digitSymbols.end(), ch);
|
||||
|
||||
if (it != m_digitSymbols.end())
|
||||
{
|
||||
auto index = std::distance(m_digitSymbols.begin(), it);
|
||||
ch = index.ToString()->Data()[0];
|
||||
}
|
||||
}
|
||||
if (ch == m_decimalSeparator)
|
||||
{
|
||||
ch = L'.';
|
||||
}
|
||||
englishString += ch;
|
||||
}
|
||||
|
||||
return ref new Platform::String(englishString.c_str());
|
||||
}
|
||||
|
||||
Platform::String ^ RemoveGroupSeparators(Platform::String ^ source)
|
||||
{
|
||||
std::wstring destination;
|
||||
std::copy_if(
|
||||
begin(source), end(source), std::back_inserter(destination), [this](auto const c) { return c != L' ' && c != m_numberGroupSeparator; });
|
||||
|
||||
return ref new Platform::String(destination.c_str());
|
||||
}
|
||||
|
||||
Platform::String ^ GetCalendarIdentifier()
|
||||
{
|
||||
return m_calendarIdentifier;
|
||||
}
|
||||
|
||||
Windows::Globalization::DayOfWeek GetFirstDayOfWeek()
|
||||
{
|
||||
return m_firstDayOfWeek;
|
||||
}
|
||||
|
||||
int GetCurrencyTrailingDigits()
|
||||
{
|
||||
return m_currencyTrailingDigits;
|
||||
}
|
||||
|
||||
int GetCurrencySymbolPrecedence()
|
||||
{
|
||||
return m_currencySymbolPrecedence;
|
||||
}
|
||||
|
||||
wchar_t GetDecimalSeparator()
|
||||
{
|
||||
return m_decimalSeparator;
|
||||
}
|
||||
|
||||
wchar_t GetDigitSymbolFromEnUsDigit(wchar_t digitSymbol)
|
||||
{
|
||||
assert(digitSymbol >= L'0' && digitSymbol <= L'9');
|
||||
int digit = digitSymbol - L'0';
|
||||
return m_digitSymbols.at(digit); // throws on out of range
|
||||
}
|
||||
|
||||
wchar_t GetNumberGroupSeparator()
|
||||
{
|
||||
return m_numberGroupSeparator;
|
||||
}
|
||||
|
||||
bool IsEnUsDigit(wchar_t digit)
|
||||
{
|
||||
return (digit >= L'0' && digit <= L'9');
|
||||
}
|
||||
|
||||
bool IsLocalizedDigit(wchar_t digit)
|
||||
{
|
||||
return std::find(m_digitSymbols.begin(), m_digitSymbols.end(), digit) != m_digitSymbols.end();
|
||||
}
|
||||
|
||||
bool IsLocalizedHexDigit(wchar_t digit)
|
||||
{
|
||||
if (IsLocalizedDigit(digit))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return std::find(s_hexSymbols.begin(), s_hexSymbols.end(), digit) != s_hexSymbols.end();
|
||||
}
|
||||
|
||||
Platform::String ^ GetListSeparatorWinRT()
|
||||
{
|
||||
return ref new Platform::String(GetListSeparator().c_str());
|
||||
}
|
||||
|
||||
Platform::String ^ GetDecimalSeparatorStrWinRT()
|
||||
{
|
||||
return ref new Platform::String(GetDecimalSeparatorStr().c_str());
|
||||
}
|
||||
|
||||
internal:
|
||||
void LocalizeDisplayValue(_Inout_ std::wstring* stringToLocalize)
|
||||
{
|
||||
if (IsDigitEnUsSetting())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (wchar_t& ch : *stringToLocalize)
|
||||
{
|
||||
if (IsEnUsDigit(ch))
|
||||
{
|
||||
ch = GetDigitSymbolFromEnUsDigit(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring GetDecimalSeparatorStr()
|
||||
{
|
||||
return std::wstring(1, m_decimalSeparator);
|
||||
}
|
||||
|
||||
std::wstring GetNumberGroupingSeparatorStr()
|
||||
{
|
||||
return std::wstring(1, m_numberGroupSeparator);
|
||||
}
|
||||
|
||||
std::wstring GetNumberGroupingStr()
|
||||
{
|
||||
return m_numberGrouping;
|
||||
}
|
||||
|
||||
std::wstring GetListSeparator()
|
||||
{
|
||||
return m_listSeparator;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
void Initialize(Windows::Globalization::NumberFormatting::DecimalFormatter ^ formatter)
|
||||
{
|
||||
formatter->FractionDigits = 0;
|
||||
formatter->IsDecimalPointAlwaysDisplayed = false;
|
||||
|
@ -125,167 +294,6 @@ namespace CalculatorApp
|
|||
m_firstDayOfWeek = static_cast<Windows::Globalization::DayOfWeek>((_wtoi(day) + 1) % 7); // static cast int to DayOfWeek enum
|
||||
}
|
||||
|
||||
// A LocalizationSettings object is not copyable.
|
||||
LocalizationSettings(const LocalizationSettings&) = delete;
|
||||
LocalizationSettings& operator=(const LocalizationSettings&) = delete;
|
||||
|
||||
// A LocalizationSettings object is not moveable.
|
||||
LocalizationSettings(LocalizationSettings&&) = delete;
|
||||
LocalizationSettings& operator=(LocalizationSettings&&) = delete;
|
||||
|
||||
// Provider of the singleton LocalizationSettings instance.
|
||||
static const LocalizationSettings& GetInstance()
|
||||
{
|
||||
static const LocalizationSettings localizationSettings;
|
||||
|
||||
return localizationSettings;
|
||||
}
|
||||
|
||||
Platform::String ^ GetLocaleName() const
|
||||
{
|
||||
return m_resolvedName;
|
||||
}
|
||||
|
||||
bool IsDigitEnUsSetting() const
|
||||
{
|
||||
return (this->GetDigitSymbolFromEnUsDigit('0') == L'0');
|
||||
}
|
||||
|
||||
void LocalizeDisplayValue(_Inout_ std::wstring* stringToLocalize) const
|
||||
{
|
||||
if (IsDigitEnUsSetting())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (wchar_t& ch : *stringToLocalize)
|
||||
{
|
||||
if (IsEnUsDigit(ch))
|
||||
{
|
||||
ch = GetDigitSymbolFromEnUsDigit(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Platform::String ^ GetEnglishValueFromLocalizedDigits(Platform::String ^ localizedString) const
|
||||
{
|
||||
if (m_resolvedName == L"en-US")
|
||||
{
|
||||
return localizedString;
|
||||
}
|
||||
|
||||
std::wstring englishString;
|
||||
englishString.reserve(localizedString->Length());
|
||||
|
||||
for (wchar_t ch : localizedString)
|
||||
{
|
||||
if (!IsEnUsDigit(ch))
|
||||
{
|
||||
auto it = std::find(m_digitSymbols.begin(), m_digitSymbols.end(), ch);
|
||||
|
||||
if (it != m_digitSymbols.end())
|
||||
{
|
||||
auto index = std::distance(m_digitSymbols.begin(), it);
|
||||
ch = index.ToString()->Data()[0];
|
||||
}
|
||||
}
|
||||
if (ch == m_decimalSeparator)
|
||||
{
|
||||
ch = L'.';
|
||||
}
|
||||
englishString += ch;
|
||||
}
|
||||
|
||||
return ref new Platform::String(englishString.c_str());
|
||||
}
|
||||
|
||||
bool IsEnUsDigit(const wchar_t digit) const
|
||||
{
|
||||
return (digit >= L'0' && digit <= L'9');
|
||||
}
|
||||
|
||||
bool IsLocalizedDigit(const wchar_t digit) const
|
||||
{
|
||||
return std::find(m_digitSymbols.begin(), m_digitSymbols.end(), digit) != m_digitSymbols.end();
|
||||
}
|
||||
|
||||
bool IsLocalizedHexDigit(const wchar_t digit) const
|
||||
{
|
||||
if (IsLocalizedDigit(digit))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return std::find(s_hexSymbols.begin(), s_hexSymbols.end(), digit) != s_hexSymbols.end();
|
||||
}
|
||||
|
||||
wchar_t GetDigitSymbolFromEnUsDigit(wchar_t digitSymbol) const
|
||||
{
|
||||
assert(digitSymbol >= L'0' && digitSymbol <= L'9');
|
||||
int digit = digitSymbol - L'0';
|
||||
return m_digitSymbols.at(digit); // throws on out of range
|
||||
}
|
||||
|
||||
wchar_t GetDecimalSeparator() const
|
||||
{
|
||||
return m_decimalSeparator;
|
||||
}
|
||||
|
||||
wchar_t GetNumberGroupSeparator() const
|
||||
{
|
||||
return m_numberGroupSeparator;
|
||||
}
|
||||
|
||||
std::wstring GetDecimalSeparatorStr() const
|
||||
{
|
||||
return std::wstring(1, m_decimalSeparator);
|
||||
}
|
||||
|
||||
std::wstring GetNumberGroupingSeparatorStr() const
|
||||
{
|
||||
return std::wstring(1, m_numberGroupSeparator);
|
||||
}
|
||||
|
||||
std::wstring GetNumberGroupingStr() const
|
||||
{
|
||||
return m_numberGrouping;
|
||||
}
|
||||
|
||||
Platform::String ^ RemoveGroupSeparators(Platform::String ^ source) const
|
||||
{
|
||||
std::wstring destination;
|
||||
std::copy_if(
|
||||
begin(source), end(source), std::back_inserter(destination), [this](auto const c) { return c != L' ' && c != m_numberGroupSeparator; });
|
||||
|
||||
return ref new Platform::String(destination.c_str());
|
||||
}
|
||||
|
||||
Platform::String ^ GetCalendarIdentifier() const
|
||||
{
|
||||
return m_calendarIdentifier;
|
||||
}
|
||||
|
||||
std::wstring GetListSeparator() const
|
||||
{
|
||||
return m_listSeparator;
|
||||
}
|
||||
|
||||
Windows::Globalization::DayOfWeek GetFirstDayOfWeek() const
|
||||
{
|
||||
return m_firstDayOfWeek;
|
||||
}
|
||||
|
||||
int GetCurrencyTrailingDigits() const
|
||||
{
|
||||
return m_currencyTrailingDigits;
|
||||
}
|
||||
|
||||
int GetCurrencySymbolPrecedence() const
|
||||
{
|
||||
return m_currencySymbolPrecedence;
|
||||
}
|
||||
|
||||
private:
|
||||
static Platform::String^ GetCalendarIdentifierFromCalid(CALID calId)
|
||||
{
|
||||
switch (calId)
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include "AppResourceProvider.h"
|
||||
|
||||
namespace CalculatorApp
|
||||
namespace CalculatorApp::ViewModel
|
||||
{
|
||||
namespace Common
|
||||
{
|
||||
|
@ -16,7 +16,7 @@ namespace CalculatorApp
|
|||
{
|
||||
std::wstring returnString = L"";
|
||||
const UINT32 length = 1024;
|
||||
std::unique_ptr<wchar_t[]> spBuffer = std::unique_ptr<wchar_t[]>(new wchar_t[length]);
|
||||
std::unique_ptr<wchar_t[]> spBuffer = std::make_unique<wchar_t[]>(length);
|
||||
va_list args = NULL;
|
||||
va_start(args, pMessage);
|
||||
DWORD fmtReturnVal = FormatMessage(FORMAT_MESSAGE_FROM_STRING, pMessage->Data(), 0, 0, spBuffer.get(), length, &args);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
namespace CalculatorApp
|
||||
namespace CalculatorApp::ViewModel
|
||||
{
|
||||
namespace Common
|
||||
{
|
||||
|
|
|
@ -8,11 +8,11 @@
|
|||
#include <initializer_list>
|
||||
|
||||
using namespace CalculatorApp;
|
||||
using namespace CalculatorApp::Common;
|
||||
using namespace CalculatorApp::ViewModel::Common;
|
||||
using namespace CalculatorApp::ViewModel;
|
||||
using namespace Concurrency;
|
||||
using namespace Platform;
|
||||
using namespace Platform::Collections;
|
||||
using namespace std;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
using namespace Windows::Management::Policies;
|
||||
using namespace Windows::System;
|
||||
|
@ -47,451 +47,236 @@ static constexpr int CURRENCY_ID = 16;
|
|||
static constexpr int GRAPHING_ID = 17;
|
||||
// ^^^ THESE CONSTANTS SHOULD NEVER CHANGE ^^^
|
||||
|
||||
wchar_t* towchar_t(int number)
|
||||
namespace // put the utils within this TU
|
||||
{
|
||||
auto wstr = to_wstring(number);
|
||||
return _wcsdup(wstr.c_str());
|
||||
}
|
||||
Platform::String^ CurrentUserId;
|
||||
std::mutex GraphingModeCheckMutex;
|
||||
|
||||
bool IsGraphingModeAvailable()
|
||||
{
|
||||
static bool supportGraph = Windows::Foundation::Metadata::ApiInformation::IsMethodPresent("Windows.UI.Text.RichEditTextDocument", "GetMath");
|
||||
return supportGraph;
|
||||
}
|
||||
|
||||
Box<bool> ^ _isGraphingModeEnabledCached = nullptr;
|
||||
bool IsGraphingModeEnabled(User ^ currentUser = nullptr)
|
||||
{
|
||||
if (!IsGraphingModeAvailable())
|
||||
bool IsGraphingModeEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static bool isChecked = false;
|
||||
static bool isEnabled = false;
|
||||
|
||||
if (_isGraphingModeEnabledCached != nullptr)
|
||||
{
|
||||
return _isGraphingModeEnabledCached->Value;
|
||||
}
|
||||
|
||||
if (!currentUser)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
auto namedPolicyData = NamedPolicy::GetPolicyFromPathForUser(currentUser, L"Education", L"AllowGraphingCalculator");
|
||||
_isGraphingModeEnabledCached = namedPolicyData->GetBoolean() == true;
|
||||
|
||||
return _isGraphingModeEnabledCached->Value;
|
||||
}
|
||||
|
||||
// The order of items in this list determines the order of items in the menu.
|
||||
static list<NavCategoryInitializer> s_categoryManifest = [] {
|
||||
auto res = list<NavCategoryInitializer>{ NavCategoryInitializer{ ViewMode::Standard,
|
||||
STANDARD_ID,
|
||||
L"Standard",
|
||||
L"StandardMode",
|
||||
L"\uE8EF",
|
||||
CategoryGroupType::Calculator,
|
||||
MyVirtualKey::Number1,
|
||||
L"1",
|
||||
SUPPORTS_ALL,
|
||||
true },
|
||||
NavCategoryInitializer{ ViewMode::Scientific,
|
||||
SCIENTIFIC_ID,
|
||||
L"Scientific",
|
||||
L"ScientificMode",
|
||||
L"\uF196",
|
||||
CategoryGroupType::Calculator,
|
||||
MyVirtualKey::Number2,
|
||||
L"2",
|
||||
SUPPORTS_ALL,
|
||||
true } };
|
||||
|
||||
int currentIndex = 3;
|
||||
bool supportGraphingCalculator = IsGraphingModeAvailable();
|
||||
if (supportGraphingCalculator)
|
||||
{
|
||||
bool isEnabled = IsGraphingModeEnabled();
|
||||
res.push_back(NavCategoryInitializer{ ViewMode::Graphing,
|
||||
GRAPHING_ID,
|
||||
L"Graphing",
|
||||
L"GraphingCalculatorMode",
|
||||
L"\uF770",
|
||||
CategoryGroupType::Calculator,
|
||||
MyVirtualKey::Number3,
|
||||
L"3",
|
||||
SUPPORTS_ALL,
|
||||
isEnabled });
|
||||
++currentIndex;
|
||||
}
|
||||
res.insert(
|
||||
res.end(),
|
||||
{ NavCategoryInitializer{ ViewMode::Programmer,
|
||||
PROGRAMMER_ID,
|
||||
L"Programmer",
|
||||
L"ProgrammerMode",
|
||||
L"\uECCE",
|
||||
CategoryGroupType::Calculator,
|
||||
supportGraphingCalculator ? MyVirtualKey::Number4 : MyVirtualKey::Number3,
|
||||
towchar_t(currentIndex++),
|
||||
SUPPORTS_ALL,
|
||||
true },
|
||||
NavCategoryInitializer{ ViewMode::Date,
|
||||
DATE_ID,
|
||||
L"Date",
|
||||
L"DateCalculationMode",
|
||||
L"\uE787",
|
||||
CategoryGroupType::Calculator,
|
||||
supportGraphingCalculator ? MyVirtualKey::Number5 : MyVirtualKey::Number4,
|
||||
towchar_t(currentIndex++),
|
||||
SUPPORTS_ALL,
|
||||
true },
|
||||
NavCategoryInitializer{ ViewMode::Currency,
|
||||
CURRENCY_ID,
|
||||
L"Currency",
|
||||
L"CategoryName_Currency",
|
||||
L"\uEB0D",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
nullptr,
|
||||
POSITIVE_ONLY,
|
||||
true },
|
||||
NavCategoryInitializer{ ViewMode::Volume,
|
||||
VOLUME_ID,
|
||||
L"Volume",
|
||||
L"CategoryName_Volume",
|
||||
L"\uF1AA",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
nullptr,
|
||||
POSITIVE_ONLY,
|
||||
true },
|
||||
NavCategoryInitializer{ ViewMode::Length,
|
||||
LENGTH_ID,
|
||||
L"Length",
|
||||
L"CategoryName_Length",
|
||||
L"\uECC6",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
nullptr,
|
||||
POSITIVE_ONLY,
|
||||
true },
|
||||
NavCategoryInitializer{ ViewMode::Weight,
|
||||
WEIGHT_ID,
|
||||
L"Weight and Mass",
|
||||
L"CategoryName_Weight",
|
||||
L"\uF4C1",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
nullptr,
|
||||
POSITIVE_ONLY,
|
||||
true },
|
||||
NavCategoryInitializer{ ViewMode::Temperature,
|
||||
TEMPERATURE_ID,
|
||||
L"Temperature",
|
||||
L"CategoryName_Temperature",
|
||||
L"\uE7A3",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
nullptr,
|
||||
SUPPORTS_NEGATIVE,
|
||||
true },
|
||||
NavCategoryInitializer{ ViewMode::Energy,
|
||||
ENERGY_ID,
|
||||
L"Energy",
|
||||
L"CategoryName_Energy",
|
||||
L"\uECAD",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
nullptr,
|
||||
POSITIVE_ONLY,
|
||||
true },
|
||||
NavCategoryInitializer{ ViewMode::Area,
|
||||
AREA_ID,
|
||||
L"Area",
|
||||
L"CategoryName_Area",
|
||||
L"\uE809",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
nullptr,
|
||||
POSITIVE_ONLY,
|
||||
true },
|
||||
NavCategoryInitializer{ ViewMode::Speed,
|
||||
SPEED_ID,
|
||||
L"Speed",
|
||||
L"CategoryName_Speed",
|
||||
L"\uEADA",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
nullptr,
|
||||
POSITIVE_ONLY,
|
||||
true },
|
||||
NavCategoryInitializer{ ViewMode::Time,
|
||||
TIME_ID,
|
||||
L"Time",
|
||||
L"CategoryName_Time",
|
||||
L"\uE917",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
nullptr,
|
||||
POSITIVE_ONLY,
|
||||
true },
|
||||
NavCategoryInitializer{ ViewMode::Power,
|
||||
POWER_ID,
|
||||
L"Power",
|
||||
L"CategoryName_Power",
|
||||
L"\uE945",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
nullptr,
|
||||
SUPPORTS_NEGATIVE,
|
||||
true },
|
||||
NavCategoryInitializer{ ViewMode::Data,
|
||||
DATA_ID,
|
||||
L"Data",
|
||||
L"CategoryName_Data",
|
||||
L"\uF20F",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
nullptr,
|
||||
POSITIVE_ONLY,
|
||||
true },
|
||||
NavCategoryInitializer{ ViewMode::Pressure,
|
||||
PRESSURE_ID,
|
||||
L"Pressure",
|
||||
L"CategoryName_Pressure",
|
||||
L"\uEC4A",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
nullptr,
|
||||
POSITIVE_ONLY,
|
||||
true },
|
||||
NavCategoryInitializer{ ViewMode::Angle,
|
||||
ANGLE_ID,
|
||||
L"Angle",
|
||||
L"CategoryName_Angle",
|
||||
L"\uF515",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
nullptr,
|
||||
SUPPORTS_NEGATIVE,
|
||||
true } });
|
||||
return res;
|
||||
}();
|
||||
|
||||
void NavCategory::InitializeCategoryManifest(User ^ user)
|
||||
{
|
||||
int i = 0;
|
||||
for (NavCategoryInitializer category : s_categoryManifest)
|
||||
{
|
||||
if (category.viewMode == ViewMode::Graphing)
|
||||
std::scoped_lock<std::mutex> lock(GraphingModeCheckMutex);
|
||||
if (isChecked)
|
||||
{
|
||||
auto navCatInit = s_categoryManifest.begin();
|
||||
std::advance(navCatInit, i);
|
||||
(*navCatInit).isEnabled = IsGraphingModeEnabled(user);
|
||||
break;
|
||||
return isEnabled;
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This function should only be used when storing the mode to app data.
|
||||
int NavCategory::Serialize(ViewMode mode)
|
||||
{
|
||||
auto iter =
|
||||
find_if(begin(s_categoryManifest), end(s_categoryManifest), [mode](const NavCategoryInitializer& initializer) { return initializer.viewMode == mode; });
|
||||
|
||||
return (iter != s_categoryManifest.end()) ? iter->serializationId : -1;
|
||||
}
|
||||
|
||||
// This function should only be used when restoring the mode from app data.
|
||||
ViewMode NavCategory::Deserialize(Platform::Object ^ obj)
|
||||
{
|
||||
// If we cast directly to ViewMode we will fail
|
||||
// because we technically store an int.
|
||||
// Need to cast to int, then ViewMode.
|
||||
auto boxed = dynamic_cast<Box<int> ^>(obj);
|
||||
if (boxed != nullptr)
|
||||
{
|
||||
int serializationId = boxed->Value;
|
||||
auto iter = find_if(begin(s_categoryManifest), end(s_categoryManifest), [serializationId](const NavCategoryInitializer& initializer) {
|
||||
return initializer.serializationId == serializationId;
|
||||
});
|
||||
|
||||
if (iter != s_categoryManifest.end())
|
||||
{
|
||||
if (iter->viewMode == ViewMode::Graphing)
|
||||
auto user = User::GetFromId(CurrentUserId);
|
||||
if (user == nullptr)
|
||||
{
|
||||
// check if the user is allowed to use this feature
|
||||
if (!IsGraphingModeEnabled())
|
||||
{
|
||||
return ViewMode::None;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return iter->viewMode;
|
||||
|
||||
auto namedPolicyData = NamedPolicy::GetPolicyFromPathForUser(
|
||||
user,
|
||||
L"Education",
|
||||
L"AllowGraphingCalculator");
|
||||
isEnabled = namedPolicyData->GetBoolean();
|
||||
isChecked = true;
|
||||
return isEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
return ViewMode::None;
|
||||
}
|
||||
// The order of items in this list determines the order of items in the menu.
|
||||
const std::vector<NavCategoryInitializer> s_categoryManifest {
|
||||
NavCategoryInitializer{ ViewMode::Standard,
|
||||
STANDARD_ID,
|
||||
L"Standard",
|
||||
L"StandardMode",
|
||||
L"\uE8EF",
|
||||
CategoryGroupType::Calculator,
|
||||
MyVirtualKey::Number1,
|
||||
L"1",
|
||||
SUPPORTS_ALL },
|
||||
NavCategoryInitializer{ ViewMode::Scientific,
|
||||
SCIENTIFIC_ID,
|
||||
L"Scientific",
|
||||
L"ScientificMode",
|
||||
L"\uF196",
|
||||
CategoryGroupType::Calculator,
|
||||
MyVirtualKey::Number2,
|
||||
L"2",
|
||||
SUPPORTS_ALL },
|
||||
NavCategoryInitializer{ ViewMode::Graphing,
|
||||
GRAPHING_ID,
|
||||
L"Graphing",
|
||||
L"GraphingCalculatorMode",
|
||||
L"\uF770",
|
||||
CategoryGroupType::Calculator,
|
||||
MyVirtualKey::Number3,
|
||||
L"3",
|
||||
SUPPORTS_ALL },
|
||||
NavCategoryInitializer{ ViewMode::Programmer,
|
||||
PROGRAMMER_ID,
|
||||
L"Programmer",
|
||||
L"ProgrammerMode",
|
||||
L"\uECCE",
|
||||
CategoryGroupType::Calculator,
|
||||
MyVirtualKey::Number4,
|
||||
L"4",
|
||||
SUPPORTS_ALL },
|
||||
NavCategoryInitializer{ ViewMode::Date,
|
||||
DATE_ID,
|
||||
L"Date",
|
||||
L"DateCalculationMode",
|
||||
L"\uE787",
|
||||
CategoryGroupType::Calculator,
|
||||
MyVirtualKey::Number5,
|
||||
L"5",
|
||||
SUPPORTS_ALL },
|
||||
NavCategoryInitializer{ ViewMode::Currency,
|
||||
CURRENCY_ID,
|
||||
L"Currency",
|
||||
L"CategoryName_Currency",
|
||||
L"\uEB0D",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
std::nullopt,
|
||||
POSITIVE_ONLY },
|
||||
NavCategoryInitializer{ ViewMode::Volume,
|
||||
VOLUME_ID,
|
||||
L"Volume",
|
||||
L"CategoryName_Volume",
|
||||
L"\uF1AA",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
std::nullopt,
|
||||
POSITIVE_ONLY },
|
||||
NavCategoryInitializer{ ViewMode::Length,
|
||||
LENGTH_ID,
|
||||
L"Length",
|
||||
L"CategoryName_Length",
|
||||
L"\uECC6",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
std::nullopt,
|
||||
POSITIVE_ONLY },
|
||||
NavCategoryInitializer{ ViewMode::Weight,
|
||||
WEIGHT_ID,
|
||||
L"Weight and Mass",
|
||||
L"CategoryName_Weight",
|
||||
L"\uF4C1",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
std::nullopt,
|
||||
POSITIVE_ONLY },
|
||||
NavCategoryInitializer{ ViewMode::Temperature,
|
||||
TEMPERATURE_ID,
|
||||
L"Temperature",
|
||||
L"CategoryName_Temperature",
|
||||
L"\uE7A3",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
std::nullopt,
|
||||
SUPPORTS_NEGATIVE },
|
||||
NavCategoryInitializer{ ViewMode::Energy,
|
||||
ENERGY_ID,
|
||||
L"Energy",
|
||||
L"CategoryName_Energy",
|
||||
L"\uECAD",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
std::nullopt,
|
||||
POSITIVE_ONLY },
|
||||
NavCategoryInitializer{ ViewMode::Area,
|
||||
AREA_ID,
|
||||
L"Area",
|
||||
L"CategoryName_Area",
|
||||
L"\uE809",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
std::nullopt,
|
||||
POSITIVE_ONLY },
|
||||
NavCategoryInitializer{ ViewMode::Speed,
|
||||
SPEED_ID,
|
||||
L"Speed",
|
||||
L"CategoryName_Speed",
|
||||
L"\uEADA",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
std::nullopt,
|
||||
POSITIVE_ONLY },
|
||||
NavCategoryInitializer{ ViewMode::Time,
|
||||
TIME_ID,
|
||||
L"Time",
|
||||
L"CategoryName_Time",
|
||||
L"\uE917",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
std::nullopt,
|
||||
POSITIVE_ONLY },
|
||||
NavCategoryInitializer{ ViewMode::Power,
|
||||
POWER_ID,
|
||||
L"Power",
|
||||
L"CategoryName_Power",
|
||||
L"\uE945",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
std::nullopt,
|
||||
SUPPORTS_NEGATIVE },
|
||||
NavCategoryInitializer{ ViewMode::Data,
|
||||
DATA_ID,
|
||||
L"Data",
|
||||
L"CategoryName_Data",
|
||||
L"\uF20F",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
std::nullopt,
|
||||
POSITIVE_ONLY },
|
||||
NavCategoryInitializer{ ViewMode::Pressure,
|
||||
PRESSURE_ID,
|
||||
L"Pressure",
|
||||
L"CategoryName_Pressure",
|
||||
L"\uEC4A",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
std::nullopt,
|
||||
POSITIVE_ONLY },
|
||||
NavCategoryInitializer{ ViewMode::Angle,
|
||||
ANGLE_ID,
|
||||
L"Angle",
|
||||
L"CategoryName_Angle",
|
||||
L"\uF515",
|
||||
CategoryGroupType::Converter,
|
||||
MyVirtualKey::None,
|
||||
std::nullopt,
|
||||
SUPPORTS_NEGATIVE },
|
||||
};
|
||||
} // namespace unnamed
|
||||
|
||||
bool NavCategory::IsValidViewMode(ViewMode mode)
|
||||
{
|
||||
auto iter =
|
||||
find_if(begin(s_categoryManifest), end(s_categoryManifest), [mode](const NavCategoryInitializer& initializer) { return initializer.viewMode == mode; });
|
||||
|
||||
return iter != s_categoryManifest.end();
|
||||
}
|
||||
|
||||
bool NavCategory::IsViewModeEnabled(ViewMode mode)
|
||||
{
|
||||
auto iter = find_if(begin(s_categoryManifest), end(s_categoryManifest), [mode](const NavCategoryInitializer& initializer) {
|
||||
return initializer.viewMode == mode && initializer.isEnabled;
|
||||
});
|
||||
|
||||
return iter != s_categoryManifest.end();
|
||||
}
|
||||
|
||||
bool NavCategory::IsCalculatorViewMode(ViewMode mode)
|
||||
bool NavCategory::IsCalculatorViewMode(ViewModeType mode)
|
||||
{
|
||||
// Historically, Calculator modes are Standard, Scientific, and Programmer.
|
||||
return !IsDateCalculatorViewMode(mode) && !IsGraphingCalculatorViewMode(mode) && IsModeInCategoryGroup(mode, CategoryGroupType::Calculator);
|
||||
}
|
||||
|
||||
bool NavCategory::IsGraphingCalculatorViewMode(ViewMode mode)
|
||||
bool NavCategory::IsGraphingCalculatorViewMode(ViewModeType mode)
|
||||
{
|
||||
return mode == ViewMode::Graphing;
|
||||
return mode == ViewModeType::Graphing;
|
||||
}
|
||||
|
||||
bool NavCategory::IsDateCalculatorViewMode(ViewMode mode)
|
||||
bool NavCategory::IsDateCalculatorViewMode(ViewModeType mode)
|
||||
{
|
||||
return mode == ViewMode::Date;
|
||||
return mode == ViewModeType::Date;
|
||||
}
|
||||
|
||||
bool NavCategory::IsConverterViewMode(ViewMode mode)
|
||||
bool NavCategory::IsConverterViewMode(ViewModeType mode)
|
||||
{
|
||||
return IsModeInCategoryGroup(mode, CategoryGroupType::Converter);
|
||||
}
|
||||
|
||||
bool NavCategory::IsModeInCategoryGroup(ViewMode mode, CategoryGroupType type)
|
||||
bool NavCategory::IsModeInCategoryGroup(ViewModeType mode, CategoryGroupType type)
|
||||
{
|
||||
auto iter = find_if(begin(s_categoryManifest), end(s_categoryManifest), [mode, type](const NavCategoryInitializer& initializer) {
|
||||
return initializer.viewMode == mode && initializer.groupType == type;
|
||||
});
|
||||
|
||||
return iter != s_categoryManifest.end();
|
||||
}
|
||||
|
||||
String ^ NavCategory::GetFriendlyName(ViewMode mode)
|
||||
{
|
||||
auto iter =
|
||||
find_if(begin(s_categoryManifest), end(s_categoryManifest), [mode](const NavCategoryInitializer& initializer) { return initializer.viewMode == mode; });
|
||||
|
||||
return (iter != s_categoryManifest.end()) ? StringReference(iter->friendlyName) : L"None";
|
||||
}
|
||||
|
||||
ViewMode NavCategory::GetViewModeForFriendlyName(String ^ name)
|
||||
{
|
||||
auto iter = find_if(begin(s_categoryManifest), end(s_categoryManifest), [name](const NavCategoryInitializer& initializer) {
|
||||
return wcscmp(initializer.friendlyName, name->Data()) == 0;
|
||||
});
|
||||
|
||||
return (iter != s_categoryManifest.end()) ? iter->viewMode : ViewMode::None;
|
||||
}
|
||||
|
||||
String ^ NavCategory::GetNameResourceKey(ViewMode mode)
|
||||
{
|
||||
auto iter =
|
||||
find_if(begin(s_categoryManifest), end(s_categoryManifest), [mode](const NavCategoryInitializer& initializer) { return initializer.viewMode == mode; });
|
||||
|
||||
return (iter != s_categoryManifest.end()) ? StringReference(iter->nameResourceKey) + "Text" : nullptr;
|
||||
}
|
||||
|
||||
CategoryGroupType NavCategory::GetGroupType(ViewMode mode)
|
||||
{
|
||||
auto iter =
|
||||
find_if(begin(s_categoryManifest), end(s_categoryManifest), [mode](const NavCategoryInitializer& initializer) { return initializer.viewMode == mode; });
|
||||
|
||||
return (iter != s_categoryManifest.end()) ? iter->groupType : CategoryGroupType::None;
|
||||
}
|
||||
|
||||
// GetIndex is 0-based, GetPosition is 1-based
|
||||
int NavCategory::GetIndex(ViewMode mode)
|
||||
{
|
||||
int position = NavCategory::GetPosition(mode);
|
||||
return max(-1, position - 1);
|
||||
}
|
||||
|
||||
int NavCategory::GetFlatIndex(ViewMode mode)
|
||||
{
|
||||
int index = -1;
|
||||
CategoryGroupType type = CategoryGroupType::None;
|
||||
auto iter = find_if(begin(s_categoryManifest), end(s_categoryManifest), [mode, &type, &index](const NavCategoryInitializer& initializer) {
|
||||
index++;
|
||||
if (initializer.groupType != type)
|
||||
{
|
||||
type = initializer.groupType;
|
||||
index++;
|
||||
}
|
||||
|
||||
return initializer.viewMode == mode;
|
||||
});
|
||||
|
||||
return (iter != s_categoryManifest.end()) ? index : -1;
|
||||
}
|
||||
|
||||
// GetIndex is 0-based, GetPosition is 1-based
|
||||
int NavCategory::GetIndexInGroup(ViewMode mode, CategoryGroupType type)
|
||||
{
|
||||
int index = -1;
|
||||
auto iter = find_if(begin(s_categoryManifest), end(s_categoryManifest), [mode, type, &index](const NavCategoryInitializer& initializer) {
|
||||
if (initializer.groupType == type)
|
||||
{
|
||||
index++;
|
||||
return initializer.viewMode == mode;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
return (iter != s_categoryManifest.end()) ? index : -1;
|
||||
}
|
||||
|
||||
// GetIndex is 0-based, GetPosition is 1-based
|
||||
int NavCategory::GetPosition(ViewMode mode)
|
||||
{
|
||||
int position = 0;
|
||||
auto iter = find_if(begin(s_categoryManifest), end(s_categoryManifest), [mode, &position](const NavCategoryInitializer& initializer) {
|
||||
position++;
|
||||
return initializer.viewMode == mode;
|
||||
});
|
||||
|
||||
return (iter != s_categoryManifest.end()) ? position : -1;
|
||||
}
|
||||
|
||||
ViewMode NavCategory::GetViewModeForVirtualKey(MyVirtualKey virtualKey)
|
||||
{
|
||||
auto iter = find_if(begin(s_categoryManifest), end(s_categoryManifest), [virtualKey](const NavCategoryInitializer& initializer) {
|
||||
return initializer.virtualKey == virtualKey;
|
||||
});
|
||||
|
||||
return (iter != s_categoryManifest.end()) ? iter->viewMode : ViewMode::None;
|
||||
}
|
||||
|
||||
vector<MyVirtualKey> NavCategory::GetCategoryAcceleratorKeys()
|
||||
{
|
||||
vector<MyVirtualKey> accelerators{};
|
||||
for (auto category : s_categoryManifest)
|
||||
{
|
||||
if (category.virtualKey != MyVirtualKey::None)
|
||||
{
|
||||
accelerators.push_back(category.virtualKey);
|
||||
}
|
||||
}
|
||||
|
||||
return accelerators;
|
||||
return std::any_of(
|
||||
s_categoryManifest.cbegin(),
|
||||
s_categoryManifest.cend(),
|
||||
[mode, type](const auto& initializer) {
|
||||
return initializer.viewMode == mode && initializer.groupType == type;
|
||||
});
|
||||
}
|
||||
|
||||
NavCategoryGroup::NavCategoryGroup(const NavCategoryGroupInitializer& groupInitializer)
|
||||
|
@ -521,32 +306,225 @@ NavCategoryGroup::NavCategoryGroup(const NavCategoryGroupInitializer& groupIniti
|
|||
categoryName,
|
||||
categoryAutomationName,
|
||||
StringReference(categoryInitializer.glyph),
|
||||
categoryInitializer.accessKey != nullptr ? ref new String(categoryInitializer.accessKey)
|
||||
categoryInitializer.accessKey.has_value() ? ref new String(categoryInitializer.accessKey->c_str())
|
||||
: resProvider->GetResourceString(nameResourceKey + "AccessKey"),
|
||||
groupMode,
|
||||
categoryInitializer.viewMode,
|
||||
categoryInitializer.supportsNegative,
|
||||
categoryInitializer.isEnabled));
|
||||
categoryInitializer.viewMode != ViewMode::Graphing));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IObservableVector<NavCategoryGroup ^> ^ NavCategoryGroup::CreateMenuOptions()
|
||||
void NavCategoryStates::SetCurrentUser(Platform::String^ userId)
|
||||
{
|
||||
std::scoped_lock<std::mutex> lock(GraphingModeCheckMutex);
|
||||
CurrentUserId = userId;
|
||||
}
|
||||
|
||||
IObservableVector<NavCategoryGroup ^> ^ NavCategoryStates::CreateMenuOptions()
|
||||
{
|
||||
auto menuOptions = ref new Vector<NavCategoryGroup ^>();
|
||||
menuOptions->Append(CreateCalculatorCategory());
|
||||
menuOptions->Append(CreateConverterCategory());
|
||||
menuOptions->Append(CreateCalculatorCategoryGroup());
|
||||
menuOptions->Append(CreateConverterCategoryGroup());
|
||||
return menuOptions;
|
||||
}
|
||||
|
||||
NavCategoryGroup ^ NavCategoryGroup::CreateCalculatorCategory()
|
||||
NavCategoryGroup ^ NavCategoryStates::CreateCalculatorCategoryGroup()
|
||||
{
|
||||
return ref new NavCategoryGroup(
|
||||
NavCategoryGroupInitializer{ CategoryGroupType::Calculator, L"CalculatorModeTextCaps", L"CalculatorModeText", L"CalculatorModePluralText" });
|
||||
}
|
||||
|
||||
NavCategoryGroup ^ NavCategoryGroup::CreateConverterCategory()
|
||||
NavCategoryGroup ^ NavCategoryStates::CreateConverterCategoryGroup()
|
||||
{
|
||||
return ref new NavCategoryGroup(
|
||||
NavCategoryGroupInitializer{ CategoryGroupType::Converter, L"ConverterModeTextCaps", L"ConverterModeText", L"ConverterModePluralText" });
|
||||
}
|
||||
|
||||
// This function should only be used when storing the mode to app data.
|
||||
int NavCategoryStates::Serialize(ViewMode mode)
|
||||
{
|
||||
const auto& citer = find_if(
|
||||
cbegin(s_categoryManifest),
|
||||
cend(s_categoryManifest),
|
||||
[mode](const auto& initializer) { return initializer.viewMode == mode; });
|
||||
|
||||
return (citer != s_categoryManifest.cend()) ? citer->serializationId : -1;
|
||||
}
|
||||
|
||||
// This function should only be used when restoring the mode from app data.
|
||||
ViewMode NavCategoryStates::Deserialize(Platform::Object ^ obj)
|
||||
{
|
||||
// If we cast directly to ViewMode we will fail
|
||||
// because we technically store an int.
|
||||
// Need to cast to int, then ViewMode.
|
||||
auto boxed = dynamic_cast<Box<int> ^>(obj);
|
||||
if (boxed != nullptr)
|
||||
{
|
||||
int serializationId = boxed->Value;
|
||||
const auto& citer = find_if(
|
||||
cbegin(s_categoryManifest),
|
||||
cend(s_categoryManifest),
|
||||
[serializationId](const auto& initializer) { return initializer.serializationId == serializationId; });
|
||||
|
||||
return citer != s_categoryManifest.cend() ?
|
||||
(citer->viewMode == ViewMode::Graphing ?
|
||||
(IsGraphingModeEnabled() ? citer->viewMode : ViewMode::None)
|
||||
: citer->viewMode)
|
||||
: ViewMode::None;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ViewMode::None;
|
||||
}
|
||||
}
|
||||
|
||||
ViewMode NavCategoryStates::GetViewModeForFriendlyName(String ^ name)
|
||||
{
|
||||
const auto& citer = find_if(
|
||||
cbegin(s_categoryManifest),
|
||||
cend(s_categoryManifest),
|
||||
[name](const auto& initializer) { return wcscmp(initializer.friendlyName, name->Data()) == 0; });
|
||||
|
||||
return (citer != s_categoryManifest.cend()) ? citer->viewMode : ViewMode::None;
|
||||
}
|
||||
|
||||
String ^ NavCategoryStates::GetFriendlyName(ViewMode mode)
|
||||
{
|
||||
const auto& citer = find_if(
|
||||
cbegin(s_categoryManifest),
|
||||
cend(s_categoryManifest),
|
||||
[mode](const auto& initializer) { return initializer.viewMode == mode; });
|
||||
|
||||
return (citer != s_categoryManifest.cend()) ? StringReference(citer->friendlyName) : L"None";
|
||||
}
|
||||
|
||||
String ^ NavCategoryStates::GetNameResourceKey(ViewMode mode)
|
||||
{
|
||||
const auto& citer = find_if(
|
||||
cbegin(s_categoryManifest),
|
||||
cend(s_categoryManifest),
|
||||
[mode](const auto& initializer) { return initializer.viewMode == mode; });
|
||||
|
||||
return (citer != s_categoryManifest.cend()) ? StringReference(citer->nameResourceKey) + "Text" : nullptr;
|
||||
}
|
||||
|
||||
CategoryGroupType NavCategoryStates::GetGroupType(ViewMode mode)
|
||||
{
|
||||
const auto& citer = find_if(
|
||||
cbegin(s_categoryManifest),
|
||||
cend(s_categoryManifest),
|
||||
[mode](const auto& initializer) { return initializer.viewMode == mode; });
|
||||
|
||||
return (citer != s_categoryManifest.cend()) ? citer->groupType : CategoryGroupType::None;
|
||||
}
|
||||
|
||||
// GetIndex is 0-based, GetPosition is 1-based
|
||||
int NavCategoryStates::GetIndex(ViewMode mode)
|
||||
{
|
||||
int position = GetPosition(mode);
|
||||
return std::max(-1, position - 1);
|
||||
}
|
||||
|
||||
int NavCategoryStates::GetFlatIndex(ViewMode mode)
|
||||
{
|
||||
int index = -1;
|
||||
CategoryGroupType type = CategoryGroupType::None;
|
||||
const auto& citer = find_if(
|
||||
cbegin(s_categoryManifest),
|
||||
cend(s_categoryManifest),
|
||||
[mode, &type, &index](const auto& initializer) {
|
||||
++index;
|
||||
if (initializer.groupType != type)
|
||||
{
|
||||
type = initializer.groupType;
|
||||
++index;
|
||||
}
|
||||
return initializer.viewMode == mode;
|
||||
});
|
||||
|
||||
return (citer != s_categoryManifest.cend()) ? index : -1;
|
||||
}
|
||||
|
||||
// GetIndex is 0-based, GetPosition is 1-based
|
||||
int NavCategoryStates::GetIndexInGroup(ViewMode mode, CategoryGroupType type)
|
||||
{
|
||||
int index = -1;
|
||||
const auto& citer = find_if(
|
||||
cbegin(s_categoryManifest),
|
||||
cend(s_categoryManifest),
|
||||
[mode, type, &index](const auto& initializer) {
|
||||
if (initializer.groupType == type)
|
||||
{
|
||||
++index;
|
||||
return initializer.viewMode == mode;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
return (citer != s_categoryManifest.cend()) ? index : -1;
|
||||
}
|
||||
|
||||
// GetIndex is 0-based, GetPosition is 1-based
|
||||
int NavCategoryStates::GetPosition(ViewMode mode)
|
||||
{
|
||||
int position = 0;
|
||||
const auto& citer = find_if(
|
||||
cbegin(s_categoryManifest),
|
||||
cend(s_categoryManifest),
|
||||
[mode, &position](const auto& initializer) {
|
||||
++position;
|
||||
return initializer.viewMode == mode;
|
||||
});
|
||||
|
||||
return (citer != s_categoryManifest.cend()) ? position : -1;
|
||||
}
|
||||
|
||||
ViewMode NavCategoryStates::GetViewModeForVirtualKey(MyVirtualKey virtualKey)
|
||||
{
|
||||
const auto& citer = find_if(
|
||||
cbegin(s_categoryManifest),
|
||||
cend(s_categoryManifest),
|
||||
[virtualKey](const auto& initializer) { return initializer.virtualKey == virtualKey; });
|
||||
|
||||
return (citer != s_categoryManifest.end()) ? citer->viewMode : ViewMode::None;
|
||||
}
|
||||
|
||||
void NavCategoryStates::GetCategoryAcceleratorKeys(IVector<MyVirtualKey> ^ accelerators)
|
||||
{
|
||||
if (accelerators != nullptr)
|
||||
{
|
||||
accelerators->Clear();
|
||||
for (const auto& category : s_categoryManifest)
|
||||
{
|
||||
if (category.virtualKey != MyVirtualKey::None)
|
||||
{
|
||||
accelerators->Append(category.virtualKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool NavCategoryStates::IsValidViewMode(ViewMode mode)
|
||||
{
|
||||
const auto& citer = find_if(
|
||||
cbegin(s_categoryManifest),
|
||||
cend(s_categoryManifest),
|
||||
[mode](const auto& initializer) { return initializer.viewMode == mode; });
|
||||
|
||||
return citer != s_categoryManifest.cend();
|
||||
}
|
||||
|
||||
bool NavCategoryStates::IsViewModeEnabled(ViewMode mode)
|
||||
{
|
||||
if (mode != ViewMode::Graphing)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return IsGraphingModeEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "Utils.h"
|
||||
#include "MyVirtualKey.h"
|
||||
|
||||
namespace CalculatorApp
|
||||
namespace CalculatorApp::ViewModel
|
||||
{
|
||||
namespace Common
|
||||
{
|
||||
|
@ -59,46 +59,21 @@ namespace CalculatorApp
|
|||
private
|
||||
struct NavCategoryInitializer
|
||||
{
|
||||
constexpr NavCategoryInitializer(
|
||||
ViewMode mode,
|
||||
int id,
|
||||
wchar_t const* name,
|
||||
wchar_t const* nameKey,
|
||||
wchar_t const* glyph,
|
||||
CategoryGroupType group,
|
||||
MyVirtualKey vKey,
|
||||
wchar_t const* aKey,
|
||||
bool categorySupportsNegative,
|
||||
bool enabled)
|
||||
: viewMode(mode)
|
||||
, serializationId(id)
|
||||
, friendlyName(name)
|
||||
, nameResourceKey(nameKey)
|
||||
, glyph(glyph)
|
||||
, groupType(group)
|
||||
, virtualKey(vKey)
|
||||
, accessKey(aKey)
|
||||
, supportsNegative(categorySupportsNegative)
|
||||
, isEnabled(enabled)
|
||||
{
|
||||
}
|
||||
|
||||
const ViewMode viewMode;
|
||||
const int serializationId;
|
||||
const wchar_t* const friendlyName;
|
||||
const wchar_t* const nameResourceKey;
|
||||
const wchar_t* const glyph;
|
||||
const CategoryGroupType groupType;
|
||||
const MyVirtualKey virtualKey;
|
||||
const wchar_t* const accessKey;
|
||||
const bool supportsNegative;
|
||||
bool isEnabled;
|
||||
ViewMode viewMode;
|
||||
int serializationId;
|
||||
const wchar_t* friendlyName;
|
||||
const wchar_t* nameResourceKey;
|
||||
const wchar_t* glyph;
|
||||
CategoryGroupType groupType;
|
||||
MyVirtualKey virtualKey;
|
||||
std::optional<std::wstring> accessKey;
|
||||
bool supportsNegative;
|
||||
};
|
||||
|
||||
private
|
||||
struct NavCategoryGroupInitializer
|
||||
{
|
||||
constexpr NavCategoryGroupInitializer(CategoryGroupType t, wchar_t const* h, wchar_t const* n, wchar_t const* a)
|
||||
NavCategoryGroupInitializer(CategoryGroupType t, wchar_t const* h, wchar_t const* n, wchar_t const* a)
|
||||
: type(t)
|
||||
, headerResourceKey(h)
|
||||
, modeResourceKey(n)
|
||||
|
@ -112,36 +87,85 @@ namespace CalculatorApp
|
|||
const wchar_t* automationResourceKey;
|
||||
};
|
||||
|
||||
[Windows::UI::Xaml::Data::Bindable] public ref class NavCategory sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
|
||||
[Windows::UI::Xaml::Data::Bindable]
|
||||
public ref class NavCategory sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
|
||||
{
|
||||
private:
|
||||
using ViewModeType = ::CalculatorApp::ViewModel::Common::ViewMode;
|
||||
public:
|
||||
OBSERVABLE_OBJECT();
|
||||
PROPERTY_R(Platform::String ^, Name);
|
||||
PROPERTY_R(Platform::String ^, AutomationName);
|
||||
PROPERTY_R(Platform::String ^, Glyph);
|
||||
PROPERTY_R(ViewMode, Mode);
|
||||
PROPERTY_R(ViewModeType, ViewMode);
|
||||
PROPERTY_R(Platform::String ^, AccessKey);
|
||||
PROPERTY_R(bool, SupportsNegative);
|
||||
PROPERTY_R(bool, IsEnabled);
|
||||
PROPERTY_RW(bool, IsEnabled);
|
||||
|
||||
property Platform::String
|
||||
^ AutomationId { Platform::String ^ get() { return m_Mode.ToString(); } }
|
||||
^ AutomationId { Platform::String ^ get() { return m_ViewMode.ToString(); } }
|
||||
|
||||
static bool IsCalculatorViewMode(ViewModeType mode);
|
||||
static bool IsGraphingCalculatorViewMode(ViewModeType mode);
|
||||
static bool IsDateCalculatorViewMode(ViewModeType mode);
|
||||
static bool IsConverterViewMode(ViewModeType mode);
|
||||
|
||||
internal : NavCategory(
|
||||
Platform::String ^ name,
|
||||
Platform::String ^ automationName,
|
||||
Platform::String ^ glyph,
|
||||
Platform::String ^ accessKey,
|
||||
Platform::String ^ mode,
|
||||
ViewModeType viewMode,
|
||||
bool supportsNegative,
|
||||
bool isEnabled)
|
||||
: m_Name(name)
|
||||
, m_AutomationName(automationName)
|
||||
, m_Glyph(glyph)
|
||||
, m_AccessKey(accessKey)
|
||||
, m_modeString(mode)
|
||||
, m_ViewMode(viewMode)
|
||||
, m_SupportsNegative(supportsNegative)
|
||||
, m_IsEnabled(isEnabled)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
static bool IsModeInCategoryGroup(ViewModeType mode, CategoryGroupType groupType);
|
||||
|
||||
Platform::String ^ m_modeString;
|
||||
};
|
||||
|
||||
[Windows::UI::Xaml::Data::Bindable]
|
||||
public ref class NavCategoryGroup sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
|
||||
{
|
||||
internal:
|
||||
NavCategoryGroup(const NavCategoryGroupInitializer& groupInitializer);
|
||||
public:
|
||||
OBSERVABLE_OBJECT();
|
||||
OBSERVABLE_PROPERTY_R(Platform::String ^, Name);
|
||||
OBSERVABLE_PROPERTY_R(Platform::String ^, AutomationName);
|
||||
OBSERVABLE_PROPERTY_R(CategoryGroupType, GroupType);
|
||||
OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IObservableVector<NavCategory ^> ^, Categories);
|
||||
};
|
||||
|
||||
public ref class NavCategoryStates sealed
|
||||
{
|
||||
public:
|
||||
static void SetCurrentUser(Platform::String^ user);
|
||||
static Windows::Foundation::Collections::IObservableVector<NavCategoryGroup ^> ^ CreateMenuOptions();
|
||||
static NavCategoryGroup ^ CreateCalculatorCategoryGroup();
|
||||
static NavCategoryGroup ^ CreateConverterCategoryGroup();
|
||||
|
||||
static bool IsValidViewMode(ViewMode mode);
|
||||
static bool IsViewModeEnabled(ViewMode mode);
|
||||
|
||||
// For saving/restoring last mode used.
|
||||
static int Serialize(ViewMode mode);
|
||||
static ViewMode Deserialize(Platform::Object ^ obj);
|
||||
|
||||
// Query properties from states
|
||||
static ViewMode GetViewModeForFriendlyName(Platform::String ^ name);
|
||||
|
||||
static bool IsValidViewMode(ViewMode mode);
|
||||
static bool IsViewModeEnabled(ViewMode mode);
|
||||
static bool IsCalculatorViewMode(ViewMode mode);
|
||||
static bool IsGraphingCalculatorViewMode(ViewMode mode);
|
||||
static bool IsDateCalculatorViewMode(ViewMode mode);
|
||||
static bool IsConverterViewMode(ViewMode mode);
|
||||
|
||||
static void InitializeCategoryManifest(Windows::System::User ^ user);
|
||||
|
||||
static Platform::String ^ GetFriendlyName(ViewMode mode);
|
||||
static Platform::String ^ GetNameResourceKey(ViewMode mode);
|
||||
static CategoryGroupType GetGroupType(ViewMode mode);
|
||||
|
@ -152,52 +176,9 @@ namespace CalculatorApp
|
|||
static int GetIndexInGroup(ViewMode mode, CategoryGroupType type);
|
||||
static int GetPosition(ViewMode mode);
|
||||
|
||||
// Virtual key related
|
||||
static ViewMode GetViewModeForVirtualKey(MyVirtualKey virtualKey);
|
||||
|
||||
internal : NavCategory(
|
||||
Platform::String ^ name,
|
||||
Platform::String ^ automationName,
|
||||
Platform::String ^ glyph,
|
||||
Platform::String ^ accessKey,
|
||||
Platform::String ^ mode,
|
||||
ViewMode viewMode,
|
||||
bool supportsNegative,
|
||||
bool isEnabled)
|
||||
: m_Name(name)
|
||||
, m_AutomationName(automationName)
|
||||
, m_Glyph(glyph)
|
||||
, m_AccessKey(accessKey)
|
||||
, m_modeString(mode)
|
||||
, m_Mode(viewMode)
|
||||
, m_SupportsNegative(supportsNegative)
|
||||
, m_IsEnabled(isEnabled)
|
||||
{
|
||||
}
|
||||
|
||||
static std::vector<MyVirtualKey> GetCategoryAcceleratorKeys();
|
||||
|
||||
private:
|
||||
static bool IsModeInCategoryGroup(ViewMode mode, CategoryGroupType groupType);
|
||||
|
||||
Platform::String ^ m_modeString;
|
||||
};
|
||||
|
||||
[Windows::UI::Xaml::Data::Bindable] public ref class NavCategoryGroup sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
|
||||
{
|
||||
public:
|
||||
OBSERVABLE_OBJECT();
|
||||
OBSERVABLE_PROPERTY_R(Platform::String ^, Name);
|
||||
OBSERVABLE_PROPERTY_R(Platform::String ^, AutomationName);
|
||||
OBSERVABLE_PROPERTY_R(CategoryGroupType, GroupType);
|
||||
OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IObservableVector<NavCategory ^> ^, Categories);
|
||||
|
||||
static Windows::Foundation::Collections::IObservableVector<NavCategoryGroup ^> ^ CreateMenuOptions();
|
||||
|
||||
internal : static NavCategoryGroup ^ CreateCalculatorCategory();
|
||||
static NavCategoryGroup ^ CreateConverterCategory();
|
||||
|
||||
private:
|
||||
NavCategoryGroup(const NavCategoryGroupInitializer& groupInitializer);
|
||||
static void GetCategoryAcceleratorKeys(Windows::Foundation::Collections::IVector<MyVirtualKey> ^ resutls);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include "NetworkManager.h"
|
||||
|
||||
using namespace CalculatorApp;
|
||||
using namespace CalculatorApp::ViewModel;
|
||||
using namespace CalculatorApp::ViewModel::Common;
|
||||
using namespace Platform;
|
||||
using namespace Windows::Networking::Connectivity;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
namespace CalculatorApp
|
||||
namespace CalculatorApp::ViewModel::Common
|
||||
{
|
||||
public
|
||||
enum class NetworkAccessBehavior
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
namespace CalculatorApp::Common
|
||||
namespace CalculatorApp::ViewModel::Common
|
||||
{
|
||||
public
|
||||
enum class NumberBase
|
||||
|
|
8
src/CalcViewModel/Common/RadixType.cpp
Normal file
8
src/CalcViewModel/Common/RadixType.cpp
Normal file
|
@ -0,0 +1,8 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include "pch.h"
|
||||
#include "RadixType.h"
|
||||
|
||||
// export enum RadixType
|
||||
|
19
src/CalcViewModel/Common/RadixType.h
Normal file
19
src/CalcViewModel/Common/RadixType.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace CalculatorApp::ViewModel
|
||||
{
|
||||
namespace Common
|
||||
{
|
||||
// This is expected to be in same order as IDM_HEX, IDM_DEC, IDM_OCT, IDM_BIN
|
||||
public enum class RadixType
|
||||
{
|
||||
Hex,
|
||||
Decimal,
|
||||
Octal,
|
||||
Binary
|
||||
};
|
||||
}
|
||||
}
|
|
@ -7,7 +7,8 @@
|
|||
#include "CalculatorButtonUser.h"
|
||||
|
||||
using namespace CalculatorApp;
|
||||
using namespace CalculatorApp::Common;
|
||||
using namespace CalculatorApp::ViewModel::Common;
|
||||
using namespace CalculatorApp::ViewModel;
|
||||
using namespace TraceLogging;
|
||||
using namespace Concurrency;
|
||||
using namespace std;
|
||||
|
@ -78,7 +79,7 @@ namespace CalculatorApp
|
|||
{
|
||||
auto fields = ref new LoggingFields();
|
||||
|
||||
fields->AddString(StringReference(CALC_MODE), NavCategory::GetFriendlyName(mode));
|
||||
fields->AddString(StringReference(CALC_MODE), NavCategoryStates::GetFriendlyName(mode));
|
||||
fields->AddString(StringReference(L"VisualState"), state);
|
||||
fields->AddBoolean(StringReference(L"IsAlwaysOnTop"), isAlwaysOnTop);
|
||||
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_VISUAL_STATE_CHANGED), fields);
|
||||
|
@ -93,18 +94,17 @@ namespace CalculatorApp
|
|||
}
|
||||
|
||||
auto fields = ref new LoggingFields();
|
||||
fields->AddString(StringReference(CALC_MODE), NavCategory::GetFriendlyName(mode));
|
||||
fields->AddString(StringReference(CALC_MODE), NavCategoryStates::GetFriendlyName(mode));
|
||||
fields->AddUInt64(StringReference(L"NumOfOpenWindows"), currentWindowCount);
|
||||
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_WINDOW_ON_CREATED), fields);
|
||||
}
|
||||
|
||||
void TraceLogger::LogModeChange(ViewMode mode)
|
||||
{
|
||||
if (NavCategory::IsValidViewMode(mode))
|
||||
if (NavCategoryStates::IsValidViewMode(mode))
|
||||
{
|
||||
auto fields = ref new LoggingFields();
|
||||
;
|
||||
fields->AddString(StringReference(CALC_MODE), NavCategory::GetFriendlyName(mode));
|
||||
fields->AddString(StringReference(CALC_MODE), NavCategoryStates::GetFriendlyName(mode));
|
||||
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_MODE_CHANGED), fields);
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ namespace CalculatorApp
|
|||
void TraceLogger::LogHistoryItemLoad(ViewMode mode, int historyListSize, int loadedIndex)
|
||||
{
|
||||
auto fields = ref new LoggingFields();
|
||||
fields->AddString(StringReference(CALC_MODE), NavCategory::GetFriendlyName(mode));
|
||||
fields->AddString(StringReference(CALC_MODE), NavCategoryStates::GetFriendlyName(mode));
|
||||
fields->AddInt32(StringReference(L"HistoryListSize"), historyListSize);
|
||||
fields->AddInt32(StringReference(L"HistoryItemIndex"), loadedIndex);
|
||||
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_HISTORY_ITEM_LOAD), fields);
|
||||
|
@ -121,7 +121,7 @@ namespace CalculatorApp
|
|||
void TraceLogger::LogMemoryItemLoad(ViewMode mode, int memoryListSize, int loadedIndex)
|
||||
{
|
||||
auto fields = ref new LoggingFields();
|
||||
fields->AddString(StringReference(CALC_MODE), NavCategory::GetFriendlyName(mode));
|
||||
fields->AddString(StringReference(CALC_MODE), NavCategoryStates::GetFriendlyName(mode));
|
||||
fields->AddInt32(StringReference(L"MemoryListSize"), memoryListSize);
|
||||
fields->AddInt32(StringReference(L"MemoryItemIndex"), loadedIndex);
|
||||
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_MEMORY_ITEM_LOAD), fields);
|
||||
|
@ -130,7 +130,7 @@ namespace CalculatorApp
|
|||
void TraceLogger::LogError(ViewMode mode, Platform::String ^ functionName, Platform::String ^ errorString)
|
||||
{
|
||||
auto fields = ref new LoggingFields();
|
||||
fields->AddString(StringReference(CALC_MODE), NavCategory::GetFriendlyName(mode));
|
||||
fields->AddString(StringReference(CALC_MODE), NavCategoryStates::GetFriendlyName(mode));
|
||||
fields->AddString(StringReference(L"FunctionName"), functionName);
|
||||
fields->AddString(StringReference(L"Message"), errorString);
|
||||
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_EXCEPTION), fields);
|
||||
|
@ -139,7 +139,7 @@ namespace CalculatorApp
|
|||
void TraceLogger::LogStandardException(ViewMode mode, wstring_view functionName, const exception& e)
|
||||
{
|
||||
auto fields = ref new LoggingFields();
|
||||
fields->AddString(StringReference(CALC_MODE), NavCategory::GetFriendlyName(mode));
|
||||
fields->AddString(StringReference(CALC_MODE), NavCategoryStates::GetFriendlyName(mode));
|
||||
fields->AddString(StringReference(L"FunctionName"), StringReference(functionName.data()));
|
||||
wstringstream exceptionMessage;
|
||||
exceptionMessage << e.what();
|
||||
|
@ -147,16 +147,21 @@ namespace CalculatorApp
|
|||
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_EXCEPTION), fields);
|
||||
}
|
||||
|
||||
void TraceLogger::LogPlatformException(ViewMode mode, wstring_view functionName, Platform::Exception ^ e)
|
||||
void TraceLogger::LogPlatformExceptionInfo(CalculatorApp::ViewModel::Common::ViewMode mode, Platform::String ^ functionName, Platform::String^ message, int hresult)
|
||||
{
|
||||
auto fields = ref new LoggingFields();
|
||||
fields->AddString(StringReference(CALC_MODE), NavCategory::GetFriendlyName(mode));
|
||||
fields->AddString(StringReference(L"FunctionName"), StringReference(functionName.data()));
|
||||
fields->AddString(StringReference(L"Message"), e->Message);
|
||||
fields->AddInt32(StringReference(L"HRESULT"), e->HResult);
|
||||
fields->AddString(StringReference(CALC_MODE), NavCategoryStates::GetFriendlyName(mode));
|
||||
fields->AddString(StringReference(L"FunctionName"), functionName);
|
||||
fields->AddString(StringReference(L"Message"), message);
|
||||
fields->AddInt32(StringReference(L"HRESULT"), hresult);
|
||||
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_EXCEPTION), fields);
|
||||
}
|
||||
|
||||
void TraceLogger::LogPlatformException(ViewMode mode, Platform::String ^ functionName, Platform::Exception ^ e)
|
||||
{
|
||||
LogPlatformExceptionInfo(mode, functionName, e->Message, e->HResult);
|
||||
}
|
||||
|
||||
void TraceLogger::UpdateButtonUsage(NumbersAndOperatorsEnum button, ViewMode mode)
|
||||
{
|
||||
// IsProgrammerMode, IsScientificMode, IsStandardMode and None are not actual buttons, so ignore them
|
||||
|
@ -217,7 +222,7 @@ namespace CalculatorApp
|
|||
Platform::String ^ buttonUsageString;
|
||||
for (size_t i = 0; i < buttonLog.size(); i++)
|
||||
{
|
||||
buttonUsageString += NavCategory::GetFriendlyName(buttonLog[i].mode);
|
||||
buttonUsageString += NavCategoryStates::GetFriendlyName(buttonLog[i].mode);
|
||||
buttonUsageString += "|";
|
||||
buttonUsageString += buttonLog[i].button.ToString();
|
||||
buttonUsageString += "|";
|
||||
|
@ -239,7 +244,7 @@ namespace CalculatorApp
|
|||
{
|
||||
const wchar_t* calculationType = AddSubtractMode ? L"AddSubtractMode" : L"DateDifferenceMode";
|
||||
auto fields = ref new LoggingFields();
|
||||
fields->AddString(StringReference(CALC_MODE), NavCategory::GetFriendlyName(ViewMode::Date));
|
||||
fields->AddString(StringReference(CALC_MODE), NavCategoryStates::GetFriendlyName(ViewMode::Date));
|
||||
fields->AddString(StringReference(L"CalculationType"), StringReference(calculationType));
|
||||
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_DATE_CALCULATION_MODE_USED), fields);
|
||||
}
|
||||
|
@ -247,7 +252,7 @@ namespace CalculatorApp
|
|||
void TraceLogger::LogConverterInputReceived(ViewMode mode)
|
||||
{
|
||||
auto fields = ref new LoggingFields();
|
||||
fields->AddString(StringReference(CALC_MODE), NavCategory::GetFriendlyName(mode));
|
||||
fields->AddString(StringReference(CALC_MODE), NavCategoryStates::GetFriendlyName(mode));
|
||||
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_CONVERTER_INPUT_RECEIVED), fields);
|
||||
}
|
||||
|
||||
|
@ -260,7 +265,7 @@ namespace CalculatorApp
|
|||
void TraceLogger::LogInputPasted(ViewMode mode)
|
||||
{
|
||||
auto fields = ref new LoggingFields();
|
||||
fields->AddString(StringReference(CALC_MODE), NavCategory::GetFriendlyName(mode));
|
||||
fields->AddString(StringReference(CALC_MODE), NavCategoryStates::GetFriendlyName(mode));
|
||||
TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_INPUT_PASTED), fields);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,15 +8,15 @@
|
|||
|
||||
// A trace logging provider can only be instantiated and registered once per module.
|
||||
// This class implements a singleton model ensure that only one instance is created.
|
||||
namespace CalculatorApp
|
||||
namespace CalculatorApp::ViewModel::Common
|
||||
{
|
||||
struct ButtonLog
|
||||
{
|
||||
public:
|
||||
int count;
|
||||
CalculatorApp::NumbersAndOperatorsEnum button;
|
||||
CalculatorApp::Common::ViewMode mode;
|
||||
ButtonLog(CalculatorApp::NumbersAndOperatorsEnum btn, CalculatorApp::Common::ViewMode vMode)
|
||||
CalculatorApp::ViewModel::Common::NumbersAndOperatorsEnum button;
|
||||
CalculatorApp::ViewModel::Common::ViewMode mode;
|
||||
ButtonLog(CalculatorApp::ViewModel::Common::NumbersAndOperatorsEnum btn, CalculatorApp::ViewModel::Common::ViewMode vMode)
|
||||
{
|
||||
button = btn;
|
||||
mode = vMode;
|
||||
|
@ -62,20 +62,20 @@ namespace CalculatorApp
|
|||
public:
|
||||
static TraceLogger ^ GetInstance();
|
||||
|
||||
void LogModeChange(CalculatorApp::Common::ViewMode mode);
|
||||
void LogHistoryItemLoad(CalculatorApp::Common::ViewMode mode, int historyListSize, int loadedIndex);
|
||||
void LogMemoryItemLoad(CalculatorApp::Common::ViewMode mode, int memoryListSize, int loadedIndex);
|
||||
void UpdateButtonUsage(CalculatorApp::NumbersAndOperatorsEnum button, CalculatorApp::Common::ViewMode mode);
|
||||
void LogModeChange(CalculatorApp::ViewModel::Common::ViewMode mode);
|
||||
void LogHistoryItemLoad(CalculatorApp::ViewModel::Common::ViewMode mode, int historyListSize, int loadedIndex);
|
||||
void LogMemoryItemLoad(CalculatorApp::ViewModel::Common::ViewMode mode, int memoryListSize, int loadedIndex);
|
||||
void UpdateButtonUsage(CalculatorApp::ViewModel::Common::NumbersAndOperatorsEnum button, CalculatorApp::ViewModel::Common::ViewMode mode);
|
||||
void LogButtonUsage();
|
||||
void LogDateCalculationModeUsed(bool AddSubtractMode);
|
||||
void UpdateWindowCount(uint64 windowCount);
|
||||
void DecreaseWindowCount();
|
||||
bool IsWindowIdInLog(int windowId);
|
||||
void LogVisualStateChanged(CalculatorApp::Common::ViewMode mode, Platform::String ^ state, bool isAlwaysOnTop);
|
||||
void LogWindowCreated(CalculatorApp::Common::ViewMode mode, int windowId);
|
||||
void LogConverterInputReceived(CalculatorApp::Common::ViewMode mode);
|
||||
void LogVisualStateChanged(CalculatorApp::ViewModel::Common::ViewMode mode, Platform::String ^ state, bool isAlwaysOnTop);
|
||||
void LogWindowCreated(CalculatorApp::ViewModel::Common::ViewMode mode, int windowId);
|
||||
void LogConverterInputReceived(CalculatorApp::ViewModel::Common::ViewMode mode);
|
||||
void LogNavBarOpened();
|
||||
void LogError(CalculatorApp::Common::ViewMode mode, Platform::String ^ functionName, Platform::String ^ errorString);
|
||||
void LogError(CalculatorApp::ViewModel::Common::ViewMode mode, Platform::String ^ functionName, Platform::String ^ errorString);
|
||||
void LogShowHideButtonClicked(bool isHideButton);
|
||||
void LogGraphButtonClicked(GraphButton buttonName, GraphButtonValue buttonValue);
|
||||
void LogGraphLineStyleChanged(LineStyleType style);
|
||||
|
@ -83,10 +83,12 @@ namespace CalculatorApp
|
|||
void LogVariableSettingsChanged(Platform::String ^ setting);
|
||||
void LogGraphSettingsChanged(GraphSettingsType settingsType, Platform::String ^ settingValue);
|
||||
void LogGraphTheme(Platform::String ^ graphTheme);
|
||||
void LogInputPasted(CalculatorApp::ViewModel::Common::ViewMode mode);
|
||||
void LogPlatformExceptionInfo(CalculatorApp::ViewModel::Common::ViewMode mode, Platform::String ^ functionName, Platform::String ^ message, int hresult);
|
||||
|
||||
internal:
|
||||
void LogStandardException(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, _In_ const std::exception& e);
|
||||
void LogPlatformException(CalculatorApp::Common::ViewMode mode, std::wstring_view functionName, _In_ Platform::Exception ^ e);
|
||||
void LogInputPasted(CalculatorApp::Common::ViewMode mode);
|
||||
void LogPlatformException(CalculatorApp::ViewModel::Common::ViewMode mode, Platform::String ^ functionName, Platform::Exception ^ e);
|
||||
void LogStandardException(CalculatorApp::ViewModel::Common::ViewMode mode, std::wstring_view functionName, _In_ const std::exception& e);
|
||||
|
||||
private:
|
||||
// Create an instance of TraceLogger
|
||||
|
|
|
@ -6,13 +6,16 @@
|
|||
//
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include <winmeta.h>
|
||||
|
||||
#include "Utils.h"
|
||||
#include "Common/AppResourceProvider.h"
|
||||
#include "Common/ExpressionCommandSerializer.h"
|
||||
#include "Common/ExpressionCommandDeserializer.h"
|
||||
|
||||
using namespace CalculatorApp;
|
||||
using namespace CalculatorApp::Common;
|
||||
using namespace CalculatorApp::ViewModel::Common;
|
||||
using namespace concurrency;
|
||||
using namespace Graphing::Renderer;
|
||||
using namespace Platform;
|
||||
|
@ -168,18 +171,20 @@ void Utils::TrimBack(wstring& value)
|
|||
}).base(), value.end());
|
||||
}
|
||||
|
||||
String^ Utils::EscapeHtmlSpecialCharacters(String^ originalString, shared_ptr<vector<wchar_t>> specialCharacters)
|
||||
bool operator==(const Color& color1, const Color& color2)
|
||||
{
|
||||
return equal_to<Color>()(color1, color2);
|
||||
}
|
||||
|
||||
bool operator!=(const Color& color1, const Color& color2)
|
||||
{
|
||||
return !(color1 == color2);
|
||||
}
|
||||
|
||||
String^ CalculatorApp::ViewModel::Common::Utilities::EscapeHtmlSpecialCharacters(String^ originalString)
|
||||
{
|
||||
// Construct a default special characters if not provided.
|
||||
if (specialCharacters == nullptr)
|
||||
{
|
||||
specialCharacters = make_shared<vector<wchar_t>>();
|
||||
specialCharacters->push_back(L'&');
|
||||
specialCharacters->push_back(L'\"');
|
||||
specialCharacters->push_back(L'\'');
|
||||
specialCharacters->push_back(L'<');
|
||||
specialCharacters->push_back(L'>');
|
||||
}
|
||||
const std::vector<wchar_t> specialCharacters {L'&', L'\"', L'\'', L'<', L'>'};
|
||||
|
||||
bool replaceCharacters = false;
|
||||
const wchar_t* pCh;
|
||||
|
@ -189,7 +194,7 @@ String^ Utils::EscapeHtmlSpecialCharacters(String^ originalString, shared_ptr<ve
|
|||
// If there isn't any special character, we simply return the original string
|
||||
for (pCh = originalString->Data(); *pCh; pCh++)
|
||||
{
|
||||
if (std::find(specialCharacters->begin(), specialCharacters->end(), *pCh) != specialCharacters->end())
|
||||
if (std::find(specialCharacters.begin(), specialCharacters.end(), *pCh) != specialCharacters.end())
|
||||
{
|
||||
replaceCharacters = true;
|
||||
break;
|
||||
|
@ -233,20 +238,15 @@ String^ Utils::EscapeHtmlSpecialCharacters(String^ originalString, shared_ptr<ve
|
|||
return replaceCharacters ? replacementString : originalString;
|
||||
}
|
||||
|
||||
bool operator==(const Color& color1, const Color& color2)
|
||||
bool CalculatorApp::ViewModel::Common::Utilities::AreColorsEqual(Windows::UI::Color color1, Windows::UI::Color color2)
|
||||
{
|
||||
return equal_to<Color>()(color1, color2);
|
||||
}
|
||||
|
||||
bool operator!=(const Color& color1, const Color& color2)
|
||||
{
|
||||
return !(color1 == color2);
|
||||
return Utils::AreColorsEqual(color1, color2);
|
||||
}
|
||||
|
||||
// This method calculates the luminance ratio between White and the given background color.
|
||||
// The luminance is calculate using the RGB values and does not use the A value.
|
||||
// White or Black is returned
|
||||
SolidColorBrush ^ Utils::GetContrastColor(Color backgroundColor)
|
||||
SolidColorBrush ^ CalculatorApp::ViewModel::Common::Utilities::GetContrastColor(Color backgroundColor)
|
||||
{
|
||||
auto luminance = 0.2126 * backgroundColor.R + 0.7152 * backgroundColor.G + 0.0722 * backgroundColor.B;
|
||||
|
||||
|
@ -257,3 +257,21 @@ SolidColorBrush ^ Utils::GetContrastColor(Color backgroundColor)
|
|||
|
||||
return static_cast<SolidColorBrush ^>(Application::Current->Resources->Lookup(L"BlackBrush"));
|
||||
}
|
||||
|
||||
int CalculatorApp::ViewModel::Common::Utilities::GetWindowId()
|
||||
{
|
||||
return Utils::GetWindowId();
|
||||
}
|
||||
|
||||
long long CalculatorApp::ViewModel::Common::Utilities::GetConst_WINEVENT_KEYWORD_RESPONSE_TIME()
|
||||
{
|
||||
return WINEVENT_KEYWORD_RESPONSE_TIME;
|
||||
}
|
||||
|
||||
bool CalculatorApp::ViewModel::Common::Utilities::GetIntegratedDisplaySize(double* size)
|
||||
{
|
||||
if (SUCCEEDED(::GetIntegratedDisplaySize(size)))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -168,11 +168,22 @@ public:
|
|||
// The variable member generated by this macro should not be used in the class code, use the
|
||||
// property getter instead.
|
||||
#define COMMAND_FOR_METHOD(p, m) \
|
||||
property Windows::UI::Xaml::Input::ICommand^ p {\
|
||||
Windows::UI::Xaml::Input::ICommand^ get() {\
|
||||
if (!donotuse_##p) {\
|
||||
donotuse_##p = CalculatorApp::Common::MakeDelegate(this, &m);\
|
||||
} return donotuse_##p; }} private: Windows::UI::Xaml::Input::ICommand^ donotuse_##p; \
|
||||
property Windows::UI::Xaml::Input::ICommand ^ p \
|
||||
{ \
|
||||
Windows::UI::Xaml::Input::ICommand ^ get() \
|
||||
{ \
|
||||
if (!donotuse_##p) \
|
||||
{ \
|
||||
donotuse_##p = ref new CalculatorApp::ViewModel::Common::DelegateCommand( \
|
||||
CalculatorApp::ViewModel::Common::MakeDelegateCommandHandler(this, &m) \
|
||||
); \
|
||||
} \
|
||||
return donotuse_##p; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
private: \
|
||||
Windows::UI::Xaml::Input::ICommand ^ donotuse_##p; \
|
||||
\
|
||||
public:
|
||||
|
||||
|
@ -398,10 +409,6 @@ namespace Utils
|
|||
void Trim(std::wstring& value);
|
||||
void TrimFront(std::wstring& value);
|
||||
void TrimBack(std::wstring& value);
|
||||
|
||||
Platform::String ^ EscapeHtmlSpecialCharacters(Platform::String ^ originalString, std::shared_ptr<std::vector<wchar_t>> specialCharacters = nullptr);
|
||||
|
||||
Windows::UI::Xaml::Media::SolidColorBrush ^ GetContrastColor(Windows::UI::Color backgroundColor);
|
||||
}
|
||||
|
||||
// This goes into the header to define the property, in the public: section of the class
|
||||
|
@ -697,6 +704,22 @@ namespace CalculatorApp
|
|||
|
||||
return to;
|
||||
}
|
||||
|
||||
namespace ViewModel::Common
|
||||
{
|
||||
// below utilities are intended to support interops between C# and C++/CX
|
||||
// they can be removed if the entire codebase has been migrated to C#
|
||||
public ref class Utilities sealed
|
||||
{
|
||||
public:
|
||||
static Platform::String ^ EscapeHtmlSpecialCharacters(Platform::String ^ originalString);
|
||||
static bool AreColorsEqual(Windows::UI::Color color1, Windows::UI::Color color2);
|
||||
static Windows::UI::Xaml::Media::SolidColorBrush ^ GetContrastColor(Windows::UI::Color backgroundColor);
|
||||
static int GetWindowId();
|
||||
static long long GetConst_WINEVENT_KEYWORD_RESPONSE_TIME();
|
||||
static bool GetIntegratedDisplaySize(double* size);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// There's no standard definition of equality for Windows::UI::Color structs.
|
||||
|
|
|
@ -11,11 +11,11 @@
|
|||
#include "UnitConverterDataConstants.h"
|
||||
|
||||
using namespace CalculatorApp;
|
||||
using namespace CalculatorApp::Common;
|
||||
using namespace CalculatorApp::Common::LocalizationServiceProperties;
|
||||
using namespace CalculatorApp::DataLoaders;
|
||||
using namespace CalculatorApp::ViewModel::Common;
|
||||
using namespace CalculatorApp::ViewModel::Common::LocalizationServiceProperties;
|
||||
using namespace CalculatorApp::ViewModel::DataLoaders;
|
||||
using namespace CalculatorApp::ViewModel;
|
||||
using namespace CalculatorApp::ViewModel::CurrencyDataLoaderConstants;
|
||||
using namespace CalculatorApp::ViewModel::DataLoaders::CurrencyDataLoaderConstants;
|
||||
using namespace concurrency;
|
||||
using namespace Platform;
|
||||
using namespace std;
|
||||
|
@ -69,7 +69,7 @@ static constexpr auto DEFAULT_TO_CURRENCY = L"EUR";
|
|||
|
||||
namespace CalculatorApp
|
||||
{
|
||||
namespace ViewModel
|
||||
namespace ViewModel::DataLoaders
|
||||
{
|
||||
namespace UnitConverterResourceKeys
|
||||
{
|
||||
|
@ -188,10 +188,9 @@ void CurrencyDataLoader::ResetLoadStatus()
|
|||
#pragma optimize("", off) // Turn off optimizations to work around DevDiv 393321
|
||||
void CurrencyDataLoader::LoadData()
|
||||
{
|
||||
RegisterForNetworkBehaviorChanges();
|
||||
|
||||
if (!LoadFinished())
|
||||
{
|
||||
RegisterForNetworkBehaviorChanges();
|
||||
create_task([this]() -> task<bool> {
|
||||
vector<function<future<bool>()>> loadFunctions = {
|
||||
[this]() { return TryLoadDataFromCacheAsync(); },
|
||||
|
@ -241,7 +240,7 @@ unordered_map<UCM::Unit, UCM::ConversionData, UCM::UnitHash> CurrencyDataLoader:
|
|||
|
||||
bool CurrencyDataLoader::SupportsCategory(const UCM::Category& target)
|
||||
{
|
||||
static int currencyId = NavCategory::Serialize(ViewMode::Currency);
|
||||
static int currencyId = NavCategoryStates::Serialize(ViewMode::Currency);
|
||||
return target.id == currencyId;
|
||||
}
|
||||
|
||||
|
@ -300,7 +299,7 @@ pair<wstring, wstring> CurrencyDataLoader::GetCurrencyRatioEquality(_In_ const U
|
|||
double ratio = (iter2->second).ratio;
|
||||
double rounded = RoundCurrencyRatio(ratio);
|
||||
|
||||
auto digit = LocalizationSettings::GetInstance().GetDigitSymbolFromEnUsDigit(L'1');
|
||||
auto digit = LocalizationSettings::GetInstance()->GetDigitSymbolFromEnUsDigit(L'1');
|
||||
auto digitSymbol = ref new String(&digit, 1);
|
||||
auto roundedFormat = m_ratioFormatter->Format(rounded);
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
namespace CalculatorApp
|
||||
{
|
||||
namespace ViewModel
|
||||
namespace ViewModel::DataLoaders
|
||||
{
|
||||
public
|
||||
enum class CurrencyLoadStatus
|
||||
|
@ -54,7 +54,9 @@ namespace CalculatorApp
|
|||
class CurrencyDataLoader : public UCM::IConverterDataLoader, public UCM::ICurrencyConverterDataLoader
|
||||
{
|
||||
public:
|
||||
CurrencyDataLoader(_In_ std::unique_ptr<CalculatorApp::DataLoaders::ICurrencyHttpClient> client, const wchar_t* overrideLanguage = nullptr);
|
||||
CurrencyDataLoader(
|
||||
_In_ std::unique_ptr<CalculatorApp::ViewModel::DataLoaders::ICurrencyHttpClient> client,
|
||||
const wchar_t* overrideLanguage = nullptr);
|
||||
~CurrencyDataLoader();
|
||||
|
||||
bool LoadFinished();
|
||||
|
@ -82,7 +84,7 @@ namespace CalculatorApp
|
|||
std::future<bool> TryLoadDataFromWebOverrideAsync() override;
|
||||
// ICurrencyConverterDataLoader
|
||||
|
||||
void OnNetworkBehaviorChanged(CalculatorApp::NetworkAccessBehavior newBehavior);
|
||||
void OnNetworkBehaviorChanged(CalculatorApp::ViewModel::Common::NetworkAccessBehavior newBehavior);
|
||||
|
||||
private:
|
||||
void ResetLoadStatus();
|
||||
|
@ -112,7 +114,7 @@ namespace CalculatorApp
|
|||
|
||||
private:
|
||||
Platform::String ^ m_responseLanguage;
|
||||
std::unique_ptr<CalculatorApp::DataLoaders::ICurrencyHttpClient> m_client;
|
||||
std::unique_ptr<CalculatorApp::ViewModel::DataLoaders::ICurrencyHttpClient> m_client;
|
||||
|
||||
bool m_isRtlLanguage;
|
||||
|
||||
|
@ -130,8 +132,8 @@ namespace CalculatorApp
|
|||
|
||||
CurrencyLoadStatus m_loadStatus;
|
||||
|
||||
CalculatorApp::NetworkManager ^ m_networkManager;
|
||||
CalculatorApp::NetworkAccessBehavior m_networkAccessBehavior;
|
||||
CalculatorApp::ViewModel::Common::NetworkManager ^ m_networkManager;
|
||||
CalculatorApp::ViewModel::Common::NetworkAccessBehavior m_networkAccessBehavior;
|
||||
Windows::Foundation::EventRegistrationToken m_networkBehaviorToken;
|
||||
bool m_meteredOverrideSet;
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#endif
|
||||
|
||||
using namespace CalculatorApp::DataLoaders;
|
||||
using namespace CalculatorApp::ViewModel::DataLoaders;
|
||||
using namespace Platform;
|
||||
using namespace std;
|
||||
using namespace Windows::Foundation;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace CalculatorApp
|
||||
{
|
||||
namespace DataLoaders
|
||||
namespace ViewModel::DataLoaders
|
||||
{
|
||||
class CurrencyHttpClient : public ICurrencyHttpClient
|
||||
{
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
namespace CalculatorApp
|
||||
{
|
||||
namespace DataLoaders
|
||||
namespace ViewModel::DataLoaders
|
||||
{
|
||||
class ICurrencyHttpClient
|
||||
{
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue