Passive & Active tracing (#638)
* Plumebd with data transfer * Getting mainpage to talk to getbitmap. moving share callbacks from mainpage to graphingcalculator * Trying to get bitmap from renderer. * work * Share worked * cleanups * Cleanups progressing * Share working, need loc for title string and user notification incase of a failure. Then add the equations key. * More cleanup, now using share icon image and resources for strings. Still need to do the graph equation key. * Change share to html based start. * Key working, with UL but going to try changing to table. * Fix a html formating error, generating a new UL for each equation. * Switched over to a table for equation key and have color block formating * Updates from PR feedback, using Graphing::IBitmap abstraction. * Update src/Calculator/Views/GraphingCalculator/GraphingCalculator.xaml.h Fixed Co-Authored-By: Pepe Rivera <joseartrivera@gmail.com> * PR Updates. * Add variables to the graph key. * eod * Passive graph value tracing working. * Basic active tracing cursor working. * Move active tracing from graphingcalculator to grapher to save some hops. Also block tracking of the active tracing key's when in the EquationTextBox. * Active tracing working, need to put button on screen for activation. * Added active tracing control button (placeholder image) * Eod * Popup trace value now tracks the highlighted point. * Popup skined * PR Updates. * Update certificate thumbnail so VS2019 doesn't have a build error. * PR comments in process. * PR Updates * PR Updates, change tracing value to use tooltip static resource so we automatically change depending on system values. And changed text formatting of the value to be generic (x,y) value. * PR updates, changed how we detect who has focus so we don't eat keys when not in active tracing. * Additional filtering for the Key Up/Down in the grapher.
This commit is contained in:
parent
7864fe6413
commit
18f80a89db
@ -9,7 +9,8 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="using:CalculatorApp.ViewModel"
|
||||
DataContextChanged="GraphingCalculator_DataContextChanged"
|
||||
mc:Ignorable="d">
|
||||
mc:Ignorable="d"
|
||||
>
|
||||
|
||||
<UserControl.Resources>
|
||||
<Style x:Key="ZoomRepeatButtonStyle" TargetType="RepeatButton">
|
||||
@ -32,7 +33,7 @@
|
||||
<converters:BooleanToVisibilityNegationConverter x:Name="BooleanToVisibilityNegationConverter"/>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid x:Name="RootGrid">
|
||||
<Grid x:Name="RootGrid" >
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition x:Name="RowHamburger" Height="{StaticResource HamburgerHeightGridLength}"/>
|
||||
<RowDefinition/>
|
||||
@ -46,21 +47,45 @@
|
||||
<Grid x:Name="LeftGrid"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0">
|
||||
<graphControl:Grapher Name="GraphingControl"
|
||||
Margin="4,7,4,4"
|
||||
<Grid Grid.Row="0" Margin="4,7,4,4">
|
||||
<graphControl:Grapher Name="GraphingControl"
|
||||
EquationsSource="{x:Bind ViewModel.Equations, Mode=OneWay}"
|
||||
ForceProportionalAxes="True"
|
||||
UseSystemFocusVisuals="True"
|
||||
VariablesUpdated="GraphVariablesUpdated">
|
||||
<graphControl:Grapher.Background>
|
||||
<SolidColorBrush Color="White"/>
|
||||
</graphControl:Grapher.Background>
|
||||
<graphControl:Grapher.EquationTemplate>
|
||||
<DataTemplate x:DataType="vm:EquationViewModel">
|
||||
<graphControl:Equation Expression="{x:Bind Expression, Mode=OneWay}" LineColor="{x:Bind LineColor, Mode=OneWay}"/>
|
||||
</DataTemplate>
|
||||
</graphControl:Grapher.EquationTemplate>
|
||||
</graphControl:Grapher>
|
||||
VariablesUpdated="GraphVariablesUpdated"
|
||||
LostFocus="OnGraphLostFocus"
|
||||
LosingFocus="OnLoosingFocus">
|
||||
<graphControl:Grapher.Background>
|
||||
<SolidColorBrush Color="White"/>
|
||||
</graphControl:Grapher.Background>
|
||||
<graphControl:Grapher.EquationTemplate>
|
||||
<DataTemplate x:DataType="vm:EquationViewModel">
|
||||
<graphControl:Equation Expression="{x:Bind Expression, Mode=OneWay}" LineColor="{x:Bind LineColor, Mode=OneWay}"/>
|
||||
</DataTemplate>
|
||||
</graphControl:Grapher.EquationTemplate>
|
||||
|
||||
</graphControl:Grapher>
|
||||
|
||||
<StackPanel Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,0,10,10">
|
||||
<Button x:Name="ActiveTracing" Click="OnActiveTracingClick" MinWidth="40" MinHeight="40" Margin="0,0,10,0">
|
||||
<FontIcon FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph=""/>
|
||||
</Button>
|
||||
<Button x:Name="Share" Click="OnShareClick" MinWidth="40" MinHeight="40">
|
||||
<FontIcon FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph=""/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
<Popup x:Name="TraceValuePopup" Grid.Row="0" RenderTransformOrigin="0,1">
|
||||
<Popup.RenderTransform>
|
||||
<TranslateTransform x:Name="TraceValuePopupTransform" X="50" Y="150"/>
|
||||
</Popup.RenderTransform>
|
||||
<Grid Background="{StaticResource ToolTipBackground}" BorderBrush="{StaticResource ToolTipBorderBrush}" BorderThickness="3,3,3,3">
|
||||
<TextBlock x:Name="TraceValue" Text="x=0,y=0" Margin="5,5,5,5" Foreground="{StaticResource ToolTipForeground}"/>
|
||||
</Grid>
|
||||
</Popup>
|
||||
|
||||
</Grid>
|
||||
|
||||
|
||||
<!-- Temporary button until the final UI is created -->
|
||||
<Button Margin="12,0,0,12"
|
||||
@ -372,9 +397,6 @@
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="1*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Button x:Name="Share" Click="OnShareClick">
|
||||
<FontIcon FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph=""/>
|
||||
</Button>
|
||||
<local:EquationInputArea Grid.Row="1"
|
||||
Margin="0,8,0,0"
|
||||
Equations="{x:Bind ViewModel.Equations}"/>
|
||||
|
@ -22,6 +22,7 @@ using namespace Windows::Foundation::Collections;
|
||||
using namespace Windows::Storage::Streams;
|
||||
using namespace Windows::System;
|
||||
using namespace Windows::UI::Core;
|
||||
using namespace Windows::UI::Input;
|
||||
using namespace Windows::UI::Xaml;
|
||||
using namespace Windows::UI::Xaml::Data;
|
||||
using namespace Windows::UI::Xaml::Controls;
|
||||
@ -30,35 +31,61 @@ using namespace Windows::UI::Xaml::Media;
|
||||
using namespace Windows::UI::Xaml::Media::Imaging;
|
||||
using namespace Windows::UI::Popups;
|
||||
|
||||
|
||||
constexpr auto sc_ViewModelPropertyName = L"ViewModel";
|
||||
|
||||
|
||||
GraphingCalculator::GraphingCalculator()
|
||||
{
|
||||
Equation::RegisterDependencyProperties();
|
||||
Grapher::RegisterDependencyProperties();
|
||||
InitializeComponent();
|
||||
|
||||
DataTransferManager^ dataTransferManager = DataTransferManager::GetForCurrentView();
|
||||
DataTransferManager ^ dataTransferManager = DataTransferManager::GetForCurrentView();
|
||||
|
||||
// Register the current control as a share source.
|
||||
m_dataRequestedToken = dataTransferManager->DataRequested += ref new TypedEventHandler<DataTransferManager^, DataRequestedEventArgs^>(this, &GraphingCalculator::OnDataRequested);
|
||||
m_dataRequestedToken = dataTransferManager->DataRequested +=
|
||||
ref new TypedEventHandler<DataTransferManager ^, DataRequestedEventArgs ^>(this, &GraphingCalculator::OnDataRequested);
|
||||
|
||||
// Request notifications when we should be showing the trace values
|
||||
GraphingControl->TracingChangedEvent += ref new TracingChangedEventHandler(this, &GraphingCalculator::OnShowTracePopupChanged);
|
||||
|
||||
// And when the actual trace value changes
|
||||
GraphingControl->TracingValueChangedEvent += ref new TracingValueChangedEventHandler(this, &GraphingCalculator::OnTracePointChanged);
|
||||
}
|
||||
|
||||
void GraphingCalculator::GraphingCalculator_DataContextChanged(FrameworkElement^ sender, DataContextChangedEventArgs^ args)
|
||||
void GraphingCalculator::OnShowTracePopupChanged(bool newValue)
|
||||
{
|
||||
ViewModel = dynamic_cast<GraphingCalculatorViewModel^>(args->NewValue);
|
||||
if (TraceValuePopup->IsOpen != newValue)
|
||||
{
|
||||
TraceValuePopup->IsOpen = newValue;
|
||||
if (TraceValuePopup->IsOpen)
|
||||
{
|
||||
// Set the keyboard focus to the graph control so we can use the arrow keys safely.
|
||||
GraphingControl->Focus(::FocusState::Programmatic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GraphingCalculator::GraphingCalculator_DataContextChanged(FrameworkElement ^ sender, DataContextChangedEventArgs ^ args)
|
||||
{
|
||||
ViewModel = dynamic_cast<GraphingCalculatorViewModel ^>(args->NewValue);
|
||||
|
||||
ViewModel->VariableUpdated += ref new EventHandler<VariableChangedEventArgs>(this, &CalculatorApp::GraphingCalculator::OnVariableChanged);
|
||||
}
|
||||
|
||||
GraphingCalculatorViewModel^ GraphingCalculator::ViewModel::get()
|
||||
void GraphingCalculator::OnTracePointChanged(Windows::Foundation::Point newPoint)
|
||||
{
|
||||
TraceValuePopupTransform->X = (int)GraphingControl->TraceLocation.X + 15;
|
||||
TraceValuePopupTransform->Y = (int)GraphingControl->TraceLocation.Y - 30;
|
||||
|
||||
TraceValue->Text = "(" + newPoint.X.ToString() + ", " + newPoint.Y.ToString() + ")";
|
||||
}
|
||||
|
||||
GraphingCalculatorViewModel ^ GraphingCalculator::ViewModel::get()
|
||||
{
|
||||
return m_viewModel;
|
||||
}
|
||||
|
||||
void GraphingCalculator::ViewModel::set(GraphingCalculatorViewModel^ vm)
|
||||
void GraphingCalculator::ViewModel::set(GraphingCalculatorViewModel ^ vm)
|
||||
{
|
||||
if (m_viewModel != vm)
|
||||
{
|
||||
@ -67,7 +94,7 @@ void GraphingCalculator::ViewModel::set(GraphingCalculatorViewModel^ vm)
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorApp::GraphingCalculator::OnShareClick(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
|
||||
void CalculatorApp::GraphingCalculator::OnShareClick(Platform::Object ^ sender, Windows::UI::Xaml::RoutedEventArgs ^ e)
|
||||
{
|
||||
// Ask the OS to start a share action.
|
||||
DataTransferManager::ShowShareUI();
|
||||
@ -75,7 +102,7 @@ void CalculatorApp::GraphingCalculator::OnShareClick(Platform::Object^ sender, W
|
||||
|
||||
// When share is invoked (by the user or programmatically) the event handler we registered will be called to populate the data package with the
|
||||
// data to be shared. We will request the current graph image from the grapher as a stream that will pass to the share request.
|
||||
void GraphingCalculator::OnDataRequested(DataTransferManager^ sender, DataRequestedEventArgs^ args)
|
||||
void GraphingCalculator::OnDataRequested(DataTransferManager ^ sender, DataRequestedEventArgs ^ args)
|
||||
{
|
||||
auto resourceLoader = Windows::ApplicationModel::Resources::ResourceLoader::GetForCurrentView();
|
||||
try
|
||||
@ -142,11 +169,10 @@ void GraphingCalculator::OnDataRequested(DataTransferManager^ sender, DataReques
|
||||
}
|
||||
rawHtml += L"</table></p>";
|
||||
|
||||
|
||||
// Shortcut to the request data
|
||||
auto requestData = args->Request->Data;
|
||||
|
||||
DataPackage^ dataPackage = ref new DataPackage();
|
||||
DataPackage ^ dataPackage = ref new DataPackage();
|
||||
auto html = HtmlFormatHelper::CreateHtmlFormat(ref new String(rawHtml.c_str()));
|
||||
|
||||
auto titleString = resourceLoader->GetString(L"ShareActionTitle");
|
||||
@ -164,7 +190,7 @@ void GraphingCalculator::OnDataRequested(DataTransferManager^ sender, DataReques
|
||||
// And the bitmap (in case the share target can't handle HTML)
|
||||
requestData->SetBitmap(bitmapStream);
|
||||
}
|
||||
catch(Exception ^ ex)
|
||||
catch (Exception ^ ex)
|
||||
{
|
||||
TraceLogger::GetInstance().LogPlatformException(ViewMode::Graphing, __FUNCTIONW__, ex);
|
||||
|
||||
@ -179,20 +205,19 @@ void GraphingCalculator::OnDataRequested(DataTransferManager^ sender, DataReques
|
||||
}
|
||||
}
|
||||
|
||||
void GraphingCalculator::GraphVariablesUpdated(Object^, Object^)
|
||||
void GraphingCalculator::GraphVariablesUpdated(Object ^, Object ^)
|
||||
{
|
||||
m_viewModel->UpdateVariables(GraphingControl->Variables);
|
||||
}
|
||||
|
||||
void GraphingCalculator::OnVariableChanged(Platform::Object^ sender, VariableChangedEventArgs args)
|
||||
void GraphingCalculator::OnVariableChanged(Platform::Object ^ sender, VariableChangedEventArgs args)
|
||||
{
|
||||
GraphingControl->SetVariable(args.variableName, args.newValue);
|
||||
}
|
||||
|
||||
|
||||
void GraphingCalculator::SubmitTextbox(TextBox^ sender)
|
||||
void GraphingCalculator::SubmitTextbox(TextBox ^ sender)
|
||||
{
|
||||
auto variableViewModel = static_cast<VariableViewModel^>(sender->DataContext);
|
||||
auto variableViewModel = static_cast<VariableViewModel ^>(sender->DataContext);
|
||||
|
||||
if (sender->Name == "ValueTextBox")
|
||||
{
|
||||
@ -212,13 +237,12 @@ void GraphingCalculator::SubmitTextbox(TextBox^ sender)
|
||||
}
|
||||
}
|
||||
|
||||
void GraphingCalculator::TextBoxLosingFocus(TextBox^ sender, LosingFocusEventArgs^)
|
||||
void GraphingCalculator::TextBoxLosingFocus(TextBox ^ sender, LosingFocusEventArgs ^)
|
||||
{
|
||||
SubmitTextbox(sender);
|
||||
}
|
||||
|
||||
|
||||
void GraphingCalculator::TextBoxKeyDown(TextBox^ sender, KeyRoutedEventArgs^ e)
|
||||
void GraphingCalculator::TextBoxKeyDown(TextBox ^ sender, KeyRoutedEventArgs ^ e)
|
||||
{
|
||||
if (e->Key == ::VirtualKey::Enter)
|
||||
{
|
||||
@ -226,7 +250,7 @@ void GraphingCalculator::TextBoxKeyDown(TextBox^ sender, KeyRoutedEventArgs^ e)
|
||||
}
|
||||
}
|
||||
|
||||
double GraphingCalculator::validateDouble(String^ value, double defaultValue)
|
||||
double GraphingCalculator::validateDouble(String ^ value, double defaultValue)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -238,7 +262,7 @@ double GraphingCalculator::validateDouble(String^ value, double defaultValue)
|
||||
}
|
||||
}
|
||||
|
||||
void GraphingCalculator::TextBoxGotFocus(TextBox^ sender, RoutedEventArgs^ e)
|
||||
void GraphingCalculator::TextBoxGotFocus(TextBox ^ sender, RoutedEventArgs ^ e)
|
||||
{
|
||||
sender->SelectAll();
|
||||
}
|
||||
@ -257,3 +281,30 @@ void GraphingCalculator::OnZoomResetCommand(Object ^ /* parameter */)
|
||||
{
|
||||
GraphingControl->ResetGrid();
|
||||
}
|
||||
|
||||
void GraphingCalculator::OnActiveTracingClick(Platform::Object ^ sender, Windows::UI::Xaml::RoutedEventArgs ^ e)
|
||||
{
|
||||
GraphingControl->ActiveTracing = !GraphingControl->ActiveTracing;
|
||||
}
|
||||
|
||||
void CalculatorApp::GraphingCalculator::OnGraphLostFocus(Platform::Object ^ sender, Windows::UI::Xaml::RoutedEventArgs ^ e)
|
||||
{
|
||||
// If the graph is losing focus while we are in active tracing we need to turn it off so we don't try to eat keys in other controls.
|
||||
if (GraphingControl->ActiveTracing)
|
||||
{
|
||||
GraphingControl->ActiveTracing = false;
|
||||
OnShowTracePopupChanged(false);
|
||||
}
|
||||
}
|
||||
|
||||
void CalculatorApp::GraphingCalculator::OnLoosingFocus(Windows::UI::Xaml::UIElement ^ sender, Windows::UI::Xaml::Input::LosingFocusEventArgs ^ args)
|
||||
{
|
||||
FrameworkElement ^ newFocusElement = (FrameworkElement ^) args->NewFocusedElement;
|
||||
if (newFocusElement == nullptr || newFocusElement->Name == nullptr)
|
||||
{
|
||||
// Because clicking on the swap chain panel will try to move focus to a control that can't actually take focus
|
||||
// we will get a null destination. So we are going to try and cancel that request.
|
||||
// If the destination is not in our application we will also get a null destination but the cancel will fail so it doesn't hurt to try.
|
||||
args->TryCancel();
|
||||
}
|
||||
}
|
||||
|
@ -45,13 +45,18 @@ namespace CalculatorApp
|
||||
|
||||
void OnShareClick(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
|
||||
void OnShowTracePopupChanged(bool newValue);
|
||||
void OnTracePointChanged(Windows::Foundation::Point newPoint);
|
||||
|
||||
|
||||
private:
|
||||
Windows::Foundation::EventRegistrationToken m_dataRequestedToken;
|
||||
|
||||
void OnDataRequested(Windows::ApplicationModel::DataTransfer::DataTransferManager^ sender, Windows::ApplicationModel::DataTransfer::DataRequestedEventArgs^ e);
|
||||
void CommandInvokedHandler(Windows::UI::Popups::IUICommand^ command);
|
||||
|
||||
void TextBoxGotFocus(Windows::UI::Xaml::Controls::TextBox^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
void OnActiveTracingClick(Platform::Object ^ sender, Windows::UI::Xaml::RoutedEventArgs ^ e);
|
||||
void OnGraphLostFocus(Platform::Object ^ sender, Windows::UI::Xaml::RoutedEventArgs ^ e);
|
||||
void OnLoosingFocus(Windows::UI::Xaml::UIElement ^ sender, Windows::UI::Xaml::Input::LosingFocusEventArgs ^ args);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -130,6 +130,10 @@
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros">
|
||||
<PackageCertificateKeyFile>CalculatorUnitTests_TemporaryKey.pfx</PackageCertificateKeyFile>
|
||||
<PackageCertificateThumbprint>BE776C83699DBCE4969DE9EE730AEAF66C5D5182</PackageCertificateThumbprint>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<ClCompile>
|
||||
<AdditionalOptions>/bigobj /await /std:c++17 /permissive- /Zc:twoPhase- /utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
|
@ -13,6 +13,7 @@ using namespace Windows::Foundation::Collections;
|
||||
using namespace Windows::Storage::Streams;
|
||||
using namespace Windows::System;
|
||||
using namespace Windows::UI;
|
||||
using namespace Windows::UI::Core;
|
||||
using namespace Windows::UI::Input;
|
||||
using namespace Windows::UI::Xaml;
|
||||
using namespace Windows::UI::Xaml::Controls;
|
||||
@ -54,6 +55,7 @@ namespace GraphControl
|
||||
Grapher::Grapher()
|
||||
: m_solver{ IMathSolver::CreateMathSolver() }
|
||||
, m_graph{ m_solver->CreateGrapher() }
|
||||
, m_Moving{ false }
|
||||
{
|
||||
m_solver->ParsingOptions().SetFormatType(FormatType::MathML);
|
||||
|
||||
@ -67,6 +69,10 @@ namespace GraphControl
|
||||
|
||||
this->ManipulationMode = ManipulationModes::TranslateX | ManipulationModes::TranslateY | ManipulationModes::TranslateInertia | ManipulationModes::Scale
|
||||
| ManipulationModes::ScaleInertia;
|
||||
|
||||
auto cw = CoreWindow::GetForCurrentThread();
|
||||
cw->KeyDown += ref new TypedEventHandler<CoreWindow ^, KeyEventArgs ^>(this, &Grapher::OnCoreKeyDown);
|
||||
cw->KeyUp += ref new TypedEventHandler<CoreWindow ^, KeyEventArgs ^>(this, &Grapher::OnCoreKeyUp);
|
||||
}
|
||||
|
||||
void Grapher::OnLoaded(Object ^ sender, RoutedEventArgs ^ args)
|
||||
@ -126,6 +132,7 @@ namespace GraphControl
|
||||
auto swapChainPanel = dynamic_cast<SwapChainPanel ^>(GetTemplateChild(StringReference(s_templateKey_SwapChainPanel)));
|
||||
if (swapChainPanel)
|
||||
{
|
||||
swapChainPanel->AllowFocusOnInteraction = true;
|
||||
m_renderMain = ref new RenderMain(swapChainPanel);
|
||||
}
|
||||
|
||||
@ -535,12 +542,27 @@ namespace GraphControl
|
||||
}
|
||||
}
|
||||
|
||||
void Grapher::UpdateTracingChanged()
|
||||
{
|
||||
if (m_renderMain->Tracing || m_renderMain->ActiveTracing)
|
||||
{
|
||||
TracingChangedEvent(true);
|
||||
|
||||
TracingValueChangedEvent(m_renderMain->TraceValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
TracingChangedEvent(false);
|
||||
}
|
||||
}
|
||||
|
||||
void Grapher::OnPointerMoved(PointerRoutedEventArgs ^ e)
|
||||
{
|
||||
if (m_renderMain)
|
||||
{
|
||||
PointerPoint ^ currPoint = e->GetCurrentPoint(/* relativeTo */ this);
|
||||
m_renderMain->PointerLocation = currPoint->Position;
|
||||
UpdateTracingChanged();
|
||||
|
||||
e->Handled = true;
|
||||
}
|
||||
@ -551,6 +573,11 @@ namespace GraphControl
|
||||
if (m_renderMain)
|
||||
{
|
||||
m_renderMain->DrawNearestPoint = false;
|
||||
if (ActiveTracing == false)
|
||||
{
|
||||
// IF we are active tracing we never want to hide the popup..
|
||||
TracingChangedEvent(false);
|
||||
}
|
||||
e->Handled = true;
|
||||
}
|
||||
}
|
||||
@ -699,3 +726,175 @@ namespace GraphControl
|
||||
return outputStream;
|
||||
}
|
||||
}
|
||||
|
||||
void Grapher::OnCoreKeyUp(CoreWindow ^ sender, KeyEventArgs ^ e)
|
||||
{
|
||||
// We don't want to react to keyboard input unless the graph control has the focus.
|
||||
// NOTE: you can't select the graph control from the mouse for focus but you can tab to it.
|
||||
GraphControl::Grapher ^ gcHasFocus = dynamic_cast<GraphControl::Grapher ^>(FocusManager::GetFocusedElement());
|
||||
if (gcHasFocus == nullptr || gcHasFocus != this)
|
||||
{
|
||||
// Not a graphingCalculator control so we don't want the input.
|
||||
return;
|
||||
}
|
||||
|
||||
switch (e->VirtualKey)
|
||||
{
|
||||
case VirtualKey::Left:
|
||||
case VirtualKey::Right:
|
||||
case VirtualKey::Down:
|
||||
case VirtualKey::Up:
|
||||
case VirtualKey::Shift:
|
||||
{
|
||||
HandleKey(false, e->VirtualKey);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Grapher::OnCoreKeyDown(CoreWindow ^ sender, KeyEventArgs ^ e)
|
||||
{
|
||||
// We don't want to react to any keys when we are not in the graph control
|
||||
GraphControl::Grapher ^ gcHasFocus = dynamic_cast<GraphControl::Grapher ^>(FocusManager::GetFocusedElement());
|
||||
if (gcHasFocus == nullptr || gcHasFocus != this)
|
||||
{
|
||||
// Not a graphingCalculator control so we don't want the input.
|
||||
return;
|
||||
}
|
||||
|
||||
switch (e->VirtualKey)
|
||||
{
|
||||
case VirtualKey::Left:
|
||||
case VirtualKey::Right:
|
||||
case VirtualKey::Down:
|
||||
case VirtualKey::Up:
|
||||
case VirtualKey::Shift:
|
||||
{
|
||||
HandleKey(true, e->VirtualKey);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Grapher::HandleKey(bool keyDown, VirtualKey key)
|
||||
{
|
||||
int pressedKeys = 0;
|
||||
if (key == VirtualKey::Left)
|
||||
{
|
||||
m_KeysPressed[KeysPressedSlots::Left] = keyDown;
|
||||
if (keyDown)
|
||||
{
|
||||
pressedKeys++;
|
||||
}
|
||||
}
|
||||
if (key == VirtualKey::Right)
|
||||
{
|
||||
m_KeysPressed[KeysPressedSlots::Right] = keyDown;
|
||||
if (keyDown)
|
||||
{
|
||||
pressedKeys++;
|
||||
}
|
||||
}
|
||||
if (key == VirtualKey::Up)
|
||||
{
|
||||
m_KeysPressed[KeysPressedSlots::Up] = keyDown;
|
||||
if (keyDown)
|
||||
{
|
||||
pressedKeys++;
|
||||
}
|
||||
}
|
||||
if (key == VirtualKey::Down)
|
||||
{
|
||||
m_KeysPressed[KeysPressedSlots::Down] = keyDown;
|
||||
if (keyDown)
|
||||
{
|
||||
pressedKeys++;
|
||||
}
|
||||
}
|
||||
if (key == VirtualKey::Shift)
|
||||
{
|
||||
m_KeysPressed[KeysPressedSlots::Accelerator] = keyDown;
|
||||
}
|
||||
|
||||
if (pressedKeys > 0 && !m_Moving)
|
||||
{
|
||||
m_Moving = true;
|
||||
// Key(s) we care about, so ensure we are ticking our timer (and that we have one to tick)
|
||||
if (m_TracingTrackingTimer == nullptr)
|
||||
{
|
||||
m_TracingTrackingTimer = ref new DispatcherTimer();
|
||||
|
||||
m_TracingTrackingTimer->Tick += ref new EventHandler<Object ^>(this, &Grapher::HandleTracingMovementTick);
|
||||
TimeSpan ts;
|
||||
ts.Duration = 100000; // .1 second
|
||||
m_TracingTrackingTimer->Interval = ts;
|
||||
auto i = m_TracingTrackingTimer->Interval;
|
||||
}
|
||||
m_TracingTrackingTimer->Start();
|
||||
}
|
||||
}
|
||||
|
||||
void Grapher::HandleTracingMovementTick(Object ^ sender, Object ^ e)
|
||||
{
|
||||
int delta = 5;
|
||||
int liveKeys = 0;
|
||||
|
||||
if (m_KeysPressed[KeysPressedSlots::Accelerator])
|
||||
{
|
||||
delta = 1;
|
||||
}
|
||||
|
||||
auto curPos = ActiveTraceCursorPosition;
|
||||
|
||||
if (m_KeysPressed[KeysPressedSlots::Left])
|
||||
{
|
||||
liveKeys++;
|
||||
curPos.X -= delta;
|
||||
if (curPos.X < 0)
|
||||
{
|
||||
curPos.X = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_KeysPressed[KeysPressedSlots::Right])
|
||||
{
|
||||
liveKeys++;
|
||||
curPos.X += delta;
|
||||
if (curPos.X > ActualWidth - delta)
|
||||
{
|
||||
curPos.X = (float)ActualWidth - delta; // TODO change this to deal with size of cursor
|
||||
}
|
||||
}
|
||||
|
||||
if (m_KeysPressed[KeysPressedSlots::Up])
|
||||
{
|
||||
liveKeys++;
|
||||
curPos.Y -= delta;
|
||||
if (curPos.Y < 0)
|
||||
{
|
||||
curPos.Y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_KeysPressed[KeysPressedSlots::Down])
|
||||
{
|
||||
liveKeys++;
|
||||
curPos.Y += delta;
|
||||
if (curPos.Y > ActualHeight - delta)
|
||||
{
|
||||
curPos.Y = (float)ActualHeight - delta; // TODO change this to deal with size of cursor
|
||||
}
|
||||
}
|
||||
|
||||
if (liveKeys == 0)
|
||||
{
|
||||
m_Moving = false;
|
||||
|
||||
// Non of the keys we care about are being hit any longer so shut down our timer
|
||||
m_TracingTrackingTimer->Stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
ActiveTraceCursorPosition = curPos;
|
||||
}
|
||||
}
|
||||
|
@ -9,15 +9,24 @@
|
||||
|
||||
namespace GraphControl
|
||||
{
|
||||
[Windows::UI::Xaml::Markup::ContentPropertyAttribute(Name = L"Equations")]
|
||||
public ref class Grapher sealed : public Windows::UI::Xaml::Controls::Control
|
||||
public
|
||||
delegate void TracingChangedEventHandler(bool newValue);
|
||||
|
||||
public
|
||||
delegate void TracingValueChangedEventHandler(Windows::Foundation::Point value);
|
||||
|
||||
[Windows::UI::Xaml::Markup::ContentPropertyAttribute(Name = L"Equations")] public ref class Grapher sealed : public Windows::UI::Xaml::Controls::Control
|
||||
{
|
||||
public:
|
||||
event TracingValueChangedEventHandler ^ TracingValueChangedEvent;
|
||||
event TracingChangedEventHandler ^ TracingChangedEvent;
|
||||
|
||||
public:
|
||||
Grapher();
|
||||
|
||||
static void RegisterDependencyProperties();
|
||||
|
||||
#pragma region Windows::UI::Xaml::DataTemplate^ EquationTemplate DependencyProperty
|
||||
#pragma region Windows::UI::Xaml::DataTemplate ^ EquationTemplate DependencyProperty
|
||||
static property Windows::UI::Xaml::DependencyProperty^ EquationTemplateProperty
|
||||
{
|
||||
Windows::UI::Xaml::DependencyProperty^ get()
|
||||
@ -37,9 +46,9 @@ namespace GraphControl
|
||||
SetValue(s_equationTemplateProperty, value);
|
||||
}
|
||||
}
|
||||
#pragma endregion
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Platform::Object^ EquationsSource DependencyProperty
|
||||
#pragma region Platform::Object ^ EquationsSource DependencyProperty
|
||||
static property Windows::UI::Xaml::DependencyProperty^ EquationsSourceProperty
|
||||
{
|
||||
Windows::UI::Xaml::DependencyProperty^ get()
|
||||
@ -59,9 +68,9 @@ namespace GraphControl
|
||||
SetValue(s_equationsSourceProperty, value);
|
||||
}
|
||||
}
|
||||
#pragma endregion
|
||||
#pragma endregion
|
||||
|
||||
#pragma region GraphControl::EquationCollection^ Equations DependencyProperty
|
||||
#pragma region GraphControl::EquationCollection ^ Equations DependencyProperty
|
||||
static property Windows::UI::Xaml::DependencyProperty^ EquationsProperty
|
||||
{
|
||||
Windows::UI::Xaml::DependencyProperty^ get()
|
||||
@ -77,9 +86,9 @@ namespace GraphControl
|
||||
return static_cast< GraphControl::EquationCollection^ >(GetValue(s_equationsProperty));
|
||||
}
|
||||
}
|
||||
#pragma endregion
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Windows::Foundation::Collections::IObservableMap<Platform::String^, double>^ Variables DependencyProperty
|
||||
#pragma region Windows::Foundation::Collections::IObservableMap < Platform::String ^, double> ^ Variables DependencyProperty
|
||||
static property Windows::UI::Xaml::DependencyProperty^ VariablesProperty
|
||||
{
|
||||
Windows::UI::Xaml::DependencyProperty^ get()
|
||||
@ -100,9 +109,9 @@ namespace GraphControl
|
||||
SetValue(s_variablesProperty, value);
|
||||
}
|
||||
}
|
||||
#pragma endregion
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Windows::UI::Xaml::DataTemplate^ ForceProportionalAxes DependencyProperty
|
||||
#pragma region Windows::UI::Xaml::DataTemplate ^ ForceProportionalAxes DependencyProperty
|
||||
static property Windows::UI::Xaml::DependencyProperty^ ForceProportionalAxesTemplateProperty
|
||||
{
|
||||
Windows::UI::Xaml::DependencyProperty^ get()
|
||||
@ -122,52 +131,103 @@ namespace GraphControl
|
||||
SetValue(s_forceProportionalAxesTemplateProperty, value);
|
||||
}
|
||||
}
|
||||
#pragma endregion
|
||||
#pragma endregion
|
||||
|
||||
event Windows::Foundation::EventHandler<Windows::Foundation::Collections::IMap<Platform::String^, double>^>^ VariablesUpdated;
|
||||
// Pass active tracing turned on or off down to the renderer
|
||||
property bool ActiveTracing
|
||||
{
|
||||
bool get()
|
||||
{
|
||||
return m_renderMain->ActiveTracing;
|
||||
}
|
||||
|
||||
void set(bool value)
|
||||
{
|
||||
m_renderMain->ActiveTracing = value;
|
||||
UpdateTracingChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void SetVariable(Platform::String^ variableName, double newValue);
|
||||
void ZoomFromCenter(double scale);
|
||||
void ResetGrid();
|
||||
|
||||
property Windows::Foundation::Point TraceValue
|
||||
{
|
||||
Windows::Foundation::Point get()
|
||||
{
|
||||
return m_renderMain->TraceValue;
|
||||
}
|
||||
}
|
||||
|
||||
property Windows::Foundation::Point TraceLocation
|
||||
{
|
||||
Windows::Foundation::Point get()
|
||||
{
|
||||
return m_renderMain->TraceLocation;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
property Windows::Foundation::Point ActiveTraceCursorPosition
|
||||
{
|
||||
Windows::Foundation::Point get()
|
||||
{
|
||||
return m_renderMain->ActiveTraceCursorPosition;
|
||||
}
|
||||
|
||||
void set(Windows::Foundation::Point newValue)
|
||||
{
|
||||
if (m_renderMain->ActiveTraceCursorPosition != newValue)
|
||||
{
|
||||
m_renderMain->ActiveTraceCursorPosition = newValue;
|
||||
UpdateTracingChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
event Windows::Foundation::EventHandler<Windows::Foundation::Collections::IMap<Platform::String ^, double> ^> ^ VariablesUpdated;
|
||||
void SetVariable(Platform::String ^ variableName, double newValue);
|
||||
|
||||
protected:
|
||||
#pragma region Control Overrides
|
||||
#pragma region Control Overrides
|
||||
void OnApplyTemplate() override;
|
||||
|
||||
void OnPointerEntered(Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e) override;
|
||||
void OnPointerMoved(Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e) override;
|
||||
void OnPointerExited(Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e) override;
|
||||
void OnPointerWheelChanged(Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e) override;
|
||||
void OnPointerPressed(Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e) override;
|
||||
void OnPointerReleased(Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e) override;
|
||||
void OnPointerCanceled(Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e) override;
|
||||
void OnManipulationDelta(Windows::UI::Xaml::Input::ManipulationDeltaRoutedEventArgs^ e) override;
|
||||
#pragma endregion
|
||||
void OnPointerEntered(Windows::UI::Xaml::Input::PointerRoutedEventArgs ^ e) override;
|
||||
void OnPointerMoved(Windows::UI::Xaml::Input::PointerRoutedEventArgs ^ e) override;
|
||||
void OnPointerExited(Windows::UI::Xaml::Input::PointerRoutedEventArgs ^ e) override;
|
||||
void OnPointerWheelChanged(Windows::UI::Xaml::Input::PointerRoutedEventArgs ^ e) override;
|
||||
void OnPointerPressed(Windows::UI::Xaml::Input::PointerRoutedEventArgs ^ e) override;
|
||||
void OnPointerReleased(Windows::UI::Xaml::Input::PointerRoutedEventArgs ^ e) override;
|
||||
void OnPointerCanceled(Windows::UI::Xaml::Input::PointerRoutedEventArgs ^ e) override;
|
||||
void OnManipulationDelta(Windows::UI::Xaml::Input::ManipulationDeltaRoutedEventArgs ^ e) override;
|
||||
#pragma endregion
|
||||
|
||||
private:
|
||||
void OnLoaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ args);
|
||||
void OnUnloaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ args);
|
||||
void OnLoaded(Platform::Object ^ sender, Windows::UI::Xaml::RoutedEventArgs ^ args);
|
||||
void OnUnloaded(Platform::Object ^ sender, Windows::UI::Xaml::RoutedEventArgs ^ args);
|
||||
|
||||
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);
|
||||
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 OnEquationTemplateChanged(Windows::UI::Xaml::DependencyPropertyChangedEventArgs ^ args);
|
||||
|
||||
void OnEquationsSourceChanged(Windows::UI::Xaml::DependencyPropertyChangedEventArgs^ args);
|
||||
void OnDataSourceChanged(GraphControl::InspectingDataSource^ sender, GraphControl::DataSourceChangedEventArgs 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 OnEquationsChanged(Windows::UI::Xaml::DependencyPropertyChangedEventArgs ^ args);
|
||||
void OnEquationsVectorChanged(
|
||||
Windows::Foundation::Collections::IObservableVector<GraphControl::Equation ^> ^ sender,
|
||||
Windows::Foundation::Collections::IVectorChangedEventArgs ^ event);
|
||||
void OnEquationChanged();
|
||||
void OnEquationStyleChanged();
|
||||
|
||||
void UpdateGraph();
|
||||
void UpdateGraphOptions(Graphing::IGraphingOptions& options, const std::vector<Equation^>& validEqs);
|
||||
std::vector<Equation^> GetValidEquations();
|
||||
void UpdateGraphOptions(Graphing::IGraphingOptions& options, const std::vector<Equation ^>& validEqs);
|
||||
std::vector<Equation ^> GetValidEquations();
|
||||
void SetGraphArgs();
|
||||
void UpdateVariables();
|
||||
|
||||
void OnForceProportionalAxesChanged(Windows::UI::Xaml::DependencyPropertyChangedEventArgs^ args);
|
||||
void OnForceProportionalAxesChanged(Windows::UI::Xaml::DependencyPropertyChangedEventArgs ^ args);
|
||||
|
||||
void OnBackgroundColorChanged(const Windows::UI::Color& color);
|
||||
|
||||
@ -177,29 +237,52 @@ namespace GraphControl
|
||||
|
||||
void ScaleRange(double centerX, double centerY, double scale);
|
||||
|
||||
void OnCoreKeyDown(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::KeyEventArgs ^ e);
|
||||
void OnCoreKeyUp(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::KeyEventArgs ^ e);
|
||||
|
||||
void UpdateTracingChanged();
|
||||
void HandleTracingMovementTick(Object ^ sender, Object ^ e);
|
||||
void HandleKey(bool keyDown, Windows::System::VirtualKey key);
|
||||
|
||||
|
||||
private:
|
||||
DX::RenderMain^ m_renderMain = nullptr;
|
||||
DX::RenderMain ^ m_renderMain = nullptr;
|
||||
|
||||
static Windows::UI::Xaml::DependencyProperty^ s_equationTemplateProperty;
|
||||
static Windows::UI::Xaml::DependencyProperty ^ s_equationTemplateProperty;
|
||||
|
||||
static Windows::UI::Xaml::DependencyProperty^ s_equationsSourceProperty;
|
||||
InspectingDataSource^ m_dataSource;
|
||||
static Windows::UI::Xaml::DependencyProperty ^ s_equationsSourceProperty;
|
||||
InspectingDataSource ^ m_dataSource;
|
||||
Windows::Foundation::EventRegistrationToken m_tokenDataSourceChanged;
|
||||
|
||||
static Windows::UI::Xaml::DependencyProperty^ s_equationsProperty;
|
||||
static Windows::UI::Xaml::DependencyProperty^ s_variablesProperty;
|
||||
static Windows::UI::Xaml::DependencyProperty ^ s_equationsProperty;
|
||||
static Windows::UI::Xaml::DependencyProperty ^ s_variablesProperty;
|
||||
Windows::Foundation::EventRegistrationToken m_tokenEquationsChanged;
|
||||
Windows::Foundation::EventRegistrationToken m_tokenEquationStyleChanged;
|
||||
Windows::Foundation::EventRegistrationToken m_tokenEquationChanged;
|
||||
|
||||
static Windows::UI::Xaml::DependencyProperty^ s_forceProportionalAxesTemplateProperty;
|
||||
static Windows::UI::Xaml::DependencyProperty ^ s_forceProportionalAxesTemplateProperty;
|
||||
|
||||
Windows::Foundation::EventRegistrationToken m_tokenBackgroundColorChanged;
|
||||
|
||||
const std::unique_ptr<Graphing::IMathSolver> m_solver;
|
||||
const std::shared_ptr<Graphing::IGraph> m_graph;
|
||||
|
||||
public:
|
||||
Windows::Storage::Streams::RandomAccessStreamReference^ GetGraphBitmapStream();
|
||||
bool m_tracingTracking;
|
||||
enum KeysPressedSlots
|
||||
{
|
||||
Left,
|
||||
Right,
|
||||
Down,
|
||||
Up,
|
||||
Accelerator
|
||||
};
|
||||
|
||||
bool m_KeysPressed[5];
|
||||
bool m_Moving;
|
||||
|
||||
Windows::UI::Xaml::DispatcherTimer ^ m_TracingTrackingTimer;
|
||||
|
||||
public:
|
||||
Windows::Storage::Streams::RandomAccessStreamReference ^ GetGraphBitmapStream();
|
||||
};
|
||||
}
|
||||
|
78
src/GraphControl/DirectX/ActiveTracingPointRenderer.cpp
Normal file
78
src/GraphControl/DirectX/ActiveTracingPointRenderer.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
#include "pch.h"
|
||||
#include "ActiveTracingPointRenderer.h"
|
||||
#include "DirectXHelper.h"
|
||||
|
||||
using namespace D2D1;
|
||||
using namespace GraphControl::DX;
|
||||
using namespace std;
|
||||
using namespace Windows::Foundation;
|
||||
|
||||
namespace
|
||||
{
|
||||
const ColorF c_DefaultPointColor = ColorF::Red;
|
||||
constexpr float c_ActiveTracingPointRadius = 2;
|
||||
}
|
||||
|
||||
ActiveTracingPointRenderer::ActiveTracingPointRenderer(DeviceResources* deviceResources)
|
||||
: m_deviceResources{ deviceResources }
|
||||
, m_color{ c_DefaultPointColor }
|
||||
|
||||
{
|
||||
m_RoundedRect.rect.bottom = 0;
|
||||
m_RoundedRect.rect.left = 0;
|
||||
m_RoundedRect.rect.right = 10;
|
||||
m_RoundedRect.rect.top = 10;
|
||||
m_width = (int)(m_RoundedRect.rect.right - m_RoundedRect.rect.left);
|
||||
m_height = (int)(m_RoundedRect.rect.top - m_RoundedRect.rect.bottom);
|
||||
m_RoundedRect.radiusX = c_ActiveTracingPointRadius;
|
||||
m_RoundedRect.radiusY = c_ActiveTracingPointRadius;
|
||||
|
||||
CreateDeviceDependentResources();
|
||||
}
|
||||
|
||||
void ActiveTracingPointRenderer::CreateDeviceDependentResources()
|
||||
{
|
||||
CreateBrush();
|
||||
}
|
||||
|
||||
void ActiveTracingPointRenderer::ReleaseDeviceDependentResources()
|
||||
{
|
||||
m_brush.Reset();
|
||||
}
|
||||
|
||||
void ActiveTracingPointRenderer::Render(const Point& location)
|
||||
{
|
||||
// We want to center this around the location
|
||||
if (ID2D1DeviceContext* context = m_deviceResources->GetD2DDeviceContext())
|
||||
{
|
||||
m_RoundedRect.rect.bottom = location.Y - m_height / 2;
|
||||
m_RoundedRect.rect.left = location.X - m_width / 2;
|
||||
m_RoundedRect.rect.top = m_RoundedRect.rect.bottom + m_height;
|
||||
m_RoundedRect.rect.right = m_RoundedRect.rect.left + m_width;
|
||||
|
||||
context->BeginDraw();
|
||||
context->FillRoundedRectangle(m_RoundedRect, m_brush.Get());
|
||||
|
||||
// Ignore D2DERR_RECREATE_TARGET here. This error indicates that the device
|
||||
// is lost. It will be handled during the next call to Present.
|
||||
HRESULT hr = context->EndDraw();
|
||||
if (hr != D2DERR_RECREATE_TARGET)
|
||||
{
|
||||
ThrowIfFailed(hr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ActiveTracingPointRenderer::SetColor(const ColorF& color)
|
||||
{
|
||||
m_color = color;
|
||||
CreateBrush();
|
||||
}
|
||||
|
||||
void ActiveTracingPointRenderer::CreateBrush()
|
||||
{
|
||||
m_brush.Reset();
|
||||
ThrowIfFailed(
|
||||
m_deviceResources->GetD2DDeviceContext()->CreateSolidColorBrush(m_color, &m_brush)
|
||||
);
|
||||
}
|
32
src/GraphControl/DirectX/ActiveTracingPointRenderer.h
Normal file
32
src/GraphControl/DirectX/ActiveTracingPointRenderer.h
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
namespace GraphControl::DX
|
||||
{
|
||||
class DeviceResources;
|
||||
|
||||
class ActiveTracingPointRenderer
|
||||
{
|
||||
public:
|
||||
ActiveTracingPointRenderer(DeviceResources* deviceResources);
|
||||
|
||||
void CreateDeviceDependentResources();
|
||||
void ReleaseDeviceDependentResources();
|
||||
void Render(const Windows::Foundation::Point& location);
|
||||
|
||||
void SetColor(const D2D1::ColorF& color);
|
||||
|
||||
private:
|
||||
void CreateBrush();
|
||||
|
||||
private:
|
||||
DeviceResources* const m_deviceResources;
|
||||
|
||||
D2D1::ColorF m_color;
|
||||
D2D1_ROUNDED_RECT m_RoundedRect;
|
||||
int m_width;
|
||||
int m_height;
|
||||
|
||||
// Resources related to rendering.
|
||||
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> m_brush;
|
||||
};
|
||||
}
|
@ -26,16 +26,24 @@ namespace
|
||||
|
||||
namespace GraphControl::DX
|
||||
{
|
||||
RenderMain::RenderMain(SwapChainPanel^ panel) :
|
||||
m_deviceResources{ panel },
|
||||
m_nearestPointRenderer{ &m_deviceResources },
|
||||
m_backgroundColor{ {} },
|
||||
m_swapChainPanel{ panel }
|
||||
RenderMain::RenderMain(SwapChainPanel ^ panel)
|
||||
: m_deviceResources{ panel }
|
||||
, m_nearestPointRenderer{ &m_deviceResources }
|
||||
, m_backgroundColor{ {} }
|
||||
, m_swapChainPanel{ panel }
|
||||
, m_TraceValue(Point(0, 0))
|
||||
, m_TraceLocation(Point(0,0))
|
||||
, m_Tracing(false)
|
||||
, m_ActiveTracingPointRenderer{ &m_deviceResources }
|
||||
{
|
||||
// Register to be notified if the Device is lost or recreated
|
||||
m_deviceResources.RegisterDeviceNotify(this);
|
||||
|
||||
RegisterEventHandlers();
|
||||
|
||||
m_drawActiveTracing = false;
|
||||
m_activeTracingPointerLocation.X = 50;
|
||||
m_activeTracingPointerLocation.Y = 50;
|
||||
}
|
||||
|
||||
RenderMain::~RenderMain()
|
||||
@ -43,7 +51,7 @@ namespace GraphControl::DX
|
||||
UnregisterEventHandlers();
|
||||
}
|
||||
|
||||
void RenderMain::Graph::set(shared_ptr< IGraph > graph)
|
||||
void RenderMain::Graph::set(shared_ptr<IGraph> graph)
|
||||
{
|
||||
m_graph = move(graph);
|
||||
|
||||
@ -54,9 +62,7 @@ namespace GraphControl::DX
|
||||
float dpi = m_deviceResources.GetDpi();
|
||||
renderer->SetDpi(dpi, dpi);
|
||||
|
||||
renderer->SetGraphSize(
|
||||
static_cast<unsigned int>(m_swapChainPanel->ActualWidth),
|
||||
static_cast<unsigned int>(m_swapChainPanel->ActualHeight));
|
||||
renderer->SetGraphSize(static_cast<unsigned int>(m_swapChainPanel->ActualWidth), static_cast<unsigned int>(m_swapChainPanel->ActualHeight));
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,9 +71,9 @@ namespace GraphControl::DX
|
||||
|
||||
void RenderMain::BackgroundColor::set(Windows::UI::Color backgroundColor)
|
||||
{
|
||||
m_backgroundColor[s_RedChannelIndex] = static_cast<float>(backgroundColor.R) / s_MaxChannelValue;
|
||||
m_backgroundColor[s_RedChannelIndex] = static_cast<float>(backgroundColor.R) / s_MaxChannelValue;
|
||||
m_backgroundColor[s_GreenChannelIndex] = static_cast<float>(backgroundColor.G) / s_MaxChannelValue;
|
||||
m_backgroundColor[s_BlueChannelIndex] = static_cast<float>(backgroundColor.B) / s_MaxChannelValue;
|
||||
m_backgroundColor[s_BlueChannelIndex] = static_cast<float>(backgroundColor.B) / s_MaxChannelValue;
|
||||
m_backgroundColor[s_AlphaChannelIndex] = static_cast<float>(backgroundColor.A) / s_MaxChannelValue;
|
||||
|
||||
RunRenderPass();
|
||||
@ -78,6 +84,10 @@ namespace GraphControl::DX
|
||||
if (m_drawNearestPoint != value)
|
||||
{
|
||||
m_drawNearestPoint = value;
|
||||
if (!m_drawNearestPoint)
|
||||
{
|
||||
m_Tracing = false;
|
||||
}
|
||||
RunRenderPass();
|
||||
}
|
||||
}
|
||||
@ -91,6 +101,20 @@ namespace GraphControl::DX
|
||||
}
|
||||
}
|
||||
|
||||
void RenderMain::ActiveTracing::set(bool value)
|
||||
{
|
||||
if (m_drawActiveTracing != value)
|
||||
{
|
||||
m_drawActiveTracing = value;
|
||||
RunRenderPass();
|
||||
}
|
||||
}
|
||||
|
||||
bool RenderMain::ActiveTracing::get()
|
||||
{
|
||||
return m_drawActiveTracing;
|
||||
}
|
||||
|
||||
// Updates application state when the window size changes (e.g. device orientation change)
|
||||
void RenderMain::CreateWindowSizeDependentResources()
|
||||
{
|
||||
@ -113,8 +137,8 @@ namespace GraphControl::DX
|
||||
bool successful = true;
|
||||
|
||||
// Must call BeginDraw before any draw commands.
|
||||
ID2D1Factory3 *pFactory = m_deviceResources.GetD2DFactory();
|
||||
ID2D1DeviceContext *pRenderTarget = m_deviceResources.GetD2DDeviceContext();
|
||||
ID2D1Factory3* pFactory = m_deviceResources.GetD2DFactory();
|
||||
ID2D1DeviceContext* pRenderTarget = m_deviceResources.GetD2DDeviceContext();
|
||||
|
||||
auto context = m_deviceResources.GetD3DDeviceContext();
|
||||
|
||||
@ -138,20 +162,43 @@ namespace GraphControl::DX
|
||||
DX::ThrowIfFailed(endDraw);
|
||||
}
|
||||
|
||||
if (successful && m_drawNearestPoint)
|
||||
if (successful)
|
||||
{
|
||||
int formulaId;
|
||||
Point nearestPointLocation;
|
||||
pair<float, float> nearestPointValue;
|
||||
renderer->GetClosePointData(
|
||||
m_pointerLocation.X, m_pointerLocation.Y,
|
||||
formulaId,
|
||||
nearestPointLocation.X, nearestPointLocation.Y,
|
||||
nearestPointValue.first, nearestPointValue.second);
|
||||
|
||||
if (!isnan(nearestPointLocation.X) && !isnan(nearestPointLocation.Y))
|
||||
if (m_drawNearestPoint || m_drawActiveTracing)
|
||||
{
|
||||
m_nearestPointRenderer.Render(nearestPointLocation);
|
||||
Point trackPoint = m_pointerLocation;
|
||||
|
||||
if (m_drawActiveTracing)
|
||||
{
|
||||
// Active tracing takes over for draw nearest point input from the mouse pointer.
|
||||
trackPoint = m_activeTracingPointerLocation;
|
||||
|
||||
m_ActiveTracingPointRenderer.Render(m_activeTracingPointerLocation);
|
||||
}
|
||||
|
||||
int formulaId;
|
||||
Point nearestPointLocation;
|
||||
pair<float, float> nearestPointValue;
|
||||
renderer->GetClosePointData(
|
||||
trackPoint.X,
|
||||
trackPoint.Y,
|
||||
formulaId,
|
||||
nearestPointLocation.X,
|
||||
nearestPointLocation.Y,
|
||||
nearestPointValue.first,
|
||||
nearestPointValue.second);
|
||||
|
||||
if (!isnan(nearestPointLocation.X) && !isnan(nearestPointLocation.Y))
|
||||
{
|
||||
m_nearestPointRenderer.Render(nearestPointLocation);
|
||||
m_Tracing = true;
|
||||
m_TraceLocation = Point(nearestPointLocation.X, nearestPointLocation.Y);
|
||||
m_TraceValue = Point(nearestPointValue.first, nearestPointValue.second);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Tracing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -160,7 +207,7 @@ namespace GraphControl::DX
|
||||
return successful;
|
||||
}
|
||||
|
||||
void RenderMain::OnLoaded(Object^ sender, RoutedEventArgs^ e)
|
||||
void RenderMain::OnLoaded(Object ^ sender, RoutedEventArgs ^ e)
|
||||
{
|
||||
RunRenderPass();
|
||||
}
|
||||
@ -173,39 +220,30 @@ namespace GraphControl::DX
|
||||
m_coreWindow = Agile<CoreWindow>(Window::Current->CoreWindow);
|
||||
if (m_coreWindow != nullptr)
|
||||
{
|
||||
m_tokenVisibilityChanged =
|
||||
m_coreWindow->VisibilityChanged +=
|
||||
ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &RenderMain::OnVisibilityChanged);
|
||||
m_tokenVisibilityChanged = m_coreWindow->VisibilityChanged +=
|
||||
ref new TypedEventHandler<CoreWindow ^, VisibilityChangedEventArgs ^>(this, &RenderMain::OnVisibilityChanged);
|
||||
}
|
||||
|
||||
m_displayInformation = DisplayInformation::GetForCurrentView();
|
||||
if (m_displayInformation != nullptr)
|
||||
{
|
||||
m_tokenDpiChanged =
|
||||
m_displayInformation->DpiChanged +=
|
||||
ref new TypedEventHandler<DisplayInformation^, Object^>(this, &RenderMain::OnDpiChanged);
|
||||
m_tokenDpiChanged = m_displayInformation->DpiChanged += ref new TypedEventHandler<DisplayInformation ^, Object ^>(this, &RenderMain::OnDpiChanged);
|
||||
|
||||
m_tokenOrientationChanged =
|
||||
m_displayInformation->OrientationChanged +=
|
||||
ref new TypedEventHandler<DisplayInformation^, Object^>(this, &RenderMain::OnOrientationChanged);
|
||||
m_tokenOrientationChanged = m_displayInformation->OrientationChanged +=
|
||||
ref new TypedEventHandler<DisplayInformation ^, Object ^>(this, &RenderMain::OnOrientationChanged);
|
||||
}
|
||||
|
||||
m_tokenDisplayContentsInvalidated =
|
||||
DisplayInformation::DisplayContentsInvalidated +=
|
||||
ref new TypedEventHandler<DisplayInformation^, Object^>(this, &RenderMain::OnDisplayContentsInvalidated);
|
||||
m_tokenDisplayContentsInvalidated = DisplayInformation::DisplayContentsInvalidated +=
|
||||
ref new TypedEventHandler<DisplayInformation ^, Object ^>(this, &RenderMain::OnDisplayContentsInvalidated);
|
||||
|
||||
if (m_swapChainPanel != nullptr)
|
||||
{
|
||||
m_tokenLoaded =
|
||||
m_swapChainPanel->Loaded += ref new RoutedEventHandler(this, &RenderMain::OnLoaded);
|
||||
m_tokenLoaded = m_swapChainPanel->Loaded += ref new RoutedEventHandler(this, &RenderMain::OnLoaded);
|
||||
|
||||
m_tokenCompositionScaleChanged =
|
||||
m_swapChainPanel->CompositionScaleChanged +=
|
||||
ref new TypedEventHandler< SwapChainPanel^, Object^ >(this, &RenderMain::OnCompositionScaleChanged);
|
||||
m_tokenCompositionScaleChanged = m_swapChainPanel->CompositionScaleChanged +=
|
||||
ref new TypedEventHandler<SwapChainPanel ^, Object ^>(this, &RenderMain::OnCompositionScaleChanged);
|
||||
|
||||
m_tokenSizeChanged =
|
||||
m_swapChainPanel->SizeChanged +=
|
||||
ref new SizeChangedEventHandler(this, &RenderMain::OnSizeChanged);
|
||||
m_tokenSizeChanged = m_swapChainPanel->SizeChanged += ref new SizeChangedEventHandler(this, &RenderMain::OnSizeChanged);
|
||||
}
|
||||
}
|
||||
|
||||
@ -262,7 +300,7 @@ namespace GraphControl::DX
|
||||
}
|
||||
}
|
||||
|
||||
void RenderMain::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
|
||||
void RenderMain::OnVisibilityChanged(CoreWindow ^ sender, VisibilityChangedEventArgs ^ args)
|
||||
{
|
||||
if (args->Visible)
|
||||
{
|
||||
@ -270,7 +308,7 @@ namespace GraphControl::DX
|
||||
}
|
||||
}
|
||||
|
||||
void RenderMain::OnDpiChanged(DisplayInformation^ sender, Object^ args)
|
||||
void RenderMain::OnDpiChanged(DisplayInformation ^ sender, Object ^ args)
|
||||
{
|
||||
// Note: The value for LogicalDpi retrieved here may not match the effective DPI of the app
|
||||
// if it is being scaled for high resolution devices. Once the DPI is set on DeviceResources,
|
||||
@ -290,24 +328,24 @@ namespace GraphControl::DX
|
||||
CreateWindowSizeDependentResources();
|
||||
}
|
||||
|
||||
void RenderMain::OnOrientationChanged(DisplayInformation^ sender, Object^ args)
|
||||
void RenderMain::OnOrientationChanged(DisplayInformation ^ sender, Object ^ args)
|
||||
{
|
||||
m_deviceResources.SetCurrentOrientation(sender->CurrentOrientation);
|
||||
CreateWindowSizeDependentResources();
|
||||
}
|
||||
|
||||
void RenderMain::OnDisplayContentsInvalidated(DisplayInformation^ sender, Object^ args)
|
||||
void RenderMain::OnDisplayContentsInvalidated(DisplayInformation ^ sender, Object ^ args)
|
||||
{
|
||||
m_deviceResources.ValidateDevice();
|
||||
}
|
||||
|
||||
void RenderMain::OnCompositionScaleChanged(SwapChainPanel^ sender, Object^ args)
|
||||
void RenderMain::OnCompositionScaleChanged(SwapChainPanel ^ sender, Object ^ args)
|
||||
{
|
||||
m_deviceResources.SetCompositionScale(sender->CompositionScaleX, sender->CompositionScaleY);
|
||||
CreateWindowSizeDependentResources();
|
||||
}
|
||||
|
||||
void RenderMain::OnSizeChanged(Object^ sender, SizeChangedEventArgs^ e)
|
||||
void RenderMain::OnSizeChanged(Object ^ sender, SizeChangedEventArgs ^ e)
|
||||
{
|
||||
m_deviceResources.SetLogicalSize(e->NewSize);
|
||||
|
||||
@ -316,9 +354,7 @@ namespace GraphControl::DX
|
||||
if (auto renderer = m_graph->GetRenderer())
|
||||
{
|
||||
const auto& newSize = e->NewSize;
|
||||
renderer->SetGraphSize(
|
||||
static_cast<unsigned int>(newSize.Width),
|
||||
static_cast<unsigned int>(newSize.Height));
|
||||
renderer->SetGraphSize(static_cast<unsigned int>(newSize.Width), static_cast<unsigned int>(newSize.Height));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "DeviceResources.h"
|
||||
#include "NearestPointRenderer.h"
|
||||
#include "ActiveTracingPointRenderer.h"
|
||||
#include "IGraph.h"
|
||||
|
||||
// Renders Direct2D and 3D content on the screen.
|
||||
@ -18,12 +19,11 @@ namespace GraphControl::DX
|
||||
virtual void OnDeviceLost();
|
||||
virtual void OnDeviceRestored();
|
||||
|
||||
internal:
|
||||
RenderMain(Windows::UI::Xaml::Controls::SwapChainPanel^ panel);
|
||||
internal : RenderMain(Windows::UI::Xaml::Controls::SwapChainPanel ^ panel);
|
||||
|
||||
property std::shared_ptr< Graphing::IGraph > Graph
|
||||
property std::shared_ptr<Graphing::IGraph> Graph
|
||||
{
|
||||
void set(std::shared_ptr< Graphing::IGraph > graph);
|
||||
void set(std::shared_ptr<Graphing::IGraph> graph);
|
||||
}
|
||||
|
||||
property Windows::UI::Color BackgroundColor
|
||||
@ -45,43 +45,98 @@ namespace GraphControl::DX
|
||||
|
||||
void RunRenderPass();
|
||||
|
||||
// Indicates if we are in active tracing mode (the tracing box is being used and controlled through keyboard input)
|
||||
property bool ActiveTracing
|
||||
{
|
||||
bool get();
|
||||
void set(bool value);
|
||||
}
|
||||
|
||||
property Windows::Foundation::Point ActiveTraceCursorPosition
|
||||
{
|
||||
Windows::Foundation::Point get()
|
||||
{
|
||||
return m_activeTracingPointerLocation;
|
||||
}
|
||||
|
||||
void set(Windows::Foundation::Point newValue)
|
||||
{
|
||||
if (m_activeTracingPointerLocation != newValue)
|
||||
{
|
||||
m_activeTracingPointerLocation = newValue;
|
||||
m_ActiveTracingPointRenderer.Render(m_activeTracingPointerLocation);
|
||||
RunRenderPass();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property Windows::Foundation::Point TraceValue
|
||||
{
|
||||
Windows::Foundation::Point get()
|
||||
{
|
||||
return m_TraceValue;
|
||||
}
|
||||
}
|
||||
|
||||
property Windows::Foundation::Point TraceLocation
|
||||
{
|
||||
Windows::Foundation::Point get()
|
||||
{
|
||||
return m_TraceLocation;
|
||||
}
|
||||
}
|
||||
|
||||
// Any time we should be showing the tracing popup (either active or passive tracing)
|
||||
property bool Tracing
|
||||
{
|
||||
bool get()
|
||||
{
|
||||
return m_Tracing;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool Render();
|
||||
|
||||
// Loaded/Unloaded
|
||||
void OnLoaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
void OnLoaded(Platform::Object ^ sender, Windows::UI::Xaml::RoutedEventArgs ^ e);
|
||||
|
||||
// Dependent event registration
|
||||
void RegisterEventHandlers();
|
||||
void UnregisterEventHandlers();
|
||||
|
||||
// Window event handlers.
|
||||
void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args);
|
||||
void OnVisibilityChanged(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::VisibilityChangedEventArgs ^ args);
|
||||
|
||||
// DisplayInformation event handlers.
|
||||
void OnDpiChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args);
|
||||
void OnOrientationChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args);
|
||||
void OnDisplayContentsInvalidated(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args);
|
||||
void OnDpiChanged(Windows::Graphics::Display::DisplayInformation ^ sender, Platform::Object ^ args);
|
||||
void OnOrientationChanged(Windows::Graphics::Display::DisplayInformation ^ sender, Platform::Object ^ args);
|
||||
void OnDisplayContentsInvalidated(Windows::Graphics::Display::DisplayInformation ^ sender, Platform::Object ^ args);
|
||||
|
||||
// Other event handlers.
|
||||
void OnCompositionScaleChanged(Windows::UI::Xaml::Controls::SwapChainPanel^ sender, Object^ args);
|
||||
void OnSizeChanged(Platform::Object^ sender, Windows::UI::Xaml::SizeChangedEventArgs^ e);
|
||||
void OnCompositionScaleChanged(Windows::UI::Xaml::Controls::SwapChainPanel ^ sender, Object ^ args);
|
||||
void OnSizeChanged(Platform::Object ^ sender, Windows::UI::Xaml::SizeChangedEventArgs ^ e);
|
||||
|
||||
private:
|
||||
DX::DeviceResources m_deviceResources;
|
||||
NearestPointRenderer m_nearestPointRenderer;
|
||||
ActiveTracingPointRenderer m_ActiveTracingPointRenderer;
|
||||
|
||||
// Cached Graph object with Renderer property.
|
||||
std::shared_ptr< Graphing::IGraph > m_graph = nullptr;
|
||||
std::shared_ptr<Graphing::IGraph> m_graph = nullptr;
|
||||
|
||||
// Track current input pointer position.
|
||||
bool m_drawNearestPoint = false;
|
||||
Windows::Foundation::Point m_pointerLocation;
|
||||
|
||||
// Track current active tracing pointer position.
|
||||
bool m_drawActiveTracing = false;
|
||||
Windows::Foundation::Point m_activeTracingPointerLocation;
|
||||
|
||||
float m_backgroundColor[4];
|
||||
|
||||
// The SwapChainPanel^ surface.
|
||||
Windows::UI::Xaml::Controls::SwapChainPanel^ m_swapChainPanel = nullptr;
|
||||
// The SwapChainPanel^ surface.
|
||||
Windows::UI::Xaml::Controls::SwapChainPanel ^ m_swapChainPanel = nullptr;
|
||||
Windows::Foundation::EventRegistrationToken m_tokenLoaded;
|
||||
Windows::Foundation::EventRegistrationToken m_tokenCompositionScaleChanged;
|
||||
Windows::Foundation::EventRegistrationToken m_tokenSizeChanged;
|
||||
@ -90,13 +145,22 @@ namespace GraphControl::DX
|
||||
Platform::Agile<Windows::UI::Core::CoreWindow> m_coreWindow = nullptr;
|
||||
Windows::Foundation::EventRegistrationToken m_tokenVisibilityChanged;
|
||||
|
||||
Windows::Graphics::Display::DisplayInformation^ m_displayInformation = nullptr;
|
||||
Windows::Graphics::Display::DisplayInformation ^ m_displayInformation = nullptr;
|
||||
Windows::Foundation::EventRegistrationToken m_tokenDpiChanged;
|
||||
Windows::Foundation::EventRegistrationToken m_tokenOrientationChanged;
|
||||
Windows::Foundation::EventRegistrationToken m_tokenDisplayContentsInvalidated;
|
||||
|
||||
// Track our independent input on a background worker thread.
|
||||
Windows::Foundation::IAsyncAction^ m_inputLoopWorker = nullptr;
|
||||
Windows::UI::Core::CoreIndependentInputSource^ m_coreInput = nullptr;
|
||||
Windows::Foundation::IAsyncAction ^ m_inputLoopWorker = nullptr;
|
||||
Windows::UI::Core::CoreIndependentInputSource ^ m_coreInput = nullptr;
|
||||
|
||||
// What is the current trace value
|
||||
Windows::Foundation::Point m_TraceValue;
|
||||
|
||||
// And where is it located on screen
|
||||
Windows::Foundation::Point m_TraceLocation;
|
||||
|
||||
// Are we currently showing the tracing value
|
||||
bool m_Tracing;
|
||||
};
|
||||
}
|
||||
|
@ -308,6 +308,7 @@
|
||||
<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" />
|
||||
<ClInclude Include="DirectX\NearestPointRenderer.h" />
|
||||
@ -319,6 +320,7 @@
|
||||
<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" />
|
||||
<ClCompile Include="DirectX\RenderMain.cpp" />
|
||||
|
@ -31,6 +31,9 @@
|
||||
<ClCompile Include="DirectX\NearestPointRenderer.cpp">
|
||||
<Filter>DirectX</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DirectX\ActiveTracingPointRenderer.cpp">
|
||||
<Filter>DirectX</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
@ -59,6 +62,9 @@
|
||||
<ClInclude Include="DirectX\NearestPointRenderer.h">
|
||||
<Filter>DirectX</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DirectX\ActiveTracingPointRenderer.h">
|
||||
<Filter>DirectX</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="Themes\generic.xaml">
|
||||
|
Loading…
Reference in New Issue
Block a user