モノトーンの伝説日記

OBS Studio と Blackmagic Design が大好き。

<mini> 【Windows アプリ向け】 AppBarHintButton 【ハイコントラスト対応】

 作ったので、公開する。

 割とめんどくさい。IE11 からリバースエンジニアリングしたけど、IE11 は xaml じゃなくて独自レンダリングっぽく、フォーカス枠がきれいに出るんだけど、俺の作ったやつは WQHD 140%/180% スケーリングではフルスクリーンだときれいにでないっぽい。スナップにしたり、100 とか 1000 px と指定するときれいに出るんだけども。今後の課題。

 一応、TabStop はメールアプリとかだと殺してある。ただ、俺的には App キーが付いているキーボードがすべてじゃないので、TabStop したほうがいいとおもんだけども。 よく考えたら Win+Z という統一的な UX があるのでいらないかも。

 xaml

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.ThemeDictionaries>
        <ResourceDictionary
            x:Key="Default">
            <Thickness
                x:Key="AppBarHintButtonBorderThemeThickness">0,1,0,0</Thickness>
            <SolidColorBrush
                x:Key="AppBarHintButtonBackgroundThemeBrush"
                Color="#FF000000" />
            <SolidColorBrush
                x:Key="AppBarHintButtonBorderThemeBrush"
                Color="#FF000000" />
            <SolidColorBrush
                x:Key="AppBarHintButtonDisabledBackgroundThemeBrush"
                Color="#66000000" />
            <SolidColorBrush
                x:Key="AppBarHintButtonDisabledBorderThemeBrush"
                Color="#66000000" />
            <SolidColorBrush
                x:Key="AppBarHintButtonDisabledForegroundThemeBrush"
                Color="#66FFFFFF" />
            <SolidColorBrush
                x:Key="AppBarHintButtonForegroundThemeBrush"
                Color="#FFFFFFFF" />
            <SolidColorBrush
                x:Key="AppBarHintButtonPointerOverBackgroundThemeBrush"
                Color="#B2000000" />
            <SolidColorBrush
                x:Key="AppBarHintButtonPointerOverBorderThemeBrush"
                Color="#B2000000" />
            <SolidColorBrush
                x:Key="AppBarHintButtonPointerOverForegroundThemeBrush"
                Color="#FFFFFFFF" />
            <SolidColorBrush
                x:Key="AppBarHintButtonPressedBackgroundThemeBrush"
                Color="#66000000" />
            <SolidColorBrush
                x:Key="AppBarHintButtonPressedBorderThemeBrush"
                Color="#66000000" />
            <SolidColorBrush
                x:Key="AppBarHintButtonPressedForegroundThemeBrush"
                Color="#FFFFFFFF" />
        </ResourceDictionary>
        <ResourceDictionary
            x:Key="HighContrast">
            <Thickness
                x:Key="AppBarHintButtonBorderThemeThickness">0,1,0,0</Thickness>
            <SolidColorBrush
                x:Key="AppBarHintButtonBackgroundThemeBrush"
                Color="{ThemeResource SystemColorWindowColor}" />
            <SolidColorBrush
                x:Key="AppBarHintButtonBorderThemeBrush"
                Color="{ThemeResource SystemColorHighlightColor}" />
            <SolidColorBrush
                x:Key="AppBarHintButtonDisabledBackgroundThemeBrush"
                Color="{ThemeResource SystemColorWindowColor}" />
            <SolidColorBrush
                x:Key="AppBarHintButtonDisabledBorderThemeBrush"
                Color="{ThemeResource SystemColorHighlightColor}" />
            <SolidColorBrush
                x:Key="AppBarHintButtonDisabledForegroundThemeBrush"
                Color="{ThemeResource SystemColorGrayTextColor}" />
            <SolidColorBrush
                x:Key="AppBarHintButtonForegroundThemeBrush"
                Color="{ThemeResource SystemColorWindowTextColor}" />
            <SolidColorBrush
                x:Key="AppBarHintButtonPointerOverBackgroundThemeBrush"
                Color="{ThemeResource SystemColorHighlightColor}" />
            <SolidColorBrush
                x:Key="AppBarHintButtonPointerOverBorderThemeBrush"
                Color="{ThemeResource SystemColorHighlightColor}" />
            <SolidColorBrush
                x:Key="AppBarHintButtonPointerOverForegroundThemeBrush"
                Color="{ThemeResource SystemColorHighlightTextColor}" />
            <SolidColorBrush
                x:Key="AppBarHintButtonPressedBackgroundThemeBrush"
                Color="{ThemeResource SystemColorButtonFaceColor}" />
            <SolidColorBrush
                x:Key="AppBarHintButtonPressedBorderThemeBrush"
                Color="{ThemeResource SystemColorHighlightColor}" />
            <SolidColorBrush
                x:Key="AppBarHintButtonPressedForegroundThemeBrush"
                Color="{ThemeResource SystemColorButtonTextColor}" />
        </ResourceDictionary>
        <ResourceDictionary
            x:Key="Light">
            <Thickness
                x:Key="AppBarHintButtonBorderThemeThickness">0,1,0,0</Thickness>
            <SolidColorBrush
                x:Key="AppBarHintButtonBackgroundThemeBrush"
                Color="#FFF0F0F0" />
            <SolidColorBrush
                x:Key="AppBarHintButtonBorderThemeBrush"
                Color="#FFF0F0F0" />
            <SolidColorBrush
                x:Key="AppBarHintButtonDisabledBackgroundThemeBrush"
                Color="#66F0F0F0" />
            <SolidColorBrush
                x:Key="AppBarHintButtonDisabledBorderThemeBrush"
                Color="#66F0F0F0" />
            <SolidColorBrush
                x:Key="AppBarHintButtonDisabledForegroundThemeBrush"
                Color="#66000000" />
            <SolidColorBrush
                x:Key="AppBarHintButtonForegroundThemeBrush"
                Color="#FF000000" />
            <SolidColorBrush
                x:Key="AppBarHintButtonPointerOverBackgroundThemeBrush"
                Color="#B2F0F0F0" />
            <SolidColorBrush
                x:Key="AppBarHintButtonPointerOverBorderThemeBrush"
                Color="#B2F0F0F0" />
            <SolidColorBrush
                x:Key="AppBarHintButtonPointerOverForegroundThemeBrush"
                Color="#FF000000" />
            <SolidColorBrush
                x:Key="AppBarHintButtonPressedBackgroundThemeBrush"
                Color="#66F0F0F0" />
            <SolidColorBrush
                x:Key="AppBarHintButtonPressedBorderThemeBrush"
                Color="#66F0F0F0" />
            <SolidColorBrush
                x:Key="AppBarHintButtonPressedForegroundThemeBrush"
                Color="#FF000000" />
        </ResourceDictionary>
    </ResourceDictionary.ThemeDictionaries>

    <Style
        x:Name="AppBarHintButton"
        TargetType="Button">
        <Setter
            Property="Background"
            Value="{ThemeResource AppBarHintButtonBackgroundThemeBrush}" />
        <Setter
            Property="Foreground"
            Value="{ThemeResource AppBarHintButtonForegroundThemeBrush}" />
        <Setter
            Property="BorderBrush"
            Value="{ThemeResource AppBarHintButtonBorderThemeBrush}" />
        <Setter
            Property="BorderThickness"
            Value="{ThemeResource AppBarHintButtonBorderThemeThickness}" />
        <Setter
            Property="Padding"
            Value="3,3,61,3" />
        <Setter
            Property="HorizontalAlignment"
            Value="Stretch" />
        <Setter
            Property="VerticalAlignment"
            Value="Stretch" />
        <Setter
            Property="HorizontalContentAlignment"
            Value="Right" />
        <Setter
            Property="VerticalContentAlignment"
            Value="Bottom" />
        <Setter
            Property="IsTabStop"
            Value="False" />
        <Setter
            Property="ToolTipService.ToolTip"
            Value="Show more commands (Windows logo key+Z, or right-click)" />
        <Setter
            Property="AutomationProperties.Name"
            Value="Show more commands" />
        <Setter
            Property="AutomationProperties.AutomationId"
            Value="AppBarHintButton" />
        <Setter
            Property="AutomationProperties.ItemType"
            Value="AppBar Hint Button" />
        <Setter
            Property="Template">
            <Setter.Value>
                <ControlTemplate
                    TargetType="Button">
                    <Grid>
                        <Grid.Resources>
                            <Style
                                x:Key="AppBarHintButtonEllipseStyle"
                                TargetType="Ellipse">
                                <Setter
                                    Property="HorizontalAlignment"
                                    Value="Left" />
                                <Setter
                                    Property="VerticalAlignment"
                                    Value="Bottom" />
                                <Setter
                                    Property="Margin"
                                    Value="2" />
                                <Setter
                                    Property="Width"
                                    Value="4" />
                                <Setter
                                    Property="Height"
                                    Value="4" />
                            </Style>
                        </Grid.Resources>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup
                                x:Name="CommonStates">
                                <VisualState
                                    x:Name="Normal" />
                                <VisualState
                                    x:Name="PointerOver">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames
                                            Storyboard.TargetName="Border"
                                            Storyboard.TargetProperty="Background">
                                            <DiscreteObjectKeyFrame
                                                KeyTime="0"
                                                Value="{ThemeResource AppBarHintButtonPointerOverBackgroundThemeBrush}" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames
                                            Storyboard.TargetName="Border"
                                            Storyboard.TargetProperty="BorderBrush">
                                            <DiscreteObjectKeyFrame
                                                KeyTime="0"
                                                Value="{ThemeResource AppBarHintButtonPointerOverBorderThemeBrush}" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames
                                            Storyboard.TargetName="E1"
                                            Storyboard.TargetProperty="Fill">
                                            <DiscreteObjectKeyFrame
                                                KeyTime="0"
                                                Value="{ThemeResource AppBarHintButtonPointerOverForegroundThemeBrush}" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames
                                            Storyboard.TargetName="E2"
                                            Storyboard.TargetProperty="Fill">
                                            <DiscreteObjectKeyFrame
                                                KeyTime="0"
                                                Value="{ThemeResource AppBarHintButtonPointerOverForegroundThemeBrush}" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames
                                            Storyboard.TargetName="E3"
                                            Storyboard.TargetProperty="Fill">
                                            <DiscreteObjectKeyFrame
                                                KeyTime="0"
                                                Value="{ThemeResource AppBarHintButtonPointerOverForegroundThemeBrush}" />
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <VisualState
                                    x:Name="Pressed">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames
                                            Storyboard.TargetName="Border"
                                            Storyboard.TargetProperty="Background">
                                            <DiscreteObjectKeyFrame
                                                KeyTime="0"
                                                Value="{ThemeResource AppBarHintButtonPressedBackgroundThemeBrush}" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames
                                            Storyboard.TargetName="Border"
                                            Storyboard.TargetProperty="BorderBrush">
                                            <DiscreteObjectKeyFrame
                                                KeyTime="0"
                                                Value="{ThemeResource AppBarHintButtonPressedBorderThemeBrush}" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames
                                            Storyboard.TargetName="E1"
                                            Storyboard.TargetProperty="Fill">
                                            <DiscreteObjectKeyFrame
                                                KeyTime="0"
                                                Value="{ThemeResource AppBarHintButtonPressedForegroundThemeBrush}" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames
                                            Storyboard.TargetName="E2"
                                            Storyboard.TargetProperty="Fill">
                                            <DiscreteObjectKeyFrame
                                                KeyTime="0"
                                                Value="{ThemeResource AppBarHintButtonPressedForegroundThemeBrush}" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames
                                            Storyboard.TargetName="E3"
                                            Storyboard.TargetProperty="Fill">
                                            <DiscreteObjectKeyFrame
                                                KeyTime="0"
                                                Value="{ThemeResource AppBarHintButtonPressedForegroundThemeBrush}" />
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <VisualState
                                    x:Name="Disabled">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames
                                            Storyboard.TargetName="Border"
                                            Storyboard.TargetProperty="Background">
                                            <DiscreteObjectKeyFrame
                                                KeyTime="0"
                                                Value="{ThemeResource AppBarHintButtonDisabledBackgroundThemeBrush}" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames
                                            Storyboard.TargetName="Border"
                                            Storyboard.TargetProperty="BorderBrush">
                                            <DiscreteObjectKeyFrame
                                                KeyTime="0"
                                                Value="{ThemeResource AppBarHintButtonDisabledBorderThemeBrush}" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames
                                            Storyboard.TargetName="E1"
                                            Storyboard.TargetProperty="Fill">
                                            <DiscreteObjectKeyFrame
                                                KeyTime="0"
                                                Value="{ThemeResource AppBarHintButtonDisabledForegroundThemeBrush}" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames
                                            Storyboard.TargetName="E2"
                                            Storyboard.TargetProperty="Fill">
                                            <DiscreteObjectKeyFrame
                                                KeyTime="0"
                                                Value="{ThemeResource AppBarHintButtonDisabledForegroundThemeBrush}" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames
                                            Storyboard.TargetName="E3"
                                            Storyboard.TargetProperty="Fill">
                                            <DiscreteObjectKeyFrame
                                                KeyTime="0"
                                                Value="{ThemeResource AppBarHintButtonDisabledForegroundThemeBrush}" />
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                            <VisualStateGroup
                                x:Name="FocusStates">
                                <VisualState
                                    x:Name="Focused">
                                    <Storyboard>
                                        <DoubleAnimation
                                            Storyboard.TargetName="FocusVisualWhite"
                                            Storyboard.TargetProperty="Opacity"
                                            To="1"
                                            Duration="0" />
                                        <DoubleAnimation
                                            Storyboard.TargetName="FocusVisualBlack"
                                            Storyboard.TargetProperty="Opacity"
                                            To="1"
                                            Duration="0" />
                                    </Storyboard>
                                </VisualState>
                                <VisualState
                                    x:Name="Unfocused" />
                                <VisualState
                                    x:Name="PointerFocused" />
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Border
                            x:Name="Border"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                            <StackPanel
                                x:Name="Hint"
                                Orientation="Horizontal"
                                Margin="{TemplateBinding Padding}"
                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                                <Ellipse
                                    x:Name="E1"
                                    Style="{StaticResource AppBarHintButtonEllipseStyle}"
                                    Fill="{TemplateBinding Foreground}" />
                                <Ellipse
                                    x:Name="E2"
                                    Style="{StaticResource AppBarHintButtonEllipseStyle}"
                                    Fill="{TemplateBinding Foreground}" />
                                <Ellipse
                                    x:Name="E3"
                                    Style="{StaticResource AppBarHintButtonEllipseStyle}"
                                    Fill="{TemplateBinding Foreground}" />
                            </StackPanel>
                        </Border>
                        <Rectangle
                            x:Name="FocusVisualWhite"
                            IsHitTestVisible="False"
                            Stroke="{ThemeResource FocusVisualWhiteStrokeThemeBrush}"
                            StrokeEndLineCap="Square"
                            StrokeDashArray="1,1"
                            Opacity="0"
                            Margin="2,3,2,2"
                            StrokeDashOffset="1.5" />
                        <Rectangle
                            x:Name="FocusVisualBlack"
                            IsHitTestVisible="False"
                            Stroke="{ThemeResource FocusVisualBlackStrokeThemeBrush}"
                            StrokeEndLineCap="Square"
                            StrokeDashArray="1,1"
                            Opacity="0"
                            Margin="2,3,2,2"
                            StrokeDashOffset="0.5" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

 ちなみに日本語言語だけのアプリや、ローカライズ アプリでは以下をリソースにぶっこむといいです。日本語だけですが。

  • AppBarHintButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name: その他のコマンドの表示
  • AppBarHintButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip: その他のコマンドの表示 (Windows ロゴ キー + Z または右クリック)

ただし、表示はこの限りではありません。IE11 みたいに「アドレス バー」のような具体要素を書くのもありです。

 以上です。