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:
parent
1b72ecb6b3
commit
28dbdb3d94
@ -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 });
|
||||||
});
|
});
|
||||||
|
@ -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:
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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"
|
||||||
@ -855,13 +855,13 @@
|
|||||||
<ResourceDictionary>
|
<ResourceDictionary>
|
||||||
<ResourceDictionary.ThemeDictionaries>
|
<ResourceDictionary.ThemeDictionaries>
|
||||||
<ResourceDictionary x:Key="Light">
|
<ResourceDictionary x:Key="Light">
|
||||||
<SolidColorBrush x:Key="DividerBrush" Color="#33000000" />
|
<SolidColorBrush x:Key="DividerBrush" Color="#33000000"/>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
<ResourceDictionary x:Key="Dark">
|
<ResourceDictionary x:Key="Dark">
|
||||||
<SolidColorBrush x:Key="DividerBrush" Color="#60FFFFFF"/>
|
<SolidColorBrush x:Key="DividerBrush" Color="#60FFFFFF"/>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
<ResourceDictionary x:Key="HighContrast">
|
<ResourceDictionary x:Key="HighContrast">
|
||||||
<SolidColorBrush x:Key="DividerBrush" Color="Transparent" />
|
<SolidColorBrush x:Key="DividerBrush" Color="Transparent"/>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</ResourceDictionary.ThemeDictionaries>
|
</ResourceDictionary.ThemeDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
@ -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>
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
@ -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>
|
||||||
|
@ -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>
|
26
src/GraphControl/Models/Variable.h
Normal file
26
src/GraphControl/Models/Variable.h
Normal 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 }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user