Refactor Equation to be treated as a model and update Key Graph Features (#791)
* refactor code * update KGF * Rename some functions * Undo comment out of proj file * Pr feedback
This commit is contained in:
parent
9ee2f8a293
commit
288a90e0fe
@ -413,6 +413,9 @@
|
||||
<ProjectReference Include="..\CalcManager\CalcManager.vcxproj">
|
||||
<Project>{311e866d-8b93-4609-a691-265941fee101}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\GraphControl\GraphControl.vcxproj">
|
||||
<Project>{e727a92b-f149-492c-8117-c039a298719b}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemDefinitionGroup Condition="!Exists('DataLoaders\DataLoaderConstants.h')">
|
||||
<ClCompile>
|
||||
|
@ -14,6 +14,7 @@ using namespace std;
|
||||
using namespace Windows::UI;
|
||||
using namespace Windows::UI::Xaml;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
using namespace GraphControl;
|
||||
|
||||
namespace CalculatorApp::ViewModel
|
||||
{
|
||||
@ -31,83 +32,62 @@ namespace CalculatorApp::ViewModel
|
||||
{
|
||||
}
|
||||
|
||||
EquationViewModel::EquationViewModel()
|
||||
: m_LineColor{ nullptr }
|
||||
, m_Expression{ "" }
|
||||
, m_IsAnalysisUpdated{ false }
|
||||
, m_Domain{ "" }
|
||||
, m_Range{ "" }
|
||||
, m_XIntercept{ "" }
|
||||
, m_YIntercept{ "" }
|
||||
, m_Parity{ -1 }
|
||||
, m_PeriodicityDirection{ -1 }
|
||||
, m_PeriodicityExpression{ "" }
|
||||
, m_Minima{ ref new Vector<String ^>() }
|
||||
, m_Maxima{ ref new Vector<String ^>() }
|
||||
, m_InflectionPoints{ ref new Vector<String ^>() }
|
||||
, m_Monotonicity{ ref new Map<String ^, String ^>() }
|
||||
, m_VerticalAsymptotes{ ref new Vector<String ^>() }
|
||||
, m_HorizontalAsymptotes{ ref new Vector<String ^>() }
|
||||
, m_ObliqueAsymptotes{ ref new Vector<String ^>() }
|
||||
, m_TooComplexFeatures{ -1 }
|
||||
, m_AnalysisError{ 0 }
|
||||
, m_AnalysisErrorVisible{ false }
|
||||
EquationViewModel::EquationViewModel(GraphControl::Equation ^ equation)
|
||||
: m_AnalysisErrorVisible{ false }
|
||||
, m_KeyGraphFeaturesItems{ ref new Vector<KeyGraphFeaturesItem ^>() }
|
||||
, m_resourceLoader{ Windows::ApplicationModel::Resources::ResourceLoader::GetForCurrentView() }
|
||||
{
|
||||
}
|
||||
|
||||
void EquationViewModel::OnPropertyChanged(String ^ propertyName)
|
||||
{
|
||||
if (propertyName == L"IsAnalysisUpdated")
|
||||
if (equation == nullptr)
|
||||
{
|
||||
OnIsAnalysisUpdatedChanged();
|
||||
throw ref new InvalidArgumentException(L"Equation cannot be null");
|
||||
}
|
||||
|
||||
GraphEquation = equation;
|
||||
}
|
||||
|
||||
void EquationViewModel::OnIsAnalysisUpdatedChanged()
|
||||
void EquationViewModel::PopulateKeyGraphFeatures()
|
||||
{
|
||||
if (IsAnalysisUpdated)
|
||||
if (GraphEquation->AnalysisError != 0)
|
||||
{
|
||||
if (AnalysisError != 0)
|
||||
AnalysisErrorVisible = true;
|
||||
if (GraphEquation->AnalysisError == static_cast<int>(AnalysisErrorType::AnalysisCouldNotBePerformed))
|
||||
{
|
||||
AnalysisErrorVisible = true;
|
||||
if (AnalysisError == static_cast<int>(AnalysisErrorType::AnalysisCouldNotBePerformed))
|
||||
{
|
||||
AnalysisErrorString = m_resourceLoader->GetString(L"KGFAnalysisCouldNotBePerformed");
|
||||
}
|
||||
else if (AnalysisError == static_cast<int>(AnalysisErrorType::AnalysisNotSupported))
|
||||
{
|
||||
AnalysisErrorString = m_resourceLoader->GetString(L"KGFAnalysisNotSupported");
|
||||
}
|
||||
return;
|
||||
AnalysisErrorString = m_resourceLoader->GetString(L"KGFAnalysisCouldNotBePerformed");
|
||||
}
|
||||
KeyGraphFeaturesItems->Clear();
|
||||
SetKeyGraphFeaturesItems(m_resourceLoader->GetString(L"Domain"), Domain, m_resourceLoader->GetString(L"KGFDomainNone"));
|
||||
SetKeyGraphFeaturesItems(m_resourceLoader->GetString(L"Range"), Range, m_resourceLoader->GetString(L"KGFRangeNone"));
|
||||
SetKeyGraphFeaturesItems(m_resourceLoader->GetString(L"XIntercept"), XIntercept, m_resourceLoader->GetString(L"KGFXInterceptNone"));
|
||||
SetKeyGraphFeaturesItems(m_resourceLoader->GetString(L"YIntercept"), YIntercept, m_resourceLoader->GetString(L"KGFYInterceptNone"));
|
||||
SetKeyGraphFeaturesItems(m_resourceLoader->GetString(L"Minima"), Minima, m_resourceLoader->GetString(L"KGFMinimaNone"));
|
||||
SetKeyGraphFeaturesItems(m_resourceLoader->GetString(L"Maxima"), Maxima, m_resourceLoader->GetString(L"KGFMaximaNone"));
|
||||
SetKeyGraphFeaturesItems(
|
||||
m_resourceLoader->GetString(L"InflectionPoints"), InflectionPoints, m_resourceLoader->GetString(L"KGFInflectionPointsNone"));
|
||||
SetKeyGraphFeaturesItems(
|
||||
m_resourceLoader->GetString(L"VerticalAsymptotes"), VerticalAsymptotes, m_resourceLoader->GetString(L"KGFVerticalAsymptotesNone"));
|
||||
SetKeyGraphFeaturesItems(
|
||||
m_resourceLoader->GetString(L"HorizontalAsymptotes"), HorizontalAsymptotes, m_resourceLoader->GetString(L"KGFHorizontalAsymptotesNone"));
|
||||
SetKeyGraphFeaturesItems(
|
||||
m_resourceLoader->GetString(L"ObliqueAsymptotes"), ObliqueAsymptotes, m_resourceLoader->GetString(L"KGFObliqueAsymptotesNone"));
|
||||
SetParityStringProperty();
|
||||
SetPeriodicityStringProperty();
|
||||
SetMonotoncityStringProperty();
|
||||
SetTooComplexFeaturesErrorProperty();
|
||||
|
||||
AnalysisErrorVisible = false;
|
||||
IsAnalysisUpdated = false;
|
||||
else if (GraphEquation->AnalysisError == static_cast<int>(AnalysisErrorType::AnalysisNotSupported))
|
||||
{
|
||||
AnalysisErrorString = m_resourceLoader->GetString(L"KGFAnalysisNotSupported");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
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"InflectionPoints"), GraphEquation->InflectionPoints, m_resourceLoader->GetString(L"KGFInflectionPointsNone"));
|
||||
AddKeyGraphFeature(
|
||||
m_resourceLoader->GetString(L"VerticalAsymptotes"), GraphEquation->VerticalAsymptotes, m_resourceLoader->GetString(L"KGFVerticalAsymptotesNone"));
|
||||
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();
|
||||
|
||||
AnalysisErrorVisible = false;
|
||||
}
|
||||
|
||||
void EquationViewModel::SetKeyGraphFeaturesItems(String ^ title, String ^ expression, String ^ errorString)
|
||||
void EquationViewModel::AddKeyGraphFeature(String ^ title, String ^ expression, String ^ errorString)
|
||||
{
|
||||
KeyGraphFeaturesItem ^ item = ref new KeyGraphFeaturesItem();
|
||||
item->Title = title;
|
||||
@ -124,7 +104,7 @@ namespace CalculatorApp::ViewModel
|
||||
KeyGraphFeaturesItems->Append(item);
|
||||
}
|
||||
|
||||
void EquationViewModel::SetKeyGraphFeaturesItems(String ^ title, IObservableVector<String ^> ^ expressionVector, String ^ errorString)
|
||||
void EquationViewModel::AddKeyGraphFeature(String ^ title, IVector<String ^> ^ expressionVector, String ^ errorString)
|
||||
{
|
||||
KeyGraphFeaturesItem ^ item = ref new KeyGraphFeaturesItem();
|
||||
item->Title = title;
|
||||
@ -144,11 +124,11 @@ namespace CalculatorApp::ViewModel
|
||||
KeyGraphFeaturesItems->Append(item);
|
||||
}
|
||||
|
||||
void EquationViewModel::SetParityStringProperty()
|
||||
void EquationViewModel::AddParityKeyGraphFeature()
|
||||
{
|
||||
KeyGraphFeaturesItem ^ parityItem = ref new KeyGraphFeaturesItem();
|
||||
parityItem->Title = m_resourceLoader->GetString(L"Parity");
|
||||
switch (Parity)
|
||||
switch (GraphEquation->Parity)
|
||||
{
|
||||
case 0:
|
||||
parityItem->DisplayItems->Append(m_resourceLoader->GetString(L"KGFParityUnknown"));
|
||||
@ -164,18 +144,17 @@ namespace CalculatorApp::ViewModel
|
||||
break;
|
||||
default:
|
||||
parityItem->DisplayItems->Append(m_resourceLoader->GetString(L"KGFParityUnknown"));
|
||||
|
||||
}
|
||||
parityItem->IsText = true;
|
||||
|
||||
KeyGraphFeaturesItems->Append(parityItem);
|
||||
}
|
||||
|
||||
void EquationViewModel::SetPeriodicityStringProperty()
|
||||
void EquationViewModel::AddPeriodicityKeyGraphFeature()
|
||||
{
|
||||
KeyGraphFeaturesItem ^ periodicityItem = ref new KeyGraphFeaturesItem();
|
||||
periodicityItem->Title = m_resourceLoader->GetString(L"Periodicity");
|
||||
switch (PeriodicityDirection)
|
||||
switch (GraphEquation->PeriodicityDirection)
|
||||
{
|
||||
case 0:
|
||||
// Periodicity is not supported or is too complex to calculate.
|
||||
@ -183,14 +162,14 @@ namespace CalculatorApp::ViewModel
|
||||
// SetTooComplexFeaturesErrorProperty will set the too complex error when periodicity is supported and unknown
|
||||
return;
|
||||
case 1:
|
||||
if (PeriodicityExpression == L"")
|
||||
if (GraphEquation->PeriodicityExpression == L"")
|
||||
{
|
||||
periodicityItem->DisplayItems->Append(m_resourceLoader->GetString(L"KGFPeriodicityUnknown"));
|
||||
periodicityItem->IsText = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
periodicityItem->DisplayItems->Append(PeriodicityExpression);
|
||||
periodicityItem->DisplayItems->Append(GraphEquation->PeriodicityExpression);
|
||||
periodicityItem->IsText = false;
|
||||
}
|
||||
break;
|
||||
@ -206,13 +185,13 @@ namespace CalculatorApp::ViewModel
|
||||
KeyGraphFeaturesItems->Append(periodicityItem);
|
||||
}
|
||||
|
||||
void EquationViewModel::SetMonotoncityStringProperty()
|
||||
void EquationViewModel::AddMonotoncityKeyGraphFeature()
|
||||
{
|
||||
KeyGraphFeaturesItem ^ monotonicityItem = ref new KeyGraphFeaturesItem();
|
||||
monotonicityItem->Title = m_resourceLoader->GetString(L"Monotonicity");
|
||||
if (Monotonicity->Size != 0)
|
||||
if (GraphEquation->Monotonicity->Size != 0)
|
||||
{
|
||||
for (auto item : Monotonicity)
|
||||
for (auto item : GraphEquation->Monotonicity)
|
||||
{
|
||||
GridDisplayItems ^ gridItem = ref new GridDisplayItems();
|
||||
gridItem->Expression = item->Key;
|
||||
@ -250,9 +229,9 @@ namespace CalculatorApp::ViewModel
|
||||
KeyGraphFeaturesItems->Append(monotonicityItem);
|
||||
}
|
||||
|
||||
void EquationViewModel::SetTooComplexFeaturesErrorProperty()
|
||||
void EquationViewModel::AddTooComplexKeyGraphFeature()
|
||||
{
|
||||
if (TooComplexFeatures <= 0)
|
||||
if (GraphEquation->TooComplexFeatures <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -260,55 +239,55 @@ namespace CalculatorApp::ViewModel
|
||||
Platform::String ^ separator = ref new String(LocalizationSettings::GetInstance().GetListSeparator().c_str());
|
||||
|
||||
wstring error;
|
||||
if ((TooComplexFeatures & KeyGraphFeaturesFlag::Domain) == KeyGraphFeaturesFlag::Domain)
|
||||
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::Domain) == KeyGraphFeaturesFlag::Domain)
|
||||
{
|
||||
error.append((m_resourceLoader->GetString(L"Domain") + separator + L" ")->Data());
|
||||
}
|
||||
if ((TooComplexFeatures & KeyGraphFeaturesFlag::Range) == KeyGraphFeaturesFlag::Range)
|
||||
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::Range) == KeyGraphFeaturesFlag::Range)
|
||||
{
|
||||
error.append((m_resourceLoader->GetString(L"Range") + separator + L" ")->Data());
|
||||
}
|
||||
if ((TooComplexFeatures & KeyGraphFeaturesFlag::Zeros) == KeyGraphFeaturesFlag::Zeros)
|
||||
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::Zeros) == KeyGraphFeaturesFlag::Zeros)
|
||||
{
|
||||
error.append((m_resourceLoader->GetString(L"XIntercept") + separator + L" ")->Data());
|
||||
}
|
||||
if ((TooComplexFeatures & KeyGraphFeaturesFlag::YIntercept) == KeyGraphFeaturesFlag::YIntercept)
|
||||
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::YIntercept) == KeyGraphFeaturesFlag::YIntercept)
|
||||
{
|
||||
error.append((m_resourceLoader->GetString(L"YIntercept") + separator + L" ")->Data());
|
||||
}
|
||||
if ((TooComplexFeatures & KeyGraphFeaturesFlag::Parity) == KeyGraphFeaturesFlag::Parity)
|
||||
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::Parity) == KeyGraphFeaturesFlag::Parity)
|
||||
{
|
||||
error.append((m_resourceLoader->GetString(L"Parity") + separator + L" ")->Data());
|
||||
}
|
||||
if ((TooComplexFeatures & KeyGraphFeaturesFlag::Periodicity) == KeyGraphFeaturesFlag::Periodicity)
|
||||
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::Periodicity) == KeyGraphFeaturesFlag::Periodicity)
|
||||
{
|
||||
error.append((m_resourceLoader->GetString(L"Periodicity") + separator + L" ")->Data());
|
||||
}
|
||||
if ((TooComplexFeatures & KeyGraphFeaturesFlag::Minima) == KeyGraphFeaturesFlag::Minima)
|
||||
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::Minima) == KeyGraphFeaturesFlag::Minima)
|
||||
{
|
||||
error.append((m_resourceLoader->GetString(L"Minima") + separator + L" ")->Data());
|
||||
}
|
||||
if ((TooComplexFeatures & KeyGraphFeaturesFlag::Maxima) == KeyGraphFeaturesFlag::Maxima)
|
||||
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::Maxima) == KeyGraphFeaturesFlag::Maxima)
|
||||
{
|
||||
error.append((m_resourceLoader->GetString(L"Maxima") + separator + L" ")->Data());
|
||||
}
|
||||
if ((TooComplexFeatures & KeyGraphFeaturesFlag::InflectionPoints) == KeyGraphFeaturesFlag::InflectionPoints)
|
||||
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::InflectionPoints) == KeyGraphFeaturesFlag::InflectionPoints)
|
||||
{
|
||||
error.append((m_resourceLoader->GetString(L"InflectionPoints") + separator + L" ")->Data());
|
||||
}
|
||||
if ((TooComplexFeatures & KeyGraphFeaturesFlag::VerticalAsymptotes) == KeyGraphFeaturesFlag::VerticalAsymptotes)
|
||||
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::VerticalAsymptotes) == KeyGraphFeaturesFlag::VerticalAsymptotes)
|
||||
{
|
||||
error.append((m_resourceLoader->GetString(L"VerticalAsymptotes") + separator + L" ")->Data());
|
||||
}
|
||||
if ((TooComplexFeatures & KeyGraphFeaturesFlag::HorizontalAsymptotes) == KeyGraphFeaturesFlag::HorizontalAsymptotes)
|
||||
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::HorizontalAsymptotes) == KeyGraphFeaturesFlag::HorizontalAsymptotes)
|
||||
{
|
||||
error.append((m_resourceLoader->GetString(L"HorizontalAsymptotes") + separator + L" ")->Data());
|
||||
}
|
||||
if ((TooComplexFeatures & KeyGraphFeaturesFlag::ObliqueAsymptotes) == KeyGraphFeaturesFlag::ObliqueAsymptotes)
|
||||
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::ObliqueAsymptotes) == KeyGraphFeaturesFlag::ObliqueAsymptotes)
|
||||
{
|
||||
error.append((m_resourceLoader->GetString(L"ObliqueAsymptotes") + separator + L" ")->Data());
|
||||
}
|
||||
if ((TooComplexFeatures & KeyGraphFeaturesFlag::MonotoneIntervals) == KeyGraphFeaturesFlag::MonotoneIntervals)
|
||||
if ((GraphEquation->TooComplexFeatures & KeyGraphFeaturesFlag::MonotoneIntervals) == KeyGraphFeaturesFlag::MonotoneIntervals)
|
||||
{
|
||||
error.append((m_resourceLoader->GetString(L"Monotonicity") + separator + L" ")->Data());
|
||||
}
|
||||
|
@ -36,58 +36,60 @@ public
|
||||
ref class EquationViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
|
||||
{
|
||||
public:
|
||||
EquationViewModel();
|
||||
EquationViewModel(GraphControl::Equation ^ equation);
|
||||
|
||||
OBSERVABLE_OBJECT_CALLBACK(OnPropertyChanged);
|
||||
OBSERVABLE_PROPERTY_RW(Platform::String ^, Expression);
|
||||
OBSERVABLE_PROPERTY_RW(Windows::UI::Xaml::Media::SolidColorBrush ^, LineColor);
|
||||
OBSERVABLE_OBJECT();
|
||||
OBSERVABLE_PROPERTY_R(GraphControl::Equation ^, GraphEquation);
|
||||
|
||||
// Key Graph Features
|
||||
OBSERVABLE_PROPERTY_RW_ALWAYS_NOTIFY(bool, IsAnalysisUpdated);
|
||||
OBSERVABLE_PROPERTY_RW(Platform::String ^, Domain);
|
||||
OBSERVABLE_PROPERTY_RW(Platform::String ^, Range);
|
||||
OBSERVABLE_PROPERTY_RW(Platform::String ^, XIntercept);
|
||||
OBSERVABLE_PROPERTY_RW(Platform::String ^, YIntercept);
|
||||
OBSERVABLE_PROPERTY_RW(int, Parity);
|
||||
OBSERVABLE_PROPERTY_RW(int, PeriodicityDirection);
|
||||
OBSERVABLE_PROPERTY_RW(Platform::String ^, PeriodicityExpression);
|
||||
OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IObservableVector<Platform::String ^> ^, Minima);
|
||||
OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IObservableVector<Platform::String ^> ^, Maxima);
|
||||
OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IObservableVector<Platform::String ^> ^, InflectionPoints);
|
||||
OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IObservableVector<Platform::String ^> ^, VerticalAsymptotes);
|
||||
OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IObservableVector<Platform::String ^> ^, HorizontalAsymptotes);
|
||||
OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IObservableVector<Platform::String ^> ^, ObliqueAsymptotes);
|
||||
OBSERVABLE_PROPERTY_RW(int, TooComplexFeatures);
|
||||
OBSERVABLE_PROPERTY_RW(int, AnalysisError);
|
||||
OBSERVABLE_PROPERTY_R(Platform::String ^, AnalysisErrorString);
|
||||
OBSERVABLE_PROPERTY_R(bool, AnalysisErrorVisible);
|
||||
OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IObservableVector<CalculatorApp::ViewModel::KeyGraphFeaturesItem ^> ^, KeyGraphFeaturesItems)
|
||||
|
||||
property Windows::Foundation::Collections::IObservableMap<Platform::String ^, Platform::String^> ^ Monotonicity
|
||||
property Platform::String ^ Expression
|
||||
{
|
||||
Windows::Foundation::Collections::IObservableMap<Platform::String ^, Platform::String^> ^ get()
|
||||
Platform::String ^ get()
|
||||
{
|
||||
return m_Monotonicity;
|
||||
return GraphEquation->Expression;
|
||||
}
|
||||
void set(Windows::Foundation::Collections::IObservableMap<Platform::String ^, Platform::String^> ^ value)
|
||||
void set(Platform::String ^ value)
|
||||
{
|
||||
if (m_Monotonicity != value)
|
||||
if (GraphEquation->Expression != value)
|
||||
{
|
||||
m_Monotonicity = value;
|
||||
GraphEquation->Expression = value;
|
||||
RaisePropertyChanged("Expression");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property Windows::UI::Xaml::Media::SolidColorBrush ^ LineColor
|
||||
{
|
||||
Windows::UI::Xaml::Media::SolidColorBrush ^ get()
|
||||
{
|
||||
return GraphEquation->LineColor;
|
||||
}
|
||||
void set(Windows::UI::Xaml::Media::SolidColorBrush ^ value)
|
||||
{
|
||||
if (GraphEquation->LineColor != value)
|
||||
{
|
||||
GraphEquation->LineColor = value;
|
||||
RaisePropertyChanged("LineColor");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Key Graph Features
|
||||
OBSERVABLE_PROPERTY_R(Platform::String ^, AnalysisErrorString);
|
||||
OBSERVABLE_PROPERTY_R(bool, AnalysisErrorVisible);
|
||||
OBSERVABLE_PROPERTY_R(Windows::Foundation::Collections::IObservableVector<CalculatorApp::ViewModel::KeyGraphFeaturesItem ^> ^, KeyGraphFeaturesItems)
|
||||
|
||||
void PopulateKeyGraphFeatures();
|
||||
|
||||
private:
|
||||
void OnPropertyChanged(Platform::String ^ propertyName);
|
||||
void SetParityStringProperty();
|
||||
void SetPeriodicityStringProperty();
|
||||
void SetKeyGraphFeaturesItems(Platform::String ^ title, Platform::String ^ expression, Platform::String ^ errorString);
|
||||
void SetKeyGraphFeaturesItems(Platform::String ^ title, Windows::Foundation::Collections::IObservableVector<Platform::String ^> ^ expressionVector,
|
||||
void AddKeyGraphFeature(Platform::String ^ title, Platform::String ^ expression, Platform::String ^ errorString);
|
||||
void AddKeyGraphFeature(
|
||||
Platform::String ^ title,
|
||||
Windows::Foundation::Collections::IVector<Platform::String ^> ^ expressionVector,
|
||||
Platform::String ^ errorString);
|
||||
void SetMonotoncityStringProperty();
|
||||
void SetTooComplexFeaturesErrorProperty();
|
||||
void OnIsAnalysisUpdatedChanged();
|
||||
void AddParityKeyGraphFeature();
|
||||
void AddPeriodicityKeyGraphFeature();
|
||||
void AddMonotoncityKeyGraphFeature();
|
||||
void AddTooComplexKeyGraphFeature();
|
||||
|
||||
Windows::Foundation::Collections::IObservableMap<Platform::String ^, Platform::String ^> ^ m_Monotonicity;
|
||||
Windows::ApplicationModel::Resources::ResourceLoader ^ m_resourceLoader;
|
||||
|
@ -63,7 +63,7 @@ void EquationInputArea::AddEquationButton_Click(Object ^ sender, RoutedEventArgs
|
||||
|
||||
void EquationInputArea::AddNewEquation()
|
||||
{
|
||||
auto eq = ref new EquationViewModel();
|
||||
auto eq = ref new EquationViewModel(ref new Equation());
|
||||
|
||||
m_lastLineColorIndex = (m_lastLineColorIndex + 1) % AvailableColors->Size;
|
||||
|
||||
@ -111,7 +111,7 @@ void EquationInputArea::EquationTextBox_KeyGraphFeaturesButtonClicked(Object ^ s
|
||||
auto tb = static_cast<EquationTextBox ^>(sender);
|
||||
auto eq = static_cast<EquationViewModel ^>(tb->DataContext);
|
||||
EquationVM = eq;
|
||||
KeyGraphFeaturesVisibilityChanged(this, ref new RoutedEventArgs());
|
||||
KeyGraphFeaturesRequested(EquationVM, ref new RoutedEventArgs());
|
||||
}
|
||||
|
||||
void EquationInputArea::EquationTextBox_EquationButtonClicked(Object ^ sender, RoutedEventArgs ^ e)
|
||||
|
@ -23,7 +23,7 @@ namespace CalculatorApp
|
||||
OBSERVABLE_PROPERTY_RW_ALWAYS_NOTIFY(ViewModel::EquationViewModel ^, EquationVM);
|
||||
OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IObservableVector<Windows::UI::Xaml::Media::SolidColorBrush ^> ^, AvailableColors);
|
||||
|
||||
event Windows::UI::Xaml::RoutedEventHandler ^ KeyGraphFeaturesVisibilityChanged;
|
||||
event Windows::UI::Xaml::RoutedEventHandler ^ KeyGraphFeaturesRequested;
|
||||
|
||||
private:
|
||||
void OnPropertyChanged(Platform::String^ propertyName);
|
||||
|
@ -182,7 +182,6 @@
|
||||
Grid.Column="0">
|
||||
<Grid Grid.Row="0" Margin="0,4,0,0">
|
||||
<graphControl:Grapher Name="GraphingControl"
|
||||
EquationsSource="{x:Bind ViewModel.Equations, Mode=OneWay}"
|
||||
ForceProportionalAxes="True"
|
||||
LosingFocus="GraphingControl_LosingFocus"
|
||||
LostFocus="GraphingControl_LostFocus"
|
||||
@ -191,30 +190,6 @@
|
||||
<graphControl:Grapher.Background>
|
||||
<SolidColorBrush Color="White"/>
|
||||
</graphControl:Grapher.Background>
|
||||
<graphControl:Grapher.EquationTemplate>
|
||||
<DataTemplate x:DataType="vm:EquationViewModel">
|
||||
<graphControl:Equation AnalysisError="{x:Bind AnalysisError, Mode=TwoWay}"
|
||||
Domain="{x:Bind Domain, Mode=TwoWay}"
|
||||
Expression="{x:Bind Expression, Mode=OneWay}"
|
||||
HorizontalAsymptotes="{x:Bind HorizontalAsymptotes, Mode=TwoWay}"
|
||||
InflectionPoints="{x:Bind InflectionPoints, Mode=TwoWay}"
|
||||
IsAnalysisUpdated="{x:Bind IsAnalysisUpdated, Mode=TwoWay}"
|
||||
LineColor="{x:Bind LineColor, Mode=OneWay}"
|
||||
Maxima="{x:Bind Maxima, Mode=TwoWay}"
|
||||
Minima="{x:Bind Minima, Mode=TwoWay}"
|
||||
Monotonicity="{x:Bind Monotonicity, Mode=TwoWay}"
|
||||
ObliqueAsymptotes="{x:Bind ObliqueAsymptotes, Mode=TwoWay}"
|
||||
Parity="{x:Bind Parity, Mode=TwoWay}"
|
||||
PeriodicityDirection="{x:Bind PeriodicityDirection, Mode=TwoWay}"
|
||||
PeriodicityExpression="{x:Bind PeriodicityExpression, Mode=TwoWay}"
|
||||
Range="{x:Bind Range, Mode=TwoWay}"
|
||||
TooComplexFeatures="{x:Bind TooComplexFeatures, Mode=TwoWay}"
|
||||
VerticalAsymptotes="{x:Bind VerticalAsymptotes, Mode=TwoWay}"
|
||||
XIntercept="{x:Bind XIntercept, Mode=TwoWay}"
|
||||
YIntercept="{x:Bind YIntercept, Mode=TwoWay}"/>
|
||||
</DataTemplate>
|
||||
</graphControl:Grapher.EquationTemplate>
|
||||
|
||||
</graphControl:Grapher>
|
||||
|
||||
<StackPanel Grid.Row="0"
|
||||
@ -525,7 +500,7 @@
|
||||
Margin="0,4,0,0"
|
||||
Visibility="{x:Bind IsKeyGraphFeaturesVisible, Converter={StaticResource BooleanToVisibilityNegationConverter}, Mode=OneWay}"
|
||||
Equations="{x:Bind ViewModel.Equations}"
|
||||
KeyGraphFeaturesVisibilityChanged="OnEquationKeyGraphFeaturesVisibilityChanged"/>
|
||||
KeyGraphFeaturesRequested="OnEquationKeyGraphFeaturesRequested"/>
|
||||
|
||||
<Grid x:Name="ButtonContainerGrid"
|
||||
Grid.Row="1"
|
||||
|
@ -77,9 +77,43 @@ void GraphingCalculator::OnShowTracePopupChanged(bool newValue)
|
||||
|
||||
void GraphingCalculator::GraphingCalculator_DataContextChanged(FrameworkElement ^ sender, DataContextChangedEventArgs ^ args)
|
||||
{
|
||||
if (ViewModel != nullptr)
|
||||
{
|
||||
if (m_vectorChangedToken.Value != 0)
|
||||
{
|
||||
ViewModel->Equations->VectorChanged -= m_vectorChangedToken;
|
||||
m_vectorChangedToken.Value = 0;
|
||||
}
|
||||
|
||||
if (m_variableUpdatedToken.Value != 0)
|
||||
{
|
||||
ViewModel->VariableUpdated -= m_variableUpdatedToken;
|
||||
m_variableUpdatedToken.Value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ViewModel = dynamic_cast<GraphingCalculatorViewModel ^>(args->NewValue);
|
||||
|
||||
ViewModel->VariableUpdated += ref new EventHandler<VariableChangedEventArgs>(this, &CalculatorApp::GraphingCalculator::OnVariableChanged);
|
||||
m_vectorChangedToken = ViewModel->Equations->VectorChanged +=
|
||||
ref new VectorChangedEventHandler<EquationViewModel ^>(this, &GraphingCalculator::OnEquationsVectorChanged);
|
||||
|
||||
m_variableUpdatedToken = ViewModel->VariableUpdated +=
|
||||
ref new EventHandler<VariableChangedEventArgs>(this, &CalculatorApp::GraphingCalculator::OnVariableChanged);
|
||||
}
|
||||
|
||||
void GraphingCalculator::OnEquationsVectorChanged(IObservableVector<EquationViewModel ^> ^ sender, IVectorChangedEventArgs ^ event)
|
||||
{
|
||||
if (event->CollectionChange != ::CollectionChange::ItemChanged)
|
||||
{
|
||||
GraphingControl->Equations->Clear();
|
||||
|
||||
for (auto equationViewModel : ViewModel->Equations)
|
||||
{
|
||||
GraphingControl->Equations->Append(equationViewModel->GraphEquation);
|
||||
}
|
||||
|
||||
GraphingControl->PlotGraph();
|
||||
}
|
||||
}
|
||||
|
||||
void GraphingCalculator::OnTracePointChanged(Windows::Foundation::Point newPoint)
|
||||
@ -331,8 +365,11 @@ void GraphingCalculator::GraphingControl_LosingFocus(UIElement ^ sender, LosingF
|
||||
}
|
||||
}
|
||||
|
||||
void GraphingCalculator::OnEquationKeyGraphFeaturesVisibilityChanged(Object ^ sender, RoutedEventArgs ^ e)
|
||||
void GraphingCalculator::OnEquationKeyGraphFeaturesRequested(Object ^ sender, RoutedEventArgs ^ e)
|
||||
{
|
||||
auto equationViewModel = static_cast<EquationViewModel ^>(sender);
|
||||
GraphingControl->AnalyzeEquation(equationViewModel->GraphEquation);
|
||||
equationViewModel->PopulateKeyGraphFeatures();
|
||||
IsKeyGraphFeaturesVisible = true;
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,9 @@ namespace CalculatorApp
|
||||
void GraphingCalculator_DataContextChanged(Windows::UI::Xaml::FrameworkElement^ sender, Windows::UI::Xaml::DataContextChangedEventArgs^ args);
|
||||
|
||||
void OnVariableChanged(Platform::Object^ sender, CalculatorApp::ViewModel::VariableChangedEventArgs args);
|
||||
void OnEquationsVectorChanged(
|
||||
Windows::Foundation::Collections::IObservableVector<CalculatorApp::ViewModel::EquationViewModel ^> ^ sender,
|
||||
Windows::Foundation::Collections::IVectorChangedEventArgs ^ event);
|
||||
|
||||
void TextBoxLosingFocus(Windows::UI::Xaml::Controls::TextBox^ textbox, Windows::UI::Xaml::Input::LosingFocusEventArgs^ args);
|
||||
void TextBoxKeyDown(Windows::UI::Xaml::Controls::TextBox^ textbox, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e);
|
||||
@ -55,6 +58,8 @@ namespace CalculatorApp
|
||||
|
||||
private:
|
||||
Windows::Foundation::EventRegistrationToken m_dataRequestedToken;
|
||||
Windows::Foundation::EventRegistrationToken m_vectorChangedToken;
|
||||
Windows::Foundation::EventRegistrationToken m_variableUpdatedToken;
|
||||
void OnDataRequested(Windows::ApplicationModel::DataTransfer::DataTransferManager^ sender, Windows::ApplicationModel::DataTransfer::DataRequestedEventArgs^ e);
|
||||
|
||||
void TextBoxGotFocus(Windows::UI::Xaml::Controls::TextBox^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
@ -62,7 +67,7 @@ namespace CalculatorApp
|
||||
void GraphingControl_LostFocus(Platform::Object ^ sender, Windows::UI::Xaml::RoutedEventArgs ^ e);
|
||||
void GraphingControl_LosingFocus(Windows::UI::Xaml::UIElement ^ sender, Windows::UI::Xaml::Input::LosingFocusEventArgs ^ args);
|
||||
void GraphingControl_VariablesUpdated(Platform::Object ^ sender, Object ^ args);
|
||||
void OnEquationKeyGraphFeaturesVisibilityChanged(Platform::Object ^ sender, Windows::UI::Xaml::RoutedEventArgs ^ e);
|
||||
void OnEquationKeyGraphFeaturesRequested(Platform::Object ^ sender, Windows::UI::Xaml::RoutedEventArgs ^ e);
|
||||
void OnKeyGraphFeaturesClosed(Platform::Object ^ sender, Windows::UI::Xaml::RoutedEventArgs ^ e);
|
||||
bool ActiveTracingOn;
|
||||
};
|
||||
|
@ -23,9 +23,6 @@ namespace GraphControl
|
||||
DependencyProperty ^ Equation::s_lineColorProperty;
|
||||
static constexpr auto s_propertyName_LineColor = L"LineColor";
|
||||
|
||||
DependencyProperty ^ Equation::s_isAnalysisUpdatedProperty;
|
||||
static constexpr auto s_propertyName_IsAnalysisUpdated = L"IsAnalysisUpdated";
|
||||
|
||||
DependencyProperty ^ Equation::s_xInterceptProperty;
|
||||
static constexpr auto s_propertyName_XIntercept = L"XIntercept";
|
||||
|
||||
@ -78,7 +75,6 @@ namespace GraphControl
|
||||
{
|
||||
String ^ Expression = StringReference(s_propertyName_Expression);
|
||||
String ^ LineColor = StringReference(s_propertyName_LineColor);
|
||||
String ^ IsAnalysisUpdated = StringReference(s_propertyName_IsAnalysisUpdated);
|
||||
String ^ XIntercept = StringReference(s_propertyName_XIntercept);
|
||||
String ^ YIntercept = StringReference(s_propertyName_YIntercept);
|
||||
String ^ Parity = StringReference(s_propertyName_Parity);
|
||||
@ -120,15 +116,6 @@ namespace GraphControl
|
||||
ref new PropertyMetadata(nullptr, ref new PropertyChangedCallback(&Equation::OnCustomDependencyPropertyChanged)));
|
||||
}
|
||||
|
||||
if (!s_isAnalysisUpdatedProperty)
|
||||
{
|
||||
s_isAnalysisUpdatedProperty = DependencyProperty::Register(
|
||||
EquationProperties::IsAnalysisUpdated,
|
||||
bool ::typeid,
|
||||
Equation::typeid,
|
||||
ref new PropertyMetadata(nullptr, ref new PropertyChangedCallback(&Equation::OnCustomDependencyPropertyChanged)));
|
||||
}
|
||||
|
||||
if (!s_xInterceptProperty)
|
||||
{
|
||||
s_xInterceptProperty = DependencyProperty::Register(
|
||||
@ -286,10 +273,6 @@ namespace GraphControl
|
||||
{
|
||||
propertyName = EquationProperties::LineColor;
|
||||
}
|
||||
else if (args->Property == s_isAnalysisUpdatedProperty)
|
||||
{
|
||||
propertyName = EquationProperties::IsAnalysisUpdated;
|
||||
}
|
||||
else if (args->Property == s_xInterceptProperty)
|
||||
{
|
||||
propertyName = EquationProperties::XIntercept;
|
||||
|
@ -14,7 +14,7 @@ namespace GraphControl
|
||||
ref class Equation;
|
||||
delegate void PropertyChangedEventHandler(Equation ^ sender, Platform::String ^ propertyName);
|
||||
|
||||
[Windows::UI::Xaml::Data::Bindable] public ref class Equation sealed : public Windows::UI::Xaml::FrameworkElement
|
||||
[Windows::UI::Xaml::Data::Bindable] public ref class Equation sealed : public Windows::UI::Xaml::DependencyObject
|
||||
{
|
||||
public:
|
||||
|
||||
@ -70,26 +70,7 @@ namespace GraphControl
|
||||
|
||||
#pragma region Key Graph Features
|
||||
|
||||
#pragma region bool IsAnalysisUpdated DependencyProperty
|
||||
static property Windows::UI::Xaml::DependencyProperty^ IsAnalysisUpdatedProperty
|
||||
{
|
||||
Windows::UI::Xaml::DependencyProperty^ get()
|
||||
{
|
||||
return s_isAnalysisUpdatedProperty;
|
||||
}
|
||||
}
|
||||
property bool IsAnalysisUpdated
|
||||
{
|
||||
bool get()
|
||||
{
|
||||
return static_cast<bool>(GetValue(s_isAnalysisUpdatedProperty));
|
||||
}
|
||||
void set(bool value)
|
||||
{
|
||||
SetValue(s_isAnalysisUpdatedProperty, value);
|
||||
}
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Platform::String ^ XIntercept DependencyProperty
|
||||
static property Windows::UI::Xaml::DependencyProperty^ XInterceptProperty
|
||||
{
|
||||
@ -441,7 +422,6 @@ namespace GraphControl
|
||||
private:
|
||||
static Windows::UI::Xaml::DependencyProperty ^ s_expressionProperty;
|
||||
static Windows::UI::Xaml::DependencyProperty ^ s_lineColorProperty;
|
||||
static Windows::UI::Xaml::DependencyProperty ^ s_isAnalysisUpdatedProperty;
|
||||
static Windows::UI::Xaml::DependencyProperty ^ s_xInterceptProperty;
|
||||
static Windows::UI::Xaml::DependencyProperty ^ s_yInterceptProperty;
|
||||
static Windows::UI::Xaml::DependencyProperty ^ s_parityProperty;
|
||||
|
@ -30,9 +30,7 @@ namespace
|
||||
constexpr auto s_defaultStyleKey = L"GraphControl.Grapher";
|
||||
constexpr auto s_templateKey_SwapChainPanel = L"GraphSurface";
|
||||
|
||||
constexpr auto s_propertyName_EquationTemplate = L"EquationTemplate";
|
||||
constexpr auto s_propertyName_Equations = L"Equations";
|
||||
constexpr auto s_propertyName_EquationsSource = L"EquationsSource";
|
||||
constexpr auto s_propertyName_Variables = L"Variables";
|
||||
constexpr auto s_propertyName_ForceProportionalAxes = L"ForceProportionalAxes";
|
||||
|
||||
@ -54,9 +52,7 @@ namespace
|
||||
|
||||
namespace GraphControl
|
||||
{
|
||||
DependencyProperty ^ Grapher::s_equationTemplateProperty;
|
||||
DependencyProperty ^ Grapher::s_equationsProperty;
|
||||
DependencyProperty ^ Grapher::s_equationsSourceProperty;
|
||||
DependencyProperty ^ Grapher::s_variablesProperty;
|
||||
DependencyProperty ^ Grapher::s_forceProportionalAxesTemplateProperty;
|
||||
|
||||
@ -160,24 +156,6 @@ namespace GraphControl
|
||||
ref new PropertyMetadata(nullptr, ref new PropertyChangedCallback(&Grapher::OnCustomDependencyPropertyChanged)));
|
||||
}
|
||||
|
||||
if (!s_equationsSourceProperty)
|
||||
{
|
||||
s_equationsSourceProperty = DependencyProperty::Register(
|
||||
StringReference(s_propertyName_EquationsSource),
|
||||
Object::typeid,
|
||||
Grapher::typeid,
|
||||
ref new PropertyMetadata(nullptr, ref new PropertyChangedCallback(&Grapher::OnCustomDependencyPropertyChanged)));
|
||||
}
|
||||
|
||||
if (!s_equationTemplateProperty)
|
||||
{
|
||||
s_equationTemplateProperty = DependencyProperty::Register(
|
||||
StringReference(s_propertyName_EquationTemplate),
|
||||
DataTemplate::typeid,
|
||||
Grapher::typeid,
|
||||
ref new PropertyMetadata(nullptr, ref new PropertyChangedCallback(&Grapher::OnCustomDependencyPropertyChanged)));
|
||||
}
|
||||
|
||||
if (!s_variablesProperty)
|
||||
{
|
||||
s_variablesProperty = DependencyProperty::Register(
|
||||
@ -206,14 +184,6 @@ namespace GraphControl
|
||||
{
|
||||
self->OnEquationsChanged(args);
|
||||
}
|
||||
else if (args->Property == EquationsSourceProperty)
|
||||
{
|
||||
self->OnEquationsSourceChanged(args);
|
||||
}
|
||||
else if (args->Property == EquationTemplateProperty)
|
||||
{
|
||||
self->OnEquationTemplateChanged(args);
|
||||
}
|
||||
else if (args->Property == ForceProportionalAxesTemplateProperty)
|
||||
{
|
||||
self->OnForceProportionalAxesChanged(args);
|
||||
@ -230,95 +200,10 @@ namespace GraphControl
|
||||
}
|
||||
}
|
||||
|
||||
void Grapher::OnEquationTemplateChanged(DependencyPropertyChangedEventArgs ^ args)
|
||||
{
|
||||
SyncEquationsWithItemsSource();
|
||||
}
|
||||
|
||||
void Grapher::OnEquationsSourceChanged(DependencyPropertyChangedEventArgs ^ args)
|
||||
{
|
||||
if (m_dataSource && m_tokenDataSourceChanged.Value != 0)
|
||||
{
|
||||
m_dataSource->DataSourceChanged -= m_tokenDataSourceChanged;
|
||||
}
|
||||
|
||||
m_dataSource = args->NewValue ? ref new InspectingDataSource(args->NewValue) : nullptr;
|
||||
if (m_dataSource)
|
||||
{
|
||||
m_tokenDataSourceChanged = m_dataSource->DataSourceChanged +=
|
||||
ref new TypedEventHandler<InspectingDataSource ^, DataSourceChangedEventArgs>(this, &Grapher::OnDataSourceChanged);
|
||||
}
|
||||
|
||||
SyncEquationsWithItemsSource();
|
||||
}
|
||||
|
||||
void Grapher::OnDataSourceChanged(InspectingDataSource ^ sender, DataSourceChangedEventArgs args)
|
||||
{
|
||||
switch (args.Action)
|
||||
{
|
||||
case DataSourceChangedAction::Insert:
|
||||
OnItemsAdded(args.NewStartingIndex, args.NewItemsCount);
|
||||
break;
|
||||
|
||||
case DataSourceChangedAction::Remove:
|
||||
OnItemsRemoved(args.OldStartingIndex, args.OldItemsCount);
|
||||
break;
|
||||
|
||||
case DataSourceChangedAction::Reset:
|
||||
SyncEquationsWithItemsSource();
|
||||
break;
|
||||
|
||||
case DataSourceChangedAction::Replace:
|
||||
OnItemsRemoved(args.OldStartingIndex, args.OldItemsCount);
|
||||
OnItemsAdded(args.NewStartingIndex, args.NewItemsCount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Grapher::OnItemsAdded(int index, int count)
|
||||
{
|
||||
for (int i = index + count - 1; i >= index; i--)
|
||||
{
|
||||
auto eq = safe_cast<Equation ^>(EquationTemplate->LoadContent());
|
||||
eq->DataContext = m_dataSource->GetAt(i);
|
||||
|
||||
Equations->InsertAt(index, eq);
|
||||
}
|
||||
}
|
||||
|
||||
void Grapher::OnItemsRemoved(int index, int count)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Equations->RemoveAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
void Grapher::SyncEquationsWithItemsSource()
|
||||
{
|
||||
Equations->Clear();
|
||||
if (m_dataSource)
|
||||
{
|
||||
auto size = m_dataSource->GetSize();
|
||||
for (auto i = 0u; i < size; i++)
|
||||
{
|
||||
auto eq = safe_cast<Equation ^>(EquationTemplate->LoadContent());
|
||||
eq->DataContext = m_dataSource->GetAt(i);
|
||||
|
||||
Equations->Append(eq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Grapher::OnEquationsChanged(DependencyPropertyChangedEventArgs ^ args)
|
||||
{
|
||||
if (auto older = static_cast<EquationCollection ^>(args->OldValue))
|
||||
{
|
||||
if (m_tokenEquationsChanged.Value != 0)
|
||||
{
|
||||
older->VectorChanged -= m_tokenEquationsChanged;
|
||||
m_tokenEquationsChanged.Value = 0;
|
||||
}
|
||||
if (m_tokenEquationChanged.Value != 0)
|
||||
{
|
||||
older->EquationChanged -= m_tokenEquationChanged;
|
||||
@ -334,8 +219,6 @@ namespace GraphControl
|
||||
|
||||
if (auto newer = static_cast<EquationCollection ^>(args->NewValue))
|
||||
{
|
||||
m_tokenEquationsChanged = newer->VectorChanged += ref new VectorChangedEventHandler<Equation ^>(this, &Grapher::OnEquationsVectorChanged);
|
||||
|
||||
m_tokenEquationChanged = newer->EquationChanged += ref new EquationChangedEventHandler(this, &Grapher::OnEquationChanged);
|
||||
|
||||
m_tokenEquationStyleChanged = newer->EquationStyleChanged += ref new EquationChangedEventHandler(this, &Grapher::OnEquationStyleChanged);
|
||||
@ -344,22 +227,6 @@ namespace GraphControl
|
||||
UpdateGraph();
|
||||
}
|
||||
|
||||
void Grapher::OnEquationsVectorChanged(IObservableVector<Equation ^> ^ sender, IVectorChangedEventArgs ^ event)
|
||||
{
|
||||
if (event->CollectionChange == ::CollectionChange::ItemInserted || event->CollectionChange == ::CollectionChange::ItemChanged)
|
||||
{
|
||||
auto eq = sender->GetAt(event->Index);
|
||||
|
||||
// Don't update the graph unless the equations being added/modified is valid.
|
||||
if (eq->Expression->IsEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateGraph();
|
||||
}
|
||||
|
||||
void Grapher::OnEquationChanged()
|
||||
{
|
||||
UpdateGraph();
|
||||
@ -378,6 +245,56 @@ namespace GraphControl
|
||||
}
|
||||
}
|
||||
|
||||
void Grapher::PlotGraph()
|
||||
{
|
||||
UpdateGraph();
|
||||
}
|
||||
|
||||
void Grapher::AnalyzeEquation(Equation ^ equation)
|
||||
{
|
||||
if (auto graph = GetGraph(equation))
|
||||
{
|
||||
if (auto analyzer = graph->GetAnalyzer())
|
||||
{
|
||||
if (analyzer->CanFunctionAnalysisBePerformed())
|
||||
{
|
||||
if (S_OK == analyzer->PerformFunctionAnalysis((Graphing::Analyzer::NativeAnalysisType)Graphing::Analyzer::PerformAnalysisType::PerformAnalysisType_All))
|
||||
{
|
||||
Graphing::IGraphFunctionAnalysisData functionAnalysisData = m_solver->Analyze(analyzer.get());
|
||||
{
|
||||
equation->XIntercept = ref new String(functionAnalysisData.Zeros.c_str());
|
||||
equation->YIntercept = ref new String(functionAnalysisData.YIntercept.c_str());
|
||||
equation->Domain = ref new String(functionAnalysisData.Domain.c_str());
|
||||
equation->Range = ref new String(functionAnalysisData.Range.c_str());
|
||||
equation->Parity = functionAnalysisData.Parity;
|
||||
equation->PeriodicityDirection = functionAnalysisData.PeriodicityDirection;
|
||||
equation->PeriodicityExpression = ref new String(functionAnalysisData.PeriodicityExpression.c_str());
|
||||
equation->Minima = ConvertWStringVector(functionAnalysisData.Minima);
|
||||
equation->Maxima = ConvertWStringVector(functionAnalysisData.Maxima);
|
||||
equation->InflectionPoints = ConvertWStringVector(functionAnalysisData.InflectionPoints);
|
||||
equation->Monotonicity = ConvertWStringIntMap(functionAnalysisData.MonotoneIntervals);
|
||||
equation->VerticalAsymptotes = ConvertWStringVector(functionAnalysisData.VerticalAsymptotes);
|
||||
equation->HorizontalAsymptotes = ConvertWStringVector(functionAnalysisData.HorizontalAsymptotes);
|
||||
equation->ObliqueAsymptotes = ConvertWStringVector(functionAnalysisData.ObliqueAsymptotes);
|
||||
equation->TooComplexFeatures = functionAnalysisData.TooComplexFeatures;
|
||||
equation->AnalysisError = CalculatorApp::AnalysisErrorType::NoError;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
equation->AnalysisError = CalculatorApp::AnalysisErrorType::AnalysisNotSupported;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
equation->AnalysisError = CalculatorApp::AnalysisErrorType::AnalysisCouldNotBePerformed;
|
||||
}
|
||||
|
||||
void Grapher::UpdateGraph()
|
||||
{
|
||||
if (m_renderMain && m_graph != nullptr)
|
||||
@ -414,7 +331,6 @@ namespace GraphControl
|
||||
m_renderMain->Graph = m_graph;
|
||||
|
||||
UpdateVariables();
|
||||
UpdateKeyGraphFeatures();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -428,7 +344,6 @@ namespace GraphControl
|
||||
m_renderMain->Graph = m_graph;
|
||||
|
||||
UpdateVariables();
|
||||
UpdateKeyGraphFeatures();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -467,59 +382,6 @@ namespace GraphControl
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Grapher::UpdateKeyGraphFeatures()
|
||||
{
|
||||
auto equations = GetValidEquations();
|
||||
for (auto equation : equations)
|
||||
{
|
||||
equation->IsAnalysisUpdated = false;
|
||||
|
||||
if (auto graph = GetGraph(equation))
|
||||
{
|
||||
if (auto analyzer = graph->GetAnalyzer())
|
||||
{
|
||||
if (analyzer->CanFunctionAnalysisBePerformed())
|
||||
{
|
||||
if (S_OK
|
||||
== analyzer->PerformFunctionAnalysis(
|
||||
(Graphing::Analyzer::NativeAnalysisType)Graphing::Analyzer::PerformAnalysisType::PerformAnalysisType_All))
|
||||
{
|
||||
Graphing::IGraphFunctionAnalysisData functionAnalysisData = m_solver->Analyze(analyzer.get());
|
||||
{
|
||||
equation->XIntercept = ref new String(functionAnalysisData.Zeros.c_str());
|
||||
equation->YIntercept = ref new String(functionAnalysisData.YIntercept.c_str());
|
||||
equation->Domain = ref new String(functionAnalysisData.Domain.c_str());
|
||||
equation->Range = ref new String(functionAnalysisData.Range.c_str());
|
||||
equation->Parity = functionAnalysisData.Parity;
|
||||
equation->PeriodicityDirection = functionAnalysisData.PeriodicityDirection;
|
||||
equation->PeriodicityExpression = ref new String(functionAnalysisData.PeriodicityExpression.c_str());
|
||||
equation->Minima = ConvertWStringVector(functionAnalysisData.Minima);
|
||||
equation->Maxima = ConvertWStringVector(functionAnalysisData.Maxima);
|
||||
equation->InflectionPoints = ConvertWStringVector(functionAnalysisData.InflectionPoints);
|
||||
equation->Monotonicity = ConvertWStringIntMap(functionAnalysisData.MonotoneIntervals);
|
||||
equation->VerticalAsymptotes = ConvertWStringVector(functionAnalysisData.VerticalAsymptotes);
|
||||
equation->HorizontalAsymptotes = ConvertWStringVector(functionAnalysisData.HorizontalAsymptotes);
|
||||
equation->ObliqueAsymptotes = ConvertWStringVector(functionAnalysisData.ObliqueAsymptotes);
|
||||
equation->TooComplexFeatures = functionAnalysisData.TooComplexFeatures;
|
||||
equation->AnalysisError = CalculatorApp::AnalysisErrorType::NoError;
|
||||
equation->IsAnalysisUpdated = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
equation->AnalysisError = CalculatorApp::AnalysisErrorType::AnalysisNotSupported;
|
||||
equation->IsAnalysisUpdated = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
equation->AnalysisError = CalculatorApp::AnalysisErrorType::AnalysisCouldNotBePerformed;
|
||||
equation->IsAnalysisUpdated = true;
|
||||
}
|
||||
}
|
||||
IObservableVector<String ^> ^ Grapher::ConvertWStringVector(vector<wstring> inVector)
|
||||
{
|
||||
Vector<String ^> ^ outVector = ref new Vector<String ^>();
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "InspectingDataSource.h"
|
||||
#include "DirectX/RenderMain.h"
|
||||
#include "Equation.h"
|
||||
#include "EquationCollection.h"
|
||||
@ -30,50 +29,6 @@ public
|
||||
|
||||
static void RegisterDependencyProperties();
|
||||
|
||||
#pragma region Windows::UI::Xaml::DataTemplate ^ EquationTemplate DependencyProperty
|
||||
static property Windows::UI::Xaml::DependencyProperty^ EquationTemplateProperty
|
||||
{
|
||||
Windows::UI::Xaml::DependencyProperty^ get()
|
||||
{
|
||||
return s_equationTemplateProperty;
|
||||
}
|
||||
}
|
||||
|
||||
property Windows::UI::Xaml::DataTemplate^ EquationTemplate
|
||||
{
|
||||
Windows::UI::Xaml::DataTemplate^ get()
|
||||
{
|
||||
return static_cast<Windows::UI::Xaml::DataTemplate^>(GetValue(s_equationTemplateProperty));
|
||||
}
|
||||
void set(Windows::UI::Xaml::DataTemplate^ value)
|
||||
{
|
||||
SetValue(s_equationTemplateProperty, value);
|
||||
}
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Platform::Object ^ EquationsSource DependencyProperty
|
||||
static property Windows::UI::Xaml::DependencyProperty^ EquationsSourceProperty
|
||||
{
|
||||
Windows::UI::Xaml::DependencyProperty^ get()
|
||||
{
|
||||
return s_equationsSourceProperty;
|
||||
}
|
||||
}
|
||||
|
||||
property Platform::Object^ EquationsSource
|
||||
{
|
||||
Platform::Object^ get()
|
||||
{
|
||||
return GetValue(s_equationsSourceProperty);
|
||||
}
|
||||
void set(Platform::Object^ value)
|
||||
{
|
||||
SetValue(s_equationsSourceProperty, value);
|
||||
}
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region GraphControl::EquationCollection ^ Equations DependencyProperty
|
||||
static property Windows::UI::Xaml::DependencyProperty^ EquationsProperty
|
||||
{
|
||||
@ -191,6 +146,8 @@ public
|
||||
event Windows::Foundation::EventHandler<Windows::Foundation::Collections::IMap<Platform::String ^, double> ^> ^ VariablesUpdated;
|
||||
void SetVariable(Platform::String ^ variableName, double newValue);
|
||||
Platform::String ^ ConvertToLinear(Platform::String ^ mmlString);
|
||||
void PlotGraph();
|
||||
void AnalyzeEquation(GraphControl::Equation ^ equation);
|
||||
|
||||
protected:
|
||||
#pragma region Control Overrides
|
||||
@ -213,15 +170,7 @@ public
|
||||
static void OnCustomDependencyPropertyChanged(Windows::UI::Xaml::DependencyObject ^ obj, Windows::UI::Xaml::DependencyPropertyChangedEventArgs ^ args);
|
||||
void OnDependencyPropertyChanged(Windows::UI::Xaml::DependencyObject ^ obj, Windows::UI::Xaml::DependencyProperty ^ p);
|
||||
|
||||
void OnEquationTemplateChanged(Windows::UI::Xaml::DependencyPropertyChangedEventArgs ^ args);
|
||||
|
||||
void OnEquationsSourceChanged(Windows::UI::Xaml::DependencyPropertyChangedEventArgs ^ args);
|
||||
void OnDataSourceChanged(GraphControl::InspectingDataSource ^ sender, GraphControl::DataSourceChangedEventArgs args);
|
||||
|
||||
void OnEquationsChanged(Windows::UI::Xaml::DependencyPropertyChangedEventArgs ^ args);
|
||||
void OnEquationsVectorChanged(
|
||||
Windows::Foundation::Collections::IObservableVector<GraphControl::Equation ^> ^ sender,
|
||||
Windows::Foundation::Collections::IVectorChangedEventArgs ^ event);
|
||||
void OnEquationChanged();
|
||||
void OnEquationStyleChanged();
|
||||
|
||||
@ -231,16 +180,11 @@ public
|
||||
void SetGraphArgs();
|
||||
std::shared_ptr<Graphing::IGraph> GetGraph(GraphControl::Equation ^ equation);
|
||||
void UpdateVariables();
|
||||
void UpdateKeyGraphFeatures();
|
||||
|
||||
void OnForceProportionalAxesChanged(Windows::UI::Xaml::DependencyPropertyChangedEventArgs ^ args);
|
||||
|
||||
void OnBackgroundColorChanged(const Windows::UI::Color& color);
|
||||
|
||||
void SyncEquationsWithItemsSource();
|
||||
void OnItemsAdded(int index, int count);
|
||||
void OnItemsRemoved(int index, int count);
|
||||
|
||||
void ScaleRange(double centerX, double centerY, double scale);
|
||||
|
||||
void OnCoreKeyDown(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::KeyEventArgs ^ e);
|
||||
@ -259,7 +203,6 @@ public
|
||||
static Windows::UI::Xaml::DependencyProperty ^ s_equationTemplateProperty;
|
||||
|
||||
static Windows::UI::Xaml::DependencyProperty ^ s_equationsSourceProperty;
|
||||
InspectingDataSource ^ m_dataSource;
|
||||
Windows::Foundation::EventRegistrationToken m_tokenDataSourceChanged;
|
||||
|
||||
static Windows::UI::Xaml::DependencyProperty ^ s_equationsProperty;
|
||||
|
@ -1,245 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include "pch.h"
|
||||
#include "InspectingDataSource.h"
|
||||
|
||||
using namespace Platform;
|
||||
using namespace Platform::Collections;
|
||||
using namespace std;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
using namespace Windows::UI::Xaml::Interop;
|
||||
|
||||
namespace winrt
|
||||
{
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
using namespace winrt::Windows::UI::Xaml::Interop;
|
||||
}
|
||||
|
||||
namespace GraphControl
|
||||
{
|
||||
InspectingDataSource::InspectingDataSource(Object^ source)
|
||||
{
|
||||
if (!source)
|
||||
{
|
||||
throw ref new InvalidArgumentException(L"Argument 'source' is null.");
|
||||
}
|
||||
|
||||
auto inspectable = from_cx<winrt::IInspectable>(source);
|
||||
if (auto vector = inspectable.try_as<winrt::IVector<winrt::IInspectable>>())
|
||||
{
|
||||
m_vector = vector;
|
||||
ListenToCollectionChanges();
|
||||
}
|
||||
else if (auto bindableVector = inspectable.try_as<winrt::IBindableVector>())
|
||||
{
|
||||
// The bindable interop interface are abi compatible with the corresponding
|
||||
// WinRT interfaces.
|
||||
|
||||
m_vector = reinterpret_cast<const winrt::IVector<winrt::IInspectable>&>(bindableVector);
|
||||
ListenToCollectionChanges();
|
||||
}
|
||||
else if (auto iterable = inspectable.try_as<winrt::IIterable<winrt::IInspectable>>())
|
||||
{
|
||||
m_vector = WrapIterable(iterable);
|
||||
}
|
||||
else if (auto bindableIterable = inspectable.try_as<winrt::IBindableIterable>())
|
||||
{
|
||||
m_vector = WrapIterable(reinterpret_cast<const winrt::IIterable<winrt::IInspectable> &>(bindableIterable));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw ref new InvalidArgumentException(L"Argument 'source' is not a supported vector.");
|
||||
}
|
||||
}
|
||||
|
||||
InspectingDataSource::~InspectingDataSource()
|
||||
{
|
||||
UnlistenToCollectionChanges();
|
||||
}
|
||||
|
||||
unsigned int InspectingDataSource::GetSize()
|
||||
{
|
||||
return m_vector.Size();
|
||||
}
|
||||
|
||||
Object^ InspectingDataSource::GetAt(unsigned int index)
|
||||
{
|
||||
return to_cx<Object>(m_vector.GetAt(index));
|
||||
}
|
||||
|
||||
optional<unsigned int> InspectingDataSource::IndexOf(Object^ value)
|
||||
{
|
||||
if ((m_vector != nullptr) && value)
|
||||
{
|
||||
uint32_t v;
|
||||
auto inspectable = from_cx<winrt::IInspectable>(value);
|
||||
if (m_vector.IndexOf(inspectable, v))
|
||||
{
|
||||
return v;
|
||||
}
|
||||
}
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
winrt::IVector<winrt::IInspectable> InspectingDataSource::WrapIterable(const winrt::IIterable<winrt::IInspectable>& iterable)
|
||||
{
|
||||
auto vector = winrt::single_threaded_vector<winrt::IInspectable>();
|
||||
auto iterator = iterable.First();
|
||||
while (iterator.HasCurrent())
|
||||
{
|
||||
vector.Append(iterator.Current());
|
||||
iterator.MoveNext();
|
||||
}
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
void InspectingDataSource::UnlistenToCollectionChanges()
|
||||
{
|
||||
if (m_notifyCollectionChanged)
|
||||
{
|
||||
m_notifyCollectionChanged.CollectionChanged(m_eventToken);
|
||||
}
|
||||
else if (m_observableVector)
|
||||
{
|
||||
m_observableVector.VectorChanged(m_eventToken);
|
||||
}
|
||||
else if (m_bindableObservableVector)
|
||||
{
|
||||
m_bindableObservableVector.VectorChanged(m_eventToken);
|
||||
}
|
||||
}
|
||||
|
||||
void InspectingDataSource::ListenToCollectionChanges()
|
||||
{
|
||||
assert(m_vector);
|
||||
if (auto incc = m_vector.try_as<winrt::INotifyCollectionChanged>())
|
||||
{
|
||||
m_eventToken = incc.CollectionChanged([this](
|
||||
const winrt::IInspectable& sender,
|
||||
const winrt::NotifyCollectionChangedEventArgs& e)
|
||||
{
|
||||
OnCollectionChanged(sender, e);
|
||||
});
|
||||
|
||||
m_notifyCollectionChanged = incc;
|
||||
}
|
||||
else if (auto observableVector = m_vector.try_as<winrt::IObservableVector<winrt::IInspectable>>())
|
||||
{
|
||||
m_eventToken = observableVector.VectorChanged([this](
|
||||
const winrt::IObservableVector<winrt::IInspectable>& sender,
|
||||
const winrt::IVectorChangedEventArgs& e)
|
||||
{
|
||||
OnVectorChanged(sender, e);
|
||||
});
|
||||
|
||||
m_observableVector = observableVector;
|
||||
}
|
||||
else if (auto bindableObservableVector = m_vector.try_as<winrt::IBindableObservableVector>())
|
||||
{
|
||||
m_eventToken = bindableObservableVector.VectorChanged([this](
|
||||
winrt::IBindableObservableVector const& vector,
|
||||
winrt::IInspectable const& e)
|
||||
{
|
||||
OnBindableVectorChanged(vector, e);
|
||||
});
|
||||
|
||||
m_bindableObservableVector = bindableObservableVector;
|
||||
}
|
||||
}
|
||||
|
||||
void InspectingDataSource::OnCollectionChanged(
|
||||
const winrt::IInspectable& /*sender*/,
|
||||
const winrt::NotifyCollectionChangedEventArgs& e)
|
||||
{
|
||||
DataSourceChangedAction action;
|
||||
|
||||
switch (e.Action())
|
||||
{
|
||||
case winrt::NotifyCollectionChangedAction::Add:
|
||||
action = DataSourceChangedAction::Insert;
|
||||
break;
|
||||
case winrt::NotifyCollectionChangedAction::Remove:
|
||||
action = DataSourceChangedAction::Remove;
|
||||
break;
|
||||
case winrt::NotifyCollectionChangedAction::Replace:
|
||||
action = DataSourceChangedAction::Replace;
|
||||
break;
|
||||
case winrt::NotifyCollectionChangedAction::Reset:
|
||||
action = DataSourceChangedAction::Reset;
|
||||
break;
|
||||
case winrt::NotifyCollectionChangedAction::Move:
|
||||
throw ref new Exception(E_FAIL, L"Move operations are not supported. Use a combination of Add and Remove instead.");
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
const auto& newItems = e.NewItems();
|
||||
const auto& oldItems = e.OldItems();
|
||||
|
||||
DataSourceChanged(this, DataSourceChangedEventArgs{
|
||||
action,
|
||||
e.OldStartingIndex(),
|
||||
oldItems ? static_cast<int>(oldItems.Size()) : 0,
|
||||
e.NewStartingIndex(),
|
||||
newItems ? static_cast<int>(newItems.Size()) : 0 });
|
||||
}
|
||||
|
||||
void InspectingDataSource::OnVectorChanged(
|
||||
const winrt::Collections::IObservableVector<winrt::IInspectable>& /*sender*/,
|
||||
const winrt::Collections::IVectorChangedEventArgs& e)
|
||||
{
|
||||
DataSourceChangedAction action;
|
||||
int oldStartingIndex = -1;
|
||||
int oldItemsCount = 0;
|
||||
int newStartingIndex = -1;
|
||||
int newItemsCount = 0;
|
||||
|
||||
// Note that the event args' Index property should NOT be accessed
|
||||
// in the Reset case, as the property accessor will throw an exception.
|
||||
switch (e.CollectionChange())
|
||||
{
|
||||
case winrt::CollectionChange::ItemInserted:
|
||||
action = DataSourceChangedAction::Insert;
|
||||
newStartingIndex = e.Index();
|
||||
newItemsCount = 1;
|
||||
break;
|
||||
case winrt::CollectionChange::ItemRemoved:
|
||||
action = DataSourceChangedAction::Remove;
|
||||
oldStartingIndex = e.Index();
|
||||
oldItemsCount = 1;
|
||||
break;
|
||||
case winrt::CollectionChange::ItemChanged:
|
||||
action = DataSourceChangedAction::Replace;
|
||||
oldStartingIndex = e.Index();
|
||||
oldItemsCount = 1;
|
||||
newStartingIndex = e.Index();
|
||||
newItemsCount = 1;
|
||||
break;
|
||||
case winrt::CollectionChange::Reset:
|
||||
action = DataSourceChangedAction::Reset;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
DataSourceChanged(this, DataSourceChangedEventArgs{
|
||||
action,
|
||||
oldStartingIndex,
|
||||
oldItemsCount,
|
||||
newStartingIndex,
|
||||
newItemsCount });
|
||||
}
|
||||
|
||||
void InspectingDataSource::OnBindableVectorChanged(
|
||||
winrt::IBindableObservableVector const& vector,
|
||||
winrt::IInspectable const& e)
|
||||
{
|
||||
OnVectorChanged(nullptr, e.as<winrt::IVectorChangedEventArgs>());
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace GraphControl
|
||||
{
|
||||
public enum class DataSourceChangedAction
|
||||
{
|
||||
Insert,
|
||||
Remove,
|
||||
Replace,
|
||||
Reset
|
||||
};
|
||||
|
||||
value struct DataSourceChangedEventArgs sealed
|
||||
{
|
||||
DataSourceChangedAction Action;
|
||||
int OldStartingIndex;
|
||||
int OldItemsCount;
|
||||
int NewStartingIndex;
|
||||
int NewItemsCount;
|
||||
};
|
||||
|
||||
ref class InspectingDataSource sealed
|
||||
{
|
||||
internal:
|
||||
InspectingDataSource(Platform::Object^ source);
|
||||
|
||||
event Windows::Foundation::TypedEventHandler<InspectingDataSource^, DataSourceChangedEventArgs>^ DataSourceChanged;
|
||||
|
||||
unsigned int GetSize();
|
||||
Platform::Object^ GetAt(unsigned int index);
|
||||
std::optional<unsigned int> IndexOf(Platform::Object^ value);
|
||||
|
||||
private:
|
||||
~InspectingDataSource();
|
||||
|
||||
static winrt::Windows::Foundation::Collections::IVector<winrt::Windows::Foundation::IInspectable>
|
||||
WrapIterable(const winrt::Windows::Foundation::Collections::IIterable<winrt::Windows::Foundation::IInspectable>& iterable);
|
||||
|
||||
void ListenToCollectionChanges();
|
||||
void UnlistenToCollectionChanges();
|
||||
|
||||
void OnCollectionChanged(
|
||||
const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Windows::UI::Xaml::Interop::NotifyCollectionChangedEventArgs& e);
|
||||
|
||||
void OnVectorChanged(
|
||||
const winrt::Windows::Foundation::Collections::IObservableVector<winrt::Windows::Foundation::IInspectable>& sender,
|
||||
const winrt::Windows::Foundation::Collections::IVectorChangedEventArgs& e);
|
||||
|
||||
void OnBindableVectorChanged(
|
||||
winrt::Windows::UI::Xaml::Interop::IBindableObservableVector const& vector,
|
||||
winrt::Windows::Foundation::IInspectable const& e);
|
||||
|
||||
private:
|
||||
winrt::Windows::Foundation::Collections::IVector<winrt::Windows::Foundation::IInspectable> m_vector;
|
||||
|
||||
winrt::Windows::UI::Xaml::Interop::INotifyCollectionChanged m_notifyCollectionChanged;
|
||||
winrt::Windows::Foundation::Collections::IObservableVector<winrt::Windows::Foundation::IInspectable> m_observableVector;
|
||||
winrt::Windows::UI::Xaml::Interop::IBindableObservableVector m_bindableObservableVector;
|
||||
winrt::event_token m_eventToken;
|
||||
};
|
||||
}
|
@ -307,7 +307,6 @@
|
||||
<ClInclude Include="Control\Equation.h" />
|
||||
<ClInclude Include="Control\EquationCollection.h" />
|
||||
<ClInclude Include="Control\Grapher.h" />
|
||||
<ClInclude Include="Control\InspectingDataSource.h" />
|
||||
<ClInclude Include="DirectX\ActiveTracingPointRenderer.h" />
|
||||
<ClInclude Include="DirectX\DeviceResources.h" />
|
||||
<ClInclude Include="DirectX\DirectXHelper.h" />
|
||||
@ -319,7 +318,6 @@
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Control\Equation.cpp" />
|
||||
<ClCompile Include="Control\Grapher.cpp" />
|
||||
<ClCompile Include="Control\InspectingDataSource.cpp" />
|
||||
<ClCompile Include="DirectX\ActiveTracingPointRenderer.cpp" />
|
||||
<ClCompile Include="DirectX\DeviceResources.cpp" />
|
||||
<ClCompile Include="DirectX\NearestPointRenderer.cpp" />
|
||||
|
@ -25,9 +25,6 @@
|
||||
<ClCompile Include="Control\Grapher.cpp">
|
||||
<Filter>Control</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Control\InspectingDataSource.cpp">
|
||||
<Filter>Control</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DirectX\NearestPointRenderer.cpp">
|
||||
<Filter>DirectX</Filter>
|
||||
</ClCompile>
|
||||
@ -56,9 +53,6 @@
|
||||
<ClInclude Include="Control\Grapher.h">
|
||||
<Filter>Control</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Control\InspectingDataSource.h">
|
||||
<Filter>Control</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DirectX\NearestPointRenderer.h">
|
||||
<Filter>DirectX</Filter>
|
||||
</ClInclude>
|
||||
|
Loading…
Reference in New Issue
Block a user