Updating from TanvasTouch .NET API version 4 to version 5
This document describes:
- The differences between versions 4 and 5 of the TanvasTouch .NET API.
- How to update an application using version 4 of the .NET API to version 5.
The .NET API and Engine now use screen coordinates
Version 5 of the TanvasTouch Engine introduces two new features:
- Before version 5, the haptic monitor had to be the main display. In version 5, the haptic monitor may be any display in a multi-display configuration.
- Before version 5, the haptic monitor had to be in its native (landscape) orientation. In version 5, the haptic monitor may be used in native orientation or any 90-degree rotation thereof.
The TanvasTouch Engine before version 5 did not specify a coordinate system for haptic resources, but it was assumed that haptic resources were specified in screen coordinates. Version 5 of the TanvasTouch Engine makes this assumption explicit and builds these new features on that assumption.
Under Windows 10, the TanvasTouch Engine runs as a "per-monitor DPI-aware" application, which means that it receives monitor information using the native pixel dimensions for each monitor. For more information on Windows DPI awareness modes, see https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows.
Guidelines for updating your applications
Update the Tanvas.TanvasTouch
and Tanvas.TanvasTouch.WpfUtilities
packages to version 5
The Tanvas.TanvasTouch
package must be updated to the latest version 5 release (currently 5.0.0). If you use Tanvas.TanvasTouch.WpfUtilities
, you need to update that as well.
Use per-monitor DPI awareness mode in your application
To use the version 5 API, your application must also be per-monitor DPI-aware. To do this, add the following snippet to your application's app.manifest
:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
</windowsSettings>
</application>
The <dpiAware>
and <dpiAwareness>
elements can be added to an existing <windowsSettings>
element. If you need to support Windows 10 versions older than build 1703, you can use PerMonitor
instead of PerMonitorV2
.
Position and size haptic resources in screen coordinates
When positioning haptic resources over WPF Visual
s, you will need to specify the coordinates of those haptic resources in screen coordinates, not window coordinates. The Visual.PointToScreen
method, which is part of WPF, can be used to do this.
Example: Haptic Knob
The Haptic Knob application, which is part of the TanvasTouch Windows SDK, can be used to illustrate the above guidelines. The Haptic Knob source code is made available under the BSD 3-Clause License and can be freely reused in most situations.
The Haptic Knob uses TanvasTouchViewTracker
to provide a haptic view whose position and size is kept in sync with the window. The Haptic Knob updates the positions of haptic sprites when the view is moved or resized:
private void OnViewGeometryChanged(TView View)
{
AlignRotationHaptics();
AlignNubHaptics();
}
The AlignRotationHaptics
and AlignNubHaptics
methods correspond to parts of the Haptic Knob that, in the codebase, are called the knob and the nub.
AlignNubHaptics
positions a haptic sprite over the center of the nub. To do this, it calculates the center of the nub in haptic view space and moves the top-left corner of the haptic sprite so that the center of the sprite and nub coincide.
private void AlignNubHaptics()
{
if (NubHaptics == null)
{
return;
}
// Get the center point of the nub in haptic view space.
var nubCenterOffset = new Point(NubElement.ActualWidth / 2.0, NubElement.ActualHeight / 2.0);
var nubCenterPoint = NubElement.PointToHapticView(nubCenterOffset, TrackedTView.View);
// Now position the sprite so that its center is coincident with the nub's center.
NubHaptics.X = (float) (nubCenterPoint.X - (NubHaptics.Width / 2.0));
NubHaptics.Y = (float) (nubCenterPoint.Y - (NubHaptics.Height / 2.0));
}
AlignNubHaptics
makes use of an extension method on Visual
s named PointToHapticView
, which converts a point in a Visual
to its matching point in a haptic view. It is defined as follows:
public static class FrameworkElementHapticsExtensions
{
/// <summary>
/// Converts a Point in the coordinate system of a Visual into a Point in a TView.
/// </summary>
/// <param name="visual">The Visual containing the point.</param>
/// <param name="point">The point to convert.</param>
/// <param name="hapticView">The target TView.</param>
/// <returns></returns>
public static Point PointToHapticView(this Visual visual, Point point, TView hapticView)
{
// Haptic views exist in screen space. To convert a point in a Visual to haptic view space,
// we ask the Visual to convert that point to screen space and then present the converted point
// relative to the selected haptic view.
var screenSpace = visual.PointToScreen(point);
return new Point(screenSpace.X - hapticView.X, screenSpace.Y - hapticView.Y);
}
}
Haptic textures and sprites must be manually resized on DPI change
Version 5 of the TanvasTouch Engine does not automatically resize haptic textures on DPI change. The reason is that upsampling friction maps as if they were images usually produces an undesirable result. For more information on designing and enlarging haptic textures, visit https://tanvas.co/resources/tutorials/generating-haptic-textures-for-multiple-dpis.
Windows 10 offers only 100% and 125% zoom for the Mimo Vue HD with TanvasTouch haptic display, which is not too large a change for most visual elements. In many cases, this size difference can be dealt with making a haptic sprite that is large enough for your visual element at 125% and using that same sprite at 100%. However, if you need more control, you will need to:
- Create textures sized for 100%, 125%, and any other zoom factors that you may want to handle.
- Add an event handler for the
Window.DpiChanged
event that loads new textures and resizes sprites according to the new DPI.
The Haptic Knob application handles Window.DpiChanged
by uploading textures sized for the new DPI as follows:
private void KnobWindow_DpiChanged(object sender, DpiChangedEventArgs e)
{
if (e.Source == KnobWindow)
{
TeardownHaptics();
SetupHaptics(e.NewDpi);
}
}
Future work
The guidelines in this document represent Tanvas' current best advice for handling multi-display configurations at different zoom levels. Future 5.x versions may introduce a XAML component for handling most, if not all, of the work described above.