diff --git a/src/CalcViewModel/CalcViewModel.vcxproj b/src/CalcViewModel/CalcViewModel.vcxproj index f506dff..e1cc190 100644 --- a/src/CalcViewModel/CalcViewModel.vcxproj +++ b/src/CalcViewModel/CalcViewModel.vcxproj @@ -413,6 +413,9 @@ {311e866d-8b93-4609-a691-265941fee101} + + {e727a92b-f149-492c-8117-c039a298719b} + diff --git a/src/CalcViewModel/GraphingCalculator/EquationViewModel.cpp b/src/CalcViewModel/GraphingCalculator/EquationViewModel.cpp index ae9b63f..f52302f 100644 --- a/src/CalcViewModel/GraphingCalculator/EquationViewModel.cpp +++ b/src/CalcViewModel/GraphingCalculator/EquationViewModel.cpp @@ -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() } - , m_Maxima{ ref new Vector() } - , m_InflectionPoints{ ref new Vector() } - , m_Monotonicity{ ref new Map() } - , m_VerticalAsymptotes{ ref new Vector() } - , m_HorizontalAsymptotes{ ref new Vector() } - , m_ObliqueAsymptotes{ ref new Vector() } - , m_TooComplexFeatures{ -1 } - , m_AnalysisError{ 0 } - , m_AnalysisErrorVisible{ false } + EquationViewModel::EquationViewModel(GraphControl::Equation ^ equation) + : m_AnalysisErrorVisible{ false } , m_KeyGraphFeaturesItems{ ref new Vector() } , 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(AnalysisErrorType::AnalysisCouldNotBePerformed)) { - AnalysisErrorVisible = true; - if (AnalysisError == static_cast(AnalysisErrorType::AnalysisCouldNotBePerformed)) - { - AnalysisErrorString = m_resourceLoader->GetString(L"KGFAnalysisCouldNotBePerformed"); - } - else if (AnalysisError == static_cast(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(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 ^ expressionVector, String ^ errorString) + void EquationViewModel::AddKeyGraphFeature(String ^ title, IVector ^ 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()); } diff --git a/src/CalcViewModel/GraphingCalculator/EquationViewModel.h b/src/CalcViewModel/GraphingCalculator/EquationViewModel.h index 8f7a0db..82c3144 100644 --- a/src/CalcViewModel/GraphingCalculator/EquationViewModel.h +++ b/src/CalcViewModel/GraphingCalculator/EquationViewModel.h @@ -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 ^, Minima); - OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IObservableVector ^, Maxima); - OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IObservableVector ^, InflectionPoints); - OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IObservableVector ^, VerticalAsymptotes); - OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IObservableVector ^, HorizontalAsymptotes); - OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IObservableVector ^, 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 ^, KeyGraphFeaturesItems) - - property Windows::Foundation::Collections::IObservableMap ^ Monotonicity + property Platform::String ^ Expression { - Windows::Foundation::Collections::IObservableMap ^ get() + Platform::String ^ get() { - return m_Monotonicity; + return GraphEquation->Expression; } - void set(Windows::Foundation::Collections::IObservableMap ^ 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 ^, 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 ^ expressionVector, + void AddKeyGraphFeature(Platform::String ^ title, Platform::String ^ expression, Platform::String ^ errorString); + void AddKeyGraphFeature( + Platform::String ^ title, + Windows::Foundation::Collections::IVector ^ expressionVector, Platform::String ^ errorString); - void SetMonotoncityStringProperty(); - void SetTooComplexFeaturesErrorProperty(); - void OnIsAnalysisUpdatedChanged(); + void AddParityKeyGraphFeature(); + void AddPeriodicityKeyGraphFeature(); + void AddMonotoncityKeyGraphFeature(); + void AddTooComplexKeyGraphFeature(); Windows::Foundation::Collections::IObservableMap ^ m_Monotonicity; Windows::ApplicationModel::Resources::ResourceLoader ^ m_resourceLoader; diff --git a/src/Calculator/Views/GraphingCalculator/EquationInputArea.xaml.cpp b/src/Calculator/Views/GraphingCalculator/EquationInputArea.xaml.cpp index 4e351ab..4b0fa13 100644 --- a/src/Calculator/Views/GraphingCalculator/EquationInputArea.xaml.cpp +++ b/src/Calculator/Views/GraphingCalculator/EquationInputArea.xaml.cpp @@ -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(sender); auto eq = static_cast(tb->DataContext); EquationVM = eq; - KeyGraphFeaturesVisibilityChanged(this, ref new RoutedEventArgs()); + KeyGraphFeaturesRequested(EquationVM, ref new RoutedEventArgs()); } void EquationInputArea::EquationTextBox_EquationButtonClicked(Object ^ sender, RoutedEventArgs ^ e) diff --git a/src/Calculator/Views/GraphingCalculator/EquationInputArea.xaml.h b/src/Calculator/Views/GraphingCalculator/EquationInputArea.xaml.h index 7f900ae..9648547 100644 --- a/src/Calculator/Views/GraphingCalculator/EquationInputArea.xaml.h +++ b/src/Calculator/Views/GraphingCalculator/EquationInputArea.xaml.h @@ -23,7 +23,7 @@ namespace CalculatorApp OBSERVABLE_PROPERTY_RW_ALWAYS_NOTIFY(ViewModel::EquationViewModel ^, EquationVM); OBSERVABLE_PROPERTY_RW(Windows::Foundation::Collections::IObservableVector ^, AvailableColors); - event Windows::UI::Xaml::RoutedEventHandler ^ KeyGraphFeaturesVisibilityChanged; + event Windows::UI::Xaml::RoutedEventHandler ^ KeyGraphFeaturesRequested; private: void OnPropertyChanged(Platform::String^ propertyName); diff --git a/src/Calculator/Views/GraphingCalculator/GraphingCalculator.xaml b/src/Calculator/Views/GraphingCalculator/GraphingCalculator.xaml index 6aed74b..3a83f90 100644 --- a/src/Calculator/Views/GraphingCalculator/GraphingCalculator.xaml +++ b/src/Calculator/Views/GraphingCalculator/GraphingCalculator.xaml @@ -182,7 +182,6 @@ Grid.Column="0"> - - - - - - + KeyGraphFeaturesRequested="OnEquationKeyGraphFeaturesRequested"/> Equations->VectorChanged -= m_vectorChangedToken; + m_vectorChangedToken.Value = 0; + } + + if (m_variableUpdatedToken.Value != 0) + { + ViewModel->VariableUpdated -= m_variableUpdatedToken; + m_variableUpdatedToken.Value = 0; + } + } + ViewModel = dynamic_cast(args->NewValue); - ViewModel->VariableUpdated += ref new EventHandler(this, &CalculatorApp::GraphingCalculator::OnVariableChanged); + m_vectorChangedToken = ViewModel->Equations->VectorChanged += + ref new VectorChangedEventHandler(this, &GraphingCalculator::OnEquationsVectorChanged); + + m_variableUpdatedToken = ViewModel->VariableUpdated += + ref new EventHandler(this, &CalculatorApp::GraphingCalculator::OnVariableChanged); +} + +void GraphingCalculator::OnEquationsVectorChanged(IObservableVector ^ 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(sender); + GraphingControl->AnalyzeEquation(equationViewModel->GraphEquation); + equationViewModel->PopulateKeyGraphFeatures(); IsKeyGraphFeaturesVisible = true; } diff --git a/src/Calculator/Views/GraphingCalculator/GraphingCalculator.xaml.h b/src/Calculator/Views/GraphingCalculator/GraphingCalculator.xaml.h index 45fdf2a..004f36f 100644 --- a/src/Calculator/Views/GraphingCalculator/GraphingCalculator.xaml.h +++ b/src/Calculator/Views/GraphingCalculator/GraphingCalculator.xaml.h @@ -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 ^ 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; }; diff --git a/src/GraphControl/Control/Equation.cpp b/src/GraphControl/Control/Equation.cpp index 2825290..fc3af48 100644 --- a/src/GraphControl/Control/Equation.cpp +++ b/src/GraphControl/Control/Equation.cpp @@ -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; diff --git a/src/GraphControl/Control/Equation.h b/src/GraphControl/Control/Equation.h index b575a2f..7eeee60 100644 --- a/src/GraphControl/Control/Equation.h +++ b/src/GraphControl/Control/Equation.h @@ -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(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; diff --git a/src/GraphControl/Control/Grapher.cpp b/src/GraphControl/Control/Grapher.cpp index e30108b..c93ce2d 100644 --- a/src/GraphControl/Control/Grapher.cpp +++ b/src/GraphControl/Control/Grapher.cpp @@ -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(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(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(EquationTemplate->LoadContent()); - eq->DataContext = m_dataSource->GetAt(i); - - Equations->Append(eq); - } - } - } - void Grapher::OnEquationsChanged(DependencyPropertyChangedEventArgs ^ args) { if (auto older = static_cast(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(args->NewValue)) { - m_tokenEquationsChanged = newer->VectorChanged += ref new VectorChangedEventHandler(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 ^ 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 ^ Grapher::ConvertWStringVector(vector inVector) { Vector ^ outVector = ref new Vector(); diff --git a/src/GraphControl/Control/Grapher.h b/src/GraphControl/Control/Grapher.h index 5c8d797..9f82bdd 100644 --- a/src/GraphControl/Control/Grapher.h +++ b/src/GraphControl/Control/Grapher.h @@ -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(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 ^> ^ 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 ^ sender, - Windows::Foundation::Collections::IVectorChangedEventArgs ^ event); void OnEquationChanged(); void OnEquationStyleChanged(); @@ -231,16 +180,11 @@ public void SetGraphArgs(); std::shared_ptr 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; diff --git a/src/GraphControl/Control/InspectingDataSource.cpp b/src/GraphControl/Control/InspectingDataSource.cpp deleted file mode 100644 index abccdf8..0000000 --- a/src/GraphControl/Control/InspectingDataSource.cpp +++ /dev/null @@ -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(source); - if (auto vector = inspectable.try_as>()) - { - m_vector = vector; - ListenToCollectionChanges(); - } - else if (auto bindableVector = inspectable.try_as()) - { - // The bindable interop interface are abi compatible with the corresponding - // WinRT interfaces. - - m_vector = reinterpret_cast&>(bindableVector); - ListenToCollectionChanges(); - } - else if (auto iterable = inspectable.try_as>()) - { - m_vector = WrapIterable(iterable); - } - else if (auto bindableIterable = inspectable.try_as()) - { - m_vector = WrapIterable(reinterpret_cast &>(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(m_vector.GetAt(index)); - } - - optional InspectingDataSource::IndexOf(Object^ value) - { - if ((m_vector != nullptr) && value) - { - uint32_t v; - auto inspectable = from_cx(value); - if (m_vector.IndexOf(inspectable, v)) - { - return v; - } - } - return nullopt; - } - - winrt::IVector InspectingDataSource::WrapIterable(const winrt::IIterable& iterable) - { - auto vector = winrt::single_threaded_vector(); - 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()) - { - 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>()) - { - m_eventToken = observableVector.VectorChanged([this]( - const winrt::IObservableVector& sender, - const winrt::IVectorChangedEventArgs& e) - { - OnVectorChanged(sender, e); - }); - - m_observableVector = observableVector; - } - else if (auto bindableObservableVector = m_vector.try_as()) - { - 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(oldItems.Size()) : 0, - e.NewStartingIndex(), - newItems ? static_cast(newItems.Size()) : 0 }); - } - - void InspectingDataSource::OnVectorChanged( - const winrt::Collections::IObservableVector& /*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()); - } -} diff --git a/src/GraphControl/Control/InspectingDataSource.h b/src/GraphControl/Control/InspectingDataSource.h deleted file mode 100644 index b6cead3..0000000 --- a/src/GraphControl/Control/InspectingDataSource.h +++ /dev/null @@ -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^ DataSourceChanged; - - unsigned int GetSize(); - Platform::Object^ GetAt(unsigned int index); - std::optional IndexOf(Platform::Object^ value); - - private: - ~InspectingDataSource(); - - static winrt::Windows::Foundation::Collections::IVector - WrapIterable(const winrt::Windows::Foundation::Collections::IIterable& 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& 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 m_vector; - - winrt::Windows::UI::Xaml::Interop::INotifyCollectionChanged m_notifyCollectionChanged; - winrt::Windows::Foundation::Collections::IObservableVector m_observableVector; - winrt::Windows::UI::Xaml::Interop::IBindableObservableVector m_bindableObservableVector; - winrt::event_token m_eventToken; - }; -} diff --git a/src/GraphControl/GraphControl.vcxproj b/src/GraphControl/GraphControl.vcxproj index d9c0042..1392681 100644 --- a/src/GraphControl/GraphControl.vcxproj +++ b/src/GraphControl/GraphControl.vcxproj @@ -307,7 +307,6 @@ - @@ -319,7 +318,6 @@ - diff --git a/src/GraphControl/GraphControl.vcxproj.filters b/src/GraphControl/GraphControl.vcxproj.filters index 00b889e..d62288f 100644 --- a/src/GraphControl/GraphControl.vcxproj.filters +++ b/src/GraphControl/GraphControl.vcxproj.filters @@ -25,9 +25,6 @@ Control - - Control - DirectX @@ -56,9 +53,6 @@ Control - - Control - DirectX