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

View File

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

View File

@ -86,7 +86,12 @@ namespace GraphControl::DX
{
m_Tracing = false;
}
RunRenderPass();
bool wasPointRendered = m_Tracing;
if (CanRenderPoint() || wasPointRendered)
{
RunRenderPassAsync();
}
}
}
@ -95,7 +100,12 @@ namespace GraphControl::DX
if (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)
{
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()
{
// Non async render passes cancel if they can't obtain the lock immediatly

View File

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