Interações de gamepad e de controle remoto

imagem de teclado e gamepad

Muitas experiências de interação são compartilhadas entre gamepad, controle remoto e teclado

Crie experiências de interação em seus aplicativos do Windows que garantam que seu aplicativo seja utilizável e acessível por meio dos tipos de entrada tradicionais de computadores, laptops e tablets (mouse, teclado, toque e assim por diante), bem como os tipos de entrada típicos da experiência de TV e Xbox de 10 pés , como o gamepad e o controle remoto.

Consulte Projetando para Xbox e TV para obter diretrizes gerais de design sobre aplicativos do Windows na experiência de 3 metros .

Visão geral

Neste tópico, discutiremos o que você deve considerar em seu design de interação (ou o que você não faz, se a plataforma cuidar dela para você) e fornecer diretrizes, recomendações e sugestões para criar aplicativos do Windows que sejam agradáveis de usar, independentemente do dispositivo, tipo de entrada ou habilidades e preferências do usuário.

Resumindo, seu aplicativo deve ser tão intuitivo e fácil de usar no ambiente de 2 pés quanto no ambiente de 3 metros (e vice-versa ). Dê suporte aos dispositivos preferenciais do usuário, torne o foco da interface do usuário claro e inconfundível, organize o conteúdo para que a navegação seja consistente e previsível e dê aos usuários o caminho mais curto possível para o que eles querem fazer.

Observação

A maioria dos snippets de código neste tópico está em XAML/C#; no entanto, os princípios e conceitos se aplicam a todos os aplicativos do Windows. Se você estiver desenvolvendo um aplicativo WINDOWS HTML/JavaScript para Xbox, marcar a excelente biblioteca TVHelpers no GitHub.

Otimizar para experiências de 2 pés e 10 pés

No mínimo, recomendamos que você teste seus aplicativos para garantir que eles funcionem bem em cenários de 2 pés e 3 metros e que todas as funcionalidades sejam detectáveis e acessíveis para o gamepad xbox e o controle remoto.

Aqui estão algumas outras maneiras de otimizar seu aplicativo para uso em experiências de 2 pés e 10 pés e com todos os dispositivos de entrada (cada um dos links para a seção apropriada neste tópico).

Observação

Como os gamepads e controles remotos do Xbox dão suporte a muitos comportamentos e experiências de teclado do Windows, essas recomendações são apropriadas para ambos os tipos de entrada. Consulte Interações de teclado para obter informações mais detalhadas do teclado.

Recurso Descrição
Interação e navegação de foco do plano XY A navegação de foco XY permite que o usuário navegue pela interface do usuário do aplicativo. No entanto, isso limita o usuário a navegar para cima, para baixo, para a esquerda e direita. Recomendações para lidar com isso e outras considerações são descritas nesta seção.
Modo do mouse A navegação de foco XY não é prática ou mesmo possível para alguns tipos de aplicativos, como mapas ou aplicativos de desenho e pintura. Nesses casos, o modo de mouse permite que os usuários naveguem livremente com um gamepad ou controle remoto, assim como um mouse em um computador.
Visual de foco O visual de foco é uma borda que realça o elemento de interface do usuário focado no momento. Isso ajuda o usuário a identificar rapidamente a interface do usuário com a qual ele está navegando ou interagindo.
Envolvimento de foco O envolvimento de foco exige que o usuário pressione o botão A/Selecionar em um gamepad ou controle remoto quando um elemento de interface do usuário tem foco para interagir com ele.
Botões de hardware O gamepad e o controle remoto fornecem botões e configurações muito diferentes.

Gamepad e controle remoto

Assim como o teclado e o mouse estão para o computador e o touch está para o telefone e o tablet, o gamepad e o controle remoto são os principais dispositivos de entrada para a experiência de 3 metros. Esta seção apresenta os botões de hardware e o que eles fazem. Em Interação e navegação de foco do plano XY e Modo de mouse, você aprenderá como otimizar seu aplicativo ao usar esses dispositivos de entrada.

A qualidade do comportamento do gamepad e do controle remoto que você obtém de imediato depende do nível de suporte ao teclado em seu aplicativo. Uma boa maneira de garantir que seu aplicativo funcione bem com gamepad/controle remoto é se certificar de que ele funcione bem com o teclado no computador e, seguida, testá-lo com gamepad/controle remoto para encontrar pontos fracos na sua interface do usuário.

Botões de hardware

Neste documento, os botões serão chamada pelos nomes fornecidos no diagrama a seguir.

Diagrama de botões do controle remoto e do gamepad

Como você pode ver no diagrama, há alguns botões que são compatíveis com o gamepad mas não com o controle remoto, e vice-versa. Embora você possa usar botões compatíveis apenas com um dispositivo de entrada para tornar a navegação da interface do usuário mais rápida, lembre-se de que usá-los para interações críticas pode criar uma situação em que o usuário não consegue interagir com determinadas partes da interface do usuário.

A tabela a seguir lista todos os botões de hardware compatíveis com aplicativos do Windows e qual dispositivo de entrada dá suporte a eles.

Botão Gamepad Controle remoto
Botão A/Selecionar Sim Sim
Botão B/Voltar Sim Sim
Direcional (D-pad) Sim Sim
Botão Menu Sim Sim
Botão Exibir Sim Sim
Botões X e Y Sim Não
Joystick esquerdo Sim Não
Joystick direito Sim Não
Gatilhos para esquerda e direita Sim Não
Complementos para esquerda e direita Sim Não
Botão OneGuide Não Sim
Botão de volume Não Sim
Botão Canal Não Sim
Botões de controle de mídia Não Sim
Botão silenciar Não Sim

Suporte interno para botões

A UWP mapeia automaticamente o comportamento de entrada de teclado existente para o gamepad e a entrada de controle remoto. A tabela a seguir lista esses mapeamentos internos.

Keyboard Gamepad/controle remoto
Teclas de direção D-pad (também joystick esquerdo no gamepad)
Barra de espaços Botão A/Selecionar
Digite Botão A/Selecionar
Escape Botão B/Voltar*

*Quando nem os eventos KeyDown nem KeyUp para o botão B são manipulados pelo aplicativo, o evento SystemNavigationManager.BackRequested será acionado, o que deve resultar em navegação inativa dentro do aplicativo. No entanto, você precisa implementar isso por conta própria, como no seguinte trecho de código:

// This code goes in the MainPage class

public MainPage()
{
    this.InitializeComponent();

    // Handling Page Back navigation behaviors
    SystemNavigationManager.GetForCurrentView().BackRequested +=
        SystemNavigationManager_BackRequested;
}

private void SystemNavigationManager_BackRequested(
    object sender,
    BackRequestedEventArgs e)
{
    if (!e.Handled)
    {
        e.Handled = this.BackRequested();
    }
}

public Frame AppFrame { get { return this.Frame; } }

private bool BackRequested()
{
    // Get a hold of the current frame so that we can inspect the app back stack
    if (this.AppFrame == null)
        return false;

    // Check to see if this is the top-most page on the app back stack
    if (this.AppFrame.CanGoBack)
    {
        // If not, set the event to handled and go back to the previous page in the
        // app.
        this.AppFrame.GoBack();
        return true;
    }
    return false;
}

Observação

Se o botão B é usado para voltar, então não exiba um botão Voltar na interface do usuário. Se você estiver usando um Modo de exibição de navegação, o botão Voltar ficará oculto automaticamente. Para obter mais informações sobre navegação com versões anteriores, consulte Histórico de navegação e navegação com versões anteriores para aplicativos do Windows.

Os aplicativos do Windows no Xbox One também dão suporte ao pressionamento do botão Menu para abrir menus de contexto. Para obter mais informações, consulte CommandBar e ContextFlyout.

Suporte a acelerador

Botões aceleradores são aqueles que podem ser usados para acelerar a navegação por meio de uma interface do usuário. No entanto, esses botões podem ser exclusivos para um determinado dispositivo de entrada, sendo assim, tenha em mente que nem todos os usuários poderão usar essas funções. Na verdade, o gamepad é atualmente o único dispositivo de entrada que dá suporte a funções de acelerador para aplicativos do Windows no Xbox One.

A tabela a seguir lista o suporte a acelerador incorporado à UWP, bem como o que você pode implementar por conta própria. Utilize esses comportamentos em sua interface do usuário personalizada para oferecer uma experiência de usuário consistente e amigável.

Interação Teclado/Mouse Gamepad Incorporado em: Recomendado para:
Page up/Page down Page up/Page down Gatilhos esquerdo/direito CalendarView, ListBox, ListViewBase, ListView, ScrollViewer, Selector, LoopingSelector, ComboBox, FlipView Exibições que dão suporte à rolagem vertical
Página esquerda/direita Nenhum Botões superiores esquerdo/direito ListBox, ListViewBase, ListView, ScrollViewer, Selector, LoopingSelector, FlipView Exibições que dão suporte à rolagem horizontal
Ampliar/reduzir Ctrl +/- Gatilhos esquerdo/direito Nenhum ScrollViewer, exibições que dão suporte a ampliação e redução
Abrir/fechar painel de navegação Nenhum Visualizar Nenhum Painéis de navegação
Pesquisar Nenhum Botão Y Nenhum Atalho para a função de pesquisa principal no aplicativo
Abrir menu de contexto Clique com o botão direito em Botão Menu ContextFlyout Menus de contexto

Interação e navegação de foco do plano XY

Se o seu aplicativo dá suporte à navegação de foco adequada para teclado, isso será convertido corretamente para o gamepad e o controle remoto. A navegação com as teclas de direção é mapeada para o D-pad (bem como o joystick esquerdo no gamepad), e a interação com os elementos de interface do usuário é mapeada para a tecla Enter/Select (consulte Gamepad e controle remoto).

Muitos eventos e propriedades são usados pelo teclado e pelo gamepad — ambos são acionados KeyDown e KeyUp eventos, e ambos só navegarão para controles que têm as propriedades IsTabStop="True" e Visibility="Visible". Para obter diretrizes de design de teclado, consulte Interações de teclado.

Se o suporte ao teclado for implementado corretamente, seu aplicativo funcionará razoavelmente bem; no entanto, pode haver algum trabalho extra necessário para dar suporte a cada cenário. Pense em necessidades específicas do seu aplicativo para oferecer a melhor experiência possível ao usuário.

Importante

O modo de mouse é habilitado por padrão para aplicativos do Windows em execução no Xbox One. Para desabilitar o modo de mouse e habilitar a navegação de foco do plano XY, defina Application.RequiresPointerMode=WhenRequested.

Depurando problemas de foco

O método FocusManager.GetFocusedElement informará qual elemento tem o foco no momento. Isso é útil para situações em que a localização do foco visual talvez não seja óbvia. Você pode registrar essa informação na janela de saída do Visual Studio da seguinte forma:

page.GotFocus += (object sender, RoutedEventArgs e) =>
{
    FrameworkElement focus = FocusManager.GetFocusedElement() as FrameworkElement;
    if (focus != null)
    {
        Debug.WriteLine("got focus: " + focus.Name + " (" +
            focus.GetType().ToString() + ")");
    }
};

Existem três motivos comuns para a navegação do plano XY não funcionar da maneira esperada:

  • A propriedade IsTabStop ou Visibility está definida incorretamente.
  • O controle que recebe o foco é realmente maior do que você pensa — a navegação XY examina o tamanho total do controle (ActualWidth e ActualHeight), não apenas a parte do controle que renderiza algo interessante.
  • Um controle focalizável está sobre outro: a navegação XY não dá suporte a controles sobrepostos.

Se a navegação do plano XY ainda não estiver funcionando da maneira esperada após a correção desses problemas, você poderá apontar manualmente para o elemento que deve receber o foco usando o método descrito em Substituindo a navegação padrão.

Se a navegação do plano XY estiver funcionando conforme o esperado, mas nenhum foco visual for exibido, a causa poderá ser uma das seguintes:

  • Você remodelou o controle e não incluiu um foco visual. Defina UseSystemFocusVisuals="True" ou adicione um foco visual manualmente.
  • Você moveu o foco chamando Focus(FocusState.Pointer). O parâmetro FocusState controla o que acontece com o foco visual. Em geral, isso deve ser definido como FocusState.Programmatic, que mantém o foco visual visível se ele estava visível antes, e o oculta se ele estava oculto antes.

O restante desta seção entra em detalhes sobre os desafios de design comuns ao usar a navegação do plano XY e oferece várias maneiras de resolvê-los.

Interface do usuário inacessível

Como a navegação de foco do plano XY limita o usuário a se mover para cima, para baixo, para a esquerda e para a direita, você pode se deparar com cenários onde partes da interface do usuário são inacessíveis. O diagrama a seguir ilustra um exemplo do tipo de layout de interface do usuário que não dá suporte à navegação de foco do plano XY. Observe que o elemento do meio não é acessível com o uso do gamepad/controle remoto porque a navegação vertical e horizontal será priorizada e o elemento do meio nunca terá prioridade alta o suficiente para receber o foco.

Elementos nos quatro cantos com elemento inacessível no meio

Se por algum motivo a reorganização da interface do usuário não for possível, use uma das técnicas discutidas na próxima seção para substituir o comportamento de foco padrão.

Substituindo a navegação padrão

Embora a Plataforma Universal do Windows tente garantir que a navegação com D-pad/joystick esquerdo faça sentido para o usuário, ela não pode garantir que o comportamento seja otimizado para a finalidade do seu aplicativo. A melhor maneira de garantir que a navegação seja otimizada para o seu aplicativo é testá-lo com um gamepad e confirmar se cada elemento da interface do usuário pode ser acessado pelo usuário de forma que faça sentido nos cenários do seu aplicativo. Caso os cenários do seu aplicativo necessitem de um comportamento não conseguido através da navegação de foco do plano XY fornecida, considere seguir as recomendações das seções a seguir e/ou substituir o comportamento para colocar o foco em um item lógico.

O trecho de código a seguir mostra como você pode substituir o comportamento de navegação de foco do plano XY:

<StackPanel>
    <Button x:Name="MyBtnLeft"
            Content="Search" />
    <Button x:Name="MyBtnRight"
            Content="Delete"/>
    <Button x:Name="MyBtnTop"
            Content="Update" />
    <Button x:Name="MyBtnDown"
            Content="Undo" />
    <Button Content="Home"  
            XYFocusLeft="{x:Bind MyBtnLeft}"
            XYFocusRight="{x:Bind MyBtnRight}"
            XYFocusDown="{x:Bind MyBtnDown}"
            XYFocusUp="{x:Bind MyBtnTop}" />
</StackPanel>

Neste caso, quando o foco estiver no botão Home e o usuário navegar para a esquerda, o foco se moverá para o botão MyBtnLeft; se o usuário navegar para a direita, o foco se moverá para o botão MyBtnRight botão; e assim por diante.

Para impedir que o foco se mova de um controle em uma determinada direção, use a propriedade XYFocus* para apontá-lo para o mesmo controle:

<Button Name="HomeButton"  
        Content="Home"  
        XYFocusLeft ="{x:Bind HomeButton}" />

Usando essas propriedades XYFocus, um controle pai também pode forçar a navegação de seus filhos quando o próximo candidato de foco estiver fora de sua árvore visual, a menos que o filho que tem o foco use a mesma propriedade XYFocus.

<StackPanel Orientation="Horizontal" Margin="300,300">
    <UserControl XYFocusRight="{x:Bind ButtonThree}">
        <StackPanel>
            <Button Content="One"/>
            <Button Content="Two"/>
        </StackPanel>
    </UserControl>
    <StackPanel>
        <Button x:Name="ButtonThree" Content="Three"/>
        <Button Content="Four"/>
    </StackPanel>
</StackPanel>

No exemplo acima, se o foco estiver no Button dois e o usuário navegar para a direita, o melhor candidato de foco será Button quatro. No entanto, o foco é movido para Button três porque o UserControl pai força a navegar até lá quando está fora da sua árvore visual.

Caminho de menos cliques

Tente permitir que o usuário execute as tarefas mais comuns com o menor número de cliques. No exemplo a seguir, o TextBlock é colocado entre o botão Reproduzir (que inicialmente recebe o foco) e um elemento comumente usado, sendo assim, um elemento desnecessário seja colocado entre as tarefas prioritárias.

As práticas recomendadas de navegação fornecem caminho com menos cliques

No exemplo a seguir, o TextBlock é colocado acima do botão Reproduzir em vez disso. Simplesmente reorganizar a interface do usuário para que elementos desnecessários não sejam colocados entre tarefas prioritárias melhorará consideravelmente a usabilidade do seu aplicativo.

TextBlock movido para cima do botão Reproduzir para que não fique mais entre tarefas prioritárias

CommandBar e ContextFlyout

Ao usar um CommandBar, tenha em mente o problema de rolagem em uma lista, como mencionado em Problema: elementos de interface do usuário localizados após uma lista/grade de rolagem longa. A imagem a seguir mostra um layout de interface do usuário com o CommandBar na parte inferior de uma lista/grade. O usuário precisa rolar até o final da lista/grade para acessar o elemento CommandBar.

CommandBar na parte inferior da lista/grade

E se você colocar o elemento CommandBaracima da lista/grade? Embora o usuário que rolou a lista/grade para baixo tenha que rolar de volta para cima para acessar o CommandBar, haverá um pouco menos de navegação do que na configuração anterior. Observe que isso pressupõe que o foco inicial do seu aplicativo seja colocado ao lado ou acima do CommandBar; Essa abordagem não funcionará bem se o foco inicial está abaixo da lista/grade. Se esses itens de CommandBar forem itens de ação global que não precisem ser acessados com frequência (como um botão Sincronizar), talvez seja aceitável tê-los acima da lista/grade.

Embora você não possa empilhar itens de uma CommandBarverticalmente, colocá-los contra a direção de rolagem (por exemplo, para a esquerda ou direita de uma lista de rolagem vertical, ou para cima ou para baixo de uma lista de rolagem horizontal) é outra opção que você poderá considerar se ela funcionar bem no layout de sua interface do usuário.

Se o seu aplicativo tiver uma CommandBar cujos itens precisam ser prontamente acessados pelos usuários, considere colocar esses itens dentro de uma propriedade ContextFlyout e remova-os da CommandBar. ContextFlyout é uma propriedade de UIElement e é o menu de contexto associado a esse elemento. No computador, quando você clica em um elemento com ContextFlyout, esse menu de contexto é aberto. No Xbox One, isso acontecerá quando você pressionar o botão Menu enquanto o foco estiver em um elemento.

Desafios de layout de interface do usuário

Alguns layouts de interface do usuário são mais desafiadores devido à natureza da navegação de foco do plano XY e devem ser avaliados caso a caso. Embora não haja uma única maneira "correta", e a solução que você escolher depende das necessidades específicas do seu aplicativo, existem algumas técnicas que você pode utilizar para criar uma ótima experiência de TV.

Para entender isso melhor, vamos examinar um aplicativo imaginário que ilustra alguns desses problemas, e as técnicas para superá-los.

Observação

Esse aplicativo fictício serve para ilustrar problemas de interface do usuário e as possíveis soluções para eles, e não se destina a mostrar a melhor experiência de usuário para seu aplicativo específico.

A seguir há um aplicativo de imóveis imaginário que mostra uma lista de imóveis disponíveis para venda, um mapa, uma descrição de uma propriedade e outras informações. Esse aplicativo apresenta três desafios que você pode solucionar usando as seguintes técnicas:

Aplicativo de imóveis fictício

Problema: elementos de interface do usuário localizados após uma lista/grade de rolagem longa

O ListView de propriedades mostradas na imagem a seguir é uma lista de rolagem muito longa. Se o envolvimentonão for necessária no ListView, quando o usuário navegar para a lista, o foco será colocado no primeiro item da lista. Para o usuário acessar o botão Anterior ou Próximo, ele deve passar por todos os itens da lista. Em casos como esse em que exigir que o usuário percorra toda a lista é doloroso, ou seja, quando a lista não é curta o suficiente para que essa experiência seja aceitável, talvez você queira considerar outras opções.

Aplicativo de imóveis: a lista de 50 itens leva 51 cliques para alcançar os botões abaixo

Soluções

Reorganização da interface do usuário

A menos que o foco inicial seja colocado na parte inferior da página, os elementos de interface do usuário colocados acima de uma lista de rolagem longa são normalmente mais acessíveis que se forem colocados abaixo. Se esse novo layout funciona para outros dispositivos, alterar o layout para todas as famílias de dispositivos em vez de fazer alterações especiais na interface do usuário apenas para o Xbox One pode ser uma abordagem mais barata. Além disso, colocar os elementos de interface do usuário contra a direção de rolagem (ou seja, na horizontal em uma lista de rolagem vertical, ou na vertical em uma lista de rolagem horizontal) tornará a acessibilidade ainda melhor.

Aplicativo de imóveis: colocar botões acima da lista de rolagem longa

Envolvimento em foco

Quando o envolvimento é necessário, todo o ListView se torna um destino de foco único. O usuário poderá ignorar o conteúdo da lista para acessar o próximo elemento focalizável. Leia mais sobre quais controles oferecem suporte a envolvimento e como usá-los em Envolvimento de foco.

Aplicativo de imóveis: definir o envolvimento como necessário para que leve apenas 1 clique para acessar os botões Anterior/Próximo

Problema: ScrollViewer sem elementos focalizáveis

Como a navegação de foco do plano XY depende de navegar para um elemento de interface do usuário focalizável ao mesmo tempo, um ScrollViewer que não contém elementos focalizáveis (tal como um elemento apenas com texto, como neste exemplo) pode criar um cenário em que o usuário não consegue exibir todo o conteúdo no ScrollViewer. Para obter soluções para esse e outros cenários relacionados, veja Envolvimento de foco.

Aplicativo de imóveis: ScrollViewer apenas com texto

Problema: interface de usuário de rolagem livre

Quando seu aplicativo requer uma interface de usuário de rolagem livre, como uma superfície de desenho ou, neste exemplo, um mapa, a navegação de foco do plano XY simplesmente não funciona. Nesses casos, você pode ativar o modo de mouse para permitir que o usuário navegue livremente dentro de um elemento de interface do usuário.

Mapear elemento de interface do usuário usando o modo de mouse

Modo do mouse

Conforme descrito em Interação e navegação de foco do plano XY, o foco no Xbox One é movido por meio de um sistema de navegação do plano XY, permitindo que o usuário mude o foco de controle para controle movendo-se para cima, para baixo, para a esquerda e para a direita. No entanto, alguns controles, como WebView e MapControl, exigem uma interação de mouse na qual os usuários podem mover livremente o ponteiro dentro dos limites do controle. Há também alguns aplicativos nos quais faz sentido para o usuário poder mover o ponteiro em toda a página, ter uma experiência com gamepad/controle remoto semelhante ao que os usuários podem encontrar em um computador com o mouse.

Para esses cenários, você deve solicitar um ponteiro (modo de mouse) para a página inteira ou em um controle dentro de uma página. Por exemplo, seu aplicativo pode ter uma página que tem um controle WebView que usa o modo de mouse somente enquanto está dentro do controle, e navegação de foco do plano XY em todos os outros locais. Para solicitar um ponteiro, você pode especificar que o deseja quando uma página ou controle está envolvido ou quando uma página tem o foco.

Observação

Não há suporte para a solicitação de um ponteiro quando um controle recebe o foco.

Para aplicativos Web hospedados e XAML executados no Xbox One, o modo de mouse está ativado por padrão para o aplicativo inteiro. É altamente recomendável que você desative essa opção e otimize seu aplicativo para navegação do plano XY. Para fazer isso, defina a propriedade Application.RequiresPointerMode como WhenRequested para habilitar o modo de mouse somente quando um controle ou uma página o solicitar.

Para fazer isso em um app XAML, use o código a seguir em sua classe App:

public App()
{
    this.InitializeComponent();
    this.RequiresPointerMode =
        Windows.UI.Xaml.ApplicationRequiresPointerMode.WhenRequested;
    this.Suspending += OnSuspending;
}

Para obter mais informações, incluindo o código de exemplo para HTML/JavaScript, consulte Como desabilitar o modo de mouse.

O diagrama a seguir mostra os mapeamentos de botões para gamepad/controle remoto no modo de mouse.

Mapeamentos de botões para gamepad/controle remoto no modo de mouse

Observação

O modo de mouse só tem suporte no Xbox One com gamepad/controle remoto. Em outras famílias de dispositivos e tipos de entrada ele é silenciosamente ignorado.

Use a propriedade RequiresPointer em um controle ou uma página para ativar o modo de mouse no item. Essa propriedade tem três valores possíveis: Never (o valor padrão), WhenEngaged e WhenFocused.

Ativando o modo de mouse em um controle

Quando o usuário vincula um controle a RequiresPointer="WhenEngaged", o modo de mouse é ativado no controle até o usuário desvinculá-lo. O trecho de código a seguir demonstra um MapControl simples que ativa o modo de mouse quando ativado:

<Page>
    <Grid>
        <MapControl IsEngagementRequired="true"
                    RequiresPointer="WhenEngaged"/>
    </Grid>
</Page>

Observação

Se um controle ativar o modo de mouse quando ativado, ele também deverá exigir a interação com IsEngagementRequired="true"; caso contrário, o modo de mouse nunca será ativado.

Quando um controle está no modo de mouse, seus controles aninhados estarão no modo de mouse também. O modo solicitado de seus filhos será ignorado– é impossível que um pai esteja no modo de mouse, mas um filho não esteja.

Além disso, o modo solicitado de um controle é inspecionado apenas quando ele recebe o foco, para que o modo não mude dinamicamente enquanto ele tem foco.

Ativando o modo de mouse em uma página

Quando uma página tem a propriedade RequiresPointer="WhenFocused", o modo de mouse será ativado para a página inteira quando ela receber foco. O trecho de código a seguir demonstra como fornecer essa propriedade a uma página:

<Page RequiresPointer="WhenFocused">
    ...
</Page>

Observação

O valor WhenFocused tem suporte apenas em objetos Page. Se você tentar definir esse valor em um controle, será gerada uma exceção.

Desativando o modo de mouse para conteúdo de tela inteira

Geralmente, ao exibir vídeos ou outros tipos de conteúdo em tela inteira, você deseja ocultar o cursor porque ele pode distrair o usuário. Esse cenário ocorre quando o resto do aplicativo usa o modo de mouse, mas você deseja desativá-lo ao mostrar conteúdo de tela inteira. Para fazer isso, coloque o conteúdo de tela inteira em seu próprio Page e siga as etapas abaixo.

  1. No objeto App, defina RequiresPointerMode="WhenRequested".
  2. Em cada objeto Page, exceto para a tela inteira Page, defina RequiresPointer="WhenFocused".
  3. Para a Page em tela inteira, defina RequiresPointer="Never".

Dessa forma, o cursor nunca aparecerá ao mostrar conteúdo de tela inteira.

Visual de foco

O foco visual é a borda em torno do elemento de interface do usuário que tem o foco no momento. Isso ajuda a orientar o usuário para que ele possa navegar facilmente em sua interface do usuário sem se perder.

Com uma atualização visual e várias opções de personalização adicionadas ao visual de foco, os desenvolvedores podem confiar que um único visual de foco funcionará bem em computadores e Xbox One, bem como em qualquer outro dispositivo Windows que dê suporte a teclado e/ou gamepad/remote.

Embora o mesmo foco visual possa ser usado em diferentes plataformas, o contexto em que o usuário se encontra é ligeiramente diferente para a experiência de 3 metros. Você deve presumir que o usuário não está prestando atenção total à toda a tela da TV e, portanto, é importante que o elemento focalizado no momento esteja claramente visível para o usuário em todos os momentos para evitar a frustração de procurar o foco visual.

Também é importante ter em mente que o foco visual é exibido por padrão, ao usar um gamepad ou controle remoto, mas não um teclado. Portanto, mesmo se você não implementá-lo, ele será exibido quando você executar seu aplicativo no Xbox One.

Posicionamento visual do foco inicial

Ao iniciar um aplicativo ou navegar para uma página, coloque o foco em um elemento de interface do usuário que faça sentido como o primeiro elemento no qual o usuário pode executar uma ação. Por exemplo, um aplicativo de fotos pode colocar o foco no primeiro item da galeria e um aplicativo de música navegado até um modo de exibição detalhado de uma música pode colocar o foco no botão Reproduzir para facilitar a reprodução da música.

Tente colocar o foco inicial na região superior esquerda do seu aplicativo (ou o canto superior direito para um fluxo da direita para a esquerda). A maioria dos usuários tende a se concentrar no que canto primeiro porque é onde o fluxo de conteúdo do aplicativo geralmente começa.

Tornando o foco claramente visível

Um foco visual sempre deve ficar visível na tela para que o usuário possa recomeçar de onde parou sem procurar o foco. Da mesma forma, deve haver um item focalizável na tela o tempo todo— por exemplo, não use pop-ups apenas com texto e sem elementos focalizáveis.

Uma exceção a essa regra seria para experiências de tela inteira, como assistir a vídeos ou exibir imagens, em cujos casos não seria adequado mostrar o foco visual.

Foco de revelação

O foco do Revelação é um efeito de iluminação que anima a borda de elementos focalizáveis, como um botão, quando o usuário move o foco do gamepad ou do teclado até eles. Ao animar o brilho ao redor da borda dos elementos em foco, Revelar foco proporciona aos usuários uma melhor compreensão de onde o foco está e para onde ele está indo.

O foco do Revelação está desativado por padrão. Para experiências de 10 pés, você deve optar por revelar o foco definindo a propriedade Application.FocusVisualKind no construtor do aplicativo.

    if(AnalyticsInfo.VersionInfo.DeviceFamily == "Windows.Xbox")
    {
        this.FocusVisualKind = FocusVisualKind.Reveal;
    }

Para obter mais informações, consulte as diretrizes de Foco do Revelação.

Personalizando o foco visual

Se você quiser personalizar o foco visual, poderá fazer isso modificando as propriedades relacionadas ao foco visual de cada controle. Há várias propriedades desse tipo que você pode utilizar para personalizar seu aplicativo.

Você pode até recusar os elementos visuais de foco fornecidos pelo sistema desenhando seus próprios estados visuais de uso. Para saber mais, consulte VisualState.

Sobreposição light dismiss

Para chamar a atenção do usuário para os elementos de interface do usuário que o usuário está manipulando no momento com o controlador de jogo ou controle remoto, a UWP adiciona automaticamente uma camada de "fumaça" que abrange áreas fora da interface do usuário pop-up quando o aplicativo está em execução no Xbox One. Isso não exige nenhum trabalho extra, mas é algo que você deve ter em mente ao projetar sua interface do usuário. Você pode definir a propriedade LightDismissOverlayMode em qualquer FlyoutBase para habilitar ou desabilitar a camada de fumaça; o padrão passa a ser Auto, o que significa que ela está habilitada no Xbox e desabilitada em outros lugares. Para obter mais informações, consulte Modal vs. light dismiss.

Envolvimento de foco

O envolvimento de foco destina-se a facilitar o uso de um gamepad ou controle remoto para interagir com um aplicativo.

Observação

Definir o envolvimento do foco não afeta o teclado ou outros dispositivos de entrada.

Quando a propriedade IsFocusEngagementEnabled em um objeto FrameworkElement é definida como True, ela marca o controle para exigir o envolvimento de foco. Isso significa que o usuário deve pressionar o botão A/Selecionar para "envolver" o controle e interagir com ele. Ao terminar, ele poderá pressionar o botão B/Voltar para desvincular o controle e navegar fora dele.

Observação

IsFocusEngagementEnabled é uma nova API e ainda não está documentada.

Trapping de foco

O trapping de foco é o que acontece quando um usuário tenta navegar na interface do usuário de em aplicativo mas fica "preso" dentro de um controle, o que torna difícil ou impossível mover-se para fora do controle.

O exemplo a seguir mostra a interface do usuário que cria o ajuste de registro de foco.

Botões esquerdo e direito de um controle deslizante horizontal

Se o usuário deseja navegar do botão esquerdo para o botão direito, seria lógico pressupor que basta pressionar direita duas vezes D-pad/no joystick esquerdo. No entanto, se o Slider não exigisse envolvimento, o comportamento a seguir ocorreria: quando o usuário pressionasse direta pela primeira vez, o foco poderia alternar para o Slider, e quando ele pressionasse direita novamente, o Sliderdo identificador se moveria para a direita. O usuário poderia continuar movendo o identificador para a direita e não seria capaz de acessar o botão.

Há várias abordagens para contornar esse problema. Uma é criar um layout diferente, semelhante ao exemplo de aplicativo de imóveis em Interação e navegação de foco do plano XY, onde podemos realocar os botões Anterior e Próximo acima de ListView. Empilhar os controles verticalmente em vez de horizontalmente como na imagem a seguir pode resolver o problema.

Botões acima e abaixo de um controle deslizante horizontal

Agora, o usuário pode navegar para cada um dos controles, pressionando a tecla para cima e para baixo no D-pad/joystick esquerdo e quando o Slider tem o foco, ele poderá pressionar a tecla para esquerda e para direita a fim de mover o identificador do Slider, conforme o esperado.

Outra abordagem para solucionar esse problema é exigir envolvimento no Slider. Se você definir IsFocusEngagementEnabled="True", isso resultará no comportamento a seguir.

Exigir o envolvimento do foco no controle deslizante para que o usuário possa navegar para o botão à direita

Quando o Slider exige envolvimento de foco, o usuário pode acessar o botão à direita pressionando diretamente no D-pad/joystick esquerdo duas vezes. Essa solução é excelente porque não requer nenhum ajuste de interface do usuário e produz o comportamento esperado.

Controles de itens

Além do controle Slider, há outros controles para os quais você talvez possa exigir envolvimento, tais como:

Ao contrário do controle Slider, esses controles não aprisionam o foco dentro deles mesmos; no entanto, eles podem causar problemas de usabilidade quando contêm grandes quantidades de dados. A seguir está um exemplo de um ListView que contém uma grande quantidade de dados.

ListView com grande quantidade de dados e botões acima e abaixo

Semelhante ao exemplo do Slider, vamos tentar navegar do botão na parte superior para o botão na parte inferior com um gamepad/controle remoto. Começando com foco no botão superior, pressionar para baixo no D-pad/joystick colocará o foco no primeiro item no ListView ("Item 1"). Quando o usuário pressiona para baixo novamente, o próximo item na lista obtém o foco, não o botão na parte inferior. Para acessar o botão, o usuário deve navegar por cada item no ListView primeiro. Se o ListView contiver uma grande quantidade de dados, isso pode ser inconveniente e não uma experiência de usuário ideal.

Para solucionar esse problema, defina a propriedade IsFocusEngagementEnabled="True" no ListView para exigir envolvimento. Isso permitirá que o usuário ignore rapidamente o ListView simplesmente pressionando para baixo. Entretanto, eles não poderão rolar a lista ou escolher um item nela a menos que a vinculem, pressionando o botão A/Selecionar quando ela tem o foco e, em seguida, pressionando o botão B/Voltar para desvincular.

ListView com envolvimento necessário

ScrollViewer

O controle ScrollViewer é um pouco diferente desses controles, pois tem seus próprios quirks a serem considerados. Se você tiver um ScrollViewer com conteúdo focalizável, por padrão, navegar para o ScrollViewer permitirá que você se mova através de seus elementos focalizáveis. Como em um ListView, você deve rolar por cada item para navegar fora do ScrollViewer.

Se o ScrollViewernão tiver conteúdo focalizável, por exemplo, se ele contiver apenas texto, você poderá definir IsFocusEngagementEnabled="True" para que o usuário possa envolver o ScrollViewer usando o botão A/Selecionar . Depois de vinculados, os usuários podem rolar pelo texto usando o D-pad/joystick esquerdo e, em seguida, pressionar o botão B/Voltar para desvincular quando terminarem.

Outra abordagem seria definir IsTabStop="True" no ScrollViewer para que o usuário não precise envolver o controle , ele pode simplesmente colocar o foco nele e, em seguida, rolar usando o joystick D-pad/left quando não houver elementos focalizáveis dentro do ScrollViewer.

Padrões de envolvimento de foco

Alguns controles tornam o ajuste de registro de foco comum o suficiente para garantir que as configurações padrão exijam o envolvimento de foco, enquanto outros têm o envolvimento de foco desativado por padrão, mas podem se beneficiar ao ativá-lo. A tabela a seguir lista esses controles e seus comportamentos de envolvimento de foco padrão.

Control Padrão de envolvimento de foco
CalendarDatePicker Ativado
FlipView Desativado
GridView Desativado
ListBox Desativado
ListView Desativado
ScrollViewer Desativado
SemanticZoom Desativado
Controle deslizante Ativado

Todos os outros controles do Windows não resultarão em alterações comportamentais ou visuais quando IsFocusEngagementEnabled="True".

Resumo

Você pode criar aplicativos do Windows otimizados para um dispositivo ou experiência específico, mas o Plataforma Universal do Windows também permite que você crie aplicativos que podem ser usados com êxito em dispositivos, em experiências de 2 pés e 10 pés, e independentemente da capacidade do dispositivo de entrada ou do usuário. Usar as recomendações neste artigo pode garantir que seu aplicativo seja o melhor possível na TV e em um computador.