GraphControl: refactoring and optimizations (#831)

* GraphControl cleaning

* replace textbox value after submission

* rebase

* rebase

* rebase

* Add filters

* rebase!

* rebase
This commit is contained in:
Rudy Huyn
2019-12-13 16:33:08 -08:00
committed by Eric Wong
parent da38b5a015
commit 534139d67d
33 changed files with 1169 additions and 1393 deletions

View File

@@ -331,6 +331,7 @@
<ClInclude Include="GraphingCalculatorEnums.h" />
<ClInclude Include="GraphingCalculator\EquationViewModel.h" />
<ClInclude Include="GraphingCalculator\GraphingCalculatorViewModel.h" />
<ClInclude Include="GraphingCalculator\VariableViewModel.h" />
<ClInclude Include="HistoryItemViewModel.h" />
<ClInclude Include="HistoryViewModel.h" />
<ClInclude Include="MemoryItemViewModel.h" />

View File

@@ -217,6 +217,9 @@
<ClInclude Include="GraphingCalculatorEnums.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="GraphingCalculator\VariableViewModel.h">
<Filter>GraphingCalculator</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="DataLoaders\DefaultFromToCurrency.json">

View File

@@ -10,6 +10,8 @@
// Utility macros to make Models easier to write
// generates a member variable called m_<n>
#define SINGLE_ARG(...) __VA_ARGS__
#define PROPERTY_R(t, n) \
property t n \
{ \
@@ -72,25 +74,6 @@ private:
\
public:
#define OBSERVABLE_PROPERTY_RW_ALWAYS_NOTIFY(t, n) \
property t n \
{ \
t get() \
{ \
return m_##n; \
} \
void set(t value) \
{ \
m_##n = value; \
RaisePropertyChanged(L#n); \
} \
} \
\
private: \
t m_##n; \
\
public:
#define OBSERVABLE_PROPERTY_RW(t, n) \
property t n \
{ \

View File

@@ -32,9 +32,9 @@ namespace CalculatorApp::ViewModel
{
}
EquationViewModel::EquationViewModel(GraphControl::Equation ^ equation)
EquationViewModel::EquationViewModel(Equation ^ equation, int functionLabelIndex, Windows::UI::Color color)
: m_AnalysisErrorVisible{ false }
, m_FunctionLabelIndex{ 0 }
, m_FunctionLabelIndex{ functionLabelIndex }
, m_KeyGraphFeaturesItems{ ref new Vector<KeyGraphFeaturesItem ^>() }
, m_resourceLoader{ Windows::ApplicationModel::Resources::ResourceLoader::GetForCurrentView() }
{
@@ -44,18 +44,20 @@ namespace CalculatorApp::ViewModel
}
GraphEquation = equation;
LineColor = color;
IsLineEnabled = true;
}
void EquationViewModel::PopulateKeyGraphFeatures()
void EquationViewModel::PopulateKeyGraphFeatures(KeyGraphFeaturesInfo ^ graphEquation)
{
if (GraphEquation->AnalysisError != 0)
if (graphEquation->AnalysisError != 0)
{
AnalysisErrorVisible = true;
if (GraphEquation->AnalysisError == static_cast<int>(AnalysisErrorType::AnalysisCouldNotBePerformed))
if (graphEquation->AnalysisError == static_cast<int>(AnalysisErrorType::AnalysisCouldNotBePerformed))
{
AnalysisErrorString = m_resourceLoader->GetString(L"KGFAnalysisCouldNotBePerformed");
}
else if (GraphEquation->AnalysisError == static_cast<int>(AnalysisErrorType::AnalysisNotSupported))
else if (graphEquation->AnalysisError == static_cast<int>(AnalysisErrorType::AnalysisNotSupported))
{
AnalysisErrorString = m_resourceLoader->GetString(L"KGFAnalysisNotSupported");
}
@@ -64,26 +66,23 @@ namespace CalculatorApp::ViewModel
KeyGraphFeaturesItems->Clear();
AddKeyGraphFeature(m_resourceLoader->GetString(L"Domain"), GraphEquation->Domain, m_resourceLoader->GetString(L"KGFDomainNone"));
AddKeyGraphFeature(m_resourceLoader->GetString(L"Range"), GraphEquation->Range, m_resourceLoader->GetString(L"KGFRangeNone"));
AddKeyGraphFeature(m_resourceLoader->GetString(L"XIntercept"), GraphEquation->XIntercept, m_resourceLoader->GetString(L"KGFXInterceptNone"));
AddKeyGraphFeature(m_resourceLoader->GetString(L"YIntercept"), GraphEquation->YIntercept, m_resourceLoader->GetString(L"KGFYInterceptNone"));
AddKeyGraphFeature(m_resourceLoader->GetString(L"Minima"), GraphEquation->Minima, m_resourceLoader->GetString(L"KGFMinimaNone"));
AddKeyGraphFeature(m_resourceLoader->GetString(L"Maxima"), GraphEquation->Maxima, m_resourceLoader->GetString(L"KGFMaximaNone"));
AddKeyGraphFeature(m_resourceLoader->GetString(L"Domain"), graphEquation->Domain, m_resourceLoader->GetString(L"KGFDomainNone"));
AddKeyGraphFeature(m_resourceLoader->GetString(L"Range"), graphEquation->Range, m_resourceLoader->GetString(L"KGFRangeNone"));
AddKeyGraphFeature(m_resourceLoader->GetString(L"XIntercept"), graphEquation->XIntercept, m_resourceLoader->GetString(L"KGFXInterceptNone"));
AddKeyGraphFeature(m_resourceLoader->GetString(L"YIntercept"), graphEquation->YIntercept, m_resourceLoader->GetString(L"KGFYInterceptNone"));
AddKeyGraphFeature(m_resourceLoader->GetString(L"Minima"), graphEquation->Minima, m_resourceLoader->GetString(L"KGFMinimaNone"));
AddKeyGraphFeature(m_resourceLoader->GetString(L"Maxima"), graphEquation->Maxima, m_resourceLoader->GetString(L"KGFMaximaNone"));
AddKeyGraphFeature(m_resourceLoader->GetString(L"InflectionPoints"), graphEquation->InflectionPoints, m_resourceLoader->GetString(L"KGFInflectionPointsNone"));
AddKeyGraphFeature(
m_resourceLoader->GetString(L"InflectionPoints"), GraphEquation->InflectionPoints, m_resourceLoader->GetString(L"KGFInflectionPointsNone"));
m_resourceLoader->GetString(L"VerticalAsymptotes"), graphEquation->VerticalAsymptotes, m_resourceLoader->GetString(L"KGFVerticalAsymptotesNone"));
AddKeyGraphFeature(
m_resourceLoader->GetString(L"VerticalAsymptotes"), GraphEquation->VerticalAsymptotes, m_resourceLoader->GetString(L"KGFVerticalAsymptotesNone"));
m_resourceLoader->GetString(L"HorizontalAsymptotes"), graphEquation->HorizontalAsymptotes, m_resourceLoader->GetString(L"KGFHorizontalAsymptotesNone"));
AddKeyGraphFeature(
m_resourceLoader->GetString(L"HorizontalAsymptotes"),
GraphEquation->HorizontalAsymptotes,
m_resourceLoader->GetString(L"KGFHorizontalAsymptotesNone"));
AddKeyGraphFeature(
m_resourceLoader->GetString(L"ObliqueAsymptotes"), GraphEquation->ObliqueAsymptotes, m_resourceLoader->GetString(L"KGFObliqueAsymptotesNone"));
AddParityKeyGraphFeature();
AddPeriodicityKeyGraphFeature();
AddMonotoncityKeyGraphFeature();
AddTooComplexKeyGraphFeature();
m_resourceLoader->GetString(L"ObliqueAsymptotes"), graphEquation->ObliqueAsymptotes, m_resourceLoader->GetString(L"KGFObliqueAsymptotesNone"));
AddParityKeyGraphFeature(graphEquation);
AddPeriodicityKeyGraphFeature(graphEquation);
AddMonotoncityKeyGraphFeature(graphEquation);
AddTooComplexKeyGraphFeature(graphEquation);
AnalysisErrorVisible = false;
}
@@ -125,11 +124,11 @@ namespace CalculatorApp::ViewModel
KeyGraphFeaturesItems->Append(item);
}
void EquationViewModel::AddParityKeyGraphFeature()
void EquationViewModel::AddParityKeyGraphFeature(KeyGraphFeaturesInfo ^ graphEquation)
{
KeyGraphFeaturesItem ^ parityItem = ref new KeyGraphFeaturesItem();
parityItem->Title = m_resourceLoader->GetString(L"Parity");
switch (GraphEquation->Parity)
switch (graphEquation->Parity)
{
case 0:
parityItem->DisplayItems->Append(m_resourceLoader->GetString(L"KGFParityUnknown"));
@@ -151,11 +150,11 @@ namespace CalculatorApp::ViewModel
KeyGraphFeaturesItems->Append(parityItem);
}
void EquationViewModel::AddPeriodicityKeyGraphFeature()
void EquationViewModel::AddPeriodicityKeyGraphFeature(KeyGraphFeaturesInfo ^ graphEquation)
{
KeyGraphFeaturesItem ^ periodicityItem = ref new KeyGraphFeaturesItem();
periodicityItem->Title = m_resourceLoader->GetString(L"Periodicity");
switch (GraphEquation->PeriodicityDirection)
switch (graphEquation->PeriodicityDirection)
{
case 0:
// Periodicity is not supported or is too complex to calculate.
@@ -163,14 +162,14 @@ namespace CalculatorApp::ViewModel
// SetTooComplexFeaturesErrorProperty will set the too complex error when periodicity is supported and unknown
return;
case 1:
if (GraphEquation->PeriodicityExpression == L"")
if (graphEquation->PeriodicityExpression == L"")
{
periodicityItem->DisplayItems->Append(m_resourceLoader->GetString(L"KGFPeriodicityUnknown"));
periodicityItem->IsText = true;
}
else
{
periodicityItem->DisplayItems->Append(GraphEquation->PeriodicityExpression);
periodicityItem->DisplayItems->Append(graphEquation->PeriodicityExpression);
periodicityItem->IsText = false;
}
break;
@@ -186,13 +185,13 @@ namespace CalculatorApp::ViewModel
KeyGraphFeaturesItems->Append(periodicityItem);
}
void EquationViewModel::AddMonotoncityKeyGraphFeature()
void EquationViewModel::AddMonotoncityKeyGraphFeature(KeyGraphFeaturesInfo ^ graphEquation)
{
KeyGraphFeaturesItem ^ monotonicityItem = ref new KeyGraphFeaturesItem();
monotonicityItem->Title = m_resourceLoader->GetString(L"Monotonicity");
if (GraphEquation->Monotonicity->Size != 0)
if (graphEquation->Monotonicity->Size != 0)
{
for (auto item : GraphEquation->Monotonicity)
for (auto item : graphEquation->Monotonicity)
{
GridDisplayItems ^ gridItem = ref new GridDisplayItems();
gridItem->Expression = item->Key;
@@ -230,9 +229,9 @@ namespace CalculatorApp::ViewModel
KeyGraphFeaturesItems->Append(monotonicityItem);
}
void EquationViewModel::AddTooComplexKeyGraphFeature()
void EquationViewModel::AddTooComplexKeyGraphFeature(KeyGraphFeaturesInfo ^ graphEquation)
{
if (GraphEquation->TooComplexFeatures <= 0)
if (graphEquation->TooComplexFeatures <= 0)
{
return;
}
@@ -240,55 +239,55 @@ namespace CalculatorApp::ViewModel
Platform::String ^ separator = ref new String(LocalizationSettings::GetInstance().GetListSeparator().c_str());
wstring error;
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::Domain) == KeyGraphFeaturesFlag::Domain)
if ((graphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::Domain) == KeyGraphFeaturesFlag::Domain)
{
error.append((m_resourceLoader->GetString(L"Domain") + separator + L" ")->Data());
}
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::Range) == KeyGraphFeaturesFlag::Range)
if ((graphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::Range) == KeyGraphFeaturesFlag::Range)
{
error.append((m_resourceLoader->GetString(L"Range") + separator + L" ")->Data());
}
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::Zeros) == KeyGraphFeaturesFlag::Zeros)
if ((graphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::Zeros) == KeyGraphFeaturesFlag::Zeros)
{
error.append((m_resourceLoader->GetString(L"XIntercept") + separator + L" ")->Data());
}
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::YIntercept) == KeyGraphFeaturesFlag::YIntercept)
if ((graphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::YIntercept) == KeyGraphFeaturesFlag::YIntercept)
{
error.append((m_resourceLoader->GetString(L"YIntercept") + separator + L" ")->Data());
}
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::Parity) == KeyGraphFeaturesFlag::Parity)
if ((graphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::Parity) == KeyGraphFeaturesFlag::Parity)
{
error.append((m_resourceLoader->GetString(L"Parity") + separator + L" ")->Data());
}
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::Periodicity) == KeyGraphFeaturesFlag::Periodicity)
if ((graphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::Periodicity) == KeyGraphFeaturesFlag::Periodicity)
{
error.append((m_resourceLoader->GetString(L"Periodicity") + separator + L" ")->Data());
}
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::Minima) == KeyGraphFeaturesFlag::Minima)
if ((graphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::Minima) == KeyGraphFeaturesFlag::Minima)
{
error.append((m_resourceLoader->GetString(L"Minima") + separator + L" ")->Data());
}
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::Maxima) == KeyGraphFeaturesFlag::Maxima)
if ((graphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::Maxima) == KeyGraphFeaturesFlag::Maxima)
{
error.append((m_resourceLoader->GetString(L"Maxima") + separator + L" ")->Data());
}
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::InflectionPoints) == KeyGraphFeaturesFlag::InflectionPoints)
if ((graphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::InflectionPoints) == KeyGraphFeaturesFlag::InflectionPoints)
{
error.append((m_resourceLoader->GetString(L"InflectionPoints") + separator + L" ")->Data());
}
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::VerticalAsymptotes) == KeyGraphFeaturesFlag::VerticalAsymptotes)
if ((graphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::VerticalAsymptotes) == KeyGraphFeaturesFlag::VerticalAsymptotes)
{
error.append((m_resourceLoader->GetString(L"VerticalAsymptotes") + separator + L" ")->Data());
}
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::HorizontalAsymptotes) == KeyGraphFeaturesFlag::HorizontalAsymptotes)
if ((graphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::HorizontalAsymptotes) == KeyGraphFeaturesFlag::HorizontalAsymptotes)
{
error.append((m_resourceLoader->GetString(L"HorizontalAsymptotes") + separator + L" ")->Data());
}
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::ObliqueAsymptotes) == KeyGraphFeaturesFlag::ObliqueAsymptotes)
if ((graphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::ObliqueAsymptotes) == KeyGraphFeaturesFlag::ObliqueAsymptotes)
{
error.append((m_resourceLoader->GetString(L"ObliqueAsymptotes") + separator + L" ")->Data());
}
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::MonotoneIntervals) == KeyGraphFeaturesFlag::MonotoneIntervals)
if ((graphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::MonotoneIntervals) == KeyGraphFeaturesFlag::MonotoneIntervals)
{
error.append((m_resourceLoader->GetString(L"Monotonicity") + separator + L" ")->Data());
}
@@ -300,5 +299,4 @@ namespace CalculatorApp::ViewModel
KeyGraphFeaturesItems->Append(tooComplexItem);
}
}

View File

@@ -5,6 +5,12 @@
#include "../Common/Utils.h"
namespace GraphControl
{
ref class Equation;
ref class KeyGraphFeaturesInfo;
}
namespace CalculatorApp::ViewModel
{
public
@@ -31,16 +37,15 @@ public
OBSERVABLE_PROPERTY_RW(bool, IsText);
};
public
ref class EquationViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
{
public:
EquationViewModel(GraphControl::Equation ^ equation);
EquationViewModel(GraphControl::Equation ^ equation, int functionLabelIndex, Windows::UI::Color color);
OBSERVABLE_OBJECT();
OBSERVABLE_PROPERTY_R(GraphControl::Equation ^, GraphEquation);
OBSERVABLE_PROPERTY_RW(int, FunctionLabelIndex);
OBSERVABLE_PROPERTY_R(int, FunctionLabelIndex);
OBSERVABLE_PROPERTY_RW(bool, IsLastItemInList);
property Platform::String ^ Expression
@@ -59,15 +64,15 @@ public
}
}
property Windows::UI::Xaml::Media::SolidColorBrush ^ LineColor
property Windows::UI::Color LineColor
{
Windows::UI::Xaml::Media::SolidColorBrush ^ get()
Windows::UI::Color get()
{
return GraphEquation->LineColor;
}
void set(Windows::UI::Xaml::Media::SolidColorBrush ^ value)
void set(Windows::UI::Color value)
{
if (GraphEquation->LineColor != value)
if (!Utils::AreColorsEqual(GraphEquation->LineColor, value))
{
GraphEquation->LineColor = value;
RaisePropertyChanged("LineColor");
@@ -96,7 +101,7 @@ public
OBSERVABLE_PROPERTY_R(bool, AnalysisErrorVisible);
OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IObservableVector<CalculatorApp::ViewModel::KeyGraphFeaturesItem ^> ^, KeyGraphFeaturesItems)
void PopulateKeyGraphFeatures();
void PopulateKeyGraphFeatures(GraphControl::KeyGraphFeaturesInfo ^ info);
private:
void AddKeyGraphFeature(Platform::String ^ title, Platform::String ^ expression, Platform::String ^ errorString);
@@ -104,13 +109,12 @@ public
Platform::String ^ title,
Windows::Foundation::Collections::IVector<Platform::String ^> ^ expressionVector,
Platform::String ^ errorString);
void AddParityKeyGraphFeature();
void AddPeriodicityKeyGraphFeature();
void AddMonotoncityKeyGraphFeature();
void AddTooComplexKeyGraphFeature();
void AddParityKeyGraphFeature(GraphControl::KeyGraphFeaturesInfo ^ info);
void AddPeriodicityKeyGraphFeature(GraphControl::KeyGraphFeaturesInfo ^ info);
void AddMonotoncityKeyGraphFeature(GraphControl::KeyGraphFeaturesInfo ^ info);
void AddTooComplexKeyGraphFeature(GraphControl::KeyGraphFeaturesInfo ^ info);
Windows::Foundation::Collections::IObservableMap<Platform::String ^, Platform::String ^> ^ m_Monotonicity;
Windows::ApplicationModel::Resources::ResourceLoader ^ m_resourceLoader;
};
}

View File

@@ -15,27 +15,30 @@ namespace CalculatorApp::ViewModel
{
GraphingCalculatorViewModel::GraphingCalculatorViewModel()
: m_IsDecimalEnabled{ true }
, m_Equations{ ref new Vector< EquationViewModel^ >() }
, m_Variables{ ref new Vector< VariableViewModel^ >() }
, m_Equations{ ref new Vector<EquationViewModel ^>() }
, m_Variables{ ref new Vector<VariableViewModel ^>() }
{
}
void GraphingCalculatorViewModel::OnButtonPressed(Object^ parameter)
void GraphingCalculatorViewModel::OnButtonPressed(Object ^ parameter)
{
}
void GraphingCalculatorViewModel::UpdateVariables(IMap<String^, double>^ variables)
void GraphingCalculatorViewModel::UpdateVariables(IMap<String ^, double> ^ variables)
{
Variables->Clear();
for (auto var : variables)
{
auto variable = ref new VariableViewModel(var->Key, var->Value);
variable->VariableUpdated += ref new EventHandler<VariableChangedEventArgs>([this, variable](Object^ sender, VariableChangedEventArgs e)
{
VariableUpdated(variable, VariableChangedEventArgs{ e.variableName, e.newValue });
});
variable->VariableUpdated += ref new EventHandler<VariableChangedEventArgs>([this, variable](Object ^ sender, VariableChangedEventArgs e) {
VariableUpdated(variable, VariableChangedEventArgs{ e.variableName, e.newValue });
});
Variables->Append(variable);
}
}
void GraphingCalculatorViewModel::SetSelectedEquation(EquationViewModel ^ equation)
{
SelectedEquation = equation;
}
}

View File

@@ -5,66 +5,10 @@
#include "../Common/Utils.h"
#include "EquationViewModel.h"
#include "VariableViewModel.h"
namespace CalculatorApp::ViewModel
{
public
value struct VariableChangedEventArgs sealed
{
Platform::String ^ variableName;
double newValue;
};
[Windows::UI::Xaml::Data::Bindable] public ref class VariableViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
{
public:
VariableViewModel(Platform::String ^ name, double value)
: m_Name(name)
, m_Value(value)
, m_SliderSettingsVisible(false)
, m_Min(0.0)
, m_Step(0.1)
, m_Max(2.0)
{
}
OBSERVABLE_OBJECT_CALLBACK(OnPropertyChanged);
OBSERVABLE_PROPERTY_R(Platform::String ^, Name);
// TODO: Consider removing this work around and manually set the textbox text.
OBSERVABLE_PROPERTY_RW_ALWAYS_NOTIFY(double, Value);
OBSERVABLE_PROPERTY_RW_ALWAYS_NOTIFY(double, Min);
OBSERVABLE_PROPERTY_RW_ALWAYS_NOTIFY(double, Step);
OBSERVABLE_PROPERTY_RW_ALWAYS_NOTIFY(double, Max);
OBSERVABLE_PROPERTY_RW(bool, SliderSettingsVisible);
event Windows::Foundation::EventHandler<VariableChangedEventArgs> ^ VariableUpdated;
void SetValue(double value)
{
if (value < Min)
{
value = Min;
}
else if (value > Max)
{
value = Max;
}
Value = value;
}
private:
void OnPropertyChanged(Platform::String ^ propertyName)
{
if (propertyName == "Value")
{
VariableUpdated(this, VariableChangedEventArgs{ Name, Value });
}
}
};
[Windows::UI::Xaml::Data::Bindable] public ref class GraphingCalculatorViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
{
public:
@@ -74,6 +18,7 @@ public
OBSERVABLE_PROPERTY_R(bool, IsDecimalEnabled);
OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IObservableVector<EquationViewModel ^> ^, Equations);
OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IObservableVector<VariableViewModel ^> ^, Variables);
OBSERVABLE_PROPERTY_R(EquationViewModel ^, SelectedEquation);
COMMAND_FOR_METHOD(ButtonPressed, GraphingCalculatorViewModel::OnButtonPressed);
@@ -81,6 +26,7 @@ public
void UpdateVariables(Windows::Foundation::Collections::IMap<Platform::String ^, double> ^ variables);
void SetSelectedEquation(EquationViewModel ^ equation);
private:
void OnButtonPressed(Platform::Object ^ parameter);
};

View File

@@ -0,0 +1,69 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
#include "../Common/Utils.h"
#include "EquationViewModel.h"
namespace CalculatorApp::ViewModel
{
public
value struct VariableChangedEventArgs sealed
{
Platform::String ^ variableName;
double newValue;
};
[Windows::UI::Xaml::Data::Bindable] public ref class VariableViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
{
public:
VariableViewModel(Platform::String ^ name, double value)
: m_Name(name)
, m_Value(value)
, m_SliderSettingsVisible(false)
, m_Min(0.0)
, m_Step(0.1)
, m_Max(2.0)
{
}
OBSERVABLE_OBJECT();
OBSERVABLE_PROPERTY_R(Platform::String ^, Name);
OBSERVABLE_PROPERTY_RW(double, Min);
OBSERVABLE_PROPERTY_RW(double, Step);
OBSERVABLE_PROPERTY_RW(double, Max);
OBSERVABLE_PROPERTY_RW(bool, SliderSettingsVisible);
event Windows::Foundation::EventHandler<VariableChangedEventArgs> ^ VariableUpdated;
property double Value
{
double get()
{
return m_Value;
}
void set(double value)
{
if (value < Min)
{
value = Min;
}
else if (value > Max)
{
value = Max;
}
if (Value != value)
{
m_Value = value;
VariableUpdated(this, VariableChangedEventArgs{ Name, value });
RaisePropertyChanged(L"Value");
}
}
}
private:
double m_Value;
};
}