Skip to content

Commit 1475b49

Browse files
Create EquationTextBox control (#547)
1 parent c3c001a commit 1475b49

File tree

17 files changed

+1058
-90
lines changed

17 files changed

+1058
-90
lines changed

src/CalcViewModel/GraphingCalculator/EquationViewModel.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22
#include "EquationViewModel.h"
33

44
using namespace Windows::UI;
5+
using namespace Windows::UI::Xaml;
56

67
namespace CalculatorApp::ViewModel
78
{
89
EquationViewModel::EquationViewModel()
9-
: m_LineColor{ Colors::Transparent }
10+
: m_LineColor{ Colors::Transparent },
11+
m_KeyGraphFeaturesVisibility{ ::Visibility::Collapsed },
12+
m_Expression{ "" }
1013
{
1114
}
1215
}

src/CalcViewModel/GraphingCalculator/EquationViewModel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ namespace CalculatorApp::ViewModel
1212
OBSERVABLE_OBJECT();
1313
OBSERVABLE_PROPERTY_RW(Platform::String^, Expression);
1414
OBSERVABLE_PROPERTY_RW(Windows::UI::Color, LineColor);
15+
OBSERVABLE_PROPERTY_RW(Windows::UI::Xaml::Visibility, KeyGraphFeaturesVisibility);
1516
};
1617
}

src/Calculator/App.xaml

Lines changed: 651 additions & 0 deletions
Large diffs are not rendered by default.

src/Calculator/Calculator.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@
255255
<ClInclude Include="Converters\RadixToStringConverter.h" />
256256
<ClInclude Include="Converters\VisibilityNegationConverter.h" />
257257
<ClInclude Include="Controls\HorizontalNoOverflowStackPanel.h" />
258+
<ClInclude Include="Controls\EquationTextBox.h" />
258259
<ClInclude Include="pch.h" />
259260
<ClInclude Include="App.xaml.h">
260261
<DependentUpon>App.xaml</DependentUpon>
@@ -397,6 +398,7 @@
397398
<ClCompile Include="Converters\RadixToStringConverter.cpp" />
398399
<ClCompile Include="Converters\VisibilityNegationConverter.cpp" />
399400
<ClCompile Include="Controls\HorizontalNoOverflowStackPanel.cpp" />
401+
<ClCompile Include="Controls\EquationTextBox.cpp" />
400402
<ClCompile Include="pch.cpp">
401403
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
402404
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>

src/Calculator/Calculator.vcxproj.filters

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,11 @@
314314
<ClCompile Include="Controls\HorizontalNoOverflowStackPanel.cpp">
315315
<Filter>Controls</Filter>
316316
</ClCompile>
317+
<ClCompile Include="Views\GraphingCalculator\EquationInputArea.xaml.cpp" />
318+
<ClCompile Include="Views\GraphingCalculator\GraphingCalculator.xaml.cpp" />
319+
<ClCompile Include="Controls\EquationTextBox.cpp">
320+
<Filter>Controls</Filter>
321+
</ClCompile>
317322
</ItemGroup>
318323
<ItemGroup>
319324
<ClInclude Include="pch.h" />
@@ -416,6 +421,11 @@
416421
<ClInclude Include="Controls\HorizontalNoOverflowStackPanel.h">
417422
<Filter>Controls</Filter>
418423
</ClInclude>
424+
<ClInclude Include="Views\GraphingCalculator\EquationInputArea.xaml.h" />
425+
<ClInclude Include="Views\GraphingCalculator\GraphingCalculator.xaml.h" />
426+
<ClInclude Include="Controls\EquationTextBox.h">
427+
<Filter>Controls</Filter>
428+
</ClInclude>
419429
</ItemGroup>
420430
<ItemGroup>
421431
<AppxManifest Include="Package.appxmanifest" />
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#include "pch.h"
5+
#include "EquationTextBox.h"
6+
#include "CalcViewModel/GraphingCalculator/EquationViewModel.h"
7+
8+
using namespace std;
9+
using namespace Platform;
10+
using namespace CalculatorApp;
11+
using namespace CalculatorApp::Common;
12+
using namespace CalculatorApp::Controls;
13+
using namespace CalculatorApp::ViewModel;
14+
using namespace Windows::Foundation;
15+
using namespace Windows::UI::Xaml;
16+
using namespace Windows::UI::Xaml::Controls;
17+
using namespace Windows::UI::Xaml::Input;
18+
using namespace Windows::UI::Xaml::Controls::Primitives;
19+
using namespace Windows::UI::Text;
20+
21+
DEPENDENCY_PROPERTY_INITIALIZATION(EquationTextBox, EquationColor);
22+
DEPENDENCY_PROPERTY_INITIALIZATION(EquationTextBox, KeyGraphFeaturesContent);
23+
DEPENDENCY_PROPERTY_INITIALIZATION(EquationTextBox, ColorChooserFlyout);
24+
25+
void EquationTextBox::OnApplyTemplate()
26+
{
27+
m_equationButton = dynamic_cast<Button^>(GetTemplateChild("EquationButton"));
28+
m_richEditBox = dynamic_cast<RichEditBox^>(GetTemplateChild("EquationTextBox"));
29+
m_deleteButton = dynamic_cast<Button^>(GetTemplateChild("DeleteButton"));
30+
m_removeButton = dynamic_cast<Button^>(GetTemplateChild("RemoveButton"));
31+
m_functionButton = dynamic_cast<Button^>(GetTemplateChild("FunctionButton"));
32+
m_colorChooserButton = dynamic_cast<ToggleButton^>(GetTemplateChild("ColorChooserButton"));
33+
34+
if (m_richEditBox != nullptr)
35+
{
36+
m_richEditBox->GotFocus += ref new RoutedEventHandler(this, &EquationTextBox::OnRichEditBoxGotFocus);
37+
m_richEditBox->LostFocus += ref new RoutedEventHandler(this, &EquationTextBox::OnRichEditBoxLostFocus);
38+
m_richEditBox->TextChanged += ref new RoutedEventHandler(this, &EquationTextBox::OnRichEditBoxTextChanged);
39+
}
40+
41+
if (m_equationButton != nullptr)
42+
{
43+
m_equationButton->Click += ref new RoutedEventHandler(this, &EquationTextBox::OnEquationButtonClicked);
44+
}
45+
46+
if (m_deleteButton != nullptr)
47+
{
48+
m_deleteButton->Click += ref new RoutedEventHandler(this, &EquationTextBox::OnDeleteButtonClicked);
49+
}
50+
51+
if (m_removeButton != nullptr)
52+
{
53+
m_removeButton->Click += ref new RoutedEventHandler(this, &EquationTextBox::OnRemoveButtonClicked);
54+
}
55+
56+
if (m_colorChooserButton != nullptr)
57+
{
58+
m_colorChooserButton->Click += ref new RoutedEventHandler(this, &EquationTextBox::OnColorChooserButtonClicked);
59+
}
60+
61+
if (m_functionButton != nullptr)
62+
{
63+
m_functionButton->Click += ref new RoutedEventHandler(this, &EquationTextBox::OnFunctionButtonClicked);
64+
}
65+
66+
if (ColorChooserFlyout != nullptr)
67+
{
68+
ColorChooserFlyout->Opened += ref new EventHandler<Object^>(this, &EquationTextBox::OnColorFlyoutOpened);
69+
ColorChooserFlyout->Closed += ref new EventHandler<Object^>(this, &EquationTextBox::OnColorFlyoutClosed);
70+
}
71+
}
72+
73+
void EquationTextBox::OnPointerEntered(PointerRoutedEventArgs^ e)
74+
{
75+
m_isPointerOver = true;
76+
UpdateCommonVisualState();
77+
}
78+
79+
void EquationTextBox::OnPointerExited(PointerRoutedEventArgs^ e)
80+
{
81+
m_isPointerOver = false;
82+
UpdateCommonVisualState();
83+
}
84+
85+
void EquationTextBox::OnPointerCanceled(PointerRoutedEventArgs^ e)
86+
{
87+
m_isPointerOver = false;
88+
UpdateCommonVisualState();
89+
}
90+
91+
void EquationTextBox::OnPointerCaptureLost(PointerRoutedEventArgs^ e)
92+
{
93+
m_isPointerOver = false;
94+
UpdateCommonVisualState();
95+
}
96+
97+
void EquationTextBox::OnColorFlyoutOpened(Object^ sender, Object^ e)
98+
{
99+
m_isColorChooserFlyoutOpen = true;
100+
UpdateCommonVisualState();
101+
}
102+
103+
void EquationTextBox::OnColorFlyoutClosed(Object^ sender, Object^ e)
104+
{
105+
m_colorChooserButton->IsChecked = false;
106+
m_isColorChooserFlyoutOpen = false;
107+
UpdateCommonVisualState();
108+
}
109+
110+
void EquationTextBox::OnRichEditBoxTextChanged(Object^ sender, RoutedEventArgs^ e)
111+
{
112+
UpdateDeleteButtonVisualState();
113+
}
114+
115+
void EquationTextBox::OnRichEditBoxGotFocus(Object^ sender, RoutedEventArgs^ e)
116+
{
117+
m_isFocused = true;
118+
UpdateCommonVisualState();
119+
UpdateDeleteButtonVisualState();
120+
}
121+
122+
void EquationTextBox::OnRichEditBoxLostFocus(Object^ sender, RoutedEventArgs^ e)
123+
{
124+
m_isFocused = false;
125+
UpdateCommonVisualState();
126+
UpdateDeleteButtonVisualState();
127+
}
128+
129+
void EquationTextBox::OnDeleteButtonClicked(Object^ sender, RoutedEventArgs^ e)
130+
{
131+
if (m_richEditBox != nullptr)
132+
{
133+
m_richEditBox->TextDocument->SetText(::TextSetOptions::None, L"");
134+
}
135+
}
136+
137+
void EquationTextBox::OnEquationButtonClicked(Object^ sender, RoutedEventArgs^ e)
138+
{
139+
140+
}
141+
142+
void EquationTextBox::OnRemoveButtonClicked(Object^ sender, RoutedEventArgs^ e)
143+
{
144+
RemoveButtonClicked(this, ref new RoutedEventArgs());
145+
}
146+
147+
void EquationTextBox::OnColorChooserButtonClicked(Object^ sender, RoutedEventArgs^ e)
148+
{
149+
if (ColorChooserFlyout != nullptr && m_richEditBox != nullptr)
150+
{
151+
ColorChooserFlyout->ShowAt(m_richEditBox);
152+
}
153+
}
154+
155+
void EquationTextBox::OnFunctionButtonClicked(Object^ sender, RoutedEventArgs^ e)
156+
{
157+
auto equationViewModel = static_cast<EquationViewModel^>(DataContext);
158+
equationViewModel->KeyGraphFeaturesVisibility = (equationViewModel->KeyGraphFeaturesVisibility == ::Visibility::Collapsed) ? ::Visibility::Visible : ::Visibility::Collapsed;
159+
UpdateCommonVisualState();
160+
}
161+
162+
void EquationTextBox::UpdateDeleteButtonVisualState()
163+
{
164+
String^ state;
165+
166+
if (ShouldDeleteButtonBeVisible())
167+
{
168+
state = "ButtonVisible";
169+
}
170+
else
171+
{
172+
state = "ButtonCollapsed";
173+
}
174+
175+
VisualStateManager::GoToState(this, state, true);
176+
}
177+
178+
void EquationTextBox::UpdateCommonVisualState()
179+
{
180+
String^ state = "Normal";
181+
182+
if (m_isFocused)
183+
{
184+
state = "Focused";
185+
}
186+
else if (m_isPointerOver || m_isColorChooserFlyoutOpen)
187+
{
188+
state = "PointerOver";
189+
}
190+
191+
VisualStateManager::GoToState(this, state, true);
192+
}
193+
194+
195+
Platform::String^ EquationTextBox::GetEquationText()
196+
{
197+
String^ text;
198+
199+
if (m_richEditBox != nullptr)
200+
{
201+
m_richEditBox->TextDocument->GetText(::TextGetOptions::NoHidden, &text);
202+
}
203+
204+
return text;
205+
}
206+
207+
void EquationTextBox::SetEquationText(Platform::String^ equationText)
208+
{
209+
if (m_richEditBox != nullptr)
210+
{
211+
m_richEditBox->TextDocument->SetText(::TextSetOptions::None, equationText);
212+
}
213+
}
214+
215+
216+
bool EquationTextBox::ShouldDeleteButtonBeVisible()
217+
{
218+
return (!GetEquationText()->IsEmpty() && m_isFocused);
219+
220+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#pragma once
5+
6+
#include "CalcViewModel/Common/Utils.h"
7+
8+
namespace CalculatorApp
9+
{
10+
namespace Controls
11+
{
12+
public ref class EquationTextBox sealed : public Windows::UI::Xaml::Controls::Control
13+
{
14+
public:
15+
EquationTextBox()
16+
{
17+
}
18+
19+
DEPENDENCY_PROPERTY_OWNER(EquationTextBox);
20+
DEPENDENCY_PROPERTY(Windows::UI::Xaml::Media::SolidColorBrush^, EquationColor);
21+
DEPENDENCY_PROPERTY(Windows::UI::Xaml::UIElement^, KeyGraphFeaturesContent);
22+
DEPENDENCY_PROPERTY(Windows::UI::Xaml::Controls::Flyout^, ColorChooserFlyout);
23+
24+
event Windows::UI::Xaml::RoutedEventHandler^ RemoveButtonClicked;
25+
26+
Platform::String^ GetEquationText();
27+
void SetEquationText(Platform::String^ equationText);
28+
29+
protected:
30+
virtual void OnApplyTemplate() override;
31+
virtual void OnPointerEntered(Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e) override;
32+
virtual void OnPointerExited(Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e) override;
33+
virtual void OnPointerCanceled(Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e) override;
34+
virtual void OnPointerCaptureLost(Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e) override;
35+
36+
private:
37+
void UpdateCommonVisualState();
38+
void UpdateDeleteButtonVisualState();
39+
bool ShouldDeleteButtonBeVisible();
40+
41+
void OnRichEditBoxGotFocus(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
42+
void OnRichEditBoxLostFocus(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
43+
void OnRichEditBoxTextChanged(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
44+
45+
void OnDeleteButtonClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
46+
void OnEquationButtonClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
47+
void OnRemoveButtonClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
48+
void OnColorChooserButtonClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
49+
void OnFunctionButtonClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
50+
51+
void OnColorFlyoutOpened(Platform::Object^ sender, Platform::Object^ e);
52+
void OnColorFlyoutClosed(Platform::Object^ sender, Platform::Object^ e);
53+
54+
Windows::UI::Xaml::Controls::RichEditBox^ m_richEditBox;
55+
Windows::UI::Xaml::Controls::Button^ m_equationButton;
56+
Windows::UI::Xaml::Controls::Button^ m_deleteButton;
57+
Windows::UI::Xaml::Controls::Button^ m_removeButton;
58+
Windows::UI::Xaml::Controls::Button^ m_functionButton;
59+
Windows::UI::Xaml::Controls::Primitives::ToggleButton^ m_colorChooserButton;
60+
61+
bool m_isFocused;
62+
bool m_isPointerOver;
63+
bool m_isColorChooserFlyoutOpen;
64+
};
65+
}
66+
}

src/Calculator/Resources/en-US/Resources.resw

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3407,12 +3407,12 @@
34073407
<value>Y</value>
34083408
<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>
34093409
</data>
3410-
<data name="EquationInputAreaHeader.Text" xml:space="preserve">
3411-
<value>Equations</value>
3412-
<comment>The text that shows as the header for the equation input area in Graphing Calculator mode.</comment>
3413-
</data>
34143410
<data name="graphingPowerButton.[using:CalculatorApp.Common]KeyboardShortcutManager.Character" xml:space="preserve">
34153411
<value>^</value>
34163412
<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>
34173413
</data>
3414+
<data name="EquationInputButtonPlaceholderText" xml:space="preserve">
3415+
<value>Add Equation</value>
3416+
<comment>Placeholder text for the equation input button</comment>
3417+
</data>
34183418
</root>

src/Calculator/Resources/es-ES/Resources.resw

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
1+
<?xml version="1.0" encoding="utf-8"?>
22
<root>
33
<!--
44
Microsoft ResX Schema
@@ -2907,4 +2907,4 @@
29072907
<value>Contrato de servicios de Microsoft</value>
29082908
<comment>Displayed on a link to the Microsoft Services Agreement in the about this app information</comment>
29092909
</data>
2910-
</root>
2910+
</root>

src/Calculator/Views/Calculator.xaml.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "Controls/CalculatorButton.h"
1313
#include "Controls/CalculationResult.h"
1414
#include "Controls/OverflowTextBlock.h"
15+
#include "Controls/EquationTextBox.h"
1516
#include "CalcViewModel/HistoryViewModel.h"
1617
#include "Views/CalculatorProgrammerDisplayPanel.xaml.h"
1718
#include "Views/CalculatorProgrammerOperators.xaml.h"

0 commit comments

Comments
 (0)