Show / Hide Table of Contents

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:

  1. 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.
  2. 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 Visuals, 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.

A diagram of the "nub" and "knob" parts of the Haptic Knob.  The knob is the portion that rotates; the nub is the part that the user may grab.

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 Visuals 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.

Back to top Generated by DocFX