Oficina: Tecnologias para TV Digital Interativa - XPTA Lab

A Oficina: Tecnologias para TV Digital Interativa é um evento integrante do Laboratório de Excelência em Desenvolvimento de Aplicativos para Produção, Edição e Difusão de Conteúdos Audiovisuais pela Internet e TV Digital - XPTA Lab . O grupo Ginga-RN já existe desde maio de 2008 e é composto por desenvolvedores, pesquisadores e empresários interessados em TV Digital Interativa.

Informações

LOCAL: Universidade Federal do Rio Grande do Norte - Auditório da Reitoria
DATA: 25/03/2010
HORÁRIO: (10:00-12:00) e (14:00-15:15)

Ministrantes

Aquiles Burlamaqui
Possui graduação em Ciências da Computação pela Universidade Federal do Rio Grande do Norte (2003) e mestrado em Sistemas e Computação pela Universidade Federal do Rio Grande do Norte (2004). Doutor pela Universidade Federal do Rio Grande do Norte, professor da Universidade do Estado do Rio Grande do Norte e pesquisador do Laboratório Natalnet-DCA , atuando principalmente nos seguintes temas: Ambientes Virtuais Colaborativos Massivos, TV Digital Interativa, Sistemas Web, Aplicações de Robótica, Realidade Virtual e Engenharia de Software.

Roteiro:

  • Programação de aplicações interativas
  • Prática de aplicações interativas
    • Conceitos Básicos
    • Aprendizagem por exemplos

Enquete Ginga-NCL Simples - Passo a Passo

Passo 1 - Esqueleto NCL

Todos os códigos NCL possuem algumas tags em comum. O código abaixo deve servir para 90% dos exemplos que você for trabalhar.
Ele cria um documento NCL e adiciona um vídeo em tela cheia em exibição.

<?xml version="1.0" encoding="ISO-8859-1"?>
<ncl id="esqueleto">
    <head>
        <regionBase>
           <region left="0%" top="0%" width="100%" height="100%" id="rgVideo"/>    
        </regionBase>
 
    <descriptorBase>
        <descriptor region="rgVideo" id="dVideo"/>
    </descriptorBase>
 
    <connectorBase>
    </connectorBase>
    </head>
 
    <body>
         <port component="video" id="pInicio"/>
 
    <media descriptor="dVideo" src="midias/wanna.avi" id="video"/>
    </body>
</ncl>

Passo 2 - Adicionar a pergunta

Vamos colocar uma imagem contendo a pergunta da enquete.
Para isso precisamos definir:

  1. Onde ela vai aparecer ?
  2. Como vai aparecer ?
  3. O que vai aparecer ?
  4. Quando vai aparecer ?

1 - Onde ela vai aparecer ? - Para responder a essa pergunta adicionamos uma nova região(<region>).

<region zIndex="0" left="5%" top="70%" width="85%" height="25%" id="rgEnquete"/>

2 - Como vai aparecer ? - Respondemos com a adição de um descritor(<descriptor>).
<descriptor region="rgEnquete" id="dEnquete"/>

3 - O que vai aparecer ? - Aqui definimos qual a mídia que será apresentada.
<media descriptor="dEnquete" src="midias/pergunta.png" id="enquete"/>

4 - Quando vai aparecer ? - Vamos definir que ela vai aparecer assim que o vídeo principal começar. Para isso precisamos criar um comportamento do estilo: QuandoComeçarInicieAsMidias. Fazemos isso definindo um conector.
<connectorBase>
               <causalConnector id="onBeginStart">
            <simpleCondition role="onBegin"/>
            <simpleAction role="start"/>
        </causalConnector>
</connectorBase>

E depois de definir esse comportamente, dizemos quem vai seguir esse comportamento. No nosso caso, quando o video começar(onBegin) ele vai iniciar a midia enquete.
<link xconnector="onBeginStart" >
    <bind role="onBegin" component="video"/>
    <bind role="start" component="enquete"/>
</link>

O passo 2 completo fica assim:
<?xml version="1.0" encoding="ISO-8859-1"?>
 
<ncl id="esqueleto">
 
    <head>
        <regionBase>
           <region left="0%" top="0%" width="100%" height="100%" id="rgVideo"/>
           <region zIndex="0" left="5%" top="70%" width="85%" height="25%" id="rgEnquete"/>
 
        </regionBase>
 
        <descriptorBase>
            <descriptor region="rgVideo" id="dVideo"/>
            <descriptor region="rgEnquete" id="dEnquete"/>
        </descriptorBase>
 
        <connectorBase>
                   <causalConnector id="onBeginStart">
                        <simpleCondition role="onBegin"/>
                        <simpleAction role="start"/>
                </causalConnector>
        </connectorBase>
 
    </head>
 
    <body>
       <port component="video" id="pInicio"/>
       <media descriptor="dEnquete" src="midias/pergunta.png" id="enquete"/>
       <media descriptor="dVideo" src="midias/wanna.avi" id="video"/>
      <link xconnector="onBeginStart" >
            <bind role="onBegin" component="video"/>
              <bind role="start" component="enquete"/>
      </link>
 
    </body>
 
</ncl>

Passo 3 - Adicionar as Respostas

Alem da pergunta, precisamos das opções de resposta. Nossa enquete exemplo possui somente duas alternativas: SIM ou NÃO. Criamos uma imagem para cada opção. Precisamos adicioná-la ao documento.
Mais uma vez precisamos definir:

  1. Onde ela vai aparecer ?
  2. Como vai aparecer ?
  3. O que vai aparecer ?
  4. Quando vai aparecer ?

1 - Onde ela vai aparecer ? - Para responder a essa pergunta adicionamos uma nova região(<region>).

<region zIndex="1" left="15%" top="80%" width="15%" height="10%" id="rgSim"/>
<region zIndex="1" left="65%" top="80%" width="15%" height="10%" id="rgNao"/>

2 - Como vai aparecer ? - Respondemos com a adição de um descritor(<descriptor>).
<descriptor focusIndex="1" moveRight="2" region="rgSim" id="dSim"/>
<descriptor focusIndex="2" moveLeft="1" region="rgNao" id="dNao"/>

3 - O que vai aparecer ? - Aqui definimos qual a mídia que será apresentada.
<media descriptor="dSim" src="midias/sim.png" id="sim"/>
<media descriptor="dNao" src="midias/nao.png" id="nao"/>

4 - Quando vai aparecer ? - Vamos definir que elas também vão aparecer assim que o vídeo principal começar. Para isso basta dizer para o Conector que ele agora vai lidar com MAIS de um mídia(max="unbounded").
        <connectorBase>
                   <causalConnector id="onBeginStart">
                        <simpleCondition role="onBegin"/>
                        <simpleAction  max="unbounded" role="start"/>
                </causalConnector>
        </connectorBase>

E adicionar as novas mídias dentro do <link> já criado.
<link xconnector="onBeginStart" >
    <bind role="onBegin" component="video"/>
    <bind role="start" component="enquete"/>
    <bind role="start" component="sim"/>
    <bind role="start" component="nao"/>
</link>

Código final do passo 3 a seguir:
<?xml version="1.0" encoding="ISO-8859-1"?>
 
<ncl id="esqueleto">
 
    <head>
        <regionBase>
           <region left="0%" top="0%" width="100%" height="100%" id="rgVideo"/>
           <region zIndex="0" left="5%" top="70%" width="85%" height="25%" id="rgEnquete"/>
        <region zIndex="1" left="15%" top="80%" width="15%" height="10%" id="rgSim"/>
           <region zIndex="1" left="65%" top="80%" width="15%" height="10%" id="rgNao"/>
        </regionBase>
 
        <descriptorBase>
            <descriptor region="rgVideo" id="dVideo"/>
            <descriptor region="rgEnquete" id="dEnquete"/>
            <descriptor focusIndex="1" moveRight="2" region="rgSim" id="dSim"/>
            <descriptor focusIndex="2" moveLeft="1" region="rgNao" id="dNao"/>
        </descriptorBase>
 
        <connectorBase>
                   <causalConnector id="onBeginStart">
                        <simpleCondition role="onBegin"/>
                        <simpleAction  max="unbounded" role="start"/>
                </causalConnector>
        </connectorBase>
 
    </head>
 
    <body>
       <port component="video" id="pInicio"/>
       <media descriptor="dEnquete" src="midias/pergunta.png" id="enquete"/>
       <media descriptor="dVideo" src="midias/wanna.avi" id="video"/>
       <media descriptor="dSim" src="midias/sim.png" id="sim"/>
       <media descriptor="dNao" src="midias/nao.png" id="nao"/>
 
       <link xconnector="onBeginStart" >
            <bind role="onBegin" component="video"/>
            <bind role="start" component="enquete"/>
            <bind role="start" component="sim"/>
            <bind role="start" component="nao"/>
       </link>
 
    </body>
 
</ncl>

Passo 4 - Capturar a Interação do usuário

Vamos transformar as imagens SIM e NÃO em itens selecionáveis. Fazemos isso adicionando os atributos focusIndex ao descritor de cada uma delas. O focusIndex recebe um identificador numérico para guiar a navegação. Outro dois atributos, moveRight e moveLeft, são responsáveis por mover o foco de uma mídia para outra. Nessa caso entre os botões. O foco começa na mídia de index 1 e se o usuário mover a seta do controle remoto para a direita(moveRight) o foco muda para a mídia de index 2, e estiver na 2 e moder para esquerda(moveLeft) o foco volta para a mídia 1.

<descriptor focusIndex="1" moveRight="2" region="rgSim" id="dSim"/>
<descriptor focusIndex="2" moveLeft="1" region="rgNao" id="dNao"/>

Vamos agora criar um comportamento que permita a perceber a seleção de alguma dessas mídias, que ao serem selecionadas vão realizar alguma ação. No nosso caso quando um dos botões forem selecionados precisamos apagar os botões(SIM e NÃO) e a pergunta. Dessa forma, optamos por um conector que para(dá STOP) as mídias caso haja alguma seleção(onSelection).
<causalConnector id="onSelectionStop">
        <simpleCondition role="onSelection" />    
        <simpleAction max="unbounded" role="stop"/>
</causalConnector>

Vamos definir com o <link> quem vai assumir os papeis do comportamento criado anteriormente no conector.
<link xconnector="onSelectionStop" >
    <bind role="onSelection" component="sim" />
    <bind role="stop" component="enquete"/>
    <bind role="stop" component="sim"/>
    <bind role="stop" component="nao"/>
</link>
 
<link xconnector="onSelectionStop" >
    <bind role="onSelection" component="nao" />
    <bind role="stop" component="enquete"/>
    <bind role="stop" component="sim"/>
    <bind role="stop" component="nao"/>
</link>

Versão final do código no passo 4.
<?xml version="1.0" encoding="ISO-8859-1"?>
 
<ncl id="esqueleto">
 
    <head>
        <regionBase>
           <region left="0%" top="0%" width="100%" height="100%" id="rgVideo"/>
           <region zIndex="0" left="5%" top="70%" width="85%" height="25%" id="rgEnquete"/>
        <region zIndex="1" left="15%" top="80%" width="15%" height="10%" id="rgSim"/>
           <region zIndex="1" left="65%" top="80%" width="15%" height="10%" id="rgNao"/>
        </regionBase>
 
        <descriptorBase>
            <descriptor region="rgVideo" id="dVideo"/>
            <descriptor region="rgEnquete" id="dEnquete"/>
            <descriptor focusIndex="1" moveRight="2" region="rgSim" id="dSim"/>
            <descriptor focusIndex="2" moveLeft="1" region="rgNao" id="dNao"/>
        </descriptorBase>
 
        <connectorBase>
                   <causalConnector id="onBeginStart">
                        <simpleCondition role="onBegin"/>
                        <simpleAction  max="unbounded" role="start"/>
                </causalConnector>
            <causalConnector id="onSelectionStop">
                    <simpleCondition role="onSelection" />    
                    <simpleAction max="unbounded" role="stop"/>
            </causalConnector>
 
        </connectorBase>
 
    </head>
 
    <body>
       <port component="video" id="pInicio"/>
       <media descriptor="dEnquete" src="midias/pergunta.png" id="enquete"/>
       <media descriptor="dVideo" src="midias/wanna.avi" id="video"/>
       <media descriptor="dSim" src="midias/sim.png" id="sim"/>
       <media descriptor="dNao" src="midias/nao.png" id="nao"/>
 
       <link xconnector="onBeginStart" >
            <bind role="onBegin" component="video"/>
            <bind role="start" component="enquete"/>
            <bind role="start" component="sim"/>
            <bind role="start" component="nao"/>
       </link>
 
       <link xconnector="onSelectionStop" >
                    <bind role="onSelection" component="sim" />
              <bind role="stop" component="enquete"/>
              <bind role="stop" component="sim"/>
              <bind role="stop" component="nao"/>
       </link>
 
       <link xconnector="onSelectionStop" >
                   <bind role="onSelection" component="nao" />
              <bind role="stop" component="enquete"/>
                <bind role="stop" component="sim"/>
               <bind role="stop" component="nao"/>
       </link>
 
    </body>
 
</ncl>

Passo 5 - Capturar a Interação e exibir o resultado

Vamos agora exibir uma mídia que indique eu o voto do usuário foi reconhecido.
Alem de retirar o as antigas mídias, queremos agora exibir uma nova que seja de acordo com a escolha feita pelo usuário. Se ele responder SIM, uma imagem alegre será exibida, se escolher NÃO uma imagem triste aparecerá.
Vamo criar uma nova região e descritores para essa nova mídia.

<region zIndex="1" left="15%" top="30%" width="50%" height="50%" id="rgCentro"/>
<descriptor region="rgCentro" id="dCentro"/>

Vamos definir as mídias:

<media descriptor="dCentro" src="midias/happy-dog.jpg" id="feliz"/>
<media descriptor="dCentro" src="midias/triste.jpg" id="triste"/>

E agora, quando elas aparecem ?
Vamos modificar o conector onSelectionStop, e transformá-lo em onSelectionStartStop. Como isso, quando o usuário selecionar uma opção alem de parar as mídias ele poderá iniciar outras. Notem que agrupamos uma simpleAction dentro de uma compoundAction.

<causalConnector id="onSelectionStartStop">
        <simpleCondition role="onSelection" />
        <compoundAction operator="par">
            <simpleAction max="unbounded" qualifier="par" role="start"/>
            <simpleAction max="unbounded" qualifier="par" role="stop"/>
        </compoundAction>
</causalConnector>

Por fim vamos modificar o link responsável por executar tais comportamentos:
       <link xconnector="onSelectionStartStop" >
                    <bind role="onSelection" component="sim" />
              <bind role="stop" component="enquete"/>
              <bind role="stop" component="sim"/>
              <bind role="stop" component="nao"/>
               <bind role="start" component="feliz"/>
       </link>
 
       <link xconnector="onSelectionStartStop" >
                   <bind role="onSelection" component="nao" />
              <bind role="stop" component="enquete"/>
                <bind role="stop" component="sim"/>
               <bind role="stop" component="nao"/>
               <bind role="start" component="triste"/>
       </link>

Código completo do programa.
<?xml version="1.0" encoding="ISO-8859-1"?>
 
<ncl id="esqueleto">
 
    <head>
        <regionBase>
           <region left="0%" top="0%" width="100%" height="100%" id="rgVideo"/>
           <region zIndex="0" left="5%" top="70%" width="85%" height="25%" id="rgEnquete"/>
        <region zIndex="1" left="15%" top="80%" width="15%" height="10%" id="rgSim"/>
           <region zIndex="1" left="65%" top="80%" width="15%" height="10%" id="rgNao"/>
        <region zIndex="1" left="15%" top="30%" width="50%" height="50%" id="rgCentro"/>
 
        </regionBase>
 
        <descriptorBase>
            <descriptor region="rgVideo" id="dVideo"/>
            <descriptor region="rgEnquete" id="dEnquete"/>
            <descriptor focusIndex="1" moveRight="2" region="rgSim" id="dSim"/>
            <descriptor focusIndex="2" moveLeft="1" region="rgNao" id="dNao"/>
            <descriptor region="rgCentro" id="dCentro"/>
 
        </descriptorBase>
 
        <connectorBase>
                   <causalConnector id="onBeginStart">
                        <simpleCondition role="onBegin"/>
                        <simpleAction  max="unbounded" role="start"/>
                </causalConnector>
            <causalConnector id="onSelectionStartStop">
                    <simpleCondition role="onSelection" />
                    <compoundAction operator="par">
                            <simpleAction max="unbounded" qualifier="par" role="start"/>
                            <simpleAction max="unbounded" qualifier="par" role="stop"/>
                    </compoundAction>
            </causalConnector>
 
        </connectorBase>
 
    </head>
 
    <body>
       <port component="video" id="pInicio"/>
       <media descriptor="dEnquete" src="midias/pergunta.png" id="enquete"/>
       <media descriptor="dVideo" src="midias/wanna.avi" id="video"/>
       <media descriptor="dSim" src="midias/sim.png" id="sim"/>
       <media descriptor="dNao" src="midias/nao.png" id="nao"/>
       <media descriptor="dCentro" src="midias/happy-dog.jpg" id="feliz"/>
       <media descriptor="dCentro" src="midias/triste.jpg" id="triste"/>
 
       <link xconnector="onBeginStart" >
            <bind role="onBegin" component="video"/>
            <bind role="start" component="enquete"/>
            <bind role="start" component="sim"/>
            <bind role="start" component="nao"/>
       </link>
 
        <link xconnector="onSelectionStartStop" >
            <bind role="onSelection" component="sim" />
            <bind role="stop" component="enquete"/>
            <bind role="stop" component="sim"/>
            <bind role="stop" component="nao"/>
             <bind role="start" component="feliz"/>
       </link>
 
       <link xconnector="onSelectionStartStop" >
              <bind role="onSelection" component="nao" />
              <bind role="stop" component="enquete"/>
              <bind role="stop" component="sim"/>
              <bind role="stop" component="nao"/>
              <bind role="start" component="triste"/>
       </link>
 
    </body>
 
</ncl>
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License