Wire up keyboard in graphing calculator (#863)
* Wire up graphing calculator keyboard with math rich edit control * CR feedback * Handle focus bug in flyout
This commit is contained in:
@@ -31,7 +31,7 @@ namespace CalculatorApp
|
||||
|
||||
static Windows::UI::Xaml::Media::SolidColorBrush
|
||||
^ ToSolidColorBrush(Windows::UI::Color color) { return ref new Windows::UI::Xaml::Media::SolidColorBrush(color); }
|
||||
|
||||
|
||||
private:
|
||||
void OnPropertyChanged(Platform::String^ propertyName);
|
||||
void OnEquationsPropertyChanged();
|
||||
@@ -59,7 +59,6 @@ namespace CalculatorApp
|
||||
void TextBoxKeyDown(Windows::UI::Xaml::Controls::TextBox ^ textbox, Windows::UI::Xaml::Input::KeyRoutedEventArgs ^ e);
|
||||
void SubmitTextbox(Windows::UI::Xaml::Controls::TextBox ^ textbox);
|
||||
|
||||
private:
|
||||
Windows::UI::ViewManagement::AccessibilitySettings ^ m_accessibilitySettings;
|
||||
int m_lastLineColorIndex;
|
||||
int m_lastFunctionLabelIndex;
|
||||
|
@@ -514,7 +514,8 @@
|
||||
Variables="{x:Bind ViewModel.Variables}"
|
||||
Visibility="{x:Bind IsKeyGraphFeaturesVisible, Converter={StaticResource BooleanToVisibilityNegationConverter}, Mode=OneWay}"/>
|
||||
|
||||
<local:GraphingNumPad Grid.Row="1"
|
||||
<local:GraphingNumPad x:Name="GraphingNumberPad"
|
||||
Grid.Row="1"
|
||||
Margin="2,0,2,2"
|
||||
Visibility="{x:Bind IsKeyGraphFeaturesVisible, Converter={StaticResource BooleanToVisibilityNegationConverter}, Mode=OneWay}"/>
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,9 @@
|
||||
#include "pch.h"
|
||||
#include "GraphingNumPad.xaml.h"
|
||||
#include "Views/NumberPad.xaml.h"
|
||||
#include "Controls/CalculatorButton.h"
|
||||
#include "CalcViewModel/Common/LocalizationSettings.h"
|
||||
#include "Controls/MathRichEditBox.h"
|
||||
|
||||
using namespace CalculatorApp;
|
||||
|
||||
@@ -18,43 +21,130 @@ using namespace Windows::UI::Xaml::Input;
|
||||
using namespace Windows::UI::Xaml::Media;
|
||||
using namespace Windows::UI::Xaml::Navigation;
|
||||
|
||||
// Dictionary of the enum of the button clicked mapped to an object with the string to enter into the rich edit, and the start and end of the selection after text has been entered.
|
||||
static const std::unordered_map<NumbersAndOperatorsEnum, std::tuple<Platform::String ^, int, int>> buttonOutput = {
|
||||
{ NumbersAndOperatorsEnum::Sin, { L"sin()", 4, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Cos, { L"cos()", 4, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Tan, { L"tan()", 4, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Sec, { L"sec()", 4, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Csc, { L"csc()", 4, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Cot, { L"cot()", 4, 0 } },
|
||||
{ NumbersAndOperatorsEnum::InvSin, { L"arcsin()", 7, 0 } },
|
||||
{ NumbersAndOperatorsEnum::InvCos, { L"arccos()", 7, 0 } },
|
||||
{ NumbersAndOperatorsEnum::InvTan, { L"arctan()", 7, 0 } },
|
||||
{ NumbersAndOperatorsEnum::InvSec, { L"arcsec()", 7, 0 } },
|
||||
{ NumbersAndOperatorsEnum::InvCsc, { L"arccsc()", 7, 0 } },
|
||||
{ NumbersAndOperatorsEnum::InvCot, { L"arccot()", 7, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Sinh, { L"sinh()", 5, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Cosh, { L"cosh()", 5, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Tanh, { L"tanh()", 5, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Sech, { L"sech()", 5, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Csch, { L"csch()", 5, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Coth, { L"coth()", 5, 0 } },
|
||||
{ NumbersAndOperatorsEnum::InvSinh, { L"arcsinh()", 8, 0 } },
|
||||
{ NumbersAndOperatorsEnum::InvCosh, { L"arccosh()", 8, 0 } },
|
||||
{ NumbersAndOperatorsEnum::InvTanh, { L"arctanh()", 8, 0 } },
|
||||
{ NumbersAndOperatorsEnum::InvSech, { L"arcsech()", 8, 0 } },
|
||||
{ NumbersAndOperatorsEnum::InvCsch, { L"arccsch()", 8, 0 } },
|
||||
{ NumbersAndOperatorsEnum::InvCoth, { L"arccoth()", 8, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Abs, { L"abs()", 4, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Floor, { L"floor()", 6, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Ceil, { L"ceiling()", 8, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Pi, { L"\u03C0", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Euler, { L"e", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::XPower2, { L"^2", 2, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Cube, { L"^3", 2, 0 } },
|
||||
{ NumbersAndOperatorsEnum::XPowerY, { L"^", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::TenPowerX, { L"10^", 3, 0 } },
|
||||
{ NumbersAndOperatorsEnum::LogBase10, { L"log()", 4, 0 } },
|
||||
{ NumbersAndOperatorsEnum::LogBaseE, { L"ln()", 3, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Sqrt, { L"sqrt()", 5, 0 } },
|
||||
{ NumbersAndOperatorsEnum::CubeRoot, { L"cbrt()", 5, 0 } },
|
||||
{ NumbersAndOperatorsEnum::YRootX, { L"root(x,n)", 7, 1 } },
|
||||
{ NumbersAndOperatorsEnum::TwoPowerX, { L"2^", 2, 0 } },
|
||||
{ NumbersAndOperatorsEnum::LogBaseX, { L"log(b, x)", 4, 1 } },
|
||||
{ NumbersAndOperatorsEnum::EPowerX, { L"e^", 4, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Abs, { L"abs()", 4, 0 } },
|
||||
{ NumbersAndOperatorsEnum::X, { L"x", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Y, { L"y", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::OpenParenthesis, { L"(", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::CloseParenthesis, { L")", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Equals, { L"=", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Divide, { L"/", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Multiply, { L"*", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Subtract, { L"-", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Add, { L"+", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Invert, { L"1/", 2, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Negate, { L"-", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::GreaterThan, { L">", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::GreaterThanOrEqualTo, { L"\u2265", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::LessThan, { L"<", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::LessThanOrEqualTo, { L"\u2264", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Zero, { L"0", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::One, { L"1", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Two, { L"2", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Three, { L"3", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Four, { L"4", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Five, { L"5", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Six, { L"6", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Seven, { L"7", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Eight, { L"8", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Nine, { L"9", 1, 0 } },
|
||||
{ NumbersAndOperatorsEnum::Decimal, { L".", 1, 0 } },
|
||||
};
|
||||
|
||||
GraphingNumPad::GraphingNumPad()
|
||||
{
|
||||
InitializeComponent();
|
||||
const auto& localizationSettings = CalculatorApp::Common::LocalizationSettings::GetInstance();
|
||||
DecimalSeparatorButton->Content = localizationSettings.GetDecimalSeparator();
|
||||
Num0Button->Content = localizationSettings.GetDigitSymbolFromEnUsDigit('0');
|
||||
Num1Button->Content = localizationSettings.GetDigitSymbolFromEnUsDigit('1');
|
||||
Num2Button->Content = localizationSettings.GetDigitSymbolFromEnUsDigit('2');
|
||||
Num3Button->Content = localizationSettings.GetDigitSymbolFromEnUsDigit('3');
|
||||
Num4Button->Content = localizationSettings.GetDigitSymbolFromEnUsDigit('4');
|
||||
Num5Button->Content = localizationSettings.GetDigitSymbolFromEnUsDigit('5');
|
||||
Num6Button->Content = localizationSettings.GetDigitSymbolFromEnUsDigit('6');
|
||||
Num7Button->Content = localizationSettings.GetDigitSymbolFromEnUsDigit('7');
|
||||
Num8Button->Content = localizationSettings.GetDigitSymbolFromEnUsDigit('8');
|
||||
Num9Button->Content = localizationSettings.GetDigitSymbolFromEnUsDigit('9');
|
||||
}
|
||||
|
||||
void GraphingNumPad::ShiftButton_Check(_In_ Platform::Object ^ /*sender*/, _In_ Windows::UI::Xaml::RoutedEventArgs ^ /*e*/)
|
||||
void GraphingNumPad::ShiftButton_Check(_In_ Platform::Object ^ /*sender*/, _In_ RoutedEventArgs ^ /*e*/)
|
||||
{
|
||||
SetOperatorRowVisibility();
|
||||
}
|
||||
|
||||
void GraphingNumPad::ShiftButton_Uncheck(_In_ Platform::Object ^ /*sender*/, _In_ Windows::UI::Xaml::RoutedEventArgs ^ /*e*/)
|
||||
void GraphingNumPad::ShiftButton_Uncheck(_In_ Platform::Object ^ sender, _In_ RoutedEventArgs ^ /*e*/)
|
||||
{
|
||||
ShiftButton->IsChecked = false;
|
||||
SetOperatorRowVisibility();
|
||||
FocusManager::TryFocusAsync(ShiftButton, ::FocusState::Programmatic);
|
||||
|
||||
GraphingNumPad::Button_Clicked(sender, nullptr);
|
||||
}
|
||||
|
||||
void GraphingNumPad::TrigFlyoutShift_Toggle(_In_ Platform::Object ^ /*sender*/, _In_ Windows::UI::Xaml::RoutedEventArgs ^ /*e*/)
|
||||
void GraphingNumPad::TrigFlyoutShift_Toggle(_In_ Platform::Object ^ /*sender*/, _In_ RoutedEventArgs ^ /*e*/)
|
||||
{
|
||||
SetTrigRowVisibility();
|
||||
}
|
||||
|
||||
void GraphingNumPad::TrigFlyoutHyp_Toggle(_In_ Platform::Object ^ /*sender*/, _In_ Windows::UI::Xaml::RoutedEventArgs ^ /*e*/)
|
||||
void GraphingNumPad::TrigFlyoutHyp_Toggle(_In_ Platform::Object ^ /*sender*/, _In_ RoutedEventArgs ^ /*e*/)
|
||||
{
|
||||
SetTrigRowVisibility();
|
||||
}
|
||||
|
||||
void GraphingNumPad::FlyoutButton_Clicked(_In_ Platform::Object ^ /*sender*/, _In_ Windows::UI::Xaml::RoutedEventArgs ^ /*e*/)
|
||||
void GraphingNumPad::FlyoutButton_Clicked(_In_ Platform::Object ^ sender, _In_ RoutedEventArgs ^ /*e*/)
|
||||
{
|
||||
this->HypButton->IsChecked = false;
|
||||
this->TrigShiftButton->IsChecked = false;
|
||||
this->Trigflyout->Hide();
|
||||
this->FuncFlyout->Hide();
|
||||
this->InequalityFlyout->Hide();
|
||||
|
||||
GraphingNumPad::Button_Clicked(sender, nullptr);
|
||||
}
|
||||
|
||||
void GraphingNumPad::ShiftButton_IsEnabledChanged(_In_ Platform::Object ^ /*sender*/, _In_ Windows::UI::Xaml::DependencyPropertyChangedEventArgs ^ /*e*/)
|
||||
void GraphingNumPad::ShiftButton_IsEnabledChanged(_In_ Platform::Object ^ /*sender*/, _In_ DependencyPropertyChangedEventArgs ^ /*e*/)
|
||||
{
|
||||
SetOperatorRowVisibility();
|
||||
}
|
||||
@@ -104,3 +194,64 @@ void GraphingNumPad::SetOperatorRowVisibility()
|
||||
Row1->Visibility = rowVis;
|
||||
InvRow1->Visibility = invRowVis;
|
||||
}
|
||||
|
||||
void GraphingNumPad::Button_Clicked(Platform::Object ^ sender, DependencyPropertyChangedEventArgs ^ /*e*/)
|
||||
{
|
||||
auto mathRichEdit = GetActiveRichEdit();
|
||||
auto button = dynamic_cast<CalculatorApp::Controls::CalculatorButton ^>(sender);
|
||||
if (mathRichEdit != nullptr && sender != nullptr)
|
||||
{
|
||||
auto id = button->ButtonId;
|
||||
auto output = buttonOutput.find(id);
|
||||
mathRichEdit->InsertText(std::get<0>(output->second), std::get<1>(output->second), std::get<2>(output->second));
|
||||
}
|
||||
}
|
||||
|
||||
void GraphingNumPad::SubmitButton_Clicked(Platform::Object ^ /*sender*/, RoutedEventArgs ^ /*e*/)
|
||||
{
|
||||
auto mathRichEdit = GetActiveRichEdit();
|
||||
if (mathRichEdit != nullptr)
|
||||
{
|
||||
mathRichEdit->SubmitEquation(CalculatorApp::Controls::EquationSubmissionSource::ENTER_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
void GraphingNumPad::ClearButton_Clicked(Platform::Object ^ /*sender*/, RoutedEventArgs ^ /*e*/)
|
||||
{
|
||||
auto mathRichEdit = GetActiveRichEdit();
|
||||
if (mathRichEdit != nullptr)
|
||||
{
|
||||
mathRichEdit->MathText = L"<math xmlns=\"http://www.w3.org/1998/Math/MathML\"></math>";
|
||||
mathRichEdit->SubmitEquation(CalculatorApp::Controls::EquationSubmissionSource::PROGRAMMATIC);
|
||||
}
|
||||
}
|
||||
|
||||
void GraphingNumPad::BackSpaceButton_Clicked(Platform::Object ^ /*sender*/, RoutedEventArgs ^ /*e*/)
|
||||
{
|
||||
auto mathRichEdit = GetActiveRichEdit();
|
||||
if (mathRichEdit != nullptr)
|
||||
{
|
||||
mathRichEdit->BackSpace();
|
||||
}
|
||||
}
|
||||
|
||||
// To avoid focus moving when the space between buttons is clicked, handle click events that make it through the keypad.
|
||||
void GraphingNumPad::GraphingNumPad_PointerPressed(Platform::Object ^ /*sender*/, PointerRoutedEventArgs ^ e)
|
||||
{
|
||||
e->Handled = true;
|
||||
}
|
||||
|
||||
CalculatorApp::Controls::MathRichEditBox ^ GraphingNumPad::GetActiveRichEdit()
|
||||
{
|
||||
return dynamic_cast<Controls::MathRichEditBox ^>(FocusManager::GetFocusedElement());
|
||||
}
|
||||
|
||||
// Adding event because the ShowMode property is ignored in xaml.
|
||||
void GraphingNumPad::Flyout_Opening(Platform::Object ^ sender, Platform::Object ^ /*e*/)
|
||||
{
|
||||
auto flyout = dynamic_cast<Flyout ^>(sender);
|
||||
if (flyout)
|
||||
{
|
||||
flyout->ShowMode = FlyoutShowMode::Transient;
|
||||
}
|
||||
}
|
||||
|
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "Views\GraphingCalculator\GraphingNumPad.g.h"
|
||||
#include "CalcViewModel/GraphingCalculator/GraphingCalculatorViewModel.h"
|
||||
#include "Views/GraphingCalculator/EquationInputArea.xaml.h"
|
||||
#include "CalcViewModel/Common/CalculatorButtonUser.h"
|
||||
|
||||
namespace CalculatorApp
|
||||
{
|
||||
@@ -23,5 +25,12 @@ namespace CalculatorApp
|
||||
void ShiftButton_IsEnabledChanged(_In_ Platform::Object ^ sender, _In_ Windows::UI::Xaml::DependencyPropertyChangedEventArgs ^ e);
|
||||
void SetOperatorRowVisibility();
|
||||
void SetTrigRowVisibility();
|
||||
};
|
||||
void Button_Clicked(_In_ Platform::Object ^ sender, _In_ Windows::UI::Xaml::DependencyPropertyChangedEventArgs ^ e);
|
||||
void SubmitButton_Clicked(Platform::Object ^ sender, Windows::UI::Xaml::RoutedEventArgs ^ e);
|
||||
void ClearButton_Clicked(Platform::Object ^ sender, Windows::UI::Xaml::RoutedEventArgs ^ e);
|
||||
void BackSpaceButton_Clicked(Platform::Object ^ sender, Windows::UI::Xaml::RoutedEventArgs ^ e);
|
||||
void GraphingNumPad_PointerPressed(Platform::Object ^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs ^ e);
|
||||
Controls::MathRichEditBox^ GetActiveRichEdit();
|
||||
void Flyout_Opening(Platform::Object ^ sender, Platform::Object ^ e);
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user