quinta-feira, 15 de maio de 2008

FullScreen do flash não funciona em players abaixo de 9.0.28, e agora?

Desde a versão 9.0.28 do flash é possível definir seu swf para rodar em tela cheia de maneira bem simples. Também é possivel definir um listener para ser notificado quando o modo de exibição do flash é alterado de normal para fullscreen e vice-versa. Contudo, se você colocar essas funcionalidades, seu swf não rodará em versões anteriores a 9.028.

O jeito então é alterar seu ActionScript para só setar a o fullscreen quando a versão for compatível. Veja abaixo como isso pode ser feito:
import flash.display.StageDisplayState;

public class Main extends MovieClip {

//...

function suportaTelaCheia():Boolean {
//Verifica versao >= que 9.0.28
}
function onBotaoTelaCheiaClique(event:MouseEvent):void {
if( suportaTelaCheia() ) {
stage.displayState = StageDisplayState.FULL_SCREEN;
}
}
function onBotaSaiTelaCheiaClique(event:MouseEvent):void {
if( suportaTelaCheia() ) {
stage.displayState = StageDisplayState.NORMAL;
}
}

//...
}
Apesar da classe flash.display.StageDisplayState não existir no player com versão menor que 9.0.28, a importação dela não trará erro, pois o flash só executa a importação de uma classe quando faz uso dela. Portanto a seleção da versão feita com o método suportaTelaCheia impede seu uso e consequente importação.

O problema maior é quando precisamos definir um listener para sabermos quando o swf entrou em modo fullscreen e quando saiu. Normalmente isso é necessário quando precisamos redimensionar, ou adicionar elementos ao stage. No caso o código, sem o tratamento de versão, ou seja, o que daria erro nas versões de flash anteriores a 9.0.28 ficaria assim:
import flash.events.FullScreenEvent;

public class Main extends MovieClip {

//...

private function onStage(event:Event):void {
stage.addEventListener( FullScreenEvent.FULL_SCREEN, redrawFullScreen );
}

//...

function redrawFullScreen(event:FullScreenEvent):void {
if( event.fullScreen ) {
//Posicionar elementos para tela cheia
} else {
//Posicionar elementos para tamanho normal
}
}

//....

}
O grande problema disso é que o uso da classe FullScreenEvent está na definição do método redrawFullScreen e portanto não é possivel defini-lo somente quando for uma versão ou outra. O jeito então então é mudar a assinatura do método, para ao invés de receber um FullScreenEvent receber um Event. Com essa correção o código ficaria assim:
import flash.events.FullScreenEvent;

public class Main extends MovieClip {

//...

function suportaTelaCheia():Boolean {
//Verifica versao >= que 9.0.28
}

private function onStage(event:Event):void {
if( suportaTelaCheia() ) {
stage.addEventListener( FullScreenEvent.FULL_SCREEN, redrawFullScreen );
}
}

//...

function redrawFullScreen(event:Event):void {
if( event['fullScreen'] ) {
//Posicionar elementos para tela cheia
} else {
//Posicionar elementos para tamanho normal
}
}

//....

}
Repare que além de ter mudado a assinatura do método, mudei também o uso do objeto event. Isso foi feito porque a classe Event não possui o atributo fullScreen declarado, então utilizar event.fullScreen daria erro de compilação. Mas como sabemos que ali há este atributo, podemos utilizá-lo usando a notação event['fullScreen'].

quarta-feira, 14 de maio de 2008

Como instalar o flash 9.0.16 para testar seu swf

É muito importante que ao criar um swf complexo, como um player de vídeo por exemplo, você execute testes em todas as versões de flash player que você deseja que ele suporte. Para isso a Adobe oferece em seu site diversas versões antigas do flash player para download. Contudo, se você está no Windows XP e deseja intalar a versão 9.0.16, mas já possui uma versão mais nova instalada, é preciso seguir os seguintes passos.

Primeiro é preciso desinstalar a versão atual do flash player executando o programa uninstall_flash_player.exe encontrado na página How to uninstall the Adobe Flash Player plug-in and ActiveX control. Depois de executar isso é preciso acessar o regedit e remover a seguinte chave: HKEY_LOCAL_MACHINE\SOFTWARE\Macromedia\FlashPlayer.

Feito isso, reinicie o computador. Ok ok, paciência, estamos lidando com Windows portanto todo cuidado é pouco. Mãos a obra: Iniciar > Reiniciar (Heim?).

Após reiniciado basta instalar a versão 9.0.16 que pode ser baixada em Archived Flash Players available for testing purposes. Nesse link podem ser encontradas diversas outras versões do flash player e é bem possível que o escrito aqui sirva para instalar essas outras versões.

terça-feira, 6 de maio de 2008

Undefined method *_path no uso do form_for

Essa é uma dica boba para aqueles que estão começando em ruby on rails como eu. Fazendo aqui um exemplos simples de cadastro de filmes recebi o seguinte erro:
NoMethodError in Filme#incluir

Showing filme/incluir.html.erb where line #5 raised:

undefined method `filmes_path' for #<ActionView::Base:0xb76f144c>

Extracted source (around line #5):

2:
3: <%= error_messages_for :filme %>
4:
5: <% form_for @filme do |f| %>
6: <p>
7: <b>Título</b><br />
8: <%= f.text_field :titulo %>
Pelo que eu entendi até agora, isso acontece porque eu não estou utilizando os métodos padrões do ruby on rails. Se eu estiver falando besteira por favor me corrijam. O fato é que resolvi isso definindo a ação que o form deverá executar, o código da view então ficaria da seguinte forma:
<h1>Incluir novo filme</h1>

<%= error_messages_for :filme %>

<% form_for @filme, :url => { :action => 'salvar' } do |f| %>
<p>
<b>Título</b><br />
<%= f.text_field :titulo %>
</p>

<p>
<b>Resumo</b><br />
<%= f.text_area :resumo %>
</p>

<p>
<%= f.submit "Incluir" %>
</p>
<% end %>
No caso o controlador possui o método salvar.

quinta-feira, 1 de maio de 2008

Dependência entre tarefas no Scrum

Um problema recorrente nas reuniões diárias do nosso projeto aqui na globo.com é a dependência entre tarefas. Sempre ocorrem interrupções entre o fluxo de "O que eu fiz" e "O que farei" para questionar a algum colega do time se determinada tarefa já foi concluída. No caso afirmativo ele pode então pegar a tarefa que era dependente. Isso acontece frequentemente, e quando ocorre o fluxo desanda e a atenção se dispersa. Começam então algumas conversas paralelas que acabam atrapalhando o andamento da reunião.

O ideal, é claro, é que não houvessem tarefas dependentes entre si em uma história. Mas isso é muito díficil, e segundo minha breve experiência com Scrum, e nesse ponto ela se resume a apenas alguns poucos projetos web, me parece ser impossivel. Como exemplo posso mostrar três tarefas que foram presentes na maioria das histórias dos projetos que participei e que são dependentes entre si:

1- Criar design
2- Criar html e css estático
3- Implementar camada de visualização

A tarefa 2 depende da tarefa 1, e a tarefa 3 depende da tarefa 2. É claro que seria possível paralelizar a tarefa 3 com a 2, fazendo com que a implementação da camada de visualização fosse apenas de um html tosco. Mas mesmo assim seria necessária uma quarta tarefa para fazer o merge do html bonito com a camada de visualização, e esta nova tarefa seria enfim dependente da tarefa 2.

Ou seja, não vejo como paralelizar todas elas. E cabe aqui uma brecha para colaboração dos leitores no caso de terem encontrado alternativas, ficaria feliz de conhecê-las. De qualquer forma, existem outras situações específicas de cada empresa e de cada time que elevam mais ainda o número de dependência entre as tarefas.

Eis então que presenciei em outro time uma boa adaptação da reunião diária. Ao invés de cada membro do time responder as três perguntas, um em seguida do outro, os membros dizem primeiro o que fizeram, uma após o outro, depois dizem o que pretendem fazer, um atrás do outro, e ao final o que os impede, também da mesma forma.

Com isso o time resolveu de maneira simples um problema que parece não ter solução, sem sacrificar a reunião diária, pois todos saem dela sabendo o que fazer, o que já está pronto e quais são os impedimentos do projeto. Cumprindo exatamente o propósito dela.