Feature/GraphingCalculator initial commit (#450)

Initial PR for the feature/GraphingCalculator feature branch, part of #338.

The feature incorporates a proprietary Microsoft-owned graphing engine to drive graphing experiences in the Windows Calculator app. Due to the private nature of the graphing engine, the source available in the public repo will make use of a mock graphing engine. See README.md for more details.

This PR simply serves as a base for future feature development. As such, the PR will be immediately merged. Feedback on the content of this PR, and on the feature in general, is encouraged. If there is feedback related to the content of this specific PR, please leave comments on the PR page. We will address the comments in future PRs to the feature branch.
This commit is contained in:
Daniel Belcher
2019-04-10 18:15:10 -07:00
committed by GitHub
parent 47a2741218
commit 091732aa94
65 changed files with 5190 additions and 109 deletions

View File

@@ -130,6 +130,9 @@
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup>
<Import Project="$(SolutionDir)\GraphControl\GraphingImplOverrides.props" Condition="Exists('$(SolutionDir)\GraphControl\GraphingImplOverrides.props')" />
</ImportGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<AdditionalOptions>/bigobj /await /std:c++17 </AdditionalOptions>
@@ -281,6 +284,12 @@
<ClInclude Include="Views\CalculatorStandardOperators.xaml.h">
<DependentUpon>Views\CalculatorStandardOperators.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="Views\GraphingCalculator\EquationInputArea.xaml.h">
<DependentUpon>Views\GraphingCalculator\EquationInputArea.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="Views\GraphingCalculator\GraphingCalculator.xaml.h">
<DependentUpon>Views\GraphingCalculator\GraphingCalculator.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="Views\HistoryList.xaml.h">
<DependentUpon>Views\HistoryList.xaml</DependentUpon>
</ClInclude>
@@ -336,6 +345,8 @@
</Page>
<Page Include="Views\CalculatorStandardOperators.xaml" />
<Page Include="Views\DelighterUnitStyles.xaml" />
<Page Include="Views\GraphingCalculator\EquationInputArea.xaml" />
<Page Include="Views\GraphingCalculator\GraphingCalculator.xaml" />
<Page Include="Views\HistoryList.xaml" />
<Page Include="Views\MainPage.xaml" />
<Page Include="Views\Memory.xaml" />
@@ -421,6 +432,12 @@
<ClCompile Include="Views\CalculatorStandardOperators.xaml.cpp">
<DependentUpon>Views\CalculatorStandardOperators.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="Views\GraphingCalculator\EquationInputArea.xaml.cpp">
<DependentUpon>Views\GraphingCalculator\EquationInputArea.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="Views\GraphingCalculator\GraphingCalculator.xaml.cpp">
<DependentUpon>Views\GraphingCalculator\GraphingCalculator.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="Views\HistoryList.xaml.cpp">
<DependentUpon>Views\HistoryList.xaml</DependentUpon>
</ClCompile>
@@ -829,6 +846,9 @@
<ProjectReference Include="..\CalcViewModel\CalcViewModel.vcxproj">
<Project>{90e9761d-9262-4773-942d-caeae75d7140}</Project>
</ProjectReference>
<ProjectReference Include="..\GraphControl\GraphControl.vcxproj">
<Project>{e727a92b-f149-492c-8117-c039a298719b}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<!-- Override MSBuild target to workaround VS bug with building using framework packages -->

View File

@@ -218,6 +218,9 @@
<Filter Include="Views\StateTriggers">
<UniqueIdentifier>{0120c344-0bc0-4a1d-b82c-df7945f46189}</UniqueIdentifier>
</Filter>
<Filter Include="Views\GraphingCalculator">
<UniqueIdentifier>{e23e2a6e-491b-4200-9bf7-d355a1ee695b}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml" />
@@ -480,6 +483,12 @@
<Page Include="Views\OperatorsPanel.xaml">
<Filter>Views</Filter>
</Page>
<Page Include="Views\GraphingCalculator\EquationInputArea.xaml">
<Filter>Views\GraphingCalculator</Filter>
</Page>
<Page Include="Views\GraphingCalculator\GraphingCalculator.xaml">
<Filter>Views\GraphingCalculator</Filter>
</Page>
</ItemGroup>
<ItemGroup>
<PRIResource Include="Resources\en-US\CEngineStrings.resw">

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5" IgnorableNamespaces="uap uap5 mp">
<Identity Name="Microsoft.WindowsCalculator.Dev" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" Version="0.0.0.0" />
<Identity Name="Microsoft.WindowsCalculator.Graphing" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" Version="0.0.0.0" />
<mp:PhoneIdentity PhoneProductId="b58171c6-c70c-4266-a2e8-8f9c994f4456" PhonePublisherId="95d94207-0c7c-47ed-82db-d75c81153c35" />
<Properties>
<DisplayName>ms-resource:DevAppStoreName</DisplayName>

View File

@@ -118,7 +118,7 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AppName" xml:space="preserve">
<value>Calculator</value>
<value>Graphing Calculator</value>
<comment>{@Appx_ShortDisplayName@}{StringCategory="Feature Title"} This is the title of the official application when published through Windows Store.</comment>
</data>
<data name="DevAppName" xml:space="preserve">
@@ -1271,7 +1271,7 @@
</data>
<data name="equalButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Equals</value>
<comment>Screen reader prompt for the invert button on the scientific operator keypad</comment>
<comment>Screen reader prompt for the equals button on the scientific operator keypad</comment>
</data>
<data name="shiftButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Inverse Function</value>
@@ -3379,4 +3379,40 @@
<value>Microsoft Services Agreement</value>
<comment>Displayed on a link to the Microsoft Services Agreement in the about this app information</comment>
</data>
<data name="GraphingCalculatorModeText" xml:space="preserve">
<value>Graphing</value>
<comment>Name of the Graphing mode of the Calculator app. Displayed in the navigation menu.</comment>
</data>
<data name="graphingEqualButton.[using:CalculatorApp.Common]KeyboardShortcutManager.Character" xml:space="preserve">
<value>=</value>
<comment>{Locked}This is the character that should trigger this button. Note that it is a character and not a key, so it does not come from the Windows::System::VirtualKey enum.</comment>
</data>
<data name="graphingEqualButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Equals</value>
<comment>Screen reader prompt for the equal button on the graphing calculator operator keypad</comment>
</data>
<data name="plotButton.[using:CalculatorApp.Common]KeyboardShortcutManager.VirtualKey" xml:space="preserve">
<value>Enter</value>
<comment>{Locked}This is the value from the VirtualKey enum that maps to this button</comment>
</data>
<data name="plotButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Plot</value>
<comment>Screen reader prompt for the plot button on the graphing calculator operator keypad</comment>
</data>
<data name="xButton.[using:CalculatorApp.Common]KeyboardShortcutManager.VirtualKey" xml:space="preserve">
<value>X</value>
<comment>{Locked}This is the value that comes from the VirtualKey enum that represents the button. This value is not localized and must be one value that comes from the Windows::System::VirtualKey enum.</comment>
</data>
<data name="yButton.[using:CalculatorApp.Common]KeyboardShortcutManager.VirtualKey" xml:space="preserve">
<value>Y</value>
<comment>{Locked}This is the value that comes from the VirtualKey enum that represents the button. This value is not localized and must be one value that comes from the Windows::System::VirtualKey enum.</comment>
</data>
<data name="EquationInputAreaHeader.Text" xml:space="preserve">
<value>Equations</value>
<comment>The text that shows as the header for the equation input area in Graphing Calculator mode.</comment>
</data>
<data name="graphingPowerButton.[using:CalculatorApp.Common]KeyboardShortcutManager.Character" xml:space="preserve">
<value>^</value>
<comment>{Locked}This is the character that should trigger this button. Note that it is a character and not a key, so it does not come from the Windows::System::VirtualKey enum.</comment>
</data>
</root>

View File

@@ -0,0 +1,86 @@
<UserControl x:Class="CalculatorApp.EquationInputArea"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:CalculatorApp.ViewModel"
d:DesignHeight="300"
d:DesignWidth="400"
mc:Ignorable="d">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Margin="0,0,17,0">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock x:Uid="EquationInputAreaHeader"
Grid.Column="0"
Style="{ThemeResource SubheaderTextBlockStyle}"
FontSize="20"/>
<Button Grid.Column="1"
Click="AddEquationButton_Click"
Content="+"/>
</Grid>
<ListView x:Name="EquationInputList"
Grid.Row="2"
Margin="0,4,0,0"
IsItemClickEnabled="False"
ItemsSource="{x:Bind Equations}"
SelectionMode="None">
<ListView.Resources>
<x:Double x:Key="ItemHeight">40</x:Double>
</ListView.Resources>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="0,0,17,1"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate x:DataType="vm:EquationViewModel">
<Grid Height="{StaticResource ItemHeight}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.Resources>
<SolidColorBrush x:Key="LineColorBrush" Color="{x:Bind LineColor, Mode=OneWay}"/>
</Grid.Resources>
<Grid.Background>
<StaticResource ResourceKey="LineColorBrush"/>
</Grid.Background>
<Button Width="{StaticResource ItemHeight}"
Height="{StaticResource ItemHeight}"
Background="{StaticResource LineColorBrush}"/>
<Rectangle x:Name="InputBackplate"
Grid.Column="1"
Margin="0,2,3,2"
Fill="White"/>
<TextBox Grid.Column="1"
Margin="0,2,3,2"
GotFocus="InputTextBox_GotFocus"
KeyUp="InputTextBox_KeyUp"
LostFocus="InputTextBox_LostFocus"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</UserControl>

View File

@@ -0,0 +1,108 @@
#include "pch.h"
#include "EquationInputArea.xaml.h"
#include "CalcViewModel/Common/KeyboardShortcutManager.h"
using namespace CalculatorApp;
using namespace CalculatorApp::Common;
using namespace CalculatorApp::ViewModel;
using namespace Platform;
using namespace std;
using namespace Windows::System;
using namespace Windows::UI;
using namespace Windows::UI::ViewManagement;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Input;
namespace
{
const Color accentColor = (ref new UISettings())->GetColorValue(UIColorType::Accent);
const Color lineColors[] = {
accentColor,
Colors::DarkOrange,
Colors::MediumPurple,
Colors::ForestGreen,
Colors::BlueViolet,
Colors::DarkRed,
Colors::LightGoldenrodYellow,
Colors::DarkOliveGreen
};
const size_t lineColorsSize = std::size(lineColors);
StringReference EquationsPropertyName(L"Equations");
}
EquationInputArea::EquationInputArea()
: m_lastLineColorIndex{ -1 }
{
InitializeComponent();
}
void EquationInputArea::OnPropertyChanged(String^ propertyName)
{
if (propertyName == EquationsPropertyName)
{
OnEquationsPropertyChanged();
}
}
void EquationInputArea::OnEquationsPropertyChanged()
{
if (Equations != nullptr && Equations->Size == 0)
{
AddNewEquation();
// For now, the first equation needs to be y = 0.
// We can remove this when we can create empty graphs.
if (EquationViewModel^ eqvm = Equations->GetAt(0))
{
eqvm->Expression = L"0";
}
}
}
void EquationInputArea::AddEquationButton_Click(Object^ sender, RoutedEventArgs^ e)
{
AddNewEquation();
}
void EquationInputArea::AddNewEquation()
{
auto eq = ref new EquationViewModel();
eq->LineColor = GetNextLineColor();
Equations->Append(eq);
EquationInputList->ScrollIntoView(eq);
}
void EquationInputArea::InputTextBox_GotFocus(Object^ sender, RoutedEventArgs^ e)
{
KeyboardShortcutManager::HonorShortcuts(false);
}
void EquationInputArea::InputTextBox_LostFocus(Object^ sender, RoutedEventArgs^ e)
{
KeyboardShortcutManager::HonorShortcuts(true);
auto tb = static_cast<TextBox^>(sender);
auto eq = static_cast<EquationViewModel^>(tb->DataContext);
tb->Text = eq->Expression;
}
void EquationInputArea::InputTextBox_KeyUp(Object^ sender, KeyRoutedEventArgs^ e)
{
if (e->Key == VirtualKey::Enter)
{
auto tb = static_cast<TextBox^>(sender);
auto eq = static_cast<EquationViewModel^>(tb->DataContext);
eq->Expression = tb->Text;
e->Handled = true;
}
}
Color EquationInputArea::GetNextLineColor()
{
m_lastLineColorIndex = (m_lastLineColorIndex + 1) % lineColorsSize;
return lineColors[m_lastLineColorIndex];
}

View File

@@ -0,0 +1,33 @@
#pragma once
#include "Views/GraphingCalculator/EquationInputArea.g.h"
#include "CalcViewModel/Common/Utils.h"
#include "CalcViewModel/GraphingCalculator/EquationViewModel.h"
namespace CalculatorApp
{
public ref class EquationInputArea sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
{
public:
EquationInputArea();
OBSERVABLE_OBJECT_CALLBACK(OnPropertyChanged);
OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IObservableVector< ViewModel::EquationViewModel^ >^, Equations);
private:
void OnPropertyChanged(Platform::String^ propertyName);
void OnEquationsPropertyChanged();
void AddEquationButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void AddNewEquation();
void InputTextBox_GotFocus(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void InputTextBox_LostFocus(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void InputTextBox_KeyUp(Platform::Object^ sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e);
Windows::UI::Color GetNextLineColor();
private:
int m_lastLineColorIndex;
};
}

View File

@@ -0,0 +1,242 @@
<UserControl x:Class="CalculatorApp.GraphingCalculator"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CalculatorApp.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:graphControl="using:GraphControl"
xmlns:local="using:CalculatorApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:CalculatorApp.ViewModel"
DataContextChanged="GraphingCalculator_DataContextChanged"
mc:Ignorable="d">
<Grid x:Name="RootGrid">
<Grid.RowDefinitions>
<RowDefinition x:Name="RowHamburger" Height="{StaticResource HamburgerHeightGridLength}"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<!-- Left portion of the screen -->
<Grid x:Name="LeftGrid"
Grid.Row="1"
Grid.Column="0">
<graphControl:Grapher Grid.Row="0"
Margin="4,7,4,4"
EquationsSource="{x:Bind ViewModel.Equations, Mode=OneWay}"
ForceProportionalAxes="True"
UseSystemFocusVisuals="True">
<graphControl:Grapher.Background>
<SolidColorBrush Color="White"/>
</graphControl:Grapher.Background>
<graphControl:Grapher.EquationTemplate>
<DataTemplate x:DataType="vm:EquationViewModel">
<graphControl:Equation Expression="{x:Bind Expression, Mode=OneWay}" LineColor="{x:Bind LineColor, Mode=OneWay}"/>
</DataTemplate>
</graphControl:Grapher.EquationTemplate>
</graphControl:Grapher>
</Grid>
<!-- Right portion of the screen -->
<Grid x:Name="RightGrid"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Margin="4,0,4,0">
<Grid.RowDefinitions>
<RowDefinition Height="5*"/>
<RowDefinition Height="3*"/>
</Grid.RowDefinitions>
<local:EquationInputArea Grid.Row="0" Equations="{x:Bind ViewModel.Equations}"/>
<Grid x:Name="ButtonContainerGrid"
Grid.Row="1"
Margin="3,0,3,3"
UseLayoutRounding="False">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<controls:CalculatorButton x:Name="XButton"
x:Uid="xButton"
Grid.Row="0"
Grid.Column="0"
Style="{StaticResource OperatorButtonStyle}"
FontSize="16"
ButtonId="X"
Content="𝑥"
FlowDirection="LeftToRight"/>
<controls:CalculatorButton x:Name="YButton"
x:Uid="yButton"
Grid.Row="0"
Grid.Column="1"
Style="{StaticResource OperatorButtonStyle}"
FontSize="16"
ButtonId="Y"
Content="𝑦"
FlowDirection="LeftToRight"/>
<controls:CalculatorButton x:Name="PowerButton"
x:Uid="graphingPowerButton"
Grid.Row="0"
Grid.Column="2"
Style="{StaticResource OperatorButtonStyle}"
ButtonId="XPowerY"
Content="^"/>
<controls:CalculatorButton x:Name="squareRootButton"
x:Uid="squareRootButton"
Grid.Row="0"
Grid.Column="3"
Style="{StaticResource SymbolOperatorButtonStyle}"
FontFamily="{StaticResource SymbolThemeFontFamily}"
ButtonId="Sqrt"
Content="&#xE94B;"/>
<!-- Display controls -->
<controls:CalculatorButton x:Name="ClearButton"
x:Uid="clearButton"
Grid.Row="1"
Grid.Column="2"
Style="{StaticResource OperatorButtonStyle}"
FontSize="16"
ButtonId="Clear"
Content="C"/>
<controls:CalculatorButton x:Name="BackSpaceButton"
x:Uid="backSpaceButton"
Grid.Row="1"
Grid.Column="3"
Style="{StaticResource SymbolOperatorButtonStyle}"
FontSize="16"
ButtonId="Backspace"
Content="&#xE94F;"/>
<!-- Basic operators -->
<controls:CalculatorButton x:Name="EqualButton"
x:Uid="graphingEqualButton"
Grid.Row="0"
Grid.Column="4"
Style="{StaticResource AccentCalcButtonStyle}"
ButtonId="Equals"
Content="&#xE94E;"/>
<controls:CalculatorButton x:Name="DivideButton"
x:Uid="divideButton"
Grid.Row="1"
Grid.Column="4"
Style="{StaticResource AccentCalcButtonStyle}"
ButtonId="Divide"
Content="&#xE94A;"/>
<controls:CalculatorButton x:Name="MultiplyButton"
x:Uid="multiplyButton"
Grid.Row="2"
Grid.Column="4"
Style="{StaticResource AccentCalcButtonStyle}"
ButtonId="Multiply"
Content="&#xE947;"/>
<controls:CalculatorButton x:Name="MinusButton"
x:Uid="minusButton"
Grid.Row="3"
Grid.Column="4"
Style="{StaticResource AccentCalcButtonStyle}"
ButtonId="Subtract"
Content="&#xE949;"/>
<controls:CalculatorButton x:Name="PlusButton"
x:Uid="plusButton"
Grid.Row="4"
Grid.Column="4"
Style="{StaticResource AccentCalcButtonStyle}"
ButtonId="Add"
Content="&#xE948;"/>
<controls:CalculatorButton x:Name="logBase10Button"
x:Uid="logBase10Button"
Grid.Row="1"
Grid.Column="0"
Style="{StaticResource OperatorButtonStyle}"
ButtonId="LogBase10"
Content="log"/>
<controls:CalculatorButton x:Name="logBaseEButton"
x:Uid="logBaseEButton"
Grid.Row="1"
Grid.Column="1"
Style="{StaticResource OperatorButtonStyle}"
ButtonId="LogBaseE"
Content="ln"/>
<controls:CalculatorButton x:Name="powerOf10Button"
x:Uid="powerOf10Button"
Grid.Row="2"
Grid.Column="0"
Style="{StaticResource SymbolOperatorButtonStyle}"
AutomationProperties.AutomationId="powerOf10Button"
ButtonId="TenPowerX"
Content="&#xF7CC;"/>
<controls:CalculatorButton x:Name="powerOfEButton"
x:Uid="powerOfEButton"
Grid.Row="3"
Grid.Column="0"
Style="{StaticResource SymbolOperatorButtonStyle}"
ButtonId="EPowerX"
Content="&#xf7ce;"/>
<controls:CalculatorButton x:Name="piButton"
x:Uid="piButton"
Grid.Row="4"
Grid.Column="0"
Style="{StaticResource SymbolOperatorButtonStyle}"
FontSize="14"
ButtonId="Pi"
Content="&#xf7cf;"/>
<controls:CalculatorButton x:Name="openParenthesisButton"
x:Uid="openParenthesisButton"
Grid.Row="5"
Grid.Column="0"
Style="{StaticResource ParenthesisCalcButtonStyle}"
FontSize="19"
ButtonId="OpenParenthesis"
Content="("/>
<controls:CalculatorButton x:Name="closeParenthesisButton"
x:Uid="closeParenthesisButton"
Grid.Row="5"
Grid.Column="1"
Style="{StaticResource OperatorButtonStyle}"
FontSize="19"
ButtonId="CloseParenthesis"
Content=")"/>
<!-- The Numberpad -->
<local:NumberPad x:Name="NumberPad"
x:Uid="NumberPad"
Grid.Row="2"
Grid.RowSpan="4"
Grid.Column="1"
Grid.ColumnSpan="3"
ButtonStyle="{StaticResource NumericButtonStyle24}"/>
<controls:CalculatorButton x:Name="PlotButton"
x:Uid="plotButton"
Grid.Row="5"
Grid.Column="4"
Style="{StaticResource AccentCalcButtonStyle}"
FontFamily="{StaticResource SymbolThemeFontFamily}"
ButtonId="Plot"
Content="&#xE72A;"/>
</Grid>
</Grid>
</Grid>
</UserControl>

View File

@@ -0,0 +1,51 @@
#include "pch.h"
#include "GraphingCalculator.xaml.h"
#include "CalcViewModel/Common/KeyboardShortcutManager.h"
#include "Controls/CalculationResult.h"
using namespace CalculatorApp;
using namespace CalculatorApp::Common;
using namespace CalculatorApp::Controls;
using namespace CalculatorApp::ViewModel;
using namespace concurrency;
using namespace GraphControl;
using namespace Platform;
using namespace std::chrono;
using namespace Utils;
using namespace Windows::Foundation::Collections;
using namespace Windows::Storage::Streams;
using namespace Windows::System;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Media::Imaging;
constexpr auto sc_ViewModelPropertyName = L"ViewModel";
GraphingCalculator::GraphingCalculator()
{
Equation::RegisterDependencyProperties();
Grapher::RegisterDependencyProperties();
InitializeComponent();
}
void GraphingCalculator::GraphingCalculator_DataContextChanged(FrameworkElement^ sender, DataContextChangedEventArgs^ args)
{
ViewModel = dynamic_cast<GraphingCalculatorViewModel^>(args->NewValue);
}
GraphingCalculatorViewModel^ GraphingCalculator::ViewModel::get()
{
return m_viewModel;
}
void GraphingCalculator::ViewModel::set(GraphingCalculatorViewModel^ vm)
{
if (m_viewModel != vm)
{
m_viewModel = vm;
RaisePropertyChanged(StringReference(sc_ViewModelPropertyName));
}
}

View File

@@ -0,0 +1,28 @@
#pragma once
#include "Views\GraphingCalculator\GraphingCalculator.g.h"
#include "CalcViewModel/GraphingCalculator/GraphingCalculatorViewModel.h"
#include "Views\NumberPad.xaml.h"
namespace CalculatorApp
{
public ref class GraphingCalculator sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
{
public:
GraphingCalculator();
OBSERVABLE_OBJECT();
property CalculatorApp::ViewModel::GraphingCalculatorViewModel^ ViewModel
{
CalculatorApp::ViewModel::GraphingCalculatorViewModel^ get();
void set(CalculatorApp::ViewModel::GraphingCalculatorViewModel^ vm);
}
private:
void GraphingCalculator_DataContextChanged(Windows::UI::Xaml::FrameworkElement^ sender, Windows::UI::Xaml::DataContextChangedEventArgs^ args);
private:
CalculatorApp::ViewModel::GraphingCalculatorViewModel^ m_viewModel;
};
}

View File

@@ -154,6 +154,9 @@
<Border x:Name="DateCalcHolder">
<!-- PLACEHOLDER!!!! This is where the date calculator goes when it is delay loaded -->
</Border>
<Border x:Name="GraphingCalcHolder" Grid.Row="1">
<!-- PLACEHOLDER!!!! This is where the graphing calculator goes when it is delay loaded -->
</Border>
<Border x:Name="ConverterHolder">
<!-- PLACEHOLDER!!!! This is where the converter goes when it is delay loaded -->
</Border>

View File

@@ -167,6 +167,10 @@ void MainPage::OnAppPropertyChanged(_In_ Platform::Object^ sender, _In_ Windows:
}
EnsureDateCalculator();
}
else if (newValue == ViewMode::Graphing)
{
EnsureGraphingCalculator();
}
else if (NavCategory::IsConverterViewMode(newValue))
{
if (m_model->CalculatorViewModel)
@@ -196,9 +200,10 @@ void MainPage::OnAppPropertyChanged(_In_ Platform::Object^ sender, _In_ Windows:
void MainPage::ShowHideControls(ViewMode mode)
{
auto isCalcViewMode = NavCategory::IsCalculatorViewMode(mode);
auto isDateCalcViewMode = NavCategory::IsDateCalculatorViewMode(mode);
auto isConverterViewMode = NavCategory::IsConverterViewMode(mode);
bool isCalcViewMode = NavCategory::IsCalculatorViewMode(mode);
bool isDateCalcViewMode = NavCategory::IsDateCalculatorViewMode(mode);
bool isGraphingCalcViewMode = NavCategory::IsGraphingCalculatorViewMode(mode);
bool isConverterViewMode = NavCategory::IsConverterViewMode(mode);
if (m_calculator)
{
@@ -212,6 +217,12 @@ void MainPage::ShowHideControls(ViewMode mode)
m_dateCalculator->IsEnabled = isDateCalcViewMode;
}
if (m_graphingCalculator)
{
m_graphingCalculator->Visibility = BooleanToVisibilityConverter::Convert(isGraphingCalcViewMode);
m_graphingCalculator->IsEnabled = isGraphingCalcViewMode;
}
if (m_converter)
{
m_converter->Visibility = BooleanToVisibilityConverter::Convert(isConverterViewMode);
@@ -239,7 +250,7 @@ void MainPage::UpdatePanelViewState()
void MainPage::OnPageLoaded(_In_ Object^, _In_ RoutedEventArgs^ args)
{
if (!m_converter && !m_calculator && !m_dateCalculator)
if (!m_converter && !m_calculator && !m_dateCalculator && !m_graphingCalculator)
{
// We have just launched into our default mode (standard calc) so ensure calc is loaded
EnsureCalculator();
@@ -292,6 +303,10 @@ void MainPage::SetDefaultFocus()
{
m_dateCalculator->SetDefaultFocus();
}
if (m_graphingCalculator != nullptr && m_graphingCalculator->Visibility == ::Visibility::Visible)
{
m_graphingCalculator->Focus(::FocusState::Programmatic);
}
if (m_converter != nullptr && m_converter->Visibility == ::Visibility::Visible)
{
m_converter->SetDefaultFocus();
@@ -354,6 +369,18 @@ void MainPage::EnsureDateCalculator()
}
}
void MainPage::EnsureGraphingCalculator()
{
if (!m_graphingCalculator)
{
m_graphingCalculator = ref new GraphingCalculator();
m_graphingCalculator->Name = L"GraphingCalculator";
m_graphingCalculator->DataContext = m_model->GraphingCalcViewModel;
GraphingCalcHolder->Child = m_graphingCalculator;
}
}
void MainPage::EnsureConverter()
{
if (!m_converter)
@@ -571,7 +598,7 @@ void MainPage::SetHeaderAutomationName()
else
{
wstring full;
if (NavCategory::IsCalculatorViewMode(mode))
if (NavCategory::IsCalculatorViewMode(mode) || NavCategory::IsGraphingCalculatorViewMode(mode))
{
full = resProvider.GetResourceString(L"HeaderAutomationName_Calculator")->Data();
}
@@ -581,6 +608,7 @@ void MainPage::SetHeaderAutomationName()
}
string::size_type found = full.find(L"%1");
assert(found != wstring::npos);
wstring strMode = m_model->CategoryName->Data();
full = full.replace(found, 2, strMode);

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.
#pragma once
@@ -6,6 +6,7 @@
#include "Views/Calculator.xaml.h"
#include "Views/MainPage.g.h"
#include "Views/DateCalculator.xaml.h"
#include "Views/GraphingCalculator/GraphingCalculator.xaml.h"
#include "Views/UnitConverter.xaml.h"
#include "CalcViewModel/ApplicationViewModel.h"
#include "Views/TitleBar.xaml.h"
@@ -24,9 +25,9 @@ namespace CalculatorApp
{
public:
MainPage();
property CalculatorApp::ViewModel::ApplicationViewModel^ Model
property ViewModel::ApplicationViewModel^ Model
{
CalculatorApp::ViewModel::ApplicationViewModel^ get(){
ViewModel::ApplicationViewModel^ get(){
return m_model;
}
}
@@ -36,7 +37,7 @@ namespace CalculatorApp
void SetDefaultFocus();
void SetHeaderAutomationName();
Windows::Foundation::Collections::IObservableVector<Platform::Object^>^ CreateUIElementsForCategories(_In_ Windows::Foundation::Collections::IObservableVector<CalculatorApp::Common::NavCategoryGroup^>^ categories);
Windows::Foundation::Collections::IObservableVector<Platform::Object^>^ CreateUIElementsForCategories(_In_ Windows::Foundation::Collections::IObservableVector<Common::NavCategoryGroup^>^ categories);
protected:
void OnNavigatedTo(_In_ Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
@@ -57,13 +58,13 @@ namespace CalculatorApp
void OnAboutFlyoutOpened(_In_ Platform::Object^ sender, _In_ Platform::Object^ e);
void OnAboutFlyoutClosed(_In_ Platform::Object^ sender, _In_ Platform::Object^ e);
Microsoft::UI::Xaml::Controls::NavigationViewItemHeader^ CreateNavViewHeaderFromGroup(CalculatorApp::Common::NavCategoryGroup^ group);
Microsoft::UI::Xaml::Controls::NavigationViewItem^ CreateNavViewItemFromCategory(CalculatorApp::Common::NavCategory^ category);
Microsoft::UI::Xaml::Controls::NavigationViewItemHeader^ CreateNavViewHeaderFromGroup(Common::NavCategoryGroup^ group);
Microsoft::UI::Xaml::Controls::NavigationViewItem^ CreateNavViewItemFromCategory(Common::NavCategory^ category);
Windows::Foundation::EventRegistrationToken m_fullscreenFlyoutClosedToken;
void OnFullscreenFlyoutClosed();
void ShowHideControls(CalculatorApp::Common::ViewMode mode);
void ShowHideControls(Common::ViewMode mode);
void UpdateViewState();
void UpdatePanelViewState();
@@ -73,21 +74,23 @@ namespace CalculatorApp
void PinUnpinAppBarButtonOnClicked(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void EnsureCalculator();
void EnsureConverter();
void EnsureDateCalculator();
void EnsureGraphingCalculator();
void EnsureConverter();
void ShowAboutPage();
void AnnounceCategoryName();
CalculatorApp::Calculator^ m_calculator;
CalculatorApp::UnitConverter^ m_converter;
CalculatorApp::DateCalculator^ m_dateCalculator;
Calculator^ m_calculator;
GraphingCalculator^ m_graphingCalculator;
UnitConverter^ m_converter;
DateCalculator^ m_dateCalculator;
Windows::Foundation::EventRegistrationToken _windowSizeEventToken;
Windows::Foundation::EventRegistrationToken m_hardwareButtonsBackPressedToken;
Windows::Foundation::EventRegistrationToken m_colorValuesChangedToken;
CalculatorApp::ViewModel::ApplicationViewModel^ m_model;
ViewModel::ApplicationViewModel^ m_model;
Windows::UI::ViewManagement::UISettings^ m_uiSettings;
std::unique_ptr<CalculatorApp::Common::TitleBarHelper> m_titleBarHelper;
std::unique_ptr<Common::TitleBarHelper> m_titleBarHelper;
};
}