Persist variable settings after graph is plotted (#1055)

* Allow copying graph as image

* Persist variables

* Revert "Allow copying graph as image"

This reverts commit 4fc9d798bc5f3ff82efc4fb00140103213fb81e2.

* fix binding bug

* undo cert change

* fix animation

* remove extra lines

* remove overrides

* undo key comment
This commit is contained in:
Pepe Rivera 2020-03-17 11:27:00 -07:00 committed by GitHub
parent 1b72ecb6b3
commit 28dbdb3d94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 125 additions and 50 deletions

View File

@ -10,6 +10,7 @@ using namespace Platform::Collections;
using namespace Windows::Foundation; using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections; using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml::Data; using namespace Windows::UI::Xaml::Data;
using namespace GraphControl;
namespace CalculatorApp::ViewModel namespace CalculatorApp::ViewModel
{ {
@ -24,12 +25,12 @@ namespace CalculatorApp::ViewModel
{ {
} }
void GraphingCalculatorViewModel::UpdateVariables(IMap<String ^, double> ^ variables) void GraphingCalculatorViewModel::UpdateVariables(IMap<String ^, Variable ^> ^ variables)
{ {
Variables->Clear(); Variables->Clear();
for (auto var : variables) for (auto variablePair : variables)
{ {
auto variable = ref new VariableViewModel(var->Key, var->Value); auto variable = ref new VariableViewModel(variablePair->Key, variablePair->Value);
variable->VariableUpdated += ref new EventHandler<VariableChangedEventArgs>([this, variable](Object ^ sender, VariableChangedEventArgs e) { variable->VariableUpdated += ref new EventHandler<VariableChangedEventArgs>([this, variable](Object ^ sender, VariableChangedEventArgs e) {
VariableUpdated(variable, VariableChangedEventArgs{ e.variableName, e.newValue }); VariableUpdated(variable, VariableChangedEventArgs{ e.variableName, e.newValue });
}); });

View File

@ -24,7 +24,7 @@ namespace CalculatorApp::ViewModel
event Windows::Foundation::EventHandler<VariableChangedEventArgs> ^ VariableUpdated; event Windows::Foundation::EventHandler<VariableChangedEventArgs> ^ VariableUpdated;
void UpdateVariables(Windows::Foundation::Collections::IMap<Platform::String ^, double> ^ variables); void UpdateVariables(Windows::Foundation::Collections::IMap<Platform::String ^, GraphControl::Variable ^> ^ variables);
void SetSelectedEquation(EquationViewModel ^ equation); void SetSelectedEquation(EquationViewModel ^ equation);
private: private:

View File

@ -18,47 +18,89 @@ public
[Windows::UI::Xaml::Data::Bindable] public ref class VariableViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged [Windows::UI::Xaml::Data::Bindable] public ref class VariableViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
{ {
public: public:
VariableViewModel(Platform::String ^ name, double value) VariableViewModel(Platform::String ^ name, GraphControl::Variable ^ variable)
: m_Name(name) : m_Name(name)
, m_Value(value) , m_variable{ variable }
, m_SliderSettingsVisible(false) , m_SliderSettingsVisible(false)
, m_Min(0.0)
, m_Step(0.1)
, m_Max(2.0)
{ {
} }
OBSERVABLE_OBJECT(); OBSERVABLE_OBJECT();
OBSERVABLE_PROPERTY_R(Platform::String ^, Name); OBSERVABLE_PROPERTY_R(Platform::String ^, Name);
OBSERVABLE_PROPERTY_RW(double, Min);
OBSERVABLE_PROPERTY_RW(double, Step);
OBSERVABLE_PROPERTY_RW(double, Max);
OBSERVABLE_PROPERTY_RW(bool, SliderSettingsVisible); OBSERVABLE_PROPERTY_RW(bool, SliderSettingsVisible);
property double Min
{
double get()
{
return m_variable->Min;
}
void set(double value)
{
if (m_variable->Min != value)
{
m_variable->Min = value;
RaisePropertyChanged("Min");
}
}
}
property double Step
{
double get()
{
return m_variable->Step;
}
void set(double value)
{
if (m_variable->Step != value)
{
m_variable->Step = value;
RaisePropertyChanged("Step");
}
}
}
property double Max
{
double get()
{
return m_variable->Max;
}
void set(double value)
{
if (m_variable->Max != value)
{
m_variable->Max = value;
RaisePropertyChanged("Max");
}
}
}
event Windows::Foundation::EventHandler<VariableChangedEventArgs> ^ VariableUpdated; event Windows::Foundation::EventHandler<VariableChangedEventArgs> ^ VariableUpdated;
property double Value property double Value
{ {
double get() double get()
{ {
return m_Value; return m_variable->Value;
} }
void set(double value) void set(double value)
{ {
if (value < Min) if (value < m_variable->Min)
{ {
Min = value; m_variable->Min = value;
RaisePropertyChanged(L"Min"); RaisePropertyChanged(L"Min");
} }
else if (value > Max) else if (value > m_variable->Max)
{ {
Max = value; m_variable->Max = value;
RaisePropertyChanged(L"Max"); RaisePropertyChanged(L"Max");
} }
if (Value != value) if (m_variable->Value != value)
{ {
m_Value = value; m_variable->Value = value;
VariableUpdated(this, VariableChangedEventArgs{ Name, value }); VariableUpdated(this, VariableChangedEventArgs{ Name, value });
RaisePropertyChanged(L"Value"); RaisePropertyChanged(L"Value");
} }
@ -66,6 +108,6 @@ public
} }
private: private:
double m_Value; GraphControl::Variable ^ m_variable;
}; };
} }

View File

@ -132,11 +132,11 @@
Margin="8,0,8,-6" Margin="8,0,8,-6"
VerticalAlignment="Center" VerticalAlignment="Center"
DataContext="{x:Bind}" DataContext="{x:Bind}"
Maximum="{x:Bind Max, Mode=TwoWay}"
Minimum="{x:Bind Min, Mode=TwoWay}"
StepFrequency="{x:Bind Step, Mode=TwoWay}" StepFrequency="{x:Bind Step, Mode=TwoWay}"
ValueChanged="Slider_ValueChanged" ValueChanged="Slider_ValueChanged"
Value="{x:Bind Value, Mode=TwoWay}"/> Value="{x:Bind Value, Mode=TwoWay}"
Maximum="{x:Bind Max, Mode=TwoWay}"
Minimum="{x:Bind Min, Mode=TwoWay}"/>
<Grid Grid.Row="1" <Grid Grid.Row="1"
Padding="8,0,8,8" Padding="8,0,8,8"
@ -882,10 +882,11 @@
<Setter Property="Margin" Value="1,0,1,0"/> <Setter Property="Margin" Value="1,0,1,0"/>
</Style> </Style>
</ListView.ItemContainerStyle> </ListView.ItemContainerStyle>
<ListView.ItemContainerTransitions>
<TransitionCollection/>
</ListView.ItemContainerTransitions>
<ListView.Transitions> <ListView.Transitions>
<TransitionCollection> <TransitionCollection/>
<AddDeleteThemeTransition/>
</TransitionCollection>
</ListView.Transitions> </ListView.Transitions>
</ListView> </ListView>
</StackPanel> </StackPanel>

View File

@ -442,9 +442,9 @@ namespace GraphControl
{ {
critical_section::scoped_lock lock(m_renderMain->GetCriticalSection()); critical_section::scoped_lock lock(m_renderMain->GetCriticalSection());
for (auto variable : Variables) for (auto variablePair : Variables)
{ {
graph->SetArgValue(variable->Key->Data(), variable->Value); graph->SetArgValue(variablePair->Key->Data(), variablePair->Value->Value);
} }
} }
} }
@ -470,7 +470,7 @@ namespace GraphControl
void Grapher::UpdateVariables() void Grapher::UpdateVariables()
{ {
auto updatedVariables = ref new Map<String ^, double>(); auto updatedVariables = ref new Map<String ^, Variable ^>();
if (m_graph) if (m_graph)
{ {
@ -483,12 +483,19 @@ namespace GraphControl
auto key = ref new String(graphVar->GetVariableName().data()); auto key = ref new String(graphVar->GetVariableName().data());
double value = 1.0; double value = 1.0;
Variable ^ variable;
if (Variables->HasKey(key)) if (Variables->HasKey(key))
{ {
value = Variables->Lookup(key); variable = Variables->Lookup(key);
} }
updatedVariables->Insert(key, value); if (variable == nullptr)
{
variable = ref new Variable(1.0);
}
updatedVariables->Insert(key, variable);
} }
} }
} }
@ -504,17 +511,11 @@ namespace GraphControl
void Grapher::SetVariable(Platform::String ^ variableName, double newValue) void Grapher::SetVariable(Platform::String ^ variableName, double newValue)
{ {
if (Variables->HasKey(variableName)) if (!Variables->HasKey(variableName))
{ {
if (Variables->Lookup(variableName) == newValue) Variables->Insert(variableName, ref new Variable(newValue));
{
return;
} }
Variables->Remove(variableName);
}
Variables->Insert(variableName, newValue);
if (m_graph != nullptr && m_renderMain != nullptr) if (m_graph != nullptr && m_renderMain != nullptr)
{ {

View File

@ -4,9 +4,10 @@
#pragma once #pragma once
#include "DirectX/RenderMain.h" #include "DirectX/RenderMain.h"
#include "../Models/Equation.h" #include "Models/Equation.h"
#include "../Models/EquationCollection.h" #include "Models/EquationCollection.h"
#include "../Utils.h" #include "Models/Variable.h"
#include "Utils.h"
#include "IGraphAnalyzer.h" #include "IGraphAnalyzer.h"
#include "IMathSolver.h" #include "IMathSolver.h"
#include "Common.h" #include "Common.h"
@ -43,9 +44,9 @@ public
DEPENDENCY_PROPERTY_WITH_DEFAULT_AND_CALLBACK(bool, ForceProportionalAxes, true); DEPENDENCY_PROPERTY_WITH_DEFAULT_AND_CALLBACK(bool, ForceProportionalAxes, true);
DEPENDENCY_PROPERTY_WITH_DEFAULT_AND_CALLBACK(bool, UseCommaDecimalSeperator, false); DEPENDENCY_PROPERTY_WITH_DEFAULT_AND_CALLBACK(bool, UseCommaDecimalSeperator, false);
DEPENDENCY_PROPERTY_WITH_DEFAULT( DEPENDENCY_PROPERTY_WITH_DEFAULT(
SINGLE_ARG(Windows::Foundation::Collections::IObservableMap<Platform::String ^, double> ^), SINGLE_ARG(Windows::Foundation::Collections::IObservableMap<Platform::String ^, GraphControl::Variable ^> ^),
Variables, Variables,
SINGLE_ARG(ref new Platform::Collections::Map<Platform::String ^, double>())); SINGLE_ARG(ref new Platform::Collections::Map<Platform::String ^, GraphControl::Variable ^>()));
DEPENDENCY_PROPERTY_R_WITH_DEFAULT_AND_CALLBACK(GraphControl::EquationCollection ^, Equations, nullptr); DEPENDENCY_PROPERTY_R_WITH_DEFAULT_AND_CALLBACK(GraphControl::EquationCollection ^, Equations, nullptr);
DEPENDENCY_PROPERTY_WITH_DEFAULT_AND_CALLBACK(Windows::UI::Color, AxesColor, Windows::UI::Colors::Transparent); DEPENDENCY_PROPERTY_WITH_DEFAULT_AND_CALLBACK(Windows::UI::Color, AxesColor, Windows::UI::Colors::Transparent);
DEPENDENCY_PROPERTY_WITH_DEFAULT_AND_CALLBACK(Windows::UI::Color, GraphBackground, Windows::UI::Colors::Transparent); DEPENDENCY_PROPERTY_WITH_DEFAULT_AND_CALLBACK(Windows::UI::Color, GraphBackground, Windows::UI::Colors::Transparent);
@ -105,7 +106,7 @@ public
} }
} }
event Windows::Foundation::EventHandler<Windows::Foundation::Collections::IMap<Platform::String ^, double> ^> ^ VariablesUpdated; event Windows::Foundation::EventHandler<Windows::Foundation::Collections::IMap<Platform::String ^, Variable ^> ^> ^ VariablesUpdated;
void SetVariable(Platform::String ^ variableName, double newValue); void SetVariable(Platform::String ^ variableName, double newValue);
Platform::String ^ ConvertToLinear(Platform::String ^ mmlString); Platform::String ^ ConvertToLinear(Platform::String ^ mmlString);
Platform::String ^ FormatMathML(Platform::String ^ mmlString); Platform::String ^ FormatMathML(Platform::String ^ mmlString);

View File

@ -300,6 +300,7 @@
<ClInclude Include="Models\KeyGraphFeaturesInfo.h" /> <ClInclude Include="Models\KeyGraphFeaturesInfo.h" />
<ClInclude Include="pch.h" /> <ClInclude Include="pch.h" />
<ClInclude Include="Utils.h" /> <ClInclude Include="Utils.h" />
<ClInclude Include="Models\Variable.h" />
<ClInclude Include="winrtHeaders.h" /> <ClInclude Include="winrtHeaders.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -60,6 +60,9 @@
<ClInclude Include="Models\EquationCollection.h"> <ClInclude Include="Models\EquationCollection.h">
<Filter>Models</Filter> <Filter>Models</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Models\Variable.h">
<Filter>Models</Filter>
</ClInclude>
<ClInclude Include="Logger\TraceLogger.h" /> <ClInclude Include="Logger\TraceLogger.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -70,7 +73,5 @@
<ItemGroup> <ItemGroup>
<CopyFileToFolders Include="$(GraphingImplDll)" /> <CopyFileToFolders Include="$(GraphingImplDll)" />
<CopyFileToFolders Include="$(GraphingEngineDll)" /> <CopyFileToFolders Include="$(GraphingEngineDll)" />
<CopyFileToFolders Include="$(GraphingImplDll)" />
<CopyFileToFolders Include="$(GraphingEngineDll)" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -0,0 +1,26 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
#include "Utils.h"
namespace GraphControl
{
public
ref class Variable sealed
{
public:
PROPERTY_RW(double, Value);
PROPERTY_RW(double, Step);
PROPERTY_RW(double, Min);
PROPERTY_RW(double, Max);
Variable(double value)
: m_Value{ value }
, m_Step{ 0.1 }
, m_Min{ 0.0 }
, m_Max{ 2.0 }
{
}
};
}

View File

@ -19,7 +19,8 @@
"*:*, *", "*:*, *",
"PageSource, PageIndex, Offset, Color, TargetName, Property, Value, StartPoint, EndPoint", "PageSource, PageIndex, Offset, Color, TargetName, Property, Value, StartPoint, EndPoint",
"mc:Ignorable, d:IsDataSource, d:LayoutOverrides, d:IsStaticText", "mc:Ignorable, d:IsDataSource, d:LayoutOverrides, d:IsStaticText",
"IsEnabled, x:Load, Load" "IsEnabled, x:Load, Load",
"Value, Maximum, Minimum"
], ],
"OrderAttributesByName": true, "OrderAttributesByName": true,
"PutEndingBracketOnNewLine": false, "PutEndingBracketOnNewLine": false,