しっぽを追いかけて

ぐるぐるしながら考えています

Unity と猫の話題が中心   掲載内容は個人の私見であり、所属組織の見解ではありません

Surface Dial を UWP で使ってみる

※ これは 2016/11/16 時点の情報です

最新版では動作が異なる可能性がありますのでご注意ください

前回 はとりあえず Surface Dial をいじってみましたが、これをさっそく UWP で使ってみたい!

ということで、英語にて公開されている下記 API ドキュメントをもとにかんたんなサンプルアプリを作ってみます

Surface Dial interactions

RadialController class - Windows app development

※ 今回のサンプルコードは下記にアップしています

まずは Surface Dial のメニュー UI に表示するアイコン画像(64 x 64px)を用意します

今回は下記サイトのアイコン画像を利用させていただくことにしました

次に Visual Studio を起動し、UWP のプロジェクト(Blank App)を作成

f:id:matatabi_ux:20161113130016p:plain

途中利用バージョンを聞かれるので、Target、Minimum ともに Windows 10 Anniversary Edition(Build 14393) を選択します

f:id:matatabi_ux:20161113125805p:plain

プロジェクトができたら、とりあえず先ほどのアイコン画像を Assets/CatHand.png として追加します

その後 MainPage.xaml を修正

<Page
    x:Class="SurfaceDialSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:SurfaceDialSample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="2*"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="2*"/>
        </Grid.RowDefinitions>

        <TextBlock Grid.Column="1"
                   Grid.Row="1"
                   Text="Dial Sample"
                   Style="{ThemeResource HeaderTextBlockStyle}"
                   HorizontalAlignment="Center"/>

        <Slider x:Name="DialSlider"
                Grid.Column="1"
                Grid.Row="3"
                Width="480"
                Value="50"
                Minimum="0"
                Maximum="100"/>
        
        <ToggleSwitch x:Name="DialToggle"
                      Grid.Column="1"
                      Grid.Row="4"
                      HorizontalAlignment="Center"/>

    </Grid>
</Page>

タイトルの TextBlock、さらに Slider と ToggleSwitch を追加しただけです

さらにコードビハインド

namespace SurfaceDialSample
{
    /// <summary>
    /// それ自体で使用できる空白ページまたはフレーム内に移動できる空白ページ。
    /// </summary>
    public sealed partial class MainPage : Page
    {
        /// <summary>
        /// Surface Dial 管理クラス
        /// </summary>
        private RadialController control;

        public MainPage()
        {
            this.InitializeComponent();

            this.control = RadialController.CreateForCurrentView();

            // オリジナルのメニューを追加
            var icon = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/CatHand.png"));
            var item = RadialControllerMenuItem.CreateFromIcon("Sample", icon);
            this.control.Menu.Items.Add(item);

            // イベントの購読
            this.control.ButtonClicked += this.OnButtonClicked;
            this.control.RotationChanged += this.OnRotationChanged;
        }

        /// <summary>
        /// Surface Dial ボタンクリックイベントハンドラ
        /// </summary>
        /// <param name="sender">イベント発行者</param>
        /// <param name="args">イベント引数</param>
        private void OnButtonClicked(RadialController sender, RadialControllerButtonClickedEventArgs args)
        {
            this.DialToggle.IsOn = !this.DialToggle.IsOn;
        }

        /// <summary>
        /// Surface Dial 回転イベントハンドラ
        /// </summary>
        /// <param name="sender">イベント発行者</param>
        /// <param name="args">イベント引数</param>
        private void OnRotationChanged(RadialController sender, RadialControllerRotationChangedEventArgs args)
        {
            this.DialSlider.Value = Math.Max(0d, Math.Min(this.DialSlider.Value + args.RotationDeltaInDegrees, 100d));
        }
    }
}

Surface Dial は RadialController によって管理できるので、こちらを CreateForCurrentView() メソッドで取得しています

また、この UWP 専用のカスタムメニューを RadialControllerMenuItem.CreateFromIcon() メソッドで生成し、追加しました

第一引数は表示されるメニュー名、第二引数はアイコン画像(先ほど用意した画像)を指定します

あとはボタンクリックと回転時のイベントハンドラを追加しただけ

Dial のクリックがされたら ToggleSwitch のオン/オフを切り替え、回転に合わせて Slider のつまみが移動するようにしてみました

ここまで実装したらお試し実行

f:id:matatabi_ux:20161113131455g:plain

追加したメニューを選択後、Dial を回転したりクリックすることで画面の表示も反応しましたね