segunda-feira, 24 de outubro de 2011

Afinal, o que significa Context Sensitive Interface?

Se você já se perguntou afinal o que são as interfaces sensitivas a contexto, ou já teve curiosidade de entender um pouco a respeito disso, vou te passar algumas dicas, já se você nunca ouviu falar, ou não gosta muito de interfaces web, então esse post pode te dar algumas novas visões de como planejar e construir uma interface gráfica web a partir de componentes, e quem sabe te anima a entrar nesse mundo tão interessante. Portanto, acho que esse assunto pode ser do interesse de muitos, foi pra mim, e acredito que poderá te ajudar um pouco, pois não tenho dúvidas que esse é um mecanismo que merece atenção no projeto de boas interfaces web.

Imagine uma interface montada com componentes apenas, onde não se passa nenhum parametro entre elas,assim como essa imagem apresentada a seguir.


Agora considere que as três possuem Grids e na medida em que se clica em alguma linha de um dos grids as demais respondem de acordo com o registro selecionado.  Ou seja, ao se selecionar um cliente qualquer na interface Clientes, a interface Compras e Produtos respondem filtrando informações relativas a esse cliente.


Não perca de vista a questão de que não passamos parametros, via Parm(), para os componentes, então como fazemos isso? como realizar a comunicação entre componentes isolados e agrupados em um painel?  A resposta: Interfaces Sensitivas a Contexto.

Em Genexus você já deve ter observado que quanto menos se programar melhor, veja os domínios que com um pouco de planejamento podem auxiliar na manutenção do sistema todo, o próprio for...each, por exemplo, pode ser otimizado com o objeto Data Selector, enfim, temos na montagem da interface elementos que poderiam ser reaproveitados em outras interfaces similares. 

Poderíamos dizer que um grid que seleciona um registro de uma tabela poderia muito bem ser aproveitado em diversas outras interfaces, desde que se tenha um pouco de planejamento anterior.  Assim poderíamos ter um modelo de projeto onde teríamos diversos componentes previamente planejados e nosso trabalho seria o de conectá-los ao nosso interesse. Soa bem isso não?  Isso é possível nas interfaces sensitivas a contexto.

O Que é Contexto?
Entenda contexto como sendo o item atualmente em foco na interface, alcançado por meio da tecla Tab ou do click do mouse.  Desta forma se ocorreu um click em um Grid, o contexto terá a linha corrente do grid, se em uma coluna do grid o contexto armazenará o valor da coluna selecionada, se em uma variável o valor da mesma e assim por diante.

Um evento chamado Track Context é utilizado para ler o contexto dos diversos controles na interface, e o interessante é que percebe a mudança assim que ocorre o foco no controle.  Em outras palavras, em nossa interface modelo, ao clicar em algum cliente no Grid apresentado à esquerda, o código do cliente ‘selecionado’ poderia então ser utilizado nos demais grids para apresentar suas compras e os produtos adquiridos pelo cliente.

Para facilitar um pouco, pense em Context como sendo um controle na interface (variável ou atributo), e que ao entrar em foco, imediatamente conseguimos ler seu valor.


Programando o Exemplo
Um web panel é montado apenas para integrar os três webcomponents, ou seja, não é necessário programar nada, a não ser o posicionamento dos componentes na interface, um exemplo poderia ser o apresentado na figura 1 acima.

O web componente Clientes, possui um grid simples do tipo Freestyle, com variáveis e atributos, e a propriedade NotifyContextChange é definida como True.


Os eventos programados nessa interface são meramente de carga do grid, nenhuma informação adicional.
 
Event Load
     &ClienteId   = ClienteId
     &ClienteFoto = ClienteFoto
     load
EndEvent

A segunda e terceira interface também são Web Componentes, programados com grids simples, como podem ser observados na Figura 4 e 5 abaixo.




O grid de Compras agrega um total de compras apenas, calculado na carga do grid.

Ambos os grids possuem um filtro ClienteId = &ClienteId. Observe que &ClienteId não existe em ambos os webcomponents, sendo o valor obtido do primeiro WebComponent (Figura 3), quando o usuário clicar em algum registro do Grid.  A pergunta é como &ClienteId é carregado? 

Um evento TrackContext foi adicionado para realizar a leitura do valor do contexto atual de &ClienteId, que na prática foi definido no outro no componente Cliente (Figura 3).  Não foi necessário programar nada no evento a não ser receber por parâmetro o valor de &ClienteId, do outro componente, por isso que o evento se encontra definido de forma tão simples. 

Event TrackContext(&ClienteId)
    
EndEvent

O evento TrackContext é o responsável por interceptar o Click e obter o cliente selecionado.

Em resumo, para que o grid notifique mudanças no contexto é necessário programar o NotifyContextChange=true, e para interceptar os clicks é necessário programar o Event TrackContext.

Entre parenteses se coloca as variáveis (apenas) que se deseja obter, e podem haver mais que um TrackContext na mesma interface.

Conclusão
Esse tema é muito importante e esse post está ficando um tanto quanto grande, acho que futuramente poderemos voltar a esse assunto, quem sabe tratar um pouco mais a respeito de TrackContext multiplos, e o SetContext que também é um evento bem interessante.

Não sei se entendeu o impacto disso, mas poderiamos pensar que todo WebComponent já programado poderia servir de base para montagem de outras interfaces completamente distintas, bastando programar o mecanismo de comunicação entre componentes, muito interessante não?

ps. Coloquei um vìdeo no YouTube mostrando o funcionamento da interface, caso tenha curiosidade. Interfaces Baseadas em Contexto