しっぽを追いかけて

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

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

Xamarin.Forms で Microsoft Band のテーマカラーを設定する

Microsoft Band のテーマカラーが取得できたので、今度は設定を試してみます

ソースコードの一式は下記にあります!

細かい実装などはこちらを参照ください

github.com

※ 順次改修していく予定なので、この記事の内容が現時点のソースより古い可能性があります


まずは iOSAndroidWindows Phone の NativePersonalizationManager を改修

/// <summary>
/// iOS 用着せ替え管理クラス
/// </summary>
public class NativeBandPersonalizationManager : IBandPersonalizationImageManager
{
    ~ 中略 ~

    /// <summary>
    /// テーマカラーの設定
    /// </summary>
    /// <param name="theme">テーマ情報</param>
    /// <param name="cancel">中断トークン</param>
    /// <returns>Task</returns>
    [Obsolete("CancellationToken is not supported for iOS.")]
    public Task SetThemeAsync(BandTheme theme, CancellationToken cancel)
    {
        return this.SetThemeAsync(theme);
    }

    /// <summary>
    /// テーマカラーの設定
    /// </summary>
    /// <param name="theme">テーマ情報</param>
    /// <returns>Task</returns>
    public Task SetThemeAsync(BandTheme theme)
    {
        return Native.Personalization.BandPersonalizationManagerExtensions.SetThemeTaskAsync(
            this.manager, NativeBandThemeConvert.ToNative(theme));
    }
}

といっても基本 Binding された API を呼び出すだけ

次に ViewModel

/// <summary>
/// 着せ替え設定 ViewModel
/// </summary>
public class PersonalizeViewModel : BindableBase
{
    ~ 中略 ~

    /// <summary>
    /// コンストラクタ
    /// </summary>
    /// <param name="client">接続クライアント</param>
    [InjectionConstructor]
    public PersonalizeViewModel(IBandClient client, IBandPersonalizationImageManager manager)
    {
        this.IsBusy = true;
        this.client = client;
        this.manager = manager;

        this.PullCommand = DelegateCommand.FromAsyncHandler(this.Pull);
        this.ApplyCommand = DelegateCommand.FromAsyncHandler(this.Apply);

        this.BaseColor.SelecedIndex = 1;
        this.HighContrastColor.Color = "#FF9966ff";
        this.HighlightColor.Color = "#FF9966ff";
        this.LowlightColor.Color = "#FF6633cc";
        this.MutedColor.Color = "#FF663399";

        this.SecondaryTextColor.SelecedIndex = 5;
        this.baseColor.PropertyChanged += this.OnBaseColorChanged;

        this.IsBusy = false;
    }

    ~ 中略 ~

    /// <summary>
    /// 配色文字列を BandColor に変換する
    /// </summary>
    /// <param name="colorString">配色文字列を</param>
    /// <returns>BandColor</returns>
    private static BandColor StringToColor(string colorString)
    {
        var color = (Color)ColorConverter.ConvertFrom(colorString);
        color.ToString();
        return new BandColor(
            (byte)(color.R * 255d),
            (byte)(color.G * 255d),
            (byte)(color.B * 255d));
    }

    /// <summary>
    /// 基本色変更イベントハンドラ
    /// </summary>
    /// <param name="sender">イベント発行者</param>
    /// <param name="e">イベント引数</param>
    private void OnBaseColorChanged(object sender, PropertyChangedEventArgs e)
    {
        if (!e.PropertyName.Equals("SelecedIndex"))
        {
            return;
        }
        switch (this.baseColor.SelecedIndex)
        {
            case 0:
                this.HighContrastColor.Color = "#FF6699ff";
                this.HighlightColor.Color = "#FF6699ff";
                this.LowlightColor.Color = "#FF3366cc";
                this.MutedColor.Color = "#FF336699";
                break;

            case 1:
                this.HighContrastColor.Color = "#FF9966ff";
                this.HighlightColor.Color = "#FF9966ff";
                this.LowlightColor.Color = "#FF6633cc";
                this.MutedColor.Color = "#FF663399";
                break;

            case 2:
                this.HighContrastColor.Color = "#FFff6699";
                this.HighlightColor.Color = "#FFff6699";
                this.LowlightColor.Color = "#FFcc3366";
                this.MutedColor.Color = "#FF993366";
                break;

            case 3:
                this.HighContrastColor.Color = "#FF66ff99";
                this.HighlightColor.Color = "#FF66ff99";
                this.LowlightColor.Color = "#FF33cc66";
                this.MutedColor.Color = "#FF339966";
                break;

            case 4:
                this.HighContrastColor.Color = "#FFffcc33";
                this.HighlightColor.Color = "#FFffcc33";
                this.LowlightColor.Color = "#FFff9900";
                this.MutedColor.Color = "#FFcc9900";
                break;

            case 5:
                this.HighContrastColor.Color = "#FFcccccc";
                this.HighlightColor.Color = "#FFcccccc";
                this.LowlightColor.Color = "#FF999999";
                this.MutedColor.Color = "#FF666666";
                break;

            case 6:
                this.HighContrastColor.Color = "#FF33ffff";
                this.HighlightColor.Color = "#FF33ffff";
                this.LowlightColor.Color = "#FF00ccff";
                this.MutedColor.Color = "#FF0099cc";
                break;

            case 7:
                this.HighContrastColor.Color = "#FFff9933";
                this.HighlightColor.Color = "#FFff9933";
                this.LowlightColor.Color = "#FFff6600";
                this.MutedColor.Color = "#FFcc6600";
                break;

            case 8:
                this.HighContrastColor.Color = "#FFff66ff";
                this.HighlightColor.Color = "#FFff66ff";
                this.LowlightColor.Color = "#FFcc33cc";
                this.MutedColor.Color = "#FF993399";
                break;

            case 9:
                this.HighContrastColor.Color = "#FFccff33";
                this.HighlightColor.Color = "#FFccff33";
                this.LowlightColor.Color = "#FF99cc00";
                this.MutedColor.Color = "#FF669900";
                break;
        }
    }

    /// <summary>
    /// 配色コンバーター
    /// </summary>
    private static ColorTypeConverter ColorConverter = new ColorTypeConverter();

    /// <summary>
    /// 設定適用
    /// </summary>
    /// <returns>Task</returns>
    private async Task Apply()
    {
        this.IsBusy = true;
        var theme = new BandTheme()
        {
            Base = StringToColor(this.BaseColor.Color),
            HighContrast = StringToColor(this.HighContrastColor.Color),
            Highlight = StringToColor(this.HighlightColor.Color),
            Lowlight = StringToColor(this.LowlightColor.Color),
            Muted = StringToColor(this.MutedColor.Color),
            SecondaryText = StringToColor(this.SecondaryTextColor.Color),
        };

        await this.manager.SetThemeAsync(theme);

        this.IsBusy = false;
    }
}

ちょっと面倒ですが、基本色が変更されたら関連する配色も同系色が選ばれるように

    /// <summary>
    /// 基本色変更イベントハンドラ
    /// </summary>
    /// <param name="sender">イベント発行者</param>
    /// <param name="e">イベント引数</param>
    private void OnBaseColorChanged(object sender, PropertyChangedEventArgs e)
    {
        if (!e.PropertyName.Equals("SelecedIndex"))
        {
            return;
        }
        switch (this.baseColor.SelecedIndex)
        {
            case 0:
                this.HighContrastColor.Color = "#FF6699ff";
                this.HighlightColor.Color = "#FF6699ff";
                this.LowlightColor.Color = "#FF3366cc";
                this.MutedColor.Color = "#FF336699";
                break;

            case 1:
                this.HighContrastColor.Color = "#FF9966ff";
                this.HighlightColor.Color = "#FF9966ff";
                this.LowlightColor.Color = "#FF6633cc";
                this.MutedColor.Color = "#FF663399";
                break;

            case 2:
                this.HighContrastColor.Color = "#FFff6699";
                this.HighlightColor.Color = "#FFff6699";
                this.LowlightColor.Color = "#FFcc3366";
                this.MutedColor.Color = "#FF993366";
                break;

            case 3:
                this.HighContrastColor.Color = "#FF66ff99";
                this.HighlightColor.Color = "#FF66ff99";
                this.LowlightColor.Color = "#FF33cc66";
                this.MutedColor.Color = "#FF339966";
                break;

            case 4:
                this.HighContrastColor.Color = "#FFffcc33";
                this.HighlightColor.Color = "#FFffcc33";
                this.LowlightColor.Color = "#FFff9900";
                this.MutedColor.Color = "#FFcc9900";
                break;

            case 5:
                this.HighContrastColor.Color = "#FFcccccc";
                this.HighlightColor.Color = "#FFcccccc";
                this.LowlightColor.Color = "#FF999999";
                this.MutedColor.Color = "#FF666666";
                break;

            case 6:
                this.HighContrastColor.Color = "#FF33ffff";
                this.HighlightColor.Color = "#FF33ffff";
                this.LowlightColor.Color = "#FF00ccff";
                this.MutedColor.Color = "#FF0099cc";
                break;

            case 7:
                this.HighContrastColor.Color = "#FFff9933";
                this.HighlightColor.Color = "#FFff9933";
                this.LowlightColor.Color = "#FFff6600";
                this.MutedColor.Color = "#FFcc6600";
                break;

            case 8:
                this.HighContrastColor.Color = "#FFff66ff";
                this.HighlightColor.Color = "#FFff66ff";
                this.LowlightColor.Color = "#FFcc33cc";
                this.MutedColor.Color = "#FF993399";
                break;

            case 9:
                this.HighContrastColor.Color = "#FFccff33";
                this.HighlightColor.Color = "#FFccff33";
                this.LowlightColor.Color = "#FF99cc00";
                this.MutedColor.Color = "#FF669900";
                break;
        }
    }

PropertyChanged のイベントを拾って分岐処理させています

また、選択された配色を BandColor に変換して PersonalizationManager.SetThemeAsync でテーマカラーを設定する処理も追加しました

    /// <summary>
    /// 設定適用
    /// </summary>
    /// <returns>Task</returns>
    private async Task Apply()
    {
        this.IsBusy = true;
        var theme = new BandTheme()
        {
            Base = StringToColor(this.BaseColor.Color),
            HighContrast = StringToColor(this.HighContrastColor.Color),
            Highlight = StringToColor(this.HighlightColor.Color),
            Lowlight = StringToColor(this.LowlightColor.Color),
            Muted = StringToColor(this.MutedColor.Color),
            SecondaryText = StringToColor(this.SecondaryTextColor.Color),
        };

        await this.manager.SetThemeAsync(theme);

        this.IsBusy = false;
    }

これでおためし実行

f:id:matatabi_ux:20150501214551p:plain

青いテーマカラーを選択して Apply、その後 Band の方の画面遷移させると

f:id:matatabi_ux:20150501214639p:plain

ちゃんと適用されたっぽいですね