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:
Ações que ocorrem enquanto o usuário desenha o traço
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 .
O DynamicRenderer renderiza os pontos da caneta no thread de renderização dinâmica. Isso acontece ao mesmo tempo em que a etapa anterior.
O InkCanvas recebe os pontos da caneta no thread da interface do usuário.
Ações que ocorrem após o usuário terminar o traço
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.
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.
No diagrama anterior, o seguinte comportamento ocorre:
StylusPlugin1
modifica os valores de x e y.DynamicRenderer recebe os pontos de caneta modificados e os renderiza no thread de renderização dinâmica.
StylusPlugin2
recebe os pontos da caneta modificados e modifica mais os valores de x e y.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 .
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.
O usuário inicia o traço.
- O DynamicRenderer cria a árvore visual.
O usuário está desenhando o traço.
- O DynamicRenderer constrói a árvore visual.
O usuário termina o traço.
O InkPresenter adiciona o traçado à sua árvore visual.
A MIL (camada de integração de mídia) renderiza estaticamente os traços.
O DynamicRenderer limpa o visual.
.NET Desktop feedback