RadialController RadialController RadialController RadialController RadialController Class

Definition

Represents a wheel input device or accessory such as the Surface Dial.

Note

Wheel devices are a new category of input device (supported in Windows 10, version 1607 and newer).

Surface Dial with Surface Studio and Pen

With a form factor based on a rotate action (or gesture), the Surface Dial is intended as a secondary, multi-modal input device that complements input from a primary device. In most cases, the device is manipulated by a user's non-dominant hand while performing a task with their dominant hand (such as inking with a pen). It is not designed for precision pointer input (like touch, pen, or mouse).

The Surface Dial also supports both a press and hold action and a click action. Press and hold has a single function: display a menu of commands. If the menu is active, the rotate and click input is processed by the menu. Otherwise, the input is passed to your app for processing.

The RadialController and related APIs (see end of topic) enable you to customize both the integrated command menu and the interaction experience supported by your app.

public : sealed class RadialController : IRadialController, IRadialController2
struct winrt::Windows::UI::Input::RadialController : IRadialController, IRadialController2
public sealed class RadialController : IRadialController, IRadialController2
Public NotInheritable Class RadialController Implements IRadialController, IRadialController2
// This class does not provide a public constructor.
Attributes
Windows 10 requirements
Device family
Windows 10 Anniversary Edition (introduced v10.0.14393.0)
API contract
Windows.Foundation.UniversalApiContract (introduced v3)

Examples

In this example, we add a custom tool to the Surface Dial menu and declare the RadialController input handlers.

  1. First, we create a reference to the RadialController object for the Surface Dial (myController) by calling CreateForCurrentView.
  2. We then create an instance of a RadialControllerMenuItem (myItem) by calling RadialControllerMenuItem.CreateFromIcon.
  3. Next, we append that item to the collection of menu items.
  4. We declare the input event handlers (ButtonClicked and RotationChanged ) for the RadialController object.
  5. Finally, we define the event handlers.
public sealed partial class MainPage : Page
 {
     RadialController myController;

     public MainPage()
     {
         this.InitializeComponent();
         // Create a reference to the RadialController.
         myController = RadialController.CreateForCurrentView();

         // Create an icon for the custom tool.
         RandomAccessStreamReference icon =
           RandomAccessStreamReference.CreateFromUri(
             new Uri("ms-appx:///Assets/StoreLogo.png"));

         // Create a menu item for the custom tool.
         RadialControllerMenuItem myItem =
           RadialControllerMenuItem.CreateFromIcon("Sample", icon);

         // Add the custom tool to the RadialController menu.
         myController.Menu.Items.Add(myItem);

         // Declare input handlers for the RadialController.
         myController.ButtonClicked += MyController_ButtonClicked;
         myController.RotationChanged += MyController_RotationChanged;
     }

     // Handler for rotation input from the RadialController.
     private void MyController_RotationChanged(RadialController sender,
       RadialControllerRotationChangedEventArgs args)
     {
         if (RotationSlider.Value + args.RotationDeltaInDegrees > 100)
         {
             RotationSlider.Value = 100;
             return;
         }
         else if (RotationSlider.Value + args.RotationDeltaInDegrees < 0)
         {
             RotationSlider.Value = 0;
             return;
         }
         RotationSlider.Value += args.RotationDeltaInDegrees;
     }

     // Handler for click input from the RadialController.
     private void MyController_ButtonClicked(RadialController sender,
       RadialControllerButtonClickedEventArgs args)
     {
         ButtonToggle.IsOn = !ButtonToggle.IsOn;
     }
 }

In the initialization function shown here, we declare the various input event handlers for the RadialController object.

// Create and configure our radial controller.
private void InitializeController() 
{
    // Create a reference to the RadialController.
    radialController = RadialController.CreateForCurrentView();
    // Set rotation resolution to 1 degree of sensitivity.
    radialController.RotationResolutionInDegrees = 1;

    // Declare input handlers for the RadialController.
    radialController.ButtonClicked += (sender, args) =>
    { RadialController_ButtonClicked(sender, args); };
    radialController.RotationChanged += (sender, args) =>
    { RadialController_RotationChanged(sender, args); };

    radialController.ControlAcquired += (sender, args) =>
    { RadialController_ControlAcquired(sender, args); };
    radialController.ControlLost += (sender, args) =>
    { RadialController_ControlLost(sender, args); };
    radialController.ScreenContactStarted += (sender, args) =>
    { RadialController_ScreenContactStarted(sender, args); };
    radialController.ScreenContactContinued += (sender, args) =>
    { RadialController_ScreenContactContinued(sender, args); };
    radialController.ScreenContactEnded += (sender, args) =>
    { RadialController_ScreenContactEnded(sender, args); };
    AddToLog("Input handlers created");

    // Create the custom menu items.
    CreateMenuItems();
    // Specify the menu items.
    ConfigureMenu();
}

In the ButtonClicked handler, the interaction sets the state of a toggle button to checked or unchecked.

// Occurs when the wheel device is pressed and then released 
// while a customRadialController tool is active.
// NOTE: Your app does not receive this event when the RadialController 
// menu is active or a built-in tool is active
// Send click input to toggle button of active region.
private void RadialController_ButtonClicked(RadialController sender,
  RadialControllerButtonClickedEventArgs args)
{
    toggles[activeMenuItemIndex].IsOn = !toggles[activeMenuItemIndex].IsOn;
}

In the RotationChanged handler, the interaction modifies the value of a slider.

// Occurs when the wheel device is rotated while a custom 
// RadialController tool is active.
// NOTE: Your app does not receive this event when the RadialController 
// menu is active or a built-in tool is active
// Send rotation input to slider of active region.
private void RadialController_RotationChanged(RadialController sender,
  RadialControllerRotationChangedEventArgs args)
{
    Slider slider = sliders[activeMenuItemIndex];
    if (slider.Value + args.RotationDeltaInDegrees > 100)
    {
        slider.Value = 100;
        return;
    }
    else if (slider.Value + args.RotationDeltaInDegrees < 0)
    {
        slider.Value = 0;
        return;
    }
    slider.Value += args.RotationDeltaInDegrees;
    AddToLog("\nRotation: " + sliders[activeMenuItemIndex].Name + " value changed to " + slider.Value);
}

Properties

Menu Menu Menu Menu Menu

Gets a reference to the menu associated with the RadialController object.

RotationResolutionInDegrees RotationResolutionInDegrees RotationResolutionInDegrees RotationResolutionInDegrees RotationResolutionInDegrees

Gets or sets the minimum rotational value required for the RadialController object to fire a RotationChanged event.

UseAutomaticHapticFeedback UseAutomaticHapticFeedback UseAutomaticHapticFeedback UseAutomaticHapticFeedback UseAutomaticHapticFeedback

Gets or sets whether haptic feedback is enabled on the wheel device for each RotationChanged event fired by the RadialController.

Methods

CreateForCurrentView() CreateForCurrentView() CreateForCurrentView() CreateForCurrentView() CreateForCurrentView()

Instantiates a RadialController object for the wheel device and binds it to the active application.

IsSupported() IsSupported() IsSupported() IsSupported() IsSupported()

Retrieves a value that indicates whether wheel devices are supported by the system.

Events

ButtonClicked ButtonClicked ButtonClicked ButtonClicked ButtonClicked

Occurs when the wheel device is pressed and then released while a custom RadialController tool is active.

Your app does not receive this event when:

Note

When a time threshold is crossed, click becomes a press and hold action. In this case, the integrated menu of contextual app commands associated with the RadialController object is displayed, and subsequent rotate and click events are processed by the menu.

ButtonHolding ButtonHolding ButtonHolding ButtonHolding ButtonHolding

Occurs when the user presses and holds down the wheel device.

ButtonPressed ButtonPressed ButtonPressed ButtonPressed ButtonPressed

Occurs when the wheel device is pressed.

ButtonReleased ButtonReleased ButtonReleased ButtonReleased ButtonReleased

Occurs when the wheel device is pressed and then released.

ControlAcquired ControlAcquired ControlAcquired ControlAcquired ControlAcquired

Occurs when a custom RadialController tool (defined by an app) is selected from the menu, or when an app associated with the RadialController object is brought to the foreground while a custom RadialController tool is active.

ControlLost ControlLost ControlLost ControlLost ControlLost

Occurs while a custom RadialController tool (defined by an app) is active, and either the app associated with the RadialController object is sent to the background, or the user activates the RadialController menu.

RotationChanged RotationChanged RotationChanged RotationChanged RotationChanged

Occurs when the wheel device is rotated while a custom RadialController tool is active.

Your app does not receive this event when:

ScreenContactContinued ScreenContactContinued ScreenContactContinued ScreenContactContinued ScreenContactContinued

Occurs only when the wheel device is moved while in contact with the digitizer surface, and a custom RadialController tool is active.

Your app does not receive this event when:

Tip

In addition to the default press and hold menu experience, the Surface Dial can also be placed directly on the screen of the Surface Studio. This enables a special "on-screen" menu.

By detecting both the contact location and bounds of the Surface Dial, the system can handle occlusion by the device and display a larger version of the menu that wraps around the outside of the Dial. This same info can also be used by your app to adapt the UI for both the presence of the device and its anticipated usage, such as the placement of the user's hand and arm.

This event occurs after ScreenContactStarted and stops on ScreenContactEnded.

ScreenContactEnded ScreenContactEnded ScreenContactEnded ScreenContactEnded ScreenContactEnded

Occurs when a wheel device that is in contact with the digitizer surface is removed (or is no longer detected), and a custom RadialController tool is active.

Your app does not receive this event when:

Tip

In addition to the default press and hold menu experience, the Surface Dial can also be placed directly on the screen of the Surface Studio. This enables a special "on-screen" menu.

By detecting both the contact location and bounds of the Surface Dial, the system can handle occlusion by the device and display a larger version of the menu that wraps around the outside of the Dial. This same info can also be used by your app to adapt the UI for both the presence of the device and its anticipated usage, such as the placement of the user's hand and arm.

This event occurs after ScreenContactStarted.

ScreenContactStarted ScreenContactStarted ScreenContactStarted ScreenContactStarted ScreenContactStarted

Occurs when initial contact is detected between a wheel device and the digitizer surface, and a custom RadialController tool is active.

Your app does not receive this event when:

Tip

In addition to the default press and hold menu experience, the Surface Dial can also be placed directly on the screen of the Surface Studio. This enables a special "on-screen" menu.

By detecting both the contact location and bounds of the Surface Dial, the system can handle occlusion by the device and display a larger version of the menu that wraps around the outside of the Dial. This same info can also be used by your app to adapt the UI for both the presence of the device and its anticipated usage, such as the placement of the user's hand and arm.

See Also