Construindo Gadgets para o Windows Vista

Parte 2: Utilizando DHTML e o Modelo de Objetos do Windows Sidebar

Publicado em: 24 de novembro de 2006
*

Desenvolvendo Gadgets Utilizando Scripts

Na primeira parte deste tutorial (“Construindo Gadgets para o Windows Vista – Parte 01: Introdução aos Windows Gadgets”), fizemos a criação da estrutura de diretórios de um gadget, incluindo a adição dos arquivos básicos (como “default.html” e “settings.html”) e do arquivo de script “default.js”.

Na ocasião, vimos que o uso de código javascript é fundamental para o desenvolvimento de Gadgets, incluindo como exemplo o comando que nos permite atribuir ao gadget o endereço break da página correspondente à tela de “Configurações”:

System.Gadget.settingsUI = "settings.html";
		

Para dar “vida” ao gadget que iniciamos (adicionando funcionalidades que irão permitir a consulta de dados de um serviço remoto e exibição do conteúdo) iremos utilizar código script tanto com o modelo de objetos DHTML convencional (o mesmo utilizado tradicionalmente com aplicações web) , quanto com um novo conjunto de bibliotecas denominadas “Sidebar APIs”, criadas exclusivamente para uso pelos gadgets para acesso a recursos locais do sistema e tratamento de eventos do gadget na barra lateral.

É através destas APIs que é possível, por exemplo, fazer a leitura de valores de variáveis de sistema, criar e alterar variáveis gerais de ambiente, criar e ler arquivos, acessar recursos de hardware e exibir informações gerais de rede e do sistema operacional. Portanto, antes de iniciarmos a criação de funcionalidades para nosso gadget-exemplo (rebatizado de “Agenda do TechEd 2006”), vamos explorar alguns destes importantes objetos (tanto das bibliotecas DHTML quanto do Sidebar).

Início da páginaInício da página

Gadget-Exemplo: “Agenda do TechEd 2006”

Nosso exemplo fará consulta a um serviço que retornará as informações gerais das palestras do TechEd 2006. Este serviço originalmente é uma webpart do Windows SharePoint Services 2007 que retorna um XML específico conforme o filtro de opções utilizado: por tipo de palestra (se “Desenvolvedores” ou “Profissionais de IT”) e por data de realização (se queremos os valores para o primeiro ou segundo dia de palestras). Com a técnica utilizada neste exemplo, é possível consumir serviços e acessar quaisquer endereços HTTP remotos. Para teste local do exemplo, estão disponíveis com o código-fonte do gadget versões “estáticas” dos arquivos XML que seriam dinamicamente retornados pelo servidor após consulta dos dados no banco de dados SQL Server do SharePoint. Após a instalação do gadget, leia o arquivo “readme.txt” para mais informações sobre os arquivos XML.

Início da páginaInício da página

Estados do Gadget e o Modelo de Objetos da Windows Sidebar

Antes de começarmos a explorar o modelo de objetos da Windows Sidebar, é necessário lembrar que um gadget, após selecionado na “Galeria de Gadgets” da barra lateral, pode assumir um dos seguintes estados:

“Docked” : quando “acoplado” à barra lateral; ou

“Undocked”: quando “desacoplado” e livre para posicionamento em qualquer local da área de trabalho.

Quando um gadget está acoplado à barra lateral ele deve seguir um padrão de dimensões e obedecer o limite de 130 pixels de comprimento. Para a altura não há valores máximos pré-estabelecidos, mas é importante observar que seu gadget provavelmente não será o único a ocupar a barra lateral (portanto é importante otimizar espaço).

A cada mudança de estado do gadget (de “Undocked” para “Docked”, e vice-versa), é possível implementar funções que executem determinadas operações, conforme estes eventos. Em nosso exemplo, iremos alterar as dimensões do gadget para que ele seja “maximizado” quando estiver fora da barra lateral. O gadget também pode receber funções de tratamento para seu evento “onSettingsClosing”, permitindo inclusive decisões distintas na efetivação ou cancelamento das configurações (que se dá pelo clique nos botões “OK” ou “Cancel”, respectivamente).

Vamos começar fazendo algumas alterações no arquivo “settings.html”, de modo que seja possível configurar nosso gadget para a exibição de dados conforme tipo de perfil (se “Desenvolvedores” ou “Profissionais de IT”) e data de realização (“29/11/2006” ou “30/11/2006”) do TechEd. O valor fornecido em “Perfil” será utilizado para determinar qual logomarca será exibida na tela principal do gadget, conforme fig.01:

Fig. 01 – Tela “Settings” com campos para alteração de configuração do gadget

Para informar para “default.html” o novo valor do campo “Perfil” selecionado na tela “settings.html”, vamos utilizar dois métodos do objeto “System.Gadget.Settings”: “readString” (utilizado para recuperar o valor em “default”) e “writeString” (quando escrevemos o valor a ser armazenado entre sessões).

mySettings.profileOptions = System.Gadget.Settings.readString("profileOptions");
System.Gadget.Settings.writeString("profileOptions", mySettings.profileOptions);     
			

Os valores atribuído em “System.Gadget.Settings” com “writeString” são mantidos enquanto não forem explicitamente alterados, mesmo quando o computador é desligado ou a barra lateral é fechada (observação: quando o gadget, porém, é fechado e readicionado à barra lateral, os valores de configuração não são mantidos).

A escrita efetiva dos valores com “System.Gadget.Settings.writeString” são feitas em nosso exemplo apenas quando o botão “OK” é pressionado (se clicarmos em “Cancel”, as mudanças realizadas são desconsideradas). Para isso, incluímos o seguinte tratamento de evento no arquivo “settings.js”, que contém as funções javascript para o arquivo “settings.html”:

//Lógica implementada em: “settings.js”
System.Gadget.onSettingsClosing = settingsClosing;
function settingsClosing(event){
		if(event.closeAction == event.Action.commit)
		{
			System.Gadget.Settings.writeString("profileOptions", mySettings.profileOptions);     
		}
}
			

Também incluímos no arquivo “default.js” o mesmo tratamento de evento, porém com a implementação da função que recupera o valor e exibe as diferentes logomarcas:

//Lógica implementada em: “default.js”

System.Gadget.onSettingsClosing = settingsClosing;

// Constantes:
var C_LOGO_0 = "images/logoDev.gif";
var C_LOGO_1 = "images/logoIt.gif";
function settingsClosing(event)
{
	if(event.closeAction == event.Action.commit)
	{
		// Recuperar informacoes configuradas em " Settings":
			var currentProfileOption = 
			System.Gadget.Settings.readString("profileOptions");
		//”trackLogo” é o id do controle HTML: <img id="trackLogo" />
			trackLogo.src = eval("C_LOGO_" + currentProfileOption);
	}
}
			

O tratamento dos eventos “System.Gadget.onUndock” e “System.Gadget.onDock” irá redimensionar nosso gadget para que ocupe uma área maior quando desacoplado, oferecendo espaço para que a agenda do evento seja exibida (note que os controles HTML são acessado através de seus atributos “id”). Estamos utilizando áreas “<div>” distintas para a exibição do conteúdo que deve ser mostrado quando o gadget está acoplado (<div id=”gadgetLogo”>) ou desacoplado (<div id=”gadgetContent”>):

//Lógica implementada em: “default.js”
System.Gadget.onUndock = showMaximizedPanel;
System.Gadget.onDock = showMinimizedPanel;
function showMaximizedPanel()
{
	with(document.body.style)
		width=650, height=315;

	mainBackground.src="url(../images/backdesktop.png)";

	with(gadgetContent.style)
		width=635, height=285, paddingTop=13, paddingLeft=20, paddingRight=15;

	gadgetLogo.style.display = "none";
	gadgetContent.style.display = "block";
}
function showMinimizedPanel()
{
	with(document.body.style)
		width=130, height=80;

	mainBackground.src="url(../images/backsidebar.png)";

	with(gadgetLogo.style)
		width=122, height=71, paddingTop=6, paddingLeft=8, paddingRight=6;

	gadgetLogo.style.display = "block";
	gadgetContent.style.display = "none";
}
			

Utilizando o objeto “XmlHttpRequest” (este, um objeto do modelo DHTML geral para uso em construções web), iremos recuperar o conteúdo xml contendo a lista de palestras do TechEd, o que será feito no método “onLoadMain” (<body onload="onLoadMain();">).

//Lógica implementada em: “default.js”
function onLoadMain(){
	showContent();
	// Atualização do conteúdo, chamando novamente a função "showContent"
	// a cada 30 minutos:
	g_timer = setInterval(showContent, g_timerMilliSecs);
}

function showContent ()
{
try {
	var oReq = new XMLHttpRequest();
	oReq.open("GET", "http://sharepoint/sites/brzisvde/_vti_bin/owssvr.dll?
	CS=65001&XMLDATA=1&RowLimit=0&List={41E838A2-B6FA-4097-9861-E72C70E7FC05}&View=" + myListURL );

	oReq.onreadystatechange = function(){
		if(oReq.readyState == 4)

			//Depois que o conteúdo é retornado,
			// obtemos o XML, processando-o na função "processXml":

			returnedXML = oReq;
			processXml(returnedXML);
		};

	oReq.send();
	}

	catch (e){
        // Na vida real a ocorrência de erros deveria ser tratada, 
		// em especial porque a conexão com a intranet pode nem sempre estar disponível. 
		// É possível inclusive enviar mensagens para o Event Viewer através do "System.Diagnostics.EventLog".
		processedHTML = 'Serviço não disponível';
	}
}
			

Detalhes sobre a implementação e o tratamento feito com o XML retornado para exibição dos dados e paginação dos resultados poderão ser encontrados no código-fonte disponível com este exemplo (a função “processXml” com o suporte à paginação estão no arquivo “global.js”).

Notem que é através do valor atribuído à variável “myListURL” que é possível determinar qual o filtro que será utilizado para retorno da lista de palestras conforme perfil do público e data de exibição. O resultado desta implementação será a exibição do gadget com diferentes tamanhos e informações conforme esteja ou não acoplado à barra lateral, como ilustra a fig.02:

Fig. 02 – Visão e dimensões do gadget “TechEd 2006” quando desacoplado da barra lateral

Início da páginaInício da página

Uso do objeto “System.Gadget.Flyout”

Assim como o modelo de objetos da barra lateral cria toda a infra-estrutura para exibição e tratamento de eventos da janela de “Settings”, sendo necessário somente criar um arquivo HTML e associá-lo à propriedade “settingsUI” ( em nosso exemplo, System.Gadget.settingsUI = "settings.html" ), um gadget tem ainda a possibilidade de exibir uma janela “Flyout”, posicionada automaticamente sobre o gadget acoplado, extendendo-o para fora da barra lateral, porém sem desacoplá-lo. Veja como exemplo a janela “Flyout” exibida pelo gadget “Stocks” nativo de seu Windows Vista:

Fig. 03 – Tela “Flyout” exibida com o gadget “Stocks”

Para criarmos um “flyout” em nosso gadget-agenda que exiba a lista de palestras sem que seja necessário desacoplar o gadget da barra lateral, indicamos o arquivo HTML correspondente e quais métodos serão utilizados para tratamento dos eventos “onShow” e “onHide” da janela, além de vincular o método “openAgenda” ao clicarmos no link “Ver Agenda” do nosso gadget acoplado:

//Lógica implementada em: “default.js”

System.Gadget.Flyout.file = "flyout.html";

System.Gadget.Flyout.onShow = addContentToFlyout;
System.Gadget.Flyout.onHide = restoreInitialValues;

function openAgenda()
{
	System.Gadget.Flyout.show = !(System.Gadget.Flyout.show);
}

function addContentToFlyout(){
	flyOutOpener.innerHTML = "Fechar Agenda";
	var flyoutDiv =  System.Gadget.Flyout.document;

	flyoutDiv.getElementById("flyAgendaDate").innerHTML = currentTimeOptionText;
}
function restoreInitialValues(){
	flyOutOpener.innerHTML = "Ver Agenda";
}
			

Para o arquivo “flyout.html”, criamos um arquivo “flyout.js” associado e também incluímos como referência o arquivo “global.js” que possui as funções de processamento da lista retornada e paginação. Criando uma rotina semelhante de recuperação e exibição de dados àquela já descrita para o gadget desacoplado, temos como resultado o conteúdo exibido na fig. 04:

Fig. 04 – Tela “Flyout” exibida com o gadget ”Agenda do TechEd 2006”



Próximos Tópicos e Mais Informações

Para a lista completa de objetos Sidebar acessíveis via javascript, consulte a lista de referências no MSDN (em inglês): http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sidebar/sidebar/reference/refs.asp

A lista de referência DHTML também é bastante útil no desenvolvimento de gadgets, segue como exemplo os links para as informações sobre o “XmlHttpRequest” (utilizado para a recuperação dos dados da agenda) e como estabelecer intervalos de atualização de conteúdo com o “setInterval”: http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/objects/obj_xmlhttprequest.asp, http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/methods/setinterval.asp

Apesar do uso de HTML ser a forma suportada e indicada para a construção de gadgets para a barra lateral, qualquer funcionalidade necessária a um gadget mas não disponível como API pode ser desenvolvida como controle ActiveX feito sob medida. O desenvolvimento de controles em C# ou VB.NET pode habilitar desenvolvedores com menos familiaridade na programação DHTML/javascript a construirem seus gadgets, possibilitando riqueza de experiência visual, porém trazendo alguns desafios que serão discutidos na terceira parte deste tutorial, quando abordaremos o uso de código gerenciado e desenvolvimento WPF com gadgets.


Abraços e boa diversão!

Aline Rokutan – http://alinefmrk.spaces.live.com


Início da páginaInício da página