Compartilhar via


O modelo de threading da tinta

Um dos benefícios da tinta em um Tablet PC é que ela se parece muito com escrever com uma caneta comum e papel. Para fazer isso, a caneta eletrônica coleta dados de entrada a uma taxa muito maior do que um mouse e renderiza a tinta enquanto o usuário escreve. O thread da interface do usuário do aplicativo não é suficiente para coletar dados da caneta e renderizar a tinta, porque ele pode ser bloqueado. Para resolver isso, um aplicativo WPF usa dois threads adicionais quando um usuário grava tinta.

A lista a seguir descreve os threads que fazem parte da coleta e renderização da tinta digital:

  • Thread de caneta – o thread que coleta dados da caneta. (Na realidade, trata-se de um pool de threads, mas este tópico refere-se a ele como um thread de caneta.)

  • Thread da interface do usuário do aplicativo – o thread que controla a interface do usuário do aplicativo.

  • Thread de renderização dinâmica – o thread que renderiza a tinta enquanto o usuário desenha um traço. O thread de renderização dinâmica é diferente do thread que renderiza outros elementos da interface do usuário para o aplicativo, conforme mencionado no Modelo de threading da Windows Presentation Foundation.

O modelo de tinta digital é o mesmo se o aplicativo usa o InkCanvas ou um controle personalizado semelhante ao em Criando um controle de entrada de tinta. Embora este tópico discuta o threading em termos do InkCanvas, os mesmos conceitos se aplicam quando você cria um controle personalizado.

Visão geral do threading

O diagrama a seguir ilustra o modelo de threading quando um usuário desenha um traço:

Threading model while drawing a stroke.

  1. Ações que ocorrem enquanto o usuário desenha o traço

    1. Quando o usuário desenha um traço, os pontos da caneta entram no thread da caneta. Os plug-ins da caneta, incluindo o DynamicRenderer, aceitam os pontos da caneta no fio da caneta e têm a chance de modificá-los antes de recebê-los InkCanvas .

    2. O DynamicRenderer renderiza os pontos da caneta no thread de renderização dinâmica. Isso acontece ao mesmo tempo em que a etapa anterior.

    3. O InkCanvas recebe os pontos da caneta no thread da interface do usuário.

  2. Ações que ocorrem após o usuário terminar o traço

    1. Quando o usuário termina de desenhar o traçado, o cria um Stroke objeto e o adiciona ao InkPresenter, que o InkCanvas renderiza estaticamente.

    2. O thread da interface do usuário alerta que DynamicRenderer o traçado é renderizado estaticamente, portanto, remove DynamicRenderer sua representação visual do traçado.

Plug-ins de caneta e coleta de tinta

Cada UIElement um tem um StylusPlugInCollectionarquivo . Os StylusPlugIn objetos no recebem e podem modificar os pontos da caneta no StylusPlugInCollection fio da caneta. Os StylusPlugIn objetos recebem os pontos da caneta de acordo com sua ordem no StylusPlugInCollection.

O diagrama a seguir ilustra a situação hipotética em que a coleção de a contém stylusPlugin1, a DynamicRendererUIElementStylusPlugIns , e stylusPlugin2, nessa ordem.

Order of Stylus Plugins affect output.

No diagrama anterior, o seguinte comportamento ocorre:

  1. StylusPlugin1 modifica os valores de x e y.

  2. DynamicRenderer recebe os pontos de caneta modificados e os renderiza no thread de renderização dinâmica.

  3. StylusPlugin2 recebe os pontos da caneta modificados e modifica mais os valores de x e y.

  4. O aplicativo coleta os pontos da caneta e, quando o usuário termina o traço, renderiza estaticamente o traço.

Suponha que stylusPlugin1 restrinja os pontos da caneta a um retângulo e stylusPlugin2 mova os pontos da caneta para a direita. No cenário anterior, o DynamicRenderer recebe os pontos de caneta restritos, mas não os pontos de caneta traduzidos. Quando o usuário desenha o traço, o traço é renderizado dentro dos limites do retângulo, mas o traço não parece ser movido até que o usuário levante a caneta.

Executando operações com um plug-in de caneta no thread da interface do usuário

Como testes de acertos precisos não podem ser executados no thread da caneta, alguns elementos podem, ocasionalmente, receber entradas da caneta destinadas a outros elementos. Se você precisar verificar se a entrada foi roteada corretamente antes de executar uma operação, inscreva-se e execute a operação no OnStylusDownProcessedmétodo , OnStylusMoveProcessedou OnStylusUpProcessed . Esses métodos são invocados pelo thread do aplicativo após testes de acertos precisos terem sido executados. Para assinar esses métodos, chame o NotifyWhenProcessed método no método que ocorre no fio da caneta.

O diagrama a seguir ilustra a relação entre o thread da caneta e o thread da interface do usuário em relação aos eventos de caneta de um StylusPlugInarquivo .

Ink Threading Models (UI and Pen)

Renderizando tinta

À medida que o usuário desenha um traçado, DynamicRenderer renderiza a tinta em um thread separado para que a tinta pareça "fluir" da caneta mesmo quando o thread da interface do usuário estiver ocupado. O DynamicRenderer cria uma árvore visual no thread de renderização dinâmica à medida que coleta pontos de caneta. Quando o usuário termina o traçado, o pede para ser notificado quando o DynamicRenderer aplicativo faz a próxima passagem de renderização. Depois que o aplicativo concluir a próxima etapa de renderização, o DynamicRenderer limpará sua árvore visual. O diagrama a seguir ilustra esse processo.

Ink threading diagram

  1. O usuário inicia o traço.

    1. O DynamicRenderer cria a árvore visual.
  2. O usuário está desenhando o traço.

    1. O DynamicRenderer constrói a árvore visual.
  3. O usuário termina o traço.

    1. O InkPresenter adiciona o traçado à sua árvore visual.

    2. A MIL (camada de integração de mídia) renderiza estaticamente os traços.

    3. O DynamicRenderer limpa o visual.