Merge remote-tracking branch 'upstream/master' into Fix420

This commit is contained in:
Rudy Huyn 2019-04-24 00:11:34 -07:00
commit 23e894648b
194 changed files with 2895 additions and 3239 deletions

View file

@ -6,36 +6,45 @@ labels: ''
assignees: '' assignees: ''
--- ---
<!--Before filing a bug <!--
Before filing a bug
- Ensure the bug reproduces on the latest version of the app. - Ensure the bug reproduces on the latest version of the app.
- Search existing issues and make sure this issue is not already filed.--> - Search existing issues and make sure this issue is not already filed.
-->
**Describe the bug** **Describe the bug**
<!--A clear and concise description of what the bug is.--> <!-- A clear and concise description of what the bug is. -->
**Steps To Reproduce** **Steps To Reproduce**
<!--Steps to reproduce the behavior: <!--
Steps to reproduce the behavior:
1. Go to '...' 1. Go to '...'
2. Click on '....' 2. Click on '....'
3. Scroll down to '....' 3. Scroll down to '....'
4. See error--> 4. See error
-->
**Expected behavior** **Expected behavior**
<!--A clear and concise description of what you expected to happen.--> <!-- A clear and concise description of what you expected to happen. -->
**Screenshots** **Screenshots**
<!--If applicable, add screenshots to help explain your problem.--> <!-- If applicable, add screenshots to help explain your problem. -->
**Device and Application Information (please complete the following information):** **Device and Application Information**
- OS Build: - OS Build:
- Architecture: - Architecture:
- Application Version: - Application Version:
- Region:
<!--Run the following commands in Powershell and copy/paste the output. - Dev Version Installed:
<!--
Run the following commands in Powershell and copy/paste the output.
" - OS Build: $([Environment]::OSVersion.Version)" " - OS Build: $([Environment]::OSVersion.Version)"
" - Architecture: $((Get-AppxPackage -Name Microsoft.WindowsCalculator).Architecture)" " - Architecture: $((Get-AppxPackage -Name Microsoft.WindowsCalculator).Architecture)"
" - Application Version: $((Get-AppxPackage -Name Microsoft.WindowsCalculator).Version)" " - Application Version: $((Get-AppxPackage -Name Microsoft.WindowsCalculator).Version)"
" - Region: $((Get-Culture).Name)"
" - Dev Version Installed: $($null -ne (Get-AppxPackage -Name Microsoft.WindowsCalculator.Dev))"
--> -->
**Additional context** **Additional context**
<!--Add any other context about the problem here.--> <!-- Add any other context about the problem here. -->

View file

@ -2,42 +2,42 @@
name: Feature request name: Feature request
about: Propose a new feature in the app about: Propose a new feature in the app
title: '' title: ''
labels: '' labels: 'Enhancement'
assignees: '' 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/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
--> -->
**Problem Statement** **Problem Statement**
<!-- What problem are we trying to solve? Whos the target audience? Is there a customer need or <!--
pain point we need to remedy? Is there a business goal or metric we are trying to improve? Do we What problem are we trying to solve? Whos the target audience? Is there a customer need or pain point we need to remedy? Is there a business goal or metric we are trying to improve? Do we have a hypothesis we want to prove or disprove?
have a hypothesis we want to prove or disprove? --> -->
**Evidence or User Insights** **Evidence or User Insights**
<!-- Why should we do this? Potential sources of data: Feedback Hub, other GitHub issues, other <!--
anecdotes from listening to customers in person or online, request from another team, telemetry Why should we do this? Potential sources of data: Feedback Hub, other GitHub issues, other anecdotes from listening to customers in person or online, request from another team, telemetry data, user research, market or competitive research
data, user research, market or competitive research --> -->
**Proposal** **Proposal**
<!-- How will the solution/feature help us solve the problem? How will it meet the target <!--
audiences needs? If there are business goals or metrics, how does this improve them? --> How will the solution/feature help us solve the problem? How will it meet the target audiences needs? If there are business goals or metrics, how does this improve them?
-->
**Goals** **Goals**
<!-- What you want to accomplish with this feature. Typical examples include <!--
“User Can *perform some task*” --> What you want to accomplish with this feature. Typical examples include
"User Can *perform some task*"
-->
**Non-Goals** **Non-Goals**
<!-- Things we are explicitly not doing or supporting or that are out of scope, including reasons <!--
why. --> Things we are explicitly not doing or supporting or that are out of scope, including reasons why.
-->
**Low-Fidelity Concept** **Low-Fidelity Concept**
<!-- Show as much of the experience as needed to explain the idea. This can be as simple as a <!--
napkin drawing but can also be a code prototype, a PowerPoint walkthrough, or a design Show as much of the experience as needed to explain the idea. This can be as simple as a napkin drawing but can also be a code prototype, or a design comp. Keep it simple at this stage, as it can be refined later during the pre-production stage.
comp. --> -->

View file

@ -0,0 +1,54 @@
---
name: Localization Suggestion
about: Report a problem or suggested change to Calculator's localized content.
title: '[Localization] '
labels: 'Area: World-Readiness'
assignees: ''
---
<!--
PLEASE NOTE:
We cannot _merge_ any suggested localization changes to our localized resources files. These files are automatically generated from an internal localization process. Any suggestion submitted this way will be duplicated into our internal localization system, and then closed here.
Alternatively, you can launch feedback-hub://, click on the "Language Community" tab on the left-side of the app, and follow the steps to submit a localization suggestion that way. (The "Language Community" tab currently will only be visible if your system is running a non-English language).
Before filing a bug
- Ensure the bug reproduces on the latest version of the app.
- Search existing issues and make sure this issue is not already filed.
-->
**Describe the bug**
<!-- A clear and concise description of what the bug is. -->
**Steps To Reproduce**
<!--
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
-->
**Expected behavior**
<!-- A clear and concise description of what you expected to happen. -->
**Screenshots**
<!-- If applicable, add screenshots to help explain your problem. -->
**Device and Application Information**
- OS Build:
- Architecture:
- Application Version:
- Region:
- Dev Version Installed:
<!--
Run the following commands in Powershell and copy/paste the output.
" - OS Build: $([Environment]::OSVersion.Version)"
" - Architecture: $((Get-AppxPackage -Name Microsoft.WindowsCalculator).Architecture)"
" - Application Version: $((Get-AppxPackage -Name Microsoft.WindowsCalculator).Version)"
" - Region: $((Get-Culture).Name)"
" - Dev Version Installed: $($null -ne (Get-AppxPackage -Name Microsoft.WindowsCalculator.Dev))"
-->
**Additional context**
<!-- Add any other context about the problem here. -->

1
.gitignore vendored
View file

@ -289,6 +289,7 @@ __pycache__/
# Calculator specific # Calculator specific
Generated Files/ Generated Files/
src/GraphControl/GraphingImplOverrides.props
!/build/config/TRexDefs/** !/build/config/TRexDefs/**
!src/Calculator/TemporaryKey.pfx !src/Calculator/TemporaryKey.pfx
!src/CalculatorUnitTests/CalculatorUnitTests_TemporaryKey.pfx !src/CalculatorUnitTests/CalculatorUnitTests_TemporaryKey.pfx

View file

@ -3,7 +3,8 @@ The Calculator team encourages community feedback and contributions. Thank you f
making Calculator better! There are several ways you can get involved. making Calculator better! There are several ways you can get involved.
## Reporting issues and suggesting new features ## Reporting issues and suggesting new features
If Calculator is not working properly, please file a report in the [Feedback Hub](https://insider.windows.com/en-us/fb/?contextid=130&newFeedback=True). If Calculator is not working properly, please file a report in the
[Feedback Hub](https://insider.windows.com/en-us/fb/?contextid=130&newFeedback=True).
Feedback Hub reports automatically include diagnostic data, such as the version of Calculator Feedback Hub reports automatically include diagnostic data, such as the version of Calculator
you're using. you're using.
@ -17,21 +18,38 @@ all community interactions must abide by the [Code of Conduct](CODE_OF_CONDUCT.m
## Finding issues you can help with ## Finding issues you can help with
Looking for something to work on? Looking for something to work on?
[Issues marked *good first issue*](https://github.com/Microsoft/calculator/labels/good%20first%20issue) Issues marked [``good first issue``](https://github.com/Microsoft/calculator/labels/good%20first%20issue)
are a good place to start. are a good place to start.
You can also check [the *help wanted* tag](https://github.com/Microsoft/calculator/labels/help%20wanted) You can also check the [``help wanted``](https://github.com/Microsoft/calculator/labels/help%20wanted) tag to find
to find other issues to help with. other issues to help with. If you're interested in working on a fix, leave a comment to let everyone know and to help
avoid duplicated effort from others.
## Contributions we accept ## Contributions we accept
We welcome your contributions to the Calculator project, especially to fix bugs and to make We welcome your contributions to the Calculator project, especially to fix bugs and to make
improvements which address the top issues reported by Calculator users. improvements which address the top issues reported by Calculator users. Some general guidelines:
We have a high bar for new features and changes to the user experience. We prefer to evaluate * **DO** create one pull request per Issue, and ensure that the Issue is linked in the pull request.
*prototypes* to ensure that the design meets users' needs before we start discussing implementation * **DO** follow our [Coding and Style](#style-guidelines) guidelines, and keep code changes as small as possible.
details and reviewing code. We follow a [user-centered process for developing features](docs/NewFeatureProcess.md). * **DO** include corresponding tests whenever possible.
New features need sponsorship from the Calculator team, but we welcome community contributions at * **DO** check for additional occurrences of the same problem in other parts of the codebase before submitting your PR.
many stages of the process. * **DO** [link the issue](https://github.com/blog/957-introducing-issue-mentions) you are addressing in the
pull request.
* **DO** write a good description for your pull request. More detail is better. Describe *why* the change is being
made and *why* you have chosen a particular solution. Describe any manual testing you performed to validate your change.
* **DO NOT** submit a PR unless it is linked to an Issue marked
[`triage approved`](https://github.com/Microsoft/calculator/issues?q=is%3Aissue+is%3Aopen+label%3A%22Triage%3A+Approved%22).
This enables us to have a discussion on the idea before anyone invests time in an implementation.
* **DO NOT** merge multiple changes into one PR unless they have the same root cause.
* **DO NOT** submit pure formatting/typo changes to code that has not been modified otherwise.
We follow a [user-centered process for developing features](docs/NewFeatureProcess.md). New features
need sponsorship from the Calculator team, but we welcome community contributions at many stages of
the process.
> Submitting a pull request for an approved Issue is not a guarantee it will be approved.
> The change must meet our high bar for code quality, architecture, and performance, as well as
> [other requirements](#docs/NewFeatureProcess.md#technical-review).
## Making changes to the code ## Making changes to the code
@ -41,7 +59,8 @@ To learn how to build the code and run tests, follow the instructions in the [RE
### Style guidelines ### Style guidelines
The code in this project uses several different coding styles, depending on the age and history of The code in this project uses several different coding styles, depending on the age and history of
the code. Please attempt to match the style of surrounding code as much as possible. In new the code. Please attempt to match the style of surrounding code as much as possible. In new
components, prefer the patterns described in the [C++ core guidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines) components, prefer the patterns described in the
[C++ core guidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines)
and the [modern C++/WinRT language projections](https://docs.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/). and the [modern C++/WinRT language projections](https://docs.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/).
### Testing ### Testing
@ -61,18 +80,9 @@ to group your changes into a small number of commits which we can review one at
When completing a pull request, we will generally squash your changes into a single commit. Please When completing a pull request, we will generally squash your changes into a single commit. Please
let us know if your pull request needs to be merged as separate commits. let us know if your pull request needs to be merged as separate commits.
## Submitting a pull request and participating in code review ## Review Process
Writing a good description for your pull request is crucial to help reviewers and future
maintainers understand your change. More detail is better.
- [Link the issue you're addressing in the pull request](https://github.com/blog/957-introducing-issue-mentions).
- Describe *why* the change is being made and *why* you've chosen a particular solution.
- Describe any manual testing you performed to validate your change.
Please submit one pull request per issue. Large pull requests which have unrelated changes can be
difficult to review.
After submitting a pull request, members of the calculator team will review your code. We will After submitting a pull request, members of the calculator team will review your code. We will
assign the request to an appropriate reviewer within two days. Any member of the community may assign the request to an appropriate reviewer. Any member of the community may
participate in the review, but at least one member of the Calculator team will ultimately approve participate in the review, but at least one member of the Calculator team will ultimately approve
the request. the request.

View file

@ -12,9 +12,13 @@ Calculator ships regularly with new features and bug fixes. You can get the late
- Standard Calculator functionality which offers basic operations and evaluates commands immediately as they are entered. - Standard Calculator functionality which offers basic operations and evaluates commands immediately as they are entered.
- Scientific Calculator functionality which offers expanded operations and evaluates commands using order of operations. - Scientific Calculator functionality which offers expanded operations and evaluates commands using order of operations.
- Programmer Calculator functionality which offers common mathematical operations for developers including conversion between common bases. - Programmer Calculator functionality which offers common mathematical operations for developers including conversion between common bases.
- Date Calculation functionality which offers the difference between two dates, as well as the ability to add/subtract years, months and/or days to/from a given input date.
- Calculation history and memory capabilities. - Calculation history and memory capabilities.
- Conversion between many units of measurement. - Conversion between many units of measurement.
- Currency conversion based on data retrieved from [Bing](https://www.bing.com). - Currency conversion based on data retrieved from [Bing](https://www.bing.com).
- [Infinite precision](https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic) for basic
arithmetic operations (addition, subtraction, multiplication, division) so that calculations
never lose precision.
## Getting started ## Getting started
Prerequisites: Prerequisites:

View file

@ -35,7 +35,7 @@ jobs:
cd $(Build.SourcesDirectory) cd $(Build.SourcesDirectory)
git add -A git add -A
git diff --cached --exit-code git diff --cached --exit-code
echo '##vso[task.setvariable variable=hasChanges]%errorlevel%' echo ##vso[task.setvariable variable=hasChanges]%errorlevel%
git diff --cached > $(Build.ArtifactStagingDirectory)\LocalizedStrings.patch git diff --cached > $(Build.ArtifactStagingDirectory)\LocalizedStrings.patch
displayName: Check for changes and create patch file displayName: Check for changes and create patch file

View file

@ -9,8 +9,8 @@ pr: none
variables: variables:
versionMajor: 10 versionMajor: 10
versionMinor: 1903 versionMinor: 1904
versionBuild: $[counter('10.1903.*', 0)] versionBuild: $[counter('10.1904.*', 0)]
versionPatch: 0 versionPatch: 0
name: '$(versionMajor).$(versionMinor).$(versionBuild).$(versionPatch)' name: '$(versionMajor).$(versionMinor).$(versionBuild).$(versionPatch)'

View file

@ -28,8 +28,8 @@ jobs:
- task: PkgESSetupBuild@10 - task: PkgESSetupBuild@10
displayName: Initialize Package ES displayName: Initialize Package ES
inputs: inputs:
productName: Calculator productName: Calculator
disableWorkspace: true disableWorkspace: true
env: env:
XES_DISABLEPROV: true XES_DISABLEPROV: true
@ -46,6 +46,8 @@ jobs:
- task: PkgESCodeSign@10 - task: PkgESCodeSign@10
displayName: Send bundle to Package ES code signing service displayName: Send bundle to Package ES code signing service
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
inputs: inputs:
signConfigXml: build\config\SignConfig.xml signConfigXml: build\config\SignConfig.xml
inPathRoot: $(Build.ArtifactStagingDirectory)\appxBundle inPathRoot: $(Build.ArtifactStagingDirectory)\appxBundle
@ -60,25 +62,25 @@ jobs:
- task: CopyFiles@2 - task: CopyFiles@2
displayName: Copy signed AppxBundle to vpack staging folder displayName: Copy signed AppxBundle to vpack staging folder
inputs: inputs:
sourceFolder: $(Build.ArtifactStagingDirectory)\appxBundleSigned sourceFolder: $(Build.ArtifactStagingDirectory)\appxBundleSigned
targetFolder: $(Build.ArtifactStagingDirectory)\vpack\appxBundle targetFolder: $(Build.ArtifactStagingDirectory)\vpack\appxBundle
- task: PkgESVPack@10 - task: PkgESVPack@10
displayName: Create and push vpack for app displayName: Create and push vpack for app
env: env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken) SYSTEM_ACCESSTOKEN: $(System.AccessToken)
inputs: inputs:
sourceDirectory: $(Build.ArtifactStagingDirectory)\vpack\appxBundle sourceDirectory: $(Build.ArtifactStagingDirectory)\vpack\appxBundle
description: VPack for the Calculator Application description: VPack for the Calculator Application
pushPkgName: calculator.app pushPkgName: calculator.app
version: $(versionMajor).$(versionMinor).$(versionBuild) version: $(versionMajor).$(versionMinor).$(versionBuild)
owner: paxeeapps owner: paxeeapps
- task: PublishBuildArtifacts@1 - task: PublishBuildArtifacts@1
displayName: Publish vpack\app artifact with vpack manifest displayName: Publish vpack\app artifact with vpack manifest
inputs: inputs:
pathtoPublish: $(XES_VPACKMANIFESTDIRECTORY)\$(XES_VPACKMANIFESTNAME) pathtoPublish: $(XES_VPACKMANIFESTDIRECTORY)\$(XES_VPACKMANIFESTNAME)
artifactName: vpack\app artifactName: vpack\app
# TODO (macool): create and push internal test packages and test config # TODO (macool): create and push internal test packages and test config

View file

@ -153,7 +153,9 @@ The CalcEngine contains the logic for interpreting and performing operations acc
### RatPack ### RatPack
The RatPack (short for Rational Pack) is the core of the Calculator model and contains the logic for performing its mathematical operations. The interface to this layer is defined in [ratpak.h][ratpak.h]. The RatPack (short for Rational Pack) is the core of the Calculator model and contains the logic for
performing its mathematical operations (using [infinite precision][Infinite Precision] arithmetic
instead of regular floating point arithmetic). The interface to this layer is defined in [ratpak.h][ratpak.h].
[References]:#################################################################################################### [References]:####################################################################################################

View file

@ -1,7 +1,8 @@
# New feature process # New feature process
## Where do I submit my idea for a new feature? ## Where do I submit my idea for a new feature?
The easiest way to submit new feature requests is through [Feedback Hub](https://insider.windows.com/en-us/fb/?contextid=130). The easiest way to submit new feature requests is through
[Feedback Hub](https://insider.windows.com/en-us/fb/?contextid=130).
In Feedback Hub, any Windows user (even if they aren't on GitHub) can upvote suggestions. The In Feedback Hub, any Windows user (even if they aren't on GitHub) can upvote suggestions. The
Calculator team reviews these suggestions regularly, and when we're ready to work on an idea we Calculator team reviews these suggestions regularly, and when we're ready to work on an idea we
create [feature pitch issues here on GitHub](https://github.com/Microsoft/calculator/issues?q=is%3Aissue+is%3Aopen+project%3AMicrosoft%2Fcalculator%2F1). create [feature pitch issues here on GitHub](https://github.com/Microsoft/calculator/issues?q=is%3Aissue+is%3Aopen+project%3AMicrosoft%2Fcalculator%2F1).
@ -12,73 +13,45 @@ product. The [Feature Tracking board](https://github.com/Microsoft/calculator/pr
all the features we're working on and where they're at in the process. all the features we're working on and where they're at in the process.
## Do I need to follow this process? Can I just start coding and submit a PR? ## Do I need to follow this process? Can I just start coding and submit a PR?
You *do not* need to follow this process for bug fixes, performance improvements, or changes to the You **do not** need to follow this process for bug fixes, performance improvements, or changes to the
development tools. To contribute these changes, [discuss the proposed change in an issue](https://github.com/Microsoft/calculator/issues/new) development tools. To contribute these changes,
[discuss the proposed change in an issue](https://github.com/Microsoft/calculator/issues/new)
and then submit a pull request. and then submit a pull request.
You *do* need to follow this process for any change which "users will notice". This applies You **do** need to follow this process for any change which "users will notice". This applies
especially to new features and major visual changes. especially to new features and major visual changes.
## Step 1: Feature pitch ## Step 1: Feature pitch
The feature pitch concisely describes a point of view on the problem the new feature should solve. Feature pitches are submitted as issues on GitHub using the
It will typically include these sections: [Feature Request template](https://github.com/Microsoft/calculator/issues/new?assignees=&labels=&template=feature_request.md&title=).
We encourage discussion on open issues, and as discussion progresses we will edit the issue description to refine the
idea until it is ready for review.
* **Problem Statement**: What problem are we trying to solve? Whos the target audience? Is there a We review pitches regularly, and will approve or close issues based on whether they broadly align with the
customer need or pain point we need to remedy? Is there a business goal or metric we are trying [Calculator roadmap](https://github.com/Microsoft/calculator/blob/master/docs/Roadmap.md). Approved pitches are moved
to improve? Do we have a hypothesis we want to prove or disprove? into [pre-production](https://github.com/Microsoft/calculator/projects/1) on the feature tracking board.
* **Evidence or User Insights**: Why should we do this? Potential sources of data: Feedback Hub,
other GitHub issues, other anecdotes from listening to customers in person or online, request
from another team, telemetry data, user research, market or competitive research
* **Proposal**: How will the solution/feature help us solve the problem? How will it meet the
target audiences needs? If there are business goals or metrics, how does this improve them?
* **Goals**: What you want to accomplish with this feature. Typical examples include “User Can
*perform some task*
* **Non-Goals**: Things we are explicitly not doing or supporting or that are out of scope,
including reasons why.
* **Low-Fidelity Concept**: Show as much of the experience as needed to explain the idea. This
can be as simple as a napkin drawing but can also be a code prototype, a PowerPoint walkthrough,
or a design comp.
The low-fidelity concept should be kept simple at this stage and refined during the pre-production
process.
Feature pitches are submitted as issues on GitHub. We encourage discussion on open issues, and as
discussion progresses we will edit the issue description to refine the idea.
## Step 2: Pre-production ## Step 2: Pre-production
In the pre-production phase, we experiment with a variety of ways to address the goals described in For most features, the output of this phase is a specification which describes how the feature will work, supported by
the feature pitch. The output of this phase is a specification which demonstrates how the feature design renderings and code prototypes as needed. The original issue will continue to track the overall progress of the
will work, supported by design renderings and code prototypes as needed. Sometimes we'll learn new feature, but we will create and iterate on spec documentation in the
things about a feature proposal during pre-production, and we'll edit or close the original pitch. [Calculator Spec repo](https://github.com/Microsoft/calculator-specs). Sometimes we'll learn new things about a feature
proposal during pre-production, and we'll edit or close the original pitch.
We welcome community participation in the pre-production process. The GitHub issue will be the We welcome community participation throughout pre-production. The best ideas often come from trying many ideas during
primary place to share progress updates. the pre-production phase. To enable rapid
The best ideas often come from trying many ideas during the pre-production phase. To enable rapid
experimentation, we encourage developing and sharing rough ideas&mdash;maybe even with pencil and experimentation, we encourage developing and sharing rough ideas&mdash;maybe even with pencil and
paper&mdash;before making designs pixel-perfect or making code robust and maintainable. paper&mdash;before making designs pixel-perfect or making code robust and maintainable.
### Spec review After the [spec review](https://github.com/Microsoft/calculator-specs#spec-review) is completed, we will move the issue
Once there is a high-fidelity design which addresses the goals described in the original pitch, the into [production](https://github.com/Microsoft/calculator/projects/1) on the feature tracking board. In _some_ cases,
Microsoft product team will review the prototype and ensure all items on this checklist are all of the details of an idea can be captured concisely in original feature pitch. When that happens, we may move ideas
addressed: directly into production.
- [ ] Is there a high-fidelity design which gives reviewers a clear idea of how the feature will
look and function when implemented?
- [ ] Has the plan been shared with the community (documented on the wiki and updates posted in the
original issue) and have others been given an opportunity to provide suggestions?
- [ ] Are [Fluent design principles](https://docs.microsoft.com/en-us/windows/uwp/design/fluent-design-system/)
followed? If we do something which deviates from the guidelines, do we have a good reason?
- [ ] Does the design include provisions for [all users](https://docs.microsoft.com/en-us/windows/uwp/design/accessibility/designing-inclusive-software)
and [all cultures](https://docs.microsoft.com/en-us/windows/uwp/design/globalizing/guidelines-and-checklist-for-globalizing-your-app)?
- [ ] Is it technically feasible to build this feature? Take a look at the "before committing"
checklist below and identify any issues which are likely to be blockers.
## Step 3: Production ## Step 3: Production
A feature can be implemented by the original proposer, a Microsoft team member, or by other A feature can be implemented by the original submitter, a Microsoft team member, or by other
community members. Code contributions and testing help are greatly appreciated. Please let us know community members. Code contributions and testing help are greatly appreciated. Please let everyone know if you're
in the issue comments if you're actively working on a feature so we can ensure it's assigned to actively working on a feature to help avoid duplicated efforts from others.
you.
You might be able to reuse code written during the prototype process, although there will typically You might be able to reuse code written during the prototype process, although there will typically
be more work required to make the solution robust. Once the code is ready, you can begin be more work required to make the solution robust. Once the code is ready, you can begin
@ -122,7 +95,8 @@ new features, the Microsoft team considers at least these items:
- [ ] Run the perf tests to measure any increase in startup time. Move work out of the startup - [ ] Run the perf tests to measure any increase in startup time. Move work out of the startup
path if possible. path if possible.
- [ ] If the change adds additional logging: - [ ] If the change adds additional logging:
- [ ] All logging should use [TraceLogging](https://docs.microsoft.com/en-us/windows/desktop/tracelogging/trace-logging-about). - [ ] All logging should use
[TraceLogging](https://docs.microsoft.com/en-us/windows/desktop/tracelogging/trace-logging-about).
- [ ] Unnecessary log events should be removed, or configured so that they are collected only when - [ ] Unnecessary log events should be removed, or configured so that they are collected only when
needed to debug issues or measure feature usage. needed to debug issues or measure feature usage.
- [ ] If the change reads user data from files or app settings: - [ ] If the change reads user data from files or app settings:

View file

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h" #include <sstream>
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
using namespace std; using namespace std;

View file

@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h"
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
#include "Header Files/CalcUtils.h" #include "Header Files/CalcUtils.h"

View file

@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h"
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
#include "Command.h" #include "Command.h"
#include "CalculatorVector.h" #include "CalculatorVector.h"

View file

@ -1,6 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
#include "pch.h" #include <algorithm>
#include "Header Files/Number.h" #include "Header Files/Number.h"
using namespace std; using namespace std;

View file

@ -1,6 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
#include "pch.h" #include <intsafe.h>
#include "Header Files/Rational.h" #include "Header Files/Rational.h"
using namespace std; using namespace std;
@ -182,6 +182,13 @@ namespace CalcEngine
return *this; return *this;
} }
/// <summary>
/// Calculate the remainder after division, the sign of a result will match the sign of the current object.
/// </summary>
/// <remarks>
/// This function has the same behavior as the standard C/C++ operator '%'
/// to calculate the modulus after division instead, use <see cref="RationalMath::Mod"/> instead.
/// </remarks>
Rational& Rational::operator%=(Rational const& rhs) Rational& Rational::operator%=(Rational const& rhs)
{ {
PRAT lhsRat = this->ToPRAT(); PRAT lhsRat = this->ToPRAT();
@ -189,7 +196,7 @@ namespace CalcEngine
try try
{ {
modrat(&lhsRat, rhsRat); remrat(&lhsRat, rhsRat);
destroyrat(rhsRat); destroyrat(rhsRat);
} }
catch (uint32_t error) catch (uint32_t error)
@ -342,6 +349,12 @@ namespace CalcEngine
return lhs; return lhs;
} }
/// <summary>
/// Calculate the remainder after division, the sign of a result will match the sign of lhs.
/// </summary>
/// <remarks>
/// This function has the same behavior as the standard C/C++ operator '%', to calculate the modulus after division instead, use <see cref="Rational::operator%"/> instead.
/// </remarks>
Rational operator%(Rational lhs, Rational const& rhs) Rational operator%(Rational lhs, Rational const& rhs)
{ {
lhs %= rhs; lhs %= rhs;

View file

@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h"
#include "Header Files/RationalMath.h" #include "Header Files/RationalMath.h"
using namespace std; using namespace std;
@ -387,3 +386,33 @@ Rational RationalMath::ATanh(Rational const& rat)
return result; return result;
} }
/// <summary>
/// Calculate the modulus after division, the sign of the result will match the sign of b.
/// </summary>
/// <remarks>
/// When one of the operand is negative
/// the result will differ from the C/C++ operator '%'
/// use <see cref="Rational::operator%"/> instead to calculate the remainder after division.
/// </remarks>
Rational RationalMath::Mod(Rational const& a, Rational const& b)
{
PRAT prat = a.ToPRAT();
PRAT pn = b.ToPRAT();
try
{
modrat(&prat, pn);
destroyrat(pn);
}
catch (uint32_t error)
{
destroyrat(prat);
destroyrat(pn);
throw(error);
}
auto res = Rational{ prat };
destroyrat(prat);
return res;
}

View file

@ -1,9 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h" #include <cassert>
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
#include "CalculatorResource.h" #include "CalculatorResource.h"
using namespace std; using namespace std;
@ -25,13 +24,18 @@ static constexpr wstring_view DEFAULT_NUMBER_STR = L"0";
// Read strings for keys, errors, trig types, etc. // Read strings for keys, errors, trig types, etc.
// These will be copied from the resources to local memory. // These will be copied from the resources to local memory.
array<wstring, CSTRINGSENGMAX> CCalcEngine::s_engineStrings; unordered_map<wstring, wstring> CCalcEngine::s_engineStrings;
void CCalcEngine::LoadEngineStrings(CalculationManager::IResourceProvider& resourceProvider) void CCalcEngine::LoadEngineStrings(CalculationManager::IResourceProvider& resourceProvider)
{ {
for (size_t i = 0; i < s_engineStrings.size(); i++) for (const auto& sid : g_sids)
{ {
s_engineStrings[i] = resourceProvider.GetCEngineString(g_sids[i]); auto locKey = wstring{ sid };
auto locString = resourceProvider.GetCEngineString(locKey);
if (!locString.empty())
{
s_engineStrings[locKey] = locString;
}
} }
} }
@ -168,7 +172,7 @@ void CCalcEngine::SettingsChanged()
m_HistoryCollector.SetDecimalSymbol(m_decimalSeparator); m_HistoryCollector.SetDecimalSymbol(m_decimalSeparator);
// put the new decimal symbol into the table used to draw the decimal key // put the new decimal symbol into the table used to draw the decimal key
s_engineStrings[IDS_DECIMAL] = m_decimalSeparator; s_engineStrings[SIDS_DECIMAL_SEPARATOR] = m_decimalSeparator;
// we need to redraw to update the decimal point button // we need to redraw to update the decimal point button
numChanged = true; numChanged = true;

View file

@ -12,17 +12,11 @@
* *
* Author: * Author:
\****************************************************************************/ \****************************************************************************/
#include "pch.h"
#include <string>
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
#include "Header Files/CalcUtils.h" #include "Header Files/CalcUtils.h"
#define IDC_RADSIN IDC_UNARYLAST+1
#define IDC_RADCOS IDC_UNARYLAST+2
#define IDC_RADTAN IDC_UNARYLAST+3
#define IDC_GRADSIN IDC_UNARYLAST+4
#define IDC_GRADCOS IDC_UNARYLAST+5
#define IDC_GRADTAN IDC_UNARYLAST+6
using namespace std; using namespace std;
using namespace CalcEngine; using namespace CalcEngine;
@ -397,7 +391,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
cleared for CENTR */ cleared for CENTR */
if (nullptr != m_pCalcDisplay) if (nullptr != m_pCalcDisplay)
{ {
m_pCalcDisplay->SetParenDisplayText(L""); m_pCalcDisplay->SetParenthesisNumber(0);
m_pCalcDisplay->SetExpressionDisplay(make_shared<CalculatorVector<pair<wstring, int>>>(), make_shared<CalculatorVector<shared_ptr<IExpressionCommand>>>()); m_pCalcDisplay->SetExpressionDisplay(make_shared<CalculatorVector<pair<wstring, int>>>(), make_shared<CalculatorVector<shared_ptr<IExpressionCommand>>>());
} }
@ -463,45 +457,12 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
m_HistoryCollector.AddOpndToHistory(m_numberString, m_currentVal); m_HistoryCollector.AddOpndToHistory(m_numberString, m_currentVal);
} }
do { // Evaluate the precedence stack.
ResolveHighestPrecedenceOperation();
if (m_nOpCode) /* Is there a valid operation around? */ while (m_fPrecedence && m_precedenceOpCount > 0)
{ {
/* If this is the first EQU in a string, set m_holdVal=m_currentVal */ m_precedenceOpCount--;
/* Otherwise let m_currentVal=m_holdVal. This keeps m_currentVal constant */ m_nOpCode = m_nPrecOp[m_precedenceOpCount];
/* through all EQUs in a row. */
if (m_bNoPrevEqu)
{
m_holdVal = m_currentVal;
}
else
{
m_currentVal = m_holdVal;
DisplayNum(); // to update the m_numberString
m_HistoryCollector.AddBinOpToHistory(m_nOpCode, false);
m_HistoryCollector.AddOpndToHistory(m_numberString, m_currentVal); // Adding the repeated last op to history
}
// Do the current or last operation.
m_currentVal = DoOperation(m_nOpCode, m_currentVal, m_lastVal);
m_nPrevOpCode = m_nOpCode;
m_lastVal = m_currentVal;
/* Check for errors. If this wasn't done, DisplayNum */
/* would immediately overwrite any error message. */
if (!m_bError)
DisplayNum();
/* No longer the first EQU. */
m_bNoPrevEqu = false;
}
else if (!m_bError)
DisplayNum();
if (m_precedenceOpCount == 0 || !m_fPrecedence)
break;
m_nOpCode = m_nPrecOp[--m_precedenceOpCount];
m_lastVal = m_precedenceVals[m_precedenceOpCount]; m_lastVal = m_precedenceVals[m_precedenceOpCount];
// Precedence Inversion check // Precedence Inversion check
@ -514,7 +475,9 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
m_HistoryCollector.PopLastOpndStart(); m_HistoryCollector.PopLastOpndStart();
m_bNoPrevEqu = true; m_bNoPrevEqu = true;
} while (m_precedenceOpCount >= 0);
ResolveHighestPrecedenceOperation();
}
if (!m_bError) if (!m_bError)
{ {
@ -632,7 +595,7 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
// Set the "(=xx" indicator. // Set the "(=xx" indicator.
if (nullptr != m_pCalcDisplay) if (nullptr != m_pCalcDisplay)
{ {
m_pCalcDisplay->SetParenDisplayText(m_openParenCount ? to_wstring(m_openParenCount) : L""); m_pCalcDisplay->SetParenthesisNumber(m_openParenCount >= 0 ? static_cast<unsigned int>(m_openParenCount) : 0);
} }
if (!m_bError) if (!m_bError)
@ -789,6 +752,48 @@ void CCalcEngine::ProcessCommandWorker(OpCode wParam)
} }
// Helper function to resolve one item on the precedence stack.
void CCalcEngine::ResolveHighestPrecedenceOperation()
{
// Is there a valid operation around?
if (m_nOpCode)
{
// If this is the first EQU in a string, set m_holdVal=m_currentVal
// Otherwise let m_currentVal=m_holdVal. This keeps m_currentVal constant
// through all EQUs in a row.
if (m_bNoPrevEqu)
{
m_holdVal = m_currentVal;
}
else
{
m_currentVal = m_holdVal;
DisplayNum(); // to update the m_numberString
m_HistoryCollector.AddBinOpToHistory(m_nOpCode, false);
m_HistoryCollector.AddOpndToHistory(m_numberString, m_currentVal); // Adding the repeated last op to history
}
// Do the current or last operation.
m_currentVal = DoOperation(m_nOpCode, m_currentVal, m_lastVal);
m_nPrevOpCode = m_nOpCode;
m_lastVal = m_currentVal;
// Check for errors. If this wasn't done, DisplayNum
// would immediately overwrite any error message.
if (!m_bError)
{
DisplayNum();
}
// No longer the first EQU.
m_bNoPrevEqu = false;
}
else if (!m_bError)
{
DisplayNum();
}
}
// CheckAndAddLastBinOpToHistory // CheckAndAddLastBinOpToHistory
// //
// This is a very confusing helper routine to add the last entered binary operator to the history. This is expected to // This is a very confusing helper routine to add the last entered binary operator to the history. This is expected to
@ -857,155 +862,94 @@ void CCalcEngine::DisplayAnnounceBinaryOperator()
// Unary operator Function Name table Element // Unary operator Function Name table Element
// since unary operators button names aren't exactly friendly for history purpose, // since unary operators button names aren't exactly friendly for history purpose,
// we have this separate table to get its localized name and for its Inv function if it exists. // we have this separate table to get its localized name and for its Inv function if it exists.
typedef struct struct FunctionNameElement
{ {
int idsFunc; // index of string for the unary op function. Can be NULL, in which case it same as button name wstring degreeString; // Used by default if there are no rad or grad specific strings.
int idsFuncInv; // index of string for Inv of unary op. Can be NULL, in case it is same as idsFunc wstring inverseDegreeString; // Will fall back to degreeString if empty
bool fDontUseInExpEval; // true if this cant be used in reverse direction as well, ie. during expression evaluation
} UFNE; wstring radString;
wstring inverseRadString; // Will fall back to radString if empty
wstring gradString;
wstring inverseGradString; // Will fall back to gradString if empty
bool hasAngleStrings = ((!radString.empty()) || (!inverseRadString.empty()) || (!gradString.empty()) || (!inverseGradString.empty()));
};
// Table for each unary operator // Table for each unary operator
static const UFNE rgUfne[] = static const std::unordered_map<int, FunctionNameElement> unaryOperatorStringTable =
{ {
/* IDC_CHOP */{ 0, IDS_FRAC, false }, { IDC_CHOP, { L"", SIDS_FRAC} },
/* IDC_ROL */{ 0, 0, true },
/* IDC_ROR */{ 0, 0, true },
/* IDC_COM */{ 0, 0, true }, { IDC_SIN, { SIDS_SIND, SIDS_ASIND, SIDS_SINR, SIDS_ASINR, SIDS_SING, SIDS_ASING } },
/* IDC_SIN */{ IDS_SIND, IDS_ASIND, false }, // default in this table is degrees for sin,cos & tan { IDC_COS, { SIDS_COSD, SIDS_ACOSD, SIDS_COSR, SIDS_ACOSR, SIDS_COSG, SIDS_ACOSG } },
/* IDC_COS */{ IDS_COSD, IDS_ACOSD, false }, { IDC_TAN, { SIDS_TAND, SIDS_ATAND, SIDS_TANR, SIDS_ATANR, SIDS_TANG, SIDS_ATANG } },
/* IDC_TAN */{ IDS_TAND, IDS_ATAND, false },
/* IDC_SINH */{ 0, IDS_ASINH, false }, { IDC_SINH, { L"", SIDS_ASINH } },
/* IDC_COSH */{ 0, IDS_ACOSH, false }, { IDC_COSH, { L"", SIDS_ACOSH } },
/* IDC_TANH */{ 0, IDS_ATANH, false }, { IDC_TANH, { L"", SIDS_ATANH } },
/* IDC_LN */{ 0, IDS_POWE, false }, { IDC_LN , { L"", SIDS_POWE } },
/* IDC_LOG */{ 0, 0, false }, { IDC_SQR, { SIDS_SQR } },
/* IDC_SQRT */{ 0, 0, false }, { IDC_CUB, { SIDS_CUBE } },
/* IDC_SQR */{ IDS_SQR, 0, false }, { IDC_FAC, { SIDS_FACT } },
/* IDC_CUB */{ IDS_CUBE, 0, false }, { IDC_REC, { SIDS_RECIPROC } },
/* IDC_FAC */{ IDS_FACT, 0, false }, { IDC_DMS, { L"", SIDS_DEGREES } },
/* IDC_REC */{ IDS_REC, 0, false }, { IDC_SIGN, { SIDS_NEGATE } },
/* IDC_DMS */{ 0, IDS_DEGREES, false }, { IDC_DEGREES, { SIDS_DEGREES } }
/* IDC_CUBEROOT */{ 0, 0, false },
/* IDC_POW10 */{ 0, 0, false },
/* IDC_PERCENT */{ 0, 0, false },
/* IDC_RADSIN */{ IDS_SINR, IDS_ASINR, false },
/* IDC_RADCOS */{ IDS_COSR, IDS_ACOSR, false },
/* IDC_RADTAN */{ IDS_TANR, IDS_ATANR, false },
/* IDC_GRADCOS */{ IDS_SING, IDS_ASING, false },
/* IDC_GRADCOS */{ IDS_COSG, IDS_ACOSG, false },
/* IDC_GRADTAN */{ IDS_TANG, IDS_ATANG, false },
}; };
wstring_view CCalcEngine::OpCodeToUnaryString(int nOpCode, bool fInv, ANGLE_TYPE angletype) wstring_view CCalcEngine::OpCodeToUnaryString(int nOpCode, bool fInv, ANGLE_TYPE angletype)
{ {
// Special cases for Sign and Degrees
if (IDC_SIGN == nOpCode)
{
return GetString(IDS_NEGATE);
}
if (IDC_DEGREES == nOpCode)
{
return GetString(IDS_DEGREES);
}
// Correct the trigonometric functions with type of angle argument they take
if (ANGLE_RAD == angletype)
{
switch (nOpCode)
{
case IDC_SIN:
nOpCode = IDC_RADSIN;
break;
case IDC_COS:
nOpCode = IDC_RADCOS;
break;
case IDC_TAN:
nOpCode = IDC_RADTAN;
break;
}
}
else if (ANGLE_GRAD == angletype)
{
switch (nOpCode)
{
case IDC_SIN:
nOpCode = IDC_GRADSIN;
break;
case IDC_COS:
nOpCode = IDC_GRADCOS;
break;
case IDC_TAN:
nOpCode = IDC_GRADTAN;
break;
}
}
// Try to lookup the ID in the UFNE table // Try to lookup the ID in the UFNE table
int ids = 0; wstring ids = L"";
int iufne = nOpCode - IDC_UNARYFIRST;
if (iufne >= 0 && (size_t)iufne < size(rgUfne)) if (auto pair = unaryOperatorStringTable.find(nOpCode); pair != unaryOperatorStringTable.end())
{ {
if (fInv) const FunctionNameElement& element = pair->second;
if (!element.hasAngleStrings || ANGLE_DEG == angletype)
{ {
ids = rgUfne[iufne].idsFuncInv; if (fInv)
{
ids = element.inverseDegreeString;
}
if (ids.empty())
{
ids = element.degreeString;
}
} }
if (0 == ids) else if (ANGLE_RAD == angletype)
{ {
ids = rgUfne[iufne].idsFunc; if (fInv)
{
ids = element.inverseRadString;
}
if (ids.empty())
{
ids = element.radString;
}
} }
else if (ANGLE_GRAD == angletype)
{
if (fInv)
{
ids = element.inverseGradString;
}
if (ids.empty())
{
ids = element.gradString;
}
}
}
if (!ids.empty())
{
return GetString(ids);
} }
// If we didn't find an ID in the table, use the op code. // If we didn't find an ID in the table, use the op code.
if (0 == ids) return OpCodeToString(nOpCode);
{
ids = IdStrFromCmdId(nOpCode);
}
return GetString(ids);
}
//
// Sets the Angle Mode for special unary op IDC's which are used to index to the table rgUfne
// and returns the equivalent plain IDC for trigonometric function. If it isn't a trigonometric function
// returns the passed in idc itself.
int CCalcEngine::IdcSetAngleTypeDecMode(int idc)
{
int idcAngleCmd = IDM_DEG;
switch (idc)
{
case IDC_RADSIN:
idcAngleCmd = IDM_RAD;
idc = IDC_SIN;
break;
case IDC_RADCOS:
idcAngleCmd = IDM_RAD;
idc = IDC_COS;
break;
case IDC_RADTAN:
idcAngleCmd = IDM_RAD;
idc = IDC_TAN;
break;
case IDC_GRADSIN:
idcAngleCmd = IDM_GRAD;
idc = IDC_SIN;
break;
case IDC_GRADCOS:
idcAngleCmd = IDM_GRAD;
idc = IDC_COS;
break;
case IDC_GRADTAN:
idcAngleCmd = IDM_GRAD;
idc = IDC_TAN;
break;
}
ProcessCommand(idcAngleCmd);
return idc;
} }
bool CCalcEngine::IsCurrentTooBigForTrig() bool CCalcEngine::IsCurrentTooBigForTrig()

View file

@ -12,7 +12,9 @@
* *
* Author: * Author:
\****************************************************************************/ \****************************************************************************/
#include "pch.h"
#include <sstream>
#include <regex>
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
using namespace std; using namespace std;

View file

@ -16,7 +16,6 @@
/*** ***/ /*** ***/
/*** ***/ /*** ***/
/**************************************************************************/ /**************************************************************************/
#include "pch.h"
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
using namespace std; using namespace std;

View file

@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h"
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
using namespace CalcEngine; using namespace CalcEngine;
@ -78,7 +77,7 @@ CalcEngine::Rational CCalcEngine::DoOperation(int operation, CalcEngine::Rationa
case IDC_DIV: case IDC_DIV:
case IDC_MOD: case IDC_MOD:
{ {
int iNumeratorSign = 1, iDenominatorSign = 1, iFinalSign = 1; int iNumeratorSign = 1, iDenominatorSign = 1;
auto temp = result; auto temp = result;
result = rhs; result = rhs;
@ -107,20 +106,30 @@ CalcEngine::Rational CCalcEngine::DoOperation(int operation, CalcEngine::Rationa
if (operation == IDC_DIV) if (operation == IDC_DIV)
{ {
iFinalSign = iNumeratorSign * iDenominatorSign;
result /= temp; result /= temp;
if (m_fIntegerMode && (iNumeratorSign * iDenominatorSign) == -1)
{
result = -(Integer(result));
}
} }
else else
{ {
iFinalSign = iNumeratorSign; if (m_fIntegerMode)
result %= temp; {
} // Programmer mode, use remrat (remainder after division)
result %= temp;
if (m_fIntegerMode && iFinalSign == -1) if (iNumeratorSign == -1)
{ {
result = -(Integer(result)); result = -(Integer(result));
}
}
else
{
//other modes, use modrat (modulus after division)
result = Mod(result, temp);
}
} }
break; break;
} }

View file

@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h"
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
using namespace CalcEngine; using namespace CalcEngine;

View file

@ -157,6 +157,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -173,6 +174,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -189,6 +191,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -205,6 +208,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -222,6 +226,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -238,6 +243,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -254,6 +260,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -270,6 +277,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -278,7 +286,6 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="CalcException.h" />
<ClInclude Include="CalculatorHistory.h" /> <ClInclude Include="CalculatorHistory.h" />
<ClInclude Include="CalculatorManager.h" /> <ClInclude Include="CalculatorManager.h" />
<ClInclude Include="CalculatorResource.h" /> <ClInclude Include="CalculatorResource.h" />

View file

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h" #include <cassert>
#include "CalculatorHistory.h" #include "CalculatorHistory.h"
using namespace std; using namespace std;

View file

@ -38,7 +38,7 @@ namespace CalculationManager
void ClearHistory(); void ClearHistory();
unsigned int AddItem(_In_ std::shared_ptr<HISTORYITEM> const &spHistoryItem); unsigned int AddItem(_In_ std::shared_ptr<HISTORYITEM> const &spHistoryItem);
bool RemoveItem(unsigned int uIdx); bool RemoveItem(unsigned int uIdx);
const size_t MaxHistorySize() const { return m_maxHistorySize; } size_t MaxHistorySize() const { return m_maxHistorySize; }
~CalculatorHistory(void); ~CalculatorHistory(void);
private: private:

View file

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h" #include <climits> // for UCHAR_MAX
#include "Header Files/CalcEngine.h" #include "Header Files/CalcEngine.h"
#include "CalculatorManager.h" #include "CalculatorManager.h"
#include "CalculatorResource.h" #include "CalculatorResource.h"
@ -111,9 +111,9 @@ namespace CalculationManager
/// Callback from the engine /// Callback from the engine
/// </summary> /// </summary>
/// <param name="parenthesisCount">string containing the parenthesis count</param> /// <param name="parenthesisCount">string containing the parenthesis count</param>
void CalculatorManager::SetParenDisplayText(const wstring& parenthesisCount) void CalculatorManager::SetParenthesisNumber(_In_ unsigned int parenthesisCount)
{ {
m_displayCallback->SetParenDisplayText(parenthesisCount); m_displayCallback->SetParenthesisNumber(parenthesisCount);
} }
/// <summary> /// <summary>

View file

@ -94,7 +94,7 @@ namespace CalculationManager
void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands) override; void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands) override;
void SetMemorizedNumbers(_In_ const std::vector<std::wstring>& memorizedNumbers) override; void SetMemorizedNumbers(_In_ const std::vector<std::wstring>& memorizedNumbers) override;
void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override; void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override;
void SetParenDisplayText(const std::wstring& parenthesisCount) override; void SetParenthesisNumber(_In_ unsigned int parenthesisCount) override;
void OnNoRightParenAdded() override; void OnNoRightParenAdded() override;
void DisplayPasteError(); void DisplayPasteError();
void MaxDigitsReached() override; void MaxDigitsReached() override;

View file

@ -1,9 +1,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#pragma once #pragma once
#include <string>
#include <vector>
#include <winerror.h>
#include "Ratpack/CalcErr.h" #include "Ratpack/CalcErr.h"
#include <stdexcept> // for std::out_of_range
#include <sal.h> // for SAL
template <typename TType> template <typename TType>
class CalculatorVector class CalculatorVector

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#pragma once #pragma once

View file

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h" #include <string>
#include "Header Files/CCommand.h" #include "Header Files/CCommand.h"
#include "CalculatorVector.h" #include "CalculatorVector.h"
#include "ExpressionCommand.h" #include "ExpressionCommand.h"

View file

@ -1,7 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#pragma once #pragma once
#include <memory> // for std::shared_ptr
#include "CalculatorVector.h" #include "CalculatorVector.h"
#include "Command.h" #include "Command.h"

View file

@ -13,6 +13,8 @@
* *
\****************************************************************************/ \****************************************************************************/
#pragma once
// The following are the valid id's which can be passed to CCalcEngine::ProcessCommand // The following are the valid id's which can be passed to CCalcEngine::ProcessCommand
#define IDM_HEX 313 #define IDM_HEX 313

View file

@ -45,7 +45,7 @@ namespace CalculationManager
class IResourceProvider; class IResourceProvider;
} }
namespace CalculatorUnitTests namespace CalculatorEngineTests
{ {
class CalcEngineTests; class CalcEngineTests;
} }
@ -72,7 +72,8 @@ public:
// Static methods for the instance // Static methods for the instance
static void InitialOneTimeOnlySetup(CalculationManager::IResourceProvider& resourceProvider); // Once per load time to call to initialize all shared global variables static void InitialOneTimeOnlySetup(CalculationManager::IResourceProvider& resourceProvider); // Once per load time to call to initialize all shared global variables
// returns the ptr to string representing the operator. Mostly same as the button, but few special cases for x^y etc. // returns the ptr to string representing the operator. Mostly same as the button, but few special cases for x^y etc.
static std::wstring_view GetString(int ids) { return s_engineStrings[ids]; } static std::wstring_view GetString(int ids) { return s_engineStrings[std::to_wstring(ids)]; }
static std::wstring_view GetString(std::wstring ids) { return s_engineStrings[ids]; }
static std::wstring_view OpCodeToString(int nOpCode) { return GetString(IdStrFromCmdId(nOpCode)); } static std::wstring_view OpCodeToString(int nOpCode) { return GetString(IdStrFromCmdId(nOpCode)); }
static std::wstring_view OpCodeToUnaryString(int nOpCode, bool fInv, ANGLE_TYPE angletype); static std::wstring_view OpCodeToUnaryString(int nOpCode, bool fInv, ANGLE_TYPE angletype);
@ -123,12 +124,13 @@ private:
std::array<CalcEngine::Rational, NUM_WIDTH_LENGTH> m_chopNumbers; // word size enforcement std::array<CalcEngine::Rational, NUM_WIDTH_LENGTH> m_chopNumbers; // word size enforcement
std::array<std::wstring, NUM_WIDTH_LENGTH> m_maxDecimalValueStrings; // maximum values represented by a given word width based off m_chopNumbers std::array<std::wstring, NUM_WIDTH_LENGTH> m_maxDecimalValueStrings; // maximum values represented by a given word width based off m_chopNumbers
static std::array<std::wstring, CSTRINGSENGMAX> s_engineStrings; // the string table shared across all instances static std::unordered_map<std::wstring, std::wstring> s_engineStrings; // the string table shared across all instances
wchar_t m_decimalSeparator; wchar_t m_decimalSeparator;
wchar_t m_groupSeparator; wchar_t m_groupSeparator;
private: private:
void ProcessCommandWorker(OpCode wParam); void ProcessCommandWorker(OpCode wParam);
void ResolveHighestPrecedenceOperation();
void HandleErrorCommand(OpCode idc); void HandleErrorCommand(OpCode idc);
void HandleMaxDigitsReached(); void HandleMaxDigitsReached();
void DisplayNum(void); void DisplayNum(void);
@ -145,12 +147,11 @@ private:
bool TryToggleBit(CalcEngine::Rational& rat, uint32_t wbitno); bool TryToggleBit(CalcEngine::Rational& rat, uint32_t wbitno);
void CheckAndAddLastBinOpToHistory(bool addToHistory = true); void CheckAndAddLastBinOpToHistory(bool addToHistory = true);
int IdcSetAngleTypeDecMode(int idc);
void InitChopNumbers(); void InitChopNumbers();
static void LoadEngineStrings(CalculationManager::IResourceProvider& resourceProvider); static void LoadEngineStrings(CalculationManager::IResourceProvider& resourceProvider);
static int IdStrFromCmdId(int id) { return id - IDC_FIRSTCONTROL + IDS_FIRSTENGSTR; } static int IdStrFromCmdId(int id) { return id - IDC_FIRSTCONTROL + IDS_ENGINESTR_FIRST; }
static std::vector<uint32_t> DigitGroupingStringToGroupingVector(std::wstring_view groupingString); static std::vector<uint32_t> DigitGroupingStringToGroupingVector(std::wstring_view groupingString);
std::wstring GroupDigits(std::wstring_view delimiter, std::vector<uint32_t> const& grouping, std::wstring_view displayString, bool isNumNegative = false); std::wstring GroupDigits(std::wstring_view delimiter, std::vector<uint32_t> const& grouping, std::wstring_view displayString, bool isNumNegative = false);
@ -159,5 +160,5 @@ private:
static void ChangeBaseConstants(uint32_t radix, int maxIntDigits, int32_t precision); static void ChangeBaseConstants(uint32_t radix, int maxIntDigits, int32_t precision);
void BaseOrPrecisionChanged(); void BaseOrPrecisionChanged();
friend class CalculatorUnitTests::CalcEngineTests; friend class CalculatorEngineTests::CalcEngineTests;
}; };

View file

@ -13,327 +13,284 @@
* Created: 13-Feb-2008 * Created: 13-Feb-2008
* *
\****************************************************************************/ \****************************************************************************/
#define IDS_FIRSTENGSTR IDS_ENGINESTR_FIRST
#define IDS_DECIMAL 4 #pragma once
// All unary op function names for easy history reading #include <string>
// This is where the first string after all the commands in order have been placed, should be placed
// keeping in consecutive helps us to allocate 1 string table and index them
#define IDS_FNSZFIRST (IDC_F -IDC_FIRSTCONTROL)+1
#define IDS_FRAC IDS_FNSZFIRST inline constexpr auto IDS_ERRORS_FIRST = 99;
#define IDS_SIND IDS_FNSZFIRST+1
#define IDS_COSD IDS_FNSZFIRST+2
#define IDS_TAND IDS_FNSZFIRST+3
#define IDS_ASIND IDS_FNSZFIRST+4
#define IDS_ACOSD IDS_FNSZFIRST+5
#define IDS_ATAND IDS_FNSZFIRST+6
#define IDS_SINR IDS_FNSZFIRST+7
#define IDS_COSR IDS_FNSZFIRST+8
#define IDS_TANR IDS_FNSZFIRST+9
#define IDS_ASINR IDS_FNSZFIRST+10
#define IDS_ACOSR IDS_FNSZFIRST+11
#define IDS_ATANR IDS_FNSZFIRST+12
#define IDS_SING IDS_FNSZFIRST+13
#define IDS_COSG IDS_FNSZFIRST+14
#define IDS_TANG IDS_FNSZFIRST+15
#define IDS_ASING IDS_FNSZFIRST+16
#define IDS_ACOSG IDS_FNSZFIRST+17
#define IDS_ATANG IDS_FNSZFIRST+18
#define IDS_ASINH IDS_FNSZFIRST+19
#define IDS_ACOSH IDS_FNSZFIRST+20
#define IDS_ATANH IDS_FNSZFIRST+21
#define IDS_POWE IDS_FNSZFIRST+22
#define IDS_POW10 IDS_FNSZFIRST+23
#define IDS_SQRT IDS_FNSZFIRST+24
#define IDS_SQR IDS_FNSZFIRST+25
#define IDS_CUBE IDS_FNSZFIRST+26
#define IDS_CUBERT IDS_FNSZFIRST+27
#define IDS_FACT IDS_FNSZFIRST+28
#define IDS_REC IDS_FNSZFIRST+29
#define IDS_DEGREES IDS_FNSZFIRST+30
#define IDS_NEGATE IDS_FNSZFIRST+31
#define IDS_RSH IDS_FNSZFIRST+32
#define IDS_FNSZLAST IDS_RSH
#define IDS_ERRORS_FIRST IDS_FNSZLAST+1
// This is the list of error strings corresponding to SCERR_DIVIDEZERO.. // This is the list of error strings corresponding to SCERR_DIVIDEZERO..
#define IDS_DIVBYZERO IDS_ERRORS_FIRST inline constexpr auto IDS_DIVBYZERO = IDS_ERRORS_FIRST;
#define IDS_DOMAIN IDS_ERRORS_FIRST+1 inline constexpr auto IDS_DOMAIN = IDS_ERRORS_FIRST + 1;
#define IDS_UNDEFINED IDS_ERRORS_FIRST+2 inline constexpr auto IDS_UNDEFINED = IDS_ERRORS_FIRST + 2;
#define IDS_POS_INFINITY IDS_ERRORS_FIRST+3 inline constexpr auto IDS_POS_INFINITY = IDS_ERRORS_FIRST + 3;
#define IDS_NEG_INFINITY IDS_ERRORS_FIRST+4 inline constexpr auto IDS_NEG_INFINITY = IDS_ERRORS_FIRST + 4;
#define IDS_NOMEM IDS_ERRORS_FIRST+6 inline constexpr auto IDS_NOMEM = IDS_ERRORS_FIRST + 6;
#define IDS_TOOMANY IDS_ERRORS_FIRST+7 inline constexpr auto IDS_TOOMANY = IDS_ERRORS_FIRST + 7;
#define IDS_OVERFLOW IDS_ERRORS_FIRST+8 inline constexpr auto IDS_OVERFLOW = IDS_ERRORS_FIRST + 8;
#define IDS_NORESULT IDS_ERRORS_FIRST+9 inline constexpr auto IDS_NORESULT = IDS_ERRORS_FIRST + 9;
#define IDS_INSUFFICIENT_DATA IDS_ERRORS_FIRST+10 inline constexpr auto IDS_INSUFFICIENT_DATA = IDS_ERRORS_FIRST + 10;
#define CSTRINGSENGMAX IDS_INSUFFICIENT_DATA+1 inline constexpr auto CSTRINGSENGMAX = IDS_INSUFFICIENT_DATA + 1;
// Arithmetic expression evaluator error strings // Arithmetic expression evaluator error strings
#define IDS_ERR_UNK_CH CSTRINGSENGMAX+1 inline constexpr auto IDS_ERR_UNK_CH = CSTRINGSENGMAX + 1;
#define IDS_ERR_UNK_FN CSTRINGSENGMAX+2 inline constexpr auto IDS_ERR_UNK_FN = CSTRINGSENGMAX + 2;
#define IDS_ERR_UNEX_NUM CSTRINGSENGMAX+3 inline constexpr auto IDS_ERR_UNEX_NUM = CSTRINGSENGMAX + 3;
#define IDS_ERR_UNEX_CH CSTRINGSENGMAX+4 inline constexpr auto IDS_ERR_UNEX_CH = CSTRINGSENGMAX + 4;
#define IDS_ERR_UNEX_SZ CSTRINGSENGMAX+5 inline constexpr auto IDS_ERR_UNEX_SZ = CSTRINGSENGMAX + 5;
#define IDS_ERR_MISMATCH_CLOSE CSTRINGSENGMAX+6 inline constexpr auto IDS_ERR_MISMATCH_CLOSE = CSTRINGSENGMAX + 6;
#define IDS_ERR_UNEX_END CSTRINGSENGMAX+7 inline constexpr auto IDS_ERR_UNEX_END = CSTRINGSENGMAX + 7;
#define IDS_ERR_SG_INV_ERROR CSTRINGSENGMAX+8 inline constexpr auto IDS_ERR_SG_INV_ERROR = CSTRINGSENGMAX + 8;
#define IDS_ERR_INPUT_OVERFLOW CSTRINGSENGMAX+9 inline constexpr auto IDS_ERR_INPUT_OVERFLOW = CSTRINGSENGMAX + 9;
#define IDS_ERR_OUTPUT_OVERFLOW CSTRINGSENGMAX+10 inline constexpr auto IDS_ERR_OUTPUT_OVERFLOW = CSTRINGSENGMAX + 10;
// Resource keys for CEngineStrings.resw
#define SIDS_PLUS_MINUS L"0" inline constexpr auto SIDS_PLUS_MINUS = L"0";
#define SIDS_CLEAR L"1" inline constexpr auto SIDS_CLEAR = L"1";
#define SIDS_CE L"2" inline constexpr auto SIDS_CE = L"2";
#define SIDS_BACKSPACE L"3" inline constexpr auto SIDS_BACKSPACE = L"3";
#define SIDS_DECIMAL_SEPARATOR L"4" inline constexpr auto SIDS_DECIMAL_SEPARATOR = L"4";
#define SIDS_EMPTY_STRING L"5" inline constexpr auto SIDS_EMPTY_STRING = L"5";
#define SIDS_AND L"6" inline constexpr auto SIDS_AND = L"6";
#define SIDS_OR L"7" inline constexpr auto SIDS_OR = L"7";
#define SIDS_XOR L"8" inline constexpr auto SIDS_XOR = L"8";
#define SIDS_LSH L"9" inline constexpr auto SIDS_LSH = L"9";
#define SIDS_RSH L"10" inline constexpr auto SIDS_RSH = L"10";
#define SIDS_DIVIDE L"11" inline constexpr auto SIDS_DIVIDE = L"11";
#define SIDS_MULTIPLY L"12" inline constexpr auto SIDS_MULTIPLY = L"12";
#define SIDS_PLUS L"13" inline constexpr auto SIDS_PLUS = L"13";
#define SIDS_MINUS L"14" inline constexpr auto SIDS_MINUS = L"14";
#define SIDS_MOD L"15" inline constexpr auto SIDS_MOD = L"15";
#define SIDS_YROOT L"16" inline constexpr auto SIDS_YROOT = L"16";
#define SIDS_POW_HAT L"17" inline constexpr auto SIDS_POW_HAT = L"17";
#define SIDS_INT L"18" inline constexpr auto SIDS_INT = L"18";
#define SIDS_ROL L"19" inline constexpr auto SIDS_ROL = L"19";
#define SIDS_ROR L"20" inline constexpr auto SIDS_ROR = L"20";
#define SIDS_NOT L"21" inline constexpr auto SIDS_NOT = L"21";
#define SIDS_SIN L"22" inline constexpr auto SIDS_SIN = L"22";
#define SIDS_COS L"23" inline constexpr auto SIDS_COS = L"23";
#define SIDS_TAN L"24" inline constexpr auto SIDS_TAN = L"24";
#define SIDS_SINH L"25" inline constexpr auto SIDS_SINH = L"25";
#define SIDS_COSH L"26" inline constexpr auto SIDS_COSH = L"26";
#define SIDS_TANH L"27" inline constexpr auto SIDS_TANH = L"27";
#define SIDS_LN L"28" inline constexpr auto SIDS_LN = L"28";
#define SIDS_LOG L"29" inline constexpr auto SIDS_LOG = L"29";
#define SIDS_SQRT L"30" inline constexpr auto SIDS_SQRT = L"30";
#define SIDS_XPOW2 L"31" inline constexpr auto SIDS_XPOW2 = L"31";
#define SIDS_XPOW3 L"32" inline constexpr auto SIDS_XPOW3 = L"32";
#define SIDS_NFACTORIAL L"33" inline constexpr auto SIDS_NFACTORIAL = L"33";
#define SIDS_RECIPROCAL L"34" inline constexpr auto SIDS_RECIPROCAL = L"34";
#define SIDS_DMS L"35" inline constexpr auto SIDS_DMS = L"35";
#define SIDS_CUBEROOT L"36" inline constexpr auto SIDS_CUBEROOT = L"36";
#define SIDS_POWTEN L"37" inline constexpr auto SIDS_POWTEN = L"37";
#define SIDS_PERCENT L"38" inline constexpr auto SIDS_PERCENT = L"38";
#define SIDS_SCIENTIFIC_NOTATION L"39" inline constexpr auto SIDS_SCIENTIFIC_NOTATION = L"39";
#define SIDS_PI L"40" inline constexpr auto SIDS_PI = L"40";
#define SIDS_EQUAL L"41" inline constexpr auto SIDS_EQUAL = L"41";
#define SIDS_MC L"42" inline constexpr auto SIDS_MC = L"42";
#define SIDS_MR L"43" inline constexpr auto SIDS_MR = L"43";
#define SIDS_MS L"44" inline constexpr auto SIDS_MS = L"44";
#define SIDS_MPLUS L"45" inline constexpr auto SIDS_MPLUS = L"45";
#define SIDS_MMINUS L"46" inline constexpr auto SIDS_MMINUS = L"46";
#define SIDS_EXP L"47" inline constexpr auto SIDS_EXP = L"47";
#define SIDS_OPEN_PAREN L"48" inline constexpr auto SIDS_OPEN_PAREN = L"48";
#define SIDS_CLOSE_PAREN L"49" inline constexpr auto SIDS_CLOSE_PAREN = L"49";
#define SIDS_0 L"50" inline constexpr auto SIDS_0 = L"50";
#define SIDS_1 L"51" inline constexpr auto SIDS_1 = L"51";
#define SIDS_2 L"52" inline constexpr auto SIDS_2 = L"52";
#define SIDS_3 L"53" inline constexpr auto SIDS_3 = L"53";
#define SIDS_4 L"54" inline constexpr auto SIDS_4 = L"54";
#define SIDS_5 L"55" inline constexpr auto SIDS_5 = L"55";
#define SIDS_6 L"56" inline constexpr auto SIDS_6 = L"56";
#define SIDS_7 L"57" inline constexpr auto SIDS_7 = L"57";
#define SIDS_8 L"58" inline constexpr auto SIDS_8 = L"58";
#define SIDS_9 L"59" inline constexpr auto SIDS_9 = L"59";
#define SIDS_A L"60" inline constexpr auto SIDS_A = L"60";
#define SIDS_B L"61" inline constexpr auto SIDS_B = L"61";
#define SIDS_C L"62" inline constexpr auto SIDS_C = L"62";
#define SIDS_D L"63" inline constexpr auto SIDS_D = L"63";
#define SIDS_E L"64" inline constexpr auto SIDS_E = L"64";
#define SIDS_F L"65" inline constexpr auto SIDS_F = L"65";
#define SIDS_FRAC L"66" inline constexpr auto SIDS_FRAC = L"66";
#define SIDS_SIND L"67" inline constexpr auto SIDS_SIND = L"67";
#define SIDS_COSD L"68" inline constexpr auto SIDS_COSD = L"68";
#define SIDS_TAND L"69" inline constexpr auto SIDS_TAND = L"69";
#define SIDS_ASIND L"70" inline constexpr auto SIDS_ASIND = L"70";
#define SIDS_ACOSD L"71" inline constexpr auto SIDS_ACOSD = L"71";
#define SIDS_ATAND L"72" inline constexpr auto SIDS_ATAND = L"72";
#define SIDS_SINR L"73" inline constexpr auto SIDS_SINR = L"73";
#define SIDS_COSR L"74" inline constexpr auto SIDS_COSR = L"74";
#define SIDS_TANR L"75" inline constexpr auto SIDS_TANR = L"75";
#define SIDS_ASINR L"76" inline constexpr auto SIDS_ASINR = L"76";
#define SIDS_ACOSR L"77" inline constexpr auto SIDS_ACOSR = L"77";
#define SIDS_ATANR L"78" inline constexpr auto SIDS_ATANR = L"78";
#define SIDS_SING L"79" inline constexpr auto SIDS_SING = L"79";
#define SIDS_COSG L"80" inline constexpr auto SIDS_COSG = L"80";
#define SIDS_TANG L"81" inline constexpr auto SIDS_TANG = L"81";
#define SIDS_ASING L"82" inline constexpr auto SIDS_ASING = L"82";
#define SIDS_ACOSG L"83" inline constexpr auto SIDS_ACOSG = L"83";
#define SIDS_ATANG L"84" inline constexpr auto SIDS_ATANG = L"84";
#define SIDS_ASINH L"85" inline constexpr auto SIDS_ASINH = L"85";
#define SIDS_ACOSH L"86" inline constexpr auto SIDS_ACOSH = L"86";
#define SIDS_ATANH L"87" inline constexpr auto SIDS_ATANH = L"87";
#define SIDS_POWE L"88" inline constexpr auto SIDS_POWE = L"88";
#define SIDS_POWTEN2 L"89" inline constexpr auto SIDS_POWTEN2 = L"89";
#define SIDS_SQRT2 L"90" inline constexpr auto SIDS_SQRT2 = L"90";
#define SIDS_SQR L"91" inline constexpr auto SIDS_SQR = L"91";
#define SIDS_CUBE L"92" inline constexpr auto SIDS_CUBE = L"92";
#define SIDS_CUBERT L"93" inline constexpr auto SIDS_CUBERT = L"93";
#define SIDS_FACT L"94" inline constexpr auto SIDS_FACT = L"94";
#define SIDS_RECIPROC L"95" inline constexpr auto SIDS_RECIPROC = L"95";
#define SIDS_DEGREES L"96" inline constexpr auto SIDS_DEGREES = L"96";
#define SIDS_NEGATE L"97" inline constexpr auto SIDS_NEGATE = L"97";
#define SIDS_RSH2 L"98" inline constexpr auto SIDS_RSH2 = L"98";
#define SIDS_DIVIDEBYZERO L"99" inline constexpr auto SIDS_DIVIDEBYZERO = L"99";
#define SIDS_DOMAIN L"100" inline constexpr auto SIDS_DOMAIN = L"100";
#define SIDS_UNDEFINED L"101" inline constexpr auto SIDS_UNDEFINED = L"101";
#define SIDS_POS_INFINITY L"102" inline constexpr auto SIDS_POS_INFINITY = L"102";
#define SIDS_NEG_INFINITY L"103" inline constexpr auto SIDS_NEG_INFINITY = L"103";
#define SIDS_ABORTED L"104" inline constexpr auto SIDS_ABORTED = L"104";
#define SIDS_NOMEM L"105" inline constexpr auto SIDS_NOMEM = L"105";
#define SIDS_TOOMANY L"106" inline constexpr auto SIDS_TOOMANY = L"106";
#define SIDS_OVERFLOW L"107" inline constexpr auto SIDS_OVERFLOW = L"107";
#define SIDS_NORESULT L"108" inline constexpr auto SIDS_NORESULT = L"108";
#define SIDS_INSUFFICIENT_DATA L"109" inline constexpr auto SIDS_INSUFFICIENT_DATA = L"109";
// 110 is skipped by CSTRINGSENGMAX // 110 is skipped by CSTRINGSENGMAX
#define SIDS_ERR_UNK_CH L"111" inline constexpr auto SIDS_ERR_UNK_CH = L"111";
#define SIDS_ERR_UNK_FN L"112" inline constexpr auto SIDS_ERR_UNK_FN = L"112";
#define SIDS_ERR_UNEX_NUM L"113" inline constexpr auto SIDS_ERR_UNEX_NUM = L"113";
#define SIDS_ERR_UNEX_CH L"114" inline constexpr auto SIDS_ERR_UNEX_CH = L"114";
#define SIDS_ERR_UNEX_SZ L"115" inline constexpr auto SIDS_ERR_UNEX_SZ = L"115";
#define SIDS_ERR_MISMATCH_CLOSE L"116" inline constexpr auto SIDS_ERR_MISMATCH_CLOSE = L"116";
#define SIDS_ERR_UNEX_END L"117" inline constexpr auto SIDS_ERR_UNEX_END = L"117";
#define SIDS_ERR_SG_INV_ERROR L"118" inline constexpr auto SIDS_ERR_SG_INV_ERROR = L"118";
#define SIDS_ERR_INPUT_OVERFLOW L"119" inline constexpr auto SIDS_ERR_INPUT_OVERFLOW = L"119";
#define SIDS_ERR_OUTPUT_OVERFLOW L"120" inline constexpr auto SIDS_ERR_OUTPUT_OVERFLOW = L"120";
__declspec(selectany) std::wstring g_sids[] = // Include the resource key ID from above into this vector to load it into memory for the engine to use
inline constexpr std::array<std::wstring_view, 120> g_sids =
{ {
std::wstring(SIDS_PLUS_MINUS), SIDS_PLUS_MINUS,
std::wstring(SIDS_C), SIDS_C,
std::wstring(SIDS_CE), SIDS_CE,
std::wstring(SIDS_BACKSPACE), SIDS_BACKSPACE,
std::wstring(SIDS_DECIMAL_SEPARATOR), SIDS_DECIMAL_SEPARATOR,
std::wstring(SIDS_EMPTY_STRING), SIDS_EMPTY_STRING,
std::wstring(SIDS_AND), SIDS_AND,
std::wstring(SIDS_OR), SIDS_OR,
std::wstring(SIDS_XOR), SIDS_XOR,
std::wstring(SIDS_LSH), SIDS_LSH,
std::wstring(SIDS_RSH), SIDS_RSH,
std::wstring(SIDS_DIVIDE), SIDS_DIVIDE,
std::wstring(SIDS_MULTIPLY), SIDS_MULTIPLY,
std::wstring(SIDS_PLUS), SIDS_PLUS,
std::wstring(SIDS_MINUS), SIDS_MINUS,
std::wstring(SIDS_MOD), SIDS_MOD,
std::wstring(SIDS_YROOT), SIDS_YROOT,
std::wstring(SIDS_POW_HAT), SIDS_POW_HAT,
std::wstring(SIDS_INT), SIDS_INT,
std::wstring(SIDS_ROL), SIDS_ROL,
std::wstring(SIDS_ROR), SIDS_ROR,
std::wstring(SIDS_NOT), SIDS_NOT,
std::wstring(SIDS_SIN), SIDS_SIN,
std::wstring(SIDS_COS), SIDS_COS,
std::wstring(SIDS_TAN), SIDS_TAN,
std::wstring(SIDS_SINH), SIDS_SINH,
std::wstring(SIDS_COSH), SIDS_COSH,
std::wstring(SIDS_TANH), SIDS_TANH,
std::wstring(SIDS_LN), SIDS_LN,
std::wstring(SIDS_LOG), SIDS_LOG,
std::wstring(SIDS_SQRT), SIDS_SQRT,
std::wstring(SIDS_XPOW2), SIDS_XPOW2,
std::wstring(SIDS_XPOW3), SIDS_XPOW3,
std::wstring(SIDS_NFACTORIAL), SIDS_NFACTORIAL,
std::wstring(SIDS_RECIPROCAL), SIDS_RECIPROCAL,
std::wstring(SIDS_DMS), SIDS_DMS,
std::wstring(SIDS_CUBEROOT), SIDS_CUBEROOT,
std::wstring(SIDS_POWTEN), SIDS_POWTEN,
std::wstring(SIDS_PERCENT), SIDS_PERCENT,
std::wstring(SIDS_SCIENTIFIC_NOTATION), SIDS_SCIENTIFIC_NOTATION,
std::wstring(SIDS_PI), SIDS_PI,
std::wstring(SIDS_EQUAL), SIDS_EQUAL,
std::wstring(SIDS_MC), SIDS_MC,
std::wstring(SIDS_MR), SIDS_MR,
std::wstring(SIDS_MS), SIDS_MS,
std::wstring(SIDS_MPLUS), SIDS_MPLUS,
std::wstring(SIDS_MMINUS), SIDS_MMINUS,
std::wstring(SIDS_EXP), SIDS_EXP,
std::wstring(SIDS_OPEN_PAREN), SIDS_OPEN_PAREN,
std::wstring(SIDS_CLOSE_PAREN), SIDS_CLOSE_PAREN,
std::wstring(SIDS_0), SIDS_0,
std::wstring(SIDS_1), SIDS_1,
std::wstring(SIDS_2), SIDS_2,
std::wstring(SIDS_3), SIDS_3,
std::wstring(SIDS_4), SIDS_4,
std::wstring(SIDS_5), SIDS_5,
std::wstring(SIDS_6), SIDS_6,
std::wstring(SIDS_7), SIDS_7,
std::wstring(SIDS_8), SIDS_8,
std::wstring(SIDS_9), SIDS_9,
std::wstring(SIDS_A), SIDS_A,
std::wstring(SIDS_B), SIDS_B,
std::wstring(SIDS_C), SIDS_C,
std::wstring(SIDS_D), SIDS_D,
std::wstring(SIDS_E), SIDS_E,
std::wstring(SIDS_F), SIDS_F,
std::wstring(SIDS_FRAC), SIDS_FRAC,
std::wstring(SIDS_SIND), SIDS_SIND,
std::wstring(SIDS_COSD), SIDS_COSD,
std::wstring(SIDS_TAND), SIDS_TAND,
std::wstring(SIDS_ASIND), SIDS_ASIND,
std::wstring(SIDS_ACOSD), SIDS_ACOSD,
std::wstring(SIDS_ATAND), SIDS_ATAND,
std::wstring(SIDS_SINR), SIDS_SINR,
std::wstring(SIDS_COSR), SIDS_COSR,
std::wstring(SIDS_TANR), SIDS_TANR,
std::wstring(SIDS_ASINR), SIDS_ASINR,
std::wstring(SIDS_ACOSR), SIDS_ACOSR,
std::wstring(SIDS_ATANR), SIDS_ATANR,
std::wstring(SIDS_SING), SIDS_SING,
std::wstring(SIDS_COSG), SIDS_COSG,
std::wstring(SIDS_TANG), SIDS_TANG,
std::wstring(SIDS_ASING), SIDS_ASING,
std::wstring(SIDS_ACOSG), SIDS_ACOSG,
std::wstring(SIDS_ATANG), SIDS_ATANG,
std::wstring(SIDS_ASINH), SIDS_ASINH,
std::wstring(SIDS_ACOSH), SIDS_ACOSH,
std::wstring(SIDS_ATANH), SIDS_ATANH,
std::wstring(SIDS_POWE), SIDS_POWE,
std::wstring(SIDS_POWTEN2), SIDS_POWTEN2,
std::wstring(SIDS_SQRT2), SIDS_SQRT2,
std::wstring(SIDS_SQR), SIDS_SQR,
std::wstring(SIDS_CUBE), SIDS_CUBE,
std::wstring(SIDS_CUBERT), SIDS_CUBERT,
std::wstring(SIDS_FACT), SIDS_FACT,
std::wstring(SIDS_RECIPROC), SIDS_RECIPROC,
std::wstring(SIDS_DEGREES), SIDS_DEGREES,
std::wstring(SIDS_NEGATE), SIDS_NEGATE,
std::wstring(SIDS_RSH), SIDS_RSH,
std::wstring(SIDS_DIVIDEBYZERO), SIDS_DIVIDEBYZERO,
std::wstring(SIDS_DOMAIN), SIDS_DOMAIN,
std::wstring(SIDS_UNDEFINED), SIDS_UNDEFINED,
std::wstring(SIDS_POS_INFINITY), SIDS_POS_INFINITY,
std::wstring(SIDS_NEG_INFINITY), SIDS_NEG_INFINITY,
std::wstring(SIDS_ABORTED), SIDS_ABORTED,
std::wstring(SIDS_NOMEM), SIDS_NOMEM,
std::wstring(SIDS_TOOMANY), SIDS_TOOMANY,
std::wstring(SIDS_OVERFLOW), SIDS_OVERFLOW,
std::wstring(SIDS_NORESULT), SIDS_NORESULT,
std::wstring(SIDS_INSUFFICIENT_DATA), SIDS_INSUFFICIENT_DATA,
std::wstring(SIDS_ERR_UNK_CH), SIDS_ERR_UNK_CH,
std::wstring(SIDS_ERR_UNK_FN), SIDS_ERR_UNK_FN,
std::wstring(SIDS_ERR_UNEX_NUM), SIDS_ERR_UNEX_NUM,
std::wstring(SIDS_ERR_UNEX_CH), SIDS_ERR_UNEX_CH,
std::wstring(SIDS_ERR_UNEX_SZ), SIDS_ERR_UNEX_SZ,
std::wstring(SIDS_ERR_MISMATCH_CLOSE), SIDS_ERR_MISMATCH_CLOSE,
std::wstring(SIDS_ERR_UNEX_END), SIDS_ERR_UNEX_END,
std::wstring(SIDS_ERR_SG_INV_ERROR), SIDS_ERR_SG_INV_ERROR,
std::wstring(SIDS_ERR_INPUT_OVERFLOW), SIDS_ERR_INPUT_OVERFLOW,
std::wstring(SIDS_ERR_OUTPUT_OVERFLOW) SIDS_ERR_OUTPUT_OVERFLOW
}; };

View file

@ -3,6 +3,7 @@
#pragma once #pragma once
#include <array>
#include "ICalcDisplay.h" #include "ICalcDisplay.h"
#include "IHistoryDisplay.h" #include "IHistoryDisplay.h"
#include "Rational.h" #include "Rational.h"

View file

@ -12,7 +12,7 @@ public:
virtual void SetPrimaryDisplay(const std::wstring& pszText, bool isError) = 0; virtual void SetPrimaryDisplay(const std::wstring& pszText, bool isError) = 0;
virtual void SetIsInError(bool isInError) = 0; virtual void SetIsInError(bool isInError) = 0;
virtual void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands) = 0; virtual void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands) = 0;
virtual void SetParenDisplayText(const std::wstring& pszText) = 0; virtual void SetParenthesisNumber(_In_ unsigned int count) = 0;
virtual void OnNoRightParenAdded() = 0; virtual void OnNoRightParenAdded() = 0;
virtual void MaxDigitsReached() = 0; // not an error but still need to inform UI layer. virtual void MaxDigitsReached() = 0; // not an error but still need to inform UI layer.
virtual void BinaryOperatorReceived() = 0; virtual void BinaryOperatorReceived() = 0;

View file

@ -3,6 +3,7 @@
#pragma once #pragma once
#include <vector>
#include "Ratpack/ratpak.h" #include "Ratpack/ratpak.h"
namespace CalcEngine namespace CalcEngine

View file

@ -13,6 +13,7 @@ namespace CalcEngine::RationalMath
Rational Pow(Rational const& base, Rational const& pow); Rational Pow(Rational const& base, Rational const& pow);
Rational Root(Rational const& base, Rational const& root); Rational Root(Rational const& base, Rational const& root);
Rational Fact(Rational const& rat); Rational Fact(Rational const& rat);
Rational Mod(Rational const& a, Rational const& b);
Rational Exp(Rational const& rat); Rational Exp(Rational const& rat);
Rational Log(Rational const& rat); Rational Log(Rational const& rat);

View file

@ -14,8 +14,8 @@
// internal base is a power of 2. // internal base is a power of 2.
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "pch.h"
#include "ratpak.h" #include "ratpak.h"
#include <cstring> // for memmove
void _mulnumx( PNUMBER *pa, PNUMBER b ); void _mulnumx( PNUMBER *pa, PNUMBER b );

View file

@ -17,7 +17,10 @@
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#include "pch.h" #include <algorithm>
#include <winerror.h>
#include <sstream>
#include <cstring> // for memmove, memcpy
#include "ratpak.h" #include "ratpak.h"
using namespace std; using namespace std;

View file

@ -14,7 +14,6 @@
// //
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "pch.h"
#include "ratpak.h" #include "ratpak.h"
@ -408,7 +407,7 @@ void powratNumeratorDenominator(PRAT *px, PRAT y, uint32_t radix, int32_t precis
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void powratcomp(PRAT *px, PRAT y, uint32_t radix, int32_t precision) void powratcomp(PRAT *px, PRAT y, uint32_t radix, int32_t precision)
{ {
int32_t sign = ((*px)->pp->sign * (*px)->pq->sign); int32_t sign = SIGN(*px);
// Take the absolute value // Take the absolute value
(*px)->pp->sign = 1; (*px)->pp->sign = 1;

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -13,7 +13,6 @@
// Contains fact(orial) and supporting _gamma functions. // Contains fact(orial) and supporting _gamma functions.
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "pch.h"
#include "ratpak.h" #include "ratpak.h"
@ -216,7 +215,7 @@ void factrat( PRAT *px, uint32_t radix, int32_t precision)
// Check for negative integers and throw an error. // Check for negative integers and throw an error.
if ( ( zerrat(frac) || ( LOGRATRADIX(frac) <= -precision) ) && if ( ( zerrat(frac) || ( LOGRATRADIX(frac) <= -precision) ) &&
( (*px)->pp->sign * (*px)->pq->sign == -1 ) ) ( SIGN(*px) == -1 ) )
{ {
throw CALC_E_DOMAIN; throw CALC_E_DOMAIN;
} }

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -15,7 +15,6 @@
// Special Information // Special Information
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "pch.h"
#include "ratpak.h" #include "ratpak.h"
@ -92,11 +91,9 @@ void asinanglerat( _Inout_ PRAT *pa, ANGLE_TYPE angletype, uint32_t radix, int32
void asinrat( PRAT *px, uint32_t radix, int32_t precision) void asinrat( PRAT *px, uint32_t radix, int32_t precision)
{ {
int32_t sgn;
PRAT pret= nullptr; PRAT pret= nullptr;
PRAT phack= nullptr; PRAT phack= nullptr;
int32_t sgn = SIGN(*px);
sgn = (*px)->pp->sign* (*px)->pq->sign;
(*px)->pp->sign = 1; (*px)->pp->sign = 1;
(*px)->pq->sign = 1; (*px)->pq->sign = 1;
@ -204,9 +201,7 @@ void _acosrat( PRAT *px, int32_t precision)
void acosrat( PRAT *px, uint32_t radix, int32_t precision) void acosrat( PRAT *px, uint32_t radix, int32_t precision)
{ {
int32_t sgn; int32_t sgn = SIGN(*px);
sgn = (*px)->pp->sign*(*px)->pq->sign;
(*px)->pp->sign = 1; (*px)->pp->sign = 1;
(*px)->pq->sign = 1; (*px)->pq->sign = 1;
@ -291,10 +286,8 @@ void _atanrat( PRAT *px, int32_t precision)
void atanrat( PRAT *px, uint32_t radix, int32_t precision) void atanrat( PRAT *px, uint32_t radix, int32_t precision)
{ {
int32_t sgn;
PRAT tmpx= nullptr; PRAT tmpx= nullptr;
int32_t sgn = SIGN(*px);
sgn = (*px)->pp->sign * (*px)->pq->sign;
(*px)->pp->sign = 1; (*px)->pp->sign = 1;
(*px)->pq->sign = 1; (*px)->pq->sign = 1;

View file

@ -16,7 +16,6 @@
// //
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "pch.h"
#include "ratpak.h" #include "ratpak.h"

View file

@ -13,59 +13,58 @@
// Contains routines for and, or, xor, not and other support // Contains routines for and, or, xor, not and other support
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#include "pch.h"
#include "ratpak.h" #include "ratpak.h"
using namespace std; using namespace std;
void lshrat( PRAT *pa, PRAT b, uint32_t radix, int32_t precision) void lshrat(PRAT *pa, PRAT b, uint32_t radix, int32_t precision)
{ {
PRAT pwr= nullptr; PRAT pwr = nullptr;
int32_t intb; int32_t intb;
intrat(pa, radix, precision); intrat(pa, radix, precision);
if ( !zernum( (*pa)->pp ) ) if (!zernum((*pa)->pp))
{ {
// If input is zero we're done. // If input is zero we're done.
if ( rat_gt( b, rat_max_exp, precision) ) if (rat_gt(b, rat_max_exp, precision))
{ {
// Don't attempt lsh of anything big // Don't attempt lsh of anything big
throw( CALC_E_DOMAIN ); throw(CALC_E_DOMAIN);
} }
intb = rattoi32(b, radix, precision); intb = rattoi32(b, radix, precision);
DUPRAT(pwr,rat_two); DUPRAT(pwr, rat_two);
ratpowi32(&pwr, intb, precision); ratpowi32(&pwr, intb, precision);
mulrat(pa, pwr, precision); mulrat(pa, pwr, precision);
destroyrat(pwr); destroyrat(pwr);
} }
} }
void rshrat( PRAT *pa, PRAT b, uint32_t radix, int32_t precision) void rshrat(PRAT *pa, PRAT b, uint32_t radix, int32_t precision)
{ {
PRAT pwr= nullptr; PRAT pwr = nullptr;
int32_t intb; int32_t intb;
intrat(pa, radix, precision); intrat(pa, radix, precision);
if ( !zernum( (*pa)->pp ) ) if (!zernum((*pa)->pp))
{ {
// If input is zero we're done. // If input is zero we're done.
if ( rat_lt( b, rat_min_exp, precision) ) if (rat_lt(b, rat_min_exp, precision))
{ {
// Don't attempt rsh of anything big and negative. // Don't attempt rsh of anything big and negative.
throw( CALC_E_DOMAIN ); throw(CALC_E_DOMAIN);
} }
intb = rattoi32(b, radix, precision); intb = rattoi32(b, radix, precision);
DUPRAT(pwr,rat_two); DUPRAT(pwr, rat_two);
ratpowi32(&pwr, intb, precision); ratpowi32(&pwr, intb, precision);
divrat(pa, pwr, precision); divrat(pa, pwr, precision);
destroyrat(pwr); destroyrat(pwr);
} }
} }
void boolrat( PRAT *pa, PRAT b, int func, uint32_t radix, int32_t precision); void boolrat(PRAT *pa, PRAT b, int func, uint32_t radix, int32_t precision);
void boolnum( PNUMBER *pa, PNUMBER b, int func ); void boolnum(PNUMBER *pa, PNUMBER b, int func);
enum { enum {
@ -74,22 +73,22 @@ enum {
FUNC_XOR FUNC_XOR
} BOOL_FUNCS; } BOOL_FUNCS;
void andrat( PRAT *pa, PRAT b, uint32_t radix, int32_t precision) void andrat(PRAT *pa, PRAT b, uint32_t radix, int32_t precision)
{ {
boolrat( pa, b, FUNC_AND, radix, precision); boolrat(pa, b, FUNC_AND, radix, precision);
} }
void orrat( PRAT *pa, PRAT b, uint32_t radix, int32_t precision) void orrat(PRAT *pa, PRAT b, uint32_t radix, int32_t precision)
{ {
boolrat( pa, b, FUNC_OR, radix, precision); boolrat(pa, b, FUNC_OR, radix, precision);
} }
void xorrat( PRAT *pa, PRAT b, uint32_t radix, int32_t precision) void xorrat(PRAT *pa, PRAT b, uint32_t radix, int32_t precision)
{ {
boolrat( pa, b, FUNC_XOR, radix, precision); boolrat(pa, b, FUNC_XOR, radix, precision);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -104,15 +103,15 @@ void xorrat( PRAT *pa, PRAT b, uint32_t radix, int32_t precision)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void boolrat( PRAT *pa, PRAT b, int func, uint32_t radix, int32_t precision) void boolrat(PRAT *pa, PRAT b, int func, uint32_t radix, int32_t precision)
{ {
PRAT tmp= nullptr; PRAT tmp = nullptr;
intrat( pa, radix, precision); intrat(pa, radix, precision);
DUPRAT(tmp,b); DUPRAT(tmp, b);
intrat( &tmp, radix, precision); intrat(&tmp, radix, precision);
boolnum( &((*pa)->pp), tmp->pp, func ); boolnum(&((*pa)->pp), tmp->pp, func);
destroyrat(tmp); destroyrat(tmp);
} }
@ -130,11 +129,11 @@ void boolrat( PRAT *pa, PRAT b, int func, uint32_t radix, int32_t precision)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void boolnum( PNUMBER *pa, PNUMBER b, int func ) void boolnum(PNUMBER *pa, PNUMBER b, int func)
{ {
PNUMBER c= nullptr; PNUMBER c = nullptr;
PNUMBER a= nullptr; PNUMBER a = nullptr;
MANTTYPE *pcha; MANTTYPE *pcha;
MANTTYPE *pchb; MANTTYPE *pchb;
MANTTYPE *pchc; MANTTYPE *pchc;
@ -143,26 +142,26 @@ void boolnum( PNUMBER *pa, PNUMBER b, int func )
MANTTYPE da; MANTTYPE da;
MANTTYPE db; MANTTYPE db;
a=*pa; a = *pa;
cdigits = max( a->cdigit+a->exp, b->cdigit+b->exp ) - cdigits = max(a->cdigit + a->exp, b->cdigit + b->exp) -
min( a->exp, b->exp ); min(a->exp, b->exp);
createnum( c, cdigits ); createnum(c, cdigits);
c->exp = min( a->exp, b->exp ); c->exp = min(a->exp, b->exp);
mexp = c->exp; mexp = c->exp;
c->cdigit = cdigits; c->cdigit = cdigits;
pcha = a->mant; pcha = a->mant;
pchb = b->mant; pchb = b->mant;
pchc = c->mant; pchc = c->mant;
for ( ;cdigits > 0; cdigits--, mexp++ ) for (; cdigits > 0; cdigits--, mexp++)
{
da = (((mexp >= a->exp) && (cdigits + a->exp - c->exp >
(c->cdigit - a->cdigit))) ?
*pcha++ : 0);
db = (((mexp >= b->exp) && (cdigits + b->exp - c->exp >
(c->cdigit - b->cdigit))) ?
*pchb++ : 0);
switch (func)
{ {
da = ( ( ( mexp >= a->exp ) && ( cdigits + a->exp - c->exp >
(c->cdigit - a->cdigit) ) ) ?
*pcha++ : 0 );
db = ( ( ( mexp >= b->exp ) && ( cdigits + b->exp - c->exp >
(c->cdigit - b->cdigit) ) ) ?
*pchb++ : 0 );
switch ( func )
{
case FUNC_AND: case FUNC_AND:
*pchc++ = da & db; *pchc++ = da & db;
break; break;
@ -172,15 +171,51 @@ void boolnum( PNUMBER *pa, PNUMBER b, int func )
case FUNC_XOR: case FUNC_XOR:
*pchc++ = da ^ db; *pchc++ = da ^ db;
break; break;
}
} }
}
c->sign = a->sign; c->sign = a->sign;
while ( c->cdigit > 1 && *(--pchc) == 0 ) while (c->cdigit > 1 && *(--pchc) == 0)
{ {
c->cdigit--; c->cdigit--;
} }
destroynum( *pa ); destroynum(*pa);
*pa=c; *pa = c;
}
//-----------------------------------------------------------------------------
//
// FUNCTION: remrat
//
// ARGUMENTS: pointer to a rational a second rational.
//
// RETURN: None, changes pointer.
//
// DESCRIPTION: Calculate the remainder of *pa / b,
// equivalent of 'pa % b' in C/C++ and produces a result
// that is either zero or has the same sign as the dividend.
//
//-----------------------------------------------------------------------------
void remrat(PRAT *pa, PRAT b)
{
if (zerrat(b))
{
throw CALC_E_INDEFINITE;
}
PRAT tmp = nullptr;
DUPRAT(tmp, b);
mulnumx(&((*pa)->pp), tmp->pq);
mulnumx(&(tmp->pp), (*pa)->pq);
remnum(&((*pa)->pp), tmp->pp, BASEX);
mulnumx(&((*pa)->pq), tmp->pq);
// Get *pa back in the integer over integer form.
RENORMALIZE(*pa);
destroyrat(tmp);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -191,28 +226,38 @@ void boolnum( PNUMBER *pa, PNUMBER b, int func )
// //
// RETURN: None, changes pointer. // RETURN: None, changes pointer.
// //
// DESCRIPTION: Does the rational equivalent of frac(*pa); // DESCRIPTION: Calculate the remainder of *pa / b, with the sign of the result
// either zero or has the same sign as the divisor.
// NOTE: When *pa or b are negative, the result won't be the same as
// the C/C++ operator %, use remrat if it's the behavior you expect.
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void modrat( PRAT *pa, PRAT b ) void modrat(PRAT *pa, PRAT b)
{ {
//contrary to remrat(X, 0) returning 0, modrat(X, 0) must return X
if (zerrat(b))
{
return;
}
PRAT tmp = nullptr; PRAT tmp = nullptr;
DUPRAT(tmp, b);
if ( zerrat( b ) ) auto needAdjust = (SIGN(*pa) == -1 ? (SIGN(b) == 1) : (SIGN(b) == -1));
{
throw CALC_E_INDEFINITE;
}
DUPRAT(tmp,b);
mulnumx( &((*pa)->pp), tmp->pq ); mulnumx(&((*pa)->pp), tmp->pq);
mulnumx( &(tmp->pp), (*pa)->pq ); mulnumx(&(tmp->pp), (*pa)->pq);
remnum( &((*pa)->pp), tmp->pp, BASEX ); remnum(&((*pa)->pp), tmp->pp, BASEX);
mulnumx( &((*pa)->pq), tmp->pq ); mulnumx(&((*pa)->pq), tmp->pq);
if (needAdjust && !zerrat(*pa))
{
addrat(pa, b, BASEX);
}
// Get *pa back in the integer over integer form. // Get *pa back in the integer over integer form.
RENORMALIZE(*pa); RENORMALIZE(*pa);
destroyrat( tmp ); destroyrat(tmp);
} }

View file

@ -17,7 +17,8 @@
// //
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "pch.h" #include <list>
#include <cstring> // for memmove
#include "ratpak.h" #include "ratpak.h"
using namespace std; using namespace std;

View file

@ -16,7 +16,6 @@
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "pch.h"
#include "ratpak.h" #include "ratpak.h"
using namespace std; using namespace std;

View file

@ -17,7 +17,11 @@
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include <algorithm>
#include <string>
#include "CalcErr.h" #include "CalcErr.h"
#include <cstring> // for memmove
#include <sal.h> // for SAL
static constexpr uint32_t BASEXPWR = 31L;// Internal log2(BASEX) static constexpr uint32_t BASEXPWR = 31L;// Internal log2(BASEX)
static constexpr uint32_t BASEX = 0x80000000; // Internal radix used in calculations, hope to raise static constexpr uint32_t BASEX = 0x80000000; // Internal radix used in calculations, hope to raise
@ -148,6 +152,9 @@ extern PRAT rat_min_i32;
#define LOGNUM2(pnum) ((pnum)->cdigit+(pnum)->exp) #define LOGNUM2(pnum) ((pnum)->cdigit+(pnum)->exp)
#define LOGRAT2(prat) (LOGNUM2((prat)->pp)-LOGNUM2((prat)->pq)) #define LOGRAT2(prat) (LOGNUM2((prat)->pp)-LOGNUM2((prat)->pq))
// SIGN returns the sign of the rational
#define SIGN(prat) ((prat)->pp->sign*(prat)->pq->sign)
#if defined( DEBUG_RATPAK ) #if defined( DEBUG_RATPAK )
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// //
@ -423,7 +430,8 @@ extern void divnumx( _Inout_ PNUMBER *pa, _In_ PNUMBER b, int32_t precision);
extern void divrat( _Inout_ PRAT *pa, _In_ PRAT b, int32_t precision); extern void divrat( _Inout_ PRAT *pa, _In_ PRAT b, int32_t precision);
extern void fracrat( _Inout_ PRAT *pa , uint32_t radix, int32_t precision); extern void fracrat( _Inout_ PRAT *pa , uint32_t radix, int32_t precision);
extern void factrat( _Inout_ PRAT *pa, uint32_t radix, int32_t precision); extern void factrat( _Inout_ PRAT *pa, uint32_t radix, int32_t precision);
extern void modrat( _Inout_ PRAT *pa, _In_ PRAT b ); extern void remrat(_Inout_ PRAT *pa, _In_ PRAT b);
extern void modrat(_Inout_ PRAT *pa, _In_ PRAT b);
extern void gcdrat( _Inout_ PRAT *pa, int32_t precision); extern void gcdrat( _Inout_ PRAT *pa, int32_t precision);
extern void intrat( _Inout_ PRAT *px, uint32_t radix, int32_t precision); extern void intrat( _Inout_ PRAT *px, uint32_t radix, int32_t precision);
extern void mulnum( _Inout_ PNUMBER *pa, _In_ PNUMBER b, uint32_t radix); extern void mulnum( _Inout_ PNUMBER *pa, _In_ PNUMBER b, uint32_t radix);

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -18,7 +18,9 @@
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
#include "pch.h" #include <string>
#include <cstring> // for memmove
#include <iostream> // for wostream
#include "ratpak.h" #include "ratpak.h"
using namespace std; using namespace std;
@ -296,7 +298,7 @@ void intrat( PRAT *px, uint32_t radix, int32_t precision)
// Subtract the fractional part of the rational // Subtract the fractional part of the rational
PRAT pret = nullptr; PRAT pret = nullptr;
DUPRAT(pret,*px); DUPRAT(pret,*px);
modrat( &pret, rat_one ); remrat( &pret, rat_one );
subrat( px, pret, precision); subrat( px, pret, precision);
destroyrat( pret ); destroyrat( pret );
@ -348,8 +350,7 @@ bool rat_ge( PRAT a, PRAT b, int32_t precision)
b->pp->sign *= -1; b->pp->sign *= -1;
addrat( &rattmp, b, precision); addrat( &rattmp, b, precision);
b->pp->sign *= -1; b->pp->sign *= -1;
bool bret = ( zernum( rattmp->pp ) || bool bret = ( zernum( rattmp->pp ) || SIGN(rattmp) == 1 );
rattmp->pp->sign * rattmp->pq->sign == 1 );
destroyrat( rattmp ); destroyrat( rattmp );
return( bret ); return( bret );
} }
@ -374,8 +375,7 @@ bool rat_gt( PRAT a, PRAT b, int32_t precision)
b->pp->sign *= -1; b->pp->sign *= -1;
addrat( &rattmp, b, precision); addrat( &rattmp, b, precision);
b->pp->sign *= -1; b->pp->sign *= -1;
bool bret = ( !zernum( rattmp->pp ) && bool bret = ( !zernum( rattmp->pp ) && SIGN(rattmp) == 1 );
rattmp->pp->sign * rattmp->pq->sign == 1 );
destroyrat( rattmp ); destroyrat( rattmp );
return( bret ); return( bret );
} }
@ -400,8 +400,7 @@ bool rat_le( PRAT a, PRAT b, int32_t precision)
b->pp->sign *= -1; b->pp->sign *= -1;
addrat( &rattmp, b, precision); addrat( &rattmp, b, precision);
b->pp->sign *= -1; b->pp->sign *= -1;
bool bret = ( zernum( rattmp->pp ) || bool bret = ( zernum( rattmp->pp ) || SIGN(rattmp) == -1 );
rattmp->pp->sign * rattmp->pq->sign == -1 );
destroyrat( rattmp ); destroyrat( rattmp );
return( bret ); return( bret );
} }
@ -426,8 +425,7 @@ bool rat_lt( PRAT a, PRAT b, int32_t precision)
b->pp->sign *= -1; b->pp->sign *= -1;
addrat( &rattmp, b, precision); addrat( &rattmp, b, precision);
b->pp->sign *= -1; b->pp->sign *= -1;
bool bret = ( !zernum( rattmp->pp ) && bool bret = ( !zernum( rattmp->pp ) && SIGN(rattmp) == -1 );
rattmp->pp->sign * rattmp->pq->sign == -1 );
destroyrat( rattmp ); destroyrat( rattmp );
return( bret ); return( bret );
} }

View file

@ -14,7 +14,6 @@
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
#include "pch.h"
#include "ratpak.h" #include "ratpak.h"

View file

@ -14,7 +14,6 @@
// //
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "pch.h"
#include "ratpak.h" #include "ratpak.h"

View file

@ -1,7 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h" #include <cassert>
#include <sstream>
#include <algorithm> // for std::sort
#include "Command.h" #include "Command.h"
#include "UnitConverter.h" #include "UnitConverter.h"
@ -63,7 +65,8 @@ UnitConverter::UnitConverter(_In_ const shared_ptr<IConverterDataLoader>& dataLo
unquoteConversions[L"{sc}"] = L';'; unquoteConversions[L"{sc}"] = L';';
unquoteConversions[L"{lb}"] = LEFTESCAPECHAR; unquoteConversions[L"{lb}"] = LEFTESCAPECHAR;
unquoteConversions[L"{rb}"] = RIGHTESCAPECHAR; unquoteConversions[L"{rb}"] = RIGHTESCAPECHAR;
Reset(); ClearValues();
ResetCategoriesAndRatios();
} }
void UnitConverter::Initialize() void UnitConverter::Initialize()
@ -75,7 +78,7 @@ bool UnitConverter::CheckLoad()
{ {
if (m_categories.empty()) if (m_categories.empty())
{ {
Reset(); ResetCategoriesAndRatios();
} }
return !m_categories.empty(); return !m_categories.empty();
} }
@ -152,7 +155,6 @@ void UnitConverter::SetCurrentUnitTypes(const Unit& fromType, const Unit& toType
Calculate(); Calculate();
UpdateCurrencySymbols(); UpdateCurrencySymbols();
UpdateViewModel();
} }
/// <summary> /// <summary>
@ -336,7 +338,8 @@ wstring UnitConverter::Serialize()
/// <param name="serializedData">wstring holding the serialized data. If it does not have expected number of parameters, we will ignore it</param> /// <param name="serializedData">wstring holding the serialized data. If it does not have expected number of parameters, we will ignore it</param>
void UnitConverter::DeSerialize(const wstring& serializedData) void UnitConverter::DeSerialize(const wstring& serializedData)
{ {
Reset(); ClearValues();
ResetCategoriesAndRatios();
if (serializedData.empty()) if (serializedData.empty())
{ {
@ -403,12 +406,30 @@ void UnitConverter::RestoreUserPreferences(const wstring& userPreferences)
} }
vector<wstring> outerTokens = StringToVector(userPreferences, L"|"); vector<wstring> outerTokens = StringToVector(userPreferences, L"|");
if (outerTokens.size() == 3) if (outerTokens.size() != 3)
{ {
m_fromType = StringToUnit(outerTokens[0]); return;
m_toType = StringToUnit(outerTokens[1]);
m_currentCategory = StringToCategory(outerTokens[2]);
} }
auto fromType = StringToUnit(outerTokens[0]);
auto toType = StringToUnit(outerTokens[1]);
m_currentCategory = StringToCategory(outerTokens[2]);
// Only restore from the saved units if they are valid in the current available units.
auto itr = m_categoryToUnits.find(m_currentCategory);
if (itr != m_categoryToUnits.end())
{
const auto& curUnits = itr->second;
if (find(curUnits.begin(), curUnits.end(), fromType) != curUnits.end())
{
m_fromType = fromType;
}
if (find(curUnits.begin(), curUnits.end(), toType) != curUnits.end())
{
m_toType = toType;
}
}
} }
/// <summary> /// <summary>
@ -615,7 +636,7 @@ void UnitConverter::SendCommand(Command command)
clearFront = false; clearFront = false;
clearBack = false; clearBack = false;
ClearValues(); ClearValues();
Reset(); ResetCategoriesAndRatios();
break; break;
default: default:
@ -634,8 +655,6 @@ void UnitConverter::SendCommand(Command command)
} }
Calculate(); Calculate();
UpdateViewModel();
} }
/// <summary> /// <summary>
@ -824,19 +843,16 @@ vector<tuple<wstring, Unit>> UnitConverter::CalculateSuggested()
returnVector.push_back(whimsicalReturnVector.at(0)); returnVector.push_back(whimsicalReturnVector.at(0));
} }
//
return returnVector; return returnVector;
} }
/// <summary> /// <summary>
/// Resets the converter to its initial state /// Resets categories and ratios
/// </summary> /// </summary>
void UnitConverter::Reset() void UnitConverter::ResetCategoriesAndRatios()
{ {
m_categories = m_dataLoader->LoadOrderedCategories(); m_categories = m_dataLoader->LoadOrderedCategories();
ClearValues();
m_switchedActive = false; m_switchedActive = false;
if (m_categories.empty()) if (m_categories.empty())
@ -881,7 +897,6 @@ void UnitConverter::Reset()
} }
InitializeSelectedUnits(); InitializeSelectedUnits();
Calculate();
} }
/// <summary> /// <summary>
@ -972,11 +987,21 @@ bool UnitConverter::AnyUnitIsEmpty()
/// </summary> /// </summary>
void UnitConverter::Calculate() void UnitConverter::Calculate()
{ {
unordered_map<Unit, ConversionData, UnitHash> conversionTable = m_ratioMap[m_fromType]; if (AnyUnitIsEmpty())
double returnValue = stod(m_currentDisplay);
if (AnyUnitIsEmpty() || (conversionTable[m_toType].ratio == 1.0 && conversionTable[m_toType].offset == 0.0))
{ {
m_returnDisplay = m_currentDisplay; m_returnDisplay = m_currentDisplay;
m_returnHasDecimal = m_currentHasDecimal;
TrimString(m_returnDisplay);
UpdateViewModel();
return;
}
unordered_map<Unit, ConversionData, UnitHash> conversionTable = m_ratioMap[m_fromType];
double returnValue = stod(m_currentDisplay);
if (conversionTable[m_toType].ratio == 1.0 && conversionTable[m_toType].offset == 0.0)
{
m_returnDisplay = m_currentDisplay;
m_returnHasDecimal = m_currentHasDecimal;
TrimString(m_returnDisplay); TrimString(m_returnDisplay);
} }
else else
@ -1015,9 +1040,9 @@ void UnitConverter::Calculate()
m_returnDisplay = returnString; m_returnDisplay = returnString;
TrimString(m_returnDisplay); TrimString(m_returnDisplay);
} }
m_returnHasDecimal = (m_returnDisplay.find(L'.') != m_returnDisplay.npos);
} }
UpdateViewModel();
m_returnHasDecimal = (m_returnDisplay.find(L'.') != m_returnDisplay.npos);
} }
/// <summary> /// <summary>

View file

@ -1,8 +1,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#pragma once #pragma once
#include <vector>
#include <unordered_map>
#include <ppltasks.h>
#include <sal.h> // for SAL
#include <memory> // for std::shared_ptr
namespace UnitConversionManager namespace UnitConversionManager
{ {
enum class Command; enum class Command;
@ -195,6 +201,8 @@ namespace UnitConversionManager
virtual void SetViewModelCallback(_In_ const std::shared_ptr<IUnitConverterVMCallback>& newCallback) = 0; virtual void SetViewModelCallback(_In_ const std::shared_ptr<IUnitConverterVMCallback>& newCallback) = 0;
virtual void SetViewModelCurrencyCallback(_In_ const std::shared_ptr<IViewModelCurrencyCallback>& newCallback) = 0; virtual void SetViewModelCurrencyCallback(_In_ const std::shared_ptr<IViewModelCurrencyCallback>& newCallback) = 0;
virtual concurrency::task<std::pair<bool, std::wstring>> RefreshCurrencyRatios() = 0; virtual concurrency::task<std::pair<bool, std::wstring>> RefreshCurrencyRatios() = 0;
virtual void Calculate() = 0;
virtual void ResetCategoriesAndRatios() = 0;
}; };
class UnitConverter : public IUnitConverter, public std::enable_shared_from_this<UnitConverter> class UnitConverter : public IUnitConverter, public std::enable_shared_from_this<UnitConverter>
@ -218,6 +226,8 @@ namespace UnitConversionManager
void SetViewModelCallback(_In_ const std::shared_ptr<IUnitConverterVMCallback>& newCallback) override; void SetViewModelCallback(_In_ const std::shared_ptr<IUnitConverterVMCallback>& newCallback) override;
void SetViewModelCurrencyCallback(_In_ const std::shared_ptr<IViewModelCurrencyCallback>& newCallback) override; void SetViewModelCurrencyCallback(_In_ const std::shared_ptr<IViewModelCurrencyCallback>& newCallback) override;
concurrency::task<std::pair<bool, std::wstring>> RefreshCurrencyRatios() override; concurrency::task<std::pair<bool, std::wstring>> RefreshCurrencyRatios() override;
void Calculate() override;
void ResetCategoriesAndRatios() override;
// IUnitConverter // IUnitConverter
static std::vector<std::wstring> StringToVector(const std::wstring& w, const wchar_t * delimiter, bool addRemainder = false); static std::vector<std::wstring> StringToVector(const std::wstring& w, const wchar_t * delimiter, bool addRemainder = false);
@ -228,9 +238,7 @@ namespace UnitConversionManager
bool CheckLoad(); bool CheckLoad();
double Convert(double value, ConversionData conversionData); double Convert(double value, ConversionData conversionData);
std::vector<std::tuple<std::wstring, Unit>> CalculateSuggested(); std::vector<std::tuple<std::wstring, Unit>> CalculateSuggested();
void Reset();
void ClearValues(); void ClearValues();
void Calculate();
void TrimString(std::wstring& input); void TrimString(std::wstring& input);
void InitializeSelectedUnits(); void InitializeSelectedUnits();
std::wstring RoundSignificant(double num, int numSignificant); std::wstring RoundSignificant(double num, int numSignificant);

View file

@ -1,4 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h" // Intentionally do not include the pch.h here. For projects that don't
// use precompiled headers, including the header here would force unnecessary compilation.
// The pch will be included through forced include.

View file

@ -3,27 +3,20 @@
#pragma once #pragma once
#ifndef WIN32_LEAN_AND_MEAN // The CalcManager project should be able to be compiled with or without a precompiled header
#define WIN32_LEAN_AND_MEAN // in - order to support other toolchains besides MSVC. When adding new system headers, make sure
#endif // that the relevant source file includes all headers it needs, but then also add the system headers
// here so that MSVC users see the performance benefit.
// Windows headers define min/max macros. #include <algorithm>
// Disable it for project code.
#define NOMINMAX
#include <assert.h>
#include <windows.h>
#include <winerror.h>
#include <sstream>
#include <iostream>
#include <iterator>
#include <string>
#include <memory>
#include <vector>
#include <limits>
#include <list>
#include <regex>
#include <unordered_map>
#include <intsafe.h>
#include <array> #include <array>
#include <cassert>
#include <intsafe.h>
#include <list>
#include <ppltasks.h> #include <ppltasks.h>
#include <regex>
#include <sstream>
#include <string>
#include <unordered_map>
#include <vector>
#include <winerror.h>

View file

@ -1,11 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>

View file

@ -36,7 +36,6 @@ namespace
{ {
StringReference CategoriesPropertyName(L"Categories"); StringReference CategoriesPropertyName(L"Categories");
StringReference ClearMemoryVisibilityPropertyName(L"ClearMemoryVisibility"); StringReference ClearMemoryVisibilityPropertyName(L"ClearMemoryVisibility");
StringReference AppBarVisibilityPropertyName(L"AppBarVisibility");
} }
ApplicationViewModel::ApplicationViewModel() : ApplicationViewModel::ApplicationViewModel() :
@ -164,7 +163,6 @@ void ApplicationViewModel::OnModeChanged()
TraceLogger::GetInstance().LogModeChangeEnd(m_mode, ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread())); TraceLogger::GetInstance().LogModeChangeEnd(m_mode, ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread()));
RaisePropertyChanged(ClearMemoryVisibilityPropertyName); RaisePropertyChanged(ClearMemoryVisibilityPropertyName);
RaisePropertyChanged(AppBarVisibilityPropertyName);
} }
void ApplicationViewModel::OnCopyCommand(Object^ parameter) void ApplicationViewModel::OnCopyCommand(Object^ parameter)
@ -189,7 +187,7 @@ void ApplicationViewModel::OnPasteCommand(Object^ parameter)
{ {
ConverterViewModel->OnPasteCommand(parameter); ConverterViewModel->OnPasteCommand(parameter);
} }
else else if (NavCategory::IsCalculatorViewMode(m_mode))
{ {
CalculatorViewModel->OnPasteCommand(parameter); CalculatorViewModel->OnPasteCommand(parameter);
} }

View file

@ -66,16 +66,6 @@ namespace CalculatorApp
} }
} }
property Windows::UI::Xaml::Visibility AppBarVisibility
{
Windows::UI::Xaml::Visibility get()
{
return CalculatorApp::Common::NavCategory::IsCalculatorViewMode(Mode)
? Windows::UI::Xaml::Visibility::Visible
: Windows::UI::Xaml::Visibility::Collapsed;
}
}
private: private:
bool TryRecoverFromNavigationModeFailure(); bool TryRecoverFromNavigationModeFailure();

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
// Implementation of the NarratorNotifier class. // Implementation of the NarratorNotifier class.

View file

@ -36,7 +36,7 @@ void CalculatorDisplay::SetPrimaryDisplay(_In_ const wstring& displayStringValue
} }
} }
void CalculatorDisplay::SetParenDisplayText(_In_ const std::wstring& parenthesisCount) void CalculatorDisplay::SetParenthesisNumber(_In_ unsigned int parenthesisCount)
{ {
if (m_callbackReference != nullptr) if (m_callbackReference != nullptr)
{ {

View file

@ -21,7 +21,7 @@ namespace CalculatorApp
void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands) override; void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands) override;
void SetMemorizedNumbers(_In_ const std::vector<std::wstring>& memorizedNumbers) override; void SetMemorizedNumbers(_In_ const std::vector<std::wstring>& memorizedNumbers) override;
void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override; void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) override;
void SetParenDisplayText(_In_ const std::wstring& parenthesisCount) override; void SetParenthesisNumber(_In_ unsigned int parenthesisCount) override;
void OnNoRightParenAdded() override; void OnNoRightParenAdded() override;
void MaxDigitsReached() override; void MaxDigitsReached() override;
void BinaryOperatorReceived() override; void BinaryOperatorReceived() override;

View file

@ -15,14 +15,15 @@ using namespace Windows::Foundation;
using namespace Windows::System; using namespace Windows::System;
using namespace Windows::ApplicationModel::DataTransfer; using namespace Windows::ApplicationModel::DataTransfer;
unsigned long long maxOperandNumber;
String^ CopyPasteManager::supportedFormats[] = String^ CopyPasteManager::supportedFormats[] =
{ {
StandardDataFormats::Text StandardDataFormats::Text
}; };
constexpr wstring_view c_validCharacterSet{ L"0123456789()+-*/.abcdefABCDEF" }; static constexpr wstring_view c_validCharacterSet{ L"0123456789()+-*/.abcdefABCDEF" };
// The below values can not be "constexpr"-ed,
// as both wstring_view and wchar[] can not be concatenated
// [\s\x85] means white-space characters // [\s\x85] means white-space characters
static const wstring c_wspc = L"[\\s\\x85]*"; static const wstring c_wspc = L"[\\s\\x85]*";
static const wstring c_wspcLParens = c_wspc + L"[(]*" + c_wspc; static const wstring c_wspcLParens = c_wspc + L"[(]*" + c_wspc;
@ -103,19 +104,16 @@ task<String^> CopyPasteManager::GetStringToPaste(ViewMode mode, CategoryGroupTyp
int CopyPasteManager::ClipboardTextFormat() int CopyPasteManager::ClipboardTextFormat()
{ {
int result = -1; const auto dataPackageView = Clipboard::GetContent();
auto dataPackageView = Clipboard::GetContent();
for (int i = 0; i < RTL_NUMBER_OF(supportedFormats); i++) for (int i = 0; i < RTL_NUMBER_OF(supportedFormats); i++)
{ {
if (dataPackageView->Contains(supportedFormats[i])) if (dataPackageView->Contains(supportedFormats[i]))
{ {
result = i; return i;
break;
} }
} }
return result; return -1;
} }
String^ CopyPasteManager::ValidatePasteExpression(String^ pastedText, ViewMode mode, int programmerNumberBase, int bitLengthType) String^ CopyPasteManager::ValidatePasteExpression(String^ pastedText, ViewMode mode, int programmerNumberBase, int bitLengthType)
@ -268,13 +266,8 @@ bool CopyPasteManager::ExpressionRegExMatch(vector<wstring> operands, ViewMode m
return false; return false;
} }
bool expMatched = true;
vector<wregex> patterns{}; vector<wregex> patterns{};
pair<size_t, uint64_t> operandLimits = GetMaxOperandLengthAndValue(mode, modeType, programmerNumberBase, bitLengthType);
size_t maxOperandLength = operandLimits.first;
uint64_t maxOperandValue = operandLimits.second;
if (mode == ViewMode::Standard) if (mode == ViewMode::Standard)
{ {
patterns.assign(standardModePatterns.begin(), standardModePatterns.end()); patterns.assign(standardModePatterns.begin(), standardModePatterns.end());
@ -292,11 +285,14 @@ bool CopyPasteManager::ExpressionRegExMatch(vector<wstring> operands, ViewMode m
patterns.assign(unitConverterPatterns.begin(), unitConverterPatterns.end()); patterns.assign(unitConverterPatterns.begin(), unitConverterPatterns.end());
} }
for (const wstring& operand : operands) const auto [maxOperandLength, maxOperandValue] = GetMaxOperandLengthAndValue(mode, modeType, programmerNumberBase, bitLengthType);
bool expMatched = true;
for (const auto& operand : operands)
{ {
// Each operand only needs to match one of the available patterns. // Each operand only needs to match one of the available patterns.
bool operandMatched = false; bool operandMatched = false;
for (const wregex& pattern : patterns) for (const auto& pattern : patterns)
{ {
operandMatched = operandMatched || regex_match(operand, pattern); operandMatched = operandMatched || regex_match(operand, pattern);
} }
@ -305,7 +301,7 @@ bool CopyPasteManager::ExpressionRegExMatch(vector<wstring> operands, ViewMode m
{ {
// Remove characters that are valid in the expression but we do not want to include in length calculations // Remove characters that are valid in the expression but we do not want to include in length calculations
// or which will break conversion from string-to-ULL. // or which will break conversion from string-to-ULL.
wstring operandValue = SanitizeOperand(operand); const wstring operandValue = SanitizeOperand(operand);
// If an operand exceeds the maximum length allowed, break and return. // If an operand exceeds the maximum length allowed, break and return.
if (OperandLength(operandValue, mode, modeType, programmerNumberBase) > maxOperandLength) if (OperandLength(operandValue, mode, modeType, programmerNumberBase) > maxOperandLength)
@ -341,16 +337,16 @@ bool CopyPasteManager::ExpressionRegExMatch(vector<wstring> operands, ViewMode m
pair<size_t, uint64_t> CopyPasteManager::GetMaxOperandLengthAndValue(ViewMode mode, CategoryGroupType modeType, int programmerNumberBase, int bitLengthType) pair<size_t, uint64_t> CopyPasteManager::GetMaxOperandLengthAndValue(ViewMode mode, CategoryGroupType modeType, int programmerNumberBase, int bitLengthType)
{ {
size_t maxLength = 0; constexpr size_t defaultMaxOperandLength = 0;
uint64_t maxValue = 0; constexpr uint64_t defaultMaxValue = 0;
if (mode == ViewMode::Standard) if (mode == ViewMode::Standard)
{ {
maxLength = MaxStandardOperandLength; return make_pair(MaxStandardOperandLength, defaultMaxValue);
} }
else if (mode == ViewMode::Scientific) else if (mode == ViewMode::Scientific)
{ {
maxLength = MaxScientificOperandLength; return make_pair(MaxScientificOperandLength, defaultMaxValue);
} }
else if (mode == ViewMode::Programmer) else if (mode == ViewMode::Programmer)
{ {
@ -390,15 +386,17 @@ pair<size_t, uint64_t> CopyPasteManager::GetMaxOperandLengthAndValue(ViewMode mo
unsigned int signBit = (programmerNumberBase == DecBase) ? 1 : 0; unsigned int signBit = (programmerNumberBase == DecBase) ? 1 : 0;
maxLength = (size_t)ceil((bitLength - signBit) / bitsPerDigit); const auto maxLength = static_cast<size_t>(ceil((bitLength - signBit) / bitsPerDigit));
maxValue = UINT64_MAX >> (MaxProgrammerBitLength - (bitLength - signBit)); const uint64_t maxValue = UINT64_MAX >> (MaxProgrammerBitLength - (bitLength - signBit));
return make_pair(maxLength, maxValue);
} }
else if (modeType == CategoryGroupType::Converter) else if (modeType == CategoryGroupType::Converter)
{ {
maxLength = MaxConverterInputLength; return make_pair(MaxConverterInputLength, defaultMaxValue);
} }
return make_pair(maxLength, maxValue); return make_pair(defaultMaxOperandLength, defaultMaxValue);
} }
wstring CopyPasteManager::SanitizeOperand(const wstring& operand) wstring CopyPasteManager::SanitizeOperand(const wstring& operand)
@ -417,8 +415,7 @@ bool CopyPasteManager::TryOperandToULL(const wstring& operand, int numberBase, u
return false; return false;
} }
// Default to base10 int intBase;
int intBase = 10;
switch (numberBase) switch (numberBase)
{ {
case HexBase: case HexBase:
@ -430,6 +427,7 @@ bool CopyPasteManager::TryOperandToULL(const wstring& operand, int numberBase, u
case BinBase: case BinBase:
intBase = 2; intBase = 2;
break; break;
default:
case DecBase: case DecBase:
intBase = 10; intBase = 10;
break; break;
@ -441,11 +439,11 @@ bool CopyPasteManager::TryOperandToULL(const wstring& operand, int numberBase, u
result = stoull(operand, &size, intBase); result = stoull(operand, &size, intBase);
return true; return true;
} }
catch (invalid_argument) catch (const invalid_argument&)
{ {
// Do nothing // Do nothing
} }
catch (out_of_range) catch (const out_of_range&)
{ {
// Do nothing // Do nothing
} }
@ -453,35 +451,28 @@ bool CopyPasteManager::TryOperandToULL(const wstring& operand, int numberBase, u
return false; return false;
} }
size_t CopyPasteManager::OperandLength(wstring operand, ViewMode mode, CategoryGroupType modeType, int programmerNumberBase) size_t CopyPasteManager::OperandLength(const wstring& operand, ViewMode mode, CategoryGroupType modeType, int programmerNumberBase)
{ {
size_t len = 0; if (modeType == CategoryGroupType::Converter) {
if (mode == ViewMode::Standard || mode == ViewMode::Scientific) return operand.length();
{
len = StandardScientificOperandLength(operand);
}
else if (mode == ViewMode::Programmer)
{
len = ProgrammerOperandLength(operand, programmerNumberBase);
}
else if (modeType == CategoryGroupType::Converter)
{
len = operand.length();
} }
return len; switch(mode) {
case ViewMode::Standard:
case ViewMode::Scientific:
return StandardScientificOperandLength(operand);
case ViewMode::Programmer:
return ProgrammerOperandLength(operand, programmerNumberBase);
default:
return 0;
}
} }
size_t CopyPasteManager::StandardScientificOperandLength(wstring operand) size_t CopyPasteManager::StandardScientificOperandLength(const wstring& operand)
{ {
bool hasDecimal = false; const bool hasDecimal = operand.find('.') != wstring::npos;
for (size_t i = 0; i < operand.length(); i++)
{
if (operand[i] == L'.')
{
hasDecimal = true;
}
}
if (hasDecimal) if (hasDecimal)
{ {
@ -503,8 +494,7 @@ size_t CopyPasteManager::StandardScientificOperandLength(wstring operand)
size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int numberBase) size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int numberBase)
{ {
size_t len = operand.length();
vector<wstring> prefixes{}; vector<wstring> prefixes{};
vector<wstring> suffixes{}; vector<wstring> suffixes{};
switch (numberBase) switch (numberBase)
@ -525,7 +515,7 @@ size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int num
break; break;
default: default:
// No defined prefixes/suffixes // No defined prefixes/suffixes
break; return 0;
} }
// UInt suffixes are common across all modes // UInt suffixes are common across all modes
@ -535,9 +525,11 @@ size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int num
wstring operandUpper = operand; wstring operandUpper = operand;
transform(operandUpper.begin(), operandUpper.end(), operandUpper.begin(), towupper); transform(operandUpper.begin(), operandUpper.end(), operandUpper.begin(), towupper);
size_t len = operand.length();
// Detect if there is a suffix and subtract its length // Detect if there is a suffix and subtract its length
// Check suffixes first to allow e.g. "0b" to result in length 1 (value 0), rather than length 0 (no value). // Check suffixes first to allow e.g. "0b" to result in length 1 (value 0), rather than length 0 (no value).
for (const wstring& suffix : suffixes) for (const auto& suffix : suffixes)
{ {
if (len < suffix.length()) if (len < suffix.length())
{ {
@ -552,7 +544,7 @@ size_t CopyPasteManager::ProgrammerOperandLength(const wstring& operand, int num
} }
// Detect if there is a prefix and subtract its length // Detect if there is a prefix and subtract its length
for (const wstring& prefix : prefixes) for (const auto& prefix : prefixes)
{ {
if (len < prefix.length()) if (len < prefix.length())
{ {

View file

@ -13,15 +13,14 @@ namespace CalculatorUnitTests
namespace CalculatorApp namespace CalculatorApp
{ {
inline constexpr auto QwordType = 1;
#define QwordType 1 inline constexpr auto DwordType = 2;
#define DwordType 2 inline constexpr auto WordType = 3;
#define WordType 3 inline constexpr auto ByteType = 4;
#define ByteType 4 inline constexpr auto HexBase = 5;
#define HexBase 5 inline constexpr auto DecBase = 6;
#define DecBase 6 inline constexpr auto OctBase = 7;
#define OctBase 7 inline constexpr auto BinBase = 8;
#define BinBase 8
class CopyPasteManager class CopyPasteManager
{ {
@ -55,8 +54,8 @@ namespace CalculatorApp
static std::pair<size_t, uint64_t> GetMaxOperandLengthAndValue(CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType, int programmerNumberBase = -1, int bitLengthType = -1); static std::pair<size_t, uint64_t> GetMaxOperandLengthAndValue(CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType, int programmerNumberBase = -1, int bitLengthType = -1);
static std::wstring SanitizeOperand(const std::wstring& operand); static std::wstring SanitizeOperand(const std::wstring& operand);
static bool TryOperandToULL(const std::wstring& operand, int numberBase, unsigned long long int& result); static bool TryOperandToULL(const std::wstring& operand, int numberBase, unsigned long long int& result);
static size_t OperandLength(std::wstring operand, CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType, int programmerNumberBase = -1); static size_t OperandLength(const std::wstring& operand, CalculatorApp::Common::ViewMode mode, CalculatorApp::Common::CategoryGroupType modeType, int programmerNumberBase = -1);
static size_t StandardScientificOperandLength(std::wstring operand); static size_t StandardScientificOperandLength(const std::wstring& operand);
static size_t ProgrammerOperandLength(const std::wstring& operand, int numberBase); static size_t ProgrammerOperandLength(const std::wstring& operand, int numberBase);
static std::wstring RemoveUnwantedCharsFromWstring(const std::wstring& input); static std::wstring RemoveUnwantedCharsFromWstring(const std::wstring& input);

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
namespace CalculatorApp namespace CalculatorApp
@ -162,7 +162,8 @@ namespace CalculatorApp
Data_Zebibytes = UnitStart + 162, Data_Zebibytes = UnitStart + 162,
Data_Zetabits = UnitStart + 163, Data_Zetabits = UnitStart + 163,
Data_Zetabytes = UnitStart + 164, Data_Zetabytes = UnitStart + 164,
UnitEnd = Data_Zetabytes Area_Pyeong = UnitStart + 165,
UnitEnd = Area_Pyeong
}; };
} }
} }

View file

@ -118,12 +118,19 @@ void UnitConverterDataLoader::LoadData()
unordered_map<int, double> unitConversions = categoryToUnitConversionDataMap.at(categoryViewMode); unordered_map<int, double> unitConversions = categoryToUnitConversionDataMap.at(categoryViewMode);
double unitFactor = unitConversions[unit.id]; double unitFactor = unitConversions[unit.id];
for (auto itr = unitConversions.begin(); itr != unitConversions.end(); ++itr) for (const auto&[id, conversionFactor] : unitConversions)
{ {
if (idToUnit.find(id) == idToUnit.end())
{
// Optional units will not be in idToUnit but can be in unitConversions.
// For optional units that did not make it to the current set of units, just continue.
continue;
}
UCM::ConversionData parsedData = { 1.0, 0.0, false }; UCM::ConversionData parsedData = { 1.0, 0.0, false };
assert(itr->second > 0); // divide by zero assert assert(conversionFactor > 0); // divide by zero assert
parsedData.ratio = unitFactor / itr->second; parsedData.ratio = unitFactor / conversionFactor;
conversions.insert(pair<UCM::Unit, UCM::ConversionData>(idToUnit.at(itr->first), parsedData)); conversions.insert(pair<UCM::Unit, UCM::ConversionData>(idToUnit.at(id), parsedData));
} }
} }
else else
@ -175,6 +182,10 @@ void UnitConverterDataLoader::GetUnits(_In_ unordered_map<ViewMode, vector<Order
bool useWattInsteadOfKilowatt = m_currentRegionCode == "GB"; bool useWattInsteadOfKilowatt = m_currentRegionCode == "GB";
// Use Pyeong, a Korean floorspace unit.
// https://en.wikipedia.org/wiki/Korean_units_of_measurement#Area
bool usePyeong = m_currentRegionCode == L"KP" || m_currentRegionCode == L"KR";
vector<OrderedUnit> areaUnits; vector<OrderedUnit> areaUnits;
areaUnits.push_back(OrderedUnit{ UnitConverterUnits::Area_Acre, GetLocalizedStringName(L"UnitName_Acre"), GetLocalizedStringName(L"UnitAbbreviation_Acre"), 9 }); areaUnits.push_back(OrderedUnit{ UnitConverterUnits::Area_Acre, GetLocalizedStringName(L"UnitName_Acre"), GetLocalizedStringName(L"UnitAbbreviation_Acre"), 9 });
areaUnits.push_back(OrderedUnit{ UnitConverterUnits::Area_Hectare, GetLocalizedStringName(L"UnitName_Hectare"), GetLocalizedStringName(L"UnitAbbreviation_Hectare"), 4 }); areaUnits.push_back(OrderedUnit{ UnitConverterUnits::Area_Hectare, GetLocalizedStringName(L"UnitName_Hectare"), GetLocalizedStringName(L"UnitAbbreviation_Hectare"), 4 });
@ -190,6 +201,10 @@ void UnitConverterDataLoader::GetUnits(_In_ unordered_map<ViewMode, vector<Order
areaUnits.push_back(OrderedUnit{ UnitConverterUnits::Area_Paper, GetLocalizedStringName(L"UnitName_Paper"), GetLocalizedStringName(L"UnitAbbreviation_Paper"), 12, false, false, true }); areaUnits.push_back(OrderedUnit{ UnitConverterUnits::Area_Paper, GetLocalizedStringName(L"UnitName_Paper"), GetLocalizedStringName(L"UnitAbbreviation_Paper"), 12, false, false, true });
areaUnits.push_back(OrderedUnit{ UnitConverterUnits::Area_SoccerField, GetLocalizedStringName(L"UnitName_SoccerField"), GetLocalizedStringName(L"UnitAbbreviation_SoccerField"),13, false, false, true }); areaUnits.push_back(OrderedUnit{ UnitConverterUnits::Area_SoccerField, GetLocalizedStringName(L"UnitName_SoccerField"), GetLocalizedStringName(L"UnitAbbreviation_SoccerField"),13, false, false, true });
areaUnits.push_back(OrderedUnit{ UnitConverterUnits::Area_Castle, GetLocalizedStringName(L"UnitName_Castle"), GetLocalizedStringName(L"UnitAbbreviation_Castle"), 14, false, false, true }); areaUnits.push_back(OrderedUnit{ UnitConverterUnits::Area_Castle, GetLocalizedStringName(L"UnitName_Castle"), GetLocalizedStringName(L"UnitAbbreviation_Castle"), 14, false, false, true });
if (usePyeong)
{
areaUnits.push_back(OrderedUnit{ UnitConverterUnits::Area_Pyeong, GetLocalizedStringName(L"UnitName_Pyeong"), GetLocalizedStringName(L"UnitAbbreviation_Pyeong"), 15, false, false, false });
}
unitMap.emplace(ViewMode::Area, areaUnits); unitMap.emplace(ViewMode::Area, areaUnits);
vector<OrderedUnit> dataUnits; vector<OrderedUnit> dataUnits;
@ -384,6 +399,7 @@ void UnitConverterDataLoader::GetConversionData(_In_ unordered_map<ViewMode, uno
{ ViewMode::Area, UnitConverterUnits::Area_Paper, 0.06032246 }, { ViewMode::Area, UnitConverterUnits::Area_Paper, 0.06032246 },
{ ViewMode::Area, UnitConverterUnits::Area_SoccerField, 10869.66 }, { ViewMode::Area, UnitConverterUnits::Area_SoccerField, 10869.66 },
{ ViewMode::Area, UnitConverterUnits::Area_Castle, 100000 }, { ViewMode::Area, UnitConverterUnits::Area_Castle, 100000 },
{ ViewMode::Area, UnitConverterUnits::Area_Pyeong, 400.0 / 121.0 },
{ ViewMode::Data, UnitConverterUnits::Data_Bit, 0.000000125 }, { ViewMode::Data, UnitConverterUnits::Data_Bit, 0.000000125 },
{ ViewMode::Data, UnitConverterUnits::Data_Byte, 0.000001 }, { ViewMode::Data, UnitConverterUnits::Data_Byte, 0.000001 },

View file

@ -48,7 +48,6 @@ namespace CalculatorResourceKeys
StringReference DecButton(L"Format_DecButtonValue"); StringReference DecButton(L"Format_DecButtonValue");
StringReference OctButton(L"Format_OctButtonValue"); StringReference OctButton(L"Format_OctButtonValue");
StringReference BinButton(L"Format_BinButtonValue"); StringReference BinButton(L"Format_BinButtonValue");
StringReference LeftParenthesisAutomationFormat(L"Format_OpenParenthesisAutomationNamePrefix");
StringReference OpenParenthesisCountAutomationFormat(L"Format_OpenParenthesisCountAutomationNamePrefix"); StringReference OpenParenthesisCountAutomationFormat(L"Format_OpenParenthesisCountAutomationNamePrefix");
StringReference NoParenthesisAdded(L"NoRightParenthesisAdded_Announcement"); StringReference NoParenthesisAdded(L"NoRightParenthesisAdded_Announcement");
StringReference MaxDigitsReachedFormat(L"Format_MaxDigitsReached"); StringReference MaxDigitsReachedFormat(L"Format_MaxDigitsReached");
@ -67,6 +66,7 @@ StandardCalculatorViewModel::StandardCalculatorViewModel() :
m_BinaryDisplayValue(L"0"), m_BinaryDisplayValue(L"0"),
m_OctalDisplayValue(L"0"), m_OctalDisplayValue(L"0"),
m_standardCalculatorManager(&m_calculatorDisplay, &m_resourceProvider), m_standardCalculatorManager(&m_calculatorDisplay, &m_resourceProvider),
m_ExpressionTokens(ref new Vector<DisplayExpressionToken^>()),
m_MemorizedNumbers(ref new Vector<MemoryItemViewModel^>()), m_MemorizedNumbers(ref new Vector<MemoryItemViewModel^>()),
m_IsMemoryEmpty(true), m_IsMemoryEmpty(true),
m_IsFToEChecked(false), m_IsFToEChecked(false),
@ -80,8 +80,8 @@ StandardCalculatorViewModel::StandardCalculatorViewModel() :
m_isBinaryBitFlippingEnabled(false), m_isBinaryBitFlippingEnabled(false),
m_CurrentRadixType(RADIX_TYPE::DEC_RADIX), m_CurrentRadixType(RADIX_TYPE::DEC_RADIX),
m_CurrentAngleType(NumbersAndOperatorsEnum::Degree), m_CurrentAngleType(NumbersAndOperatorsEnum::Degree),
m_OpenParenthesisCount(L""),
m_Announcement(nullptr), m_Announcement(nullptr),
m_OpenParenthesisCount(0),
m_feedbackForButtonPress(nullptr), m_feedbackForButtonPress(nullptr),
m_isRtlLanguage(false), m_isRtlLanguage(false),
m_localizedMaxDigitsReachedAutomationFormat(nullptr), m_localizedMaxDigitsReachedAutomationFormat(nullptr),
@ -102,7 +102,6 @@ StandardCalculatorViewModel::StandardCalculatorViewModel() :
m_localizedDecimalAutomationFormat = AppResourceProvider::GetInstance().GetResourceString(CalculatorResourceKeys::DecButton); m_localizedDecimalAutomationFormat = AppResourceProvider::GetInstance().GetResourceString(CalculatorResourceKeys::DecButton);
m_localizedOctalAutomationFormat = AppResourceProvider::GetInstance().GetResourceString(CalculatorResourceKeys::OctButton); m_localizedOctalAutomationFormat = AppResourceProvider::GetInstance().GetResourceString(CalculatorResourceKeys::OctButton);
m_localizedBinaryAutomationFormat = AppResourceProvider::GetInstance().GetResourceString(CalculatorResourceKeys::BinButton); m_localizedBinaryAutomationFormat = AppResourceProvider::GetInstance().GetResourceString(CalculatorResourceKeys::BinButton);
m_leftParenthesisAutomationFormat = AppResourceProvider::GetInstance().GetResourceString(CalculatorResourceKeys::LeftParenthesisAutomationFormat);
// Initialize the Automation Name // Initialize the Automation Name
CalculationResultAutomationName = GetLocalizedStringFormat(m_localizedCalculationResultAutomationFormat, m_DisplayValue); CalculationResultAutomationName = GetLocalizedStringFormat(m_localizedCalculationResultAutomationFormat, m_DisplayValue);
@ -216,19 +215,23 @@ void StandardCalculatorViewModel::DisplayPasteError()
m_standardCalculatorManager.DisplayPasteError(); m_standardCalculatorManager.DisplayPasteError();
} }
void StandardCalculatorViewModel::SetParenthesisCount(_In_ const wstring& parenthesisCount) void StandardCalculatorViewModel::SetParenthesisCount(_In_ unsigned int parenthesisCount)
{ {
if (m_OpenParenthesisCount == parenthesisCount)
{
return;
}
OpenParenthesisCount = parenthesisCount;
if (IsProgrammer || IsScientific) if (IsProgrammer || IsScientific)
{ {
OpenParenthesisCount = ref new String(parenthesisCount.c_str()); SetOpenParenthesisCountNarratorAnnouncement();
RaisePropertyChanged("LeftParenthesisAutomationName");
} }
} }
void StandardCalculatorViewModel::SetOpenParenthesisCountNarratorAnnouncement() void StandardCalculatorViewModel::SetOpenParenthesisCountNarratorAnnouncement()
{ {
String^ parenthesisCount = ((m_OpenParenthesisCount == nullptr) ? "0" : m_OpenParenthesisCount); wstring localizedParenthesisCount = to_wstring(m_OpenParenthesisCount).c_str();
wstring localizedParenthesisCount = parenthesisCount->Data();
LocalizationSettings::GetInstance().LocalizeDisplayValue(&localizedParenthesisCount); LocalizationSettings::GetInstance().LocalizeDisplayValue(&localizedParenthesisCount);
String^ announcement = LocalizationStringUtil::GetLocalizedNarratorAnnouncement( String^ announcement = LocalizationStringUtil::GetLocalizedNarratorAnnouncement(
@ -281,15 +284,6 @@ void StandardCalculatorViewModel::DisableButtons(CommandType selectedExpressionC
} }
} }
String ^ StandardCalculatorViewModel::GetLeftParenthesisAutomationName()
{
String^ parenthesisCount = ((m_OpenParenthesisCount == nullptr) ? "0" : m_OpenParenthesisCount);
wstring localizedParenthesisCount = std::wstring(parenthesisCount->Data());
LocalizationSettings::GetInstance().LocalizeDisplayValue(&localizedParenthesisCount);
return GetLocalizedStringFormat(m_leftParenthesisAutomationFormat, ref new String(localizedParenthesisCount.c_str()));
}
void StandardCalculatorViewModel::SetExpressionDisplay(_Inout_ shared_ptr<CalculatorVector<pair<wstring, int>>> const &tokens, _Inout_ shared_ptr<CalculatorVector <shared_ptr<IExpressionCommand>>> const &commands) void StandardCalculatorViewModel::SetExpressionDisplay(_Inout_ shared_ptr<CalculatorVector<pair<wstring, int>>> const &tokens, _Inout_ shared_ptr<CalculatorVector <shared_ptr<IExpressionCommand>>> const &commands)
{ {
m_tokens = tokens; m_tokens = tokens;
@ -321,59 +315,67 @@ void StandardCalculatorViewModel::SetTokens(_Inout_ shared_ptr<CalculatorVector<
{ {
AreTokensUpdated = false; AreTokensUpdated = false;
if (m_ExpressionTokens == nullptr)
{
m_ExpressionTokens = ref new Vector<DisplayExpressionToken^>();
}
else
{
m_ExpressionTokens->Clear();
}
unsigned int nTokens = 0; unsigned int nTokens = 0;
tokens->GetSize(&nTokens); tokens->GetSize(&nTokens);
if (nTokens == 0)
{
m_ExpressionTokens->Clear();
return;
}
pair <wstring, int> currentToken; pair <wstring, int> currentToken;
const auto& localizer = LocalizationSettings::GetInstance(); const auto& localizer = LocalizationSettings::GetInstance();
const wstring separator = L" ";
for (unsigned int i = 0; i < nTokens; ++i) for (unsigned int i = 0; i < nTokens; ++i)
{ {
if (SUCCEEDED(tokens->GetAt(i, &currentToken))) if (SUCCEEDED(tokens->GetAt(i, &currentToken)))
{ {
Common::TokenType type; Common::TokenType type;
const wstring separator = L" ";
bool isEditable = (currentToken.second == -1) ? false : true; bool isEditable = (currentToken.second == -1) ? false : true;
localizer.LocalizeDisplayValue(&(currentToken.first)); localizer.LocalizeDisplayValue(&(currentToken.first));
if (!isEditable) if (!isEditable)
{ {
if (currentToken.first == separator) type = currentToken.first == separator ? TokenType::Separator : TokenType::Operator;
{
type = TokenType::Separator;
}
else
{
type = TokenType::Operator;
}
} }
else else
{ {
shared_ptr<IExpressionCommand> command; shared_ptr<IExpressionCommand> command;
IFTPlatformException(m_commands->GetAt(static_cast<unsigned int>(currentToken.second), &command)); IFTPlatformException(m_commands->GetAt(static_cast<unsigned int>(currentToken.second), &command));
type = command->GetCommandType() == CommandType::OperandCommand ? TokenType::Operand : TokenType::Operator;
}
if (command->GetCommandType() == CommandType::OperandCommand) auto currentTokenString = ref new String(currentToken.first.c_str());
if (i < m_ExpressionTokens->Size)
{
auto existingItem = m_ExpressionTokens->GetAt(i);
if (type == existingItem->Type && existingItem->Token->Equals(currentTokenString))
{ {
type = TokenType::Operand; existingItem->TokenPosition = i;
existingItem->IsTokenEditable = isEditable;
existingItem->CommandIndex = 0;
} }
else else
{ {
type = TokenType::Operator; auto expressionToken = ref new DisplayExpressionToken(currentTokenString, i, isEditable, type);
m_ExpressionTokens->InsertAt(i, expressionToken);
} }
}
else
{
auto expressionToken = ref new DisplayExpressionToken(currentTokenString, i, isEditable, type);
m_ExpressionTokens->Append(expressionToken);
} }
DisplayExpressionToken^ expressionToken = ref new DisplayExpressionToken(ref new String(currentToken.first.c_str()), i, isEditable, type);
m_ExpressionTokens->Append(expressionToken);
} }
} }
while (m_ExpressionTokens->Size != nTokens)
{
m_ExpressionTokens->RemoveAtEnd();
}
} }
String^ StandardCalculatorViewModel::GetCalculatorExpressionAutomationName() String^ StandardCalculatorViewModel::GetCalculatorExpressionAutomationName()
@ -531,7 +533,7 @@ void StandardCalculatorViewModel::HandleUpdatedOperandData(Command cmdenum)
{ {
if (commandIndex == 0) if (commandIndex == 0)
{ {
delete [] temp; delete[] temp;
return; return;
} }
@ -552,7 +554,7 @@ void StandardCalculatorViewModel::HandleUpdatedOperandData(Command cmdenum)
length = m_selectedExpressionLastData->Length() + 1; length = m_selectedExpressionLastData->Length() + 1;
if (length > 50) if (length > 50)
{ {
delete [] temp; delete[] temp;
return; return;
} }
for (; i < length; ++i) for (; i < length; ++i)
@ -1427,29 +1429,29 @@ void StandardCalculatorViewModel::SaveEditedCommand(_In_ unsigned int tokenPosit
switch (nOpCode) switch (nOpCode)
{ {
case static_cast<int>(Command::CommandASIN) : case static_cast<int>(Command::CommandASIN) :
updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandSIN), true, angleType); updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandSIN), true, angleType);
break; break;
case static_cast<int>(Command::CommandACOS) : case static_cast<int>(Command::CommandACOS) :
updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandCOS), true, angleType); updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandCOS), true, angleType);
break; break;
case static_cast<int>(Command::CommandATAN) : case static_cast<int>(Command::CommandATAN) :
updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandTAN), true, angleType); updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandTAN), true, angleType);
break; break;
case static_cast<int>(Command::CommandASINH) : case static_cast<int>(Command::CommandASINH) :
updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandSINH), true, angleType); updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandSINH), true, angleType);
break; break;
case static_cast<int>(Command::CommandACOSH) : case static_cast<int>(Command::CommandACOSH) :
updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandCOSH), true, angleType); updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandCOSH), true, angleType);
break; break;
case static_cast<int>(Command::CommandATANH) : case static_cast<int>(Command::CommandATANH) :
updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandTANH), true, angleType); updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandTANH), true, angleType);
break; break;
case static_cast<int>(Command::CommandPOWE) : case static_cast<int>(Command::CommandPOWE) :
updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandLN), true, angleType); updatedToken = CCalcEngine::OpCodeToUnaryString(static_cast<int>(Command::CommandLN), true, angleType);
break; break;
default: default:
updatedToken = CCalcEngine::OpCodeToUnaryString(nOpCode, false, angleType); updatedToken = CCalcEngine::OpCodeToUnaryString(nOpCode, false, angleType);
} }
if ((token.first.length() > 0) && (token.first[token.first.length() - 1] == L'(')) if ((token.first.length() > 0) && (token.first[token.first.length() - 1] == L'('))
{ {

View file

@ -48,7 +48,7 @@ namespace CalculatorApp
OBSERVABLE_NAMED_PROPERTY_RW(bool, IsInError); OBSERVABLE_NAMED_PROPERTY_RW(bool, IsInError);
OBSERVABLE_PROPERTY_RW(bool, IsOperatorCommand); OBSERVABLE_PROPERTY_RW(bool, IsOperatorCommand);
OBSERVABLE_PROPERTY_RW(Platform::String^, DisplayStringExpression); OBSERVABLE_PROPERTY_RW(Platform::String^, DisplayStringExpression);
OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IVector<Common::DisplayExpressionToken^>^, ExpressionTokens); OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IObservableVector<Common::DisplayExpressionToken^>^, ExpressionTokens);
OBSERVABLE_PROPERTY_RW(Platform::String^, DecimalDisplayValue); OBSERVABLE_PROPERTY_RW(Platform::String^, DecimalDisplayValue);
OBSERVABLE_PROPERTY_RW(Platform::String^, HexDisplayValue); OBSERVABLE_PROPERTY_RW(Platform::String^, HexDisplayValue);
OBSERVABLE_PROPERTY_RW(Platform::String^, OctalDisplayValue); OBSERVABLE_PROPERTY_RW(Platform::String^, OctalDisplayValue);
@ -75,18 +75,17 @@ namespace CalculatorApp
OBSERVABLE_PROPERTY_RW(bool, IsDwordEnabled); OBSERVABLE_PROPERTY_RW(bool, IsDwordEnabled);
OBSERVABLE_PROPERTY_RW(bool, IsWordEnabled); OBSERVABLE_PROPERTY_RW(bool, IsWordEnabled);
OBSERVABLE_PROPERTY_RW(bool, IsByteEnabled); OBSERVABLE_PROPERTY_RW(bool, IsByteEnabled);
OBSERVABLE_NAMED_PROPERTY_RW(Platform::String^, OpenParenthesisCount);
OBSERVABLE_PROPERTY_RW(int, CurrentRadixType); OBSERVABLE_PROPERTY_RW(int, CurrentRadixType);
OBSERVABLE_PROPERTY_RW(bool, AreTokensUpdated); OBSERVABLE_PROPERTY_RW(bool, AreTokensUpdated);
OBSERVABLE_PROPERTY_RW(bool, AreHistoryShortcutsEnabled); OBSERVABLE_PROPERTY_RW(bool, AreHistoryShortcutsEnabled);
OBSERVABLE_PROPERTY_RW(bool, AreProgrammerRadixOperatorsEnabled); OBSERVABLE_PROPERTY_RW(bool, AreProgrammerRadixOperatorsEnabled);
OBSERVABLE_PROPERTY_RW(CalculatorApp::Common::Automation::NarratorAnnouncement^, Announcement); OBSERVABLE_PROPERTY_RW(CalculatorApp::Common::Automation::NarratorAnnouncement^, Announcement);
OBSERVABLE_PROPERTY_R(unsigned int, OpenParenthesisCount);
COMMAND_FOR_METHOD(CopyCommand, StandardCalculatorViewModel::OnCopyCommand); COMMAND_FOR_METHOD(CopyCommand, StandardCalculatorViewModel::OnCopyCommand);
COMMAND_FOR_METHOD(PasteCommand, StandardCalculatorViewModel::OnPasteCommand); COMMAND_FOR_METHOD(PasteCommand, StandardCalculatorViewModel::OnPasteCommand);
COMMAND_FOR_METHOD(ButtonPressed, StandardCalculatorViewModel::OnButtonPressed); COMMAND_FOR_METHOD(ButtonPressed, StandardCalculatorViewModel::OnButtonPressed);
COMMAND_FOR_METHOD(ClearMemoryCommand, StandardCalculatorViewModel::OnClearMemoryCommand); COMMAND_FOR_METHOD(ClearMemoryCommand, StandardCalculatorViewModel::OnClearMemoryCommand);
COMMAND_FOR_METHOD(PinUnpinAppBarButtonOnClicked, StandardCalculatorViewModel::OnPinUnpinCommand);
COMMAND_FOR_METHOD(MemoryItemPressed, StandardCalculatorViewModel::OnMemoryItemPressed); COMMAND_FOR_METHOD(MemoryItemPressed, StandardCalculatorViewModel::OnMemoryItemPressed);
COMMAND_FOR_METHOD(MemoryAdd, StandardCalculatorViewModel::OnMemoryAdd); COMMAND_FOR_METHOD(MemoryAdd, StandardCalculatorViewModel::OnMemoryAdd);
COMMAND_FOR_METHOD(MemorySubtract, StandardCalculatorViewModel::OnMemorySubtract); COMMAND_FOR_METHOD(MemorySubtract, StandardCalculatorViewModel::OnMemorySubtract);
@ -255,14 +254,6 @@ namespace CalculatorApp
void set(bool value) { m_completeTextSelection = value; } void set(bool value) { m_completeTextSelection = value; }
} }
property Platform::String^ LeftParenthesisAutomationName
{
Platform::String^ get()
{
return GetLeftParenthesisAutomationName();
}
}
internal: internal:
void OnPaste(Platform::String^ pastedString, CalculatorApp::Common::ViewMode mode); void OnPaste(Platform::String^ pastedString, CalculatorApp::Common::ViewMode mode);
void OnCopyCommand(Platform::Object^ parameter); void OnCopyCommand(Platform::Object^ parameter);
@ -283,7 +274,7 @@ namespace CalculatorApp
void SetTokens(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens); void SetTokens(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens);
void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands); void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands);
void SetHistoryExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector <std::shared_ptr<IExpressionCommand>>> const &commands); void SetHistoryExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector <std::shared_ptr<IExpressionCommand>>> const &commands);
void SetParenthesisCount(_In_ const std::wstring& parenthesisCount); void SetParenthesisCount(_In_ unsigned int parenthesisCount);
void SetOpenParenthesisCountNarratorAnnouncement(); void SetOpenParenthesisCountNarratorAnnouncement();
void OnNoRightParenAdded(); void OnNoRightParenAdded();
void SetNoParenAddedNarratorAnnouncement(); void SetNoParenAddedNarratorAnnouncement();
@ -354,7 +345,6 @@ namespace CalculatorApp
bool m_isLastOperationHistoryLoad; bool m_isLastOperationHistoryLoad;
Platform::String^ m_selectedExpressionLastData; Platform::String^ m_selectedExpressionLastData;
Common::DisplayExpressionToken^ m_selectedExpressionToken; Common::DisplayExpressionToken^ m_selectedExpressionToken;
Platform::String^ m_leftParenthesisAutomationFormat;
Platform::String^ LocalizeDisplayValue(_In_ std::wstring const &displayValue, _In_ bool isError); Platform::String^ LocalizeDisplayValue(_In_ std::wstring const &displayValue, _In_ bool isError);
Platform::String^ CalculateNarratorDisplayValue(_In_ std::wstring const &displayValue, _In_ Platform::String^ localizedDisplayValue, _In_ bool isError); Platform::String^ CalculateNarratorDisplayValue(_In_ std::wstring const &displayValue, _In_ Platform::String^ localizedDisplayValue, _In_ bool isError);
@ -364,7 +354,6 @@ namespace CalculatorApp
CalculationManager::Command ConvertToOperatorsEnum(NumbersAndOperatorsEnum operation); CalculationManager::Command ConvertToOperatorsEnum(NumbersAndOperatorsEnum operation);
void DisableButtons(CalculationManager::CommandType selectedExpressionCommandType); void DisableButtons(CalculationManager::CommandType selectedExpressionCommandType);
Platform::String^ GetLeftParenthesisAutomationName();
Platform::String^ m_feedbackForButtonPress; Platform::String^ m_feedbackForButtonPress;
void OnButtonPressed(Platform::Object^ parameter); void OnButtonPressed(Platform::Object^ parameter);

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#include "pch.h" #include "pch.h"
@ -165,12 +165,16 @@ void UnitConverterViewModel::PopulateData()
} }
void UnitConverterViewModel::OnCategoryChanged(Object^ parameter) void UnitConverterViewModel::OnCategoryChanged(Object^ parameter)
{
m_model->SendCommand(UCM::Command::Clear);
ResetCategory();
}
void UnitConverterViewModel::ResetCategory()
{ {
UCM::Category currentCategory = CurrentCategory->GetModelCategory(); UCM::Category currentCategory = CurrentCategory->GetModelCategory();
IsCurrencyCurrentCategory = currentCategory.id == NavCategory::Serialize(ViewMode::Currency); IsCurrencyCurrentCategory = currentCategory.id == NavCategory::Serialize(ViewMode::Currency);
m_model->SendCommand(UCM::Command::Clear);
m_isInputBlocked = false; m_isInputBlocked = false;
SetSelectedUnits(); SetSelectedUnits();
@ -394,7 +398,7 @@ String^ UnitConverterViewModel::ConvertToLocalizedString(const std::wstring& str
void UnitConverterViewModel::DisplayPasteError() void UnitConverterViewModel::DisplayPasteError()
{ {
String^ errorMsg = AppResourceProvider::GetInstance().GetCEngineString(SIDS_DOMAIN); /*SIDS_DOMAIN is for "invalid input"*/ String^ errorMsg = AppResourceProvider::GetInstance().GetCEngineString(StringReference(SIDS_DOMAIN)); /*SIDS_DOMAIN is for "invalid input"*/
Value1 = errorMsg; Value1 = errorMsg;
Value2 = errorMsg; Value2 = errorMsg;
m_relocalizeStringOnSwitch = false; m_relocalizeStringOnSwitch = false;
@ -706,7 +710,9 @@ void UnitConverterViewModel::OnCurrencyDataLoadFinished(bool didLoad)
{ {
m_isCurrencyDataLoaded = true; m_isCurrencyDataLoaded = true;
CurrencyDataLoadFailed = !didLoad; CurrencyDataLoadFailed = !didLoad;
ResetView(); m_model->ResetCategoriesAndRatios();
m_model->Calculate();
ResetCategory();
StringReference key = didLoad ? UnitConverterResourceKeys::CurrencyRatesUpdated : UnitConverterResourceKeys::CurrencyRatesUpdateFailed; StringReference key = didLoad ? UnitConverterResourceKeys::CurrencyRatesUpdated : UnitConverterResourceKeys::CurrencyRatesUpdateFailed;
String^ announcement = AppResourceProvider::GetInstance().GetResourceString(key); String^ announcement = AppResourceProvider::GetInstance().GetResourceString(key);

View file

@ -223,6 +223,7 @@ namespace CalculatorApp
void UpdateValue2AutomationName(); void UpdateValue2AutomationName();
Platform::String^ Serialize(); Platform::String^ Serialize();
void Deserialize(Platform::String^ state); void Deserialize(Platform::String^ state);
void ResetCategoriesAndRatio();
// Saving And Restoring User Preferences of Category and Associated-Units across Sessions. // Saving And Restoring User Preferences of Category and Associated-Units across Sessions.
void SaveUserPreferences(); void SaveUserPreferences();
@ -263,6 +264,7 @@ namespace CalculatorApp
void RefreshSupplementaryResults(); void RefreshSupplementaryResults();
void UpdateInputBlocked(_In_ const std::wstring& currencyInput); void UpdateInputBlocked(_In_ const std::wstring& currencyInput);
bool UnitsAreValid(); bool UnitsAreValid();
void ResetCategory();
void OnButtonPressed(Platform::Object^ parameter); void OnButtonPressed(Platform::Object^ parameter);
Platform::String^ ConvertToLocalizedString(const std::wstring& stringToLocalize, bool allowPartialStrings); Platform::String^ ConvertToLocalizedString(const std::wstring& stringToLocalize, bool allowPartialStrings);

View file

@ -19,7 +19,6 @@
<Color x:Key="ChromeMediumLowColor">#FF2B2B2B</Color> <Color x:Key="ChromeMediumLowColor">#FF2B2B2B</Color>
<SolidColorBrush x:Key="SystemControlBackgroundAltHighBrush" Color="{StaticResource AltHighColor}"/> <SolidColorBrush x:Key="SystemControlBackgroundAltHighBrush" Color="{StaticResource AltHighColor}"/>
<SolidColorBrush x:Key="SystemControlBackgroundChromeMediumLowBrush" Color="{StaticResource ChromeMediumLowColor}"/> <SolidColorBrush x:Key="SystemControlBackgroundChromeMediumLowBrush" Color="{StaticResource ChromeMediumLowColor}"/>
<SolidColorBrush x:Key="TitleBarBackgroundTransparentBrush" Color="Transparent"/>
<SolidColorBrush x:Key="TitleBarForegroundBaseHighBrush" Color="{StaticResource SystemBaseHighColor}"/> <SolidColorBrush x:Key="TitleBarForegroundBaseHighBrush" Color="{StaticResource SystemBaseHighColor}"/>
<SolidColorBrush x:Key="SystemControlBackgroundTransparentBrush" Color="Transparent"/> <SolidColorBrush x:Key="SystemControlBackgroundTransparentBrush" Color="Transparent"/>
<SolidColorBrush x:Key="SystemControlHighlightTransparentBrush" Color="Transparent"/> <SolidColorBrush x:Key="SystemControlHighlightTransparentBrush" Color="Transparent"/>
@ -34,7 +33,11 @@
FallbackColor="Transparent" FallbackColor="Transparent"
TargetTheme="Dark" TargetTheme="Dark"
Color="Transparent"/> Color="Transparent"/>
<RevealBackgroundBrush x:Key="AppControlHighlightAltListAccentHighRevealBackgroundBrush" <RevealBackgroundBrush x:Key="AppControlHighlightAccentRevealBackgroundBrush"
FallbackColor="{ThemeResource SystemAccentColor}"
TargetTheme="Dark"
Color="{ThemeResource SystemAccentColor}"/>
<RevealBackgroundBrush x:Key="AppControlBackgroundListAccentHighRevealBackgroundBrush"
FallbackColor="{ThemeResource SystemAccentColorDark3}" FallbackColor="{ThemeResource SystemAccentColorDark3}"
TargetTheme="Dark" TargetTheme="Dark"
Color="{ThemeResource SystemAccentColorDark3}"/> Color="{ThemeResource SystemAccentColorDark3}"/>
@ -51,7 +54,6 @@
<Color x:Key="ChromeMediumLowColor">#FFE0E0E0</Color> <Color x:Key="ChromeMediumLowColor">#FFE0E0E0</Color>
<SolidColorBrush x:Key="SystemControlBackgroundAltHighBrush" Color="{StaticResource SystemAltHighColor}"/> <SolidColorBrush x:Key="SystemControlBackgroundAltHighBrush" Color="{StaticResource SystemAltHighColor}"/>
<SolidColorBrush x:Key="SystemControlBackgroundChromeMediumLowBrush" Color="{StaticResource ChromeMediumLowColor}"/> <SolidColorBrush x:Key="SystemControlBackgroundChromeMediumLowBrush" Color="{StaticResource ChromeMediumLowColor}"/>
<SolidColorBrush x:Key="TitleBarBackgroundTransparentBrush" Color="Transparent"/>
<SolidColorBrush x:Key="TitleBarForegroundBaseHighBrush" Color="{StaticResource SystemBaseHighColor}"/> <SolidColorBrush x:Key="TitleBarForegroundBaseHighBrush" Color="{StaticResource SystemBaseHighColor}"/>
<SolidColorBrush x:Key="SystemControlBackgroundTransparentBrush" Color="Transparent"/> <SolidColorBrush x:Key="SystemControlBackgroundTransparentBrush" Color="Transparent"/>
<SolidColorBrush x:Key="SystemControlHighlightTransparentBrush" Color="Transparent"/> <SolidColorBrush x:Key="SystemControlHighlightTransparentBrush" Color="Transparent"/>
@ -66,7 +68,11 @@
FallbackColor="Transparent" FallbackColor="Transparent"
TargetTheme="Light" TargetTheme="Light"
Color="Transparent"/> Color="Transparent"/>
<RevealBackgroundBrush x:Key="AppControlHighlightAltListAccentHighRevealBackgroundBrush" <RevealBackgroundBrush x:Key="AppControlHighlightAccentRevealBackgroundBrush"
FallbackColor="{ThemeResource SystemAccentColor}"
TargetTheme="Light"
Color="{ThemeResource SystemAccentColor}"/>
<RevealBackgroundBrush x:Key="AppControlBackgroundListAccentHighRevealBackgroundBrush"
FallbackColor="{ThemeResource SystemAccentColorLight3}" FallbackColor="{ThemeResource SystemAccentColorLight3}"
TargetTheme="Light" TargetTheme="Light"
Color="{ThemeResource SystemAccentColorLight3}"/> Color="{ThemeResource SystemAccentColorLight3}"/>
@ -81,7 +87,6 @@
<x:Double x:Key="HighContrastStrokeThickness">2</x:Double> <x:Double x:Key="HighContrastStrokeThickness">2</x:Double>
<SolidColorBrush x:Key="SystemControlBackgroundAltHighBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/> <SolidColorBrush x:Key="SystemControlBackgroundAltHighBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/>
<SolidColorBrush x:Key="SystemControlBackgroundChromeMediumLowBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/> <SolidColorBrush x:Key="SystemControlBackgroundChromeMediumLowBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/>
<SolidColorBrush x:Key="TitleBarBackgroundTransparentBrush" Color="{ThemeResource SystemColorActiveCaptionColor}"/>
<SolidColorBrush x:Key="TitleBarForegroundBaseHighBrush" Color="{ThemeResource SystemColorCaptionTextColor}"/> <SolidColorBrush x:Key="TitleBarForegroundBaseHighBrush" Color="{ThemeResource SystemColorCaptionTextColor}"/>
<SolidColorBrush x:Key="SystemControlBackgroundTransparentBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/> <SolidColorBrush x:Key="SystemControlBackgroundTransparentBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/>
<SolidColorBrush x:Key="SystemControlHighlightTransparentBrush" Color="{ThemeResource SystemColorHighlightColor}"/> <SolidColorBrush x:Key="SystemControlHighlightTransparentBrush" Color="{ThemeResource SystemColorHighlightColor}"/>
@ -93,7 +98,8 @@
<SolidColorBrush x:Key="AppControlPageTextBaseHighColorBrush" Color="{ThemeResource SystemColorWindowTextColor}"/> <SolidColorBrush x:Key="AppControlPageTextBaseHighColorBrush" Color="{ThemeResource SystemColorWindowTextColor}"/>
<SolidColorBrush x:Key="AppControlPageTextRedColorBrush" Color="{ThemeResource SystemColorWindowTextColor}"/> <SolidColorBrush x:Key="AppControlPageTextRedColorBrush" Color="{ThemeResource SystemColorWindowTextColor}"/>
<SolidColorBrush x:Key="AppControlForegroundTransparentRevealBorderBrush" Color="{ThemeResource SystemColorButtonTextColor}"/> <SolidColorBrush x:Key="AppControlForegroundTransparentRevealBorderBrush" Color="{ThemeResource SystemColorButtonTextColor}"/>
<SolidColorBrush x:Key="AppControlHighlightAltListAccentHighRevealBackgroundBrush" Color="{ThemeResource SystemColorHighlightTextColor}"/> <SolidColorBrush x:Key="AppControlHighlightAccentRevealBackgroundBrush" Color="{ThemeResource SystemColorHighlightColor}"/>
<SolidColorBrush x:Key="AppControlBackgroundListAccentHighRevealBackgroundBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/>
<SolidColorBrush x:Key="AppControlListLowRevealHighlightBrush" Color="{ThemeResource SystemColorHighlightColor}"/> <SolidColorBrush x:Key="AppControlListLowRevealHighlightBrush" Color="{ThemeResource SystemColorHighlightColor}"/>
<SolidColorBrush x:Key="AppChromeAcrylicHostBackdropMediumLowBrush" Color="{ThemeResource SystemColorWindowColor}"/> <SolidColorBrush x:Key="AppChromeAcrylicHostBackdropMediumLowBrush" Color="{ThemeResource SystemColorWindowColor}"/>
</ResourceDictionary> </ResourceDictionary>
@ -125,10 +131,6 @@
<!-- Standard Operators Standard/Scientific in Fill/Full --> <!-- Standard Operators Standard/Scientific in Fill/Full -->
<x:Double x:Key="CalcOperatorCaptionSize">15</x:Double> <x:Double x:Key="CalcOperatorCaptionSize">15</x:Double>
<x:Double x:Key="CalcResultFontSizeL">72</x:Double>
<x:Double x:Key="CalcResultFontSizeM">46</x:Double>
<x:Double x:Key="CalcResultFontSizeS">28</x:Double>
<!-- Base style for calc buttons --> <!-- Base style for calc buttons -->
<Style x:Key="CalcButtonStyle" TargetType="Controls:CalculatorButton"> <Style x:Key="CalcButtonStyle" TargetType="Controls:CalculatorButton">
<Setter Property="MinWidth" Value="24"/> <Setter Property="MinWidth" Value="24"/>
@ -326,9 +328,9 @@
<Style x:Key="AccentCalcButtonStyle" <Style x:Key="AccentCalcButtonStyle"
BasedOn="{StaticResource SymbolOperatorButtonStyle}" BasedOn="{StaticResource SymbolOperatorButtonStyle}"
TargetType="Controls:CalculatorButton"> TargetType="Controls:CalculatorButton">
<Setter Property="HoverBackground" Value="{ThemeResource SystemControlHighlightAccentRevealBackgroundBrush}"/> <Setter Property="HoverBackground" Value="{ThemeResource AppControlHighlightAccentRevealBackgroundBrush}"/>
<Setter Property="HoverForeground" Value="{ThemeResource SystemControlHighlightAltAltHighBrush}"/> <Setter Property="HoverForeground" Value="{ThemeResource SystemControlHighlightAltAltHighBrush}"/>
<Setter Property="PressBackground" Value="{ThemeResource AppControlHighlightAltListAccentHighRevealBackgroundBrush}"/> <Setter Property="PressBackground" Value="{ThemeResource AppControlBackgroundListAccentHighRevealBackgroundBrush}"/>
<Setter Property="PressForeground" Value="{ThemeResource SystemControlHighlightAltAltHighBrush}"/> <Setter Property="PressForeground" Value="{ThemeResource SystemControlHighlightAltAltHighBrush}"/>
</Style> </Style>
@ -351,7 +353,8 @@
<Setter Property="ZoomMode" Value="Disabled"/> <Setter Property="ZoomMode" Value="Disabled"/>
</Style> </Style>
<Style x:Key="CalculationResultStyleL" TargetType="Controls:CalculationResult"> <Style x:Key="CalculationResultStyle"
TargetType="Controls:CalculationResult">
<Setter Property="Background" Value="Transparent"/> <Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlPageTextBaseHighBrush}"/> <Setter Property="Foreground" Value="{ThemeResource SystemControlPageTextBaseHighBrush}"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/> <Setter Property="HorizontalAlignment" Value="Stretch"/>
@ -363,7 +366,7 @@
<Setter Property="Template"> <Setter Property="Template">
<Setter.Value> <Setter.Value>
<ControlTemplate TargetType="Controls:CalculationResult"> <ControlTemplate TargetType="Controls:CalculationResult">
<Grid x:Name="border" Background="{TemplateBinding Background}"> <Grid x:Name="Border" Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="12"/> <ColumnDefinition Width="12"/>
<ColumnDefinition/> <ColumnDefinition/>
@ -373,19 +376,19 @@
<VisualStateGroup x:Name="ActiveStates"> <VisualStateGroup x:Name="ActiveStates">
<VisualState x:Name="Active"> <VisualState x:Name="Active">
<VisualState.Setters> <VisualState.Setters>
<Setter Target="normalOutput.FontWeight" Value="SemiBold"/> <Setter Target="NormalOutput.FontWeight" Value="SemiBold"/>
<Setter Target="normalOutput.IsTextSelectionEnabled" Value="True"/> <Setter Target="NormalOutput.IsTextSelectionEnabled" Value="True"/>
</VisualState.Setters> </VisualState.Setters>
</VisualState> </VisualState>
<VisualState x:Name="Normal"/> <VisualState x:Name="Normal"/>
</VisualStateGroup> </VisualStateGroup>
</VisualStateManager.VisualStateGroups> </VisualStateManager.VisualStateGroups>
<ScrollViewer x:Name="textContainer" <ScrollViewer x:Name="TextContainer"
Grid.Column="1" Grid.Column="1"
Padding="0,0,0,0" Padding="0,0,0,0"
Style="{ThemeResource ResultsScrollerSnapped}" Style="{ThemeResource ResultsScrollerSnapped}"
AutomationProperties.AccessibilityView="Raw"> AutomationProperties.AccessibilityView="Raw">
<TextBlock x:Name="normalOutput" <TextBlock x:Name="NormalOutput"
Margin="{TemplateBinding DisplayMargin}" Margin="{TemplateBinding DisplayMargin}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
@ -397,7 +400,7 @@
TextAlignment="{TemplateBinding HorizontalContentAlignment}" TextAlignment="{TemplateBinding HorizontalContentAlignment}"
TextWrapping="NoWrap"/> TextWrapping="NoWrap"/>
</ScrollViewer> </ScrollViewer>
<HyperlinkButton x:Name="scrollLeft" <HyperlinkButton x:Name="ScrollLeft"
Grid.Column="0" Grid.Column="0"
Width="20" Width="20"
MinWidth="20" MinWidth="20"
@ -410,12 +413,12 @@
Foreground="{ThemeResource SystemControlForegroundAccentBrush}" Foreground="{ThemeResource SystemControlForegroundAccentBrush}"
BorderThickness="0" BorderThickness="0"
Visibility="Collapsed"> Visibility="Collapsed">
<FontIcon x:Name="scrollLeftText" <FontIcon x:Name="ScrollLeftText"
FontFamily="{ThemeResource SymbolThemeFontFamily}" FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12" FontSize="12"
Glyph="&#xE26C;"/> Glyph="&#xE26C;"/>
</HyperlinkButton> </HyperlinkButton>
<HyperlinkButton x:Name="scrollRight" <HyperlinkButton x:Name="ScrollRight"
Grid.Column="2" Grid.Column="2"
Width="20" Width="20"
MinWidth="20" MinWidth="20"
@ -428,182 +431,7 @@
Foreground="{ThemeResource SystemControlForegroundAccentBrush}" Foreground="{ThemeResource SystemControlForegroundAccentBrush}"
BorderThickness="0" BorderThickness="0"
Visibility="Collapsed"> Visibility="Collapsed">
<FontIcon x:Name="scrollRightText" <FontIcon x:Name="ScrollRightText"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12"
Glyph="&#xE26B;"/>
</HyperlinkButton>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="CalculationResultStyleM" TargetType="Controls:CalculationResult">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlPageTextBaseHighBrush}"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Right"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="IsTextScaleFactorEnabled" Value="False"/>
<Setter Property="UseSystemFocusVisuals" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Controls:CalculationResult">
<Grid x:Name="border" Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="12"/>
<ColumnDefinition/>
<ColumnDefinition Width="12"/>
</Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ActiveStates">
<VisualState x:Name="Active">
<VisualState.Setters>
<Setter Target="normalOutput.IsTextSelectionEnabled" Value="True"/>
<Setter Target="normalOutput.FontWeight" Value="SemiBold"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Normal"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ScrollViewer x:Name="textContainer"
Grid.Column="1"
Padding="0,0,0,0"
Style="{ThemeResource ResultsScrollerSnapped}"
AutomationProperties.AccessibilityView="Raw">
<TextBlock x:Name="normalOutput"
Margin="{TemplateBinding DisplayMargin}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Foreground="{TemplateBinding Foreground}"
FontSize="{TemplateBinding FontSize}"
FontWeight="Light"
AutomationProperties.AccessibilityView="Raw"
Text="{TemplateBinding DisplayValue}"
TextAlignment="{TemplateBinding HorizontalContentAlignment}"
TextWrapping="NoWrap"/>
</ScrollViewer>
<HyperlinkButton x:Name="scrollLeft"
Grid.Column="0"
Width="20"
MinWidth="20"
MinHeight="24"
Margin="-4,0,-4,0"
Padding="0,-3,0,4"
VerticalAlignment="Top"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Foreground="{ThemeResource SystemControlForegroundAccentBrush}"
BorderThickness="0"
Visibility="Collapsed">
<FontIcon x:Name="scrollLeftText"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12"
Glyph="&#xE26C;"/>
</HyperlinkButton>
<HyperlinkButton x:Name="scrollRight"
Grid.Column="2"
Width="20"
MinWidth="20"
MinHeight="24"
Margin="-4,0,-4,0"
Padding="0,-3,0,4"
VerticalAlignment="Top"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Foreground="{ThemeResource SystemControlForegroundAccentBrush}"
BorderThickness="0"
Visibility="Collapsed">
<FontIcon x:Name="scrollRightText"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12"
Glyph="&#xE26B;"/>
</HyperlinkButton>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="CalculationResultStyleS" TargetType="Controls:CalculationResult">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlPageTextBaseHighBrush}"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Right"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="MinHeight" Value="12"/>
<Setter Property="IsTextScaleFactorEnabled" Value="False"/>
<Setter Property="UseSystemFocusVisuals" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Controls:CalculationResult">
<Grid x:Name="border" Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="12"/>
<ColumnDefinition/>
<ColumnDefinition Width="12"/>
</Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ActiveStates">
<VisualState x:Name="Active">
<VisualState.Setters>
<Setter Target="normalOutput.FontWeight" Value="SemiBold"/>
<Setter Target="normalOutput.IsTextSelectionEnabled" Value="True"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Normal"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ScrollViewer x:Name="textContainer"
Grid.Column="1"
Padding="0,0,0,0"
Style="{ThemeResource ResultsScrollerSnapped}"
AutomationProperties.AccessibilityView="Raw">
<TextBlock x:Name="normalOutput"
Margin="{TemplateBinding DisplayMargin}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Foreground="{TemplateBinding Foreground}"
FontSize="{TemplateBinding FontSize}"
FontWeight="Light"
AutomationProperties.AccessibilityView="Raw"
Text="{TemplateBinding DisplayValue}"
TextAlignment="{TemplateBinding HorizontalContentAlignment}"
TextWrapping="NoWrap"/>
</ScrollViewer>
<HyperlinkButton x:Name="scrollLeft"
Grid.Column="0"
Width="20"
MinWidth="20"
MinHeight="24"
Margin="-4,0,-4,0"
Padding="0,-3,0,4"
VerticalAlignment="Top"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Foreground="{ThemeResource SystemControlForegroundAccentBrush}"
BorderThickness="0"
Visibility="Collapsed">
<FontIcon x:Name="scrollLeftText"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12"
Glyph="&#xE26C;"/>
</HyperlinkButton>
<HyperlinkButton x:Name="scrollRight"
Grid.Column="2"
Width="20"
MinWidth="20"
MinHeight="24"
Margin="-4,0,-4,0"
Padding="0,-3,0,4"
VerticalAlignment="Top"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Foreground="{ThemeResource SystemControlForegroundAccentBrush}"
BorderThickness="0"
Visibility="Collapsed">
<FontIcon x:Name="scrollRightText"
FontFamily="{ThemeResource SymbolThemeFontFamily}" FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12" FontSize="12"
Glyph="&#xE26B;"/> Glyph="&#xE26B;"/>
@ -701,7 +529,7 @@
<VisualState x:Name="Pressed"> <VisualState x:Name="Pressed">
<VisualState.Setters> <VisualState.Setters>
<Setter Target="RootGrid.(RevealBrush.State)" Value="Pressed"/> <Setter Target="RootGrid.(RevealBrush.State)" Value="Pressed"/>
<Setter Target="RootGrid.Background" Value="{ThemeResource AppControlHighlightAltListAccentHighRevealBackgroundBrush}"/> <Setter Target="RootGrid.Background" Value="{ThemeResource AppControlBackgroundListAccentHighRevealBackgroundBrush}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource SystemControlHighlightAltAltHighBrush}"/> <Setter Target="ContentPresenter.Foreground" Value="{ThemeResource SystemControlHighlightAltAltHighBrush}"/>
</VisualState.Setters> </VisualState.Setters>
</VisualState> </VisualState>

View file

@ -233,12 +233,14 @@ void App::OnAppLaunch(IActivatedEventArgs^ args, String^ argument)
TraceLogger::GetInstance().LogOnAppLaunch(previousExecutionState.ToString()->Data()); TraceLogger::GetInstance().LogOnAppLaunch(previousExecutionState.ToString()->Data());
#if _DEBUG // Uncomment the following lines to display frame-rate and per-frame CPU usage info.
if (IsDebuggerPresent()) //#if _DEBUG
{ // if (IsDebuggerPresent())
DebugSettings->EnableFrameRateCounter = true; // {
} // DebugSettings->EnableFrameRateCounter = true;
#endif // }
//#endif
auto userSettings = ref new Windows::UI::ViewManagement::UISettings(); auto userSettings = ref new Windows::UI::ViewManagement::UISettings();
m_isAnimationEnabled = userSettings->AnimationsEnabled; m_isAnimationEnabled = userSettings->AnimationsEnabled;

View file

@ -234,19 +234,15 @@
<ClInclude Include="Controls\OverflowTextBlockAutomationPeer.h" /> <ClInclude Include="Controls\OverflowTextBlockAutomationPeer.h" />
<ClInclude Include="Common\AlwaysSelectedCollectionView.h" /> <ClInclude Include="Common\AlwaysSelectedCollectionView.h" />
<ClInclude Include="Common\BindableBase.h" /> <ClInclude Include="Common\BindableBase.h" />
<ClInclude Include="Controls\AppBar.h" />
<ClInclude Include="Controls\CalculationResult.h" /> <ClInclude Include="Controls\CalculationResult.h" />
<ClInclude Include="Controls\CalculatorButton.h" /> <ClInclude Include="Controls\CalculatorButton.h" />
<ClInclude Include="Controls\FlipButtons.h" /> <ClInclude Include="Controls\FlipButtons.h" />
<ClInclude Include="Controls\OperandTextBox.h" />
<ClInclude Include="Controls\OperatorTextBox.h" />
<ClInclude Include="Controls\OverflowTextBlock.h" /> <ClInclude Include="Controls\OverflowTextBlock.h" />
<ClInclude Include="Controls\RadixButton.h" /> <ClInclude Include="Controls\RadixButton.h" />
<ClInclude Include="Controls\SupplementaryItemsControl.h" /> <ClInclude Include="Controls\SupplementaryItemsControl.h" />
<ClInclude Include="Converters\BitFlipAutomationNameConverter.h" /> <ClInclude Include="Converters\BitFlipAutomationNameConverter.h" />
<ClInclude Include="Converters\BooleanNegationConverter.h" /> <ClInclude Include="Converters\BooleanNegationConverter.h" />
<ClInclude Include="Converters\BooleanToVisibilityConverter.h" /> <ClInclude Include="Converters\BooleanToVisibilityConverter.h" />
<ClInclude Include="Converters\ExpressionItemContainerStyle.h" />
<ClInclude Include="Converters\ExpressionItemTemplateSelector.h" /> <ClInclude Include="Converters\ExpressionItemTemplateSelector.h" />
<ClInclude Include="Converters\ItemSizeToVisibilityConverter.h" /> <ClInclude Include="Converters\ItemSizeToVisibilityConverter.h" />
<ClInclude Include="Converters\RadixToStringConverter.h" /> <ClInclude Include="Converters\RadixToStringConverter.h" />
@ -256,7 +252,6 @@
<ClInclude Include="App.xaml.h"> <ClInclude Include="App.xaml.h">
<DependentUpon>App.xaml</DependentUpon> <DependentUpon>App.xaml</DependentUpon>
</ClInclude> </ClInclude>
<ClInclude Include="Common\TitleBarHelper.h" />
<ClInclude Include="Views\Calculator.xaml.h"> <ClInclude Include="Views\Calculator.xaml.h">
<DependentUpon>Views\Calculator.xaml</DependentUpon> <DependentUpon>Views\Calculator.xaml</DependentUpon>
</ClInclude> </ClInclude>
@ -372,15 +367,12 @@
<ClCompile Include="Controls\CalculationResult.cpp" /> <ClCompile Include="Controls\CalculationResult.cpp" />
<ClCompile Include="Controls\CalculatorButton.cpp" /> <ClCompile Include="Controls\CalculatorButton.cpp" />
<ClCompile Include="Controls\FlipButtons.cpp" /> <ClCompile Include="Controls\FlipButtons.cpp" />
<ClCompile Include="Controls\OperandTextBox.cpp" />
<ClCompile Include="Controls\OperatorTextBox.cpp" />
<ClCompile Include="Controls\OverflowTextBlock.cpp" /> <ClCompile Include="Controls\OverflowTextBlock.cpp" />
<ClCompile Include="Controls\RadixButton.cpp" /> <ClCompile Include="Controls\RadixButton.cpp" />
<ClCompile Include="Controls\SupplementaryItemsControl.cpp" /> <ClCompile Include="Controls\SupplementaryItemsControl.cpp" />
<ClCompile Include="Converters\BitFlipAutomationNameConverter.cpp" /> <ClCompile Include="Converters\BitFlipAutomationNameConverter.cpp" />
<ClCompile Include="Converters\BooleanNegationConverter.cpp" /> <ClCompile Include="Converters\BooleanNegationConverter.cpp" />
<ClCompile Include="Converters\BooleanToVisibilityConverter.cpp" /> <ClCompile Include="Converters\BooleanToVisibilityConverter.cpp" />
<ClCompile Include="Converters\ExpressionItemContainerStyle.cpp" />
<ClCompile Include="Converters\ExpressionItemTemplateSelector.cpp" /> <ClCompile Include="Converters\ExpressionItemTemplateSelector.cpp" />
<ClCompile Include="Converters\ItemSizeToVisibilityConverter.cpp" /> <ClCompile Include="Converters\ItemSizeToVisibilityConverter.cpp" />
<ClCompile Include="Converters\RadixToStringConverter.cpp" /> <ClCompile Include="Converters\RadixToStringConverter.cpp" />
@ -396,7 +388,6 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile> </ClCompile>
<ClCompile Include="Common\TitleBarHelper.cpp" />
<ClCompile Include="Views\Calculator.xaml.cpp"> <ClCompile Include="Views\Calculator.xaml.cpp">
<DependentUpon>Views\Calculator.xaml</DependentUpon> <DependentUpon>Views\Calculator.xaml</DependentUpon>
</ClCompile> </ClCompile>

View file

@ -243,9 +243,6 @@
<ClCompile Include="Converters\BooleanToVisibilityConverter.cpp"> <ClCompile Include="Converters\BooleanToVisibilityConverter.cpp">
<Filter>Converters</Filter> <Filter>Converters</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Converters\ExpressionItemContainerStyle.cpp">
<Filter>Converters</Filter>
</ClCompile>
<ClCompile Include="Converters\ExpressionItemTemplateSelector.cpp"> <ClCompile Include="Converters\ExpressionItemTemplateSelector.cpp">
<Filter>Converters</Filter> <Filter>Converters</Filter>
</ClCompile> </ClCompile>
@ -271,12 +268,6 @@
<ClCompile Include="Views\NumberPad.xaml.cpp" /> <ClCompile Include="Views\NumberPad.xaml.cpp" />
<ClCompile Include="Views\SupplementaryResults.xaml.cpp" /> <ClCompile Include="Views\SupplementaryResults.xaml.cpp" />
<ClCompile Include="Views\UnitConverter.xaml.cpp" /> <ClCompile Include="Views\UnitConverter.xaml.cpp" />
<ClCompile Include="Controls\OperandTextBox.cpp">
<Filter>Controls</Filter>
</ClCompile>
<ClCompile Include="Controls\OperatorTextBox.cpp">
<Filter>Controls</Filter>
</ClCompile>
<ClCompile Include="Controls\FlipButtons.cpp"> <ClCompile Include="Controls\FlipButtons.cpp">
<Filter>Controls</Filter> <Filter>Controls</Filter>
</ClCompile> </ClCompile>
@ -287,9 +278,6 @@
</ClCompile> </ClCompile>
<ClCompile Include="WindowFrameService.cpp" /> <ClCompile Include="WindowFrameService.cpp" />
<ClCompile Include="Views\DateCalculator.xaml.cpp" /> <ClCompile Include="Views\DateCalculator.xaml.cpp" />
<ClCompile Include="Common\TitleBarHelper.cpp">
<Filter>Common</Filter>
</ClCompile>
<ClCompile Include="Controls\CalculationResultAutomationPeer.cpp"> <ClCompile Include="Controls\CalculationResultAutomationPeer.cpp">
<Filter>Controls</Filter> <Filter>Controls</Filter>
</ClCompile> </ClCompile>
@ -299,7 +287,6 @@
<ClCompile Include="Views\StateTriggers\AspectRatioTrigger.cpp"> <ClCompile Include="Views\StateTriggers\AspectRatioTrigger.cpp">
<Filter>Views\StateTriggers</Filter> <Filter>Views\StateTriggers</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Views\TitleBar.xaml.cpp" />
<ClCompile Include="Views\MemoryListItem.xaml.cpp" /> <ClCompile Include="Views\MemoryListItem.xaml.cpp" />
<ClCompile Include="Views\OperatorsPanel.xaml.cpp" /> <ClCompile Include="Views\OperatorsPanel.xaml.cpp" />
<ClCompile Include="Controls\SupplementaryItemsControl.cpp"> <ClCompile Include="Controls\SupplementaryItemsControl.cpp">
@ -311,6 +298,7 @@
<ClCompile Include="Controls\HorizontalNoOverflowStackPanel.cpp"> <ClCompile Include="Controls\HorizontalNoOverflowStackPanel.cpp">
<Filter>Controls</Filter> <Filter>Controls</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Views\TitleBar.xaml.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="pch.h" /> <ClInclude Include="pch.h" />
@ -321,9 +309,6 @@
<ClInclude Include="Common\BindableBase.h"> <ClInclude Include="Common\BindableBase.h">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Controls\AppBar.h">
<Filter>Controls</Filter>
</ClInclude>
<ClInclude Include="Controls\CalculationResult.h"> <ClInclude Include="Controls\CalculationResult.h">
<Filter>Controls</Filter> <Filter>Controls</Filter>
</ClInclude> </ClInclude>
@ -342,9 +327,6 @@
<ClInclude Include="Converters\BooleanToVisibilityConverter.h"> <ClInclude Include="Converters\BooleanToVisibilityConverter.h">
<Filter>Converters</Filter> <Filter>Converters</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Converters\ExpressionItemContainerStyle.h">
<Filter>Converters</Filter>
</ClInclude>
<ClInclude Include="Converters\ExpressionItemTemplateSelector.h"> <ClInclude Include="Converters\ExpressionItemTemplateSelector.h">
<Filter>Converters</Filter> <Filter>Converters</Filter>
</ClInclude> </ClInclude>
@ -370,12 +352,6 @@
<ClInclude Include="Views\NumberPad.xaml.h" /> <ClInclude Include="Views\NumberPad.xaml.h" />
<ClInclude Include="Views\SupplementaryResults.xaml.h" /> <ClInclude Include="Views\SupplementaryResults.xaml.h" />
<ClInclude Include="Views\UnitConverter.xaml.h" /> <ClInclude Include="Views\UnitConverter.xaml.h" />
<ClInclude Include="Controls\OperandTextBox.h">
<Filter>Controls</Filter>
</ClInclude>
<ClInclude Include="Controls\OperatorTextBox.h">
<Filter>Controls</Filter>
</ClInclude>
<ClInclude Include="Controls\FlipButtons.h"> <ClInclude Include="Controls\FlipButtons.h">
<Filter>Controls</Filter> <Filter>Controls</Filter>
</ClInclude> </ClInclude>
@ -389,9 +365,6 @@
<ClInclude Include="Converters\BitFlipAutomationNameConverter.h"> <ClInclude Include="Converters\BitFlipAutomationNameConverter.h">
<Filter>Converters</Filter> <Filter>Converters</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Common\TitleBarHelper.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Controls\CalculationResultAutomationPeer.h"> <ClInclude Include="Controls\CalculationResultAutomationPeer.h">
<Filter>Controls</Filter> <Filter>Controls</Filter>
</ClInclude> </ClInclude>
@ -401,7 +374,6 @@
<ClInclude Include="Views\StateTriggers\AspectRatioTrigger.h"> <ClInclude Include="Views\StateTriggers\AspectRatioTrigger.h">
<Filter>Views\StateTriggers</Filter> <Filter>Views\StateTriggers</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Views\TitleBar.xaml.h" />
<ClInclude Include="Views\MemoryListItem.xaml.h" /> <ClInclude Include="Views\MemoryListItem.xaml.h" />
<ClInclude Include="Views\OperatorsPanel.xaml.h" /> <ClInclude Include="Views\OperatorsPanel.xaml.h" />
<ClInclude Include="Controls\SupplementaryItemsControl.h"> <ClInclude Include="Controls\SupplementaryItemsControl.h">
@ -413,6 +385,7 @@
<ClInclude Include="Controls\HorizontalNoOverflowStackPanel.h"> <ClInclude Include="Controls\HorizontalNoOverflowStackPanel.h">
<Filter>Controls</Filter> <Filter>Controls</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Views\TitleBar.xaml.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<AppxManifest Include="Package.appxmanifest" /> <AppxManifest Include="Package.appxmanifest" />
@ -471,15 +444,15 @@
<Page Include="Views\DateCalculator.xaml"> <Page Include="Views\DateCalculator.xaml">
<Filter>Views</Filter> <Filter>Views</Filter>
</Page> </Page>
<Page Include="Views\TitleBar.xaml">
<Filter>Views</Filter>
</Page>
<Page Include="Views\MemoryListItem.xaml"> <Page Include="Views\MemoryListItem.xaml">
<Filter>Views</Filter> <Filter>Views</Filter>
</Page> </Page>
<Page Include="Views\OperatorsPanel.xaml"> <Page Include="Views\OperatorsPanel.xaml">
<Filter>Views</Filter> <Filter>Views</Filter>
</Page> </Page>
<Page Include="Views\TitleBar.xaml">
<Filter>Views</Filter>
</Page>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PRIResource Include="Resources\en-US\CEngineStrings.resw"> <PRIResource Include="Resources\en-US\CEngineStrings.resw">

View file

@ -1,94 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "pch.h"
#include "TitleBarHelper.h"
#include "Converters/BooleanToVisibilityConverter.h"
#include "CalcViewModel/ViewState.h"
using namespace CalculatorApp::Common;
using namespace CalculatorApp::Converters;
using namespace Platform;
using namespace std;
using namespace Windows::ApplicationModel::Core;
using namespace Windows::Foundation;
using namespace Windows::UI::Xaml;
unique_ptr<TitleBarHelper> TitleBarHelper::CreateTitleBarHelperIfNotDocked(FrameworkElement^ customTitleBar)
{
return (App::GetAppViewState() == ViewState::DockedView)
? nullptr
: CalculatorApp::Common::TitleBarHelper::CreateTitleBarHelper(customTitleBar);
}
unique_ptr<TitleBarHelper> TitleBarHelper::CreateTitleBarHelper(_In_ FrameworkElement^ customTitleBar)
{
assert(customTitleBar != nullptr);
if (customTitleBar != nullptr)
{
CoreApplicationViewTitleBar^ coreTitleBar = CoreApplication::GetCurrentView()->TitleBar;
assert(coreTitleBar != nullptr);
if (coreTitleBar != nullptr)
{
return make_unique<TitleBarHelper>(coreTitleBar, customTitleBar);
}
}
return nullptr;
}
TitleBarHelper::TitleBarHelper(_In_ CoreApplicationViewTitleBar^ coreTitleBar, _In_ FrameworkElement^ customTitleBar) :
m_coreTitleBar(coreTitleBar),
m_customTitleBar(customTitleBar)
{
RegisterForLayoutChanged();
RegisterForVisibilityChanged();
SetCustomTitleBar();
}
TitleBarHelper::~TitleBarHelper()
{
m_coreTitleBar->LayoutMetricsChanged -= m_layoutChangedToken;
m_coreTitleBar->IsVisibleChanged -= m_visibilityChangedToken;
}
void TitleBarHelper::SetTitleBarHeight(double height)
{
m_customTitleBar->Height = height;
}
void TitleBarHelper::SetTitleBarVisibility(bool isVisible)
{
m_customTitleBar->Visibility = BooleanToVisibilityConverter::Convert(isVisible);
}
void TitleBarHelper::RegisterForLayoutChanged()
{
m_layoutChangedToken =
m_coreTitleBar->LayoutMetricsChanged += ref new TypedEventHandler<CoreApplicationViewTitleBar^, Object^>(
[this](CoreApplicationViewTitleBar^ cTitleBar, Object^)
{
// Update title bar control size as needed to account for system size changes
SetTitleBarHeight(cTitleBar->Height);
});
}
void TitleBarHelper::RegisterForVisibilityChanged()
{
m_visibilityChangedToken =
m_coreTitleBar->IsVisibleChanged += ref new TypedEventHandler<CoreApplicationViewTitleBar^, Object^>(
[this](CoreApplicationViewTitleBar^ cTitleBar, Object^)
{
// Update title bar visibility
SetTitleBarVisibility(cTitleBar->IsVisible);
});
}
void TitleBarHelper::SetCustomTitleBar()
{
// Set custom XAML Title Bar
m_coreTitleBar->ExtendViewIntoTitleBar = true;
SetTitleBarHeight(m_coreTitleBar->Height);
SetTitleBarVisibility(m_coreTitleBar->IsVisible);
Window::Current->SetTitleBar(m_customTitleBar);
}

View file

@ -1,40 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
namespace CalculatorApp
{
namespace Common
{
class TitleBarHelper
{
public:
static std::unique_ptr<TitleBarHelper> CreateTitleBarHelperIfNotDocked(
_In_ Windows::UI::Xaml::FrameworkElement^ customTitleBar);
// Prefer CreateTitleBarHelper over constructing your own instance,
// because Create* will nullcheck the parameters.
static std::unique_ptr<TitleBarHelper> CreateTitleBarHelper(
_In_ Windows::UI::Xaml::FrameworkElement^ customTitleBar);
TitleBarHelper(
_In_ Windows::ApplicationModel::Core::CoreApplicationViewTitleBar^ coreTitleBar,
_In_ Windows::UI::Xaml::FrameworkElement^ customTitleBar);
~TitleBarHelper();
void SetTitleBarHeight(double height);
void SetTitleBarVisibility(bool isVisible);
private:
void RegisterForLayoutChanged();
void RegisterForVisibilityChanged();
void SetCustomTitleBar();
Platform::Agile<Windows::ApplicationModel::Core::CoreApplicationViewTitleBar^> m_coreTitleBar;
Windows::UI::Xaml::FrameworkElement^ m_customTitleBar;
Windows::Foundation::EventRegistrationToken m_layoutChangedToken;
Windows::Foundation::EventRegistrationToken m_visibilityChangedToken;
};
}
}

View file

@ -1,29 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
#include "Common/KeyboardShortcutManager.h"
namespace CalculatorApp
{
namespace Controls
{
public ref class AppBar sealed : public Windows::UI::Xaml::Controls::AppBar
{
public:
AppBar()
{}
protected:
virtual void OnKeyDown(Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e) override
{
Windows::UI::Xaml::Controls::AppBar::OnKeyDown(e);
if (e->Key == Windows::System::VirtualKey::Escape)
{
Common::KeyboardShortcutManager::IgnoreEscape(true);
}
}
};
}
}

View file

@ -28,6 +28,7 @@ using namespace std;
DEPENDENCY_PROPERTY_INITIALIZATION(CalculationResult, IsActive); DEPENDENCY_PROPERTY_INITIALIZATION(CalculationResult, IsActive);
DEPENDENCY_PROPERTY_INITIALIZATION(CalculationResult, AccentColor); DEPENDENCY_PROPERTY_INITIALIZATION(CalculationResult, AccentColor);
DEPENDENCY_PROPERTY_INITIALIZATION(CalculationResult, MinFontSize); DEPENDENCY_PROPERTY_INITIALIZATION(CalculationResult, MinFontSize);
DEPENDENCY_PROPERTY_INITIALIZATION(CalculationResult, MaxFontSize);
DEPENDENCY_PROPERTY_INITIALIZATION(CalculationResult, DisplayMargin); DEPENDENCY_PROPERTY_INITIALIZATION(CalculationResult, DisplayMargin);
DEPENDENCY_PROPERTY_INITIALIZATION(CalculationResult, MaxExpressionHistoryCharacters); DEPENDENCY_PROPERTY_INITIALIZATION(CalculationResult, MaxExpressionHistoryCharacters);
DEPENDENCY_PROPERTY_INITIALIZATION(CalculationResult, ExpressionVisibility); DEPENDENCY_PROPERTY_INITIALIZATION(CalculationResult, ExpressionVisibility);
@ -50,7 +51,6 @@ StringReference CalculationResult::s_FocusedState(L"Focused");
StringReference CalculationResult::s_UnfocusedState(L"Unfocused"); StringReference CalculationResult::s_UnfocusedState(L"Unfocused");
CalculationResult::CalculationResult(): CalculationResult::CalculationResult():
m_startingFontSize(0.0),
m_isScalingText(false), m_isScalingText(false),
m_haveCalculatedMax(false) m_haveCalculatedMax(false)
{ {
@ -72,7 +72,7 @@ void CalculationResult::OnApplyTemplate()
{ {
m_textContainer->LayoutUpdated -= m_textContainerLayoutChangedToken; m_textContainer->LayoutUpdated -= m_textContainerLayoutChangedToken;
} }
m_textContainer = dynamic_cast<ScrollViewer^>(GetTemplateChild("textContainer")); m_textContainer = dynamic_cast<ScrollViewer^>(GetTemplateChild("TextContainer"));
if (m_textContainer) if (m_textContainer)
{ {
m_textContainer->SizeChanged += ref new SizeChangedEventHandler(this, &CalculationResult::TextContainerSizeChanged); m_textContainer->SizeChanged += ref new SizeChangedEventHandler(this, &CalculationResult::TextContainerSizeChanged);
@ -81,9 +81,9 @@ void CalculationResult::OnApplyTemplate()
m_textContainerLayoutChangedToken = m_textContainer->LayoutUpdated += ref new EventHandler<Object^>(this, &CalculationResult::OnTextContainerLayoutUpdated); m_textContainerLayoutChangedToken = m_textContainer->LayoutUpdated += ref new EventHandler<Object^>(this, &CalculationResult::OnTextContainerLayoutUpdated);
m_textContainer->ChangeView(m_textContainer->ExtentWidth - m_textContainer->ViewportWidth,nullptr,nullptr); m_textContainer->ChangeView(m_textContainer->ExtentWidth - m_textContainer->ViewportWidth,nullptr,nullptr);
m_scrollLeft = dynamic_cast<HyperlinkButton^>(GetTemplateChild("scrollLeft")); m_scrollLeft = dynamic_cast<HyperlinkButton^>(GetTemplateChild("ScrollLeft"));
m_scrollRight = dynamic_cast<HyperlinkButton^>(GetTemplateChild("scrollRight")); m_scrollRight = dynamic_cast<HyperlinkButton^>(GetTemplateChild("ScrollRight"));
auto borderContainer = dynamic_cast<UIElement^>(GetTemplateChild("border")); auto borderContainer = dynamic_cast<UIElement^>(GetTemplateChild("Border"));
if (m_scrollLeft && m_scrollRight) if (m_scrollLeft && m_scrollRight)
{ {
m_scrollLeft->Click += ref new RoutedEventHandler(this, &CalculationResult::OnScrollClick); m_scrollLeft->Click += ref new RoutedEventHandler(this, &CalculationResult::OnScrollClick);
@ -91,11 +91,10 @@ void CalculationResult::OnApplyTemplate()
borderContainer->PointerEntered += ref new PointerEventHandler(this, &CalculationResult::OnPointerEntered); borderContainer->PointerEntered += ref new PointerEventHandler(this, &CalculationResult::OnPointerEntered);
borderContainer->PointerExited += ref new PointerEventHandler(this, &CalculationResult::OnPointerExited); borderContainer->PointerExited += ref new PointerEventHandler(this, &CalculationResult::OnPointerExited);
} }
m_textBlock = dynamic_cast<TextBlock^>(m_textContainer->FindName("normalOutput")); m_textBlock = dynamic_cast<TextBlock^>(m_textContainer->FindName("NormalOutput"));
if (m_textBlock) if (m_textBlock)
{ {
m_textBlock->Visibility = ::Visibility::Visible; m_textBlock->Visibility = ::Visibility::Visible;
m_startingFontSize = m_textBlock->FontSize;
} }
} }
UpdateAllState(); UpdateAllState();
@ -143,6 +142,16 @@ void CalculationResult::OnDisplayValuePropertyChanged(String^ /*oldValue*/, Stri
UpdateTextState(); UpdateTextState();
} }
void CalculationResult::OnMinFontSizePropertyChanged(double /*oldValue*/, double /*newValue*/)
{
UpdateTextState();
}
void CalculationResult::OnMaxFontSizePropertyChanged(double /*oldValue*/, double /*newValue*/)
{
UpdateTextState();
}
void CalculationResult::OnIsInErrorPropertyChanged(bool /*oldValue*/, bool newValue) void CalculationResult::OnIsInErrorPropertyChanged(bool /*oldValue*/, bool newValue)
{ {
// We need to have a good template for this to work // We need to have a good template for this to work
@ -212,7 +221,7 @@ void CalculationResult::UpdateTextState()
{ {
fontSizeChange = min<double>(max<double>(floor(WIDTHTOFONTSCALAR * widthDiff) - WIDTHTOFONTOFFSET, INCREMENTOFFSET), MAXFONTINCREMENT); fontSizeChange = min<double>(max<double>(floor(WIDTHTOFONTSCALAR * widthDiff) - WIDTHTOFONTOFFSET, INCREMENTOFFSET), MAXFONTINCREMENT);
} }
if (m_textBlock->ActualWidth < containerSize && abs(m_textBlock->FontSize - m_startingFontSize) > FONTTOLERANCE && !m_haveCalculatedMax) if (m_textBlock->ActualWidth < containerSize && abs(m_textBlock->FontSize - MaxFontSize) > FONTTOLERANCE && !m_haveCalculatedMax)
{ {
ModifyFontAndMargin(m_textBlock, fontSizeChange); ModifyFontAndMargin(m_textBlock, fontSizeChange);
m_textBlock->InvalidateArrange(); m_textBlock->InvalidateArrange();
@ -228,7 +237,7 @@ void CalculationResult::UpdateTextState()
m_textBlock->InvalidateArrange(); m_textBlock->InvalidateArrange();
return; return;
} }
assert(m_textBlock->FontSize >= MinFontSize && m_textBlock->FontSize <= m_startingFontSize); assert(m_textBlock->FontSize >= MinFontSize && m_textBlock->FontSize <= MaxFontSize);
m_isScalingText = false; m_isScalingText = false;
if (IsOperatorCommand) if (IsOperatorCommand)
{ {
@ -361,24 +370,15 @@ void CalculationResult::ModifyFontAndMargin(TextBlock^ textBox, double fontChang
{ {
double cur = textBox->FontSize; double cur = textBox->FontSize;
double newFontSize = 0.0; double newFontSize = 0.0;
Thickness t = textBox->Margin;
double scaleFactor = SCALEFACTOR; double scaleFactor = SCALEFACTOR;
if (m_textContainer->ActualHeight <= HEIGHTCUTOFF) if (m_textContainer->ActualHeight <= HEIGHTCUTOFF)
{ {
scaleFactor = SMALLHEIGHTSCALEFACTOR; scaleFactor = SMALLHEIGHTSCALEFACTOR;
} }
if (fontChange < 0)
{ newFontSize = min(max(cur + fontChange, MinFontSize), MaxFontSize);
newFontSize = max(cur + fontChange, MinFontSize); m_textContainer->Padding = Thickness(0, 0, 0, scaleFactor * abs(cur - newFontSize));
t.Bottom += scaleFactor * abs(cur - newFontSize);
}
else
{
newFontSize = min(cur + fontChange, m_startingFontSize);
t.Bottom -= scaleFactor * abs(cur - newFontSize);
}
textBox->FontSize = newFontSize; textBox->FontSize = newFontSize;
textBox->Margin = t;
} }
void CalculationResult::UpdateAllState() void CalculationResult::UpdateAllState()

View file

@ -19,7 +19,8 @@ namespace CalculatorApp
DEPENDENCY_PROPERTY_OWNER(CalculationResult); DEPENDENCY_PROPERTY_OWNER(CalculationResult);
DEPENDENCY_PROPERTY(Windows::UI::Xaml::Visibility, ExpressionVisibility); DEPENDENCY_PROPERTY(Windows::UI::Xaml::Visibility, ExpressionVisibility);
DEPENDENCY_PROPERTY(double, MinFontSize); DEPENDENCY_PROPERTY_WITH_DEFAULT_AND_CALLBACK(double, MinFontSize, 0.0);
DEPENDENCY_PROPERTY_WITH_DEFAULT_AND_CALLBACK(double, MaxFontSize, 30.0);
DEPENDENCY_PROPERTY(Windows::UI::Xaml::Thickness, DisplayMargin); DEPENDENCY_PROPERTY(Windows::UI::Xaml::Thickness, DisplayMargin);
DEPENDENCY_PROPERTY(int, MaxExpressionHistoryCharacters); DEPENDENCY_PROPERTY(int, MaxExpressionHistoryCharacters);
DEPENDENCY_PROPERTY_WITH_CALLBACK(bool, IsActive); DEPENDENCY_PROPERTY_WITH_CALLBACK(bool, IsActive);
@ -52,6 +53,8 @@ namespace CalculatorApp
void OnAccentColorPropertyChanged(Windows::UI::Xaml::Media::Brush^ oldValue, Windows::UI::Xaml::Media::Brush^ newValue); void OnAccentColorPropertyChanged(Windows::UI::Xaml::Media::Brush^ oldValue, Windows::UI::Xaml::Media::Brush^ newValue);
void OnDisplayValuePropertyChanged(Platform::String^ oldValue, Platform::String^ newValue); void OnDisplayValuePropertyChanged(Platform::String^ oldValue, Platform::String^ newValue);
void OnIsInErrorPropertyChanged(bool oldValue, bool newValue); void OnIsInErrorPropertyChanged(bool oldValue, bool newValue);
void OnMinFontSizePropertyChanged(double oldValue, double newValue);
void OnMaxFontSizePropertyChanged(double oldValue, double newValue);
void TextContainerSizeChanged(Object^ sender, Windows::UI::Xaml::SizeChangedEventArgs^ e); void TextContainerSizeChanged(Object^ sender, Windows::UI::Xaml::SizeChangedEventArgs^ e);
void OnTextContainerLayoutUpdated(Object^ sender, Object^ e); void OnTextContainerLayoutUpdated(Object^ sender, Object^ e);
void UpdateVisualState(); void UpdateVisualState();
@ -74,7 +77,6 @@ namespace CalculatorApp
Windows::UI::Xaml::Controls::TextBlock^ m_textBlock; Windows::UI::Xaml::Controls::TextBlock^ m_textBlock;
Windows::UI::Xaml::Controls::HyperlinkButton^ m_scrollLeft; Windows::UI::Xaml::Controls::HyperlinkButton^ m_scrollLeft;
Windows::UI::Xaml::Controls::HyperlinkButton^ m_scrollRight; Windows::UI::Xaml::Controls::HyperlinkButton^ m_scrollRight;
double m_startingFontSize;
double scrollRatio = 0.7; double scrollRatio = 0.7;
bool m_isScalingText; bool m_isScalingText;
bool m_haveCalculatedMax; bool m_haveCalculatedMax;

View file

@ -1,58 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "pch.h"
#include "OperandTextBox.h"
#include "regex"
using namespace CalculatorApp;
using namespace CalculatorApp::Controls;
using namespace Platform;
using namespace std;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Devices::Input;
using namespace Windows::System;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
void OperandTextBox::OnApplyTemplate()
{
this->IsEnabled = false;
this->IsHitTestVisible = false;
this->IsTapEnabled = false;
this->MaxLength = 50;
this->IsRightTapEnabled = false;
this->IsTabStop = false;
auto parent = VisualTreeHelper::GetParent(this);
ListViewItem^ listViewItem;
ListView^ listView;
while (parent != nullptr)
{
if (listViewItem == nullptr)
{
listViewItem = dynamic_cast<ListViewItem^>(parent);
}
listView = dynamic_cast<ListView^>(parent);
if (listView != nullptr)
{
break;
}
parent = VisualTreeHelper::GetParent(parent);
}
if (listView != nullptr)
{
listViewItem->IsEnabled = false;
listViewItem->IsHitTestVisible = false;
listViewItem->IsTapEnabled = false;
}
TextBox::OnApplyTemplate();
}

View file

@ -1,19 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
namespace CalculatorApp
{
namespace Controls
{
public ref class OperandTextBox sealed : public Windows::UI::Xaml::Controls::TextBox
{
public:
OperandTextBox() { }
protected:
virtual void OnApplyTemplate() override;
};
}
}

View file

@ -1,59 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "pch.h"
#include "OperatorTextBox.h"
#include "regex"
using namespace CalculatorApp;
using namespace CalculatorApp::Controls;
using namespace Platform;
using namespace std;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Devices::Input;
using namespace Windows::System;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
void OperatorTextBox::OnApplyTemplate()
{
this->IsEnabled = false;
this->IsHitTestVisible = false;
this->IsTapEnabled = false;
this->MaxLength = 50;
this->IsReadOnly = true;
this->IsRightTapEnabled = false;
this->IsTabStop = false;
auto parent = VisualTreeHelper::GetParent(this);
ListViewItem^ listViewItem;
ListView^ listView;
while (parent != nullptr)
{
if (listViewItem == nullptr)
{
listViewItem = dynamic_cast<ListViewItem^>(parent);
}
listView = dynamic_cast<ListView^>(parent);
if (listView != nullptr)
{
break;
}
parent = VisualTreeHelper::GetParent(parent);
}
if (listView != nullptr)
{
listViewItem->IsEnabled = false;
listViewItem->IsHitTestVisible = false;
listViewItem->IsTapEnabled = false;
}
TextBox::OnApplyTemplate();
}

View file

@ -1,19 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
namespace CalculatorApp
{
namespace Controls
{
public ref class OperatorTextBox sealed : public Windows::UI::Xaml::Controls::TextBox
{
public:
OperatorTextBox() { }
protected:
virtual void OnApplyTemplate() override;
};
}
}

View file

@ -30,25 +30,38 @@ DEPENDENCY_PROPERTY_INITIALIZATION(OverflowTextBlock, TokensUpdated);
void OverflowTextBlock::OnApplyTemplate() void OverflowTextBlock::OnApplyTemplate()
{ {
assert(((m_scrollLeft == nullptr) && (m_scrollRight == nullptr)) || ((m_scrollLeft != nullptr) && (m_scrollRight != nullptr))); UnregisterEventHandlers();
m_expressionContainer = safe_cast<ScrollViewer^>(GetTemplateChild("expressionContainer")); auto uiElement = GetTemplateChild("ExpressionContainer");
m_expressionContainer->ChangeView(m_expressionContainer->ExtentWidth - m_expressionContainer->ViewportWidth, nullptr, nullptr); if (uiElement != nullptr)
{
m_expressionContainer = safe_cast<ScrollViewer^>(uiElement);
m_expressionContainer->ChangeView(m_expressionContainer->ExtentWidth - m_expressionContainer->ViewportWidth, nullptr, nullptr);
m_containerViewChangedToken = m_expressionContainer->ViewChanged += ref new EventHandler<ScrollViewerViewChangedEventArgs ^>(this, &OverflowTextBlock::OnViewChanged);
}
m_scrollLeft = safe_cast<Button^>(GetTemplateChild("scrollLeft")); uiElement = GetTemplateChild("ScrollLeft");
m_scrollRight = safe_cast<Button^>(GetTemplateChild("scrollRight")); if (uiElement != nullptr)
{
m_scrollLeft = safe_cast<Button^>(uiElement);
m_scrollLeftClickEventToken = m_scrollLeft->Click += ref new RoutedEventHandler(this, &OverflowTextBlock::OnScrollClick);
}
m_scrollLeftClickEventToken = m_scrollLeft->Click += ref new RoutedEventHandler(this, &OverflowTextBlock::OnScrollClick); uiElement = GetTemplateChild("ScrollRight");
m_scrollRightClickEventToken = m_scrollRight->Click += ref new RoutedEventHandler(this, &OverflowTextBlock::OnScrollClick); if (uiElement != nullptr)
{
m_scrollRight = safe_cast<Button^>(uiElement);
m_scrollRightClickEventToken = m_scrollRight->Click += ref new RoutedEventHandler(this, &OverflowTextBlock::OnScrollClick);
}
m_scrollingLeft = false; m_scrollingLeft = false;
m_scrollingRight = false; m_scrollingRight = false;
auto borderContainer = safe_cast<Border^>(GetTemplateChild("expressionborder")); uiElement = GetTemplateChild("TokenList");
m_pointerEnteredEventToken = borderContainer->PointerEntered += ref new PointerEventHandler(this, &OverflowTextBlock::OnPointerEntered); if (uiElement != nullptr)
m_pointerExitedEventToken = borderContainer->PointerExited += ref new PointerEventHandler(this, &OverflowTextBlock::OnPointerExited); {
m_itemsControl = safe_cast<ItemsControl^>(uiElement);
m_listView = safe_cast<ListView^>(GetTemplateChild("TokenList")); }
UpdateAllState(); UpdateAllState();
} }
@ -60,18 +73,19 @@ AutomationPeer^ OverflowTextBlock::OnCreateAutomationPeer()
void OverflowTextBlock::OnTokensUpdatedPropertyChanged(bool /*oldValue*/, bool newValue) void OverflowTextBlock::OnTokensUpdatedPropertyChanged(bool /*oldValue*/, bool newValue)
{ {
if ((m_listView != nullptr) && (newValue)) if (m_expressionContainer != nullptr && newValue)
{ {
unsigned int tokenCount = m_listView->Items->Size; m_expressionContainer->UpdateLayout();
if (tokenCount > 0) m_expressionContainer->ChangeView(m_expressionContainer->ScrollableWidth, nullptr, nullptr, true);
{
m_listView->UpdateLayout();
m_listView->ScrollIntoView(m_listView->Items->GetAt(tokenCount - 1));
m_expressionContainer->ChangeView(m_expressionContainer->ExtentWidth - m_expressionContainer->ViewportWidth, nullptr, nullptr);
}
} }
AutomationProperties::SetAccessibilityView(this, auto newIsAccessibilityViewControl = m_itemsControl != nullptr && m_itemsControl->Items->Size > 0;
m_listView != nullptr && m_listView->Items->Size > 0 ? AccessibilityView::Control : AccessibilityView::Raw); if (m_isAccessibilityViewControl != newIsAccessibilityViewControl)
{
m_isAccessibilityViewControl = newIsAccessibilityViewControl;
AutomationProperties::SetAccessibilityView(this,
newIsAccessibilityViewControl ? AccessibilityView::Control : AccessibilityView::Raw);
}
UpdateScrollButtons();
} }
void OverflowTextBlock::UpdateAllState() void OverflowTextBlock::UpdateAllState()
@ -93,7 +107,7 @@ void OverflowTextBlock::UpdateVisualState()
void OverflowTextBlock::ScrollLeft() void OverflowTextBlock::ScrollLeft()
{ {
if (m_expressionContainer->HorizontalOffset > 0) if (m_expressionContainer != nullptr && m_expressionContainer->HorizontalOffset > 0)
{ {
m_scrollingLeft = true; m_scrollingLeft = true;
double offset = m_expressionContainer->HorizontalOffset - (scrollRatio * m_expressionContainer->ViewportWidth); double offset = m_expressionContainer->HorizontalOffset - (scrollRatio * m_expressionContainer->ViewportWidth);
@ -105,7 +119,7 @@ void OverflowTextBlock::ScrollLeft()
void OverflowTextBlock::ScrollRight() void OverflowTextBlock::ScrollRight()
{ {
if (m_expressionContainer->HorizontalOffset < m_expressionContainer->ExtentWidth - m_expressionContainer->ViewportWidth) if (m_expressionContainer != nullptr && m_expressionContainer->HorizontalOffset < m_expressionContainer->ExtentWidth - m_expressionContainer->ViewportWidth)
{ {
m_scrollingRight = true; m_scrollingRight = true;
double offset = m_expressionContainer->HorizontalOffset + (scrollRatio * m_expressionContainer->ViewportWidth); double offset = m_expressionContainer->HorizontalOffset + (scrollRatio * m_expressionContainer->ViewportWidth);
@ -128,26 +142,15 @@ void OverflowTextBlock::OnScrollClick(_In_ Object^ sender, _In_ RoutedEventArgs^
} }
} }
void OverflowTextBlock::OnPointerEntered(_In_ Object^, _In_ PointerRoutedEventArgs^ e)
{
if (e->Pointer->PointerDeviceType == PointerDeviceType::Mouse)
{
UpdateScrollButtons();
}
}
void OverflowTextBlock::OnPointerExited(_In_ Object^, _In_ PointerRoutedEventArgs^ e)
{
if (e->Pointer->PointerDeviceType == PointerDeviceType::Mouse)
{
UpdateScrollButtons();
}
}
void OverflowTextBlock::UpdateScrollButtons() void OverflowTextBlock::UpdateScrollButtons()
{ {
if (m_itemsControl == nullptr || m_expressionContainer == nullptr)
{
return;
}
// When the width is smaller than the container, don't show any // When the width is smaller than the container, don't show any
if (m_listView->ActualWidth <= m_expressionContainer->ActualWidth) if (m_itemsControl->ActualWidth <= m_expressionContainer->ActualWidth)
{ {
ShowHideScrollButtons(::Visibility::Collapsed, ::Visibility::Collapsed); ShowHideScrollButtons(::Visibility::Collapsed, ::Visibility::Collapsed);
} }
@ -163,7 +166,10 @@ void OverflowTextBlock::UpdateScrollButtons()
if (m_scrollingLeft) if (m_scrollingLeft)
{ {
m_scrollingLeft = false; m_scrollingLeft = false;
m_scrollRight->Focus(::FocusState::Programmatic); if (m_scrollRight != nullptr)
{
m_scrollRight->Focus(::FocusState::Programmatic);
}
} }
} }
else // Width is larger than the container and right most part of the number is shown. Should be able to scroll left. else // Width is larger than the container and right most part of the number is shown. Should be able to scroll left.
@ -172,7 +178,10 @@ void OverflowTextBlock::UpdateScrollButtons()
if (m_scrollingRight) if (m_scrollingRight)
{ {
m_scrollingRight = false; m_scrollingRight = false;
m_scrollLeft->Focus(::FocusState::Programmatic); if (m_scrollLeft != nullptr)
{
m_scrollLeft->Focus(::FocusState::Programmatic);
}
} }
} }
} }
@ -199,12 +208,13 @@ void OverflowTextBlock::UnregisterEventHandlers()
m_scrollRight->Click -= m_scrollRightClickEventToken; m_scrollRight->Click -= m_scrollRightClickEventToken;
} }
auto borderContainer = safe_cast<Border^>(GetTemplateChild("expressionborder")); if (m_expressionContainer != nullptr)
// Adding an extra check, in case the returned template is null
if (borderContainer != nullptr)
{ {
borderContainer->PointerEntered -= m_pointerEnteredEventToken; m_expressionContainer->ViewChanged -= m_containerViewChangedToken;
borderContainer->PointerExited -= m_pointerExitedEventToken;
} }
} }
void OverflowTextBlock::OnViewChanged(_In_opt_ Object^ /*sender*/, _In_opt_ ScrollViewerViewChangedEventArgs^ /*args*/)
{
UpdateScrollButtons();
}

View file

@ -34,6 +34,7 @@ namespace CalculatorApp
void OnPointerExited(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e); void OnPointerExited(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e);
void ShowHideScrollButtons(Windows::UI::Xaml::Visibility vLeft, Windows::UI::Xaml::Visibility vRight); void ShowHideScrollButtons(Windows::UI::Xaml::Visibility vLeft, Windows::UI::Xaml::Visibility vRight);
void OnTokensUpdatedPropertyChanged(bool oldValue, bool newValue); void OnTokensUpdatedPropertyChanged(bool oldValue, bool newValue);
void OnViewChanged(_In_opt_ Platform::Object ^sender, _In_opt_ Windows::UI::Xaml::Controls::ScrollViewerViewChangedEventArgs ^args);
void UpdateVisualState(); void UpdateVisualState();
void UpdateExpressionState(); void UpdateExpressionState();
@ -44,15 +45,15 @@ namespace CalculatorApp
double scrollRatio = 0.7; double scrollRatio = 0.7;
bool m_scrollingLeft; bool m_scrollingLeft;
bool m_scrollingRight; bool m_scrollingRight;
Windows::UI::Xaml::Controls::ListView^ m_listView; bool m_isAccessibilityViewControl;
Windows::UI::Xaml::Controls::ItemsControl^ m_itemsControl;
Windows::UI::Xaml::Controls::ScrollViewer^ m_expressionContainer; Windows::UI::Xaml::Controls::ScrollViewer^ m_expressionContainer;
Windows::UI::Xaml::Controls::Button^ m_scrollLeft; Windows::UI::Xaml::Controls::Button^ m_scrollLeft;
Windows::UI::Xaml::Controls::Button^ m_scrollRight; Windows::UI::Xaml::Controls::Button^ m_scrollRight;
Windows::Foundation::EventRegistrationToken m_scrollLeftClickEventToken; Windows::Foundation::EventRegistrationToken m_scrollLeftClickEventToken;
Windows::Foundation::EventRegistrationToken m_scrollRightClickEventToken; Windows::Foundation::EventRegistrationToken m_scrollRightClickEventToken;
Windows::Foundation::EventRegistrationToken m_pointerEnteredEventToken; Windows::Foundation::EventRegistrationToken m_containerViewChangedToken;
Windows::Foundation::EventRegistrationToken m_pointerExitedEventToken;
}; };
} }
} }

View file

@ -1,44 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "pch.h"
#include "ExpressionItemContainerStyle.h"
#include "CalcViewModel/Common/DisplayExpressionToken.h"
using namespace CalculatorApp::Common;
namespace CalculatorApp
{
namespace Converters
{
Windows::UI::Xaml::Style^ ExpressionItemContainerStyle::SelectStyleCore(Platform::Object^ item, Windows::UI::Xaml::DependencyObject^ container)
{
DisplayExpressionToken^ token = dynamic_cast<DisplayExpressionToken^>(item);
if (token != nullptr)
{
Common::TokenType type = token->Type;
switch (type)
{
case TokenType::Operator:
if (token->IsTokenEditable)
{
return m_editableOperatorStyle;
}
else
{
return m_nonEditableOperatorStyle;
}
case TokenType::Operand:
return m_operandStyle;
case TokenType::Separator:
return m_separatorStyle;
default:
throw ref new Platform::Exception(E_FAIL, L"Invalid token type");
}
}
return m_separatorStyle;
}
}
}

View file

@ -1,71 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
namespace CalculatorApp
{
namespace Converters
{
[Windows::UI::Xaml::Data::Bindable]
public ref class ExpressionItemContainerStyle sealed : public Windows::UI::Xaml::Controls::StyleSelector
{
public:
virtual Windows::UI::Xaml::Style^ SelectStyleCore(Platform::Object^ item, Windows::UI::Xaml::DependencyObject^ container) override;
property Windows::UI::Xaml::Style^ EditableOperatorStyle
{
Windows::UI::Xaml::Style^ get()
{
return m_editableOperatorStyle;
}
void set(Windows::UI::Xaml::Style^ val)
{
m_editableOperatorStyle = val;
}
}
property Windows::UI::Xaml::Style^ OperandStyle
{
Windows::UI::Xaml::Style^ get()
{
return m_operandStyle;
}
void set(Windows::UI::Xaml::Style^ val)
{
m_operandStyle = val;
}
}
property Windows::UI::Xaml::Style^ SeparatorStyle
{
Windows::UI::Xaml::Style^ get()
{
return m_separatorStyle;
}
void set(Windows::UI::Xaml::Style^ val)
{
m_separatorStyle = val;
}
}
property Windows::UI::Xaml::Style^ NonEditableOperatorStyle
{
Windows::UI::Xaml::Style^ get()
{
return m_nonEditableOperatorStyle;
}
void set(Windows::UI::Xaml::Style^ val)
{
m_nonEditableOperatorStyle = val;
}
}
private:
Windows::UI::Xaml::Style^ m_editableOperatorStyle;
Windows::UI::Xaml::Style^ m_nonEditableOperatorStyle;
Windows::UI::Xaml::Style^ m_operandStyle;
Windows::UI::Xaml::Style^ m_separatorStyle;
};
}
}

View file

@ -909,6 +909,14 @@
<value>Hakies regs</value> <value>Hakies regs</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisCountAutomationNamePrefix" xml:space="preserve">
<value>Aantal oop hakies %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific and programmer operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="NoRightParenthesisAdded_Announcement" xml:space="preserve">
<value>Daar is geen oop hakies om te sluit nie.</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator when the ")" button on the scientific and programmer operator keypad cannot be added to the equation. e.g. "1+)".</comment>
</data>
<data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Wetenskaplike notering</value> <value>Wetenskaplike notering</value>
<comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment>

View file

@ -901,14 +901,19 @@
<value>የግራ ቅንፍ</value> <value>የግራ ቅንፍ</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>የግራ ቅንፍ፣ የክፍት ቅንፍ ቁጥር %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>የቀኝ ቅንፍ</value> <value>የቀኝ ቅንፍ</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisCountAutomationNamePrefix" xml:space="preserve">
<value>የክፍት ቅንፎች ብዛት %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific and programmer operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="NoRightParenthesisAdded_Announcement" xml:space="preserve">
<value>ምንም የሚዘጋ ክፍት ቅንፍ የለም።</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator when the ")" button on the scientific and programmer operator keypad cannot be added to the equation. e.g. "1+)".</comment>
</data>
<data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>ሳይንሳዊ እሳቤ</value> <value>ሳይንሳዊ እሳቤ</value>
<comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment>
@ -2278,7 +2283,7 @@
<comment>Displayed on a link to the Microsoft Privacy Statement on the About panel</comment> <comment>Displayed on a link to the Microsoft Privacy Statement on the About panel</comment>
</data> </data>
<data name="AboutControlCopyright" xml:space="preserve"> <data name="AboutControlCopyright" xml:space="preserve">
<value>© %1 Microsoft. ሁሉም መብቱ የተጠበቀ።</value> <value>© %1 Microsoft. ሁሉም መብቶች በህግ የተከበሩ ናቸው።</value>
<comment>{Locked="%1"}. Copyright statement, displayed on the About panel. %1 = the current year (4 digits)</comment> <comment>{Locked="%1"}. Copyright statement, displayed on the About panel. %1 = the current year (4 digits)</comment>
</data> </data>
<data name="AboutButton.Content" xml:space="preserve"> <data name="AboutButton.Content" xml:space="preserve">

View file

@ -901,14 +901,19 @@
<value>أقواس يسرى</value> <value>أقواس يسرى</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>القوس الأيسر، عدد الأقواس المفتوحة %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>أقواس يمنى</value> <value>أقواس يمنى</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisCountAutomationNamePrefix" xml:space="preserve">
<value>عدد الأقواس المفتوحة %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific and programmer operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="NoRightParenthesisAdded_Announcement" xml:space="preserve">
<value>لا توجد أي أقواس مفتوحة لإغلاقها.</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator when the ")" button on the scientific and programmer operator keypad cannot be added to the equation. e.g. "1+)".</comment>
</data>
<data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>رموز علمية</value> <value>رموز علمية</value>
<comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment>
@ -2279,7 +2284,7 @@
<comment>Displayed on a link to the Microsoft Privacy Statement on the About panel</comment> <comment>Displayed on a link to the Microsoft Privacy Statement on the About panel</comment>
</data> </data>
<data name="AboutControlCopyright" xml:space="preserve"> <data name="AboutControlCopyright" xml:space="preserve">
<value>© %1 Microsoft. جميع الحقوق محفوظة.</value> <value>حقوق النشر © محفوظة لشركة Microsoft لعام %1. جميع الحقوق محفوظة.</value>
<comment>{Locked="%1"}. Copyright statement, displayed on the About panel. %1 = the current year (4 digits)</comment> <comment>{Locked="%1"}. Copyright statement, displayed on the About panel. %1 = the current year (4 digits)</comment>
</data> </data>
<data name="AboutButton.Content" xml:space="preserve"> <data name="AboutButton.Content" xml:space="preserve">

View file

@ -901,14 +901,19 @@
<value>Sol mötərizə</value> <value>Sol mötərizə</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>Sol mötərizə, açıq mötərizənin sayı %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Sağ mötərizə</value> <value>Sağ mötərizə</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisCountAutomationNamePrefix" xml:space="preserve">
<value>Açıq mötərizənin sayı %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific and programmer operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="NoRightParenthesisAdded_Announcement" xml:space="preserve">
<value>Bağlamaq üçün açıq mötərizələr yoxdur.</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator when the ")" button on the scientific and programmer operator keypad cannot be added to the equation. e.g. "1+)".</comment>
</data>
<data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Eksponensial format</value> <value>Eksponensial format</value>
<comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment>

View file

@ -901,14 +901,19 @@
<value>Левая дужка</value> <value>Левая дужка</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>Левая дужка, пачатак адліку дужак (%1)</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Правая дужка</value> <value>Правая дужка</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisCountAutomationNamePrefix" xml:space="preserve">
<value>Лік адсутных дужак %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific and programmer operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="NoRightParenthesisAdded_Announcement" xml:space="preserve">
<value>Няма незакрытых дужак.</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator when the ")" button on the scientific and programmer operator keypad cannot be added to the equation. e.g. "1+)".</comment>
</data>
<data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Экспанентавы запіс</value> <value>Экспанентавы запіс</value>
<comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment>
@ -2899,4 +2904,4 @@
<value>Пагадненне аб выкарыстанні сэрвісаў Microsoft</value> <value>Пагадненне аб выкарыстанні сэрвісаў Microsoft</value>
<comment>Displayed on a link to the Microsoft Services Agreement in the about this app information</comment> <comment>Displayed on a link to the Microsoft Services Agreement in the about this app information</comment>
</data> </data>
</root> </root>

View file

@ -901,14 +901,19 @@
<value>Лява скоба</value> <value>Лява скоба</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>Лява скоба, брой на отваряща скоба %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Дясна скоба</value> <value>Дясна скоба</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisCountAutomationNamePrefix" xml:space="preserve">
<value>Брой отворени скоби: %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific and programmer operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="NoRightParenthesisAdded_Announcement" xml:space="preserve">
<value>Няма отворени скоби за затваряне.</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator when the ")" button on the scientific and programmer operator keypad cannot be added to the equation. e.g. "1+)".</comment>
</data>
<data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Експоненциален запис</value> <value>Експоненциален запис</value>
<comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment>

View file

@ -909,6 +909,14 @@
<value>ডান বন্ধনী</value> <value>ডান বন্ধনী</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisCountAutomationNamePrefix" xml:space="preserve">
<value>বন্ধনী গণনা খুলুন %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific and programmer operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="NoRightParenthesisAdded_Announcement" xml:space="preserve">
<value>বন্ধ করার জন্য এখানে কোনো খোলা বন্ধনী নেই।</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator when the ")" button on the scientific and programmer operator keypad cannot be added to the equation. e.g. "1+)".</comment>
</data>
<data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>বৈজ্ঞানিক নোটেশন</value> <value>বৈজ্ঞানিক নোটেশন</value>
<comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment>
@ -2278,7 +2286,7 @@
<comment>Displayed on a link to the Microsoft Privacy Statement on the About panel</comment> <comment>Displayed on a link to the Microsoft Privacy Statement on the About panel</comment>
</data> </data>
<data name="AboutControlCopyright" xml:space="preserve"> <data name="AboutControlCopyright" xml:space="preserve">
<value>© %1 Microsoft. সর্বস্বত্ব সংরক্ষিত।</value> <value>© %1 Microsoft সর্বস্বত্ব সংরক্ষিত।</value>
<comment>{Locked="%1"}. Copyright statement, displayed on the About panel. %1 = the current year (4 digits)</comment> <comment>{Locked="%1"}. Copyright statement, displayed on the About panel. %1 = the current year (4 digits)</comment>
</data> </data>
<data name="AboutButton.Content" xml:space="preserve"> <data name="AboutButton.Content" xml:space="preserve">

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
@ -901,14 +901,19 @@
<value>Parèntesi d'obertura</value> <value>Parèntesi d'obertura</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>Parèntesi d'obertura, recompte de parèntesis d'obertura %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Parèntesi de tancament</value> <value>Parèntesi de tancament</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisCountAutomationNamePrefix" xml:space="preserve">
<value>Recompte de parèntesis oberts: %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific and programmer operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="NoRightParenthesisAdded_Announcement" xml:space="preserve">
<value>No hi ha cap parèntesi obert per tancar.</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator when the ")" button on the scientific and programmer operator keypad cannot be added to the equation. e.g. "1+)".</comment>
</data>
<data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Notació científica</value> <value>Notació científica</value>
<comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment>
@ -2899,4 +2904,4 @@
<value>Contracte de serveis de Microsoft</value> <value>Contracte de serveis de Microsoft</value>
<comment>Displayed on a link to the Microsoft Services Agreement in the about this app information</comment> <comment>Displayed on a link to the Microsoft Services Agreement in the about this app information</comment>
</data> </data>
</root> </root>

View file

@ -901,14 +901,19 @@
<value>Levá závorka</value> <value>Levá závorka</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>Levá závorka, počet otevřených závorek %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Pravá závorka</value> <value>Pravá závorka</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisCountAutomationNamePrefix" xml:space="preserve">
<value>Počet levých okrouhlých závorek %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific and programmer operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="NoRightParenthesisAdded_Announcement" xml:space="preserve">
<value>Nenašly se žádné levé okrouhlé závorky, ke kterým by bylo třeba přidat pravou závorku.</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator when the ")" button on the scientific and programmer operator keypad cannot be added to the equation. e.g. "1+)".</comment>
</data>
<data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Vědecký zápis</value> <value>Vědecký zápis</value>
<comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment>

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
@ -901,14 +901,19 @@
<value>Venstreparentes</value> <value>Venstreparentes</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>Venstre parentes, åben parentes antal %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Højreparentes</value> <value>Højreparentes</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisCountAutomationNamePrefix" xml:space="preserve">
<value>Åbn parentesantal %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific and programmer operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="NoRightParenthesisAdded_Announcement" xml:space="preserve">
<value>Der er ingen åbne parenteser at lukke.</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator when the ")" button on the scientific and programmer operator keypad cannot be added to the equation. e.g. "1+)".</comment>
</data>
<data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Videnskabelig notation</value> <value>Videnskabelig notation</value>
<comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment>
@ -2899,4 +2904,4 @@
<value>Microsoft-serviceaftale</value> <value>Microsoft-serviceaftale</value>
<comment>Displayed on a link to the Microsoft Services Agreement in the about this app information</comment> <comment>Displayed on a link to the Microsoft Services Agreement in the about this app information</comment>
</data> </data>
</root> </root>

View file

@ -434,7 +434,7 @@
<comment>This is the automation name and label for the memory button when the memory flyout is open.</comment> <comment>This is the automation name and label for the memory button when the memory flyout is open.</comment>
</data> </data>
<data name="MemoryButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve"> <data name="MemoryButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Arbeitsspeicher</value> <value>Speicher</value>
<comment>This is the tool tip automation name for the memory button.</comment> <comment>This is the tool tip automation name for the memory button.</comment>
</data> </data>
<data name="HistoryButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve"> <data name="HistoryButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
@ -454,7 +454,7 @@
<comment>This is the tool tip automation name for the Clear Memory (MC) button.</comment> <comment>This is the tool tip automation name for the Clear Memory (MC) button.</comment>
</data> </data>
<data name="MemoryLabel.Text" xml:space="preserve"> <data name="MemoryLabel.Text" xml:space="preserve">
<value>Arbeitsspeicher</value> <value>Speicher</value>
<comment>The text that shows as the header for the memory list</comment> <comment>The text that shows as the header for the memory list</comment>
</data> </data>
<data name="MemoryPivotItem.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="MemoryPivotItem.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
@ -562,7 +562,7 @@
<comment>Screen reader prompt for the history flyout</comment> <comment>Screen reader prompt for the history flyout</comment>
</data> </data>
<data name="MemoryPane" xml:space="preserve"> <data name="MemoryPane" xml:space="preserve">
<value>Arbeitsspeicher</value> <value>Speicher</value>
<comment>Screen reader prompt for the memory flyout</comment> <comment>Screen reader prompt for the memory flyout</comment>
</data> </data>
<data name="Format_HexButtonValue" xml:space="preserve"> <data name="Format_HexButtonValue" xml:space="preserve">
@ -606,7 +606,7 @@
<comment>Screen reader prompt for the Calculator Memory button</comment> <comment>Screen reader prompt for the Calculator Memory button</comment>
</data> </data>
<data name="memButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve"> <data name="memButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Gespeicherten Wert speichern (STRG+M)</value> <value>Speicher (STRG+M)</value>
<comment>This is the tool tip automation name for the Memory Store (MS) button.</comment> <comment>This is the tool tip automation name for the Memory Store (MS) button.</comment>
</data> </data>
<data name="ClearMemoryButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="ClearMemoryButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
@ -901,14 +901,19 @@
<value>Öffnende Klammer</value> <value>Öffnende Klammer</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>Runde Klammer links, Anzahl der öffnenden Klammern: %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Schließende Klammer</value> <value>Schließende Klammer</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisCountAutomationNamePrefix" xml:space="preserve">
<value>Anzahl geöffneter Klammern %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific and programmer operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="NoRightParenthesisAdded_Announcement" xml:space="preserve">
<value>Es sind keine zu schließenden Klammern vorhanden.</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator when the ")" button on the scientific and programmer operator keypad cannot be added to the equation. e.g. "1+)".</comment>
</data>
<data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Wissenschaftliche Schreibweise</value> <value>Wissenschaftliche Schreibweise</value>
<comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment>
@ -1162,7 +1167,7 @@
<comment>A measurement unit for volume. (Please choose the most appropriate plural form to fit any number between 0 and 999,999,999,999,999)</comment> <comment>A measurement unit for volume. (Please choose the most appropriate plural form to fit any number between 0 and 999,999,999,999,999)</comment>
</data> </data>
<data name="UnitAbbreviation_Liter" xml:space="preserve"> <data name="UnitAbbreviation_Liter" xml:space="preserve">
<value>L</value> <value>l</value>
<comment>An abbreviation for a measurement unit of volume</comment> <comment>An abbreviation for a measurement unit of volume</comment>
</data> </data>
<data name="UnitName_Milliliter" xml:space="preserve"> <data name="UnitName_Milliliter" xml:space="preserve">
@ -1170,7 +1175,7 @@
<comment>A measurement unit for volume. (Please choose the most appropriate plural form to fit any number between 0 and 999,999,999,999,999)</comment> <comment>A measurement unit for volume. (Please choose the most appropriate plural form to fit any number between 0 and 999,999,999,999,999)</comment>
</data> </data>
<data name="UnitAbbreviation_Milliliter" xml:space="preserve"> <data name="UnitAbbreviation_Milliliter" xml:space="preserve">
<value>mL</value> <value>ml</value>
<comment>An abbreviation for a measurement unit of volume</comment> <comment>An abbreviation for a measurement unit of volume</comment>
</data> </data>
<data name="UnitName_PintUK" xml:space="preserve"> <data name="UnitName_PintUK" xml:space="preserve">
@ -1506,7 +1511,7 @@
<comment>An abbreviation for a measurement unit of power</comment> <comment>An abbreviation for a measurement unit of power</comment>
</data> </data>
<data name="UnitAbbreviation_Week" xml:space="preserve"> <data name="UnitAbbreviation_Week" xml:space="preserve">
<value>wo</value> <value>w</value>
<comment>An abbreviation for a measurement unit of time</comment> <comment>An abbreviation for a measurement unit of time</comment>
</data> </data>
<data name="UnitAbbreviation_Yard" xml:space="preserve"> <data name="UnitAbbreviation_Yard" xml:space="preserve">

View file

@ -901,14 +901,19 @@
<value>Αριστερή παρένθεση</value> <value>Αριστερή παρένθεση</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>Αριστερή παρένθεση, πλήθος ανοιχτών παρενθέσεων %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Δεξιά παρένθεση</value> <value>Δεξιά παρένθεση</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisCountAutomationNamePrefix" xml:space="preserve">
<value>Πλήθος ανοιχτών παρενθέσεων %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific and programmer operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="NoRightParenthesisAdded_Announcement" xml:space="preserve">
<value>Δεν υπάρχουν ανοιχτές παρενθέσεις για κλείσιμο.</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator when the ")" button on the scientific and programmer operator keypad cannot be added to the equation. e.g. "1+)".</comment>
</data>
<data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Επιστημονική σημειογραφία</value> <value>Επιστημονική σημειογραφία</value>
<comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment>

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
@ -901,14 +901,19 @@
<value>Left parenthesis</value> <value>Left parenthesis</value>
<comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator "(" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisAutomationNamePrefix" xml:space="preserve">
<value>Left parenthesis, open parenthesis count %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="closeParenthesisButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Right parenthesis</value> <value>Right parenthesis</value>
<comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator ")" button on the scientific operator keypad</comment>
</data> </data>
<data name="Format_OpenParenthesisCountAutomationNamePrefix" xml:space="preserve">
<value>Open parenthesis count %1</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator "(" button on the scientific and programmer operator keypad. %1 is the localized count of open parenthesis, e.g. "2".</comment>
</data>
<data name="NoRightParenthesisAdded_Announcement" xml:space="preserve">
<value>There are no open parentheses to close.</value>
<comment>{Locked="%1"} Screen reader prompt for the Calculator when the ")" button on the scientific and programmer operator keypad cannot be added to the equation. e.g. "1+)".</comment>
</data>
<data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve"> <data name="ftoeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Scientific notation</value> <value>Scientific notation</value>
<comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment> <comment>Screen reader prompt for the Calculator F-E the scientific operator keypad</comment>
@ -2899,4 +2904,4 @@
<value>Microsoft Services Agreement</value> <value>Microsoft Services Agreement</value>
<comment>Displayed on a link to the Microsoft Services Agreement in the about this app information</comment> <comment>Displayed on a link to the Microsoft Services Agreement in the about this app information</comment>
</data> </data>
</root> </root>

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