Support mouse gestures when active tracing is enabled (#1064)

* Make the pointer follow the mouse

* Only render when necessary

* Move trace rendering to background thread
This commit is contained in:
Pepe Rivera 2020-03-16 11:54:19 -07:00 committed by GitHub
parent f527dce88d
commit 76fa670f92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 121 additions and 7 deletions

View File

@ -93,11 +93,19 @@ namespace GraphControl
{ {
if (auto renderer = m_graph->GetRenderer()) if (auto renderer = m_graph->GetRenderer())
{ {
m_renderMain->GetCriticalSection().lock();
if (SUCCEEDED(renderer->ScaleRange(centerX, centerY, scale))) if (SUCCEEDED(renderer->ScaleRange(centerX, centerY, scale)))
{ {
m_renderMain->GetCriticalSection().unlock();
m_renderMain->RunRenderPass(); m_renderMain->RunRenderPass();
GraphViewChangedEvent(this, ref new RoutedEventArgs()); GraphViewChangedEvent(this, ref new RoutedEventArgs());
} }
else
{
m_renderMain->GetCriticalSection().unlock();
}
} }
} }
} }
@ -612,9 +620,33 @@ namespace GraphControl
{ {
if (m_renderMain) if (m_renderMain)
{ {
PointerPoint ^ currPoint = e->GetCurrentPoint(/* relativeTo */ this); Point currPosition = e->GetCurrentPoint(/* relativeTo */ this)->Position;
m_renderMain->PointerLocation = currPoint->Position;
if (m_renderMain->ActiveTracing)
{
PointerValueChangedEvent(currPosition);
ActiveTraceCursorPosition = currPosition;
if (m_cachedCursor == nullptr)
{
m_cachedCursor = ::CoreWindow::GetForCurrentThread()->PointerCursor;
::CoreWindow::GetForCurrentThread()->PointerCursor = nullptr;
}
}
else if (m_cachedCursor != nullptr)
{
m_renderMain->PointerLocation = currPosition;
::CoreWindow::GetForCurrentThread()->PointerCursor = m_cachedCursor;
m_cachedCursor = nullptr;
UpdateTracingChanged(); UpdateTracingChanged();
}
else
{
m_renderMain->PointerLocation = currPosition;
UpdateTracingChanged();
}
e->Handled = true; e->Handled = true;
} }
@ -628,6 +660,12 @@ namespace GraphControl
TracingChangedEvent(false); TracingChangedEvent(false);
e->Handled = true; e->Handled = true;
} }
if (m_cachedCursor != nullptr)
{
::CoreWindow::GetForCurrentThread()->PointerCursor = m_cachedCursor;
m_cachedCursor = nullptr;
}
} }
void Grapher::OnPointerWheelChanged(PointerRoutedEventArgs ^ e) void Grapher::OnPointerWheelChanged(PointerRoutedEventArgs ^ e)
@ -699,11 +737,15 @@ namespace GraphControl
translationX /= -width; translationX /= -width;
translationY /= height; translationY /= height;
m_renderMain->GetCriticalSection().lock();
if (FAILED(renderer->MoveRangeByRatio(translationX, translationY))) if (FAILED(renderer->MoveRangeByRatio(translationX, translationY)))
{ {
m_renderMain->GetCriticalSection().unlock();
return; return;
} }
m_renderMain->GetCriticalSection().unlock();
needsRenderPass = true; needsRenderPass = true;
} }
@ -717,11 +759,15 @@ namespace GraphControl
const auto& pos = e->Position; const auto& pos = e->Position;
const auto [centerX, centerY] = PointerPositionToGraphPosition(pos.X, pos.Y, width, height); const auto [centerX, centerY] = PointerPositionToGraphPosition(pos.X, pos.Y, width, height);
m_renderMain->GetCriticalSection().lock();
if (FAILED(renderer->ScaleRange(centerX, centerY, scale))) if (FAILED(renderer->ScaleRange(centerX, centerY, scale)))
{ {
m_renderMain->GetCriticalSection().unlock();
return; return;
} }
m_renderMain->GetCriticalSection().unlock();
needsRenderPass = true; needsRenderPass = true;
} }

View File

@ -333,6 +333,7 @@ public
bool m_KeysPressed[5]; bool m_KeysPressed[5];
bool m_Moving; bool m_Moving;
Windows::UI::Xaml::DispatcherTimer ^ m_TracingTrackingTimer; Windows::UI::Xaml::DispatcherTimer ^ m_TracingTrackingTimer;
Windows::UI::Core::CoreCursor ^ m_cachedCursor;
public: public:
Windows::Storage::Streams::RandomAccessStreamReference ^ GetGraphBitmapStream(); Windows::Storage::Streams::RandomAccessStreamReference ^ GetGraphBitmapStream();

View File

@ -86,7 +86,12 @@ namespace GraphControl::DX
{ {
m_Tracing = false; m_Tracing = false;
} }
RunRenderPass();
bool wasPointRendered = m_Tracing;
if (CanRenderPoint() || wasPointRendered)
{
RunRenderPassAsync();
}
} }
} }
@ -95,7 +100,12 @@ namespace GraphControl::DX
if (m_pointerLocation != location) if (m_pointerLocation != location)
{ {
m_pointerLocation = location; m_pointerLocation = location;
RunRenderPass();
bool wasPointRendered = m_Tracing;
if (CanRenderPoint() || wasPointRendered)
{
RunRenderPassAsync();
}
} }
} }
@ -104,7 +114,12 @@ namespace GraphControl::DX
if (m_drawActiveTracing != value) if (m_drawActiveTracing != value)
{ {
m_drawActiveTracing = value; m_drawActiveTracing = value;
RunRenderPass();
bool wasPointRendered = m_Tracing;
if (CanRenderPoint() || wasPointRendered)
{
RunRenderPassAsync();
}
} }
} }
@ -127,6 +142,51 @@ namespace GraphControl::DX
} }
} }
bool RenderMain::CanRenderPoint()
{
if (m_drawNearestPoint || m_drawActiveTracing)
{
Point trackPoint = m_pointerLocation;
if (m_drawActiveTracing)
{
trackPoint = m_activeTracingPointerLocation;
}
if (!m_criticalSection.try_lock())
{
return false;
}
m_criticalSection.unlock();
critical_section::scoped_lock lock(m_criticalSection);
int formulaId = -1;
float nearestPointLocationX, nearestPointLocationY;
double nearestPointValueX, nearestPointValueY, rhoValueOut, thetaValueOut, tValueOut;
m_Tracing = m_graph->GetRenderer()->GetClosePointData(
trackPoint.X,
trackPoint.Y,
formulaId,
nearestPointLocationX,
nearestPointLocationY,
nearestPointValueX,
nearestPointValueY,
rhoValueOut,
thetaValueOut,
tValueOut)
== S_OK;
m_Tracing = m_Tracing && !isnan(nearestPointLocationX) && !isnan(nearestPointLocationY);
}
else
{
m_Tracing = false;
}
return m_Tracing;
}
bool RenderMain::RunRenderPass() bool RenderMain::RunRenderPass()
{ {
// Non async render passes cancel if they can't obtain the lock immediatly // Non async render passes cancel if they can't obtain the lock immediatly

View File

@ -45,6 +45,8 @@ namespace GraphControl::DX
void CreateWindowSizeDependentResources(); void CreateWindowSizeDependentResources();
bool RenderMain::CanRenderPoint();
bool RunRenderPass(); bool RunRenderPass();
Windows::Foundation::IAsyncAction ^ RunRenderPassAsync(bool allowCancel = true); Windows::Foundation::IAsyncAction ^ RunRenderPassAsync(bool allowCancel = true);
@ -78,7 +80,12 @@ namespace GraphControl::DX
if (m_activeTracingPointerLocation != newValue) if (m_activeTracingPointerLocation != newValue)
{ {
m_activeTracingPointerLocation = newValue; m_activeTracingPointerLocation = newValue;
RunRenderPass();
bool wasPointRendered = m_Tracing;
if (CanRenderPoint() || wasPointRendered)
{
RunRenderPassAsync();
}
} }
} }
} }